public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/4] arm64: realm: Support for probing RSI earlier
@ 2026-04-29 10:35 Suzuki K Poulose
  2026-04-29 10:35 ` [RFC PATCH 1/4] arm64: acpi: Refactor FADT table verification Suzuki K Poulose
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Suzuki K Poulose @ 2026-04-29 10:35 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, catalin.marinas, will, ardb, lpieralisi,
	mark.rutland, steven.price, aneesh.kumar, sudeep.holla, robh, maz,
	Suzuki K Poulose

The Realm Guest linux support is broken without rodata=full (fortunately default
for arm64), as we detect the RSI support after we have created the Linear map
with Block/Contiguous mappings. If the boot CPU doesn't support BBML2_NOABORT
(there are CPUs out there with FEAT_RME and no - useable - BBML2_NOABORT)
we are then not able to split the page tables down to PTE level if the system
as such doesn't support BBML2.

See the following link for the discussion.

https://lore.kernel.org/all/20260330161705.3349825-2-ryan.roberts@arm.com/

The available options are :
 1. Start with PTE level mappings at paging_init() and then "FOLD" the page tables
    to Block/Cont mappings after we have the full picture available. Looking at the
    future (with BBML3), this might mean "additional work" for most of the systems
    at boot. But not bad as splitting them ?
 2. Hold the secondary CPUs in busy loop with MMU disabled and split the mappings
    by the boot CPU with MMU off (if Boot CPU can't support BBML2). This is tricky
    with the page allocations required to add the page-tables.
 3. Move the detection of Realm support earlier to make a better decision for
    paging_init(), with an added bonus of earlycon support for Realms without
    the user having to work out the "top bit" for the Realm.

This series is an attempt to implement (3) (without the earlycon support). We try
to probe the PSCI conduit early from the DT/ACPI. DT is not flattened at this time.

ACPI table is not mapped in full, so we have to map one table at a time and walk
from the Root of the table (RSDP) through to XSDT and find the FADT table from
the array of table pointers there. Minimal verification is performed on the 
tables (e.g., revision checks, standard FADT sanity checks). Checksum is not
verified, but should be possible to do for the parts we consume.

With arm64, during the normal boot, we could fallback to using DT if the ACPI
tables are not useable. So, during the early probe, we try to follow the similar
logic and probe the conduit from both DT and ACPI where available. If both of
them contain a conduit, we only proceed if they match. Otherwise, we skip the
early probe and do things the normal way. (Any sane system shouldn't have such
a mismatch, but..)

Once we probe the PSCI conduit, PSCI is probed, along with the presence of SMCCC.
With that in place, we try to probe the RSI support after the early probe and
advertise the Realm World. If the early probe wasn't successful, we fall back
to the late mode, where we could end up with (on a possibly rare broken firmware).

NOTE: This is an early RFC attempt to moving the PSCI detection earlier. The other
option(s) that may be worth exploring are:

1. On systems with EFI, parse this from EFI Stub and pass the data back in the
   DT Stub, under chosen node. e.g., "linux,uefi-arm-psci-conduit".
   Challenge: EFI stub doesn't seem to be ACPI aware. We could make that change,
   we only need a few table walks.
2. Have EFI firmware provide this information (with my limited knowledge on the
   area, this looks like too much work, and bending the standards)
3. Append arm64 boot protocol to have this information passed to the kernel.
   (Firmware provided) - (Steven's idea)
4. Any other options ?


This series is also available here :

git@git.gitlab.arm.com:linux-arm/linux-cca.git	cca-guest/early-rsi-detection/rfc-v1

Thoughts ?

Suzuki


Suzuki K Poulose (4):
  arm64: acpi: Refactor FADT table verification
  psci: Add support for Early detection and init
  arm64: psci: Move detection and SMCCC probe earlier
  arm64: realm: Move RSI detection earlier

 arch/arm64/include/asm/acpi.h |   1 +
 arch/arm64/include/asm/rsi.h  |   1 +
 arch/arm64/kernel/acpi.c      | 136 +++++++++++++++++++++++++++-------
 arch/arm64/kernel/rsi.c       |  23 +++++-
 arch/arm64/kernel/setup.c     |  69 +++++++++++++++++
 drivers/firmware/psci/psci.c  |  49 +++++++++++-
 include/linux/psci.h          |   2 +
 7 files changed, 252 insertions(+), 29 deletions(-)

-- 
2.43.0



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [RFC PATCH 1/4] arm64: acpi: Refactor FADT table verification
  2026-04-29 10:35 [RFC PATCH 0/4] arm64: realm: Support for probing RSI earlier Suzuki K Poulose
@ 2026-04-29 10:35 ` Suzuki K Poulose
  2026-04-29 10:35 ` [RFC PATCH 2/4] psci: Add support for Early detection and init Suzuki K Poulose
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Suzuki K Poulose @ 2026-04-29 10:35 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, catalin.marinas, will, ardb, lpieralisi,
	mark.rutland, steven.price, aneesh.kumar, sudeep.holla, robh, maz,
	Suzuki K Poulose

Refactor the FADT sanity check, such that this could be reused. We are soon
going to consume the FADT early at boot for probing the PSCI conduit, and this
will be of use.

Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 arch/arm64/kernel/acpi.c | 55 +++++++++++++++++++++-------------------
 1 file changed, 29 insertions(+), 26 deletions(-)

diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index af90128cfed5..30c7b11a8a9d 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -118,6 +118,34 @@ bool acpi_psci_use_hvc(void)
 	return acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC;
 }
 
+static int __init __acpi_fadt_sanity_check(struct acpi_table_fadt *fadt)
+{
+	struct acpi_table_header *table = (struct acpi_table_header *)fadt;
+
+	/*
+	 * Revision in table header is the FADT Major revision, and there
+	 * is a minor revision of FADT which was introduced by ACPI 5.1,
+	 * we only deal with ACPI 5.1 or newer revision to get GIC and SMP
+	 * boot protocol configuration data.
+	 */
+	if (table->revision < 5 ||
+	   (table->revision == 5 && fadt->minor_revision < 1)) {
+		pr_err(FW_BUG "Unsupported FADT revision %d.%d, should be 5.1+\n",
+		       table->revision, fadt->minor_revision);
+
+		if (!fadt->arm_boot_flags) {
+			return -EINVAL;
+		}
+		pr_err("FADT has ARM boot flags set, assuming 5.1\n");
+	}
+
+	if (!(fadt->flags & ACPI_FADT_HW_REDUCED)) {
+		pr_err("FADT not ACPI hardware reduced compliant\n");
+		return -EINVAL;
+	}
+	return 0;
+}
+
 /*
  * acpi_fadt_sanity_check() - Check FADT presence and carry out sanity
  *			      checks on it
@@ -127,7 +155,6 @@ bool acpi_psci_use_hvc(void)
 static int __init acpi_fadt_sanity_check(void)
 {
 	struct acpi_table_header *table;
-	struct acpi_table_fadt *fadt;
 	acpi_status status;
 	int ret = 0;
 
@@ -143,32 +170,8 @@ static int __init acpi_fadt_sanity_check(void)
 		return -ENODEV;
 	}
 
-	fadt = (struct acpi_table_fadt *)table;
+	ret = __acpi_fadt_sanity_check((struct acpi_table_fadt *)table);
 
-	/*
-	 * Revision in table header is the FADT Major revision, and there
-	 * is a minor revision of FADT which was introduced by ACPI 5.1,
-	 * we only deal with ACPI 5.1 or newer revision to get GIC and SMP
-	 * boot protocol configuration data.
-	 */
-	if (table->revision < 5 ||
-	   (table->revision == 5 && fadt->minor_revision < 1)) {
-		pr_err(FW_BUG "Unsupported FADT revision %d.%d, should be 5.1+\n",
-		       table->revision, fadt->minor_revision);
-
-		if (!fadt->arm_boot_flags) {
-			ret = -EINVAL;
-			goto out;
-		}
-		pr_err("FADT has ARM boot flags set, assuming 5.1\n");
-	}
-
-	if (!(fadt->flags & ACPI_FADT_HW_REDUCED)) {
-		pr_err("FADT not ACPI hardware reduced compliant\n");
-		ret = -EINVAL;
-	}
-
-out:
 	/*
 	 * acpi_get_table() creates FADT table mapping that
 	 * should be released after parsing and before resuming boot
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [RFC PATCH 2/4] psci: Add support for Early detection and init
  2026-04-29 10:35 [RFC PATCH 0/4] arm64: realm: Support for probing RSI earlier Suzuki K Poulose
  2026-04-29 10:35 ` [RFC PATCH 1/4] arm64: acpi: Refactor FADT table verification Suzuki K Poulose
