cacheflush completely broken, suspecting PAN+LPAE
Arnd Bergmann
arnd at arndb.de
Mon Nov 11 22:41:12 PST 2024
On Tue, Nov 12, 2024, at 02:15, Linus Walleij wrote:
> On Mon, Nov 11, 2024 at 11:38 PM Michał Pecio <michal.pecio at gmail.com> wrote:
>> cacheflush(0xb374a000, 0xb374b000, 0) = -1 EFAULT (Bad address)
...
>> So I guess it looks like there is a problem with this feature, perhaps
>> a missing "permit user accesss" somewhere?
>
> static inline int
> do_cache_op(unsigned long start, unsigned long end, int flags)
> {
> if (end < start || flags)
> return -EINVAL;
>
> if (!access_ok((void __user *)start, end - start))
> return -EFAULT;
>
> return __do_cache_op(start, end);
> }
I would guess that the problem is not the access_ok() but
the actual access in v7_coherent_user_range() that does
not appear to call uaccess_save_and_enable() or its assembler
equivalent around the lines
USER( mcr p15, 0, r12, c7, c11, 1 )
...
USER( mcr p15, 0, r12, c7, c5, 1 )
> diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
> index 480e307501bb..400650519bd1 100644
> --- a/arch/arm/kernel/traps.c
> +++ b/arch/arm/kernel/traps.c
> @@ -592,11 +592,14 @@ __do_cache_op(unsigned long start, unsigned long end)
> static inline int
> do_cache_op(unsigned long start, unsigned long end, int flags)
> {
> + pr_info("%s(%08lx-%08lx)\n", __func__, start, end);
> if (end < start || flags)
> return -EINVAL;
>
> - if (!access_ok((void __user *)start, end - start))
> + if (!access_ok((void __user *)start, end - start)) {
> + pr_err("ACCESS NOT OK\n");
> return -EFAULT;
> + }
>
> return __do_cache_op(start, end);
> }
This does not catch -EFAULT being returned from the USER()
trap in __do_cache_op(), so I would expect it to trigger but
also not to flush the caches.
It's unclear to me if this problem is specific to the TTBR0
PAN variant, or if it can also happen on any variant of the
CPU_SW_DOMAIN_PAN. It seems unlikely that CPU_SW_DOMAIN_PAN
has been broken for this long without anyone noticing, but
I also don't see why it doesn't trap in the cache flush
when the TTBR0 version does.
Arnd
More information about the linux-arm-kernel
mailing list