Commit 26973fa5ac0e ("powerpc/mm: use pte helpers in generic code")
changed those two functions to use pte helpers to determine which
bits to clear and which bits to set.
This change was based on the assumption that bits to be set/cleared
are always the same and can be determined by applying the pte
manipulation helpers on __pte(0).
But on platforms like book3e, the bits depend on whether the page
is a user page or not.
For the time being it more or less works because of _PAGE_EXEC being
used for user pages only and exec right being set at all time on
kernel page. But following patch will clean that and output of
pte_mkexec() will depend on the page being a user or kernel page.
Instead of trying to make an even more complicated helper where bits
would become dependent on the final pte value, come back to a more
static situation like before commit 26973fa5ac0e ("powerpc/mm: use
pte helpers in generic code"), by introducing an 8xx specific
version of __ptep_set_access_flags() and ptep_set_wrprotect().
Fixes: 26973fa5ac0e ("powerpc/mm: use pte helpers in generic code")
Signed-off-by: Christophe Leroy <redacted>
---
v3: No change
v2: New
---
arch/powerpc/include/asm/nohash/32/pgtable.h | 17 +++++++--------
arch/powerpc/include/asm/nohash/32/pte-8xx.h | 22 ++++++++++++++++++++
2 files changed, 30 insertions(+), 9 deletions(-)
set_memory_x() calls pte_mkexec() which sets _PAGE_EXEC.
set_memory_nx() calls pte_exprotec() which clears _PAGE_EXEC.
Book3e has 2 bits, UX and SX, which defines the exec rights
resp. for user (PR=1) and for kernel (PR=0).
_PAGE_EXEC is defined as UX only.
An executable kernel page is set with either _PAGE_KERNEL_RWX
or _PAGE_KERNEL_ROX, which both have SX set and UX cleared.
So set_memory_nx() call for an executable kernel page does
nothing because UX is already cleared.
And set_memory_x() on a non-executable kernel page makes it
executable for the user and keeps it non-executable for kernel.
Also, pte_exec() always returns 'false' on kernel pages, because
it checks _PAGE_EXEC which doesn't include SX, so for instance
the W+X check doesn't work.
To fix this:
- change tlb_low_64e.S to use _PAGE_BAP_UX instead of _PAGE_USER
- sets both UX and SX in _PAGE_EXEC so that pte_user() returns
true whenever one of the two bits is set and pte_exprotect()
clears both bits.
- Define a book3e specific version of pte_mkexec() which sets
either SX or UX based on UR.
Fixes: 1f9ad21c3b38 ("powerpc/mm: Implement set_memory() routines")
Signed-off-by: Christophe Leroy <redacted>
---
v3: Removed pte_mkexec() from nohash/64/pgtable.h
v2: New
---
arch/powerpc/include/asm/nohash/32/pgtable.h | 2 ++
arch/powerpc/include/asm/nohash/64/pgtable.h | 5 -----
arch/powerpc/include/asm/nohash/pte-book3e.h | 18 ++++++++++++++----
arch/powerpc/mm/nohash/tlb_low_64e.S | 8 ++++----
4 files changed, 20 insertions(+), 13 deletions(-)
Building tqm8541_defconfig results in:
arch/powerpc/mm/nohash/fsl_book3e.c: In function 'settlbcam':
arch/powerpc/mm/nohash/fsl_book3e.c:126:40: error: '_PAGE_BAP_SX' undeclared (first use in this function)
126 | TLBCAM[index].MAS3 |= (flags & _PAGE_BAP_SX) ? MAS3_SX : 0;
| ^~~~~~~~~~~~
arch/powerpc/mm/nohash/fsl_book3e.c:126:40: note: each undeclared identifier is reported only once for each function it appears in
make[3]: *** [scripts/Makefile.build:277: arch/powerpc/mm/nohash/fsl_book3e.o] Error 1
make[2]: *** [scripts/Makefile.build:540: arch/powerpc/mm/nohash] Error 2
make[1]: *** [scripts/Makefile.build:540: arch/powerpc/mm] Error 2
make: *** [Makefile:1868: arch/powerpc] Error 2
This is because _PAGE_BAP_SX is not defined when using 32 bits PTE.
Now that _PAGE_EXEC contains both _PAGE_BAP_SX and _PAGE_BAP_UX, it can be used instead.
Reported-by: kernel test robot <redacted>
Fixes: 01116e6e98b0 ("powerpc/fsl_booke: Take exec flag into account when setting TLBCAMs")
Signed-off-by: Christophe Leroy <redacted>
---
arch/powerpc/mm/nohash/fsl_book3e.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
From: Nicholas Piggin <npiggin@gmail.com> Date: 2021-10-27 04:23:52
Excerpts from Christophe Leroy's message of October 26, 2021 3:39 pm:
Commit 26973fa5ac0e ("powerpc/mm: use pte helpers in generic code")
changed those two functions to use pte helpers to determine which
bits to clear and which bits to set.
This change was based on the assumption that bits to be set/cleared
are always the same and can be determined by applying the pte
manipulation helpers on __pte(0).
But on platforms like book3e, the bits depend on whether the page
is a user page or not.
For the time being it more or less works because of _PAGE_EXEC being
used for user pages only and exec right being set at all time on
kernel page. But following patch will clean that and output of
pte_mkexec() will depend on the page being a user or kernel page.
Instead of trying to make an even more complicated helper where bits
would become dependent on the final pte value, come back to a more
static situation like before commit 26973fa5ac0e ("powerpc/mm: use
pte helpers in generic code"), by introducing an 8xx specific
version of __ptep_set_access_flags() and ptep_set_wrprotect().
What is this actually fixing? Does it change anything itself, or
just a preparation patch?
Thanks,
Nick
quoted hunk
Fixes: 26973fa5ac0e ("powerpc/mm: use pte helpers in generic code")
Signed-off-by: Christophe Leroy <redacted>
---
v3: No change
v2: New
---
arch/powerpc/include/asm/nohash/32/pgtable.h | 17 +++++++--------
arch/powerpc/include/asm/nohash/32/pte-8xx.h | 22 ++++++++++++++++++++
2 files changed, 30 insertions(+), 9 deletions(-)
Excerpts from Christophe Leroy's message of October 26, 2021 3:39 pm:
quoted
Commit 26973fa5ac0e ("powerpc/mm: use pte helpers in generic code")
changed those two functions to use pte helpers to determine which
bits to clear and which bits to set.
This change was based on the assumption that bits to be set/cleared
are always the same and can be determined by applying the pte
manipulation helpers on __pte(0).
But on platforms like book3e, the bits depend on whether the page
is a user page or not.
For the time being it more or less works because of _PAGE_EXEC being
used for user pages only and exec right being set at all time on
kernel page. But following patch will clean that and output of
pte_mkexec() will depend on the page being a user or kernel page.
Instead of trying to make an even more complicated helper where bits
would become dependent on the final pte value, come back to a more
static situation like before commit 26973fa5ac0e ("powerpc/mm: use
pte helpers in generic code"), by introducing an 8xx specific
version of __ptep_set_access_flags() and ptep_set_wrprotect().
What is this actually fixing? Does it change anything itself, or
just a preparation patch?
Just a preparation patch I think.
I didn't flag it for stable.
Once patch 2 is applied, __ptep_set_access_flags() doesn't work anymore
without this patch, because then pte_mkexec(__pte(0)) sets SX and clears
UX while pte_mkexec(__pte(~0)) sets UX and clears SX
Christophe
Thanks,
Nick
quoted
Fixes: 26973fa5ac0e ("powerpc/mm: use pte helpers in generic code")
Signed-off-by: Christophe Leroy <redacted>
---
v3: No change
v2: New
---
arch/powerpc/include/asm/nohash/32/pgtable.h | 17 +++++++--------
arch/powerpc/include/asm/nohash/32/pte-8xx.h | 22 ++++++++++++++++++++
2 files changed, 30 insertions(+), 9 deletions(-)
From: Nicholas Piggin <npiggin@gmail.com> Date: 2021-10-27 04:44:19
Excerpts from Christophe Leroy's message of October 26, 2021 3:39 pm:
set_memory_x() calls pte_mkexec() which sets _PAGE_EXEC.
set_memory_nx() calls pte_exprotec() which clears _PAGE_EXEC.
Book3e has 2 bits, UX and SX, which defines the exec rights
resp. for user (PR=1) and for kernel (PR=0).
_PAGE_EXEC is defined as UX only.
An executable kernel page is set with either _PAGE_KERNEL_RWX
or _PAGE_KERNEL_ROX, which both have SX set and UX cleared.
So set_memory_nx() call for an executable kernel page does
nothing because UX is already cleared.
And set_memory_x() on a non-executable kernel page makes it
executable for the user and keeps it non-executable for kernel.
Also, pte_exec() always returns 'false' on kernel pages, because
it checks _PAGE_EXEC which doesn't include SX, so for instance
the W+X check doesn't work.
To fix this:
- change tlb_low_64e.S to use _PAGE_BAP_UX instead of _PAGE_USER
- sets both UX and SX in _PAGE_EXEC so that pte_user() returns
true whenever one of the two bits is set
I don't understand this change. Which pte_user() returns true after
this change? Or do you mean pte_exec()?
Does this filter through in some cases at least for kernel executable
PTEs will get both bits set? Seems cleaner to distinguish user and
kernel exec for that but maybe it's a lot of churn?
Thanks,
Nick
and pte_exprotect()
clears both bits.
- Define a book3e specific version of pte_mkexec() which sets
either SX or UX based on UR.
Fixes: 1f9ad21c3b38 ("powerpc/mm: Implement set_memory() routines")
Signed-off-by: Christophe Leroy <redacted>
---
v3: Removed pte_mkexec() from nohash/64/pgtable.h
v2: New
---
Excerpts from Christophe Leroy's message of October 26, 2021 3:39 pm:
quoted
set_memory_x() calls pte_mkexec() which sets _PAGE_EXEC.
set_memory_nx() calls pte_exprotec() which clears _PAGE_EXEC.
Book3e has 2 bits, UX and SX, which defines the exec rights
resp. for user (PR=1) and for kernel (PR=0).
_PAGE_EXEC is defined as UX only.
An executable kernel page is set with either _PAGE_KERNEL_RWX
or _PAGE_KERNEL_ROX, which both have SX set and UX cleared.
So set_memory_nx() call for an executable kernel page does
nothing because UX is already cleared.
And set_memory_x() on a non-executable kernel page makes it
executable for the user and keeps it non-executable for kernel.
Also, pte_exec() always returns 'false' on kernel pages, because
it checks _PAGE_EXEC which doesn't include SX, so for instance
the W+X check doesn't work.
To fix this:
- change tlb_low_64e.S to use _PAGE_BAP_UX instead of _PAGE_USER
- sets both UX and SX in _PAGE_EXEC so that pte_user() returns
true whenever one of the two bits is set
I don't understand this change. Which pte_user() returns true after
this change? Or do you mean pte_exec()?
Oops, yes, I mean pte_exec()
Unless I have to re-spin, can Michael eventually fix that typo while
applying ?
Does this filter through in some cases at least for kernel executable
PTEs will get both bits set? Seems cleaner to distinguish user and
kernel exec for that but maybe it's a lot of churn?
Didn't understand what you mean.
I did it like that to be able to continue using _PAGE_EXEC for checking
executability regardless of whether this is user or kernel, and then
continue using the generic nohash pte_exec() helper.
Other solution would be to get rid of _PAGE_EXEC completely for book3e
and implement both pte_exec() and pte_mkexec() with _PAGE_BAP_UX and
_PAGE_BAP_SX, but I'm not sure it is worth the churn as you say. It
would also mean different helpers for book3s/32 when it is using 32 bits
PTE (CONFIG_PTE_64BIT=n)
Christophe
Thanks,
Nick
quoted
and pte_exprotect()
clears both bits.
- Define a book3e specific version of pte_mkexec() which sets
either SX or UX based on UR.
Fixes: 1f9ad21c3b38 ("powerpc/mm: Implement set_memory() routines")
Signed-off-by: Christophe Leroy <redacted>
---
v3: Removed pte_mkexec() from nohash/64/pgtable.h
v2: New
---
From: Nicholas Piggin <npiggin@gmail.com> Date: 2021-10-27 05:27:30
Excerpts from Christophe Leroy's message of October 27, 2021 2:55 pm:
Le 27/10/2021 à 06:44, Nicholas Piggin a écrit :
quoted
Excerpts from Christophe Leroy's message of October 26, 2021 3:39 pm:
quoted
set_memory_x() calls pte_mkexec() which sets _PAGE_EXEC.
set_memory_nx() calls pte_exprotec() which clears _PAGE_EXEC.
Book3e has 2 bits, UX and SX, which defines the exec rights
resp. for user (PR=1) and for kernel (PR=0).
_PAGE_EXEC is defined as UX only.
An executable kernel page is set with either _PAGE_KERNEL_RWX
or _PAGE_KERNEL_ROX, which both have SX set and UX cleared.
So set_memory_nx() call for an executable kernel page does
nothing because UX is already cleared.
And set_memory_x() on a non-executable kernel page makes it
executable for the user and keeps it non-executable for kernel.
Also, pte_exec() always returns 'false' on kernel pages, because
it checks _PAGE_EXEC which doesn't include SX, so for instance
the W+X check doesn't work.
To fix this:
- change tlb_low_64e.S to use _PAGE_BAP_UX instead of _PAGE_USER
- sets both UX and SX in _PAGE_EXEC so that pte_user() returns
true whenever one of the two bits is set
I don't understand this change. Which pte_user() returns true after
this change? Or do you mean pte_exec()?
Oops, yes, I mean pte_exec()
Unless I have to re-spin, can Michael eventually fix that typo while
applying ?
quoted
Does this filter through in some cases at least for kernel executable
PTEs will get both bits set? Seems cleaner to distinguish user and
kernel exec for that but maybe it's a lot of churn?
Didn't understand what you mean.
I did it like that to be able to continue using _PAGE_EXEC for checking
executability regardless of whether this is user or kernel, and then
continue using the generic nohash pte_exec() helper.
Other solution would be to get rid of _PAGE_EXEC completely for book3e
and implement both pte_exec() and pte_mkexec() with _PAGE_BAP_UX and
_PAGE_BAP_SX, but I'm not sure it is worth the churn as you say. It
would also mean different helpers for book3s/32 when it is using 32 bits
PTE (CONFIG_PTE_64BIT=n)
That's basically what I mean. And _PAGE_KERNEL_ROX etc would then not
set the UX bit. But at least for now it seems to be an improvement.
Thanks,
Nick
Excerpts from Christophe Leroy's message of October 27, 2021 2:55 pm:
quoted
Le 27/10/2021 à 06:44, Nicholas Piggin a écrit :
quoted
Excerpts from Christophe Leroy's message of October 26, 2021 3:39 pm:
quoted
set_memory_x() calls pte_mkexec() which sets _PAGE_EXEC.
set_memory_nx() calls pte_exprotec() which clears _PAGE_EXEC.
Book3e has 2 bits, UX and SX, which defines the exec rights
resp. for user (PR=1) and for kernel (PR=0).
_PAGE_EXEC is defined as UX only.
An executable kernel page is set with either _PAGE_KERNEL_RWX
or _PAGE_KERNEL_ROX, which both have SX set and UX cleared.
So set_memory_nx() call for an executable kernel page does
nothing because UX is already cleared.
And set_memory_x() on a non-executable kernel page makes it
executable for the user and keeps it non-executable for kernel.
Also, pte_exec() always returns 'false' on kernel pages, because
it checks _PAGE_EXEC which doesn't include SX, so for instance
the W+X check doesn't work.
To fix this:
- change tlb_low_64e.S to use _PAGE_BAP_UX instead of _PAGE_USER
- sets both UX and SX in _PAGE_EXEC so that pte_user() returns
true whenever one of the two bits is set
I don't understand this change. Which pte_user() returns true after
this change? Or do you mean pte_exec()?
Oops, yes, I mean pte_exec()
Unless I have to re-spin, can Michael eventually fix that typo while
applying ?
quoted
Does this filter through in some cases at least for kernel executable
PTEs will get both bits set? Seems cleaner to distinguish user and
kernel exec for that but maybe it's a lot of churn?
Didn't understand what you mean.
I did it like that to be able to continue using _PAGE_EXEC for checking
executability regardless of whether this is user or kernel, and then
continue using the generic nohash pte_exec() helper.
Other solution would be to get rid of _PAGE_EXEC completely for book3e
and implement both pte_exec() and pte_mkexec() with _PAGE_BAP_UX and
_PAGE_BAP_SX, but I'm not sure it is worth the churn as you say. It
would also mean different helpers for book3s/32 when it is using 32 bits
PTE (CONFIG_PTE_64BIT=n)
That's basically what I mean. And _PAGE_KERNEL_ROX etc would then not
set the UX bit. But at least for now it seems to be an improvement.
From: Nicholas Piggin <npiggin@gmail.com> Date: 2021-10-27 07:15:38
Excerpts from Christophe Leroy's message of October 27, 2021 3:50 pm:
Le 27/10/2021 à 07:27, Nicholas Piggin a écrit :
quoted
Excerpts from Christophe Leroy's message of October 27, 2021 2:55 pm:
quoted
Le 27/10/2021 à 06:44, Nicholas Piggin a écrit :
quoted
Excerpts from Christophe Leroy's message of October 26, 2021 3:39 pm:
quoted
set_memory_x() calls pte_mkexec() which sets _PAGE_EXEC.
set_memory_nx() calls pte_exprotec() which clears _PAGE_EXEC.
Book3e has 2 bits, UX and SX, which defines the exec rights
resp. for user (PR=1) and for kernel (PR=0).
_PAGE_EXEC is defined as UX only.
An executable kernel page is set with either _PAGE_KERNEL_RWX
or _PAGE_KERNEL_ROX, which both have SX set and UX cleared.
So set_memory_nx() call for an executable kernel page does
nothing because UX is already cleared.
And set_memory_x() on a non-executable kernel page makes it
executable for the user and keeps it non-executable for kernel.
Also, pte_exec() always returns 'false' on kernel pages, because
it checks _PAGE_EXEC which doesn't include SX, so for instance
the W+X check doesn't work.
To fix this:
- change tlb_low_64e.S to use _PAGE_BAP_UX instead of _PAGE_USER
- sets both UX and SX in _PAGE_EXEC so that pte_user() returns
true whenever one of the two bits is set
I don't understand this change. Which pte_user() returns true after
this change? Or do you mean pte_exec()?
Oops, yes, I mean pte_exec()
Unless I have to re-spin, can Michael eventually fix that typo while
applying ?
quoted
Does this filter through in some cases at least for kernel executable
PTEs will get both bits set? Seems cleaner to distinguish user and
kernel exec for that but maybe it's a lot of churn?
Didn't understand what you mean.
I did it like that to be able to continue using _PAGE_EXEC for checking
executability regardless of whether this is user or kernel, and then
continue using the generic nohash pte_exec() helper.
Other solution would be to get rid of _PAGE_EXEC completely for book3e
and implement both pte_exec() and pte_mkexec() with _PAGE_BAP_UX and
_PAGE_BAP_SX, but I'm not sure it is worth the churn as you say. It
would also mean different helpers for book3s/32 when it is using 32 bits
PTE (CONFIG_PTE_64BIT=n)
That's basically what I mean. And _PAGE_KERNEL_ROX etc would then not
set the UX bit. But at least for now it seems to be an improvement.
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2021-10-28 11:33:49
Christophe Leroy [off-list ref] writes:
Le 27/10/2021 à 06:44, Nicholas Piggin a écrit :
quoted
Excerpts from Christophe Leroy's message of October 26, 2021 3:39 pm:
quoted
set_memory_x() calls pte_mkexec() which sets _PAGE_EXEC.
set_memory_nx() calls pte_exprotec() which clears _PAGE_EXEC.
Book3e has 2 bits, UX and SX, which defines the exec rights
resp. for user (PR=1) and for kernel (PR=0).
_PAGE_EXEC is defined as UX only.
An executable kernel page is set with either _PAGE_KERNEL_RWX
or _PAGE_KERNEL_ROX, which both have SX set and UX cleared.
So set_memory_nx() call for an executable kernel page does
nothing because UX is already cleared.
And set_memory_x() on a non-executable kernel page makes it
executable for the user and keeps it non-executable for kernel.
Also, pte_exec() always returns 'false' on kernel pages, because
it checks _PAGE_EXEC which doesn't include SX, so for instance
the W+X check doesn't work.
To fix this:
- change tlb_low_64e.S to use _PAGE_BAP_UX instead of _PAGE_USER
- sets both UX and SX in _PAGE_EXEC so that pte_user() returns
true whenever one of the two bits is set
I don't understand this change. Which pte_user() returns true after
this change? Or do you mean pte_exec()?
Oops, yes, I mean pte_exec()
Unless I have to re-spin, can Michael eventually fix that typo while
applying ?
From: Michael Ellerman <hidden> Date: 2021-11-02 11:38:30
On Tue, 26 Oct 2021 07:39:24 +0200, Christophe Leroy wrote:
Commit 26973fa5ac0e ("powerpc/mm: use pte helpers in generic code")
changed those two functions to use pte helpers to determine which
bits to clear and which bits to set.
This change was based on the assumption that bits to be set/cleared
are always the same and can be determined by applying the pte
manipulation helpers on __pte(0).
[...]