2023-08-01 19:44:07

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v4 00/12] tools/nolibc: add 32/64-bit powerpc support

Hi, Willy, Hi Thomas

v4 here is mainly with a new nolibc-test-config target from your
suggestions and with the reordering of some patches to make
nolibc-test-config be fast forward.

run-user tests for all of the powerpc variants:

$ for arch in ppc ppc64 ppc64le; do make run-user XARCH=$arch | grep status; done
165 test(s): 157 passed, 8 skipped, 0 failed => status: warning
165 test(s): 157 passed, 8 skipped, 0 failed => status: warning
165 test(s): 157 passed, 8 skipped, 0 failed => status: warning

and defconfig + run for ppc:

$ make nolibc-test-config XARCH=ppc
$ make run XARCH=ppc
165 test(s): 159 passed, 6 skipped, 0 failed => status: warning


* tools/nolibc: add support for powerpc
tools/nolibc: add support for powerpc64

No change.

* selftests/nolibc: fix up O= option support
selftests/nolibc: add macros to reduce duplicated changes

From tinyconfig-part1 patchset, required by our nolibc-test-config target

Let nolibc-test-config be able to use objtree and the kernel related
macros directly.

* selftests/nolibc: add XARCH and ARCH mapping support

Moved before nolibc-test-config, for the NOLIBC_TEST_CONFIG macro used by
nolibc-test-config target

Willy talked about this twice, let nolibc-test-config be able to use
nolibc-test-$(XARCH).config listed in NOLIBC_TEST_CONFIG directly.

* selftests/nolibc: add nolibc-test-config target
selftests/nolibc: add help for nolibc-test-config target

A new generic nolibc-test-config target is added, allows to enable
additional options for a top-level config target.

defconfig is reserved as an alias of nolibc-test-config.

As suggested by Thomas and Willy.

* selftests/nolibc: add test support for ppc
selftests/nolibc: add test support for ppc64le
selftests/nolibc: add test support for ppc64

Renamed from $(XARCH).config to nolibc-test-$(XARCH).config

As suggested by Willy.

* selftests/nolibc: allow customize CROSS_COMPILE by architecture
selftests/nolibc: customize CROSS_COMPILE for 32/64-bit powerpc

Moved here as suggested by Willy.

Best regards,
Zhangjin
---
[1]: https://lore.kernel.org/lkml/[email protected]/



Zhangjin Wu (12):
tools/nolibc: add support for powerpc
tools/nolibc: add support for powerpc64
selftests/nolibc: fix up O= option support
selftests/nolibc: add macros to reduce duplicated changes
selftests/nolibc: add XARCH and ARCH mapping support
selftests/nolibc: add nolibc-test-config target
selftests/nolibc: add help for nolibc-test-config target
selftests/nolibc: add test support for ppc
selftests/nolibc: add test support for ppc64le
selftests/nolibc: add test support for ppc64
selftests/nolibc: allow customize CROSS_COMPILE by architecture
selftests/nolibc: customize CROSS_COMPILE for 32/64-bit powerpc

tools/include/nolibc/arch-powerpc.h | 202 ++++++++++++++++++
tools/include/nolibc/arch.h | 2 +
tools/testing/selftests/nolibc/Makefile | 157 ++++++++++----
.../nolibc/configs/nolibc-test-ppc.config | 3 +
4 files changed, 327 insertions(+), 37 deletions(-)
create mode 100644 tools/include/nolibc/arch-powerpc.h
create mode 100644 tools/testing/selftests/nolibc/configs/nolibc-test-ppc.config

--
2.25.1



2023-08-01 20:19:51

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v4 03/12] selftests/nolibc: fix up O= option support

To avoid pollute the source code tree and avoid mrproper for every
architecture switch, the O= argument must be supported.

Both IMAGE and .config are from the building directory, let's use
objtree instead of srctree for them.

If no O= option specified, means building kernel in source code tree,
objtree should be srctree in such case.

Suggested-by: Willy Tarreau <[email protected]>
Link: https://lore.kernel.org/lkml/[email protected]/
Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/Makefile | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index f42adef87e12..f0bda0d28000 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -9,6 +9,9 @@ ifeq ($(srctree),)
srctree := $(patsubst %/tools/testing/selftests/,%,$(dir $(CURDIR)))
endif

+# add objtree for O= argument, required by IMAGE and .config
+objtree ?= $(srctree)
+
ifeq ($(ARCH),)
include $(srctree)/scripts/subarch.include
ARCH = $(SUBARCH)
@@ -167,12 +170,12 @@ kernel: initramfs

# run the tests after building the kernel
run: kernel
- $(Q)qemu-system-$(QEMU_ARCH) -display none -no-reboot -kernel "$(srctree)/$(IMAGE)" -serial stdio $(QEMU_ARGS) > "$(CURDIR)/run.out"
+ $(Q)qemu-system-$(QEMU_ARCH) -display none -no-reboot -kernel "$(objtree)/$(IMAGE)" -serial stdio $(QEMU_ARGS) > "$(CURDIR)/run.out"
$(Q)$(REPORT) $(CURDIR)/run.out

# re-run the tests from an existing kernel
rerun:
- $(Q)qemu-system-$(QEMU_ARCH) -display none -no-reboot -kernel "$(srctree)/$(IMAGE)" -serial stdio $(QEMU_ARGS) > "$(CURDIR)/run.out"
+ $(Q)qemu-system-$(QEMU_ARCH) -display none -no-reboot -kernel "$(objtree)/$(IMAGE)" -serial stdio $(QEMU_ARGS) > "$(CURDIR)/run.out"
$(Q)$(REPORT) $(CURDIR)/run.out

clean:
--
2.25.1


2023-08-01 20:19:52

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v4 04/12] selftests/nolibc: add macros to reduce duplicated changes

The kernel targets share the same kernel make operations, the same
.config file, the same kernel image, add MAKE_KERNEL, KERNEL_CONFIG and
KERNEL_IMAGE for them.

Many targets use the same log file, add RUN_OUT to allow save log by
architecture, for example: 'make RUN_OUT=$PWD/run.$arch.out'.

The qemu run/rerun targets share the same qemu system run command, add
QEMU_SYSTEM_RUN for them.

Suggested-by: Willy Tarreau <[email protected]>
Link: https://lore.kernel.org/lkml/[email protected]/
Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/Makefile | 35 ++++++++++++++++---------
1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index f0bda0d28000..fdc72ca75589 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -142,41 +142,52 @@ endif
libc-test: nolibc-test.c
$(QUIET_CC)$(CC) -o $@ $<

+# common macros for logging
+RUN_OUT = $(CURDIR)/run.out
+
# local libc-test
run-libc-test: libc-test
- $(Q)./libc-test > "$(CURDIR)/run.out" || :
- $(Q)$(REPORT) $(CURDIR)/run.out
+ $(Q)./libc-test > "$(RUN_OUT)" || :
+ $(Q)$(REPORT) "$(RUN_OUT)"

# local nolibc-test
run-nolibc-test: nolibc-test
- $(Q)./nolibc-test > "$(CURDIR)/run.out" || :
- $(Q)$(REPORT) $(CURDIR)/run.out
+ $(Q)./nolibc-test > "$(RUN_OUT)" || :
+ $(Q)$(REPORT) "$(RUN_OUT)"

# qemu user-land test
run-user: nolibc-test
- $(Q)qemu-$(QEMU_ARCH) ./nolibc-test > "$(CURDIR)/run.out" || :
- $(Q)$(REPORT) $(CURDIR)/run.out
+ $(Q)qemu-$(QEMU_ARCH) ./nolibc-test > "$(RUN_OUT)" || :
+ $(Q)$(REPORT) "$(RUN_OUT)"

initramfs: nolibc-test
$(QUIET_MKDIR)mkdir -p initramfs
$(call QUIET_INSTALL, initramfs/init)
$(Q)cp nolibc-test initramfs/init

+# common macros for kernel targets
+MAKE_KERNEL = $(MAKE) -C $(srctree) ARCH=$(ARCH) CC=$(CC) CROSS_COMPILE=$(CROSS_COMPILE)
+KERNEL_CONFIG = $(objtree)/.config
+KERNEL_IMAGE = $(objtree)/$(IMAGE)
+
defconfig:
- $(Q)$(MAKE) -C $(srctree) ARCH=$(ARCH) CC=$(CC) CROSS_COMPILE=$(CROSS_COMPILE) mrproper $(DEFCONFIG) prepare
+ $(Q)$(MAKE_KERNEL) mrproper $(DEFCONFIG) prepare

kernel: initramfs
- $(Q)$(MAKE) -C $(srctree) ARCH=$(ARCH) CC=$(CC) CROSS_COMPILE=$(CROSS_COMPILE) $(IMAGE_NAME) CONFIG_INITRAMFS_SOURCE=$(CURDIR)/initramfs
+ $(Q)$(MAKE_KERNEL) $(IMAGE_NAME) CONFIG_INITRAMFS_SOURCE=$(CURDIR)/initramfs
+
+# common macros for qemu run/rerun targets
+QEMU_SYSTEM_RUN = qemu-system-$(QEMU_ARCH) -display none -no-reboot -kernel "$(KERNEL_IMAGE)" -serial stdio $(QEMU_ARGS)

# run the tests after building the kernel
run: kernel
- $(Q)qemu-system-$(QEMU_ARCH) -display none -no-reboot -kernel "$(objtree)/$(IMAGE)" -serial stdio $(QEMU_ARGS) > "$(CURDIR)/run.out"
- $(Q)$(REPORT) $(CURDIR)/run.out
+ $(Q)$(QEMU_SYSTEM_RUN) > "$(RUN_OUT)"
+ $(Q)$(REPORT) "$(RUN_OUT)"

# re-run the tests from an existing kernel
rerun:
- $(Q)qemu-system-$(QEMU_ARCH) -display none -no-reboot -kernel "$(objtree)/$(IMAGE)" -serial stdio $(QEMU_ARGS) > "$(CURDIR)/run.out"
- $(Q)$(REPORT) $(CURDIR)/run.out
+ $(Q)$(QEMU_SYSTEM_RUN) > "$(RUN_OUT)"
+ $(Q)$(REPORT) "$(RUN_OUT)"

clean:
$(call QUIET_CLEAN, sysroot)
--
2.25.1


2023-08-01 20:20:21

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v4 01/12] tools/nolibc: add support for powerpc

Both syscall declarations and _start code definition are added for
powerpc to nolibc.

Like mips, powerpc uses a register (exactly, the summary overflow bit)
to record the error occurred, and uses another register to return the
value [1]. So, the return value of every syscall declaration must be
normalized to match the __sysret() helper, return -value when there is
an error, otheriwse, return value directly.

Glibc and musl use different methods to check the summary overflow bit,
glibc (sysdeps/unix/sysv/linux/powerpc/sysdep.h) saves the cr register
to r0 at first, and then check the summary overflow bit in cr0:

mfcr r0
r0 & (1 << 28) ? -r3 : r3

-->

10003c14: 7c 00 00 26 mfcr r0
10003c18: 74 09 10 00 andis. r9,r0,4096
10003c1c: 41 82 00 08 beq 0x10003c24
10003c20: 7c 63 00 d0 neg r3,r3

Musl (arch/powerpc/syscall_arch.h) directly checks the summary overflow
bit with the 'bns' instruction, it is smaller:

/* no summary overflow bit means no error, return value directly */
bns+ 1f
/* otherwise, return negated value */
neg r3, r3
1:

-->

10000418: 40 a3 00 08 bns 0x10000420
1000041c: 7c 63 00 d0 neg r3,r3

Like musl, Linux (arch/powerpc/include/asm/vdso/gettimeofday.h) uses the
same method for do_syscall_2() too.

Here applies the second method to get smaller size.

[1]: https://man7.org/linux/man-pages/man2/syscall.2.html

Reviewed-by: Thomas Weißschuh <[email protected]>
Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/include/nolibc/arch-powerpc.h | 188 ++++++++++++++++++++++++++++
tools/include/nolibc/arch.h | 2 +
2 files changed, 190 insertions(+)
create mode 100644 tools/include/nolibc/arch-powerpc.h

diff --git a/tools/include/nolibc/arch-powerpc.h b/tools/include/nolibc/arch-powerpc.h
new file mode 100644
index 000000000000..caa943e1521a
--- /dev/null
+++ b/tools/include/nolibc/arch-powerpc.h
@@ -0,0 +1,188 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * PowerPC specific definitions for NOLIBC
+ * Copyright (C) 2023 Zhangjin Wu <[email protected]>
+ */
+
+#ifndef _NOLIBC_ARCH_POWERPC_H
+#define _NOLIBC_ARCH_POWERPC_H
+
+#include "compiler.h"
+#include "crt.h"
+
+/* Syscalls for PowerPC :
+ * - stack is 16-byte aligned
+ * - syscall number is passed in r0
+ * - arguments are in r3, r4, r5, r6, r7, r8, r9
+ * - the system call is performed by calling "sc"
+ * - syscall return comes in r3, and the summary overflow bit is checked
+ * to know if an error occurred, in which case errno is in r3.
+ * - the arguments are cast to long and assigned into the target
+ * registers which are then simply passed as registers to the asm code,
+ * so that we don't have to experience issues with register constraints.
+ */
+
+#define _NOLIBC_SYSCALL_CLOBBERLIST \
+ "memory", "cr0", "r12", "r11", "r10", "r9"
+
+#define my_syscall0(num) \
+({ \
+ register long _ret __asm__ ("r3"); \
+ register long _num __asm__ ("r0") = (num); \
+ \
+ __asm__ volatile ( \
+ " sc\n" \
+ " bns+ 1f\n" \
+ " neg %0, %0\n" \
+ "1:\n" \
+ : "=r"(_ret), "+r"(_num) \
+ : \
+ : _NOLIBC_SYSCALL_CLOBBERLIST, "r8", "r7", "r6", "r5", "r4" \
+ ); \
+ _ret; \
+})
+
+#define my_syscall1(num, arg1) \
+({ \
+ register long _ret __asm__ ("r3"); \
+ register long _num __asm__ ("r0") = (num); \
+ register long _arg1 __asm__ ("r3") = (long)(arg1); \
+ \
+ __asm__ volatile ( \
+ " sc\n" \
+ " bns+ 1f\n" \
+ " neg %0, %0\n" \
+ "1:\n" \
+ : "=r"(_ret), "+r"(_num) \
+ : "0"(_arg1) \
+ : _NOLIBC_SYSCALL_CLOBBERLIST, "r8", "r7", "r6", "r5", "r4" \
+ ); \
+ _ret; \
+})
+
+
+#define my_syscall2(num, arg1, arg2) \
+({ \
+ register long _ret __asm__ ("r3"); \
+ register long _num __asm__ ("r0") = (num); \
+ register long _arg1 __asm__ ("r3") = (long)(arg1); \
+ register long _arg2 __asm__ ("r4") = (long)(arg2); \
+ \
+ __asm__ volatile ( \
+ " sc\n" \
+ " bns+ 1f\n" \
+ " neg %0, %0\n" \
+ "1:\n" \
+ : "=r"(_ret), "+r"(_num), "+r"(_arg2) \
+ : "0"(_arg1) \
+ : _NOLIBC_SYSCALL_CLOBBERLIST, "r8", "r7", "r6", "r5" \
+ ); \
+ _ret; \
+})
+
+
+#define my_syscall3(num, arg1, arg2, arg3) \
+({ \
+ register long _ret __asm__ ("r3"); \
+ register long _num __asm__ ("r0") = (num); \
+ register long _arg1 __asm__ ("r3") = (long)(arg1); \
+ register long _arg2 __asm__ ("r4") = (long)(arg2); \
+ register long _arg3 __asm__ ("r5") = (long)(arg3); \
+ \
+ __asm__ volatile ( \
+ " sc\n" \
+ " bns+ 1f\n" \
+ " neg %0, %0\n" \
+ "1:\n" \
+ : "=r"(_ret), "+r"(_num), "+r"(_arg2), "+r"(_arg3) \
+ : "0"(_arg1) \
+ : _NOLIBC_SYSCALL_CLOBBERLIST, "r8", "r7", "r6" \
+ ); \
+ _ret; \
+})
+
+
+#define my_syscall4(num, arg1, arg2, arg3, arg4) \
+({ \
+ register long _ret __asm__ ("r3"); \
+ register long _num __asm__ ("r0") = (num); \
+ register long _arg1 __asm__ ("r3") = (long)(arg1); \
+ register long _arg2 __asm__ ("r4") = (long)(arg2); \
+ register long _arg3 __asm__ ("r5") = (long)(arg3); \
+ register long _arg4 __asm__ ("r6") = (long)(arg4); \
+ \
+ __asm__ volatile ( \
+ " sc\n" \
+ " bns+ 1f\n" \
+ " neg %0, %0\n" \
+ "1:\n" \
+ : "=r"(_ret), "+r"(_num), "+r"(_arg2), "+r"(_arg3), \
+ "+r"(_arg4) \
+ : "0"(_arg1) \
+ : _NOLIBC_SYSCALL_CLOBBERLIST, "r8", "r7" \
+ ); \
+ _ret; \
+})
+
+
+#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
+({ \
+ register long _ret __asm__ ("r3"); \
+ register long _num __asm__ ("r0") = (num); \
+ register long _arg1 __asm__ ("r3") = (long)(arg1); \
+ register long _arg2 __asm__ ("r4") = (long)(arg2); \
+ register long _arg3 __asm__ ("r5") = (long)(arg3); \
+ register long _arg4 __asm__ ("r6") = (long)(arg4); \
+ register long _arg5 __asm__ ("r7") = (long)(arg5); \
+ \
+ __asm__ volatile ( \
+ " sc\n" \
+ " bns+ 1f\n" \
+ " neg %0, %0\n" \
+ "1:\n" \
+ : "=r"(_ret), "+r"(_num), "+r"(_arg2), "+r"(_arg3), \
+ "+r"(_arg4), "+r"(_arg5) \
+ : "0"(_arg1) \
+ : _NOLIBC_SYSCALL_CLOBBERLIST, "r8" \
+ ); \
+ _ret; \
+})
+
+#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
+({ \
+ register long _ret __asm__ ("r3"); \
+ register long _num __asm__ ("r0") = (num); \
+ register long _arg1 __asm__ ("r3") = (long)(arg1); \
+ register long _arg2 __asm__ ("r4") = (long)(arg2); \
+ register long _arg3 __asm__ ("r5") = (long)(arg3); \
+ register long _arg4 __asm__ ("r6") = (long)(arg4); \
+ register long _arg5 __asm__ ("r7") = (long)(arg5); \
+ register long _arg6 __asm__ ("r8") = (long)(arg6); \
+ \
+ __asm__ volatile ( \
+ " sc\n" \
+ " bns+ 1f\n" \
+ " neg %0, %0\n" \
+ "1:\n" \
+ : "=r"(_ret), "+r"(_num), "+r"(_arg2), "+r"(_arg3), \
+ "+r"(_arg4), "+r"(_arg5), "+r"(_arg6) \
+ : "0"(_arg1) \
+ : _NOLIBC_SYSCALL_CLOBBERLIST \
+ ); \
+ _ret; \
+})
+
+/* startup code */
+void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_stack_protector _start(void)
+{
+ __asm__ volatile (
+ "mr 3, 1\n" /* save stack pointer to r3, as arg1 of _start_c */
+ "clrrwi 1, 1, 4\n" /* align the stack to 16 bytes */
+ "li 0, 0\n" /* zero the frame pointer */
+ "stwu 1, -16(1)\n" /* the initial stack frame */
+ "bl _start_c\n" /* transfer to c runtime */
+ );
+ __builtin_unreachable();
+}
+
+#endif /* _NOLIBC_ARCH_POWERPC_H */
diff --git a/tools/include/nolibc/arch.h b/tools/include/nolibc/arch.h
index 82b43935650f..e276fb0680af 100644
--- a/tools/include/nolibc/arch.h
+++ b/tools/include/nolibc/arch.h
@@ -25,6 +25,8 @@
#include "arch-aarch64.h"
#elif defined(__mips__) && defined(_ABIO32)
#include "arch-mips.h"
+#elif defined(__powerpc__)
+#include "arch-powerpc.h"
#elif defined(__riscv)
#include "arch-riscv.h"
#elif defined(__s390x__)
--
2.25.1


2023-08-01 20:24:39

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v4 08/12] selftests/nolibc: add test support for ppc

Kernel uses ARCH=powerpc for both 32-bit and 64-bit PowerPC, here adds a
ppc variant for 32-bit PowerPC and uses it as the default variant of
powerpc architecture.

Users can pass ARCH=powerpc or XARCH=ppc to test 32-bit PowerPC.

The default qemu-system-ppc g3beige machine [1] is used to run 32-bit
powerpc kernel.

