firmware: arm_rmm: Move RSI support out of arch/arm64

The RSI SMCCC function IDs describe a firmware ABI and are not arm64
architecture specific definitions. Follow-up changes need to use them from
non-arch code, including drivers/firmware/smccc and the Arm CCA guest
driver.

Move the complete Realm Service Interface (RSI) implementation from
arch/arm64 to drivers/firmware/arm_rmm. The RSI SMCCC definitions and
command helpers are also moved to include/linux so they can be shared by
architecture code and firmware or driver code. This also keeps the
firmware interface outside architecture code, as requested [1].

[1] https://lore.kernel.org/all/agsNO9cc7H-b0H8L@willie-the-truck

Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Acked-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
Aneesh Kumar K.V (Arm) 2026-09-23 19:34:00 +05:30 committed by Catalin Marinas
parent d8263a131b
commit 4cd849026e
18 changed files with 111 additions and 89 deletions

View File

@ -3951,8 +3951,11 @@ S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
F: Documentation/arch/arm64/
F: arch/arm64/
F: drivers/firmware/arm_rmm/
F: drivers/virt/coco/arm-cca-guest/
F: drivers/virt/coco/pkvm-guest/
F: include/linux/arm-rsi-cmds.h
F: include/linux/arm-smccc-rsi.h
F: tools/testing/selftests/arm64/
X: arch/arm64/boot/dts/
X: arch/arm64/configs/defconfig

View File

@ -38,6 +38,7 @@ config ARM64
select ARCH_HAS_MEMBARRIER_SYNC_CORE
select ARCH_HAS_MEM_ENCRYPT
select ARCH_SUPPORTS_MSEAL_SYSTEM_MAPPINGS
select ARCH_SUPPORTS_RMM
select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS
select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
select ARCH_HAS_NONLEAF_PMD_YOUNG if ARM64_HAFT

View File

