Re: [PATCH v6 18/19] linux-user/s390x: Add vdso
On 05/10/2023 18.14, Philippe Mathieu-Daudé wrote: On 4/10/23 01:01, Richard Henderson wrote: On 10/3/23 06:07, Philippe Mathieu-Daudé wrote: +++ b/linux-user/s390x/vdso.ld @@ -0,0 +1,69 @@ +/* + * Linker script for linux x86-64 replacement vdso. Should that be s390x instead of x86-64 ? + * Copyright 2023 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +VERSION { + LINUX_2.6.29 { + global: + __kernel_gettimeofday; + __kernel_clock_gettime; + __kernel_clock_getres; + __kernel_getcpu; + __kernel_restart_syscall; Where is __kernel_restart_syscall defined? It isn't, and I guess isn't needed for qemu (we have QEMU_ERESTARTSYS). I'm not sure why it's an exported symbol for the s390x vdso for the kernel, even if they do require some user-space code. Anyway, I'll remove the symbol here. OK. I dare to give: Reviewed-by: Philippe Mathieu-Daudé But still I'm Cc'ing David / Thomas who better know s390x :) Uh, oh, vdso ... I remember some dark magic here on the real kernels on s390x, involving access registers ... good that we don't need those here :-) I quickly glanced through the code, and apart from the typo above, it looks good to me, so: Acked-by: Thomas Huth
Re: [PATCH v6 18/19] linux-user/s390x: Add vdso
On 4/10/23 01:01, Richard Henderson wrote: On 10/3/23 06:07, Philippe Mathieu-Daudé wrote: +++ b/linux-user/s390x/vdso.ld @@ -0,0 +1,69 @@ +/* + * Linker script for linux x86-64 replacement vdso. + * + * Copyright 2023 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +VERSION { + LINUX_2.6.29 { + global: + __kernel_gettimeofday; + __kernel_clock_gettime; + __kernel_clock_getres; + __kernel_getcpu; + __kernel_restart_syscall; Where is __kernel_restart_syscall defined? It isn't, and I guess isn't needed for qemu (we have QEMU_ERESTARTSYS). I'm not sure why it's an exported symbol for the s390x vdso for the kernel, even if they do require some user-space code. Anyway, I'll remove the symbol here. OK. I dare to give: Reviewed-by: Philippe Mathieu-Daudé But still I'm Cc'ing David / Thomas who better know s390x :)
Re: [PATCH v6 18/19] linux-user/s390x: Add vdso
On 10/3/23 06:07, Philippe Mathieu-Daudé wrote: +++ b/linux-user/s390x/vdso.ld @@ -0,0 +1,69 @@ +/* + * Linker script for linux x86-64 replacement vdso. + * + * Copyright 2023 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +VERSION { + LINUX_2.6.29 { + global: + __kernel_gettimeofday; + __kernel_clock_gettime; + __kernel_clock_getres; + __kernel_getcpu; + __kernel_restart_syscall; Where is __kernel_restart_syscall defined? It isn't, and I guess isn't needed for qemu (we have QEMU_ERESTARTSYS). I'm not sure why it's an exported symbol for the s390x vdso for the kernel, even if they do require some user-space code. Anyway, I'll remove the symbol here. r~
Re: [PATCH v6 18/19] linux-user/s390x: Add vdso
Hi Richard, On 30/9/23 04:15, Richard Henderson wrote: Signed-off-by: Richard Henderson --- linux-user/s390x/vdso-asmoffset.h | 2 + linux-user/elfload.c | 2 + linux-user/s390x/signal.c | 4 +- linux-user/s390x/Makefile.vdso| 11 + linux-user/s390x/meson.build | 6 +++ linux-user/s390x/vdso.S | 61 ++ linux-user/s390x/vdso.ld | 69 ++ linux-user/s390x/vdso.so | Bin 0 -> 3464 bytes 8 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 linux-user/s390x/vdso-asmoffset.h create mode 100644 linux-user/s390x/Makefile.vdso create mode 100644 linux-user/s390x/vdso.S create mode 100644 linux-user/s390x/vdso.ld create mode 100755 linux-user/s390x/vdso.so diff --git a/linux-user/s390x/Makefile.vdso b/linux-user/s390x/Makefile.vdso new file mode 100644 index 00..e82bf9e29f --- /dev/null +++ b/linux-user/s390x/Makefile.vdso @@ -0,0 +1,11 @@ +include $(BUILD_DIR)/tests/tcg/s390x-linux-user/config-target.mak + +SUBDIR = $(SRC_PATH)/linux-user/s390x +VPATH += $(SUBDIR) + +all: $(SUBDIR)/vdso.so + +$(SUBDIR)/vdso.so: vdso.S vdso.ld vdso-asmoffset.h + $(CC) -o $@ -nostdlib -shared -Wl,-h,linux-vdso64.so.1 \ + -Wl,--build-id=sha1 -Wl,--hash-style=both \ + -Wl,-T,$(SUBDIR)/vdso.ld $< diff --git a/linux-user/s390x/meson.build b/linux-user/s390x/meson.build index 0781ccea1d..a7a25ed9ce 100644 --- a/linux-user/s390x/meson.build +++ b/linux-user/s390x/meson.build @@ -3,3 +3,9 @@ syscall_nr_generators += { arguments: [ meson.current_source_dir() / 'syscallhdr.sh', '@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@' ], output: '@BASENAME@_nr.h') } + +vdso_inc = gen_vdso.process('vdso.so', extra_args: [ +'-s', '__kernel_sigreturn', +'-r', '__kernel_rt_sigreturn' +]) +linux_user_ss.add(when: 'TARGET_S390X', if_true: vdso_inc) diff --git a/linux-user/s390x/vdso.S b/linux-user/s390x/vdso.S new file mode 100644 index 00..3332492477 --- /dev/null +++ b/linux-user/s390x/vdso.S @@ -0,0 +1,61 @@ +/* + * s390x linux replacement vdso. + * + * Copyright 2023 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include +#include "vdso-asmoffset.h" + +.macro endf name + .globl \name + .type \name, @function + .size \name, . - \name +.endm + +.macro raw_syscall n +.ifne \n < 0x100 + svc \n + .else + lghi%r1, \n + svc 0 +.endif +.endm + +.macro vdso_syscall name, nr +\name: + .cfi_startproc + aghi%r15, -(STACK_FRAME_OVERHEAD + 16) + .cfi_adjust_cfa_offset STACK_FRAME_OVERHEAD + 16 + stg %r14, STACK_FRAME_OVERHEAD(%r15) + .cfi_rel_offset %r14, STACK_FRAME_OVERHEAD + raw_syscall \nr + lg %r14, STACK_FRAME_OVERHEAD(%r15) + aghi%r15, STACK_FRAME_OVERHEAD + 16 + .cfi_restore %r14 + .cfi_adjust_cfa_offset -(STACK_FRAME_OVERHEAD + 16) + br %r14 + .cfi_endproc +endf \name +.endm + +vdso_syscall __kernel_gettimeofday, __NR_gettimeofday +vdso_syscall __kernel_clock_gettime, __NR_clock_gettime +vdso_syscall __kernel_clock_getres, __NR_clock_getres +vdso_syscall __kernel_getcpu, __NR_getcpu + +/* + * TODO unwind info, though we're ok without it. + * The kernel supplies bogus empty unwind info, and it is likely ignored + * by all users. Without it we get the fallback signal frame handling. + */ + +__kernel_sigreturn: + raw_syscall __NR_sigreturn +endf __kernel_sigreturn + +__kernel_rt_sigreturn: + raw_syscall __NR_rt_sigreturn +endf __kernel_rt_sigreturn diff --git a/linux-user/s390x/vdso.ld b/linux-user/s390x/vdso.ld new file mode 100644 index 00..2a30ff382a --- /dev/null +++ b/linux-user/s390x/vdso.ld @@ -0,0 +1,69 @@ +/* + * Linker script for linux x86-64 replacement vdso. + * + * Copyright 2023 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +VERSION { +LINUX_2.6.29 { +global: +__kernel_gettimeofday; +__kernel_clock_gettime; +__kernel_clock_getres; +__kernel_getcpu; +__kernel_restart_syscall; Where is __kernel_restart_syscall defined? +__kernel_rt_sigreturn; +__kernel_sigreturn; +local: *; +}; +}
[PATCH v6 18/19] linux-user/s390x: Add vdso
Signed-off-by: Richard Henderson --- linux-user/s390x/vdso-asmoffset.h | 2 + linux-user/elfload.c | 2 + linux-user/s390x/signal.c | 4 +- linux-user/s390x/Makefile.vdso| 11 + linux-user/s390x/meson.build | 6 +++ linux-user/s390x/vdso.S | 61 ++ linux-user/s390x/vdso.ld | 69 ++ linux-user/s390x/vdso.so | Bin 0 -> 3464 bytes 8 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 linux-user/s390x/vdso-asmoffset.h create mode 100644 linux-user/s390x/Makefile.vdso create mode 100644 linux-user/s390x/vdso.S create mode 100644 linux-user/s390x/vdso.ld create mode 100755 linux-user/s390x/vdso.so diff --git a/linux-user/s390x/vdso-asmoffset.h b/linux-user/s390x/vdso-asmoffset.h new file mode 100644 index 00..27a062d6c1 --- /dev/null +++ b/linux-user/s390x/vdso-asmoffset.h @@ -0,0 +1,2 @@ +/* Minimum stack frame size */ +#define STACK_FRAME_OVERHEAD160 diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 4a2d21a1f9..7450f9eab0 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1886,6 +1886,8 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, #define USE_ELF_CORE_DUMP #define ELF_EXEC_PAGESIZE 4096 +#define VDSO_HEADER "vdso.c.inc" + #endif /* TARGET_S390X */ #ifdef TARGET_RISCV diff --git a/linux-user/s390x/signal.c b/linux-user/s390x/signal.c index 0f8b8e04bf..b40f738a70 100644 --- a/linux-user/s390x/signal.c +++ b/linux-user/s390x/signal.c @@ -21,14 +21,12 @@ #include "user-internals.h" #include "signal-common.h" #include "linux-user/trace.h" +#include "vdso-asmoffset.h" #define __NUM_GPRS 16 #define __NUM_FPRS 16 #define __NUM_ACRS 16 -/* Minimum stack frame size */ -#define STACK_FRAME_OVERHEAD160 - #define _SIGCONTEXT_NSIG64 #define _SIGCONTEXT_NSIG_BPW64 /* FIXME: 31-bit mode -> 32 */ #define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW) diff --git a/linux-user/s390x/Makefile.vdso b/linux-user/s390x/Makefile.vdso new file mode 100644 index 00..e82bf9e29f --- /dev/null +++ b/linux-user/s390x/Makefile.vdso @@ -0,0 +1,11 @@ +include $(BUILD_DIR)/tests/tcg/s390x-linux-user/config-target.mak + +SUBDIR = $(SRC_PATH)/linux-user/s390x +VPATH += $(SUBDIR) + +all: $(SUBDIR)/vdso.so + +$(SUBDIR)/vdso.so: vdso.S vdso.ld vdso-asmoffset.h + $(CC) -o $@ -nostdlib -shared -Wl,-h,linux-vdso64.so.1 \ + -Wl,--build-id=sha1 -Wl,--hash-style=both \ + -Wl,-T,$(SUBDIR)/vdso.ld $< diff --git a/linux-user/s390x/meson.build b/linux-user/s390x/meson.build index 0781ccea1d..a7a25ed9ce 100644 --- a/linux-user/s390x/meson.build +++ b/linux-user/s390x/meson.build @@ -3,3 +3,9 @@ syscall_nr_generators += { arguments: [ meson.current_source_dir() / 'syscallhdr.sh', '@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@' ], output: '@BASENAME@_nr.h') } + +vdso_inc = gen_vdso.process('vdso.so', extra_args: [ +'-s', '__kernel_sigreturn', +'-r', '__kernel_rt_sigreturn' +]) +linux_user_ss.add(when: 'TARGET_S390X', if_true: vdso_inc) diff --git a/linux-user/s390x/vdso.S b/linux-user/s390x/vdso.S new file mode 100644 index 00..3332492477 --- /dev/null +++ b/linux-user/s390x/vdso.S @@ -0,0 +1,61 @@ +/* + * s390x linux replacement vdso. + * + * Copyright 2023 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include +#include "vdso-asmoffset.h" + +.macro endf name + .globl \name + .type \name, @function + .size \name, . - \name +.endm + +.macro raw_syscall n +.ifne \n < 0x100 + svc \n + .else + lghi%r1, \n + svc 0 +.endif +.endm + +.macro vdso_syscall name, nr +\name: + .cfi_startproc + aghi%r15, -(STACK_FRAME_OVERHEAD + 16) + .cfi_adjust_cfa_offset STACK_FRAME_OVERHEAD + 16 + stg %r14, STACK_FRAME_OVERHEAD(%r15) + .cfi_rel_offset %r14, STACK_FRAME_OVERHEAD + raw_syscall \nr + lg %r14, STACK_FRAME_OVERHEAD(%r15) + aghi%r15, STACK_FRAME_OVERHEAD + 16 + .cfi_restore %r14 + .cfi_adjust_cfa_offset -(STACK_FRAME_OVERHEAD + 16) + br %r14 + .cfi_endproc +endf \name +.endm + +vdso_syscall __kernel_gettimeofday, __NR_gettimeofday +vdso_syscall __kernel_clock_gettime, __NR_clock_gettime +vdso_syscall __kernel_clock_getres, __NR_clock_getres +vdso_syscall __kernel_getcpu, __NR_getcpu + +/* + * TODO unwind info, though we're ok without it. + * The kernel supplies bogus empty unwind info, and it is likely ignored + * by all users. Without it we get the fallback signal frame handling. + */ + +__kernel_sigreturn: + raw_syscall __NR_sigreturn +endf __kernel_sigreturn + +__kernel_rt_sigreturn: + raw_syscall __NR_rt_sigreturn +endf __kernel_rt_sigretur