diff options
author | Heiko Carstens <hca@linux.ibm.com> | 2024-02-03 11:45:09 +0100 |
---|---|---|
committer | Heiko Carstens <hca@linux.ibm.com> | 2024-02-16 14:30:15 +0100 |
commit | 419abc4d3828813b58d047da146f519eedaa395b (patch) | |
tree | b358423efb377ffd2c050aab1ab2e41740ba44ab | |
parent | 918c7cad66509c2170e38a088550fb4a525e0878 (diff) |
s390/fpu: convert FPU CIF flag to regular TIF flag
The FPU state, as represented by the CIF_FPU flag reflects the FPU state of
a task, not the CPU it is running on. Therefore convert the flag to a
regular TIF flag.
This removes the magic in switch_to() where a save_fpu_regs() call for the
currently (previous) running task sets the per-cpu CIF_FPU flag, which is
required to restore FPU register contents of the next task, when it returns
to user space.
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
-rw-r--r-- | arch/s390/include/asm/entry-common.h | 2 | ||||
-rw-r--r-- | arch/s390/include/asm/fpu.h | 2 | ||||
-rw-r--r-- | arch/s390/include/asm/processor.h | 2 | ||||
-rw-r--r-- | arch/s390/include/asm/thread_info.h | 2 | ||||
-rw-r--r-- | arch/s390/kernel/entry.S | 2 | ||||
-rw-r--r-- | arch/s390/kernel/fpu.c | 6 | ||||
-rw-r--r-- | arch/s390/kernel/process.c | 7 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 2 | ||||
-rw-r--r-- | arch/s390/kvm/vsie.c | 2 |
9 files changed, 11 insertions, 16 deletions
diff --git a/arch/s390/include/asm/entry-common.h b/arch/s390/include/asm/entry-common.h index a1dbab19c0bd..e479d39e1445 100644 --- a/arch/s390/include/asm/entry-common.h +++ b/arch/s390/include/asm/entry-common.h @@ -41,7 +41,7 @@ static __always_inline void arch_exit_to_user_mode_work(struct pt_regs *regs, static __always_inline void arch_exit_to_user_mode(void) { - if (test_cpu_flag(CIF_FPU)) + if (test_thread_flag(TIF_FPU)) __load_fpu_regs(); if (IS_ENABLED(CONFIG_DEBUG_ENTRY)) diff --git a/arch/s390/include/asm/fpu.h b/arch/s390/include/asm/fpu.h index be85c28cdcde..3f076172a283 100644 --- a/arch/s390/include/asm/fpu.h +++ b/arch/s390/include/asm/fpu.h @@ -148,7 +148,7 @@ static inline void kernel_fpu_begin(struct kernel_fpu *state, u32 flags) { preempt_disable(); state->mask = S390_lowcore.fpu_flags; - if (!test_cpu_flag(CIF_FPU)) { + if (!test_thread_flag(TIF_FPU)) { /* Save user space FPU state and register contents */ save_fpu_regs(); } else if (state->mask & flags) { diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index a422a2cf9d05..f25617cbc49e 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -15,13 +15,11 @@ #include <linux/bits.h> #define CIF_NOHZ_DELAY 2 /* delay HZ disable for a tick */ -#define CIF_FPU 3 /* restore FPU registers */ #define CIF_ENABLED_WAIT 5 /* in enabled wait state */ #define CIF_MCCK_GUEST 6 /* machine check happening in guest */ #define CIF_DEDICATED_CPU 7 /* this CPU is dedicated */ #define _CIF_NOHZ_DELAY BIT(CIF_NOHZ_DELAY) -#define _CIF_FPU BIT(CIF_FPU) #define _CIF_ENABLED_WAIT BIT(CIF_ENABLED_WAIT) #define _CIF_MCCK_GUEST BIT(CIF_MCCK_GUEST) #define _CIF_DEDICATED_CPU BIT(CIF_DEDICATED_CPU) diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index a674c7d25da5..e3f70b94a79b 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h @@ -69,6 +69,7 @@ void arch_setup_new_exec(void); #define TIF_PATCH_PENDING 5 /* pending live patching update */ #define TIF_PGSTE 6 /* New mm's will use 4K page tables */ #define TIF_NOTIFY_SIGNAL 7 /* signal notifications exist */ +#define TIF_FPU 8 /* restore FPU registers on exit to usermode */ #define TIF_ISOLATE_BP_GUEST 9 /* Run KVM guests with isolated BP */ #define TIF_PER_TRAP 10 /* Need to handle PER trap on exit to usermode */ @@ -92,6 +93,7 @@ void arch_setup_new_exec(void); #define _TIF_UPROBE BIT(TIF_UPROBE) #define _TIF_GUARDED_STORAGE BIT(TIF_GUARDED_STORAGE) #define _TIF_PATCH_PENDING BIT(TIF_PATCH_PENDING) +#define _TIF_FPU BIT(TIF_FPU) #define _TIF_ISOLATE_BP_GUEST BIT(TIF_ISOLATE_BP_GUEST) #define _TIF_PER_TRAP BIT(TIF_PER_TRAP) diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 01c3b2d2821d..00f2e1741501 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -220,7 +220,7 @@ SYM_FUNC_START(__sie64a) oi __SIE_PROG0C+3(%r14),1 # we are going into SIE now tm __SIE_PROG20+3(%r14),3 # last exit... jnz .Lsie_skip - TSTMSK __LC_CPU_FLAGS,_CIF_FPU + TSTMSK __SF_SIE_FLAGS(%r15),_TIF_FPU jo .Lsie_skip # exit if fp/vx regs changed lg %r14,__SF_SIE_CONTROL_PHYS(%r15) # get sie block phys addr BPEXIT __SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST diff --git a/arch/s390/kernel/fpu.c b/arch/s390/kernel/fpu.c index 0a31408a46f3..12d6e9d97104 100644 --- a/arch/s390/kernel/fpu.c +++ b/arch/s390/kernel/fpu.c @@ -117,7 +117,7 @@ void __load_fpu_regs(void) load_vx_regs(regs); else load_fp_regs(regs); - clear_cpu_flag(CIF_FPU); + clear_thread_flag(TIF_FPU); } void load_fpu_regs(void) @@ -136,7 +136,7 @@ void save_fpu_regs(void) local_irq_save(flags); - if (test_cpu_flag(CIF_FPU)) + if (test_thread_flag(TIF_FPU)) goto out; state = ¤t->thread.fpu; @@ -147,7 +147,7 @@ void save_fpu_regs(void) save_vx_regs(regs); else save_fp_regs(regs); - set_cpu_flag(CIF_FPU); + set_thread_flag(TIF_FPU); out: local_irq_restore(flags); } diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index b0578ea230e7..f4c355f080f2 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -88,7 +88,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) { /* * Save the floating-point or vector register state of the current - * task and set the CIF_FPU flag to lazy restore the FPU register + * task and set the TIF_FPU flag to lazy restore the FPU register * state when returning to user space. */ save_fpu_regs(); @@ -196,11 +196,6 @@ void execve_tail(void) struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *next) { - /* - * save_fpu_regs() sets the CIF_FPU flag, which enforces - * a restore of the floating point / vector registers as - * soon as the next task returns to user space. - */ save_fpu_regs(); save_access_regs(&prev->thread.acrs[0]); save_ri_cb(prev->thread.ri_cb); diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 8f4414539756..0cee7192a1c2 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -4829,7 +4829,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) vcpu->run->s.regs.gprs, sizeof(sie_page->pv_grregs)); } - if (test_cpu_flag(CIF_FPU)) + if (test_thread_flag(TIF_FPU)) load_fpu_regs(); exit_reason = sie64a(vcpu->arch.sie_block, vcpu->run->s.regs.gprs); diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c index 457d92c2949a..b8a242360ed0 100644 --- a/arch/s390/kvm/vsie.c +++ b/arch/s390/kvm/vsie.c @@ -1149,7 +1149,7 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) */ vcpu->arch.sie_block->prog0c |= PROG_IN_SIE; barrier(); - if (test_cpu_flag(CIF_FPU)) + if (test_thread_flag(TIF_FPU)) load_fpu_regs(); if (!kvm_s390_vcpu_sie_inhibited(vcpu)) rc = sie64a(scb_s, vcpu->run->s.regs.gprs); |