All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mostafa Saleh <smostafa@google.com>
To: linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,  kvmarm@lists.linux.dev,
	iommu@lists.linux.dev
Cc: catalin.marinas@arm.com, will@kernel.org, maz@kernel.org,
	 oliver.upton@linux.dev, joey.gouly@arm.com,
	suzuki.poulose@arm.com,  yuzenghui@huawei.com, joro@8bytes.org,
	jgg@ziepe.ca, mark.rutland@arm.com,  qperret@google.com,
	tabba@google.com, vdonnefort@google.com,
	 sebastianene@google.com, keirf@google.com,
	 Mostafa Saleh <smostafa@google.com>
Subject: [PATCH v7 15/24] iommu/arm-smmu-v3-kvm: Add CMDQ functions
Date: Wed, 15 Jul 2026 11:58:56 +0000	[thread overview]
Message-ID: <20260715115906.2664882-16-smostafa@google.com> (raw)
In-Reply-To: <20260715115906.2664882-1-smostafa@google.com>

Add functions to access the command queue, there are 2 main usage:
- Hypervisor's own commands, as TLB invalidation, would use functions
  as smmu_send_cmd(), which creates and sends a command.
- Add host commands to the shadow command queue, after being filtered,
  these will be added with smmu_add_cmd_raw.

Signed-off-by: Mostafa Saleh <smostafa@google.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  14 ++-
 .../iommu/arm/arm-smmu-v3/pkvm/arm-smmu-v3.c  | 109 ++++++++++++++++++
 2 files changed, 117 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 842d0c9b883c..cbc4589e89a8 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -1226,19 +1226,21 @@ unsigned long smmu_iidr_features(u32 reg, unsigned long features);
 unsigned long smmu_iidr_options(u32 reg, unsigned long options);
 
 /* Queue functions shared between kernel and hyp. */
-static inline bool queue_has_space(struct arm_smmu_ll_queue *q, u32 n)
+static inline u32 queue_space(struct arm_smmu_ll_queue *q)
 {
-	u32 space, prod, cons;
+	u32 prod, cons;
 
 	prod = Q_IDX(q, q->prod);
 	cons = Q_IDX(q, q->cons);
 
 	if (Q_WRP(q, q->prod) == Q_WRP(q, q->cons))
-		space = (1 << q->max_n_shift) - (prod - cons);
-	else
-		space = cons - prod;
+		return (1 << q->max_n_shift) - (prod - cons);
+	return cons - prod;
+}
 
-	return space >= n;
+static inline bool queue_has_space(struct arm_smmu_ll_queue *q, u32 n)
+{
+	return queue_space(q) >= n;
 }
 
 static inline bool queue_full(struct arm_smmu_ll_queue *q)
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 9f76f4e82341..8e798fd8fdaa 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
@@ -6,6 +6,7 @@
  */
 #include <asm/kvm_hyp.h>
 
+#include <nvhe/clock.h>
 #include <nvhe/iommu.h>
 #include <nvhe/mem_protect.h>
 #include <nvhe/trap_handler.h>
@@ -22,6 +23,36 @@ struct hyp_arm_smmu_v3_device *kvm_hyp_arm_smmu_v3_smmus;
 
 #define cmdq_size(cmdq)	((1 << ((cmdq)->llq.max_n_shift)) * CMDQ_ENT_DWORDS * 8)
 
+#define ARM_SMMU_EL2_POLL_TIMEOUT_US	1000
+/*
+ * Wait until @cond is true, can use WFE, if polling on an SMMU and
+ * event that supports it.
+ * Return 0 on success, or -ETIMEDOUT
+ */
+#define smmu_wait(__use_wfe, __cond)					\
+({									\
+	int __ret = 0;							\
+	u64 start = hyp_clock_ns();					\
+	u64 timeout = ARM_SMMU_EL2_POLL_TIMEOUT_US * 1000;		\
+									\
+	while (!(__cond)) {						\
+		if (__use_wfe) {					\
+			wfe();						\
+			if (__cond)					\
+				break;					\
+		} else {						\
+			cpu_relax();					\
+		}							\
+		if ((hyp_clock_ns() - start) >= timeout) {		\
+			if (__cond)					\
+				break;					\
+			__ret = -ETIMEDOUT;				\
+			break;						\
+		}							\
+	}								\
+	__ret;								\
+})
+
 static bool is_cmdq_enabled(struct hyp_arm_smmu_v3_device *smmu)
 {
 	return FIELD_GET(CR0_CMDQEN, smmu->cr0);
@@ -74,6 +105,84 @@ static int smmu_unshare_pages(phys_addr_t addr, size_t size)
 	return 0;
 }
 
