]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kvm tools: Fixes for PCI module
authorSasha Levin <levinsasha928@gmail.com>
Sun, 18 Dec 2011 20:46:35 +0000 (22:46 +0200)
committerSasha Levin <levinsasha928@gmail.com>
Sun, 29 Jan 2012 14:37:57 +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/include/kvm/pci.h
tools/kvm/pci.c

index b76184d05ebe6e47b09cccd3c01caa3dd132acd2..7fd8303157f809967704844a6faf7d9714713a05 100644 (file)
@@ -1030,7 +1030,11 @@ static int kvm_cmd_run_init(int argc, const char **argv)
                goto fail;
        }
 
-       pci__init();
+       r = pci__init(kvm);
+       if (r < 0) {
+               pr_err("pci__init() failed with error %d\n", r);
+               goto fail;
+       }
 
        r = ioport__init(kvm);
        if (r < 0) {
@@ -1286,6 +1290,10 @@ static void kvm_cmd_run_exit(int guest_ret)
        if (r < 0)
                pr_warning("ioeventfd__exit() failed with error %d\n", r);
 
+       r = pci__exit(kvm);
+       if (r < 0)
+               pr_warning("pci__exit() failed with error %d\n", r);
+
        kvm__delete(kvm);
 
        if (guest_ret == 0)
index 07b5403232ed67fd986b140599e8642c0b5a346f..64e42f577613aba74575d93e1d56865312545dc1 100644 (file)
@@ -84,8 +84,9 @@ struct pci_device_header {
        u32             bar_size[6];
 } __attribute__((packed));
 
-void pci__init(void);
-void pci__register(struct pci_device_header *dev, u8 dev_num);
+int pci__init(struct kvm *kvm);
+int pci__exit(struct kvm *kvm);
+int pci__register(struct pci_device_header *dev, u8 dev_num);
 struct pci_device_header *pci__find_dev(u8 dev_num);
 u32 pci_get_io_space_block(u32 size);
 void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, int size);
index 41c40852d91c4e2d68d6496945158bfbf629558e..38f47785a747921911916408614a00539ff1a059 100644 (file)
@@ -3,6 +3,9 @@
 #include "kvm/util.h"
 #include "kvm/kvm.h"
 
+#include <linux/err.h>
+#include <assert.h>
+
 #define PCI_BAR_OFFSET(b)              (offsetof(struct pci_device_header, bar[b]))
 
 static struct pci_device_header                *pci_devices[PCI_MAX_DEVICES];
@@ -29,8 +32,8 @@ static void *pci_config_address_ptr(u16 port)
        unsigned long offset;
        void *base;
 
-       offset          = port - PCI_CONFIG_ADDRESS;
-       base            = &pci_config_address;
+       offset  = port - PCI_CONFIG_ADDRESS;
+       base    = &pci_config_address;
 
        return base + offset;
 }
@@ -54,8 +57,8 @@ static bool pci_config_address_in(struct ioport *ioport, struct kvm *kvm, u16 po
 }
 
 static struct ioport_operations pci_config_address_ops = {
-       .io_in          = pci_config_address_in,
-       .io_out         = pci_config_address_out,
+       .io_in  = pci_config_address_in,
+       .io_out = pci_config_address_out,
 };
 
 static bool pci_device_exists(u8 bus_number, u8 device_number, u8 function_number)
@@ -71,7 +74,7 @@ static bool pci_device_exists(u8 bus_number, u8 device_number, u8 function_numbe
        if (device_number >= PCI_MAX_DEVICES)
                return false;
 
-       dev             = pci_devices[device_number];
+       dev = pci_devices[device_number];
 
        return dev != NULL;
 }
@@ -103,15 +106,15 @@ static bool pci_config_data_in(struct ioport *ioport, struct kvm *kvm, u16 port,
 }
 
 static struct ioport_operations pci_config_data_ops = {
-       .io_in          = pci_config_data_in,
-       .io_out         = pci_config_data_out,
+       .io_in  = pci_config_data_in,
+       .io_out = pci_config_data_out,
 };
 
 void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, int size)
 {
        u8 dev_num;
 
-       dev_num         = addr.device_number;
+       dev_num = addr.device_number;
 
        if (pci_device_exists(0, dev_num, 0)) {
                unsigned long offset;
@@ -148,7 +151,7 @@ void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data,
 {
        u8 dev_num;
 
-       dev_num         = addr.device_number;
+       dev_num = addr.device_number;
 
        if (pci_device_exists(0, dev_num, 0)) {
                unsigned long offset;
@@ -166,20 +169,45 @@ void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data,
        }
 }
 
-void pci__register(struct pci_device_header *dev, u8 dev_num)
+int pci__register(struct pci_device_header *dev, u8 dev_num)
 {
-       BUG_ON(dev_num >= PCI_MAX_DEVICES);
-       pci_devices[dev_num]    = dev;
+       if (dev_num >= PCI_MAX_DEVICES)
+               return -ENOSPC;
+
+       pci_devices[dev_num] = dev;
+
+       return 0;
 }
 
 struct pci_device_header *pci__find_dev(u8 dev_num)
 {
-       BUG_ON(dev_num >= PCI_MAX_DEVICES);
+       if (dev_num >= PCI_MAX_DEVICES)
+               return ERR_PTR(-EOVERFLOW);
+
        return pci_devices[dev_num];
 }
 
-void pci__init(void)
+int pci__init(struct kvm *kvm)
+{
+       int r;
+
+       r = ioport__register(PCI_CONFIG_DATA + 0, &pci_config_data_ops, 4, NULL);
+       if (r < 0)
+               return r;
+
+       r = ioport__register(PCI_CONFIG_ADDRESS + 0, &pci_config_address_ops, 4, NULL);
+       if (r < 0) {
+               ioport__unregister(PCI_CONFIG_DATA);
+               return r;
+       }
+
+       return 0;
+}
+
+int pci__exit(struct kvm *kvm)
 {
-       ioport__register(PCI_CONFIG_DATA + 0, &pci_config_data_ops, 4, NULL);
-       ioport__register(PCI_CONFIG_ADDRESS + 0, &pci_config_address_ops, 4, NULL);
+       ioport__unregister(PCI_CONFIG_DATA);
+       ioport__unregister(PCI_CONFIG_ADDRESS);
+
+       return 0;
 }