[RFC PATCH v2 29/58] KVM: arm64: smmu-v3: Setup event queue
Mostafa Saleh
smostafa at google.com
Thu Dec 12 10:03:53 PST 2024
The host can use the event queue for debuging, and unlike the command
queue, it would be managed by the kernel.
However, it must set in a shared state so it can't be donated to the
hypervisor later.
This relies on the ARM_SMMU_EVTQ_BASE can't be changed after
de-privilege.
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c | 39 +++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
index 43d2ce7828c1..5020f74421ad 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
@@ -342,6 +342,41 @@ static int smmu_init_cmdq(struct hyp_arm_smmu_v3_device *smmu)
return 0;
}
+/*
+ * Event q support is optional and managed by the kernel,
+ * However, it must set in a shared state so it can't be donated
+ * to the hypervisor later.
+ * This relies on the ARM_SMMU_EVTQ_BASE can't be changed after
+ * de-privilege.
+ */
+static int smmu_init_evtq(struct hyp_arm_smmu_v3_device *smmu)
+{
+ u64 evtq_base, evtq_pfn;
+ size_t evtq_nr_entries, evtq_size, evtq_nr_pages;
+ size_t i;
+ int ret;
+
+ evtq_base = readq_relaxed(smmu->base + ARM_SMMU_EVTQ_BASE);
+ if (!evtq_base)
+ return 0;
+
+ if (evtq_base & ~(Q_BASE_RWA | Q_BASE_ADDR_MASK | Q_BASE_LOG2SIZE))
+ return -EINVAL;
+
+ evtq_nr_entries = 1 << (evtq_base & Q_BASE_LOG2SIZE);
+ evtq_size = evtq_nr_entries * EVTQ_ENT_DWORDS * 8;
+ evtq_nr_pages = PAGE_ALIGN(evtq_size) >> PAGE_SHIFT;
+
+ evtq_pfn = PAGE_ALIGN(evtq_base & Q_BASE_ADDR_MASK) >> PAGE_SHIFT;
+
+ for (i = 0 ; i < evtq_nr_pages ; ++i) {
+ ret = __pkvm_host_share_hyp(evtq_pfn + i);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
static int smmu_init_strtab(struct hyp_arm_smmu_v3_device *smmu)
{
int ret;
@@ -429,6 +464,10 @@ static int smmu_init_device(struct hyp_arm_smmu_v3_device *smmu)
if (ret)
return ret;
+ ret = smmu_init_evtq(smmu);
+ if (ret)
+ return ret;
+
ret = smmu_init_strtab(smmu);
if (ret)
return ret;
--
2.47.0.338.g60cca15819-goog
More information about the linux-arm-kernel
mailing list