cacheflush completely broken, suspecting PAN+LPAE

Russell King (Oracle) linux at armlinux.org.uk
Tue Nov 12 02:21:36 PST 2024


On Mon, Nov 11, 2024 at 11:38:17PM +0100, Michał Pecio wrote:
> Hi,
> So I guess it looks like there is a problem with this feature, perhaps
> a missing "permit user accesss" somewhere?

That's exactly the reason - user access needs to be enabled before
calling flush_icache_user_range() so that the cache operation
instructions don't fault. The patch below should fix this.

Please ensure that you copy me with ARM related bugs in future.

Thanks for finding the issue.

8<===
From: "Russell King (Oracle)" <rmk+kernel at armlinux.org.uk>
Subject: [PATCH] ARM: fix cacheflush with PAN

It seems that the cacheflush syscall got broken when PAN was
implemented. User access was not enabled around the cache maintenance
instructions, causing them to fault.

Fixes: a5e090acbf54 ("ARM: software-based priviledged-no-access support")
Reported-by: From: Michał Pecio <michal.pecio at gmail.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 arch/arm/kernel/traps.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 54dcdcde3f77..6518771c1496 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -574,6 +574,7 @@ static int bad_syscall(int n, struct pt_regs *regs)
 static inline int
 __do_cache_op(unsigned long start, unsigned long end)
 {
+	unsigned int ua_flags;
 	int ret;
 
 	do {
@@ -582,7 +583,9 @@ __do_cache_op(unsigned long start, unsigned long end)
 		if (fatal_signal_pending(current))
 			return 0;
 
+		ua_flags = uaccess_save_and_enable();
 		ret = flush_icache_user_range(start, start + chunk);
+		uaccess_restore(ua_flags);
 		if (ret)
 			return ret;
 
-- 
2.30.2

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!



More information about the linux-arm-kernel mailing list