@ 2026-04-29 10:35 ` Suzuki K Poulose
  2026-04-29 10:35 ` [RFC PATCH 3/4] arm64: psci: Move detection and SMCCC probe earlier Suzuki K Poulose
  2026-04-29 10:35 ` [RFC PATCH 4/4] arm64: realm: Move RSI detection earlier Suzuki K Poulose
  3 siblings, 0 replies; 5+ messages in thread
From: Suzuki K Poulose @ 2026-04-29 10:35 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, catalin.marinas, will, ardb, lpieralisi,
	mark.rutland, steven.price, aneesh.kumar, sudeep.holla, robh, maz,
	Suzuki K Poulose

Allow early detection of the PSCI conduit and presence of SMCCC. Primary motive
is to detect if we are a Realm as early as possible to make better decisions

 1. For mapping the memory without BBML2_NOABORT
 2. Making use of the earlycon, to be able to debug problems at early boot.

Add a new psci_early_init_conduit() which can probe the PSCI and SMCCC. This is
optional, and could really fallback to the normal if the architecture cannot
reliably detect the conduit. Later patches will make use of this.

Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 drivers/firmware/psci/psci.c | 49 ++++++++++++++++++++++++++++++++++--
 include/linux/psci.h         |  2 ++
 2 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
index 38ca190d4a22..fa0839513d64 100644
--- a/drivers/firmware/psci/psci.c
+++ b/drivers/firmware/psci/psci.c
@@ -80,6 +80,11 @@ static u32 psci_cpu_suspend_feature;
 static bool psci_system_reset2_supported;
 static bool psci_system_off2_hibernate_supported;
 
+static inline bool psci_probed(void)
+{
+	return psci_ops.get_version != NULL;
+}
+
 static inline bool psci_has_ext_power_state(void)
 {
 	return psci_cpu_suspend_feature &
@@ -270,6 +275,15 @@ static unsigned long psci_migrate_info_up_cpu(void)
 
 static void set_conduit(enum arm_smccc_conduit conduit)
 {
+	/*
+	 * If we have set the conduit already, make sure
+	 * it is the same as we have found.
+	 */
+	if (psci_conduit != SMCCC_CONDUIT_NONE) {
+		WARN_ON(conduit != psci_conduit);
+		return;
+	}
+
 	switch (conduit) {
 	case SMCCC_CONDUIT_HVC:
 		invoke_psci_fn = __invoke_psci_fn_hvc;
@@ -679,7 +693,16 @@ static void __init psci_0_2_set_functions(void)
  */
 static int __init psci_probe(void)
 {
-	u32 ver = psci_0_2_get_version();
+	u32 ver;
+
+	/* Make sure we have a set CONDUIT */
+	if (WARN_ON(psci_conduit == SMCCC_CONDUIT_NONE))
+		return -ENODEV;
+
+	if (WARN_ON(psci_probed()))
+		return 0;
+
+	ver = psci_0_2_get_version();
 
 	pr_info("PSCIv%d.%d detected in firmware.\n",
 			PSCI_VERSION_MAJOR(ver),
@@ -717,10 +740,12 @@ static int __init psci_0_2_init(const struct device_node *np)
 {
 	int err;
 
+	if (psci_probed())
+		return 0;
+
 	err = get_set_conduit_method(np);
 	if (err)
 		return err;
-
 	/*
 	 * Starting with v0.2, the PSCI specification introduced a call
 	 * (PSCI_VERSION) that allows probing the firmware version, so
@@ -739,6 +764,9 @@ static int __init psci_0_1_init(const struct device_node *np)
 	u32 id;
 	int err;
 
+	if (psci_probed())
+		return 0;
+
 	err = get_set_conduit_method(np);
 	if (err)
 		return err;
@@ -816,6 +844,20 @@ int __init psci_dt_init(void)
 	return ret;
 }
 
+int __init psci_early_init_conduit(enum arm_smccc_conduit conduit)
+{
+	switch (conduit) {
+	case SMCCC_CONDUIT_HVC:
+	case SMCCC_CONDUIT_SMC:
+		set_conduit(conduit);
+		break;
+	default:
+		WARN_ON(1);
+		return -EINVAL;
+	}
+	return psci_probe();
+}
+
 #ifdef CONFIG_ACPI
 /*
  * We use PSCI 0.2+ when ACPI is deployed on ARM64 and it's
@@ -823,6 +865,9 @@ int __init psci_dt_init(void)
  */
 int __init psci_acpi_init(void)
 {
+	if (psci_probed())
+		return 0;
+
 	if (!acpi_psci_present()) {
 		pr_info("is not implemented in ACPI.\n");
 		return -EOPNOTSUPP;
diff --git a/include/linux/psci.h b/include/linux/psci.h
index 4ca0060a3fc4..8f98d61a69e4 100644
--- a/include/linux/psci.h
+++ b/include/linux/psci.h
@@ -59,4 +59,6 @@ static inline bool acpi_psci_present(void) { return false; }
 static inline bool acpi_psci_use_hvc(void) {return false; }
 #endif
 
+int __init psci_early_init_conduit(enum arm_smccc_conduit);
+
 #endif /* __LINUX_PSCI_H */
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [RFC PATCH 3/4] arm64: psci: Move detection and SMCCC probe earlier
  2026-04-29 10:35 [RFC PATCH 0/4] arm64: realm: Support for probing RSI earlier Suzuki K Poulose
  2026-04-29 10:35 ` [RFC PATCH 1/4] arm64: acpi: Refactor FADT table verification Suzuki K Poulose
  2026-04-29 10:35 ` [RFC PATCH 2/4] psci: Add support for Early detection and init Suzuki K Poulose
@ 2026-04-29 10:35 ` Suzuki K Poulose
  2026-04-29 10:35 ` [RFC PATCH 4/4] arm64: realm: Move RSI detection earlier Suzuki K Poulose
  3 siblings, 0 replies; 5+ messages in thread
From: Suzuki K Poulose @ 2026-04-29 10:35 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, catalin.marinas, will, ardb, lpieralisi,
	mark.rutland, steven.price, aneesh.kumar, sudeep.holla, robh, maz,
	Suzuki K Poulose

We parse the ACPI/DT for the PSCI conduit after the linear map is created via
paging_init(). This implies that we do not have all the information required to
decide whether block mappings are safe for the linear map.

e.g., With Realms, we cannot use Block mappings without BBML2_NOABORT support.
See [0] for more discussion.

This patch moves the detection of PSCI and SMCCC probing, before paging_init(),
after the efi_init(). We scan the ACPI and the DT (unflattened) for the conduit.
If we both have conduit set, we proceed only if they match. Otherwise, we can't
be sure what gets used eventually by the OS. e.g., if the ACPI table is corrupt,
DT may be used.

We do minimal validations on the ACPI tables (e.g. revision checks, FADT
checks etc.). TODO: Verify the checksum ? (acpi_table_checksum())

[0] https://lore.kernel.org/all/20260330161705.3349825-2-ryan.roberts@arm.com/

Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Steven Price <steven.price@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Lorenzo Pieralisi <lpieralisi@kernel.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 arch/arm64/include/asm/acpi.h |  1 +
 arch/arm64/kernel/acpi.c      | 81 +++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/setup.c     | 68 +++++++++++++++++++++++++++++
 3 files changed, 150 insertions(+)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index c07a58b96329..a5198fa46088 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -188,4 +188,5 @@ static inline void acpi_map_cpus_to_nodes(void) { }
 
 #define ACPI_TABLE_UPGRADE_MAX_PHYS MEMBLOCK_ALLOC_ACCESSIBLE
 
+enum arm_smccc_conduit __init acpi_early_psci_conduit(void);
 #endif /*_ASM_ACPI_H*/
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 30c7b11a8a9d..88d79def4c90 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -180,6 +180,87 @@ static int __init acpi_fadt_sanity_check(void)
 	return ret;
 }
 
+/*
+ * Find the PSCI conduit from ACPI FADT table. We only proceed with the parsing
+ * if acpi *may be* used. i.e, acpi=force or acpi=on or DT is stub.
+ *
+ * FADT table is located as below:
+ *
+ *  RSDP -> XSDT ptr -> array of pointers to different Tables
+ *
+ * Note: Arm64 requires ACPI v5.1+, thus we always use XSDT (not RSDT, for < 2.0)
+ *	 from RSDP.
+ *
+ * Returns : Conduit if system is PSCI compliant.
+ *	     Otherwise returns SMCCC_CONDUIT_NONE.
+ */
+enum arm_smccc_conduit __init acpi_early_psci_conduit(void)
+{
+	enum arm_smccc_conduit c = SMCCC_CONDUIT_NONE;
+	struct acpi_table_rsdp *rsdp;
+	struct acpi_table_xsdt *xsdt;
+	u64 *ptr, *end;
+	u64 xsdt_pa, xsdt_len;
+	bool found = false;
+
+	if (param_acpi_off ||
+	    (!param_acpi_on && !param_acpi_force && !dt_is_stub()))
+		return SMCCC_CONDUIT_NONE;
+
+	if (efi.acpi20 == EFI_INVALID_TABLE_ADDR)
+		return SMCCC_CONDUIT_NONE;
+
+	rsdp = early_memremap(efi.acpi20, sizeof(*rsdp));
+	if (!rsdp)
+		return SMCCC_CONDUIT_NONE;
+
+	if (!ACPI_VALIDATE_RSDP_SIG(rsdp->signature) || rsdp->revision < 2 ||
+	    rsdp->xsdt_physical_address == 0) {
+		early_memunmap(rsdp, sizeof(*rsdp));
+		return SMCCC_CONDUIT_NONE;
+	}
+
+	xsdt_pa = rsdp->xsdt_physical_address;
+
+	/* Now that XSDT is found, unmap the RSDP */
+	early_memunmap(rsdp, sizeof(*rsdp));
+
+	/*
+	 * XSDT is mainly an array of table pointers, with standard header.
+	 * So we map upto a PAGE_SIZE (and more with alignment) and only
+	 * look there, with a WARNING.
+	 */
+	xsdt = early_memremap(xsdt_pa, PAGE_SIZE);
+	if (!xsdt)
+		return SMCCC_CONDUIT_NONE;
+
+	xsdt_len = ((struct acpi_table_header*)xsdt)->length;
+	if (xsdt_len > (ALIGN(xsdt_pa + PAGE_SIZE, PAGE_SIZE) - xsdt_pa)) {
+		pr_warn("XSDT table is larger than a page\n");
+	}
+
+	/* Find FADT table from the XSDT */
+	ptr = &xsdt->table_offset_entry[0];
+	end = (u64*)((void *)xsdt + xsdt_len);
+	for (; ptr < end && !found; ptr++) {
+		struct acpi_table_fadt *fadt = early_memremap(*ptr, sizeof(*fadt));
+
+		if (ACPI_COMPARE_NAMESEG(&fadt->header.signature, ACPI_SIG_FADT) &&
+		    __acpi_fadt_sanity_check(fadt) == 0) {
+			u16 arm_boot_flags = fadt->arm_boot_flags;
+
+			if (arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT) {
+				c = arm_boot_flags & ACPI_FADT_PSCI_USE_HVC ?
+					SMCCC_CONDUIT_HVC : SMCCC_CONDUIT_SMC;
+			}
+			found = true;
+		}
+		early_memunmap(fadt, sizeof(*fadt));
+	}
+	early_memunmap(xsdt, PAGE_SIZE);
+	return c;
+}
+
 /*
  * acpi_boot_table_init() called from setup_arch(), always.
  *	1. find RSDP and get its address, and then find XSDT
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 23c05dc7a8f2..595aff6f17d5 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -278,6 +278,71 @@ u64 cpu_logical_map(unsigned int cpu)
 	return __cpu_logical_map[cpu];
 }
 
+static enum arm_smccc_conduit early_dt_probe_psci_conduit(void)
+{
+	int len;
+	int psci_node;
+	const char *method;
+	enum arm_smccc_conduit conduit = SMCCC_CONDUIT_NONE;
+	unsigned long dt_root;
+
+	/* DT hasn't been unflattened yet, we have to work with the flat blob */
+	dt_root = of_get_flat_dt_root();
+	psci_node = of_get_flat_dt_subnode_by_name(dt_root, "psci");
+	if (psci_node <= 0)
+		return conduit;
+
+	method = of_get_flat_dt_prop(psci_node, "method", &len);
+	if (!method)
+		return conduit;
+
+	if (strncmp(method, "smc", len) == 0) {
+		conduit = SMCCC_CONDUIT_SMC;
+	} else if (strncmp(method, "hvc", len) == 0) {
+		conduit = SMCCC_CONDUIT_HVC;
+	}
+	return conduit;
+}
+
+/*
+ * Detect the PSCI conduit from both ACPI and DT, and probe the PSCI/SMCCC
+ * early if we can.
+ *
+ * Given both ACPI and DT could have valid configurations, we go forward with
+ * the early detection only if there is a valid conduit and both of them match.
+ */
+static void __init early_psci_init(void)
+{
+	enum arm_smccc_conduit dt_conduit = SMCCC_CONDUIT_NONE;
+	enum arm_smccc_conduit acpi_conduit = SMCCC_CONDUIT_NONE;
+	enum arm_smccc_conduit conduit = SMCCC_CONDUIT_NONE;
+
+	dt_conduit = early_dt_probe_psci_conduit();
+
+#ifdef CONFIG_ACPI
+	if (efi_enabled(EFI_BOOT))
+		acpi_conduit = acpi_early_psci_conduit();
+#endif
+	if (dt_conduit == SMCCC_CONDUIT_NONE &&
+	    acpi_conduit == SMCCC_CONDUIT_NONE) {
+		pr_crit("PSCI: Early probe: no conduit found\n");
+		return;
+	}
+
+	if (acpi_conduit == SMCCC_CONDUIT_NONE) {
+		conduit = dt_conduit;
+	} else if (dt_conduit == SMCCC_CONDUIT_NONE) {
+		conduit = acpi_conduit;
+	} else if (dt_conduit == acpi_conduit) {
+		conduit = acpi_conduit;
+	} else {
+		WARN(1, "PSCI: Early probe: Mismatched PSCI conduit, skipping\n");
+		return;
+	}
+
+	psci_early_init_conduit(conduit);
+}
+
 void __init __no_sanitize_address setup_arch(char **cmdline_p)
 {
 	setup_initial_init_mm(_text, _etext, _edata, _end);
@@ -322,6 +387,9 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
 	xen_early_init();
 	efi_init();
 
+	/* Probe the PSCI early after the efi_init() */
+	early_psci_init();
+
 	if (!efi_enabled(EFI_BOOT)) {
 		if ((u64)_text % MIN_KIMG_ALIGN)
 			pr_warn(FW_BUG "Kernel image misaligned at boot, please fix your bootloader!");
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [RFC PATCH 4/4] arm64: realm: Move RSI detection earlier
  2026-04-29 10:35 [RFC PATCH 0/4] arm64: realm: Support for probing RSI earlier Suzuki K Poulose
                   ` (2 preceding siblings ...)
  2026-04-29 10:35 ` [RFC PATCH 3/4] arm64: psci: Move detection and SMCCC probe earlier Suzuki K Poulose
@ 2026-04-29 10:35 ` Suzuki K Poulose
  3 siblings, 0 replies; 5+ messages in thread
