ioctl(iommufd, IOMMU_HWPT_GET_DIRTY_BITMAP, arg) is the UAPI
that fetches the bitmap that tells what was dirty in an IOVA
range.
A single bitmap is allocated and used across all the hwpts
sharing an IOAS which is then used in log_sync() to set Qemu
global bitmaps.
Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
---
include/sysemu/iommufd.h | 3 +++
backends/iommufd.c | 26 ++++++++++++++++++++++++++
hw/vfio/iommufd.c | 34 ++++++++++++++++++++++++++++++++++
backends/trace-events | 1 +
4 files changed, 64 insertions(+)
diff --git a/include/sysemu/iommufd.h b/include/sysemu/iommufd.h
index 1470377f55ba..223f1ea14e84 100644
--- a/include/sysemu/iommufd.h
+++ b/include/sysemu/iommufd.h
@@ -56,6 +56,9 @@ int iommufd_backend_alloc_hwpt(IOMMUFDBackend *be, uint32_t dev_id,
void *data_ptr, uint32_t *out_hwpt);
int iommufd_backend_set_dirty_tracking(IOMMUFDBackend *be, uint32_t hwpt_id,
bool start);
+int iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be, uint32_t hwpt_id,
+ uint64_t iova, ram_addr_t size,
+ uint64_t page_size, uint64_t *data);
#define TYPE_HOST_IOMMU_DEVICE_IOMMUFD TYPE_HOST_IOMMU_DEVICE "-iommufd"
diff --git a/backends/iommufd.c b/backends/iommufd.c
index 69daabc27473..b2d3bbd7c31b 100644
--- a/backends/iommufd.c
+++ b/backends/iommufd.c
@@ -257,6 +257,32 @@ int iommufd_backend_set_dirty_tracking(IOMMUFDBackend *be, uint32_t hwpt_id,
return ret;
}
+int iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be, uint32_t hwpt_id,
+ uint64_t iova, ram_addr_t size,
+ uint64_t page_size, uint64_t *data)
+{
+ int ret;
+ struct iommu_hwpt_get_dirty_bitmap get_dirty_bitmap = {
+ .size = sizeof(get_dirty_bitmap),
+ .hwpt_id = hwpt_id,
+ .iova = iova,
+ .length = size,
+ .page_size = page_size,
+ .data = (uintptr_t)data,
+ };
+
+ ret = ioctl(be->fd, IOMMU_HWPT_GET_DIRTY_BITMAP, &get_dirty_bitmap);
+ trace_iommufd_backend_get_dirty_bitmap(be->fd, hwpt_id, iova, size,
+ page_size, ret);
+ if (ret) {
+ error_report("IOMMU_HWPT_GET_DIRTY_BITMAP (iova: 0x%"PRIx64
+ " size: 0x%"PRIx64") failed: %s", iova,
+ size, strerror(errno));
+ }
+
+ return !ret ? 0 : -errno;
+}
+
bool iommufd_backend_get_device_info(IOMMUFDBackend *be, uint32_t devid,
uint32_t *type, void *data, uint32_t len,
uint64_t *caps, Error **errp)
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index 158a98cb3b12..9fad47baed9e 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -25,6 +25,7 @@
#include "qemu/cutils.h"
#include "qemu/chardev_open.h"
#include "pci.h"
+#include "exec/ram_addr.h"
static int iommufd_cdev_map(const VFIOContainerBase *bcontainer, hwaddr iova,
ram_addr_t size, void *vaddr, bool readonly)
@@ -152,6 +153,38 @@ err:
return ret;
}
+static int iommufd_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
+ VFIOBitmap *vbmap, hwaddr iova,
+ hwaddr size, Error **errp)
+{
+ VFIOIOMMUFDContainer *container = container_of(bcontainer,
+ VFIOIOMMUFDContainer,
+ bcontainer);
+ int ret;
+ VFIOIOASHwpt *hwpt;
+ unsigned long page_size;
+
+ page_size = qemu_real_host_page_size();
+ QLIST_FOREACH(hwpt, &container->hwpt_list, next) {
+ if (!iommufd_hwpt_dirty_tracking(hwpt)) {
+ continue;
+ }
+
+ ret = iommufd_backend_get_dirty_bitmap(container->be, hwpt->hwpt_id,
+ iova, size, page_size,
+ vbmap->bitmap);
+ if (ret) {
+ error_setg_errno(errp, ret,
+ "Failed to get dirty bitmap report, hwpt_id %u, iova: "
+ "0x%" HWADDR_PRIx ", size: 0x%" HWADDR_PRIx,
+ hwpt->hwpt_id, iova, size);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
static int iommufd_cdev_getfd(const char *sysfs_path, Error **errp)
{
ERRP_GUARD();
@@ -777,6 +810,7 @@ static void vfio_iommu_iommufd_class_init(ObjectClass *klass, void *data)
vioc->detach_device = iommufd_cdev_detach;
vioc->pci_hot_reset = iommufd_cdev_pci_hot_reset;
vioc->set_dirty_page_tracking = iommufd_set_dirty_page_tracking;
+ vioc->query_dirty_bitmap = iommufd_query_dirty_bitmap;
};
static bool hiod_iommufd_vfio_realize(HostIOMMUDevice *hiod, void *opaque,
diff --git a/backends/trace-events b/backends/trace-events
index 28aca3b859d4..40811a316215 100644
--- a/backends/trace-events
+++ b/backends/trace-events
@@ -17,3 +17,4 @@ iommufd_backend_alloc_ioas(int iommufd, uint32_t ioas) " iommufd=%d ioas=%d"
iommufd_backend_alloc_hwpt(int iommufd, uint32_t dev_id, uint32_t pt_id, uint32_t flags, uint32_t hwpt_type, uint32_t len, uint64_t data_ptr, uint32_t out_hwpt_id, int ret) " iommufd=%d dev_id=%u pt_id=%u flags=0x%x hwpt_type=%u len=%u data_ptr=0x%"PRIx64" out_hwpt=%u (%d)"
iommufd_backend_free_id(int iommufd, uint32_t id, int ret) " iommufd=%d id=%d (%d)"
iommufd_backend_set_dirty(int iommufd, uint32_t hwpt_id, bool start, int ret) " iommufd=%d hwpt=%u enable=%d (%d)"
+iommufd_backend_get_dirty_bitmap(int iommufd, uint32_t hwpt_id, uint64_t iova, uint64_t size, uint64_t page_size, int ret) " iommufd=%d hwpt=%u iova=0x%"PRIx64" size=0x%"PRIx64" page_size=0x%"PRIx64" (%d)"
--
2.17.2
On 7/8/24 4:34 PM, Joao Martins wrote:
> ioctl(iommufd, IOMMU_HWPT_GET_DIRTY_BITMAP, arg) is the UAPI
> that fetches the bitmap that tells what was dirty in an IOVA
> range.
>
> A single bitmap is allocated and used across all the hwpts
> sharing an IOAS which is then used in log_sync() to set Qemu
> global bitmaps.
>
> Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
> ---
> include/sysemu/iommufd.h | 3 +++
> backends/iommufd.c | 26 ++++++++++++++++++++++++++
> hw/vfio/iommufd.c | 34 ++++++++++++++++++++++++++++++++++
> backends/trace-events | 1 +
> 4 files changed, 64 insertions(+)
>
> diff --git a/include/sysemu/iommufd.h b/include/sysemu/iommufd.h
> index 1470377f55ba..223f1ea14e84 100644
> --- a/include/sysemu/iommufd.h
> +++ b/include/sysemu/iommufd.h
> @@ -56,6 +56,9 @@ int iommufd_backend_alloc_hwpt(IOMMUFDBackend *be, uint32_t dev_id,
> void *data_ptr, uint32_t *out_hwpt);
> int iommufd_backend_set_dirty_tracking(IOMMUFDBackend *be, uint32_t hwpt_id,
> bool start);
> +int iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be, uint32_t hwpt_id,
> + uint64_t iova, ram_addr_t size,
> + uint64_t page_size, uint64_t *data);
>
> #define TYPE_HOST_IOMMU_DEVICE_IOMMUFD TYPE_HOST_IOMMU_DEVICE "-iommufd"
>
> diff --git a/backends/iommufd.c b/backends/iommufd.c
> index 69daabc27473..b2d3bbd7c31b 100644
> --- a/backends/iommufd.c
> +++ b/backends/iommufd.c
> @@ -257,6 +257,32 @@ int iommufd_backend_set_dirty_tracking(IOMMUFDBackend *be, uint32_t hwpt_id,
> return ret;
> }
>
> +int iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be, uint32_t hwpt_id,
> + uint64_t iova, ram_addr_t size,
> + uint64_t page_size, uint64_t *data)
> +{
> + int ret;
> + struct iommu_hwpt_get_dirty_bitmap get_dirty_bitmap = {
> + .size = sizeof(get_dirty_bitmap),
> + .hwpt_id = hwpt_id,
> + .iova = iova,
> + .length = size,
> + .page_size = page_size,
> + .data = (uintptr_t)data,
> + };
> +
> + ret = ioctl(be->fd, IOMMU_HWPT_GET_DIRTY_BITMAP, &get_dirty_bitmap);
> + trace_iommufd_backend_get_dirty_bitmap(be->fd, hwpt_id, iova, size,
> + page_size, ret);
> + if (ret) {
> + error_report("IOMMU_HWPT_GET_DIRTY_BITMAP (iova: 0x%"PRIx64
> + " size: 0x%"PRIx64") failed: %s", iova,
> + size, strerror(errno));
> + }
> +
> + return !ret ? 0 : -errno;
> +}
> +
> bool iommufd_backend_get_device_info(IOMMUFDBackend *be, uint32_t devid,
> uint32_t *type, void *data, uint32_t len,
> uint64_t *caps, Error **errp)
> diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
> index 158a98cb3b12..9fad47baed9e 100644
> --- a/hw/vfio/iommufd.c
> +++ b/hw/vfio/iommufd.c
> @@ -25,6 +25,7 @@
> #include "qemu/cutils.h"
> #include "qemu/chardev_open.h"
> #include "pci.h"
> +#include "exec/ram_addr.h"
>
> static int iommufd_cdev_map(const VFIOContainerBase *bcontainer, hwaddr iova,
> ram_addr_t size, void *vaddr, bool readonly)
> @@ -152,6 +153,38 @@ err:
> return ret;
> }
>
> +static int iommufd_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
> + VFIOBitmap *vbmap, hwaddr iova,
> + hwaddr size, Error **errp)
> +{
> + VFIOIOMMUFDContainer *container = container_of(bcontainer,
> + VFIOIOMMUFDContainer,
> + bcontainer);
> + int ret;
> + VFIOIOASHwpt *hwpt;
> + unsigned long page_size;
> +
> + page_size = qemu_real_host_page_size();
> + QLIST_FOREACH(hwpt, &container->hwpt_list, next) {
> + if (!iommufd_hwpt_dirty_tracking(hwpt)) {
> + continue;
> + }
> +
> + ret = iommufd_backend_get_dirty_bitmap(container->be, hwpt->hwpt_id,
> + iova, size, page_size,
> + vbmap->bitmap);
> + if (ret) {
> + error_setg_errno(errp, ret,
> + "Failed to get dirty bitmap report, hwpt_id %u, iova: "
> + "0x%" HWADDR_PRIx ", size: 0x%" HWADDR_PRIx,
> + hwpt->hwpt_id, iova, size);
This error looks redundant with the one printed out in
iommufd_backend_get_dirty_bitmap(). Couldn't we add an 'Error **'
parameter and simply return a bool ?
Thanks,
C.
> + return ret;
> + }
> + }
> +
> + return 0;
> +}
> +
> static int iommufd_cdev_getfd(const char *sysfs_path, Error **errp)
> {
> ERRP_GUARD();
> @@ -777,6 +810,7 @@ static void vfio_iommu_iommufd_class_init(ObjectClass *klass, void *data)
> vioc->detach_device = iommufd_cdev_detach;
> vioc->pci_hot_reset = iommufd_cdev_pci_hot_reset;
> vioc->set_dirty_page_tracking = iommufd_set_dirty_page_tracking;
> + vioc->query_dirty_bitmap = iommufd_query_dirty_bitmap;
> };
>
> static bool hiod_iommufd_vfio_realize(HostIOMMUDevice *hiod, void *opaque,
> diff --git a/backends/trace-events b/backends/trace-events
> index 28aca3b859d4..40811a316215 100644
> --- a/backends/trace-events
> +++ b/backends/trace-events
> @@ -17,3 +17,4 @@ iommufd_backend_alloc_ioas(int iommufd, uint32_t ioas) " iommufd=%d ioas=%d"
> iommufd_backend_alloc_hwpt(int iommufd, uint32_t dev_id, uint32_t pt_id, uint32_t flags, uint32_t hwpt_type, uint32_t len, uint64_t data_ptr, uint32_t out_hwpt_id, int ret) " iommufd=%d dev_id=%u pt_id=%u flags=0x%x hwpt_type=%u len=%u data_ptr=0x%"PRIx64" out_hwpt=%u (%d)"
> iommufd_backend_free_id(int iommufd, uint32_t id, int ret) " iommufd=%d id=%d (%d)"
> iommufd_backend_set_dirty(int iommufd, uint32_t hwpt_id, bool start, int ret) " iommufd=%d hwpt=%u enable=%d (%d)"
> +iommufd_backend_get_dirty_bitmap(int iommufd, uint32_t hwpt_id, uint64_t iova, uint64_t size, uint64_t page_size, int ret) " iommufd=%d hwpt=%u iova=0x%"PRIx64" size=0x%"PRIx64" page_size=0x%"PRIx64" (%d)"
On 09/07/2024 08:05, Cédric Le Goater wrote:
> On 7/8/24 4:34 PM, Joao Martins wrote:
>> ioctl(iommufd, IOMMU_HWPT_GET_DIRTY_BITMAP, arg) is the UAPI
>> that fetches the bitmap that tells what was dirty in an IOVA
>> range.
>>
>> A single bitmap is allocated and used across all the hwpts
>> sharing an IOAS which is then used in log_sync() to set Qemu
>> global bitmaps.
>>
>> Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
>> ---
>> include/sysemu/iommufd.h | 3 +++
>> backends/iommufd.c | 26 ++++++++++++++++++++++++++
>> hw/vfio/iommufd.c | 34 ++++++++++++++++++++++++++++++++++
>> backends/trace-events | 1 +
>> 4 files changed, 64 insertions(+)
>>
>> diff --git a/include/sysemu/iommufd.h b/include/sysemu/iommufd.h
>> index 1470377f55ba..223f1ea14e84 100644
>> --- a/include/sysemu/iommufd.h
>> +++ b/include/sysemu/iommufd.h
>> @@ -56,6 +56,9 @@ int iommufd_backend_alloc_hwpt(IOMMUFDBackend *be, uint32_t
>> dev_id,
>> void *data_ptr, uint32_t *out_hwpt);
>> int iommufd_backend_set_dirty_tracking(IOMMUFDBackend *be, uint32_t hwpt_id,
>> bool start);
>> +int iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be, uint32_t hwpt_id,
>> + uint64_t iova, ram_addr_t size,
>> + uint64_t page_size, uint64_t *data);
>> #define TYPE_HOST_IOMMU_DEVICE_IOMMUFD TYPE_HOST_IOMMU_DEVICE "-iommufd"
>> diff --git a/backends/iommufd.c b/backends/iommufd.c
>> index 69daabc27473..b2d3bbd7c31b 100644
>> --- a/backends/iommufd.c
>> +++ b/backends/iommufd.c
>> @@ -257,6 +257,32 @@ int iommufd_backend_set_dirty_tracking(IOMMUFDBackend
>> *be, uint32_t hwpt_id,
>> return ret;
>> }
>> +int iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be, uint32_t hwpt_id,
>> + uint64_t iova, ram_addr_t size,
>> + uint64_t page_size, uint64_t *data)
>> +{
>> + int ret;
>> + struct iommu_hwpt_get_dirty_bitmap get_dirty_bitmap = {
>> + .size = sizeof(get_dirty_bitmap),
>> + .hwpt_id = hwpt_id,
>> + .iova = iova,
>> + .length = size,
>> + .page_size = page_size,
>> + .data = (uintptr_t)data,
>> + };
>> +
>> + ret = ioctl(be->fd, IOMMU_HWPT_GET_DIRTY_BITMAP, &get_dirty_bitmap);
>> + trace_iommufd_backend_get_dirty_bitmap(be->fd, hwpt_id, iova, size,
>> + page_size, ret);
>> + if (ret) {
>> + error_report("IOMMU_HWPT_GET_DIRTY_BITMAP (iova: 0x%"PRIx64
>> + " size: 0x%"PRIx64") failed: %s", iova,
>> + size, strerror(errno));
>> + }
>> +
>> + return !ret ? 0 : -errno;
>> +}
>> +
>> bool iommufd_backend_get_device_info(IOMMUFDBackend *be, uint32_t devid,
>> uint32_t *type, void *data, uint32_t len,
>> uint64_t *caps, Error **errp)
>> diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
>> index 158a98cb3b12..9fad47baed9e 100644
>> --- a/hw/vfio/iommufd.c
>> +++ b/hw/vfio/iommufd.c
>> @@ -25,6 +25,7 @@
>> #include "qemu/cutils.h"
>> #include "qemu/chardev_open.h"
>> #include "pci.h"
>> +#include "exec/ram_addr.h"
>> static int iommufd_cdev_map(const VFIOContainerBase *bcontainer, hwaddr iova,
>> ram_addr_t size, void *vaddr, bool readonly)
>> @@ -152,6 +153,38 @@ err:
>> return ret;
>> }
>> +static int iommufd_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
>> + VFIOBitmap *vbmap, hwaddr iova,
>> + hwaddr size, Error **errp)
>> +{
>> + VFIOIOMMUFDContainer *container = container_of(bcontainer,
>> + VFIOIOMMUFDContainer,
>> + bcontainer);
>> + int ret;
>> + VFIOIOASHwpt *hwpt;
>> + unsigned long page_size;
>> +
>> + page_size = qemu_real_host_page_size();
>> + QLIST_FOREACH(hwpt, &container->hwpt_list, next) {
>> + if (!iommufd_hwpt_dirty_tracking(hwpt)) {
>> + continue;
>> + }
>> +
>> + ret = iommufd_backend_get_dirty_bitmap(container->be, hwpt->hwpt_id,
>> + iova, size, page_size,
>> + vbmap->bitmap);
>> + if (ret) {
>> + error_setg_errno(errp, ret,
>> + "Failed to get dirty bitmap report, hwpt_id %u,
>> iova: "
>> + "0x%" HWADDR_PRIx ", size: 0x%" HWADDR_PRIx,
>> + hwpt->hwpt_id, iova, size);
>
> This error looks redundant with the one printed out in
> iommufd_backend_get_dirty_bitmap(). Couldn't we add an 'Error **'
> parameter and simply return a bool ?
>
I'll add it.
Just as a sidebar: This is a odd pattern which seems somewhat spread, that
somehow we only care about @errno as something to put on a message, rather then
letting the user know what exact error code it had returned programmatically.
Here in this series it is only important for the device attach so likely doesn't
justify a Error structure enhancement, hence the rest of functions I introduced
here can just adopt bool+errp.
On 09/07/2024 10:13, Joao Martins wrote:
> On 09/07/2024 08:05, Cédric Le Goater wrote:
>> On 7/8/24 4:34 PM, Joao Martins wrote:
>>> ioctl(iommufd, IOMMU_HWPT_GET_DIRTY_BITMAP, arg) is the UAPI
>>> that fetches the bitmap that tells what was dirty in an IOVA
>>> range.
>>>
>>> A single bitmap is allocated and used across all the hwpts
>>> sharing an IOAS which is then used in log_sync() to set Qemu
>>> global bitmaps.
>>>
>>> Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
>>> ---
>>> include/sysemu/iommufd.h | 3 +++
>>> backends/iommufd.c | 26 ++++++++++++++++++++++++++
>>> hw/vfio/iommufd.c | 34 ++++++++++++++++++++++++++++++++++
>>> backends/trace-events | 1 +
>>> 4 files changed, 64 insertions(+)
>>>
>>> diff --git a/include/sysemu/iommufd.h b/include/sysemu/iommufd.h
>>> index 1470377f55ba..223f1ea14e84 100644
>>> --- a/include/sysemu/iommufd.h
>>> +++ b/include/sysemu/iommufd.h
>>> @@ -56,6 +56,9 @@ int iommufd_backend_alloc_hwpt(IOMMUFDBackend *be, uint32_t
>>> dev_id,
>>> void *data_ptr, uint32_t *out_hwpt);
>>> int iommufd_backend_set_dirty_tracking(IOMMUFDBackend *be, uint32_t hwpt_id,
>>> bool start);
>>> +int iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be, uint32_t hwpt_id,
>>> + uint64_t iova, ram_addr_t size,
>>> + uint64_t page_size, uint64_t *data);
>>> #define TYPE_HOST_IOMMU_DEVICE_IOMMUFD TYPE_HOST_IOMMU_DEVICE "-iommufd"
>>> diff --git a/backends/iommufd.c b/backends/iommufd.c
>>> index 69daabc27473..b2d3bbd7c31b 100644
>>> --- a/backends/iommufd.c
>>> +++ b/backends/iommufd.c
>>> @@ -257,6 +257,32 @@ int iommufd_backend_set_dirty_tracking(IOMMUFDBackend
>>> *be, uint32_t hwpt_id,
>>> return ret;
>>> }
>>> +int iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be, uint32_t hwpt_id,
>>> + uint64_t iova, ram_addr_t size,
>>> + uint64_t page_size, uint64_t *data)
>>> +{
>>> + int ret;
>>> + struct iommu_hwpt_get_dirty_bitmap get_dirty_bitmap = {
>>> + .size = sizeof(get_dirty_bitmap),
>>> + .hwpt_id = hwpt_id,
>>> + .iova = iova,
>>> + .length = size,
>>> + .page_size = page_size,
>>> + .data = (uintptr_t)data,
>>> + };
>>> +
>>> + ret = ioctl(be->fd, IOMMU_HWPT_GET_DIRTY_BITMAP, &get_dirty_bitmap);
>>> + trace_iommufd_backend_get_dirty_bitmap(be->fd, hwpt_id, iova, size,
>>> + page_size, ret);
>>> + if (ret) {
>>> + error_report("IOMMU_HWPT_GET_DIRTY_BITMAP (iova: 0x%"PRIx64
>>> + " size: 0x%"PRIx64") failed: %s", iova,
>>> + size, strerror(errno));
>>> + }
>>> +
>>> + return !ret ? 0 : -errno;
>>> +}
>>> +
>>> bool iommufd_backend_get_device_info(IOMMUFDBackend *be, uint32_t devid,
>>> uint32_t *type, void *data, uint32_t len,
>>> uint64_t *caps, Error **errp)
>>> diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
>>> index 158a98cb3b12..9fad47baed9e 100644
>>> --- a/hw/vfio/iommufd.c
>>> +++ b/hw/vfio/iommufd.c
>>> @@ -25,6 +25,7 @@
>>> #include "qemu/cutils.h"
>>> #include "qemu/chardev_open.h"
>>> #include "pci.h"
>>> +#include "exec/ram_addr.h"
>>> static int iommufd_cdev_map(const VFIOContainerBase *bcontainer, hwaddr iova,
>>> ram_addr_t size, void *vaddr, bool readonly)
>>> @@ -152,6 +153,38 @@ err:
>>> return ret;
>>> }
>>> +static int iommufd_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
>>> + VFIOBitmap *vbmap, hwaddr iova,
>>> + hwaddr size, Error **errp)
>>> +{
>>> + VFIOIOMMUFDContainer *container = container_of(bcontainer,
>>> + VFIOIOMMUFDContainer,
>>> + bcontainer);
>>> + int ret;
>>> + VFIOIOASHwpt *hwpt;
>>> + unsigned long page_size;
>>> +
>>> + page_size = qemu_real_host_page_size();
>>> + QLIST_FOREACH(hwpt, &container->hwpt_list, next) {
>>> + if (!iommufd_hwpt_dirty_tracking(hwpt)) {
>>> + continue;
>>> + }
>>> +
>>> + ret = iommufd_backend_get_dirty_bitmap(container->be, hwpt->hwpt_id,
>>> + iova, size, page_size,
>>> + vbmap->bitmap);
>>> + if (ret) {
>>> + error_setg_errno(errp, ret,
>>> + "Failed to get dirty bitmap report, hwpt_id %u,
>>> iova: "
>>> + "0x%" HWADDR_PRIx ", size: 0x%" HWADDR_PRIx,
>>> + hwpt->hwpt_id, iova, size);
>>
>> This error looks redundant with the one printed out in
>> iommufd_backend_get_dirty_bitmap(). Couldn't we add an 'Error **'
>> parameter and simply return a bool ?
>>
>
> I'll add it.
>
> Just as a sidebar: This is a odd pattern which seems somewhat spread, that
> somehow we only care about @errno as something to put on a message, rather then
> letting the user know what exact error code it had returned programmatically.
> Here in this series it is only important for the device attach so likely doesn't
> justify a Error structure enhancement, hence the rest of functions I introduced
> here can just adopt bool+errp.
>
>
Looks like this. A bit odd as the container ops (and legacy backend) expect an
errno. But I am assuming that you intended that way.
-int iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be, uint32_t hwpt_id,
- uint64_t iova, ram_addr_t size,
- uint64_t page_size, uint64_t *data)
+bool iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be,
+ uint32_t hwpt_id,
+ uint64_t iova, ram_addr_t size,
+ uint64_t page_size, uint64_t *data,
+ Error **errp)
{
int ret;
struct iommu_hwpt_get_dirty_bitmap get_dirty_bitmap = {
@@ -273,14 +278,15 @@ int iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be,
uint32_t hwpt_id,
ret = ioctl(be->fd, IOMMU_HWPT_GET_DIRTY_BITMAP, &get_dirty_bitmap);
trace_iommufd_backend_get_dirty_bitmap(be->fd, hwpt_id, iova, size,
- page_size, ret);
+ page_size, ret ? errno : 0);
if (ret) {
- error_report("IOMMU_HWPT_GET_DIRTY_BITMAP (iova: 0x%"PRIx64
- " size: 0x%"PRIx64") failed: %s", iova,
- size, strerror(errno));
+ error_setg_errno(errp, errno,
+ "IOMMU_HWPT_GET_DIRTY_BITMAP (iova: 0x%"HWADDR_PRIx
+ " size: 0x%"HWADDR_PRIx") failed", iova, size);
+ return false;
}
- return !ret ? 0 : -errno;
+ return true;
}
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index 35cf8da22ef7..4369df34a6ac 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -160,25 +154,18 @@ static int iommufd_query_dirty_bitmap(const
VFIOContainerBase *bcontainer,
VFIOIOMMUFDContainer *container = container_of(bcontainer,
VFIOIOMMUFDContainer,
bcontainer);
- int ret;
+ unsigned long page_size = qemu_real_host_page_size();
VFIOIOASHwpt *hwpt;
- unsigned long page_size;
- page_size = qemu_real_host_page_size();
QLIST_FOREACH(hwpt, &container->hwpt_list, next) {
if (!iommufd_hwpt_dirty_tracking(hwpt)) {
continue;
}
- ret = iommufd_backend_get_dirty_bitmap(container->be, hwpt->hwpt_id,
- iova, size, page_size,
- vbmap->bitmap);
- if (ret) {
- error_setg_errno(errp, ret,
- "Failed to get dirty bitmap report, hwpt_id %u,
iova: "
- "0x%" HWADDR_PRIx ", size: 0x%" HWADDR_PRIx,
- hwpt->hwpt_id, iova, size);
- return ret;
+ if (!iommufd_backend_get_dirty_bitmap(container->be, hwpt->hwpt_id,
+ iova, size, page_size,
+ vbmap->bitmap)) {
+ return -EINVAL;
}
}
@@ -287,24 +274,11 @@ static bool iommufd_cdev_detach_ioas_hwpt(VFIODevice
*vbasedev, Error **errp)
return true;
}
(...)
© 2016 - 2026 Red Hat, Inc.