2023-02-08 10:19:00

by Feiyang Chen

[permalink] [raw]
Subject: [PATCH v2 0/5] Add LoongArch support to nolibc

From: Feiyang Chen <[email protected]>

Add statx() and make stat() rely on statx() when available.
Add support for LoongArch (32 and 64 bit) to nolibc.
It was tested on LoongArch64 only.

The latest QEMU support full-system emulation of a LoongArch64
machine, but for the moment we need to specify the firmware manually.
https://github.com/loongson/Firmware/tree/main/LoongArchVirtMachine

QEMU_ARGS_loongarch = -M virt -bios edk2-loongarch64-code.fd ...

v2:
- Mention that statx() will also benefit other architectures.
- Make stat() rely on statx() when available.
- Put the whitespace changes into one commit.

Feiyang Chen (5):
tools/nolibc: Include linux/fcntl.h and remove duplicate code
tools/nolibc: Add statx() and make stat() rely on statx() when
available
tools/nolibc: Add support for LoongArch
selftests/nolibc: Add support for LoongArch
selftests/nolibc: Adjust indentation for Makefile

tools/include/nolibc/arch-loongarch.h | 200 ++++++++++++++++++++++++
tools/include/nolibc/arch.h | 2 +
tools/include/nolibc/sys.h | 53 ++++++-
tools/include/nolibc/types.h | 5 -
tools/testing/selftests/nolibc/Makefile | 78 ++++-----
5 files changed, 295 insertions(+), 43 deletions(-)
create mode 100644 tools/include/nolibc/arch-loongarch.h

--
2.39.0



2023-02-08 10:19:04

by Feiyang Chen

[permalink] [raw]
Subject: [PATCH v2 1/5] tools/nolibc: Include linux/fcntl.h and remove duplicate code

From: Feiyang Chen <[email protected]>

Include linux/fcntl.h for O_* and AT_*. asm/fcntl.h is included
by linux/fcntl.h, so it can be safely removed.

Signed-off-by: Feiyang Chen <[email protected]>
---
tools/include/nolibc/sys.h | 2 +-
tools/include/nolibc/types.h | 5 -----
2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index b5f8cd35c03b..c4818a9c8823 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -11,7 +11,6 @@
#include "std.h"

/* system includes */
-#include <asm/fcntl.h> // for O_*
#include <asm/unistd.h>
#include <asm/signal.h> // for SIGCHLD
#include <asm/ioctls.h>
@@ -20,6 +19,7 @@
#include <linux/loop.h>
#include <linux/time.h>
#include <linux/auxvec.h>
+#include <linux/fcntl.h> // for O_* and AT_*

#include "arch.h"
#include "errno.h"
diff --git a/tools/include/nolibc/types.h b/tools/include/nolibc/types.h
index fbbc0e68c001..a3651c514e2f 100644
--- a/tools/include/nolibc/types.h
+++ b/tools/include/nolibc/types.h
@@ -60,11 +60,6 @@
#define MAXPATHLEN (PATH_MAX)
#endif

-/* Special FD used by all the *at functions */
-#ifndef AT_FDCWD
-#define AT_FDCWD (-100)
-#endif
-
/* whence values for lseek() */
#define SEEK_SET 0
#define SEEK_CUR 1
--
2.39.0


2023-02-08 10:19:08

by Feiyang Chen

[permalink] [raw]
Subject: [PATCH v2 2/5] tools/nolibc: Add statx() and make stat() rely on statx() when available

From: Feiyang Chen <[email protected]>

loongarch and riscv32 only have statx(). arc, hexagon, nios2 and
openrisc have statx() and stat64() but not stat() or newstat().
Add statx() and make stat() rely on statx() to make them happy.

Signed-off-by: Feiyang Chen <[email protected]>
---
tools/include/nolibc/sys.h | 51 ++++++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)

diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index c4818a9c8823..46b6b3bb3b4e 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -20,6 +20,7 @@
#include <linux/time.h>
#include <linux/auxvec.h>
#include <linux/fcntl.h> // for O_* and AT_*
+#include <linux/stat.h> // for statx()

#include "arch.h"
#include "errno.h"
@@ -1048,12 +1049,61 @@ pid_t setsid(void)
return ret;
}

+/*
+ * int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf);
+ */
+
+static __attribute__((unused))
+int sys_statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf)
+{
+ return my_syscall5(__NR_statx, fd, path, flags, mask, buf);
+}
+
+static __attribute__((unused))
+int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf)
+{
+ int ret = sys_statx(fd, path, flags, mask, buf);
+
+ if (ret < 0) {
+ SET_ERRNO(-ret);
+ ret = -1;
+ }
+ return ret;
+}

/*
* int stat(const char *path, struct stat *buf);
* Warning: the struct stat's layout is arch-dependent.
*/

+#ifdef __NR_statx
+static __attribute__((unused))
+int sys_stat(const char *path, struct stat *buf)
+{
+ struct statx stat;
+ long ret;
+
+ ret = sys_statx(AT_FDCWD, path, AT_NO_AUTOMOUNT, STATX_BASIC_STATS, &stat);
+ buf->st_dev = ((stat.stx_dev_minor & 0xff)
+ | (stat.stx_dev_major << 8)
+ | ((stat.stx_dev_minor & ~0xff) << 12));
+ buf->st_ino = stat.stx_ino;
+ buf->st_mode = stat.stx_mode;
+ buf->st_nlink = stat.stx_nlink;
+ buf->st_uid = stat.stx_uid;
+ buf->st_gid = stat.stx_gid;
+ buf->st_rdev = ((stat.stx_rdev_minor & 0xff)
+ | (stat.stx_rdev_major << 8)
+ | ((stat.stx_rdev_minor & ~0xff) << 12));
+ buf->st_size = stat.stx_size;
+ buf->st_blksize = stat.stx_blksize;
+ buf->st_blocks = stat.stx_blocks;
+ buf->st_atime = stat.stx_atime.tv_sec;
+ buf->st_mtime = stat.stx_mtime.tv_sec;
+ buf->st_ctime = stat.stx_ctime.tv_sec;
+ return ret;
+}
+#else
static __attribute__((unused))
int sys_stat(const char *path, struct stat *buf)
{
@@ -1083,6 +1133,7 @@ int sys_stat(const char *path, struct stat *buf)
buf->st_ctime = stat.st_ctime;
return ret;
}
+#endif /* __NR_statx */

static __attribute__((unused))
int stat(const char *path, struct stat *buf)
--
2.39.0


2023-02-08 10:19:11

by Feiyang Chen

[permalink] [raw]
Subject: [PATCH v2 3/5] tools/nolibc: Add support for LoongArch

From: Feiyang Chen <[email protected]>

Add support for LoongArch (32 and 64 bit) to nolibc.

Signed-off-by: Feiyang Chen <[email protected]>
---
tools/include/nolibc/arch-loongarch.h | 200 ++++++++++++++++++++++++++
tools/include/nolibc/arch.h | 2 +
2 files changed, 202 insertions(+)
create mode 100644 tools/include/nolibc/arch-loongarch.h

diff --git a/tools/include/nolibc/arch-loongarch.h b/tools/include/nolibc/arch-loongarch.h
new file mode 100644
index 000000000000..029ee3cd6baf
--- /dev/null
+++ b/tools/include/nolibc/arch-loongarch.h
@@ -0,0 +1,200 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * LoongArch specific definitions for NOLIBC
+ * Copyright (C) 2023 Loongson Technology Corporation Limited
+ */
+
+#ifndef _NOLIBC_ARCH_LOONGARCH_H
+#define _NOLIBC_ARCH_LOONGARCH_H
+
+/* Syscalls for LoongArch :
+ * - stack is 16-byte aligned
+ * - syscall number is passed in a7
+ * - arguments are in a0, a1, a2, a3, a4, a5
+ * - the system call is performed by calling "syscall 0"
+ * - syscall return comes in a0
+ * - 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.
+ *
+ * On LoongArch, select() is not implemented so we have to use pselect6().
+ */
+#define __ARCH_WANT_SYS_PSELECT6
+
+#define my_syscall0(num) \
+({ \
+ register long _num __asm__ ("a7") = (num); \
+ register long _arg1 __asm__ ("a0"); \
+ \
+ __asm__ volatile ( \
+ "syscall 0\n" \
+ : "=r"(_arg1) \
+ : "r"(_num) \
+ : "memory", "$t0", "$t1", "$t2", "$t3", \
+ "$t4", "$t5", "$t6", "$t7", "$t8" \
+ ); \
+ _arg1; \
+})
+
+#define my_syscall1(num, arg1) \
+({ \
+ register long _num __asm__ ("a7") = (num); \
+ register long _arg1 __asm__ ("a0") = (long)(arg1); \
+ \
+ __asm__ volatile ( \
+ "syscall 0\n" \
+ : "+r"(_arg1) \
+ : "r"(_num) \
+ : "memory", "$t0", "$t1", "$t2", "$t3", \
+ "$t4", "$t5", "$t6", "$t7", "$t8" \
+ ); \
+ _arg1; \
+})
+
+#define my_syscall2(num, arg1, arg2) \
+({ \
+ register long _num __asm__ ("a7") = (num); \
+ register long _arg1 __asm__ ("a0") = (long)(arg1); \
+ register long _arg2 __asm__ ("a1") = (long)(arg2); \
+ \
+ __asm__ volatile ( \
+ "syscall 0\n" \
+ : "+r"(_arg1) \
+ : "r"(_arg2), \
+ "r"(_num) \
+ : "memory", "$t0", "$t1", "$t2", "$t3", \
+ "$t4", "$t5", "$t6", "$t7", "$t8" \
+ ); \
+ _arg1; \
+})
+
+#define my_syscall3(num, arg1, arg2, arg3) \
+({ \
+ register long _num __asm__ ("a7") = (num); \
+ register long _arg1 __asm__ ("a0") = (long)(arg1); \
+ register long _arg2 __asm__ ("a1") = (long)(arg2); \
+ register long _arg3 __asm__ ("a2") = (long)(arg3); \
+ \
+ __asm__ volatile ( \
+ "syscall 0\n" \
+ : "+r"(_arg1) \
+ : "r"(_arg2), "r"(_arg3), \
+ "r"(_num) \
+ : "memory", "$t0", "$t1", "$t2", "$t3", \
+ "$t4", "$t5", "$t6", "$t7", "$t8" \
+ ); \
+ _arg1; \
+})
+
+#define my_syscall4(num, arg1, arg2, arg3, arg4) \
+({ \
+ register long _num __asm__ ("a7") = (num); \
+ register long _arg1 __asm__ ("a0") = (long)(arg1); \
+ register long _arg2 __asm__ ("a1") = (long)(arg2); \
+ register long _arg3 __asm__ ("a2") = (long)(arg3); \
+ register long _arg4 __asm__ ("a3") = (long)(arg4); \
+ \
+ __asm__ volatile ( \
+ "syscall 0\n" \
+ : "+r"(_arg1) \
+ : "r"(_arg2), "r"(_arg3), "r"(_arg4), \
+ "r"(_num) \
+ : "memory", "$t0", "$t1", "$t2", "$t3", \
+ "$t4", "$t5", "$t6", "$t7", "$t8" \
+ ); \
+ _arg1; \
+})
+
+#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
+({ \
+ register long _num __asm__ ("a7") = (num); \
+ register long _arg1 __asm__ ("a0") = (long)(arg1); \
+ register long _arg2 __asm__ ("a1") = (long)(arg2); \
+ register long _arg3 __asm__ ("a2") = (long)(arg3); \
+ register long _arg4 __asm__ ("a3") = (long)(arg4); \
+ register long _arg5 __asm__ ("a4") = (long)(arg5); \
+ \
+ __asm__ volatile ( \
+ "syscall 0\n" \
+ : "+r"(_arg1) \
+ : "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
+ "r"(_num) \
+ : "memory", "$t0", "$t1", "$t2", "$t3", \
+ "$t4", "$t5", "$t6", "$t7", "$t8" \
+ ); \
+ _arg1; \
+})
+
+#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
+({ \
+ register long _num __asm__ ("a7") = (num); \
+ register long _arg1 __asm__ ("a0") = (long)(arg1); \
+ register long _arg2 __asm__ ("a1") = (long)(arg2); \
+ register long _arg3 __asm__ ("a2") = (long)(arg3); \
+ register long _arg4 __asm__ ("a3") = (long)(arg4); \
+ register long _arg5 __asm__ ("a4") = (long)(arg5); \
+ register long _arg6 __asm__ ("a5") = (long)(arg6); \
+ \
+ __asm__ volatile ( \
+ "syscall 0\n" \
+ : "+r"(_arg1) \
+ : "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), "r"(_arg6), \
+ "r"(_num) \
+ : "memory", "$t0", "$t1", "$t2", "$t3", \
+ "$t4", "$t5", "$t6", "$t7", "$t8" \
+ ); \
+ _arg1; \
+})
+
+char **environ __attribute__((weak));
+const unsigned long *_auxv __attribute__((weak));
+
+#if __loongarch_grlen == 32
+#define LONGLOG "2"
+#define SZREG "4"
+#define REG_L "ld.w"
+#define LONG_S "st.w"
+#define LONG_ADD "add.w"
+#define LONG_ADDI "addi.w"
+#define LONG_SLL "slli.w"
+#define LONG_BSTRINS "bstrins.w"
+#else // __loongarch_grlen == 64
+#define LONGLOG "3"
+#define SZREG "8"
+#define REG_L "ld.d"
+#define LONG_S "st.d"
+#define LONG_ADD "add.d"
+#define LONG_ADDI "addi.d"
+#define LONG_SLL "slli.d"
+#define LONG_BSTRINS "bstrins.d"
+#endif
+
+/* startup code */
+void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) _start(void)
+{
+ __asm__ volatile (
+ REG_L " $a0, $sp, 0\n" // argc (a0) was in the stack
+ LONG_ADDI " $a1, $sp, "SZREG"\n" // argv (a1) = sp + SZREG
+ LONG_SLL " $a2, $a0, "LONGLOG"\n" // envp (a2) = SZREG*argc ...
+ LONG_ADDI " $a2, $a2, "SZREG"\n" // + SZREG (skip null)
+ LONG_ADD " $a2, $a2, $a1\n" // + argv
+
+ "move $a3, $a2\n" // iterate a3 over envp to find auxv (after NULL)
+ "0:\n" // do {
+ REG_L " $a4, $a3, 0\n" // a4 = *a3;
+ LONG_ADDI " $a3, $a3, "SZREG"\n" // a3 += sizeof(void*);
+ "bne $a4, $zero, 0b\n" // } while (a4);
+ "la.pcrel $a4, _auxv\n" // a4 = &_auxv
+ LONG_S " $a3, $a4, 0\n" // store a3 into _auxv
+
+ "la.pcrel $a3, environ\n" // a3 = &environ
+ LONG_S " $a2, $a3, 0\n" // store envp(a2) into environ
+ LONG_BSTRINS " $sp, $zero, 3, 0\n" // sp must be 16-byte aligned
+ "bl main\n" // main() returns the status code, we'll exit with it.
+ "li.w $a7, 93\n" // NR_exit == 93
+ "syscall 0\n"
+ );
+ __builtin_unreachable();
+}
+
+#endif // _NOLIBC_ARCH_LOONGARCH_H
diff --git a/tools/include/nolibc/arch.h b/tools/include/nolibc/arch.h
index 78b067a4fa47..2d5386a8d6aa 100644
--- a/tools/include/nolibc/arch.h
+++ b/tools/include/nolibc/arch.h
@@ -29,6 +29,8 @@
#include "arch-riscv.h"
#elif defined(__s390x__)
#include "arch-s390.h"
+#elif defined(__loongarch__)
+#include "arch-loongarch.h"
#endif

#endif /* _NOLIBC_ARCH_H */
--
2.39.0


2023-02-08 10:19:13

by Feiyang Chen

[permalink] [raw]
Subject: [PATCH v2 4/5] selftests/nolibc: Add support for LoongArch

From: Feiyang Chen <[email protected]>

Add support for LoongArch (64 bit) to nolibc selftest.

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

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index 8fe61d3e3cce..e9c4a9d011a0 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -21,6 +21,7 @@ IMAGE_arm = arch/arm/boot/zImage
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_NAME = $(notdir $(IMAGE))

@@ -33,6 +34,7 @@ DEFCONFIG_arm = multi_v7_defconfig
DEFCONFIG_mips = malta_defconfig
DEFCONFIG_riscv = defconfig
DEFCONFIG_s390 = defconfig
+DEFCONFIG_loongarch = defconfig
DEFCONFIG = $(DEFCONFIG_$(ARCH))

# optional tests to run (default = all)
@@ -47,6 +49,7 @@ QEMU_ARCH_arm = arm
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_ARGS : some arch-specific args to pass to qemu
@@ -58,6 +61,7 @@ QEMU_ARGS_arm = -M virt -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)"
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))

