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 <shiqing.gao@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Shiqing Gao 2018-06-05 13:29:39 +08:00 committed by lijinxia
parent 13dc9617e5
commit b435c74e91

View File

@ -864,6 +864,31 @@ cfginit(struct vmctx *ctx, struct passthru_dev *ptdev, int bus,
return irq_type; 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 * return zero on success or non-zero on failure
*/ */
@ -875,8 +900,8 @@ pciaccess_init(void)
pthread_mutex_lock(&ref_cnt_mtx); pthread_mutex_lock(&ref_cnt_mtx);
if (!pciaccess_ref_cnt) { if (!pciaccess_ref_cnt) {
error = pci_system_init(); error = native_pci_system_init();
if (error) { if (error < 0) {
warnx("libpciaccess couldn't access PCI system"); warnx("libpciaccess couldn't access PCI system");
pthread_mutex_unlock(&ref_cnt_mtx); pthread_mutex_unlock(&ref_cnt_mtx);
return error; return error;
@ -909,12 +934,12 @@ passthru_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
struct pci_device *phys_dev; struct pci_device *phys_dev;
ptdev = NULL; ptdev = NULL;
error = 1; error = -EINVAL;
if (opts == NULL || if (opts == NULL ||
sscanf(opts, "%x/%x/%x", &bus, &slot, &func) != 3) { sscanf(opts, "%x/%x/%x", &bus, &slot, &func) != 3) {
warnx("invalid passthru options, %s", opts); warnx("invalid passthru options, %s", opts);
return error; return -EINVAL;
} }
if (vm_assign_ptdev(ctx, bus, slot, func) != 0) { 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)); ptdev = calloc(1, sizeof(struct passthru_dev));
if (ptdev == NULL) { if (ptdev == NULL) {
warnx("%s: calloc FAIL!", __func__); warnx("%s: calloc FAIL!", __func__);
return error; return -ENOMEM;
} }
ptdev->phys_bdf = PCI_BDF(bus, slot, func); ptdev->phys_bdf = PCI_BDF(bus, slot, func);
error = pciaccess_init(); error = pciaccess_init();
if (error) if (error < 0)
return error; return error;
error = 1; error = -ENODEV;
iter = pci_slot_match_iterator_create(NULL); iter = pci_slot_match_iterator_create(NULL);
while ((phys_dev = pci_device_next(iter)) != NULL) { while ((phys_dev = pci_device_next(iter)) != NULL) {
if (phys_dev->bus == bus && phys_dev->dev == slot && 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) { if (error < 0) {
warnx("No PCI device %x:%x.%x", bus, slot, func); warnx("No physical PCI device %x:%x.%x!", bus, slot, func);
return error; return -ENODEV;
} }
pci_device_probe(ptdev->phys_dev); pci_device_probe(ptdev->phys_dev);