The pmac32_defconfig is used with extra PMACZILOG console options to
enable normal print.

Note, zImage doesn't boot due to "qemu-system-ppc: Some ROM regions are
overlapping" error, so, vmlinux is used instead.

[1]: https://qemu.readthedocs.io/en/latest/system/ppc/powermac.html

Suggested-by: Willy Tarreau <[email protected]>
Link: https://lore.kernel.org/lkml/[email protected]/
Reviewed-by: Thomas Weißschuh <[email protected]>
Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/Makefile | 6 ++++++
.../testing/selftests/nolibc/configs/nolibc-test-ppc.config | 3 +++
2 files changed, 9 insertions(+)
create mode 100644 tools/testing/selftests/nolibc/configs/nolibc-test-ppc.config

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index 3c9e3963fbad..29e02b49903a 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -33,9 +33,11 @@ endif
# architectures where both are equal.

# configure default variants for target kernel supported architectures
+XARCH_powerpc = ppc
XARCH = $(or $(XARCH_$(ARCH)),$(ARCH))

# map from user input variants to their kernel supported architectures
+ARCH_ppc = powerpc
ARCH := $(or $(ARCH_$(XARCH)),$(XARCH))

# kernel image names by architecture
@@ -45,6 +47,7 @@ IMAGE_x86 = arch/x86/boot/bzImage
IMAGE_arm64 = arch/arm64/boot/Image
IMAGE_arm = arch/arm/boot/zImage
IMAGE_mips = vmlinuz
+IMAGE_ppc = vmlinux
IMAGE_riscv = arch/riscv/boot/Image
IMAGE_s390 = arch/s390/boot/bzImage
IMAGE_loongarch = arch/loongarch/boot/vmlinuz.efi
@@ -58,6 +61,7 @@ DEFCONFIG_x86 = defconfig
DEFCONFIG_arm64 = defconfig
DEFCONFIG_arm = multi_v7_defconfig
DEFCONFIG_mips = malta_defconfig
+DEFCONFIG_ppc = pmac32_defconfig
DEFCONFIG_riscv = defconfig
DEFCONFIG_s390 = defconfig
DEFCONFIG_loongarch = defconfig
@@ -77,6 +81,7 @@ QEMU_ARCH_x86 = x86_64
QEMU_ARCH_arm64 = aarch64
QEMU_ARCH_arm = arm
QEMU_ARCH_mips = mipsel # works with malta_defconfig
+QEMU_ARCH_ppc = ppc
QEMU_ARCH_riscv = riscv64
QEMU_ARCH_s390 = s390x
QEMU_ARCH_loongarch = loongarch64
@@ -89,6 +94,7 @@ QEMU_ARGS_x86 = -M pc -append "console=ttyS0,9600 i8042.noaux panic=-1 $(
QEMU_ARGS_arm64 = -M virt -cpu cortex-a53 -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)"
QEMU_ARGS_arm = -M virt -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)"
QEMU_ARGS_mips = -M malta -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)"
+QEMU_ARGS_ppc = -M g3beige -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
QEMU_ARGS_riscv = -M virt -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
QEMU_ARGS_s390 = -M s390-ccw-virtio -m 1G -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
QEMU_ARGS_loongarch = -M virt -append "console=ttyS0,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
diff --git a/tools/testing/selftests/nolibc/configs/nolibc-test-ppc.config b/tools/testing/selftests/nolibc/configs/nolibc-test-ppc.config
new file mode 100644
index 000000000000..b1975f8253f7
--- /dev/null
+++ b/tools/testing/selftests/nolibc/configs/nolibc-test-ppc.config
@@ -0,0 +1,3 @@
+CONFIG_SERIAL_PMACZILOG=y
+CONFIG_SERIAL_PMACZILOG_TTYS=y
+CONFIG_SERIAL_PMACZILOG_CONSOLE=y
--
2.25.1


2023-08-01 20:25:30

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v4 07/12] selftests/nolibc: add help for nolibc-test-config target

Both the nolibc-test-config target and the NOLIBC_TEST_CONFIG marco are
listed in the help output.

Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/Makefile | 42 +++++++++++++------------
1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index f01b258ef19b..3c9e3963fbad 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -119,30 +119,32 @@ REPORT ?= awk '/\[OK\][\r]*$$/{p++} /\[FAIL\][\r]*$$/{if (!f) printf("\n"); f++

help:
@echo "Supported targets under selftests/nolibc:"
- @echo " all call the \"run\" target below"
- @echo " help this help"
- @echo " sysroot create the nolibc sysroot here (uses \$$ARCH)"
- @echo " nolibc-test build the executable (uses \$$CC and \$$CROSS_COMPILE)"
- @echo " libc-test build an executable using the compiler's default libc instead"
- @echo " run-user runs the executable under QEMU (uses \$$XARCH, \$$TEST)"
- @echo " initramfs prepare the initramfs with nolibc-test"
- @echo " defconfig create a fresh new default config (uses \$$XARCH)"
- @echo " kernel (re)build the kernel with the initramfs (uses \$$XARCH)"
- @echo " run runs the kernel in QEMU after building it (uses \$$XARCH, \$$TEST)"
- @echo " rerun runs a previously prebuilt kernel in QEMU (uses \$$XARCH, \$$TEST)"
- @echo " clean clean the sysroot, initramfs, build and output files"
+ @echo " all call the \"run\" target below"
+ @echo " help this help"
+ @echo " sysroot create the nolibc sysroot here (uses \$$ARCH)"
+ @echo " nolibc-test build the executable (uses \$$CC and \$$CROSS_COMPILE)"
+ @echo " libc-test build an executable using the compiler's default libc instead"
+ @echo " run-user runs the executable under QEMU (uses \$$XARCH, \$$TEST)"
+ @echo " initramfs prepare the initramfs with nolibc-test"
+ @echo " nolibc-test-config create a fresh new \$$(CONFIG) config with extra options from \$$NOLIBC_TEST_CONFIG files (uses \$$XARCH)"
+ @echo " defconfig do nolibc-test-config with default config (uses \$$XARCH)"
+ @echo " kernel (re)build the kernel with the initramfs (uses \$$XARCH)"
+ @echo " run runs the kernel in QEMU after building it (uses \$$XARCH, \$$TEST)"
+ @echo " rerun runs a previously prebuilt kernel in QEMU (uses \$$XARCH, \$$TEST)"
+ @echo " clean clean the sysroot, initramfs, build and output files"
@echo ""
@echo "The output file is \"run.out\". Test ranges may be passed using \$$TEST."
@echo ""
@echo "Currently using the following variables:"
- @echo " ARCH = $(ARCH)"
- @echo " XARCH = $(XARCH)"
- @echo " CROSS_COMPILE = $(CROSS_COMPILE)"
- @echo " CC = $(CC)"
- @echo " OUTPUT = $(OUTPUT)"
- @echo " TEST = $(TEST)"
- @echo " QEMU_ARCH = $(if $(QEMU_ARCH),$(QEMU_ARCH),UNKNOWN_ARCH) [determined from \$$XARCH]"
- @echo " IMAGE_NAME = $(if $(IMAGE_NAME),$(IMAGE_NAME),UNKNOWN_ARCH) [determined from \$$XARCH]"
+ @echo " ARCH = $(ARCH)"
+ @echo " XARCH = $(XARCH)"
+ @echo " CROSS_COMPILE = $(CROSS_COMPILE)"
+ @echo " CC = $(CC)"
+ @echo " OUTPUT = $(OUTPUT)"
+ @echo " TEST = $(TEST)"
+ @echo " QEMU_ARCH = $(if $(QEMU_ARCH),$(QEMU_ARCH),UNKNOWN_ARCH) [determined from \$$XARCH]"
+ @echo " IMAGE_NAME = $(if $(IMAGE_NAME),$(IMAGE_NAME),UNKNOWN_ARCH) [determined from \$$XARCH]"
+ @echo " NOLIBC_TEST_CONFIG = $(strip $(foreach c,$(NOLIBC_TEST_CONFIG),$(wildcard $(CURDIR)/configs/$c))) [determined from \$$XARCH]"
@echo ""

all: run
--
2.25.1


2023-08-01 20:27:33

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v4 09/12] selftests/nolibc: add test support for ppc64le

Kernel uses ARCH=powerpc for both 32-bit and 64-bit PowerPC, here adds a
ppc64le variant for little endian 64-bit PowerPC, users can pass
XARCH=ppc64le to test it.

The powernv machine of qemu-system-ppc64le is used for there is just a
working powernv_defconfig.

As the document [1] shows:

PowerNV (as Non-Virtualized) is the “bare metal” platform using the
OPAL firmware. It runs Linux on IBM and OpenPOWER systems and it can be
used as an hypervisor OS, running KVM guests, or simply as a host OS.

Note, since the VSX support may be disabled in kernel side, to avoid
"illegal instruction" errors due to missing VSX kernel support, let's
simply let compiler not generate vector/scalar (VSX) instructions via
the '-mno-vsx' option.

[1]: https://qemu.readthedocs.io/en/latest/system/ppc/powernv.html

Suggested-by: Willy Tarreau <[email protected]>
Link: https://lore.kernel.org/lkml/[email protected]/
Reviewed-by: Thomas Weißschuh <[email protected]>
Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/Makefile | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index 29e02b49903a..8ec2ae33fdcd 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -38,6 +38,7 @@ XARCH = $(or $(XARCH_$(ARCH)),$(ARCH))

# map from user input variants to their kernel supported architectures
ARCH_ppc = powerpc
+ARCH_ppc64le = powerpc
ARCH := $(or $(ARCH_$(XARCH)),$(XARCH))

# kernel image names by architecture
@@ -48,6 +49,7 @@ IMAGE_arm64 = arch/arm64/boot/Image
IMAGE_arm = arch/arm/boot/zImage
IMAGE_mips = vmlinuz
IMAGE_ppc = vmlinux
+IMAGE_ppc64le = arch/powerpc/boot/zImage
IMAGE_riscv = arch/riscv/boot/Image
IMAGE_s390 = arch/s390/boot/bzImage
IMAGE_loongarch = arch/loongarch/boot/vmlinuz.efi
@@ -62,6 +64,7 @@ DEFCONFIG_arm64 = defconfig
DEFCONFIG_arm = multi_v7_defconfig
DEFCONFIG_mips = malta_defconfig
DEFCONFIG_ppc = pmac32_defconfig
+DEFCONFIG_ppc64le = powernv_defconfig
DEFCONFIG_riscv = defconfig
DEFCONFIG_s390 = defconfig
DEFCONFIG_loongarch = defconfig
@@ -82,6 +85,7 @@ QEMU_ARCH_arm64 = aarch64
QEMU_ARCH_arm = arm
QEMU_ARCH_mips = mipsel # works with malta_defconfig
QEMU_ARCH_ppc = ppc
+QEMU_ARCH_ppc64le = ppc64le
QEMU_ARCH_riscv = riscv64
QEMU_ARCH_s390 = s390x
QEMU_ARCH_loongarch = loongarch64
@@ -95,6 +99,7 @@ QEMU_ARGS_arm64 = -M virt -cpu cortex-a53 -append "panic=-1 $(TEST:%=NOLIBC
QEMU_ARGS_arm = -M virt -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)"
QEMU_ARGS_mips = -M malta -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)"
QEMU_ARGS_ppc = -M g3beige -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
+QEMU_ARGS_ppc64le = -M powernv -append "console=hvc0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
QEMU_ARGS_riscv = -M virt -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
QEMU_ARGS_s390 = -M s390-ccw-virtio -m 1G -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
QEMU_ARGS_loongarch = -M virt -append "console=ttyS0,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
@@ -110,6 +115,7 @@ else
Q=@
endif

+CFLAGS_ppc64le = -m64 -mlittle-endian -Wl,-EL,-melf64ppc -mno-vsx
CFLAGS_s390 = -m64
CFLAGS_mips = -EL
CFLAGS_STACKPROTECTOR ?= $(call cc-option,-mstack-protector-guard=global $(call cc-option,-fstack-protector-all))
--
2.25.1


2023-08-01 20:28:10

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v4 10/12] selftests/nolibc: add test support for ppc64

Kernel uses ARCH=powerpc for both 32-bit and 64-bit PowerPC, here adds a
ppc64 variant for big endian 64-bit PowerPC, users can pass ARCH=ppc64
to test it.

The powernv machine of qemu-system-ppc64 is used with
powernv_be_defconfig.

As the document [1] shows:

PowerNV (as Non-Virtualized) is the “bare metal” platform using the
OPAL firmware. It runs Linux on IBM and OpenPOWER systems and it can be
used as an hypervisor OS, running KVM guests, or simply as a host OS.

Notes,

- differs from little endian 64-bit PowerPC, vmlinux is used instead of
zImage, because big endian zImage [2] only boot on qemu with x-vof=on
(added from qemu v7.0) and a fixup patch [3] for qemu v7.0.51:

- since the VSX support may be disabled in kernel side, to avoid
"illegal instruction" errors due to missing VSX kernel support, let's
simply let compiler not generate vector/scalar (VSX) instructions via
the '-mno-vsx' option.

- as 'man gcc' shows, '-mmultiple' is used to generate code that uses
the load multiple word instructions and the store multiple word
instructions. Those instructions do not work when the processor is in
little-endian mode (except PPC740/PPC750), so, we only enable it
for big endian powerpc.

[1]: https://qemu.readthedocs.io/en/latest/system/ppc/powernv.html
[2]: https://github.com/linuxppc/issues/issues/402
[3]: https://lore.kernel.org/qemu-devel/[email protected]/

Suggested-by: Willy Tarreau <[email protected]>
Link: https://lore.kernel.org/lkml/[email protected]/
Link: https://lore.kernel.org/lkml/[email protected]/
Reviewed-by: Thomas Weißschuh <[email protected]>
Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/Makefile | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index 8ec2ae33fdcd..ef4b8ba83898 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -38,6 +38,7 @@ XARCH = $(or $(XARCH_$(ARCH)),$(ARCH))

# map from user input variants to their kernel supported architectures
ARCH_ppc = powerpc
+ARCH_ppc64 = powerpc
ARCH_ppc64le = powerpc
ARCH := $(or $(ARCH_$(XARCH)),$(XARCH))

@@ -49,6 +50,7 @@ IMAGE_arm64 = arch/arm64/boot/Image
IMAGE_arm = arch/arm/boot/zImage
IMAGE_mips = vmlinuz
IMAGE_ppc = vmlinux
+IMAGE_ppc64 = vmlinux
IMAGE_ppc64le = arch/powerpc/boot/zImage
IMAGE_riscv = arch/riscv/boot/Image
IMAGE_s390 = arch/s390/boot/bzImage
@@ -64,6 +66,7 @@ DEFCONFIG_arm64 = defconfig
DEFCONFIG_arm = multi_v7_defconfig
DEFCONFIG_mips = malta_defconfig
DEFCONFIG_ppc = pmac32_defconfig
+DEFCONFIG_ppc64 = powernv_be_defconfig
DEFCONFIG_ppc64le = powernv_defconfig
DEFCONFIG_riscv = defconfig
DEFCONFIG_s390 = defconfig
@@ -85,6 +88,7 @@ QEMU_ARCH_arm64 = aarch64
QEMU_ARCH_arm = arm
QEMU_ARCH_mips = mipsel # works with malta_defconfig
QEMU_ARCH_ppc = ppc
+QEMU_ARCH_ppc64 = ppc64
QEMU_ARCH_ppc64le = ppc64le
QEMU_ARCH_riscv = riscv64
QEMU_ARCH_s390 = s390x
@@ -99,6 +103,7 @@ QEMU_ARGS_arm64 = -M virt -cpu cortex-a53 -append "panic=-1 $(TEST:%=NOLIBC
QEMU_ARGS_arm = -M virt -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)"
QEMU_ARGS_mips = -M malta -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)"
QEMU_ARGS_ppc = -M g3beige -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
+QEMU_ARGS_ppc64 = -M powernv -append "console=hvc0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
QEMU_ARGS_ppc64le = -M powernv -append "console=hvc0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
QEMU_ARGS_riscv = -M virt -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
QEMU_ARGS_s390 = -M s390-ccw-virtio -m 1G -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
@@ -115,6 +120,7 @@ else
Q=@
endif

+CFLAGS_ppc64 = -m64 -mbig-endian -Wl,-EB,-melf64ppc -mmultiple -mno-vsx
CFLAGS_ppc64le = -m64 -mlittle-endian -Wl,-EL,-melf64ppc -mno-vsx
CFLAGS_s390 = -m64
CFLAGS_mips = -EL
--
2.25.1


2023-08-01 20:29:42

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v4 12/12] selftests/nolibc: customize CROSS_COMPILE for 32/64-bit powerpc

The little-endian powerpc64le compilers provided by Ubuntu and Fedora
are able to compile big endian kernel and big endian nolibc-test [1].

These default CROSS_COMPILE settings allow to test target architectures
with:

$ cd /path/to/tools/testing/selftests/nolibc/

$ for arch in ppc ppc64 ppc64le; do \
make run-user ARCH=$arch | grep "status: "; \
done

If want to use another cross compiler, please simply pass CROSS_COMPILE
or CC as before.

For example, it is able to build 64-bit nolibc-test with the big endian
powerpc64-linux-gcc crosstool from [2]:

$ wget -c https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/13.1.0/x86_64-gcc-13.1.0-nolibc-powerpc64-linux.tar.xz
$ tar xvf x86_64-gcc-13.1.0-nolibc-powerpc64-linux.tar.xz
$ export PATH=$PWD/gcc-13.1.0-nolibc/powerpc64-linux/bin/:$PATH

$ export CROSS_COMPILE_ppc64=powerpc64-linux-
$ export CROSS_COMPILE_ppc64le=powerpc64-linux-
$ for arch in ppc64 ppc64le; do \
make run-user ARCH=$arch | grep "status: "; \
done

Or specify CC directly with full path:

$ export CC=$PWD/gcc-13.1.0-nolibc/powerpc64-linux/bin/powerpc64-linux-gcc
$ for arch in ppc64 ppc64le; do \
make run-user ARCH=$arch | grep "status: "; \
done

[1]: https://github.com/open-power/skiboot
[2]: https://mirrors.edge.kernel.org/pub/tools/crosstool/

Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/Makefile | 3 +++
1 file changed, 3 insertions(+)

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index 822cc4bae619..f44a09c39235 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -59,6 +59,9 @@ IMAGE = $(IMAGE_$(XARCH))
IMAGE_NAME = $(notdir $(IMAGE))

# CROSS_COMPILE: cross toolchain prefix by architecture
+CROSS_COMPILE_ppc ?= powerpc-linux-gnu-
+CROSS_COMPILE_ppc64 ?= powerpc64le-linux-gnu-
+CROSS_COMPILE_ppc64le ?= powerpc64le-linux-gnu-
CROSS_COMPILE ?= $(CROSS_COMPILE_$(XARCH))

# make sure CC is prefixed with CROSS_COMPILE
--
2.25.1


2023-08-01 20:48:29

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v4 06/12] selftests/nolibc: add nolibc-test-config target

The default DEFCONFIG_<XARCH> of some architectures may not just work
for nolibc test, some require extra kernel config options to enable
features like console for print.

To make nolibc-test happy, a new nolibc-test-config target is added with
a new NOLIBC_TEST_CONFIG macro. The macro allows store extra common
options via nolibc-test-common.config and the ones by architecture (or
variant) via nolibc-test-$(XARCH).config.

During the nolibc-test-config target, the above extra options will be
appended to .config generated by the old DEFCONFIG_<XARCH> target or by
another config target specified via the CONFIG variable (e.g.
tinyconfig). At last, the 'allnoconfig' target is called with the
.config as the base to let them take effect and let new missing symbols
as no.

The scripts/kconfig/merge_config.sh tool is used to merge the extra
config files listed in NOLIBC_TEST_CONFIG.

Suggested-by: Thomas Weißschuh <[email protected]>
Link: https://lore.kernel.org/lkml/[email protected]/
Link: https://lore.kernel.org/lkml/[email protected]/
Suggested-by: Suggested-by: Willy Tarreau <[email protected]>
Link: https://lore.kernel.org/lkml/[email protected]/#t
Reviewed-by: Thomas Weißschuh <[email protected]>
Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/Makefile | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index 7902b86911a5..f01b258ef19b 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -63,6 +63,10 @@ DEFCONFIG_s390 = defconfig
DEFCONFIG_loongarch = defconfig
DEFCONFIG = $(DEFCONFIG_$(XARCH))

+# extra configs/ files appended to .config during the nolibc-test-config target
+# include common + architecture specific
+NOLIBC_TEST_CONFIG = nolibc-test-common.config nolibc-test-$(XARCH).config
+
# optional tests to run (default = all)
TEST =

