mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-29 09:13:38 +00:00
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/8-v4-9e99b76f3518+3a8-smmuv3_nesting_jgg@nvidia.com Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> Tested-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
parent
4e6bd13aa3
commit
69d9b312f3
@ -29,3 +29,48 @@ void *arm_smmu_hw_info(struct device *dev, u32 *length, u32 *type)
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static const struct iommufd_viommu_ops arm_vsmmu_ops = {
|
||||
};
|
||||
|
||||
struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
|
||||
struct iommu_domain *parent,
|
||||
struct iommufd_ctx *ictx,
|
||||
unsigned int viommu_type)
|
||||
{
|
||||
struct arm_smmu_device *smmu =
|
||||
iommu_get_iommu_dev(dev, struct arm_smmu_device, iommu);
|
||||
struct arm_smmu_master *master = dev_iommu_priv_get(dev);
|
||||
struct arm_smmu_domain *s2_parent = to_smmu_domain(parent);
|
||||
struct arm_vsmmu *vsmmu;
|
||||
|
||||
if (viommu_type != IOMMU_VIOMMU_TYPE_ARM_SMMUV3)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
if (!(smmu->features & ARM_SMMU_FEAT_NESTING))
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
if (s2_parent->smmu != master->smmu)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/*
|
||||
* Must support some way to prevent the VM from bypassing the cache
|
||||
* because VFIO currently does not do any cache maintenance. canwbs
|
||||
* indicates the device is fully coherent and no cache maintenance is
|
||||
* ever required, even for PCI No-Snoop.
|
||||
*/
|
||||
if (!arm_smmu_master_canwbs(master))
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
vsmmu = iommufd_viommu_alloc(ictx, struct arm_vsmmu, core,
|
||||
&arm_vsmmu_ops);
|
||||
if (IS_ERR(vsmmu))
|
||||
return ERR_CAST(vsmmu);
|
||||
|
||||
vsmmu->smmu = smmu;
|
||||
vsmmu->s2_parent = s2_parent;
|
||||
/* FIXME Move VMID allocation from the S2 domain allocation to here */
|
||||
vsmmu->vmid = s2_parent->s2_cfg.vmid;
|
||||
|
||||
return &vsmmu->core;
|
||||
}
|
||||
|
@ -3517,6 +3517,7 @@ static struct iommu_ops arm_smmu_ops = {
|
||||
.dev_disable_feat = arm_smmu_dev_disable_feature,
|
||||
.page_response = arm_smmu_page_response,
|
||||
.def_domain_type = arm_smmu_def_domain_type,
|
||||
.viommu_alloc = arm_vsmmu_alloc,
|
||||
.pgsize_bitmap = -1UL, /* Restricted during device attach */
|
||||
.owner = THIS_MODULE,
|
||||
.default_domain_ops = &(const struct iommu_domain_ops) {
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/iommufd.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mmzone.h>
|
||||
#include <linux/sizes.h>
|
||||
@ -976,10 +977,22 @@ tegra241_cmdqv_probe(struct arm_smmu_device *smmu)
|
||||
}
|
||||
#endif /* CONFIG_TEGRA241_CMDQV */
|
||||
|
||||
struct arm_vsmmu {
|
||||
struct iommufd_viommu core;
|
||||
struct arm_smmu_device *smmu;
|
||||
struct arm_smmu_domain *s2_parent;
|
||||
u16 vmid;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_ARM_SMMU_V3_IOMMUFD)
|
||||
void *arm_smmu_hw_info(struct device *dev, u32 *length, u32 *type);
|
||||
struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
|
||||
struct iommu_domain *parent,
|
||||
struct iommufd_ctx *ictx,
|
||||
unsigned int viommu_type);
|
||||
#else
|
||||
#define arm_smmu_hw_info NULL
|
||||
#define arm_vsmmu_alloc NULL
|
||||
#endif /* CONFIG_ARM_SMMU_V3_IOMMUFD */
|
||||
|
||||
#endif /* _ARM_SMMU_V3_H */
|
||||
|
@ -425,10 +425,12 @@ struct iommu_hwpt_vtd_s1 {
|
||||
* enum iommu_hwpt_data_type - IOMMU HWPT Data Type
|
||||
* @IOMMU_HWPT_DATA_NONE: no data
|
||||
* @IOMMU_HWPT_DATA_VTD_S1: Intel VT-d stage-1 page table
|
||||
* @IOMMU_HWPT_DATA_ARM_SMMUV3: ARM SMMUv3 Context Descriptor Table
|
||||
*/
|
||||
enum iommu_hwpt_data_type {
|
||||
IOMMU_HWPT_DATA_NONE = 0,
|
||||
IOMMU_HWPT_DATA_VTD_S1 = 1,
|
||||
IOMMU_HWPT_DATA_ARM_SMMUV3 = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -868,9 +870,11 @@ struct iommu_fault_alloc {
|
||||
/**
|
||||
* enum iommu_viommu_type - Virtual IOMMU Type
|
||||
* @IOMMU_VIOMMU_TYPE_DEFAULT: Reserved for future use
|
||||
* @IOMMU_VIOMMU_TYPE_ARM_SMMUV3: ARM SMMUv3 driver specific type
|
||||
*/
|
||||
enum iommu_viommu_type {
|
||||
IOMMU_VIOMMU_TYPE_DEFAULT = 0,
|
||||
IOMMU_VIOMMU_TYPE_ARM_SMMUV3 = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user