All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks
@ 2011-05-26  6:42 Sasha Levin
  2011-05-26  6:42 ` [PATCH v2 2/8] kvm tools: Add basic ioport dynamic allocation Sasha Levin
                   ` (7 more replies)
  0 siblings, 8 replies; 16+ messages in thread
From: Sasha Levin @ 2011-05-26  6:42 UTC (permalink / raw)
  To: penberg
  Cc: john, kvm, mingo, asias.hejun, gorcunov, prasadjoshi124, Sasha Levin

Allow specifying an optional parameter when registering an
ioport range. The callback functions provided by the registering
module will be called with the same parameter.

This may be used to keep context during callbacks on IO operations.

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 tools/kvm/include/kvm/ioport.h |    3 ++
 tools/kvm/ioport.c             |   54 +++++++++++++++++++++++++++++----------
 2 files changed, 43 insertions(+), 14 deletions(-)

diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
index 8253938..2a8d74d 100644
--- a/tools/kvm/include/kvm/ioport.h
+++ b/tools/kvm/include/kvm/ioport.h
@@ -25,11 +25,14 @@ struct kvm;
 struct ioport_operations {
 	bool (*io_in)(struct kvm *kvm, u16 port, void *data, int size, u32 count);
 	bool (*io_out)(struct kvm *kvm, u16 port, void *data, int size, u32 count);
+	bool (*io_in_param)(struct kvm *kvm, u16 port, void *data, int size, u32 count, void *param);
+	bool (*io_out_param)(struct kvm *kvm, u16 port, void *data, int size, u32 count, void *param);
 };
 
 void ioport__setup_legacy(void);
 
 void ioport__register(u16 port, struct ioport_operations *ops, int count);
+void ioport__register_param(u16 port, struct ioport_operations *ops, int count, void *param);
 
 static inline u8 ioport__read8(u8 *data)
 {
diff --git a/tools/kvm/ioport.c b/tools/kvm/ioport.c
index 1f13960..159d089 100644
--- a/tools/kvm/ioport.c
+++ b/tools/kvm/ioport.c
@@ -18,6 +18,7 @@
 struct ioport_entry {
 	struct rb_int_node		node;
 	struct ioport_operations	*ops;
+	void				*param;
 };
 
 static struct rb_root ioport_tree = RB_ROOT;
@@ -89,6 +90,29 @@ void ioport__register(u16 port, struct ioport_operations *ops, int count)
 	ioport_insert(&ioport_tree, entry);
 }
 
+void ioport__register_param(u16 port, struct ioport_operations *ops, int count, void *param)
+{
+	struct ioport_entry *entry;
+
+	entry = ioport_search(&ioport_tree, port);
+	if (entry) {
+		pr_warning("ioport re-registered: %x", port);
+		rb_int_erase(&ioport_tree, &entry->node);
+	}
+
+	entry = malloc(sizeof(*entry));
+	if (entry == NULL)
+		die("Failed allocating new ioport entry");
+
+	*entry = (struct ioport_entry) {
+		.node	= RB_INT_INIT(port, port + count),
+		.ops	= ops,
+		.param	= param,
+	};
+
+	ioport_insert(&ioport_tree, entry);
+}
+
 static const char *to_direction(int direction)
 {
 	if (direction == KVM_EXIT_IO_IN)
@@ -105,30 +129,32 @@ static void ioport_error(u16 port, void *data, int direction, int size, u32 coun
 bool kvm__emulate_io(struct kvm *kvm, u16 port, void *data, int direction, int size, u32 count)
 {
 	struct ioport_operations *ops;
-	bool ret;
+	bool ret = false;
 	struct ioport_entry *entry;
+	void *param;
 
 	entry = ioport_search(&ioport_tree, port);
 	if (!entry)
 		goto error;
 
-	ops = entry->ops;
+	ops	= entry->ops;
+	param	= entry->param;
 
 	if (direction == KVM_EXIT_IO_IN) {
-		if (!ops->io_in)
-			goto error;
-
-		ret = ops->io_in(kvm, port, data, size, count);
-		if (!ret)
-			goto error;
+		if (!param && ops->io_in)
+			ret = ops->io_in(kvm, port, data, size, count);
+		if (param && ops->io_in_param)
+			ret = ops->io_in_param(kvm, port, data, size, count, param);
 	} else {
-		if (!ops->io_out)
-			goto error;
-
-		ret = ops->io_out(kvm, port, data, size, count);
-		if (!ret)
-			goto error;
+		if (!param && ops->io_out)
+			ret = ops->io_out(kvm, port, data, size, count);
+		if (param && ops->io_out_param)
+			ret = ops->io_out_param(kvm, port, data, size, count, param);
 	}
+
+	if (!ret)
+		goto error;
+
 	return true;
 error:
 	if (ioport_debug)
-- 
1.7.5.rc3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 2/8] kvm tools: Add basic ioport dynamic allocation
  2011-05-26  6:42 [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks Sasha Levin
@ 2011-05-26  6:42 ` Sasha Levin
  2011-05-26  6:42 ` [PATCH v2 3/8] kvm tools: Use ioport context to control blk devices Sasha Levin
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Sasha Levin @ 2011-05-26  6:42 UTC (permalink / raw)
  To: penberg
  Cc: john, kvm, mingo, asias.hejun, gorcunov, prasadjoshi124, Sasha Levin

Add a very simple allocation of ioports.

This prevents the need to coordinate ioports between different
modules.

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 tools/kvm/include/kvm/ioport.h |   11 +++++++++--
 tools/kvm/ioport.c             |   36 ++++++++++++++++++++++++++++++++++--
 2 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
index 2a8d74d..c500f1e 100644
--- a/tools/kvm/include/kvm/ioport.h
+++ b/tools/kvm/include/kvm/ioport.h
@@ -7,6 +7,9 @@
 
 /* some ports we reserve for own use */
 #define IOPORT_DBG			0xe0
+#define IOPORT_START			0x6200
+#define IOPORT_SIZE			0x400
+
 #define IOPORT_VESA			0xa200
 #define IOPORT_VESA_SIZE		256
 #define IOPORT_VIRTIO_P9		0xb200	/* Virtio 9P device */
@@ -20,6 +23,8 @@
 #define IOPORT_VIRTIO_RNG		0xf200	/* Virtio network device */
 #define IOPORT_VIRTIO_RNG_SIZE		256
 
+#define IOPORT_EMPTY			USHRT_MAX
+
 struct kvm;
 
 struct ioport_operations {
@@ -31,8 +36,10 @@ struct ioport_operations {
 
 void ioport__setup_legacy(void);
 
-void ioport__register(u16 port, struct ioport_operations *ops, int count);
-void ioport__register_param(u16 port, struct ioport_operations *ops, int count, void *param);
+u16 ioport__register(u16 port, struct ioport_operations *ops, int count);
+u16 ioport__register_param(u16 port, struct ioport_operations *ops, int count, void *param);
+
+u16 ioport__find_free_range(void);
 
 static inline u8 ioport__read8(u8 *data)
 {
diff --git a/tools/kvm/ioport.c b/tools/kvm/ioport.c
index 159d089..b2a3272 100644
--- a/tools/kvm/ioport.c
+++ b/tools/kvm/ioport.c
@@ -3,6 +3,7 @@
 #include "kvm/kvm.h"
 #include "kvm/util.h"
 #include "kvm/rbtree-interval.h"
+#include "kvm/mutex.h"
 
 #include <linux/kvm.h>	/* for KVM_EXIT_* */
 #include <linux/types.h>
@@ -21,9 +22,23 @@ struct ioport_entry {
 	void				*param;
 };
 
+static u16 free_io_port_idx;
+DEFINE_MUTEX(free_io_port_idx_lock);
 static struct rb_root ioport_tree = RB_ROOT;
 bool ioport_debug;
 
+static u16 ioport__find_free_port(void)
+{
+	u16 free_port;
+
+	mutex_lock(&free_io_port_idx_lock);
+	free_port = IOPORT_START + free_io_port_idx * IOPORT_SIZE;
+	free_io_port_idx++;
+	mutex_unlock(&free_io_port_idx_lock);
+
+	return free_port;
+}
+
 static struct ioport_entry *ioport_search(struct rb_root *root, u64 addr)
 {
 	struct rb_int_node *node;
@@ -68,10 +83,13 @@ static struct ioport_operations dummy_write_only_ioport_ops = {
 	.io_out		= dummy_io_out,
 };
 
-void ioport__register(u16 port, struct ioport_operations *ops, int count)
+u16 ioport__register(u16 port, struct ioport_operations *ops, int count)
 {
 	struct ioport_entry *entry;
 
+	if (port == IOPORT_EMPTY)
+		port = ioport__find_free_port();
+
 	entry = ioport_search(&ioport_tree, port);
 	if (entry) {
 		pr_warning("ioport re-registered: %x", port);
@@ -88,12 +106,17 @@ void ioport__register(u16 port, struct ioport_operations *ops, int count)
 	};
 
 	ioport_insert(&ioport_tree, entry);
+
+	return port;
 }
 
-void ioport__register_param(u16 port, struct ioport_operations *ops, int count, void *param)
+u16 ioport__register_param(u16 port, struct ioport_operations *ops, int count, void *param)
 {
 	struct ioport_entry *entry;
 
+	if (port == IOPORT_EMPTY)
+		port = ioport__find_free_port();
+
 	entry = ioport_search(&ioport_tree, port);
 	if (entry) {
 		pr_warning("ioport re-registered: %x", port);
@@ -111,6 +134,8 @@ void ioport__register_param(u16 port, struct ioport_operations *ops, int count,
 	};
 
 	ioport_insert(&ioport_tree, entry);
+
+	return port;
 }
 
 static const char *to_direction(int direction)
@@ -126,6 +151,13 @@ static void ioport_error(u16 port, void *data, int direction, int size, u32 coun
 	fprintf(stderr, "IO error: %s port=%x, size=%d, count=%u\n", to_direction(direction), port, size, count);
 }
 
+u16 ioport__find_free_range(void)
+{
+	static u16 cur_loc;
+
+	return IOPORT_START + (cur_loc++ * IOPORT_SIZE);
+}
+
 bool kvm__emulate_io(struct kvm *kvm, u16 port, void *data, int direction, int size, u32 count)
 {
 	struct ioport_operations *ops;
-- 
1.7.5.rc3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 3/8] kvm tools: Use ioport context to control blk devices
  2011-05-26  6:42 [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks Sasha Levin
  2011-05-26  6:42 ` [PATCH v2 2/8] kvm tools: Add basic ioport dynamic allocation Sasha Levin
@ 2011-05-26  6:42 ` Sasha Levin
  2011-05-26  6:42 ` [PATCH v2 4/8] kvm tools: Add support for multiple virtio-rng devices Sasha Levin
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Sasha Levin @ 2011-05-26  6:42 UTC (permalink / raw)
  To: penberg
  Cc: john, kvm, mingo, asias.hejun, gorcunov, prasadjoshi124, Sasha Levin

Since ioports now has the ability to pass context to its
callbacks, we can implement multiple blk devices more efficiently.

We can get a ptr to the 'current' blk dev on each ioport call, which
means that we don't need to keep track of the blk device allocation
and ioport distribution within the module.

The advantages are easier management of multiple blk devices and
removal of any hardcoded limits to the amount of possible blk
devices.

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 tools/kvm/include/kvm/ioport.h |    2 -
 tools/kvm/virtio/blk.c         |   75 ++++++++++++++--------------------------
 2 files changed, 26 insertions(+), 51 deletions(-)

diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
index c500f1e..47f9fb5 100644
--- a/tools/kvm/include/kvm/ioport.h
+++ b/tools/kvm/include/kvm/ioport.h
@@ -14,8 +14,6 @@
 #define IOPORT_VESA_SIZE		256
 #define IOPORT_VIRTIO_P9		0xb200	/* Virtio 9P device */
 #define IOPORT_VIRTIO_P9_SIZE		256
-#define IOPORT_VIRTIO_BLK		0xc200	/* Virtio block device */
-#define IOPORT_VIRTIO_BLK_SIZE		0x200
 #define IOPORT_VIRTIO_CONSOLE		0xd200	/* Virtio console device */
 #define IOPORT_VIRTIO_CONSOLE_SIZE	256
 #define IOPORT_VIRTIO_NET		0xe200	/* Virtio network device */
diff --git a/tools/kvm/virtio/blk.c b/tools/kvm/virtio/blk.c
index 25ce61f..cb103fc 100644
--- a/tools/kvm/virtio/blk.c
+++ b/tools/kvm/virtio/blk.c
@@ -14,6 +14,7 @@
 #include <linux/virtio_ring.h>
 #include <linux/virtio_blk.h>
 
+#include <linux/list.h>
 #include <linux/types.h>
 #include <pthread.h>
 
@@ -34,15 +35,16 @@ struct blk_dev_job {
 
 struct blk_dev {
 	pthread_mutex_t			mutex;
+	struct list_head		list;
 
 	struct virtio_blk_config	blk_config;
 	struct disk_image		*disk;
+	u64				base_addr;
 	u32				host_features;
 	u32				guest_features;
 	u16				config_vector;
 	u8				status;
 	u8				isr;
-	u8				idx;
 
 	/* virtio queue */
 	u16				queue_selector;
@@ -52,7 +54,7 @@ struct blk_dev {
 	struct pci_device_header	pci_hdr;
 };
 
-static struct blk_dev *bdevs[VIRTIO_BLK_MAX_DEV];
+static LIST_HEAD(bdevs);
 
 static bool virtio_blk_dev_in(struct blk_dev *bdev, void *data, unsigned long offset, int size, u32 count)
 {
@@ -66,22 +68,14 @@ static bool virtio_blk_dev_in(struct blk_dev *bdev, void *data, unsigned long of
 	return true;
 }
 
-/* Translate port into device id + offset in that device addr space */
-static void virtio_blk_port2dev(u16 port, u16 base, u16 size, u16 *dev_idx, u16 *offset)
-{
-	*dev_idx	= (port - base) / size;
-	*offset		= port - (base + *dev_idx * size);
-}
-
-static bool virtio_blk_pci_io_in(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool virtio_blk_pci_io_in(struct kvm *kvm, u16 port, void *data, int size, u32 count, void *param)
 {
 	struct blk_dev *bdev;
-	u16 offset, dev_idx;
+	u16 offset;
 	bool ret = true;
 
-	virtio_blk_port2dev(port, IOPORT_VIRTIO_BLK, IOPORT_VIRTIO_BLK_SIZE, &dev_idx, &offset);
-
-	bdev = bdevs[dev_idx];
+	bdev	= param;
+	offset	= port - bdev->base_addr;
 
 	mutex_lock(&bdev->mutex);
 
@@ -178,15 +172,14 @@ static void virtio_blk_do_io(struct kvm *kvm, void *param)
 	virt_queue__trigger_irq(vq, bdev->pci_hdr.irq_line, &bdev->isr, kvm);
 }
 
-static bool virtio_blk_pci_io_out(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool virtio_blk_pci_io_out(struct kvm *kvm, u16 port, void *data, int size, u32 count, void *param)
 {
 	struct blk_dev *bdev;
-	u16 offset, dev_idx;
+	u16 offset;
 	bool ret = true;
 
-	virtio_blk_port2dev(port, IOPORT_VIRTIO_BLK, IOPORT_VIRTIO_BLK_SIZE, &dev_idx, &offset);
-
-	bdev = bdevs[dev_idx];
+	bdev	= param;
+	offset	= port - bdev->base_addr;
 
 	mutex_lock(&bdev->mutex);
 
@@ -246,48 +239,29 @@ static bool virtio_blk_pci_io_out(struct kvm *kvm, u16 port, void *data, int siz
 }
 
 static struct ioport_operations virtio_blk_io_ops = {
-	.io_in		= virtio_blk_pci_io_in,
-	.io_out		= virtio_blk_pci_io_out,
+	.io_in_param	= virtio_blk_pci_io_in,
+	.io_out_param	= virtio_blk_pci_io_out,
 };
 
-static int virtio_blk_find_empty_dev(void)
-{
-	int i;
-
-	for (i = 0; i < VIRTIO_BLK_MAX_DEV; i++) {
-		if (bdevs[i] == NULL)
-			return i;
-	}
-
-	return -1;
-}
-
 void virtio_blk__init(struct kvm *kvm, struct disk_image *disk)
 {
 	u16 blk_dev_base_addr;
 	u8 dev, pin, line;
 	struct blk_dev *bdev;
-	int new_dev_idx;
 
 	if (!disk)
 		return;
 
-	new_dev_idx		= virtio_blk_find_empty_dev();
-	if (new_dev_idx < 0)
-		die("Could not find an empty block device slot");
-
-	bdevs[new_dev_idx]	= calloc(1, sizeof(struct blk_dev));
-	if (bdevs[new_dev_idx] == NULL)
+	bdev = calloc(1, sizeof(struct blk_dev));
+	if (bdev == NULL)
 		die("Failed allocating bdev");
 
-	bdev			= bdevs[new_dev_idx];
-
-	blk_dev_base_addr	= IOPORT_VIRTIO_BLK + new_dev_idx * IOPORT_VIRTIO_BLK_SIZE;
+	blk_dev_base_addr	= ioport__register_param(IOPORT_EMPTY, &virtio_blk_io_ops, IOPORT_SIZE, bdev);
 
 	*bdev			= (struct blk_dev) {
 		.mutex				= PTHREAD_MUTEX_INITIALIZER,
 		.disk				= disk,
-		.idx				= new_dev_idx,
+		.base_addr			= blk_dev_base_addr,
 		.blk_config			= (struct virtio_blk_config) {
 			.capacity		= disk->size / SECTOR_SIZE,
 			.seg_max		= DISK_SEG_MAX,
@@ -310,6 +284,8 @@ void virtio_blk__init(struct kvm *kvm, struct disk_image *disk)
 		.host_features			= (1UL << VIRTIO_BLK_F_SEG_MAX | 1UL << VIRTIO_BLK_F_FLUSH),
 	};
 
+	list_add_tail(&bdev->list, &bdevs);
+
 	if (irq__register_device(VIRTIO_ID_BLOCK, &dev, &pin, &line) < 0)
 		return;
 
@@ -317,8 +293,6 @@ void virtio_blk__init(struct kvm *kvm, struct disk_image *disk)
 	bdev->pci_hdr.irq_line	= line;
 
 	pci__register(&bdev->pci_hdr, dev);
-
-	ioport__register(blk_dev_base_addr, &virtio_blk_io_ops, IOPORT_VIRTIO_BLK_SIZE);
 }
 
 void virtio_blk__init_all(struct kvm *kvm)
@@ -331,8 +305,11 @@ void virtio_blk__init_all(struct kvm *kvm)
 
 void virtio_blk__delete_all(struct kvm *kvm)
 {
-	int i;
+	while (!list_empty(&bdevs)) {
+		struct blk_dev *bdev;
 
-	for (i = 0; i < kvm->nr_disks; i++)
-		free(bdevs[i]);
+		bdev = list_first_entry(&bdevs, struct blk_dev, list);
+		list_del(&bdev->list);
+		free(bdev);
+	}
 }
-- 
1.7.5.rc3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 4/8] kvm tools: Add support for multiple virtio-rng devices
  2011-05-26  6:42 [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks Sasha Levin
  2011-05-26  6:42 ` [PATCH v2 2/8] kvm tools: Add basic ioport dynamic allocation Sasha Levin
  2011-05-26  6:42 ` [PATCH v2 3/8] kvm tools: Use ioport context to control blk devices Sasha Levin
@ 2011-05-26  6:42 ` Sasha Levin
  2011-05-26  6:42 ` [PATCH v2 5/8] kvm tools: Use dynamic IO port allocation in vesa driver Sasha Levin
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Sasha Levin @ 2011-05-26  6:42 UTC (permalink / raw)
  To: penberg
  Cc: john, kvm, mingo, asias.hejun, gorcunov, prasadjoshi124, Sasha Levin

Since multiple hardware rng devices of the same type are currently
unsupported by the kernel, this serves more as an example of a basic
virtio driver under kvm tools and can be used to debug the PCI layer.

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 tools/kvm/include/kvm/ioport.h        |    2 -
 tools/kvm/include/kvm/parse-options.h |    9 +++
 tools/kvm/include/kvm/virtio-rng.h    |    1 +
 tools/kvm/kvm-run.c                   |    8 ++-
 tools/kvm/virtio/rng.c                |  126 ++++++++++++++++++++++-----------
 5 files changed, 100 insertions(+), 46 deletions(-)

diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
index 47f9fb5..ffa6893 100644
--- a/tools/kvm/include/kvm/ioport.h
+++ b/tools/kvm/include/kvm/ioport.h
@@ -18,8 +18,6 @@
 #define IOPORT_VIRTIO_CONSOLE_SIZE	256
 #define IOPORT_VIRTIO_NET		0xe200	/* Virtio network device */
 #define IOPORT_VIRTIO_NET_SIZE		256
-#define IOPORT_VIRTIO_RNG		0xf200	/* Virtio network device */
-#define IOPORT_VIRTIO_RNG_SIZE		256
 
 #define IOPORT_EMPTY			USHRT_MAX
 
diff --git a/tools/kvm/include/kvm/parse-options.h b/tools/kvm/include/kvm/parse-options.h
index 2d5c99e..6bf9a1d 100644
--- a/tools/kvm/include/kvm/parse-options.h
+++ b/tools/kvm/include/kvm/parse-options.h
@@ -132,6 +132,15 @@ intptr_t defval;
 	.help = (h)                         \
 }
 
+#define OPT_INCR(s, l, v, h)                \
+{                                           \
+	.type = OPTION_INCR,	            \
+	.short_name = (s),                  \
+	.long_name = (l),                   \
+	.value = check_vtype(v, int *),     \
+	.help = (h)                         \
+}
+
 #define OPT_GROUP(h)                        \
 {                                           \
 	.type = OPTION_GROUP,               \
diff --git a/tools/kvm/include/kvm/virtio-rng.h b/tools/kvm/include/kvm/virtio-rng.h
index 7015c1f..c0a413b 100644
--- a/tools/kvm/include/kvm/virtio-rng.h
+++ b/tools/kvm/include/kvm/virtio-rng.h
@@ -4,5 +4,6 @@
 struct kvm;
 
 void virtio_rng__init(struct kvm *kvm);
+void virtio_rng__delete_all(struct kvm *kvm);
 
 #endif /* KVM__RNG_VIRTIO_H */
diff --git a/tools/kvm/kvm-run.c b/tools/kvm/kvm-run.c
index adbb25b..76b5782 100644
--- a/tools/kvm/kvm-run.c
+++ b/tools/kvm/kvm-run.c
@@ -52,6 +52,7 @@ static __thread struct kvm_cpu *current_kvm_cpu;
 
 static u64 ram_size;
 static u8  image_count;
+static int virtio_rng;
 static const char *kernel_cmdline;
 static const char *kernel_filename;
 static const char *vmlinux_filename;
@@ -66,7 +67,6 @@ static const char *script;
 static const char *virtio_9p_dir;
 static bool single_step;
 static bool readonly_image[MAX_DISK_IMAGES];
-static bool virtio_rng;
 static bool vnc;
 extern bool ioport_debug;
 extern int  active_console;
@@ -107,7 +107,7 @@ static const struct option options[] = {
 	OPT_CALLBACK('d', "disk", NULL, "image", "Disk image", img_name_parser),
 	OPT_STRING('\0', "console", &console, "serial or virtio",
 			"Console to use"),
-	OPT_BOOLEAN('\0', "rng", &virtio_rng,
+	OPT_INCR('\0', "rng", &virtio_rng,
 			"Enable virtio Random Number Generator"),
 	OPT_STRING('\0', "kvm-dev", &kvm_dev, "kvm-dev", "KVM device file"),
 	OPT_STRING('\0', "virtio-9p", &virtio_9p_dir, "root dir",
@@ -570,7 +570,8 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 		virtio_console__init(kvm);
 
 	if (virtio_rng)
-		virtio_rng__init(kvm);
+		while (virtio_rng--)
+			virtio_rng__init(kvm);
 
 	if (!network)
 		network = DEFAULT_NETWORK;
@@ -631,6 +632,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 	}
 
 	virtio_blk__delete_all(kvm);
+	virtio_rng__delete_all(kvm);
 
 	disk_image__close_all(kvm->disks, image_count);
 	kvm__delete(kvm);
diff --git a/tools/kvm/virtio/rng.c b/tools/kvm/virtio/rng.c
index 9bd0098..f71a59b 100644
--- a/tools/kvm/virtio/rng.c
+++ b/tools/kvm/virtio/rng.c
@@ -5,7 +5,6 @@
 #include "kvm/disk-image.h"
 #include "kvm/virtio.h"
 #include "kvm/ioport.h"
-#include "kvm/mutex.h"
 #include "kvm/util.h"
 #include "kvm/kvm.h"
 #include "kvm/pci.h"
@@ -15,6 +14,7 @@
 #include <linux/virtio_ring.h>
 #include <linux/virtio_rng.h>
 
+#include <linux/list.h>
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -23,18 +23,17 @@
 #define NUM_VIRT_QUEUES				1
 #define VIRTIO_RNG_QUEUE_SIZE			128
 
-static struct pci_device_header virtio_rng_pci_device = {
-	.vendor_id		= PCI_VENDOR_ID_REDHAT_QUMRANET,
-	.device_id		= PCI_DEVICE_ID_VIRTIO_RNG,
-	.header_type		= PCI_HEADER_TYPE_NORMAL,
-	.revision_id		= 0,
-	.class			= 0x010000,
-	.subsys_vendor_id	= PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
-	.subsys_id		= VIRTIO_ID_RNG,
-	.bar[0]			= IOPORT_VIRTIO_RNG | PCI_BASE_ADDRESS_SPACE_IO,
+struct rng_dev_job {
+	struct virt_queue		*vq;
+	struct rng_dev			*rdev;
+	void				*job_id;
 };
 
 struct rng_dev {
+	struct pci_device_header pci_hdr;
+	struct list_head	list;
+
+	u16			base_addr;
 	u8			status;
 	u8			isr;
 	u16			config_vector;
@@ -43,17 +42,19 @@ struct rng_dev {
 	/* virtio queue */
 	u16			queue_selector;
 	struct virt_queue	vqs[NUM_VIRT_QUEUES];
-	void			*jobs[NUM_VIRT_QUEUES];
+	struct rng_dev_job	jobs[NUM_VIRT_QUEUES];
 };
 
-static struct rng_dev rdev;
+static LIST_HEAD(rdevs);
 
-static bool virtio_rng_pci_io_in(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool virtio_rng_pci_io_in(struct kvm *kvm, u16 port, void *data, int size, u32 count, void *param)
 {
 	unsigned long offset;
 	bool ret = true;
+	struct rng_dev *rdev;
 
-	offset = port - IOPORT_VIRTIO_RNG;
+	rdev = param;
+	offset = port - rdev->base_addr;
 
 	switch (offset) {
 	case VIRTIO_PCI_HOST_FEATURES:
@@ -63,21 +64,21 @@ static bool virtio_rng_pci_io_in(struct kvm *kvm, u16 port, void *data, int size
 		ret		= false;
 		break;
 	case VIRTIO_PCI_QUEUE_PFN:
-		ioport__write32(data, rdev.vqs[rdev.queue_selector].pfn);
+		ioport__write32(data, rdev->vqs[rdev->queue_selector].pfn);
 		break;
 	case VIRTIO_PCI_QUEUE_NUM:
 		ioport__write16(data, VIRTIO_RNG_QUEUE_SIZE);
 		break;
 	case VIRTIO_PCI_STATUS:
-		ioport__write8(data, rdev.status);
+		ioport__write8(data, rdev->status);
 		break;
 	case VIRTIO_PCI_ISR:
-		ioport__write8(data, rdev.isr);
-		kvm__irq_line(kvm, virtio_rng_pci_device.irq_line, VIRTIO_IRQ_LOW);
-		rdev.isr = VIRTIO_IRQ_LOW;
+		ioport__write8(data, rdev->isr);
+		kvm__irq_line(kvm, rdev->pci_hdr.irq_line, VIRTIO_IRQ_LOW);
+		rdev->isr = VIRTIO_IRQ_LOW;
 		break;
 	case VIRTIO_MSI_CONFIG_VECTOR:
-		ioport__write16(data, rdev.config_vector);
+		ioport__write16(data, rdev->config_vector);
 		break;
 	default:
 		ret		= false;
@@ -87,14 +88,14 @@ static bool virtio_rng_pci_io_in(struct kvm *kvm, u16 port, void *data, int size
 	return ret;
 }
 
-static bool virtio_rng_do_io_request(struct kvm *kvm, struct virt_queue *queue)
+static bool virtio_rng_do_io_request(struct kvm *kvm, struct rng_dev *rdev, struct virt_queue *queue)
 {
 	struct iovec iov[VIRTIO_RNG_QUEUE_SIZE];
 	unsigned int len = 0;
 	u16 out, in, head;
 
 	head		= virt_queue__get_iov(queue, iov, &out, &in, kvm);
-	len		= readv(rdev.fd, iov, in);
+	len		= readv(rdev->fd, iov, in);
 
 	virt_queue__set_used_elem(queue, head, len);
 
@@ -103,20 +104,24 @@ static bool virtio_rng_do_io_request(struct kvm *kvm, struct virt_queue *queue)
 
 static void virtio_rng_do_io(struct kvm *kvm, void *param)
 {
-	struct virt_queue *vq = param;
+	struct rng_dev_job *job = param;
+	struct virt_queue *vq = job->vq;
+	struct rng_dev *rdev = job->rdev;
 
 	while (virt_queue__available(vq)) {
-		virtio_rng_do_io_request(kvm, vq);
-		virt_queue__trigger_irq(vq, virtio_rng_pci_device.irq_line, &rdev.isr, kvm);
+		virtio_rng_do_io_request(kvm, rdev, vq);
+		virt_queue__trigger_irq(vq, rdev->pci_hdr.irq_line, &rdev->isr, kvm);
 	}
 }
 
-static bool virtio_rng_pci_io_out(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool virtio_rng_pci_io_out(struct kvm *kvm, u16 port, void *data, int size, u32 count, void *param)
 {
 	unsigned long offset;
 	bool ret = true;
+	struct rng_dev *rdev;
 
-	offset		= port - IOPORT_VIRTIO_RNG;
+	rdev = param;
+	offset = port - rdev->base_addr;
 
 	switch (offset) {
 	case VIRTIO_MSI_QUEUE_VECTOR:
@@ -124,32 +129,40 @@ static bool virtio_rng_pci_io_out(struct kvm *kvm, u16 port, void *data, int siz
 		break;
 	case VIRTIO_PCI_QUEUE_PFN: {
 		struct virt_queue *queue;
+		struct rng_dev_job *job;
 		void *p;
 
-		queue			= &rdev.vqs[rdev.queue_selector];
+		queue			= &rdev->vqs[rdev->queue_selector];
 		queue->pfn		= ioport__read32(data);
 		p			= guest_pfn_to_host(kvm, queue->pfn);
 
+		job = &rdev->jobs[rdev->queue_selector];
+
 		vring_init(&queue->vring, VIRTIO_RNG_QUEUE_SIZE, p, VIRTIO_PCI_VRING_ALIGN);
 
-		rdev.jobs[rdev.queue_selector] = thread_pool__add_job(kvm, virtio_rng_do_io, queue);
+		*job			= (struct rng_dev_job) {
+			.vq			= queue,
+			.rdev			= rdev,
+		};
+
+		job->job_id = thread_pool__add_job(kvm, virtio_rng_do_io, job);
 
 		break;
 	}
 	case VIRTIO_PCI_QUEUE_SEL:
-		rdev.queue_selector	= ioport__read16(data);
+		rdev->queue_selector	= ioport__read16(data);
 		break;
 	case VIRTIO_PCI_QUEUE_NOTIFY: {
 		u16 queue_index;
 		queue_index		= ioport__read16(data);
-		thread_pool__do_job(rdev.jobs[queue_index]);
+		thread_pool__do_job(rdev->jobs[queue_index].job_id);
 		break;
 	}
 	case VIRTIO_PCI_STATUS:
-		rdev.status		= ioport__read8(data);
+		rdev->status		= ioport__read8(data);
 		break;
 	case VIRTIO_MSI_CONFIG_VECTOR:
-		rdev.config_vector	= VIRTIO_MSI_NO_VECTOR;
+		rdev->config_vector	= VIRTIO_MSI_NO_VECTOR;
 		break;
 	default:
 		ret			= false;
@@ -160,24 +173,55 @@ static bool virtio_rng_pci_io_out(struct kvm *kvm, u16 port, void *data, int siz
 }
 
 static struct ioport_operations virtio_rng_io_ops = {
-	.io_in				= virtio_rng_pci_io_in,
-	.io_out				= virtio_rng_pci_io_out,
+	.io_in_param			= virtio_rng_pci_io_in,
+	.io_out_param			= virtio_rng_pci_io_out,
 };
 
 void virtio_rng__init(struct kvm *kvm)
 {
 	u8 pin, line, dev;
+	u16 rdev_base_addr;
+	struct rng_dev *rdev;
+
+	rdev = malloc(sizeof(*rdev));
+	if (rdev == NULL)
+		return;
+
+	rdev_base_addr = ioport__register_param(IOPORT_EMPTY, &virtio_rng_io_ops, IOPORT_SIZE, rdev);
+
+	rdev->pci_hdr = (struct pci_device_header) {
+		.vendor_id		= PCI_VENDOR_ID_REDHAT_QUMRANET,
+		.device_id		= PCI_DEVICE_ID_VIRTIO_RNG,
+		.header_type		= PCI_HEADER_TYPE_NORMAL,
+		.revision_id		= 0,
+		.class			= 0x010000,
+		.subsys_vendor_id	= PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
+		.subsys_id		= VIRTIO_ID_RNG,
+		.bar[0]			= rdev_base_addr | PCI_BASE_ADDRESS_SPACE_IO,
+	};
 
-	rdev.fd = open("/dev/urandom", O_RDONLY);
-	if (rdev.fd < 0)
+	rdev->base_addr = rdev_base_addr;
+	rdev->fd = open("/dev/urandom", O_RDONLY);
+	if (rdev->fd < 0)
 		die("Failed initializing RNG");
 
 	if (irq__register_device(VIRTIO_ID_RNG, &dev, &pin, &line) < 0)
 		return;
 
-	virtio_rng_pci_device.irq_pin	= pin;
-	virtio_rng_pci_device.irq_line	= line;
-	pci__register(&virtio_rng_pci_device, dev);
+	rdev->pci_hdr.irq_pin	= pin;
+	rdev->pci_hdr.irq_line	= line;
+	pci__register(&rdev->pci_hdr, dev);
+
+	list_add_tail(&rdev->list, &rdevs);
+}
+
+void virtio_rng__delete_all(struct kvm *kvm)
+{
+	while (!list_empty(&rdevs)) {
+		struct rng_dev *rdev;
 
-	ioport__register(IOPORT_VIRTIO_RNG, &virtio_rng_io_ops, IOPORT_VIRTIO_RNG_SIZE);
+		rdev = list_first_entry(&rdevs, struct rng_dev, list);
+		list_del(&rdev->list);
+		free(rdev);
+	}
 }
-- 
1.7.5.rc3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 5/8] kvm tools: Use dynamic IO port allocation in vesa driver
  2011-05-26  6:42 [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks Sasha Levin
                   ` (2 preceding siblings ...)
  2011-05-26  6:42 ` [PATCH v2 4/8] kvm tools: Add support for multiple virtio-rng devices Sasha Levin
@ 2011-05-26  6:42 ` Sasha Levin
  2011-05-26  6:42 ` [PATCH v2 6/8] kvm tools: Use dynamic IO port allocation in 9p driver Sasha Levin
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Sasha Levin @ 2011-05-26  6:42 UTC (permalink / raw)
  To: penberg
  Cc: john, kvm, mingo, asias.hejun, gorcunov, prasadjoshi124, Sasha Levin

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 tools/kvm/hw/vesa.c            |    7 +++----
 tools/kvm/include/kvm/ioport.h |    2 --
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/tools/kvm/hw/vesa.c b/tools/kvm/hw/vesa.c
index 6ab07ee..9315510 100644
--- a/tools/kvm/hw/vesa.c
+++ b/tools/kvm/hw/vesa.c
@@ -49,7 +49,6 @@ static struct pci_device_header vesa_pci_device = {
 	.class			= 0x030000,
 	.subsys_vendor_id	= PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
 	.subsys_id		= PCI_SUBSYSTEM_ID_VESA,
-	.bar[0]			= IOPORT_VESA   | PCI_BASE_ADDRESS_SPACE_IO,
 	.bar[1]			= VESA_MEM_ADDR | PCI_BASE_ADDRESS_SPACE_MEMORY,
 };
 
@@ -66,17 +65,17 @@ void vesa__init(struct kvm *kvm)
 {
 	u8 dev, line, pin;
 	pthread_t thread;
+	u16 vesa_base_addr;
 
 	if (irq__register_device(PCI_DEVICE_ID_VESA, &dev, &pin, &line) < 0)
 		return;
 
 	vesa_pci_device.irq_pin		= pin;
 	vesa_pci_device.irq_line	= line;
-
+	vesa_base_addr			= ioport__register(IOPORT_EMPTY, &vesa_io_ops, IOPORT_SIZE);
+	vesa_pci_device.bar[0]		= vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO;
 	pci__register(&vesa_pci_device, dev);
 
-	ioport__register(IOPORT_VESA, &vesa_io_ops, IOPORT_VESA_SIZE);
-
 	kvm__register_mmio(VESA_MEM_ADDR, VESA_MEM_SIZE, &vesa_mmio_callback);
 
 	pthread_create(&thread, NULL, vesa__dovnc, kvm);
diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
index ffa6893..5dee9d2 100644
--- a/tools/kvm/include/kvm/ioport.h
+++ b/tools/kvm/include/kvm/ioport.h
@@ -10,8 +10,6 @@
 #define IOPORT_START			0x6200
 #define IOPORT_SIZE			0x400
 
-#define IOPORT_VESA			0xa200
-#define IOPORT_VESA_SIZE		256
 #define IOPORT_VIRTIO_P9		0xb200	/* Virtio 9P device */
 #define IOPORT_VIRTIO_P9_SIZE		256
 #define IOPORT_VIRTIO_CONSOLE		0xd200	/* Virtio console device */
-- 
1.7.5.rc3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 6/8] kvm tools: Use dynamic IO port allocation in 9p driver
  2011-05-26  6:42 [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks Sasha Levin
                   ` (3 preceding siblings ...)
  2011-05-26  6:42 ` [PATCH v2 5/8] kvm tools: Use dynamic IO port allocation in vesa driver Sasha Levin
@ 2011-05-26  6:42 ` Sasha Levin
  2011-05-26  6:42 ` [PATCH v2 7/8] kvm tools: Use dynamic IO port allocation in virtio-console Sasha Levin
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Sasha Levin @ 2011-05-26  6:42 UTC (permalink / raw)
  To: penberg
  Cc: john, kvm, mingo, asias.hejun, gorcunov, prasadjoshi124, Sasha Levin

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 tools/kvm/include/kvm/ioport.h |    2 --
 tools/kvm/virtio/9p.c          |   12 +++++++-----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
index 5dee9d2..a6bcc6a 100644
--- a/tools/kvm/include/kvm/ioport.h
+++ b/tools/kvm/include/kvm/ioport.h
@@ -10,8 +10,6 @@
 #define IOPORT_START			0x6200
 #define IOPORT_SIZE			0x400
 
-#define IOPORT_VIRTIO_P9		0xb200	/* Virtio 9P device */
-#define IOPORT_VIRTIO_P9_SIZE		256
 #define IOPORT_VIRTIO_CONSOLE		0xd200	/* Virtio console device */
 #define IOPORT_VIRTIO_CONSOLE_SIZE	256
 #define IOPORT_VIRTIO_NET		0xe200	/* Virtio network device */
diff --git a/tools/kvm/virtio/9p.c b/tools/kvm/virtio/9p.c
index e307592..af21463 100644
--- a/tools/kvm/virtio/9p.c
+++ b/tools/kvm/virtio/9p.c
@@ -50,7 +50,6 @@ static struct pci_device_header virtio_p9_pci_device = {
 	.class			= 0x010000,
 	.subsys_vendor_id	= PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
 	.subsys_id		= VIRTIO_ID_9P,
-	.bar[0]			= IOPORT_VIRTIO_P9 | PCI_BASE_ADDRESS_SPACE_IO,
 };
 
 struct p9_dev {
@@ -59,6 +58,7 @@ struct p9_dev {
 	u16			config_vector;
 	u32			features;
 	struct virtio_9p_config	*config;
+	u16			base_addr;
 
 	/* virtio queue */
 	u16			queue_selector;
@@ -96,7 +96,7 @@ static bool virtio_p9_pci_io_in(struct kvm *kvm, u16 port, void *data, int size,
 	unsigned long offset;
 	bool ret = true;
 
-	offset = port - IOPORT_VIRTIO_P9;
+	offset = port - p9dev.base_addr;
 
 	switch (offset) {
 	case VIRTIO_PCI_HOST_FEATURES:
@@ -584,7 +584,7 @@ static bool virtio_p9_pci_io_out(struct kvm *kvm, u16 port, void *data, int size
 	unsigned long offset;
 	bool ret = true;
 
-	offset		= port - IOPORT_VIRTIO_P9;
+	offset = port - p9dev.base_addr;
 
 	switch (offset) {
 	case VIRTIO_MSI_QUEUE_VECTOR:
@@ -636,6 +636,7 @@ void virtio_9p__init(struct kvm *kvm, const char *root)
 {
 	u8 pin, line, dev;
 	u32 i, root_len;
+	u16 p9_base_addr;
 
 	p9dev.config = calloc(1, sizeof(*p9dev.config) + sizeof(VIRTIO_P9_TAG));
 	if (p9dev.config == NULL)
@@ -662,7 +663,8 @@ void virtio_9p__init(struct kvm *kvm, const char *root)
 
 	virtio_p9_pci_device.irq_pin	= pin;
 	virtio_p9_pci_device.irq_line	= line;
+	p9_base_addr			= ioport__register(IOPORT_EMPTY, &virtio_p9_io_ops, IOPORT_SIZE);
+	virtio_p9_pci_device.bar[0]	= p9_base_addr | PCI_BASE_ADDRESS_SPACE_IO;
+	p9dev.base_addr			= p9_base_addr;
 	pci__register(&virtio_p9_pci_device, dev);
-
-	ioport__register(IOPORT_VIRTIO_P9, &virtio_p9_io_ops, IOPORT_VIRTIO_P9_SIZE);
 }
-- 
1.7.5.rc3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 7/8] kvm tools: Use dynamic IO port allocation in virtio-console
  2011-05-26  6:42 [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks Sasha Levin
                   ` (4 preceding siblings ...)
  2011-05-26  6:42 ` [PATCH v2 6/8] kvm tools: Use dynamic IO port allocation in 9p driver Sasha Levin
@ 2011-05-26  6:42 ` Sasha Levin
  2011-05-26  6:42 ` [PATCH v2 8/8] kvm tools: Use dynamic IO port allocation in virtio-net Sasha Levin
  2011-05-26  8:53 ` [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks Pekka Enberg
  7 siblings, 0 replies; 16+ messages in thread
From: Sasha Levin @ 2011-05-26  6:42 UTC (permalink / raw)
  To: penberg
  Cc: john, kvm, mingo, asias.hejun, gorcunov, prasadjoshi124, Sasha Levin

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 tools/kvm/include/kvm/ioport.h |    2 --
 tools/kvm/virtio/console.c     |   11 +++++++----
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
index a6bcc6a..0c68e8c 100644
--- a/tools/kvm/include/kvm/ioport.h
+++ b/tools/kvm/include/kvm/ioport.h
@@ -10,8 +10,6 @@
 #define IOPORT_START			0x6200
 #define IOPORT_SIZE			0x400
 
-#define IOPORT_VIRTIO_CONSOLE		0xd200	/* Virtio console device */
-#define IOPORT_VIRTIO_CONSOLE_SIZE	256
 #define IOPORT_VIRTIO_NET		0xe200	/* Virtio network device */
 #define IOPORT_VIRTIO_NET_SIZE		256
 
diff --git a/tools/kvm/virtio/console.c b/tools/kvm/virtio/console.c
index affff0b..a954f22 100644
--- a/tools/kvm/virtio/console.c
+++ b/tools/kvm/virtio/console.c
@@ -36,7 +36,6 @@ static struct pci_device_header virtio_console_pci_device = {
 	.class			= 0x078000,
 	.subsys_vendor_id	= PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
 	.subsys_id		= VIRTIO_ID_CONSOLE,
-	.bar[0]			= IOPORT_VIRTIO_CONSOLE | PCI_BASE_ADDRESS_SPACE_IO,
 };
 
 struct con_dev {
@@ -50,6 +49,7 @@ struct con_dev {
 	u8				status;
 	u8				isr;
 	u16				queue_selector;
+	u16				base_addr;
 
 	void				*jobs[VIRTIO_CONSOLE_NUM_QUEUES];
 };
@@ -113,7 +113,7 @@ static bool virtio_console_pci_io_device_specific_in(void *data, unsigned long o
 
 static bool virtio_console_pci_io_in(struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
-	unsigned long offset = port - IOPORT_VIRTIO_CONSOLE;
+	unsigned long offset = port - cdev.base_addr;
 	bool ret = true;
 
 	mutex_lock(&cdev.mutex);
@@ -181,7 +181,7 @@ static void virtio_console_handle_callback(struct kvm *kvm, void *param)
 
 static bool virtio_console_pci_io_out(struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
-	unsigned long offset = port - IOPORT_VIRTIO_CONSOLE;
+	unsigned long offset = port - cdev.base_addr;
 	bool ret = true;
 
 	mutex_lock(&cdev.mutex);
@@ -243,12 +243,15 @@ static struct ioport_operations virtio_console_io_ops = {
 void virtio_console__init(struct kvm *kvm)
 {
 	u8 dev, line, pin;
+	u16 console_base_addr;
 
 	if (irq__register_device(VIRTIO_ID_CONSOLE, &dev, &pin, &line) < 0)
 		return;
 
 	virtio_console_pci_device.irq_pin	= pin;
 	virtio_console_pci_device.irq_line	= line;
+	console_base_addr			= ioport__register(IOPORT_EMPTY, &virtio_console_io_ops, IOPORT_SIZE);
+	virtio_console_pci_device.bar[0]	= console_base_addr | PCI_BASE_ADDRESS_SPACE_IO;
+	cdev.base_addr				= console_base_addr;
 	pci__register(&virtio_console_pci_device, dev);
-	ioport__register(IOPORT_VIRTIO_CONSOLE, &virtio_console_io_ops, IOPORT_VIRTIO_CONSOLE_SIZE);
 }
-- 
1.7.5.rc3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 8/8] kvm tools: Use dynamic IO port allocation in virtio-net
  2011-05-26  6:42 [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks Sasha Levin
                   ` (5 preceding siblings ...)
  2011-05-26  6:42 ` [PATCH v2 7/8] kvm tools: Use dynamic IO port allocation in virtio-console Sasha Levin
@ 2011-05-26  6:42 ` Sasha Levin
  2011-05-26  8:53 ` [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks Pekka Enberg
  7 siblings, 0 replies; 16+ messages in thread
From: Sasha Levin @ 2011-05-26  6:42 UTC (permalink / raw)
  To: penberg
  Cc: john, kvm, mingo, asias.hejun, gorcunov, prasadjoshi124, Sasha Levin

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 tools/kvm/include/kvm/ioport.h |    3 ---
 tools/kvm/virtio/net.c         |   12 ++++++++----
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
index 0c68e8c..396928b 100644
--- a/tools/kvm/include/kvm/ioport.h
+++ b/tools/kvm/include/kvm/ioport.h
@@ -10,9 +10,6 @@
 #define IOPORT_START			0x6200
 #define IOPORT_SIZE			0x400
 
-#define IOPORT_VIRTIO_NET		0xe200	/* Virtio network device */
-#define IOPORT_VIRTIO_NET_SIZE		256
-
 #define IOPORT_EMPTY			USHRT_MAX
 
 struct kvm;
diff --git a/tools/kvm/virtio/net.c b/tools/kvm/virtio/net.c
index 649bc0f..7e4400a 100644
--- a/tools/kvm/virtio/net.c
+++ b/tools/kvm/virtio/net.c
@@ -37,7 +37,6 @@ static struct pci_device_header pci_header = {
 	.class				= 0x020000,
 	.subsys_vendor_id		= PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
 	.subsys_id			= VIRTIO_ID_NET,
-	.bar[0]				= IOPORT_VIRTIO_NET | PCI_BASE_ADDRESS_SPACE_IO,
 };
 
 struct net_device {
@@ -51,6 +50,7 @@ struct net_device {
 	u8				status;
 	u8				isr;
 	u16				queue_selector;
+	u16				base_addr;
 
 	pthread_t			io_rx_thread;
 	pthread_mutex_t			io_rx_lock;
@@ -166,7 +166,7 @@ static bool virtio_net_pci_io_device_specific_in(void *data, unsigned long offse
 
 static bool virtio_net_pci_io_in(struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
-	unsigned long	offset	= port - IOPORT_VIRTIO_NET;
+	unsigned long	offset	= port - ndev.base_addr;
 	bool		ret	= true;
 
 	mutex_lock(&ndev.mutex);
@@ -230,7 +230,7 @@ static void virtio_net_handle_callback(struct kvm *kvm, u16 queue_index)
 
 static bool virtio_net_pci_io_out(struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
-	unsigned long	offset		= port - IOPORT_VIRTIO_NET;
+	unsigned long	offset		= port - ndev.base_addr;
 	bool		ret		= true;
 
 	mutex_lock(&ndev.mutex);
@@ -387,14 +387,18 @@ void virtio_net__init(const struct virtio_net_parameters *params)
 {
 	if (virtio_net__tap_init(params)) {
 		u8 dev, line, pin;
+		u16 net_base_addr;
 
 		if (irq__register_device(VIRTIO_ID_NET, &dev, &pin, &line) < 0)
 			return;
 
 		pci_header.irq_pin	= pin;
 		pci_header.irq_line	= line;
+		net_base_addr		= ioport__register(IOPORT_EMPTY, &virtio_net_io_ops, IOPORT_SIZE);
+		pci_header.bar[0]	= net_base_addr | PCI_BASE_ADDRESS_SPACE_IO;
+		ndev.base_addr		= net_base_addr;
+
 		pci__register(&pci_header, dev);
-		ioport__register(IOPORT_VIRTIO_NET, &virtio_net_io_ops, IOPORT_VIRTIO_NET_SIZE);
 
 		virtio_net__io_thread_init(params->kvm);
 	}
-- 
1.7.5.rc3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks
  2011-05-26  6:42 [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks Sasha Levin
                   ` (6 preceding siblings ...)
  2011-05-26  6:42 ` [PATCH v2 8/8] kvm tools: Use dynamic IO port allocation in virtio-net Sasha Levin
@ 2011-05-26  8:53 ` Pekka Enberg
  2011-05-26  9:02   ` Sasha Levin
  7 siblings, 1 reply; 16+ messages in thread
From: Pekka Enberg @ 2011-05-26  8:53 UTC (permalink / raw)
  To: Sasha Levin; +Cc: john, kvm, mingo, asias.hejun, gorcunov, prasadjoshi124

On Thu, 2011-05-26 at 09:42 +0300, Sasha Levin wrote:
> Allow specifying an optional parameter when registering an
> ioport range. The callback functions provided by the registering
> module will be called with the same parameter.
> 
> This may be used to keep context during callbacks on IO operations.
> 
> Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> ---
>  tools/kvm/include/kvm/ioport.h |    3 ++
>  tools/kvm/ioport.c             |   54 +++++++++++++++++++++++++++++----------
>  2 files changed, 43 insertions(+), 14 deletions(-)
> 
> diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
> index 8253938..2a8d74d 100644
> --- a/tools/kvm/include/kvm/ioport.h
> +++ b/tools/kvm/include/kvm/ioport.h
> @@ -25,11 +25,14 @@ struct kvm;
>  struct ioport_operations {
>  	bool (*io_in)(struct kvm *kvm, u16 port, void *data, int size, u32 count);
>  	bool (*io_out)(struct kvm *kvm, u16 port, void *data, int size, u32 count);
> +	bool (*io_in_param)(struct kvm *kvm, u16 port, void *data, int size, u32 count, void *param);
> +	bool (*io_out_param)(struct kvm *kvm, u16 port, void *data, int size, u32 count, void *param);

So why not make that 'param' unconditional for io_in and io_out and just
pass NULL if it's not needed?


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks
  2011-05-26  8:53 ` [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks Pekka Enberg
@ 2011-05-26  9:02   ` Sasha Levin
  2011-05-26  9:04     ` Pekka Enberg
  0 siblings, 1 reply; 16+ messages in thread
From: Sasha Levin @ 2011-05-26  9:02 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: john, kvm, mingo, asias.hejun, gorcunov, prasadjoshi124

On Thu, 2011-05-26 at 11:53 +0300, Pekka Enberg wrote:
> On Thu, 2011-05-26 at 09:42 +0300, Sasha Levin wrote:
> > Allow specifying an optional parameter when registering an
> > ioport range. The callback functions provided by the registering
> > module will be called with the same parameter.
> > 
> > This may be used to keep context during callbacks on IO operations.
> > 
> > Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> > ---
> >  tools/kvm/include/kvm/ioport.h |    3 ++
> >  tools/kvm/ioport.c             |   54 +++++++++++++++++++++++++++++----------
> >  2 files changed, 43 insertions(+), 14 deletions(-)
> > 
> > diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
> > index 8253938..2a8d74d 100644
> > --- a/tools/kvm/include/kvm/ioport.h
> > +++ b/tools/kvm/include/kvm/ioport.h
> > @@ -25,11 +25,14 @@ struct kvm;
> >  struct ioport_operations {
> >  	bool (*io_in)(struct kvm *kvm, u16 port, void *data, int size, u32 count);
> >  	bool (*io_out)(struct kvm *kvm, u16 port, void *data, int size, u32 count);
> > +	bool (*io_in_param)(struct kvm *kvm, u16 port, void *data, int size, u32 count, void *param);
> > +	bool (*io_out_param)(struct kvm *kvm, u16 port, void *data, int size, u32 count, void *param);
> 
> So why not make that 'param' unconditional for io_in and io_out and just
> pass NULL if it's not needed?
> 

I've wanted to keep the original interface clean, Most of the IO port
users don't (and probably won't) require a parameter.

-- 

Sasha.


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks
  2011-05-26  9:02   ` Sasha Levin
@ 2011-05-26  9:04     ` Pekka Enberg
  2011-05-26  9:14       ` Sasha Levin
  0 siblings, 1 reply; 16+ messages in thread
From: Pekka Enberg @ 2011-05-26  9:04 UTC (permalink / raw)
  To: Sasha Levin; +Cc: john, kvm, mingo, asias.hejun, gorcunov, prasadjoshi124

On Thu, May 26, 2011 at 12:02 PM, Sasha Levin <levinsasha928@gmail.com> wrote:
> On Thu, 2011-05-26 at 11:53 +0300, Pekka Enberg wrote:
>> On Thu, 2011-05-26 at 09:42 +0300, Sasha Levin wrote:
>> > Allow specifying an optional parameter when registering an
>> > ioport range. The callback functions provided by the registering
>> > module will be called with the same parameter.
>> >
>> > This may be used to keep context during callbacks on IO operations.
>> >
>> > Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
>> > ---
>> >  tools/kvm/include/kvm/ioport.h |    3 ++
>> >  tools/kvm/ioport.c             |   54 +++++++++++++++++++++++++++++----------
>> >  2 files changed, 43 insertions(+), 14 deletions(-)
>> >
>> > diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
>> > index 8253938..2a8d74d 100644
>> > --- a/tools/kvm/include/kvm/ioport.h
>> > +++ b/tools/kvm/include/kvm/ioport.h
>> > @@ -25,11 +25,14 @@ struct kvm;
>> >  struct ioport_operations {
>> >     bool (*io_in)(struct kvm *kvm, u16 port, void *data, int size, u32 count);
>> >     bool (*io_out)(struct kvm *kvm, u16 port, void *data, int size, u32 count);
>> > +   bool (*io_in_param)(struct kvm *kvm, u16 port, void *data, int size, u32 count, void *param);
>> > +   bool (*io_out_param)(struct kvm *kvm, u16 port, void *data, int size, u32 count, void *param);
>>
>> So why not make that 'param' unconditional for io_in and io_out and just
>> pass NULL if it's not needed?
>>
>
> I've wanted to keep the original interface clean, Most of the IO port
> users don't (and probably won't) require a parameter.

Well now struct ioport_operations isn't very clean is it - or the code
that needs to determine which function pointer to call?-)

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks
  2011-05-26  9:04     ` Pekka Enberg
@ 2011-05-26  9:14       ` Sasha Levin
  2011-05-26  9:20         ` Pekka Enberg
  0 siblings, 1 reply; 16+ messages in thread
From: Sasha Levin @ 2011-05-26  9:14 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: john, kvm, mingo, asias.hejun, gorcunov, prasadjoshi124

On Thu, 2011-05-26 at 12:04 +0300, Pekka Enberg wrote:
> On Thu, May 26, 2011 at 12:02 PM, Sasha Levin <levinsasha928@gmail.com> wrote:
> > On Thu, 2011-05-26 at 11:53 +0300, Pekka Enberg wrote:
> >> On Thu, 2011-05-26 at 09:42 +0300, Sasha Levin wrote:
> >> > Allow specifying an optional parameter when registering an
> >> > ioport range. The callback functions provided by the registering
> >> > module will be called with the same parameter.
> >> >
> >> > This may be used to keep context during callbacks on IO operations.
> >> >
> >> > Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> >> > ---
> >> >  tools/kvm/include/kvm/ioport.h |    3 ++
> >> >  tools/kvm/ioport.c             |   54 +++++++++++++++++++++++++++++----------
> >> >  2 files changed, 43 insertions(+), 14 deletions(-)
> >> >
> >> > diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
> >> > index 8253938..2a8d74d 100644
> >> > --- a/tools/kvm/include/kvm/ioport.h
> >> > +++ b/tools/kvm/include/kvm/ioport.h
> >> > @@ -25,11 +25,14 @@ struct kvm;
> >> >  struct ioport_operations {
> >> >     bool (*io_in)(struct kvm *kvm, u16 port, void *data, int size, u32 count);
> >> >     bool (*io_out)(struct kvm *kvm, u16 port, void *data, int size, u32 count);
> >> > +   bool (*io_in_param)(struct kvm *kvm, u16 port, void *data, int size, u32 count, void *param);
> >> > +   bool (*io_out_param)(struct kvm *kvm, u16 port, void *data, int size, u32 count, void *param);
> >>
> >> So why not make that 'param' unconditional for io_in and io_out and just
> >> pass NULL if it's not needed?
> >>
> >
> > I've wanted to keep the original interface clean, Most of the IO port
> > users don't (and probably won't) require a parameter.
> 
> Well now struct ioport_operations isn't very clean is it - or the code
> that needs to determine which function pointer to call?-)

struct ioport_operations is a bit more messy, but it's one spot instead
of adding a 'parameter' to each module that doesn't really need it.

My assumption is that most ioport users now and in the future won't need
it, it just solves several special cases more easily (multiple devices
which share same handling functions).

-- 

Sasha.


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks
  2011-05-26  9:14       ` Sasha Levin
@ 2011-05-26  9:20         ` Pekka Enberg
  2011-05-26  9:38           ` Sasha Levin
  0 siblings, 1 reply; 16+ messages in thread
From: Pekka Enberg @ 2011-05-26  9:20 UTC (permalink / raw)
  To: Sasha Levin; +Cc: john, kvm, mingo, asias.hejun, gorcunov, prasadjoshi124

On Thu, May 26, 2011 at 12:14 PM, Sasha Levin <levinsasha928@gmail.com> wrote:
>> > I've wanted to keep the original interface clean, Most of the IO port
>> > users don't (and probably won't) require a parameter.
>>
>> Well now struct ioport_operations isn't very clean is it - or the code
>> that needs to determine which function pointer to call?-)
>
> struct ioport_operations is a bit more messy, but it's one spot instead
> of adding a 'parameter' to each module that doesn't really need it.
>
> My assumption is that most ioport users now and in the future won't need
> it, it just solves several special cases more easily (multiple devices
> which share same handling functions).

Hey, that's not an excuse to make struct ioport_operations 'bit
messy'! Look at any kernel code that uses ops like we do here and you
will see we don't do APIs like this.

One option here is to rename 'struct ioport_entry' to 'struct ioport'
and pass a pointer to that as the first argument to all of the ops.
That's what most APIs in the kernel do anyway.

                        Pekka

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks
  2011-05-26  9:20         ` Pekka Enberg
@ 2011-05-26  9:38           ` Sasha Levin
  2011-05-26  9:43             ` Pekka Enberg
  0 siblings, 1 reply; 16+ messages in thread
From: Sasha Levin @ 2011-05-26  9:38 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: john, kvm, mingo, asias.hejun, gorcunov, prasadjoshi124

On Thu, 2011-05-26 at 12:20 +0300, Pekka Enberg wrote:
> On Thu, May 26, 2011 at 12:14 PM, Sasha Levin <levinsasha928@gmail.com> wrote:
> >> > I've wanted to keep the original interface clean, Most of the IO port
> >> > users don't (and probably won't) require a parameter.
> >>
> >> Well now struct ioport_operations isn't very clean is it - or the code
> >> that needs to determine which function pointer to call?-)
> >
> > struct ioport_operations is a bit more messy, but it's one spot instead
> > of adding a 'parameter' to each module that doesn't really need it.
> >
> > My assumption is that most ioport users now and in the future won't need
> > it, it just solves several special cases more easily (multiple devices
> > which share same handling functions).
> 
> Hey, that's not an excuse to make struct ioport_operations 'bit
> messy'! Look at any kernel code that uses ops like we do here and you
> will see we don't do APIs like this.
> 
> One option here is to rename 'struct ioport_entry' to 'struct ioport'
> and pass a pointer to that as the first argument to all of the ops.
> That's what most APIs in the kernel do anyway.

Why do it like that? this way users of the callback functions will need
to know the internal structure of struct ioport_entry.

-- 

Sasha.


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks
  2011-05-26  9:38           ` Sasha Levin
@ 2011-05-26  9:43             ` Pekka Enberg
  2011-05-26  9:49               ` Pekka Enberg
  0 siblings, 1 reply; 16+ messages in thread
From: Pekka Enberg @ 2011-05-26  9:43 UTC (permalink / raw)
  To: Sasha Levin; +Cc: john, kvm, mingo, asias.hejun, gorcunov, prasadjoshi124

On Thu, May 26, 2011 at 12:38 PM, Sasha Levin <levinsasha928@gmail.com> wrote:
>> One option here is to rename 'struct ioport_entry' to 'struct ioport'
>> and pass a pointer to that as the first argument to all of the ops.
>> That's what most APIs in the kernel do anyway.
>
> Why do it like that? this way users of the callback functions will need
> to know the internal structure of struct ioport_entry.

Look at 'struct inode' or similar data structure in the kernel. That's
how we do it. You can then also do s/params/priv/.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks
  2011-05-26  9:43             ` Pekka Enberg
@ 2011-05-26  9:49               ` Pekka Enberg
  0 siblings, 0 replies; 16+ messages in thread
From: Pekka Enberg @ 2011-05-26  9:49 UTC (permalink / raw)
  To: Sasha Levin; +Cc: john, kvm, mingo, asias.hejun, gorcunov, prasadjoshi124

Hi Sasha,

On Thu, May 26, 2011 at 12:38 PM, Sasha Levin <levinsasha928@gmail.com> wrote:
>>> One option here is to rename 'struct ioport_entry' to 'struct ioport'
>>> and pass a pointer to that as the first argument to all of the ops.
>>> That's what most APIs in the kernel do anyway.
>>
>> Why do it like that? this way users of the callback functions will need
>> to know the internal structure of struct ioport_entry.

On Thu, May 26, 2011 at 12:43 PM, Pekka Enberg <penberg@kernel.org> wrote:
> Look at 'struct inode' or similar data structure in the kernel. That's
> how we do it. You can then also do s/params/priv/.

Btw, the whole notion of 'internal structure' for structs in C code is
a pretty broken concept. In most cases, you just end up passing
untyped fragments of the data to callers which makes following the
data flow in code difficult. Passing 'struct ioport' down to the code
makes the code more obvious and readable.

Encapsulation is important but emulating that with hiding structs in
.c files isn't helpful at all. Face it, there's no proper support for
that in C so you just need to rely on conventions to do it.

                      Pekka

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2011-05-26  9:49 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-26  6:42 [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks Sasha Levin
2011-05-26  6:42 ` [PATCH v2 2/8] kvm tools: Add basic ioport dynamic allocation Sasha Levin
2011-05-26  6:42 ` [PATCH v2 3/8] kvm tools: Use ioport context to control blk devices Sasha Levin
2011-05-26  6:42 ` [PATCH v2 4/8] kvm tools: Add support for multiple virtio-rng devices Sasha Levin
2011-05-26  6:42 ` [PATCH v2 5/8] kvm tools: Use dynamic IO port allocation in vesa driver Sasha Levin
2011-05-26  6:42 ` [PATCH v2 6/8] kvm tools: Use dynamic IO port allocation in 9p driver Sasha Levin
2011-05-26  6:42 ` [PATCH v2 7/8] kvm tools: Use dynamic IO port allocation in virtio-console Sasha Levin
2011-05-26  6:42 ` [PATCH v2 8/8] kvm tools: Use dynamic IO port allocation in virtio-net Sasha Levin
2011-05-26  8:53 ` [PATCH v2 1/8] kvm tools: Add optional parameter used in ioport callbacks Pekka Enberg
2011-05-26  9:02   ` Sasha Levin
2011-05-26  9:04     ` Pekka Enberg
2011-05-26  9:14       ` Sasha Levin
2011-05-26  9:20         ` Pekka Enberg
2011-05-26  9:38           ` Sasha Levin
2011-05-26  9:43             ` Pekka Enberg
2011-05-26  9:49               ` Pekka Enberg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.