s390/ctltreg: make initialization of control register save area explicit
authorHeiko Carstens <hca@linux.ibm.com>
Mon, 11 Sep 2023 19:40:05 +0000 (21:40 +0200)
committerVasily Gorbik <gor@linux.ibm.com>
Tue, 19 Sep 2023 11:26:56 +0000 (13:26 +0200)
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>
arch/s390/include/asm/ctlreg.h
arch/s390/kernel/ctlreg.c
arch/s390/kernel/setup.c

index 57cc610dd997798641655028293c4cc6aa01c40c..1f25601d75a0610d245d085b4f302085d54b848b 100644 (file)
@@ -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)
 {
index 14f715bc5f7367f476b77084218fd8e6519a291b..7acc40804874330f677933b775785da5482094c7 100644 (file)
@@ -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;
index 1c049a65c769f142d4864663ed8ac155f6a3fe51..d399f18d0379e72af109478b3671a25ba817e670 100644 (file)
@@ -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);