summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeiko Carstens <hca@linux.ibm.com>2023-09-11 22:40:05 +0300
committerVasily Gorbik <gor@linux.ibm.com>2023-09-19 14:26:56 +0300
commitd11d5c8c8426a4abdcb2252999f1b57e3aa79e5b (patch)
tree8d4a4e3f67f7d975c63f34df473bfa1af8f286e8
parent527618abb92793b9d4dba548d55822dcebd95317 (diff)
downloadlinux-d11d5c8c8426a4abdcb2252999f1b57e3aa79e5b.tar.xz
s390/ctltreg: make initialization of control register save area explicit
Commit e1b9c2749af0 ("s390/smp: ensure global control register contents are in sync") made the control register save area contained within the lowcore at absolute address zero a resource which is used when initializing CPUs. However this is anything but obvious from the code. Add an ctlreg_init_save_area() function in order to make this explicit. Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
-rw-r--r--arch/s390/include/asm/ctlreg.h3
-rw-r--r--arch/s390/kernel/ctlreg.c11
-rw-r--r--arch/s390/kernel/setup.c3
3 files changed, 15 insertions, 2 deletions
diff --git a/arch/s390/include/asm/ctlreg.h b/arch/s390/include/asm/ctlreg.h
index 57cc610dd997..1f25601d75a0 100644
--- a/arch/s390/include/asm/ctlreg.h
+++ b/arch/s390/include/asm/ctlreg.h
@@ -110,9 +110,12 @@ static __always_inline void local_ctl_clear_bit(unsigned int cr, unsigned int bi
local_ctl_load(cr, &reg);
}
+struct lowcore;
+
void system_ctlreg_lock(void);
void system_ctlreg_unlock(void);
void system_ctl_set_clear_bit(unsigned int cr, unsigned int bit, bool set);
+void system_ctlreg_init_save_area(struct lowcore *lc);
static inline void system_ctl_set_bit(unsigned int cr, unsigned int bit)
{
diff --git a/arch/s390/kernel/ctlreg.c b/arch/s390/kernel/ctlreg.c
index 14f715bc5f73..7acc40804874 100644
--- a/arch/s390/kernel/ctlreg.c
+++ b/arch/s390/kernel/ctlreg.c
@@ -4,6 +4,7 @@
*/
#include <linux/spinlock.h>
+#include <linux/init.h>
#include <linux/smp.h>
#include <asm/abs_lowcore.h>
#include <asm/ctlreg.h>
@@ -27,6 +28,16 @@ void system_ctlreg_unlock(void)
spin_unlock(&system_ctl_lock);
}
+void __init system_ctlreg_init_save_area(struct lowcore *lc)
+{
+ struct lowcore *abs_lc;
+
+ abs_lc = get_abs_lowcore();
+ __local_ctl_store(0, 15, lc->cregs_save_area);
+ __local_ctl_store(0, 15, abs_lc->cregs_save_area);
+ put_abs_lowcore(abs_lc);
+}
+
struct ctl_bit_parms {
unsigned long orval;
unsigned long andval;
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 1c049a65c769..d399f18d0379 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -449,7 +449,6 @@ static void __init setup_lowcore(void)
lc->restart_fn = (unsigned long) do_restart;
lc->restart_data = 0;
lc->restart_source = -1U;
- __local_ctl_store(0, 15, lc->cregs_save_area);
lc->spinlock_lockval = arch_spin_lockval(0);
lc->spinlock_index = 0;
arch_spin_lock_setup(0);
@@ -459,6 +458,7 @@ static void __init setup_lowcore(void)
lc->kernel_asce = S390_lowcore.kernel_asce;
lc->user_asce = S390_lowcore.user_asce;
+ system_ctlreg_init_save_area(lc);
abs_lc = get_abs_lowcore();
abs_lc->restart_stack = lc->restart_stack;
abs_lc->restart_fn = lc->restart_fn;
@@ -466,7 +466,6 @@ static void __init setup_lowcore(void)
abs_lc->restart_source = lc->restart_source;
abs_lc->restart_psw = lc->restart_psw;
abs_lc->restart_flags = RESTART_FLAG_CTLREGS;
- memcpy(abs_lc->cregs_save_area, lc->cregs_save_area, sizeof(abs_lc->cregs_save_area));
abs_lc->program_new_psw = lc->program_new_psw;
abs_lc->mcesad = lc->mcesad;
put_abs_lowcore(abs_lc);