On Sat, 26 Oct 2024 at 07:50, Nicolin Chen nicolinc@nvidia.com wrote:
Now a vIOMMU holds a shareable nesting parent HWPT. So, it can act like that nesting parent HWPT to allocate a nested HWPT.
Support that in the IOMMU_HWPT_ALLOC ioctl handler, and update its kdoc.
Also, add an iommufd_hwpt_nested_alloc_for_viommu helper to allocate a nested HWPT for a vIOMMU object. Since a vIOMMU object holds the parent hwpt's refcount already, increase the refcount of the vIOMMU only.
Signed-off-by: Nicolin Chen nicolinc@nvidia.com
drivers/iommu/iommufd/iommufd_private.h | 1 + include/uapi/linux/iommufd.h | 14 ++--- drivers/iommu/iommufd/hw_pagetable.c | 71 ++++++++++++++++++++++++- 3 files changed, 79 insertions(+), 7 deletions(-)
diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h index 9adf8d616796..8c9ab35eaea5 100644 --- a/drivers/iommu/iommufd/iommufd_private.h +++ b/drivers/iommu/iommufd/iommufd_private.h @@ -288,6 +288,7 @@ struct iommufd_hwpt_paging { struct iommufd_hwpt_nested { struct iommufd_hw_pagetable common; struct iommufd_hwpt_paging *parent;
struct iommufd_viommu *viommu;
};
static inline bool hwpt_is_paging(struct iommufd_hw_pagetable *hwpt) diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h index 3d320d069654..717659b9fdce 100644 --- a/include/uapi/linux/iommufd.h +++ b/include/uapi/linux/iommufd.h @@ -430,7 +430,7 @@ enum iommu_hwpt_data_type {
- @size: sizeof(struct iommu_hwpt_alloc)
- @flags: Combination of enum iommufd_hwpt_alloc_flags
- @dev_id: The device to allocate this HWPT for
- @pt_id: The IOAS or HWPT to connect this HWPT to
- @pt_id: The IOAS or HWPT or vIOMMU to connect this HWPT to
- @out_hwpt_id: The ID of the new HWPT
- @__reserved: Must be 0
- @data_type: One of enum iommu_hwpt_data_type
@@ -449,11 +449,13 @@ enum iommu_hwpt_data_type {
- IOMMU_HWPT_DATA_NONE. The HWPT can be allocated as a parent HWPT for a
- nesting configuration by passing IOMMU_HWPT_ALLOC_NEST_PARENT via @flags.
- A user-managed nested HWPT will be created from a given parent HWPT via
- @pt_id, in which the parent HWPT must be allocated previously via the
- same ioctl from a given IOAS (@pt_id). In this case, the @data_type
- must be set to a pre-defined type corresponding to an I/O page table
- type supported by the underlying IOMMU hardware.
- A user-managed nested HWPT will be created from a given vIOMMU (wrapping a
- parent HWPT) or a parent HWPT via @pt_id, in which the parent HWPT must be
- allocated previously via the same ioctl from a given IOAS (@pt_id). In this
- case, the @data_type must be set to a pre-defined type corresponding to an
- I/O page table type supported by the underlying IOMMU hardware. The device
- via @dev_id and the vIOMMU via @pt_id must be associated to the same IOMMU
- instance.
- If the @data_type is set to IOMMU_HWPT_DATA_NONE, @data_len and
- @data_uptr should be zero. Otherwise, both @data_len and @data_uptr
diff --git a/drivers/iommu/iommufd/hw_pagetable.c b/drivers/iommu/iommufd/hw_pagetable.c index d06bf6e6c19f..1df5d40c93df 100644 --- a/drivers/iommu/iommufd/hw_pagetable.c +++ b/drivers/iommu/iommufd/hw_pagetable.c @@ -57,7 +57,10 @@ void iommufd_hwpt_nested_destroy(struct iommufd_object *obj) container_of(obj, struct iommufd_hwpt_nested, common.obj);
__iommufd_hwpt_destroy(&hwpt_nested->common);
refcount_dec(&hwpt_nested->parent->common.obj.users);
if (hwpt_nested->viommu)
refcount_dec(&hwpt_nested->viommu->obj.users);
else
refcount_dec(&hwpt_nested->parent->common.obj.users);
}
void iommufd_hwpt_nested_abort(struct iommufd_object *obj) @@ -260,6 +263,56 @@ iommufd_hwpt_nested_alloc(struct iommufd_ctx *ictx, return ERR_PTR(rc); }
+/**
- iommufd_viommu_alloc_hwpt_nested() - Get a hwpt_nested for a vIOMMU
- @viommu: vIOMMU ojbect to associate the hwpt_nested/domain with
- @user_data: user_data pointer. Must be valid
- Allocate a new IOMMU_DOMAIN_NESTED for a vIOMMU and return it as a NESTED
- hw_pagetable.
- */
+static struct iommufd_hwpt_nested * +iommufd_viommu_alloc_hwpt_nested(struct iommufd_viommu *viommu, u32 flags,
const struct iommu_user_data *user_data)
+{
struct iommufd_hwpt_nested *hwpt_nested;
struct iommufd_hw_pagetable *hwpt;
int rc;
if (flags)
return ERR_PTR(-EOPNOTSUPP);
This check should be removed.
When a user page fault is required, IOMMU_HWPT_FAULT_ID_VALID is set. if (cmd->flags & IOMMU_HWPT_FAULT_ID_VALID) {
By the way, has qemu changed compared with v3? I still got a hardware error in this version, in check
Thanks