* [PATCH v3 0/2] Add SMCCC cache clean/invalidate provider
@ 2026-09-10 8:21 Srirangan Madhavan
2026-09-10 8:21 ` [PATCH v3 1/2] arm64: smccc: add cache clean/invalidate IDs and return codes Srirangan Madhavan
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Srirangan Madhavan @ 2026-09-10 8:21 UTC (permalink / raw)
To: mark.rutland, lpieralisi, sudeep.holla, conor, jic23
Cc: catalin.marinas, will, treding, jonathanh, bence.csokas,
linux-arm-kernel, linux-kernel, linux-tegra, Srirangan Madhavan
Apologies for the delay in posting v3. We waited until the corresponding
firmware support was available in TF-A. This allowed the provider to be
tested end to end with the CXL Reset series [2].
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:
- discovers SMCCC support and attributes at init time
- 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 provider is not
registered and existing behavior is preserved.
References:
[1] https://developer.arm.com/documentation/den0028/h
[2] https://lore.kernel.org/linux-cxl/20260902072804.665639-1-smadhavan@nvidia.com/
DEN0028 v1.7 has since been confirmed as stable.
Testing:
- With corresponding TF-A support enabled, exercised the provider through
the CXL Reset path 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 v2:
- Rebased onto Linux v7.3-rc1.
- Preserved the final BUSY or RATE_LIMITED error after retry exhaustion.
- Dropped the redundant feature query for the mandatory ATTRIBUTES call.
- Preserved the full 64-bit maximum-call-rate value returned in X3.
- Reordered local declarations in reverse-fir-tree order.
- Removed the routine provider registration message.
Changes since v1:
- Added Jonathan Cameron's Reviewed-by tags.
- Clarified the ARM_SMCCC_CACHE Kconfig help text.
- Added a Makefile comment identifying the providers that depend on
CACHEMAINT_FOR_HOTPLUG.
- Dropped the final-backoff-sleep skip in the retry loop.
Changes since RFC:
- Dropped the RFC tag.
- Moved the provider from arch/arm64/mm to drivers/cache.
- Added a dedicated CONFIG_ARM_SMCCC_CACHE option under the existing
CACHEMAINT_FOR_HOTPLUG menu.
- Dropped the global-operation coalescing optimization.
- Dropped provider handling for SMCCC_RET_NOT_REQUIRED.
- Removed the unnecessary global provider pointer.
- Removed arm64_ prefixes from static provider-local names.
- Documented why these SMCCC Arch cache maintenance calls use SMC64.
- Anchored the SMCCC return-code comment to DEN0028 v1.7.
- Used fsleep() for retry backoff.
- Used unsigned long for retry delay values passed to fsleep().
- Skipped the final backoff sleep when no retry remains.
- Documented the bounded mutex hold time across the serialized retry
sequence.
- Added mutex_destroy() on the registration failure path.
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 | 149 ++++++++++++++++++++++++++++++++
include/linux/arm-smccc.h | 21 ++++-
tools/include/linux/arm-smccc.h | 21 ++++-
5 files changed, 200 insertions(+), 4 deletions(-)
create mode 100644 drivers/cache/arm_smccc_cache.c
base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v3 1/2] arm64: smccc: add cache clean/invalidate IDs and return codes
2026-09-10 8:21 [PATCH v3 0/2] Add SMCCC cache clean/invalidate provider Srirangan Madhavan
@ 2026-09-10 8:21 ` Srirangan Madhavan
2026-10-01 9:34 ` Andre Przywara
2026-09-10 8:21 ` [PATCH v3 2/2] cache: add SMCCC-backed cache invalidate provider Srirangan Madhavan
2026-09-14 7:53 ` [PATCH v3 0/2] Add SMCCC cache clean/invalidate provider Bence Csókás
2 siblings, 1 reply; 8+ messages in thread
From: Srirangan Madhavan @ 2026-09-10 8:21 UTC (permalink / raw)
To: mark.rutland, lpieralisi, sudeep.holla, conor, jic23
Cc: catalin.marinas, will, 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>
---
include/linux/arm-smccc.h | 21 +++++++++++++++++++--
tools/include/linux/arm-smccc.h | 21 +++++++++++++++++++--
2 files changed, 38 insertions(+), 4 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__
diff --git a/tools/include/linux/arm-smccc.h b/tools/include/linux/arm-smccc.h
index 63ce9bebccd3..ae5637b3240f 100644
--- a/tools/include/linux/arm-smccc.h
+++ b/tools/include/linux/arm-smccc.h
@@ -96,6 +96,22 @@
ARM_SMCCC_SMC_32, \
0, 0x3fff)
+/*
+ * 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, \
@@ -182,12 +198,13 @@
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
#endif /*__LINUX_ARM_SMCCC_H*/
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v3 2/2] cache: add SMCCC-backed cache invalidate provider
2026-09-10 8:21 [PATCH v3 0/2] Add SMCCC cache clean/invalidate provider Srirangan Madhavan
2026-09-10 8:21 ` [PATCH v3 1/2] arm64: smccc: add cache clean/invalidate IDs and return codes Srirangan Madhavan
@ 2026-09-10 8:21 ` Srirangan Madhavan
2026-09-10 18:52 ` Jonathan Cameron
` (2 more replies)
2026-09-14 7:53 ` [PATCH v3 0/2] Add SMCCC cache clean/invalidate provider Bence Csókás
2 siblings, 3 replies; 8+ messages in thread
From: Srirangan Madhavan @ 2026-09-10 8:21 UTC (permalink / raw)
To: mark.rutland, lpieralisi, sudeep.holla, conor, jic23
Cc: catalin.marinas, will, treding, jonathanh, bence.csokas,
linux-arm-kernel, linux-kernel, linux-tegra, Srirangan Madhavan
Add a cache maintenance provider for the Arm SMCCC cache clean+invalidate
interface.
The provider discovers SMCCC support and attributes at init time,
serializes firmware calls, handles transient BUSY and RATE_LIMITED
responses with bounded retries, and registers with the generic cache
coherency framework used by memregion callers.
Signed-off-by: Srirangan Madhavan <smadhavan@nvidia.com>
Reviewed-by: Jonathan Cameron <jic23@kernel.org>
---
drivers/cache/Kconfig | 11 +++
drivers/cache/Makefile | 2 +
drivers/cache/arm_smccc_cache.c | 149 ++++++++++++++++++++++++++++++++
3 files changed, 162 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..1cfa8f8809d0
--- /dev/null
+++ b/drivers/cache/arm_smccc_cache.c
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2026 NVIDIA Corporation
+ *
+ * Arm SMCCC cache maintenance provider using cache clean+invalidate calls.
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/cache_coherency.h>
+#include <linux/cleanup.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/nmi.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 __init smccc_cache_init(void)
+{
+ struct arm_smccc_res res = {};
+ struct smccc_cache *cache;
+ int ret;
+
+ if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_1)
+ return -ENODEV;
+
+ if (arm_smccc_1_1_get_conduit() == SMCCC_CONDUIT_NONE)
+ return -ENODEV;
+
+ arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+ ARM_SMCCC_ARCH_CLEAN_INV_MEMREGION, &res);
+ if ((s32)res.a0 < 0)
+ return -ENODEV;
+
+ arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_CLEAN_INV_MEMREGION_ATTRIBUTES,
+ &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;
+}
+arch_initcall(smccc_cache_init);
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v3 2/2] cache: add SMCCC-backed cache invalidate provider
2026-09-10 8:21 ` [PATCH v3 2/2] cache: add SMCCC-backed cache invalidate provider Srirangan Madhavan
@ 2026-09-10 18:52 ` Jonathan Cameron
2026-09-12 11:05 ` Conor Dooley
2026-10-01 9:21 ` Andre Przywara
2 siblings, 0 replies; 8+ messages in thread
From: Jonathan Cameron @ 2026-09-10 18:52 UTC (permalink / raw)
To: Srirangan Madhavan
Cc: mark.rutland, lpieralisi, sudeep.holla, conor, jic23,
catalin.marinas, will, treding, jonathanh, bence.csokas,
linux-arm-kernel, linux-kernel, linux-tegra
On Thu, 10 Sep 2026 08:21:42 +0000
Srirangan Madhavan <smadhavan@nvidia.com> wrote:
> Add a cache maintenance provider for the Arm SMCCC cache clean+invalidate
> interface.
>
> The provider discovers SMCCC support and attributes at init time,
> serializes firmware calls, handles transient BUSY and RATE_LIMITED
> responses with bounded retries, and registers with the generic cache
> coherency framework used by memregion callers.
>
> Signed-off-by: Srirangan Madhavan <smadhavan@nvidia.com>
> Reviewed-by: Jonathan Cameron <jic23@kernel.org>
One tiny thing inline.
Thanks,
Jonathan
> diff --git a/drivers/cache/arm_smccc_cache.c b/drivers/cache/arm_smccc_cache.c
> new file mode 100644
> index 000000000000..1cfa8f8809d0
> --- /dev/null
> +++ b/drivers/cache/arm_smccc_cache.c
> @@ -0,0 +1,149 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2026 NVIDIA Corporation
> + *
> + * Arm SMCCC cache maintenance provider using cache clean+invalidate calls.
> + */
> +
> +#include <linux/arm-smccc.h>
> +#include <linux/cache_coherency.h>
> +#include <linux/cleanup.h>
> +#include <linux/delay.h>
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
Small thing, but can we avoid including the catch all that is kernel.h.
Generally aim for more specific headers for what is actually used.
> +#include <linux/mutex.h>
> +#include <linux/nmi.h>
> +
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3 2/2] cache: add SMCCC-backed cache invalidate provider
2026-09-10 8:21 ` [PATCH v3 2/2] cache: add SMCCC-backed cache invalidate provider Srirangan Madhavan
2026-09-10 18:52 ` Jonathan Cameron
@ 2026-09-12 11:05 ` Conor Dooley
2026-10-01 9:21 ` Andre Przywara
2 siblings, 0 replies; 8+ messages in thread
From: Conor Dooley @ 2026-09-12 11:05 UTC (permalink / raw)
To: Srirangan Madhavan
Cc: mark.rutland, lpieralisi, sudeep.holla, jic23, catalin.marinas,
will, treding, jonathanh, bence.csokas, linux-arm-kernel,
linux-kernel, linux-tegra
[-- Attachment #1: Type: text/plain, Size: 658 bytes --]
Will/Catalin,
On Thu, Sep 10, 2026 at 08:21:42AM +0000, Srirangan Madhavan wrote:
> Add a cache maintenance provider for the Arm SMCCC cache clean+invalidate
> interface.
>
> The provider discovers SMCCC support and attributes at init time,
> serializes firmware calls, handles transient BUSY and RATE_LIMITED
> responses with bounded retries, and registers with the generic cache
> coherency framework used by memregion callers.
>
> Signed-off-by: Srirangan Madhavan <smadhavan@nvidia.com>
> Reviewed-by: Jonathan Cameron <jic23@kernel.org>
If yous wanna take this,
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Cheers,
Conor.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3 0/2] Add SMCCC cache clean/invalidate provider
2026-09-10 8:21 [PATCH v3 0/2] Add SMCCC cache clean/invalidate provider Srirangan Madhavan
2026-09-10 8:21 ` [PATCH v3 1/2] arm64: smccc: add cache clean/invalidate IDs and return codes Srirangan Madhavan
2026-09-10 8:21 ` [PATCH v3 2/2] cache: add SMCCC-backed cache invalidate provider Srirangan Madhavan
@ 2026-09-14 7:53 ` Bence Csókás
2 siblings, 0 replies; 8+ messages in thread
From: Bence Csókás @ 2026-09-14 7:53 UTC (permalink / raw)
To: Srirangan Madhavan, mark.rutland, lpieralisi, sudeep.holla, conor,
jic23
Cc: catalin.marinas, will, treding, jonathanh, linux-arm-kernel,
linux-kernel, linux-tegra
Hi,
On 2026. 09. 10. 10:21, Srirangan Madhavan wrote:
> Apologies for the delay in posting v3. We waited until the corresponding
> firmware support was available in TF-A. This allowed the provider to be
> tested end to end with the CXL Reset series [2].
>
> 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:
> - discovers SMCCC support and attributes at init time
> - 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 provider is not
> registered and existing behavior is preserved.
>
> References:
> [1] https://developer.arm.com/documentation/den0028/h
> [2] https://lore.kernel.org/linux-cxl/20260902072804.665639-1-smadhavan@nvidia.com/
>
> DEN0028 v1.7 has since been confirmed as stable.
>
> Testing:
> - With corresponding TF-A support enabled, exercised the provider through
> the CXL Reset path 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 v2:
> - Rebased onto Linux v7.3-rc1.
> - Preserved the final BUSY or RATE_LIMITED error after retry exhaustion.
> - Dropped the redundant feature query for the mandatory ATTRIBUTES call.
> - Preserved the full 64-bit maximum-call-rate value returned in X3.
> - Reordered local declarations in reverse-fir-tree order.
> - Removed the routine provider registration message.
Reviewed-by: Bence Csókás <bence.csokas@arm.com>
I have yet to try it out on actual hardware, but from looking at the
code, it now seems to match the spec.
> Changes since v1:
> - Added Jonathan Cameron's Reviewed-by tags.
> - Clarified the ARM_SMCCC_CACHE Kconfig help text.
> - Added a Makefile comment identifying the providers that depend on
> CACHEMAINT_FOR_HOTPLUG.
> - Dropped the final-backoff-sleep skip in the retry loop.
>
> Changes since RFC:
> - Dropped the RFC tag.
> - Moved the provider from arch/arm64/mm to drivers/cache.
> - Added a dedicated CONFIG_ARM_SMCCC_CACHE option under the existing
> CACHEMAINT_FOR_HOTPLUG menu.
> - Dropped the global-operation coalescing optimization.
> - Dropped provider handling for SMCCC_RET_NOT_REQUIRED.
> - Removed the unnecessary global provider pointer.
> - Removed arm64_ prefixes from static provider-local names.
> - Documented why these SMCCC Arch cache maintenance calls use SMC64.
> - Anchored the SMCCC return-code comment to DEN0028 v1.7.
> - Used fsleep() for retry backoff.
> - Used unsigned long for retry delay values passed to fsleep().
> - Skipped the final backoff sleep when no retry remains.
> - Documented the bounded mutex hold time across the serialized retry
> sequence.
> - Added mutex_destroy() on the registration failure path.
>
> 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 | 149 ++++++++++++++++++++++++++++++++
> include/linux/arm-smccc.h | 21 ++++-
> tools/include/linux/arm-smccc.h | 21 ++++-
> 5 files changed, 200 insertions(+), 4 deletions(-)
> create mode 100644 drivers/cache/arm_smccc_cache.c
>
>
> base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
Bence
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3 2/2] cache: add SMCCC-backed cache invalidate provider
2026-09-10 8:21 ` [PATCH v3 2/2] cache: add SMCCC-backed cache invalidate provider Srirangan Madhavan
2026-09-10 18:52 ` Jonathan Cameron
2026-09-12 11:05 ` Conor Dooley
@ 2026-10-01 9:21 ` Andre Przywara
2 siblings, 0 replies; 8+ messages in thread
From: Andre Przywara @ 2026-10-01 9:21 UTC (permalink / raw)
To: Srirangan Madhavan, mark.rutland, lpieralisi, sudeep.holla, conor,
jic23
Cc: catalin.marinas, will, treding, jonathanh, bence.csokas,
linux-arm-kernel, linux-kernel, linux-tegra
Hi,
On 9/10/26 10:21, Srirangan Madhavan wrote:
> Add a cache maintenance provider for the Arm SMCCC cache clean+invalidate
> interface.
>
> The provider discovers SMCCC support and attributes at init time,
> serializes firmware calls, handles transient BUSY and RATE_LIMITED
> responses with bounded retries, and registers with the generic cache
> coherency framework used by memregion callers.
Is there any chance you could hook this up to the new Arm SMCCC bus?
Looks like Aneesh's series[1] is now queued for v7.4. You would just
need to pick the first two patches, then replicate the work that's done
in patch 2/8.
The rest looks okay on a first glance, but can you please mention the
respective spec document (Arm DEN0028) somewhere, ideally at the top of
the file and maybe in the commit message?
Cheers,
Andre
[1]
https://lore.kernel.org/linux-arm-kernel/179026658584.3654431.7189876471375206962.b4-ty@b4/
>
> Signed-off-by: Srirangan Madhavan <smadhavan@nvidia.com>
> Reviewed-by: Jonathan Cameron <jic23@kernel.org>
> ---
> drivers/cache/Kconfig | 11 +++
> drivers/cache/Makefile | 2 +
> drivers/cache/arm_smccc_cache.c | 149 ++++++++++++++++++++++++++++++++
> 3 files changed, 162 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..1cfa8f8809d0
> --- /dev/null
> +++ b/drivers/cache/arm_smccc_cache.c
> @@ -0,0 +1,149 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2026 NVIDIA Corporation
> + *
> + * Arm SMCCC cache maintenance provider using cache clean+invalidate calls.
> + */
> +
> +#include <linux/arm-smccc.h>
> +#include <linux/cache_coherency.h>
> +#include <linux/cleanup.h>
> +#include <linux/delay.h>
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/mutex.h>
> +#include <linux/nmi.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 __init smccc_cache_init(void)
> +{
> + struct arm_smccc_res res = {};
> + struct smccc_cache *cache;
> + int ret;
> +
> + if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_1)
> + return -ENODEV;
> +
> + if (arm_smccc_1_1_get_conduit() == SMCCC_CONDUIT_NONE)
> + return -ENODEV;
> +
> + arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
> + ARM_SMCCC_ARCH_CLEAN_INV_MEMREGION, &res);
> + if ((s32)res.a0 < 0)
> + return -ENODEV;
> +
> + arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_CLEAN_INV_MEMREGION_ATTRIBUTES,
> + &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;
> +}
> +arch_initcall(smccc_cache_init);
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3 1/2] arm64: smccc: add cache clean/invalidate IDs and return codes
2026-09-10 8:21 ` [PATCH v3 1/2] arm64: smccc: add cache clean/invalidate IDs and return codes Srirangan Madhavan
@ 2026-10-01 9:34 ` Andre Przywara
0 siblings, 0 replies; 8+ messages in thread
From: Andre Przywara @ 2026-10-01 9:34 UTC (permalink / raw)
To: Srirangan Madhavan, mark.rutland, lpieralisi, sudeep.holla, conor,
jic23
Cc: catalin.marinas, will, treding, jonathanh, bence.csokas,
linux-arm-kernel, linux-kernel, linux-tegra
Hi,
On 9/10/26 10:21, Srirangan Madhavan wrote:
> 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>
> ---
> include/linux/arm-smccc.h | 21 +++++++++++++++++++--
> tools/include/linux/arm-smccc.h | 21 +++++++++++++++++++--
> 2 files changed, 38 insertions(+), 4 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.hARM_SMCCC_FAST_CALL
> @@ -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__
>
> diff --git a/tools/include/linux/arm-smccc.h b/tools/include/linux/arm-smccc.h
> index 63ce9bebccd3..ae5637b3240f 100644
> --- a/tools/include/linux/arm-smccc.h
> +++ b/tools/include/linux/arm-smccc.h
Why is that? Is there any tool using that? I don't think we
unconditionally sync the two files?
The numbers in the file above match the spec, so for that part:
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Cheers,
Andre
> @@ -96,6 +96,22 @@
> ARM_SMCCC_SMC_32, \
> 0, 0x3fff)
>
> +/*
> + * 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, \
> @@ -182,12 +198,13 @@
> 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
>
> #endif /*__LINUX_ARM_SMCCC_H*/
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-10-01 9:34 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-10 8:21 [PATCH v3 0/2] Add SMCCC cache clean/invalidate provider Srirangan Madhavan
2026-09-10 8:21 ` [PATCH v3 1/2] arm64: smccc: add cache clean/invalidate IDs and return codes Srirangan Madhavan
2026-10-01 9:34 ` Andre Przywara
2026-09-10 8:21 ` [PATCH v3 2/2] cache: add SMCCC-backed cache invalidate provider Srirangan Madhavan
2026-09-10 18:52 ` Jonathan Cameron
2026-09-12 11:05 ` Conor Dooley
2026-10-01 9:21 ` Andre Przywara
2026-09-14 7:53 ` [PATCH v3 0/2] Add SMCCC cache clean/invalidate provider Bence Csókás
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.