linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT
@ 2010-09-23 20:10 Paul Gortmaker
  2010-09-23 20:33 ` Scott Wood
  0 siblings, 1 reply; 8+ messages in thread
From: Paul Gortmaker @ 2010-09-23 20:10 UTC (permalink / raw)
  To: linuxppc-dev

From: Tiejun Chen <tiejun.chen@windriver.com>

There exists a four line chunk of code, which when configured for
64 bit address space, can incorrectly set certain page flags during
the TLB creation.  It turns out that this is legacy code that is no
longer required, but since it isn't obvious why this is legacy code
or why it causes problems, the below description covers both in detail.

For powerpc bootstrap, the physical memory (at most 768M), is mapped
into the kernel space via the following path:

MMU_init()
    |
    + adjust_total_lowmem()
            |
            + map_mem_in_cams()
                    |
                    + settlbcam(i, virt, phys, cam_sz, PAGE_KERNEL_X, 0);

On settlbcam(), the kernel will create TLB entries according to the flag,
PAGE_KERNEL_X.

settlbcam()
{
        ...
        TLBCAM[index].MAS1 = MAS1_VALID
                        | MAS1_IPROT | MAS1_TSIZE(tsize) | MAS1_TID(pid);
                                ^
			These entries cannot be invalidated by the
			kernel since MAS1_IPROT is set on TLB property.
        ...
        if (flags & _PAGE_USER) {
           TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
           TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
        }

For classic BookE (flags & _PAGE_USER) is 'zero' so it's fine.
But on boards like the the Freescale P4080, we want to support 36-bit
physical address on it. So the following options may be set:

CONFIG_FSL_BOOKE=y
CONFIG_PTE_64BIT=y
CONFIG_PHYS_64BIT=y

As a result, boards like the P4080 will introduce PTE format as Book3E.
As per the file: arch/powerpc/include/asm/pgtable-ppc32.h

  * #elif defined(CONFIG_FSL_BOOKE) && defined(CONFIG_PTE_64BIT)
  * #include <asm/pte-book3e.h>

So PAGE_KERNEL_X is __pgprot(_PAGE_BASE | _PAGE_KERNEL_RWX) and the
book3E version of _PAGE_KERNEL_RWX is defined with:

  (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY | _PAGE_BAP_SX)

Note the _PAGE_BAP_SR, which is also defined in the book3E _PAGE_USER:

  #define _PAGE_USER        (_PAGE_BAP_UR | _PAGE_BAP_SR) /* Can be read */

So the possibility exists to wrongly assign the user MAS3_U<RWX> bits
to kernel (PAGE_KERNEL_X) address space via the following code fragment:

        if (flags & _PAGE_USER) {
           TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
           TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
        }

Here is a dump of the TLB info from Simics with the above code present:
------
L2 TLB1
                                            GT                   SSS UUU V I
 Row  Logical           Physical            SS TLPID  TID  WIMGE XWR XWR F P   V
----- ----------------- ------------------- -- ----- ----- ----- --- --- - -   -
  0   c0000000-cfffffff 000000000-00fffffff 00     0     0   M   XWR XWR 0 1   1
  1   d0000000-dfffffff 010000000-01fffffff 00     0     0   M   XWR XWR 0 1   1
  2   e0000000-efffffff 020000000-02fffffff 00     0     0   M   XWR XWR 0 1   1

Actually this conditional code was only used for two legacy functions:

  1: support KGDB to set break point.
     KGDB already dropped this; now uses its core write to set break point.

  2: io_block_mapping() to create TLB in segmentation size (not PAGE_SIZE)
     for device IO space.
     This use case is also removed from the latest PowerPC kernel.

So it looks like the deletion of these 4 lines of code was simply
overlooked when the above two cases went away.

With the code deleted, the TLB appears without U having XWR as below:

-------
L2 TLB1
                                            GT                   SSS UUU V I
 Row  Logical           Physical            SS TLPID  TID  WIMGE XWR XWR F P   V
----- ----------------- ------------------- -- ----- ----- ----- --- --- - -   -
  0   c0000000-cfffffff 000000000-00fffffff 00     0     0   M   XWR     0 1   1
  1   d0000000-dfffffff 010000000-01fffffff 00     0     0   M   XWR     0 1   1
  2   e0000000-efffffff 020000000-02fffffff 00     0     0   M   XWR     0 1   1

Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 arch/powerpc/mm/fsl_booke_mmu.c |    5 -----
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index d5fa5f2..9de7e1b 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -136,11 +136,6 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
 	if (mmu_has_feature(MMU_FTR_BIG_PHYS))
 		TLBCAM[index].MAS7 = (u64)phys >> 32;
 
-	if (flags & _PAGE_USER) {
-	   TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
-	   TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
-	}
-
 	tlbcam_addrs[index].start = virt;
 	tlbcam_addrs[index].limit = virt + size - 1;
 	tlbcam_addrs[index].phys = phys;
-- 
1.7.2.1

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

* Re: [PATCH] powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT
  2010-09-23 20:10 [PATCH] powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT Paul Gortmaker
@ 2010-09-23 20:33 ` Scott Wood
  2010-09-23 21:59   ` Benjamin Herrenschmidt
  2010-09-24  4:54   ` [PATCH] powerpc: Fix invalid page flags in create TLB CAM pathfor PTE_64BIT Chen, Tiejun
  0 siblings, 2 replies; 8+ messages in thread
From: Scott Wood @ 2010-09-23 20:33 UTC (permalink / raw)
  To: Paul Gortmaker; +Cc: linuxppc-dev

On Thu, 23 Sep 2010 16:10:15 -0400
Paul Gortmaker <paul.gortmaker@windriver.com> wrote:

> So the possibility exists to wrongly assign the user MAS3_U<RWX> bits
> to kernel (PAGE_KERNEL_X) address space via the following code fragment:
> 
>         if (flags & _PAGE_USER) {
>            TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
>            TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
>         }
> 
> Here is a dump of the TLB info from Simics with the above code present:
> ------
> L2 TLB1
>                                             GT                   SSS UUU V I
>  Row  Logical           Physical            SS TLPID  TID  WIMGE XWR XWR F P   V
> ----- ----------------- ------------------- -- ----- ----- ----- --- --- - -   -
>   0   c0000000-cfffffff 000000000-00fffffff 00     0     0   M   XWR XWR 0 1   1
>   1   d0000000-dfffffff 010000000-01fffffff 00     0     0   M   XWR XWR 0 1   1
>   2   e0000000-efffffff 020000000-02fffffff 00     0     0   M   XWR XWR 0 1   1
> 
> Actually this conditional code was only used for two legacy functions:
> 
>   1: support KGDB to set break point.
>      KGDB already dropped this; now uses its core write to set break point.
> 
>   2: io_block_mapping() to create TLB in segmentation size (not PAGE_SIZE)
>      for device IO space.
>      This use case is also removed from the latest PowerPC kernel.

io_block_mapping() went away, but the feature itself is still useful
and might come back with something like this:

http://www.mail-archive.com/linuxppc-dev@lists.ozlabs.org/msg33851.html

...though I'm not sure why such mappings would ever have user access.

This could end up being used for large user pages by something like
hugetlbfs or KVM, though.  I don't think we want to make large user
pages fail, especailly if it just happens with the 32-bit page table
format (which i may not what the person adding such a feature tests
with).

I don't see a generic accessor that can test PTE flags for user
access -- in the absence of one, I guess we need an ifdef here.  Or at
least put in a comment so anyone who adds a userspace use knows they
need to fix it.

-Scott

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

