linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 1/2] powerpc: Add a proper syscall for switching endianness
@ 2015-03-10  7:36 Michael Ellerman
  2015-03-10  7:36 ` [RFC PATCH 2/2] selftests/powerpc: Add a test of the switch_endian() syscall Michael Ellerman
  2015-03-10  9:34 ` [RFC PATCH 1/2] powerpc: Add a proper syscall for switching endianness Benjamin Herrenschmidt
  0 siblings, 2 replies; 7+ messages in thread
From: Michael Ellerman @ 2015-03-10  7:36 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr

We currently have a "special" syscall for switching endianness. This is
syscall number 0x1ebe, which is handled explicitly in the 64-bit syscall
exception entry.

That has a few problems, firstly the syscall number is outside of the
usual range, which confuses various tools. For example strace doesn't
recognise the syscalls at all.

Secondly it's handled explicitly as a special case in the syscall
exception entry, which is complicated enough without it.

As a first step toward removing the special syscall, we need to add a
regular syscall that implements the same functionality.

The logic is simple, it simply toggles the MSR_LE bit in the userspace
MSR. This is the same as the special syscall, with the caveat that the
special syscall clobbers fewer registers.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/include/asm/systbl.h      | 1 +
 arch/powerpc/include/asm/unistd.h      | 2 +-
 arch/powerpc/include/uapi/asm/unistd.h | 1 +
 arch/powerpc/kernel/syscalls.c         | 7 +++++++
 4 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index 91062eef582f..524bf5dff9f9 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -367,3 +367,4 @@ SYSCALL_SPU(getrandom)
 SYSCALL_SPU(memfd_create)
 SYSCALL_SPU(bpf)
 COMPAT_SYS(execveat)
+SYSCALL(switch_endian)
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index 36b79c31eedd..f4f8b667d75b 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -12,7 +12,7 @@
 #include <uapi/asm/unistd.h>
 
 
-#define __NR_syscalls		363
+#define __NR_syscalls		364
 
 #define __NR__exit __NR_exit
 #define NR_syscalls	__NR_syscalls
diff --git a/arch/powerpc/include/uapi/asm/unistd.h b/arch/powerpc/include/uapi/asm/unistd.h
index ef5b5b1f3123..e4aa173dae62 100644
--- a/arch/powerpc/include/uapi/asm/unistd.h
+++ b/arch/powerpc/include/uapi/asm/unistd.h
@@ -385,5 +385,6 @@
 #define __NR_memfd_create	360
 #define __NR_bpf		361
 #define __NR_execveat		362
+#define __NR_switch_endian	363
 
 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
index b2702e87db0d..0ea01957990e 100644
--- a/arch/powerpc/kernel/syscalls.c
+++ b/arch/powerpc/kernel/syscalls.c
@@ -121,3 +121,10 @@ long ppc_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low,
 	return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low,
 			     (u64)len_high << 32 | len_low, advice);
 }
+
+long sys_switch_endian(void)
+{
+	current->thread.regs->msr ^= MSR_LE;
+
+	return 0;
+}
-- 
2.1.0

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

* [RFC PATCH 2/2] selftests/powerpc: Add a test of the switch_endian() syscall
  2015-03-10  7:36 [RFC PATCH 1/2] powerpc: Add a proper syscall for switching endianness Michael Ellerman
@ 2015-03-10  7:36 ` Michael Ellerman
  2015-03-10  9:34 ` [RFC PATCH 1/2] powerpc: Add a proper syscall for switching endianness Benjamin Herrenschmidt
  1 sibling, 0 replies; 7+ messages in thread
From: Michael Ellerman @ 2015-03-10  7:36 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeremy Kerr

This adds a test of the switch_endian() syscall we added in the previous
commit.

We test it by calling the endian switch syscall, and then executing some
code in the other endian which writes to stdout and then does exit(0).

