diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-09 12:21:02 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-09 12:21:02 -0400 |
| commit | 6b04014f3f151ed62878327813859e76e8e23d78 (patch) | |
| tree | 217c5d024b92f5ba5df910c50dc555b80537b721 /include/linux | |
| parent | c6b6cebbc597aaf7d941f781b5fc114c58cc3352 (diff) | |
| parent | d95c3885865b71e56d8d60c8617f2ce1f0fa079d (diff) | |
Merge tag 'iommu-updates-v5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull iommu updates from Joerg Roedel:
- Make the dma-iommu code more generic so that it can be used outside
of the ARM context with other IOMMU drivers. Goal is to make use of
it on x86 too.
- Generic IOMMU domain support for the Intel VT-d driver. This driver
now makes more use of common IOMMU code to allocate default domains
for the devices it handles.
- An IOMMU fault reporting API to userspace. With that the IOMMU fault
handling can be done in user-space, for example to forward the faults
to a VM.
- Better handling for reserved regions requested by the firmware. These
can be 'relaxed' now, meaning that those don't prevent a device being
attached to a VM.
- Suspend/Resume support for the Renesas IOMMU driver.
- Added support for dumping SVA related fields of the DMAR table in the
Intel VT-d driver via debugfs.
- A pile of smaller fixes and cleanups.
* tag 'iommu-updates-v5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: (90 commits)
iommu/omap: No need to check return value of debugfs_create functions
iommu/arm-smmu-v3: Invalidate ATC when detaching a device
iommu/arm-smmu-v3: Fix compilation when CONFIG_CMA=n
iommu/vt-d: Cleanup unused variable
iommu/amd: Flush not present cache in iommu_map_page
iommu/amd: Only free resources once on init error
iommu/amd: Move gart fallback to amd_iommu_init
iommu/amd: Make iommu_disable safer
iommu/io-pgtable: Support non-coherent page tables
iommu/io-pgtable: Replace IO_PGTABLE_QUIRK_NO_DMA with specific flag
iommu/io-pgtable-arm: Add support to use system cache
iommu/arm-smmu-v3: Increase maximum size of queues
iommu/vt-d: Silence a variable set but not used
iommu/vt-d: Remove an unused variable "length"
iommu: Fix integer truncation
iommu: Add padding to struct iommu_fault
iommu/vt-d: Consolidate domain_init() to avoid duplication
iommu/vt-d: Cleanup after delegating DMA domain to generic iommu
iommu/vt-d: Fix suspicious RCU usage in probe_acpi_namespace_devices()
iommu/vt-d: Allow DMA domain attaching to rmrr locked device
...
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/device.h | 3 | ||||
| -rw-r--r-- | include/linux/dma-iommu.h | 49 | ||||
| -rw-r--r-- | include/linux/intel-iommu.h | 7 | ||||
| -rw-r--r-- | include/linux/intel-svm.h | 2 | ||||
| -rw-r--r-- | include/linux/io-pgtable.h | 11 | ||||
| -rw-r--r-- | include/linux/iommu.h | 105 |
6 files changed, 124 insertions, 53 deletions
diff --git a/include/linux/device.h b/include/linux/device.h index 4a295e324ac5..b6ff25d9fff4 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
| @@ -42,6 +42,7 @@ struct iommu_ops; | |||
| 42 | struct iommu_group; | 42 | struct iommu_group; |
| 43 | struct iommu_fwspec; | 43 | struct iommu_fwspec; |
| 44 | struct dev_pin_info; | 44 | struct dev_pin_info; |
| 45 | struct iommu_param; | ||
| 45 | 46 | ||
| 46 | struct bus_attribute { | 47 | struct bus_attribute { |
| 47 | struct attribute attr; | 48 | struct attribute attr; |
| @@ -961,6 +962,7 @@ struct dev_links_info { | |||
| 961 | * device (i.e. the bus driver that discovered the device). | 962 | * device (i.e. the bus driver that discovered the device). |
| 962 | * @iommu_group: IOMMU group the device belongs to. | 963 | * @iommu_group: IOMMU group the device belongs to. |
| 963 | * @iommu_fwspec: IOMMU-specific properties supplied by firmware. | 964 | * @iommu_fwspec: IOMMU-specific properties supplied by firmware. |
| 965 | * @iommu_param: Per device generic IOMMU runtime data | ||
| 964 | * | 966 | * |
| 965 | * @offline_disabled: If set, the device is permanently online. | 967 | * @offline_disabled: If set, the device is permanently online. |
| 966 | * @offline: Set after successful invocation of bus type's .offline(). | 968 | * @offline: Set after successful invocation of bus type's .offline(). |
| @@ -1054,6 +1056,7 @@ struct device { | |||
| 1054 | void (*release)(struct device *dev); | 1056 | void (*release)(struct device *dev); |
| 1055 | struct iommu_group *iommu_group; | 1057 | struct iommu_group *iommu_group; |
| 1056 | struct iommu_fwspec *iommu_fwspec; | 1058 | struct iommu_fwspec *iommu_fwspec; |
| 1059 | struct iommu_param *iommu_param; | ||
| 1057 | 1060 | ||
| 1058 | bool offline_disabled:1; | 1061 | bool offline_disabled:1; |
| 1059 | bool offline:1; | 1062 | bool offline:1; |
diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h index 37258c8b2063..2112f21f73d8 100644 --- a/include/linux/dma-iommu.h +++ b/include/linux/dma-iommu.h | |||
| @@ -5,59 +5,21 @@ | |||
| 5 | #ifndef __DMA_IOMMU_H | 5 | #ifndef __DMA_IOMMU_H |
| 6 | #define __DMA_IOMMU_H | 6 | #define __DMA_IOMMU_H |
| 7 | 7 | ||
| 8 | #ifdef __KERNEL__ | 8 | #include <linux/errno.h> |
| 9 | #include <linux/types.h> | 9 | #include <linux/types.h> |
| 10 | #include <asm/errno.h> | ||
| 11 | 10 | ||
| 12 | #ifdef CONFIG_IOMMU_DMA | 11 | #ifdef CONFIG_IOMMU_DMA |
| 13 | #include <linux/dma-mapping.h> | 12 | #include <linux/dma-mapping.h> |
| 14 | #include <linux/iommu.h> | 13 | #include <linux/iommu.h> |
| 15 | #include <linux/msi.h> | 14 | #include <linux/msi.h> |
| 16 | 15 | ||
| 17 | int iommu_dma_init(void); | ||
| 18 | |||
| 19 | /* Domain management interface for IOMMU drivers */ | 16 | /* Domain management interface for IOMMU drivers */ |
| 20 | int iommu_get_dma_cookie(struct iommu_domain *domain); | 17 | int iommu_get_dma_cookie(struct iommu_domain *domain); |
| 21 | int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base); | 18 | int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base); |
| 22 | void iommu_put_dma_cookie(struct iommu_domain *domain); | 19 | void iommu_put_dma_cookie(struct iommu_domain *domain); |
| 23 | 20 | ||
| 24 | /* Setup call for arch DMA mapping code */ | 21 | /* Setup call for arch DMA mapping code */ |
| 25 | int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base, | 22 | void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size); |
| 26 | u64 size, struct device *dev); | ||
| 27 | |||
| 28 | /* General helpers for DMA-API <-> IOMMU-API interaction */ | ||
| 29 | int dma_info_to_prot(enum dma_data_direction dir, bool coherent, | ||
| 30 | unsigned long attrs); | ||
| 31 | |||
| 32 | /* | ||
| 33 | * These implement the bulk of the relevant DMA mapping callbacks, but require | ||
| 34 | * the arch code to take care of attributes and cache maintenance | ||
| 35 | */ | ||
| 36 | struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp, | ||
| 37 | unsigned long attrs, int prot, dma_addr_t *handle, | ||
| 38 | void (*flush_page)(struct device *, const void *, phys_addr_t)); | ||
| 39 | void iommu_dma_free(struct device *dev, struct page **pages, size_t size, | ||
| 40 | dma_addr_t *handle); | ||
| 41 | |||
| 42 | int iommu_dma_mmap(struct page **pages, size_t size, struct vm_area_struct *vma); | ||
| 43 | |||
| 44 | dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page, | ||
| 45 | unsigned long offset, size_t size, int prot); | ||
| 46 | int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg, | ||
| 47 | int nents, int prot); | ||
| 48 | |||
| 49 | /* | ||
| 50 | * Arch code with no special attribute handling may use these | ||
| 51 | * directly as DMA mapping callbacks for simplicity | ||
| 52 | */ | ||
| 53 | void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size, | ||
| 54 | enum dma_data_direction dir, unsigned long attrs); | ||
| 55 | void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, | ||
| 56 | enum dma_data_direction dir, unsigned long attrs); | ||
| 57 | dma_addr_t iommu_dma_map_resource(struct device *dev, phys_addr_t phys, | ||
| 58 | size_t size, enum dma_data_direction dir, unsigned long attrs); | ||
| 59 | void iommu_dma_unmap_resource(struct device *dev, dma_addr_t handle, | ||
| 60 | size_t size, enum dma_data_direction dir, unsigned long attrs); | ||
| 61 | 23 | ||
| 62 | /* The DMA API isn't _quite_ the whole story, though... */ | 24 | /* The DMA API isn't _quite_ the whole story, though... */ |
| 63 | /* | 25 | /* |
| @@ -75,16 +37,16 @@ void iommu_dma_compose_msi_msg(struct msi_desc *desc, | |||
| 75 | 37 | ||
| 76 | void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list); | 38 | void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list); |
| 77 | 39 | ||
| 78 | #else | 40 | #else /* CONFIG_IOMMU_DMA */ |
| 79 | 41 | ||
| 80 | struct iommu_domain; | 42 | struct iommu_domain; |
| 81 | struct msi_desc; | 43 | struct msi_desc; |
| 82 | struct msi_msg; | 44 | struct msi_msg; |
| 83 | struct device; | 45 | struct device; |
| 84 | 46 | ||
| 85 | static inline int iommu_dma_init(void) | 47 | static inline void iommu_setup_dma_ops(struct device *dev, u64 dma_base, |
| 48 | u64 size) | ||
| 86 | { | 49 | { |
| 87 | return 0; | ||
| 88 | } | 50 | } |
| 89 | 51 | ||
| 90 | static inline int iommu_get_dma_cookie(struct iommu_domain *domain) | 52 | static inline int iommu_get_dma_cookie(struct iommu_domain *domain) |
| @@ -117,5 +79,4 @@ static inline void iommu_dma_get_resv_regions(struct device *dev, struct list_he | |||
| 117 | } | 79 | } |
| 118 | 80 | ||
| 119 | #endif /* CONFIG_IOMMU_DMA */ | 81 | #endif /* CONFIG_IOMMU_DMA */ |
| 120 | #endif /* __KERNEL__ */ | ||
| 121 | #endif /* __DMA_IOMMU_H */ | 82 | #endif /* __DMA_IOMMU_H */ |
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 6a8dd4af0147..f2ae8a006ff8 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h | |||
| @@ -435,6 +435,12 @@ enum { | |||
| 435 | #define VTD_FLAG_TRANS_PRE_ENABLED (1 << 0) | 435 | #define VTD_FLAG_TRANS_PRE_ENABLED (1 << 0) |
| 436 | #define VTD_FLAG_IRQ_REMAP_PRE_ENABLED (1 << 1) | 436 | #define VTD_FLAG_IRQ_REMAP_PRE_ENABLED (1 << 1) |
| 437 | 437 | ||
| 438 | extern int intel_iommu_sm; | ||
| 439 | |||
| 440 | #define sm_supported(iommu) (intel_iommu_sm && ecap_smts((iommu)->ecap)) | ||
| 441 | #define pasid_supported(iommu) (sm_supported(iommu) && \ | ||
| 442 | ecap_pasid((iommu)->ecap)) | ||
| 443 | |||
| 438 | struct pasid_entry; | 444 | struct pasid_entry; |
| 439 | struct pasid_state_entry; | 445 | struct pasid_state_entry; |
| 440 | struct page_req_dsc; | 446 | struct page_req_dsc; |
| @@ -642,7 +648,6 @@ extern int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu); | |||
| 642 | 648 | ||
| 643 | extern int dmar_ir_support(void); | 649 | extern int dmar_ir_support(void); |
| 644 | 650 | ||
| 645 | struct dmar_domain *get_valid_domain_for_dev(struct device *dev); | ||
| 646 | void *alloc_pgtable_page(int node); | 651 | void *alloc_pgtable_page(int node); |
| 647 | void free_pgtable_page(void *vaddr); | 652 | void free_pgtable_page(void *vaddr); |
| 648 | struct intel_iommu *domain_get_iommu(struct dmar_domain *domain); | 653 | struct intel_iommu *domain_get_iommu(struct dmar_domain *domain); |
diff --git a/include/linux/intel-svm.h b/include/linux/intel-svm.h index 54ffcc6a322e..94f047a8a845 100644 --- a/include/linux/intel-svm.h +++ b/include/linux/intel-svm.h | |||
| @@ -49,7 +49,7 @@ struct svm_dev_ops { | |||
| 49 | 49 | ||
| 50 | /** | 50 | /** |
| 51 | * intel_svm_bind_mm() - Bind the current process to a PASID | 51 | * intel_svm_bind_mm() - Bind the current process to a PASID |
| 52 | * @dev: Device to be granted acccess | 52 | * @dev: Device to be granted access |
| 53 | * @pasid: Address for allocated PASID | 53 | * @pasid: Address for allocated PASID |
| 54 | * @flags: Flags. Later for requesting supervisor mode, etc. | 54 | * @flags: Flags. Later for requesting supervisor mode, etc. |
| 55 | * @ops: Callbacks to device driver | 55 | * @ops: Callbacks to device driver |
diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h index 76969a564831..b5a450a3bb47 100644 --- a/include/linux/io-pgtable.h +++ b/include/linux/io-pgtable.h | |||
| @@ -44,6 +44,8 @@ struct iommu_gather_ops { | |||
| 44 | * tables. | 44 | * tables. |
| 45 | * @ias: Input address (iova) size, in bits. | 45 | * @ias: Input address (iova) size, in bits. |
| 46 | * @oas: Output address (paddr) size, in bits. | 46 | * @oas: Output address (paddr) size, in bits. |
| 47 | * @coherent_walk A flag to indicate whether or not page table walks made | ||
| 48 | * by the IOMMU are coherent with the CPU caches. | ||
| 47 | * @tlb: TLB management callbacks for this set of tables. | 49 | * @tlb: TLB management callbacks for this set of tables. |
| 48 | * @iommu_dev: The device representing the DMA configuration for the | 50 | * @iommu_dev: The device representing the DMA configuration for the |
| 49 | * page table walker. | 51 | * page table walker. |
| @@ -68,11 +70,6 @@ struct io_pgtable_cfg { | |||
| 68 | * when the SoC is in "4GB mode" and they can only access the high | 70 | * when the SoC is in "4GB mode" and they can only access the high |
| 69 | * remap of DRAM (0x1_00000000 to 0x1_ffffffff). | 71 | * remap of DRAM (0x1_00000000 to 0x1_ffffffff). |
| 70 | * | 72 | * |
| 71 | * IO_PGTABLE_QUIRK_NO_DMA: Guarantees that the tables will only ever | ||
| 72 | * be accessed by a fully cache-coherent IOMMU or CPU (e.g. for a | ||
| 73 | * software-emulated IOMMU), such that pagetable updates need not | ||
| 74 | * be treated as explicit DMA data. | ||
| 75 | * | ||
| 76 | * IO_PGTABLE_QUIRK_NON_STRICT: Skip issuing synchronous leaf TLBIs | 73 | * IO_PGTABLE_QUIRK_NON_STRICT: Skip issuing synchronous leaf TLBIs |
| 77 | * on unmap, for DMA domains using the flush queue mechanism for | 74 | * on unmap, for DMA domains using the flush queue mechanism for |
| 78 | * delayed invalidation. | 75 | * delayed invalidation. |
| @@ -81,12 +78,12 @@ struct io_pgtable_cfg { | |||
| 81 | #define IO_PGTABLE_QUIRK_NO_PERMS BIT(1) | 78 | #define IO_PGTABLE_QUIRK_NO_PERMS BIT(1) |
| 82 | #define IO_PGTABLE_QUIRK_TLBI_ON_MAP BIT(2) | 79 | #define IO_PGTABLE_QUIRK_TLBI_ON_MAP BIT(2) |
| 83 | #define IO_PGTABLE_QUIRK_ARM_MTK_4GB BIT(3) | 80 | #define IO_PGTABLE_QUIRK_ARM_MTK_4GB BIT(3) |
| 84 | #define IO_PGTABLE_QUIRK_NO_DMA BIT(4) | 81 | #define IO_PGTABLE_QUIRK_NON_STRICT BIT(4) |
| 85 | #define IO_PGTABLE_QUIRK_NON_STRICT BIT(5) | ||
| 86 | unsigned long quirks; | 82 | unsigned long quirks; |
| 87 | unsigned long pgsize_bitmap; | 83 | unsigned long pgsize_bitmap; |
| 88 | unsigned int ias; | 84 | unsigned int ias; |
| 89 | unsigned int oas; | 85 | unsigned int oas; |
| 86 | bool coherent_walk; | ||
| 90 | const struct iommu_gather_ops *tlb; | 87 | const struct iommu_gather_ops *tlb; |
| 91 | struct device *iommu_dev; | 88 | struct device *iommu_dev; |
| 92 | 89 | ||
diff --git a/include/linux/iommu.h b/include/linux/iommu.h index e552c3b63f6f..fdc355ccc570 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
| 14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
| 15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
| 16 | #include <uapi/linux/iommu.h> | ||
| 16 | 17 | ||
| 17 | #define IOMMU_READ (1 << 0) | 18 | #define IOMMU_READ (1 << 0) |
| 18 | #define IOMMU_WRITE (1 << 1) | 19 | #define IOMMU_WRITE (1 << 1) |
| @@ -29,6 +30,12 @@ | |||
| 29 | * if the IOMMU page table format is equivalent. | 30 | * if the IOMMU page table format is equivalent. |
| 30 | */ | 31 | */ |
| 31 | #define IOMMU_PRIV (1 << 5) | 32 | #define IOMMU_PRIV (1 << 5) |
| 33 | /* | ||
| 34 | * Non-coherent masters on few Qualcomm SoCs can use this page protection flag | ||
| 35 | * to set correct cacheability attributes to use an outer level of cache - | ||
| 36 | * last level cache, aka system cache. | ||
| 37 | */ | ||
| 38 | #define IOMMU_QCOM_SYS_CACHE (1 << 6) | ||
| 32 | 39 | ||
| 33 | struct iommu_ops; | 40 | struct iommu_ops; |
| 34 | struct iommu_group; | 41 | struct iommu_group; |
| @@ -37,6 +44,7 @@ struct device; | |||
| 37 | struct iommu_domain; | 44 | struct iommu_domain; |
| 38 | struct notifier_block; | 45 | struct notifier_block; |
| 39 | struct iommu_sva; | 46 | struct iommu_sva; |
| 47 | struct iommu_fault_event; | ||
| 40 | 48 | ||
| 41 | /* iommu fault flags */ | 49 | /* iommu fault flags */ |
| 42 | #define IOMMU_FAULT_READ 0x0 | 50 | #define IOMMU_FAULT_READ 0x0 |
| @@ -46,6 +54,7 @@ typedef int (*iommu_fault_handler_t)(struct iommu_domain *, | |||
| 46 | struct device *, unsigned long, int, void *); | 54 | struct device *, unsigned long, int, void *); |
| 47 | typedef int (*iommu_mm_exit_handler_t)(struct device *dev, struct iommu_sva *, | 55 | typedef int (*iommu_mm_exit_handler_t)(struct device *dev, struct iommu_sva *, |
| 48 | void *); | 56 | void *); |
| 57 | typedef int (*iommu_dev_fault_handler_t)(struct iommu_fault *, void *); | ||
| 49 | 58 | ||
| 50 | struct iommu_domain_geometry { | 59 | struct iommu_domain_geometry { |
| 51 | dma_addr_t aperture_start; /* First address that can be mapped */ | 60 | dma_addr_t aperture_start; /* First address that can be mapped */ |
| @@ -123,6 +132,12 @@ enum iommu_attr { | |||
| 123 | enum iommu_resv_type { | 132 | enum iommu_resv_type { |
| 124 | /* Memory regions which must be mapped 1:1 at all times */ | 133 | /* Memory regions which must be mapped 1:1 at all times */ |
| 125 | IOMMU_RESV_DIRECT, | 134 | IOMMU_RESV_DIRECT, |
| 135 | /* | ||
| 136 | * Memory regions which are advertised to be 1:1 but are | ||
| 137 | * commonly considered relaxable in some conditions, | ||
| 138 | * for instance in device assignment use case (USB, Graphics) | ||
| 139 | */ | ||
| 140 | IOMMU_RESV_DIRECT_RELAXABLE, | ||
| 126 | /* Arbitrary "never map this or give it to a device" address ranges */ | 141 | /* Arbitrary "never map this or give it to a device" address ranges */ |
| 127 | IOMMU_RESV_RESERVED, | 142 | IOMMU_RESV_RESERVED, |
| 128 | /* Hardware MSI region (untranslated) */ | 143 | /* Hardware MSI region (untranslated) */ |
| @@ -212,6 +227,7 @@ struct iommu_sva_ops { | |||
| 212 | * @sva_bind: Bind process address space to device | 227 | * @sva_bind: Bind process address space to device |
| 213 | * @sva_unbind: Unbind process address space from device | 228 | * @sva_unbind: Unbind process address space from device |
| 214 | * @sva_get_pasid: Get PASID associated to a SVA handle | 229 | * @sva_get_pasid: Get PASID associated to a SVA handle |
| 230 | * @page_response: handle page request response | ||
| 215 | * @pgsize_bitmap: bitmap of all possible supported page sizes | 231 | * @pgsize_bitmap: bitmap of all possible supported page sizes |
| 216 | */ | 232 | */ |
| 217 | struct iommu_ops { | 233 | struct iommu_ops { |
| @@ -272,6 +288,10 @@ struct iommu_ops { | |||
| 272 | void (*sva_unbind)(struct iommu_sva *handle); | 288 | void (*sva_unbind)(struct iommu_sva *handle); |
| 273 | int (*sva_get_pasid)(struct iommu_sva *handle); | 289 | int (*sva_get_pasid)(struct iommu_sva *handle); |
| 274 | 290 | ||
| 291 | int (*page_response)(struct device *dev, | ||
| 292 | struct iommu_fault_event *evt, | ||
| 293 | struct iommu_page_response *msg); | ||
| 294 | |||
| 275 | unsigned long pgsize_bitmap; | 295 | unsigned long pgsize_bitmap; |
| 276 | }; | 296 | }; |
| 277 | 297 | ||
| @@ -289,6 +309,48 @@ struct iommu_device { | |||
| 289 | struct device *dev; | 309 | struct device *dev; |
| 290 | }; | 310 | }; |
| 291 | 311 | ||
| 312 | /** | ||
| 313 | * struct iommu_fault_event - Generic fault event | ||
| 314 | * | ||
| 315 | * Can represent recoverable faults such as a page requests or | ||
| 316 | * unrecoverable faults such as DMA or IRQ remapping faults. | ||
| 317 | * | ||
| 318 | * @fault: fault descriptor | ||
| 319 | * @list: pending fault event list, used for tracking responses | ||
| 320 | */ | ||
| 321 | struct iommu_fault_event { | ||
| 322 | struct iommu_fault fault; | ||
| 323 | struct list_head list; | ||
| 324 | }; | ||
| 325 | |||
| 326 | /** | ||
| 327 | * struct iommu_fault_param - per-device IOMMU fault data | ||
| 328 | * @handler: Callback function to handle IOMMU faults at device level | ||
| 329 | * @data: handler private data | ||
| 330 | * @faults: holds the pending faults which needs response | ||
| 331 | * @lock: protect pending faults list | ||
| 332 | */ | ||
| 333 | struct iommu_fault_param { | ||
| 334 | iommu_dev_fault_handler_t handler; | ||
| 335 | void *data; | ||
| 336 | struct list_head faults; | ||
| 337 | struct mutex lock; | ||
| 338 | }; | ||
| 339 | |||
| 340 | /** | ||
| 341 | * struct iommu_param - collection of per-device IOMMU data | ||
| 342 | * | ||
| 343 | * @fault_param: IOMMU detected device fault reporting data | ||
| 344 | * | ||
| 345 | * TODO: migrate other per device data pointers under iommu_dev_data, e.g. | ||
| 346 | * struct iommu_group *iommu_group; | ||
| 347 | * struct iommu_fwspec *iommu_fwspec; | ||
| 348 | */ | ||
| 349 | struct iommu_param { | ||
| 350 | struct mutex lock; | ||
| 351 | struct iommu_fault_param *fault_param; | ||
| 352 | }; | ||
| 353 | |||
| 292 | int iommu_device_register(struct iommu_device *iommu); | 354 | int iommu_device_register(struct iommu_device *iommu); |
| 293 | void iommu_device_unregister(struct iommu_device *iommu); | 355 | void iommu_device_unregister(struct iommu_device *iommu); |
| 294 | int iommu_device_sysfs_add(struct iommu_device *iommu, | 356 | int iommu_device_sysfs_add(struct iommu_device *iommu, |
| @@ -350,6 +412,7 @@ extern void iommu_set_fault_handler(struct iommu_domain *domain, | |||
| 350 | extern void iommu_get_resv_regions(struct device *dev, struct list_head *list); | 412 | extern void iommu_get_resv_regions(struct device *dev, struct list_head *list); |
| 351 | extern void iommu_put_resv_regions(struct device *dev, struct list_head *list); | 413 | extern void iommu_put_resv_regions(struct device *dev, struct list_head *list); |
| 352 | extern int iommu_request_dm_for_dev(struct device *dev); | 414 | extern int iommu_request_dm_for_dev(struct device *dev); |
| 415 | extern int iommu_request_dma_domain_for_dev(struct device *dev); | ||
| 353 | extern struct iommu_resv_region * | 416 | extern struct iommu_resv_region * |
| 354 | iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot, | 417 | iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot, |
| 355 | enum iommu_resv_type type); | 418 | enum iommu_resv_type type); |
| @@ -378,6 +441,17 @@ extern int iommu_group_register_notifier(struct iommu_group *group, | |||
| 378 | struct notifier_block *nb); | 441 | struct notifier_block *nb); |
| 379 | extern int iommu_group_unregister_notifier(struct iommu_group *group, | 442 | extern int iommu_group_unregister_notifier(struct iommu_group *group, |
| 380 | struct notifier_block *nb); | 443 | struct notifier_block *nb); |
| 444 | extern int iommu_register_device_fault_handler(struct device *dev, | ||
| 445 | iommu_dev_fault_handler_t handler, | ||
| 446 | void *data); | ||
| 447 | |||
| 448 | extern int iommu_unregister_device_fault_handler(struct device *dev); | ||
| 449 | |||
| 450 | extern int iommu_report_device_fault(struct device *dev, | ||
| 451 | struct iommu_fault_event *evt); | ||
| 452 | extern int iommu_page_response(struct device *dev, | ||
| 453 | struct iommu_page_response *msg); | ||
| 454 | |||
| 381 | extern int iommu_group_id(struct iommu_group *group); | 455 | extern int iommu_group_id(struct iommu_group *group); |
| 382 | extern struct iommu_group *iommu_group_get_for_dev(struct device *dev); | 456 | extern struct iommu_group *iommu_group_get_for_dev(struct device *dev); |
| 383 | extern struct iommu_domain *iommu_group_default_domain(struct iommu_group *); | 457 | extern struct iommu_domain *iommu_group_default_domain(struct iommu_group *); |
| @@ -492,6 +566,7 @@ struct iommu_ops {}; | |||
| 492 | struct iommu_group {}; | 566 | struct iommu_group {}; |
| 493 | struct iommu_fwspec {}; | 567 | struct iommu_fwspec {}; |
| 494 | struct iommu_device {}; | 568 | struct iommu_device {}; |
| 569 | struct iommu_fault_param {}; | ||
| 495 | 570 | ||
| 496 | static inline bool iommu_present(struct bus_type *bus) | 571 | static inline bool iommu_present(struct bus_type *bus) |
| 497 | { | 572 | { |
| @@ -614,6 +689,11 @@ static inline int iommu_request_dm_for_dev(struct device *dev) | |||
| 614 | return -ENODEV; | 689 | return -ENODEV; |
| 615 | } | 690 | } |
| 616 | 691 | ||
| 692 | static inline int iommu_request_dma_domain_for_dev(struct device *dev) | ||
| 693 | { | ||
| 694 | return -ENODEV; | ||
| 695 | } | ||
| 696 | |||
| 617 | static inline int iommu_attach_group(struct iommu_domain *domain, | 697 | static inline int iommu_attach_group(struct iommu_domain *domain, |
| 618 | struct iommu_group *group) | 698 | struct iommu_group *group) |
| 619 | { | 699 | { |
| @@ -685,6 +765,31 @@ static inline int iommu_group_unregister_notifier(struct iommu_group *group, | |||
| 685 | return 0; | 765 | return 0; |
| 686 | } | 766 | } |
| 687 | 767 | ||
| 768 | static inline | ||
| 769 | int iommu_register_device_fault_handler(struct device *dev, | ||
| 770 | iommu_dev_fault_handler_t handler, | ||
| 771 | void *data) | ||
| 772 | { | ||
| 773 | return -ENODEV; | ||
| 774 | } | ||
| 775 | |||
| 776 | static inline int iommu_unregister_device_fault_handler(struct device *dev) | ||
| 777 | { | ||
| 778 | return 0; | ||
| 779 | } | ||
| 780 | |||
| 781 | static inline | ||
| 782 | int iommu_report_device_fault(struct device *dev, struct iommu_fault_event *evt) | ||
| 783 | { | ||
| 784 | return -ENODEV; | ||
| 785 | } | ||
| 786 | |||
| 787 | static inline int iommu_page_response(struct device *dev, | ||
| 788 | struct iommu_page_response *msg) | ||
| 789 | { | ||
| 790 | return -ENODEV; | ||
| 791 | } | ||
| 792 | |||
| 688 | static inline int iommu_group_id(struct iommu_group *group) | 793 | static inline int iommu_group_id(struct iommu_group *group) |
| 689 | { | 794 | { |
| 690 | return -ENODEV; | 795 | return -ENODEV; |
