[PATCH 5/6] kvm tools: Seperate virtio-pci layer out of virtio-9p

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

 



Signed-off-by: Sasha Levin <levinsasha928@xxxxxxxxx>
---
 tools/kvm/builtin-run.c           |    8 +-
 tools/kvm/include/kvm/virtio-9p.h |   16 ++--
 tools/kvm/virtio/9p.c             |  247 +++++++++++++++----------------------
 3 files changed, 111 insertions(+), 160 deletions(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 501e0bf..00f9b25 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -106,7 +106,7 @@ static int img_name_parser(const struct option *opt, const char *arg, int unset)
 		char tmp[PATH_MAX];
 
 		if (realpath(arg, tmp) == 0 ||
-		    virtio_9p__init(kvm, tmp, "/dev/root") < 0)
+		    virtio_9p__register(kvm, tmp, "/dev/root") < 0)
 			die("Unable to initialize virtio 9p");
 		using_rootfs = 1;
 		return 0;
@@ -144,7 +144,7 @@ static int virtio_9p_rootdir_parser(const struct option *opt, const char *arg, i
 		tag_name++;
 	}
 	if (realpath(arg, tmp)) {
-		if (virtio_9p__init(kvm, tmp, tag_name) < 0)
+		if (virtio_9p__register(kvm, tmp, tag_name) < 0)
 			die("Unable to initialize virtio 9p");
 	} else
 		die("Failed resolving 9p path");
