mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
iommufd/selftest: Add set_dev_pasid in mock iommu
The callback is needed to make pasid_attach/detach path complete for mock device. A nop is enough for set_dev_pasid. A MOCK_FLAGS_DEVICE_PASID is added to indicate a pasid-capable mock device for the pasid test cases. Other test cases will still create a non-pasid mock device. While the mock iommu always pretends to be pasid-capable. Link: https://patch.msgid.link/r/20250321171940.7213-16-yi.l.liu@intel.com Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Yi Liu <yi.l.liu@intel.com> Tested-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
parent
dbc5f37b4f
commit
9eb59204d5
2 changed files with 36 additions and 5 deletions
|
@ -49,6 +49,7 @@ enum {
|
||||||
enum {
|
enum {
|
||||||
MOCK_FLAGS_DEVICE_NO_DIRTY = 1 << 0,
|
MOCK_FLAGS_DEVICE_NO_DIRTY = 1 << 0,
|
||||||
MOCK_FLAGS_DEVICE_HUGE_IOVA = 1 << 1,
|
MOCK_FLAGS_DEVICE_HUGE_IOVA = 1 << 1,
|
||||||
|
MOCK_FLAGS_DEVICE_PASID = 1 << 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -154,6 +155,9 @@ struct iommu_test_cmd {
|
||||||
};
|
};
|
||||||
#define IOMMU_TEST_CMD _IO(IOMMUFD_TYPE, IOMMUFD_CMD_BASE + 32)
|
#define IOMMU_TEST_CMD _IO(IOMMUFD_TYPE, IOMMUFD_CMD_BASE + 32)
|
||||||
|
|
||||||
|
/* Mock device/iommu PASID width */
|
||||||
|
#define MOCK_PASID_WIDTH 20
|
||||||
|
|
||||||
/* Mock structs for IOMMU_DEVICE_GET_HW_INFO ioctl */
|
/* Mock structs for IOMMU_DEVICE_GET_HW_INFO ioctl */
|
||||||
#define IOMMU_HW_INFO_TYPE_SELFTEST 0xfeedbeef
|
#define IOMMU_HW_INFO_TYPE_SELFTEST 0xfeedbeef
|
||||||
#define IOMMU_HW_INFO_SELFTEST_REGVAL 0xdeadbeef
|
#define IOMMU_HW_INFO_SELFTEST_REGVAL 0xdeadbeef
|
||||||
|
|
|
@ -223,8 +223,16 @@ static int mock_domain_nop_attach(struct iommu_domain *domain,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mock_domain_set_dev_pasid_nop(struct iommu_domain *domain,
|
||||||
|
struct device *dev, ioasid_t pasid,
|
||||||
|
struct iommu_domain *old)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct iommu_domain_ops mock_blocking_ops = {
|
static const struct iommu_domain_ops mock_blocking_ops = {
|
||||||
.attach_dev = mock_domain_nop_attach,
|
.attach_dev = mock_domain_nop_attach,
|
||||||
|
.set_dev_pasid = mock_domain_set_dev_pasid_nop
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct iommu_domain mock_blocking_domain = {
|
static struct iommu_domain mock_blocking_domain = {
|
||||||
|
@ -366,7 +374,7 @@ mock_domain_alloc_nested(struct device *dev, struct iommu_domain *parent,
|
||||||
struct mock_iommu_domain_nested *mock_nested;
|
struct mock_iommu_domain_nested *mock_nested;
|
||||||
struct mock_iommu_domain *mock_parent;
|
struct mock_iommu_domain *mock_parent;
|
||||||
|
|
||||||
if (flags)
|
if (flags & ~IOMMU_HWPT_ALLOC_PASID)
|
||||||
return ERR_PTR(-EOPNOTSUPP);
|
return ERR_PTR(-EOPNOTSUPP);
|
||||||
if (!parent || parent->ops != mock_ops.default_domain_ops)
|
if (!parent || parent->ops != mock_ops.default_domain_ops)
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
@ -388,7 +396,8 @@ mock_domain_alloc_paging_flags(struct device *dev, u32 flags,
|
||||||
{
|
{
|
||||||
bool has_dirty_flag = flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
|
bool has_dirty_flag = flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
|
||||||
const u32 PAGING_FLAGS = IOMMU_HWPT_ALLOC_DIRTY_TRACKING |
|
const u32 PAGING_FLAGS = IOMMU_HWPT_ALLOC_DIRTY_TRACKING |
|
||||||
IOMMU_HWPT_ALLOC_NEST_PARENT;
|
IOMMU_HWPT_ALLOC_NEST_PARENT |
|
||||||
|
IOMMU_HWPT_ALLOC_PASID;
|
||||||
struct mock_dev *mdev = to_mock_dev(dev);
|
struct mock_dev *mdev = to_mock_dev(dev);
|
||||||
bool no_dirty_ops = mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY;
|
bool no_dirty_ops = mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY;
|
||||||
struct mock_iommu_domain *mock;
|
struct mock_iommu_domain *mock;
|
||||||
|
@ -608,7 +617,7 @@ mock_viommu_alloc_domain_nested(struct iommufd_viommu *viommu, u32 flags,
|
||||||
struct mock_viommu *mock_viommu = to_mock_viommu(viommu);
|
struct mock_viommu *mock_viommu = to_mock_viommu(viommu);
|
||||||
struct mock_iommu_domain_nested *mock_nested;
|
struct mock_iommu_domain_nested *mock_nested;
|
||||||
|
|
||||||
if (flags)
|
if (flags & ~IOMMU_HWPT_ALLOC_PASID)
|
||||||
return ERR_PTR(-EOPNOTSUPP);
|
return ERR_PTR(-EOPNOTSUPP);
|
||||||
|
|
||||||
mock_nested = __mock_domain_alloc_nested(user_data);
|
mock_nested = __mock_domain_alloc_nested(user_data);
|
||||||
|
@ -743,6 +752,7 @@ static const struct iommu_ops mock_ops = {
|
||||||
.map_pages = mock_domain_map_pages,
|
.map_pages = mock_domain_map_pages,
|
||||||
.unmap_pages = mock_domain_unmap_pages,
|
.unmap_pages = mock_domain_unmap_pages,
|
||||||
.iova_to_phys = mock_domain_iova_to_phys,
|
.iova_to_phys = mock_domain_iova_to_phys,
|
||||||
|
.set_dev_pasid = mock_domain_set_dev_pasid_nop,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -803,6 +813,7 @@ static struct iommu_domain_ops domain_nested_ops = {
|
||||||
.free = mock_domain_free_nested,
|
.free = mock_domain_free_nested,
|
||||||
.attach_dev = mock_domain_nop_attach,
|
.attach_dev = mock_domain_nop_attach,
|
||||||
.cache_invalidate_user = mock_domain_cache_invalidate_user,
|
.cache_invalidate_user = mock_domain_cache_invalidate_user,
|
||||||
|
.set_dev_pasid = mock_domain_set_dev_pasid_nop,
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct iommufd_hw_pagetable *
|
static inline struct iommufd_hw_pagetable *
|
||||||
|
@ -862,11 +873,17 @@ static void mock_dev_release(struct device *dev)
|
||||||
|
|
||||||
static struct mock_dev *mock_dev_create(unsigned long dev_flags)
|
static struct mock_dev *mock_dev_create(unsigned long dev_flags)
|
||||||
{
|
{
|
||||||
|
struct property_entry prop[] = {
|
||||||
|
PROPERTY_ENTRY_U32("pasid-num-bits", 0),
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
const u32 valid_flags = MOCK_FLAGS_DEVICE_NO_DIRTY |
|
||||||
|
MOCK_FLAGS_DEVICE_HUGE_IOVA |
|
||||||
|
MOCK_FLAGS_DEVICE_PASID;
|
||||||
struct mock_dev *mdev;
|
struct mock_dev *mdev;
|
||||||
int rc, i;
|
int rc, i;
|
||||||
|
|
||||||
if (dev_flags &
|
if (dev_flags & ~valid_flags)
|
||||||
~(MOCK_FLAGS_DEVICE_NO_DIRTY | MOCK_FLAGS_DEVICE_HUGE_IOVA))
|
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
|
mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
|
||||||
|
@ -890,6 +907,15 @@ static struct mock_dev *mock_dev_create(unsigned long dev_flags)
|
||||||
if (rc)
|
if (rc)
|
||||||
goto err_put;
|
goto err_put;
|
||||||
|
|
||||||
|
if (dev_flags & MOCK_FLAGS_DEVICE_PASID)
|
||||||
|
prop[0] = PROPERTY_ENTRY_U32("pasid-num-bits", MOCK_PASID_WIDTH);
|
||||||
|
|
||||||
|
rc = device_create_managed_software_node(&mdev->dev, prop, NULL);
|
||||||
|
if (rc) {
|
||||||
|
dev_err(&mdev->dev, "add pasid-num-bits property failed, rc: %d", rc);
|
||||||
|
goto err_put;
|
||||||
|
}
|
||||||
|
|
||||||
rc = device_add(&mdev->dev);
|
rc = device_add(&mdev->dev);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto err_put;
|
goto err_put;
|
||||||
|
@ -1778,6 +1804,7 @@ int __init iommufd_test_init(void)
|
||||||
init_completion(&mock_iommu.complete);
|
init_completion(&mock_iommu.complete);
|
||||||
|
|
||||||
mock_iommu_iopf_queue = iopf_queue_alloc("mock-iopfq");
|
mock_iommu_iopf_queue = iopf_queue_alloc("mock-iopfq");
|
||||||
|
mock_iommu.iommu_dev.max_pasids = (1 << MOCK_PASID_WIDTH);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue