From 4a7da93bdbfcd166f5bb67a69d6f017da158c7e2 Mon Sep 17 00:00:00 2001 From: David Brazdil Date: Fri, 9 Jul 2021 11:47:09 +0100 Subject: [PATCH] ANDROID: KVM: arm64: Read and check S2MPU_VERSION Read S2MPU_VERSION during driver init and check it against list of supported versions. The register fields are as follows: - MAJOR_ARCH_VER, - MINOR_ARCH_VER, - REV_ARCH_VER, - RTL_VER. Their exact use is not documented. For now, we mask out RTL_VER and expect a match on MAJOR_, MINOR_ and REV_ARCH_VER. This may be tweaked in the future. Test: builds, boots Bug: 190463801 Signed-off-by: David Brazdil Change-Id: I2fbd20ab78a992c8bdb3574a6d480012260c9ded --- arch/arm64/include/asm/kvm_s2mpu.h | 17 +++++++++++++++++ arch/arm64/kvm/iommu/s2mpu.c | 12 +++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/kvm_s2mpu.h b/arch/arm64/include/asm/kvm_s2mpu.h index ba0db7988117..2ae35aba43e6 100644 --- a/arch/arm64/include/asm/kvm_s2mpu.h +++ b/arch/arm64/include/asm/kvm_s2mpu.h @@ -7,6 +7,23 @@ #ifndef __ARM64_KVM_S2MPU_H__ #define __ARM64_KVM_S2MPU_H__ +#define REG_NS_VERSION 0x60 + +#define VERSION_MAJOR_ARCH_VER_MASK GENMASK(31, 28) +#define VERSION_MINOR_ARCH_VER_MASK GENMASK(27, 24) +#define VERSION_REV_ARCH_VER_MASK GENMASK(23, 16) +#define VERSION_RTL_VER_MASK GENMASK(7, 0) + +/* Ignore RTL version in driver version check. */ +#define VERSION_CHECK_MASK (VERSION_MAJOR_ARCH_VER_MASK | \ + VERSION_MINOR_ARCH_VER_MASK | \ + VERSION_REV_ARCH_VER_MASK) + +enum s2mpu_version { + S2MPU_VERSION_8 = 0x11000000, + S2MPU_VERSION_9 = 0x20000000, +}; + enum s2mpu_power_state { S2MPU_POWER_ALWAYS_ON, S2MPU_POWER_ON, diff --git a/arch/arm64/kvm/iommu/s2mpu.c b/arch/arm64/kvm/iommu/s2mpu.c index 9a9e2db44037..5d7a87dee0d3 100644 --- a/arch/arm64/kvm/iommu/s2mpu.c +++ b/arch/arm64/kvm/iommu/s2mpu.c @@ -18,7 +18,7 @@ static int s2mpu_probe(struct platform_device *pdev) void __iomem *kaddr; size_t res_size; enum s2mpu_power_state power_state = S2MPU_POWER_ALWAYS_ON; - u32 power_domain_id = 0; + u32 version, power_domain_id = 0; int ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -58,6 +58,16 @@ static int s2mpu_probe(struct platform_device *pdev) return ret; } + version = readl_relaxed(kaddr + REG_NS_VERSION); + switch (version & VERSION_CHECK_MASK) { + case S2MPU_VERSION_8: + case S2MPU_VERSION_9: + break; + default: + dev_err(&pdev->dev, "unexpected version 0x%08x", version); + return -EINVAL; + } + return 0; }