* [PATCH v3 1/2] powerpc: Add a proper syscall for switching endianness
@ 2015-03-16 6:57 Michael Ellerman
2015-03-16 6:57 ` [PATCH v3 2/2] selftests/powerpc: Add a test of the switch_endian() syscall Michael Ellerman
0 siblings, 1 reply; 11+ messages in thread
From: Michael Ellerman @ 2015-03-16 6:57 UTC (permalink / raw)
To: linuxppc-dev; +Cc: linuxram, Jeremy Kerr, khandual
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 syscall 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.
This version clobbers r9-r12, XER, CTR, and CR0-1,5-7.
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
v3: Don't provide the syscall on 32-bit.
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/entry_64.S | 5 +++++
arch/powerpc/kernel/syscalls.c | 17 +++++++++++++++++
arch/powerpc/kernel/systbl.S | 2 ++
arch/powerpc/kernel/systbl_chk.c | 2 ++
arch/powerpc/platforms/cell/spu_callbacks.c | 1 +
8 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index 91062eef582f..f1863a138b4a 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)
+PPC64ONLY(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/entry_64.S b/arch/powerpc/kernel/entry_64.S
index d180caf2d6de..afbc20019c2e 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -356,6 +356,11 @@ _GLOBAL(ppc64_swapcontext)
bl sys_swapcontext
b .Lsyscall_exit
+_GLOBAL(ppc_switch_endian)
+ bl save_nvgprs
+ bl sys_switch_endian
+ b .Lsyscall_exit
+
_GLOBAL(ret_from_fork)
bl schedule_tail
REST_NVGPRS(r1)
diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
index b2702e87db0d..5fa92706444b 100644
--- a/arch/powerpc/kernel/syscalls.c
+++ b/arch/powerpc/kernel/syscalls.c
@@ -121,3 +121,20 @@ 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)
+{
+ struct thread_info *ti;
+
+ current->thread.regs->msr ^= MSR_LE;
+
+ /*
+ * Set TIF_RESTOREALL so that r3 isn't clobbered on return to
+ * userspace. That also has the effect of restoring the non-volatile
+ * GPRs, so we saved them on the way in here.
+ */
+ ti = current_thread_info();
+ ti->flags |= _TIF_RESTOREALL;
+
+ return 0;
+}
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S
index 7ab5d434e2ee..4d6b1d3a747f 100644
--- a/arch/powerpc/kernel/systbl.S
+++ b/arch/powerpc/kernel/systbl.S
@@ -22,6 +22,7 @@
#define PPC_SYS(func) .llong DOTSYM(ppc_##func),DOTSYM(ppc_##func)
#define OLDSYS(func) .llong DOTSYM(sys_ni_syscall),DOTSYM(sys_ni_syscall)
#define SYS32ONLY(func) .llong DOTSYM(sys_ni_syscall),DOTSYM(compat_sys_##func)
+#define PPC64ONLY(func) .llong DOTSYM(ppc_##func),DOTSYM(sys_ni_syscall)
#define SYSX(f, f3264, f32) .llong DOTSYM(f),DOTSYM(f3264)
#else
#define SYSCALL(func) .long sys_##func
@@ -29,6 +30,7 @@
#define PPC_SYS(func) .long ppc_##func
#define OLDSYS(func) .long sys_##func
#define SYS32ONLY(func) .long sys_##func
+#define PPC64ONLY(func) .long sys_ni_syscall
#define SYSX(f, f3264, f32) .long f32
#endif
#define SYSCALL_SPU(func) SYSCALL(func)
diff --git a/arch/powerpc/kernel/systbl_chk.c b/arch/powerpc/kernel/systbl_chk.c
index 238aa63ced8f..2384129f5893 100644
--- a/arch/powerpc/kernel/systbl_chk.c
+++ b/arch/powerpc/kernel/systbl_chk.c
@@ -21,9 +21,11 @@
#ifdef CONFIG_PPC64
#define OLDSYS(func) -1
#define SYS32ONLY(func) -1
+#define PPC64ONLY(func) __NR_##func
#else
#define OLDSYS(func) __NR_old##func
#define SYS32ONLY(func) __NR_##func
+#define PPC64ONLY(func) -1
#endif
#define SYSX(f, f3264, f32) -1
diff --git a/arch/powerpc/platforms/cell/spu_callbacks.c b/arch/powerpc/platforms/cell/spu_callbacks.c
index b0ec78e8ad68..a494028b2cdf 100644
--- a/arch/powerpc/platforms/cell/spu_callbacks.c
+++ b/arch/powerpc/platforms/cell/spu_callbacks.c
@@ -39,6 +39,7 @@ static void *spu_syscall_table[] = {
#define PPC_SYS(func) sys_ni_syscall,
#define OLDSYS(func) sys_ni_syscall,
#define SYS32ONLY(func) sys_ni_syscall,
+#define PPC64ONLY(func) sys_ni_syscall,
#define SYSX(f, f3264, f32) sys_ni_syscall,
#define SYSCALL_SPU(func) sys_##func,
--
2.1.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v3 2/2] selftests/powerpc: Add a test of the switch_endian() syscall
2015-03-16 6:57 [PATCH v3 1/2] powerpc: Add a proper syscall for switching endianness Michael Ellerman
@ 2015-03-16 6:57 ` Michael Ellerman
2015-03-16 11:00 ` Anshuman Khandual
0 siblings, 1 reply; 11+ messages in thread
From: Michael Ellerman @ 2015-03-16 6:57 UTC (permalink / raw)
To: linuxppc-dev; +Cc: linuxram, Jeremy Kerr, khandual
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 to check everything went as expected. That code
checks registers we expect to be maintained are, and then writes to
stdout. If the endian switch failed to happen that code sequence will be
illegal and cause the test to abort.
We then switch back to the original endian, do the same checks and
finally write a success message and exit(0).
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
v3: Have the test switch back to the original endian.
tools/testing/selftests/powerpc/Makefile | 2 +-
.../selftests/powerpc/switch_endian/Makefile | 23 +++++
.../selftests/powerpc/switch_endian/check.S | 101 +++++++++++++++++++++
.../selftests/powerpc/switch_endian/common.h | 6 ++
.../powerpc/switch_endian/switch_endian_test.S | 92 +++++++++++++++++++
5 files changed, 223 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/switch_endian/Makefile
create mode 100644 tools/testing/selftests/powerpc/switch_endian/check.S
create mode 100644 tools/testing/selftests/powerpc/switch_endian/common.h
create mode 100644 tools/testing/selftests/powerpc/switch_endian/switch_endian_test.S
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
index 1d5e7ad2c460..85c24a2210b5 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 switch_endian
endif
diff --git a/tools/testing/selftests/powerpc/switch_endian/Makefile b/tools/testing/selftests/powerpc/switch_endian/Makefile
new file mode 100644
index 000000000000..c7fefbf880b5
--- /dev/null
+++ b/tools/testing/selftests/powerpc/switch_endian/Makefile
@@ -0,0 +1,23 @@
+PROGS := switch_endian_test
+
+ASFLAGS += -O2 -Wall -g -nostdlib -m64
+
+all: $(PROGS)
+
+switch_endian_test: check-reversed.S
+
+check-reversed.o: check.o
+ objcopy -j .text --reverse-bytes=4 -O binary $< $@
+
+check-reversed.S: check-reversed.o
+ hexdump -v -e '/1 ".byte 0x%02X\n"' $< > $@
+
+run_tests: all
+ @-for PROG in $(PROGS); do \
+ ./$$PROG; \
+ done;
+
+clean:
+ rm -f $(PROGS) *.o check-reversed.S
+
+.PHONY: all run_tests clean
diff --git a/tools/testing/selftests/powerpc/switch_endian/check.S b/tools/testing/selftests/powerpc/switch_endian/check.S
new file mode 100644
index 000000000000..671d20ab9cf9
--- /dev/null
+++ b/tools/testing/selftests/powerpc/switch_endian/check.S
@@ -0,0 +1,101 @@
+#include "common.h"
+
+/*
+ * Checks that registers contain what we expect, ie. they were not clobbered by
+ * the syscall. If that all works we then print a message.
+ *
+ * r14: address of message to print (size is hardcoded at 25 bytes)
+ * r15: pattern to check registers against.
+ *
+ * At the end r3 == 0 if everything's OK.
+ */
+ nop # guaranteed to be illegal in reverse-endian
+ cmpd r15,r3
+ bne 1f
+ addi r3,r15,4
+ cmpd r3,r4
+ bne 1f
+ lis r3,0x00FF
+ ori r3,r3,0xF000
+ mfcr r4
+ and r4,r4,r3
+ cmpw r3,r4
+ addi r3,r15,34
+ bne 1f
+ addi r3,r15,32
+ mflr r4
+ cmpd r3,r4
+ bne 1f
+ addi r3,r15,5
+ cmpd r3,r5
+ bne 1f
+ addi r3,r15,6
+ cmpd r3,r6
+ bne 1f
+ addi r3,r15,7
+ cmpd r3,r7
+ bne 1f
+ addi r3,r15,8
+ cmpd r3,r8
+ bne 1f
+ addi r3,r15,13
+ cmpd r3,r13
+ bne 1f
+ addi r3,r15,16
+ cmpd r3,r16
+ bne 1f
+ addi r3,r15,17
+ cmpd r3,r17
+ bne 1f
+ addi r3,r15,18
+ cmpd r3,r18
+ bne 1f
+ addi r3,r15,19
+ cmpd r3,r19
+ bne 1f
+ addi r3,r15,20
+ cmpd r3,r20
+ bne 1f
+ addi r3,r15,21
+ cmpd r3,r21
+ bne 1f
+ addi r3,r15,22
+ cmpd r3,r22
+ bne 1f
+ addi r3,r15,23
+ cmpd r3,r23
+ bne 1f
+ addi r3,r15,24
+ cmpd r3,r24
+ bne 1f
+ addi r3,r15,25
+ cmpd r3,r25
+ bne 1f
+ addi r3,r15,26
+ cmpd r3,r26
+ bne 1f
+ addi r3,r15,27
+ cmpd r3,r27
+ bne 1f
+ addi r3,r15,28
+ cmpd r3,r28
+ bne 1f
+ addi r3,r15,29
+ cmpd r3,r29
+ bne 1f
+ addi r3,r15,30
+ cmpd r3,r30
+ bne 1f
+ addi r3,r15,31
+ cmpd r3,r31
+ bne 1f
+ li r0,4
+ li r3,1 /* stdout */
+ mr r4,r14
+ li r5,25 /* strlen(message) */
+ sc
+ b 2f
+1: li r0, __NR_exit
+ sc
+2: li r0, __NR_switch_endian
+ nop
diff --git a/tools/testing/selftests/powerpc/switch_endian/common.h b/tools/testing/selftests/powerpc/switch_endian/common.h
new file mode 100644
index 000000000000..69e399698c64
--- /dev/null
+++ b/tools/testing/selftests/powerpc/switch_endian/common.h
@@ -0,0 +1,6 @@
+#include <ppc-asm.h>
+#include <asm/unistd.h>
+
+#ifndef __NR_switch_endian
+#define __NR_switch_endian 363
+#endif
diff --git a/tools/testing/selftests/powerpc/switch_endian/switch_endian_test.S b/tools/testing/selftests/powerpc/switch_endian/switch_endian_test.S
new file mode 100644
index 000000000000..f26475a9f811
--- /dev/null
+++ b/tools/testing/selftests/powerpc/switch_endian/switch_endian_test.S
@@ -0,0 +1,92 @@
+#include "common.h"
+
+ .data
+ .balign 8
+message1:
+ .ascii "Hello wrong-endian world\n\0"
+
+message2:
+ .ascii "Hello right-endian world\n\0"
+
+message3:
+ .ascii "success: switch_endian_test\n\0"
+
+ .section ".toc"
+ .balign 8
+pattern:
+ .llong 0x5555AAAA5555AAAA
+
+ .text
+FUNC_START(_start)
+ /* Load some addresses to start with */
+ ld r14, message1@got(%r2)
+ ld r15, pattern@TOC(%r2)
+
+ /* Setup CR, only CR2-CR4 are maintained */
+ lis r3, 0x00FF
+ ori r3, r3, 0xF000
+ mtcr r3
+
+ /* Load the pattern slightly modified into the registers */
+ mr r3, r15
+ addi r4, r15, 4
+
+ addi r5, r15, 32
+ mtlr r5
+
+ addi r5, r15, 5
+ addi r6, r15, 6
+ addi r7, r15, 7
+ addi r8, r15, 8
+
+ /* r9 - r12 are clobbered */
+
+ addi r13, r15, 13
+
+ /* Skip r14 & r15 we're using them */
+
+ addi r16, r15, 16
+ addi r17, r15, 17
+ addi r18, r15, 18
+ addi r19, r15, 19
+ addi r20, r15, 20
+ addi r21, r15, 21
+ addi r22, r15, 22
+ addi r23, r15, 23
+ addi r24, r15, 24
+ addi r25, r15, 25
+ addi r26, r15, 26
+ addi r27, r15, 27
+ addi r28, r15, 28
+ addi r29, r15, 29
+ addi r30, r15, 30
+ addi r31, r15, 31
+
+ /*
+ * Call the syscall to switch endian.
+ * It clobbers r9-r12, XER, CTR and CR0-1,5-7.
+ */
+ li r0, __NR_switch_endian
+ sc
+
+#include "check-reversed.S"
+
+ /* Flip back, r0 already has the switch syscall number */
+ .long 0x02000044 /* sc */
+
+ ld r14, message2@got(%r2)
+ mr r3, r15
+ addi r4, r15, 4
+ addi r5, r15, 5
+
+#include "check.S"
+
+ li r0, __NR_write
+ li r3, 1 /* stdout */
+ ld r4, message3@got(%r2)
+ li r5, 28 /* strlen(message3) */
+ sc
+ li r0, __NR_exit
+ li r3, 0
+ sc
+ b .
--
2.1.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v3 2/2] selftests/powerpc: Add a test of the switch_endian() syscall
2015-03-16 6:57 ` [PATCH v3 2/2] selftests/powerpc: Add a test of the switch_endian() syscall Michael Ellerman
@ 2015-03-16 11:00 ` Anshuman Khandual
2015-03-16 23:04 ` Michael Ellerman
0 siblings, 1 reply; 11+ messages in thread
From: Anshuman Khandual @ 2015-03-16 11:00 UTC (permalink / raw)
To: Michael Ellerman, linuxppc-dev; +Cc: linuxram, Jeremy Kerr
On 03/16/2015 12:27 PM, Michael Ellerman wrote:
> 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 to check everything went as expected. That code
> checks registers we expect to be maintained are, and then writes to
> stdout. If the endian switch failed to happen that code sequence will be
> illegal and cause the test to abort.
>
> We then switch back to the original endian, do the same checks and
> finally write a success message and exit(0).
>
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Hey Michael,
Did a quick test, passes on LE but seems like failing on BE.
On LE:
Hello wrong-endian world
Hello right-endian world
success: switch_endian_test
on BE:
Hello wrong-endian world (returns 176)
The previous version of the test was passing both on LE
and BE (after applying the compiler trick in the assembly)
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 2/2] selftests/powerpc: Add a test of the switch_endian() syscall
2015-03-16 11:00 ` Anshuman Khandual
@ 2015-03-16 23:04 ` Michael Ellerman
2015-03-17 6:05 ` Anshuman Khandual
0 siblings, 1 reply; 11+ messages in thread
From: Michael Ellerman @ 2015-03-16 23:04 UTC (permalink / raw)
To: Anshuman Khandual; +Cc: linuxppc-dev, linuxram, Jeremy Kerr
On Mon, 2015-03-16 at 16:30 +0530, Anshuman Khandual wrote:
> On 03/16/2015 12:27 PM, Michael Ellerman wrote:
> > 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 to check everything went as expected. That code
> > checks registers we expect to be maintained are, and then writes to
> > stdout. If the endian switch failed to happen that code sequence will be
> > illegal and cause the test to abort.
> >
> > We then switch back to the original endian, do the same checks and
> > finally write a success message and exit(0).
> >
> > Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
>
> Hey Michael,
>
> Did a quick test, passes on LE but seems like failing on BE.
>
> On LE:
>
> Hello wrong-endian world
> Hello right-endian world
> success: switch_endian_test
>
> on BE:
>
> Hello wrong-endian world (returns 176)
>
> The previous version of the test was passing both on LE
> and BE (after applying the compiler trick in the assembly)
Hmm, odd. Works for me:
$ uname -a
Linux bebuntu 4.0.0-rc3-00002-g9dd2601a490a #1 SMP Fri Mar 13 15:52:11 AEDT 2015 ppc64 ppc64 ppc64 GNU/Linux
$ make
cc -O2 -Wall -g -nostdlib -m64 -c -o check.o check.S
objcopy -j .text --reverse-bytes=4 -O binary check.o check-reversed.o
hexdump -v -e '/1 ".byte 0x%02X\n"' check-reversed.o > check-reversed.S
cc -O2 -Wall -g -nostdlib -m64 switch_endian_test.S check-reversed.S -o switch_endian_test
$ ./switch_endian_test
Hello wrong-endian world
Hello right-endian world
success: switch_endian_test
What are you seeing exactly?
cheers
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 2/2] selftests/powerpc: Add a test of the switch_endian() syscall
2015-03-16 23:04 ` Michael Ellerman
@ 2015-03-17 6:05 ` Anshuman Khandual
2015-03-18 5:04 ` Michael Ellerman
0 siblings, 1 reply; 11+ messages in thread
From: Anshuman Khandual @ 2015-03-17 6:05 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, linuxram, Jeremy Kerr
On 03/17/2015 04:34 AM, Michael Ellerman wrote:
> On Mon, 2015-03-16 at 16:30 +0530, Anshuman Khandual wrote:
>> On 03/16/2015 12:27 PM, Michael Ellerman wrote:
>>> 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 to check everything went as expected. That code
>>> checks registers we expect to be maintained are, and then writes to
>>> stdout. If the endian switch failed to happen that code sequence will be
>>> illegal and cause the test to abort.
>>>
>>> We then switch back to the original endian, do the same checks and
>>> finally write a success message and exit(0).
>>>
>>> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
>>
>> Hey Michael,
>>
>> Did a quick test, passes on LE but seems like failing on BE.
>>
>> On LE:
>>
>> Hello wrong-endian world
>> Hello right-endian world
>> success: switch_endian_test
>>
>> on BE:
>>
>> Hello wrong-endian world (returns 176)
>>
>> The previous version of the test was passing both on LE
>> and BE (after applying the compiler trick in the assembly)
>
> Hmm, odd. Works for me:
>
> $ uname -a
> Linux bebuntu 4.0.0-rc3-00002-g9dd2601a490a #1 SMP Fri Mar 13 15:52:11 AEDT 2015 ppc64 ppc64 ppc64 GNU/Linux
> $ make
> cc -O2 -Wall -g -nostdlib -m64 -c -o check.o check.S
> objcopy -j .text --reverse-bytes=4 -O binary check.o check-reversed.o
> hexdump -v -e '/1 ".byte 0x%02X\n"' check-reversed.o > check-reversed.S
> cc -O2 -Wall -g -nostdlib -m64 switch_endian_test.S check-reversed.S -o switch_endian_test
> $ ./switch_endian_test
> Hello wrong-endian world
> Hello right-endian world
> success: switch_endian_test
>
>
> What are you seeing exactly?
I am running on a BE PKVM guest but compiling the test case on
a different BE machine which has newer version of the compiler.
cc (GCC) 4.8.3 20140624
cc -O2 -Wall -g -nostdlib -m64 -c -o check.o check.S
objcopy -j .text --reverse-bytes=4 -O binary check.o check-reversed.o
hexdump -v -e '/1 ".byte 0x%02X\n"' check-reversed.o > check-reversed.S
cc -O2 -Wall -g -nostdlib -m64 switch_endian_test.S check-reversed.S -o switch_endian_test
which looks very similar to the details you have provided above.
Running on guest or host should not make any difference.
BTW, we need to add one .gitignore file to this new test directory.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 2/2] selftests/powerpc: Add a test of the switch_endian() syscall
2015-03-17 6:05 ` Anshuman Khandual
@ 2015-03-18 5:04 ` Michael Ellerman
2015-03-25 5:28 ` Michael Ellerman
0 siblings, 1 reply; 11+ messages in thread
From: Michael Ellerman @ 2015-03-18 5:04 UTC (permalink / raw)
To: Anshuman Khandual; +Cc: linuxppc-dev, linuxram, Jeremy Kerr
On Tue, 2015-03-17 at 11:35 +0530, Anshuman Khandual wrote:
> On 03/17/2015 04:34 AM, Michael Ellerman wrote:
> > What are you seeing exactly?
>
> I am running on a BE PKVM guest but compiling the test case on
> a different BE machine which has newer version of the compiler.
>
> cc (GCC) 4.8.3 20140624
>
> cc -O2 -Wall -g -nostdlib -m64 -c -o check.o check.S
> objcopy -j .text --reverse-bytes=4 -O binary check.o check-reversed.o
> hexdump -v -e '/1 ".byte 0x%02X\n"' check-reversed.o > check-reversed.S
> cc -O2 -Wall -g -nostdlib -m64 switch_endian_test.S check-reversed.S -o switch_endian_test
>
> which looks very similar to the details you have provided above.
> Running on guest or host should not make any difference.
No it shouldn't.
Can you try strace, that should give you the full result code.
Also can you try gdb. You can't breakpoint in the wrong-endian region, but it
looks like you're getting through that anyway.
So try setting a breakpoint at line ~77, and you should be back in BE. Then you
can single step and see where it errors out.
> BTW, we need to add one .gitignore file to this new test directory.
Oh yeah, thanks for the reminder.
cheers
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 2/2] selftests/powerpc: Add a test of the switch_endian() syscall
2015-03-18 5:04 ` Michael Ellerman
@ 2015-03-25 5:28 ` Michael Ellerman
2015-03-25 11:32 ` Anshuman Khandual
0 siblings, 1 reply; 11+ messages in thread
From: Michael Ellerman @ 2015-03-25 5:28 UTC (permalink / raw)
To: Anshuman Khandual; +Cc: linuxppc-dev, linuxram, Jeremy Kerr
On Wed, 2015-03-18 at 16:04 +1100, Michael Ellerman wrote:
> On Tue, 2015-03-17 at 11:35 +0530, Anshuman Khandual wrote:
> > On 03/17/2015 04:34 AM, Michael Ellerman wrote:
> > > What are you seeing exactly?
> >
> > I am running on a BE PKVM guest but compiling the test case on
> > a different BE machine which has newer version of the compiler.
> >
> > cc (GCC) 4.8.3 20140624
> >
> > cc -O2 -Wall -g -nostdlib -m64 -c -o check.o check.S
> > objcopy -j .text --reverse-bytes=4 -O binary check.o check-reversed.o
> > hexdump -v -e '/1 ".byte 0x%02X\n"' check-reversed.o > check-reversed.S
> > cc -O2 -Wall -g -nostdlib -m64 switch_endian_test.S check-reversed.S -o switch_endian_test
> >
> > which looks very similar to the details you have provided above.
> > Running on guest or host should not make any difference.
>
> No it shouldn't.
>
> Can you try strace, that should give you the full result code.
>
> Also can you try gdb. You can't breakpoint in the wrong-endian region, but it
> looks like you're getting through that anyway.
>
> So try setting a breakpoint at line ~77, and you should be back in BE. Then you
> can single step and see where it errors out.
Did you try these?
I want to merge this, and it works for me, but I'd be interested if you can
track down why it's failing for you.
cheers
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 2/2] selftests/powerpc: Add a test of the switch_endian() syscall
2015-03-25 5:28 ` Michael Ellerman
@ 2015-03-25 11:32 ` Anshuman Khandual
2015-03-26 0:36 ` Michael Ellerman
0 siblings, 1 reply; 11+ messages in thread
From: Anshuman Khandual @ 2015-03-25 11:32 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, linuxram, Jeremy Kerr
On 03/25/2015 10:58 AM, Michael Ellerman wrote:
> On Wed, 2015-03-18 at 16:04 +1100, Michael Ellerman wrote:
>> On Tue, 2015-03-17 at 11:35 +0530, Anshuman Khandual wrote:
>>> On 03/17/2015 04:34 AM, Michael Ellerman wrote:
>>>> What are you seeing exactly?
>>>
>>> I am running on a BE PKVM guest but compiling the test case on
>>> a different BE machine which has newer version of the compiler.
>>>
>>> cc (GCC) 4.8.3 20140624
>>>
>>> cc -O2 -Wall -g -nostdlib -m64 -c -o check.o check.S
>>> objcopy -j .text --reverse-bytes=4 -O binary check.o check-reversed.o
>>> hexdump -v -e '/1 ".byte 0x%02X\n"' check-reversed.o > check-reversed.S
>>> cc -O2 -Wall -g -nostdlib -m64 switch_endian_test.S check-reversed.S -o switch_endian_test
>>>
>>> which looks very similar to the details you have provided above.
>>> Running on guest or host should not make any difference.
>>
>> No it shouldn't.
>>
>> Can you try strace, that should give you the full result code.
>>
>> Also can you try gdb. You can't breakpoint in the wrong-endian region, but it
>> looks like you're getting through that anyway.
>>
>> So try setting a breakpoint at line ~77, and you should be back in BE. Then you
>> can single step and see where it errors out.
>
> Did you try these?
Yeah. The test program is showing some strange behavior.
(1) Without strace: It just fails with 176 return code as before
(2) With strace: It works with return code 0 and prints everything !!
strace ./switch_endian_test
execve("./switch_endian_test", ["./switch_endian_test"], [/* 50 vars */]) = 0
SYS_363(0x5555aaaa5555aaaa, 0x5555aaaa5555aaae, 0x5555aaaa5555aaaf,
0x5555aaaa5555aab0, 0x5555aaaa5555aab1) = 6149008514797120170
write(1, "Hello wrong-endian world\n", 25Hello wrong-endian world
) = 25
SYS_363(0x19, 0x10010638, 0x19, 0x5555aaaa5555aab0, 0x5555aaaa5555aab1) = 25
write(1, "Hello right-endian world\n", 25Hello right-endian world
) = 25
write(1, "success: switch_endian_test\n", 28success: switch_endian_test
) = 28
exit(0) = ?
With GDB and breaking at line 77, it exits with a different exit code this time
30 cmpd r3,r5
(gdb)
31 bne 1f
(gdb)
32 addi r3,r15,6
(gdb)
33 cmpd r3,r6
(gdb)
34 bne 1f
(gdb)
98 1: li r0, __NR_exit
(gdb)
99 sc
(gdb)
[Inferior 1 (process 6456) exited with code 0260]
Also (this might sound bit strange), after multiple attempts of GDB, the program
did ran successfully with exit code of 0. Also it ran successfully without GDB
as well. But again after a fresh reboot, the problem was recreated again.
Will look into this further.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 2/2] selftests/powerpc: Add a test of the switch_endian() syscall
2015-03-25 11:32 ` Anshuman Khandual
@ 2015-03-26 0:36 ` Michael Ellerman
2015-03-26 6:24 ` Anshuman Khandual
0 siblings, 1 reply; 11+ messages in thread
From: Michael Ellerman @ 2015-03-26 0:36 UTC (permalink / raw)
To: Anshuman Khandual; +Cc: linuxppc-dev, linuxram, Jeremy Kerr
On Wed, 2015-03-25 at 17:02 +0530, Anshuman Khandual wrote:
> On 03/25/2015 10:58 AM, Michael Ellerman wrote:
> > On Wed, 2015-03-18 at 16:04 +1100, Michael Ellerman wrote:
> >> On Tue, 2015-03-17 at 11:35 +0530, Anshuman Khandual wrote:
> >>> On 03/17/2015 04:34 AM, Michael Ellerman wrote:
> >>>> What are you seeing exactly?
> >>>
> >>> I am running on a BE PKVM guest but compiling the test case on
> >>> a different BE machine which has newer version of the compiler.
> >>>
> >>> cc (GCC) 4.8.3 20140624
> >>>
> >>> cc -O2 -Wall -g -nostdlib -m64 -c -o check.o check.S
> >>> objcopy -j .text --reverse-bytes=4 -O binary check.o check-reversed.o
> >>> hexdump -v -e '/1 ".byte 0x%02X\n"' check-reversed.o > check-reversed.S
> >>> cc -O2 -Wall -g -nostdlib -m64 switch_endian_test.S check-reversed.S -o switch_endian_test
> >>>
> >>> which looks very similar to the details you have provided above.
> >>> Running on guest or host should not make any difference.
> >>
> >> No it shouldn't.
> >>
> >> Can you try strace, that should give you the full result code.
> >>
> >> Also can you try gdb. You can't breakpoint in the wrong-endian region, but it
> >> looks like you're getting through that anyway.
> >>
> >> So try setting a breakpoint at line ~77, and you should be back in BE. Then you
> >> can single step and see where it errors out.
> >
> > Did you try these?
>
> Yeah. The test program is showing some strange behavior.
>
> (1) Without strace: It just fails with 176 return code as before
> (2) With strace: It works with return code 0 and prints everything !!
>
> strace ./switch_endian_test
> execve("./switch_endian_test", ["./switch_endian_test"], [/* 50 vars */]) = 0
> SYS_363(0x5555aaaa5555aaaa, 0x5555aaaa5555aaae, 0x5555aaaa5555aaaf,
> 0x5555aaaa5555aab0, 0x5555aaaa5555aab1) = 6149008514797120170
> write(1, "Hello wrong-endian world\n", 25Hello wrong-endian world
> ) = 25
> SYS_363(0x19, 0x10010638, 0x19, 0x5555aaaa5555aab0, 0x5555aaaa5555aab1) = 25
> write(1, "Hello right-endian world\n", 25Hello right-endian world
> ) = 25
> write(1, "success: switch_endian_test\n", 28success: switch_endian_test
> ) = 28
> exit(0) = ?
>
> With GDB and breaking at line 77, it exits with a different exit code this time
No that's the same code, 176 == 0260 (octal).
> 30 cmpd r3,r5
> (gdb)
> 31 bne 1f
> (gdb)
> 32 addi r3,r15,6
> (gdb)
> 33 cmpd r3,r6
> (gdb)
> 34 bne 1f
> (gdb)
> 98 1: li r0, __NR_exit
> (gdb)
> 99 sc
> (gdb)
> [Inferior 1 (process 6456) exited with code 0260]
And that makes sense, it's bailing because r6 doesn't match. In the setup we do:
addi r6, r15, 6
Where r15 is 0x5555aaaa5555aaaa, so:
0x5555aaaa5555aaaa + 6 = 0x5555aaaa5555aab0
And when we exit the kernel masks the exit code in r3 with 0xff, so:
0x5555aaaa5555aab0 & 0xff = 0xb0 = 176
So for some reason r6 does not contain our pattern.
Can you do an "info registers" and see what's in r6?
cheers
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 2/2] selftests/powerpc: Add a test of the switch_endian() syscall
2015-03-26 0:36 ` Michael Ellerman
@ 2015-03-26 6:24 ` Anshuman Khandual
2015-03-28 2:34 ` Michael Ellerman
0 siblings, 1 reply; 11+ messages in thread
From: Anshuman Khandual @ 2015-03-26 6:24 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, linuxram, Jeremy Kerr
On 03/26/2015 06:06 AM, Michael Ellerman wrote:
> On Wed, 2015-03-25 at 17:02 +0530, Anshuman Khandual wrote:
>> On 03/25/2015 10:58 AM, Michael Ellerman wrote:
>>> On Wed, 2015-03-18 at 16:04 +1100, Michael Ellerman wrote:
>>>> On Tue, 2015-03-17 at 11:35 +0530, Anshuman Khandual wrote:
>>>>> On 03/17/2015 04:34 AM, Michael Ellerman wrote:
>>>>>> What are you seeing exactly?
>>>>>
>>>>> I am running on a BE PKVM guest but compiling the test case on
>>>>> a different BE machine which has newer version of the compiler.
>>>>>
>>>>> cc (GCC) 4.8.3 20140624
>>>>>
>>>>> cc -O2 -Wall -g -nostdlib -m64 -c -o check.o check.S
>>>>> objcopy -j .text --reverse-bytes=4 -O binary check.o check-reversed.o
>>>>> hexdump -v -e '/1 ".byte 0x%02X\n"' check-reversed.o > check-reversed.S
>>>>> cc -O2 -Wall -g -nostdlib -m64 switch_endian_test.S check-reversed.S -o switch_endian_test
>>>>>
>>>>> which looks very similar to the details you have provided above.
>>>>> Running on guest or host should not make any difference.
>>>>
>>>> No it shouldn't.
>>>>
>>>> Can you try strace, that should give you the full result code.
>>>>
>>>> Also can you try gdb. You can't breakpoint in the wrong-endian region, but it
>>>> looks like you're getting through that anyway.
>>>>
>>>> So try setting a breakpoint at line ~77, and you should be back in BE. Then you
>>>> can single step and see where it errors out.
>>>
>>> Did you try these?
>>
>> Yeah. The test program is showing some strange behavior.
>>
>> (1) Without strace: It just fails with 176 return code as before
>> (2) With strace: It works with return code 0 and prints everything !!
>>
>> strace ./switch_endian_test
>> execve("./switch_endian_test", ["./switch_endian_test"], [/* 50 vars */]) = 0
>> SYS_363(0x5555aaaa5555aaaa, 0x5555aaaa5555aaae, 0x5555aaaa5555aaaf,
>> 0x5555aaaa5555aab0, 0x5555aaaa5555aab1) = 6149008514797120170
>> write(1, "Hello wrong-endian world\n", 25Hello wrong-endian world
>> ) = 25
>> SYS_363(0x19, 0x10010638, 0x19, 0x5555aaaa5555aab0, 0x5555aaaa5555aab1) = 25
>> write(1, "Hello right-endian world\n", 25Hello right-endian world
>> ) = 25
>> write(1, "success: switch_endian_test\n", 28success: switch_endian_test
>> ) = 28
>> exit(0) = ?
>>
>> With GDB and breaking at line 77, it exits with a different exit code this time
>
> No that's the same code, 176 == 0260 (octal).
>
>> 30 cmpd r3,r5
>> (gdb)
>> 31 bne 1f
>> (gdb)
>> 32 addi r3,r15,6
>> (gdb)
>> 33 cmpd r3,r6
>> (gdb)
>> 34 bne 1f
>> (gdb)
>> 98 1: li r0, __NR_exit
>> (gdb)
>> 99 sc
>> (gdb)
>> [Inferior 1 (process 6456) exited with code 0260]
>
> And that makes sense, it's bailing because r6 doesn't match. In the setup we do:
>
> addi r6, r15, 6
>
> Where r15 is 0x5555aaaa5555aaaa, so:
>
> 0x5555aaaa5555aaaa + 6 = 0x5555aaaa5555aab0
>
> And when we exit the kernel masks the exit code in r3 with 0xff, so:
>
> 0x5555aaaa5555aab0 & 0xff = 0xb0 = 176
>
>
> So for some reason r6 does not contain our pattern.
>
> Can you do an "info registers" and see what's in r6?
Sure, here are the details.
(gdb)
98 1: li r0, __NR_exit
(gdb)
99 sc
(gdb) info registers
r0 0x1 1
r1 0x3ffffffff360 70368744174432
r2 0x10018670 268535408
r3 0x5555aaaa5555aab0 6149008514797120176
r4 0x5555aaaa5555aaca 6149008514797120202
r5 0x5555aaaa5555aaaf 6149008514797120175
r6 0x4000 16384 <<=========================
r7 0x100002e4 268436196
r8 0x800000010000d033 9223372041149796403
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0x0 0
r13 0x5555aaaa5555aab7 6149008514797120183
r14 0x1001061a 268502554
r15 0x5555aaaa5555aaaa 6149008514797120170
r16 0x5555aaaa5555aaba 6149008514797120186
r17 0x5555aaaa5555aabb 6149008514797120187
r18 0x5555aaaa5555aabc 6149008514797120188
r19 0x5555aaaa5555aabd 6149008514797120189
r20 0x5555aaaa5555aabe 6149008514797120190
r21 0x5555aaaa5555aabf 6149008514797120191
r22 0x5555aaaa5555aac0 6149008514797120192
r23 0x5555aaaa5555aac1 6149008514797120193
r24 0x5555aaaa5555aac2 6149008514797120194
r25 0x5555aaaa5555aac3 6149008514797120195
r26 0x5555aaaa5555aac4 6149008514797120196
r27 0x5555aaaa5555aac5 6149008514797120197
r28 0x5555aaaa5555aac6 6149008514797120198
r29 0x5555aaaa5555aac7 6149008514797120199
r30 0x5555aaaa5555aac8 6149008514797120200
r31 0x5555aaaa5555aac9 6149008514797120201
pc 0x10000468 0x10000468 <._start+856>
msr 0x800000014000d032 9223372042223538226
cr 0x40fff000 1090514944
lr 0x5555aaaa5555aaca 0x5555aaaa5555aaca
ctr 0x0 0
xer 0x0 0
orig_r3 0xc000000000009974 -4611686018427348620
trap 0xd00 3328
(gdb) s
[Inferior 1 (process 8377) exited with code 0260]
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 2/2] selftests/powerpc: Add a test of the switch_endian() syscall
2015-03-26 6:24 ` Anshuman Khandual
@ 2015-03-28 2:34 ` Michael Ellerman
0 siblings, 0 replies; 11+ messages in thread
From: Michael Ellerman @ 2015-03-28 2:34 UTC (permalink / raw)
To: Anshuman Khandual; +Cc: linuxppc-dev, linuxram, Jeremy Kerr
On Thu, 2015-03-26 at 11:54 +0530, Anshuman Khandual wrote:
> On 03/26/2015 06:06 AM, Michael Ellerman wrote:
> > On Wed, 2015-03-25 at 17:02 +0530, Anshuman Khandual wrote:
> >> On 03/25/2015 10:58 AM, Michael Ellerman wrote:
> >>> On Wed, 2015-03-18 at 16:04 +1100, Michael Ellerman wrote:
> >>>> On Tue, 2015-03-17 at 11:35 +0530, Anshuman Khandual wrote:
> >>>>> On 03/17/2015 04:34 AM, Michael Ellerman wrote:
> >>>>>> What are you seeing exactly?
> >>>>>
> >>>>> I am running on a BE PKVM guest but compiling the test case on
> >>>>> a different BE machine which has newer version of the compiler.
> >>>>>
> >>>>> cc (GCC) 4.8.3 20140624
> >>>>>
> >>>>> cc -O2 -Wall -g -nostdlib -m64 -c -o check.o check.S
> >>>>> objcopy -j .text --reverse-bytes=4 -O binary check.o check-reversed.o
> >>>>> hexdump -v -e '/1 ".byte 0x%02X\n"' check-reversed.o > check-reversed.S
> >>>>> cc -O2 -Wall -g -nostdlib -m64 switch_endian_test.S check-reversed.S -o switch_endian_test
> >>>>>
> >>>>> which looks very similar to the details you have provided above.
> >>>>> Running on guest or host should not make any difference.
> >>>>
> >>>> No it shouldn't.
> >>>>
> >>>> Can you try strace, that should give you the full result code.
> >>>>
> >>>> Also can you try gdb. You can't breakpoint in the wrong-endian region, but it
> >>>> looks like you're getting through that anyway.
> >>>>
> >>>> So try setting a breakpoint at line ~77, and you should be back in BE. Then you
> >>>> can single step and see where it errors out.
> >>>
> >>> Did you try these?
> >>
> >> Yeah. The test program is showing some strange behavior.
> >>
> >> (1) Without strace: It just fails with 176 return code as before
> >> (2) With strace: It works with return code 0 and prints everything !!
> >>
> >> strace ./switch_endian_test
> >> execve("./switch_endian_test", ["./switch_endian_test"], [/* 50 vars */]) = 0
> >> SYS_363(0x5555aaaa5555aaaa, 0x5555aaaa5555aaae, 0x5555aaaa5555aaaf,
> >> 0x5555aaaa5555aab0, 0x5555aaaa5555aab1) = 6149008514797120170
> >> write(1, "Hello wrong-endian world\n", 25Hello wrong-endian world
> >> ) = 25
> >> SYS_363(0x19, 0x10010638, 0x19, 0x5555aaaa5555aab0, 0x5555aaaa5555aab1) = 25
> >> write(1, "Hello right-endian world\n", 25Hello right-endian world
> >> ) = 25
> >> write(1, "success: switch_endian_test\n", 28success: switch_endian_test
> >> ) = 28
> >> exit(0) = ?
> >>
> >> With GDB and breaking at line 77, it exits with a different exit code this time
> >
> > No that's the same code, 176 == 0260 (octal).
> >
> >> 30 cmpd r3,r5
> >> (gdb)
> >> 31 bne 1f
> >> (gdb)
> >> 32 addi r3,r15,6
> >> (gdb)
> >> 33 cmpd r3,r6
> >> (gdb)
> >> 34 bne 1f
> >> (gdb)
> >> 98 1: li r0, __NR_exit
> >> (gdb)
> >> 99 sc
> >> (gdb)
> >> [Inferior 1 (process 6456) exited with code 0260]
> >
> > And that makes sense, it's bailing because r6 doesn't match. In the setup we do:
> >
> > addi r6, r15, 6
> >
> > Where r15 is 0x5555aaaa5555aaaa, so:
> >
> > 0x5555aaaa5555aaaa + 6 = 0x5555aaaa5555aab0
> >
> > And when we exit the kernel masks the exit code in r3 with 0xff, so:
> >
> > 0x5555aaaa5555aab0 & 0xff = 0xb0 = 176
> >
> >
> > So for some reason r6 does not contain our pattern.
> >
> > Can you do an "info registers" and see what's in r6?
>
> Sure, here are the details.
>
> (gdb)
> 98 1: li r0, __NR_exit
> (gdb)
> 99 sc
> (gdb) info registers
> r0 0x1 1
> r1 0x3ffffffff360 70368744174432
> r2 0x10018670 268535408
> r3 0x5555aaaa5555aab0 6149008514797120176
> r4 0x5555aaaa5555aaca 6149008514797120202
> r5 0x5555aaaa5555aaaf 6149008514797120175
>
> r6 0x4000 16384 <<=========================
>
> r7 0x100002e4 268436196
> r8 0x800000010000d033 9223372041149796403
Sigh. This is just a ■■■■■■ ■■■■■■■ ■■■■ ■■ on my part.
At the end of the checking code we call write(), which is a syscall, and it
clobbers the register state! Duh.
I think the reason you were seeing it and I wasn't is that on my system I have
audit enabled, so we *always* go through the path that restores.
New patch sent.
cheers
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2015-03-28 2:34 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-16 6:57 [PATCH v3 1/2] powerpc: Add a proper syscall for switching endianness Michael Ellerman
2015-03-16 6:57 ` [PATCH v3 2/2] selftests/powerpc: Add a test of the switch_endian() syscall Michael Ellerman
2015-03-16 11:00 ` Anshuman Khandual
2015-03-16 23:04 ` Michael Ellerman
2015-03-17 6:05 ` Anshuman Khandual
2015-03-18 5:04 ` Michael Ellerman
2015-03-25 5:28 ` Michael Ellerman
2015-03-25 11:32 ` Anshuman Khandual
2015-03-26 0:36 ` Michael Ellerman
2015-03-26 6:24 ` Anshuman Khandual
2015-03-28 2:34 ` Michael Ellerman
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.