@ -8,6 +8,7 @@
#ifndef __ASM_IO_H
#define __ASM_IO_H
#include <linux/arm-rsi-cmds.h>
#include <linux/types.h>
#include <linux/pgtable.h>
@ -17,7 +18,6 @@
#include <asm/early_ioremap.h>
#include <asm/alternative.h>
#include <asm/cpufeature.h>
#include <asm/rsi.h>
/*
* Generic IO read/write. These perform native-endian accesses.

View File

@ -2,8 +2,8 @@
#ifndef __ASM_MEM_ENCRYPT_H
#define __ASM_MEM_ENCRYPT_H
#include <linux/arm-rsi-cmds.h>
#include <asm/hypervisor.h>
#include <asm/rsi.h>
struct device;

View File

@ -66,9 +66,9 @@
#ifndef __ASSEMBLER__
#include <linux/arm-rsi-cmds.h>
#include <asm/cpufeature.h>
#include <asm/pgtable-types.h>
#include <asm/rsi.h>
extern bool arm64_use_ng_mappings;
extern unsigned long prot_ns_shared;

View File

@ -1,70 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2024 ARM Ltd.
*/
#ifndef __ASM_RSI_H_
#define __ASM_RSI_H_
#include <linux/errno.h>
#include <linux/jump_label.h>
#include <asm/rsi_cmds.h>
#define RSI_PDEV_NAME "arm-cca-dev"
DECLARE_STATIC_KEY_FALSE(rsi_present);
void __init arm64_rsi_init(void);
bool arm64_rsi_is_protected(phys_addr_t base, size_t size);
static inline bool is_realm_world(void)
{
return static_branch_unlikely(&rsi_present);
}
static inline int rsi_set_memory_range(phys_addr_t start, phys_addr_t end,
enum ripas state, unsigned long flags)
{
unsigned long ret;
phys_addr_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 use this if you rely on the
* contents of a page that may already be in RAM state.
*/
static inline int rsi_set_memory_range_protected(phys_addr_t start,
phys_addr_t end)
{
return rsi_set_memory_range(start, end, RSI_RIPAS_RAM,
RSI_CHANGE_DESTROYED);
}
/*
* Convert the specified range to RAM. Do not convert any pages that may have
* been DESTROYED, without our permission.
*/
static inline int rsi_set_memory_range_protected_safe(phys_addr_t start,
phys_addr_t end)
{
return rsi_set_memory_range(start, end, RSI_RIPAS_RAM,
RSI_NO_CHANGE_DESTROYED);
}
static inline int rsi_set_memory_range_shared(phys_addr_t start,
phys_addr_t end)
{
return rsi_set_memory_range(start, end, RSI_RIPAS_EMPTY,
RSI_CHANGE_DESTROYED);
}
#endif /* __ASM_RSI_H_ */

View File

@ -34,7 +34,7 @@ obj-y := debug-monitors.o entry.o irq.o fpsimd.o \
cpufeature.o alternative.o cacheinfo.o \
smp.o smp_spin_table.o topology.o smccc-call.o \
syscall.o proton-pack.o idle.o patching.o pi/ \
rsi.o jump_label.o
jump_label.o
obj-$(CONFIG_COMPAT) += sys32.o signal32.o \
sys_compat.o

View File

@ -7,6 +7,7 @@
*/
#include <linux/acpi.h>
#include <linux/arm-rsi-cmds.h>
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/stddef.h>
@ -43,7 +44,6 @@
#include <asm/cpu_ops.h>
#include <asm/kasan.h>
#include <asm/numa.h>
#include <asm/rsi.h>
#include <asm/scs.h>
#include <asm/sections.h>
#include <asm/setup.h>

View File

@ -34,6 +34,8 @@
#include <linux/acpi_iort.h>
#include <linux/kmemleak.h>
#include <linux/execmem.h>
#include <linux/arm-rsi-cmds.h>
#include <asm/boot.h>
#include <asm/fixmap.h>
@ -43,7 +45,6 @@
#include <asm/kvm_host.h>
#include <asm/memory.h>
#include <asm/numa.h>
#include <asm/rsi.h>
#include <asm/sections.h>
#include <asm/setup.h>
#include <linux/sizes.h>

View File

@ -310,5 +310,6 @@ source "drivers/firmware/samsung/Kconfig"
source "drivers/firmware/smccc/Kconfig"
source "drivers/firmware/tegra/Kconfig"
source "drivers/firmware/xilinx/Kconfig"
source "drivers/firmware/arm_rmm/Kconfig"
endmenu

View File

@ -39,3 +39,4 @@ obj-y += samsung/
obj-y += smccc/
obj-y += tegra/
obj-y += xilinx/
obj-y += arm_rmm/

View File

@ -0,0 +1,17 @@
config ARCH_SUPPORTS_RMM
bool
config ARM_RMM_RSI
bool "Realm Service Interface (RSI) Support"
depends on ARCH_SUPPORTS_RMM
default y
help
Enable support for running Linux as a Realm guest under a Realm
Management Monitor (RMM), as defined by the Arm Confidential
Compute Architecture.
The RMM exposes the Realm Service Interface (RSI) to Realm guests.
Linux uses RSI to negotiate the interface version, obtain the Realm
configuration, and manage the protected or shared state of guest
memory.

View File

@ -0,0 +1,2 @@
obj-$(CONFIG_ARM_RMM_RSI) = rsi.o

View File

@ -8,11 +8,11 @@
#include <linux/psci.h>
#include <linux/swiotlb.h>
#include <linux/platform_device.h>
#include <linux/arm-rsi-cmds.h>
#include <asm/io.h>
#include <asm/mem_encrypt.h>
#include <asm/pgtable.h>
#include <asm/rsi.h>
static struct realm_config config;

View File

@ -1,6 +1,6 @@
config ARM_CCA_GUEST
tristate "Arm CCA Guest driver"
depends on ARM64
depends on ARM_RMM_RSI
select TSM_REPORTS
help
The driver provides userspace interface to request and

View File

@ -3,7 +3,8 @@
* Copyright (C) 2023 ARM Ltd.
*/
#include <linux/arm-smccc.h>
#include <linux/arm-rsi-cmds.h>
#include <linux/arm-smccc-rsi.h>
#include <linux/cc_platform.h>
#include <linux/kernel.h>
#include <linux/device-id/platform.h>
@ -12,8 +13,6 @@
#include <linux/tsm.h>
#include <linux/types.h>
#include <asm/rsi.h>
/**
* struct arm_cca_token_info - a descriptor for the token buffer.
* @granule: PA of the granule to which the token will be written

View File

@ -3,14 +3,36 @@
* Copyright (C) 2023 ARM Ltd.
*/
#ifndef __ASM_RSI_CMDS_H
#define __ASM_RSI_CMDS_H
#ifndef __LINUX_ARM_RSI_CMDS_H_
#define __LINUX_ARM_RSI_CMDS_H_
#include <linux/arm-smccc.h>
#include <linux/arm-smccc-rsi.h>
#include <linux/jump_label.h>
#include <linux/string.h>
#include <asm/memory.h>
#include <asm/rsi_smc.h>
#define RSI_PDEV_NAME "arm-cca-dev"
#ifdef CONFIG_ARM_RMM_RSI
DECLARE_STATIC_KEY_FALSE(rsi_present);
void __init arm64_rsi_init(void);
bool arm64_rsi_is_protected(phys_addr_t base, size_t size);
static inline bool is_realm_world(void)
{
return static_branch_unlikely(&rsi_present);
}
#else
static inline void arm64_rsi_init(void) { }
static inline bool arm64_rsi_is_protected(phys_addr_t base, size_t size)
{
return false;
}
static inline bool is_realm_world(void) { return false; }
#endif
#define RSI_GRANULE_SHIFT 12
#define RSI_GRANULE_SIZE (_AC(1, UL) << RSI_GRANULE_SHIFT)
@ -88,6 +110,51 @@ static inline long rsi_set_addr_range_state(phys_addr_t start,
return res.a0;
}
static inline int rsi_set_memory_range(phys_addr_t start, phys_addr_t end,
enum ripas state, unsigned long flags)
{
unsigned long ret;
phys_addr_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 use this if you rely on the
* contents of a page that may already be in RAM state.
*/
static inline int rsi_set_memory_range_protected(phys_addr_t start,
phys_addr_t end)
{
return rsi_set_memory_range(start, end, RSI_RIPAS_RAM,
RSI_CHANGE_DESTROYED);
}
/*
* Convert the specified range to RAM. Do not convert any pages that may have
* been DESTROYED, without our permission.
*/
static inline int rsi_set_memory_range_protected_safe(phys_addr_t start,
phys_addr_t end)
{
return rsi_set_memory_range(start, end, RSI_RIPAS_RAM,
RSI_NO_CHANGE_DESTROYED);
}
static inline int rsi_set_memory_range_shared(phys_addr_t start,
phys_addr_t end)
{
return rsi_set_memory_range(start, end, RSI_RIPAS_EMPTY,
RSI_CHANGE_DESTROYED);
}
#define RSI_ATTEST_CHALLENGE_MIN_SIZE 32
#define RSI_ATTEST_CHALLENGE_MAX_SIZE 64
@ -170,4 +237,4 @@ static inline unsigned long rsi_attestation_token_continue(phys_addr_t granule,
return res.a0;
}
#endif /* __ASM_RSI_CMDS_H */
#endif /* __LINUX_ARM_RSI_CMDS_H_ */

View File

@ -3,8 +3,8 @@
* Copyright (C) 2023 ARM Ltd.
*/
#ifndef __ASM_RSI_SMC_H_
#define __ASM_RSI_SMC_H_
#ifndef __LINUX_ARM_SMCCC_RSI_H_
#define __LINUX_ARM_SMCCC_RSI_H_
#include <linux/arm-smccc.h>
@ -190,4 +190,4 @@ struct realm_config {
*/
#define SMC_RSI_HOST_CALL SMC_RSI_FID(0x199)
#endif /* __ASM_RSI_SMC_H_ */
#endif /* __LINUX_ARM_SMCCC_RSI_H_ */