Re: [PATCH v22 02/10] firmware: arm_rmm: Check for RMI support at init
From: Gavin Shan
Date: Mon Oct 12 2026 - 23:58:02 EST
Hi Suzuki,
On 10/2/26 4:14 PM, Suzuki K Poulose wrote:
From: Steven Price <steven.price@xxxxxxx>
Query the RMI version number and check if it is a compatible version.
All RMM feature registers are read and exposed for future code to
use. Also restrict the support to SMC conduit.
We only support this for Little Endian kernels, the Big Endian kernel
support is anyway marked BROKEN and is being removed.
Cc: Marc Zyngier <maz@xxxxxxxxxx>
Cc: Oliver Upton <oupton@xxxxxxxxxx>
Reviewed-by: Jonathan Cameron <jonathan.cameron@xxxxxxxxxxxxxxxx>
Reviewed-by: Gavin Shan <gshan@xxxxxxxxxx>
Reviewed-by: Catalin Marinas <catalin.marinas@xxxxxxx>
Tested-by: Gavin Shan <gshan@xxxxxxxxxx>
Signed-off-by: Steven Price <steven.price@xxxxxxx>
Co-developed-by: Suzuki K Poulose <suzuki.poulose@xxxxxxx>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@xxxxxxx>
---
[...]
---
MAINTAINERS | 2 +
arch/arm64/Kconfig | 1 +
arch/arm64/kernel/cpufeature.c | 1 +
arch/arm64/kvm/sys_regs.c | 2 +
drivers/firmware/Kconfig | 1 +
drivers/firmware/Makefile | 1 +
drivers/firmware/arm_rmm/Kconfig | 25 +++++++
drivers/firmware/arm_rmm/Makefile | 1 +
drivers/firmware/arm_rmm/rmi.c | 112 ++++++++++++++++++++++++++++++
include/linux/arm-rmi-cmds.h | 48 +++++++++++++
10 files changed, 194 insertions(+)
create mode 100644 drivers/firmware/arm_rmm/Kconfig
create mode 100644 drivers/firmware/arm_rmm/Makefile
create mode 100644 drivers/firmware/arm_rmm/rmi.c
create mode 100644 include/linux/arm-rmi-cmds.h
[...]
diff --git a/drivers/firmware/arm_rmm/rmi.c b/drivers/firmware/arm_rmm/rmi.c
new file mode 100644
index 0000000000000..06f5392c982d2
--- /dev/null
+++ b/drivers/firmware/arm_rmm/rmi.c
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023-2026 ARM Ltd.
+ */
+
+#include <linux/arm-rmi-cmds.h>
+#include <linux/cpufeature.h>
+#include <linux/memblock.h>
+#include <linux/slab.h>
+
+#include <asm/memory.h>
+#include <asm/pgtable-hwdef.h>
+
+/* RMM v2.0 defines RmiFeatureRegister0 to RmiFeatureRegister4. */
+static unsigned long rmi_feat_reg_cache[5] __ro_after_init;
+
+static int rmi_check_version(void)
+{
+ unsigned short version_major, version_minor;
+ unsigned long host_version = RMI_ABI_VERSION(RMI_ABI_MAJOR_VERSION,
+ RMI_ABI_MINOR_VERSION);
+ unsigned long aa64pfr0 = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
+ struct arm_smccc_1_2_regs res = {
+ SMC_RMI_VERSION, host_version,
+ };
+
+ /* If RME isn't supported, then RMI can't be */
+ if (cpuid_feature_extract_unsigned_field(aa64pfr0, ID_AA64PFR0_EL1_RME_SHIFT) == 0)
+ return -ENXIO;
+
+ if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_SMC)
+ return -ENXIO;
I think we need to ensure SMCCC version is v1.2 or a newer one here? arm_smccc_1_2_smc()
is immediately called by rmi_smccc_invoke() after this check.
if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_SMC ||
arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2)
return -ENXIO;
Thanks,
Gavin
+
+ rmi_smccc_invoke(&res);
+ if (res.a0 == SMCCC_RET_NOT_SUPPORTED)
+ return -ENXIO;
+
+ version_major = RMI_ABI_VERSION_GET_MAJOR(res.a1);
+ version_minor = RMI_ABI_VERSION_GET_MINOR(res.a1);
+
+ if (res.a0 != RMI_SUCCESS) {
+ unsigned short high_version_major, high_version_minor;
+
+ high_version_major = RMI_ABI_VERSION_GET_MAJOR(res.a2);
+ high_version_minor = RMI_ABI_VERSION_GET_MINOR(res.a2);
+
+ pr_err("Unsupported RMI ABI (v%d.%d - v%d.%d) we want v%d.%d\n",
+ version_major, version_minor,
+ high_version_major, high_version_minor,
+ RMI_ABI_MAJOR_VERSION,
+ RMI_ABI_MINOR_VERSION);
+ return -ENXIO;
+ }
+
+ pr_info("RMI ABI version %d.%d\n", version_major, version_minor);
+
+ return 0;
+}
+
[...]