@@ -192,8 +196,22 @@ MAKE_KERNEL = $(MAKE) -C $(srctree) ARCH=$(ARCH) CC=$(CC) CROSS_COMPILE=$(CROS
KERNEL_CONFIG = $(objtree)/.config
KERNEL_IMAGE = $(objtree)/$(IMAGE)

-defconfig:
- $(Q)$(MAKE_KERNEL) mrproper $(DEFCONFIG) prepare
+# kernel config for nolibc-test
+#
+# - delete the current configuration and all generated files via 'mrproper' target
+# - generate .config via '$(CONFIG)' or '$(DEFCONFIG_$(XARCH))' target
+# - merge extra config options from $(NOLIBC_TEST_CONFIG) files to .config
+# - use merged .config as base and fills in any missing symbols with '# CONFIG_* is not set' via 'allnoconfig' target
+# - prepare things we need to do before we recursively start building the kernel via 'prepare' target
+#
+nolibc-test-config:
+ $(Q)$(MAKE_KERNEL) mrproper
+ $(Q)$(MAKE_KERNEL) $(or $(CONFIG),$(DEFCONFIG))
+ $(Q)$(srctree)/scripts/kconfig/merge_config.sh -Q -O "$(objtree)" -m "$(KERNEL_CONFIG)" $(foreach c,$(NOLIBC_TEST_CONFIG),$(wildcard $(CURDIR)/configs/$c))
+ $(Q)$(MAKE_KERNEL) KCONFIG_ALLCONFIG=$(KERNEL_CONFIG) allnoconfig
+ $(Q)$(MAKE_KERNEL) prepare
+
+defconfig: nolibc-test-config

kernel: initramfs
$(Q)$(MAKE_KERNEL) $(IMAGE_NAME) CONFIG_INITRAMFS_SOURCE=$(CURDIR)/initramfs
--
2.25.1


2023-08-01 20:50:08

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v4 11/12] selftests/nolibc: allow customize CROSS_COMPILE by architecture

Some cross compilers may not just be prefixed with ARCH, customize them
by architecture may simplify the test a lot, especially, when iterate
with ARCH.

After customizing this for every architecture, the minimal test argument
will be architecture itself, no CROSS_COMPILE required to be passed.

If the prefix of installed cross compiler is not the same as the one
customized, we can also pass CROSS_COMPILE as before or even pass
CROSS_COMPILE_<ARCH>.

Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/Makefile | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index ef4b8ba83898..822cc4bae619 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -58,6 +58,12 @@ IMAGE_loongarch = arch/loongarch/boot/vmlinuz.efi
IMAGE = $(IMAGE_$(XARCH))
IMAGE_NAME = $(notdir $(IMAGE))

+# CROSS_COMPILE: cross toolchain prefix by architecture
+CROSS_COMPILE ?= $(CROSS_COMPILE_$(XARCH))
+
+# make sure CC is prefixed with CROSS_COMPILE
+$(call allow-override,CC,$(CROSS_COMPILE)gcc)
+
# default kernel configurations that appear to be usable
DEFCONFIG_i386 = defconfig
DEFCONFIG_x86_64 = defconfig
--
2.25.1


2023-08-01 21:13:15

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v4 05/12] selftests/nolibc: add XARCH and ARCH mapping support

Most of the CPU architectures have different variants, but kernel
usually only accepts parts of them via the ARCH variable, the others
should be customized via kernel config files.

To simplify testing, a new XARCH variable is added to extend the
kernel's ARCH with a few variants of the same architecture, and it is
used to customize variant specific variables, at last XARCH is converted
to the kernel's ARCH:

e.g. make run XARCH=<one of the supported variants>
| \
| `-> variant specific variables:
| IMAGE, DEFCONFIG, QEMU_ARCH, QEMU_ARGS, CFLAGS ...
\
`---> kernel's ARCH

XARCH and ARCH are carefully mapped to allow users to pass architecture
variants via XARCH or pass architecture via ARCH from cmdline.

PowerPC is the first user and also a very good reference architecture of
this mapping, it has variants with different combinations of
32-bit/64-bit and bit endian/little endian.

To use this mapping, the other architectures can refer to PowerPC, If
the target architecture only has one variant, XARCH is simply an alias
of ARCH, no additional mapping required.

Suggested-by: Willy Tarreau <[email protected]>
Link: https://lore.kernel.org/lkml/[email protected]/
Link: https://lore.kernel.org/lkml/[email protected]/
Reviewed-by: Thomas Weißschuh <[email protected]>
Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/Makefile | 46 ++++++++++++++++++-------
1 file changed, 34 insertions(+), 12 deletions(-)

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index fdc72ca75589..7902b86911a5 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -17,6 +17,27 @@ include $(srctree)/scripts/subarch.include
ARCH = $(SUBARCH)
endif

+# XARCH extends the kernel's ARCH with a few variants of the same
+# architecture that only differ by the configuration, the toolchain
+# and the Qemu program used. It is copied as-is into ARCH except for
+# a few specific values which are mapped like this:
+#
+# XARCH | ARCH | config
+# -------------|-----------|-------------------------
+# ppc | powerpc | 32 bits
+# ppc64 | powerpc | 64 bits big endian
+# ppc64le | powerpc | 64 bits little endian
+#
+# It is recommended to only use XARCH, though it does not harm if
+# ARCH is already set. For simplicity, ARCH is sufficient for all
+# architectures where both are equal.
+
+# configure default variants for target kernel supported architectures
+XARCH = $(or $(XARCH_$(ARCH)),$(ARCH))
+
+# map from user input variants to their kernel supported architectures
+ARCH := $(or $(ARCH_$(XARCH)),$(XARCH))
+
# kernel image names by architecture
IMAGE_i386 = arch/x86/boot/bzImage
IMAGE_x86_64 = arch/x86/boot/bzImage
@@ -27,7 +48,7 @@ IMAGE_mips = vmlinuz
IMAGE_riscv = arch/riscv/boot/Image
IMAGE_s390 = arch/s390/boot/bzImage
IMAGE_loongarch = arch/loongarch/boot/vmlinuz.efi
-IMAGE = $(IMAGE_$(ARCH))
+IMAGE = $(IMAGE_$(XARCH))
IMAGE_NAME = $(notdir $(IMAGE))

# default kernel configurations that appear to be usable
@@ -40,7 +61,7 @@ DEFCONFIG_mips = malta_defconfig
DEFCONFIG_riscv = defconfig
DEFCONFIG_s390 = defconfig
DEFCONFIG_loongarch = defconfig
-DEFCONFIG = $(DEFCONFIG_$(ARCH))
+DEFCONFIG = $(DEFCONFIG_$(XARCH))

# optional tests to run (default = all)
TEST =
@@ -55,7 +76,7 @@ QEMU_ARCH_mips = mipsel # works with malta_defconfig
QEMU_ARCH_riscv = riscv64
QEMU_ARCH_s390 = s390x
QEMU_ARCH_loongarch = loongarch64
-QEMU_ARCH = $(QEMU_ARCH_$(ARCH))
+QEMU_ARCH = $(QEMU_ARCH_$(XARCH))

# QEMU_ARGS : some arch-specific args to pass to qemu
QEMU_ARGS_i386 = -M pc -append "console=ttyS0,9600 i8042.noaux panic=-1 $(TEST:%=NOLIBC_TEST=%)"
@@ -67,7 +88,7 @@ QEMU_ARGS_mips = -M malta -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)"
QEMU_ARGS_riscv = -M virt -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
QEMU_ARGS_s390 = -M s390-ccw-virtio -m 1G -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
QEMU_ARGS_loongarch = -M virt -append "console=ttyS0,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
-QEMU_ARGS = $(QEMU_ARGS_$(ARCH)) $(QEMU_ARGS_EXTRA)
+QEMU_ARGS = $(QEMU_ARGS_$(XARCH)) $(QEMU_ARGS_EXTRA)

# OUTPUT is only set when run from the main makefile, otherwise
# it defaults to this nolibc directory.
@@ -84,7 +105,7 @@ CFLAGS_mips = -EL
CFLAGS_STACKPROTECTOR ?= $(call cc-option,-mstack-protector-guard=global $(call cc-option,-fstack-protector-all))
CFLAGS ?= -Os -fno-ident -fno-asynchronous-unwind-tables -std=c89 \
$(call cc-option,-fno-stack-protector) \
- $(CFLAGS_$(ARCH)) $(CFLAGS_STACKPROTECTOR)
+ $(CFLAGS_$(XARCH)) $(CFLAGS_STACKPROTECTOR)
LDFLAGS := -s

REPORT ?= awk '/\[OK\][\r]*$$/{p++} /\[FAIL\][\r]*$$/{if (!f) printf("\n"); f++; print;} /\[SKIPPED\][\r]*$$/{s++} \
@@ -99,24 +120,25 @@ help:
@echo " sysroot create the nolibc sysroot here (uses \$$ARCH)"
@echo " nolibc-test build the executable (uses \$$CC and \$$CROSS_COMPILE)"
@echo " libc-test build an executable using the compiler's default libc instead"
- @echo " run-user runs the executable under QEMU (uses \$$ARCH, \$$TEST)"
+ @echo " run-user runs the executable under QEMU (uses \$$XARCH, \$$TEST)"
@echo " initramfs prepare the initramfs with nolibc-test"
- @echo " defconfig create a fresh new default config (uses \$$ARCH)"
- @echo " kernel (re)build the kernel with the initramfs (uses \$$ARCH)"
- @echo " run runs the kernel in QEMU after building it (uses \$$ARCH, \$$TEST)"
- @echo " rerun runs a previously prebuilt kernel in QEMU (uses \$$ARCH, \$$TEST)"
+ @echo " defconfig create a fresh new default config (uses \$$XARCH)"
+ @echo " kernel (re)build the kernel with the initramfs (uses \$$XARCH)"
+ @echo " run runs the kernel in QEMU after building it (uses \$$XARCH, \$$TEST)"
+ @echo " rerun runs a previously prebuilt kernel in QEMU (uses \$$XARCH, \$$TEST)"
@echo " clean clean the sysroot, initramfs, build and output files"
@echo ""
@echo "The output file is \"run.out\". Test ranges may be passed using \$$TEST."
@echo ""
@echo "Currently using the following variables:"
@echo " ARCH = $(ARCH)"
+ @echo " XARCH = $(XARCH)"
@echo " CROSS_COMPILE = $(CROSS_COMPILE)"
@echo " CC = $(CC)"
@echo " OUTPUT = $(OUTPUT)"
@echo " TEST = $(TEST)"
- @echo " QEMU_ARCH = $(if $(QEMU_ARCH),$(QEMU_ARCH),UNKNOWN_ARCH) [determined from \$$ARCH]"
- @echo " IMAGE_NAME = $(if $(IMAGE_NAME),$(IMAGE_NAME),UNKNOWN_ARCH) [determined from \$$ARCH]"
+ @echo " QEMU_ARCH = $(if $(QEMU_ARCH),$(QEMU_ARCH),UNKNOWN_ARCH) [determined from \$$XARCH]"
+ @echo " IMAGE_NAME = $(if $(IMAGE_NAME),$(IMAGE_NAME),UNKNOWN_ARCH) [determined from \$$XARCH]"
@echo ""