From: Suzuki K Poulose @ 2026-04-29 10:35 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, catalin.marinas, will, ardb, lpieralisi,
	mark.rutland, steven.price, aneesh.kumar, sudeep.holla, robh, maz,
	Suzuki K Poulose

As discussed in [0], Realm world detection happens too late for making the
decision for the Linear map granularity for Arm64. If the boot CPU doesn't support
BBML2_NOABORT, it is difficult to break the mapping to PTE level. To solve this
try probing the Realm world earlier,  now that we probe the PSCI/SMCCC earlier.
Like the PSCI probe, if we fall back to the later point if the SMCCC probe
wasn't successful. We should probably add a WARNING/panic the system if the
BBML2_NOABORT is not supported on the boot CPU and linear map was created
with block mappings. This may case avoided by using rodata=full.

[0] https://lore.kernel.org/all/20260330161705.3349825-2-ryan.roberts@arm.com/

Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 arch/arm64/include/asm/rsi.h |  1 +
 arch/arm64/kernel/rsi.c      | 23 ++++++++++++++++++++++-
 arch/arm64/kernel/setup.c    |  3 ++-
 3 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/rsi.h b/arch/arm64/include/asm/rsi.h
index 88b50d660e85..4456bf0a1f23 100644
--- a/arch/arm64/include/asm/rsi.h
+++ b/arch/arm64/include/asm/rsi.h
@@ -14,6 +14,7 @@
 
 DECLARE_STATIC_KEY_FALSE(rsi_present);
 