If the endian switch failed to happen that code sequence will be illegal
and cause the test to abort.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 tools/testing/selftests/powerpc/Makefile           |  2 +-
 tools/testing/selftests/powerpc/syscalls/Makefile  | 15 ++++++++
 .../selftests/powerpc/syscalls/endian-test.S       | 43 ++++++++++++++++++++++
 3 files changed, 59 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/powerpc/syscalls/Makefile
 create mode 100644 tools/testing/selftests/powerpc/syscalls/endian-test.S

diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
index 1d5e7ad2c460..5da93b7d1330 100644
--- a/tools/testing/selftests/powerpc/Makefile
+++ b/tools/testing/selftests/powerpc/Makefile
@@ -13,7 +13,7 @@ CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CUR
 
 export CC CFLAGS
 
-TARGETS = pmu copyloops mm tm primitives stringloops
+TARGETS = pmu copyloops mm tm primitives stringloops syscalls
 
 endif
 
diff --git a/tools/testing/selftests/powerpc/syscalls/Makefile b/tools/testing/selftests/powerpc/syscalls/Makefile
new file mode 100644
index 000000000000..b74201fa4f15
--- /dev/null
+++ b/tools/testing/selftests/powerpc/syscalls/Makefile
@@ -0,0 +1,15 @@
+PROGS := endian-test
+
+endian-test: ASFLAGS += -O2 -Wall -g -nostdlib -m64
+
+all: $(PROGS)
+
+run_tests: all
+	@-for PROG in $(PROGS); do \
+		./$$PROG; \
+	done;
+
+clean:
+	rm -f $(PROGS)
+
+.PHONY: all run_tests clean
diff --git a/tools/testing/selftests/powerpc/syscalls/endian-test.S b/tools/testing/selftests/powerpc/syscalls/endian-test.S
new file mode 100644
index 000000000000..ba596eb9925f
--- /dev/null
+++ b/tools/testing/selftests/powerpc/syscalls/endian-test.S
@@ -0,0 +1,43 @@
+#include <ppc-asm.h>
+#include <asm/unistd.h>
+
+	.data
+	.balign 8
+message:
+	.ascii "success: endian-test\n"
+
+	.text
+FUNC_START(_start)
+	ld r14, message@got(%r2)
+
+	/* Call the syscall to flip endian */
+	li r0, 363
+	sc
+
+	/*
+	 * The longs below encode the following code snippet, in the other
+	 * endian. We preloaded the address of message into r14 in case it
+	 * moves.
+	 *
+	 *	li r0, __NR_write
+	 *	li r3, 1	# stdout
+	 *      mr r4, r14	# Get &message
+	 *	li r5, 21	# strlen(message)
+	 *	sc
+	 *	li r0, __NR_exit
+	 *	li r3, 0	# exit(0)
+	 *	sc
+	 *	b .
+	 *
+	 * In both cases, if the endian has not been flipped the processor will
+	 * see an illegal instruction and the process will exit abnormally.
+	 */
+	.long 0x04000038
+	.long 0x01006038
+	.long 0x7873c47d
+	.long 0x1500a038
+	.long 0x02000044
+	.long 0x01000038
+	.long 0x00006038
+	.long 0x02000044
+	.long 0x00000048
-- 
2.1.0

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

* Re: [RFC PATCH 1/2] powerpc: Add a proper syscall for switching endianness
  2015-03-10  7:36 [RFC PATCH 1/2] powerpc: Add a proper syscall for switching endianness Michael Ellerman
  2015-03-10  7:36 ` [RFC PATCH 2/2] selftests/powerpc: Add a test of the switch_endian() syscall Michael Ellerman
@ 2015-03-10  9:34 ` Benjamin Herrenschmidt
  2015-03-10 10:55   ` Michael Ellerman
  1 sibling, 1 reply; 7+ messages in thread
From: Benjamin Herrenschmidt @ 2015-03-10  9:34 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, Jeremy Kerr

On Tue, 2015-03-10 at 18:36 +1100, Michael Ellerman wrote:
> We currently have a "special" syscall for switching endianness. This is
> syscall number 0x1ebe, which is handled explicitly in the 64-bit syscall
> exception entry.
> 
> That has a few problems, firstly the syscall number is outside of the
> usual range, which confuses various tools. For example strace doesn't
> recognise the syscalls at all.
> 
> Secondly it's handled explicitly as a special case in the syscall
> exception entry, which is complicated enough without it.
> 
> As a first step toward removing the special syscall, we need to add a
> regular syscall that implements the same functionality.
> 
> The logic is simple, it simply toggles the MSR_LE bit in the userspace
> MSR. This is the same as the special syscall, with the caveat that the
> special syscall clobbers fewer registers.

You can set _TIF_RESTOREALL to force a restore of all the registers on
the way back which should do the job.

Cheers,
Ben.

> 
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> ---
>  arch/powerpc/include/asm/systbl.h      | 1 +
>  arch/powerpc/include/asm/unistd.h      | 2 +-
>  arch/powerpc/include/uapi/asm/unistd.h | 1 +
>  arch/powerpc/kernel/syscalls.c         | 7 +++++++
>  4 files changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
> index 91062eef582f..524bf5dff9f9 100644
> --- a/arch/powerpc/include/asm/systbl.h
> +++ b/arch/powerpc/include/asm/systbl.h
> @@ -367,3 +367,4 @@ SYSCALL_SPU(getrandom)
>  SYSCALL_SPU(memfd_create)
>  SYSCALL_SPU(bpf)
>  COMPAT_SYS(execveat)
> +SYSCALL(switch_endian)
> diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
> index 36b79c31eedd..f4f8b667d75b 100644
> --- a/arch/powerpc/include/asm/unistd.h
> +++ b/arch/powerpc/include/asm/unistd.h
> @@ -12,7 +12,7 @@
>  #include <uapi/asm/unistd.h>
>  
> 
> -#define __NR_syscalls		363
> +#define __NR_syscalls		364
>  
>  #define __NR__exit __NR_exit
>  #define NR_syscalls	__NR_syscalls
> diff --git a/arch/powerpc/include/uapi/asm/unistd.h b/arch/powerpc/include/uapi/asm/unistd.h
> index ef5b5b1f3123..e4aa173dae62 100644
> --- a/arch/powerpc/include/uapi/asm/unistd.h
> +++ b/arch/powerpc/include/uapi/asm/unistd.h
> @@ -385,5 +385,6 @@
>  #define __NR_memfd_create	360
>  #define __NR_bpf		361
>  #define __NR_execveat		362
> +#define __NR_switch_endian	363
>  
>  #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
> diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
> index b2702e87db0d..0ea01957990e 100644
> --- a/arch/powerpc/kernel/syscalls.c
> +++ b/arch/powerpc/kernel/syscalls.c
> @@ -121,3 +121,10 @@ long ppc_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low,
>  	return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low,
>  			     (u64)len_high << 32 | len_low, advice);
>  }
> +
> +long sys_switch_endian(void)
> +{
> +	current->thread.regs->msr ^= MSR_LE;
> +
> +	return 0;
> +}

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

* Re: [RFC PATCH 1/2] powerpc: Add a proper syscall for switching endianness
  2015-03-10  9:34 ` [RFC PATCH 1/2] powerpc: Add a proper syscall for switching endianness Benjamin Herrenschmidt
@ 2015-03-10 10:55   ` Michael Ellerman
  2015-03-11  5:38     ` Anshuman Khandual
  0 siblings, 1 reply; 7+ messages in thread
From: Michael Ellerman @ 2015-03-10 10:55 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Jeremy Kerr

On Tue, 2015-03-10 at 20:34 +1100, Benjamin Herrenschmidt wrote:
> On Tue, 2015-03-10 at 18:36 +1100, Michael Ellerman wrote:
> > We currently have a "special" syscall for switching endianness. This is
> > syscall number 0x1ebe, which is handled explicitly in the 64-bit syscall
> > exception entry.
> > 
> > That has a few problems, firstly the syscall number is outside of the
> > usual range, which confuses various tools. For example strace doesn't
> > recognise the syscalls at all.
> > 
> > Secondly it's handled explicitly as a special case in the syscall
> > exception entry, which is complicated enough without it.
> > 
> > As a first step toward removing the special syscall, we need to add a
> > regular syscall that implements the same functionality.
> > 
> > The logic is simple, it simply toggles the MSR_LE bit in the userspace
> > MSR. This is the same as the special syscall, with the caveat that the
> > special syscall clobbers fewer registers.
> 
> You can set _TIF_RESTOREALL to force a restore of all the registers on
> the way back which should do the job.

Right, I'd forgotten we talked about that.

I'll try that tomorrow.

cheers

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

* Re: [RFC PATCH 1/2] powerpc: Add a proper syscall for switching endianness
  2015-03-10 10:55   ` Michael Ellerman
@ 2015-03-11  5:38     ` Anshuman Khandual
  2015-03-11  5:43       ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 7+ messages in thread
From: Anshuman Khandual @ 2015-03-11  5:38 UTC (permalink / raw)
  To: Michael Ellerman, Benjamin Herrenschmidt; +Cc: linuxppc-dev, Jeremy Kerr

On 03/10/2015 04:25 PM, Michael Ellerman wrote:
> On Tue, 2015-03-10 at 20:34 +1100, Benjamin Herrenschmidt wrote:
>> On Tue, 2015-03-10 at 18:36 +1100, Michael Ellerman wrote:
>>> We currently have a "special" syscall for switching endianness. This is
>>> syscall number 0x1ebe, which is handled explicitly in the 64-bit syscall
>>> exception entry.
>>>
>>> That has a few problems, firstly the syscall number is outside of the
>>> usual range, which confuses various tools. For example strace doesn't
>>> recognise the syscalls at all.
>>>
>>> Secondly it's handled explicitly as a special case in the syscall
>>> exception entry, which is complicated enough without it.
>>>
>>> As a first step toward removing the special syscall, we need to add a
>>> regular syscall that implements the same functionality.
>>>
>>> The logic is simple, it simply toggles the MSR_LE bit in the userspace
>>> MSR. This is the same as the special syscall, with the caveat that the
>>> special syscall clobbers fewer registers.
>>
>> You can set _TIF_RESTOREALL to force a restore of all the registers on
>> the way back which should do the job.
> 
> Right, I'd forgotten we talked about that.
> 
> I'll try that tomorrow.

The test fails when we add set_thread_flag(TIF_RESTOREALL) after the MSR flip.
Though the test passes with the original patch.

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

* Re: [RFC PATCH 1/2] powerpc: Add a proper syscall for switching endianness
  2015-03-11  5:38     ` Anshuman Khandual
@ 2015-03-11  5:43       ` Benjamin Herrenschmidt
  2015-03-11  6:32         ` Anshuman Khandual
  0 siblings, 1 reply; 7+ messages in thread
From: Benjamin Herrenschmidt @ 2015-03-11  5:43 UTC (permalink / raw)
  To: Anshuman Khandual; +Cc: Jeremy Kerr, linuxppc-dev

On Wed, 2015-03-11 at 11:08 +0530, Anshuman Khandual wrote:
> On 03/10/2015 04:25 PM, Michael Ellerman wrote:
> > On Tue, 2015-03-10 at 20:34 +1100, Benjamin Herrenschmidt wrote:
> >> On Tue, 2015-03-10 at 18:36 +1100, Michael Ellerman wrote:
> >>> We currently have a "special" syscall for switching endianness. This is
> >>> syscall number 0x1ebe, which is handled explicitly in the 64-bit syscall
> >>> exception entry.
> >>>
> >>> That has a few problems, firstly the syscall number is outside of the
> >>> usual range, which confuses various tools. For example strace doesn't
> >>> recognise the syscalls at all.
> >>>
> >>> Secondly it's handled explicitly as a special case in the syscall
> >>> exception entry, which is complicated enough without it.
> >>>
> >>> As a first step toward removing the special syscall, we need to add a
> >>> regular syscall that implements the same functionality.
> >>>
> >>> The logic is simple, it simply toggles the MSR_LE bit in the userspace
> >>> MSR. This is the same as the special syscall, with the caveat that the
> >>> special syscall clobbers fewer registers.
> >>
> >> You can set _TIF_RESTOREALL to force a restore of all the registers on
> >> the way back which should do the job.
> > 
> > Right, I'd forgotten we talked about that.
> > 
> > I'll try that tomorrow.
> 
> The test fails when we add set_thread_flag(TIF_RESTOREALL) after the MSR flip.
> Though the test passes with the original patch.

We also need to wrap the syscall like we do for fork() etc... to
save_nvgpr's.

Cheers,
Ben.

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

* Re: [RFC PATCH 1/2] powerpc: Add a proper syscall for switching endianness
  2015-03-11  5:43       ` Benjamin Herrenschmidt