+__maybe_unused
+static bool smmu_cmdq_has_space(struct arm_smmu_queue *cmdq, u32 n)
+{
+	struct arm_smmu_ll_queue *llq = &cmdq->llq;
+
+	WRITE_ONCE(llq->cons, readl_relaxed(cmdq->cons_reg));
+	return queue_has_space(llq, n);
+}
+
+static bool smmu_cmdq_full(struct arm_smmu_queue *cmdq)
+{
+	struct arm_smmu_ll_queue *llq = &cmdq->llq;
+
+	WRITE_ONCE(llq->cons, readl_relaxed(cmdq->cons_reg));
+	return queue_full(llq);
+}
+
+static bool smmu_cmdq_empty(struct arm_smmu_queue *cmdq)
+{
+	struct arm_smmu_ll_queue *llq = &cmdq->llq;
+
+	WRITE_ONCE(llq->cons, readl_relaxed(cmdq->cons_reg));
+	return queue_empty(llq);
+}
+
+static void smmu_add_cmd_raw(struct hyp_arm_smmu_v3_device *smmu,
+			     u64 *cmd)
+{
+	struct arm_smmu_queue *q = &smmu->cmdq;
+	struct arm_smmu_ll_queue *llq = &q->llq;
+
+	queue_write(Q_ENT(q, llq->prod), cmd,  CMDQ_ENT_DWORDS);
+	llq->prod = queue_inc_prod_n(llq, 1);
+}
+
+static int smmu_add_cmd(struct hyp_arm_smmu_v3_device *smmu,
+			struct arm_smmu_cmd *cmd)
+{
+	int ret;
+
+	hyp_assert_lock_held(&smmu->hw_lock);
+	ret = smmu_wait(false, !smmu_cmdq_full(&smmu->cmdq));
+	if (ret)
+		return ret;
+
+	smmu_add_cmd_raw(smmu, cmd->data);
+	writel(smmu->cmdq.llq.prod, smmu->cmdq.prod_reg);
+	return 0;
+}
+
+static int smmu_sync_cmd(struct hyp_arm_smmu_v3_device *smmu)
+{
+	int ret;
+	struct arm_smmu_cmd cmd;
+
+	hyp_assert_lock_held(&smmu->hw_lock);
+	cmd = arm_smmu_make_cmd_sync(CMDQ_SYNC_0_CS_SEV, 0);
+	ret = smmu_add_cmd(smmu, &cmd);
+	if (ret)
+		return ret;
+
+	return smmu_wait(smmu->features & ARM_SMMU_FEAT_SEV,
+			 smmu_cmdq_empty(&smmu->cmdq));
+}
+
+__maybe_unused
+static int smmu_send_cmd(struct hyp_arm_smmu_v3_device *smmu,
+			 struct arm_smmu_cmd *cmd)
+{
+	int ret = smmu_add_cmd(smmu, cmd);
+
+	hyp_assert_lock_held(&smmu->hw_lock);
+	if (ret)
+		return ret;
+
+	return smmu_sync_cmd(smmu);
+}
+
 /* Put the device in a state that can be probed by the host driver. */
 static void smmu_deinit_device(struct hyp_arm_smmu_v3_device *smmu)
 {
-- 
2.55.0.141.g00534a21ce-goog


  parent reply	other threads:[~2026-07-15 11:59 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-15 11:58 [PATCH v7 00/24] KVM: arm64: SMMUv3 driver for pKVM (trap and emulate) Mostafa Saleh
2026-07-15 11:58 ` [PATCH v7 01/24] KVM: arm64: Add a generic clock Mostafa Saleh
2026-07-15 13:48   ` Vincent Donnefort
2026-07-15 14:13     ` Mostafa Saleh
2026-07-15 14:34       ` Vincent Donnefort
2026-07-15 11:58 ` [PATCH v7 02/24] KVM: arm64: Donate MMIO to the hypervisor Mostafa Saleh
2026-07-15 17:26   ` Vincent Donnefort
2026-07-15 11:58 ` [PATCH v7 03/24] iommu/arm-smmu-v3: Split code with hyp Mostafa Saleh
2026-07-15 11:58 ` [PATCH v7 04/24] iommu/arm-smmu-v3: Move TLB range invalidation into common code Mostafa Saleh
2026-07-15 11:58 ` [PATCH v7 05/24] iommu/arm-smmu-v3: Move IDR parsing to common functions Mostafa Saleh
2026-07-15 11:58 ` [PATCH v7 06/24] KVM: arm64: iommu: Introduce IOMMU driver infrastructure Mostafa Saleh
2026-07-15 11:58 ` [PATCH v7 07/24] KVM: arm64: iommu: Shadow host stage-2 page table Mostafa Saleh
2026-07-15 11:58 ` [PATCH v7 08/24] KVM: arm64: iommu: Add memory pool Mostafa Saleh
2026-07-15 11:58 ` [PATCH v7 09/24] KVM: arm64: iommu: Support DABT for IOMMU Mostafa Saleh
2026-07-15 11:58 ` [PATCH v7 10/24] iommu/arm-smmu-v3-kvm: Add SMMUv3 driver Mostafa Saleh
2026-07-15 11:58 ` [PATCH v7 11/24] iommu/arm-smmu-v3-kvm: Add the kernel driver Mostafa Saleh
2026-07-15 11:58 ` [PATCH v7 12/24] iommu/arm-smmu-v3-kvm: Probe SMMU HW Mostafa Saleh
2026-07-15 11:58 ` [PATCH v7 13/24] iommu/arm-smmu-v3-kvm: Add MMIO emulation Mostafa Saleh
2026-07-15 11:58 ` [PATCH v7 14/24] iommu/arm-smmu-v3-kvm: Shadow the command queue Mostafa Saleh
2026-07-15 11:58 ` Mostafa Saleh [this message]
2026-07-15 11:58 ` [PATCH v7 16/24] iommu/arm-smmu-v3-kvm: Emulate CMDQ for host Mostafa Saleh
2026-07-15 11:58 ` [PATCH v7 17/24] iommu/arm-smmu-v3-kvm: Shadow stream table Mostafa Saleh
2026-07-15 11:58 ` [PATCH v7 18/24] iommu/arm-smmu-v3-kvm: Shadow STEs Mostafa Saleh
2026-07-15 11:59 ` [PATCH v7 19/24] iommu/arm-smmu-v3-kvm: Share other queues Mostafa Saleh
2026-07-15 11:59 ` [PATCH v7 20/24] iommu/arm-smmu-v3-kvm: Emulate GBPA Mostafa Saleh
2026-07-15 11:59 ` [PATCH v7 21/24] iommu/io-pgtable-arm: Support io-pgtable-arm in the hypervisor Mostafa Saleh
2026-07-15 11:59 ` [PATCH v7 22/24] iommu/arm-smmu-v3-kvm: Shadow the CPU stage-2 page table Mostafa Saleh
2026-07-15 11:59 ` [PATCH v7 23/24] iommu/arm-smmu-v3-kvm: Enable nesting Mostafa Saleh
2026-07-15 11:59 ` [PATCH v7 24/24] KVM: arm64: Add documentation for pKVM DMA isolation Mostafa Saleh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260715115906.2664882-16-smostafa@google.com \
    --to=smostafa@google.com \
    --cc=catalin.marinas@arm.com \
    --cc=iommu@lists.linux.dev \
    --cc=jgg@ziepe.ca \
    --cc=joey.gouly@arm.com \
    --cc=joro@8bytes.org \
    --cc=keirf@google.com \
    --cc=kvmarm@lists.linux.dev \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=maz@kernel.org \
    --cc=oliver.upton@linux.dev \
    --cc=qperret@google.com \
    --cc=sebastianene@google.com \
    --cc=suzuki.poulose@arm.com \
    --cc=tabba@google.com \
    --cc=vdonnefort@google.com \
    --cc=will@kernel.org \
    --cc=yuzenghui@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.