]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kvm tools: Fixes for ioport module
authorSasha Levin <levinsasha928@gmail.com>
Sun, 18 Dec 2011 20:53:25 +0000 (22:53 +0200)
committerSasha Levin <levinsasha928@gmail.com>
Sun, 29 Jan 2012 14:37:56 +0000 (09:37 -0500)
Fixes include:
 - Error handling
 - Cleanup
 - Standard init/uninit

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
tools/kvm/builtin-run.c
tools/kvm/hw/pci-shmem.c
tools/kvm/hw/vesa.c
tools/kvm/include/kvm/ioport.h
tools/kvm/include/kvm/rbtree-interval.h
tools/kvm/ioport.c
tools/kvm/util/rbtree-interval.c
tools/kvm/virtio/pci.c

index cd881e7849e20d7083ee1fcd57607846ce746ab6..99e81b27728c65ef88773f3c3dbcee17592af348 100644 (file)
@@ -1028,6 +1028,12 @@ static int kvm_cmd_run_init(int argc, const char **argv)
 
        pci__init();
 
+       r = ioport__init(kvm);
+       if (r < 0) {
+               pr_err("ioport__init() failed with error %d\n", r);
+               goto fail;
+       }
+
        /*
         * vidmode should be either specified
         * either set by default
@@ -1252,6 +1258,11 @@ static void kvm_cmd_run_exit(int guest_ret)
 
        disk_image__close_all(kvm->disks, image_count);
        free(kvm_cpus);
+
+       r = ioport__exit(kvm);
+       if (r < 0)
+               pr_warning("ioport__exit() failed with error %d\n", r);
+
        kvm__delete(kvm);
 
        if (guest_ret == 0)
index 61301313634f591dc5e1b5b023aa80cb1bc0e41e..8bac15180a629c12a7c5cd324c810f40439c22d0 100644 (file)
@@ -219,6 +219,7 @@ int pci_shmem__init(struct kvm *kvm)
 {
        u8 dev, line, pin;
        char *mem;
+       int r;
 
        if (shmem_region == 0)
                return 0;
@@ -231,7 +232,11 @@ int pci_shmem__init(struct kvm *kvm)
        pci_shmem_pci_device.irq_line = line;
 
        /* Register MMIO space for MSI-X */
-       ivshmem_registers = ioport__register(IOPORT_EMPTY, &shmem_pci__io_ops, IOPORT_SIZE, NULL);
+       r = ioport__register(IOPORT_EMPTY, &shmem_pci__io_ops, IOPORT_SIZE, NULL);
+       if (r < 0)
+               return r;
+       ivshmem_registers = (u16)r;
+
        msix_block = pci_get_io_space_block(0x1010);
        kvm__register_mmio(kvm, msix_block, 0x1010, false, callback_mmio_msix, NULL);
 
index 2c0101f2bb83a7132df22bd618327e56dc9db46f..757f0a2ea1ec465224acd1e183800f0ea04f2d18 100644 (file)
@@ -57,9 +57,13 @@ struct framebuffer *vesa__init(struct kvm *kvm)
        if (r < 0)
                return ERR_PTR(r);
 
+       r = ioport__register(IOPORT_EMPTY, &vesa_io_ops, IOPORT_SIZE, NULL);
+       if (r < 0)
+               return ERR_PTR(r);
+
        vesa_pci_device.irq_pin         = pin;
        vesa_pci_device.irq_line        = line;
-       vesa_base_addr                  = ioport__register(IOPORT_EMPTY, &vesa_io_ops, IOPORT_SIZE, NULL);
+       vesa_base_addr                  = (u16)r;
        vesa_pci_device.bar[0]          = cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO);
        pci__register(&vesa_pci_device, dev);
 
