* [PATCH 1/4] alpha/uapi: do not expose kernel-only stack frame structures
2025-01-29 9:43 [PATCH 0/4] alpha: stack fixes Ivan Kokshaysky
@ 2025-01-29 9:43 ` Ivan Kokshaysky
2025-01-29 18:32 ` John Paul Adrian Glaubitz
2025-01-29 9:43 ` [PATCH 2/4] alpha: replace hardcoded stack offsets with autogenerated ones Ivan Kokshaysky
` (4 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Ivan Kokshaysky @ 2025-01-29 9:43 UTC (permalink / raw)
To: Richard Henderson, Matt Turner, Oleg Nesterov, Al Viro,
Arnd Bergmann, Paul E. McKenney
Cc: Maciej W. Rozycki, Magnus Lindholm, linux-alpha, linux-kernel
Parts of asm/ptrace.h went into UAPI with commit 96433f6ee490
("UAPI: (Scripted) Disintegrate arch/alpha/include/asm") back in 2012.
At first glance it looked correct, as many other architectures expose
'struct pt_regs' for ptrace(2) PTRACE_GETREGS/PTRACE_SETREGS requests.
On Alpha, however, these requests have never been implemented;
'struct pt_regs' describes internal kernel stack frame which has
nothing to do with userspace. Same applies to 'struct switch_stack',
as PTRACE_GETFPREG/PTRACE_SETFPREG are not implemented either.
Move this stuff back into internal asm, where we can ajust it
without causing a lot of confusion about possible UAPI breakage.
Fixes: 96433f6ee490 ("UAPI: (Scripted) Disintegrate arch/alpha/include/asm")
Signed-off-by: Ivan Kokshaysky <ink@unseen.parts>
---
arch/alpha/include/asm/ptrace.h | 62 +++++++++++++++++++++++++-
arch/alpha/include/uapi/asm/ptrace.h | 66 +---------------------------
2 files changed, 62 insertions(+), 66 deletions(-)
diff --git a/arch/alpha/include/asm/ptrace.h b/arch/alpha/include/asm/ptrace.h
index 3557ce64ed21..693d4c5b4dc7 100644
--- a/arch/alpha/include/asm/ptrace.h
+++ b/arch/alpha/include/asm/ptrace.h
@@ -2,8 +2,68 @@
#ifndef _ASMAXP_PTRACE_H
#define _ASMAXP_PTRACE_H
-#include <uapi/asm/ptrace.h>
+/*
+ * This struct defines the way the registers are stored on the
+ * kernel stack during a system call or other kernel entry
+ *
+ * NOTE! I want to minimize the overhead of system calls, so this
+ * struct has as little information as possible. It does not have
+ *
+ * - floating point regs: the kernel doesn't change those
+ * - r9-15: saved by the C compiler
+ *
+ * This makes "fork()" and "exec()" a bit more complex, but should
+ * give us low system call latency.
+ */
+struct pt_regs {
+ unsigned long r0;
+ unsigned long r1;
+ unsigned long r2;
+ unsigned long r3;
+ unsigned long r4;
+ unsigned long r5;
+ unsigned long r6;
+ unsigned long r7;
+ unsigned long r8;
+ unsigned long r19;
+ unsigned long r20;
+ unsigned long r21;
+ unsigned long r22;
+ unsigned long r23;
+ unsigned long r24;
+ unsigned long r25;
+ unsigned long r26;
+ unsigned long r27;
+ unsigned long r28;
+ unsigned long hae;
+/* JRP - These are the values provided to a0-a2 by PALcode */
+ unsigned long trap_a0;
+ unsigned long trap_a1;
+ unsigned long trap_a2;
+/* These are saved by PAL-code: */
+ unsigned long ps;
+ unsigned long pc;
+ unsigned long gp;
+ unsigned long r16;
+ unsigned long r17;
+ unsigned long r18;
+};
+
+/*
+ * This is the extended stack used by signal handlers and the context
+ * switcher: it's pushed after the normal "struct pt_regs".
+ */
+struct switch_stack {
+ unsigned long r9;
+ unsigned long r10;
+ unsigned long r11;
+ unsigned long r12;
+ unsigned long r13;
+ unsigned long r14;
+ unsigned long r15;
+ unsigned long r26;
+};
#define arch_has_single_step() (1)
#define user_mode(regs) (((regs)->ps & 8) != 0)
diff --git a/arch/alpha/include/uapi/asm/ptrace.h b/arch/alpha/include/uapi/asm/ptrace.h
index 5ca45934fcbb..2c08d74deac5 100644
--- a/arch/alpha/include/uapi/asm/ptrace.h
+++ b/arch/alpha/include/uapi/asm/ptrace.h
@@ -2,72 +2,8 @@
#ifndef _UAPI_ASMAXP_PTRACE_H
#define _UAPI_ASMAXP_PTRACE_H
-
-/*
- * This struct defines the way the registers are stored on the
- * kernel stack during a system call or other kernel entry
- *
- * NOTE! I want to minimize the overhead of system calls, so this
- * struct has as little information as possible. It does not have
- *
- * - floating point regs: the kernel doesn't change those
- * - r9-15: saved by the C compiler
- *
- * This makes "fork()" and "exec()" a bit more complex, but should
- * give us low system call latency.
- */
-
-struct pt_regs {
- unsigned long r0;
- unsigned long r1;
- unsigned long r2;
- unsigned long r3;
- unsigned long r4;
- unsigned long r5;
- unsigned long r6;
- unsigned long r7;
- unsigned long r8;
- unsigned long r19;
- unsigned long r20;
- unsigned long r21;
- unsigned long r22;
- unsigned long r23;
- unsigned long r24;
- unsigned long r25;
- unsigned long r26;
- unsigned long r27;
- unsigned long r28;
- unsigned long hae;
-/* JRP - These are the values provided to a0-a2 by PALcode */
- unsigned long trap_a0;
- unsigned long trap_a1;
- unsigned long trap_a2;
-/* These are saved by PAL-code: */
- unsigned long ps;
- unsigned long pc;
- unsigned long gp;
- unsigned long r16;
- unsigned long r17;
- unsigned long r18;
-};
-
/*
- * This is the extended stack used by signal handlers and the context
- * switcher: it's pushed after the normal "struct pt_regs".
+ * We have nothing to say to userspace.
*/
-struct switch_stack {
- unsigned long r9;
- unsigned long r10;
- unsigned long r11;
- unsigned long r12;
- unsigned long r13;
- unsigned long r14;
- unsigned long r15;
- unsigned long r26;
-#ifndef __KERNEL__
- unsigned long fp[32]; /* fp[31] is fpcr */
-#endif
-};
-
#endif /* _UAPI_ASMAXP_PTRACE_H */
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 1/4] alpha/uapi: do not expose kernel-only stack frame structures
2025-01-29 9:43 ` [PATCH 1/4] alpha/uapi: do not expose kernel-only stack frame structures Ivan Kokshaysky
@ 2025-01-29 18:32 ` John Paul Adrian Glaubitz
2025-01-29 19:59 ` Ivan Kokshaysky
0 siblings, 1 reply; 10+ messages in thread
From: John Paul Adrian Glaubitz @ 2025-01-29 18:32 UTC (permalink / raw)
To: Ivan Kokshaysky, Richard Henderson, Matt Turner, Oleg Nesterov,
Al Viro, Arnd Bergmann, Paul E. McKenney
Cc: Maciej W. Rozycki, Magnus Lindholm, linux-alpha, linux-kernel
Hi Ivan,
On Wed, 2025-01-29 at 10:43 +0100, Ivan Kokshaysky wrote:
> Parts of asm/ptrace.h went into UAPI with commit 96433f6ee490
> ("UAPI: (Scripted) Disintegrate arch/alpha/include/asm") back in 2012.
> At first glance it looked correct, as many other architectures expose
> 'struct pt_regs' for ptrace(2) PTRACE_GETREGS/PTRACE_SETREGS requests.
> On Alpha, however, these requests have never been implemented;
> 'struct pt_regs' describes internal kernel stack frame which has
> nothing to do with userspace. Same applies to 'struct switch_stack',
> as PTRACE_GETFPREG/PTRACE_SETFPREG are not implemented either.
>
> Move this stuff back into internal asm, where we can ajust it
> without causing a lot of confusion about possible UAPI breakage.
>
> Fixes: 96433f6ee490 ("UAPI: (Scripted) Disintegrate arch/alpha/include/asm")
> Signed-off-by: Ivan Kokshaysky <ink@unseen.parts>
> ---
> arch/alpha/include/asm/ptrace.h | 62 +++++++++++++++++++++++++-
> arch/alpha/include/uapi/asm/ptrace.h | 66 +---------------------------
> 2 files changed, 62 insertions(+), 66 deletions(-)
>
> diff --git a/arch/alpha/include/asm/ptrace.h b/arch/alpha/include/asm/ptrace.h
> index 3557ce64ed21..693d4c5b4dc7 100644
> --- a/arch/alpha/include/asm/ptrace.h
> +++ b/arch/alpha/include/asm/ptrace.h
> @@ -2,8 +2,68 @@
> #ifndef _ASMAXP_PTRACE_H
> #define _ASMAXP_PTRACE_H
>
> -#include <uapi/asm/ptrace.h>
> +/*
> + * This struct defines the way the registers are stored on the
> + * kernel stack during a system call or other kernel entry
> + *
> + * NOTE! I want to minimize the overhead of system calls, so this
> + * struct has as little information as possible. It does not have
> + *
> + * - floating point regs: the kernel doesn't change those
> + * - r9-15: saved by the C compiler
> + *
> + * This makes "fork()" and "exec()" a bit more complex, but should
> + * give us low system call latency.
> + */
>
> +struct pt_regs {
> + unsigned long r0;
> + unsigned long r1;
> + unsigned long r2;
> + unsigned long r3;
> + unsigned long r4;
> + unsigned long r5;
> + unsigned long r6;
> + unsigned long r7;
> + unsigned long r8;
> + unsigned long r19;
> + unsigned long r20;
> + unsigned long r21;
> + unsigned long r22;
> + unsigned long r23;
> + unsigned long r24;
> + unsigned long r25;
> + unsigned long r26;
> + unsigned long r27;
> + unsigned long r28;
> + unsigned long hae;
> +/* JRP - These are the values provided to a0-a2 by PALcode */
> + unsigned long trap_a0;
> + unsigned long trap_a1;
> + unsigned long trap_a2;
> +/* These are saved by PAL-code: */
> + unsigned long ps;
> + unsigned long pc;
> + unsigned long gp;
> + unsigned long r16;
> + unsigned long r17;
> + unsigned long r18;
> +};
> +
> +/*
> + * This is the extended stack used by signal handlers and the context
> + * switcher: it's pushed after the normal "struct pt_regs".
> + */
> +struct switch_stack {
> + unsigned long r9;
> + unsigned long r10;
> + unsigned long r11;
> + unsigned long r12;
> + unsigned long r13;
> + unsigned long r14;
> + unsigned long r15;
> + unsigned long r26;
> +};
>
> #define arch_has_single_step() (1)
> #define user_mode(regs) (((regs)->ps & 8) != 0)
> diff --git a/arch/alpha/include/uapi/asm/ptrace.h b/arch/alpha/include/uapi/asm/ptrace.h
> index 5ca45934fcbb..2c08d74deac5 100644
> --- a/arch/alpha/include/uapi/asm/ptrace.h
> +++ b/arch/alpha/include/uapi/asm/ptrace.h
> @@ -2,72 +2,8 @@
> #ifndef _UAPI_ASMAXP_PTRACE_H
> #define _UAPI_ASMAXP_PTRACE_H
>
> -
> -/*
> - * This struct defines the way the registers are stored on the
> - * kernel stack during a system call or other kernel entry
> - *
> - * NOTE! I want to minimize the overhead of system calls, so this
> - * struct has as little information as possible. It does not have
> - *
> - * - floating point regs: the kernel doesn't change those
> - * - r9-15: saved by the C compiler
> - *
> - * This makes "fork()" and "exec()" a bit more complex, but should
> - * give us low system call latency.
> - */
> -
> -struct pt_regs {
> - unsigned long r0;
> - unsigned long r1;
> - unsigned long r2;
> - unsigned long r3;
> - unsigned long r4;
> - unsigned long r5;
> - unsigned long r6;
> - unsigned long r7;
> - unsigned long r8;
> - unsigned long r19;
> - unsigned long r20;
> - unsigned long r21;
> - unsigned long r22;
> - unsigned long r23;
> - unsigned long r24;
> - unsigned long r25;
> - unsigned long r26;
> - unsigned long r27;
> - unsigned long r28;
> - unsigned long hae;
> -/* JRP - These are the values provided to a0-a2 by PALcode */
> - unsigned long trap_a0;
> - unsigned long trap_a1;
> - unsigned long trap_a2;
> -/* These are saved by PAL-code: */
> - unsigned long ps;
> - unsigned long pc;
> - unsigned long gp;
> - unsigned long r16;
> - unsigned long r17;
> - unsigned long r18;
> -};
> -
> /*
> - * This is the extended stack used by signal handlers and the context
> - * switcher: it's pushed after the normal "struct pt_regs".
> + * We have nothing to say to userspace.
> */
> -struct switch_stack {
> - unsigned long r9;
> - unsigned long r10;
> - unsigned long r11;
> - unsigned long r12;
> - unsigned long r13;
> - unsigned long r14;
> - unsigned long r15;
> - unsigned long r26;
> -#ifndef __KERNEL__
> - unsigned long fp[32]; /* fp[31] is fpcr */
> -#endif
> -};
> -
>
> #endif /* _UAPI_ASMAXP_PTRACE_H */
This seems to break the build for the bpf tool on alpha:
In file included from libbpf.c:36:
/build/reproducible-path/linux-6.13~rc7/tools/include/uapi/linux/bpf_perf_event.h:14:28: error: field ‘regs’ has incomplete type
14 | bpf_user_pt_regs_t regs;
| ^~~~
Adrian
--
.''`. John Paul Adrian Glaubitz
: :' : Debian Developer
`. `' Physicist
`- GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 1/4] alpha/uapi: do not expose kernel-only stack frame structures
2025-01-29 18:32 ` John Paul Adrian Glaubitz
@ 2025-01-29 19:59 ` Ivan Kokshaysky
0 siblings, 0 replies; 10+ messages in thread
From: Ivan Kokshaysky @ 2025-01-29 19:59 UTC (permalink / raw)
To: John Paul Adrian Glaubitz
Cc: Richard Henderson, Matt Turner, Oleg Nesterov, Al Viro,
Arnd Bergmann, Paul E. McKenney, Maciej W. Rozycki,
Magnus Lindholm, linux-alpha, linux-kernel
On Wed, Jan 29, 2025 at 07:32:11PM +0100, John Paul Adrian Glaubitz wrote:
> Hi Ivan,
>
> On Wed, 2025-01-29 at 10:43 +0100, Ivan Kokshaysky wrote:
> > Parts of asm/ptrace.h went into UAPI with commit 96433f6ee490
> > ("UAPI: (Scripted) Disintegrate arch/alpha/include/asm") back in 2012.
> > At first glance it looked correct, as many other architectures expose
> > 'struct pt_regs' for ptrace(2) PTRACE_GETREGS/PTRACE_SETREGS requests.
> > On Alpha, however, these requests have never been implemented;
> > 'struct pt_regs' describes internal kernel stack frame which has
> > nothing to do with userspace. Same applies to 'struct switch_stack',
> > as PTRACE_GETFPREG/PTRACE_SETFPREG are not implemented either.
> >
> > Move this stuff back into internal asm, where we can ajust it
> > without causing a lot of confusion about possible UAPI breakage.
...
> This seems to break the build for the bpf tool on alpha:
>
> In file included from libbpf.c:36:
> /build/reproducible-path/linux-6.13~rc7/tools/include/uapi/linux/bpf_perf_event.h:14:28: error: field ‘regs’ has incomplete type
> 14 | bpf_user_pt_regs_t regs;
> | ^~~~
>
Good catch, thanks!
I wonder if bpftool ever worked properly on Alpha. Will check...
Ivan.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/4] alpha: replace hardcoded stack offsets with autogenerated ones
2025-01-29 9:43 [PATCH 0/4] alpha: stack fixes Ivan Kokshaysky
2025-01-29 9:43 ` [PATCH 1/4] alpha/uapi: do not expose kernel-only stack frame structures Ivan Kokshaysky
@ 2025-01-29 9:43 ` Ivan Kokshaysky
2025-01-29 9:43 ` [PATCH 3/4] alpha: make stack 16-byte aligned (most cases) Ivan Kokshaysky
` (3 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Ivan Kokshaysky @ 2025-01-29 9:43 UTC (permalink / raw)
To: Richard Henderson, Matt Turner, Oleg Nesterov, Al Viro,
Arnd Bergmann, Paul E. McKenney
Cc: Maciej W. Rozycki, Magnus Lindholm, linux-alpha, linux-kernel
Signed-off-by: Ivan Kokshaysky <ink@unseen.parts>
---
arch/alpha/kernel/asm-offsets.c | 4 ++++
arch/alpha/kernel/entry.S | 4 ----
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/alpha/kernel/asm-offsets.c b/arch/alpha/kernel/asm-offsets.c
index 4cfeae42c79a..e9dad60b147f 100644
--- a/arch/alpha/kernel/asm-offsets.c
+++ b/arch/alpha/kernel/asm-offsets.c
@@ -19,9 +19,13 @@ static void __used foo(void)
DEFINE(TI_STATUS, offsetof(struct thread_info, status));
BLANK();
+ DEFINE(SP_OFF, offsetof(struct pt_regs, ps));
DEFINE(SIZEOF_PT_REGS, sizeof(struct pt_regs));
BLANK();
+ DEFINE(SWITCH_STACK_SIZE, sizeof(struct switch_stack));
+ BLANK();
+
DEFINE(HAE_CACHE, offsetof(struct alpha_machine_vector, hae_cache));
DEFINE(HAE_REG, offsetof(struct alpha_machine_vector, hae_register));
}
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index dd26062d75b3..6fb38365539d 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -15,10 +15,6 @@
.set noat
.cfi_sections .debug_frame
-/* Stack offsets. */
-#define SP_OFF 184
-#define SWITCH_STACK_SIZE 64
-
.macro CFI_START_OSF_FRAME func
.align 4
.globl \func
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 3/4] alpha: make stack 16-byte aligned (most cases)
2025-01-29 9:43 [PATCH 0/4] alpha: stack fixes Ivan Kokshaysky
2025-01-29 9:43 ` [PATCH 1/4] alpha/uapi: do not expose kernel-only stack frame structures Ivan Kokshaysky
2025-01-29 9:43 ` [PATCH 2/4] alpha: replace hardcoded stack offsets with autogenerated ones Ivan Kokshaysky
@ 2025-01-29 9:43 ` Ivan Kokshaysky
2025-01-29 9:43 ` [PATCH 4/4] alpha: align stack for page fault and user unaligned trap handlers Ivan Kokshaysky
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Ivan Kokshaysky @ 2025-01-29 9:43 UTC (permalink / raw)
To: Richard Henderson, Matt Turner, Oleg Nesterov, Al Viro,
Arnd Bergmann, Paul E. McKenney
Cc: Maciej W. Rozycki, Magnus Lindholm, linux-alpha, linux-kernel
Add padding between the PAL-saved and kernel-saved registers
so that 'struct pt_regs' have an even number of 64-bit words.
This makes the stack properly aligned for most of the kernel
code, except two handlers which need special threatment.
Tested-by: Magnus Lindholm <linmag7@gmail.com>
Signed-off-by: Ivan Kokshaysky <ink@unseen.parts>
---
arch/alpha/include/asm/ptrace.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/alpha/include/asm/ptrace.h b/arch/alpha/include/asm/ptrace.h
index 693d4c5b4dc7..694b82ca62f3 100644
--- a/arch/alpha/include/asm/ptrace.h
+++ b/arch/alpha/include/asm/ptrace.h
@@ -41,6 +41,8 @@ struct pt_regs {
unsigned long trap_a0;
unsigned long trap_a1;
unsigned long trap_a2;
+/* This makes the stack 16-byte aligned as GCC expects */
+ unsigned long __pad0;
/* These are saved by PAL-code: */
unsigned long ps;
unsigned long pc;
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 4/4] alpha: align stack for page fault and user unaligned trap handlers
2025-01-29 9:43 [PATCH 0/4] alpha: stack fixes Ivan Kokshaysky
` (2 preceding siblings ...)
2025-01-29 9:43 ` [PATCH 3/4] alpha: make stack 16-byte aligned (most cases) Ivan Kokshaysky
@ 2025-01-29 9:43 ` Ivan Kokshaysky
2025-01-29 10:06 ` [PATCH 0/4] alpha: stack fixes John Paul Adrian Glaubitz
2025-01-29 16:02 ` Maciej W. Rozycki
5 siblings, 0 replies; 10+ messages in thread
From: Ivan Kokshaysky @ 2025-01-29 9:43 UTC (permalink / raw)
To: Richard Henderson, Matt Turner, Oleg Nesterov, Al Viro,
Arnd Bergmann, Paul E. McKenney
Cc: Maciej W. Rozycki, Magnus Lindholm, linux-alpha, linux-kernel
do_page_fault() and do_entUna() are special because they use
non-standard stack frame layout. Fix them manually.
Tested-by: Magnus Lindholm <linmag7@gmail.com>
Suggested-by: "Maciej W. Rozycki" <macro@orcam.me.uk>
Signed-off-by: Ivan Kokshaysky <ink@unseen.parts>
---
arch/alpha/kernel/entry.S | 20 ++++++++++----------
arch/alpha/kernel/traps.c | 2 +-
arch/alpha/mm/fault.c | 4 ++--
3 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index 6fb38365539d..f4d41b4538c2 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -194,8 +194,8 @@ CFI_END_OSF_FRAME entArith
CFI_START_OSF_FRAME entMM
SAVE_ALL
/* save $9 - $15 so the inline exception code can manipulate them. */
- subq $sp, 56, $sp
- .cfi_adjust_cfa_offset 56
+ subq $sp, 64, $sp
+ .cfi_adjust_cfa_offset 64
stq $9, 0($sp)
stq $10, 8($sp)
stq $11, 16($sp)
@@ -210,7 +210,7 @@ CFI_START_OSF_FRAME entMM
.cfi_rel_offset $13, 32
.cfi_rel_offset $14, 40
.cfi_rel_offset $15, 48
- addq $sp, 56, $19
+ addq $sp, 64, $19
/* handle the fault */
lda $8, 0x3fff
bic $sp, $8, $8
@@ -223,7 +223,7 @@ CFI_START_OSF_FRAME entMM
ldq $13, 32($sp)
ldq $14, 40($sp)
ldq $15, 48($sp)
- addq $sp, 56, $sp
+ addq $sp, 64, $sp
.cfi_restore $9
.cfi_restore $10
.cfi_restore $11
@@ -231,7 +231,7 @@ CFI_START_OSF_FRAME entMM
.cfi_restore $13
.cfi_restore $14
.cfi_restore $15
- .cfi_adjust_cfa_offset -56
+ .cfi_adjust_cfa_offset -64
/* finish up the syscall as normal. */
br ret_from_sys_call
CFI_END_OSF_FRAME entMM
@@ -378,8 +378,8 @@ entUnaUser:
.cfi_restore $0
.cfi_adjust_cfa_offset -256
SAVE_ALL /* setup normal kernel stack */
- lda $sp, -56($sp)
- .cfi_adjust_cfa_offset 56
+ lda $sp, -64($sp)
+ .cfi_adjust_cfa_offset 64
stq $9, 0($sp)
stq $10, 8($sp)
stq $11, 16($sp)
@@ -395,7 +395,7 @@ entUnaUser:
.cfi_rel_offset $14, 40
.cfi_rel_offset $15, 48
lda $8, 0x3fff
- addq $sp, 56, $19
+ addq $sp, 64, $19
bic $sp, $8, $8
jsr $26, do_entUnaUser
ldq $9, 0($sp)
@@ -405,7 +405,7 @@ entUnaUser:
ldq $13, 32($sp)
ldq $14, 40($sp)
ldq $15, 48($sp)
- lda $sp, 56($sp)
+ lda $sp, 64($sp)
.cfi_restore $9
.cfi_restore $10
.cfi_restore $11
@@ -413,7 +413,7 @@ entUnaUser:
.cfi_restore $13
.cfi_restore $14
.cfi_restore $15
- .cfi_adjust_cfa_offset -56
+ .cfi_adjust_cfa_offset -64
br ret_from_sys_call
CFI_END_OSF_FRAME entUna
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index a9a38c80c4a7..7004397937cf 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -649,7 +649,7 @@ s_reg_to_mem (unsigned long s_reg)
static int unauser_reg_offsets[32] = {
R(r0), R(r1), R(r2), R(r3), R(r4), R(r5), R(r6), R(r7), R(r8),
/* r9 ... r15 are stored in front of regs. */
- -56, -48, -40, -32, -24, -16, -8,
+ -64, -56, -48, -40, -32, -24, -16, /* padding at -8 */
R(r16), R(r17), R(r18),
R(r19), R(r20), R(r21), R(r22), R(r23), R(r24), R(r25), R(r26),
R(r27), R(r28), R(gp),
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index 8c9850437e67..a9816bbc9f34 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -78,8 +78,8 @@ __load_new_mm_context(struct mm_struct *next_mm)
/* Macro for exception fixup code to access integer registers. */
#define dpf_reg(r) \
- (((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-16 : \
- (r) <= 18 ? (r)+10 : (r)-10])
+ (((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-17 : \
+ (r) <= 18 ? (r)+11 : (r)-10])
asmlinkage void
do_page_fault(unsigned long address, unsigned long mmcsr,
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 0/4] alpha: stack fixes
2025-01-29 9:43 [PATCH 0/4] alpha: stack fixes Ivan Kokshaysky
` (3 preceding siblings ...)
2025-01-29 9:43 ` [PATCH 4/4] alpha: align stack for page fault and user unaligned trap handlers Ivan Kokshaysky
@ 2025-01-29 10:06 ` John Paul Adrian Glaubitz
2025-01-29 16:02 ` Maciej W. Rozycki
5 siblings, 0 replies; 10+ messages in thread
From: John Paul Adrian Glaubitz @ 2025-01-29 10:06 UTC (permalink / raw)
To: Ivan Kokshaysky, Richard Henderson, Matt Turner, Oleg Nesterov,
Al Viro, Arnd Bergmann, Paul E. McKenney
Cc: Maciej W. Rozycki, Magnus Lindholm, linux-alpha, linux-kernel
Hi Ivan,
On Wed, 2025-01-29 at 10:43 +0100, Ivan Kokshaysky wrote:
> This series fixes oopses on Alpha/SMP observed since kernel v6.9. [1]
> Thanks to Magnus Lindholm for identifying that remarkably longstanding
> bug.
>
> The problem is that GCC expects 16-byte alignment of the incoming stack
> since early 2004, as Maciej found out [2]:
> Having actually dug speculatively I can see that the psABI was changed in
> GCC 3.5 with commit e5e10fb4a350 ("re PR target/14539 (128-bit long double
> improperly aligned)") back in Mar 2004, when the stack pointer alignment
> was increased from 8 bytes to 16 bytes, and arch/alpha/kernel/entry.S has
> various suspicious stack pointer adjustments, starting with SP_OFF which
> is not a whole multiple of 16.
>
> Also, as Magnus noted, "ALPHA Calling Standard" [3] required the same:
> D.3.1 Stack Alignment
> This standard requires that stacks be octaword aligned at the time a
> new procedure is invoked.
>
> However:
> - the "normal" kernel stack is always misaligned by 8 bytes, thanks to
> the odd number of 64-bit words in 'struct pt_regs', which is the very
> first thing pushed onto the kernel thread stack;
> - syscall, fault, interrupt etc. handlers may, or may not, receive aligned
> stack depending on numerous factors.
>
> Somehow we got away with it until recently, when we ended up with
> a stack corruption in kernel/smp.c:smp_call_function_single() due to
> its use of 32-byte aligned local data and the compiler doing clever
> things allocating it on the stack.
>
> Patches 1-2 are preparatory; 3 - the main fix; 4 - fixes remaining
> special cases.
>
> Ivan.
>
> [1] https://lore.kernel.org/rcu/CA+=Fv5R9NG+1SHU9QV9hjmavycHKpnNyerQ=Ei90G98ukRcRJA@mail.gmail.com/#r
> [2] https://lore.kernel.org/rcu/alpine.DEB.2.21.2501130248010.18889@angie.orcam.me.uk/
> [3] https://bitsavers.org/pdf/dec/alpha/Alpha_Calling_Standard_Rev_2.0_19900427.pdf
> ---
> Ivan Kokshaysky (4):
> alpha/uapi: do not expose kernel-only stack frame structures
> alpha: replace hardcoded stack offsets with autogenerated ones
> alpha: make stack 16-byte aligned (most cases)
> alpha: align stack for page fault and user unaligned trap handlers
>
> arch/alpha/include/asm/ptrace.h | 64 ++++++++++++++++++++++++++-
> arch/alpha/include/uapi/asm/ptrace.h | 66 +---------------------------
> arch/alpha/kernel/asm-offsets.c | 4 ++
> arch/alpha/kernel/entry.S | 24 +++++-----
> arch/alpha/kernel/traps.c | 2 +-
> arch/alpha/mm/fault.c | 4 +-
> 6 files changed, 81 insertions(+), 83 deletions(-)
Thanks a lot for the series! I just applied them on top of Debian's current
6.12.11 kernel in unstable and will thoroughly test the patches. Will report
back the results later this week.
Adrian
--
.''`. John Paul Adrian Glaubitz
: :' : Debian Developer
`. `' Physicist
`- GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 0/4] alpha: stack fixes
2025-01-29 9:43 [PATCH 0/4] alpha: stack fixes Ivan Kokshaysky
` (4 preceding siblings ...)
2025-01-29 10:06 ` [PATCH 0/4] alpha: stack fixes John Paul Adrian Glaubitz
@ 2025-01-29 16:02 ` Maciej W. Rozycki
2025-01-30 14:33 ` Ivan Kokshaysky
5 siblings, 1 reply; 10+ messages in thread
From: Maciej W. Rozycki @ 2025-01-29 16:02 UTC (permalink / raw)
To: Ivan Kokshaysky
Cc: Richard Henderson, Matt Turner, Oleg Nesterov, Al Viro,
Arnd Bergmann, Paul E. McKenney, Magnus Lindholm, linux-alpha,
linux-kernel
On Wed, 29 Jan 2025, Ivan Kokshaysky wrote:
> Somehow we got away with it until recently, when we ended up with
> a stack corruption in kernel/smp.c:smp_call_function_single() due to
> its use of 32-byte aligned local data and the compiler doing clever
> things allocating it on the stack.
Thank you for doing this work.
I'll review/verify your changes by hand and push them through GCC and
glibc regression testing, which should hopefully pick any fallout without
having it buried among any intermittent failures, and report back.
However, would you please cc <stable@kernel.org> with your submission, v2
presumably, so as to have these changes backported?
The thing is I find it quite a grave bug being fixed here, which has been
there for decades and triggering occasionally[1], and it might be the only
way for users of certain older systems to get a kernel with the fix
already applied. As you may have been aware non-BWX Alpha support has
been removed and while I'm working on bringing it back, it will likely be
missing support for specific models such as Jensen there will be no kernel
developer to look after. So getting an LTS kernel might be the only way
to get a stable system for some people.
References:
[1] "System fails to boot when CONFIG_SMP=y",
<https://bugzilla.kernel.org/show_bug.cgi?id=213143>
Maciej
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 0/4] alpha: stack fixes
2025-01-29 16:02 ` Maciej W. Rozycki
@ 2025-01-30 14:33 ` Ivan Kokshaysky
0 siblings, 0 replies; 10+ messages in thread
From: Ivan Kokshaysky @ 2025-01-30 14:33 UTC (permalink / raw)
To: Maciej W. Rozycki
Cc: Richard Henderson, Matt Turner, Oleg Nesterov, Al Viro,
Arnd Bergmann, Paul E. McKenney, Magnus Lindholm, linux-alpha,
linux-kernel
On Wed, Jan 29, 2025 at 04:02:26PM +0000, Maciej W. Rozycki wrote:
> On Wed, 29 Jan 2025, Ivan Kokshaysky wrote:
>
> > Somehow we got away with it until recently, when we ended up with
> > a stack corruption in kernel/smp.c:smp_call_function_single() due to
> > its use of 32-byte aligned local data and the compiler doing clever
> > things allocating it on the stack.
>
> Thank you for doing this work.
>
> I'll review/verify your changes by hand and push them through GCC and
> glibc regression testing, which should hopefully pick any fallout without
> having it buried among any intermittent failures, and report back.
Thanks!
> However, would you please cc <stable@kernel.org> with your submission, v2
> presumably, so as to have these changes backported?
Sure.
As I need to deal with bpf build failure, v2 is inevitable.
> The thing is I find it quite a grave bug being fixed here, which has been
> there for decades and triggering occasionally[1], and it might be the only
> way for users of certain older systems to get a kernel with the fix
> already applied. As you may have been aware non-BWX Alpha support has
> been removed and while I'm working on bringing it back, it will likely be
> missing support for specific models such as Jensen there will be no kernel
> developer to look after. So getting an LTS kernel might be the only way
> to get a stable system for some people.
Yes, I know about your work on non-BWX Alpha and highly appreciate it.
> References:
>
> [1] "System fails to boot when CONFIG_SMP=y",
> <https://bugzilla.kernel.org/show_bug.cgi?id=213143>
>
> Maciej
Ivan.
^ permalink raw reply [flat|nested] 10+ messages in thread