From: Benjamin Gray <hidden> Date: 2024-03-15 02:58:52
patch_instructions() introduces new behaviour with a couple of
variations. Test each case of
* a repeated 32-bit instruction,
* a repeated 64-bit instruction (ppc64), and
* a copied sequence of instructions
for both on a single page and when it crosses a page boundary.
Signed-off-by: Benjamin Gray <redacted>
---
arch/powerpc/lib/test-code-patching.c | 92 +++++++++++++++++++++++++++
1 file changed, 92 insertions(+)
From: Benjamin Gray <hidden> Date: 2024-03-15 02:59:33
The patching page set up as a writable alias may be in quadrant 1
(userspace) if the temporary mm path is used. This causes sanitiser
failures if so. Sanitiser failures also occur on the non-mm path
because the plain memset family is instrumented, and KASAN treats the
patching window as poisoned.
Introduce locally defined patch_* variants of memset that perform an
uninstrumented lower level set, as well as detecting write errors like
the original single patch variant does.
copy_to_user() is not correct here, as the PTE makes it a proper kernel
page (the EEA is privileged access only, RW). It just happens to be in
quadrant 1 because that's the hardware's mechanism for using the current
PID vs PID 0 in translations. Importantly, it's incorrect to allow user
page accesses.
Now that the patching memsets are used, we also propagate a failure up
to the caller as the single patch variant does.
Signed-off-by: Benjamin Gray <redacted>
---
The patch_memcpy() can be optimised to 4 bytes at a time assuming the
same requirements as regular instruction patching are being followed
for the 'copy sequence of instructions' mode (i.e., they actually are
instructions following instruction alignment rules).
---
arch/powerpc/lib/code-patching.c | 42 +++++++++++++++++++++++++++++---
1 file changed, 38 insertions(+), 4 deletions(-)
From: Benjamin Gray <hidden> Date: 2024-03-15 03:00:14
As we are patching instructions, we can assume the length is a multiple
of 4 and the destination address is aligned.
Atomicity of patching a prefixed instruction is not a concern, as the
original implementation doesn't provide it anyway.
Signed-off-by: Benjamin Gray <redacted>
---
arch/powerpc/lib/code-patching.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
The patching page set up as a writable alias may be in quadrant 1
(userspace) if the temporary mm path is used. This causes sanitiser
failures if so. Sanitiser failures also occur on the non-mm path
because the plain memset family is instrumented, and KASAN treats the
patching window as poisoned.
Introduce locally defined patch_* variants of memset that perform an
uninstrumented lower level set, as well as detecting write errors like
the original single patch variant does.
copy_to_user() is not correct here, as the PTE makes it a proper kernel
page (the EEA is privileged access only, RW). It just happens to be in
quadrant 1 because that's the hardware's mechanism for using the current
PID vs PID 0 in translations. Importantly, it's incorrect to allow user
page accesses.
Now that the patching memsets are used, we also propagate a failure up
to the caller as the single patch variant does.
Signed-off-by: Benjamin Gray <redacted>
---
The patch_memcpy() can be optimised to 4 bytes at a time assuming the
same requirements as regular instruction patching are being followed
for the 'copy sequence of instructions' mode (i.e., they actually are
instructions following instruction alignment rules).
As we are patching instructions, we can assume the length is a multiple
of 4 and the destination address is aligned.
Atomicity of patching a prefixed instruction is not a concern, as the
original implementation doesn't provide it anyway.
This patch looks unnecessary.
copy_to_kernel_nofault() is what you want to use instead.
patch_instructions() introduces new behaviour with a couple of
variations. Test each case of
* a repeated 32-bit instruction,
* a repeated 64-bit instruction (ppc64), and
* a copied sequence of instructions
for both on a single page and when it crosses a page boundary.
Signed-off-by: Benjamin Gray <redacted>
---
arch/powerpc/lib/test-code-patching.c | 92 +++++++++++++++++++++++++++
1 file changed, 92 insertions(+)
Build failure:
CC arch/powerpc/lib/test-code-patching.o
arch/powerpc/lib/test-code-patching.c: In function
'test_multi_instruction_patching':
arch/powerpc/lib/test-code-patching.c:439:1: error: the frame size of
1040 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
439 | }
| ^
cc1: all warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243:
arch/powerpc/lib/test-code-patching.o] Error 1
I have to avoid big arrays on the stack.
From: Benjamin Gray <hidden> Date: 2024-03-17 21:39:50
On Fri, 2024-03-15 at 07:14 +0000, Christophe Leroy wrote:
Le 15/03/2024 à 03:57, Benjamin Gray a écrit :
quoted
patch_instructions() introduces new behaviour with a couple of
variations. Test each case of
* a repeated 32-bit instruction,
* a repeated 64-bit instruction (ppc64), and
* a copied sequence of instructions
for both on a single page and when it crosses a page boundary.
Signed-off-by: Benjamin Gray <redacted>
---
arch/powerpc/lib/test-code-patching.c | 92
+++++++++++++++++++++++++++
1 file changed, 92 insertions(+)
Build failure:
CC arch/powerpc/lib/test-code-patching.o
arch/powerpc/lib/test-code-patching.c: In function
'test_multi_instruction_patching':
arch/powerpc/lib/test-code-patching.c:439:1: error: the frame size of
1040 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
439 | }
| ^
cc1: all warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243:
arch/powerpc/lib/test-code-patching.o] Error 1
I have to avoid big arrays on the stack.
All good, I can do that.
I do run my patches through a couple of 32-bit configs, but I didn't
see this error. Is this a standard config I should be testing with?
From: Benjamin Gray <hidden> Date: 2024-03-17 21:43:41
On Fri, 2024-03-15 at 06:36 +0000, Christophe Leroy wrote:
Le 15/03/2024 à 03:57, Benjamin Gray a écrit :
quoted
The patching page set up as a writable alias may be in quadrant 1
(userspace) if the temporary mm path is used. This causes sanitiser
failures if so. Sanitiser failures also occur on the non-mm path
because the plain memset family is instrumented, and KASAN treats
the
patching window as poisoned.
Introduce locally defined patch_* variants of memset that perform
an
uninstrumented lower level set, as well as detecting write errors
like
the original single patch variant does.
copy_to_user() is not correct here, as the PTE makes it a proper
kernel
page (the EEA is privileged access only, RW). It just happens to be
in
quadrant 1 because that's the hardware's mechanism for using the
current
PID vs PID 0 in translations. Importantly, it's incorrect to allow
user
page accesses.
Now that the patching memsets are used, we also propagate a failure
up
to the caller as the single patch variant does.
Signed-off-by: Benjamin Gray <redacted>
---
The patch_memcpy() can be optimised to 4 bytes at a time assuming
the
same requirements as regular instruction patching are being
followed
for the 'copy sequence of instructions' mode (i.e., they actually
are
instructions following instruction alignment rules).
Why not use copy_to_kernel_nofault() ?
I had not come across copy_to_kernel_nofault(). It looks like the
optimised memcpy() I wanted, so thanks.
The single instruction patch returns EPERM, which was set this way to
align with ftrace's expectations. I think it's best to keep the
single/multi patching variants consistent with each other where
possible.
From: Benjamin Gray <hidden> Date: 2024-03-17 21:45:50
On Fri, 2024-03-15 at 06:39 +0000, Christophe Leroy wrote:
Le 15/03/2024 à 03:57, Benjamin Gray a écrit :
quoted
As we are patching instructions, we can assume the length is a
multiple
of 4 and the destination address is aligned.
Atomicity of patching a prefixed instruction is not a concern, as
the
original implementation doesn't provide it anyway.
This patch looks unnecessary.
copy_to_kernel_nofault() is what you want to use instead.
Yeah, I would drop this patch when using copy_to_kernel_nofault()
From: Benjamin Gray <hidden> Date: 2024-03-17 22:24:33
On Mon, 2024-03-18 at 08:38 +1100, Benjamin Gray wrote:
On Fri, 2024-03-15 at 07:14 +0000, Christophe Leroy wrote:
quoted
Le 15/03/2024 à 03:57, Benjamin Gray a écrit :
quoted
patch_instructions() introduces new behaviour with a couple of
variations. Test each case of
* a repeated 32-bit instruction,
* a repeated 64-bit instruction (ppc64), and
* a copied sequence of instructions
for both on a single page and when it crosses a page boundary.
Signed-off-by: Benjamin Gray <redacted>
---
arch/powerpc/lib/test-code-patching.c | 92
+++++++++++++++++++++++++++
1 file changed, 92 insertions(+)
Build failure:
CC arch/powerpc/lib/test-code-patching.o
arch/powerpc/lib/test-code-patching.c: In function
'test_multi_instruction_patching':
arch/powerpc/lib/test-code-patching.c:439:1: error: the frame size
of
1040 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
439 | }
| ^
cc1: all warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243:
arch/powerpc/lib/test-code-patching.o] Error 1
I have to avoid big arrays on the stack.
All good, I can do that.
I do run my patches through a couple of 32-bit configs, but I didn't
see this error. Is this a standard config I should be testing with?
Specifically pmac32_defconfig and ppc44x_defconfig
From: Benjamin Gray <hidden> Date: 2024-03-17 22:25:40
mjW5LaBPOdGiiDE1w95Ri9HRK27S2dRZpyib9L4mkfYWPAF41mTudjKmVpgtBLO//rO+zmF04OMB/4sWJhLfvhq1CXULDqw5dcuIAIYwf2ughOtyAPFK1ViDcMO5X1bVpNAFO5m4VBpZvFDQ0j0JfqfVBdL68uH05W1/8dMj76RaWj5m0rLM5slY1FQUPddSU+ic9vaZhlDepjU3ZyI8fmioofNGHaxJq6uNTytKdj87kwDV6PQ4hmuGtY56C7JCgjp053sRJ6sXqgKBWfe4ZOJH17mQm+fws93byLoZvvz4Z3im0Rb0MlFo/WirNyhu+TmTNLpnzFUZfenoKrqAkZLY8u1iCFquhgqA321P+sfYew66DtwQmaoi2GKmF89y2enXXzjLNKfLDKkuVoKxFSPeizYqrLi22R9iO8EGBYKACAWIQQ9K5v9I+L06Hi4yOJ5xrdpFsvehAUCYzuwkQIbAgCBCRB5xrdpFsvehHYgBBkRCAAdFiEESFUlaLYscsf4Dt5gaavCcpI6D/8FAmM7sJEACgkQaavCcpI6D/95UgEAqfSj0QhCrYfazQiLDKJstrz3oIKFjhB6+FYMZqt+K1MA/2ioFtHbypeeWbsqYYRhRyTjAKcvE1NZGtH/YWLgkViUidoBAN6gFX/P+VWB77/w8S/BnPmnJx45wmphlkCL8ckOyopFAQCj9eWamHCl2DSaASMSuoZed6C6Gm0OFtuZh/r8K485BQ==
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Date: Mon, 18 Mar 2024 08:55:02 +1100
MIME-Version: 1.0
User-Agent: Evolution 3.50.4 (3.50.4-1.fc39)
X-Trend-IP-HD: ip=[9.192.253.14]helo={ozlabs.au.ibm.com}sender=(bgray@linux.ibm.com)recipient=<christophe.leroy@csgroup.eu;mpe@ellerman.id.au;linuxppc-dev@lists.ozlabs.org>
On Mon, 2024-03-18 at 08:38 +1100, Benjamin Gray wrote:
On Fri, 2024-03-15 at 07:14 +0000, Christophe Leroy wrote:
quoted
=20
=20
Le 15/03/2024 =C3=A0 03:57, Benjamin Gray a =C3=A9crit=C2=A0:
quoted
patch_instructions() introduces new behaviour with a couple of
variations. Test each case of
=20
=C2=A0=C2=A0 * a repeated 32-bit instruction,
=C2=A0=C2=A0 * a repeated 64-bit instruction (ppc64), and
=C2=A0=C2=A0 * a copied sequence of instructions
=20
for both on a single page and when it crosses a page boundary.
=20
Signed-off-by: Benjamin Gray <redacted>
---
=C2=A0 arch/powerpc/lib/test-code-patching.c | 92
+++++++++++++++++++++++++++
=C2=A0 1 file changed, 92 insertions(+)
=20
arch/powerpc/lib/test-code-patching.c: In function=20
'test_multi_instruction_patching':
arch/powerpc/lib/test-code-patching.c:439:1: error: the frame size
of
1040 bytes is larger than 1024 bytes [-Werror=3Dframe-larger-than=3D]
=C2=A0=C2=A0 439 | }
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | ^
cc1: all warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243:=20
arch/powerpc/lib/test-code-patching.o] Error 1
=20
=20
I have to avoid big arrays on the stack.
=20
All good, I can do that.
=20
I do run my patches through a couple of 32-bit configs, but I didn't
see this error. Is this a standard config I should be testing with?
=20
Specifically I build pmac32_defconfig and ppc44x_defconfig
Build failure:
CC arch/powerpc/lib/test-code-patching.o
arch/powerpc/lib/test-code-patching.c: In function
'test_multi_instruction_patching':
arch/powerpc/lib/test-code-patching.c:439:1: error: the frame size
of
1040 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
439 | }
| ^
cc1: all warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243:
arch/powerpc/lib/test-code-patching.o] Error 1
I have to avoid big arrays on the stack.
All good, I can do that.
I do run my patches through a couple of 32-bit configs, but I didn't
see this error. Is this a standard config I should be testing with?
Specifically pmac32_defconfig and ppc44x_defconfig
Both of those have CONFIG_FRAME_WARN=1024, so should have caught this.
But neither have CONFIG_CODE_PATCHING_SELFTEST=y, so I suspect that's
why you didn't see it.
I recommend ppc32_allmodconfig.
cheers