Re: [Qemu-devel] [PATCH v5 07/13] vfio/ccw: vfio based subchannel passthrough driver
* Cornelia Huck[2017-04-28 13:04:07 +0200]: > On Wed, 26 Apr 2017 16:49:20 +0800 > Dong Jia Shi wrote: > > > * Dong Jia Shi [2017-04-25 13:15:19 +0800]: > > > > > * Alex Williamson [2017-04-24 16:56:28 > > > -0600]: > > > > > > [...] > > > > > > diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c > > > > > > new file mode 100644 > > > > > > index 000..c491bee > > > > > > --- /dev/null > > > > > > +++ b/hw/vfio/ccw.c > > > > > > @@ -0,0 +1,207 @@ > > > > > > +/* > > > > > > + * vfio based subchannel assignment support > > > > > > + * > > > > > > + * Copyright 2017 IBM Corp. > > > > > > + * Author(s): Dong Jia Shi > > > > > > + *Xiao Feng Ren > > > > > > + *Pierre Morel > > > > > > + * > > > > > > + * This work is licensed under the terms of the GNU GPL, version 2 > > > > > > or(at > > > > > > + * your option) any version. See the COPYING file in the top-level > > > > > > + * directory. > > > > > > + */ > > > > > > + > > > > > > +#include > > > > > > +#include > > > > > > + > > > > > > +#include "qemu/osdep.h" > > > > > > +#include "qapi/error.h" > > > > > > +#include "hw/sysbus.h" > > > > > > +#include "hw/vfio/vfio.h" > > > > > > +#include "hw/vfio/vfio-common.h" > > > > > > +#include "hw/s390x/s390-ccw.h" > > > > > > +#include "hw/s390x/ccw-device.h" > > > > > > + > > > > > > +#define TYPE_VFIO_CCW "vfio-ccw" > > > > > > +typedef struct VFIOCCWDevice { > > > > > > +S390CCWDevice cdev; > > > > > > +VFIODevice vdev; > > > > > > +} VFIOCCWDevice; > > > > > > + > > > > > > +static void vfio_ccw_compute_needs_reset(VFIODevice *vdev) > > > > > > +{ > > > > > > +vdev->needs_reset = false; > > > > > > +} > > > > > > + > > > > > > +/* > > > > > > + * We don't need vfio_hot_reset_multi and vfio_eoi operationis for > > > > > > > > One more: > > > > > > > > s/operationis/operations/ > > > > > > > Ok. > > > > > > > Hi Conny, > > > > I have pulled your cohuck-qemu/s390-next branch, and prepared a new > > patch set with all of these problems fixed directly on the coressponding > > commits on it. Fine to send out the new version as that? > > > > Or I should rebase them against the latest master branch? > > As I currently don't have things in my next branch that should interact > with your changes, either is fine :) Thanks! :> I used your branch as the code base and just sent out the v6 patches. > > [I'll take a look at the new version then] -- Dong Jia Shi
Re: [Qemu-devel] [PATCH v5 07/13] vfio/ccw: vfio based subchannel passthrough driver
On Wed, 26 Apr 2017 16:49:20 +0800 Dong Jia Shiwrote: > * Dong Jia Shi [2017-04-25 13:15:19 +0800]: > > > * Alex Williamson [2017-04-24 16:56:28 -0600]: > > > > [...] > > > > > diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c > > > > > new file mode 100644 > > > > > index 000..c491bee > > > > > --- /dev/null > > > > > +++ b/hw/vfio/ccw.c > > > > > @@ -0,0 +1,207 @@ > > > > > +/* > > > > > + * vfio based subchannel assignment support > > > > > + * > > > > > + * Copyright 2017 IBM Corp. > > > > > + * Author(s): Dong Jia Shi > > > > > + *Xiao Feng Ren > > > > > + *Pierre Morel > > > > > + * > > > > > + * This work is licensed under the terms of the GNU GPL, version 2 > > > > > or(at > > > > > + * your option) any version. See the COPYING file in the top-level > > > > > + * directory. > > > > > + */ > > > > > + > > > > > +#include > > > > > +#include > > > > > + > > > > > +#include "qemu/osdep.h" > > > > > +#include "qapi/error.h" > > > > > +#include "hw/sysbus.h" > > > > > +#include "hw/vfio/vfio.h" > > > > > +#include "hw/vfio/vfio-common.h" > > > > > +#include "hw/s390x/s390-ccw.h" > > > > > +#include "hw/s390x/ccw-device.h" > > > > > + > > > > > +#define TYPE_VFIO_CCW "vfio-ccw" > > > > > +typedef struct VFIOCCWDevice { > > > > > +S390CCWDevice cdev; > > > > > +VFIODevice vdev; > > > > > +} VFIOCCWDevice; > > > > > + > > > > > +static void vfio_ccw_compute_needs_reset(VFIODevice *vdev) > > > > > +{ > > > > > +vdev->needs_reset = false; > > > > > +} > > > > > + > > > > > +/* > > > > > + * We don't need vfio_hot_reset_multi and vfio_eoi operationis for > > > > > > One more: > > > > > > s/operationis/operations/ > > > > > Ok. > > > > Hi Conny, > > I have pulled your cohuck-qemu/s390-next branch, and prepared a new > patch set with all of these problems fixed directly on the coressponding > commits on it. Fine to send out the new version as that? > > Or I should rebase them against the latest master branch? As I currently don't have things in my next branch that should interact with your changes, either is fine :) [I'll take a look at the new version then]
Re: [Qemu-devel] [PATCH v5 07/13] vfio/ccw: vfio based subchannel passthrough driver
* Dong Jia Shi[2017-04-25 13:15:19 +0800]: > * Alex Williamson [2017-04-24 16:56:28 -0600]: > > [...] > > > > diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c > > > > new file mode 100644 > > > > index 000..c491bee > > > > --- /dev/null > > > > +++ b/hw/vfio/ccw.c > > > > @@ -0,0 +1,207 @@ > > > > +/* > > > > + * vfio based subchannel assignment support > > > > + * > > > > + * Copyright 2017 IBM Corp. > > > > + * Author(s): Dong Jia Shi > > > > + *Xiao Feng Ren > > > > + *Pierre Morel > > > > + * > > > > + * This work is licensed under the terms of the GNU GPL, version 2 > > > > or(at > > > > + * your option) any version. See the COPYING file in the top-level > > > > + * directory. > > > > + */ > > > > + > > > > +#include > > > > +#include > > > > + > > > > +#include "qemu/osdep.h" > > > > +#include "qapi/error.h" > > > > +#include "hw/sysbus.h" > > > > +#include "hw/vfio/vfio.h" > > > > +#include "hw/vfio/vfio-common.h" > > > > +#include "hw/s390x/s390-ccw.h" > > > > +#include "hw/s390x/ccw-device.h" > > > > + > > > > +#define TYPE_VFIO_CCW "vfio-ccw" > > > > +typedef struct VFIOCCWDevice { > > > > +S390CCWDevice cdev; > > > > +VFIODevice vdev; > > > > +} VFIOCCWDevice; > > > > + > > > > +static void vfio_ccw_compute_needs_reset(VFIODevice *vdev) > > > > +{ > > > > +vdev->needs_reset = false; > > > > +} > > > > + > > > > +/* > > > > + * We don't need vfio_hot_reset_multi and vfio_eoi operationis for > > > > One more: > > > > s/operationis/operations/ > > > Ok. > Hi Conny, I have pulled your cohuck-qemu/s390-next branch, and prepared a new patch set with all of these problems fixed directly on the coressponding commits on it. Fine to send out the new version as that? Or I should rebase them against the latest master branch? Thanks. [...] -- Dong Jia Shi
Re: [Qemu-devel] [PATCH v5 07/13] vfio/ccw: vfio based subchannel passthrough driver
* Alex Williamson[2017-04-24 16:56:28 -0600]: [...] > > > diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c > > > new file mode 100644 > > > index 000..c491bee > > > --- /dev/null > > > +++ b/hw/vfio/ccw.c > > > @@ -0,0 +1,207 @@ > > > +/* > > > + * vfio based subchannel assignment support > > > + * > > > + * Copyright 2017 IBM Corp. > > > + * Author(s): Dong Jia Shi > > > + *Xiao Feng Ren > > > + *Pierre Morel > > > + * > > > + * This work is licensed under the terms of the GNU GPL, version 2 or(at > > > + * your option) any version. See the COPYING file in the top-level > > > + * directory. > > > + */ > > > + > > > +#include > > > +#include > > > + > > > +#include "qemu/osdep.h" > > > +#include "qapi/error.h" > > > +#include "hw/sysbus.h" > > > +#include "hw/vfio/vfio.h" > > > +#include "hw/vfio/vfio-common.h" > > > +#include "hw/s390x/s390-ccw.h" > > > +#include "hw/s390x/ccw-device.h" > > > + > > > +#define TYPE_VFIO_CCW "vfio-ccw" > > > +typedef struct VFIOCCWDevice { > > > +S390CCWDevice cdev; > > > +VFIODevice vdev; > > > +} VFIOCCWDevice; > > > + > > > +static void vfio_ccw_compute_needs_reset(VFIODevice *vdev) > > > +{ > > > +vdev->needs_reset = false; > > > +} > > > + > > > +/* > > > + * We don't need vfio_hot_reset_multi and vfio_eoi operationis for > > One more: > > s/operationis/operations/ > Ok. > > > + * vfio_ccw device now. > > > + */ > > > +struct VFIODeviceOps vfio_ccw_ops = { > > > +.vfio_compute_needs_reset = vfio_ccw_compute_needs_reset, > > > +}; > > > + > > > +static void vfio_ccw_reset(DeviceState *dev) > > > +{ > > > +CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev); > > > +S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev); > > > +VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev); > > > + > > > +ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET); > > > +} > > > + > > > +static void vfio_put_device(VFIOCCWDevice *vcdev) > > > +{ > > > +g_free(vcdev->vdev.name); > > > +vfio_put_base_device(>vdev); > > > +} > > > + > > > +static VFIOGroup *vfio_ccw_get_group(S390CCWDevice *cdev, char **path, > > > + Error **errp) > > > +{ > > > +struct stat st; > > > +int groupid; > > > +GError *gerror = NULL; > > > + > > > +/* Check that host subchannel exists. */ > > > +path[0] = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x", > > > + cdev->hostid.cssid, > > > + cdev->hostid.ssid, > > > + cdev->hostid.devid); > > > +if (stat(path[0], ) < 0) { > > > +error_setg(errp, "vfio: no such host subchannel %s", path[0]); > > > +return NULL; > > > +} > > > + > > > +/* Check that mediated device exists. */ > > > +path[1] = g_strdup_printf("%s/%s", path[0], cdev->mdevid); > > > +if (stat(path[0], ) < 0) { > > > +error_setg(errp, "vfio: no such mediated device %s", path[1]); > > > +return NULL; > > > +} > > > > Isn't this all a bit circular since we build the S390CCWDevice based on > > the sysfsdev mdev path? > > Right! We don't need to verify the existance of the path here again, since we already did that during the realization of the S390CCWDevice, which is triggered by calling cdc->realize before vfio_ccw_get_group in vfio_ccw_realize. > > > + > > > +/* Get the iommu_group patch as the interim variable. */ > > > +path[2] = g_strconcat(path[1], "/iommu_group", NULL); > > > + > > > +/* Get the link file path of the device iommu_group. */ > > > +path[3] = g_file_read_link(path[2], ); > > > +if (!path[3]) { > > > +error_setg(errp, "vfio: error no iommu_group for subchannel"); > > > +return NULL; > > > +} > > > + > > > +/* Get the device groupid. */ > > > +if (sscanf(basename(path[3]), "%d", ) != 1) { > > > +error_setg(errp, "vfio: error reading %s:%m", path[3]); > > > +return NULL; > > > +} > > > + > > > +return vfio_get_group(groupid, _space_memory, errp); > > > +} > > > + > > > +static void vfio_ccw_put_group(VFIOGroup *group, char **path) > > > +{ > > > +g_free(path); > > > +vfio_put_group(group); > > > +} > > > + > > > +static void vfio_ccw_realize(DeviceState *dev, Error **errp) > > > +{ > > > +VFIODevice *vbasedev; > > > +VFIOGroup *group; > > > +CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev); > > > +S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev); > > > +VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev); > > > +S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev); > > > +char *path[4] = {NULL, NULL, NULL, NULL}; > > > > I don't understand what's happening with 'path' throughout this > > function. vfio_ccw_get_group() allocates strings
Re: [Qemu-devel] [PATCH v5 07/13] vfio/ccw: vfio based subchannel passthrough driver
On Mon, 24 Apr 2017 16:43:38 -0600 Alex Williamsonwrote: > On Wed, 12 Apr 2017 07:21:09 +0200 > Dong Jia Shi wrote: > > > From: Xiao Feng Ren > > > > We use the IOMMU_TYPE1 of VFIO to realize the subchannels > > passthrough, implement a vfio based subchannels passthrough > > driver called "vfio-ccw". > > > > Support qemu parameters in the style of: > > "-device vfio-ccw,sysfsdev=$mdev_file_path,devno=xx.x.' > > > > Signed-off-by: Xiao Feng Ren > > Signed-off-by: Dong Jia Shi > > --- > > default-configs/s390x-softmmu.mak | 1 + > > hw/vfio/Makefile.objs | 1 + > > hw/vfio/ccw.c | 207 > > ++ > > include/hw/vfio/vfio-common.h | 1 + > > 4 files changed, 210 insertions(+) > > create mode 100644 hw/vfio/ccw.c > > > > diff --git a/default-configs/s390x-softmmu.mak > > b/default-configs/s390x-softmmu.mak > > index 36e15de..5576b0a 100644 > > --- a/default-configs/s390x-softmmu.mak > > +++ b/default-configs/s390x-softmmu.mak > > @@ -4,4 +4,5 @@ CONFIG_VIRTIO=y > > CONFIG_SCLPCONSOLE=y > > CONFIG_S390_FLIC=y > > CONFIG_S390_FLIC_KVM=$(CONFIG_KVM) > > +CONFIG_VFIO_CCW=$(CONFIG_LINUX) > > CONFIG_WDT_DIAG288=y > > diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs > > index 05e7fbb..c3ab909 100644 > > --- a/hw/vfio/Makefile.objs > > +++ b/hw/vfio/Makefile.objs > > @@ -1,6 +1,7 @@ > > ifeq ($(CONFIG_LINUX), y) > > obj-$(CONFIG_SOFTMMU) += common.o > > obj-$(CONFIG_PCI) += pci.o pci-quirks.o > > +obj-$(CONFIG_VFIO_CCW) += ccw.o > > obj-$(CONFIG_SOFTMMU) += platform.o > > obj-$(CONFIG_VFIO_XGMAC) += calxeda-xgmac.o > > obj-$(CONFIG_VFIO_AMD_XGBE) += amd-xgbe.o > > diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c > > new file mode 100644 > > index 000..c491bee > > --- /dev/null > > +++ b/hw/vfio/ccw.c > > @@ -0,0 +1,207 @@ > > +/* > > + * vfio based subchannel assignment support > > + * > > + * Copyright 2017 IBM Corp. > > + * Author(s): Dong Jia Shi > > + *Xiao Feng Ren > > + *Pierre Morel > > + * > > + * This work is licensed under the terms of the GNU GPL, version 2 or(at > > + * your option) any version. See the COPYING file in the top-level > > + * directory. > > + */ > > + > > +#include > > +#include > > + > > +#include "qemu/osdep.h" > > +#include "qapi/error.h" > > +#include "hw/sysbus.h" > > +#include "hw/vfio/vfio.h" > > +#include "hw/vfio/vfio-common.h" > > +#include "hw/s390x/s390-ccw.h" > > +#include "hw/s390x/ccw-device.h" > > + > > +#define TYPE_VFIO_CCW "vfio-ccw" > > +typedef struct VFIOCCWDevice { > > +S390CCWDevice cdev; > > +VFIODevice vdev; > > +} VFIOCCWDevice; > > + > > +static void vfio_ccw_compute_needs_reset(VFIODevice *vdev) > > +{ > > +vdev->needs_reset = false; > > +} > > + > > +/* > > + * We don't need vfio_hot_reset_multi and vfio_eoi operationis for One more: s/operationis/operations/ > > + * vfio_ccw device now. > > + */ > > +struct VFIODeviceOps vfio_ccw_ops = { > > +.vfio_compute_needs_reset = vfio_ccw_compute_needs_reset, > > +}; > > + > > +static void vfio_ccw_reset(DeviceState *dev) > > +{ > > +CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev); > > +S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev); > > +VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev); > > + > > +ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET); > > +} > > + > > +static void vfio_put_device(VFIOCCWDevice *vcdev) > > +{ > > +g_free(vcdev->vdev.name); > > +vfio_put_base_device(>vdev); > > +} > > + > > +static VFIOGroup *vfio_ccw_get_group(S390CCWDevice *cdev, char **path, > > + Error **errp) > > +{ > > +struct stat st; > > +int groupid; > > +GError *gerror = NULL; > > + > > +/* Check that host subchannel exists. */ > > +path[0] = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x", > > + cdev->hostid.cssid, > > + cdev->hostid.ssid, > > + cdev->hostid.devid); > > +if (stat(path[0], ) < 0) { > > +error_setg(errp, "vfio: no such host subchannel %s", path[0]); > > +return NULL; > > +} > > + > > +/* Check that mediated device exists. */ > > +path[1] = g_strdup_printf("%s/%s", path[0], cdev->mdevid); > > +if (stat(path[0], ) < 0) { > > +error_setg(errp, "vfio: no such mediated device %s", path[1]); > > +return NULL; > > +} > > Isn't this all a bit circular since we build the S390CCWDevice based on > the sysfsdev mdev path? > > > + > > +/* Get the iommu_group patch as the interim variable. */ > > +path[2] = g_strconcat(path[1], "/iommu_group", NULL); > > + > > +/* Get the link
Re: [Qemu-devel] [PATCH v5 07/13] vfio/ccw: vfio based subchannel passthrough driver
On Wed, 12 Apr 2017 07:21:09 +0200 Dong Jia Shiwrote: > From: Xiao Feng Ren > > We use the IOMMU_TYPE1 of VFIO to realize the subchannels > passthrough, implement a vfio based subchannels passthrough > driver called "vfio-ccw". > > Support qemu parameters in the style of: > "-device vfio-ccw,sysfsdev=$mdev_file_path,devno=xx.x.' > > Signed-off-by: Xiao Feng Ren > Signed-off-by: Dong Jia Shi > --- > default-configs/s390x-softmmu.mak | 1 + > hw/vfio/Makefile.objs | 1 + > hw/vfio/ccw.c | 207 > ++ > include/hw/vfio/vfio-common.h | 1 + > 4 files changed, 210 insertions(+) > create mode 100644 hw/vfio/ccw.c > > diff --git a/default-configs/s390x-softmmu.mak > b/default-configs/s390x-softmmu.mak > index 36e15de..5576b0a 100644 > --- a/default-configs/s390x-softmmu.mak > +++ b/default-configs/s390x-softmmu.mak > @@ -4,4 +4,5 @@ CONFIG_VIRTIO=y > CONFIG_SCLPCONSOLE=y > CONFIG_S390_FLIC=y > CONFIG_S390_FLIC_KVM=$(CONFIG_KVM) > +CONFIG_VFIO_CCW=$(CONFIG_LINUX) > CONFIG_WDT_DIAG288=y > diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs > index 05e7fbb..c3ab909 100644 > --- a/hw/vfio/Makefile.objs > +++ b/hw/vfio/Makefile.objs > @@ -1,6 +1,7 @@ > ifeq ($(CONFIG_LINUX), y) > obj-$(CONFIG_SOFTMMU) += common.o > obj-$(CONFIG_PCI) += pci.o pci-quirks.o > +obj-$(CONFIG_VFIO_CCW) += ccw.o > obj-$(CONFIG_SOFTMMU) += platform.o > obj-$(CONFIG_VFIO_XGMAC) += calxeda-xgmac.o > obj-$(CONFIG_VFIO_AMD_XGBE) += amd-xgbe.o > diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c > new file mode 100644 > index 000..c491bee > --- /dev/null > +++ b/hw/vfio/ccw.c > @@ -0,0 +1,207 @@ > +/* > + * vfio based subchannel assignment support > + * > + * Copyright 2017 IBM Corp. > + * Author(s): Dong Jia Shi > + *Xiao Feng Ren > + *Pierre Morel > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or(at > + * your option) any version. See the COPYING file in the top-level > + * directory. > + */ > + > +#include > +#include > + > +#include "qemu/osdep.h" > +#include "qapi/error.h" > +#include "hw/sysbus.h" > +#include "hw/vfio/vfio.h" > +#include "hw/vfio/vfio-common.h" > +#include "hw/s390x/s390-ccw.h" > +#include "hw/s390x/ccw-device.h" > + > +#define TYPE_VFIO_CCW "vfio-ccw" > +typedef struct VFIOCCWDevice { > +S390CCWDevice cdev; > +VFIODevice vdev; > +} VFIOCCWDevice; > + > +static void vfio_ccw_compute_needs_reset(VFIODevice *vdev) > +{ > +vdev->needs_reset = false; > +} > + > +/* > + * We don't need vfio_hot_reset_multi and vfio_eoi operationis for > + * vfio_ccw device now. > + */ > +struct VFIODeviceOps vfio_ccw_ops = { > +.vfio_compute_needs_reset = vfio_ccw_compute_needs_reset, > +}; > + > +static void vfio_ccw_reset(DeviceState *dev) > +{ > +CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev); > +S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev); > +VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev); > + > +ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET); > +} > + > +static void vfio_put_device(VFIOCCWDevice *vcdev) > +{ > +g_free(vcdev->vdev.name); > +vfio_put_base_device(>vdev); > +} > + > +static VFIOGroup *vfio_ccw_get_group(S390CCWDevice *cdev, char **path, > + Error **errp) > +{ > +struct stat st; > +int groupid; > +GError *gerror = NULL; > + > +/* Check that host subchannel exists. */ > +path[0] = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x", > + cdev->hostid.cssid, > + cdev->hostid.ssid, > + cdev->hostid.devid); > +if (stat(path[0], ) < 0) { > +error_setg(errp, "vfio: no such host subchannel %s", path[0]); > +return NULL; > +} > + > +/* Check that mediated device exists. */ > +path[1] = g_strdup_printf("%s/%s", path[0], cdev->mdevid); > +if (stat(path[0], ) < 0) { > +error_setg(errp, "vfio: no such mediated device %s", path[1]); > +return NULL; > +} Isn't this all a bit circular since we build the S390CCWDevice based on the sysfsdev mdev path? > + > +/* Get the iommu_group patch as the interim variable. */ > +path[2] = g_strconcat(path[1], "/iommu_group", NULL); > + > +/* Get the link file path of the device iommu_group. */ > +path[3] = g_file_read_link(path[2], ); > +if (!path[3]) { > +error_setg(errp, "vfio: error no iommu_group for subchannel"); > +return NULL; > +} > + > +/* Get the device groupid. */ > +if (sscanf(basename(path[3]), "%d", ) != 1) { > +error_setg(errp, "vfio: error reading %s:%m", path[3]); > +return NULL; > +} > +