lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20241114030452.10149-1-paul@os.amperecomputing.com>
Date: Wed, 13 Nov 2024 19:04:52 -0800
From: Paul Benoit <paul@...amperecomputing.com>
To: linux-kernel@...r.kernel.org
Cc: Paul Benoit <paul@...amperecomputing.com>,
	Mark Rutland <mark.rutland@....com>,
	Lorenzo Pieralisi <lpieralisi@...nel.org>,
	Sudeep Holla <sudeep.holla@....com>,
	linux-arm-kernel@...ts.infradead.org
Subject: [PATCH] firmware: smccc: Support optional Arm SMC SOC_ID name

Issue Number 1.6 of the Arm SMC Calling Convention introduces an
optional SOC_ID name string.  If available, point the 'machine' field of
the SoC Device Attributes at this string so that it will appear under
/sys/bus/soc/devices/soc0/machine.  On Arm SMC compliant SoCs, this will
allow things like 'lscpu' to eventually get a SoC provider model name
from there rather than each tool/utility needing to get a possibly
inconsistent, obsolete, or incorrect model/machine name from its own
hardcoded model/machine name table.

Signed-off-by: Paul Benoit <paul@...amperecomputing.com>
Cc: Mark Rutland <mark.rutland@....com>
Cc: Lorenzo Pieralisi <lpieralisi@...nel.org>
Cc: Sudeep Holla <sudeep.holla@....com>
Cc: linux-arm-kernel@...ts.infradead.org
---
 drivers/firmware/smccc/smccc.c  | 70 +++++++++++++++++++++++++++++++++
 drivers/firmware/smccc/soc_id.c |  1 +
 include/linux/arm-smccc.h       | 10 +++++
 3 files changed, 81 insertions(+)

diff --git a/drivers/firmware/smccc/smccc.c b/drivers/firmware/smccc/smccc.c
index a74600d9f2d7..1c7084b0b8d7 100644
--- a/drivers/firmware/smccc/smccc.c
+++ b/drivers/firmware/smccc/smccc.c
@@ -18,10 +18,12 @@ static enum arm_smccc_conduit smccc_conduit = SMCCC_CONDUIT_NONE;
 bool __ro_after_init smccc_trng_available = false;
 s32 __ro_after_init smccc_soc_id_version = SMCCC_RET_NOT_SUPPORTED;
 s32 __ro_after_init smccc_soc_id_revision = SMCCC_RET_NOT_SUPPORTED;
+char __ro_after_init smccc_soc_id_name[136] = "";
 
 void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit)
 {
 	struct arm_smccc_res res;
+	struct arm_smccc_1_2_regs regs_1_2;
 
 	smccc_version = version;
 	smccc_conduit = conduit;
@@ -37,6 +39,66 @@ void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit)
 			smccc_soc_id_version = (s32)res.a0;
 			arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_SOC_ID, 1, &res);
 			smccc_soc_id_revision = (s32)res.a0;
+
+			/* Issue Number 1.6 of the Arm SMC Calling Convention
+			 * specification introduces an optional "name" string
+			 * to the ARM_SMCCC_ARCH_SOC_ID function.  Fetch it if
+			 * available.
+			 */
+			regs_1_2.a0 = ARM_SMCCC_ARCH_SOC_ID;
+			regs_1_2.a1 = 2;	/* SOC_ID name */
+			arm_smccc_1_2_smc(
+				(const struct arm_smccc_1_2_regs *)&regs_1_2,
+				(struct arm_smccc_1_2_regs *)&regs_1_2);
+
+			if ((u32)regs_1_2.a0 == 0) {
+				unsigned long *destination =
+					(unsigned long *)smccc_soc_id_name;
+
+				/*
+				 * Copy regs_1_2.a1..regs_1_2.a17 to the
+				 * smccc_soc_id_name string with consideration
+				 * to the endianness of the values in a1..a17.
+				 * As per Issue 1.6 of the Arm SMC Calling
+				 * Convention, the string will be NUL terminated
+				 * and padded, from the end of the string to
+				 * the end of the 136 byte buffer, with NULs.
+				 */
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a1);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a2);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a3);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a4);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a5);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a6);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a7);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a8);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a9);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a10);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a11);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a12);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a13);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a14);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a15);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a16);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a17);
+			}
 		}
 	}
 }
@@ -67,6 +129,14 @@ s32 arm_smccc_get_soc_id_revision(void)
 }
 EXPORT_SYMBOL_GPL(arm_smccc_get_soc_id_revision);
 
+char *arm_smccc_get_soc_id_name(void)
+{
+	if (strnlen(smccc_soc_id_name, sizeof(smccc_soc_id_name)))
+		return smccc_soc_id_name;
+
+	return NULL;
+}
+
 static int __init smccc_devices_init(void)
 {
 	struct platform_device *pdev;
diff --git a/drivers/firmware/smccc/soc_id.c b/drivers/firmware/smccc/soc_id.c
index 1990263fbba0..6f698c703868 100644
--- a/drivers/firmware/smccc/soc_id.c
+++ b/drivers/firmware/smccc/soc_id.c
@@ -72,6 +72,7 @@ static int __init smccc_soc_init(void)
 	soc_dev_attr->soc_id = soc_id_str;
 	soc_dev_attr->revision = soc_id_rev_str;
 	soc_dev_attr->family = soc_id_jep106_id_str;
+	soc_dev_attr->machine = arm_smccc_get_soc_id_name();
 
 	soc_dev = soc_device_register(soc_dev_attr);
 	if (IS_ERR(soc_dev)) {
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 67f6fdf2e7cd..5935cf636135 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -333,6 +333,16 @@ s32 arm_smccc_get_soc_id_version(void);
  */
 s32 arm_smccc_get_soc_id_revision(void);
 
+/**
+ * arm_smccc_get_soc_id_name()
+ *
+ * Returns the SOC ID name.
+ *
+ * When ARM_SMCCC_ARCH_SOC_ID name is not present, returns NULL.
+ */
+char *arm_smccc_get_soc_id_name(void);
+
+
 /**
  * struct arm_smccc_res - Result from SMC/HVC call
  * @a0-a3 result values from registers 0 to 3
-- 
2.46.2


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