From: Eric Auger <eric.auger@redhat.com>
To: "Duan, Zhenzhong" <zhenzhong.duan@intel.com>,
"eric.auger.pro@gmail.com" <eric.auger.pro@gmail.com>,
"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
"alex.williamson@redhat.com" <alex.williamson@redhat.com>,
"clg@redhat.com" <clg@redhat.com>,
"jgg@nvidia.com" <jgg@nvidia.com>,
"nicolinc@nvidia.com" <nicolinc@nvidia.com>,
"Martins, Joao" <joao.m.martins@oracle.com>,
"peterx@redhat.com" <peterx@redhat.com>,
"Tian, Kevin" <kevin.tian@intel.com>,
"Liu, Yi L" <yi.l.liu@intel.com>,
"Sun, Yi Y" <yi.y.sun@intel.com>,
"Peng, Chao P" <chao.p.peng@intel.com>,
"mjrosato@linux.ibm.com" <mjrosato@linux.ibm.com>,
"aik@ozlabs.ru" <aik@ozlabs.ru>
Subject: Re: [PATCH v5 07/15] vfio/pci: Introduce vfio_[attach/detach]_device
Date: Wed, 11 Oct 2023 22:11:41 +0200 [thread overview]
Message-ID: <f6ee408c-e012-903a-158a-94d1a0de74b0@redhat.com> (raw)
In-Reply-To: <PH7PR11MB6722220A69C973A55006558292CCA@PH7PR11MB6722.namprd11.prod.outlook.com>
Hi Zhenzhong,
On 10/11/23 03:33, Duan, Zhenzhong wrote:
> Hi Eric,
>
>> -----Original Message-----
>> From: Eric Auger <eric.auger@redhat.com>
>> Sent: Monday, October 9, 2023 5:09 PM
>> Subject: [PATCH v5 07/15] vfio/pci: Introduce vfio_[attach/detach]_device
>>
>> We want the VFIO devices to be able to use two different
>> IOMMU backends, the legacy VFIO one and the new iommufd one.
>>
>> Introduce vfio_[attach/detach]_device which aim at hiding the
>> underlying IOMMU backend (IOCTLs, datatypes, ...).
>>
>> Once vfio_attach_device completes, the device is attached
>> to a security context and its fd can be used. Conversely
>> When vfio_detach_device completes, the device has been
>> detached from the security context.
>>
>> At the moment only the implementation based on the legacy
>> container/group exists. Let's use it from the vfio-pci device.
>> Subsequent patches will handle other devices.
>>
>> We also take benefit of this patch to properly free
>> vbasedev->name on failure.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Yi Liu <yi.l.liu@intel.com>
>> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
>> Reviewed-by: Cédric Le Goater <clg@redhat.com>
>>
>> ---
>>
>> v4 -> v5:
>> - remove vbasedev->name g_free as it is done on instance_finalize
>>
>> v2 -> v3:
>> - added trace_vfio_detach_device
>> - added a comment explaining why we pass @name to vfio_attach_device
>> although vbasedev->name is populated
>> - free vbasedev->name and detach_device if needed
>> ---
>> include/hw/vfio/vfio-common.h | 3 ++
>> hw/vfio/common.c | 74 +++++++++++++++++++++++++++++++++++
>> hw/vfio/pci.c | 66 +++++++------------------------
>> hw/vfio/trace-events | 3 +-
>> 4 files changed, 93 insertions(+), 53 deletions(-)
>>
>> diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
>> index c4e7c3b4a7..12fbfbc37d 100644
>> --- a/include/hw/vfio/vfio-common.h
>> +++ b/include/hw/vfio/vfio-common.h
>> @@ -225,6 +225,9 @@ void vfio_put_group(VFIOGroup *group);
>> struct vfio_device_info *vfio_get_device_info(int fd);
>> int vfio_get_device(VFIOGroup *group, const char *name,
>> VFIODevice *vbasedev, Error **errp);
>> +int vfio_attach_device(char *name, VFIODevice *vbasedev,
>> + AddressSpace *as, Error **errp);
>> +void vfio_detach_device(VFIODevice *vbasedev);
>>
>> int vfio_kvm_device_add_fd(int fd, Error **errp);
>> int vfio_kvm_device_del_fd(int fd, Error **errp);
>> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
>> index d8ed432cb6..f4c33c9858 100644
>> --- a/hw/vfio/common.c
>> +++ b/hw/vfio/common.c
>> @@ -2611,3 +2611,77 @@ int vfio_eeh_as_op(AddressSpace *as, uint32_t op)
>> }
>> return vfio_eeh_container_op(container, op);
>> }
>> +
>> +static int vfio_device_groupid(VFIODevice *vbasedev, Error **errp)
>> +{
>> + char *tmp, group_path[PATH_MAX], *group_name;
>> + int ret, groupid;
>> + ssize_t len;
>> +
>> + tmp = g_strdup_printf("%s/iommu_group", vbasedev->sysfsdev);
>> + len = readlink(tmp, group_path, sizeof(group_path));
>> + g_free(tmp);
>> +
>> + if (len <= 0 || len >= sizeof(group_path)) {
>> + ret = len < 0 ? -errno : -ENAMETOOLONG;
>> + error_setg_errno(errp, -ret, "no iommu_group found");
>> + return ret;
>> + }
>> +
>> + group_path[len] = 0;
>> +
>> + group_name = basename(group_path);
>> + if (sscanf(group_name, "%d", &groupid) != 1) {
>> + error_setg_errno(errp, errno, "failed to read %s", group_path);
>> + return -errno;
>> + }
>> + return groupid;
>> +}
>> +
>> +/*
>> + * vfio_attach_device: attach a device to a security context
>> + * @name and @vbasedev->name are likely to be different depending
>> + * on the type of the device, hence the need for passing @name
>> + */
>> +int vfio_attach_device(char *name, VFIODevice *vbasedev,
>> + AddressSpace *as, Error **errp)
>> +{
>> + int groupid = vfio_device_groupid(vbasedev, errp);
>> + VFIODevice *vbasedev_iter;
>> + VFIOGroup *group;
>> + int ret;
>> +
>> + if (groupid < 0) {
>> + return groupid;
>> + }
>> +
>> + trace_vfio_attach_device(vbasedev->name, groupid);
>> +
>> + group = vfio_get_group(groupid, as, errp);
>> + if (!group) {
>> + return -ENOENT;
>> + }
>> +
>> + QLIST_FOREACH(vbasedev_iter, &group->device_list, next) {
>> + if (strcmp(vbasedev_iter->name, vbasedev->name) == 0) {
>> + error_setg(errp, "device is already attached");
>> + vfio_put_group(group);
>> + return -EBUSY;
>> + }
>> + }
>> + ret = vfio_get_device(group, name, vbasedev, errp);
>> + if (ret) {
>> + vfio_put_group(group);
>> + }
>> +
>> + return ret;
>> +}
>> +
>> +void vfio_detach_device(VFIODevice *vbasedev)
>> +{
>> + VFIOGroup *group = vbasedev->group;
>> +
>> + trace_vfio_detach_device(vbasedev->name, group->groupid);
>> + vfio_put_base_device(vbasedev);
>> + vfio_put_group(group);
>> +}
>> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
>> index 898296fd54..40ae46266e 100644
>> --- a/hw/vfio/pci.c
>> +++ b/hw/vfio/pci.c
>> @@ -2895,10 +2895,10 @@ static void vfio_populate_device(VFIOPCIDevice
>> *vdev, Error **errp)
>>
>> static void vfio_pci_put_device(VFIOPCIDevice *vdev)
>> {
>> + vfio_detach_device(&vdev->vbasedev);
>> +
>> g_free(vdev->vbasedev.name);
>> g_free(vdev->msix);
>> -
>> - vfio_put_base_device(&vdev->vbasedev);
>> }
>>
>> static void vfio_err_notifier_handler(void *opaque)
>> @@ -3045,13 +3045,9 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
>> {
>> VFIOPCIDevice *vdev = VFIO_PCI(pdev);
>> VFIODevice *vbasedev = &vdev->vbasedev;
>> - VFIODevice *vbasedev_iter;
>> - VFIOGroup *group;
>> - char *tmp, *subsys, group_path[PATH_MAX], *group_name;
>> + char *tmp, *subsys;
>> Error *err = NULL;
>> - ssize_t len;
>> struct stat st;
>> - int groupid;
>> int i, ret;
>> bool is_mdev;
>> char uuid[UUID_FMT_LEN];
>> @@ -3082,39 +3078,6 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
>> vbasedev->type = VFIO_DEVICE_TYPE_PCI;
>> vbasedev->dev = DEVICE(vdev);
>>
>> - tmp = g_strdup_printf("%s/iommu_group", vbasedev->sysfsdev);
>> - len = readlink(tmp, group_path, sizeof(group_path));
>> - g_free(tmp);
>> -
>> - if (len <= 0 || len >= sizeof(group_path)) {
>> - error_setg_errno(errp, len < 0 ? errno : ENAMETOOLONG,
>> - "no iommu_group found");
>> - goto error;
>> - }
>> -
>> - group_path[len] = 0;
>> -
>> - group_name = basename(group_path);
>> - if (sscanf(group_name, "%d", &groupid) != 1) {
>> - error_setg_errno(errp, errno, "failed to read %s", group_path);
>> - goto error;
>> - }
>> -
>> - trace_vfio_realize(vbasedev->name, groupid);
>> -
>> - group = vfio_get_group(groupid, pci_device_iommu_address_space(pdev),
>> errp);
>> - if (!group) {
>> - goto error;
>> - }
>> -
>> - QLIST_FOREACH(vbasedev_iter, &group->device_list, next) {
>> - if (strcmp(vbasedev_iter->name, vbasedev->name) == 0) {
>> - error_setg(errp, "device is already attached");
>> - vfio_put_group(group);
>> - goto error;
>> - }
>> - }
>> -
>> /*
>> * Mediated devices *might* operate compatibly with discarding of RAM, but
>> * we cannot know for certain, it depends on whether the mdev vendor driver
>> @@ -3132,7 +3095,6 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
>> if (vbasedev->ram_block_discard_allowed && !is_mdev) {
>> error_setg(errp, "x-balloon-allowed only potentially compatible "
>> "with mdev devices");
>> - vfio_put_group(group);
>> goto error;
>> }
>>
>> @@ -3143,17 +3105,17 @@ static void vfio_realize(PCIDevice *pdev, Error
>> **errp)
>> name = g_strdup(vbasedev->name);
>> }
>>
>> - ret = vfio_get_device(group, name, vbasedev, errp);
>> + ret = vfio_attach_device(name, vbasedev,
>> + pci_device_iommu_address_space(pdev), errp);
>> g_free(name);
>> if (ret) {
>> - vfio_put_group(group);
>> goto error;
>> }
>>
>> vfio_populate_device(vdev, &err);
>> if (err) {
>> error_propagate(errp, err);
>> - goto error;
>> + goto out_detach;
>> }
>>
>> /* Get a copy of config space */
>> @@ -3163,7 +3125,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
>> if (ret < (int)MIN(pci_config_size(&vdev->pdev), vdev->config_size)) {
>> ret = ret < 0 ? -errno : -EFAULT;
>> error_setg_errno(errp, -ret, "failed to read device config space");
>> - goto error;
>> + goto out_detach;
>> }
>>
>> /* vfio emulates a lot for us, but some bits need extra love */
>> @@ -3182,7 +3144,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
>> if (vdev->vendor_id != PCI_ANY_ID) {
>> if (vdev->vendor_id >= 0xffff) {
>> error_setg(errp, "invalid PCI vendor ID provided");
>> - goto error;
>> + goto out_detach;
>> }
>> vfio_add_emulated_word(vdev, PCI_VENDOR_ID, vdev->vendor_id, ~0);
>> trace_vfio_pci_emulated_vendor_id(vbasedev->name, vdev->vendor_id);
>> @@ -3193,7 +3155,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
>> if (vdev->device_id != PCI_ANY_ID) {
>> if (vdev->device_id > 0xffff) {
>> error_setg(errp, "invalid PCI device ID provided");
>> - goto error;
>> + goto out_detach;
>> }
>> vfio_add_emulated_word(vdev, PCI_DEVICE_ID, vdev->device_id, ~0);
>> trace_vfio_pci_emulated_device_id(vbasedev->name, vdev->device_id);
>> @@ -3204,7 +3166,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
>> if (vdev->sub_vendor_id != PCI_ANY_ID) {
>> if (vdev->sub_vendor_id > 0xffff) {
>> error_setg(errp, "invalid PCI subsystem vendor ID provided");
>> - goto error;
>> + goto out_detach;
>> }
>> vfio_add_emulated_word(vdev, PCI_SUBSYSTEM_VENDOR_ID,
>> vdev->sub_vendor_id, ~0);
>> @@ -3215,7 +3177,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
>> if (vdev->sub_device_id != PCI_ANY_ID) {
>> if (vdev->sub_device_id > 0xffff) {
>> error_setg(errp, "invalid PCI subsystem device ID provided");
>> - goto error;
>> + goto out_detach;
>> }
>> vfio_add_emulated_word(vdev, PCI_SUBSYSTEM_ID, vdev->sub_device_id,
>> ~0);
>> trace_vfio_pci_emulated_sub_device_id(vbasedev->name,
>> @@ -3248,7 +3210,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
>> vfio_msix_early_setup(vdev, &err);
>> if (err) {
>> error_propagate(errp, err);
>> - goto error;
>> + goto out_detach;
>> }
>>
>> vfio_bars_register(vdev);
>> @@ -3364,6 +3326,8 @@ out_deregister:
>> out_teardown:
>> vfio_teardown_msi(vdev);
>> vfio_bars_exit(vdev);
>> +out_detach:
>> + vfio_detach_device(vbasedev);
> I just reproduced a regression here with hot-unplug:
>
> (qemu) device_add vfio-pci,host=81:11.0,id=vfio0,bus=root0
> vfio: error disconnecting group 447 from container
> Error: vfio 0000:81:11.0: does not support requested IGD OpRegion feature
>
> Reason is there are some resources only released in finalize(),
> so UNSET_CONTAINER call fails here.
> IMHO, we can drop this vfio_detach_device call and let the same call in
> finalize() do the real work as original.
>
> After fix:
> (qemu) device_add vfio-pci,host=81:11.0,id=vfio0,bus=root0
> Error: vfio 0000:81:11.0: does not support requested IGD OpRegion feature
I just sent
[PATCH] vfio/pci: Remove vfio_detach_device from vfio_realize error path
Please have a check and confirm this is the fix you expected
Thanks!
Eric
>
> Thanks
> Zhenzhong
>> error:
>> error_prepend(errp, VFIO_MSG_PREFIX, vbasedev->name);
>> }
>> @@ -3371,7 +3335,6 @@ error:
>> static void vfio_instance_finalize(Object *obj)
>> {
>> VFIOPCIDevice *vdev = VFIO_PCI(obj);
>> - VFIOGroup *group = vdev->vbasedev.group;
>>
>> vfio_display_finalize(vdev);
>> vfio_bars_finalize(vdev);
>> @@ -3385,7 +3348,6 @@ static void vfio_instance_finalize(Object *obj)
>> * g_free(vdev->igd_opregion);
>> */
>> vfio_pci_put_device(vdev);
>> - vfio_put_group(group);
>> }
>>
>> static void vfio_exitfn(PCIDevice *pdev)
>> diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
>> index 0ba3c5a0e2..8ac13eb106 100644
>> --- a/hw/vfio/trace-events
>> +++ b/hw/vfio/trace-events
>> @@ -37,7 +37,8 @@ vfio_pci_hot_reset_dep_devices(int domain, int bus, int slot,
>> int function, int
>> vfio_pci_hot_reset_result(const char *name, const char *result) "%s hot
>> reset: %s"
>> vfio_populate_device_config(const char *name, unsigned long size, unsigned
>> long offset, unsigned long flags) "Device %s config:\n size: 0x%lx, offset: 0x%lx,
>> flags: 0x%lx"
>> vfio_populate_device_get_irq_info_failure(const char *errstr)
>> "VFIO_DEVICE_GET_IRQ_INFO failure: %s"
>> -vfio_realize(const char *name, int group_id) " (%s) group %d"
>> +vfio_attach_device(const char *name, int group_id) " (%s) group %d"
>> +vfio_detach_device(const char *name, int group_id) " (%s) group %d"
>> vfio_mdev(const char *name, bool is_mdev) " (%s) is_mdev %d"
>> vfio_add_ext_cap_dropped(const char *name, uint16_t cap, uint16_t offset) "%s
>> 0x%x@0x%x"
>> vfio_pci_reset(const char *name) " (%s)"
>> --
>> 2.41.0
next prev parent reply other threads:[~2023-10-11 20:12 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-09 9:09 [PATCH v5 00/15] Prerequisite changes for IOMMUFD support Eric Auger
2023-10-09 9:09 ` [PATCH v5 01/15] scripts/update-linux-headers: Add iommufd.h Eric Auger
2023-10-09 9:09 ` [PATCH v5 02/15] linux-headers: " Eric Auger
2023-10-09 9:09 ` [PATCH v5 03/15] vfio/common: Move IOMMU agnostic helpers to a separate file Eric Auger
2023-10-09 9:09 ` [PATCH v5 04/15] vfio/common: Propagate KVM_SET_DEVICE_ATTR error if any Eric Auger
2023-10-09 9:09 ` [PATCH v5 05/15] vfio/common: Introduce vfio_container_add|del_section_window() Eric Auger
2023-10-09 9:09 ` [PATCH v5 06/15] vfio/common: Extract out vfio_kvm_device_[add/del]_fd Eric Auger
2023-10-09 9:09 ` [PATCH v5 07/15] vfio/pci: Introduce vfio_[attach/detach]_device Eric Auger
2023-10-11 1:33 ` Duan, Zhenzhong
2023-10-11 20:11 ` Eric Auger [this message]
2023-10-09 9:09 ` [PATCH v5 08/15] vfio/platform: Use vfio_[attach/detach]_device Eric Auger
2023-10-09 9:09 ` [PATCH v5 09/15] vfio/ap: " Eric Auger
2023-10-09 9:09 ` [PATCH v5 10/15] vfio/ccw: " Eric Auger
2023-10-09 9:09 ` [PATCH v5 11/15] vfio/common: Move VFIO reset handler registration to a group agnostic function Eric Auger
2023-10-09 9:09 ` [PATCH v5 12/15] vfio/common: Introduce a per container device list Eric Auger
2023-10-09 9:09 ` [PATCH v5 13/15] vfio/common: Store the parent container in VFIODevice Eric Auger
2023-10-09 9:09 ` [PATCH v5 14/15] vfio/common: Introduce a global VFIODevice list Eric Auger
2023-10-09 9:09 ` [PATCH v5 15/15] vfio/common: Move legacy VFIO backend code into separate container.c Eric Auger
2023-10-09 12:58 ` [PATCH v5 00/15] Prerequisite changes for IOMMUFD support Cédric Le Goater
2023-10-09 13:38 ` Eric Auger
2023-10-09 13:53 ` Cédric Le Goater
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f6ee408c-e012-903a-158a-94d1a0de74b0@redhat.com \
--to=eric.auger@redhat.com \
--cc=aik@ozlabs.ru \
--cc=alex.williamson@redhat.com \
--cc=chao.p.peng@intel.com \
--cc=clg@redhat.com \
--cc=eric.auger.pro@gmail.com \
--cc=jgg@nvidia.com \
--cc=joao.m.martins@oracle.com \
--cc=kevin.tian@intel.com \
--cc=mjrosato@linux.ibm.com \
--cc=nicolinc@nvidia.com \
--cc=peterx@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=yi.l.liu@intel.com \
--cc=yi.y.sun@intel.com \
--cc=zhenzhong.duan@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.