From 2cc84bbe1269b883a65bb5ba8956f210eabfd8f8 Mon Sep 17 00:00:00 2001 From: Daniel Mentz Date: Tue, 3 Jun 2025 16:08:36 -0700 Subject: [PATCH] ANDROID: iommu/arm-smmu-v3-kvm: Wrap around when writing to cmdq When we write more than a single command to the command queue, we need to wrap around when we hit the end of the command queue. Otherwise, we'll write to memory locations that are past the end of the command queue. Bug: 421785718 Fixes: dd32b792c1f7 ("BACKPORT: FROMLIST: iommu/arm-smmu-v3-kvm: Support command queue batching") Change-Id: Ia6246e3e0fc6185b2373664e90c119051d1c55fc Signed-off-by: Daniel Mentz --- drivers/iommu/arm/arm-smmu-v3/pkvm/arm-smmu-v3.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu-v3/pkvm/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/pkvm/arm-smmu-v3.c index fb0c0c57cebc..2de13b39c6db 100644 --- a/drivers/iommu/arm/arm-smmu-v3/pkvm/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/pkvm/arm-smmu-v3.c @@ -209,8 +209,6 @@ static int smmu_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent) static int smmu_issue_cmds(struct hyp_arm_smmu_v3_device *smmu, u64 *cmds, int n) { - int idx = Q_IDX(smmu, smmu->cmdq_prod); - u64 *slot = smmu->cmdq_base + idx * CMDQ_ENT_DWORDS; int i; int ret; u32 prod; @@ -219,8 +217,14 @@ static int smmu_issue_cmds(struct hyp_arm_smmu_v3_device *smmu, if (ret) return ret; - for (i = 0; i < CMDQ_ENT_DWORDS * n; i++) - slot[i] = cpu_to_le64(cmds[i]); + for (i = 0; i < n; i++) { + int j; + int idx = Q_IDX(smmu, smmu->cmdq_prod + i); + u64 *slot = smmu->cmdq_base + idx * CMDQ_ENT_DWORDS; + + for (j = 0; j < CMDQ_ENT_DWORDS; j++) + slot[j] = cpu_to_le64(cmds[i * CMDQ_ENT_DWORDS + j]); + } prod = (Q_WRAP(smmu, smmu->cmdq_prod) | Q_IDX(smmu, smmu->cmdq_prod)) + n; smmu->cmdq_prod = Q_OVF(smmu->cmdq_prod) | Q_WRAP(smmu, prod) | Q_IDX(smmu, prod);