[PATCH 1/2] powerpc/strict_rwx: quirks for STRICT_RWX patches

Balbir Singh bsingharora at gmail.com
Mon Oct 16 12:01:02 AEDT 2017


On Wed, 04 Oct 2017 20:04:52 +1100
Michael Ellerman <mpe at ellerman.id.au> wrote:

> Hi Balbir,
> 
> Mainly I think we need to add a check in mark_initmem_nx() too don't we?
> Or should we put it somewhere common to both?
> 
> But seeing as I'm replying here are some more comments.
> 
> > Subject: [PATCH 1/2] powerpc/strict_rwx: quirks for STRICT_RWX patches  
> 
> This misses three key things, 1) it's a bug fix 2) it's for Power9 DD1,
> and 3) it only applies to radix.
> 
> So how about:
> 
> powerpc/64s: Fix crashes on Power9 DD1 with radix MMU and STRICT_RWX
> 
> 
> Balbir Singh <bsingharora at gmail.com> writes:
> > This patch disables STRICT_RWX for power9 DD1 machines
> > where due to some limitations with the way we do tlb
> > updates, we clear the TLB entry of the text that's doing
> > the update to kernel text and that does lead to a
> > crash.  
> 
> This mostly describes the patch, but I would prefer more detail, eg:
> 
>   When using the radix MMU on Power9 DD1, to work around a hardware
>   problem, radix__pte_update() is required to do a two stage update of
>   the PTE. First we write a zero value into the PTE, then we flush the
>   TLB, and then we write the new PTE value.
>   
>   In the normal case that works OK, but it does not work if we're
>   updating the PTE that maps the code we're executing, because the
>   mapping is removed by the TLB flush and we can no longer execute from
>   it. Unfortunately the STRICT_RWX code needs to do exactly that.
>   
>   The exact symptoms when we hit this case vary, sometimes we print an
>   oops and then get stuck after that, but I've also seen a machine just
>   get stuck continually page faulting with no oops printed. The variance
>   is presumably due to the exact layout of the text and the page size
>   used for the mappings. In all cases we are unable to boot to a shell.
>   
>   There are possible solutions such as creating a second mapping of the
>   TLB flush code, executing from that, and then jumping back to the
>   original. However we don't want to add that level of complexity for a
>   DD1 work around.
>   
>   So just detect that we're running on Power9 DD1 and refrain from
>   changing the permissions, effectively disabling STRICT_RWX on Power9
>   DD1.
>

I can copy this verbatim

> 
> > diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c
> > index 39c252b..c2a2b46 100644
> > --- a/arch/powerpc/mm/pgtable-radix.c
> > +++ b/arch/powerpc/mm/pgtable-radix.c
> > @@ -169,6 +169,18 @@ void radix__mark_rodata_ro(void)
> >  {
> >  	unsigned long start, end;
> >  
> > +	/*
> > +	 * mark_rodata_ro() will mark itself as !writable at some point  
>                                                                        ^
>                                                                        .
> > +	 * due to workaround in radix__pte_update(), we'll end up with  
>            ^     ^
>            D     the DD1
> > +	 * an invalid pte and the system will crash quite severly.  
> 
> > +	 * The alternatives are quite cumbersome and leaving out
> > +	 * the page containing the flush code is not very nice.  
> 
> Just drop the last sentence, it doesn't have enough detail to be useful
> and we chose not to implement those alternatives, so better not to
> confuse the reader by talking about them.
> 

Can and will do

> > +	 */
> > +	if (cpu_has_feature(CPU_FTR_POWER9_DD1)) {
> > +		pr_warn("Warning: Unable to mark rodata read only on P9 DD1\n");
> > +		return;
> > +	}  
> 
> Don't we also need to do the check in radix__mark_initmem_nx() ?

No.. not for NX, since we mark NX pages (.data and .init.text..init.end)
from .text. We don't change permissions for anything in .text in that
routine.

> 
> cheers



More information about the Linuxppc-dev mailing list