* [PATCH v10 0/7] Switch Arm SMCCC firmware services to an SMCCC bus
@ 2026-09-04 9:49 Aneesh Kumar K.V (Arm)
2026-09-04 9:49 ` [PATCH v10 1/7] firmware: smccc: Add an Arm " Aneesh Kumar K.V (Arm)
` (6 more replies)
0 siblings, 7 replies; 15+ messages in thread
From: Aneesh Kumar K.V (Arm) @ 2026-09-04 9:49 UTC (permalink / raw)
To: linux-coco, linux-arm-kernel, linux-kernel
Cc: Aneesh Kumar K.V (Arm), Catalin Marinas, Greg KH, Jeremy Linton,
Jonathan Cameron, Lorenzo Pieralisi, Mark Rutland, Sudeep Holla,
Will Deacon, Steven Price, Suzuki K Poulose, Andre Przywara
As discussed here:
https://lore.kernel.org/all/20250728135216.48084-12-aneesh.kumar@kernel.org
The earlier CCA guest support used an arm-cca-dev platform device as a pure
software anchor for the TSM class device. That platform device did not
correspond to a DT/ACPI described device, MMIO range, interrupt, or other
platform resource; it existed only to make the CCA guest driver bind and to
place the resulting TSM device in the driver model. The same pattern also
exists for smccc_trng. Creating separate platform devices for such
SMCCC-discovered features is misleading, because those features are not
independent platform devices.
This series adds an Arm SMCCC bus for services discovered through the SMCCC
firmware interface. The bus provides SMCCC device and driver registration
helpers, SMCCC function id based matching, uevent modalias generation, and
a sysfs modalias attribute. SMCCC service drivers can use
MODULE_DEVICE_TABLE(arm_smccc, ...) to emit arm_smccc:f<functionid>
aliases, allowing userspace to autoload service drivers when the SMCCC core
registers matching firmware-service devices.
The series then moves SMCCC TRNG and the Arm CCA guest RSI service off the
platform bus. When the SMCCC core discovers the corresponding firmware
service, it registers an arm-smccc device for that service. The hwrng
arm_smccc_trng driver and the Arm CCA guest TSM provider are converted to
SMCCC drivers that bind to those discovered devices.
The old arm-cca-dev platform device has also been used by userspace as a Realm
guest indicator. Removing it without a replacement would leave userspace
depending on an internal driver-binding device. This series therefore adds
/sys/firmware/cca/realm_guest as a stable, architecture-provided ABI for
detecting whether the kernel is running as an Arm CCA Realm guest, and then
removes the dummy arm-cca-dev platform-device registration.
Changes from v9:
https://lore.kernel.org/all/20260805063255.1638614-1-aneesh.kumar@kernel.org
* Rename CONFIG_ARM_RMM to CONFIG_ARM_RMM_RSI to make the Kconfig option RSI-specific.
* Update the modalias to use the SMCCC function ID.
* Don't issue SMC64 SMCCC calls on arm32.
* Drop the IDA usage.
Changes from v8:
https://lore.kernel.org/all/20260707081351.1680209-1-aneesh.kumar@kernel.org
* Rebase onto the arm64 for-next/core branch.
* Move the RSI code from arch/arm64 to drivers/firmware/arm_rmm in patch 3.
* Add a new patch to move the Realm memory-encryption operations to the RSI code.
* Drop the Reviewed-by tag from patch 3.
Changes from v7:
https://lore.kernel.org/all/20260611130429.295516-1-aneesh.kumar@kernel.org
* Rebase to latest kernel
* Add id_table check in arm_smccc_driver_register
* Add smccc device name check in arm_smccc_device_register
* Drop driver_data from struct arm_smccc_device_id
Changes from v6:
https://lore.kernel.org/all/20260527100233.428018-1-aneesh.kumar@kernel.org
* Move SMCCC bus-related code to bus.c.
* Remove CONFIG_ARM64 #ifdefs and switch device creation to use the generic function-ID support framework.
* Move version-specific checks and other conditionals to the device driver probe routines.
* Move RSI definitions to include/linux/arm-smccc-rsi.h.
* Split the file and variable renames into a separate patch.
Changes from v5:
https://lore.kernel.org/all/20260514094030.42495-1-aneesh.kumar@kernel.org
* Replace the arm-smccc platform-device plus auxiliary-child model with a
dedicated Arm SMCCC bus.
* Add SMCCC module alias support so SMCCC service drivers can use
MODULE_DEVICE_TABLE(arm_smccc, ...) and autoload through arm_smccc:<name>
aliases.
* Convert smccc_trng from a platform driver to an SMCCC driver.
* Convert the Arm CCA guest TSM provider from the arm-cca-dev platform device
to an SMCCC driver bound to the discovered RSI service.
* Add /sys/firmware/cca/realm_guest before removing the old arm-cca-dev dummy
platform device.
Changes from v4:
https://lore.kernel.org/all/20260427061615.905018-1-aneesh.kumar@kernel.org
* Add /sys/firmware/cca/realm_guest for detecting realm guest
* Convert smccc_trng to auxiliary device from platform device
Changes from v3:
https://lore.kernel.org/all/20260309100507.2303361-1-aneesh.kumar@kernel.org
* Rebased onto the latest kernel
* Drop pr_fmt() from drivers/firmware/smccc/rmm.c
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Jeremy Linton <jeremy.linton@arm.com>
Cc: Jonathan Cameron <jic23@kernel.org>
Cc: Lorenzo Pieralisi <lpieralisi@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Steven Price <steven.price@arm.com>
Cc: Suzuki K Poulose <Suzuki.Poulose@arm.com>
Cc: Andre Przywara <andre.przywara@arm.com>
Aneesh Kumar K.V (Arm) (7):
firmware: smccc: Add an Arm SMCCC bus
firmware: hwrng: arm_smccc_trng: Register as an SMCCC device
firmware: arm_rmm: Move RSI support out of arch/arm64
arm64: realm: Move Realm memory encryption ops to RSI code
virt: coco: arm-cca-guest: Rename TSM report source file
firmware: smccc: arm-cca-guest: Bind the TSM provider to an SMCCC
device
coco: guest: arm64: Replace dummy CCA device with sysfs ABI
Documentation/ABI/testing/sysfs-firmware-cca | 10 ++
arch/arm/include/asm/archrandom.h | 2 +-
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/archrandom.h | 2 +-
arch/arm64/include/asm/io.h | 2 +-
arch/arm64/include/asm/mem_encrypt.h | 5 +-
arch/arm64/include/asm/pgtable-prot.h | 2 +-
arch/arm64/include/asm/rsi.h | 70 --------
arch/arm64/kernel/Makefile | 2 +-
arch/arm64/kernel/setup.c | 2 +-
arch/arm64/mm/init.c | 3 +-
arch/arm64/mm/pageattr.c | 38 +----
drivers/char/hw_random/arm_smccc_trng.c | 32 ++--
drivers/firmware/Kconfig | 1 +
drivers/firmware/Makefile | 1 +
drivers/firmware/arm_rmm/Kconfig | 17 ++
drivers/firmware/arm_rmm/Makefile | 2 +
.../kernel => drivers/firmware/arm_rmm}/rsi.c | 78 +++++++--
drivers/firmware/smccc/Makefile | 2 +-
drivers/firmware/smccc/bus.c | 151 ++++++++++++++++++
drivers/firmware/smccc/smccc.c | 67 ++++++--
drivers/virt/coco/arm-cca-guest/Kconfig | 3 +-
drivers/virt/coco/arm-cca-guest/Makefile | 2 +
.../arm-cca-guest/{arm-cca-guest.c => main.c} | 55 +++----
.../linux/arm-rsi-cmds.h | 76 ++++++++-
include/linux/arm-smccc-bus.h | 48 ++++++
.../linux/arm-smccc-rsi.h | 6 +-
include/linux/device-id/arm_smccc.h | 15 ++
include/linux/mod_devicetable.h | 1 +
scripts/mod/devicetable-offsets.c | 3 +
scripts/mod/file2alias.c | 8 +
31 files changed, 518 insertions(+), 189 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-firmware-cca
delete mode 100644 arch/arm64/include/asm/rsi.h
create mode 100644 drivers/firmware/arm_rmm/Kconfig
create mode 100644 drivers/firmware/arm_rmm/Makefile
rename {arch/arm64/kernel => drivers/firmware/arm_rmm}/rsi.c (70%)
create mode 100644 drivers/firmware/smccc/bus.c
rename drivers/virt/coco/arm-cca-guest/{arm-cca-guest.c => main.c} (82%)
rename arch/arm64/include/asm/rsi_cmds.h => include/linux/arm-rsi-cmds.h (69%)
create mode 100644 include/linux/arm-smccc-bus.h
rename arch/arm64/include/asm/rsi_smc.h => include/linux/arm-smccc-rsi.h (98%)
create mode 100644 include/linux/device-id/arm_smccc.h
base-commit: 89a312991dc6e638a36adc43ccb91dbc25504c04
--
2.43.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v10 1/7] firmware: smccc: Add an Arm SMCCC bus
2026-09-04 9:49 [PATCH v10 0/7] Switch Arm SMCCC firmware services to an SMCCC bus Aneesh Kumar K.V (Arm)
@ 2026-09-04 9:49 ` Aneesh Kumar K.V (Arm)
2026-09-04 19:39 ` Jason Gunthorpe
2026-09-04 9:49 ` [PATCH v10 2/7] firmware: hwrng: arm_smccc_trng: Register as an SMCCC device Aneesh Kumar K.V (Arm)
` (5 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Aneesh Kumar K.V (Arm) @ 2026-09-04 9:49 UTC (permalink / raw)
To: linux-coco, linux-arm-kernel, linux-kernel
Cc: Aneesh Kumar K.V (Arm), Catalin Marinas, Greg KH, Jeremy Linton,
Jonathan Cameron, Lorenzo Pieralisi, Mark Rutland, Sudeep Holla,
Will Deacon, Steven Price, Suzuki K Poulose, Andre Przywara
SMCCC-discovered firmware services are currently represented by separate
platform devices, such as smccc_trng and arm-cca-dev. Those devices do not
represent independent DT/ACPI-described platform resources; they are
features of the SMCCC firmware interface.
Add an Arm SMCCC bus for services discovered through the SMCCC firmware
interface. The bus provides SMCCC device and driver registration helpers,
name-based matching, modalias generation, and a sysfs modalias attribute so
SMCCC service drivers can bind to discovered firmware services and autoload
as modules.
Follow-up changes can then register SMCCC firmware services as arm-smccc
devices instead of creating independent per-feature platform devices.
Based on arm_ffa code
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
drivers/firmware/smccc/Makefile | 2 +-
drivers/firmware/smccc/bus.c | 151 ++++++++++++++++++++++++++++
include/linux/arm-smccc-bus.h | 48 +++++++++
include/linux/device-id/arm_smccc.h | 15 +++
include/linux/mod_devicetable.h | 1 +
scripts/mod/devicetable-offsets.c | 3 +
scripts/mod/file2alias.c | 8 ++
7 files changed, 227 insertions(+), 1 deletion(-)
create mode 100644 drivers/firmware/smccc/bus.c
create mode 100644 include/linux/arm-smccc-bus.h
create mode 100644 include/linux/device-id/arm_smccc.h
diff --git a/drivers/firmware/smccc/Makefile b/drivers/firmware/smccc/Makefile
index 40d19144a860..68bbff1407b8 100644
--- a/drivers/firmware/smccc/Makefile
+++ b/drivers/firmware/smccc/Makefile
@@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
#
-obj-$(CONFIG_HAVE_ARM_SMCCC_DISCOVERY) += smccc.o kvm_guest.o
+obj-$(CONFIG_HAVE_ARM_SMCCC_DISCOVERY) += bus.o smccc.o kvm_guest.o
obj-$(CONFIG_ARM_SMCCC_SOC_ID) += soc_id.o
diff --git a/drivers/firmware/smccc/bus.c b/drivers/firmware/smccc/bus.c
new file mode 100644
index 000000000000..caba1a03c997
--- /dev/null
+++ b/drivers/firmware/smccc/bus.c
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2026 Arm Limited
+ */
+
+#include <linux/arm-smccc-bus.h>
+#include <linux/slab.h>
+
+static int arm_smccc_bus_match(struct device *dev,
+ const struct device_driver *drv)
+{
+ const struct arm_smccc_device_id *id_table;
+ struct arm_smccc_device *smccc_dev = to_arm_smccc_device(dev);
+
+ id_table = to_arm_smccc_driver(drv)->id_table;
+ if (!id_table)
+ return 0;
+
+ while (id_table->func_id) {
+ if (smccc_dev->func_id == id_table->func_id)
+ return 1;
+ id_table++;
+ }
+
+ return 0;
+}
+
+static int arm_smccc_bus_probe(struct device *dev)
+{
+ struct arm_smccc_driver *smccc_drv = to_arm_smccc_driver(dev->driver);
+
+ return smccc_drv->probe(to_arm_smccc_device(dev));
+}
+
+static void arm_smccc_bus_remove(struct device *dev)
+{
+ struct arm_smccc_driver *smcc_drv = to_arm_smccc_driver(dev->driver);
+
+ if (smcc_drv->remove)
+ smcc_drv->remove(to_arm_smccc_device(dev));
+}
+
+static int arm_smccc_bus_uevent(const struct device *dev,
+ struct kobj_uevent_env *env)
+{
+ const struct arm_smccc_device *smccc_dev = to_arm_smccc_device(dev);
+
+ return add_uevent_var(env, "MODALIAS=" ARM_SMCCC_MODULE_PREFIX "f%08X",
+ smccc_dev->func_id);
+}
+
+static ssize_t modalias_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct arm_smccc_device *smccc_dev = to_arm_smccc_device(dev);
+
+ return sysfs_emit(buf, ARM_SMCCC_MODULE_PREFIX "f%08X\n",
+ smccc_dev->func_id);
+}
+static DEVICE_ATTR_RO(modalias);
+
+static struct attribute *arm_smccc_device_attrs[] = {
+ &dev_attr_modalias.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(arm_smccc_device);
+
+const struct bus_type arm_smccc_bus_type = {
+ .name = "arm_smccc",
+ .match = arm_smccc_bus_match,
+ .probe = arm_smccc_bus_probe,
+ .remove = arm_smccc_bus_remove,
+ .uevent = arm_smccc_bus_uevent,
+ .dev_groups = arm_smccc_device_groups,
+};
+EXPORT_SYMBOL_GPL(arm_smccc_bus_type);
+
+int arm_smccc_driver_register(struct arm_smccc_driver *driver,
+ struct module *owner, const char *mod_name)
+{
+ if (!driver->probe || !driver->id_table)
+ return -EINVAL;
+
+ driver->driver.bus = &arm_smccc_bus_type;
+ driver->driver.name = driver->name;
+ driver->driver.owner = owner;
+ driver->driver.mod_name = mod_name;
+
+ return driver_register(&driver->driver);
+}
+EXPORT_SYMBOL_GPL(arm_smccc_driver_register);
+
+void arm_smccc_driver_unregister(struct arm_smccc_driver *driver)
+{
+ driver_unregister(&driver->driver);
+}
+EXPORT_SYMBOL_GPL(arm_smccc_driver_unregister);
+
+static void arm_smccc_release_device(struct device *dev)
+{
+ struct arm_smccc_device *smccc_dev = to_arm_smccc_device(dev);
+
+ kfree(smccc_dev);
+}
+
+struct arm_smccc_device *arm_smccc_device_register(const char *name, u32 func_id)
+{
+ int ret;
+ struct arm_smccc_device *smccc_dev;
+
+ if (!name)
+ return ERR_PTR(-EINVAL);
+
+ smccc_dev = kzalloc_obj(*smccc_dev);
+ if (!smccc_dev)
+ return ERR_PTR(-ENOMEM);
+
+ smccc_dev->func_id = func_id;
+ smccc_dev->dev.bus = &arm_smccc_bus_type;
+ smccc_dev->dev.release = arm_smccc_release_device;
+
+ ret = dev_set_name(&smccc_dev->dev, "%s", name);
+ if (ret) {
+ kfree(smccc_dev);
+ return ERR_PTR(ret);
+ }
+
+ ret = device_register(&smccc_dev->dev);
+ if (ret) {
+ put_device(&smccc_dev->dev);
+ return ERR_PTR(ret);
+ }
+
+ return smccc_dev;
+}
+EXPORT_SYMBOL_GPL(arm_smccc_device_register);
+
+void arm_smccc_device_unregister(struct arm_smccc_device *smccc_dev)
+{
+ if (!smccc_dev)
+ return;
+
+ device_unregister(&smccc_dev->dev);
+}
+EXPORT_SYMBOL_GPL(arm_smccc_device_unregister);
+
+static int __init arm_smccc_bus_init(void)
+{
+ return bus_register(&arm_smccc_bus_type);
+}
+subsys_initcall(arm_smccc_bus_init);
diff --git a/include/linux/arm-smccc-bus.h b/include/linux/arm-smccc-bus.h
new file mode 100644
index 000000000000..cde268fc2930
--- /dev/null
+++ b/include/linux/arm-smccc-bus.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2026 Arm Limited
+ */
+#ifndef __LINUX_ARM_SMCCC_BUS_H
+#define __LINUX_ARM_SMCCC_BUS_H
+
+#include <linux/device.h>
+#include <linux/device-id/arm_smccc.h>
+#include <linux/module.h>
+
+struct arm_smccc_device {
+ struct device dev;
+ u32 func_id;
+};
+
+#define to_arm_smccc_device(d) container_of(d, struct arm_smccc_device, dev)
+
+struct arm_smccc_driver {
+ struct device_driver driver;
+
+ const char *name;
+ int (*probe)(struct arm_smccc_device *sdev);
+ void (*remove)(struct arm_smccc_device *sdev);
+ const struct arm_smccc_device_id *id_table;
+};
+
+#define to_arm_smccc_driver(d) \
+ container_of_const(d, struct arm_smccc_driver, driver)
+
+int arm_smccc_driver_register(struct arm_smccc_driver *driver,
+ struct module *owner, const char *mod_name);
+void arm_smccc_driver_unregister(struct arm_smccc_driver *driver);
+struct arm_smccc_device *arm_smccc_device_register(const char *name, u32 func_id);
+void arm_smccc_device_unregister(struct arm_smccc_device *smcc_dev);
+
+#define arm_smccc_register(driver) \
+ arm_smccc_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
+#define arm_smccc_unregister(driver) \
+ arm_smccc_driver_unregister(driver)
+
+#define module_arm_smccc_driver(__arm_smccc_driver) \
+ module_driver(__arm_smccc_driver, arm_smccc_register, \
+ arm_smccc_unregister)
+
+extern const struct bus_type arm_smccc_bus_type;
+
+#endif /* __LINUX_ARM_SMCCC_BUS_H */
diff --git a/include/linux/device-id/arm_smccc.h b/include/linux/device-id/arm_smccc.h
new file mode 100644
index 000000000000..537bbf7a7fd5
--- /dev/null
+++ b/include/linux/device-id/arm_smccc.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_DEVICE_ID_ARM_SMCCC_H
+#define __LINUX_DEVICE_ID_ARM_SMCCC_H
+
+#define ARM_SMCCC_MODULE_PREFIX "arm_smccc:"
+
+/**
+ * struct arm_smccc_device_id - Arm SMCCC bus device identifier
+ * @func_id: SMCCC function identifier
+ */
+struct arm_smccc_device_id {
+ __u32 func_id;
+};
+
+#endif /* __LINUX_DEVICE_ID_ARM_SMCCC_H */
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index a397213bedac..318c4b5c3451 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -16,6 +16,7 @@
#include "device-id/amba.h"
#include "device-id/ap.h"
#include "device-id/apr.h"
+#include "device-id/arm_smccc.h"
#include "device-id/auxiliary.h"
#include "device-id/bcma.h"
#include "device-id/ccw.h"
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
index b4178c42d08f..1492e9fdc7cb 100644
--- a/scripts/mod/devicetable-offsets.c
+++ b/scripts/mod/devicetable-offsets.c
@@ -254,6 +254,9 @@ int main(void)
DEVID(auxiliary_device_id);
DEVID_FIELD(auxiliary_device_id, name);
+ DEVID(arm_smccc_device_id);
+ DEVID_FIELD(arm_smccc_device_id, func_id);
+
DEVID(ssam_device_id);
DEVID_FIELD(ssam_device_id, match_flags);
DEVID_FIELD(ssam_device_id, domain);
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 8d36c74dec2d..980d7da456bb 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -1349,6 +1349,13 @@ static void do_auxiliary_entry(struct module *mod, void *symval)
module_alias_printf(mod, false, AUXILIARY_MODULE_PREFIX "%s", *name);
}
+static void do_arm_smccc_entry(struct module *mod, void *symval)
+{
+ DEF_FIELD(symval, arm_smccc_device_id, func_id);
+
+ module_alias_printf(mod, false, ARM_SMCCC_MODULE_PREFIX "f%08X", func_id);
+}
+
/*
* Looks like: ssam:dNcNtNiNfN
*
@@ -1519,6 +1526,7 @@ static const struct devtable devtable[] = {
{"mhi", SIZE_mhi_device_id, do_mhi_entry},
{"mhi_ep", SIZE_mhi_device_id, do_mhi_ep_entry},
{"auxiliary", SIZE_auxiliary_device_id, do_auxiliary_entry},
+ {"arm_smccc", SIZE_arm_smccc_device_id, do_arm_smccc_entry},
{"ssam", SIZE_ssam_device_id, do_ssam_entry},
{"dfl", SIZE_dfl_device_id, do_dfl_entry},
{"ishtp", SIZE_ishtp_device_id, do_ishtp_entry},
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v10 2/7] firmware: hwrng: arm_smccc_trng: Register as an SMCCC device
2026-09-04 9:49 [PATCH v10 0/7] Switch Arm SMCCC firmware services to an SMCCC bus Aneesh Kumar K.V (Arm)
2026-09-04 9:49 ` [PATCH v10 1/7] firmware: smccc: Add an Arm " Aneesh Kumar K.V (Arm)
@ 2026-09-04 9:49 ` Aneesh Kumar K.V (Arm)
2026-09-04 19:39 ` Jason Gunthorpe
2026-09-04 9:49 ` [PATCH v10 3/7] firmware: arm_rmm: Move RSI support out of arch/arm64 Aneesh Kumar K.V (Arm)
` (4 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Aneesh Kumar K.V (Arm) @ 2026-09-04 9:49 UTC (permalink / raw)
To: linux-coco, linux-arm-kernel, linux-kernel
Cc: Aneesh Kumar K.V (Arm), Catalin Marinas, Greg KH, Jeremy Linton,
Jonathan Cameron, Lorenzo Pieralisi, Mark Rutland, Sudeep Holla,
Will Deacon, Steven Price, Suzuki K Poulose, Andre Przywara,
Jason Gunthorpe
The SMCCC TRNG interface is a firmware-provided SMCCC service rather than a
standalone platform device. Now that the SMCCC core has an SMCCC bus,
create an arm-smccc-trng device for the discovered TRNG service and convert
the hwrng driver to an SMCCC driver.
The SMCCC id table preserves module autoloading for systems where the TRNG
driver is built as a module.
The sysfs device path changes from the old smccc_trng platform-device path
to an arm-smccc device path. No known userspace dependency on the old path
was found; a Debian Code Search lookup for the existing platform-device
name/path did not find any users.
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
arch/arm/include/asm/archrandom.h | 2 +-
arch/arm64/include/asm/archrandom.h | 2 +-
drivers/char/hw_random/arm_smccc_trng.c | 32 ++++++++-----
drivers/firmware/smccc/smccc.c | 61 +++++++++++++++++++++----
4 files changed, 75 insertions(+), 22 deletions(-)
diff --git a/arch/arm/include/asm/archrandom.h b/arch/arm/include/asm/archrandom.h
index cc4714eb1a75..ee39a03ddf8a 100644
--- a/arch/arm/include/asm/archrandom.h
+++ b/arch/arm/include/asm/archrandom.h
@@ -2,7 +2,7 @@
#ifndef _ASM_ARCHRANDOM_H
#define _ASM_ARCHRANDOM_H
-static inline bool __init smccc_probe_trng(void)
+static inline bool smccc_probe_trng(void)
{
return false;
}
diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h
index 8babfbe31f95..7605dd81bd1e 100644
--- a/arch/arm64/include/asm/archrandom.h
+++ b/arch/arm64/include/asm/archrandom.h
@@ -12,7 +12,7 @@
extern bool smccc_trng_available;
-static inline bool __init smccc_probe_trng(void)
+static inline bool smccc_probe_trng(void)
{
struct arm_smccc_res res;
diff --git a/drivers/char/hw_random/arm_smccc_trng.c b/drivers/char/hw_random/arm_smccc_trng.c
index dcb8e7f37f25..01c1a30cbab8 100644
--- a/drivers/char/hw_random/arm_smccc_trng.c
+++ b/drivers/char/hw_random/arm_smccc_trng.c
@@ -16,8 +16,10 @@
#include <linux/device.h>
#include <linux/hw_random.h>
#include <linux/module.h>
-#include <linux/platform_device.h>
#include <linux/arm-smccc.h>
+#include <linux/arm-smccc-bus.h>
+
+#include <asm/archrandom.h>
#ifdef CONFIG_ARM64
#define ARM_SMCCC_TRNG_RND ARM_SMCCC_TRNG_RND64
@@ -94,29 +96,37 @@ static int smccc_trng_read(struct hwrng *rng, void *data, size_t max, bool wait)
return copied;
}
-static int smccc_trng_probe(struct platform_device *pdev)
+static int smccc_trng_probe(struct arm_smccc_device *sdev)
{
struct hwrng *trng;
- trng = devm_kzalloc(&pdev->dev, sizeof(*trng), GFP_KERNEL);
+ /* validate the minimum version requirement */
+ if (!smccc_probe_trng())
+ return -ENODEV;
+
+ trng = devm_kzalloc(&sdev->dev, sizeof(*trng), GFP_KERNEL);
if (!trng)
return -ENOMEM;
trng->name = "smccc_trng";
trng->read = smccc_trng_read;
- return devm_hwrng_register(&pdev->dev, trng);
+ return devm_hwrng_register(&sdev->dev, trng);
}
-static struct platform_driver smccc_trng_driver = {
- .driver = {
- .name = "smccc_trng",
- },
- .probe = smccc_trng_probe,
+static const struct arm_smccc_device_id smccc_trng_id_table[] = {
+ { .func_id = ARM_SMCCC_TRNG_VERSION },
+ {}
+};
+MODULE_DEVICE_TABLE(arm_smccc, smccc_trng_id_table);
+
+static struct arm_smccc_driver smccc_trng_driver = {
+ .name = KBUILD_MODNAME,
+ .probe = smccc_trng_probe,
+ .id_table = smccc_trng_id_table,
};
-module_platform_driver(smccc_trng_driver);
+module_arm_smccc_driver(smccc_trng_driver);
-MODULE_ALIAS("platform:smccc_trng");
MODULE_AUTHOR("Andre Przywara");
MODULE_DESCRIPTION("Arm SMCCC TRNG firmware interface support");
MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/smccc/smccc.c b/drivers/firmware/smccc/smccc.c
index bdee057db2fd..5ea3478be9d3 100644
--- a/drivers/firmware/smccc/smccc.c
+++ b/drivers/firmware/smccc/smccc.c
@@ -9,7 +9,8 @@
#include <linux/init.h>
#include <linux/arm-smccc.h>
#include <linux/kernel.h>
-#include <linux/platform_device.h>
+#include <linux/arm-smccc-bus.h>
+
#include <asm/archrandom.h>
static u32 smccc_version = ARM_SMCCC_VERSION_1_0;
@@ -81,16 +82,58 @@ bool arm_smccc_hypervisor_has_uuid(const uuid_t *hyp_uuid)
}
EXPORT_SYMBOL_GPL(arm_smccc_hypervisor_has_uuid);
+struct smccc_device_info {
+ u32 func_id;
+ bool requires_smc;
+ const char *device_name;
+};
+
+static const struct smccc_device_info smccc_devices[] __initconst = {
+ {
+ .func_id = ARM_SMCCC_TRNG_VERSION,
+ .requires_smc = false,
+ .device_name = "arm-smccc-trng",
+ },
+};
+
+static bool __init smccc_probe_smccc_device(const struct smccc_device_info *smccc_dev)
+{
+ int ret;
+ struct arm_smccc_res res = {};
+
+ if (smccc_conduit == SMCCC_CONDUIT_NONE)
+ return false;
+
+ if (smccc_dev->requires_smc && smccc_conduit != SMCCC_CONDUIT_SMC)
+ return false;
+
+ if (IS_ENABLED(CONFIG_ARM) && ARM_SMCCC_IS_64(smccc_dev->func_id))
+ return false;
+
+ arm_smccc_1_1_invoke(smccc_dev->func_id, &res);
+ ret = res.a0;
+
+ if (ret == SMCCC_RET_NOT_SUPPORTED)
+ return false;
+
+ return true;
+}
+
static int __init smccc_devices_init(void)
{
- struct platform_device *pdev;
-
- if (smccc_trng_available) {
- pdev = platform_device_register_simple("smccc_trng", -1,
- NULL, 0);
- if (IS_ERR(pdev))
- pr_err("smccc_trng: could not register device: %ld\n",
- PTR_ERR(pdev));
+ struct arm_smccc_device *sdev;
+ const struct smccc_device_info *smccc_dev;
+
+ for (int i = 0; i < ARRAY_SIZE(smccc_devices); i++) {
+ smccc_dev = &smccc_devices[i];
+
+ if (!smccc_probe_smccc_device(smccc_dev))
+ continue;
+
+ sdev = arm_smccc_device_register(smccc_dev->device_name, smccc_dev->func_id);
+ if (IS_ERR(sdev))
+ pr_err("%s: could not register device: %ld\n",
+ smccc_dev->device_name, PTR_ERR(sdev));
}
return 0;
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v10 3/7] firmware: arm_rmm: Move RSI support out of arch/arm64
2026-09-04 9:49 [PATCH v10 0/7] Switch Arm SMCCC firmware services to an SMCCC bus Aneesh Kumar K.V (Arm)
2026-09-04 9:49 ` [PATCH v10 1/7] firmware: smccc: Add an Arm " Aneesh Kumar K.V (Arm)
2026-09-04 9:49 ` [PATCH v10 2/7] firmware: hwrng: arm_smccc_trng: Register as an SMCCC device Aneesh Kumar K.V (Arm)
@ 2026-09-04 9:49 ` Aneesh Kumar K.V (Arm)
2026-09-04 19:39 ` Jason Gunthorpe
2026-09-04 9:49 ` [PATCH v10 4/7] arm64: realm: Move Realm memory encryption ops to RSI code Aneesh Kumar K.V (Arm)
` (3 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Aneesh Kumar K.V (Arm) @ 2026-09-04 9:49 UTC (permalink / raw)
To: linux-coco, linux-arm-kernel, linux-kernel
Cc: Aneesh Kumar K.V (Arm), Catalin Marinas, Greg KH, Jeremy Linton,
Jonathan Cameron, Lorenzo Pieralisi, Mark Rutland, Sudeep Holla,
Will Deacon, Steven Price, Suzuki K Poulose, Andre Przywara,
Jason Gunthorpe, Suzuki K Poulose
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: Jason Gunthorpe <jgg@nvidia.com>
Acked-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/io.h | 2 +-
arch/arm64/include/asm/mem_encrypt.h | 2 +-
arch/arm64/include/asm/pgtable-prot.h | 2 +-
arch/arm64/include/asm/rsi.h | 70 -----------------
arch/arm64/kernel/Makefile | 2 +-
arch/arm64/kernel/setup.c | 2 +-
arch/arm64/mm/init.c | 3 +-
drivers/firmware/Kconfig | 1 +
drivers/firmware/Makefile | 1 +
drivers/firmware/arm_rmm/Kconfig | 17 ++++
drivers/firmware/arm_rmm/Makefile | 2 +
.../kernel => drivers/firmware/arm_rmm}/rsi.c | 2 +-
drivers/virt/coco/arm-cca-guest/Kconfig | 2 +-
.../virt/coco/arm-cca-guest/arm-cca-guest.c | 5 +-
.../linux/arm-rsi-cmds.h | 77 +++++++++++++++++--
.../linux/arm-smccc-rsi.h | 6 +-
17 files changed, 108 insertions(+), 89 deletions(-)
delete mode 100644 arch/arm64/include/asm/rsi.h
create mode 100644 drivers/firmware/arm_rmm/Kconfig
create mode 100644 drivers/firmware/arm_rmm/Makefile
rename {arch/arm64/kernel => drivers/firmware/arm_rmm}/rsi.c (99%)
rename arch/arm64/include/asm/rsi_cmds.h => include/linux/arm-rsi-cmds.h (69%)
rename arch/arm64/include/asm/rsi_smc.h => include/linux/arm-smccc-rsi.h (98%)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b5a51b0ef944..ff9565d3ffa5 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -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
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 49a7002661a9..1620537f0332 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -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.
diff --git a/arch/arm64/include/asm/mem_encrypt.h b/arch/arm64/include/asm/mem_encrypt.h
index 636f45b4d8af..f03b9d7b83b4 100644
--- a/arch/arm64/include/asm/mem_encrypt.h
+++ b/arch/arm64/include/asm/mem_encrypt.h
@@ -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;
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index 09d7c00cf405..58e71e592175 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -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;
diff --git a/arch/arm64/include/asm/rsi.h b/arch/arm64/include/asm/rsi.h
deleted file mode 100644
index 88b50d660e85..000000000000
--- a/arch/arm64/include/asm/rsi.h
+++ /dev/null
@@ -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_ */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index d2690c3ec528..21fc3a3d25c9 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -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
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 29c6100f0c50..a707deba6ae7 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -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>
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index fbf215ecc7d0..2a8de20d2b44 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -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>
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index b7cc11e4fbfa..62660bf520a8 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -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
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index be46f1e1dc77..196a650ccf02 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -39,3 +39,4 @@ obj-y += samsung/
obj-y += smccc/
obj-y += tegra/
obj-y += xilinx/
+obj-y += arm_rmm/
diff --git a/drivers/firmware/arm_rmm/Kconfig b/drivers/firmware/arm_rmm/Kconfig
new file mode 100644
index 000000000000..e981e12fdbe6
--- /dev/null
+++ b/drivers/firmware/arm_rmm/Kconfig
@@ -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.
diff --git a/drivers/firmware/arm_rmm/Makefile b/drivers/firmware/arm_rmm/Makefile
new file mode 100644
index 000000000000..3708b37a9aaf
--- /dev/null
+++ b/drivers/firmware/arm_rmm/Makefile
@@ -0,0 +1,2 @@
+
+obj-$(CONFIG_ARM_RMM_RSI) = rsi.o
diff --git a/arch/arm64/kernel/rsi.c b/drivers/firmware/arm_rmm/rsi.c
similarity index 99%
rename from arch/arm64/kernel/rsi.c
rename to drivers/firmware/arm_rmm/rsi.c
index 25ca75ce1a4d..8e716f1c1e31 100644
--- a/arch/arm64/kernel/rsi.c
+++ b/drivers/firmware/arm_rmm/rsi.c
@@ -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;
diff --git a/drivers/virt/coco/arm-cca-guest/Kconfig b/drivers/virt/coco/arm-cca-guest/Kconfig
index 3f0f013f03f1..2582ebb36922 100644
--- a/drivers/virt/coco/arm-cca-guest/Kconfig
+++ b/drivers/virt/coco/arm-cca-guest/Kconfig
@@ -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
diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c b/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
index 0eeddd1ff05b..b741643d1364 100644
--- a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
+++ b/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
@@ -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
diff --git a/arch/arm64/include/asm/rsi_cmds.h b/include/linux/arm-rsi-cmds.h
similarity index 69%
rename from arch/arm64/include/asm/rsi_cmds.h
rename to include/linux/arm-rsi-cmds.h
index c1fab41f671e..9e8a8c189ca1 100644
--- a/arch/arm64/include/asm/rsi_cmds.h
+++ b/include/linux/arm-rsi-cmds.h
@@ -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_ */
diff --git a/arch/arm64/include/asm/rsi_smc.h b/include/linux/arm-smccc-rsi.h
similarity index 98%
rename from arch/arm64/include/asm/rsi_smc.h
rename to include/linux/arm-smccc-rsi.h
index e19253f96c94..fddb77986f70 100644
--- a/arch/arm64/include/asm/rsi_smc.h
+++ b/include/linux/arm-smccc-rsi.h
@@ -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_ */
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v10 4/7] arm64: realm: Move Realm memory encryption ops to RSI code
2026-09-04 9:49 [PATCH v10 0/7] Switch Arm SMCCC firmware services to an SMCCC bus Aneesh Kumar K.V (Arm)
` (2 preceding siblings ...)
2026-09-04 9:49 ` [PATCH v10 3/7] firmware: arm_rmm: Move RSI support out of arch/arm64 Aneesh Kumar K.V (Arm)
@ 2026-09-04 9:49 ` Aneesh Kumar K.V (Arm)
2026-09-04 19:39 ` Jason Gunthorpe
2026-09-04 9:49 ` [PATCH v10 5/7] virt: coco: arm-cca-guest: Rename TSM report source file Aneesh Kumar K.V (Arm)
` (2 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Aneesh Kumar K.V (Arm) @ 2026-09-04 9:49 UTC (permalink / raw)
To: linux-coco, linux-arm-kernel, linux-kernel
Cc: Aneesh Kumar K.V (Arm), Catalin Marinas, Greg KH, Jeremy Linton,
Jonathan Cameron, Lorenzo Pieralisi, Mark Rutland, Sudeep Holla,
Will Deacon, Steven Price, Suzuki K Poulose, Andre Przywara
Realm memory encryption callbacks are CCA-specific. Keep the Realm callback
registration with the RSI initialization code instead of pageattr.c, which
only needs to provide the low-level page-attribute transition helper.
Export __set_memory_enc_dec() within arm64 so the RSI code can wrap it with
the Realm-specific encrypt/decrypt callbacks and warning policy.
No functional changes in this patch.
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
arch/arm64/include/asm/mem_encrypt.h | 3 +--
arch/arm64/mm/pageattr.c | 38 +---------------------------
drivers/firmware/arm_rmm/rsi.c | 34 +++++++++++++++++++++++++
3 files changed, 36 insertions(+), 39 deletions(-)
diff --git a/arch/arm64/include/asm/mem_encrypt.h b/arch/arm64/include/asm/mem_encrypt.h
index f03b9d7b83b4..ef8b8463e52b 100644
--- a/arch/arm64/include/asm/mem_encrypt.h
+++ b/arch/arm64/include/asm/mem_encrypt.h
@@ -16,8 +16,7 @@ int arm64_mem_crypt_ops_register(const struct arm64_mem_crypt_ops *ops);
int set_memory_encrypted(unsigned long addr, int numpages);
int set_memory_decrypted(unsigned long addr, int numpages);
-
-int realm_register_memory_enc_ops(void);
+int __set_memory_enc_dec(unsigned long addr, int numpages, bool encrypt);
static inline bool force_dma_unencrypted(struct device *dev)
{
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index bbe98ac9ad8c..14b2a3801f40 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -275,9 +275,7 @@ int set_direct_map_default_noflush(struct page *page)
PAGE_SIZE, set_mask, clear_mask);
}
-static int __set_memory_enc_dec(unsigned long addr,
- int numpages,
- bool encrypt)
+int __set_memory_enc_dec(unsigned long addr, int numpages, bool encrypt)
{
unsigned long set_prot = 0, clear_prot = 0;
phys_addr_t start, end;
@@ -321,40 +319,6 @@ static int __set_memory_enc_dec(unsigned long addr,
__pgprot(PTE_PRESENT_INVALID));
}
-static int realm_set_memory_encrypted(unsigned long addr, int numpages)
-{
- int ret = __set_memory_enc_dec(addr, numpages, true);
-
- /*
- * If the request to change state fails, then the only sensible cause
- * of action for the caller is to leak the memory
- */
- WARN(ret, "Failed to encrypt memory, %d pages will be leaked",
- numpages);
-
- return ret;
-}
-
-static int realm_set_memory_decrypted(unsigned long addr, int numpages)
-{
- int ret = __set_memory_enc_dec(addr, numpages, false);
-
- WARN(ret, "Failed to decrypt memory, %d pages will be leaked",
- numpages);
-
- return ret;
-}
-
-static const struct arm64_mem_crypt_ops realm_crypt_ops = {
- .encrypt = realm_set_memory_encrypted,
- .decrypt = realm_set_memory_decrypted,
-};
-
-int realm_register_memory_enc_ops(void)
-{
- return arm64_mem_crypt_ops_register(&realm_crypt_ops);
-}
-
int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid)
{
unsigned long addr = (unsigned long)page_address(page);
diff --git a/drivers/firmware/arm_rmm/rsi.c b/drivers/firmware/arm_rmm/rsi.c
index 8e716f1c1e31..ada139d0e344 100644
--- a/drivers/firmware/arm_rmm/rsi.c
+++ b/drivers/firmware/arm_rmm/rsi.c
@@ -127,6 +127,40 @@ static int realm_ioremap_hook(phys_addr_t phys, size_t size, pgprot_t *prot)
return 0;
}
+static int realm_set_memory_encrypted(unsigned long addr, int numpages)
+{
+ int ret = __set_memory_enc_dec(addr, numpages, true);
+
+ /*
+ * If the request to change state fails, then the only sensible cause
+ * of action for the caller is to leak the memory
+ */
+ WARN(ret, "Failed to encrypt memory, %d pages will be leaked",
+ numpages);
+
+ return ret;
+}
+
+static int realm_set_memory_decrypted(unsigned long addr, int numpages)
+{
+ int ret = __set_memory_enc_dec(addr, numpages, false);
+
+ WARN(ret, "Failed to decrypt memory, %d pages will be leaked",
+ numpages);
+
+ return ret;
+}
+
+static const struct arm64_mem_crypt_ops realm_crypt_ops = {
+ .encrypt = realm_set_memory_encrypted,
+ .decrypt = realm_set_memory_decrypted,
+};
+
+static int realm_register_memory_enc_ops(void)
+{
+ return arm64_mem_crypt_ops_register(&realm_crypt_ops);
+}
+
void __init arm64_rsi_init(void)
{
if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_SMC)
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v10 5/7] virt: coco: arm-cca-guest: Rename TSM report source file
2026-09-04 9:49 [PATCH v10 0/7] Switch Arm SMCCC firmware services to an SMCCC bus Aneesh Kumar K.V (Arm)
` (3 preceding siblings ...)
2026-09-04 9:49 ` [PATCH v10 4/7] arm64: realm: Move Realm memory encryption ops to RSI code Aneesh Kumar K.V (Arm)
@ 2026-09-04 9:49 ` Aneesh Kumar K.V (Arm)
2026-09-04 19:39 ` Jason Gunthorpe
2026-09-04 9:49 ` [PATCH v10 6/7] firmware: smccc: arm-cca-guest: Bind the TSM provider to an SMCCC device Aneesh Kumar K.V (Arm)
2026-09-04 9:50 ` [PATCH v10 7/7] coco: guest: arm64: Replace dummy CCA device with sysfs ABI Aneesh Kumar K.V (Arm)
6 siblings, 1 reply; 15+ messages in thread
From: Aneesh Kumar K.V (Arm) @ 2026-09-04 9:49 UTC (permalink / raw)
To: linux-coco, linux-arm-kernel, linux-kernel
Cc: Aneesh Kumar K.V (Arm), Catalin Marinas, Greg KH, Jeremy Linton,
Jonathan Cameron, Lorenzo Pieralisi, Mark Rutland, Sudeep Holla,
Will Deacon, Steven Price, Suzuki K Poulose, Andre Przywara
The Arm CCA guest driver currently only implements TSM report support, but
follow-up changes will add more TSM-related functionality to the same
module.
Rename arm-cca-guest.c to main.c and build it as an object of the
arm-cca-guest module. This leaves room for the module to grow additional
source files.
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
drivers/virt/coco/arm-cca-guest/Makefile | 2 ++
drivers/virt/coco/arm-cca-guest/{arm-cca-guest.c => main.c} | 6 +++---
2 files changed, 5 insertions(+), 3 deletions(-)
rename drivers/virt/coco/arm-cca-guest/{arm-cca-guest.c => main.c} (97%)
diff --git a/drivers/virt/coco/arm-cca-guest/Makefile b/drivers/virt/coco/arm-cca-guest/Makefile
index 69eeba08e98a..7564f4fcc4a4 100644
--- a/drivers/virt/coco/arm-cca-guest/Makefile
+++ b/drivers/virt/coco/arm-cca-guest/Makefile
@@ -1,2 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_ARM_CCA_GUEST) += arm-cca-guest.o
+
+arm-cca-guest-y += main.o
diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c b/drivers/virt/coco/arm-cca-guest/main.c
similarity index 97%
rename from drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
rename to drivers/virt/coco/arm-cca-guest/main.c
index b741643d1364..80659f0885e9 100644
--- a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
+++ b/drivers/virt/coco/arm-cca-guest/main.c
@@ -156,7 +156,7 @@ static int arm_cca_report_new(struct tsm_report *report, void *data)
return ret;
}
-static const struct tsm_report_ops arm_cca_tsm_ops = {
+static const struct tsm_report_ops arm_cca_tsm_report_ops = {
.name = KBUILD_MODNAME,
.report_new = arm_cca_report_new,
};
@@ -177,7 +177,7 @@ static int __init arm_cca_guest_init(void)
if (!is_realm_world())
return -ENODEV;
- ret = tsm_report_register(&arm_cca_tsm_ops, NULL);
+ ret = tsm_report_register(&arm_cca_tsm_report_ops, NULL);
if (ret < 0)
pr_err("Error %d registering with TSM\n", ret);
@@ -191,7 +191,7 @@ module_init(arm_cca_guest_init);
*/
static void __exit arm_cca_guest_exit(void)
{
- tsm_report_unregister(&arm_cca_tsm_ops);
+ tsm_report_unregister(&arm_cca_tsm_report_ops);
}
module_exit(arm_cca_guest_exit);
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v10 6/7] firmware: smccc: arm-cca-guest: Bind the TSM provider to an SMCCC device
2026-09-04 9:49 [PATCH v10 0/7] Switch Arm SMCCC firmware services to an SMCCC bus Aneesh Kumar K.V (Arm)
` (4 preceding siblings ...)
2026-09-04 9:49 ` [PATCH v10 5/7] virt: coco: arm-cca-guest: Rename TSM report source file Aneesh Kumar K.V (Arm)
@ 2026-09-04 9:49 ` Aneesh Kumar K.V (Arm)
2026-09-04 19:39 ` Jason Gunthorpe
2026-09-04 9:50 ` [PATCH v10 7/7] coco: guest: arm64: Replace dummy CCA device with sysfs ABI Aneesh Kumar K.V (Arm)
6 siblings, 1 reply; 15+ messages in thread
From: Aneesh Kumar K.V (Arm) @ 2026-09-04 9:49 UTC (permalink / raw)
To: linux-coco, linux-arm-kernel, linux-kernel
Cc: Aneesh Kumar K.V (Arm), Catalin Marinas, Greg KH, Jeremy Linton,
Jonathan Cameron, Lorenzo Pieralisi, Mark Rutland, Sudeep Holla,
Will Deacon, Steven Price, Suzuki K Poulose, Andre Przywara
The Arm CCA guest TSM provider currently binds through the arm-cca-dev
platform device. Like arm-smccc-trng, this device is not an independent
platform resource; it is a software representation of the RSI firmware
service discovered through SMCCC.
Move RSI discovery into the SMCCC firmware driver. When the SMCCC conduit
is SMC and if RSI ABI version call is supported, create an arm-rsi-dev
SMCCC device. Convert the Arm CCA guest TSM provider to an SMCCC driver so
it binds to that discovered RSI service and keeps module autoloading
through the SMCCC device id table.
Keep the old arm-cca-dev platform-device registration for now. Userspace
has used that device as a Realm-guest indicator, so removing it is left to
a follow-up patch that adds a replacement sysfs ABI.
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
drivers/firmware/arm_rmm/rsi.c | 2 +-
drivers/firmware/smccc/smccc.c | 6 ++++
drivers/virt/coco/arm-cca-guest/Kconfig | 1 +
drivers/virt/coco/arm-cca-guest/main.c | 44 +++++++++++--------------
include/linux/arm-rsi-cmds.h | 1 -
5 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/drivers/firmware/arm_rmm/rsi.c b/drivers/firmware/arm_rmm/rsi.c
index ada139d0e344..2dd69febedbd 100644
--- a/drivers/firmware/arm_rmm/rsi.c
+++ b/drivers/firmware/arm_rmm/rsi.c
@@ -183,7 +183,7 @@ void __init arm64_rsi_init(void)
}
static struct platform_device rsi_dev = {
- .name = RSI_PDEV_NAME,
+ .name = "arm-cca-dev",
.id = PLATFORM_DEVID_NONE
};
diff --git a/drivers/firmware/smccc/smccc.c b/drivers/firmware/smccc/smccc.c
index 5ea3478be9d3..854276a3cd57 100644
--- a/drivers/firmware/smccc/smccc.c
+++ b/drivers/firmware/smccc/smccc.c
@@ -10,6 +10,7 @@
#include <linux/arm-smccc.h>
#include <linux/kernel.h>
#include <linux/arm-smccc-bus.h>
+#include <linux/arm-smccc-rsi.h>
#include <asm/archrandom.h>
@@ -94,6 +95,11 @@ static const struct smccc_device_info smccc_devices[] __initconst = {
.requires_smc = false,
.device_name = "arm-smccc-trng",
},
+ {
+ .func_id = SMC_RSI_ABI_VERSION,
+ .requires_smc = true,
+ .device_name = "arm-rsi",
+ },
};
static bool __init smccc_probe_smccc_device(const struct smccc_device_info *smccc_dev)
diff --git a/drivers/virt/coco/arm-cca-guest/Kconfig b/drivers/virt/coco/arm-cca-guest/Kconfig
index 2582ebb36922..0d4ce72e2d86 100644
--- a/drivers/virt/coco/arm-cca-guest/Kconfig
+++ b/drivers/virt/coco/arm-cca-guest/Kconfig
@@ -1,6 +1,7 @@
config ARM_CCA_GUEST
tristate "Arm CCA Guest driver"
depends on ARM_RMM_RSI
+ depends on HAVE_ARM_SMCCC_DISCOVERY
select TSM_REPORTS
help
The driver provides userspace interface to request and
diff --git a/drivers/virt/coco/arm-cca-guest/main.c b/drivers/virt/coco/arm-cca-guest/main.c
index 80659f0885e9..7b1fa008a8f4 100644
--- a/drivers/virt/coco/arm-cca-guest/main.c
+++ b/drivers/virt/coco/arm-cca-guest/main.c
@@ -4,6 +4,7 @@
*/
#include <linux/arm-rsi-cmds.h>
+#include <linux/arm-smccc-bus.h>
#include <linux/arm-smccc-rsi.h>
#include <linux/cc_platform.h>
#include <linux/kernel.h>
@@ -161,16 +162,7 @@ static const struct tsm_report_ops arm_cca_tsm_report_ops = {
.report_new = arm_cca_report_new,
};
-/**
- * arm_cca_guest_init - Register with the Trusted Security Module (TSM)
- * interface.
- *
- * Return:
- * * %0 - Registered successfully with the TSM interface.
- * * %-ENODEV - The execution context is not an Arm Realm.
- * * %-EBUSY - Already registered.
- */
-static int __init arm_cca_guest_init(void)
+static int cca_tsm_probe(struct arm_smccc_device *sdev)
{
int ret;
@@ -178,30 +170,32 @@ static int __init arm_cca_guest_init(void)
return -ENODEV;
ret = tsm_report_register(&arm_cca_tsm_report_ops, NULL);
- if (ret < 0)
- pr_err("Error %d registering with TSM\n", ret);
+ if (ret < 0) {
+ dev_err_probe(&sdev->dev, ret, "Error registering with TSM\n");
+ return ret;
+ }
- return ret;
+ return 0;
}
-module_init(arm_cca_guest_init);
-/**
- * arm_cca_guest_exit - unregister with the Trusted Security Module (TSM)
- * interface.
- */
-static void __exit arm_cca_guest_exit(void)
+static void cca_tsm_remove(struct arm_smccc_device *sdev)
{
tsm_report_unregister(&arm_cca_tsm_report_ops);
}
-module_exit(arm_cca_guest_exit);
-/* modalias, so userspace can autoload this module when RSI is available */
-static const struct platform_device_id arm_cca_match[] __maybe_unused = {
- { .name = RSI_PDEV_NAME },
- { }
+static const struct arm_smccc_device_id cca_tsm_id_table[] = {
+ { .func_id = SMC_RSI_ABI_VERSION },
+ {}
};
+MODULE_DEVICE_TABLE(arm_smccc, cca_tsm_id_table);
-MODULE_DEVICE_TABLE(platform, arm_cca_match);
+static struct arm_smccc_driver cca_tsm_driver = {
+ .name = KBUILD_MODNAME,
+ .probe = cca_tsm_probe,
+ .remove = cca_tsm_remove,
+ .id_table = cca_tsm_id_table,
+};
+module_arm_smccc_driver(cca_tsm_driver);
MODULE_AUTHOR("Sami Mujawar <sami.mujawar@arm.com>");
MODULE_DESCRIPTION("Arm CCA Guest TSM Driver");
MODULE_LICENSE("GPL");
diff --git a/include/linux/arm-rsi-cmds.h b/include/linux/arm-rsi-cmds.h
index 9e8a8c189ca1..3f7a6a833993 100644
--- a/include/linux/arm-rsi-cmds.h
+++ b/include/linux/arm-rsi-cmds.h
@@ -11,7 +11,6 @@
#include <linux/string.h>
#include <asm/memory.h>
-#define RSI_PDEV_NAME "arm-cca-dev"
#ifdef CONFIG_ARM_RMM_RSI
DECLARE_STATIC_KEY_FALSE(rsi_present);
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v10 7/7] coco: guest: arm64: Replace dummy CCA device with sysfs ABI
2026-09-04 9:49 [PATCH v10 0/7] Switch Arm SMCCC firmware services to an SMCCC bus Aneesh Kumar K.V (Arm)
` (5 preceding siblings ...)
2026-09-04 9:49 ` [PATCH v10 6/7] firmware: smccc: arm-cca-guest: Bind the TSM provider to an SMCCC device Aneesh Kumar K.V (Arm)
@ 2026-09-04 9:50 ` Aneesh Kumar K.V (Arm)
2026-09-04 19:39 ` Jason Gunthorpe
6 siblings, 1 reply; 15+ messages in thread
From: Aneesh Kumar K.V (Arm) @ 2026-09-04 9:50 UTC (permalink / raw)
To: linux-coco, linux-arm-kernel, linux-kernel
Cc: Aneesh Kumar K.V (Arm), Catalin Marinas, Greg KH, Jeremy Linton,
Jonathan Cameron, Lorenzo Pieralisi, Mark Rutland, Sudeep Holla,
Will Deacon, Steven Price, Suzuki K Poulose, Andre Przywara
The SMCCC firmware driver now creates the arm-smccc platform device and
instantiates the CCA RSI auxiliary devices once the RSI ABI is discovered.
The arm64-specific arm-cca-dev platform device stub is therefore no longer
needed.
However, userspace has used the arm-cca-dev platform device to detect Arm
CCA Realm guests [1]. Removing it without a replacement would break that
detection and would also leave userspace depending on kernel device-model
details.
Add /sys/firmware/cca/realm_guest as a stable, architecture-provided ABI
for detecting whether the kernel is running as an Arm CCA Realm guest. The
file returns 1 in Realm world and 0 otherwise, similar to the existing s390
/sys/firmware/uv/prot_virt_guest interface for protected virtualization
guests.
Remove the dummy arm-cca-dev registration now that userspace has a
dedicated CCA Realm guest indicator, and document the new ABI in
Documentation/ABI/testing/sysfs-firmware-cca.
[1] https://lore.kernel.org/all/4a7d84b2-2ec4-4773-a2d5-7b63d5c683cf@arm.com
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
Documentation/ABI/testing/sysfs-firmware-cca | 10 +++++
drivers/firmware/arm_rmm/rsi.c | 42 +++++++++++++++-----
2 files changed, 42 insertions(+), 10 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-firmware-cca
diff --git a/Documentation/ABI/testing/sysfs-firmware-cca b/Documentation/ABI/testing/sysfs-firmware-cca
new file mode 100644
index 000000000000..bf177d636b92
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-firmware-cca
@@ -0,0 +1,10 @@
+What: /sys/firmware/cca/realm_guest
+Date: May 2026
+Contact: Linux ARM Kernel Mailing list <linux-arm-kernel@lists.infradead.org>
+Description: Read-only. Indicates whether the kernel is running as an
+ Arm Confidential Compute Architecture (CCA) Realm guest.
+
+ The value is one of:
+
+ 0: the kernel is not running as a Realm guest
+ 1: the kernel is running as a Realm guest
diff --git a/drivers/firmware/arm_rmm/rsi.c b/drivers/firmware/arm_rmm/rsi.c
index 2dd69febedbd..52f40256bd78 100644
--- a/drivers/firmware/arm_rmm/rsi.c
+++ b/drivers/firmware/arm_rmm/rsi.c
@@ -9,12 +9,15 @@
#include <linux/swiotlb.h>
#include <linux/platform_device.h>
#include <linux/arm-rsi-cmds.h>
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
#include <asm/io.h>
#include <asm/mem_encrypt.h>
#include <asm/pgtable.h>
static struct realm_config config;
+static struct kobject *cca_kobj;
unsigned long prot_ns_shared;
EXPORT_SYMBOL(prot_ns_shared);
@@ -182,17 +185,36 @@ void __init arm64_rsi_init(void)
static_branch_enable(&rsi_present);
}
-static struct platform_device rsi_dev = {
- .name = "arm-cca-dev",
- .id = PLATFORM_DEVID_NONE
+static ssize_t cca_is_realm_guest(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sysfs_emit(buf, "%d\n", is_realm_world());
+}
+
+static struct kobj_attribute cca_realm_guest =
+ __ATTR(realm_guest, 0444, cca_is_realm_guest, NULL);
+
+static const struct attribute *cca_realm_attrs[] = {
+ &cca_realm_guest.attr,
+ NULL,
};
-static int __init arm64_create_dummy_rsi_dev(void)
+static int __init realm_sysfs_init(void)
{
- if (is_realm_world() &&
- platform_device_register(&rsi_dev))
- pr_err("failed to register rsi platform device\n");
- return 0;
-}
+ int ret;
-arch_initcall(arm64_create_dummy_rsi_dev)
+ if (!static_branch_unlikely(&rsi_present))
+ return 0;
+
+ cca_kobj = kobject_create_and_add("cca", firmware_kobj);
+ if (!cca_kobj)
+ return -ENOMEM;
+
+ ret = sysfs_create_files(cca_kobj, cca_realm_attrs);
+ if (!ret)
+ return 0;
+
+ kobject_put(cca_kobj);
+ return ret;
+}
+device_initcall(realm_sysfs_init);
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v10 1/7] firmware: smccc: Add an Arm SMCCC bus
2026-09-04 9:49 ` [PATCH v10 1/7] firmware: smccc: Add an Arm " Aneesh Kumar K.V (Arm)
@ 2026-09-04 19:39 ` Jason Gunthorpe
0 siblings, 0 replies; 15+ messages in thread
From: Jason Gunthorpe @ 2026-09-04 19:39 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: linux-coco, linux-arm-kernel, linux-kernel, Catalin Marinas,
Greg KH, Jeremy Linton, Jonathan Cameron, Lorenzo Pieralisi,
Mark Rutland, Sudeep Holla, Will Deacon, Steven Price,
Suzuki K Poulose, Andre Przywara
> [ ... 243 lines skipped ... ]
> +++ b/include/linux/device-id/arm_smccc.h
> @@ -0,0 +1,15 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __LINUX_DEVICE_ID_ARM_SMCCC_H
> +#define __LINUX_DEVICE_ID_ARM_SMCCC_H
> +
> +#define ARM_SMCCC_MODULE_PREFIX "arm_smccc:"
> +
> +/**
> + * struct arm_smccc_device_id - Arm SMCCC bus device identifier
> + * @func_id: SMCCC function identifier
> + */
> +struct arm_smccc_device_id {
> + __u32 func_id;
[Severity: Low]
Does this new header need to include <linux/types.h> so that it is
self-contained?
If a C file includes <linux/device-id/arm_smccc.h> directly without a prior
inclusion of <linux/types.h>, the __u32 type used in arm_smccc_device_id will
be undeclared, which will cause a compilation failure.
It is minor, but if you have to respin it is nice for clangd users if
headers are self contained.
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
--
Jason
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v10 2/7] firmware: hwrng: arm_smccc_trng: Register as an SMCCC device
2026-09-04 9:49 ` [PATCH v10 2/7] firmware: hwrng: arm_smccc_trng: Register as an SMCCC device Aneesh Kumar K.V (Arm)
@ 2026-09-04 19:39 ` Jason Gunthorpe
0 siblings, 0 replies; 15+ messages in thread
From: Jason Gunthorpe @ 2026-09-04 19:39 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: linux-coco, linux-arm-kernel, linux-kernel, Catalin Marinas,
Greg KH, Jeremy Linton, Jonathan Cameron, Lorenzo Pieralisi,
Mark Rutland, Sudeep Holla, Will Deacon, Steven Price,
Suzuki K Poulose, Andre Przywara, Jason Gunthorpe
> The SMCCC TRNG interface is a firmware-provided SMCCC service rather than a
> standalone platform device. Now that the SMCCC core has an SMCCC bus,
> create an arm-smccc-trng device for the discovered TRNG service and convert
> the hwrng driver to an SMCCC driver.
>
> The SMCCC id table preserves module autoloading for systems where the TRNG
> driver is built as a module.
>
> The sysfs device path changes from the old smccc_trng platform-device path
> to an arm-smccc device path. No known userspace dependency on the old path
> was found; a Debian Code Search lookup for the existing platform-device
> name/path did not find any users.
>
> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
> Tested-by: Andre Przywara <andre.przywara@arm.com>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
>
> diff --git a/arch/arm/include/asm/archrandom.h b/arch/arm/include/asm/archrandom.h
> index cc4714eb1a7556..ee39a03ddf8abe 100644
> --- a/arch/arm/include/asm/archrandom.h
> +++ b/arch/arm/include/asm/archrandom.h
> @@ -2,7 +2,7 @@
> #ifndef _ASM_ARCHRANDOM_H
> #define _ASM_ARCHRANDOM_H
>
> -static inline bool __init smccc_probe_trng(void)
> +static inline bool smccc_probe_trng(void)
> {
> return false;
> }
It is preexisting so
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
But I still think this is weird, and now looks weirder with a nice
proper device driver.
Inline this ARM64 version check code in the driver:
> diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h
> index 8babfbe31f9541..7605dd81bd1e1f 100644
> --- a/arch/arm64/include/asm/archrandom.h
> +++ b/arch/arm64/include/asm/archrandom.h
> @@ -12,7 +12,7 @@
>
> extern bool smccc_trng_available;
>
> -static inline bool __init smccc_probe_trng(void)
> +static inline bool smccc_probe_trng(void)
> {
> struct arm_smccc_res res;
And adjust the kconfig to not permit the driver on ARM32
builds. Achieves the same outcome without involving arch code.
Though I have no idea why it doesn't work on ARM32.
> [ ... 108 lines skipped ... ]
> + if (IS_ENABLED(CONFIG_ARM) && ARM_SMCCC_IS_64(smccc_dev->func_id))
> + return false;
This test passes for TRNG after all.
--
Jason
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v10 6/7] firmware: smccc: arm-cca-guest: Bind the TSM provider to an SMCCC device
2026-09-04 9:49 ` [PATCH v10 6/7] firmware: smccc: arm-cca-guest: Bind the TSM provider to an SMCCC device Aneesh Kumar K.V (Arm)
@ 2026-09-04 19:39 ` Jason Gunthorpe
0 siblings, 0 replies; 15+ messages in thread
From: Jason Gunthorpe @ 2026-09-04 19:39 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: linux-coco, linux-arm-kernel, linux-kernel, Catalin Marinas,
Greg KH, Jeremy Linton, Jonathan Cameron, Lorenzo Pieralisi,
Mark Rutland, Sudeep Holla, Will Deacon, Steven Price,
Suzuki K Poulose, Andre Przywara
> [ ... 42 lines skipped ... ]
> @@ -94,6 +95,11 @@ static const struct smccc_device_info smccc_devices[] __initconst = {
> .requires_smc = false,
> .device_name = "arm-smccc-trng",
> },
> + {
> + .func_id = SMC_RSI_ABI_VERSION,
> + .requires_smc = true,
> + .device_name = "arm-rsi",
> + },
> };
>
> static bool __init smccc_probe_smccc_device(const struct smccc_device_info *smccc_dev)
[Severity: High]
When this new entry is probed by smccc_probe_smccc_device(), does
arm_smccc_1_1_invoke() pass uninitialized registers to the firmware?
Looking at smccc_probe_smccc_device() during system initialization:
drivers/firmware/smccc/smccc.c:smccc_probe_smccc_device() {
...
arm_smccc_1_1_invoke(smccc_dev->func_id, &res);
...
}
Since arm_smccc_1_1_invoke() is a variadic macro, providing only the func_id
leaves x1/r1 uninitialized in the SMC inline assembly.
For SMC_RSI_ABI_VERSION, the RMM uses x1 as the requested interface revision
to determine supported revisions.
Could this pass a garbage requested interface revision to the RMM,
potentially causing probe failures or returning an unsupported boundary?
Could this also leak kernel register state to EL2?
Sashiko still has this to say, I think it should pass 0 as the x1
'requested version' instead of unpredictable garbage.
The rest looks OK
--
Jason
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v10 3/7] firmware: arm_rmm: Move RSI support out of arch/arm64
2026-09-04 9:49 ` [PATCH v10 3/7] firmware: arm_rmm: Move RSI support out of arch/arm64 Aneesh Kumar K.V (Arm)
@ 2026-09-04 19:39 ` Jason Gunthorpe
0 siblings, 0 replies; 15+ messages in thread
From: Jason Gunthorpe @ 2026-09-04 19:39 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: linux-coco, linux-arm-kernel, linux-kernel, Catalin Marinas,
Greg KH, Jeremy Linton, Jonathan Cameron, Lorenzo Pieralisi,
Mark Rutland, Sudeep Holla, Will Deacon, Steven Price,
Suzuki K Poulose, Andre Przywara, Jason Gunthorpe
> 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: Jason Gunthorpe <jgg@nvidia.com>
> Acked-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index b5a51b0ef9440a..ff9565d3ffa596 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -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
> diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
> index 49a7002661a928..1620537f0332d9 100644
> --- a/arch/arm64/include/asm/io.h
> +++ b/arch/arm64/include/asm/io.h
> @@ -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.
> diff --git a/arch/arm64/include/asm/mem_encrypt.h b/arch/arm64/include/asm/mem_encrypt.h
> index 636f45b4d8afc7..f03b9d7b83b438 100644
> --- a/arch/arm64/include/asm/mem_encrypt.h
> +++ b/arch/arm64/include/asm/mem_encrypt.h
> @@ -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;
>
> diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
> index 09d7c00cf40541..58e71e592175ef 100644
> --- a/arch/arm64/include/asm/pgtable-prot.h
> +++ b/arch/arm64/include/asm/pgtable-prot.h
> @@ -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;
> diff --git a/arch/arm64/include/asm/rsi.h b/arch/arm64/include/asm/rsi.h
> deleted file mode 100644
> index 88b50d660e85a0..00000000000000
> --- a/arch/arm64/include/asm/rsi.h
> +++ /dev/null
> @@ -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_ */
> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> index d2690c3ec52885..21fc3a3d25c91f 100644
> --- a/arch/arm64/kernel/Makefile
> +++ b/arch/arm64/kernel/Makefile
> @@ -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
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index 29c6100f0c50b2..a707deba6ae701 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -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>
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index fbf215ecc7d061..2a8de20d2b447b 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -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>
> diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
> index b7cc11e4fbfa65..62660bf520a8da 100644
> --- a/drivers/firmware/Kconfig
> +++ b/drivers/firmware/Kconfig
> @@ -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
> diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
> index be46f1e1dc77fa..196a650ccf025b 100644
> --- a/drivers/firmware/Makefile
> +++ b/drivers/firmware/Makefile
> @@ -39,3 +39,4 @@ obj-y += samsung/
> obj-y += smccc/
> obj-y += tegra/
> obj-y += xilinx/
> +obj-y += arm_rmm/
> diff --git a/drivers/firmware/arm_rmm/Kconfig b/drivers/firmware/arm_rmm/Kconfig
> new file mode 100644
> index 00000000000000..e981e12fdbe6a8
> --- /dev/null
> +++ b/drivers/firmware/arm_rmm/Kconfig
> @@ -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.
> diff --git a/drivers/firmware/arm_rmm/Makefile b/drivers/firmware/arm_rmm/Makefile
> new file mode 100644
> index 00000000000000..3708b37a9aafc6
> --- /dev/null
> +++ b/drivers/firmware/arm_rmm/Makefile
> @@ -0,0 +1,2 @@
> +
> +obj-$(CONFIG_ARM_RMM_RSI) = rsi.o
> diff --git a/arch/arm64/kernel/rsi.c b/drivers/firmware/arm_rmm/rsi.c
> similarity index 99%
> rename from arch/arm64/kernel/rsi.c
> rename to drivers/firmware/arm_rmm/rsi.c
> index 25ca75ce1a4dff..8e716f1c1e319d 100644
> --- a/arch/arm64/kernel/rsi.c
> +++ b/drivers/firmware/arm_rmm/rsi.c
> @@ -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;
>
> diff --git a/drivers/virt/coco/arm-cca-guest/Kconfig b/drivers/virt/coco/arm-cca-guest/Kconfig
> index 3f0f013f03f159..2582ebb36922ea 100644
> --- a/drivers/virt/coco/arm-cca-guest/Kconfig
> +++ b/drivers/virt/coco/arm-cca-guest/Kconfig
> @@ -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
> diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c b/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
> index 0eeddd1ff05b51..b741643d136476 100644
> --- a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
> +++ b/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
> @@ -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>
> -
[Severity: High]
This is a pre-existing issue, but is there a missing bounds check on the
firmware-supplied length in this file?
In arm_cca_attestation_continue(), the len value returned from the firmware
(via rsi_attestation_token_continue) is added to info->offset without verifying
that len <= size:
ret = rsi_attestation_token_continue(info->granule, info->offset, size,
&len);
info->offset += len;
If the firmware returns a maliciously large len, info->offset will exceed
RSI_GRANULE_SIZE (which is 4096 bytes).
Later in arm_cca_report_new(), this unvalidated info.offset is used as the
memcpy() length:
if (WARN_ON(token_size + info.offset > max_size))
break;
memcpy(&token[token_size], buf, info.offset);
The WARN_ON check only ensures it doesn't exceed max_size, but buf was
allocated as exactly RSI_GRANULE_SIZE bytes. Can this lead to memcpy()
reading past the end of buf and copying adjacent kernel memory into the
attestation token returned to userspace?
Pre-existing, but seems worth fixing for robustness and avoiding
future LLM bot noise.
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
--
Jason
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v10 5/7] virt: coco: arm-cca-guest: Rename TSM report source file
2026-09-04 9:49 ` [PATCH v10 5/7] virt: coco: arm-cca-guest: Rename TSM report source file Aneesh Kumar K.V (Arm)
@ 2026-09-04 19:39 ` Jason Gunthorpe
0 siblings, 0 replies; 15+ messages in thread
From: Jason Gunthorpe @ 2026-09-04 19:39 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: linux-coco, linux-arm-kernel, linux-kernel, Catalin Marinas,
Greg KH, Jeremy Linton, Jonathan Cameron, Lorenzo Pieralisi,
Mark Rutland, Sudeep Holla, Will Deacon, Steven Price,
Suzuki K Poulose, Andre Przywara
> The Arm CCA guest driver currently only implements TSM report support, but
> follow-up changes will add more TSM-related functionality to the same
> module.
>
> Rename arm-cca-guest.c to main.c and build it as an object of the
> arm-cca-guest module. This leaves room for the module to grow additional
> source files.
It doesn't matter but I would have described this as:
If a module is comprised of a single .c file with the same name as the
module then kbuild does not permit adding any more .c files to the
module. Rename arm-cca-guest.c to main.c so more source files can be
added.
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
> [ ... 19 lines skipped ... ]
> @@ -156,7 +156,7 @@ static int arm_cca_report_new(struct tsm_report *report, void *data)
> return ret;
> }
[Severity: High]
This isn't a bug introduced by this patch, but while reviewing the renamed
arm_cca_report_new() function, I noticed a potential out-of-bounds read
involving the RMM response length.
Does this code properly validate the length returned by the Realm Management
Monitor (RMM) before copying data?
In arm_cca_attestation_continue(), the untrusted length returned by the RMM
is unconditionally added to info->offset:
info->offset += len;
If a buggy or compromised RMM returns an unexpectedly large length,
info.offset can exceed RSI_GRANULE_SIZE (4096 bytes). The loop in
arm_cca_report_new() will terminate since info.offset < RSI_GRANULE_SIZE
becomes false, but as long as token_size + info.offset <= max_size, it
executes this copy:
memcpy(&token[token_size], buf, info.offset);
Since buf is allocated to be exactly RSI_GRANULE_SIZE bytes, using an
unvalidated info.offset here results in an out-of-bounds read from buf.
Could this leak adjacent kernel heap memory into the attestation token
that is returned to userspace?
This seems like something that should be fixed independently for
robustness.
--
Jason
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v10 4/7] arm64: realm: Move Realm memory encryption ops to RSI code
2026-09-04 9:49 ` [PATCH v10 4/7] arm64: realm: Move Realm memory encryption ops to RSI code Aneesh Kumar K.V (Arm)
@ 2026-09-04 19:39 ` Jason Gunthorpe
0 siblings, 0 replies; 15+ messages in thread
From: Jason Gunthorpe @ 2026-09-04 19:39 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: linux-coco, linux-arm-kernel, linux-kernel, Catalin Marinas,
Greg KH, Jeremy Linton, Jonathan Cameron, Lorenzo Pieralisi,
Mark Rutland, Sudeep Holla, Will Deacon, Steven Price,
Suzuki K Poulose, Andre Przywara
On Fri, 04 Sep 2026 15:19:57 +0530, Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org> wrote:
> Realm memory encryption callbacks are CCA-specific. Keep the Realm callback
> registration with the RSI initialization code instead of pageattr.c, which
> only needs to provide the low-level page-attribute transition helper.
>
> Export __set_memory_enc_dec() within arm64 so the RSI code can wrap it with
> the Realm-specific encrypt/decrypt callbacks and warning policy.
>
> [...]
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
--
Jason
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v10 7/7] coco: guest: arm64: Replace dummy CCA device with sysfs ABI
2026-09-04 9:50 ` [PATCH v10 7/7] coco: guest: arm64: Replace dummy CCA device with sysfs ABI Aneesh Kumar K.V (Arm)
@ 2026-09-04 19:39 ` Jason Gunthorpe
0 siblings, 0 replies; 15+ messages in thread
From: Jason Gunthorpe @ 2026-09-04 19:39 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: linux-coco, linux-arm-kernel, linux-kernel, Catalin Marinas,
Greg KH, Jeremy Linton, Jonathan Cameron, Lorenzo Pieralisi,
Mark Rutland, Sudeep Holla, Will Deacon, Steven Price,
Suzuki K Poulose, Andre Przywara
On Fri, 04 Sep 2026 15:20:00 +0530, Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org> wrote:
> The SMCCC firmware driver now creates the arm-smccc platform device and
> instantiates the CCA RSI auxiliary devices once the RSI ABI is discovered.
> The arm64-specific arm-cca-dev platform device stub is therefore no longer
> needed.
>
> However, userspace has used the arm-cca-dev platform device to detect Arm
> CCA Realm guests [1]. Removing it without a replacement would break that
> detection and would also leave userspace depending on kernel device-model
> details.
>
> [...]
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
--
Jason
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2026-09-04 19:40 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-04 9:49 [PATCH v10 0/7] Switch Arm SMCCC firmware services to an SMCCC bus Aneesh Kumar K.V (Arm)
2026-09-04 9:49 ` [PATCH v10 1/7] firmware: smccc: Add an Arm " Aneesh Kumar K.V (Arm)
2026-09-04 19:39 ` Jason Gunthorpe
2026-09-04 9:49 ` [PATCH v10 2/7] firmware: hwrng: arm_smccc_trng: Register as an SMCCC device Aneesh Kumar K.V (Arm)
2026-09-04 19:39 ` Jason Gunthorpe
2026-09-04 9:49 ` [PATCH v10 3/7] firmware: arm_rmm: Move RSI support out of arch/arm64 Aneesh Kumar K.V (Arm)
2026-09-04 19:39 ` Jason Gunthorpe
2026-09-04 9:49 ` [PATCH v10 4/7] arm64: realm: Move Realm memory encryption ops to RSI code Aneesh Kumar K.V (Arm)
2026-09-04 19:39 ` Jason Gunthorpe
2026-09-04 9:49 ` [PATCH v10 5/7] virt: coco: arm-cca-guest: Rename TSM report source file Aneesh Kumar K.V (Arm)
2026-09-04 19:39 ` Jason Gunthorpe
2026-09-04 9:49 ` [PATCH v10 6/7] firmware: smccc: arm-cca-guest: Bind the TSM provider to an SMCCC device Aneesh Kumar K.V (Arm)
2026-09-04 19:39 ` Jason Gunthorpe
2026-09-04 9:50 ` [PATCH v10 7/7] coco: guest: arm64: Replace dummy CCA device with sysfs ABI Aneesh Kumar K.V (Arm)
2026-09-04 19:39 ` Jason Gunthorpe
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox