@@ -13,6 +13,7 @@
#include <nvhe/mem_protect.h>
#include <nvhe/mm.h>
#include <nvhe/pkvm.h>
+#include <nvhe/trap_handler.h>
#define ARM_SMMU_POLL_TIMEOUT_US 100000 /* 100ms arbitrary timeout */
@@ -1269,6 +1270,62 @@ static phys_addr_t smmu_iova_to_phys(struct kvm_hyp_iommu_domain *domain,
return paddr;
}
+static bool smmu_dabt_device(struct hyp_arm_smmu_v3_device *smmu,
+ struct kvm_cpu_context *host_ctxt,
+ u64 esr, u32 off)
+{
+ bool is_write = esr & ESR_ELx_WNR;
+ unsigned int len = BIT((esr & ESR_ELx_SAS) >> ESR_ELx_SAS_SHIFT);
+ int rd = (esr & ESR_ELx_SRT_MASK) >> ESR_ELx_SRT_SHIFT;
+ const u32 no_access = 0;
+ const u32 read_write = (u32)(-1);
+ const u32 read_only = is_write ? no_access : read_write;
+ u32 mask = no_access;
+
+ /*
+ * Only handle MMIO access with u32 size and alignment.
+ * We don't need to change 64-bit registers for now.
+ */
+ if ((len != sizeof(u32)) || (off & (sizeof(u32) - 1)))
+ return false;
+
+ switch (off) {
+ case ARM_SMMU_EVTQ_PROD + SZ_64K:
+ mask = read_write;
+ break;
+ case ARM_SMMU_EVTQ_CONS + SZ_64K:
+ mask = read_write;
+ break;
+ case ARM_SMMU_GERROR:
+ mask = read_only;
+ break;
+ case ARM_SMMU_GERRORN:
+ mask = read_write;
+ break;
+ };
+
+ if (!mask)
+ return false;
+ if (is_write)
+ writel_relaxed(cpu_reg(host_ctxt, rd) & mask, smmu->base + off);
+ else
+ cpu_reg(host_ctxt, rd) = readl_relaxed(smmu->base + off);
+
+ return true;
+}
+
+static bool smmu_dabt_handler(struct kvm_cpu_context *host_ctxt, u64 esr, u64 addr)
+{
+ struct hyp_arm_smmu_v3_device *smmu;
+
+ for_each_smmu(smmu) {
+ if (addr < smmu->mmio_addr || addr >= smmu->mmio_addr + smmu->mmio_size)
+ continue;
+ return smmu_dabt_device(smmu, host_ctxt, esr, addr - smmu->mmio_addr);
+ }
+ return false;
+}
+
/* Shared with the kernel driver in EL1 */
struct kvm_iommu_ops smmu_ops = {
.init = smmu_init,
@@ -1281,4 +1338,5 @@ struct kvm_iommu_ops smmu_ops = {
.map_pages = smmu_map_pages,
.unmap_pages = smmu_unmap_pages,
.iova_to_phys = smmu_iova_to_phys,
+ .dabt_handler = smmu_dabt_handler,
};
Add a data abort handler for the SMMUv3, we allow access for ETVQ and GERROR for debug purpose. Signed-off-by: Mostafa Saleh <smostafa@google.com> --- arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c | 58 +++++++++++++++++++++ 1 file changed, 58 insertions(+)