All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: Ahmad Fatoum <a.fatoum@pengutronix.de>
Cc: barebox@lists.infradead.org
Subject: Re: [PATCH v2] ARM64: mmu: implement mmu_disable completely in assembly
Date: Mon, 15 Dec 2025 09:25:12 +0100	[thread overview]
Message-ID: <aT_F6JDPpyh__VjG@pengutronix.de> (raw)
In-Reply-To: <20251212111021.2620877-1-a.fatoum@pengutronix.de>

On Fri, Dec 12, 2025 at 12:10:19PM +0100, Ahmad Fatoum wrote:
> Splitting mmu_disable into two noinline function on a RK3568 leads to a
> barebox crash, because the code has the implicit assumption that the
> compiler won't generate memory accesses including spilling to stack.
> 
> We can't guarantee this in C code, so implement the procedure in
> assembly.
> 
> While at it, drop mmu_early_disable(), which is unused, superfluous and
> suffers from the same issue as old mmu_disable().
> 
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> v1 -> v2:
>   - fix copy-paste problem in some ELs (Ulrich)
> ---
>  arch/arm/cpu/cache-armv8.S   | 54 ++++++++++++++++++++++++++++++++++++
>  arch/arm/cpu/mmu_64.c        | 27 +-----------------
>  arch/arm/include/asm/cache.h |  1 +
>  arch/arm/include/asm/mmu.h   |  1 -
>  4 files changed, 56 insertions(+), 27 deletions(-)
> 
> diff --git a/arch/arm/cpu/cache-armv8.S b/arch/arm/cpu/cache-armv8.S
> index 9d9e0fb585a1..130338d6034f 100644
> --- a/arch/arm/cpu/cache-armv8.S
> +++ b/arch/arm/cpu/cache-armv8.S
> @@ -9,6 +9,7 @@
>  
>  #include <linux/linkage.h>
>  #include <init.h>
> +#include <asm/system.h>
>  
>  /*
>   * void v8_flush_dcache_level(level)
> @@ -120,6 +121,59 @@ ENTRY(v8_invalidate_dcache_all)
>  	ret
>  ENDPROC(v8_invalidate_dcache_all)
>  
> +/*
> + * void v8_mmu_disable(void)
> + *
> + * Implements the equivalent of following C code:
> + *
> + *	set_cr(get_cr() & ~(CR_M | CR_C))
> + *	v8_flush_dcache_all();
> + *	tlb_invalidate();
> + *
> + *	dsb();
> + *	isb();
> + *
> + * As D$ needs to be cleaned after it was disabled, this procedure
> + * is not permitted to trigger memory access, including spilling
> + * locals to stack. It's thus necessarily needs to be implemented
> + * in assembly.
> + */
> +.section .text.v8_mmu_disable
> +ENTRY(v8_mmu_disable)
> +	mov	x14, lr
> +	mov	x1, #~(CR_C | CR_M)
> +	mrs	x0, currentel
> +	lsr	w0, w0, #2		/* w0 <- current exception level */
> +	cmp	w0, #0x1
> +	b.eq	1f
> +	cmp 	w0, #0x2
> +	b.eq	2f

The switch_el macro could be used here.

Sascha

> +3:	/* EL3 */
> +	mrs	x0, sctlr_el3
> +	and	x0, x0, x1
> +	msr	sctlr_el3, x0
> +	bl	v8_flush_dcache_all
> +	tlbi	alle3
> +	b	0f
> +2:	/* EL2 */
> +	mrs	x0, sctlr_el2
> +	and	x0, x0, x1
> +	msr	sctlr_el2, x0
> +	bl	v8_flush_dcache_all
> +	tlbi	alle2
> +	b	0f
> +1:	/* EL1 */
> +	mrs	x0, sctlr_el1
> +	and	x0, x0, x1
> +	msr	sctlr_el1, x0
> +	bl	v8_flush_dcache_all
> +	tlbi	vmalle1
> +0:	/* common prologue */
> +	dsb 	sy
> +	isb
> +	ret	x14
> +ENDPROC(v8_mmu_disable)
> +
>  /*
>   * void v8_flush_dcache_range(start, end)
>   *
> diff --git a/arch/arm/cpu/mmu_64.c b/arch/arm/cpu/mmu_64.c
> index f22fcb5f8ea4..56c6a21f2b2a 100644
> --- a/arch/arm/cpu/mmu_64.c
> +++ b/arch/arm/cpu/mmu_64.c
> @@ -344,17 +344,7 @@ void __mmu_init(bool mmu_on)
>  
>  void mmu_disable(void)
>  {
> -	unsigned int cr;
> -
> -	cr = get_cr();
> -	cr &= ~(CR_M | CR_C);
> -
> -	set_cr(cr);
> -	v8_flush_dcache_all();
> -	tlb_invalidate();
> -
> -	dsb();
> -	isb();
> +	v8_mmu_disable();
>  }
>  
>  void dma_inv_range(void *ptr, size_t size)
> @@ -436,18 +426,3 @@ void mmu_early_enable(unsigned long membase, unsigned long memsize, unsigned lon
>  
>  	mmu_enable();
>  }
> -
> -void mmu_early_disable(void)
> -{
> -	unsigned int cr;
> -
> -	cr = get_cr();
> -	cr &= ~(CR_M | CR_C);
> -
> -	set_cr(cr);
> -	v8_flush_dcache_all();
> -	tlb_invalidate();
> -
> -	dsb();
> -	isb();
> -}
> diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
> index dd022c1f23f2..ea78ae123aec 100644
> --- a/arch/arm/include/asm/cache.h
> +++ b/arch/arm/include/asm/cache.h
> @@ -15,6 +15,7 @@ void v8_flush_dcache_all(void);
>  void v8_invalidate_dcache_all(void);
>  void v8_flush_dcache_range(unsigned long start, unsigned long end);
>  void v8_inv_dcache_range(unsigned long start, unsigned long end);
> +void v8_mmu_disable(void);
>  
>  static inline void icache_invalidate(void)
>  {
> diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
> index eef6c53b5912..1fafbf9d77be 100644
> --- a/arch/arm/include/asm/mmu.h
> +++ b/arch/arm/include/asm/mmu.h
> @@ -65,6 +65,5 @@ void __dma_flush_range(unsigned long, unsigned long);
>  void __dma_inv_range(unsigned long, unsigned long);
>  
>  void mmu_early_enable(unsigned long membase, unsigned long memsize, unsigned long barebox_base);
> -void mmu_early_disable(void);
>  
>  #endif /* __ASM_MMU_H */
> -- 
> 2.47.3
> 
> 
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



      reply	other threads:[~2025-12-15  8:25 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-12 11:10 [PATCH v2] ARM64: mmu: implement mmu_disable completely in assembly Ahmad Fatoum
2025-12-15  8:25 ` Sascha Hauer [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aT_F6JDPpyh__VjG@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=a.fatoum@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.