index 09bf876b323c8caa979197bad122f05f1ce71878..ced8cf594516a7a680c62e3a65e2854233d9dca6 100644 (file)
@@ -31,7 +31,10 @@ struct ioport_operations {
 
 void ioport__setup_arch(void);
 
-u16 ioport__register(u16 port, struct ioport_operations *ops, int count, void *param);
+int ioport__register(u16 port, struct ioport_operations *ops, int count, void *param);
+int ioport__unregister(u16 port);
+int ioport__init(struct kvm *kvm);
+int ioport__exit(struct kvm *kvm);
 
 static inline u8 ioport__read8(u8 *data)
 {
index a6688c42df86976fe122170c0f1f19d119093b72..13245bac7d3595da03154ba8abcdf866842ef9a5 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/types.h>
 
 #define RB_INT_INIT(l, h) (struct rb_int_node){.low = l, .high = h}
+#define rb_int(n) rb_entry(n, struct rb_int_node, node)
 
 struct rb_int_node {
        struct rb_node  node;
index 5a5a331386d1fcd14310a7e67f759b6e46be1233..12b27a1a8996f86b808f5e0d46367f1af2070cd5 100644 (file)
@@ -51,7 +51,12 @@ static int ioport_insert(struct rb_root *root, struct ioport *data)
        return rb_int_insert(root, &data->node);
 }
 
-u16 ioport__register(u16 port, struct ioport_operations *ops, int count, void *param)
+static void ioport_remove(struct rb_root *root, struct ioport *data)
+{
+       rb_int_erase(root, &data->node);
+}
+
+int ioport__register(u16 port, struct ioport_operations *ops, int count, void *param)
 {
        struct ioport *entry;
 
@@ -67,7 +72,7 @@ u16 ioport__register(u16 port, struct ioport_operations *ops, int count, void *p
 
        entry = malloc(sizeof(*entry));
        if (entry == NULL)
-               die("Failed allocating new ioport entry");
+               return -ENOMEM;
 
        *entry = (struct ioport) {
                .node   = RB_INT_INIT(port, port + count),
@@ -82,6 +87,46 @@ u16 ioport__register(u16 port, struct ioport_operations *ops, int count, void *p
        return port;
 }
 
+int ioport__unregister(u16 port)
+{
+       struct ioport *entry;
+       int r;
+
+       br_write_lock();
+
+       r = -ENOENT;
+       entry = ioport_search(&ioport_tree, port);
+       if (!entry)
+               goto done;
+
+       ioport_remove(&ioport_tree, entry);
+
+       free(entry);
+
+       r = 0;
+
+done:
+       br_write_unlock();
+
+       return r;
+}
+
+static void ioport__unregister_all(void)
+{
+       struct ioport *entry;
+       struct rb_node *rb;
+       struct rb_int_node *rb_node;
+
+       rb = rb_first(&ioport_tree);
+       while (rb) {
+               rb_node = rb_int(rb);
+               entry = ioport_node(rb_node);
+               ioport_remove(&ioport_tree, entry);
+               free(entry);
+               rb = rb_first(&ioport_tree);
+       }
+}
+
 static const char *to_direction(int direction)
 {
        if (direction == KVM_EXIT_IO_IN)
@@ -132,3 +177,14 @@ error:
 
        return !ioport_debug;
 }
+
+int ioport__init(struct kvm *kvm)
+{
+       return 0;
+}
+
+int ioport__exit(struct kvm *kvm)
+{
+       ioport__unregister_all();
+       return 0;
+}
index d02fbf0c469c08d2cff4fdcc521b566d436b1498..edc140d5e55112e2d32aa3bfb5bef4dd2215b183 100644 (file)
@@ -1,8 +1,6 @@
 #include <kvm/rbtree-interval.h>
 #include <stddef.h>
 
-#define rb_int(n) rb_entry(n, struct rb_int_node, node)
-
 struct rb_int_node *rb_int_search_single(struct rb_root *root, u64 point)
 {
        struct rb_node *node = root->rb_node;
index 305131453fea663504ad1c55dc7792e07457a828..2643d8a778732c10b317dd2ba51cca0edcc05f9c 100644 (file)
@@ -284,11 +284,16 @@ int virtio_pci__init(struct kvm *kvm, struct virtio_trans *vtrans, void *dev,
 {
        struct virtio_pci *vpci = vtrans->virtio;
        u8 pin, line, ndev;
+       int r;
 
        vpci->dev = dev;
        vpci->msix_io_block = pci_get_io_space_block(PCI_IO_SIZE * 2);
 
-       vpci->base_addr = ioport__register(IOPORT_EMPTY, &virtio_pci__io_ops, IOPORT_SIZE, vtrans);
+       r = ioport__register(IOPORT_EMPTY, &virtio_pci__io_ops, IOPORT_SIZE, vtrans);
+       if (r < 0)
+               return r;
+
+       vpci->base_addr = (u16)r;
        kvm__register_mmio(kvm, vpci->msix_io_block, PCI_IO_SIZE, false, callback_mmio_table, vpci);
 
        vpci->pci_hdr = (struct pci_device_header) {