* [PATCH v4 0/2] Add SMCCC cache clean/invalidate provider
@ 2026-10-13 7:02 Srirangan Madhavan
2026-10-13 7:02 ` [PATCH v4 1/2] arm64: smccc: add cache clean/invalidate IDs and return codes Srirangan Madhavan
2026-10-13 7:02 ` [PATCH v4 2/2] cache: add SMCCC-backed cache invalidate provider Srirangan Madhavan
0 siblings, 2 replies; 3+ messages in thread
From: Srirangan Madhavan @ 2026-10-13 7:02 UTC (permalink / raw)
To: mark.rutland, lpieralisi, sudeep.holla, conor, jic23
Cc: catalin.marinas, will, andre.przywara, aneesh.kumar,
Souvik.Chakravarty, treding, jonathanh, bence.csokas,
linux-arm-kernel, linux-kernel, linux-tegra, Srirangan Madhavan
This series adds an arm64 backend for memregion cache invalidation users
based on the Arm SMCCC cache clean+invalidate interface.
Per DEN0028, this interface targets systems where a Normal Cacheable
memory region can be modified in ways that are not handled by usual PE
coherency mechanisms, and where VA-based CMOs may be too slow or
insufficient for large ranges and/or system-cache implementations.
Representative use cases include device-backed memory state transitions
where stale CPU/system cache lines must be invalidated reliably (for
example secure erase, reset/offline flows, and dynamic memory
reconfiguration).
Patch 1 introduces the Arm SMCCC cache clean/invalidate function IDs and
transient return codes needed by callers [1].
Patch 2 adds a cache maintenance provider that:
- registers the interface attributes function as an SMCCC device
- binds to the service through the SMCCC bus
- registers with the generic cache coherency framework used by
cpu_cache_invalidate_memregion()
- handles transient BUSY/RATE_LIMITED responses with bounded retries
This patch set does not add a software fallback path; when firmware does
not implement the SMCCC cache maintenance interface, the SMCCC device is
not registered and existing behavior is preserved.
The series is based on the current SMCCC bus topic branch queued for
v7.4 [3].
References:
[1] https://developer.arm.com/documentation/den0028/h
[2] https://lore.kernel.org/linux-cxl/20260902072804.665639-1-smadhavan@nvidia.com/
[3] https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=for-next/smccc-bus
DEN0028 v1.7 has since been confirmed as stable.
Testing:
- With corresponding TF-A support enabled, exercised the cache operation
path through CXL Reset [2] and verified that it invokes the SMCCC call and
completes the cache flush successfully.
- ARM64 defconfig with CONFIG_CACHEMAINT_FOR_HOTPLUG=y and
CONFIG_ARM_SMCCC_CACHE=y
- W=1 build of drivers/cache/arm_smccc_cache.o
- W=1 build of the ARM64 Image
Changes since v3:
- Rebased onto the current SMCCC bus topic branch queued for v7.4.
- Converted the provider to an SMCCC bus driver and registered the
attributes function as an SMCCC device.
- Added an explicit DEN0028 v1.7 reference to the provider source and
patch 2 commit message.
- Dropped the unused tools/include copy of the new definitions.
- Replaced the catch-all linux/kernel.h include with the specific headers
used by the provider.
- Added Reviewed-by tags for patch 1 from Bence and Andre.
- Dropped the review tags from patch 2 because the SMCCC bus conversion
changed its discovery and initialization paths after the rebase.
Srirangan Madhavan (2):
arm64: smccc: add cache clean/invalidate IDs and return codes
cache: add SMCCC-backed cache invalidate provider
drivers/cache/Kconfig | 11 +++
drivers/cache/Makefile | 2 +
drivers/cache/arm_smccc_cache.c | 161 ++++++++++++++++++++++++++++++++
drivers/firmware/smccc/smccc.c | 5 +
include/linux/arm-smccc.h | 21 ++++-
5 files changed, 198 insertions(+), 2 deletions(-)
create mode 100644 drivers/cache/arm_smccc_cache.c
base-commit: c6e78a4080a3b310a9f61db778d6dee7bc646cb7
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v4 1/2] arm64: smccc: add cache clean/invalidate IDs and return codes
2026-10-13 7:02 [PATCH v4 0/2] Add SMCCC cache clean/invalidate provider Srirangan Madhavan
@ 2026-10-13 7:02 ` Srirangan Madhavan
2026-10-13 7:02 ` [PATCH v4 2/2] cache: add SMCCC-backed cache invalidate provider Srirangan Madhavan
1 sibling, 0 replies; 3+ messages in thread
From: Srirangan Madhavan @ 2026-10-13 7:02 UTC (permalink / raw)
To: mark.rutland, lpieralisi, sudeep.holla, conor, jic23
Cc: catalin.marinas, will, andre.przywara, aneesh.kumar,
Souvik.Chakravarty, treding, jonathanh, bence.csokas,
linux-arm-kernel, linux-kernel, linux-tegra, Srirangan Madhavan
Define SMCCC Arch function IDs for CLEAN_INV_MEMREGION and its ATTRIBUTES
call, and add RATE_LIMITED/BUSY return codes from DEN0028 for callers that
need transient error handling.
Signed-off-by: Srirangan Madhavan <smadhavan@nvidia.com>
Reviewed-by: Jonathan Cameron <jic23@kernel.org>
Reviewed-by: Bence Csókás <bence.csokas@arm.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
---
include/linux/arm-smccc.h | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 4de81848fe2e..2e205320d88a 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -116,6 +116,22 @@
ARM_SMCCC_SMC_32, \
ARM_SMCCC_OWNER_CPU, 0x10)
+/*
+ * DEN0028 v1.7 defines these cache maintenance functions as SMC64
+ * because they carry 64-bit memory range arguments.
+ */
+#define ARM_SMCCC_ARCH_CLEAN_INV_MEMREGION \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+ ARM_SMCCC_SMC_64, \
+ ARM_SMCCC_OWNER_ARCH, \
+ 0x5)
+
+#define ARM_SMCCC_ARCH_CLEAN_INV_MEMREGION_ATTRIBUTES \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+ ARM_SMCCC_SMC_64, \
+ ARM_SMCCC_OWNER_ARCH, \
+ 0x6)
+
#define ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_32, \
@@ -305,13 +321,14 @@
0x53)
/*
- * Return codes defined in ARM DEN 0070A
- * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C
+ * Return codes defined by Arm SMCCC (DEN0028 v1.7).
*/
#define SMCCC_RET_SUCCESS 0
#define SMCCC_RET_NOT_SUPPORTED -1
#define SMCCC_RET_NOT_REQUIRED -2
#define SMCCC_RET_INVALID_PARAMETER -3
+#define SMCCC_RET_RATE_LIMITED -4
+#define SMCCC_RET_BUSY -5
#ifndef __ASSEMBLY__
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v4 2/2] cache: add SMCCC-backed cache invalidate provider
2026-10-13 7:02 [PATCH v4 0/2] Add SMCCC cache clean/invalidate provider Srirangan Madhavan
2026-10-13 7:02 ` [PATCH v4 1/2] arm64: smccc: add cache clean/invalidate IDs and return codes Srirangan Madhavan
@ 2026-10-13 7:02 ` Srirangan Madhavan
1 sibling, 0 replies; 3+ messages in thread
From: Srirangan Madhavan @ 2026-10-13 7:02 UTC (permalink / raw)
To: mark.rutland, lpieralisi, sudeep.holla, conor, jic23
Cc: catalin.marinas, will, andre.przywara, aneesh.kumar,
Souvik.Chakravarty, treding, jonathanh, bence.csokas,
linux-arm-kernel, linux-kernel, linux-tegra, Srirangan Madhavan
Add a cache maintenance provider for the cache clean+invalidate interface
defined by Arm DEN0028 v1.7.
Register the interface attributes function as an SMCCC device and bind the
provider through the SMCCC bus. The provider reads the firmware attributes
during probe and serializes cache maintenance calls. It handles transient
BUSY and RATE_LIMITED responses with bounded retries. It also registers
with the generic cache coherency framework used by memregion callers.
Signed-off-by: Srirangan Madhavan <smadhavan@nvidia.com>
---
drivers/cache/Kconfig | 11 +++
drivers/cache/Makefile | 2 +
drivers/cache/arm_smccc_cache.c | 161 ++++++++++++++++++++++++++++++++
drivers/firmware/smccc/smccc.c | 5 +
4 files changed, 179 insertions(+)
create mode 100644 drivers/cache/arm_smccc_cache.c
diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig
index 1518449d47b5..57fd1823dec5 100644
--- a/drivers/cache/Kconfig
+++ b/drivers/cache/Kconfig
@@ -42,6 +42,17 @@ menuconfig CACHEMAINT_FOR_HOTPLUG
if CACHEMAINT_FOR_HOTPLUG
+config ARM_SMCCC_CACHE
+ bool "Arm SMCCC cache maintenance provider"
+ depends on ARM64 && HAVE_ARM_SMCCC_DISCOVERY
+ help
+ Enable support for the Arm SMCCC cache clean+invalidate
+ interface as a provider for memory hotplug-like cache
+ maintenance operations.
+ The provider registers only when firmware advertises the
+ SMCCC calls and attributes, so systems without firmware support
+ continue without this registered provider.
+
config HISI_SOC_HHA
tristate "HiSilicon Hydra Home Agent (HHA) device driver"
depends on (ARM64 && ACPI) || COMPILE_TEST
diff --git a/drivers/cache/Makefile b/drivers/cache/Makefile
index b3362b15d6c1..55736a032d6f 100644
--- a/drivers/cache/Makefile
+++ b/drivers/cache/Makefile
@@ -4,4 +4,6 @@ obj-$(CONFIG_AX45MP_L2_CACHE) += ax45mp_cache.o
obj-$(CONFIG_SIFIVE_CCACHE) += sifive_ccache.o
obj-$(CONFIG_STARFIVE_STARLINK_CACHE) += starfive_starlink_cache.o
+# Providers below depend on CACHEMAINT_FOR_HOTPLUG.
+obj-$(CONFIG_ARM_SMCCC_CACHE) += arm_smccc_cache.o
obj-$(CONFIG_HISI_SOC_HHA) += hisi_soc_hha.o
diff --git a/drivers/cache/arm_smccc_cache.c b/drivers/cache/arm_smccc_cache.c
new file mode 100644
index 000000000000..aca71113eb1c
--- /dev/null
+++ b/drivers/cache/arm_smccc_cache.c
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2026 NVIDIA Corporation
+ *
+ * Arm SMCCC cache maintenance provider using the cache clean+invalidate
+ * interface defined by Arm DEN0028 v1.7.
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/arm-smccc-bus.h>
+#include <linux/cache_coherency.h>
+#include <linux/cleanup.h>
+#include <linux/container_of.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/math.h>
+#include <linux/minmax.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/nmi.h>
+#include <linux/time64.h>
+#include <linux/types.h>
+#include <linux/wordpart.h>
+
+#define SMCCC_CACHE_MAX_RETRIES 5
+#define SMCCC_CACHE_DEFAULT_DELAY_US 1000UL
+#define SMCCC_CACHE_MAX_DELAY_US 20000UL
+
+struct smccc_cache {
+ /* Must be first member */
+ struct cache_coherency_ops_inst cci;
+ struct mutex lock; /* Serializes SMCCC cache maintenance calls. */
+ u64 rate_limit;
+ u32 latency_us;
+};
+
+static int smccc_cache_status_to_errno(s32 status)
+{
+ switch (status) {
+ case SMCCC_RET_SUCCESS:
+ return 0;
+ case SMCCC_RET_NOT_SUPPORTED:
+ return -EOPNOTSUPP;
+ case SMCCC_RET_INVALID_PARAMETER:
+ return -EINVAL;
+ case SMCCC_RET_RATE_LIMITED:
+ return -EAGAIN;
+ case SMCCC_RET_BUSY:
+ return -EBUSY;
+ default:
+ return -EIO;
+ }
+}
+
+static unsigned long smccc_cache_delay_us(const struct smccc_cache *cache)
+{
+ unsigned long delay_us = 0;
+
+ if (cache->rate_limit)
+ delay_us = DIV_ROUND_UP_ULL(USEC_PER_SEC, cache->rate_limit);
+
+ if (cache->latency_us)
+ delay_us = max(delay_us, (unsigned long)cache->latency_us);
+
+ /*
+ * Firmware may advertise neither a rate limit nor a latency hint; use
+ * a small bounded backoff instead of retrying in a tight loop.
+ */
+ if (!delay_us)
+ delay_us = SMCCC_CACHE_DEFAULT_DELAY_US;
+
+ return min(delay_us, SMCCC_CACHE_MAX_DELAY_US);
+}
+
+static int smccc_cache_wbinv(struct cache_coherency_ops_inst *cci,
+ struct cc_inval_params *invp)
+{
+ struct smccc_cache *cache = container_of(cci, struct smccc_cache, cci);
+ unsigned long delay_us = smccc_cache_delay_us(cache);
+ struct arm_smccc_res res = {};
+ int ret;
+
+ if (!invp->size)
+ return -EINVAL;
+
+ /*
+ * Serialize the full retry sequence. With the default bounds, a caller
+ * may hold the mutex across up to five 20ms backoff sleeps.
+ */
+ guard(mutex)(&cache->lock);
+
+ for (unsigned int i = 0; i < SMCCC_CACHE_MAX_RETRIES; i++) {
+ /* Long firmware operations can trigger watchdog checks. */
+ touch_nmi_watchdog();
+
+ arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_CLEAN_INV_MEMREGION,
+ invp->addr, invp->size, 0UL, &res);
+
+ ret = smccc_cache_status_to_errno((s32)res.a0);
+ if (!ret)
+ return 0;
+
+ if (ret != -EBUSY && ret != -EAGAIN)
+ return ret;
+
+ fsleep(delay_us);
+ }
+
+ return ret;
+}
+
+static const struct cache_coherency_ops smccc_cache_ops = {
+ .wbinv = smccc_cache_wbinv,
+};
+
+static int smccc_cache_probe(struct arm_smccc_device *sdev)
+{
+ struct arm_smccc_res res = {};
+ struct smccc_cache *cache;
+ int ret;
+
+ arm_smccc_1_1_invoke(sdev->func_id, &res);
+ if ((s32)res.a0)
+ return -ENODEV;
+
+ cache = cache_coherency_ops_instance_alloc(&smccc_cache_ops,
+ struct smccc_cache, cci);
+ if (!cache)
+ return -ENOMEM;
+
+ mutex_init(&cache->lock);
+ cache->latency_us = lower_32_bits(res.a2);
+ cache->rate_limit = res.a3;
+
+ ret = cache_coherency_ops_instance_register(&cache->cci);
+ if (ret) {
+ mutex_destroy(&cache->lock);
+ cache_coherency_ops_instance_put(&cache->cci);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct arm_smccc_device_id smccc_cache_id_table[] = {
+ { .func_id = ARM_SMCCC_ARCH_CLEAN_INV_MEMREGION_ATTRIBUTES },
+ {}
+};
+MODULE_DEVICE_TABLE(arm_smccc, smccc_cache_id_table);
+
+static struct arm_smccc_driver smccc_cache_driver = {
+ .name = KBUILD_MODNAME,
+ .probe = smccc_cache_probe,
+ .id_table = smccc_cache_id_table,
+};
+module_arm_smccc_driver(smccc_cache_driver);
+
+MODULE_IMPORT_NS("CACHE_COHERENCY");
+MODULE_AUTHOR("Srirangan Madhavan");
+MODULE_DESCRIPTION("Arm SMCCC cache maintenance provider");
+MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/smccc/smccc.c b/drivers/firmware/smccc/smccc.c
index 5dc768ac4143..5a5d50d17410 100644
--- a/drivers/firmware/smccc/smccc.c
+++ b/drivers/firmware/smccc/smccc.c
@@ -100,6 +100,11 @@ static const struct smccc_device_info smccc_devices[] __initconst = {
.requires_smc = true,
.device_name = "arm-rsi",
},
+ {
+ .func_id = ARM_SMCCC_ARCH_CLEAN_INV_MEMREGION_ATTRIBUTES,
+ .requires_smc = false,
+ .device_name = "arm-smccc-cache",
+ },
};
static bool __init smccc_probe_smccc_device(const struct smccc_device_info *smccc_dev)
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-13 7:02 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-13 7:02 [PATCH v4 0/2] Add SMCCC cache clean/invalidate provider Srirangan Madhavan
2026-10-13 7:02 ` [PATCH v4 1/2] arm64: smccc: add cache clean/invalidate IDs and return codes Srirangan Madhavan
2026-10-13 7:02 ` [PATCH v4 2/2] cache: add SMCCC-backed cache invalidate provider Srirangan Madhavan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.