DM: reset each ptdev before assignment

This helps achieving valid dev state after UOS restart

Signed-off-by: Edwin Zhai <edwin.zhai@intel.com>
Acked-by: Anthony Xu <anthony.xu@intel.com>
This commit is contained in:
Edwin Zhai 2018-06-22 14:23:22 +08:00 committed by lijinxia
parent b8384ea0dd
commit dafca1743d

View File

@ -37,6 +37,8 @@
#include <errno.h> #include <errno.h>
#include <pthread.h> #include <pthread.h>
#include <pciaccess.h> #include <pciaccess.h>
#include <fcntl.h>
#include <unistd.h>
#include "iodev.h" #include "iodev.h"
#include "vmmapi.h" #include "vmmapi.h"
@ -815,7 +817,7 @@ cfginit(struct vmctx *ctx, struct passthru_dev *ptdev, int bus,
{ {
int irq_type = IRQ_MSI; int irq_type = IRQ_MSI;
char reset_path[60]; char reset_path[60];
FILE *f; int fd;
bzero(&ptdev->sel, sizeof(struct pcisel)); bzero(&ptdev->sel, sizeof(struct pcisel));
ptdev->sel.bus = bus; ptdev->sel.bus = bus;
@ -835,25 +837,28 @@ cfginit(struct vmctx *ctx, struct passthru_dev *ptdev, int bus,
irq_type = IRQ_INTX; irq_type = IRQ_INTX;
} }
/* Check reset method for PCIe dev. If SOS kernel provides 'reset' /* If SOS kernel provides 'reset' entry in sysfs, related dev has some
* entry in sysfs, related dev has some reset capability, e.g. FLR, or * reset capability, e.g. FLR, or secondary bus reset. We do 2 things:
* secondary bus reset. PCIe dev without any reset capability is * - reset each dev before passthrough to achieve valid dev state after
* refused for passthrough. * UOS reboot
* - refuse to passthrough PCIe dev without any reset capability
*/ */
if (ptdev->pcie_cap) { snprintf(reset_path, 40,
snprintf(reset_path, 40, "/sys/bus/pci/devices/0000:%02x:%02x.%x/reset",
"/sys/bus/pci/devices/0000:%02x:%02x.%x/reset", bus, slot, func);
bus, slot, func);
if ((f = fopen(reset_path, "r"))) fd = open(reset_path, O_WRONLY);
fclose(f); if (fd >= 0) {
else if (errno == ENOENT) { if (write(fd, "1", 1) < 0)
warnx("No reset capability for PCIe %x/%x/%x, " warnx("reset dev %x/%x/%x failed!\n",
"remove it from ptdev list!!\n", bus, slot, func);
bus, slot, func); close(fd);
if (!no_reset) } else if (errno == ENOENT && ptdev->pcie_cap) {
return -1; warnx("No reset capability for PCIe %x/%x/%x, "
} "remove it from ptdev list!!\n",
bus, slot, func);
if (!no_reset)
return -1;
} }
if (cfginitbar(ctx, ptdev) != 0) { if (cfginitbar(ctx, ptdev) != 0) {