Skip to content

Commit 1daa56b

Browse files
committed
Merge tag 'iommu-updates-v5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull iommu updates from Joerg Roedel: - Conversion of the AMD IOMMU driver to use the dma-iommu code for imlementing the DMA-API. This gets rid of quite some code in the driver itself, but also has some potential for regressions (non are known at the moment). - Support for the Qualcomm SMMUv2 implementation in the SDM845 SoC. This also includes some firmware interface changes, but those are acked by the respective maintainers. - Preparatory work to support two distinct page-tables per domain in the ARM-SMMU driver - Power management improvements for the ARM SMMUv2 - Custom PASID allocator support - Multiple PCI DMA alias support for the AMD IOMMU driver - Adaption of the Mediatek driver to the changed IO/TLB flush interface of the IOMMU core code. - Preparatory patches for the Renesas IOMMU driver to support future hardware. * tag 'iommu-updates-v5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: (62 commits) iommu/rockchip: Don't provoke WARN for harmless IRQs iommu/vt-d: Turn off translations at shutdown iommu/vt-d: Check VT-d RMRR region in BIOS is reported as reserved iommu/arm-smmu: Remove duplicate error message iommu/arm-smmu-v3: Don't display an error when IRQ lines are missing iommu/ipmmu-vmsa: Add utlb_offset_base iommu/ipmmu-vmsa: Add helper functions for "uTLB" registers iommu/ipmmu-vmsa: Calculate context registers' offset instead of a macro iommu/ipmmu-vmsa: Add helper functions for MMU "context" registers iommu/ipmmu-vmsa: tidyup register definitions iommu/ipmmu-vmsa: Remove all unused register definitions iommu/mediatek: Reduce the tlb flush timeout value iommu/mediatek: Get rid of the pgtlock iommu/mediatek: Move the tlb_sync into tlb_flush iommu/mediatek: Delete the leaf in the tlb_flush iommu/mediatek: Use gather to achieve the tlb range flush iommu/mediatek: Add a new tlb_lock for tlb_flush iommu/mediatek: Correct the flush_iotlb_all callback iommu/io-pgtable-arm: Rename IOMMU_QCOM_SYS_CACHE and improve doc iommu/io-pgtable-arm: Rationalise MAIR handling ...
2 parents a5255bc + 9b3a713 commit 1daa56b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1651
-1213
lines changed

Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Required Properties:
1515
- "renesas,ipmmu-r8a7744" for the R8A7744 (RZ/G1N) IPMMU.
1616
- "renesas,ipmmu-r8a7745" for the R8A7745 (RZ/G1E) IPMMU.
1717
- "renesas,ipmmu-r8a774a1" for the R8A774A1 (RZ/G2M) IPMMU.
18+
- "renesas,ipmmu-r8a774b1" for the R8A774B1 (RZ/G2N) IPMMU.
1819
- "renesas,ipmmu-r8a774c0" for the R8A774C0 (RZ/G2E) IPMMU.
1920
- "renesas,ipmmu-r8a7790" for the R8A7790 (R-Car H2) IPMMU.
2021
- "renesas,ipmmu-r8a7791" for the R8A7791 (R-Car M2-W) IPMMU.

arch/ia64/include/asm/iommu.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,18 @@
22
#ifndef _ASM_IA64_IOMMU_H
33
#define _ASM_IA64_IOMMU_H 1
44

5+
#include <linux/acpi.h>
6+
57
/* 10 seconds */
68
#define DMAR_OPERATION_TIMEOUT (((cycles_t) local_cpu_data->itc_freq)*10)
79

810
extern void no_iommu_init(void);
911
#ifdef CONFIG_INTEL_IOMMU
1012
extern int force_iommu, no_iommu;
1113
extern int iommu_detected;
14+
15+
static inline int __init
16+
arch_rmrr_sanity_check(struct acpi_dmar_reserved_memory *rmrr) { return 0; }
1217
#else
1318
#define no_iommu (1)
1419
#define iommu_detected (0)

arch/x86/include/asm/iommu.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,28 @@
22
#ifndef _ASM_X86_IOMMU_H
33
#define _ASM_X86_IOMMU_H
44