* Re: [PATCH] powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT
  2010-09-23 20:33 ` Scott Wood
@ 2010-09-23 21:59   ` Benjamin Herrenschmidt
  2010-09-24  5:04     ` [PATCH] powerpc: Fix invalid page flags in create TLB CAM pathfor PTE_64BIT Chen, Tiejun
  2010-09-24 16:44     ` [PATCH] powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT Paul Gortmaker
  2010-09-24  4:54   ` [PATCH] powerpc: Fix invalid page flags in create TLB CAM pathfor PTE_64BIT Chen, Tiejun
  1 sibling, 2 replies; 8+ messages in thread
From: Benjamin Herrenschmidt @ 2010-09-23 21:59 UTC (permalink / raw)
  To: Scott Wood; +Cc: Paul Gortmaker, linuxppc-dev

On Thu, 2010-09-23 at 15:33 -0500, Scott Wood wrote:
> I don't see a generic accessor that can test PTE flags for user
> access -- in the absence of one, I guess we need an ifdef here.  Or at
> least put in a comment so anyone who adds a userspace use knows they
> need to fix it. 

We could make up one in powerpc arch at least

#define pte_user(val) ((val & _PAGE_USER) == _PAGE_USER)

would do

Cheers,
Ben.

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

* RE: [PATCH] powerpc: Fix invalid page flags in create TLB CAM pathfor PTE_64BIT
  2010-09-23 20:33 ` Scott Wood
  2010-09-23 21:59   ` Benjamin Herrenschmidt
@ 2010-09-24  4:54   ` Chen, Tiejun
  1 sibling, 0 replies; 8+ messages in thread
From: Chen, Tiejun @ 2010-09-24  4:54 UTC (permalink / raw)
  To: Scott Wood, Gortmaker, Paul; +Cc: linuxppc-dev

> -----Original Message-----
> From:=20
> linuxppc-dev-bounces+tiejun.chen=3Dwindriver.com@lists.ozlabs.or
> g=20
> [mailto:linuxppc-dev-bounces+tiejun.chen=3Dwindriver.com@lists.o
zlabs.org] On Behalf Of Scott Wood
> Sent: Friday, September 24, 2010 4:34 AM
> To: Gortmaker, Paul
> Cc: linuxppc-dev@lists.ozlabs.org
> Subject: Re: [PATCH] powerpc: Fix invalid page flags in=20
> create TLB CAM pathfor PTE_64BIT
>=20
> On Thu, 23 Sep 2010 16:10:15 -0400
> Paul Gortmaker <paul.gortmaker@windriver.com> wrote:
>=20
> > So the possibility exists to wrongly assign the user=20
> MAS3_U<RWX> bits=20
> > to kernel (PAGE_KERNEL_X) address space via the following=20
> code fragment:
> >=20
> >         if (flags & _PAGE_USER) {
> >            TLBCAM[index].MAS3 |=3D MAS3_UX | MAS3_UR;
> >            TLBCAM[index].MAS3 |=3D ((flags & _PAGE_RW) ? MAS3_UW : =
0);
> >         }
> >=20
> > Here is a dump of the TLB info from Simics with the above=20
> code present:
> > ------
> > L2 TLB1
> >                                             GT             =20
>      SSS UUU V I
> >  Row  Logical           Physical            SS TLPID  TID =20
> WIMGE XWR XWR F P   V
> > ----- ----------------- ------------------- -- ----- -----=20
> ----- --- --- - -   -
> >   0   c0000000-cfffffff 000000000-00fffffff 00     0     0 =20
>  M   XWR XWR 0 1   1
> >   1   d0000000-dfffffff 010000000-01fffffff 00     0     0 =20
>  M   XWR XWR 0 1   1
> >   2   e0000000-efffffff 020000000-02fffffff 00     0     0 =20
>  M   XWR XWR 0 1   1
> >=20
> > Actually this conditional code was only used for two legacy=20
> functions:
> >=20
> >   1: support KGDB to set break point.
> >      KGDB already dropped this; now uses its core write to=20
> set break point.
> >=20
> >   2: io_block_mapping() to create TLB in segmentation size=20
> (not PAGE_SIZE)
> >      for device IO space.
> >      This use case is also removed from the latest PowerPC kernel.
>=20
> io_block_mapping() went away, but the feature itself is still=20
> useful and might come back with something like this:
>=20
> http://www.mail-archive.com/linuxppc-dev@lists.ozlabs.org/msg3
3851.html
>=20
> ...though I'm not sure why such mappings would ever have user access.
>=20
> This could end up being used for large user pages by=20
> something like hugetlbfs or KVM, though.  I don't think we=20
> want to make large user pages fail, especailly if it just=20

