[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 07/11] igd: revamp host config read
On Tue, 5 Jan 2016, Gerd Hoffmann wrote: > Move all work to the host_pci_config_copy helper function, > which we can easily reuse when adding q35 support. > Open sysfs file only once for all values. Use pread. > Proper error handling. Fix bugs: > > * Don't throw away results (like old host_pci_config_read > did because val was passed by value not reference). > * Update config space directly (writing via > pci_default_write_config only works for registers > whitelisted in wmask). > > Hmm, this code can hardly ever worked before, > /me wonders what test coverage it had. > > With this patch in place igd-passthru=on actually > works, although it still requires root priviledges > because linux refuses to allow non-root users access > pci config space above offset 0x50. > > Signed-off-by: Gerd Hoffmann <kraxel@xxxxxxxxxx> > --- > hw/pci-host/igd.c | 65 > +++++++++++++++++++++++-------------------------------- > 1 file changed, 27 insertions(+), 38 deletions(-) > > diff --git a/hw/pci-host/igd.c b/hw/pci-host/igd.c > index 0784128..ec48875 100644 > --- a/hw/pci-host/igd.c > +++ b/hw/pci-host/igd.c > @@ -19,47 +19,39 @@ static const IGDHostInfo igd_host_bridge_infos[] = { > {0xa8, 4}, /* SNB: base of GTT stolen memory */ > }; > > -static int host_pci_config_read(int pos, int len, uint32_t val) > +static void host_pci_config_copy(PCIDevice *guest, const char *host, > + const IGDHostInfo *list, int len, Error > **errp) > { > - char path[PATH_MAX]; > - int config_fd; > - ssize_t size = sizeof(path); > - /* Access real host bridge. */ > - int rc = snprintf(path, size, > "/sys/bus/pci/devices/%04x:%02x:%02x.%d/%s", > - 0, 0, 0, 0, "config"); > - int ret = 0; > + char *path; > + int config_fd, rc, i; > > - if (rc >= size || rc < 0) { > - return -ENODEV; > - } > - > - config_fd = open(path, O_RDWR); > + path = g_strdup_printf("/sys/bus/pci/devices/%s/config", host); > + config_fd = open(path, O_RDONLY); > if (config_fd < 0) { > - return -ENODEV; > + error_setg_file_open(errp, errno, path); > + goto out_free; > } > > - if (lseek(config_fd, pos, SEEK_SET) != pos) { > - ret = -errno; > - goto out; > + for (i = 0; i < len; i++) { > + rc = pread(config_fd, guest->config + list[i].offset, > + list[i].len, list[i].offset); > + if (rc != list[i].len) { pread is allowed to return early, returning the number of bytes read. > + error_setg_errno(errp, errno, "read %s, offset 0x%x", > + path, list[i].offset); > + goto out_close; > + } > } > - do { > - rc = read(config_fd, (uint8_t *)&val, len); > - } while (rc < 0 && (errno == EINTR || errno == EAGAIN)); > - if (rc != len) { > - ret = -errno; > - } > -out: > + > +out_close: > close(config_fd); > - return ret; > +out_free: > + g_free(path); > } > > static void (*i440fx_realize)(PCIDevice *pci_dev, Error **errp); > static void igd_pt_i440fx_realize(PCIDevice *pci_dev, Error **errp) > { > Error *err = NULL; > - uint32_t val = 0; > - int rc, i, num; > - int pos, len; > > i440fx_realize(pci_dev, &err); > if (err != NULL) { > @@ -67,16 +59,13 @@ static void igd_pt_i440fx_realize(PCIDevice *pci_dev, > Error **errp) > return; > } > > - num = ARRAY_SIZE(igd_host_bridge_infos); > - for (i = 0; i < num; i++) { > - pos = igd_host_bridge_infos[i].offset; > - len = igd_host_bridge_infos[i].len; > - rc = host_pci_config_read(pos, len, val); > - if (rc) { > - error_setg(errp, "failed to read host config"); > - return; > - } > - pci_default_write_config(pci_dev, pos, val, len); > + host_pci_config_copy(pci_dev, "0000:00:00.0", > + igd_host_bridge_infos, > + ARRAY_SIZE(igd_host_bridge_infos), > + &err); > + if (err != NULL) { > + error_propagate(errp, err); > + return; > } > } > > -- > 1.8.3.1 > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |