mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-28 07:04:00 +08:00
6c09931b3f
Pull s390 updates from Martin Schwidefsky:
"The main new feature is machine support for System zEC12 including
transactional memory, runtime instrumentation, support for scm block
devices via eadm subchannels, and support for CEX4 crypto cards.
In addition there are some nice improvements: bpf jit compiler, arch
backend for cmpxchg_double, relative exception table entries, dasd
partition detection independent from the dasd driver ioctls, and cpu
cache information in /proc/cpuinfo and /sys/device/cpu.
And last but not least a series of cleanup patches from Heiko."
Fix up trivial add-add conflict in arch/s390/Kconfig due to commit
b952741c80
("cputime: Generalize CONFIG_VIRT_CPU_ACCOUNTING")
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (76 commits)
s390: update defconfig
s390/jump label,nss: let shared kernel support depend on !JUMP_LABEL
s390/disassembler: fix decoding of risblg instruction
s390/bpf,jit: add support for BPF_S_ANC_ALU_XOR_X instruction
s390/traps: move call to print_modules() out of show_regs()
s390/mm: mark free_initrd_mem() as __init
s390/dasd: check count address during online setting
drivers/s390/char/monreader.c: fix error return code
s390/cmpxchg,percpu: implement cmpxchg_double()
s390/percpu: implement this_cpu_add_return()
s390/percpu: implement this_cpu_xchg()
s390/kexec: remove CONFIG_KEXEC
s390/irq: use designated initializers for irq class array
s390: add uninitialized_var() to suppress false positive compiler warnings
s390/crashdump: move fill_cpu_elf_notes() prototype to header file
s390/process: add missing header include
s390/ptrace: add missing ifdef
s390/ipl,decrompressor: disable branch profiling
s390/perf_events: compile only for CONFIG_64BIT
s390/tape: remove even more tape block leftovers
...
99 lines
2.3 KiB
C
99 lines
2.3 KiB
C
/*
|
|
* Copyright IBM Corp. 1999, 2009
|
|
*
|
|
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
|
|
*/
|
|
|
|
#ifndef __ASM_SWITCH_TO_H
|
|
#define __ASM_SWITCH_TO_H
|
|
|
|
#include <linux/thread_info.h>
|
|
|
|
extern struct task_struct *__switch_to(void *, void *);
|
|
extern void update_per_regs(struct task_struct *task);
|
|
|
|
static inline void save_fp_regs(s390_fp_regs *fpregs)
|
|
{
|
|
asm volatile(
|
|
" std 0,%O0+8(%R0)\n"
|
|
" std 2,%O0+24(%R0)\n"
|
|
" std 4,%O0+40(%R0)\n"
|
|
" std 6,%O0+56(%R0)"
|
|
: "=Q" (*fpregs) : "Q" (*fpregs));
|
|
if (!MACHINE_HAS_IEEE)
|
|
return;
|
|
asm volatile(
|
|
" stfpc %0\n"
|
|
" std 1,%O0+16(%R0)\n"
|
|
" std 3,%O0+32(%R0)\n"
|
|
" std 5,%O0+48(%R0)\n"
|
|
" std 7,%O0+64(%R0)\n"
|
|
" std 8,%O0+72(%R0)\n"
|
|
" std 9,%O0+80(%R0)\n"
|
|
" std 10,%O0+88(%R0)\n"
|
|
" std 11,%O0+96(%R0)\n"
|
|
" std 12,%O0+104(%R0)\n"
|
|
" std 13,%O0+112(%R0)\n"
|
|
" std 14,%O0+120(%R0)\n"
|
|
" std 15,%O0+128(%R0)\n"
|
|
: "=Q" (*fpregs) : "Q" (*fpregs));
|
|
}
|
|
|
|
static inline void restore_fp_regs(s390_fp_regs *fpregs)
|
|
{
|
|
asm volatile(
|
|
" ld 0,%O0+8(%R0)\n"
|
|
" ld 2,%O0+24(%R0)\n"
|
|
" ld 4,%O0+40(%R0)\n"
|
|
" ld 6,%O0+56(%R0)"
|
|
: : "Q" (*fpregs));
|
|
if (!MACHINE_HAS_IEEE)
|
|
return;
|
|
asm volatile(
|
|
" lfpc %0\n"
|
|
" ld 1,%O0+16(%R0)\n"
|
|
" ld 3,%O0+32(%R0)\n"
|
|
" ld 5,%O0+48(%R0)\n"
|
|
" ld 7,%O0+64(%R0)\n"
|
|
" ld 8,%O0+72(%R0)\n"
|
|
" ld 9,%O0+80(%R0)\n"
|
|
" ld 10,%O0+88(%R0)\n"
|
|
" ld 11,%O0+96(%R0)\n"
|
|
" ld 12,%O0+104(%R0)\n"
|
|
" ld 13,%O0+112(%R0)\n"
|
|
" ld 14,%O0+120(%R0)\n"
|
|
" ld 15,%O0+128(%R0)\n"
|
|
: : "Q" (*fpregs));
|
|
}
|
|
|
|
static inline void save_access_regs(unsigned int *acrs)
|
|
{
|
|
asm volatile("stam 0,15,%0" : "=Q" (*acrs));
|
|
}
|
|
|
|
static inline void restore_access_regs(unsigned int *acrs)
|
|
{
|
|
asm volatile("lam 0,15,%0" : : "Q" (*acrs));
|
|
}
|
|
|
|
#define switch_to(prev,next,last) do { \
|
|
if (prev->mm) { \
|
|
save_fp_regs(&prev->thread.fp_regs); \
|
|
save_access_regs(&prev->thread.acrs[0]); \
|
|
save_ri_cb(prev->thread.ri_cb); \
|
|
} \
|
|
if (next->mm) { \
|
|
restore_fp_regs(&next->thread.fp_regs); \
|
|
restore_access_regs(&next->thread.acrs[0]); \
|
|
restore_ri_cb(next->thread.ri_cb, prev->thread.ri_cb); \
|
|
update_per_regs(next); \
|
|
} \
|
|
prev = __switch_to(prev,next); \
|
|
} while (0)
|
|
|
|
#define finish_arch_switch(prev) do { \
|
|
set_fs(current->thread.mm_segment); \
|
|
} while (0)
|
|
|
|
#endif /* __ASM_SWITCH_TO_H */
|