5+
#include <linux/acpi.h>
6+
7+
#include <asm/e820/api.h>
8+
59
extern int force_iommu, no_iommu;
610
extern int iommu_detected;
711

812
/* 10 seconds */
913
#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
1014

15+
static inline int __init
16+
arch_rmrr_sanity_check(struct acpi_dmar_reserved_memory *rmrr)
17+
{
18+
u64 start = rmrr->base_address;
19+
u64 end = rmrr->end_address + 1;
20+
21+
if (e820__mapped_all(start, end, E820_TYPE_RESERVED))
22+
return 0;
23+
24+
pr_err(FW_BUG "No firmware reserved region can cover this RMRR [%#018Lx-%#018Lx], contact BIOS vendor for fixes\n",
25+
start, end - 1);
26+
return -EINVAL;
27+
}
28+
1129
#endif /* _ASM_X86_IOMMU_H */

drivers/firmware/qcom_scm-32.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,3 +614,8 @@ int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val)
614614
return qcom_scm_call_atomic2(QCOM_SCM_SVC_IO, QCOM_SCM_IO_WRITE,
615615
addr, val);
616616
}
617+
618+
int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, bool enable)
619+
{
620+
return -ENODEV;
621+
}

drivers/firmware/qcom_scm-64.c

Lines changed: 108 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -62,32 +62,72 @@ static DEFINE_MUTEX(qcom_scm_lock);
6262
#define FIRST_EXT_ARG_IDX 3
6363
#define N_REGISTER_ARGS (MAX_QCOM_SCM_ARGS - N_EXT_QCOM_SCM_ARGS + 1)
6464