@ 2015-03-11  6:32         ` Anshuman Khandual
  0 siblings, 0 replies; 7+ messages in thread
From: Anshuman Khandual @ 2015-03-11  6:32 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Jeremy Kerr

On 03/11/2015 11:13 AM, Benjamin Herrenschmidt wrote:
> On Wed, 2015-03-11 at 11:08 +0530, Anshuman Khandual wrote:
>> On 03/10/2015 04:25 PM, Michael Ellerman wrote:
>>> On Tue, 2015-03-10 at 20:34 +1100, Benjamin Herrenschmidt wrote:
>>>> On Tue, 2015-03-10 at 18:36 +1100, Michael Ellerman wrote:
>>>>> We currently have a "special" syscall for switching endianness. This is
>>>>> syscall number 0x1ebe, which is handled explicitly in the 64-bit syscall
>>>>> exception entry.
>>>>>
>>>>> That has a few problems, firstly the syscall number is outside of the
>>>>> usual range, which confuses various tools. For example strace doesn't
>>>>> recognise the syscalls at all.
>>>>>
>>>>> Secondly it's handled explicitly as a special case in the syscall
>>>>> exception entry, which is complicated enough without it.
>>>>>
>>>>> As a first step toward removing the special syscall, we need to add a
>>>>> regular syscall that implements the same functionality.
>>>>>
>>>>> The logic is simple, it simply toggles the MSR_LE bit in the userspace
>>>>> MSR. This is the same as the special syscall, with the caveat that the
>>>>> special syscall clobbers fewer registers.
>>>>
>>>> You can set _TIF_RESTOREALL to force a restore of all the registers on
>>>> the way back which should do the job.
>>>
>>> Right, I'd forgotten we talked about that.
>>>
>>> I'll try that tomorrow.
>>
>> The test fails when we add set_thread_flag(TIF_RESTOREALL) after the MSR flip.
>> Though the test passes with the original patch.
> 
> We also need to wrap the syscall like we do for fork() etc... to
> save_nvgpr's.

Yeah right, replacing SYSCALL(switch_endian) with PPC_SYS(switch_endian)
in systbl.h does the trick and the test passes again.

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

end of thread, other threads:[~2015-03-11  6:32 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-10  7:36 [RFC PATCH 1/2] powerpc: Add a proper syscall for switching endianness Michael Ellerman
2015-03-10  7:36 ` [RFC PATCH 2/2] selftests/powerpc: Add a test of the switch_endian() syscall Michael Ellerman
2015-03-10  9:34 ` [RFC PATCH 1/2] powerpc: Add a proper syscall for switching endianness Benjamin Herrenschmidt
2015-03-10 10:55   ` Michael Ellerman
2015-03-11  5:38     ` Anshuman Khandual
2015-03-11  5:43       ` Benjamin Herrenschmidt
2015-03-11  6:32         ` Anshuman Khandual

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