iommu/arm-smmu-v3: Start a new batch if new command is not supported
authorNicolin Chen <nicolinc@nvidia.com>
Thu, 29 Aug 2024 22:34:38 +0000 (15:34 -0700)
committerWill Deacon <will@kernel.org>
Fri, 30 Aug 2024 14:28:25 +0000 (15:28 +0100)
The VCMDQ in the tegra241-cmdqv driver has a guest mode that supports only
a few invalidation commands. A batch is initialized with a cmdq, so it has
to confirm whether a new command is supported or not.

Add a supports_cmd function pointer to the cmdq structure, where the vcmdq
driver should hook a command scan function. Add an inline helper too so it
can be used by both sides.

If a new command is not supported, simply issue the existing batch and re-
init it as a new batch.

Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Link: https://lore.kernel.org/r/aafb24b881504f18c5d0c7c15f2134e40ad2c486.1724970714.git.nicolinc@nvidia.com
Signed-off-by: Will Deacon <will@kernel.org>
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h

index dee23ec352e747f055003f40d63aa28b5da86a4d..1e67fd4fbcf32250202ea3e757b29a7a15ffc9d6 100644 (file)
@@ -923,10 +923,12 @@ static void arm_smmu_cmdq_batch_add(struct arm_smmu_device *smmu,
                                    struct arm_smmu_cmdq_batch *cmds,
                                    struct arm_smmu_cmdq_ent *cmd)
 {
+       bool unsupported_cmd = !arm_smmu_cmdq_supports_cmd(cmds->cmdq, cmd);
+       bool force_sync = (cmds->num == CMDQ_BATCH_ENTRIES - 1) &&
+                         (smmu->options & ARM_SMMU_OPT_CMDQ_FORCE_SYNC);
        int index;
 
-       if (cmds->num == CMDQ_BATCH_ENTRIES - 1 &&
-           (smmu->options & ARM_SMMU_OPT_CMDQ_FORCE_SYNC)) {
+       if (force_sync || unsupported_cmd) {
                arm_smmu_cmdq_issue_cmdlist(smmu, cmds->cmdq, cmds->cmds,
                                            cmds->num, true);
                arm_smmu_cmdq_batch_init(smmu, cmds);
index 9fa22ee2383dc3ee33e7851b3a27b16bd05570f9..4deb40cfe2e18d948af2d5bb5206b8a07a87ebbe 100644 (file)
@@ -568,8 +568,15 @@ struct arm_smmu_cmdq {
        atomic_long_t                   *valid_map;
        atomic_t                        owner_prod;
        atomic_t                        lock;
+       bool                            (*supports_cmd)(struct arm_smmu_cmdq_ent *ent);
 };
 
+static inline bool arm_smmu_cmdq_supports_cmd(struct arm_smmu_cmdq *cmdq,
+                                             struct arm_smmu_cmdq_ent *ent)
+{
+       return cmdq->supports_cmd ? cmdq->supports_cmd(ent) : true;
+}
+
 struct arm_smmu_cmdq_batch {
        u64                             cmds[CMDQ_BATCH_ENTRIES * CMDQ_ENT_DWORDS];
        struct arm_smmu_cmdq            *cmdq;