# OUTPUT is only set when run from the main makefile, otherwise
--
2.39.0


2023-02-08 10:19:25

by Feiyang Chen

[permalink] [raw]
Subject: [PATCH v2 5/5] selftests/nolibc: Adjust indentation for Makefile

From: Feiyang Chen <[email protected]>

Reindent only, no functional changes.

Signed-off-by: Feiyang Chen <[email protected]>
---
tools/testing/selftests/nolibc/Makefile | 74 ++++++++++++-------------
1 file changed, 37 insertions(+), 37 deletions(-)

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index e9c4a9d011a0..ea2b82a3cd86 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -13,56 +13,56 @@ ARCH = $(SUBARCH)
endif

# kernel image names by architecture
-IMAGE_i386 = arch/x86/boot/bzImage
-IMAGE_x86_64 = arch/x86/boot/bzImage
-IMAGE_x86 = arch/x86/boot/bzImage
-IMAGE_arm64 = arch/arm64/boot/Image
-IMAGE_arm = arch/arm/boot/zImage
-IMAGE_mips = vmlinuz
-IMAGE_riscv = arch/riscv/boot/Image
-IMAGE_s390 = arch/s390/boot/bzImage
+IMAGE_i386 = arch/x86/boot/bzImage
+IMAGE_x86_64 = arch/x86/boot/bzImage
+IMAGE_x86 = arch/x86/boot/bzImage
+IMAGE_arm64 = arch/arm64/boot/Image
+IMAGE_arm = arch/arm/boot/zImage
+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_NAME = $(notdir $(IMAGE))
+IMAGE = $(IMAGE_$(ARCH))
+IMAGE_NAME = $(notdir $(IMAGE))

