IOMMU Updates for Linux v5.6
Including: - Allow to compile the ARM-SMMU drivers as modules. - Fixes and cleanups for the ARM-SMMU drivers and io-pgtable code collected by Will Deacon. The merge-commit (6855d1ba75) has all the details. - Cleanup of the iommu_put_resv_regions() call-backs in various drivers. - AMD IOMMU driver cleanups. - Update for the x2APIC support in the AMD IOMMU driver. - Preparation patches for Intel VT-d nested mode support. - RMRR and identity domain handling fixes for the Intel VT-d driver. - More small fixes and cleanups. -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEr9jSbILcajRFYWYyK/BELZcBGuMFAl46yTsACgkQK/BELZcB GuPldg//bHDyntUWHta11oHFnUh759mveFFsfYto/2dV7hyHOM1lgv2+ZaXdOYxE 03f9d9K9b4F3amF8wkluu9Z1Lve40JpZwD3WKTTg8sImh0z61nWoJ7+uE8ZjNzmA /6pNqIPJ4w8n5Wz2yycTR7GeUekM0X5nvF0IBlVcX3UYFG0DDlL/eldLVSk43Wmw P9C2dFwQLHBKhqhquqnXP1Z7YRfG9lX2ONAoMHSj3x2fm7UySSkrioBR0VrI6+sH 8/LFL+NgqQEZBTK0I8tZRwNuDUoHQ396PAdYEiXFFzWBLrEaadAuoh4WeLnLzlRe G601on9ScUg1xy4lQHQiZDNKYqeB7gETMW/V2Q5nCaTrq2i1D5M6IwiNvOiV6crj ZtFBqejng1BXfqLOxutHYyjNQBB/KxmWR3zT2p/spcAgxhUAJxS5GkbGm5G3OucN 2xWSnV+Dyu5jei8Ua5/onCdcuvCFi41xa9aCRrTSymIZ2W6aCNjm2mrctyRr1xmA AwHBZ0/dx/v3vZA8GnkBrrvAYVsTWiMbHD/2sChDjnwedO0o0pMooHEjywmDgMON /qXQjqR7pDpyxDA0US+30WfA3tkUcpLskza0ugWKtr/8RcHffrt5s9L0PpklgmtN ILC2/zNB43mIFw8uGJdDVFw4aYuCAqIFFHkqQ5+hOBGn/ePHawc= =HMIT -----END PGP SIGNATURE----- Merge tag 'iommu-updates-v5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu Pull iommu updates from Joerg Roedel: - Allow compiling the ARM-SMMU drivers as modules. - Fixes and cleanups for the ARM-SMMU drivers and io-pgtable code collected by Will Deacon. The merge-commit (6855d1ba75) has all the details. - Cleanup of the iommu_put_resv_regions() call-backs in various drivers. - AMD IOMMU driver cleanups. - Update for the x2APIC support in the AMD IOMMU driver. - Preparation patches for Intel VT-d nested mode support. - RMRR and identity domain handling fixes for the Intel VT-d driver. - More small fixes and cleanups. * tag 'iommu-updates-v5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: (87 commits) iommu/amd: Remove the unnecessary assignment iommu/vt-d: Remove unnecessary WARN_ON_ONCE() iommu/vt-d: Unnecessary to handle default identity domain iommu/vt-d: Allow devices with RMRRs to use identity domain iommu/vt-d: Add RMRR base and end addresses sanity check iommu/vt-d: Mark firmware tainted if RMRR fails sanity check iommu/amd: Remove unused struct member iommu/amd: Replace two consecutive readl calls with one readq iommu/vt-d: Don't reject Host Bridge due to scope mismatch PCI/ATS: Add PASID stubs iommu/arm-smmu-v3: Return -EBUSY when trying to re-add a device iommu/arm-smmu-v3: Improve add_device() error handling iommu/arm-smmu-v3: Use WRITE_ONCE() when changing validity of an STE iommu/arm-smmu-v3: Add second level of context descriptor table iommu/arm-smmu-v3: Prepare for handling arm_smmu_write_ctx_desc() failure iommu/arm-smmu-v3: Propagate ssid_bits iommu/arm-smmu-v3: Add support for Substream IDs iommu/arm-smmu-v3: Add context descriptor tables allocators iommu/arm-smmu-v3: Prepare arm_smmu_s1_cfg for SSID support ACPI/IORT: Parse SSID property of named component node ...
This commit is contained in:
commit
4fc2ea6a86
36 changed files with 1685 additions and 821 deletions
|
|
@ -34,10 +34,13 @@
|
|||
#define VTD_STRIDE_SHIFT (9)
|
||||
#define VTD_STRIDE_MASK (((u64)-1) << VTD_STRIDE_SHIFT)
|
||||
|
||||
#define DMA_PTE_READ (1)
|
||||
#define DMA_PTE_WRITE (2)
|
||||
#define DMA_PTE_LARGE_PAGE (1 << 7)
|
||||
#define DMA_PTE_SNP (1 << 11)
|
||||
#define DMA_PTE_READ BIT_ULL(0)
|
||||
#define DMA_PTE_WRITE BIT_ULL(1)
|
||||
#define DMA_PTE_LARGE_PAGE BIT_ULL(7)
|
||||
#define DMA_PTE_SNP BIT_ULL(11)
|
||||
|
||||
#define DMA_FL_PTE_PRESENT BIT_ULL(0)
|
||||
#define DMA_FL_PTE_XD BIT_ULL(63)
|
||||
|
||||
#define CONTEXT_TT_MULTI_LEVEL 0
|
||||
#define CONTEXT_TT_DEV_IOTLB 1
|
||||
|
|
@ -435,8 +438,10 @@ enum {
|
|||
|
||||
#define VTD_FLAG_TRANS_PRE_ENABLED (1 << 0)
|
||||
#define VTD_FLAG_IRQ_REMAP_PRE_ENABLED (1 << 1)
|
||||
#define VTD_FLAG_SVM_CAPABLE (1 << 2)
|
||||
|
||||
extern int intel_iommu_sm;
|
||||
extern spinlock_t device_domain_lock;
|
||||
|
||||
#define sm_supported(iommu) (intel_iommu_sm && ecap_smts((iommu)->ecap))
|
||||
#define pasid_supported(iommu) (sm_supported(iommu) && \
|
||||
|
|
@ -609,10 +614,11 @@ static inline void dma_clear_pte(struct dma_pte *pte)
|
|||
static inline u64 dma_pte_addr(struct dma_pte *pte)
|
||||
{
|
||||
#ifdef CONFIG_64BIT
|
||||
return pte->val & VTD_PAGE_MASK;
|
||||
return pte->val & VTD_PAGE_MASK & (~DMA_FL_PTE_XD);
|
||||
#else
|
||||
/* Must have a full atomic 64-bit read */
|
||||
return __cmpxchg64(&pte->val, 0ULL, 0ULL) & VTD_PAGE_MASK;
|
||||
return __cmpxchg64(&pte->val, 0ULL, 0ULL) &
|
||||
VTD_PAGE_MASK & (~DMA_FL_PTE_XD);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -645,6 +651,8 @@ extern void qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
|
|||
unsigned int size_order, u64 type);
|
||||
extern void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 pfsid,
|
||||
u16 qdep, u64 addr, unsigned mask);
|
||||
void qi_flush_piotlb(struct intel_iommu *iommu, u16 did, u32 pasid, u64 addr,
|
||||
unsigned long npages, bool ih);
|
||||
extern int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu);
|
||||
|
||||
extern int dmar_ir_support(void);
|
||||
|
|
@ -656,9 +664,10 @@ int for_each_device_domain(int (*fn)(struct device_domain_info *info,
|
|||
void *data), void *data);
|
||||
void iommu_flush_write_buffer(struct intel_iommu *iommu);
|
||||
int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev);
|
||||
struct dmar_domain *find_domain(struct device *dev);
|
||||
|
||||
#ifdef CONFIG_INTEL_IOMMU_SVM
|
||||
int intel_svm_init(struct intel_iommu *iommu);
|
||||
extern void intel_svm_check(struct intel_iommu *iommu);
|
||||
extern int intel_svm_enable_prq(struct intel_iommu *iommu);
|
||||
extern int intel_svm_finish_prq(struct intel_iommu *iommu);
|
||||
|
||||
|
|
@ -686,6 +695,8 @@ struct intel_svm {
|
|||
};
|
||||
|
||||
extern struct intel_iommu *intel_svm_device_to_iommu(struct device *dev);
|
||||
#else
|
||||
static inline void intel_svm_check(struct intel_iommu *iommu) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_INTEL_IOMMU_DEBUGFS
|
||||
|
|
|
|||
|
|
@ -83,12 +83,16 @@ struct io_pgtable_cfg {
|
|||
* IO_PGTABLE_QUIRK_NON_STRICT: Skip issuing synchronous leaf TLBIs
|
||||
* on unmap, for DMA domains using the flush queue mechanism for
|
||||
* delayed invalidation.
|
||||
*
|
||||
* IO_PGTABLE_QUIRK_ARM_TTBR1: (ARM LPAE format) Configure the table
|
||||
* for use in the upper half of a split address space.
|
||||
*/
|
||||
#define IO_PGTABLE_QUIRK_ARM_NS BIT(0)
|
||||
#define IO_PGTABLE_QUIRK_NO_PERMS BIT(1)
|
||||
#define IO_PGTABLE_QUIRK_TLBI_ON_MAP BIT(2)
|
||||
#define IO_PGTABLE_QUIRK_ARM_MTK_EXT BIT(3)
|
||||
#define IO_PGTABLE_QUIRK_NON_STRICT BIT(4)
|
||||
#define IO_PGTABLE_QUIRK_ARM_TTBR1 BIT(5)
|
||||
unsigned long quirks;
|
||||
unsigned long pgsize_bitmap;
|
||||
unsigned int ias;
|
||||
|
|
@ -100,18 +104,33 @@ struct io_pgtable_cfg {
|
|||
/* Low-level data specific to the table format */
|
||||
union {
|
||||
struct {
|
||||
u64 ttbr[2];
|
||||
u64 tcr;
|
||||
u64 ttbr;
|
||||
struct {
|
||||
u32 ips:3;
|
||||
u32 tg:2;
|
||||
u32 sh:2;
|
||||
u32 orgn:2;
|
||||
u32 irgn:2;
|
||||
u32 tsz:6;
|
||||
} tcr;
|
||||
u64 mair;
|
||||
} arm_lpae_s1_cfg;
|
||||
|
||||
struct {
|
||||
u64 vttbr;
|
||||
u64 vtcr;
|
||||
struct {
|
||||
u32 ps:3;
|
||||
u32 tg:2;
|
||||
u32 sh:2;
|
||||
u32 orgn:2;
|
||||
u32 irgn:2;
|
||||
u32 sl:2;
|
||||
u32 tsz:6;
|
||||
} vtcr;
|
||||
} arm_lpae_s2_cfg;
|
||||
|
||||
struct {
|
||||
u32 ttbr[2];
|
||||
u32 ttbr;
|
||||
u32 tcr;
|
||||
u32 nmrr;
|
||||
u32 prrr;
|
||||
|
|
|
|||
|
|
@ -246,9 +246,10 @@ struct iommu_iotlb_gather {
|
|||
* @sva_get_pasid: Get PASID associated to a SVA handle
|
||||
* @page_response: handle page request response
|
||||
* @cache_invalidate: invalidate translation caches
|
||||
* @pgsize_bitmap: bitmap of all possible supported page sizes
|
||||
* @sva_bind_gpasid: bind guest pasid and mm
|
||||
* @sva_unbind_gpasid: unbind guest pasid and mm
|
||||
* @pgsize_bitmap: bitmap of all possible supported page sizes
|
||||
* @owner: Driver module providing these ops
|
||||
*/
|
||||
struct iommu_ops {
|
||||
bool (*capable)(enum iommu_cap);
|
||||
|
|
@ -318,6 +319,7 @@ struct iommu_ops {
|
|||
int (*sva_unbind_gpasid)(struct device *dev, int pasid);
|
||||
|
||||
unsigned long pgsize_bitmap;
|
||||
struct module *owner;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -386,12 +388,19 @@ void iommu_device_sysfs_remove(struct iommu_device *iommu);
|
|||
int iommu_device_link(struct iommu_device *iommu, struct device *link);
|
||||
void iommu_device_unlink(struct iommu_device *iommu, struct device *link);
|
||||
|
||||
static inline void iommu_device_set_ops(struct iommu_device *iommu,
|
||||
const struct iommu_ops *ops)
|
||||
static inline void __iommu_device_set_ops(struct iommu_device *iommu,
|
||||
const struct iommu_ops *ops)
|
||||
{
|
||||
iommu->ops = ops;
|
||||
}
|
||||
|
||||
#define iommu_device_set_ops(iommu, ops) \
|
||||
do { \
|
||||
struct iommu_ops *__ops = (struct iommu_ops *)(ops); \
|
||||
__ops->owner = THIS_MODULE; \
|
||||
__iommu_device_set_ops(iommu, __ops); \
|
||||
} while (0)
|
||||
|
||||
static inline void iommu_device_set_fwnode(struct iommu_device *iommu,
|
||||
struct fwnode_handle *fwnode)
|
||||
{
|
||||
|
|
@ -456,6 +465,8 @@ extern void iommu_set_fault_handler(struct iommu_domain *domain,
|
|||
|
||||
extern void iommu_get_resv_regions(struct device *dev, struct list_head *list);
|
||||
extern void iommu_put_resv_regions(struct device *dev, struct list_head *list);
|
||||
extern void generic_iommu_put_resv_regions(struct device *dev,
|
||||
struct list_head *list);
|
||||
extern int iommu_request_dm_for_dev(struct device *dev);
|
||||
extern int iommu_request_dma_domain_for_dev(struct device *dev);
|
||||
extern void iommu_set_default_passthrough(bool cmd_line);
|
||||
|
|
@ -570,6 +581,7 @@ struct iommu_group *fsl_mc_device_group(struct device *dev);
|
|||
* @ops: ops for this device's IOMMU
|
||||
* @iommu_fwnode: firmware handle for this device's IOMMU
|
||||
* @iommu_priv: IOMMU driver private data for this device
|
||||
* @num_pasid_bits: number of PASID bits supported by this device
|
||||
* @num_ids: number of associated device IDs
|
||||
* @ids: IDs which this device may present to the IOMMU
|
||||
*/
|
||||
|
|
@ -578,6 +590,7 @@ struct iommu_fwspec {
|
|||
struct fwnode_handle *iommu_fwnode;
|
||||
void *iommu_priv;
|
||||
u32 flags;
|
||||
u32 num_pasid_bits;
|
||||
unsigned int num_ids;
|
||||
u32 ids[1];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ void pci_disable_pasid(struct pci_dev *pdev);
|
|||
int pci_pasid_features(struct pci_dev *pdev);
|
||||
int pci_max_pasids(struct pci_dev *pdev);
|
||||
#else /* CONFIG_PCI_PASID */
|
||||
static inline int pci_enable_pasid(struct pci_dev *pdev, int features)
|
||||
{ return -EINVAL; }
|
||||
static inline void pci_disable_pasid(struct pci_dev *pdev) { }
|
||||
static inline int pci_pasid_features(struct pci_dev *pdev)
|
||||
{ return -EINVAL; }
|
||||
static inline int pci_max_pasids(struct pci_dev *pdev)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue