[PATCH 2/2] kvm tools: Fix offset calculation for config space and MSI-X

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch makes offsets for virtio config space and MSI-X dynamic.

The change should fix the wrong usage of MSI-X space as virtio
config space.

Signed-off-by: Sasha Levin <levinsasha928@xxxxxxxxx>
---
 tools/kvm/virtio/net.c |   78 +++++++++++++++++++++++++++++++++++-------------
 1 files changed, 57 insertions(+), 21 deletions(-)

diff --git a/tools/kvm/virtio/net.c b/tools/kvm/virtio/net.c
index 96858b7..aa4536b 100644
--- a/tools/kvm/virtio/net.c
+++ b/tools/kvm/virtio/net.c
@@ -65,6 +65,7 @@ struct net_dev {
 	u32				gsis[VIRTIO_NET_NUM_QUEUES];
 	u32				msix_io_block;
 	int				compat_id;
+	bool				msix_enabled;
 
 	pthread_t			io_rx_thread;
 	pthread_mutex_t			io_rx_lock;
@@ -176,17 +177,67 @@ static void *virtio_net_tx_thread(void *p)
 
 }
 
+static bool virtio_net_pci_io_device_specific_out(struct kvm *kvm, void *data,
+							unsigned long offset, int size)
+{
+	u8 *config_space = (u8 *)&ndev.config;
+	int type;
+	u32 config_offset;
+
+	type = virtio__get_dev_specific_field(offset - 20, ndev.msix_enabled, 0, &config_offset);
+	if (type == VIRTIO_PCI_O_MSIX) {
+		if (offset == VIRTIO_MSI_CONFIG_VECTOR) {
+			ndev.config_vector	= ioport__read16(data);
+		} else {
+			u32 gsi;
+			u32 vec;
+
+			vec = ndev.vq_vector[ndev.queue_selector] = ioport__read16(data);
+
+			gsi = irq__add_msix_route(kvm,
+						  pci_header.msix.table[vec].low,
+						  pci_header.msix.table[vec].high,
+						  pci_header.msix.table[vec].data);
+
+			ndev.gsis[ndev.queue_selector] = gsi;
+		}
+		return true;
+	}
+
+	if (size != 1)
+		return false;
+
+	if ((config_offset) > sizeof(struct virtio_net_config))
+		pr_error("config offset is too big: %u", config_offset);
+
+	config_space[config_offset] = *(u8 *)data;
+
+	return true;
+}
+
 static bool virtio_net_pci_io_device_specific_in(void *data, unsigned long offset, int size)
 {
 	u8 *config_space = (u8 *)&ndev.config;
+	int type;
+	u32 config_offset;
+
+	type = virtio__get_dev_specific_field(offset - 20, ndev.msix_enabled, 0, &config_offset);
+	if (type == VIRTIO_PCI_O_MSIX) {
+		if (offset == VIRTIO_MSI_CONFIG_VECTOR)
+			ioport__write16(data, ndev.config_vector);
+		else
+			ioport__write16(data, ndev.vq_vector[ndev.queue_selector]);
+
+		return true;
+	}
 
 	if (size != 1)
 		return false;
 
-	if ((offset - VIRTIO_MSI_CONFIG_VECTOR) > sizeof(struct virtio_net_config))
-		pr_error("config offset is too big: %li", offset - VIRTIO_MSI_CONFIG_VECTOR);
+	if ((config_offset) > sizeof(struct virtio_net_config))
+		pr_error("config offset is too big: %u", config_offset);
 
-	ioport__write8(data, config_space[offset - VIRTIO_MSI_CONFIG_VECTOR]);
+	ioport__write8(data, config_space[config_offset]);
 
 	return true;
 }
@@ -290,25 +341,8 @@ static bool virtio_net_pci_io_out(struct ioport *ioport, struct kvm *kvm, u16 po
 	case VIRTIO_PCI_STATUS:
 		ndev.status		= ioport__read8(data);
 		break;
-	case VIRTIO_MSI_CONFIG_VECTOR:
-		ndev.config_vector	= ioport__read16(data);
-		break;
-	case VIRTIO_MSI_QUEUE_VECTOR: {
-		u32 gsi;
-		u32 vec;
-
-		vec = ndev.vq_vector[ndev.queue_selector] = ioport__read16(data);
-
-		gsi = irq__add_msix_route(kvm,
-					  pci_header.msix.table[vec].low,
-					  pci_header.msix.table[vec].high,
-					  pci_header.msix.table[vec].data);
-
-		ndev.gsis[ndev.queue_selector] = gsi;
-		break;
-	}
 	default:
-		ret			= false;
+		ret = virtio_net_pci_io_device_specific_out(kvm, data, offset, size);
 	};
 
 	mutex_unlock(&ndev.mutex);
@@ -333,6 +367,8 @@ static void callback_mmio(u64 addr, u8 *data, u32 len, u8 is_write, void *ptr)
 		memcpy(table + addr - ndev.msix_io_block, data, len);
 	else
 		memcpy(data, table + addr - ndev.msix_io_block, len);
+
+	ndev.msix_enabled = 1;
 }
 
 static bool virtio_net__tap_init(const struct virtio_net_parameters *params)
-- 
1.7.6

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux