[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [PATCH v4 28/41] vfio/iommufd: Implement the iommufd backend
From: |
Duan, Zhenzhong |
Subject: |
RE: [PATCH v4 28/41] vfio/iommufd: Implement the iommufd backend |
Date: |
Wed, 8 Nov 2023 05:45:29 +0000 |
>-----Original Message-----
>From: Cédric Le Goater <clg@redhat.com>
>Sent: Tuesday, November 7, 2023 9:41 PM
>Subject: Re: [PATCH v4 28/41] vfio/iommufd: Implement the iommufd backend
>
>On 11/2/23 08:12, Zhenzhong Duan wrote:
>> From: Yi Liu <yi.l.liu@intel.com>
>>
>> Add the iommufd backend. The IOMMUFD container class is implemented
>> based on the new /dev/iommu user API. This backend obviously depends
>> on CONFIG_IOMMUFD.
>>
>> So far, the iommufd backend doesn't support dirty page sync yet due
>> to missing support in the host kernel.
>>
>> Co-authored-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>
>I think one tag for Eric is enough.
>
>> Signed-off-by: Yi Liu <yi.l.liu@intel.com>
>> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
>> ---
>> v4: use SPDX identifier, use iommufd_cdev_* prefix, merge with manual alloc
>patch
>>
>> include/hw/vfio/vfio-common.h | 23 ++
>> hw/vfio/common.c | 19 +-
>> hw/vfio/iommufd.c | 504 ++++++++++++++++++++++++++++++++++
>> hw/vfio/meson.build | 3 +
>> hw/vfio/trace-events | 13 +
>> 5 files changed, 558 insertions(+), 4 deletions(-)
>> create mode 100644 hw/vfio/iommufd.c
>>
>> diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
>> index 24ecc0e7ee..3f1a39a991 100644
>> --- a/include/hw/vfio/vfio-common.h
>> +++ b/include/hw/vfio/vfio-common.h
>> @@ -89,6 +89,23 @@ typedef struct VFIOHostDMAWindow {
>> QLIST_ENTRY(VFIOHostDMAWindow) hostwin_next;
>> } VFIOHostDMAWindow;
>>
>> +#ifdef CONFIG_IOMMUFD
>
>Please remove the #ifdef.
Will do.
>
>> +typedef struct VFIOIOASHwpt {
>> + uint32_t hwpt_id;
>> + QLIST_HEAD(, VFIODevice) device_list;
>> + QLIST_ENTRY(VFIOIOASHwpt) next;
>> +} VFIOIOASHwpt;
>> +
>> +typedef struct IOMMUFDBackend IOMMUFDBackend;
>> +
>> +typedef struct VFIOIOMMUFDContainer {
>> + VFIOContainerBase bcontainer;
>> + IOMMUFDBackend *be;
>> + uint32_t ioas_id;
>> + QLIST_HEAD(, VFIOIOASHwpt) hwpt_list;
>> +} VFIOIOMMUFDContainer;
>> +#endif
>> +
>> typedef struct VFIODeviceOps VFIODeviceOps;
>>
>> typedef struct VFIODevice {
>> @@ -116,6 +133,11 @@ typedef struct VFIODevice {
>> OnOffAuto pre_copy_dirty_page_tracking;
>> bool dirty_pages_supported;
>> bool dirty_tracking;
>> +#ifdef CONFIG_IOMMUFD
>> + int devid;
>> + VFIOIOASHwpt *hwpt;
>> + IOMMUFDBackend *iommufd;
>> +#endif
>> } VFIODevice;
>>
>> struct VFIODeviceOps {
>> @@ -201,6 +223,7 @@ typedef QLIST_HEAD(VFIODeviceList, VFIODevice)
>VFIODeviceList;
>> extern VFIOGroupList vfio_group_list;
>> extern VFIODeviceList vfio_device_list;
>> extern const VFIOIOMMUOps vfio_legacy_ops;
>> +extern const VFIOIOMMUOps vfio_iommufd_ops;
>> extern const MemoryListener vfio_memory_listener;
>> extern int vfio_kvm_device_fd;
>>
>> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
>> index 572ae7c934..a61dce2845 100644
>> --- a/hw/vfio/common.c
>> +++ b/hw/vfio/common.c
>> @@ -1462,10 +1462,13 @@ VFIOAddressSpace
>*vfio_get_address_space(AddressSpace *as)
>>
>> void vfio_put_address_space(VFIOAddressSpace *space)
>> {
>> - if (QLIST_EMPTY(&space->containers)) {
>> - QLIST_REMOVE(space, list);
>> - g_free(space);
>> + if (!QLIST_EMPTY(&space->containers)) {
>> + return;
>> }
>> +
>> + QLIST_REMOVE(space, list);
>> + g_free(space);
>> +
>> if (QLIST_EMPTY(&vfio_address_spaces)) {
>> qemu_unregister_reset(vfio_reset_handler, NULL);
>> }
>> @@ -1498,8 +1501,16 @@ retry:
>> int vfio_attach_device(char *name, VFIODevice *vbasedev,
>> AddressSpace *as, Error **errp)
>> {
>> - const VFIOIOMMUOps *ops = &vfio_legacy_ops;
>> + const VFIOIOMMUOps *ops;
>>
>> +#ifdef CONFIG_IOMMUFD
>
>You can keep this one though.
Will do.
>
>> + if (vbasedev->iommufd) {
>> + ops = &vfio_iommufd_ops;
>> + } else
>> +#endif
>> + {
>> + ops = &vfio_legacy_ops;
>> + }
>> return ops->attach_device(name, vbasedev, as, errp);
>> }
>>
>> diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
>> new file mode 100644
>> index 0000000000..1bb55ca2c4
>> --- /dev/null
>> +++ b/hw/vfio/iommufd.c
>> @@ -0,0 +1,504 @@
>> +/*
>> + * iommufd container backend
>> + *
>> + * Copyright (C) 2023 Intel Corporation.
>> + * Copyright Red Hat, Inc. 2023
>> + *
>> + * Authors: Yi Liu <yi.l.liu@intel.com>
>> + * Eric Auger <eric.auger@redhat.com>
>> + *
>> + * SPDX-License-Identifier: GPL-2.0-or-later
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include <sys/ioctl.h>
>> +#include <linux/vfio.h>
>> +#include <linux/iommufd.h>
>> +
>> +#include "hw/vfio/vfio-common.h"
>> +#include "qemu/error-report.h"
>> +#include "trace.h"
>> +#include "qapi/error.h"
>> +#include "sysemu/iommufd.h"
>> +#include "hw/qdev-core.h"
>> +#include "sysemu/reset.h"
>> +#include "qemu/cutils.h"
>> +#include "qemu/chardev_open.h"
>> +
>> +static int iommufd_map(VFIOContainerBase *bcontainer, hwaddr iova,
>> + ram_addr_t size, void *vaddr, bool readonly)
>> +{
>> + VFIOIOMMUFDContainer *container =
>> + container_of(bcontainer, VFIOIOMMUFDContainer, bcontainer);
>> +
>> + return iommufd_backend_map_dma(container->be,
>> + container->ioas_id,
>> + iova, size, vaddr, readonly);
>> +}
>> +
>> +static int iommufd_unmap(VFIOContainerBase *bcontainer,
>> + hwaddr iova, ram_addr_t size,
>> + IOMMUTLBEntry *iotlb)
>> +{
>> + VFIOIOMMUFDContainer *container =
>> + container_of(bcontainer, VFIOIOMMUFDContainer, bcontainer);
>> +
>> + /* TODO: Handle dma_unmap_bitmap with iotlb args (migration) */
>> + return iommufd_backend_unmap_dma(container->be,
>> + container->ioas_id, iova, size);
>> +}
>> +
>> +static void iommufd_cdev_kvm_device_add(VFIODevice *vbasedev)
>> +{
>> + Error *err = NULL;
>> +
>> + if (vfio_kvm_device_add_fd(vbasedev->fd, &err)) {
>> + error_report_err(err);
>> + }
>> +}
>> +
>> +static void iommufd_cdev_kvm_device_del(VFIODevice *vbasedev)
>> +{
>> + Error *err = NULL;
>> +
>> + if (vfio_kvm_device_del_fd(vbasedev->fd, &err)) {
>> + error_report_err(err);
>> + }
>> +}
>> +
>> +static int iommufd_connect_and_bind(VFIODevice *vbasedev, Error **errp)
>> +{
>> + IOMMUFDBackend *iommufd = vbasedev->iommufd;
>> + struct vfio_device_bind_iommufd bind = {
>> + .argsz = sizeof(bind),
>> + .flags = 0,
>> + };
>> + int ret;
>> +
>> + ret = iommufd_backend_connect(iommufd, errp);
>> + if (ret) {
>> + return ret;
>> + }
>> +
>> + /*
>> + * Add device to kvm-vfio to be prepared for the tracking
>> + * in KVM. Especially for some emulated devices, it requires
>> + * to have kvm information in the device open.
>> + */
>> + iommufd_cdev_kvm_device_add(vbasedev);
>> +
>> + /* Bind device to iommufd */
>> + bind.iommufd = iommufd->fd;
>> + ret = ioctl(vbasedev->fd, VFIO_DEVICE_BIND_IOMMUFD, &bind);
>> + if (ret) {
>> + error_setg_errno(errp, errno, "error bind device fd=%d to
>> iommufd=%d",
>> + vbasedev->fd, bind.iommufd);
>> + goto err_bind;
>> + }
>> +
>> + vbasedev->devid = bind.out_devid;
>> + trace_iommufd_connect_and_bind(bind.iommufd, vbasedev->name,
>vbasedev->fd,
>> + vbasedev->devid);
>> + return ret;
>> +err_bind:
>> + iommufd_cdev_kvm_device_del(vbasedev);
>> + iommufd_backend_disconnect(iommufd);
>> + return ret;
>> +}
>> +
>> +static void iommufd_unbind_and_disconnect(VFIODevice *vbasedev)
>> +{
>> + /* Unbind is automatically conducted when device fd is closed */
>> + iommufd_cdev_kvm_device_del(vbasedev);
>> + iommufd_backend_disconnect(vbasedev->iommufd);
>> +}
>> +
>> +static int iommufd_cdev_getfd(const char *sysfs_path, Error **errp)
>> +{
>> + long int ret = -ENOTTY;
>> + char *path, *vfio_dev_path = NULL, *vfio_path = NULL;
>> + DIR *dir = NULL;
>> + struct dirent *dent;
>> + gchar *contents;
>> + struct stat st;
>> + gsize length;
>> + int major, minor;
>> + dev_t vfio_devt;
>> +
>> + path = g_strdup_printf("%s/vfio-dev", sysfs_path);
>> + if (stat(path, &st) < 0) {
>> + error_setg_errno(errp, errno, "no such host device");
>> + goto out_free_path;
>> + }
>> +
>> + dir = opendir(path);
>> + if (!dir) {
>> + error_setg_errno(errp, errno, "couldn't open dirrectory %s", path);
>> + goto out_free_path;
>> + }
>> +
>> + while ((dent = readdir(dir))) {
>> + if (!strncmp(dent->d_name, "vfio", 4)) {
>> + vfio_dev_path = g_strdup_printf("%s/%s/dev", path,
>> dent->d_name);
>> + break;
>> + }
>> + }
>> +
>> + if (!vfio_dev_path) {
>> + error_setg(errp, "failed to find vfio-dev/vfioX/dev");
>> + goto out_close_dir;
>> + }
>> +
>> + if (!g_file_get_contents(vfio_dev_path, &contents, &length, NULL)) {
>> + error_setg(errp, "failed to load \"%s\"", vfio_dev_path);
>> + goto out_free_dev_path;
>> + }
>> +
>> + if (sscanf(contents, "%d:%d", &major, &minor) != 2) {
>> + error_setg(errp, "failed to get major:minor for \"%s\"",
>> vfio_dev_path);
>> + goto out_free_dev_path;
>> + }
>> + g_free(contents);
>> + vfio_devt = makedev(major, minor);
>> +
>> + vfio_path = g_strdup_printf("/dev/vfio/devices/%s", dent->d_name);
>> + ret = open_cdev(vfio_path, vfio_devt);
>> + if (ret < 0) {
>> + error_setg(errp, "Failed to open %s", vfio_path);
>> + }
>> +
>> + trace_iommufd_cdev_getfd(vfio_path, ret);
>> + g_free(vfio_path);
>> +
>> +out_free_dev_path:
>> + g_free(vfio_dev_path);
>> +out_close_dir:
>> + closedir(dir);
>> +out_free_path:
>> + if (*errp) {
>> + error_prepend(errp, VFIO_MSG_PREFIX, path);
>> + }
>> + g_free(path);
>> +
>> + return ret;
>> +}
>> +
>> +static VFIOIOASHwpt
>*iommufd_container_get_hwpt(VFIOIOMMUFDContainer *container,
>> + uint32_t hwpt_id)
>> +{
>> + VFIOIOASHwpt *hwpt;
>> +
>> + QLIST_FOREACH(hwpt, &container->hwpt_list, next) {
>> + if (hwpt->hwpt_id == hwpt_id) {
>> + return hwpt;
>> + }
>> + }
>> +
>> + hwpt = g_malloc0(sizeof(*hwpt));
>> +
>> + hwpt->hwpt_id = hwpt_id;
>> + QLIST_INIT(&hwpt->device_list);
>> + QLIST_INSERT_HEAD(&container->hwpt_list, hwpt, next);
>> +
>> + return hwpt;
>> +}
>> +
>> +static void iommufd_container_put_hwpt(IOMMUFDBackend *be,
>VFIOIOASHwpt *hwpt)
>> +{
>> + QLIST_REMOVE(hwpt, next);
>> + iommufd_backend_free_id(be->fd, hwpt->hwpt_id);
>> + g_free(hwpt);
>> +}
>> +
>> +static int iommufd_cdev_attach_hwpt(VFIODevice *vbasedev, uint32_t
>hwpt_id,
>> + Error **errp)
>> +{
>> + int ret, iommufd = vbasedev->iommufd->fd;
>> + struct vfio_device_attach_iommufd_pt attach_data = {
>> + .argsz = sizeof(attach_data),
>> + .flags = 0,
>> + .pt_id = hwpt_id,
>> + };
>> +
>> + /* Attach device to an hwpt within iommufd */
>> + ret = ioctl(vbasedev->fd, VFIO_DEVICE_ATTACH_IOMMUFD_PT,
>&attach_data);
>> + if (ret) {
>> + error_setg_errno(errp, errno,
>> + "[iommufd=%d] error attach %s (%d) to hwpt_id=%d",
>> + iommufd, vbasedev->name, vbasedev->fd, hwpt_id);
>> + }
>> + trace_iommufd_cdev_attach_hwpt(iommufd, vbasedev->name, vbasedev-
>>fd,
>> + hwpt_id);
>> + return ret;
>> +}
>> +
>> +static int iommufd_cdev_detach_hwpt(VFIODevice *vbasedev, Error **errp)
>> +{
>> + int ret, iommufd = vbasedev->iommufd->fd;
>> + struct vfio_device_detach_iommufd_pt detach_data = {
>> + .argsz = sizeof(detach_data),
>> + .flags = 0,
>> + };
>> +
>> + ret = ioctl(vbasedev->fd, VFIO_DEVICE_DETACH_IOMMUFD_PT,
>&detach_data);
>> + if (ret) {
>> + error_setg_errno(errp, errno, "detach %s from ioas failed",
>> + vbasedev->name);
>> + }
>> + trace_iommufd_cdev_detach_hwpt(iommufd, vbasedev->name,
>> + vbasedev->hwpt->hwpt_id);
>> + return ret;
>> +}
>> +
>> +static int iommufd_cdev_attach_container(VFIODevice *vbasedev,
>> + VFIOIOMMUFDContainer *container,
>> + Error **errp)
>> +{
>> + int ret, iommufd = vbasedev->iommufd->fd;
>> + VFIOIOASHwpt *hwpt;
>> + uint32_t hwpt_id;
>> + Error *err = NULL;
>> +
>> + /* try to attach to an existing hwpt in this container */
>> + QLIST_FOREACH(hwpt, &container->hwpt_list, next) {
>> + ret = iommufd_cdev_attach_hwpt(vbasedev, hwpt->hwpt_id, &err);
>> + if (ret) {
>> + const char *msg = error_get_pretty(err);
>> +
>> + trace_iommufd_cdev_fail_attach_existing_hwpt(msg);
>> + error_free(err);
>> + err = NULL;
>> + } else {
>> + goto found_hwpt;
>> + }
>> + }
>> +
>> + ret = iommufd_backend_alloc_hwpt(iommufd, vbasedev->devid,
>> + container->ioas_id, &hwpt_id);
>> +
>> + if (ret) {
>> + error_setg_errno(errp, errno, "error alloc shadow hwpt");
>> + return ret;
>> + }
>> +
>> + /* Attach cdev to a new allocated hwpt within iommufd */
>> + ret = iommufd_cdev_attach_hwpt(vbasedev, hwpt_id, errp);
>> + if (ret) {
>> + iommufd_backend_free_id(iommufd, hwpt_id);
>> + return ret;
>> + }
>> +
>> + hwpt = iommufd_container_get_hwpt(container, hwpt_id);
>> +found_hwpt:
>> + QLIST_INSERT_HEAD(&hwpt->device_list, vbasedev, next);
>> + vbasedev->hwpt = hwpt;
>> +
>> + trace_iommufd_cdev_attach_container(iommufd, vbasedev->name,
>vbasedev->fd,
>> + container->ioas_id, hwpt->hwpt_id);
>> + return ret;
>> +}
>> +
>> +static void iommufd_cdev_detach_container(VFIODevice *vbasedev,
>> + VFIOIOMMUFDContainer *container)
>> +{
>> + VFIOIOASHwpt *hwpt = vbasedev->hwpt;
>> + Error *err = NULL;
>> + int ret;
>> +
>> + ret = iommufd_cdev_detach_hwpt(vbasedev, &err);
>> + if (ret) {
>> + error_report_err(err);
>> + }
>> +
>> + QLIST_REMOVE(vbasedev, next);
>> + vbasedev->hwpt = NULL;
>> + if (QLIST_EMPTY(&hwpt->device_list)) {
>> + iommufd_container_put_hwpt(vbasedev->iommufd, hwpt);
>> + }
>> +
>> + trace_iommufd_cdev_detach_container(container->be->fd, vbasedev-
>>name,
>> + container->ioas_id);
>> +}
>> +
>> +static void iommufd_container_destroy(VFIOIOMMUFDContainer *container)
>> +{
>> + VFIOContainerBase *bcontainer = &container->bcontainer;
>> +
>> + if (!QLIST_EMPTY(&container->hwpt_list)) {
>> + return;
>> + }
>> + memory_listener_unregister(&bcontainer->listener);
>> + vfio_container_destroy(bcontainer);
>> + iommufd_backend_put_ioas(container->be, container->ioas_id);
>> + g_free(container);
>> +}
>> +
>> +static int iommufd_ram_block_discard_disable(bool state)
>> +{
>> + /*
>> + * We support coordinated discarding of RAM via the RamDiscardManager.
>> + */
>> + return ram_block_uncoordinated_discard_disable(state);
>> +}
>> +
>> +static int iommufd_attach_device(const char *name, VFIODevice *vbasedev,
>> + AddressSpace *as, Error **errp)
>> +{
>> + VFIOContainerBase *bcontainer;
>> + VFIOIOMMUFDContainer *container;
>> + VFIOAddressSpace *space;
>> + struct vfio_device_info dev_info = { .argsz = sizeof(dev_info) };
>> + int ret, devfd;
>> + uint32_t ioas_id;
>> + Error *err = NULL;
>> +
>> + devfd = iommufd_cdev_getfd(vbasedev->sysfsdev, errp);
>> + if (devfd < 0) {
>> + return devfd;
>> + }
>> + vbasedev->fd = devfd;
>> +
>> + ret = iommufd_connect_and_bind(vbasedev, errp);
>> + if (ret) {
>> + goto err_connect_bind;
>> + }
>> +
>> + space = vfio_get_address_space(as);
>> +
>> + /* try to attach to an existing container in this space */
>> + QLIST_FOREACH(bcontainer, &space->containers, next) {
>> + container = container_of(bcontainer, VFIOIOMMUFDContainer,
>bcontainer);
>> + if (bcontainer->ops != &vfio_iommufd_ops ||
>> + vbasedev->iommufd != container->be) {
>> + continue;
>> + }
>> + if (iommufd_cdev_attach_container(vbasedev, container, &err)) {
>> + const char *msg = error_get_pretty(err);
>> +
>> + trace_iommufd_cdev_fail_attach_existing_container(msg);
>> + error_free(err);
>> + err = NULL;
>> + } else {
>> + ret = iommufd_ram_block_discard_disable(true);
>> + if (ret) {
>> + error_setg(errp,
>> + "Cannot set discarding of RAM broken (%d)",
>> ret);
>> + goto err_discard_disable;
>> + }
>> + goto found_container;
>> + }
>> + }
>> +
>> + /* Need to allocate a new dedicated container */
>> + ret = iommufd_backend_get_ioas(vbasedev->iommufd, &ioas_id);
>> + if (ret < 0) {
>> + error_setg_errno(errp, errno, "Failed to alloc ioas");
>> + goto err_get_ioas;
>> + }
>> +
>> + trace_iommufd_cdev_alloc_ioas(vbasedev->iommufd->fd, ioas_id);
>> +
>> + container = g_malloc0(sizeof(*container));
>> + container->be = vbasedev->iommufd;
>> + container->ioas_id = ioas_id;
>> + QLIST_INIT(&container->hwpt_list);
>> +
>> + bcontainer = &container->bcontainer;
>> + vfio_container_init(bcontainer, space, &vfio_iommufd_ops);
>> + QLIST_INSERT_HEAD(&space->containers, bcontainer, next);
>> +
>> + ret = iommufd_cdev_attach_container(vbasedev, container, errp);
>> + if (ret) {
>> + goto err_attach_container;
>> + }
>> +
>> + ret = iommufd_ram_block_discard_disable(true);
>> + if (ret) {
>> + goto err_discard_disable;
>> + }
>> +
>> + bcontainer->pgsizes = qemu_real_host_page_size();
>> +
>> + bcontainer->listener = vfio_memory_listener;
>> + memory_listener_register(&bcontainer->listener, bcontainer->space->as);
>> +
>> + if (bcontainer->error) {
>> + ret = -1;
>> + error_propagate_prepend(errp, bcontainer->error,
>> + "memory listener initialization failed: ");
>> + goto err_listener_register;
>> + }
>> +
>> + bcontainer->initialized = true;
>> +
>> +found_container:
>> + ret = ioctl(devfd, VFIO_DEVICE_GET_INFO, &dev_info);
>> + if (ret) {
>> + error_setg_errno(errp, errno, "error getting device info");
>> + goto err_listener_register;
>> + }
>> +
>> + /*
>> + * TODO: examine RAM_BLOCK_DISCARD stuff, should we do group level
>> + * for discarding incompatibility check as well?
>> + */
>> + if (vbasedev->ram_block_discard_allowed) {
>> + iommufd_ram_block_discard_disable(false);
>> + }
>> +
>> + vbasedev->group = 0;
>> + vbasedev->num_irqs = dev_info.num_irqs;
>> + vbasedev->num_regions = dev_info.num_regions;
>> + vbasedev->flags = dev_info.flags;
>> + vbasedev->reset_works = !!(dev_info.flags & VFIO_DEVICE_FLAGS_RESET);
>> + vbasedev->bcontainer = bcontainer;
>> + QLIST_INSERT_HEAD(&bcontainer->device_list, vbasedev, container_next);
>> + QLIST_INSERT_HEAD(&vfio_device_list, vbasedev, global_next);
>> +
>> + trace_iommufd_cdev_device_info(vbasedev->name, devfd, vbasedev-
>>num_irqs,
>> + vbasedev->num_regions, vbasedev->flags);
>> + return 0;
>> +
>> +err_listener_register:
>> + iommufd_ram_block_discard_disable(false);
>> +err_discard_disable:
>> + iommufd_cdev_detach_container(vbasedev, container);
>> +err_attach_container:
>> + iommufd_container_destroy(container);
>> +err_get_ioas:
>> + vfio_put_address_space(space);
>> + iommufd_unbind_and_disconnect(vbasedev);
>> +err_connect_bind:
>> + close(vbasedev->fd);
>> + return ret;
>> +}
>> +
>> +static void iommufd_detach_device(VFIODevice *vbasedev)
>> +{
>> + VFIOContainerBase *bcontainer = vbasedev->bcontainer;
>> + VFIOIOMMUFDContainer *container;
>> + VFIOAddressSpace *space = bcontainer->space;
>> +
>> + QLIST_REMOVE(vbasedev, global_next);
>> + QLIST_REMOVE(vbasedev, container_next);
>> + vbasedev->bcontainer = NULL;
>> +
>> + if (!vbasedev->ram_block_discard_allowed) {
>> + iommufd_ram_block_discard_disable(false);
>> + }
>> +
>> + container = container_of(bcontainer, VFIOIOMMUFDContainer, bcontainer);
>> + iommufd_cdev_detach_container(vbasedev, container);
>> + iommufd_container_destroy(container);
>> + vfio_put_address_space(space);
>> +
>> + iommufd_unbind_and_disconnect(vbasedev);
>> + close(vbasedev->fd);
>> +}
>> +
>> +const VFIOIOMMUOps vfio_iommufd_ops = {
>> + .dma_map = iommufd_map,
>> + .dma_unmap = iommufd_unmap,
>> + .attach_device = iommufd_attach_device,
>> + .detach_device = iommufd_detach_device,
>> +};
>> diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build
>> index eb6ce6229d..9cae2c9e21 100644
>> --- a/hw/vfio/meson.build
>> +++ b/hw/vfio/meson.build
>> @@ -7,6 +7,9 @@ vfio_ss.add(files(
>> 'spapr.c',
>> 'migration.c',
>> ))
>> +if have_iommufd
>> + vfio_ss.add(files('iommufd.c'))
>> +endif
>
>Instead,
>
>vfio_ss.add(when: 'CONFIG_IOMMUFD', if_true: files(
> 'iommufd.c',
>))
Will do.
Thanks
Zhenzhong
- Re: [PATCH v4 26/41] backends/iommufd: Introduce the iommufd object, (continued)
- Re: [PATCH v4 26/41] backends/iommufd: Introduce the iommufd object, Markus Armbruster, 2023/11/08
- Re: [PATCH v4 26/41] backends/iommufd: Introduce the iommufd object, Cédric Le Goater, 2023/11/08
- Re: [PATCH v4 26/41] backends/iommufd: Introduce the iommufd object, Markus Armbruster, 2023/11/08
- Re: [PATCH v4 26/41] backends/iommufd: Introduce the iommufd object, Cédric Le Goater, 2023/11/08
- Re: [PATCH v4 26/41] backends/iommufd: Introduce the iommufd object, Markus Armbruster, 2023/11/09
[PATCH v4 27/41] util/char_dev: Add open_cdev(), Zhenzhong Duan, 2023/11/02
[PATCH v4 28/41] vfio/iommufd: Implement the iommufd backend, Zhenzhong Duan, 2023/11/02
- Re: [PATCH v4 28/41] vfio/iommufd: Implement the iommufd backend, Cédric Le Goater, 2023/11/07
- RE: [PATCH v4 28/41] vfio/iommufd: Implement the iommufd backend,
Duan, Zhenzhong <=
- Re: [PATCH v4 28/41] vfio/iommufd: Implement the iommufd backend, Matthew Rosato, 2023/11/07
- RE: [PATCH v4 28/41] vfio/iommufd: Implement the iommufd backend, Duan, Zhenzhong, 2023/11/08
- Re: [PATCH v4 28/41] vfio/iommufd: Implement the iommufd backend, Jason Gunthorpe, 2023/11/08
- RE: [PATCH v4 28/41] vfio/iommufd: Implement the iommufd backend, Duan, Zhenzhong, 2023/11/08
- Re: [PATCH v4 28/41] vfio/iommufd: Implement the iommufd backend, Jason Gunthorpe, 2023/11/08
- RE: [PATCH v4 28/41] vfio/iommufd: Implement the iommufd backend, Duan, Zhenzhong, 2023/11/08
Re: [PATCH v4 28/41] vfio/iommufd: Implement the iommufd backend, Joao Martins, 2023/11/09
Re: [PATCH v4 28/41] vfio/iommufd: Implement the iommufd backend, Jason Gunthorpe, 2023/11/09
Re: [PATCH v4 28/41] vfio/iommufd: Implement the iommufd backend, Joao Martins, 2023/11/09
Re: [PATCH v4 28/41] vfio/iommufd: Implement the iommufd backend, Joao Martins, 2023/11/09