]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kvm tools: Add optional parameter used in ioport callbacks
authorSasha Levin <levinsasha928@gmail.com>
Thu, 26 May 2011 10:30:04 +0000 (13:30 +0300)
committerPekka Enberg <penberg@kernel.org>
Thu, 26 May 2011 15:55:55 +0000 (18:55 +0300)
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>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
tools/kvm/hw/rtc.c
tools/kvm/hw/serial.c
tools/kvm/hw/vesa.c
tools/kvm/include/kvm/ioport.h
tools/kvm/ioport.c
tools/kvm/pci.c
tools/kvm/virtio/9p.c
tools/kvm/virtio/blk.c
tools/kvm/virtio/console.c
tools/kvm/virtio/net.c
tools/kvm/virtio/rng.c

index 6735e8223230d17deea1619de899b403b9b6b0af..146f66077f0c89795bd8cc3819ebbe6d381f9abe 100644 (file)
@@ -19,7 +19,7 @@ static inline unsigned char bin2bcd(unsigned val)
        return ((val / 10) << 4) + val % 10;
 }
 
-static bool cmos_ram_data_in(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool cmos_ram_data_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        struct tm *tm;
        time_t ti;
@@ -52,7 +52,7 @@ static bool cmos_ram_data_in(struct kvm *kvm, u16 port, void *data, int size, u3
        return true;
 }
 
-static bool cmos_ram_data_out(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool cmos_ram_data_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        return true;
 }
@@ -62,7 +62,7 @@ static struct ioport_operations cmos_ram_data_ioport_ops = {
        .io_in          = cmos_ram_data_in,
 };
 
-static bool cmos_ram_index_out(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool cmos_ram_index_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        u8 value;
 
@@ -82,6 +82,6 @@ static struct ioport_operations cmos_ram_index_ioport_ops = {
 void rtc__init(void)
 {
        /* PORT 0070-007F - CMOS RAM/RTC (REAL TIME CLOCK) */
-       ioport__register(0x0070, &cmos_ram_index_ioport_ops, 1);
-       ioport__register(0x0071, &cmos_ram_data_ioport_ops, 1);
+       ioport__register(0x0070, &cmos_ram_index_ioport_ops, 1, NULL);
+       ioport__register(0x0071, &cmos_ram_data_ioport_ops, 1, NULL);
 }
index beebbba5d960b720c3fd3a5bdd2fd6996256c8c1..1199264e12e2f650a5cd2afde74f2665c9d45c8b 100644 (file)
@@ -164,7 +164,7 @@ static struct serial8250_device *find_device(u16 port)
        return NULL;
 }
 
-static bool serial8250_out(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool serial8250_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        struct serial8250_device *dev;
        u16 offset;
@@ -252,7 +252,7 @@ out_unlock:
        return ret;
 }
 
-static bool serial8250_in(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool serial8250_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        struct serial8250_device *dev;
        u16 offset;
@@ -339,7 +339,7 @@ static struct ioport_operations serial8250_ops = {
 
 static void serial8250__device_init(struct kvm *kvm, struct serial8250_device *dev)
 {
-       ioport__register(dev->iobase, &serial8250_ops, 8);
+       ioport__register(dev->iobase, &serial8250_ops, 8, NULL);
        kvm__irq_line(kvm, dev->irq, 0);
 }
 
index 6ab07eee656f810ae7393a2c33ff7559b6c2eee0..ec4788c1d377f4c5d1ed2ed826de3125284f3be9 100644 (file)
 
 static char videomem[VESA_MEM_SIZE];
 
-static bool vesa_pci_io_in(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool vesa_pci_io_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        return true;
 }
 
-static bool vesa_pci_io_out(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool vesa_pci_io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        return true;
 }
@@ -75,7 +75,7 @@ void vesa__init(struct kvm *kvm)
 
        pci__register(&vesa_pci_device, dev);
 
-       ioport__register(IOPORT_VESA, &vesa_io_ops, IOPORT_VESA_SIZE);
+       ioport__register(IOPORT_VESA, &vesa_io_ops, IOPORT_VESA_SIZE, NULL);
 
        kvm__register_mmio(VESA_MEM_ADDR, VESA_MEM_SIZE, &vesa_mmio_callback);
 
index 8253938308f29ad7bb6a79f73ab0b1bf8350c3a3..67b4a6facc19e5a37e128754299b57cd5f23fce0 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef KVM__IOPORT_H
 #define KVM__IOPORT_H
 
+#include "kvm/rbtree-interval.h"
+
 #include <stdbool.h>
 #include <asm/types.h>
 #include <linux/types.h>
 
 struct kvm;
 
+struct ioport {
+       struct rb_int_node              node;
+       struct ioport_operations        *ops;
+       void                            *priv;
+};
+
 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)(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count);
+       bool (*io_out)(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count);
 };
 
 void ioport__setup_legacy(void);
 
-void ioport__register(u16 port, struct ioport_operations *ops, int count);
+void ioport__register(u16 port, struct ioport_operations *ops, int count, void *param);
 
 static inline u8 ioport__read8(u8 *data)
 {
index 1f139603a56c513547639fd867908df136b69283..92ad15297d96a411755b9c58ef25bea34c5a56c8 100644 (file)
@@ -2,7 +2,6 @@
 
 #include "kvm/kvm.h"
 #include "kvm/util.h"
-#include "kvm/rbtree-interval.h"
 
 #include <linux/kvm.h> /* for KVM_EXIT_* */
 #include <linux/types.h>
 #include <stdlib.h>
 #include <stdio.h>
 
-#define ioport_node(n) rb_entry(n, struct ioport_entry, node)
-
-struct ioport_entry {
-       struct rb_int_node              node;
-       struct ioport_operations        *ops;
-};
+#define ioport_node(n) rb_entry(n, struct ioport, node)
 
 static struct rb_root ioport_tree = RB_ROOT;
 bool ioport_debug;
 
-static struct ioport_entry *ioport_search(struct rb_root *root, u64 addr)
+static struct ioport *ioport_search(struct rb_root *root, u64 addr)
 {
        struct rb_int_node *node;
 
@@ -34,12 +28,12 @@ static struct ioport_entry *ioport_search(struct rb_root *root, u64 addr)
        return ioport_node(node);
 }
 
-static int ioport_insert(struct rb_root *root, struct ioport_entry *data)
+static int ioport_insert(struct rb_root *root, struct ioport *data)
 {
        return rb_int_insert(root, &data->node);
 }
 
-static bool debug_io_out(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool debug_io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        exit(EXIT_SUCCESS);
 }
@@ -48,12 +42,12 @@ static struct ioport_operations debug_ops = {
        .io_out         = debug_io_out,
 };
 
-static bool dummy_io_in(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool dummy_io_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        return true;
 }
 
-static bool dummy_io_out(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool dummy_io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        return true;
 }
@@ -67,9 +61,9 @@ 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)
+void ioport__register(u16 port, struct ioport_operations *ops, int count, void *param)
 {
-       struct ioport_entry *entry;
+       struct ioport *entry;
 
        entry = ioport_search(&ioport_tree, port);
        if (entry) {
@@ -81,9 +75,10 @@ void ioport__register(u16 port, struct ioport_operations *ops, int count)
        if (entry == NULL)
                die("Failed allocating new ioport entry");
 
-       *entry = (struct ioport_entry) {
+       *entry = (struct ioport) {
                .node   = RB_INT_INIT(port, port + count),
                .ops    = ops,
+               .priv   = param,
        };
 
        ioport_insert(&ioport_tree, entry);
@@ -105,30 +100,26 @@ 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;
-       struct ioport_entry *entry;
+       bool ret = false;
+       struct ioport *entry;
 
        entry = ioport_search(&ioport_tree, port);
        if (!entry)
                goto error;
 
-       ops = entry->ops;
+       ops     = entry->ops;
 
        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 (ops->io_in)
+                       ret = ops->io_in(entry, kvm, port, data, size, count);
        } else {
-               if (!ops->io_out)
-                       goto error;
-
-               ret = ops->io_out(kvm, port, data, size, count);
-               if (!ret)
-                       goto error;
+               if (ops->io_out)
+                       ret = ops->io_out(entry, kvm, port, data, size, count);
        }
+
+       if (!ret)
+               goto error;
+
        return true;
 error:
        if (ioport_debug)
@@ -140,29 +131,29 @@ error:
 void ioport__setup_legacy(void)
 {
        /* 0x0020 - 0x003F - 8259A PIC 1 */
-       ioport__register(0x0020, &dummy_read_write_ioport_ops, 2);
+       ioport__register(0x0020, &dummy_read_write_ioport_ops, 2, NULL);
 
        /* PORT 0040-005F - PIT - PROGRAMMABLE INTERVAL TIMER (8253, 8254) */
-       ioport__register(0x0040, &dummy_read_write_ioport_ops, 4);
+       ioport__register(0x0040, &dummy_read_write_ioport_ops, 4, NULL);
 
        /* PORT 0060-006F - KEYBOARD CONTROLLER 804x (8041, 8042) (or PPI (8255) on PC,XT) */
-       ioport__register(0x0060, &dummy_read_write_ioport_ops, 2);
-       ioport__register(0x0064, &dummy_read_write_ioport_ops, 1);
+       ioport__register(0x0060, &dummy_read_write_ioport_ops, 2, NULL);
+       ioport__register(0x0064, &dummy_read_write_ioport_ops, 1, NULL);
 
        /* 0x00A0 - 0x00AF - 8259A PIC 2 */
-       ioport__register(0x00A0, &dummy_read_write_ioport_ops, 2);
+       ioport__register(0x00A0, &dummy_read_write_ioport_ops, 2, NULL);
 
        /* PORT 00E0-00EF are 'motherboard specific' so we use them for our
           internal debugging purposes.  */
-       ioport__register(IOPORT_DBG, &debug_ops, 1);
+       ioport__register(IOPORT_DBG, &debug_ops, 1, NULL);
 
        /* PORT 00ED - DUMMY PORT FOR DELAY??? */
-       ioport__register(0x00ED, &dummy_write_only_ioport_ops, 1);
+       ioport__register(0x00ED, &dummy_write_only_ioport_ops, 1, NULL);
 
        /* 0x00F0 - 0x00FF - Math co-processor */
-       ioport__register(0x00F0, &dummy_write_only_ioport_ops, 2);
+       ioport__register(0x00F0, &dummy_write_only_ioport_ops, 2, NULL);
 
        /* PORT 03D4-03D5 - COLOR VIDEO - CRT CONTROL REGISTERS */
-       ioport__register(0x03D4, &dummy_read_write_ioport_ops, 1);
-       ioport__register(0x03D5, &dummy_write_only_ioport_ops, 1);
+       ioport__register(0x03D4, &dummy_read_write_ioport_ops, 1, NULL);
+       ioport__register(0x03D5, &dummy_write_only_ioport_ops, 1, NULL);
 }
index d4fbeab83857c1398f234816870243acd3283bef..a1ad8bae3ac2b8a70ceea2c77f702e1811770519 100644 (file)
@@ -21,7 +21,7 @@ static void *pci_config_address_ptr(u16 port)
        return base + offset;
 }
 
-static bool pci_config_address_out(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool pci_config_address_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        void *p = pci_config_address_ptr(port);
 
@@ -30,7 +30,7 @@ static bool pci_config_address_out(struct kvm *kvm, u16 port, void *data, int si
        return true;
 }
 
-static bool pci_config_address_in(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool pci_config_address_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        void *p = pci_config_address_ptr(port);
 
@@ -44,7 +44,7 @@ static struct ioport_operations pci_config_address_ops = {
        .io_out         = pci_config_address_out,
 };
 
-static bool pci_config_data_out(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool pci_config_data_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        return true;
 }
@@ -67,7 +67,7 @@ static bool pci_device_exists(u8 bus_number, u8 device_number, u8 function_numbe
        return dev != NULL;
 }
 
-static bool pci_config_data_in(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool pci_config_data_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        unsigned long start;
        u8 dev_num;
@@ -110,6 +110,6 @@ void pci__register(struct pci_device_header *dev, u8 dev_num)
 
 void pci__init(void)
 {
-       ioport__register(PCI_CONFIG_DATA + 0, &pci_config_data_ops, 4);
-       ioport__register(PCI_CONFIG_ADDRESS + 0, &pci_config_address_ops, 4);
+       ioport__register(PCI_CONFIG_DATA + 0, &pci_config_data_ops, 4, NULL);
+       ioport__register(PCI_CONFIG_ADDRESS + 0, &pci_config_address_ops, 4, NULL);
 }
index e307592583a1ad89569a087a34bcc09de99f3a0b..c4410891d46ddf1aa899468be9f49f4adde689d1 100644 (file)
@@ -91,7 +91,7 @@ static bool virtio_p9_dev_in(void *data, unsigned long offset, int size, u32 cou
        return true;
 }
 
-static bool virtio_p9_pci_io_in(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool virtio_p9_pci_io_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        unsigned long offset;
        bool ret = true;
@@ -579,7 +579,7 @@ static void virtio_p9_do_io(struct kvm *kvm, void *param)
        }
 }
 
-static bool virtio_p9_pci_io_out(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool virtio_p9_pci_io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        unsigned long offset;
        bool ret = true;
@@ -664,5 +664,5 @@ void virtio_9p__init(struct kvm *kvm, const char *root)
        virtio_p9_pci_device.irq_line   = line;
        pci__register(&virtio_p9_pci_device, dev);
 
-       ioport__register(IOPORT_VIRTIO_P9, &virtio_p9_io_ops, IOPORT_VIRTIO_P9_SIZE);
+       ioport__register(IOPORT_VIRTIO_P9, &virtio_p9_io_ops, IOPORT_VIRTIO_P9_SIZE, NULL);
 }
index 25ce61f8ef5380f73044cdeb097ebb05dcb9262c..5720c7f594674af71412e1d7f8c6a7dae3f3b624 100644 (file)
@@ -73,7 +73,7 @@ static void virtio_blk_port2dev(u16 port, u16 base, u16 size, u16 *dev_idx, u16
        *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 ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        struct blk_dev *bdev;
        u16 offset, dev_idx;
@@ -178,7 +178,7 @@ 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 ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        struct blk_dev *bdev;
        u16 offset, dev_idx;
@@ -318,7 +318,7 @@ void virtio_blk__init(struct kvm *kvm, struct disk_image *disk)
 
        pci__register(&bdev->pci_hdr, dev);
 
-       ioport__register(blk_dev_base_addr, &virtio_blk_io_ops, IOPORT_VIRTIO_BLK_SIZE);
+       ioport__register(blk_dev_base_addr, &virtio_blk_io_ops, IOPORT_VIRTIO_BLK_SIZE, NULL);
 }
 
 void virtio_blk__init_all(struct kvm *kvm)
index affff0bc03281e24cdcda77b1d116bde989f7c65..614f0d2b641687b165a50a6bb706563ab8c4e862 100644 (file)
@@ -111,7 +111,7 @@ static bool virtio_console_pci_io_device_specific_in(void *data, unsigned long o
        return true;
 }
 
-static bool virtio_console_pci_io_in(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool virtio_console_pci_io_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        unsigned long offset = port - IOPORT_VIRTIO_CONSOLE;
        bool ret = true;
@@ -179,7 +179,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)
+static bool virtio_console_pci_io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        unsigned long offset = port - IOPORT_VIRTIO_CONSOLE;
        bool ret = true;
@@ -250,5 +250,5 @@ void virtio_console__init(struct kvm *kvm)
        virtio_console_pci_device.irq_pin       = pin;
        virtio_console_pci_device.irq_line      = line;
        pci__register(&virtio_console_pci_device, dev);
-       ioport__register(IOPORT_VIRTIO_CONSOLE, &virtio_console_io_ops, IOPORT_VIRTIO_CONSOLE_SIZE);
+       ioport__register(IOPORT_VIRTIO_CONSOLE, &virtio_console_io_ops, IOPORT_VIRTIO_CONSOLE_SIZE, NULL);
 }
index 649bc0feabc1d6166c413bdae8bbb1b640d66776..014205b09557208070a0a6dcc11b4087660f9ead 100644 (file)
@@ -164,7 +164,7 @@ static bool virtio_net_pci_io_device_specific_in(void *data, unsigned long offse
        return true;
 }
 
-static bool virtio_net_pci_io_in(struct kvm *kvm, u16 port, void *data, int size, u32 count)
+static bool virtio_net_pci_io_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        unsigned long   offset  = port - IOPORT_VIRTIO_NET;
        bool            ret     = true;
@@ -228,7 +228,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)
+static bool virtio_net_pci_io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        unsigned long   offset          = port - IOPORT_VIRTIO_NET;
        bool            ret             = true;
@@ -394,7 +394,7 @@ void virtio_net__init(const struct virtio_net_parameters *params)
                pci_header.irq_pin      = pin;
                pci_header.irq_line     = line;
                pci__register(&pci_header, dev);
-               ioport__register(IOPORT_VIRTIO_NET, &virtio_net_io_ops, IOPORT_VIRTIO_NET_SIZE);
+               ioport__register(IOPORT_VIRTIO_NET, &virtio_net_io_ops, IOPORT_VIRTIO_NET_SIZE, NULL);
 
                virtio_net__io_thread_init(params->kvm);
        }
index 9bd009894c7b8ec61a27fddac050c4f16c9a7de2..a553f6b7918ed1ed370c4da8f9f5d8c339765846 100644 (file)
@@ -48,7 +48,7 @@ struct rng_dev {
 
 static struct rng_dev rdev;
 
-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 ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        unsigned long offset;
        bool ret = true;
@@ -111,7 +111,7 @@ static void virtio_rng_do_io(struct kvm *kvm, void *param)
        }
 }
 
-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 ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
 {
        unsigned long offset;
        bool ret = true;
@@ -179,5 +179,5 @@ void virtio_rng__init(struct kvm *kvm)
        virtio_rng_pci_device.irq_line  = line;
        pci__register(&virtio_rng_pci_device, dev);
 
-       ioport__register(IOPORT_VIRTIO_RNG, &virtio_rng_io_ops, IOPORT_VIRTIO_RNG_SIZE);
+       ioport__register(IOPORT_VIRTIO_RNG, &virtio_rng_io_ops, IOPORT_VIRTIO_RNG_SIZE, NULL);
 }