All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] efivarfs: Rate limit statfs() handler
@ 2026-08-18 14:11 Ard Biesheuvel
  0 siblings, 0 replies; only message in thread
From: Ard Biesheuvel @ 2026-08-18 14:11 UTC (permalink / raw)
  To: linux-efi; +Cc: x86, Ard Biesheuvel, stable, Anisse Astier, Ravi Bangoria

Ravi reports that statfs() may be called by unprivileged users on the
efivarfs mount point, which may result in a flood of calls to the
QueryVariableInfo() runtime service. These calls are disproportionately
costly on x86 systems where the variable store is backed by SMM, as each
SMM entry requires a rendez-vous of all the CPUs.

So rate limit the calls to QueryVariableInfo() at twice per second, and
return the most recently obtained values for calls that are elided.

Cc: <stable@vger.kernel.org>
Cc: Anisse Astier <anisse@astier.eu>
Reported-by: Ravi Bangoria <ravi.bangoria@amd.com>
Fixes: d86ff3333cb1 ("efivarfs: expose used and total size")
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
This supersedes [0], which had some issues, the main one being that a
cache that requires explicit invalidation may go out of sync due to
direct calls to SetVariable() made by other drivers.

[0] https://lore.kernel.org/all/20260801144258.15977-2-ardb@kernel.org/

 fs/efivarfs/super.c | 30 ++++++++++++++++----
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
index 733c19571f1c..8d33f11db2a1 100644
--- a/fs/efivarfs/super.c
+++ b/fs/efivarfs/super.c
@@ -89,12 +89,30 @@ static int efivarfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 	/* Some UEFI firmware does not implement QueryVariableInfo() */
 	storage_space = remaining_space = 0;
 	if (efi_rt_services_supported(EFI_RT_SUPPORTED_QUERY_VARIABLE_INFO)) {
-		status = efivar_query_variable_info(attr, &storage_space,
-						    &remaining_space,
-						    &max_variable_size);
-		if (status != EFI_SUCCESS && status != EFI_UNSUPPORTED)
-			pr_warn_ratelimited("query_variable_info() failed: 0x%lx\n",
-					    status);
+		static DEFINE_RATELIMIT_STATE(_rs, 2 * HZ, 5);
+		static u64 storage, remaining;
+		static DEFINE_SPINLOCK(lock);
+
+		if (!__ratelimit(&_rs)) {
+			ratelimit_set_flags(&_rs, RATELIMIT_MSG_ON_RELEASE);
+
+			spin_lock(&lock);
+			storage_space = storage;
+			remaining_space = remaining;
+			spin_unlock(&lock);
+		} else {
+			status = efivar_query_variable_info(attr, &storage_space,
+							    &remaining_space,
+							    &max_variable_size);
+			if (status != EFI_SUCCESS && status != EFI_UNSUPPORTED)
+				pr_warn("query_variable_info() failed: 0x%lx\n",
+					status);
+
+			spin_lock(&lock);
+			storage = storage_space;
+			remaining = remaining_space;
+			spin_unlock(&lock);
+		}
 	}
 
 	/*
-- 
2.55.0.699.gb54405d56f-goog


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-08-18 14:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-18 14:11 [PATCH] efivarfs: Rate limit statfs() handler Ard Biesheuvel

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.