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; }