@@ -598,7 +598,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 		strlcat(real_cmdline, kernel_cmdline, sizeof(real_cmdline));
 
 	if (!using_rootfs && !image_filename[0]) {
-		if (virtio_9p__init(kvm, "/", "/dev/root") < 0)
+		if (virtio_9p__register(kvm, "/", "/dev/root") < 0)
 			die("Unable to initialize virtio 9p");
 
 		using_rootfs = 1;
@@ -650,6 +650,8 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 	if (!network)
 		network = DEFAULT_NETWORK;
 
+	virtio_9p__init(kvm);
+
 	if (strncmp(network, "none", 4)) {
 		net_params.guest_ip = guest_ip;
 		net_params.host_ip = host_ip;
diff --git a/tools/kvm/include/kvm/virtio-9p.h b/tools/kvm/include/kvm/virtio-9p.h
index 70db831..7ce56b7 100644
--- a/tools/kvm/include/kvm/virtio-9p.h
+++ b/tools/kvm/include/kvm/virtio-9p.h
@@ -3,9 +3,11 @@
 #include "kvm/virtio.h"
 #include "kvm/pci.h"
 #include "kvm/threadpool.h"
+#include "kvm/virtio-pci.h"
 
 #include <sys/types.h>
 #include <dirent.h>
+#include <linux/list.h>
 
 #define NUM_VIRT_QUEUES		1
 #define VIRTQUEUE_NUM		128
@@ -38,21 +40,18 @@ struct p9_dev_job {
 };
 
 struct p9_dev {
-	u8			status;
-	u8			isr;
-	u16			config_vector;
-	u32			features;
+	struct list_head	list;
+	struct virtio_pci	vpci;
+	
 	struct virtio_9p_config	*config;
-	u16			base_addr;
 	int			compat_id;
+	u32			features;
 
 	/* virtio queue */
-	u16			queue_selector;
 	struct virt_queue	vqs[NUM_VIRT_QUEUES];
 	struct p9_dev_job	jobs[NUM_VIRT_QUEUES];
 	struct p9_fid		fids[VIRTIO_P9_MAX_FID];
 	char			root_dir[PATH_MAX];
-	struct pci_device_header pci_hdr;
 };
 
 struct p9_pdu {
@@ -67,7 +66,8 @@ struct p9_pdu {
 
 struct kvm;
 
-int virtio_9p__init(struct kvm *kvm, const char *root, const char *tag_name);
+int virtio_9p__register(struct kvm *kvm, const char *root, const char *tag_name);
+int virtio_9p__init(struct kvm *kvm);
 int virtio_p9_pdu_readf(struct p9_pdu *pdu, const char *fmt, ...);
 int virtio_p9_pdu_writef(struct p9_pdu *pdu, const char *fmt, ...);
 
diff --git a/tools/kvm/virtio/9p.c b/tools/kvm/virtio/9p.c
index 8a4fe73..e5c106a 100644
--- a/tools/kvm/virtio/9p.c
+++ b/tools/kvm/virtio/9p.c
@@ -19,6 +19,8 @@
 #include <linux/virtio_9p.h>
 #include <net/9p/9p.h>
 
+static LIST_HEAD(devs);
+
 /* Warning: Immediately use value returned from this function */
 static const char *rel_to_abs(struct p9_dev *p9dev,
 			      const char *path, char *abs_path)
@@ -28,62 +30,6 @@ static const char *rel_to_abs(struct p9_dev *p9dev,
 	return abs_path;
 }
 
-static bool virtio_p9_dev_in(struct p9_dev *p9dev, void *data,
-			     unsigned long offset,
-			     int size)
-{
-	u8 *config_space = (u8 *) p9dev->config;
-
-	if (size != 1)
-		return false;
-
-	ioport__write8(data, config_space[offset - VIRTIO_MSI_CONFIG_VECTOR]);
-
-	return true;
-}
-
-static bool virtio_p9_pci_io_in(struct ioport *ioport, struct kvm *kvm,
-				u16 port, void *data, int size)
-{
-	bool ret = true;
-	unsigned long offset;
-	struct p9_dev *p9dev = ioport->priv;
-
-
-	offset = port - p9dev->base_addr;
-
-	switch (offset) {
-	case VIRTIO_PCI_HOST_FEATURES:
-		ioport__write32(data, p9dev->features);
-		ret = true;
-		break;
-	case VIRTIO_PCI_GUEST_FEATURES:
-	case VIRTIO_PCI_QUEUE_SEL:
-	case VIRTIO_PCI_QUEUE_NOTIFY:
-		ret = false;
-		break;
-	case VIRTIO_PCI_QUEUE_PFN:
-		ioport__write32(data, p9dev->vqs[p9dev->queue_selector].pfn);
-		break;
-	case VIRTIO_PCI_QUEUE_NUM:
-		ioport__write16(data, VIRTQUEUE_NUM);
-		break;
-	case VIRTIO_PCI_STATUS:
-		ioport__write8(data, p9dev->status);
-		break;
-	case VIRTIO_PCI_ISR:
-		ioport__write8(data, p9dev->isr);
-		kvm__irq_line(kvm, p9dev->pci_hdr.irq_line, VIRTIO_IRQ_LOW);
-		p9dev->isr = VIRTIO_IRQ_LOW;
-		break;
-	default:
-		ret = virtio_p9_dev_in(p9dev, data, offset, size);
-		break;
-	};
-
-	return ret;
-}
-
 static int omode2uflags(u8 mode)
 {
 	int ret = 0;
@@ -750,8 +696,7 @@ static void virtio_p9_do_io(struct kvm *kvm, void *param)
 
 	while (virt_queue__available(vq)) {
 		virtio_p9_do_io_request(kvm, job);
-		virt_queue__trigger_irq(vq, p9dev->pci_hdr.irq_line,
-					&p9dev->isr, kvm);
+		virtio_pci__signal_vq(kvm, &p9dev->vpci, vq - p9dev->vqs);
 	}
 }
 
@@ -762,90 +707,115 @@ static void ioevent_callback(struct kvm *kvm, void *param)
 	thread_pool__do_job(&job->job_id);
 }
 
-static bool virtio_p9_pci_io_out(struct ioport *ioport, struct kvm *kvm,
-				 u16 port, void *data, int size)
+static void set_config(struct kvm *kvm, void *dev, u8 data, u32 offset)
 {
-	unsigned long offset;
-	bool ret = true;
-	struct p9_dev  *p9dev;
-	struct ioevent ioevent;
+	struct p9_dev *p9dev = dev;
 
-	p9dev = ioport->priv;
-	offset = port - p9dev->base_addr;
+	((u8 *)(p9dev->config))[offset] = data;
+}
 
-	switch (offset) {
-	case VIRTIO_MSI_QUEUE_VECTOR:
-	case VIRTIO_PCI_GUEST_FEATURES:
-		break;
-	case VIRTIO_PCI_QUEUE_PFN: {
-		void *p;
-		struct p9_dev_job *job;
-		struct virt_queue *queue;
+static u8 get_config(struct kvm *kvm, void *dev, u32 offset)
+{
+	struct p9_dev *p9dev = dev;
 
-		compat__remove_message(p9dev->compat_id);
+	return ((u8 *)(p9dev->config))[offset];
+}
 
-		job			= &p9dev->jobs[p9dev->queue_selector];
-		queue			= &p9dev->vqs[p9dev->queue_selector];
-		queue->pfn		= ioport__read32(data);
-		p			= guest_pfn_to_host(kvm, queue->pfn);
+static u32 get_host_features(struct kvm *kvm, void *dev)
+{
+	return 1 << VIRTIO_9P_MOUNT_TAG;
+}
 
-		vring_init(&queue->vring, VIRTQUEUE_NUM, p,
-			   VIRTIO_PCI_VRING_ALIGN);
+static void set_guest_features(struct kvm *kvm, void *dev, u32 features)
+{
+	struct p9_dev *p9dev = dev;
 
-		*job			= (struct p9_dev_job) {
-			.vq			= queue,
-			.p9dev			= p9dev,
-		};
-		thread_pool__init_job(&job->job_id, kvm, virtio_p9_do_io, job);
-
-		ioevent = (struct ioevent) {
-			.io_addr		= p9dev->base_addr + VIRTIO_PCI_QUEUE_NOTIFY,
-			.io_len			= sizeof(u16),
-			.fn			= ioevent_callback,
-			.datamatch		= p9dev->queue_selector,
-			.fn_ptr			= &p9dev->jobs[p9dev->queue_selector],
-			.fn_kvm			= kvm,
-			.fd			= eventfd(0, 0),
-		};
+	p9dev->features = features;
+}
 
-		ioeventfd__add_event(&ioevent);
+static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 pfn)
+{
+	struct p9_dev *p9dev = dev;
+	struct p9_dev_job *job;
+	struct virt_queue *queue;
+	void *p;
+	struct ioevent ioevent;
 
-		break;
-	}
-	case VIRTIO_PCI_QUEUE_SEL:
-		p9dev->queue_selector	= ioport__read16(data);
-		break;
-	case VIRTIO_PCI_QUEUE_NOTIFY: {
-		u16 queue_index;
-
-		queue_index		= ioport__read16(data);
-		thread_pool__do_job(&p9dev->jobs[queue_index].job_id);
-		break;
-	}
-	case VIRTIO_PCI_STATUS:
-		p9dev->status		= ioport__read8(data);
-		break;
-	case VIRTIO_MSI_CONFIG_VECTOR:
-		p9dev->config_vector	= VIRTIO_MSI_NO_VECTOR;
-		break;
-	default:
-		ret			= false;
-		break;
+	compat__remove_message(p9dev->compat_id);
+
+	queue			= &p9dev->vqs[vq];
+	queue->pfn		= pfn;
+	p			= guest_pfn_to_host(kvm, queue->pfn);
+	job			= &p9dev->jobs[vq];
+
+	vring_init(&queue->vring, VIRTQUEUE_NUM, p, VIRTIO_PCI_VRING_ALIGN);
+
+	*job			= (struct p9_dev_job) {
+		.vq			= queue,
+		.p9dev			= p9dev,
+	};
+	thread_pool__init_job(&job->job_id, kvm, virtio_p9_do_io, job);
+
+	ioevent = (struct ioevent) {
+		.io_addr	= p9dev->vpci.base_addr + VIRTIO_PCI_QUEUE_NOTIFY,
+		.io_len		= sizeof(u16),
+		.fn		= ioevent_callback,
+		.fn_ptr		= &p9dev->jobs[vq],
+		.datamatch	= vq,
+		.fn_kvm		= kvm,
+		.fd		= eventfd(0, 0),
 	};
 
-	return ret;
+	ioeventfd__add_event(&ioevent);
+
+	return 0;
 }
 
-static struct ioport_operations virtio_p9_io_ops = {
-	.io_in				= virtio_p9_pci_io_in,
-	.io_out				= virtio_p9_pci_io_out,
-};
+static int notify_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	struct p9_dev *p9dev = dev;
+
+	thread_pool__do_job(&p9dev->jobs[vq].job_id);
+
+	return 0;
+}
+
+static int get_pfn_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	struct p9_dev *p9dev = dev;
+
+	return p9dev->vqs[vq].pfn;
+}
 
-int virtio_9p__init(struct kvm *kvm, const char *root, const char *tag_name)
+static int get_size_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	return VIRTQUEUE_NUM;
+}
+
+int virtio_9p__init(struct kvm *kvm)
+{
+	struct p9_dev *p9dev;
+
+	list_for_each_entry(p9dev, &devs, list) {
+		virtio_pci__init(kvm, &p9dev->vpci, p9dev, PCI_DEVICE_ID_VIRTIO_P9, VIRTIO_ID_9P);
+		p9dev->vpci.ops = (struct virtio_pci_ops) {
+			.set_config		= set_config,
+			.get_config		= get_config,
+			.get_host_features	= get_host_features,
+			.set_guest_features	= set_guest_features,
+			.init_vq		= init_vq,
+			.notify_vq		= notify_vq,
+			.get_pfn_vq		= get_pfn_vq,
+			.get_size_vq		= get_size_vq,
+		};
+	}
+
+	return 0;
+}
+
+int virtio_9p__register(struct kvm *kvm, const char *root, const char *tag_name)
 {
 	struct p9_dev *p9dev;
-	u8 pin, line, dev;
-	u16 p9_base_addr;
 	u32 i, root_len;
 	int err = 0;
 
@@ -878,30 +848,9 @@ int virtio_9p__init(struct kvm *kvm, const char *root, const char *tag_name)
 		goto free_p9dev_config;
 	}
 