+void __init arm64_early_rsi_init(void);
 void __init arm64_rsi_init(void);
 
 bool arm64_rsi_is_protected(phys_addr_t base, size_t size);
diff --git a/arch/arm64/kernel/rsi.c b/arch/arm64/kernel/rsi.c
index c64a06f58c0b..2d2befae2c75 100644
--- a/arch/arm64/kernel/rsi.c
+++ b/arch/arm64/kernel/rsi.c
@@ -138,10 +138,14 @@ static int realm_ioremap_hook(phys_addr_t phys, size_t size, pgprot_t *prot)
 	return 0;
 }
 
-void __init arm64_rsi_init(void)
+static bool rsi_probed = 0;
+
+static void __init rsi_probe(void)
 {
 	if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_SMC)
 		return;
+
+	rsi_probed = true;
 	if (!rsi_version_matches())
 		return;
 	if (WARN_ON(rsi_get_realm_config(&config)))
@@ -159,6 +163,23 @@ void __init arm64_rsi_init(void)
 	static_branch_enable(&rsi_present);
 }
 
+void __init arm64_early_rsi_init(void)
+{
+	rsi_probe();
+}
+
+void __init arm64_rsi_init(void)
+{
+	if (rsi_probed)
+		return;
+
+	rsi_probe();
+	/*
+	 * TODO: Warn if we don't have BBML2_NOABORT and page mapping is
+	 * not used.
+	 */
+}
+
 static struct platform_device rsi_dev = {
 	.name = RSI_PDEV_NAME,
 	.id = PLATFORM_DEVID_NONE
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 595aff6f17d5..0664130dd791 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -340,7 +340,8 @@ static void __init early_psci_init(void)
 		return;
 	}
 
-	psci_early_init_conduit(conduit);
+	if (!psci_early_init_conduit(conduit))
+		arm64_early_rsi_init();
 }
 
 void __init __no_sanitize_address setup_arch(char **cmdline_p)
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-04-29 10:36 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-29 10:35 [RFC PATCH 0/4] arm64: realm: Support for probing RSI earlier Suzuki K Poulose
2026-04-29 10:35 ` [RFC PATCH 1/4] arm64: acpi: Refactor FADT table verification Suzuki K Poulose
2026-04-29 10:35 ` [RFC PATCH 2/4] psci: Add support for Early detection and init Suzuki K Poulose
2026-04-29 10:35 ` [RFC PATCH 3/4] arm64: psci: Move detection and SMCCC probe earlier Suzuki K Poulose
2026-04-29 10:35 ` [RFC PATCH 4/4] arm64: realm: Move RSI detection earlier Suzuki K Poulose

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox