diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-05 18:59:35 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-05 18:59:35 -0400 |
| commit | dc7aafba6bfa1ea5806c6ac402e690682f950f75 (patch) | |
| tree | 01b8dbd05444d2de91cf9058a596e40c3cbc2a6d /include/linux | |
| parent | 161d2e0a195292a8a67b0f5c48e12a9984f75dac (diff) | |
| parent | 4c5e9d9f0ddf5d4ba9c51eee2ef1a4d6e93ccf56 (diff) | |
Merge tag 'iommu-updates-v3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull iommu updates from Joerg Roedel:
"This time with:
- support for the generic PCI device alias code in x86 IOMMU drivers
- a new sysfs interface for IOMMUs
- preparations for hotplug support in the Intel IOMMU driver
- change the AMD IOMMUv2 driver to not hold references to core data
structures like mm_struct or task_struct. Rely on mmu_notifers
instead.
- removal of the OMAP IOVMM interface, all users of it are converted
to DMA-API now
- make the struct iommu_ops const everywhere
- initial PCI support for the ARM SMMU driver
- there is now a generic device tree binding documented for ARM
IOMMUs
- various fixes and cleanups all over the place
Also included are some changes to the OMAP code, which are acked by
the maintainer"
* tag 'iommu-updates-v3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: (67 commits)
devicetree: Add generic IOMMU device tree bindings
iommu/vt-d: Fix race setting IRQ CPU affinity while freeing IRQ
iommu/amd: Fix 2 typos in comments
iommu/amd: Fix device_state reference counting
iommu/amd: Remove change_pte mmu_notifier call-back
iommu/amd: Don't set pasid_state->mm to NULL in unbind_pasid
iommu/exynos: Select ARM_DMA_USE_IOMMU
iommu/vt-d: Exclude devices using RMRRs from IOMMU API domains
iommu/omap: Remove platform data da_start and da_end fields
ARM: omap: Don't set iommu pdata da_start and da_end fields
iommu/omap: Remove virtual memory manager
iommu/vt-d: Fix issue in computing domain's iommu_snooping flag
iommu/vt-d: Introduce helper function iova_size() to improve code readability
iommu/vt-d: Introduce helper domain_pfn_within_range() to simplify code
iommu/vt-d: Simplify intel_unmap_sg() and kill duplicated code
iommu/vt-d: Change iommu_enable/disable_translation to return void
iommu/vt-d: Simplify include/linux/dmar.h
iommu/vt-d: Avoid freeing virtual machine domain in free_dmar_iommu()
iommu/vt-d: Fix possible invalid memory access caused by free_dmar_iommu()
iommu/vt-d: Allocate dynamic domain id for virtual domains only
...
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/amd-iommu.h | 7 | ||||
| -rw-r--r-- | include/linux/device.h | 2 | ||||
| -rw-r--r-- | include/linux/dmar.h | 50 | ||||
| -rw-r--r-- | include/linux/intel-iommu.h | 3 | ||||
| -rw-r--r-- | include/linux/iommu.h | 32 | ||||
| -rw-r--r-- | include/linux/iova.h | 5 | ||||
| -rw-r--r-- | include/linux/omap-iommu.h | 37 | ||||
| -rw-r--r-- | include/linux/platform_data/iommu-omap.h | 6 |
8 files changed, 66 insertions, 76 deletions
diff --git a/include/linux/amd-iommu.h b/include/linux/amd-iommu.h index 15f6b9edd0b1..2b08e79f5100 100644 --- a/include/linux/amd-iommu.h +++ b/include/linux/amd-iommu.h | |||
| @@ -119,6 +119,13 @@ typedef int (*amd_iommu_invalid_ppr_cb)(struct pci_dev *pdev, | |||
| 119 | extern int amd_iommu_set_invalid_ppr_cb(struct pci_dev *pdev, | 119 | extern int amd_iommu_set_invalid_ppr_cb(struct pci_dev *pdev, |
| 120 | amd_iommu_invalid_ppr_cb cb); | 120 | amd_iommu_invalid_ppr_cb cb); |
| 121 | 121 | ||
| 122 | #define PPR_FAULT_EXEC (1 << 1) | ||
| 123 | #define PPR_FAULT_READ (1 << 2) | ||
| 124 | #define PPR_FAULT_WRITE (1 << 5) | ||
| 125 | #define PPR_FAULT_USER (1 << 6) | ||
| 126 | #define PPR_FAULT_RSVD (1 << 7) | ||
| 127 | #define PPR_FAULT_GN (1 << 8) | ||
| 128 | |||
| 122 | /** | 129 | /** |
| 123 | * amd_iommu_device_info() - Get information about IOMMUv2 support of a | 130 | * amd_iommu_device_info() - Get information about IOMMUv2 support of a |
| 124 | * PCI device | 131 | * PCI device |
diff --git a/include/linux/device.h b/include/linux/device.h index b0aab0d6be7e..43d183aeb25b 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
| @@ -124,7 +124,7 @@ struct bus_type { | |||
| 124 | 124 | ||
| 125 | const struct dev_pm_ops *pm; | 125 | const struct dev_pm_ops *pm; |
| 126 | 126 | ||
| 127 | struct iommu_ops *iommu_ops; | 127 | const struct iommu_ops *iommu_ops; |
| 128 | 128 | ||
| 129 | struct subsys_private *p; | 129 | struct subsys_private *p; |
| 130 | struct lock_class_key lock_key; | 130 | struct lock_class_key lock_key; |
diff --git a/include/linux/dmar.h b/include/linux/dmar.h index 23c8db129560..1deece46a0ca 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h | |||
| @@ -114,22 +114,30 @@ extern int dmar_remove_dev_scope(struct dmar_pci_notify_info *info, | |||
| 114 | /* Intel IOMMU detection */ | 114 | /* Intel IOMMU detection */ |
| 115 | extern int detect_intel_iommu(void); | 115 | extern int detect_intel_iommu(void); |
| 116 | extern int enable_drhd_fault_handling(void); | 116 | extern int enable_drhd_fault_handling(void); |
| 117 | #else | 117 | |
| 118 | struct dmar_pci_notify_info; | 118 | #ifdef CONFIG_INTEL_IOMMU |
| 119 | static inline int detect_intel_iommu(void) | 119 | extern int iommu_detected, no_iommu; |
| 120 | extern int intel_iommu_init(void); | ||
| 121 | extern int dmar_parse_one_rmrr(struct acpi_dmar_header *header); | ||
| 122 | extern int dmar_parse_one_atsr(struct acpi_dmar_header *header); | ||
| 123 | extern int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info); | ||
| 124 | #else /* !CONFIG_INTEL_IOMMU: */ | ||
| 125 | static inline int intel_iommu_init(void) { return -ENODEV; } | ||
| 126 | static inline int dmar_parse_one_rmrr(struct acpi_dmar_header *header) | ||
| 120 | { | 127 | { |
| 121 | return -ENODEV; | 128 | return 0; |
| 122 | } | 129 | } |
| 123 | 130 | static inline int dmar_parse_one_atsr(struct acpi_dmar_header *header) | |
| 124 | static inline int dmar_table_init(void) | ||
| 125 | { | 131 | { |
| 126 | return -ENODEV; | 132 | return 0; |
| 127 | } | 133 | } |
| 128 | static inline int enable_drhd_fault_handling(void) | 134 | static inline int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info) |
| 129 | { | 135 | { |
| 130 | return -1; | 136 | return 0; |
| 131 | } | 137 | } |
| 132 | #endif /* !CONFIG_DMAR_TABLE */ | 138 | #endif /* CONFIG_INTEL_IOMMU */ |
| 139 | |||
| 140 | #endif /* CONFIG_DMAR_TABLE */ | ||
| 133 | 141 | ||
| 134 | struct irte { | 142 | struct irte { |
| 135 | union { | 143 | union { |
| @@ -177,26 +185,4 @@ extern int dmar_set_interrupt(struct intel_iommu *iommu); | |||
| 177 | extern irqreturn_t dmar_fault(int irq, void *dev_id); | 185 | extern irqreturn_t dmar_fault(int irq, void *dev_id); |
| 178 | extern int arch_setup_dmar_msi(unsigned int irq); | 186 | extern int arch_setup_dmar_msi(unsigned int irq); |
| 179 | 187 | ||
| 180 | #ifdef CONFIG_INTEL_IOMMU | ||
| 181 | extern int iommu_detected, no_iommu; | ||
| 182 | extern int dmar_parse_one_rmrr(struct acpi_dmar_header *header); | ||
| 183 | extern int dmar_parse_one_atsr(struct acpi_dmar_header *header); | ||
| 184 | extern int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info); | ||
| 185 | extern int intel_iommu_init(void); | ||
| 186 | #else /* !CONFIG_INTEL_IOMMU: */ | ||
| 187 | static inline int intel_iommu_init(void) { return -ENODEV; } | ||
| 188 | static inline int dmar_parse_one_rmrr(struct acpi_dmar_header *header) | ||
| 189 | { | ||
| 190 | return 0; | ||
| 191 | } | ||
| 192 | static inline int dmar_parse_one_atsr(struct acpi_dmar_header *header) | ||
| 193 | { | ||
| 194 | return 0; | ||
| 195 | } | ||
| 196 | static inline int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info) | ||
| 197 | { | ||
| 198 | return 0; | ||
| 199 | } | ||
| 200 | #endif /* CONFIG_INTEL_IOMMU */ | ||
| 201 | |||
| 202 | #endif /* __DMAR_H__ */ | 188 | #endif /* __DMAR_H__ */ |
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 0a2da5188217..a65208a8fe18 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h | |||
| @@ -336,6 +336,7 @@ struct intel_iommu { | |||
| 336 | #ifdef CONFIG_IRQ_REMAP | 336 | #ifdef CONFIG_IRQ_REMAP |
| 337 | struct ir_table *ir_table; /* Interrupt remapping info */ | 337 | struct ir_table *ir_table; /* Interrupt remapping info */ |
| 338 | #endif | 338 | #endif |
| 339 | struct device *iommu_dev; /* IOMMU-sysfs device */ | ||
| 339 | int node; | 340 | int node; |
| 340 | }; | 341 | }; |
| 341 | 342 | ||
| @@ -365,4 +366,6 @@ extern int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu); | |||
| 365 | 366 | ||
| 366 | extern int dmar_ir_support(void); | 367 | extern int dmar_ir_support(void); |
| 367 | 368 | ||
| 369 | extern const struct attribute_group *intel_iommu_groups[]; | ||
| 370 | |||
| 368 | #endif | 371 | #endif |
diff --git a/include/linux/iommu.h b/include/linux/iommu.h index b96a5b2136e4..20f9a527922a 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h | |||
| @@ -50,7 +50,7 @@ struct iommu_domain_geometry { | |||
| 50 | }; | 50 | }; |
| 51 | 51 | ||
| 52 | struct iommu_domain { | 52 | struct iommu_domain { |
| 53 | struct iommu_ops *ops; | 53 | const struct iommu_ops *ops; |
| 54 | void *priv; | 54 | void *priv; |
| 55 | iommu_fault_handler_t handler; | 55 | iommu_fault_handler_t handler; |
| 56 | void *handler_token; | 56 | void *handler_token; |
| @@ -140,7 +140,7 @@ struct iommu_ops { | |||
| 140 | #define IOMMU_GROUP_NOTIFY_UNBIND_DRIVER 5 /* Pre Driver unbind */ | 140 | #define IOMMU_GROUP_NOTIFY_UNBIND_DRIVER 5 /* Pre Driver unbind */ |
| 141 | #define IOMMU_GROUP_NOTIFY_UNBOUND_DRIVER 6 /* Post Driver unbind */ | 141 | #define IOMMU_GROUP_NOTIFY_UNBOUND_DRIVER 6 /* Post Driver unbind */ |
| 142 | 142 | ||
| 143 | extern int bus_set_iommu(struct bus_type *bus, struct iommu_ops *ops); | 143 | extern int bus_set_iommu(struct bus_type *bus, const struct iommu_ops *ops); |
| 144 | extern bool iommu_present(struct bus_type *bus); | 144 | extern bool iommu_present(struct bus_type *bus); |
| 145 | extern struct iommu_domain *iommu_domain_alloc(struct bus_type *bus); | 145 | extern struct iommu_domain *iommu_domain_alloc(struct bus_type *bus); |
| 146 | extern struct iommu_group *iommu_group_get_by_id(int id); | 146 | extern struct iommu_group *iommu_group_get_by_id(int id); |
| @@ -181,11 +181,18 @@ extern int iommu_group_register_notifier(struct iommu_group *group, | |||
| 181 | extern int iommu_group_unregister_notifier(struct iommu_group *group, | 181 | extern int iommu_group_unregister_notifier(struct iommu_group *group, |
| 182 | struct notifier_block *nb); | 182 | struct notifier_block *nb); |
| 183 | extern int iommu_group_id(struct iommu_group *group); | 183 | extern int iommu_group_id(struct iommu_group *group); |
| 184 | extern struct iommu_group *iommu_group_get_for_dev(struct device *dev); | ||
| 184 | 185 | ||
| 185 | extern int iommu_domain_get_attr(struct iommu_domain *domain, enum iommu_attr, | 186 | extern int iommu_domain_get_attr(struct iommu_domain *domain, enum iommu_attr, |
| 186 | void *data); | 187 | void *data); |
| 187 | extern int iommu_domain_set_attr(struct iommu_domain *domain, enum iommu_attr, | 188 | extern int iommu_domain_set_attr(struct iommu_domain *domain, enum iommu_attr, |
| 188 | void *data); | 189 | void *data); |
| 190 | struct device *iommu_device_create(struct device *parent, void *drvdata, | ||
| 191 | const struct attribute_group **groups, | ||
| 192 | const char *fmt, ...); | ||
| 193 | void iommu_device_destroy(struct device *dev); | ||
| 194 | int iommu_device_link(struct device *dev, struct device *link); | ||
| 195 | void iommu_device_unlink(struct device *dev, struct device *link); | ||
| 189 | 196 | ||
| 190 | /* Window handling function prototypes */ | 197 | /* Window handling function prototypes */ |
| 191 | extern int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr, | 198 | extern int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr, |
| @@ -396,6 +403,27 @@ static inline int iommu_domain_set_attr(struct iommu_domain *domain, | |||
| 396 | return -EINVAL; | 403 | return -EINVAL; |
| 397 | } | 404 | } |
| 398 | 405 | ||
| 406 | static inline struct device *iommu_device_create(struct device *parent, | ||
| 407 | void *drvdata, | ||
| 408 | const struct attribute_group **groups, | ||
| 409 | const char *fmt, ...) | ||
| 410 | { | ||
| 411 | return ERR_PTR(-ENODEV); | ||
| 412 | } | ||
| 413 | |||
| 414 | static inline void iommu_device_destroy(struct device *dev) | ||
| 415 | { | ||
| 416 | } | ||
| 417 | |||
| 418 | static inline int iommu_device_link(struct device *dev, struct device *link) | ||
| 419 | { | ||
| 420 | return -EINVAL; | ||
| 421 | } | ||
| 422 | |||
| 423 | static inline void iommu_device_unlink(struct device *dev, struct device *link) | ||
| 424 | { | ||
| 425 | } | ||
| 426 | |||
| 399 | #endif /* CONFIG_IOMMU_API */ | 427 | #endif /* CONFIG_IOMMU_API */ |
| 400 | 428 | ||
| 401 | #endif /* __LINUX_IOMMU_H */ | 429 | #endif /* __LINUX_IOMMU_H */ |
diff --git a/include/linux/iova.h b/include/linux/iova.h index 3277f4711349..19e81d5ccb6d 100644 --- a/include/linux/iova.h +++ b/include/linux/iova.h | |||
| @@ -34,6 +34,11 @@ struct iova_domain { | |||
| 34 | unsigned long dma_32bit_pfn; | 34 | unsigned long dma_32bit_pfn; |
| 35 | }; | 35 | }; |
| 36 | 36 | ||
| 37 | static inline unsigned long iova_size(struct iova *iova) | ||
| 38 | { | ||
| 39 | return iova->pfn_hi - iova->pfn_lo + 1; | ||
| 40 | } | ||
| 41 | |||
| 37 | struct iova *alloc_iova_mem(void); | 42 | struct iova *alloc_iova_mem(void); |
| 38 | void free_iova_mem(struct iova *iova); | 43 | void free_iova_mem(struct iova *iova); |
| 39 | void free_iova(struct iova_domain *iovad, unsigned long pfn); | 44 | void free_iova(struct iova_domain *iovad, unsigned long pfn); |
diff --git a/include/linux/omap-iommu.h b/include/linux/omap-iommu.h index cac78de09c07..c1aede46718b 100644 --- a/include/linux/omap-iommu.h +++ b/include/linux/omap-iommu.h | |||
| @@ -10,41 +10,8 @@ | |||
| 10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #ifndef _INTEL_IOMMU_H_ | 13 | #ifndef _OMAP_IOMMU_H_ |
| 14 | #define _INTEL_IOMMU_H_ | 14 | #define _OMAP_IOMMU_H_ |
| 15 | |||
| 16 | struct iovm_struct { | ||
| 17 | struct omap_iommu *iommu; /* iommu object which this belongs to */ | ||
| 18 | u32 da_start; /* area definition */ | ||
| 19 | u32 da_end; | ||
| 20 | u32 flags; /* IOVMF_: see below */ | ||
| 21 | struct list_head list; /* linked in ascending order */ | ||
| 22 | const struct sg_table *sgt; /* keep 'page' <-> 'da' mapping */ | ||
| 23 | void *va; /* mpu side mapped address */ | ||
| 24 | }; | ||
| 25 | |||
| 26 | #define MMU_RAM_ENDIAN_SHIFT 9 | ||
| 27 | #define MMU_RAM_ENDIAN_LITTLE (0 << MMU_RAM_ENDIAN_SHIFT) | ||
| 28 | #define MMU_RAM_ELSZ_8 (0 << MMU_RAM_ELSZ_SHIFT) | ||
| 29 | #define IOVMF_ENDIAN_LITTLE MMU_RAM_ENDIAN_LITTLE | ||
| 30 | #define MMU_RAM_ELSZ_SHIFT 7 | ||
| 31 | #define IOVMF_ELSZ_8 MMU_RAM_ELSZ_8 | ||
| 32 | |||
| 33 | struct iommu_domain; | ||
| 34 | |||
| 35 | extern struct iovm_struct *omap_find_iovm_area(struct device *dev, u32 da); | ||
| 36 | extern u32 | ||
| 37 | omap_iommu_vmap(struct iommu_domain *domain, struct device *dev, u32 da, | ||
| 38 | const struct sg_table *sgt, u32 flags); | ||
| 39 | extern struct sg_table *omap_iommu_vunmap(struct iommu_domain *domain, | ||
| 40 | struct device *dev, u32 da); | ||
| 41 | extern u32 | ||
| 42 | omap_iommu_vmalloc(struct iommu_domain *domain, struct device *dev, | ||
| 43 | u32 da, size_t bytes, u32 flags); | ||
| 44 | extern void | ||
| 45 | omap_iommu_vfree(struct iommu_domain *domain, struct device *dev, | ||
| 46 | const u32 da); | ||
| 47 | extern void *omap_da_to_va(struct device *dev, u32 da); | ||
| 48 | 15 | ||
| 49 | extern void omap_iommu_save_ctx(struct device *dev); | 16 | extern void omap_iommu_save_ctx(struct device *dev); |
| 50 | extern void omap_iommu_restore_ctx(struct device *dev); | 17 | extern void omap_iommu_restore_ctx(struct device *dev); |
diff --git a/include/linux/platform_data/iommu-omap.h b/include/linux/platform_data/iommu-omap.h index 5b429c43a297..54a0a9582fad 100644 --- a/include/linux/platform_data/iommu-omap.h +++ b/include/linux/platform_data/iommu-omap.h | |||
| @@ -31,14 +31,10 @@ struct omap_iommu_arch_data { | |||
| 31 | 31 | ||
| 32 | /** | 32 | /** |
| 33 | * struct omap_mmu_dev_attr - OMAP mmu device attributes for omap_hwmod | 33 | * struct omap_mmu_dev_attr - OMAP mmu device attributes for omap_hwmod |
| 34 | * @da_start: device address where the va space starts. | ||
| 35 | * @da_end: device address where the va space ends. | ||
| 36 | * @nr_tlb_entries: number of entries supported by the translation | 34 | * @nr_tlb_entries: number of entries supported by the translation |
| 37 | * look-aside buffer (TLB). | 35 | * look-aside buffer (TLB). |
| 38 | */ | 36 | */ |
| 39 | struct omap_mmu_dev_attr { | 37 | struct omap_mmu_dev_attr { |
| 40 | u32 da_start; | ||
| 41 | u32 da_end; | ||
| 42 | int nr_tlb_entries; | 38 | int nr_tlb_entries; |
| 43 | }; | 39 | }; |
| 44 | 40 | ||
| @@ -46,8 +42,6 @@ struct iommu_platform_data { | |||
| 46 | const char *name; | 42 | const char *name; |
| 47 | const char *reset_name; | 43 | const char *reset_name; |
| 48 | int nr_tlb_entries; | 44 | int nr_tlb_entries; |
| 49 | u32 da_start; | ||
| 50 | u32 da_end; | ||
| 51 | 45 | ||
| 52 | int (*assert_reset)(struct platform_device *pdev, const char *name); | 46 | int (*assert_reset)(struct platform_device *pdev, const char *name); |
| 53 | int (*deassert_reset)(struct platform_device *pdev, const char *name); | 47 | int (*deassert_reset)(struct platform_device *pdev, const char *name); |
