Skip to content

Commit 69d9b31

Browse files
nicolincjgunthorpe
authored andcommitted
iommu/arm-smmu-v3: Support IOMMU_VIOMMU_ALLOC
Add a new driver-type for ARM SMMUv3 to enum iommu_viommu_type. Implement an arm_vsmmu_alloc(). As an initial step, copy the VMID from s2_parent. A followup series is required to give the VIOMMU object it's own VMID that will be used in all nesting configurations. Link: https://patch.msgid.link/r/[email protected] Signed-off-by: Nicolin Chen <[email protected]> Tested-by: Nicolin Chen <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 4e6bd13 commit 69d9b31

File tree

4 files changed

+63
-0
lines changed

4 files changed

+63
-0
lines changed

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,48 @@ void *arm_smmu_hw_info(struct device *dev, u32 *length, u32 *type)
2929

3030
return info;
3131
}
32+
33+
static const struct iommufd_viommu_ops arm_vsmmu_ops = {
34+
};
35+
36+
struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
37+
struct iommu_domain *parent,
38+
struct iommufd_ctx *ictx,
39+
unsigned int viommu_type)
40+
{
41+
struct arm_smmu_device *smmu =
42+
iommu_get_iommu_dev(dev, struct arm_smmu_device, iommu);
43+
struct arm_smmu_master *master = dev_iommu_priv_get(dev);
44+
struct arm_smmu_domain *s2_parent = to_smmu_domain(parent);
45+
struct arm_vsmmu *vsmmu;
46+
47+
if (viommu_type != IOMMU_VIOMMU_TYPE_ARM_SMMUV3)
48+
return ERR_PTR(-EOPNOTSUPP);
49+
50+
if (!(smmu->features & ARM_SMMU_FEAT_NESTING))
51+
return ERR_PTR(-EOPNOTSUPP);
52+
53+
if (s2_parent->smmu != master->smmu)
54+
return ERR_PTR(-EINVAL);
55+
56+
/*
57+
* Must support some way to prevent the VM from bypassing the cache
58+
* because VFIO currently does not do any cache maintenance. canwbs
59+
* indicates the device is fully coherent and no cache maintenance is
60+
* ever required, even for PCI No-Snoop.
61+
*/
62+
if (!arm_smmu_master_canwbs(master))
63+
return ERR_PTR(-EOPNOTSUPP);
64+
65+
vsmmu = iommufd_viommu_alloc(ictx, struct arm_vsmmu, core,
66+
&arm_vsmmu_ops);
67+
if (IS_ERR(vsmmu))
68+
return ERR_CAST(vsmmu);
69+
70+
vsmmu->smmu = smmu;
71+
vsmmu->s2_parent = s2_parent;
72+
/* FIXME Move VMID allocation from the S2 domain allocation to here */
73+
vsmmu->vmid = s2_parent->s2_cfg.vmid;
74+
75+
return &vsmmu->core;
76+
}

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3517,6 +3517,7 @@ static struct iommu_ops arm_smmu_ops = {
35173517
.dev_disable_feat = arm_smmu_dev_disable_feature,
35183518
.page_response = arm_smmu_page_response,
35193519
.def_domain_type = arm_smmu_def_domain_type,
3520+
.viommu_alloc = arm_vsmmu_alloc,
35203521
.pgsize_bitmap = -1UL, /* Restricted during device attach */
35213522
.owner = THIS_MODULE,
35223523
.default_domain_ops = &(const struct iommu_domain_ops) {

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <linux/bitfield.h>
1212
#include <linux/iommu.h>
13+
#include <linux/iommufd.h>
1314
#include <linux/kernel.h>
1415
#include <linux/mmzone.h>
1516
#include <linux/sizes.h>
@@ -976,10 +977,22 @@ tegra241_cmdqv_probe(struct arm_smmu_device *smmu)
976977
}
977978
#endif /* CONFIG_TEGRA241_CMDQV */
978979

980+
struct arm_vsmmu {
981+
struct iommufd_viommu core;
982+
struct arm_smmu_device *smmu;
983+
struct arm_smmu_domain *s2_parent;
984+
u16 vmid;
985+
};
986+
979987
#if IS_ENABLED(CONFIG_ARM_SMMU_V3_IOMMUFD)
980988
void *arm_smmu_hw_info(struct device *dev, u32 *length, u32 *type);
989+
struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
990+
struct iommu_domain *parent,
991+
struct iommufd_ctx *ictx,
992+
unsigned int viommu_type);
981993
#else
982994
#define arm_smmu_hw_info NULL
995+
#define arm_vsmmu_alloc NULL
983996
#endif /* CONFIG_ARM_SMMU_V3_IOMMUFD */
984997

985998
#endif /* _ARM_SMMU_V3_H */

include/uapi/linux/iommufd.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,10 +425,12 @@ struct iommu_hwpt_vtd_s1 {
425425
* enum iommu_hwpt_data_type - IOMMU HWPT Data Type
426426
* @IOMMU_HWPT_DATA_NONE: no data
427427
* @IOMMU_HWPT_DATA_VTD_S1: Intel VT-d stage-1 page table
428+
* @IOMMU_HWPT_DATA_ARM_SMMUV3: ARM SMMUv3 Context Descriptor Table
428429
*/
429430
enum iommu_hwpt_data_type {
430431
IOMMU_HWPT_DATA_NONE = 0,
431432
IOMMU_HWPT_DATA_VTD_S1 = 1,
433+
IOMMU_HWPT_DATA_ARM_SMMUV3 = 2,
432434
};
433435

434436
/**
@@ -868,9 +870,11 @@ struct iommu_fault_alloc {
868870
/**
869871
* enum iommu_viommu_type - Virtual IOMMU Type
870872
* @IOMMU_VIOMMU_TYPE_DEFAULT: Reserved for future use
873+
* @IOMMU_VIOMMU_TYPE_ARM_SMMUV3: ARM SMMUv3 driver specific type
871874
*/
872875
enum iommu_viommu_type {
873876
IOMMU_VIOMMU_TYPE_DEFAULT = 0,
877+
IOMMU_VIOMMU_TYPE_ARM_SMMUV3 = 1,
874878
};
875879

876880
/**

0 commit comments

Comments
 (0)