[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] Revert patches that break libxl API
commit ac6a0af3870ba0f7ffb16af3e41827b0a53f88b0 Author: Wei Liu <wl@xxxxxxx> AuthorDate: Wed Dec 16 17:48:04 2020 +0000 Commit: Wei Liu <wl@xxxxxxx> CommitDate: Wed Dec 16 18:03:26 2020 +0000 Revert patches that break libxl API This patch reverts eight patches from staging. The offending patch is the one that introduced libxl_pci_bdf (last one in the list). The rest depend on that patch so they are also reverted. 8bf0fab14256 "libxl / libxlu: support 'xl pci-attach/detach' by name" e1141654c374 "docs/man: modify xl-pci-configuration(5) to add 'name' field to PCI_SPEC_STRING" 93c16ae47baf "xl: support naming of assignable devices" 5ab684cb3e4d "libxl: introduce libxl_pci_bdf_assignable_add/remove/list/list_free(), ..." 66c2fbc6e82b "libxl: convert internal functions in libxl_pci.c..." f73c5dd56d78 "docs/man: modify xl(1) in preparation for naming of assignable devices" 96ed6ff29741 "libxlu: introduce xlu_pci_parse_spec_string()" 929f23114061 "libxl: introduce 'libxl_pci_bdf' in the idl..." Signed-off-by: Wei Liu <wl@xxxxxxx> --- docs/man/xl-pci-configuration.5.pod | 25 +- docs/man/xl.1.pod.in | 19 +- tools/golang/xenlight/helpers.gen.go | 77 ++---- tools/golang/xenlight/types.gen.go | 8 +- tools/include/libxl.h | 48 +--- tools/include/libxlutil.h | 8 +- tools/libs/light/libxl_dm.c | 8 +- tools/libs/light/libxl_internal.h | 3 +- tools/libs/light/libxl_pci.c | 501 +++++++++++------------------------ tools/libs/light/libxl_types.idl | 17 +- tools/libs/util/libxlu_pci.c | 359 ++++++++++++------------- tools/xl/xl_cmdtable.c | 16 +- tools/xl/xl_parse.c | 4 +- tools/xl/xl_pci.c | 133 ++++------ tools/xl/xl_sxp.c | 4 +- 15 files changed, 431 insertions(+), 799 deletions(-) diff --git a/docs/man/xl-pci-configuration.5.pod b/docs/man/xl-pci-configuration.5.pod index db3360307c..4dd73bc498 100644 --- a/docs/man/xl-pci-configuration.5.pod +++ b/docs/man/xl-pci-configuration.5.pod @@ -51,7 +51,7 @@ is not specified, or if it is specified with an empty value (whether positionally or explicitly). B<NOTE>: In context of B<xl pci-detach> (see L<xl(1)>), parameters other than -B<bdf> or B<name> will be ignored. +B<bdf> will be ignored. =head1 Positional Parameters @@ -70,11 +70,7 @@ B<*> to indicate all functions of a multi-function device. =item Default Value -None. This parameter is mandatory in its positional form. As a non-positional -parameter it is also mandatory unless a B<name> parameter is present, in -which case B<bdf> must not be present since the B<name> will be used to find -the B<bdf> in the list of assignable devices. See L<xl(1)> for more information -on naming assignable devices. +None. This parameter is mandatory as it identifies the device. =back @@ -198,21 +194,4 @@ B<NOTE>: This overrides the global B<rdm> option. =back -=item B<name>=I<STRING> - -=over 4 - -=item Description - -This is the name given when the B<BDF> was made assignable. See L<xl(1)> for -more information on naming assignable devices. - -=item Default Value - -None. This parameter must not be present if a B<bdf> parameter is present. -If a B<bdf> parameter is not present then B<name> is mandatory as it is -required to look up the B<BDF> in the list of assignable devices. - -=back - =back diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in index f4779d8fd6..af31d2b572 100644 --- a/docs/man/xl.1.pod.in +++ b/docs/man/xl.1.pod.in @@ -1595,23 +1595,19 @@ List virtual network interfaces for a domain. =over 4 -=item B<pci-assignable-list> [I<-n>] +=item B<pci-assignable-list> List all the B<BDF> of assignable PCI devices. See -L<xl-pci-configuration(5)> for more information. If the -n option is -specified then any name supplied when the device was made assignable -will also be displayed. +L<xl-pci-configuration(5)> for more information. These are devices in the system which are configured to be available for passthrough and are bound to a suitable PCI backend driver in domain 0 rather than a real driver. -=item B<pci-assignable-add> [I<-n NAME>] I<BDF> +=item B<pci-assignable-add> I<BDF> Make the device at B<BDF> assignable to guests. See -L<xl-pci-configuration(5)> for more information. If the -n option is -supplied then the assignable device entry will the named with the -given B<NAME>. +L<xl-pci-configuration(5)> for more information. This will bind the device to the pciback driver and assign it to the "quarantine domain". If it is already bound to a driver, it will @@ -1626,11 +1622,10 @@ not to do this on a device critical to domain 0's operation, such as storage controllers, network interfaces, or GPUs that are currently being used. -=item B<pci-assignable-remove> [I<-r>] I<BDF>|I<NAME> +=item B<pci-assignable-remove> [I<-r>] I<BDF> -Make a device non-assignable to guests. The device may be identified -either by its B<BDF> or the B<NAME> supplied when the device was made -assignable. See L<xl-pci-configuration(5)> for more information. +Make the device at B<BDF> not assignable to guests. See +L<xl-pci-configuration(5)> for more information. This will at least unbind the device from pciback, and re-assign it from the "quarantine domain" back to domain 0. If the -r diff --git a/tools/golang/xenlight/helpers.gen.go b/tools/golang/xenlight/helpers.gen.go index b7230f693c..c8605994e7 100644 --- a/tools/golang/xenlight/helpers.gen.go +++ b/tools/golang/xenlight/helpers.gen.go @@ -1999,41 +1999,6 @@ xc.colo_checkpoint_port = C.CString(x.ColoCheckpointPort)} return nil } -// NewPciBdf returns an instance of PciBdf initialized with defaults. -func NewPciBdf() (*PciBdf, error) { -var ( -x PciBdf -xc C.libxl_pci_bdf) - -C.libxl_pci_bdf_init(&xc) -defer C.libxl_pci_bdf_dispose(&xc) - -if err := x.fromC(&xc); err != nil { -return nil, err } - -return &x, nil} - -func (x *PciBdf) fromC(xc *C.libxl_pci_bdf) error { - x.Func = byte(xc._func) -x.Dev = byte(xc.dev) -x.Bus = byte(xc.bus) -x.Domain = int(xc.domain) - - return nil} - -func (x *PciBdf) toC(xc *C.libxl_pci_bdf) (err error){defer func(){ -if err != nil{ -C.libxl_pci_bdf_dispose(xc)} -}() - -xc._func = C.uint8_t(x.Func) -xc.dev = C.uint8_t(x.Dev) -xc.bus = C.uint8_t(x.Bus) -xc.domain = C.int(x.Domain) - - return nil - } - // NewDevicePci returns an instance of DevicePci initialized with defaults. func NewDevicePci() (*DevicePci, error) { var ( @@ -2049,9 +2014,10 @@ return nil, err } return &x, nil} func (x *DevicePci) fromC(xc *C.libxl_device_pci) error { - if err := x.Bdf.fromC(&xc.bdf);err != nil { -return fmt.Errorf("converting field Bdf: %v", err) -} + x.Func = byte(xc._func) +x.Dev = byte(xc.dev) +x.Bus = byte(xc.bus) +x.Domain = int(xc.domain) x.Vdevfn = uint32(xc.vdevfn) x.VfuncMask = uint32(xc.vfunc_mask) x.Msitranslate = bool(xc.msitranslate) @@ -2067,9 +2033,10 @@ if err != nil{ C.libxl_device_pci_dispose(xc)} }() -if err := x.Bdf.toC(&xc.bdf); err != nil { -return fmt.Errorf("converting field Bdf: %v", err) -} +xc._func = C.uint8_t(x.Func) +xc.dev = C.uint8_t(x.Dev) +xc.bus = C.uint8_t(x.Bus) +xc.domain = C.int(x.Domain) xc.vdevfn = C.uint32_t(x.Vdevfn) xc.vfunc_mask = C.uint32_t(x.VfuncMask) xc.msitranslate = C.bool(x.Msitranslate) @@ -2799,13 +2766,13 @@ if err := x.Nics[i].fromC(&v); err != nil { return fmt.Errorf("converting field Nics: %v", err) } } } -x.Pcis = nil -if n := int(xc.num_pcis); n > 0 { -cPcis := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcis))[:n:n] -x.Pcis = make([]DevicePci, n) -for i, v := range cPcis { -if err := x.Pcis[i].fromC(&v); err != nil { -return fmt.Errorf("converting field Pcis: %v", err) } +x.Pcidevs = nil +if n := int(xc.num_pcidevs); n > 0 { +cPcidevs := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcidevs))[:n:n] +x.Pcidevs = make([]DevicePci, n) +for i, v := range cPcidevs { +if err := x.Pcidevs[i].fromC(&v); err != nil { +return fmt.Errorf("converting field Pcidevs: %v", err) } } } x.Rdms = nil @@ -2955,13 +2922,13 @@ return fmt.Errorf("converting field Nics: %v", err) } } } -if numPcis := len(x.Pcis); numPcis > 0 { -xc.pcis = (*C.libxl_device_pci)(C.malloc(C.ulong(numPcis)*C.sizeof_libxl_device_pci)) -xc.num_pcis = C.int(numPcis) -cPcis := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcis))[:numPcis:numPcis] -for i,v := range x.Pcis { -if err := v.toC(&cPcis[i]); err != nil { -return fmt.Errorf("converting field Pcis: %v", err) +if numPcidevs := len(x.Pcidevs); numPcidevs > 0 { +xc.pcidevs = (*C.libxl_device_pci)(C.malloc(C.ulong(numPcidevs)*C.sizeof_libxl_device_pci)) +xc.num_pcidevs = C.int(numPcidevs) +cPcidevs := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcidevs))[:numPcidevs:numPcidevs] +for i,v := range x.Pcidevs { +if err := v.toC(&cPcidevs[i]); err != nil { +return fmt.Errorf("converting field Pcidevs: %v", err) } } } diff --git a/tools/golang/xenlight/types.gen.go b/tools/golang/xenlight/types.gen.go index bc62ae8ce9..b4c5df0f2c 100644 --- a/tools/golang/xenlight/types.gen.go +++ b/tools/golang/xenlight/types.gen.go @@ -707,15 +707,11 @@ ColoCheckpointHost string ColoCheckpointPort string } -type PciBdf struct { +type DevicePci struct { Func byte Dev byte Bus byte Domain int -} - -type DevicePci struct { -Bdf PciBdf Vdevfn uint32 VfuncMask uint32 Msitranslate bool @@ -900,7 +896,7 @@ CInfo DomainCreateInfo BInfo DomainBuildInfo Disks []DeviceDisk Nics []DeviceNic -Pcis []DevicePci +Pcidevs []DevicePci Rdms []DeviceRdm Dtdevs []DeviceDtdev Vfbs []DeviceVfb diff --git a/tools/include/libxl.h b/tools/include/libxl.h index 90a7aa9b73..3433c950f9 100644 --- a/tools/include/libxl.h +++ b/tools/include/libxl.h @@ -463,25 +463,6 @@ */ #define LIBXL_HAVE_DEVICE_PCI_ASSIGNABLE_LIST_FREE 1 -/* - * LIBXL_HAVE_PCI_BDF indicates that the 'libxl_pci_bdf' type is defined - * is embedded in the 'libxl_device_pci' type. - */ -#define LIBXL_HAVE_PCI_BDF 1 - -/* - * LIBXL_HAVE_PCI_ASSIGNABLE_BDF indicates that the - * libxl_pci_bdf_assignable_add/remove/list/list_free() functions all - * exist. - */ -#define LIBXL_HAVE_PCI_ASSIGNABLE_BDF 1 - -/* - * LIBXL_HAVE_DEVICE_PCI_NAME indicates that the 'name' field of - * libxl_device_pci is defined. - */ -#define LIBXL_HAVE_DEVICE_PCI_NAME 1 - /* * libxl ABI compatibility * @@ -2370,9 +2351,9 @@ int libxl_device_events_handler(libxl_ctx *ctx, LIBXL_EXTERNAL_CALLERS_ONLY; /* - * Functions related to making PCI devices with the specified BDF - * assignable -- that is, bound to the pciback driver, ready to be given to - * a guest via libxl_pci_device_add. + * Functions related to making devices assignable -- that is, bound to + * the pciback driver, ready to be given to a guest via + * libxl_pci_device_add. * * - ..._add() will unbind the device from its current driver (if * already bound) and re-bind it to pciback; at that point it will be @@ -2384,31 +2365,16 @@ int libxl_device_events_handler(libxl_ctx *ctx, * rebind is non-zero, attempt to assign it back to the driver * from whence it came. * - * - ..._list() will return a list of the PCI BDFs available to be + * - ..._list() will return a list of the PCI devices available to be * assigned. * * add and remove are idempotent: if the device in question is already * added or is not bound, the functions will emit a warning but return * SUCCESS. */ -int libxl_pci_bdf_assignable_add(libxl_ctx *ctx, libxl_pci_bdf *pcibdf, - const char *name, int rebind); -int libxl_pci_bdf_assignable_remove(libxl_ctx *ctx, libxl_pci_bdf *pcibdf, - int rebind); -libxl_pci_bdf *libxl_pci_bdf_assignable_list(libxl_ctx *ctx, int *num); -void libxl_pci_bdf_assignable_list_free(libxl_pci_bdf *list, int num); -libxl_pci_bdf *libxl_pci_bdf_assignable_name2bdf(libxl_ctx *ctx, - const char *name); -char *libxl_pci_bdf_assignable_bdf2name(libxl_ctx *ctx, - libxl_pci_bdf *pcibdf); - -/* Compatibility functions - Use libxl_pci_bdf_assignable_* instead */ -int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci, - int rebind); -int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci, - int rebind); -libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, - int *num); +int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci, int rebind); +int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci, int rebind); +libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num); void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num); /* CPUID handling */ diff --git a/tools/include/libxlutil.h b/tools/include/libxlutil.h index cdd6aab4f8..92e35c5462 100644 --- a/tools/include/libxlutil.h +++ b/tools/include/libxlutil.h @@ -108,16 +108,10 @@ int xlu_disk_parse(XLU_Config *cfg, int nspecs, const char *const *specs, * resulting disk struct is used with libxl. */ -/* - * PCI BDF - */ -int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_pci_bdf *bdf, const char *str); - /* * PCI specification parsing */ -int xlu_pci_parse_spec_string(XLU_Config *cfg, libxl_device_pci *pci, - const char *str); +int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str); /* * RDM parsing diff --git a/tools/libs/light/libxl_dm.c b/tools/libs/light/libxl_dm.c index 1b951b0920..3da83259c0 100644 --- a/tools/libs/light/libxl_dm.c +++ b/tools/libs/light/libxl_dm.c @@ -472,10 +472,10 @@ int libxl__domain_device_construct_rdm(libxl__gc *gc, for (i = 0; i < d_config->num_pcidevs; i++) { unsigned int n, nr_entries; - seg = d_config->pcidevs[i].bdf.domain; - bus = d_config->pcidevs[i].bdf.bus; - devfn = PCI_DEVFN(d_config->pcidevs[i].bdf.dev, - d_config->pcidevs[i].bdf.func); + seg = d_config->pcidevs[i].domain; + bus = d_config->pcidevs[i].bus; + devfn = PCI_DEVFN(d_config->pcidevs[i].dev, + d_config->pcidevs[i].func); nr_entries = 0; rc = libxl__xc_device_get_rdm(gc, 0, seg, bus, devfn, &nr_entries, &xrdm); diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h index 6be7b12e4c..c79523ba92 100644 --- a/tools/libs/light/libxl_internal.h +++ b/tools/libs/light/libxl_internal.h @@ -4746,11 +4746,10 @@ void libxl__xcinfo2xlinfo(libxl_ctx *ctx, * devices have same identifier. */ #define COMPARE_DEVID(a, b) ((a)->devid == (b)->devid) #define COMPARE_DISK(a, b) (!strcmp((a)->vdev, (b)->vdev)) -#define COMPARE_BDF(a, b) ((a)->domain == (b)->domain && \ +#define COMPARE_PCI(a, b) ((a)->domain == (b)->domain && \ (a)->bus == (b)->bus && \ (a)->dev == (b)->dev && \ (a)->func == (b)->func) -#define COMPARE_PCI(a, b) COMPARE_BDF(&((a)->bdf), &((b)->bdf)) #define COMPARE_USB(a, b) ((a)->ctrl == (b)->ctrl && \ (a)->port == (b)->port) #define COMPARE_USBCTRL(a, b) ((a)->devid == (b)->devid) diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c index 5d83db2a59..74c2196ae3 100644 --- a/tools/libs/light/libxl_pci.c +++ b/tools/libs/light/libxl_pci.c @@ -25,33 +25,26 @@ #define PCI_BDF_XSPATH "%04x-%02x-%02x-%01x" #define PCI_PT_QDEV_ID "pci-pt-%02x_%02x.%01x" -static unsigned int pci_encode_bdf(libxl_pci_bdf *pcibdf) +static unsigned int pci_encode_bdf(libxl_device_pci *pci) { unsigned int value; - value = pcibdf->domain << 16; - value |= (pcibdf->bus & 0xff) << 8; - value |= (pcibdf->dev & 0x1f) << 3; - value |= (pcibdf->func & 0x7); + value = pci->domain << 16; + value |= (pci->bus & 0xff) << 8; + value |= (pci->dev & 0x1f) << 3; + value |= (pci->func & 0x7); return value; } -static void pcibdf_struct_fill(libxl_pci_bdf *pcibdf, unsigned int domain, - unsigned int bus, unsigned int dev, - unsigned int func) -{ - pcibdf->domain = domain; - pcibdf->bus = bus; - pcibdf->dev = dev; - pcibdf->func = func; -} - static void pci_struct_fill(libxl_device_pci *pci, unsigned int domain, unsigned int bus, unsigned int dev, unsigned int func, unsigned int vdevfn) { - pcibdf_struct_fill(&pci->bdf, domain, bus, dev, func); + pci->domain = domain; + pci->bus = bus; + pci->dev = dev; + pci->func = func; pci->vdevfn = vdevfn; } @@ -60,14 +53,10 @@ static void libxl_create_pci_backend_device(libxl__gc *gc, int num, const libxl_device_pci *pci) { - if (pci->name) { - flexarray_append(back, GCSPRINTF("name-%d", num)); - flexarray_append(back, GCSPRINTF("%s", pci->name)); - } flexarray_append(back, GCSPRINTF("key-%d", num)); - flexarray_append(back, GCSPRINTF(PCI_BDF, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func)); + flexarray_append(back, GCSPRINTF(PCI_BDF, pci->domain, pci->bus, pci->dev, pci->func)); flexarray_append(back, GCSPRINTF("dev-%d", num)); - flexarray_append(back, GCSPRINTF(PCI_BDF, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func)); + flexarray_append(back, GCSPRINTF(PCI_BDF, pci->domain, pci->bus, pci->dev, pci->func)); if (pci->vdevfn) flexarray_append_pair(back, GCSPRINTF("vdevfn-%d", num), GCSPRINTF("%x", pci->vdevfn)); flexarray_append(back, GCSPRINTF("opts-%d", num)); @@ -261,8 +250,8 @@ static int libxl__device_pci_remove_xenstore(libxl__gc *gc, uint32_t domid, libx unsigned int domain = 0, bus = 0, dev = 0, func = 0; xsdev = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/dev-%d", be_path, i)); sscanf(xsdev, PCI_BDF, &domain, &bus, &dev, &func); - if (domain == pci->bdf.domain && bus == pci->bdf.bus && - pci->bdf.dev == dev && pci->bdf.func == func) { + if (domain == pci->domain && bus == pci->bus && + pci->dev == dev && pci->func == func) { break; } } @@ -288,7 +277,6 @@ retry_transaction: retry_transaction2: t = xs_transaction_start(ctx->xsh); - xs_rm(ctx->xsh, t, GCSPRINTF("%s/name-%d", be_path, i)); xs_rm(ctx->xsh, t, GCSPRINTF("%s/state-%d", be_path, i)); xs_rm(ctx->xsh, t, GCSPRINTF("%s/key-%d", be_path, i)); xs_rm(ctx->xsh, t, GCSPRINTF("%s/dev-%d", be_path, i)); @@ -327,12 +315,6 @@ retry_transaction2: xs_write(ctx->xsh, t, GCSPRINTF("%s/vdevfn-%d", be_path, j - 1), tmp, strlen(tmp)); xs_rm(ctx->xsh, t, tmppath); } - tmppath = GCSPRINTF("%s/name-%d", be_path, j); - tmp = libxl__xs_read(gc, t, tmppath); - if (tmp) { - xs_write(ctx->xsh, t, GCSPRINTF("%s/name-%d", be_path, j - 1), tmp, strlen(tmp)); - xs_rm(ctx->xsh, t, tmppath); - } } if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) @@ -368,8 +350,8 @@ static bool is_pci_in_array(libxl_device_pci *pcis, int num, } /* Write the standard BDF into the sysfs path given by sysfs_path. */ -static int sysfs_write_bdf(libxl__gc *gc, const char *sysfs_path, - libxl_pci_bdf *pcibdf) +static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path, + libxl_device_pci *pci) { int rc, fd; char *buf; @@ -380,8 +362,8 @@ static int sysfs_write_bdf(libxl__gc *gc, const char *sysfs_path, return ERROR_FAIL; } - buf = GCSPRINTF(PCI_BDF, pcibdf->domain, pcibdf->bus, - pcibdf->dev, pcibdf->func); + buf = GCSPRINTF(PCI_BDF, pci->domain, pci->bus, + pci->dev, pci->func); rc = write(fd, buf, strlen(buf)); /* Annoying to have two if's, but we need the errno */ if (rc < 0) @@ -396,22 +378,22 @@ static int sysfs_write_bdf(libxl__gc *gc, const char *sysfs_path, #define PCI_INFO_PATH "/libxl/pci" -static char *pci_info_xs_path(libxl__gc *gc, libxl_pci_bdf *pcibdf, +static char *pci_info_xs_path(libxl__gc *gc, libxl_device_pci *pci, const char *node) { return node ? GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH"/%s", - pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func, + pci->domain, pci->bus, pci->dev, pci->func, node) : GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH, - pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func); + pci->domain, pci->bus, pci->dev, pci->func); } -static int pci_info_xs_write(libxl__gc *gc, libxl_pci_bdf *pcibdf, +static int pci_info_xs_write(libxl__gc *gc, libxl_device_pci *pci, const char *node, const char *val) { - char *path = pci_info_xs_path(gc, pcibdf, node); + char *path = pci_info_xs_path(gc, pci, node); int rc = libxl__xs_printf(gc, XBT_NULL, path, "%s", val); if (rc) LOGE(WARN, "Write of %s to node %s failed.", val, path); @@ -419,28 +401,28 @@ static int pci_info_xs_write(libxl__gc *gc, libxl_pci_bdf *pcibdf, return rc; } -static char *pci_info_xs_read(libxl__gc *gc, libxl_pci_bdf *pcibdf, +static char *pci_info_xs_read(libxl__gc *gc, libxl_device_pci *pci, const char *node) { - char *path = pci_info_xs_path(gc, pcibdf, node); + char *path = pci_info_xs_path(gc, pci, node); return libxl__xs_read(gc, XBT_NULL, path); } -static void pci_info_xs_remove(libxl__gc *gc, libxl_pci_bdf *pcibdf, +static void pci_info_xs_remove(libxl__gc *gc, libxl_device_pci *pci, const char *node) { - char *path = pci_info_xs_path(gc, pcibdf, node); + char *path = pci_info_xs_path(gc, pci, node); libxl_ctx *ctx = libxl__gc_owner(gc); /* Remove the xenstore entry */ xs_rm(ctx->xsh, XBT_NULL, path); } -libxl_pci_bdf *libxl_pci_bdf_assignable_list(libxl_ctx *ctx, int *num) +libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num) { GC_INIT(ctx); - libxl_pci_bdf *pcibdfs = NULL, *new; + libxl_device_pci *pcis = NULL, *new; struct dirent *de; DIR *dir; @@ -461,15 +443,15 @@ libxl_pci_bdf *libxl_pci_bdf_assignable_list(libxl_ctx *ctx, int *num) if (sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4) continue; - new = realloc(pcibdfs, ((*num) + 1) * sizeof(*new)); + new = realloc(pcis, ((*num) + 1) * sizeof(*new)); if (NULL == new) continue; - pcibdfs = new; - new = pcibdfs + *num; + pcis = new; + new = pcis + *num; - libxl_pci_bdf_init(new); - pcibdf_struct_fill(new, dom, bus, dev, func); + libxl_device_pci_init(new); + pci_struct_fill(new, dom, bus, dev, func, 0); if (pci_info_xs_read(gc, new, "domid")) /* already assigned */ continue; @@ -480,32 +462,32 @@ libxl_pci_bdf *libxl_pci_bdf_assignable_list(libxl_ctx *ctx, int *num) closedir(dir); out: GC_FREE; - return pcibdfs; + return pcis; } -void libxl_pci_bdf_assignable_list_free(libxl_pci_bdf *list, int num) +void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num) { int i; for (i = 0; i < num; i++) - libxl_pci_bdf_dispose(&list[i]); + libxl_device_pci_dispose(&list[i]); free(list); } /* Unbind device from its current driver, if any. If driver_path is non-NULL, * store the path to the original driver in it. */ -static int sysfs_dev_unbind(libxl__gc *gc, libxl_pci_bdf *pcibdf, +static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pci, char **driver_path) { char * spath, *dp = NULL; struct stat st; spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/driver", - pcibdf->domain, - pcibdf->bus, - pcibdf->dev, - pcibdf->func); + pci->domain, + pci->bus, + pci->dev, + pci->func); if ( !lstat(spath, &st) ) { /* Find the canonical path to the driver. */ dp = libxl__zalloc(gc, PATH_MAX); @@ -519,7 +501,7 @@ static int sysfs_dev_unbind(libxl__gc *gc, libxl_pci_bdf *pcibdf, /* Unbind from the old driver */ spath = GCSPRINTF("%s/unbind", dp); - if ( sysfs_write_bdf(gc, spath, pcibdf) < 0 ) { + if ( sysfs_write_bdf(gc, spath, pci) < 0 ) { LOGE(ERROR, "Couldn't unbind device"); return -1; } @@ -535,7 +517,7 @@ static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pci) { char *pci_device_vendor_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/vendor", - pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + pci->domain, pci->bus, pci->dev, pci->func); uint16_t read_items; uint16_t pci_device_vendor; @@ -543,7 +525,7 @@ static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pci) if (!f) { LOGE(ERROR, "pci device "PCI_BDF" does not have vendor attribute", - pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + pci->domain, pci->bus, pci->dev, pci->func); return 0xffff; } read_items = fscanf(f, "0x%hx\n", &pci_device_vendor); @@ -551,7 +533,7 @@ static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pci) if (read_items != 1) { LOGE(ERROR, "cannot read vendor of pci device "PCI_BDF, - pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + pci->domain, pci->bus, pci->dev, pci->func); return 0xffff; } @@ -562,7 +544,7 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pci) { char *pci_device_device_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/device", - pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + pci->domain, pci->bus, pci->dev, pci->func); uint16_t read_items; uint16_t pci_device_device; @@ -570,7 +552,7 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pci) if (!f) { LOGE(ERROR, "pci device "PCI_BDF" does not have device attribute", - pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + pci->domain, pci->bus, pci->dev, pci->func); return 0xffff; } read_items = fscanf(f, "0x%hx\n", &pci_device_device); @@ -578,7 +560,7 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pci) if (read_items != 1) { LOGE(ERROR, "cannot read device of pci device "PCI_BDF, - pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + pci->domain, pci->bus, pci->dev, pci->func); return 0xffff; } @@ -589,14 +571,14 @@ static int sysfs_dev_get_class(libxl__gc *gc, libxl_device_pci *pci, unsigned long *class) { char *pci_device_class_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/class", - pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + pci->domain, pci->bus, pci->dev, pci->func); int read_items, ret = 0; FILE *f = fopen(pci_device_class_path, "r"); if (!f) { LOGE(ERROR, "pci device "PCI_BDF" does not have class attribute", - pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + pci->domain, pci->bus, pci->dev, pci->func); ret = ERROR_FAIL; goto out; } @@ -605,7 +587,7 @@ static int sysfs_dev_get_class(libxl__gc *gc, libxl_device_pci *pci, if (read_items != 1) { LOGE(ERROR, "cannot read class of pci device "PCI_BDF, - pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + pci->domain, pci->bus, pci->dev, pci->func); ret = ERROR_FAIL; } @@ -657,8 +639,8 @@ bool libxl__is_igd_vga_passthru(libxl__gc *gc, * already exist. */ -/* Scan through /sys/.../pciback/slots looking for BDF */ -static int pciback_dev_has_slot(libxl__gc *gc, libxl_pci_bdf *pcibdf) +/* Scan through /sys/.../pciback/slots looking for pci's BDF */ +static int pciback_dev_has_slot(libxl__gc *gc, libxl_device_pci *pci) { FILE *f; int rc = 0; @@ -672,10 +654,10 @@ static int pciback_dev_has_slot(libxl__gc *gc, libxl_pci_bdf *pcibdf) } while (fscanf(f, "%x:%x:%x.%d\n", &dom, &bus, &dev, &func) == 4) { - if (dom == pcibdf->domain - && bus == pcibdf->bus - && dev == pcibdf->dev - && func == pcibdf->func) { + if (dom == pci->domain + && bus == pci->bus + && dev == pci->dev + && func == pci->func) { rc = 1; goto out; } @@ -685,7 +667,7 @@ out: return rc; } -static int pciback_dev_is_assigned(libxl__gc *gc, libxl_pci_bdf *pcibdf) +static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pci) { char * spath; int rc; @@ -701,8 +683,8 @@ static int pciback_dev_is_assigned(libxl__gc *gc, libxl_pci_bdf *pcibdf) } spath = GCSPRINTF(SYSFS_PCIBACK_DRIVER"/"PCI_BDF, - pcibdf->domain, pcibdf->bus, - pcibdf->dev, pcibdf->func); + pci->domain, pci->bus, + pci->dev, pci->func); rc = lstat(spath, &st); if( rc == 0 ) @@ -713,40 +695,40 @@ static int pciback_dev_is_assigned(libxl__gc *gc, libxl_pci_bdf *pcibdf) return -1; } -static int pciback_dev_assign(libxl__gc *gc, libxl_pci_bdf *pcibdf) +static int pciback_dev_assign(libxl__gc *gc, libxl_device_pci *pci) { int rc; - if ( (rc = pciback_dev_has_slot(gc, pcibdf)) < 0 ) { + if ( (rc = pciback_dev_has_slot(gc, pci)) < 0 ) { LOGE(ERROR, "Error checking for pciback slot"); return ERROR_FAIL; } else if (rc == 0) { if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/new_slot", - pcibdf) < 0 ) { + pci) < 0 ) { LOGE(ERROR, "Couldn't bind device to pciback!"); return ERROR_FAIL; } } - if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/bind", pcibdf) < 0 ) { + if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/bind", pci) < 0 ) { LOGE(ERROR, "Couldn't bind device to pciback!"); return ERROR_FAIL; } return 0; } -static int pciback_dev_unassign(libxl__gc *gc, libxl_pci_bdf *pcibdf) +static int pciback_dev_unassign(libxl__gc *gc, libxl_device_pci *pci) { /* Remove from pciback */ - if ( sysfs_dev_unbind(gc, pcibdf, NULL) < 0 ) { + if ( sysfs_dev_unbind(gc, pci, NULL) < 0 ) { LOG(ERROR, "Couldn't unbind device!"); return ERROR_FAIL; } /* Remove slot if necessary */ - if ( pciback_dev_has_slot(gc, pcibdf) > 0 ) { + if ( pciback_dev_has_slot(gc, pci) > 0 ) { if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/remove_slot", - pcibdf) < 0 ) { + pci) < 0 ) { LOGE(ERROR, "Couldn't remove pciback slot"); return ERROR_FAIL; } @@ -754,10 +736,9 @@ static int pciback_dev_unassign(libxl__gc *gc, libxl_pci_bdf *pcibdf) return 0; } -static int libxl__pci_bdf_assignable_add(libxl__gc *gc, - libxl_pci_bdf *pcibdf, - const char *name, - int rebind) +static int libxl__device_pci_assignable_add(libxl__gc *gc, + libxl_device_pci *pci, + int rebind) { libxl_ctx *ctx = libxl__gc_owner(gc); unsigned dom, bus, dev, func; @@ -765,28 +746,11 @@ static int libxl__pci_bdf_assignable_add(libxl__gc *gc, int rc; struct stat st; - /* Sanitise any name that was passed */ - if (name) { - unsigned int i, n = strlen(name); - - if (n > 64) { /* Reasonable upper bound on name length */ - LOG(ERROR, "Name too long"); - return ERROR_FAIL; - } - - for (i = 0; i < n; i++) { - if (!isgraph(name[i])) { - LOG(ERROR, "Names may only include printable characters"); - return ERROR_FAIL; - } - } - } - /* Local copy for convenience */ - dom = pcibdf->domain; - bus = pcibdf->bus; - dev = pcibdf->dev; - func = pcibdf->func; + dom = pci->domain; + bus = pci->bus; + dev = pci->dev; + func = pci->func; /* See if the device exists */ spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF, dom, bus, dev, func); @@ -796,17 +760,17 @@ static int libxl__pci_bdf_assignable_add(libxl__gc *gc, } /* Check to see if it's already assigned to pciback */ - rc = pciback_dev_is_assigned(gc, pcibdf); + rc = pciback_dev_is_assigned(gc, pci); if ( rc < 0 ) { return ERROR_FAIL; } if ( rc ) { LOG(WARN, PCI_BDF" already assigned to pciback", dom, bus, dev, func); - goto name; + goto quarantine; } /* Check to see if there's already a driver that we need to unbind from */ - if ( sysfs_dev_unbind(gc, pcibdf, &driver_path ) ) { + if ( sysfs_dev_unbind(gc, pci, &driver_path ) ) { LOG(ERROR, "Couldn't unbind "PCI_BDF" from driver", dom, bus, dev, func); return ERROR_FAIL; @@ -815,9 +779,9 @@ static int libxl__pci_bdf_assignable_add(libxl__gc *gc, /* Store driver_path for rebinding to dom0 */ if ( rebind ) { if ( driver_path ) { - pci_info_xs_write(gc, pcibdf, "driver_path", driver_path); + pci_info_xs_write(gc, pci, "driver_path", driver_path); } else if ( (driver_path = - pci_info_xs_read(gc, pcibdf, "driver_path")) != NULL ) { + pci_info_xs_read(gc, pci, "driver_path")) != NULL ) { LOG(INFO, PCI_BDF" not bound to a driver, will be rebound to %s", dom, bus, dev, func, driver_path); } else { @@ -825,26 +789,21 @@ static int libxl__pci_bdf_assignable_add(libxl__gc *gc, dom, bus, dev, func); } } else { - pci_info_xs_remove(gc, pcibdf, "driver_path"); + pci_info_xs_remove(gc, pci, "driver_path"); } - if ( pciback_dev_assign(gc, pcibdf) ) { + if ( pciback_dev_assign(gc, pci) ) { LOG(ERROR, "Couldn't bind device to pciback!"); return ERROR_FAIL; } -name: - if (name) - pci_info_xs_write(gc, pcibdf, "name", name); - else - pci_info_xs_remove(gc, pcibdf, "name"); - +quarantine: /* * DOMID_IO is just a sentinel domain, without any actual mappings, * so always pass XEN_DOMCTL_DEV_RDM_RELAXED to avoid assignment being * unnecessarily denied. */ - rc = xc_assign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pcibdf), + rc = xc_assign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci), XEN_DOMCTL_DEV_RDM_RELAXED); if ( rc < 0 ) { LOG(ERROR, "failed to quarantine "PCI_BDF, dom, bus, dev, func); @@ -854,33 +813,33 @@ name: return 0; } -static int libxl__pci_bdf_assignable_remove(libxl__gc *gc, - libxl_pci_bdf *pcibdf, - int rebind) +static int libxl__device_pci_assignable_remove(libxl__gc *gc, + libxl_device_pci *pci, + int rebind) { libxl_ctx *ctx = libxl__gc_owner(gc); int rc; char *driver_path; /* De-quarantine */ - rc = xc_deassign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pcibdf)); + rc = xc_deassign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci)); if ( rc < 0 ) { - LOG(ERROR, "failed to de-quarantine "PCI_BDF, pcibdf->domain, - pcibdf->bus, pcibdf->dev, pcibdf->func); + LOG(ERROR, "failed to de-quarantine "PCI_BDF, pci->domain, pci->bus, + pci->dev, pci->func); return ERROR_FAIL; } /* Unbind from pciback */ - if ( (rc = pciback_dev_is_assigned(gc, pcibdf)) < 0 ) { + if ( (rc = pciback_dev_is_assigned(gc, pci)) < 0 ) { return ERROR_FAIL; } else if ( rc ) { - pciback_dev_unassign(gc, pcibdf); + pciback_dev_unassign(gc, pci); } else { LOG(WARN, "Not bound to pciback"); } /* Rebind if necessary */ - driver_path = pci_info_xs_read(gc, pcibdf, "driver_path"); + driver_path = pci_info_xs_read(gc, pci, "driver_path"); if ( driver_path ) { if ( rebind ) { @@ -888,12 +847,12 @@ static int libxl__pci_bdf_assignable_remove(libxl__gc *gc, if ( sysfs_write_bdf(gc, GCSPRINTF("%s/bind", driver_path), - pcibdf) < 0 ) { + pci) < 0 ) { LOGE(ERROR, "Couldn't bind device to %s", driver_path); return -1; } - pci_info_xs_remove(gc, pcibdf, "driver_path"); + pci_info_xs_remove(gc, pci, "driver_path"); } } else { if ( rebind ) { @@ -902,87 +861,34 @@ static int libxl__pci_bdf_assignable_remove(libxl__gc *gc, } } - pci_info_xs_remove(gc, pcibdf, "name"); - return 0; } -int libxl_pci_bdf_assignable_add(libxl_ctx *ctx, libxl_pci_bdf *pcibdf, - const char *name, int rebind) +int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci, + int rebind) { GC_INIT(ctx); int rc; - rc = libxl__pci_bdf_assignable_add(gc, pcibdf, name, rebind); + rc = libxl__device_pci_assignable_add(gc, pci, rebind); GC_FREE; return rc; } -int libxl_pci_bdf_assignable_remove(libxl_ctx *ctx, libxl_pci_bdf *pcibdf, - int rebind) +int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci, + int rebind) { GC_INIT(ctx); int rc; - rc = libxl__pci_bdf_assignable_remove(gc, pcibdf, rebind); + rc = libxl__device_pci_assignable_remove(gc, pci, rebind); GC_FREE; return rc; } -libxl_pci_bdf *libxl_pci_bdf_assignable_name2bdf(libxl_ctx *ctx, - const char *name) -{ - GC_INIT(ctx); - char **bdfs; - libxl_pci_bdf *pcibdf = NULL; - unsigned int i, n; - - bdfs = libxl__xs_directory(gc, XBT_NULL, PCI_INFO_PATH, &n); - if (!n) - goto out; - - pcibdf = calloc(1, sizeof(*pcibdf)); - if (!pcibdf) - goto out; - - for (i = 0; i < n; i++) { - unsigned dom, bus, dev, func; - const char *tmp; - - if (sscanf(bdfs[i], PCI_BDF_XSPATH, &dom, &bus, &dev, &func) != 4) - continue; - - pcibdf_struct_fill(pcibdf, dom, bus, dev, func); - - tmp = pci_info_xs_read(gc, pcibdf, "name"); - if (tmp && !strcmp(tmp, name)) - goto out; - } - - free(pcibdf); - pcibdf = NULL; - -out: - GC_FREE; - return pcibdf; -} - -char *libxl_pci_bdf_assignable_bdf2name(libxl_ctx *ctx, - libxl_pci_bdf *pcibdf) -{ - GC_INIT(ctx); - char *name = NULL, *tmp = pci_info_xs_read(gc, pcibdf, "name"); - - if (tmp) - name = strdup(tmp); - - GC_FREE; - return name; -} - /* * This function checks that all functions of a device are bound to pciback * driver. It also initialises a bit-mask of which function numbers are present @@ -1008,11 +914,11 @@ static int pci_multifunction_check(libxl__gc *gc, libxl_device_pci *pci, unsigne if ( sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4 ) continue; - if ( pci->bdf.domain != dom ) + if ( pci->domain != dom ) continue; - if ( pci->bdf.bus != bus ) + if ( pci->bus != bus ) continue; - if ( pci->bdf.dev != dev ) + if ( pci->dev != dev ) continue; path = GCSPRINTF("%s/" PCI_BDF, SYSFS_PCIBACK_DRIVER, dom, bus, dev, func); @@ -1061,13 +967,13 @@ static int qemu_pci_add_xenstore(libxl__gc *gc, uint32_t domid, path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/parameter"); if (pci->vdevfn) { libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF_VDEVFN","PCI_OPTIONS, - pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, - pci->bdf.func, pci->vdevfn, pci->msitranslate, + pci->domain, pci->bus, pci->dev, + pci->func, pci->vdevfn, pci->msitranslate, pci->power_mgmt); } else { libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF","PCI_OPTIONS, - pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, - pci->bdf.func, pci->msitranslate, pci->power_mgmt); + pci->domain, pci->bus, pci->dev, + pci->func, pci->msitranslate, pci->power_mgmt); } libxl__qemu_traditional_cmd(gc, domid, "pci-ins"); @@ -1226,10 +1132,10 @@ static void pci_add_qmp_device_add(libxl__egc *egc, pci_add_state *pas) libxl__qmp_param_add_string(gc, &args, "driver", "xen-pci-passthrough"); QMP_PARAMETERS_SPRINTF(&args, "id", PCI_PT_QDEV_ID, - pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + pci->bus, pci->dev, pci->func); QMP_PARAMETERS_SPRINTF(&args, "hostaddr", - "%04x:%02x:%02x.%01x", pci->bdf.domain, - pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + "%04x:%02x:%02x.%01x", pci->domain, + pci->bus, pci->dev, pci->func); if (pci->vdevfn) { QMP_PARAMETERS_SPRINTF(&args, "addr", "%x.%x", PCI_SLOT(pci->vdevfn), @@ -1317,7 +1223,7 @@ static void pci_add_qmp_query_pci_cb(libxl__egc *egc, */ asked_id = GCSPRINTF(PCI_PT_QDEV_ID, - pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + pci->bus, pci->dev, pci->func); for (i = 0; (bus = libxl__json_array_get(response, i)); i++) { devices = libxl__json_map_get("devices", bus, JSON_ARRAY); @@ -1408,8 +1314,8 @@ static void pci_add_dm_done(libxl__egc *egc, if (isstubdom) starting = false; - sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->bdf.domain, - pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->domain, + pci->bus, pci->dev, pci->func); f = fopen(sysfs_path, "r"); start = end = flags = size = 0; irq = 0; @@ -1449,8 +1355,8 @@ static void pci_add_dm_done(libxl__egc *egc, } } fclose(f); - sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->bdf.domain, - pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->domain, + pci->bus, pci->dev, pci->func); f = fopen(sysfs_path, "r"); if (f == NULL) { LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path); @@ -1479,7 +1385,7 @@ static void pci_add_dm_done(libxl__egc *egc, /* Don't restrict writes to the PCI config space from this VM */ if (pci->permissive) { if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/permissive", - &pci->bdf) < 0 ) { + pci) < 0 ) { LOGD(ERROR, domainid, "Setting permissive for device"); rc = ERROR_FAIL; goto out; @@ -1495,8 +1401,7 @@ out_no_irq: rc = ERROR_FAIL; goto out; } - r = xc_assign_device(ctx->xch, domid, pci_encode_bdf(&pci->bdf), - flag); + r = xc_assign_device(ctx->xch, domid, pci_encode_bdf(pci), flag); if (r < 0 && (hvm || errno != ENOSYS)) { LOGED(ERROR, domainid, "xc_assign_device failed"); rc = ERROR_FAIL; @@ -1575,21 +1480,17 @@ int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid, return AO_INPROGRESS; } -static bool is_bdf_assignable(libxl_ctx *ctx, libxl_pci_bdf *pcibdf) +static bool libxl_pci_assignable(libxl_ctx *ctx, libxl_device_pci *pci) { - libxl_pci_bdf *pcibdfs; - int num, i; - - pcibdfs = libxl_pci_bdf_assignable_list(ctx, &num); - - for (i = 0; i < num; i++) { - if (COMPARE_BDF(pcibdf, &pcibdfs[i])) - break; - } + libxl_device_pci *pcis; + int num; + bool assignable; - libxl_pci_bdf_assignable_list_free(pcibdfs, num); + pcis = libxl_device_pci_assignable_list(ctx, &num); + assignable = is_pci_in_array(pcis, num, pci); + libxl_device_pci_assignable_list_free(pcis, num); - return i < num; + return assignable; } static void device_pci_add_stubdom_wait(libxl__egc *egc, @@ -1621,30 +1522,12 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid, pas->starting = starting; pas->callback = device_pci_add_stubdom_done; - if (pci->name) { - libxl_pci_bdf *pcibdf = - libxl_pci_bdf_assignable_name2bdf(CTX, pci->name); - - if (!pcibdf) { - rc = ERROR_FAIL; - goto out; - } - - LOGD(DETAIL, domid, "'%s' -> %04x:%02x:%02x.%u", pci->name, - pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func); - - libxl_pci_bdf_copy(CTX, &pci->bdf, pcibdf); - libxl_pci_bdf_dispose(pcibdf); - free(pcibdf); - } - if (libxl__domain_type(gc, domid) == LIBXL_DOMAIN_TYPE_HVM) { - rc = xc_test_assign_device(ctx->xch, domid, - pci_encode_bdf(&pci->bdf)); + rc = xc_test_assign_device(ctx->xch, domid, pci_encode_bdf(pci)); if (rc) { LOGD(ERROR, domid, "PCI device %04x:%02x:%02x.%u %s?", - pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func, + pci->domain, pci->bus, pci->dev, pci->func, errno == EOPNOTSUPP ? "cannot be assigned - no IOMMU" : "already assigned to a different guest"); goto out; @@ -1654,23 +1537,23 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid, rc = libxl__device_pci_setdefault(gc, domid, pci, !starting); if (rc) goto out; - if (pci->seize && !pciback_dev_is_assigned(gc, &pci->bdf)) { - rc = libxl__pci_bdf_assignable_add(gc, &pci->bdf, NULL, 1); + if (pci->seize && !pciback_dev_is_assigned(gc, pci)) { + rc = libxl__device_pci_assignable_add(gc, pci, 1); if ( rc ) goto out; } - if (!is_bdf_assignable(ctx, &pci->bdf)) { + if (!libxl_pci_assignable(ctx, pci)) { LOGD(ERROR, domid, "PCI device %x:%x:%x.%x is not assignable", - pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + pci->domain, pci->bus, pci->dev, pci->func); rc = ERROR_FAIL; goto out; } - rc = pci_info_xs_write(gc, &pci->bdf, "domid", GCSPRINTF("%u", domid)); + rc = pci_info_xs_write(gc, pci, "domid", GCSPRINTF("%u", domid)); if (rc) goto out; - libxl__device_pci_reset(gc, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + libxl__device_pci_reset(gc, pci->domain, pci->bus, pci->dev, pci->func); stubdomid = libxl_get_stubdom_id(ctx, domid); if (stubdomid != 0) { @@ -1751,13 +1634,13 @@ static void device_pci_add_stubdom_done(libxl__egc *egc, pci->vfunc_mask &= pfunc_mask; /* so now vfunc_mask == pfunc_mask */ }else{ - pfunc_mask = (1 << pci->bdf.func); + pfunc_mask = (1 << pci->func); } for (rc = 0, i = 7; i >= 0; --i) { if ( (1 << i) & pfunc_mask ) { if ( pci->vfunc_mask == pfunc_mask ) { - pci->bdf.func = i; + pci->func = i; pci->vdevfn = orig_vdev | i; } else { /* if not passing through multiple devices in a block make @@ -1786,20 +1669,12 @@ static void device_pci_add_done(libxl__egc *egc, libxl_device_pci *pci = &pas->pci; if (rc) { - if (pci->name) { - LOGD(ERROR, domid, - "libxl__device_pci_add failed for " - "PCI device '%s' (rc %d)", - pci->name, - rc); - } else { - LOGD(ERROR, domid, - "libxl__device_pci_add failed for " - "PCI device %x:%x:%x.%x (rc %d)", - pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func, - rc); - } - pci_info_xs_remove(gc, &pci->bdf, "domid"); + LOGD(ERROR, domid, + "libxl__device_pci_add failed for " + "PCI device %x:%x:%x.%x (rc %d)", + pci->domain, pci->bus, pci->dev, pci->func, + rc); + pci_info_xs_remove(gc, pci, "domid"); } libxl_device_pci_dispose(pci); aodev->rc = rc; @@ -1866,8 +1741,8 @@ static int qemu_pci_remove_xenstore(libxl__gc *gc, uint32_t domid, path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/state"); state = libxl__xs_read(gc, XBT_NULL, path); path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/parameter"); - libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF, pci->bdf.domain, - pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF, pci->domain, + pci->bus, pci->dev, pci->func); /* Remove all functions at once atomically by only signalling * device-model for function 0 */ @@ -1981,8 +1856,8 @@ static void do_pci_remove(libxl__egc *egc, pci_remove_state *prs) } else { assert(type == LIBXL_DOMAIN_TYPE_PV); - char *sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->bdf.domain, - pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + char *sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->domain, + pci->bus, pci->dev, pci->func); FILE *f = fopen(sysfs_path, "r"); unsigned int start = 0, end = 0, flags = 0, size = 0; int irq = 0; @@ -2017,8 +1892,8 @@ static void do_pci_remove(libxl__egc *egc, pci_remove_state *prs) } fclose(f); skip1: - sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->bdf.domain, - pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->domain, + pci->bus, pci->dev, pci->func); f = fopen(sysfs_path, "r"); if (f == NULL) { LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path); @@ -2082,7 +1957,7 @@ static void pci_remove_qmp_device_del(libxl__egc *egc, if (rc) goto out; QMP_PARAMETERS_SPRINTF(&args, "id", PCI_PT_QDEV_ID, - pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + pci->bus, pci->dev, pci->func); prs->qmp.callback = pci_remove_qmp_device_del_cb; rc = libxl__ev_qmp_send(egc, &prs->qmp, "device_del", args); if (rc) goto out; @@ -2151,7 +2026,7 @@ static void pci_remove_qmp_query_cb(libxl__egc *egc, libxl__ev_qmp_dispose(gc, qmp); asked_id = GCSPRINTF(PCI_PT_QDEV_ID, - pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + pci->bus, pci->dev, pci->func); /* query-pci response: * [{ 'devices': [ 'qdev_id': 'str', ... ], ... }] @@ -2202,7 +2077,7 @@ static void pci_remove_timeout(libxl__egc *egc, libxl__ev_time *ev, libxl_device_pci *const pci = &prs->pci; LOGD(WARN, prs->domid, "timed out waiting for DM to remove " - PCI_PT_QDEV_ID, pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + PCI_PT_QDEV_ID, pci->bus, pci->dev, pci->func); /* If we timed out, we might still want to keep destroying the device * (when force==true), so let the next function decide what to do on @@ -2235,12 +2110,11 @@ static void pci_remove_detached(libxl__egc *egc, /* don't do multiple resets while some functions are still passed through */ if ((pci->vdevfn & 0x7) == 0) { - libxl__device_pci_reset(gc, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func); + libxl__device_pci_reset(gc, pci->domain, pci->bus, pci->dev, pci->func); } if (!isstubdom) { - rc = xc_deassign_device(CTX->xch, domid, - pci_encode_bdf(&pci->bdf)); + rc = xc_deassign_device(CTX->xch, domid, pci_encode_bdf(pci)); if (rc < 0 && (prs->hvm || errno != ENOSYS)) LOGED(ERROR, domainid, "xc_deassign_device failed"); } @@ -2315,23 +2189,6 @@ static void libxl__device_pci_remove_common(libxl__egc *egc, libxl__ev_time_init(&prs->timeout); libxl__ev_time_init(&prs->retry_timer); - if (pci->name) { - libxl_pci_bdf *pcibdf = - libxl_pci_bdf_assignable_name2bdf(CTX, pci->name); - - if (!pcibdf) { - rc = ERROR_FAIL; - goto out; - } - - LOGD(DETAIL, domid, "'%s' -> %04x:%02x:%02x.%u", pci->name, - pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func); - - libxl_pci_bdf_copy(CTX, &prs->pci.bdf, pcibdf); - libxl_pci_bdf_dispose(pcibdf); - free(pcibdf); - } - prs->orig_vdev = pci->vdevfn & ~7U; if ( pci->vfunc_mask == LIBXL_PCI_FUNC_ALL ) { @@ -2341,7 +2198,7 @@ static void libxl__device_pci_remove_common(libxl__egc *egc, } pci->vfunc_mask &= prs->pfunc_mask; } else { - prs->pfunc_mask = (1 << pci->bdf.func); + prs->pfunc_mask = (1 << pci->func); } rc = 0; @@ -2369,7 +2226,7 @@ static void device_pci_remove_common_next(libxl__egc *egc, prs->next_func--; if ( (1 << i) & pfunc_mask ) { if ( pci->vfunc_mask == pfunc_mask ) { - pci->bdf.func = i; + pci->func = i; pci->vdevfn = orig_vdev | i; } else { pci->vdevfn = orig_vdev; @@ -2386,7 +2243,7 @@ out: libxl__ev_time_deregister(gc, &prs->timeout); libxl__ev_time_deregister(gc, &prs->retry_timer); - if (!rc) pci_info_xs_remove(gc, &pci->bdf, "domid"); + if (!rc) pci_info_xs_remove(gc, pci, "domid"); libxl_device_pci_dispose(pci); aodev->rc = rc; @@ -2466,10 +2323,6 @@ static int libxl__device_pci_from_xs_be(libxl__gc *gc, } while ((p = strtok_r(NULL, ",=", &saveptr)) != NULL); } - s = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/name-%d", be_path, nr)); - if (s) - pci->name = strdup(s); - return 0; } @@ -2582,48 +2435,6 @@ DEFINE_DEVICE_TYPE_STRUCT(pci, PCI, pcidevs, .from_xenstore = libxl__device_pci_from_xs_be, ); -int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci, - int rebind) -{ - return libxl_pci_bdf_assignable_add(ctx, &pci->bdf, NULL, rebind); -} - -int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci, - int rebind) -{ - return libxl_pci_bdf_assignable_remove(ctx, &pci->bdf, rebind); -} - -libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, - int *num) -{ - libxl_pci_bdf *pcibdfs = libxl_pci_bdf_assignable_list(ctx, num); - libxl_device_pci *pcis; - unsigned int i; - - if (!pcibdfs) - return NULL; - - pcis = calloc(*num, sizeof(*pcis)); - if (!pcis) { - libxl_pci_bdf_assignable_list_free(pcibdfs, *num); - return NULL; - } - - for (i = 0; i < *num; i++) { - libxl_device_pci_init(&pcis[i]); - libxl_pci_bdf_copy(ctx, &pcis[i].bdf, &pcibdfs[i]); - } - - libxl_pci_bdf_assignable_list_free(pcibdfs, *num); - return pcis; -} - -void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num) -{ - libxl_device_pci_list_free(list, num); -} - /* * Local variables: * mode: C diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl index 32cc99beff..05324736b7 100644 --- a/tools/libs/light/libxl_types.idl +++ b/tools/libs/light/libxl_types.idl @@ -770,23 +770,18 @@ libxl_device_nic = Struct("device_nic", [ ("colo_checkpoint_port", string) ]) -libxl_pci_bdf = Struct("pci_bdf", [ - ("func", uint8), - ("dev", uint8), - ("bus", uint8), - ("domain", integer), - ]) - libxl_device_pci = Struct("device_pci", [ - ("bdf", libxl_pci_bdf), - ("name", string), - ("vdevfn", uint32), + ("func", uint8), + ("dev", uint8), + ("bus", uint8), + ("domain", integer), + ("vdevfn", uint32), ("vfunc_mask", uint32), ("msitranslate", bool), ("power_mgmt", bool), ("permissive", bool), ("seize", bool), - ("rdm_policy", libxl_rdm_reserve_policy), + ("rdm_policy", libxl_rdm_reserve_policy), ]) libxl_device_rdm = Struct("device_rdm", [ diff --git a/tools/libs/util/libxlu_pci.c b/tools/libs/util/libxlu_pci.c index 543a1f80e9..1d38fffce3 100644 --- a/tools/libs/util/libxlu_pci.c +++ b/tools/libs/util/libxlu_pci.c @@ -1,7 +1,5 @@ #define _GNU_SOURCE -#include <ctype.h> - #include "libxlu_internal.h" #include "libxlu_disk_l.h" #include "libxlu_disk_i.h" @@ -11,218 +9,185 @@ #define XLU__PCI_ERR(_c, _x, _a...) \ if((_c) && (_c)->report) fprintf((_c)->report, _x, ##_a) -static int parse_bdf(libxl_pci_bdf *bdfp, uint32_t *vfunc_maskp, - const char *str, const char **endp) +static int hex_convert(const char *str, unsigned int *val, unsigned int mask) { - const char *ptr = str; - unsigned int colons = 0; - unsigned int domain, bus, dev, func; - int n; - - /* Count occurrences of ':' to detrmine presence/absence of the 'domain' */ - while (isxdigit(*ptr) || *ptr == ':') { - if (*ptr == ':') - colons++; - ptr++; - } - - ptr = str; - switch (colons) { - case 1: - domain = 0; - if (sscanf(ptr, "%x:%x.%n", &bus, &dev, &n) != 2) - return ERROR_INVAL; - break; - case 2: - if (sscanf(ptr, "%x:%x:%x.%n", &domain, &bus, &dev, &n) != 3) - return ERROR_INVAL; - break; - default: - return ERROR_INVAL; - } - - if (domain > 0xffff || bus > 0xff || dev > 0x1f) - return ERROR_INVAL; - - ptr += n; - if (*ptr == '*') { - if (!vfunc_maskp) - return ERROR_INVAL; - *vfunc_maskp = LIBXL_PCI_FUNC_ALL; - func = 0; - ptr++; - } else { - if (sscanf(ptr, "%x%n", &func, &n) != 1) - return ERROR_INVAL; - if (func > 7) - return ERROR_INVAL; - if (vfunc_maskp) - *vfunc_maskp = 1; - ptr += n; - } - - bdfp->domain = domain; - bdfp->bus = bus; - bdfp->dev = dev; - bdfp->func = func; - - if (endp) - *endp = ptr; - + unsigned long ret; + char *end; + + ret = strtoul(str, &end, 16); + if ( end == str || *end != '\0' ) + return -1; + if ( ret & ~mask ) + return -1; + *val = (unsigned int)ret & mask; return 0; } -static int parse_vslot(uint32_t *vdevfnp, const char *str, const char **endp) +static int pci_struct_fill(libxl_device_pci *pci, unsigned int domain, + unsigned int bus, unsigned int dev, + unsigned int func, unsigned int vdevfn) { - const char *ptr = str; - unsigned int val; - int n; - - if (sscanf(ptr, "%x%n", &val, &n) != 1) - return ERROR_INVAL; - - if (val > 0x1f) - return ERROR_INVAL; - - ptr += n; - - *vdevfnp = val << 3; - - if (endp) - *endp = ptr; - + pci->domain = domain; + pci->bus = bus; + pci->dev = dev; + pci->func = func; + pci->vdevfn = vdevfn; return 0; } -static int parse_key_val(char **keyp, char**valp, const char *str, - const char **endp) +#define STATE_DOMAIN 0 +#define STATE_BUS 1 +#define STATE_DEV 2 +#define STATE_FUNC 3 +#define STATE_VSLOT 4 +#define STATE_OPTIONS_K 6 +#define STATE_OPTIONS_V 7 +#define STATE_TERMINAL 8 +#define STATE_TYPE 9 +#define STATE_RDM_STRATEGY 10 +#define STATE_RESERVE_POLICY 11 +#define INVALID 0xffffffff +int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pci, const char *str) { - const char *ptr = str; - char *key, *val; - - while (*ptr != '=' && *ptr != '\0') - ptr++; + unsigned state = STATE_DOMAIN; + unsigned dom = INVALID, bus = INVALID, dev = INVALID, func = INVALID, vslot = 0; + char *buf2, *tok, *ptr, *end, *optkey = NULL; - if (*ptr == '\0') - return ERROR_INVAL; - - key = strndup(str, ptr - str); - if (!key) - return ERROR_NOMEM; - - str = ++ptr; /* skip '=' */ - while (*ptr != ',' && *ptr != '\0') - ptr++; - - val = strndup(str, ptr - str); - if (!val) { - free(key); + if ( NULL == (buf2 = ptr = strdup(str)) ) return ERROR_NOMEM; - } - - if (*ptr == ',') - ptr++; - *keyp = key; - *valp = val; - *endp = ptr; - - return 0; -} - -static int parse_rdm_policy(XLU_Config *cfg, libxl_rdm_reserve_policy *policy, - const char *str) -{ - int ret = libxl_rdm_reserve_policy_from_string(str, policy); - - if (ret) - XLU__PCI_ERR(cfg, "Unknown RDM policy: %s", str); - - return ret; -} - -int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_pci_bdf *bdf, const char *str) -{ - return parse_bdf(bdf, NULL, str, NULL); -} - -int xlu_pci_parse_spec_string(XLU_Config *cfg, libxl_device_pci *pcidev, - const char *str) -{ - const char *ptr = str; - bool bdf_present = false; - bool name_present = false; - int ret; - - /* Attempt to parse 'bdf' as positional parameter */ - ret = parse_bdf(&pcidev->bdf, &pcidev->vfunc_mask, ptr, &ptr); - if (!ret) { - bdf_present = true; - - /* Check whether 'vslot' if present */ - if (*ptr == '@') { - ret = parse_vslot(&pcidev->vdevfn, ++ptr, &ptr); - if (ret) - return ret; + for(tok = ptr, end = ptr + strlen(ptr) + 1; ptr < end; ptr++) { + switch(state) { + case STATE_DOMAIN: + if ( *ptr == ':' ) { + state = STATE_BUS; + *ptr = '\0'; + if ( hex_convert(tok, &dom, 0xffff) ) + goto parse_error; + tok = ptr + 1; + } + break; + case STATE_BUS: + if ( *ptr == ':' ) { + state = STATE_DEV; + *ptr = '\0'; + if ( hex_convert(tok, &bus, 0xff) ) + goto parse_error; + tok = ptr + 1; + }else if ( *ptr == '.' ) { + state = STATE_FUNC; + *ptr = '\0'; + if ( dom & ~0xff ) + goto parse_error; + bus = dom; + dom = 0; + if ( hex_convert(tok, &dev, 0xff) ) + goto parse_error; + tok = ptr + 1; + } + break; + case STATE_DEV: + if ( *ptr == '.' ) { + state = STATE_FUNC; + *ptr = '\0'; + if ( hex_convert(tok, &dev, 0xff) ) + goto parse_error; + tok = ptr + 1; + } + break; + case STATE_FUNC: + if ( *ptr == '\0' || *ptr == '@' || *ptr == ',' ) { + switch( *ptr ) { + case '\0': + state = STATE_TERMINAL; + break; + case '@': + state = STATE_VSLOT; + break; + case ',': + state = STATE_OPTIONS_K; + break; + } + *ptr = '\0'; + if ( !strcmp(tok, "*") ) { + pci->vfunc_mask = LIBXL_PCI_FUNC_ALL; + }else{ + if ( hex_convert(tok, &func, 0x7) ) + goto parse_error; + pci->vfunc_mask = (1 << 0); + } + tok = ptr + 1; + } + break; + case STATE_VSLOT: + if ( *ptr == '\0' || *ptr == ',' ) { + state = ( *ptr == ',' ) ? STATE_OPTIONS_K : STATE_TERMINAL; + *ptr = '\0'; + if ( hex_convert(tok, &vslot, 0xff) ) + goto parse_error; + tok = ptr + 1; + } + break; + case STATE_OPTIONS_K: + if ( *ptr == '=' ) { + state = STATE_OPTIONS_V; + *ptr = '\0'; + optkey = tok; + tok = ptr + 1; + } + break; + case STATE_OPTIONS_V: + if ( *ptr == ',' || *ptr == '\0' ) { + state = (*ptr == ',') ? STATE_OPTIONS_K : STATE_TERMINAL; + *ptr = '\0'; + if ( !strcmp(optkey, "msitranslate") ) { + pci->msitranslate = atoi(tok); + }else if ( !strcmp(optkey, "power_mgmt") ) { + pci->power_mgmt = atoi(tok); + }else if ( !strcmp(optkey, "permissive") ) { + pci->permissive = atoi(tok); + }else if ( !strcmp(optkey, "seize") ) { + pci->seize = atoi(tok); + } else if (!strcmp(optkey, "rdm_policy")) { + if (!strcmp(tok, "strict")) { + pci->rdm_policy = LIBXL_RDM_RESERVE_POLICY_STRICT; + } else if (!strcmp(tok, "relaxed")) { + pci->rdm_policy = LIBXL_RDM_RESERVE_POLICY_RELAXED; + } else { + XLU__PCI_ERR(cfg, "%s is not an valid PCI RDM property" + " policy: 'strict' or 'relaxed'.", + tok); + goto parse_error; + } + } else { + XLU__PCI_ERR(cfg, "Unknown PCI BDF option: %s", optkey); + } + tok = ptr + 1; + } + default: + break; } - if (*ptr == ',') - ptr++; - else if (*ptr != '\0') - return ERROR_INVAL; } - /* Parse the rest as 'key=val' pairs */ - while (*ptr != '\0') { - char *key, *val; - - ret = parse_key_val(&key, &val, ptr, &ptr); - if (ret) - return ret; - - if (!strcmp(key, "bdf")) { - ret = parse_bdf(&pcidev->bdf, &pcidev->vfunc_mask, val, NULL); - bdf_present = !ret; - } else if (!strcmp(key, "vslot")) { - ret = parse_vslot(&pcidev->vdevfn, val, NULL); - } else if (!strcmp(key, "permissive")) { - pcidev->permissive = atoi(val); - } else if (!strcmp(key, "msitranslate")) { - pcidev->msitranslate = atoi(val); - } else if (!strcmp(key, "seize")) { - pcidev->seize= atoi(val); - } else if (!strcmp(key, "power_mgmt")) { - pcidev->power_mgmt = atoi(val); - } else if (!strcmp(key, "rdm_policy")) { - ret = parse_rdm_policy(cfg, &pcidev->rdm_policy, val); - } else if (!strcmp(key, "name")) { - name_present = true; - pcidev->name = strdup(val); - if (!pcidev->name) ret = ERROR_NOMEM; - } else { - XLU__PCI_ERR(cfg, "Unknown PCI_SPEC_STRING option: %s", key); - ret = ERROR_INVAL; - } + if ( tok != ptr || state != STATE_TERMINAL ) + goto parse_error; - free(key); - free(val); + assert(dom != INVALID && bus != INVALID && dev != INVALID && func != INVALID); - if (ret) - return ret; - } + /* Just a pretty way to fill in the values */ + pci_struct_fill(pci, dom, bus, dev, func, vslot << 3); - if (!(bdf_present ^ name_present)) - return ERROR_INVAL; + free(buf2); return 0; + +parse_error: + free(buf2); + return ERROR_INVAL; } int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str) { -#define STATE_TYPE 0 -#define STATE_RDM_STRATEGY 1 -#define STATE_RESERVE_POLICY 2 -#define STATE_TERMINAL 3 - unsigned state = STATE_TYPE; char *buf2, *tok, *ptr, *end; @@ -262,8 +227,15 @@ int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str) if (*ptr == ',' || *ptr == '\0') { state = *ptr == ',' ? STATE_TYPE : STATE_TERMINAL; *ptr = '\0'; - if (!parse_rdm_policy(cfg, &rdm->policy, tok)) + if (!strcmp(tok, "strict")) { + rdm->policy = LIBXL_RDM_RESERVE_POLICY_STRICT; + } else if (!strcmp(tok, "relaxed")) { + rdm->policy = LIBXL_RDM_RESERVE_POLICY_RELAXED; + } else { + XLU__PCI_ERR(cfg, "Unknown RDM property policy value: %s", + tok); goto parse_error; + } tok = ptr + 1; } default: @@ -281,11 +253,6 @@ int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str) parse_error: free(buf2); return ERROR_INVAL; - -#undef STATE_TYPE -#undef STATE_RDM_STRATEGY -#undef STATE_RESERVE_POLICY -#undef STATE_TERMINAL } /* diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c index bd8af12ff3..6ab5e47da3 100644 --- a/tools/xl/xl_cmdtable.c +++ b/tools/xl/xl_cmdtable.c @@ -90,12 +90,12 @@ struct cmd_spec cmd_table[] = { { "pci-attach", &main_pciattach, 0, 1, "Insert a new pass-through pci device", - "<Domain> <PCI_SPEC_STRING>", + "<Domain> <BDF> [Virtual Slot]", }, { "pci-detach", &main_pcidetach, 0, 1, "Remove a domain's pass-through pci device", - "<Domain> <PCI_SPEC_STRING>", + "<Domain> <BDF>", }, { "pci-list", &main_pcilist, 0, 0, @@ -105,25 +105,21 @@ struct cmd_spec cmd_table[] = { { "pci-assignable-add", &main_pciassignable_add, 0, 1, "Make a device assignable for pci-passthru", - "[options] <BDF>", - "-n NAME, --name=NAME Name the assignable device.\n" + "<BDF>", "-h Print this help.\n" }, { "pci-assignable-remove", &main_pciassignable_remove, 0, 1, "Remove a device from being assignable", - "[options] <BDF>|NAME", + "[options] <BDF>", "-h Print this help.\n" "-r Attempt to re-assign the device to the\n" - " original driver." + " original driver" }, { "pci-assignable-list", &main_pciassignable_list, 0, 0, "List all the assignable pci devices", - "[options]", - "-h Print this help.\n" - "-n, --show-names Display assignable device names where\n" - " supplied.\n" + "", }, { "pause", &main_pause, 0, 1, diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c index 867e4d068a..4ebf39620a 100644 --- a/tools/xl/xl_parse.c +++ b/tools/xl/xl_parse.c @@ -1487,10 +1487,10 @@ void parse_config_data(const char *config_source, * the global policy by default. */ pci->rdm_policy = b_info->u.hvm.rdm.policy; - e = xlu_pci_parse_spec_string(config, pci, buf); + e = xlu_pci_parse_bdf(config, pci, buf); if (e) { fprintf(stderr, - "unable to parse PCI_SPEC_STRING `%s' for passthrough\n", + "unable to parse PCI BDF `%s' for passthrough\n", buf); exit(-e); } diff --git a/tools/xl/xl_pci.c b/tools/xl/xl_pci.c index eb29b4e08d..f71498cbb5 100644 --- a/tools/xl/xl_pci.c +++ b/tools/xl/xl_pci.c @@ -34,8 +34,7 @@ static void pcilist(uint32_t domid) for (i = 0; i < num; i++) { printf("%02x.%01x %04x:%02x:%02x.%01x\n", (pcis[i].vdevfn >> 3) & 0x1f, pcis[i].vdevfn & 0x7, - pcis[i].bdf.domain, pcis[i].bdf.bus, pcis[i].bdf.dev, - pcis[i].bdf.func); + pcis[i].domain, pcis[i].bus, pcis[i].dev, pcis[i].func); } libxl_device_pci_list_free(pcis, num); } @@ -55,7 +54,7 @@ int main_pcilist(int argc, char **argv) return 0; } -static int pcidetach(uint32_t domid, const char *spec_string, int force) +static int pcidetach(uint32_t domid, const char *bdf, int force) { libxl_device_pci pci; XLU_Config *config; @@ -66,9 +65,8 @@ static int pcidetach(uint32_t domid, const char *spec_string, int force) config = xlu_cfg_init(stderr, "command line"); if (!config) { perror("xlu_cfg_inig"); exit(-1); } - if (xlu_pci_parse_spec_string(config, &pci, spec_string)) { - fprintf(stderr, "pci-detach: malformed PCI_SPEC_STRING \"%s\"\n", - spec_string); + if (xlu_pci_parse_bdf(config, &pci, bdf)) { + fprintf(stderr, "pci-detach: malformed BDF specification \"%s\"\n", bdf); exit(2); } if (force) { @@ -90,7 +88,7 @@ int main_pcidetach(int argc, char **argv) uint32_t domid; int opt; int force = 0; - const char *spec_string = NULL; + const char *bdf = NULL; SWITCH_FOREACH_OPT(opt, "f", NULL, "pci-detach", 2) { case 'f': @@ -99,15 +97,15 @@ int main_pcidetach(int argc, char **argv) } domid = find_domain(argv[optind]); - spec_string = argv[optind + 1]; + bdf = argv[optind + 1]; - if (pcidetach(domid, spec_string, force)) + if (pcidetach(domid, bdf, force)) return EXIT_FAILURE; return EXIT_SUCCESS; } -static int pciattach(uint32_t domid, const char *spec_string) +static int pciattach(uint32_t domid, const char *bdf, const char *vs) { libxl_device_pci pci; XLU_Config *config; @@ -118,9 +116,8 @@ static int pciattach(uint32_t domid, const char *spec_string) config = xlu_cfg_init(stderr, "command line"); if (!config) { perror("xlu_cfg_inig"); exit(-1); } - if (xlu_pci_parse_spec_string(config, &pci, spec_string)) { - fprintf(stderr, "pci-attach: malformed PCI_SPEC_STRING \"%s\"\n", - spec_string); + if (xlu_pci_parse_bdf(config, &pci, bdf)) { + fprintf(stderr, "pci-attach: malformed BDF specification \"%s\"\n", bdf); exit(2); } @@ -137,83 +134,72 @@ int main_pciattach(int argc, char **argv) { uint32_t domid; int opt; - const char *spec_string = NULL; + const char *bdf = NULL, *vs = NULL; SWITCH_FOREACH_OPT(opt, "", NULL, "pci-attach", 2) { /* No options */ } domid = find_domain(argv[optind]); - spec_string = argv[optind + 1]; + bdf = argv[optind + 1]; + + if (optind + 1 < argc) + vs = argv[optind + 2]; - if (pciattach(domid, spec_string)) + if (pciattach(domid, bdf, vs)) return EXIT_FAILURE; return EXIT_SUCCESS; } -static void pciassignable_list(bool show_names) +static void pciassignable_list(void) { - libxl_pci_bdf *pcibdfs; + libxl_device_pci *pcis; int num, i; - pcibdfs = libxl_pci_bdf_assignable_list(ctx, &num); + pcis = libxl_device_pci_assignable_list(ctx, &num); - if ( pcibdfs == NULL ) + if ( pcis == NULL ) return; for (i = 0; i < num; i++) { - libxl_pci_bdf *pcibdf = &pcibdfs[i]; - char *name = show_names ? - libxl_pci_bdf_assignable_bdf2name(ctx, pcibdf) : NULL; - - printf("%04x:%02x:%02x.%01x %s\n", - pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func, - name ?: ""); - - free(name); + printf("%04x:%02x:%02x.%01x\n", + pcis[i].domain, pcis[i].bus, pcis[i].dev, pcis[i].func); } - libxl_pci_bdf_assignable_list_free(pcibdfs, num); + libxl_device_pci_assignable_list_free(pcis, num); } int main_pciassignable_list(int argc, char **argv) { int opt; - static struct option opts[] = { - {"show-names", 0, 0, 'n'}, - COMMON_LONG_OPTS - }; - bool show_names = false; - - SWITCH_FOREACH_OPT(opt, "n", opts, "pci-assignable-list", 0) { - case 'n': - show_names = true; - break; + + SWITCH_FOREACH_OPT(opt, "", NULL, "pci-assignable-list", 0) { + /* No options */ } - pciassignable_list(show_names); + pciassignable_list(); return 0; } -static int pciassignable_add(const char *bdf, const char *name, int rebind) +static int pciassignable_add(const char *bdf, int rebind) { - libxl_pci_bdf pcibdf; + libxl_device_pci pci; XLU_Config *config; int r = 0; - libxl_pci_bdf_init(&pcibdf); + libxl_device_pci_init(&pci); config = xlu_cfg_init(stderr, "command line"); if (!config) { perror("xlu_cfg_init"); exit(-1); } - if (xlu_pci_parse_bdf(config, &pcibdf, bdf)) { - fprintf(stderr, "pci-assignable-add: malformed BDF \"%s\"\n", bdf); + if (xlu_pci_parse_bdf(config, &pci, bdf)) { + fprintf(stderr, "pci-assignable-add: malformed BDF specification \"%s\"\n", bdf); exit(2); } - if (libxl_pci_bdf_assignable_add(ctx, &pcibdf, name, rebind)) + if (libxl_device_pci_assignable_add(ctx, &pci, rebind)) r = 1; - libxl_pci_bdf_dispose(&pcibdf); + libxl_device_pci_dispose(&pci); xlu_cfg_destroy(config); return r; @@ -223,58 +209,39 @@ int main_pciassignable_add(int argc, char **argv) { int opt; const char *bdf = NULL; - static struct option opts[] = { - {"name", 1, 0, 'n'}, - COMMON_LONG_OPTS - }; - const char *name = NULL; - - SWITCH_FOREACH_OPT(opt, "n:", opts, "pci-assignable-add", 0) { - case 'n': - name = optarg; - break; + + SWITCH_FOREACH_OPT(opt, "", NULL, "pci-assignable-add", 1) { + /* No options */ } bdf = argv[optind]; - if (pciassignable_add(bdf, name, 1)) + if (pciassignable_add(bdf, 1)) return EXIT_FAILURE; return EXIT_SUCCESS; } -static int pciassignable_remove(const char *ident, int rebind) +static int pciassignable_remove(const char *bdf, int rebind) { - libxl_pci_bdf *pcibdf; + libxl_device_pci pci; XLU_Config *config; int r = 0; + libxl_device_pci_init(&pci); + config = xlu_cfg_init(stderr, "command line"); if (!config) { perror("xlu_cfg_init"); exit(-1); } - pcibdf = libxl_pci_bdf_assignable_name2bdf(ctx, ident); - if (!pcibdf) { - pcibdf = calloc(1, sizeof(*pcibdf)); - - if (!pcibdf) { - fprintf(stderr, - "pci-assignable-remove: failed to allocate memory\n"); - exit(2); - } - - libxl_pci_bdf_init(pcibdf); - if (xlu_pci_parse_bdf(config, pcibdf, ident)) { - fprintf(stderr, - "pci-assignable-remove: malformed BDF '%s'\n", ident); - exit(2); - } + if (xlu_pci_parse_bdf(config, &pci, bdf)) { + fprintf(stderr, "pci-assignable-remove: malformed BDF specification \"%s\"\n", bdf); + exit(2); } - if (libxl_pci_bdf_assignable_remove(ctx, pcibdf, rebind)) + if (libxl_device_pci_assignable_remove(ctx, &pci, rebind)) r = 1; - libxl_pci_bdf_dispose(pcibdf); - free(pcibdf); + libxl_device_pci_dispose(&pci); xlu_cfg_destroy(config); return r; @@ -283,7 +250,7 @@ static int pciassignable_remove(const char *ident, int rebind) int main_pciassignable_remove(int argc, char **argv) { int opt; - const char *ident = NULL; + const char *bdf = NULL; int rebind = 0; SWITCH_FOREACH_OPT(opt, "r", NULL, "pci-assignable-remove", 1) { @@ -292,9 +259,9 @@ int main_pciassignable_remove(int argc, char **argv) break; } - ident = argv[optind]; + bdf = argv[optind]; - if (pciassignable_remove(ident, rebind)) + if (pciassignable_remove(bdf, rebind)) return EXIT_FAILURE; return EXIT_SUCCESS; diff --git a/tools/xl/xl_sxp.c b/tools/xl/xl_sxp.c index dc49fb7d50..359a001570 100644 --- a/tools/xl/xl_sxp.c +++ b/tools/xl/xl_sxp.c @@ -194,8 +194,8 @@ void printf_info_sexp(int domid, libxl_domain_config *d_config, FILE *fh) fprintf(fh, "\t(device\n"); fprintf(fh, "\t\t(pci\n"); fprintf(fh, "\t\t\t(pci dev %04x:%02x:%02x.%01x@%02x)\n", - d_config->pcidevs[i].bdf.domain, d_config->pcidevs[i].bdf.bus, - d_config->pcidevs[i].bdf.dev, d_config->pcidevs[i].bdf.func, + d_config->pcidevs[i].domain, d_config->pcidevs[i].bus, + d_config->pcidevs[i].dev, d_config->pcidevs[i].func, d_config->pcidevs[i].vdevfn); fprintf(fh, "\t\t\t(opts msitranslate %d power_mgmt %d)\n", d_config->pcidevs[i].msitranslate, -- generated by git-patchbot for /home/xen/git/xen.git#master
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |