From b435c74e910a4b14c52d2f4c33357dfc5beaf738 Mon Sep 17 00:00:00 2001 From: Shiqing Gao Date: Tue, 5 Jun 2018 13:29:39 +0800 Subject: [PATCH] dm: fix the error code issues in passthrough.c With current implementation: vm_init_vdevs only handles the negative error code, while passthru_init returns positive error code when error occurs. This causes unexpected dm crash since the real error is not being handled properly. What this patch does: Change the error code to be negative value in passthru_init because it is common in Linux kernel to return negative value when error occurs. v2 -> v3 * add more comments about the reason to convert the return value v1 -> v2: * add a wrapper API to convert the error returned from pci_system_init to the ERROR we defined in DM * use the defined errno as the return value rather than -1 Signed-off-by: Shiqing Gao Acked-by: Eddie Dong --- devicemodel/hw/pci/passthrough.c | 45 +++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/devicemodel/hw/pci/passthrough.c b/devicemodel/hw/pci/passthrough.c index ddae63eec..877c5a3be 100644 --- a/devicemodel/hw/pci/passthrough.c +++ b/devicemodel/hw/pci/passthrough.c @@ -864,6 +864,31 @@ cfginit(struct vmctx *ctx, struct passthru_dev *ptdev, int bus, return irq_type; } +/* + * convert the error code of pci_system_init in libpciaccess to DM standard + * + * pci_system_init in libpciaccess: + * return zero -> success + * return positive value -> failure + * + * DM standard: + * return zero -> success + * return negative value -> failure + */ +static int +native_pci_system_init() +{ + int error; + + error = pci_system_init(); + + /* + * convert the returned error value to negative since DM only handles + * the negative error code + */ + return -error; +} + /* * return zero on success or non-zero on failure */ @@ -875,8 +900,8 @@ pciaccess_init(void) pthread_mutex_lock(&ref_cnt_mtx); if (!pciaccess_ref_cnt) { - error = pci_system_init(); - if (error) { + error = native_pci_system_init(); + if (error < 0) { warnx("libpciaccess couldn't access PCI system"); pthread_mutex_unlock(&ref_cnt_mtx); return error; @@ -909,12 +934,12 @@ passthru_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts) struct pci_device *phys_dev; ptdev = NULL; - error = 1; + error = -EINVAL; if (opts == NULL || sscanf(opts, "%x/%x/%x", &bus, &slot, &func) != 3) { warnx("invalid passthru options, %s", opts); - return error; + return -EINVAL; } if (vm_assign_ptdev(ctx, bus, slot, func) != 0) { @@ -926,16 +951,16 @@ passthru_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts) ptdev = calloc(1, sizeof(struct passthru_dev)); if (ptdev == NULL) { warnx("%s: calloc FAIL!", __func__); - return error; + return -ENOMEM; } ptdev->phys_bdf = PCI_BDF(bus, slot, func); error = pciaccess_init(); - if (error) + if (error < 0) return error; - error = 1; + error = -ENODEV; iter = pci_slot_match_iterator_create(NULL); while ((phys_dev = pci_device_next(iter)) != NULL) { if (phys_dev->bus == bus && phys_dev->dev == slot && @@ -946,9 +971,9 @@ passthru_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts) } } - if (error) { - warnx("No PCI device %x:%x.%x", bus, slot, func); - return error; + if (error < 0) { + warnx("No physical PCI device %x:%x.%x!", bus, slot, func); + return -ENODEV; } pci_device_probe(ptdev->phys_dev);