diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-02-25 23:49:29 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-02-25 23:49:29 +0300 |
commit | e534a583cc438ec2e9a7dc534c9d80d14b440718 (patch) | |
tree | 6ac37b039f0437be3a22b0e79fee272b353dd0d3 /arch/alpha/lib | |
parent | cac85e4616b1cf4a90844b952b49b9cbc4562530 (diff) | |
parent | 290ec1d58049e6203062d5fc796c50852112ae00 (diff) | |
download | linux-e534a583cc438ec2e9a7dc534c9d80d14b440718.tar.xz |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mattst88/alpha
Pull alpha updates from Al Viro:
"Mostly small janitorial fixes but there's also more important ones: a
patch to fix loading large modules from Edward Humes, and some fixes
from Al Viro"
[ The fixes from Al mostly came in separately through Al's trees too and
are now duplicated.. - Linus ]
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mattst88/alpha:
alpha: in_irq() cleanup
alpha: lazy FPU switching
alpha/boot/misc: trim unused declarations
alpha/boot/tools/objstrip: fix the check for ELF header
alpha/boot: fix the breakage from -isystem series...
alpha: fix FEN fault handling
alpha: Avoid comma separated statements
alpha: fixed a typo in core_cia.c
alpha: remove unused __SLOW_DOWN_IO and SLOW_DOWN_IO definitions
alpha: update config files
alpha: fix R_ALPHA_LITERAL reloc for large modules
alpha: Add some spaces to ensure format specification
alpha: replace NR_SYSCALLS by NR_syscalls
alpha: Remove redundant local asm header redirections
alpha: Implement "current_stack_pointer"
alpha: remove redundant err variable
alpha: osf_sys: reduce kernel log spamming on invalid osf_mount call typenr
Diffstat (limited to 'arch/alpha/lib')
-rw-r--r-- | arch/alpha/lib/fpreg.c | 43 | ||||
-rw-r--r-- | arch/alpha/lib/stacktrace.c | 2 |
2 files changed, 38 insertions, 7 deletions
diff --git a/arch/alpha/lib/fpreg.c b/arch/alpha/lib/fpreg.c index 34fea465645b..612c5eca71bc 100644 --- a/arch/alpha/lib/fpreg.c +++ b/arch/alpha/lib/fpreg.c @@ -7,6 +7,8 @@ #include <linux/compiler.h> #include <linux/export.h> +#include <linux/preempt.h> +#include <asm/thread_info.h> #if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67) #define STT(reg,val) asm volatile ("ftoit $f"#reg",%0" : "=r"(val)); @@ -19,7 +21,12 @@ alpha_read_fp_reg (unsigned long reg) { unsigned long val; - switch (reg) { + if (unlikely(reg >= 32)) + return 0; + preempt_enable(); + if (current_thread_info()->status & TS_SAVED_FP) + val = current_thread_info()->fp[reg]; + else switch (reg) { case 0: STT( 0, val); break; case 1: STT( 1, val); break; case 2: STT( 2, val); break; @@ -52,8 +59,8 @@ alpha_read_fp_reg (unsigned long reg) case 29: STT(29, val); break; case 30: STT(30, val); break; case 31: STT(31, val); break; - default: return 0; } + preempt_enable(); return val; } EXPORT_SYMBOL(alpha_read_fp_reg); @@ -67,7 +74,14 @@ EXPORT_SYMBOL(alpha_read_fp_reg); void alpha_write_fp_reg (unsigned long reg, unsigned long val) { - switch (reg) { + if (unlikely(reg >= 32)) + return; + + preempt_disable(); + if (current_thread_info()->status & TS_SAVED_FP) { + current_thread_info()->status |= TS_RESTORE_FP; + current_thread_info()->fp[reg] = val; + } else switch (reg) { case 0: LDT( 0, val); break; case 1: LDT( 1, val); break; case 2: LDT( 2, val); break; @@ -101,6 +115,7 @@ alpha_write_fp_reg (unsigned long reg, unsigned long val) case 30: LDT(30, val); break; case 31: LDT(31, val); break; } + preempt_enable(); } EXPORT_SYMBOL(alpha_write_fp_reg); @@ -115,7 +130,14 @@ alpha_read_fp_reg_s (unsigned long reg) { unsigned long val; - switch (reg) { + if (unlikely(reg >= 32)) + return 0; + + preempt_enable(); + if (current_thread_info()->status & TS_SAVED_FP) { + LDT(0, current_thread_info()->fp[reg]); + STS(0, val); + } else switch (reg) { case 0: STS( 0, val); break; case 1: STS( 1, val); break; case 2: STS( 2, val); break; @@ -148,8 +170,8 @@ alpha_read_fp_reg_s (unsigned long reg) case 29: STS(29, val); break; case 30: STS(30, val); break; case 31: STS(31, val); break; - default: return 0; } + preempt_enable(); return val; } EXPORT_SYMBOL(alpha_read_fp_reg_s); @@ -163,7 +185,15 @@ EXPORT_SYMBOL(alpha_read_fp_reg_s); void alpha_write_fp_reg_s (unsigned long reg, unsigned long val) { - switch (reg) { + if (unlikely(reg >= 32)) + return; + + preempt_disable(); + if (current_thread_info()->status & TS_SAVED_FP) { + current_thread_info()->status |= TS_RESTORE_FP; + LDS(0, val); + STT(0, current_thread_info()->fp[reg]); + } else switch (reg) { case 0: LDS( 0, val); break; case 1: LDS( 1, val); break; case 2: LDS( 2, val); break; @@ -197,5 +227,6 @@ alpha_write_fp_reg_s (unsigned long reg, unsigned long val) case 30: LDS(30, val); break; case 31: LDS(31, val); break; } + preempt_enable(); } EXPORT_SYMBOL(alpha_write_fp_reg_s); diff --git a/arch/alpha/lib/stacktrace.c b/arch/alpha/lib/stacktrace.c index 62454a7810e2..2b1176dd5174 100644 --- a/arch/alpha/lib/stacktrace.c +++ b/arch/alpha/lib/stacktrace.c @@ -92,7 +92,7 @@ stacktrace(void) { instr * ret_pc; instr * prologue = (instr *)stacktrace; - register unsigned char * sp __asm__ ("$30"); + unsigned char *sp = (unsigned char *)current_stack_pointer; printk("\tstack trace:\n"); do { |