-	memcpy(p9dev->config->tag, tag_name, strlen(tag_name));
-	p9dev->features |= 1 << VIRTIO_9P_MOUNT_TAG;
+	memcpy(&p9dev->config->tag, tag_name, strlen(tag_name));
 
-	err = irq__register_device(VIRTIO_ID_9P, &dev, &pin, &line);
-	if (err < 0)
-		goto free_p9dev_config;
-
-	p9_base_addr = ioport__register(IOPORT_EMPTY, &virtio_p9_io_ops, IOPORT_SIZE, p9dev);
-
-	p9dev->base_addr = p9_base_addr;
-
-	p9dev->pci_hdr = (struct pci_device_header) {
-		.vendor_id		= PCI_VENDOR_ID_REDHAT_QUMRANET,
-		.device_id		= PCI_DEVICE_ID_VIRTIO_P9,
-		.header_type		= PCI_HEADER_TYPE_NORMAL,
-		.revision_id		= 0,
-		.class			= 0x010000,
-		.subsys_vendor_id	= PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
-		.subsys_id		= VIRTIO_ID_9P,
-		.irq_pin		= pin,
-		.irq_line		= line,
-		.bar[0]			= p9_base_addr | PCI_BASE_ADDRESS_SPACE_IO,
-	};
-	pci__register(&p9dev->pci_hdr, dev);
+	list_add(&p9dev->list, &devs);
 
 	p9dev->compat_id = compat__add_message("virtio-9p device was not detected",
 						"While you have requested a virtio-9p device, "
-- 
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