# default kernel configurations that appear to be usable
-DEFCONFIG_i386 = defconfig
-DEFCONFIG_x86_64 = defconfig
-DEFCONFIG_x86 = defconfig
-DEFCONFIG_arm64 = defconfig
-DEFCONFIG_arm = multi_v7_defconfig
-DEFCONFIG_mips = malta_defconfig
-DEFCONFIG_riscv = defconfig
-DEFCONFIG_s390 = defconfig
+DEFCONFIG_i386 = defconfig
+DEFCONFIG_x86_64 = defconfig
+DEFCONFIG_x86 = defconfig
+DEFCONFIG_arm64 = defconfig
+DEFCONFIG_arm = multi_v7_defconfig
+DEFCONFIG_mips = malta_defconfig
+DEFCONFIG_riscv = defconfig
+DEFCONFIG_s390 = defconfig
DEFCONFIG_loongarch = defconfig
-DEFCONFIG = $(DEFCONFIG_$(ARCH))
+DEFCONFIG = $(DEFCONFIG_$(ARCH))

# optional tests to run (default = all)
TEST =

# QEMU_ARCH: arch names used by qemu
-QEMU_ARCH_i386 = i386
-QEMU_ARCH_x86_64 = x86_64
-QEMU_ARCH_x86 = x86_64
-QEMU_ARCH_arm64 = aarch64
-QEMU_ARCH_arm = arm
-QEMU_ARCH_mips = mipsel # works with malta_defconfig
-QEMU_ARCH_riscv = riscv64
-QEMU_ARCH_s390 = s390x
+QEMU_ARCH_i386 = i386
+QEMU_ARCH_x86_64 = x86_64
+QEMU_ARCH_x86 = x86_64
+QEMU_ARCH_arm64 = aarch64
+QEMU_ARCH_arm = arm
+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_$(ARCH))

# 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=%)"
-QEMU_ARGS_x86_64 = -M pc -append "console=ttyS0,9600 i8042.noaux panic=-1 $(TEST:%=NOLIBC_TEST=%)"
-QEMU_ARGS_x86 = -M pc -append "console=ttyS0,9600 i8042.noaux panic=-1 $(TEST:%=NOLIBC_TEST=%)"
-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_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_i386 = -M pc -append "console=ttyS0,9600 i8042.noaux panic=-1 $(TEST:%=NOLIBC_TEST=%)"
+QEMU_ARGS_x86_64 = -M pc -append "console=ttyS0,9600 i8042.noaux panic=-1 $(TEST:%=NOLIBC_TEST=%)"
+QEMU_ARGS_x86 = -M pc -append "console=ttyS0,9600 i8042.noaux panic=-1 $(TEST:%=NOLIBC_TEST=%)"
+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_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 = $(QEMU_ARGS_$(ARCH))

# OUTPUT is only set when run from the main makefile, otherwise
# it defaults to this nolibc directory.
--
2.39.0


2023-02-08 10:40:56

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] tools/nolibc: Add statx() and make stat() rely on statx() when available

On Wed, Feb 8, 2023, at 11:17, [email protected] wrote:
> From: Feiyang Chen <[email protected]>
>
> loongarch and riscv32 only have statx(). arc, hexagon, nios2 and
> openrisc have statx() and stat64() but not stat() or newstat().
> Add statx() and make stat() rely on statx() to make them happy.

> +#ifdef __NR_statx
> +static __attribute__((unused))
> +int sys_stat(const char *path, struct stat *buf)
> +{

The actual #ifdef check here does what I had suggested first, using
statx() for all architectures, rather than what you describe in the
changelog. I think you should keep the check from the first version,
testing for __NR_stat/__NR_newfstatat and keep the changelog text
here. Also please add something about the possibility of using statx()
everywhere in the future.

Arnd

2023-02-08 10:41:00

by Willy Tarreau

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] tools/nolibc: Add statx() and make stat() rely on statx() when available

Hi Feiyang,

On Wed, Feb 08, 2023 at 06:17:51PM +0800, [email protected] wrote:
> From: Feiyang Chen <[email protected]>
>
> loongarch and riscv32 only have statx(). arc, hexagon, nios2 and
> openrisc have statx() and stat64() but not stat() or newstat().
> Add statx() and make stat() rely on statx() to make them happy.

Thanks for this, that's way better. I'm just having one small request
below:

> +/*
> + * int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf);
> + */
> +
> +static __attribute__((unused))
> +int sys_statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf)
> +{
> + return my_syscall5(__NR_statx, fd, path, flags, mask, buf);
> +}
> +
> +static __attribute__((unused))
> +int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf)
> +{
> + int ret = sys_statx(fd, path, flags, mask, buf);
> +
> + if (ret < 0) {
> + SET_ERRNO(-ret);
> + ret = -1;
> + }
> + return ret;
> +}

Please guard these inside #if defined(__NR_statx) so that this can still
be used as-is from slightly older toolchains that provide their own kernel
includes.

The rest of the series looks pretty good to me.

Thank you!
Willy

2023-02-08 11:01:51

by Huacai Chen

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] tools/nolibc: Add statx() and make stat() rely on statx() when available

Hi, Feiyang,

On Wed, Feb 8, 2023 at 6:18 PM <[email protected]> wrote:
>
> From: Feiyang Chen <[email protected]>
>
> loongarch and riscv32 only have statx(). arc, hexagon, nios2 and
> openrisc have statx() and stat64() but not stat() or newstat().
> Add statx() and make stat() rely on statx() to make them happy.
Some bikesheddings, maybe it is better to use LoongArch here.

Huacai
>
> Signed-off-by: Feiyang Chen <[email protected]>
> ---
> tools/include/nolibc/sys.h | 51 ++++++++++++++++++++++++++++++++++++++
> 1 file changed, 51 insertions(+)
>
> diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
> index c4818a9c8823..46b6b3bb3b4e 100644
> --- a/tools/include/nolibc/sys.h
> +++ b/tools/include/nolibc/sys.h
> @@ -20,6 +20,7 @@
> #include <linux/time.h>
> #include <linux/auxvec.h>
> #include <linux/fcntl.h> // for O_* and AT_*
> +#include <linux/stat.h> // for statx()
>
> #include "arch.h"
> #include "errno.h"
> @@ -1048,12 +1049,61 @@ pid_t setsid(void)
> return ret;
> }
>
> +/*
> + * int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf);
> + */
> +
> +static __attribute__((unused))
> +int sys_statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf)
> +{
> + return my_syscall5(__NR_statx, fd, path, flags, mask, buf);
> +}
> +
> +static __attribute__((unused))
> +int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf)
> +{
> + int ret = sys_statx(fd, path, flags, mask, buf);
> +
> + if (ret < 0) {
> + SET_ERRNO(-ret);
> + ret = -1;
> + }
> + return ret;
> +}
>
> /*
> * int stat(const char *path, struct stat *buf);
> * Warning: the struct stat's layout is arch-dependent.
> */
>
> +#ifdef __NR_statx
> +static __attribute__((unused))
> +int sys_stat(const char *path, struct stat *buf)
> +{
> + struct statx stat;
> + long ret;
> +
> + ret = sys_statx(AT_FDCWD, path, AT_NO_AUTOMOUNT, STATX_BASIC_STATS, &stat);
> + buf->st_dev = ((stat.stx_dev_minor & 0xff)
> + | (stat.stx_dev_major << 8)
> + | ((stat.stx_dev_minor & ~0xff) << 12));
> + buf->st_ino = stat.stx_ino;
> + buf->st_mode = stat.stx_mode;
> + buf->st_nlink = stat.stx_nlink;
> + buf->st_uid = stat.stx_uid;
> + buf->st_gid = stat.stx_gid;
> + buf->st_rdev = ((stat.stx_rdev_minor & 0xff)
> + | (stat.stx_rdev_major << 8)
> + | ((stat.stx_rdev_minor & ~0xff) << 12));
> + buf->st_size = stat.stx_size;
> + buf->st_blksize = stat.stx_blksize;
> + buf->st_blocks = stat.stx_blocks;
> + buf->st_atime = stat.stx_atime.tv_sec;
> + buf->st_mtime = stat.stx_mtime.tv_sec;
> + buf->st_ctime = stat.stx_ctime.tv_sec;
> + return ret;
> +}
> +#else
> static __attribute__((unused))
> int sys_stat(const char *path, struct stat *buf)
> {
> @@ -1083,6 +1133,7 @@ int sys_stat(const char *path, struct stat *buf)
> buf->st_ctime = stat.st_ctime;
> return ret;
> }
> +#endif /* __NR_statx */
>
> static __attribute__((unused))
> int stat(const char *path, struct stat *buf)
> --
> 2.39.0
>

2023-02-08 22:39:35

by David Laight

[permalink] [raw]
Subject: RE: [PATCH v2 2/5] tools/nolibc: Add statx() and make stat() rely on statx() when available

From: [email protected]
> Sent: 08 February 2023 10:18
>
> loongarch and riscv32 only have statx(). arc, hexagon, nios2 and
> openrisc have statx() and stat64() but not stat() or newstat().
> Add statx() and make stat() rely on statx() to make them happy.
>
...
> +#ifdef __NR_statx
> +static __attribute__((unused))
> +int sys_stat(const char *path, struct stat *buf)
> +{
> + struct statx stat;

If seems wrong that 'stat' has type 'struct statx'
and 'buf' type 'struct stat *'.

Maybe s/stat./statx./ and s/buf->/stat->/ ?

David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


2023-02-09 02:03:42

by Feiyang Chen

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] tools/nolibc: Add statx() and make stat() rely on statx() when available

On Wed, 8 Feb 2023 at 18:39, Willy Tarreau <[email protected]> wrote:
>
> Hi Feiyang,
>
> On Wed, Feb 08, 2023 at 06:17:51PM +0800, [email protected] wrote:
> > From: Feiyang Chen <[email protected]>
> >
> > loongarch and riscv32 only have statx(). arc, hexagon, nios2 and
> > openrisc have statx() and stat64() but not stat() or newstat().
> > Add statx() and make stat() rely on statx() to make them happy.
>
> Thanks for this, that's way better. I'm just having one small request
> below:
>
> > +/*
> > + * int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf);
> > + */
> > +
> > +static __attribute__((unused))
> > +int sys_statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf)
> > +{
> > + return my_syscall5(__NR_statx, fd, path, flags, mask, buf);
> > +}
> > +
> > +static __attribute__((unused))
> > +int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf)
> > +{
> > + int ret = sys_statx(fd, path, flags, mask, buf);
> > +
> > + if (ret < 0) {
> > + SET_ERRNO(-ret);
> > + ret = -1;
> > + }
> > + return ret;
> > +}
>
> Please guard these inside #if defined(__NR_statx) so that this can still
> be used as-is from slightly older toolchains that provide their own kernel
> includes.
>

Hi, Willy,

OK.

Thanks,
Feiyang

> The rest of the series looks pretty good to me.
>
> Thank you!
> Willy

2023-02-09 02:06:49

by Feiyang Chen

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] tools/nolibc: Add statx() and make stat() rely on statx() when available

On Wed, 8 Feb 2023 at 18:39, Arnd Bergmann <[email protected]> wrote:
>
> On Wed, Feb 8, 2023, at 11:17, [email protected] wrote:
> > From: Feiyang Chen <[email protected]>
> >
> > loongarch and riscv32 only have statx(). arc, hexagon, nios2 and
> > openrisc have statx() and stat64() but not stat() or newstat().
> > Add statx() and make stat() rely on statx() to make them happy.
>
> > +#ifdef __NR_statx
> > +static __attribute__((unused))
> > +int sys_stat(const char *path, struct stat *buf)
> > +{
>
> The actual #ifdef check here does what I had suggested first, using
> statx() for all architectures, rather than what you describe in the
> changelog. I think you should keep the check from the first version,
> testing for __NR_stat/__NR_newfstatat and keep the changelog text
> here. Also please add something about the possibility of using statx()
> everywhere in the future.
>

Hi, Arnd,

OK, I will keep the check from the first version and mention that we
may use statx() everywhere.

Thanks,
Feiyang

> Arnd

2023-02-09 02:15:09

by Feiyang Chen

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] tools/nolibc: Add statx() and make stat() rely on statx() when available

On Thu, 9 Feb 2023 at 06:39, David Laight <[email protected]> wrote:
>
> From: [email protected]
> > Sent: 08 February 2023 10:18
> >
> > loongarch and riscv32 only have statx(). arc, hexagon, nios2 and
> > openrisc have statx() and stat64() but not stat() or newstat().
> > Add statx() and make stat() rely on statx() to make them happy.
> >
> ...
> > +#ifdef __NR_statx
> > +static __attribute__((unused))
> > +int sys_stat(const char *path, struct stat *buf)
> > +{
> > + struct statx stat;
>
> If seems wrong that 'stat' has type 'struct statx'
> and 'buf' type 'struct stat *'.
>
> Maybe s/stat./statx./ and s/buf->/stat->/ ?
>

Hi, David,

Yes, it looks better to use 'struct statx statx'. Thank you!
I'd like to keep 'buf' to be consistent with the stat() below.
int stat(const char *path, struct stat *buf);

Thanks,
Feiyang

> David
>
> -
> Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
> Registration No: 1397386 (Wales)
>

2023-02-09 02:25:43

by Feiyang Chen

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] tools/nolibc: Add statx() and make stat() rely on statx() when available

On Wed, 8 Feb 2023 at 19:00, Huacai Chen <[email protected]> wrote:
>
> Hi, Feiyang,
>
> On Wed, Feb 8, 2023 at 6:18 PM <[email protected]> wrote:
> >
> > From: Feiyang Chen <[email protected]>
> >
> > loongarch and riscv32 only have statx(). arc, hexagon, nios2 and
> > openrisc have statx() and stat64() but not stat() or newstat().
> > Add statx() and make stat() rely on statx() to make them happy.
> Some bikesheddings, maybe it is better to use LoongArch here.
>

Hi, Huacai

Yes.

Thanks,
Feiyang

> Huacai
> >
> > Signed-off-by: Feiyang Chen <[email protected]>
> > ---
> > tools/include/nolibc/sys.h | 51 ++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 51 insertions(+)
> >
> > diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
> > index c4818a9c8823..46b6b3bb3b4e 100644
> > --- a/tools/include/nolibc/sys.h
> > +++ b/tools/include/nolibc/sys.h
> > @@ -20,6 +20,7 @@
> > #include <linux/time.h>
> > #include <linux/auxvec.h>
> > #include <linux/fcntl.h> // for O_* and AT_*
> > +#include <linux/stat.h> // for statx()
> >
> > #include "arch.h"
> > #include "errno.h"
> > @@ -1048,12 +1049,61 @@ pid_t setsid(void)
> > return ret;
> > }
> >
> > +/*
> > + * int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf);
> > + */
> > +
> > +static __attribute__((unused))
> > +int sys_statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf)
> > +{
> > + return my_syscall5(__NR_statx, fd, path, flags, mask, buf);
> > +}
> > +
> > +static __attribute__((unused))
> > +int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf)
> > +{
> > + int ret = sys_statx(fd, path, flags, mask, buf);
> > +
> > + if (ret < 0) {
> > + SET_ERRNO(-ret);
> > + ret = -1;
> > + }
> > + return ret;
> > +}
> >
> > /*
> > * int stat(const char *path, struct stat *buf);
> > * Warning: the struct stat's layout is arch-dependent.
> > */
> >
> > +#ifdef __NR_statx
> > +static __attribute__((unused))
> > +int sys_stat(const char *path, struct stat *buf)
> > +{
> > + struct statx stat;
> > + long ret;
> > +
> > + ret = sys_statx(AT_FDCWD, path, AT_NO_AUTOMOUNT, STATX_BASIC_STATS, &stat);
> > + buf->st_dev = ((stat.stx_dev_minor & 0xff)
> > + | (stat.stx_dev_major << 8)
> > + | ((stat.stx_dev_minor & ~0xff) << 12));
> > + buf->st_ino = stat.stx_ino;
> > + buf->st_mode = stat.stx_mode;
> > + buf->st_nlink = stat.stx_nlink;
> > + buf->st_uid = stat.stx_uid;
> > + buf->st_gid = stat.stx_gid;
> > + buf->st_rdev = ((stat.stx_rdev_minor & 0xff)
> > + | (stat.stx_rdev_major << 8)
> > + | ((stat.stx_rdev_minor & ~0xff) << 12));
> > + buf->st_size = stat.stx_size;
> > + buf->st_blksize = stat.stx_blksize;
> > + buf->st_blocks = stat.stx_blocks;
> > + buf->st_atime = stat.stx_atime.tv_sec;
> > + buf->st_mtime = stat.stx_mtime.tv_sec;
> > + buf->st_ctime = stat.stx_ctime.tv_sec;
> > + return ret;
> > +}
> > +#else
> > static __attribute__((unused))
> > int sys_stat(const char *path, struct stat *buf)
> > {
> > @@ -1083,6 +1133,7 @@ int sys_stat(const char *path, struct stat *buf)
> > buf->st_ctime = stat.st_ctime;
> > return ret;
> > }
> > +#endif /* __NR_statx */
> >
> > static __attribute__((unused))
> > int stat(const char *path, struct stat *buf)
> > --
> > 2.39.0
> >