all: run
--
2.25.1


2023-08-01 21:15:31

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v4 02/12] tools/nolibc: add support for powerpc64

This follows the 64-bit PowerPC ABI [1], refers to the slides: "A new
ABI for little-endian PowerPC64 Design & Implementation" [2] and the
musl code in arch/powerpc64/crt_arch.h.

First, stdu and clrrdi are used instead of stwu and clrrwi for
powerpc64.

Second, the stack frame size is increased to 32 bytes for powerpc64, 32
bytes is the minimal stack frame size supported described in [2].

Besides, the TOC pointer (GOT pointer) must be saved to r2.

This works on both little endian and big endian 64-bit PowerPC.

[1]: https://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.pdf
[2]: https://www.llvm.org/devmtg/2014-04/PDFs/Talks/Euro-LLVM-2014-Weigand.pdf

Reviewed-by: Thomas Weißschuh <[email protected]>
Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/include/nolibc/arch-powerpc.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/tools/include/nolibc/arch-powerpc.h b/tools/include/nolibc/arch-powerpc.h
index caa943e1521a..d783ed0b5dbd 100644
--- a/tools/include/nolibc/arch-powerpc.h
+++ b/tools/include/nolibc/arch-powerpc.h
@@ -175,6 +175,19 @@
/* startup code */
void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_stack_protector _start(void)
{
+#ifdef __powerpc64__
+ /* On 64-bit PowerPC, save TOC/GOT pointer to r2 */
+ extern char TOC __asm__ (".TOC.");
+ register volatile long r2 __asm__ ("r2") = (void *)&TOC - (void *)_start;
+
+ __asm__ volatile (
+ "mr 3, 1\n" /* save stack pointer to r3, as arg1 of _start_c */
+ "clrrdi 1, 1, 4\n" /* align the stack to 16 bytes */
+ "li 0, 0\n" /* zero the frame pointer */
+ "stdu 1, -32(1)\n" /* the initial stack frame */
+ "bl _start_c\n" /* transfer to c runtime */
+ );
+#else
__asm__ volatile (
"mr 3, 1\n" /* save stack pointer to r3, as arg1 of _start_c */
"clrrwi 1, 1, 4\n" /* align the stack to 16 bytes */
@@ -182,6 +195,7 @@ void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_
"stwu 1, -16(1)\n" /* the initial stack frame */
"bl _start_c\n" /* transfer to c runtime */
);
+#endif
__builtin_unreachable();
}

--
2.25.1


2023-08-02 06:52:22

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v4 08/12] selftests/nolibc: add test support for ppc

Hi, Willy, Thomas

Yuan is helping me to test this series and the tinyconfig series with
the latest compilers.

His first test found this ppc support failed with stackprotector when
using a newer compiler (I used an older compiler without stackprotector
for ppc), I'm debugging it, so, please ignore this revision too, of
course, if time allows, welcome to take a look at the other patches.

His other tests are trying to find out the exact poweroff support
options for every architecture one by one, let's fill this gap ...

Thanks,
Zhangjin

> Kernel uses ARCH=powerpc for both 32-bit and 64-bit PowerPC, here adds a
> ppc variant for 32-bit PowerPC and uses it as the default variant of
> powerpc architecture.
>
> Users can pass ARCH=powerpc or XARCH=ppc to test 32-bit PowerPC.
>
> The default qemu-system-ppc g3beige machine [1] is used to run 32-bit
> powerpc kernel.
>
> The pmac32_defconfig is used with extra PMACZILOG console options to
> enable normal print.
>
> Note, zImage doesn't boot due to "qemu-system-ppc: Some ROM regions are
> overlapping" error, so, vmlinux is used instead.
>
> [1]: https://qemu.readthedocs.io/en/latest/system/ppc/powermac.html
>
> Suggested-by: Willy Tarreau <[email protected]>
> Link: https://lore.kernel.org/lkml/[email protected]/
> Reviewed-by: Thomas Weißschuh <[email protected]>
> Signed-off-by: Zhangjin Wu <[email protected]>
> ---
> tools/testing/selftests/nolibc/Makefile | 6 ++++++
> .../testing/selftests/nolibc/configs/nolibc-test-ppc.config | 3 +++
> 2 files changed, 9 insertions(+)
> create mode 100644 tools/testing/selftests/nolibc/configs/nolibc-test-ppc.config
>
> diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
> index 3c9e3963fbad..29e02b49903a 100644
> --- a/tools/testing/selftests/nolibc/Makefile
> +++ b/tools/testing/selftests/nolibc/Makefile
> @@ -33,9 +33,11 @@ endif
> # architectures where both are equal.
>
> # configure default variants for target kernel supported architectures
> +XARCH_powerpc = ppc
> XARCH = $(or $(XARCH_$(ARCH)),$(ARCH))
>
> # map from user input variants to their kernel supported architectures
> +ARCH_ppc = powerpc
> ARCH := $(or $(ARCH_$(XARCH)),$(XARCH))
>
> # kernel image names by architecture
> @@ -45,6 +47,7 @@ IMAGE_x86 = arch/x86/boot/bzImage
> IMAGE_arm64 = arch/arm64/boot/Image
> IMAGE_arm = arch/arm/boot/zImage
> IMAGE_mips = vmlinuz
> +IMAGE_ppc = vmlinux
> IMAGE_riscv = arch/riscv/boot/Image
> IMAGE_s390 = arch/s390/boot/bzImage
> IMAGE_loongarch = arch/loongarch/boot/vmlinuz.efi
> @@ -58,6 +61,7 @@ DEFCONFIG_x86 = defconfig
> DEFCONFIG_arm64 = defconfig
> DEFCONFIG_arm = multi_v7_defconfig
> DEFCONFIG_mips = malta_defconfig
> +DEFCONFIG_ppc = pmac32_defconfig
> DEFCONFIG_riscv = defconfig
> DEFCONFIG_s390 = defconfig
> DEFCONFIG_loongarch = defconfig
> @@ -77,6 +81,7 @@ QEMU_ARCH_x86 = x86_64
> QEMU_ARCH_arm64 = aarch64
> QEMU_ARCH_arm = arm
> QEMU_ARCH_mips = mipsel # works with malta_defconfig
> +QEMU_ARCH_ppc = ppc
> QEMU_ARCH_riscv = riscv64
> QEMU_ARCH_s390 = s390x
> QEMU_ARCH_loongarch = loongarch64
> @@ -89,6 +94,7 @@ QEMU_ARGS_x86 = -M pc -append "console=ttyS0,9600 i8042.noaux panic=-1 $(
> QEMU_ARGS_arm64 = -M virt -cpu cortex-a53 -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)"
> QEMU_ARGS_arm = -M virt -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)"
> QEMU_ARGS_mips = -M malta -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)"
> +QEMU_ARGS_ppc = -M g3beige -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
> QEMU_ARGS_riscv = -M virt -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
> QEMU_ARGS_s390 = -M s390-ccw-virtio -m 1G -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
> QEMU_ARGS_loongarch = -M virt -append "console=ttyS0,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
> diff --git a/tools/testing/selftests/nolibc/configs/nolibc-test-ppc.config b/tools/testing/selftests/nolibc/configs/nolibc-test-ppc.config
> new file mode 100644
> index 000000000000..b1975f8253f7
> --- /dev/null
> +++ b/tools/testing/selftests/nolibc/configs/nolibc-test-ppc.config
> @@ -0,0 +1,3 @@
> +CONFIG_SERIAL_PMACZILOG=y
> +CONFIG_SERIAL_PMACZILOG_TTYS=y
> +CONFIG_SERIAL_PMACZILOG_CONSOLE=y
> --
> 2.25.1

2023-08-02 08:58:28

by Willy Tarreau

[permalink] [raw]
Subject: Re: [PATCH v4 08/12] selftests/nolibc: add test support for ppc

Hi Zhangjin,

On Wed, Aug 02, 2023 at 01:21:50PM +0800, Zhangjin Wu wrote:
> Hi, Willy, Thomas
>
> Yuan is helping me to test this series and the tinyconfig series with
> the latest compilers.
>
> His first test found this ppc support failed with stackprotector when
> using a newer compiler (I used an older compiler without stackprotector
> for ppc), I'm debugging it, so, please ignore this revision too, of
> course, if time allows, welcome to take a look at the other patches.
>
> His other tests are trying to find out the exact poweroff support
> options for every architecture one by one, let's fill this gap ...

Thanks for notifying us. I strongly suggest that you leave ppc32 aside
for now, until the rest is completely validated and merged. It turns
out that your willingness to work around some of the oddities met on
this one have resulted in a lot of drift away from the "keep it simple"
principle and significantly delayed the possibilities to integrate the
rest of your work. It would be much saner to only focus on ppc64/ppc64le
and figure later how to make ppc32 work (or decide not to support it if
it's not worth the effort in the end).

Regards,
willy

2023-08-02 11:15:25

by Zhangjin Wu

[permalink] [raw]
Subject: Re: [PATCH v4 08/12] selftests/nolibc: add test support for ppc

Hi, Willy, Hi Thomas

Good news for us ;-)

> Hi Zhangjin,
>
> On Wed, Aug 02, 2023 at 01:21:50PM +0800, Zhangjin Wu wrote:
> > Hi, Willy, Thomas
> >
> > Yuan is helping me to test this series and the tinyconfig series with
> > the latest compilers.
> >
> > His first test found this ppc support failed with stackprotector when
> > using a newer compiler (I used an older compiler without stackprotector
> > for ppc), I'm debugging it, so, please ignore this revision too, of
> > course, if time allows, welcome to take a look at the other patches.
> >
> > His other tests are trying to find out the exact poweroff support
> > options for every architecture one by one, let's fill this gap ...
>
> Thanks for notifying us. I strongly suggest that you leave ppc32 aside
> for now, until the rest is completely validated and merged. It turns

Thanks very much, but good progress here ;-)

I compared some compilers and at last got the root cause of the ppc32
failure with stackprotector.

//// gcc 13.1.0 from mirrors.edge.kernel.org

$ make run-user XARCH=ppc -j4 CC=/labs/linux-lab/prebuilt/toolchains/ppc64le/gcc-13.1.0-nolibc/powerpc64-linux/bin/powerpc64-linux-gcc
...
Segmentation fault (core dumped)

0 test(s): 0 passed, 0 skipped, 0 failed => status: success

See all results in /labs/linux-lab/src/linux-stable/tools/testing/selftests/nolibc/run.out

//// gcc 10 from ubuntu ppa

$ make run-user XARCH=ppc -j4 CC=/usr/bin/powerpc-linux-gnu-gcc-10
...
165 test(s): 157 passed, 8 skipped, 0 failed => status: warning

See all results in /labs/linux-lab/src/linux-stable/tools/testing/selftests/nolibc/run.out

$ grep stack run.out
0 -fstackprotector [OK]

And then compared the assemblies, found gcc 13.1.0 insert a bad
instruction at the beginning of _start() and break our stack eventually.

start:
stwu 1,-16(1)

Further compared the preprocessed files, found the root cause is the new
compiler using 'no_stack_protector' instead of
'__optimize__("-fno-stack-protector")'. And the attribute 'no_stack_protector'
breaks our "omit-frame-pointer" like the failure with '-O0' we fixed before.

I checked some of the other architectures, they didn't have the same issue, but
test shows the 'no_stack_protector' attribute does have such compability issue
here.

I learned the commit message of tools/include/nolibc/compiler.h, seems
__optimize__("-fno-stack-protector") is enough for all of the nolibc supported
architectures? is it ok for us to simply give up 'no_stack_protector'
eventully? otherwise, we should manually disable 'no_stack_protector' for
ppc32:

#define __no_stack_protector __attribute__((__optimize__("-fno-stack-protector")))

Benefit from the __no_stack_protetor macro, we have no need to input
__optimize__("-fno-stack-protector") for every new architecture, it may be the
time to only use __optimize__("-fno-stack-protector"), am I missing something?

> out that your willingness to work around some of the oddities met on
> this one have resulted in a lot of drift away from the "keep it simple"
> principle and significantly delayed the possibilities to integrate the
> rest of your work. It would be much saner to only focus on ppc64/ppc64le
> and figure later how to make ppc32 work (or decide not to support it if
> it's not worth the effort in the end).

Another test shows, the run target of ppc64le with the big endian gcc 13.1.0
toolchain has test startup failure (although we have verified run-user before,
run-user ok! and run with local powerpc64le toolchain ok too!), I'm debugging
this now, hope it not cost too much.

Another good news is, Yuan has found a working defconfig for ppc32 which has
poweroff support and he is helping me narrowing down the exact options, this
will eventually make us happy ;-)

Thanks & Best regards,
Zhangjin

>
> Regards,
> willy

2023-08-02 17:29:19

by Zhangjin Wu

[permalink] [raw]
Subject: Re: [PATCH v4 08/12] selftests/nolibc: add test support for ppc

Hi, Willy, Hi Thomas

I'm so happy to share with you, we have solved all of the left found
issues, include the ones about ppc and the missing poweroff options for
the tinyconfig series, will renew both series ;-)

> Further compared the preprocessed files, found the root cause is the new
> compiler using 'no_stack_protector' instead of
> '__optimize__("-fno-stack-protector")'. And the attribute 'no_stack_protector'
> breaks our "omit-frame-pointer" like the failure with '-O0' we fixed before.
>
> I checked some of the other architectures, they didn't have the same issue, but
> test shows the 'no_stack_protector' attribute does have such compability issue
> here.
>
> I learned the commit message of tools/include/nolibc/compiler.h, seems
> __optimize__("-fno-stack-protector") is enough for all of the nolibc supported
> architectures? is it ok for us to simply give up 'no_stack_protector'
> eventully? otherwise, we should manually disable 'no_stack_protector' for
> ppc32:
>
> #define __no_stack_protector __attribute__((__optimize__("-fno-stack-protector")))
>

Hello, any suggestion here? ;-)

BTW, we have found another -O0 + "omit-frame-pointer" regression with
gcc 13.1.0 on all architectures ("omit-frame-pointer" will be completely
ignored when -O0 passed whatever other internal optimize attribute like
'Os' we used together in commit '4dc4401991fc' for gcc < 11.1.0), Yuan
is doing more tests to confirm it, will open another discussion for it.

> Benefit from the __no_stack_protetor macro, we have no need to input
> __optimize__("-fno-stack-protector") for every new architecture, it may be the
> time to only use __optimize__("-fno-stack-protector"), am I missing something?
>
> > out that your willingness to work around some of the oddities met on
> > this one have resulted in a lot of drift away from the "keep it simple"
> > principle and significantly delayed the possibilities to integrate the
> > rest of your work. It would be much saner to only focus on ppc64/ppc64le
> > and figure later how to make ppc32 work (or decide not to support it if
> > it's not worth the effort in the end).
>
> Another test shows, the run target of ppc64le with the big endian gcc 13.1.0
> toolchain has test startup failure (although we have verified run-user before,
> run-user ok! and run with local powerpc64le toolchain ok too!), I'm debugging
> this now, hope it not cost too much.

Just solved this, when -mabi=elfv2 supported by the toolchain (gcc
13.1.0 has this option), kernel will compile with this ABI, to align
with kernel, our user space application should use -mabi=elfv2 too if
toolchain support it, otherwise, test will simply fails at startup, this
solves it:

$(call cc-option,-mabi=elfv2)

>
> Another good news is, Yuan has found a working defconfig for ppc32 which has
> poweroff support and he is helping me narrowing down the exact options, this
> will eventually make us happy ;-)
>

We eventually find the missing poweroff option for ppc32, will update
the patches with them.

we also found such options for all of the nolibc supported
architectures, will add them in their tinyconfig support patches.

Thanks,
Zhangjin

> Thanks & Best regards,
> Zhangjin
>
> >
> > Regards,
> > willy

2023-08-02 22:05:49

by Thomas Weißschuh

[permalink] [raw]
Subject: Re: [PATCH v4 08/12] selftests/nolibc: add test support for ppc

On 2023-08-03 00:03:58+0800, Zhangjin Wu wrote:
> Hi, Willy, Hi Thomas
>
> I'm so happy to share with you, we have solved all of the left found
> issues, include the ones about ppc and the missing poweroff options for
> the tinyconfig series, will renew both series ;-)

Can we stick to one series at a time?

> > Further compared the preprocessed files, found the root cause is the new
> > compiler using 'no_stack_protector' instead of
> > '__optimize__("-fno-stack-protector")'. And the attribute 'no_stack_protector'
> > breaks our "omit-frame-pointer" like the failure with '-O0' we fixed before.
> >
> > I checked some of the other architectures, they didn't have the same issue, but
> > test shows the 'no_stack_protector' attribute does have such compability issue
> > here.
> >
> > I learned the commit message of tools/include/nolibc/compiler.h, seems
> > __optimize__("-fno-stack-protector") is enough for all of the nolibc supported
> > architectures? is it ok for us to simply give up 'no_stack_protector'
> > eventully? otherwise, we should manually disable 'no_stack_protector' for
> > ppc32:
> >
> > #define __no_stack_protector __attribute__((__optimize__("-fno-stack-protector")))
> >
>
> Hello, any suggestion here? ;-)

Patience :-)

no_stack_protector is the offically documented mechanism to disable
stack protector for a function. As it works for all other architectures
this seems like a compiler bug.

If we want to work around it I would prefer to have both attributes.

> [..]

Thomas

2023-08-03 02:24:33

by Willy Tarreau

[permalink] [raw]
Subject: Re: [PATCH v4 08/12] selftests/nolibc: add test support for ppc

On Wed, Aug 02, 2023 at 11:36:30PM +0200, Thomas Wei?schuh wrote:
> On 2023-08-03 00:03:58+0800, Zhangjin Wu wrote:
> > Hi, Willy, Hi Thomas
> >
> > I'm so happy to share with you, we have solved all of the left found
> > issues, include the ones about ppc and the missing poweroff options for
> > the tinyconfig series, will renew both series ;-)
>
> Can we stick to one series at a time?

Yes and please this time, let's stick exclusively to what is sufficiently
tested for 6.6, otherwise it will have to be delayed.

> > > Further compared the preprocessed files, found the root cause is the new
> > > compiler using 'no_stack_protector' instead of
> > > '__optimize__("-fno-stack-protector")'. And the attribute 'no_stack_protector'
> > > breaks our "omit-frame-pointer" like the failure with '-O0' we fixed before.
> > >
> > > I checked some of the other architectures, they didn't have the same issue, but
> > > test shows the 'no_stack_protector' attribute does have such compability issue
> > > here.
> > >
> > > I learned the commit message of tools/include/nolibc/compiler.h, seems
> > > __optimize__("-fno-stack-protector") is enough for all of the nolibc supported
> > > architectures? is it ok for us to simply give up 'no_stack_protector'
> > > eventully? otherwise, we should manually disable 'no_stack_protector' for
> > > ppc32:
> > >
> > > #define __no_stack_protector __attribute__((__optimize__("-fno-stack-protector")))
> > >
> >
> > Hello, any suggestion here? ;-)
>
> Patience :-)
>
> no_stack_protector is the offically documented mechanism to disable
> stack protector for a function. As it works for all other architectures
> this seems like a compiler bug.

Or a limitation. To be honest we're playing with compiler limits by
adjusting their optimizations per function. But as long as we don't
break what currently works, we can accept to have some limits in a first
version (e.g. if ppc32 doesn't support -O0 for now it's not dramatic).
Also, some other archs use optimize("Os", "omit-frame-pointer")), maybe
that's needed there as well.

> If we want to work around it I would prefer to have both attributes.

Also if you remember we also used to have a work-around for the
function's entry code consisting in renaming _start and having a _start
pointer in the asm code itself. That can remain an option to experiment
with later. But let's not change everything again at the last minute,
all these series have been sufficiently difficult to follow :-(

thanks,
Willy

2023-08-03 03:54:09

by Zhangjin Wu

[permalink] [raw]
Subject: Re: [PATCH v4 08/12] selftests/nolibc: add test support for ppc

Hi,

> On Wed, Aug 02, 2023 at 11:36:30PM +0200, Thomas Wei?schuh wrote:
> > On 2023-08-03 00:03:58+0800, Zhangjin Wu wrote:
> > > Hi, Willy, Hi Thomas
> > >
> > > I'm so happy to share with you, we have solved all of the left found
> > > issues, include the ones about ppc and the missing poweroff options for
> > > the tinyconfig series, will renew both series ;-)
> >
> > Can we stick to one series at a time?
>
> Yes and please this time, let's stick exclusively to what is sufficiently
> tested for 6.6, otherwise it will have to be delayed.
>

Yes, ppc series at first, will renew it today. let's delay the whole tinyconfig
series (include part1) in v6.7, we have no enough time to test them carefully
for v6.6.

> > > > Further compared the preprocessed files, found the root cause is the new
> > > > compiler using 'no_stack_protector' instead of
> > > > '__optimize__("-fno-stack-protector")'. And the attribute 'no_stack_protector'
> > > > breaks our "omit-frame-pointer" like the failure with '-O0' we fixed before.
> > > >
> > > > I checked some of the other architectures, they didn't have the same issue, but
> > > > test shows the 'no_stack_protector' attribute does have such compability issue
> > > > here.
> > > >
> > > > I learned the commit message of tools/include/nolibc/compiler.h, seems
> > > > __optimize__("-fno-stack-protector") is enough for all of the nolibc supported
> > > > architectures? is it ok for us to simply give up 'no_stack_protector'
> > > > eventully? otherwise, we should manually disable 'no_stack_protector' for
> > > > ppc32:
> > > >
> > > > #define __no_stack_protector __attribute__((__optimize__("-fno-stack-protector")))
> > > >
> > >
> > > Hello, any suggestion here? ;-)
> >
> > Patience :-)
> >
> > no_stack_protector is the offically documented mechanism to disable
> > stack protector for a function. As it works for all other architectures
> > this seems like a compiler bug.
>
> Or a limitation. To be honest we're playing with compiler limits by
> adjusting their optimizations per function. But as long as we don't
> break what currently works, we can accept to have some limits in a first
> version (e.g. if ppc32 doesn't support -O0 for now it's not dramatic).
> Also, some other archs use optimize("Os", "omit-frame-pointer")), maybe
> that's needed there as well.
>

Since it is really related, let's summarize yesterdays's further test here for
a reference:

Yesterday's test result on randomly chosen x86_64 and riscv64 shows,
from at least gcc 12.3.0 (may differs from archs), even with
optimize("Os", "omit-frame-pointer")), whatever with or without
'-fno-stack-protector', -O0 forbids the per function's
"omit-frame-pointer" as the doc [1] describes (as we discussed before),
that means some imtermediate gcc versions deviate from their docs and
now, the latest gcc version come back to follow its doc [1] and become
even more strict and then breaks our optimize("Os",
"omit-frame-pointer") workaround eventually:

Most optimizations are completely disabled at -O0 or if an -O level
is not set on the command line, even if individual optimization
flags are specified.

So, it is ok for us to simply ignore -O0 currently, let's work on them
in v6.7.

[1]: https://gcc.gnu.org/onlinedocs/gcc-13.1.0/gcc/Optimize-Options.html

> > If we want to work around it I would prefer to have both attributes.
>
> Also if you remember we also used to have a work-around for the
> function's entry code consisting in renaming _start and having a _start
> pointer in the asm code itself. That can remain an option to experiment
> with later.

Yes, the 'asm' style of _start may be a choice to prevent gcc touching
our startup code.

> But let's not change everything again at the last minute,

It is reasonable.

> all these series have been sufficiently difficult to follow :-(
>

Thanks,
Zhangjin

> thanks,
> Willy

2023-08-03 05:24:02

by Willy Tarreau

[permalink] [raw]
Subject: Re: [PATCH v4 08/12] selftests/nolibc: add test support for ppc

On Thu, Aug 03, 2023 at 10:58:55AM +0800, Zhangjin Wu wrote:
> Yes, ppc series at first, will renew it today. let's delay the whole tinyconfig
> series (include part1) in v6.7, we have no enough time to test them carefully
> for v6.6.

Thanks.

> > > > > Further compared the preprocessed files, found the root cause is the new
> > > > > compiler using 'no_stack_protector' instead of
> > > > > '__optimize__("-fno-stack-protector")'. And the attribute 'no_stack_protector'
> > > > > breaks our "omit-frame-pointer" like the failure with '-O0' we fixed before.
> > > > >
> > > > > I checked some of the other architectures, they didn't have the same issue, but
> > > > > test shows the 'no_stack_protector' attribute does have such compability issue
> > > > > here.
> > > > >
> > > > > I learned the commit message of tools/include/nolibc/compiler.h, seems
> > > > > __optimize__("-fno-stack-protector") is enough for all of the nolibc supported
> > > > > architectures? is it ok for us to simply give up 'no_stack_protector'
> > > > > eventully? otherwise, we should manually disable 'no_stack_protector' for
> > > > > ppc32:
> > > > >
> > > > > #define __no_stack_protector __attribute__((__optimize__("-fno-stack-protector")))
> > > > >
> > > >
> > > > Hello, any suggestion here? ;-)
> > >
> > > Patience :-)
> > >
> > > no_stack_protector is the offically documented mechanism to disable
> > > stack protector for a function. As it works for all other architectures
> > > this seems like a compiler bug.
> >
> > Or a limitation. To be honest we're playing with compiler limits by
> > adjusting their optimizations per function. But as long as we don't
> > break what currently works, we can accept to have some limits in a first
> > version (e.g. if ppc32 doesn't support -O0 for now it's not dramatic).
> > Also, some other archs use optimize("Os", "omit-frame-pointer")), maybe
> > that's needed there as well.
> >
>
> Since it is really related, let's summarize yesterdays's further test here for
> a reference:
>
> Yesterday's test result on randomly chosen x86_64 and riscv64 shows,
> from at least gcc 12.3.0 (may differs from archs), even with
> optimize("Os", "omit-frame-pointer")), whatever with or without
> '-fno-stack-protector', -O0 forbids the per function's
> "omit-frame-pointer" as the doc [1] describes (as we discussed before),
> that means some imtermediate gcc versions deviate from their docs and
> now, the latest gcc version come back to follow its doc [1] and become
> even more strict and then breaks our optimize("Os",
> "omit-frame-pointer") workaround eventually:
>
> Most optimizations are completely disabled at -O0 or if an -O level
> is not set on the command line, even if individual optimization
> flags are specified.

Note that the quoted paragraph above is mostly independent. The point
here is that optimize("-Os") seems to be ignored then -O0 is passed
on the command line. But I'm not that much surprised, because as we
said, changing optimizations on the fly is tricky given that some have
effects beyond just a function.

> So, it is ok for us to simply ignore -O0 currently, let's work on them
> in v6.7.

Yeah I'm fine with this. In the worst case those using -O0 can also avoid
using stack-protector.

> > > If we want to work around it I would prefer to have both attributes.
> >
> > Also if you remember we also used to have a work-around for the
> > function's entry code consisting in renaming _start and having a _start
> > pointer in the asm code itself. That can remain an option to experiment
> > with later.
>
> Yes, the 'asm' style of _start may be a choice to prevent gcc touching
> our startup code.

That was the case. We had an earlier version where _start was a label
inside the asm statement, resulting in some unused prologue and epilogue
for the function around that code. It was a bit ugly and I think it had
some shortcomings but we may go back to that later if it brings some
value.

Willy

2023-08-03 08:26:45

by Zhangjin Wu

[permalink] [raw]
Subject: Re: [PATCH v4 08/12] selftests/nolibc: add test support for ppc

Hi, Willy

> On Thu, Aug 03, 2023 at 10:58:55AM +0800, Zhangjin Wu wrote:
> > Yes, ppc series at first, will renew it today. let's delay the whole tinyconfig
> > series (include part1) in v6.7, we have no enough time to test them carefully
> > for v6.6.
>
> Thanks.
>

To even further simplify the ppc series merge progress, since Yuan have helped
me sending the standalone serial console enable patch for pmac32_defconfig [1],
and it has gotten a Reviewed-by line from the ppc maintainer, perhaps we can
safely expect it in v6.6, so, I plan to delay the nolibc-test-config related
stuff and minimize the whole ppc series to only these necessary patches:

$ git log --reverse --oneline 813cab75752d9f2bbd71179b0c43c1052515cf48^..HEAD
813cab75752d tools/nolibc: add support for powerpc
122e2610c649 tools/nolibc: add support for powerpc64
f31fe18cf2e2 selftests/nolibc: add XARCH and ARCH mapping support
b25c71125154 selftests/nolibc: add test support for ppc
27bc0026f1e7 selftests/nolibc: add test support for ppc64le
d70649478ef8 (HEAD -> v6.6-nolibc-202308031233-pure-ppc-v5) selftests/nolibc: add test support for ppc64

After this ppc series, if you are still happy with parts of the left ones, I
will renew them.

[1]: https://lore.kernel.org/lkml/bb7b5f9958b3e3a20f6573ff7ce7c5dc566e7e32.1690982937.git.tanyuan@tinylab.org/

>
> [...]
> > So, it is ok for us to simply ignore -O0 currently, let's work on them
> > in v6.7.
>
> Yeah I'm fine with this. In the worst case those using -O0 can also avoid
> using stack-protector.
>

Yeah, let's ignore -O0 here.

but must clarify that, even with the default "-Os" from command line,
when using gcc 13.1.0, it has '__no_stack_protector' attribute but this
attribute breaks 'omit-frame-pointer' and result in segfaults. To avoid
touching the common code, I plan to let ppc32 uses its own
__no_stack_protector with '__optimize__("-fno-stack-protector")', I hope
it is fair enough now ;-)

Here is what I have added for arch-powerpc.h in the first patch of the series:

/* FIXME: For ppc32, with newer gcc compilers (e.g. gcc 13.1.0),
* "omit-frame-pointer" fails with __attribute__((no_stack_protector)) but
* works with __attribute__((__optimize__("-fno-stack-protector")))
*/
#ifdef __no_stack_protector
#undef __no_stack_protector
#define __no_stack_protector __attribute__((__optimize__("-fno-stack-protector")))
#endif

If you are happy with this, v5 with come with it.

Thanks!

Best regards,
Zhangjin

>
> Willy