Fixes include: - Error handling - Cleanup - Standard init/uninit Signed-off-by: Sasha Levin <levinsasha928@xxxxxxxxx> --- tools/kvm/builtin-run.c | 10 ++++++- tools/kvm/include/kvm/pci.h | 5 ++- tools/kvm/pci.c | 58 +++++++++++++++++++++++++++++++------------ 3 files changed, 54 insertions(+), 19 deletions(-) diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c index 2be3949..2950ea8 100644 --- a/tools/kvm/builtin-run.c +++ b/tools/kvm/builtin-run.c @@ -988,7 +988,11 @@ static int kvm_cmd_run_init(int argc, const char **argv) goto fail; } - pci__init(); + r = pci__init(kvm); + if (r < 0) { + pr_error("pci__init() failed with error %d\n", r); + goto fail; + } r = ioport__init(kvm); if (r < 0) { @@ -1239,6 +1243,10 @@ static void kvm_cmd_run_uninit(int guest_ret) if (r < 0) pr_warning("ioeventfd__uninit() failed with error %d\n", r); + r = pci__uninit(kvm); + if (r < 0) + pr_warning("pci__uninit() failed with error %d\n", r); + kvm__delete(kvm); if (guest_ret == 0) diff --git a/tools/kvm/include/kvm/pci.h b/tools/kvm/include/kvm/pci.h index 07b5403..f5536c7 100644 --- a/tools/kvm/include/kvm/pci.h +++ b/tools/kvm/include/kvm/pci.h @@ -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__uninit(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); diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c index 06eea0f..3696619 100644 --- a/tools/kvm/pci.c +++ b/tools/kvm/pci.c @@ -3,6 +3,7 @@ #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])) @@ -31,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; } @@ -56,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) @@ -73,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; } @@ -105,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; @@ -150,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; @@ -168,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) { - assert(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) { - assert(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) { - ioport__register(PCI_CONFIG_DATA + 0, &pci_config_data_ops, 4, NULL); - ioport__register(PCI_CONFIG_ADDRESS + 0, &pci_config_address_ops, 4, NULL); + 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__uninit(struct kvm *kvm) +{ + ioport__unregister(PCI_CONFIG_DATA); + ioport__unregister(PCI_CONFIG_ADDRESS); + + return 0; } -- 1.7.8 -- 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