linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] powerpc/strict_rwx: quirks for STRICT_RWX patches
@ 2017-09-27  9:51 Balbir Singh
  2017-09-27  9:51 ` [PATCH 2/2] powerpc/strict_rwx: fixup region splitting Balbir Singh
  2017-10-04  9:04 ` [PATCH 1/2] powerpc/strict_rwx: quirks for STRICT_RWX patches Michael Ellerman
  0 siblings, 2 replies; 6+ messages in thread
From: Balbir Singh @ 2017-09-27  9:51 UTC (permalink / raw)
  To: mpe; +Cc: linuxppc-dev, Balbir Singh

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.

Fixes: 7614ff3 ("powerpc/mm/radix: Implement STRICT_RWX/mark_rodata_ro() for Radix")

Cc: stable@vger.kernel.org

Reported-by: Andrew Jeffery <andrew@aj.id.au>
Signed-off-by: Balbir Singh <bsingharora@gmail.com>
---
 arch/powerpc/mm/pgtable-radix.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

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
+	 * 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.
+	 */
+	if (cpu_has_feature(CPU_FTR_POWER9_DD1)) {
+		pr_warn("Warning: Unable to mark rodata read only on P9 DD1\n");
+		return;
+	}
+
 	start = (unsigned long)_stext;
 	end = (unsigned long)__init_begin;
 
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/2] powerpc/strict_rwx: fixup region splitting
  2017-09-27  9:51 [PATCH 1/2] powerpc/strict_rwx: quirks for STRICT_RWX patches Balbir Singh
@ 2017-09-27  9:51 ` Balbir Singh
  2017-10-04 11:14   ` Michael Ellerman
  2017-10-04  9:04 ` [PATCH 1/2] powerpc/strict_rwx: quirks for STRICT_RWX patches Michael Ellerman
  1 sibling, 1 reply; 6+ messages in thread
From: Balbir Singh @ 2017-09-27  9:51 UTC (permalink / raw)
  To: mpe; +Cc: linuxppc-dev, Balbir Singh

We were aggressive with splitting regions and missed the case
when _stext and __init_begin completely overlap addr and addr+mapping.

This patch fixes that case and allows us to keep the largest possible
mapping through the overlap. The patch also simplies the check
into a function

Fixes: 7614ff3 ("powerpc/mm/radix: Implement STRICT_RWX/mark_rodata_ro() for Radix")

Signed-off-by: Balbir Singh <bsingharora@gmail.com>
---
 arch/powerpc/mm/pgtable-radix.c | 39 ++++++++++++++++++++++++++++-----------
 1 file changed, 28 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c
index c2a2b46..ea0da3b 100644
--- a/arch/powerpc/mm/pgtable-radix.c
+++ b/arch/powerpc/mm/pgtable-radix.c
@@ -210,17 +210,36 @@ static inline void __meminit print_mapping(unsigned long start,
 	pr_info("Mapped 0x%016lx-0x%016lx with %s pages\n", start, end, buf);
 }
 
+static inline int __meminit
+should_split_mapping_size(unsigned long addr, unsigned long mapping_size)
+{
+#ifdef CONFIG_STRICT_KERNEL_RWX
+	/*
+	 * If addr, addr+mapping overlap the text region and
+	 * _stext and __init_begin end up lying between
+	 * addr, addr+mapping split the mapping size down
+	 * further
+	 */
+	if ((addr < __pa_symbol(__init_begin)) &&
+		(addr + mapping_size) > __pa_symbol(_stext)) {
+
+		if (((addr + mapping_size) <= __pa_symbol(__init_begin)) &&
+			(addr >= __pa_symbol(_stext)))
+			return 0;
+
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+
 static int __meminit create_physical_mapping(unsigned long start,
 					     unsigned long end)
 {
 	unsigned long vaddr, addr, mapping_size = 0;
 	pgprot_t prot;
 	unsigned long max_mapping_size;
-#ifdef CONFIG_STRICT_KERNEL_RWX
-	int split_text_mapping = 1;
-#else
-	int split_text_mapping = 0;
-#endif
 
 	start = _ALIGN_UP(start, PAGE_SIZE);
 	for (addr = start; addr < end; addr += mapping_size) {
@@ -242,16 +261,14 @@ static int __meminit create_physical_mapping(unsigned long start,
 		else
 			mapping_size = PAGE_SIZE;
 
-		if (split_text_mapping && (mapping_size == PUD_SIZE) &&
-			(addr <= __pa_symbol(__init_begin)) &&
-			(addr + mapping_size) >= __pa_symbol(_stext)) {
+		if ((mapping_size == PUD_SIZE) &&
+			should_split_mapping_size(addr, mapping_size)) {
 			max_mapping_size = PMD_SIZE;
 			goto retry;
 		}
 
-		if (split_text_mapping && (mapping_size == PMD_SIZE) &&
-		    (addr <= __pa_symbol(__init_begin)) &&
-		    (addr + mapping_size) >= __pa_symbol(_stext))
+		if ((mapping_size == PMD_SIZE) &&
+			should_split_mapping_size(addr, mapping_size))
 			mapping_size = PAGE_SIZE;
 
 		if (mapping_size != previous_size) {
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] powerpc/strict_rwx: quirks for STRICT_RWX patches
  2017-09-27  9:51 [PATCH 1/2] powerpc/strict_rwx: quirks for STRICT_RWX patches Balbir Singh
  2017-09-27  9:51 ` [PATCH 2/2] powerpc/strict_rwx: fixup region splitting Balbir Singh
@ 2017-10-04  9:04 ` Michael Ellerman
  2017-10-16  1:01   ` Balbir Singh
  1 sibling, 1 reply; 6+ messages in thread
From: Michael Ellerman @ 2017-10-04  9:04 UTC (permalink / raw)
  To: Balbir Singh; +Cc: linuxppc-dev, Balbir Singh

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@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.


> 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.

> +	 */
> +	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() ?

cheers

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/2] powerpc/strict_rwx: fixup region splitting
  2017-09-27  9:51 ` [PATCH 2/2] powerpc/strict_rwx: fixup region splitting Balbir Singh
@ 2017-10-04 11:14   ` Michael Ellerman
  2017-10-16  1:03     ` Balbir Singh
  0 siblings, 1 reply; 6+ messages in thread
From: Michael Ellerman @ 2017-10-04 11:14 UTC (permalink / raw)
  To: Balbir Singh; +Cc: linuxppc-dev, Balbir Singh

Balbir Singh <bsingharora@gmail.com> writes:

> We were aggressive with splitting regions and missed the case
> when _stext and __init_begin completely overlap addr and addr+mapping.
>
> This patch fixes that case and allows us to keep the largest possible
> mapping through the overlap. The patch also simplies the check
> into a function

Please do the fix in one patch, which we can backport if necessary, and
then move it into a function in a separate patch.

cheers

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] powerpc/strict_rwx: quirks for STRICT_RWX patches
  2017-10-04  9:04 ` [PATCH 1/2] powerpc/strict_rwx: quirks for STRICT_RWX patches Michael Ellerman
@ 2017-10-16  1:01   ` Balbir Singh
  0 siblings, 0 replies; 6+ messages in thread
From: Balbir Singh @ 2017-10-16  1:01 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev

On Wed, 04 Oct 2017 20:04:52 +1100
Michael Ellerman <mpe@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@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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/2] powerpc/strict_rwx: fixup region splitting
  2017-10-04 11:14   ` Michael Ellerman
@ 2017-10-16  1:03     ` Balbir Singh
  0 siblings, 0 replies; 6+ messages in thread
From: Balbir Singh @ 2017-10-16  1:03 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev

On Wed, 04 Oct 2017 22:14:17 +1100
Michael Ellerman <mpe@ellerman.id.au> wrote:

> Balbir Singh <bsingharora@gmail.com> writes:
> 
> > We were aggressive with splitting regions and missed the case
> > when _stext and __init_begin completely overlap addr and addr+mapping.
> >
> > This patch fixes that case and allows us to keep the largest possible
> > mapping through the overlap. The patch also simplies the check
> > into a function  
> 
> Please do the fix in one patch, which we can backport if necessary, and
> then move it into a function in a separate patch.
> 

I've tried for a while now, although this looks like its touching more
code, this is more elegant. Anything else involves changing the two
if conditions almost identically.

Balbir Singh.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-10-16  1:03 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-09-27  9:51 [PATCH 1/2] powerpc/strict_rwx: quirks for STRICT_RWX patches Balbir Singh
2017-09-27  9:51 ` [PATCH 2/2] powerpc/strict_rwx: fixup region splitting Balbir Singh
2017-10-04 11:14   ` Michael Ellerman
2017-10-16  1:03     ` Balbir Singh
2017-10-04  9:04 ` [PATCH 1/2] powerpc/strict_rwx: quirks for STRICT_RWX patches Michael Ellerman
2017-10-16  1:01   ` Balbir Singh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).