kvm: Implement virtio blk device config space

Signed-off-by: Pekka Enberg <penberg@kernel.org>
This commit is contained in:
Pekka Enberg
2015-06-01 16:39:40 +01:00
committed by Will Deacon
parent dc53a427d0
commit 40ce993fd2
2 changed files with 41 additions and 13 deletions
+38 -13
View File
@@ -9,27 +9,51 @@
#define VIRTIO_BLK_IRQ 14
struct device {
uint32_t host_features;
uint32_t guest_features;
uint8_t status;
struct virtio_blk_config blk_config;
uint32_t host_features;
uint32_t guest_features;
uint16_t config_vector;
uint8_t status;
};
#define DISK_CYLINDERS 1024
#define DISK_HEADS 64
#define DISK_SECTORS 32
static struct device device = {
.blk_config = (struct virtio_blk_config) {
.capacity = DISK_CYLINDERS * DISK_HEADS * DISK_SECTORS,
/* VIRTIO_BLK_F_GEOMETRY */
.geometry = {
.cylinders = DISK_CYLINDERS,
.heads = DISK_HEADS,
.sectors = DISK_SECTORS,
},
/* VIRTIO_BLK_SIZE */
.blk_size = 4096,
},
.host_features = (1UL << VIRTIO_BLK_F_GEOMETRY)
| (1UL << VIRTIO_BLK_F_TOPOLOGY)
| (1UL << VIRTIO_BLK_F_BLK_SIZE),
};
static bool virtio_blk_config_in(void *data, unsigned long offset, int size, uint32_t count)
{
uint8_t *config_space = (uint8_t *) &device.blk_config;
if (size != 1 || count != 1)
return false;
ioport__write8(data, config_space[offset - VIRTIO_PCI_CONFIG_NOMSI]);
return true;
}
static bool blk_virtio_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count)
{
unsigned long offset;
offset = port - IOPORT_VIRTIO;
/* XXX: Let virtio block device handle this */
if (offset >= VIRTIO_PCI_CONFIG_NOMSI)
return true;
switch (offset) {
case VIRTIO_PCI_HOST_FEATURES:
ioport__write32(data, device.host_features);
@@ -53,8 +77,10 @@ static bool blk_virtio_in(struct kvm *self, uint16_t port, void *data, int size,
kvm__irq_line(self, VIRTIO_BLK_IRQ, 0);
break;
case VIRTIO_MSI_CONFIG_VECTOR:
ioport__write16(data, device.config_vector);
break;
default:
return false;
return virtio_blk_config_in(data, offset, size, count);
};
return true;
@@ -66,10 +92,6 @@ static bool blk_virtio_out(struct kvm *self, uint16_t port, void *data, int size
offset = port - IOPORT_VIRTIO;
/* XXX: Let virtio block device handle this */
if (offset >= VIRTIO_PCI_CONFIG_NOMSI)
return true;
switch (offset) {
case VIRTIO_PCI_GUEST_FEATURES:
device.guest_features = ioport__read32(data);
@@ -85,7 +107,10 @@ static bool blk_virtio_out(struct kvm *self, uint16_t port, void *data, int size
device.status = ioport__read8(data);
break;
case VIRTIO_MSI_CONFIG_VECTOR:
device.config_vector = VIRTIO_MSI_NO_VECTOR;
break;
case VIRTIO_MSI_QUEUE_VECTOR:
break;
default:
return false;
};
+3
View File
@@ -49,6 +49,9 @@
/* A 16-bit vector for selected queue notifications. */
#define VIRTIO_MSI_QUEUE_VECTOR 22
/* Vector value used to disable MSI for queue */
#define VIRTIO_MSI_NO_VECTOR 0xffff
/* Config space size */
#define VIRTIO_PCI_CONFIG_NOMSI 20
#define VIRTIO_PCI_CONFIG_MSI 24