65-
/**
66-
* qcom_scm_call() - Invoke a syscall in the secure world
67-
* @dev: device
68-
* @svc_id: service identifier
69-
* @cmd_id: command identifier
70-
* @desc: Descriptor structure containing arguments and return values
71-
*
72-
* Sends a command to the SCM and waits for the command to finish processing.
73-
* This should *only* be called in pre-emptible context.
74-
*/
75-
static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
76-
const struct qcom_scm_desc *desc,
77-
struct arm_smccc_res *res)
65+
static void __qcom_scm_call_do(const struct qcom_scm_desc *desc,
66+
struct arm_smccc_res *res, u32 fn_id,
67+
u64 x5, u32 type)
68+
{
69+
u64 cmd;
70+
struct arm_smccc_quirk quirk = { .id = ARM_SMCCC_QUIRK_QCOM_A6 };
71+
72+
cmd = ARM_SMCCC_CALL_VAL(type, qcom_smccc_convention,
73+
ARM_SMCCC_OWNER_SIP, fn_id);
74+
75+
quirk.state.a6 = 0;
76+
77+
do {
78+
arm_smccc_smc_quirk(cmd, desc->arginfo, desc->args[0],
79+
desc->args[1], desc->args[2], x5,
80+
quirk.state.a6, 0, res, &quirk);
81+
82+
if (res->a0 == QCOM_SCM_INTERRUPTED)
83+
cmd = res->a0;
84+
85+
} while (res->a0 == QCOM_SCM_INTERRUPTED);
86+
}
87+
88+
static void qcom_scm_call_do(const struct qcom_scm_desc *desc,
89+
struct arm_smccc_res *res, u32 fn_id,
90+
u64 x5, bool atomic)
91+
{
92+
int retry_count = 0;
93+
94+
if (atomic) {
95+
__qcom_scm_call_do(desc, res, fn_id, x5, ARM_SMCCC_FAST_CALL);
96+
return;
97+
}
98+
99+
do {
100+
mutex_lock(&qcom_scm_lock);
101+
102+
__qcom_scm_call_do(desc, res, fn_id, x5,
103+
ARM_SMCCC_STD_CALL);
104+
105+
mutex_unlock(&qcom_scm_lock);
106+
107+
if (res->a0 == QCOM_SCM_V2_EBUSY) {
108+
if (retry_count++ > QCOM_SCM_EBUSY_MAX_RETRY)
109+
break;
110+
msleep(QCOM_SCM_EBUSY_WAIT_MS);
111+
}
112+
} while (res->a0 == QCOM_SCM_V2_EBUSY);
113+
}
114+
115+
static int ___qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
116+
const struct qcom_scm_desc *desc,
117+
struct arm_smccc_res *res, bool atomic)
78118
{
79119
int arglen = desc->arginfo & 0xf;
80-
int retry_count = 0, i;
120+
int i;
81121
u32 fn_id = QCOM_SCM_FNID(svc_id, cmd_id);
82-
u64 cmd, x5 = desc->args[FIRST_EXT_ARG_IDX];
122+
u64 x5 = desc->args[FIRST_EXT_ARG_IDX];
83123
dma_addr_t args_phys = 0;
84124
void *args_virt = NULL;
85125
size_t alloc_len;
86-
struct arm_smccc_quirk quirk = {.id = ARM_SMCCC_QUIRK_QCOM_A6};
126+
gfp_t flag = atomic ? GFP_ATOMIC : GFP_KERNEL;
87127

88128
if (unlikely(arglen > N_REGISTER_ARGS)) {
89129
alloc_len = N_EXT_QCOM_SCM_ARGS * sizeof(u64);
90-
args_virt = kzalloc(PAGE_ALIGN(alloc_len), GFP_KERNEL);
130+
args_virt = kzalloc(PAGE_ALIGN(alloc_len), flag);
91131

92132
if (!args_virt)
93133
return -ENOMEM;
@@ -117,45 +157,55 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
117157
x5 = args_phys;
118158
}
119159

120-
do {
121-
mutex_lock(&qcom_scm_lock);
122-
123-
cmd = ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL,
124-
qcom_smccc_convention,
125-
ARM_SMCCC_OWNER_SIP, fn_id);
126-
127-
quirk.state.a6 = 0;
128-
129-
do {
130-
arm_smccc_smc_quirk(cmd, desc->arginfo, desc->args[0],
131-
desc->args[1], desc->args[2], x5,
132-
quirk.state.a6, 0, res, &quirk);
133-
134-
if (res->a0 == QCOM_SCM_INTERRUPTED)
135-
cmd = res->a0;
136-
137-
} while (res->a0 == QCOM_SCM_INTERRUPTED);
138-
139-
mutex_unlock(&qcom_scm_lock);
140-
141-
if (res->a0 == QCOM_SCM_V2_EBUSY) {
142-
if (retry_count++ > QCOM_SCM_EBUSY_MAX_RETRY)
143-
break;
144-
msleep(QCOM_SCM_EBUSY_WAIT_MS);
145-
}
146-
} while (res->a0 == QCOM_SCM_V2_EBUSY);
160+
qcom_scm_call_do(desc, res, fn_id, x5, atomic);
147161

148162
if (args_virt) {
149163
dma_unmap_single(dev, args_phys, alloc_len, DMA_TO_DEVICE);
150164
kfree(args_virt);
151165
}
152166

153-
if (res->a0 < 0)
167+
if ((long)res->a0 < 0)
154168
return qcom_scm_remap_error(res->a0);
155169

156170
return 0;
157171
}
158172

173+
/**
174+
* qcom_scm_call() - Invoke a syscall in the secure world
175+
* @dev: device
176+
* @svc_id: service identifier
177+
* @cmd_id: command identifier
178+
* @desc: Descriptor structure containing arguments and return values
179+
*
180+
* Sends a command to the SCM and waits for the command to finish processing.
181+
* This should *only* be called in pre-emptible context.
182+
*/
183+
static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
184+
const struct qcom_scm_desc *desc,
185+
struct arm_smccc_res *res)
186+
{
187+
might_sleep();
188+
return ___qcom_scm_call(dev, svc_id, cmd_id, desc, res, false);
189+
}
190+
191+
/**
192+
* qcom_scm_call_atomic() - atomic variation of qcom_scm_call()
193+
* @dev: device
194+
* @svc_id: service identifier
195+
* @cmd_id: command identifier
196+
* @desc: Descriptor structure containing arguments and return values
197+
* @res: Structure containing results from SMC/HVC call
198+
*
199+
* Sends a command to the SCM and waits for the command to finish processing.
200+
* This can be called in atomic context.
201+
*/
202+
static int qcom_scm_call_atomic(struct device *dev, u32 svc_id, u32 cmd_id,
203+
const struct qcom_scm_desc *desc,
204+
struct arm_smccc_res *res)
205+
{
206+
return ___qcom_scm_call(dev, svc_id, cmd_id, desc, res, true);
207+
}
208+
159209
/**
160210
* qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus
161211
* @entry: Entry point function for the cpus
@@ -502,3 +552,16 @@ int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val)
502552
return qcom_scm_call(dev, QCOM_SCM_SVC_IO, QCOM_SCM_IO_WRITE,
503553
&desc, &res);
504554
}
555+
556+
int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, bool en)
557+
{
558+
struct qcom_scm_desc desc = {0};
559+
struct arm_smccc_res res;
560+
561+
desc.args[0] = QCOM_SCM_CONFIG_ERRATA1_CLIENT_ALL;
562+
desc.args[1] = en;
563+
desc.arginfo = QCOM_SCM_ARGS(2);
564+
565+
return qcom_scm_call_atomic(dev, QCOM_SCM_SVC_SMMU_PROGRAM,
566+
QCOM_SCM_CONFIG_ERRATA1, &desc, &res);
567+
}

drivers/firmware/qcom_scm.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,12 @@ int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare)
345345
}
346346
EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_init);
347347

348+
int qcom_scm_qsmmu500_wait_safe_toggle(bool en)
349+
{
350+
return __qcom_scm_qsmmu500_wait_safe_toggle(__scm->dev, en);
351+
}
352+
EXPORT_SYMBOL(qcom_scm_qsmmu500_wait_safe_toggle);
353+
348354
int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val)
349355
{
350356
return __qcom_scm_io_readl(__scm->dev, addr, val);

drivers/firmware/qcom_scm.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,15 @@ extern int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id,
9191
u32 spare);
9292
#define QCOM_SCM_IOMMU_SECURE_PTBL_SIZE 3
9393
#define QCOM_SCM_IOMMU_SECURE_PTBL_INIT 4
94+
#define QCOM_SCM_SVC_SMMU_PROGRAM 0x15
95+
#define QCOM_SCM_CONFIG_ERRATA1 0x3
96+
#define QCOM_SCM_CONFIG_ERRATA1_CLIENT_ALL 0x2
9497
extern int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare,
9598
size_t *size);
9699
extern int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr,
97100
u32 size, u32 spare);
101+
extern int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev,
102+
bool enable);
98103
#define QCOM_MEM_PROT_ASSIGN_ID 0x16
99104
extern int __qcom_scm_assign_mem(struct device *dev,
100105
phys_addr_t mem_region, size_t mem_sz,

drivers/iommu/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
config IOMMU_IOVA
44
tristate
55

6+
# The IOASID library may also be used by non-IOMMU_API users
7+
config IOASID
8+
tristate
9+
610
# IOMMU_API always gets selected by whoever wants it.
711
config IOMMU_API
812
bool
@@ -138,6 +142,7 @@ config AMD_IOMMU
138142
select PCI_PASID
139143
select IOMMU_API
140144
select IOMMU_IOVA
145+
select IOMMU_DMA
141146
depends on X86_64 && PCI && ACPI
142147
---help---
143148
With this option you can enable support for AMD IOMMU hardware in

drivers/iommu/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
77
obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
88
obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
99
obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o
10+
obj-$(CONFIG_IOASID) += ioasid.o
1011
obj-$(CONFIG_IOMMU_IOVA) += iova.o
1112
obj-$(CONFIG_OF_IOMMU) += of_iommu.o
1213
obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
1314
obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o amd_iommu_quirks.o
1415
obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += amd_iommu_debugfs.o
1516
obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
16-
obj-$(CONFIG_ARM_SMMU) += arm-smmu.o arm-smmu-impl.o
17+
obj-$(CONFIG_ARM_SMMU) += arm-smmu.o arm-smmu-impl.o arm-smmu-qcom.o
1718
obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
1819
obj-$(CONFIG_DMAR_TABLE) += dmar.o
1920
obj-$(CONFIG_INTEL_IOMMU) += intel-iommu.o intel-pasid.o

0 commit comments

Comments
 (0)