Understand.=20

Actually the following is my original modification.=20
=3D=3D=3D=3D=3D=3D
+#if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_PTE_64BIT)
+	/* On there _PAGE_BAP_UR is always integrated into flag,
_PAGE_KERNEL_RWX=20
+	 * and _PAGE_USER here. So we have to only check _PAGE_BAP_UR as
the condition.
+ 	 */
+	if (flags & _PAGE_BAP_UR) {
+#else
	if (flags & _PAGE_USER) {
+#endif

But I find there is no any usage for this, except for the above #1> KGDB
and #2 io_block_mapping(). So I think it's possible to remove this
completely :)

> happens with the 32-bit page table format (which i may not=20
> what the person adding such a feature tests with).
>=20
> I don't see a generic accessor that can test PTE flags for=20
> user access -- in the absence of one, I guess we need an=20
> ifdef here.  Or at least put in a comment so anyone who adds=20
> a userspace use knows they need to fix it.

I already notice Ben's advice and looks fine to us.

Tiejun

>=20
> -Scott
>=20
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>=20

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

* RE: [PATCH] powerpc: Fix invalid page flags in create TLB CAM pathfor PTE_64BIT
  2010-09-23 21:59   ` Benjamin Herrenschmidt
@ 2010-09-24  5:04     ` Chen, Tiejun
  2010-09-24 15:02       ` Scott Wood
  2010-09-24 16:44     ` [PATCH] powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT Paul Gortmaker
  1 sibling, 1 reply; 8+ messages in thread
From: Chen, Tiejun @ 2010-09-24  5:04 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Scott Wood; +Cc: Gortmaker, Paul, linuxppc-dev

> -----Original Message-----
> From:=20
> linuxppc-dev-bounces+tiejun.chen=3Dwindriver.com@lists.ozlabs.or
> g=20
> [mailto:linuxppc-dev-bounces+tiejun.chen=3Dwindriver.com@lists.o
> zlabs.org] On Behalf Of Benjamin Herrenschmidt
> Sent: Friday, September 24, 2010 5:59 AM
> To: Scott Wood
> Cc: Gortmaker, Paul; linuxppc-dev@lists.ozlabs.org
> Subject: Re: [PATCH] powerpc: Fix invalid page flags in=20
> create TLB CAM pathfor PTE_64BIT
>=20
> On Thu, 2010-09-23 at 15:33 -0500, Scott Wood wrote:
> > I don't see a generic accessor that can test PTE flags for=20
> user access=20
> > -- in the absence of one, I guess we need an ifdef here. =20
> Or at least=20
> > put in a comment so anyone who adds a userspace use knows=20
> they need to=20
> > fix it.
>=20
> We could make up one in powerpc arch at least
>=20
> #define pte_user(val) ((val & _PAGE_USER) =3D=3D _PAGE_USER)
>=20

Looks good.=20

Ben and Scott,

But for the patched issue we're discussing we have to do #ifdef that as
my original modification. Right? Or do you have other suggestion? Then I
can improve that as v2.

Thanks
Tiejun=20

> would do
>=20
> Cheers,
> Ben.
>=20
>=20
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>=20

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

* Re: [PATCH] powerpc: Fix invalid page flags in create TLB CAM pathfor PTE_64BIT
  2010-09-24  5:04     ` [PATCH] powerpc: Fix invalid page flags in create TLB CAM pathfor PTE_64BIT Chen, Tiejun
@ 2010-09-24 15:02       ` Scott Wood
  0 siblings, 0 replies; 8+ messages in thread
From: Scott Wood @ 2010-09-24 15:02 UTC (permalink / raw)
  To: Chen, Tiejun; +Cc: linuxppc-dev, Gortmaker, Paul

On Fri, 24 Sep 2010 07:04:28 +0200
"Chen, Tiejun" <Tiejun.Chen@windriver.com> wrote:

> > -----Original Message-----
> > From: 
> > linuxppc-dev-bounces+tiejun.chen=windriver.com@lists.ozlabs.or
> > g 
> > [mailto:linuxppc-dev-bounces+tiejun.chen=windriver.com@lists.o
> > zlabs.org] On Behalf Of Benjamin Herrenschmidt
> > Sent: Friday, September 24, 2010 5:59 AM
> > To: Scott Wood
> > Cc: Gortmaker, Paul; linuxppc-dev@lists.ozlabs.org
> > Subject: Re: [PATCH] powerpc: Fix invalid page flags in 
> > create TLB CAM pathfor PTE_64BIT
> > 
> > On Thu, 2010-09-23 at 15:33 -0500, Scott Wood wrote:
> > > I don't see a generic accessor that can test PTE flags for 
> > user access 
> > > -- in the absence of one, I guess we need an ifdef here.  
> > Or at least 
> > > put in a comment so anyone who adds a userspace use knows 
> > they need to 
> > > fix it.
> > 
> > We could make up one in powerpc arch at least
> > 
> > #define pte_user(val) ((val & _PAGE_USER) == _PAGE_USER)
> > 
> 
> Looks good. 
> 
> Ben and Scott,
> 
> But for the patched issue we're discussing we have to do #ifdef that as
> my original modification. Right? Or do you have other suggestion? Then I
> can improve that as v2.

Ben's version should work without any ifdef, since it makes sure
all bits of _PAGE_USER are set.

-Scott

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

* Re: [PATCH] powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT
  2010-09-23 21:59   ` Benjamin Herrenschmidt
  2010-09-24  5:04     ` [PATCH] powerpc: Fix invalid page flags in create TLB CAM pathfor PTE_64BIT Chen, Tiejun
@ 2010-09-24 16:44     ` Paul Gortmaker
  2010-10-07  6:05       ` Kumar Gala
  1 sibling, 1 reply; 8+ messages in thread
From: Paul Gortmaker @ 2010-09-24 16:44 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Scott Wood, linuxppc-dev

[Re: [PATCH] powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT] On 24/09/2010 (Fri 07:59) Benjamin Herrenschmidt wrote:

> On Thu, 2010-09-23 at 15:33 -0500, Scott Wood wrote:
> > I don't see a generic accessor that can test PTE flags for user
> > access -- in the absence of one, I guess we need an ifdef here.  Or at
> > least put in a comment so anyone who adds a userspace use knows they
> > need to fix it. 
> 
> We could make up one in powerpc arch at least
> 
> #define pte_user(val) ((val & _PAGE_USER) == _PAGE_USER)
> 
> would do

I've put the above into pte-common.h, restored the deleted code block
which now uses pte_user() and I've updated the commit header to match.
Passes sanity boot test on an sbc8548 both with and without PTE_64BIT.

Thanks for the feedback.
Paul.


>From d48ebb58b8214f9faec775a5e06902f638f165cf Mon Sep 17 00:00:00 2001
From: Tiejun Chen <tiejun.chen@windriver.com>
Date: Tue, 21 Sep 2010 19:31:31 +0800
Subject: [PATCH] powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT

There exists a four line chunk of code, which when configured for
64 bit address space, can incorrectly set certain page flags during
the TLB creation.  It turns out that this is code which isn't used,
but might still serve a purpose.  Since it isn't obvious why it exists
or why it causes problems, the below description covers both in detail.

For powerpc bootstrap, the physical memory (at most 768M), is mapped
into the kernel space via the following path:

MMU_init()
    |
    + adjust_total_lowmem()
            |
            + map_mem_in_cams()
                    |
                    + settlbcam(i, virt, phys, cam_sz, PAGE_KERNEL_X, 0);

On settlbcam(), the kernel will create TLB entries according to the flag,
PAGE_KERNEL_X.

settlbcam()
{
        ...
        TLBCAM[index].MAS1 = MAS1_VALID
                        | MAS1_IPROT | MAS1_TSIZE(tsize) | MAS1_TID(pid);
                                ^
			These entries cannot be invalidated by the
			kernel since MAS1_IPROT is set on TLB property.
        ...
        if (flags & _PAGE_USER) {
           TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
           TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
        }

For classic BookE (flags & _PAGE_USER) is 'zero' so it's fine.
But on boards like the the Freescale P4080, we want to support 36-bit
physical address on it. So the following options may be set:

CONFIG_FSL_BOOKE=y
CONFIG_PTE_64BIT=y
CONFIG_PHYS_64BIT=y

As a result, boards like the P4080 will introduce PTE format as Book3E.
As per the file: arch/powerpc/include/asm/pgtable-ppc32.h

  * #elif defined(CONFIG_FSL_BOOKE) && defined(CONFIG_PTE_64BIT)
  * #include <asm/pte-book3e.h>

So PAGE_KERNEL_X is __pgprot(_PAGE_BASE | _PAGE_KERNEL_RWX) and the
book3E version of _PAGE_KERNEL_RWX is defined with:

  (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY | _PAGE_BAP_SX)

Note the _PAGE_BAP_SR, which is also defined in the book3E _PAGE_USER:

  #define _PAGE_USER        (_PAGE_BAP_UR | _PAGE_BAP_SR) /* Can be read */

So the possibility exists to wrongly assign the user MAS3_U<RWX> bits
to kernel (PAGE_KERNEL_X) address space via the following code fragment:

        if (flags & _PAGE_USER) {
           TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
           TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
        }

Here is a dump of the TLB info from Simics with the above code present:
------
L2 TLB1
                                            GT                   SSS UUU V I
 Row  Logical           Physical            SS TLPID  TID  WIMGE XWR XWR F P   V
----- ----------------- ------------------- -- ----- ----- ----- --- --- - -   -
  0   c0000000-cfffffff 000000000-00fffffff 00     0     0   M   XWR XWR 0 1   1
  1   d0000000-dfffffff 010000000-01fffffff 00     0     0   M   XWR XWR 0 1   1
  2   e0000000-efffffff 020000000-02fffffff 00     0     0   M   XWR XWR 0 1   1

Actually this conditional code was used for two legacy functions:

  1: support KGDB to set break point.
     KGDB already dropped this; now uses its core write to set break point.

  2: io_block_mapping() to create TLB in segmentation size (not PAGE_SIZE)
     for device IO space.
     This use case is also removed from the latest PowerPC kernel.

However, there may still be a use case for it in the future, like
large user pages, so we can't remove it entirely.  As an alternative,
we match on all bits of _PAGE_USER instead of just any bits, so the
case where just _PAGE_BAP_SR is set can't sneak through.

With this done, the TLB appears without U having XWR as below:

-------
L2 TLB1
                                            GT                   SSS UUU V I
 Row  Logical           Physical            SS TLPID  TID  WIMGE XWR XWR F P   V
----- ----------------- ------------------- -- ----- ----- ----- --- --- - -   -
  0   c0000000-cfffffff 000000000-00fffffff 00     0     0   M   XWR     0 1   1
  1   d0000000-dfffffff 010000000-01fffffff 00     0     0   M   XWR     0 1   1
  2   e0000000-efffffff 020000000-02fffffff 00     0     0   M   XWR     0 1   1

Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 arch/powerpc/include/asm/pte-common.h |    7 +++++++
 arch/powerpc/mm/fsl_booke_mmu.c       |    3 ++-
 2 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/include/asm/pte-common.h b/arch/powerpc/include/asm/pte-common.h
index f2b3701..76bb195 100644
--- a/arch/powerpc/include/asm/pte-common.h
+++ b/arch/powerpc/include/asm/pte-common.h
@@ -171,6 +171,13 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
 /* Make modules code happy. We don't set RO yet */
 #define PAGE_KERNEL_EXEC	PAGE_KERNEL_X
 
+/*
+ * Don't just check for any non zero bits in __PAGE_USER, since for book3e
+ * and PTE_64BIT, PAGE_KERNEL_X contains _PAGE_BAP_SR which is also in
+ * _PAGE_USER.  Need to explictly match _PAGE_BAP_UR bit in that case too.
+ */
+#define pte_user(val)		((val & _PAGE_USER) == _PAGE_USER)
+
 /* Advertise special mapping type for AGP */
 #define PAGE_AGP		(PAGE_KERNEL_NC)
 #define HAVE_PAGE_AGP
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index 4b66a1e..1b4354d 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -137,7 +137,8 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
 	if (mmu_has_feature(MMU_FTR_BIG_PHYS))
 		TLBCAM[index].MAS7 = (u64)phys >> 32;
 
-	if (flags & _PAGE_USER) {
+	/* Below is unlikely -- only for large user pages or similar */
+	if (pte_user(flags)) {
 	   TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
 	   TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
 	}
-- 
1.7.2.1

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

* Re: [PATCH] powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT
  2010-09-24 16:44     ` [PATCH] powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT Paul Gortmaker
@ 2010-10-07  6:05       ` Kumar Gala
  0 siblings, 0 replies; 8+ messages in thread
From: Kumar Gala @ 2010-10-07  6:05 UTC (permalink / raw)
  To: Paul Gortmaker; +Cc: Scott Wood, linuxppc-dev


On Sep 24, 2010, at 11:44 AM, Paul Gortmaker wrote:

>>=20
>> =46rom d48ebb58b8214f9faec775a5e06902f638f165cf Mon Sep 17 00:00:00 =
2001
> From: Tiejun Chen <tiejun.chen@windriver.com>
> Date: Tue, 21 Sep 2010 19:31:31 +0800
> Subject: [PATCH] powerpc: Fix invalid page flags in create TLB CAM =
path for PTE_64BIT
>=20
> There exists a four line chunk of code, which when configured for
> 64 bit address space, can incorrectly set certain page flags during
> the TLB creation.  It turns out that this is code which isn't used,
> but might still serve a purpose.  Since it isn't obvious why it exists
> or why it causes problems, the below description covers both in =
detail.
>=20
> For powerpc bootstrap, the physical memory (at most 768M), is mapped
> into the kernel space via the following path:
>=20
> MMU_init()
>    |
>    + adjust_total_lowmem()
>            |
>            + map_mem_in_cams()
>                    |
>                    + settlbcam(i, virt, phys, cam_sz, PAGE_KERNEL_X, =
0);
>=20
> On settlbcam(), the kernel will create TLB entries according to the =
flag,
> PAGE_KERNEL_X.
>=20
> settlbcam()
> {
>        ...
>        TLBCAM[index].MAS1 =3D MAS1_VALID
>                        | MAS1_IPROT | MAS1_TSIZE(tsize) | =
MAS1_TID(pid);
>                                ^
> 			These entries cannot be invalidated by the
> 			kernel since MAS1_IPROT is set on TLB property.
>        ...
>        if (flags & _PAGE_USER) {
>           TLBCAM[index].MAS3 |=3D MAS3_UX | MAS3_UR;
>           TLBCAM[index].MAS3 |=3D ((flags & _PAGE_RW) ? MAS3_UW : 0);
>        }
>=20
> For classic BookE (flags & _PAGE_USER) is 'zero' so it's fine.
> But on boards like the the Freescale P4080, we want to support 36-bit
> physical address on it. So the following options may be set:
>=20
> CONFIG_FSL_BOOKE=3Dy
> CONFIG_PTE_64BIT=3Dy
> CONFIG_PHYS_64BIT=3Dy
>=20
> As a result, boards like the P4080 will introduce PTE format as =
Book3E.
> As per the file: arch/powerpc/include/asm/pgtable-ppc32.h
>=20
>  * #elif defined(CONFIG_FSL_BOOKE) && defined(CONFIG_PTE_64BIT)
>  * #include <asm/pte-book3e.h>
>=20
> So PAGE_KERNEL_X is __pgprot(_PAGE_BASE | _PAGE_KERNEL_RWX) and the
> book3E version of _PAGE_KERNEL_RWX is defined with:
>=20
>  (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY | _PAGE_BAP_SX)
>=20
> Note the _PAGE_BAP_SR, which is also defined in the book3E _PAGE_USER:
>=20
>  #define _PAGE_USER        (_PAGE_BAP_UR | _PAGE_BAP_SR) /* Can be =
read */
>=20
> So the possibility exists to wrongly assign the user MAS3_U<RWX> bits
> to kernel (PAGE_KERNEL_X) address space via the following code =
fragment:
>=20
>        if (flags & _PAGE_USER) {
>           TLBCAM[index].MAS3 |=3D MAS3_UX | MAS3_UR;
>           TLBCAM[index].MAS3 |=3D ((flags & _PAGE_RW) ? MAS3_UW : 0);
>        }
>=20
> Here is a dump of the TLB info from Simics with the above code =
present:
> ------
> L2 TLB1
>                                            GT                   SSS =
UUU V I
> Row  Logical           Physical            SS TLPID  TID  WIMGE XWR =
XWR F P   V
> ----- ----------------- ------------------- -- ----- ----- ----- --- =
--- - -   -
>  0   c0000000-cfffffff 000000000-00fffffff 00     0     0   M   XWR =
XWR 0 1   1
>  1   d0000000-dfffffff 010000000-01fffffff 00     0     0   M   XWR =
XWR 0 1   1
>  2   e0000000-efffffff 020000000-02fffffff 00     0     0   M   XWR =
XWR 0 1   1
>=20
> Actually this conditional code was used for two legacy functions:
>=20
>  1: support KGDB to set break point.
>     KGDB already dropped this; now uses its core write to set break =
point.
>=20
>  2: io_block_mapping() to create TLB in segmentation size (not =
PAGE_SIZE)
>     for device IO space.
>     This use case is also removed from the latest PowerPC kernel.
>=20
> However, there may still be a use case for it in the future, like
> large user pages, so we can't remove it entirely.  As an alternative,
> we match on all bits of _PAGE_USER instead of just any bits, so the
> case where just _PAGE_BAP_SR is set can't sneak through.
>=20
> With this done, the TLB appears without U having XWR as below:
>=20
> -------
> L2 TLB1
>                                            GT                   SSS =
UUU V I
> Row  Logical           Physical            SS TLPID  TID  WIMGE XWR =
XWR F P   V
> ----- ----------------- ------------------- -- ----- ----- ----- --- =
--- - -   -
>  0   c0000000-cfffffff 000000000-00fffffff 00     0     0   M   XWR    =
 0 1   1
>  1   d0000000-dfffffff 010000000-01fffffff 00     0     0   M   XWR    =
 0 1   1
>  2   e0000000-efffffff 020000000-02fffffff 00     0     0   M   XWR    =
 0 1   1
>=20
> Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
> ---
> arch/powerpc/include/asm/pte-common.h |    7 +++++++
> arch/powerpc/mm/fsl_booke_mmu.c       |    3 ++-
> 2 files changed, 9 insertions(+), 1 deletions(-)

applied to next

- k

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

end of thread, other threads:[~2010-10-07  6:05 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-23 20:10 [PATCH] powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT Paul Gortmaker
2010-09-23 20:33 ` Scott Wood
2010-09-23 21:59   ` Benjamin Herrenschmidt
2010-09-24  5:04     ` [PATCH] powerpc: Fix invalid page flags in create TLB CAM pathfor PTE_64BIT Chen, Tiejun
2010-09-24 15:02       ` Scott Wood
2010-09-24 16:44     ` [PATCH] powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT Paul Gortmaker
2010-10-07  6:05       ` Kumar Gala
2010-09-24  4:54   ` [PATCH] powerpc: Fix invalid page flags in create TLB CAM pathfor PTE_64BIT Chen, Tiejun

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