Skip to content

Commit 2f657ad

Browse files
rmurphy-armwildea01
authored andcommitted
iommu/arm-smmu-v3: Specialise CMD_SYNC handling
CMD_SYNC already has a bit of special treatment here and there, but as we're about to extend it with more functionality for completing outside the CMDQ lock, things are going to get rather messy if we keep trying to cram everything into a single generic command interface. Instead, let's break out the issuing of CMD_SYNC into its own specific helper where upcoming changes will have room to breathe. Signed-off-by: Robin Murphy <[email protected]> Signed-off-by: Will Deacon <[email protected]>
1 parent 2a22baa commit 2f657ad

File tree

1 file changed

+34
-18
lines changed

1 file changed

+34
-18
lines changed

drivers/iommu/arm-smmu-v3.c

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -929,13 +929,22 @@ static void arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu)
929929
queue_write(Q_ENT(q, cons), cmd, q->ent_dwords);
930930
}
931931

932+
static void arm_smmu_cmdq_insert_cmd(struct arm_smmu_device *smmu, u64 *cmd)
933+
{
934+
struct arm_smmu_queue *q = &smmu->cmdq.q;
935+
bool wfe = !!(smmu->features & ARM_SMMU_FEAT_SEV);
936+
937+
while (queue_insert_raw(q, cmd) == -ENOSPC) {
938+
if (queue_poll_cons(q, false, wfe))
939+
dev_err_ratelimited(smmu->dev, "CMDQ timeout\n");
940+
}
941+
}
942+
932943
static void arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
933944
struct arm_smmu_cmdq_ent *ent)
934945
{
935946
u64 cmd[CMDQ_ENT_DWORDS];
936947
unsigned long flags;
937-
bool wfe = !!(smmu->features & ARM_SMMU_FEAT_SEV);
938-
struct arm_smmu_queue *q = &smmu->cmdq.q;
939948

940949
if (arm_smmu_cmdq_build_cmd(cmd, ent)) {
941950
dev_warn(smmu->dev, "ignoring unknown CMDQ opcode 0x%x\n",
@@ -944,14 +953,27 @@ static void arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
944953
}
945954

946955
spin_lock_irqsave(&smmu->cmdq.lock, flags);
947-
while (queue_insert_raw(q, cmd) == -ENOSPC) {
948-
if (queue_poll_cons(q, false, wfe))
949-
dev_err_ratelimited(smmu->dev, "CMDQ timeout\n");
950-
}
956+
arm_smmu_cmdq_insert_cmd(smmu, cmd);
957+
spin_unlock_irqrestore(&smmu->cmdq.lock, flags);
958+
}
951959

952-
if (ent->opcode == CMDQ_OP_CMD_SYNC && queue_poll_cons(q, true, wfe))
953-
dev_err_ratelimited(smmu->dev, "CMD_SYNC timeout\n");
960+
static void arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
961+
{
962+
u64 cmd[CMDQ_ENT_DWORDS];
963+
unsigned long flags;
964+
bool wfe = !!(smmu->features & ARM_SMMU_FEAT_SEV);
965+
struct arm_smmu_cmdq_ent ent = { .opcode = CMDQ_OP_CMD_SYNC };
966+
int ret;
967+
968+
arm_smmu_cmdq_build_cmd(cmd, &ent);
969+
970+
spin_lock_irqsave(&smmu->cmdq.lock, flags);
971+
arm_smmu_cmdq_insert_cmd(smmu, cmd);
972+
ret = queue_poll_cons(&smmu->cmdq.q, true, wfe);
954973
spin_unlock_irqrestore(&smmu->cmdq.lock, flags);
974+
975+
if (ret)
976+
dev_err_ratelimited(smmu->dev, "CMD_SYNC timeout\n");
955977
}
956978

957979
/* Context descriptor manipulation functions */
@@ -1027,8 +1049,7 @@ static void arm_smmu_sync_ste_for_sid(struct arm_smmu_device *smmu, u32 sid)
10271049
};
10281050

10291051
arm_smmu_cmdq_issue_cmd(smmu, &cmd);
1030-
cmd.opcode = CMDQ_OP_CMD_SYNC;
1031-
arm_smmu_cmdq_issue_cmd(smmu, &cmd);
1052+
arm_smmu_cmdq_issue_sync(smmu);
10321053
}
10331054

10341055
static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid,
@@ -1355,10 +1376,7 @@ static irqreturn_t arm_smmu_combined_irq_handler(int irq, void *dev)
13551376
/* IO_PGTABLE API */
13561377
static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu)
13571378
{
1358-
struct arm_smmu_cmdq_ent cmd;
1359-
1360-
cmd.opcode = CMDQ_OP_CMD_SYNC;
1361-
arm_smmu_cmdq_issue_cmd(smmu, &cmd);
1379+
arm_smmu_cmdq_issue_sync(smmu);
13621380
}
13631381

13641382
static void arm_smmu_tlb_sync(void *cookie)
@@ -2402,8 +2420,7 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
24022420
/* Invalidate any cached configuration */
24032421
cmd.opcode = CMDQ_OP_CFGI_ALL;
24042422
arm_smmu_cmdq_issue_cmd(smmu, &cmd);
2405-
cmd.opcode = CMDQ_OP_CMD_SYNC;
2406-
arm_smmu_cmdq_issue_cmd(smmu, &cmd);
2423+
arm_smmu_cmdq_issue_sync(smmu);
24072424

24082425
/* Invalidate any stale TLB entries */
24092426
if (smmu->features & ARM_SMMU_FEAT_HYP) {
@@ -2413,8 +2430,7 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
24132430

24142431
cmd.opcode = CMDQ_OP_TLBI_NSNH_ALL;
24152432
arm_smmu_cmdq_issue_cmd(smmu, &cmd);
2416-
cmd.opcode = CMDQ_OP_CMD_SYNC;
2417-
arm_smmu_cmdq_issue_cmd(smmu, &cmd);
2433+
arm_smmu_cmdq_issue_sync(smmu);
24182434

24192435
/* Event queue */
24202436
writeq_relaxed(smmu->evtq.q.q_base, smmu->base + ARM_SMMU_EVTQ_BASE);

0 commit comments

Comments
 (0)