From nobody Tue May 12 16:55:30 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4gFN4y3nXTz6cl5q for ; Tue, 12 May 2026 16:55:30 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R13" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gFN4y1Xsvz3vjS for ; Tue, 12 May 2026 16:55:30 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1778604930; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=EFCna7ir+8t8FFaSfvQnc2RlfY6KY/MvNmQIFoaFkaE=; b=FkoDhXsk7xWz/vZR5gfruPMpYi0anl9rUy6UoIjAPiPgJeAq6IZ5aguHA+zP7w2z3SjUZU 1YzKX0DXldUp/2vGqkn966SBvSYYSvdhC43KJoYyOGebEv35dwaxCgtwqvFpnfJxXbr0c8 NzB/E+SiDs28a9N0jrfrYnMWnJ4sCXBnA3cZzSVmasRZf0Yf7sQtKwlFFJXZUG/H2R2Hz3 aCRllvOHaO8XPJfrUZp+qNNqQdHkc6KgDPCzZzXPMsGwdZtdqMOdLk7RfosBKMhzbrduWd 7Q0sRqHhgBieXpnqHQgYXVwP1ARrmCOpycE1/8AIndlI/zFCwbAzqRH+nWjWfg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1778604930; a=rsa-sha256; cv=none; b=sI4lfkHLPj7qPy3+unCSMLTrczH+TlQgPyh/Vy+BOrswzCgAk+8pE0SD0IRgnV338VKTXa LCwoZsUg/XLKVuRe2MM4cEeURMZyvylf6EgyzokUNP13/plPp/5LLnXY4FnlwkGcm/d1os ajCg8ZuuSPmlmCOBSCf4ope068ryHaxYmVZSbRRpTfy3zARDzmJjtZ3UdMD/Ug5JnMe2Nr zhKUUw5qNf+rryC3MunlXvfUi2AvVPhd+e5RSwp+KfnbAnR4j/vOqbsne7QzfIX2FejmW9 9xurJkHMD+AihjDEgnIyQUUIz4JBvLg4+a4uVGMQEWOxp05NFX46gpVt00kWmA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1778604930; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=EFCna7ir+8t8FFaSfvQnc2RlfY6KY/MvNmQIFoaFkaE=; b=dLQFHAk6ATOijADYESf5/3fVz9SWVP9RhMsdyCbr2BfDMFOL4xbve9q1h8C5r3Yk2NunYS yyib8ZvQIWYRK5wfDET2zZ7eTema0YzGMxRuILB4ZMPsZNVNg4+3pYrHNkOBgXGzSEtO5p g9n0mJjwrzl5GiE4qLJxLbIiTIhy7+U9LF2UFADvX2C3GGqkO+IeBbXJopg+lPElP1/JiW RsF2aagc1Nff6NgftJfnyARvtjnF2eWwylwNLBk0ColnbLv1c2i3RGY/36hMMhuj2qetUD IWhO2OZ00uN+yY1bf+d6tVWfjsjoHvlmVbNOfN+bBXLGDLnSifBRZkcgGwdOSQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gFN4y16z9z1BXv for ; Tue, 12 May 2026 16:55:30 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3e295 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Tue, 12 May 2026 16:55:30 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Sarah Walker From: Andrew Turner Subject: git: 76a2904c352b - main - arm64: Add RSI detection for CCA List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: andrew X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 76a2904c352b497b32fc902523e3e485f7b06ffd Auto-Submitted: auto-generated Date: Tue, 12 May 2026 16:55:30 +0000 Message-Id: <6a035b82.3e295.91ae8c3@gitrepo.freebsd.org> The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=76a2904c352b497b32fc902523e3e485f7b06ffd commit 76a2904c352b497b32fc902523e3e485f7b06ffd Author: Sarah Walker AuthorDate: 2026-05-12 11:27:13 +0000 Commit: Andrew Turner CommitDate: 2026-05-12 16:54:40 +0000 arm64: Add RSI detection for CCA Detect the presence of the Realm Services Interface (RSI). This detection is performed early in bootup; PSCI initialisation has been moved to initarm() to faciliate this. Reviewed by: andrew Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D56598 --- sys/arm64/arm64/machdep.c | 5 ++ sys/arm64/arm64/pmap.c | 2 + sys/arm64/arm64/rsi.c | 185 ++++++++++++++++++++++++++++++++++++++++++++++ sys/arm64/include/pmap.h | 3 + sys/arm64/include/rsi.h | 129 ++++++++++++++++++++++++++++++++ sys/conf/files.arm64 | 1 + sys/dev/psci/psci.c | 11 ++- sys/dev/psci/psci.h | 3 + 8 files changed, 338 insertions(+), 1 deletion(-) diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c index adfb509d4924..d219c737c215 100644 --- a/sys/arm64/arm64/machdep.c +++ b/sys/arm64/arm64/machdep.c @@ -86,6 +86,7 @@ #include #include #include +#include #include #include @@ -103,6 +104,7 @@ #include #endif +#include #include _Static_assert(sizeof(struct pcb) == 1248, "struct pcb is incorrect size"); @@ -889,6 +891,9 @@ initarm(struct arm64_bootparams *abp) valid = bus_probe(); + psci_init(NULL); + arm64_rsi_setup_memory(); + cninit(); set_ttbr0(abp->kern_ttbr0); pmap_s1_invalidate_all_kernel(); diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index 595fba2da411..2d2982fdfae7 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -205,6 +205,8 @@ __exclusive_cache_line static struct pmap_large_md_page pv_dummy_large; #define pv_dummy pv_dummy_large.pv_page __read_mostly static struct pmap_large_md_page *pv_table; +__read_mostly uint64_t prot_ns_shared_pa; + static struct pmap_large_md_page * _pa_to_pmdp(vm_paddr_t pa) { diff --git a/sys/arm64/arm64/rsi.c b/sys/arm64/arm64/rsi.c new file mode 100644 index 000000000000..85c7896e13ce --- /dev/null +++ b/sys/arm64/arm64/rsi.c @@ -0,0 +1,185 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2026 Arm Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "opt_platform.h" + +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +static struct realm_config config; +static bool rsi_present = false; + +#define PHYSMAP_SIZE (2 * (VM_PHYSSEG_MAX - 1)) + +static vm_paddr_t physmap[PHYSMAP_SIZE]; + +static unsigned long +rsi_request_version(unsigned long req, unsigned long *out_lower, + unsigned long *out_higher) +{ + struct arm_smccc_res res; + + arm_smccc_invoke_smc(SMC_RSI_ABI_VERSION, req, &res); + + if (out_lower != NULL) + *out_lower = res.a1; + if (out_higher != NULL) + *out_higher = res.a2; + + return (res.a0); +} + +static inline unsigned long +rsi_get_realm_config(struct realm_config *cfg) +{ + struct arm_smccc_res res; + + arm_smccc_invoke_smc(SMC_RSI_REALM_CONFIG, vtophys(cfg), &res); + return (res.a0); +} + +static bool +rsi_version_matches(void) +{ + unsigned long ver_lower, ver_higher; + unsigned long ret; + + ret = rsi_request_version(RSI_ABI_VERSION, &ver_lower, &ver_higher); + + if (ret == SMCCC_RET_NOT_SUPPORTED) + return (false); + + if (ret != RSI_SUCCESS) { + printf("RME: RMM doesn't support RSI version %lu.%lu. Supported range: %lu.%lu-%lu.%lu\n", + RSI_ABI_VERSION_MAJOR, RSI_ABI_VERSION_MINOR, + RSI_ABI_VERSION_GET_MAJOR(ver_lower), + RSI_ABI_VERSION_GET_MINOR(ver_lower), + RSI_ABI_VERSION_GET_MAJOR(ver_higher), + RSI_ABI_VERSION_GET_MINOR(ver_higher)); + return (false); + } + + printf("RME: Using RSI version %lu.%lu\n", + RSI_ABI_VERSION_GET_MAJOR(ver_lower), + RSI_ABI_VERSION_GET_MINOR(ver_lower)); + + return (true); +} + + +unsigned long +rsi_set_addr_range_state(vm_paddr_t start, vm_paddr_t end, enum ripas state, + unsigned long flags, vm_paddr_t *top) +{ + struct arm_smccc_res res; + + arm_smccc_smc(SMC_RSI_IPA_STATE_SET, start, end, state, flags, 0, 0, 0, + &res); + + if (top) + *top = res.a1; + + return (res.a0); +} + +static int +rsi_set_memory_range(vm_paddr_t start, vm_paddr_t end, enum ripas state, + unsigned long flags) +{ + unsigned long ret; + vm_paddr_t top; + + while (start != end) { + ret = rsi_set_addr_range_state(start, end, state, flags, &top); + if (ret || top < start || top > end) + return (-EINVAL); + start = top; + } + + return (0); +} + +/* + * Convert the specified range to RAM. Do not convert any pages that may have + * been DESTROYED, without our permission. + */ +static int +rsi_set_memory_range_protected_safe(vm_paddr_t start, vm_paddr_t end) +{ + return (rsi_set_memory_range(start, end, RSI_RIPAS_RAM, + RSI_NO_CHANGE_DESTROYED)); +} + +void +arm64_rsi_setup_memory(void) +{ + int physmap_idx; + int i; + + if (!psci_conduit_is_smc()) + return; + if (!rsi_version_matches()) + return; + if (rsi_get_realm_config(&config)) + return; + + prot_ns_shared_pa = 1ul << (config.ipa_bits - 1); + if (bootverbose) + printf("arm64_rsi_setup_memory: rsi_present, ipa_bits=%lu prot_ns_shared_pa=%lx\n", + config.ipa_bits, prot_ns_shared_pa); + rsi_present = true; + + physmap_idx = physmem_all(physmap, nitems(physmap)); + + if (bootverbose) + printf("physmap:\n"); + + for (i = 0; i < physmap_idx; i += 2) { + if (bootverbose) + printf(" %lx %lx\n", physmap[i], physmap[i + 1]); + + if (rsi_set_memory_range_protected_safe(physmap[i], + physmap[i + 1])) + panic("rsi_set_memory_range_protected_safe failed"); + } +} + +bool +in_realm(void) +{ + return (rsi_present); +} diff --git a/sys/arm64/include/pmap.h b/sys/arm64/include/pmap.h index 2ee70fc754da..00b54a874e12 100644 --- a/sys/arm64/include/pmap.h +++ b/sys/arm64/include/pmap.h @@ -43,6 +43,7 @@ #ifndef LOCORE #include +#include #include #include #include @@ -132,6 +133,8 @@ extern vm_offset_t virtual_end; extern pt_entry_t pmap_sh_attr; +extern __read_mostly uint64_t prot_ns_shared_pa; + /* * Macros to test if a mapping is mappable with an L1 Section mapping * or an L2 Large Page mapping. diff --git a/sys/arm64/include/rsi.h b/sys/arm64/include/rsi.h new file mode 100644 index 000000000000..82e54f9c57e3 --- /dev/null +++ b/sys/arm64/include/rsi.h @@ -0,0 +1,129 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2026 Arm Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _MACHINE_RSI_H_ +#define _MACHINE_RSI_H_ + +extern uint64_t prot_ns_shared; + +bool in_realm(void); + +void arm64_rsi_setup_memory(void); + +/* + * The major version number of the RSI implementation. This is increased when + * the binary format or semantics of the SMC calls change. + */ +#define RSI_ABI_VERSION_MAJOR UL(1) + +/* + * The minor version number of the RSI implementation. This is increased when + * a bug is fixed, or a feature is added without breaking binary compatibility. + */ +#define RSI_ABI_VERSION_MINOR UL(0) + +#define RSI_ABI_VERSION ((RSI_ABI_VERSION_MAJOR << 16) | \ + RSI_ABI_VERSION_MINOR) + +#define RSI_ABI_VERSION_GET_MAJOR(_version) ((_version) >> 16) +#define RSI_ABI_VERSION_GET_MINOR(_version) ((_version) & 0xFFFF) + +#define RSI_SUCCESS UL(0) +#define RSI_ERROR_INPUT UL(1) +#define RSI_ERROR_STATE UL(2) +#define RSI_INCOMPLETE UL(3) +#define RSI_ERROR_UNKNOWN UL(4) + +#define SMC_RSI_FID(n) SMCCC_FUNC_ID(SMCCC_FAST_CALL, \ + SMCCC_64BIT_CALL, \ + SMCCC_STD_SECURE_SERVICE_CALLS, \ + n) + +/* + * Returns RSI version. + * + * arg1 == Requested interface revision + * ret0 == Status / error + * ret1 == Lower implemented interface revision + * ret2 == Higher implemented interface revision + */ +#define SMC_RSI_ABI_VERSION SMC_RSI_FID(0x190) + +/* + * Read configuration for the current Realm. + * + * arg1 == struct realm_config addr + * ret0 == Status / error + */ +#define SMC_RSI_REALM_CONFIG SMC_RSI_FID(0x196) + +struct realm_config { + union { + struct { + unsigned long ipa_bits; /* Width of IPA in bits */ + unsigned long hash_algo; /* Hash algorithm */ + }; + uint8_t pad[0x200]; + }; + union { + uint8_t rpv[64]; /* Realm Personalization Value */ + uint8_t pad2[0xe00]; + }; + /* + * The RMM requires the configuration structure to be aligned to a 4k + * boundary, ensure this happens by aligning this structure. + */ +} __aligned(0x1000); + +/* + * Request RIPAS of a target IPA range to be changed to a specified value. + * + * arg1 == Base IPA address of target region + * arg2 == Top of the region + * arg3 == RIPAS value + * arg4 == flags + * ret0 == Status / error + * ret1 == Top of modified IPA range + * ret2 == Whether the Host accepted or rejected the request + */ +#define SMC_RSI_IPA_STATE_SET SMC_RSI_FID(0x197) + +#define RSI_NO_CHANGE_DESTROYED UL(0) +#define RSI_CHANGE_DESTROYED UL(1) + +#define RSI_ACCEPT UL(0) +#define RSI_REJECT UL(1) + +enum ripas { + RSI_RIPAS_EMPTY = 0, + RSI_RIPAS_RAM +}; + +unsigned long rsi_set_addr_range_state(vm_paddr_t start, vm_paddr_t end, + enum ripas state, unsigned long flags, vm_paddr_t *top); + +#endif /* !_MACHINE_RSI_H_ */ diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index 44f292d9048f..8f550a644db6 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -77,6 +77,7 @@ arm64/arm64/ptrauth.c standard \ compile-with "${NORMAL_C:N-mbranch-protection*} -mbranch-protection=bti" arm64/arm64/pmap.c standard arm64/arm64/ptrace_machdep.c standard +arm64/arm64/rsi.c standard arm64/arm64/sdt_machdep.c optional kdtrace_hooks arm64/arm64/sigtramp.S standard arm64/arm64/spec_workaround.c standard diff --git a/sys/dev/psci/psci.c b/sys/dev/psci/psci.c index 2b250401ae83..872fae056a4b 100644 --- a/sys/dev/psci/psci.c +++ b/sys/dev/psci/psci.c @@ -133,7 +133,7 @@ static int psci_def_callfn(register_t, register_t, register_t, register_t, psci_callfn_t psci_callfn = psci_def_callfn; -static void +void psci_init(void *dummy) { psci_callfn_t new_callfn; @@ -146,8 +146,11 @@ psci_init(void *dummy) psci_callfn = new_callfn; psci_present = true; } + +#ifdef __arm__ /* This needs to be before cpu_mp at SI_SUB_CPU, SI_ORDER_THIRD */ SYSINIT(psci_start, SI_SUB_CPU, SI_ORDER_FIRST, psci_init, NULL); +#endif static int psci_def_callfn(register_t a __unused, register_t b __unused, @@ -631,3 +634,9 @@ psci_v0_2_init(device_t dev, int default_version) device_printf(dev, "PSCI version number mismatched with DT\n"); return (1); } + +bool +psci_conduit_is_smc(void) +{ + return (psci_callfn == arm_smccc_smc); +} diff --git a/sys/dev/psci/psci.h b/sys/dev/psci/psci.h index 6704eaf26c71..c250bf45d344 100644 --- a/sys/dev/psci/psci.h +++ b/sys/dev/psci/psci.h @@ -44,6 +44,9 @@ void psci_reset(void); int32_t psci_features(uint32_t); int psci_get_version(void); +void psci_init(void *dummy); +bool psci_conduit_is_smc(void); + /* Handler to let us call into the PSCI/SMCCC firmware */ extern psci_callfn_t psci_callfn; static inline int