Commit f59e8549 authored by Nicolin Chen's avatar Nicolin Chen Committed by Will Deacon

iommu/arm-smmu-v3: Start a new batch if new command is not supported

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: default avatarNicolin Chen <nicolinc@nvidia.com>
Link: https://lore.kernel.org/r/aafb24b881504f18c5d0c7c15f2134e40ad2c486.1724970714.git.nicolinc@nvidia.comSigned-off-by: default avatarWill Deacon <will@kernel.org>
parent 918eb5c8
...@@ -923,10 +923,12 @@ static void arm_smmu_cmdq_batch_add(struct arm_smmu_device *smmu, ...@@ -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_batch *cmds,
struct arm_smmu_cmdq_ent *cmd) 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; int index;
if (cmds->num == CMDQ_BATCH_ENTRIES - 1 && if (force_sync || unsupported_cmd) {
(smmu->options & ARM_SMMU_OPT_CMDQ_FORCE_SYNC)) {
arm_smmu_cmdq_issue_cmdlist(smmu, cmds->cmdq, cmds->cmds, arm_smmu_cmdq_issue_cmdlist(smmu, cmds->cmdq, cmds->cmds,
cmds->num, true); cmds->num, true);
arm_smmu_cmdq_batch_init(smmu, cmds); arm_smmu_cmdq_batch_init(smmu, cmds);
......
...@@ -568,8 +568,15 @@ struct arm_smmu_cmdq { ...@@ -568,8 +568,15 @@ struct arm_smmu_cmdq {
atomic_long_t *valid_map; atomic_long_t *valid_map;
atomic_t owner_prod; atomic_t owner_prod;
atomic_t lock; 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 { struct arm_smmu_cmdq_batch {
u64 cmds[CMDQ_BATCH_ENTRIES * CMDQ_ENT_DWORDS]; u64 cmds[CMDQ_BATCH_ENTRIES * CMDQ_ENT_DWORDS];
struct arm_smmu_cmdq *cmdq; struct arm_smmu_cmdq *cmdq;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment