]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
s390/time: Convert MACHINE_HAS_SCC to machine_has_scc()
authorHeiko Carstens <hca@linux.ibm.com>
Fri, 7 Feb 2025 14:48:59 +0000 (15:48 +0100)
committerVasily Gorbik <gor@linux.ibm.com>
Tue, 4 Mar 2025 16:18:06 +0000 (17:18 +0100)
Use static branch(es) to implement and use machine_has_scc() instead
of a runtime check via MACHINE_HAS_SCC.

This comes with a cleanup of early time initialization: the initial
tod_clock_base value is now passed via the bootdata mechanism, instead
of using absolute lowcore as transport vehicle from the decompressor
to the kernel.

Also the early tod clock initialization is moved to the decompressor
which allows to use a static branch with machine_has_scc() within the
kernel.

Reviewed-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
arch/s390/boot/head.S
arch/s390/boot/printk.c
arch/s390/boot/startup.c
arch/s390/include/asm/lowcore.h
arch/s390/include/asm/machine.h
arch/s390/include/asm/setup.h
arch/s390/include/asm/timex.h
arch/s390/kernel/asm-offsets.c
arch/s390/kernel/early.c
arch/s390/kernel/head64.S
arch/s390/kernel/time.c

index 0a47b16f641289d55a425aa29890c74790a24339..fe68c9253ea2aebb8e8374dba818e8daf78fe46e 100644 (file)
@@ -254,8 +254,9 @@ SYM_CODE_START_LOCAL(startup_normal)
        xc      0xf00(256),0xf00
        larl    %r13,.Lctl
        lctlg   %c0,%c15,0(%r13)        # load control registers
-       stcke   __LC_BOOT_CLOCK
-       mvc     __LC_LAST_UPDATE_CLOCK(8),__LC_BOOT_CLOCK+1
+       larl    %r13,tod_clock_base
+       stcke   0(%r13)
+       mvc     __LC_LAST_UPDATE_CLOCK(8),1(%r13)
        larl    %r13,6f
        spt     0(%r13)
        mvc     __LC_LAST_UPDATE_TIMER(8),0(%r13)
index b4c66fa667d54934ed1ecc0b175dd5523fc94865..8cf6331bc060839fcd272dc9ac198c3cdea94329 100644 (file)
@@ -8,6 +8,7 @@
 #include <asm/sections.h>
 #include <asm/lowcore.h>
 #include <asm/setup.h>
+#include <asm/timex.h>
 #include <asm/sclp.h>
 #include <asm/uv.h>
 #include "boot.h"
@@ -199,8 +200,7 @@ static void boot_console_earlyprintk(const char *buf)
 static char *add_timestamp(char *buf)
 {
 #ifdef CONFIG_PRINTK_TIME
-       union tod_clock *boot_clock = (union tod_clock *)&get_lowcore()->boot_clock;
-       unsigned long ns = tod_to_ns(get_tod_clock() - boot_clock->tod);
+       unsigned long ns = tod_to_ns(__get_tod_clock_monotonic());
        char ts[MAX_NUMLEN];
 
        *buf++ = '[';
index 8081f06ad25877d69160422d362b186505220b0b..1c7367a338cdd53a8d7db6784344d2fd47a9bb33 100644 (file)
@@ -10,6 +10,7 @@
 #include <asm/machine.h>
 #include <asm/cpu_mf.h>
 #include <asm/setup.h>
+#include <asm/timex.h>
 #include <asm/kasan.h>
 #include <asm/kexec.h>
 #include <asm/sclp.h>
@@ -35,6 +36,8 @@ unsigned long __bootdata_preserved(max_mappable);
 unsigned long __bootdata_preserved(page_noexec_mask);
 unsigned long __bootdata_preserved(segment_noexec_mask);
 unsigned long __bootdata_preserved(region_noexec_mask);
+union tod_clock __bootdata_preserved(tod_clock_base);
+u64 __bootdata_preserved(clock_comparator_max) = -1UL;
 
 u64 __bootdata_preserved(stfle_fac_list[16]);
 struct oldmem_data __bootdata_preserved(oldmem_data);
@@ -46,6 +49,20 @@ void error(char *x)
        disabled_wait();
 }
 
+static void reset_tod_clock(void)
+{
+       union tod_clock clk;
+
+       if (store_tod_clock_ext_cc(&clk) == 0)
+               return;
+       /* TOD clock not running. Set the clock to Unix Epoch. */
+       if (set_tod_clock(TOD_UNIX_EPOCH) || store_tod_clock_ext_cc(&clk))
+               disabled_wait();
+       memset(&tod_clock_base, 0, sizeof(tod_clock_base));
+       tod_clock_base.tod = TOD_UNIX_EPOCH;
+       get_lowcore()->last_update_clock = TOD_UNIX_EPOCH;
+}
+
 static void detect_facilities(void)
 {
        if (cpu_has_edat1())
@@ -60,6 +77,13 @@ static void detect_facilities(void)
        }
        if (IS_ENABLED(CONFIG_PCI) && test_facility(153))
                set_machine_feature(MFEATURE_PCI_MIO);
+       reset_tod_clock();
+       if (test_facility(139) && (tod_clock_base.tod >> 63)) {
+               /* Enable signed clock comparator comparisons */
+               set_machine_feature(MFEATURE_SCC);
+               clock_comparator_max = -1UL >> 1;
+               local_ctl_set_bit(0, CR0_CLOCK_COMPARATOR_SIGN_BIT);
+       }
 }
 
 static int cmma_test_essa(void)
index 60c887cdbaec97f299b899143782af2e3e82f23e..8067edd120ebcfc3df22665c816738caac348fc0 100644 (file)
@@ -127,7 +127,7 @@ struct lowcore {
        __u64   int_clock;                      /* 0x0318 */
        __u8    pad_0x0320[0x0328-0x0320];      /* 0x0320 */
        __u64   clock_comparator;               /* 0x0328 */
-       __u64   boot_clock[2];                  /* 0x0330 */
+       __u8    pad_0x0330[0x0340-0x0330];      /* 0x0330 */
 
        /* Current process. */
        __u64   current_task;                   /* 0x0340 */
index 488e5d64171301bb1fb4652cb691193cf979c1b6..e0a0e4121d08cde009726ec8a0292cac347a4bde 100644 (file)
@@ -10,6 +10,7 @@
 
 #define MFEATURE_LOWCORE       0
 #define MFEATURE_PCI_MIO       1
+#define MFEATURE_SCC           2
 
 #ifndef __ASSEMBLY__
 
@@ -78,6 +79,7 @@ static __always_inline bool machine_has_##name(void)                          \
 }
 
 DEFINE_MACHINE_HAS_FEATURE(relocated_lowcore, MFEATURE_LOWCORE)
+DEFINE_MACHINE_HAS_FEATURE(scc, MFEATURE_SCC)
 
 #endif /* __ASSEMBLY__ */
 #endif /* __ASM_S390_MACHINE_H */
index 5844f6e09162c0146a099514a9ec02903443ee05..b1f6ea1e000aa85370362ccf12e3308def2ae4e3 100644 (file)
@@ -24,7 +24,6 @@
 #define MACHINE_FLAG_ESOP      BIT(4)
 #define MACHINE_FLAG_TE                BIT(11)
 #define MACHINE_FLAG_TLB_GUEST BIT(14)
-#define MACHINE_FLAG_SCC       BIT(17)
 
 #define LPP_MAGIC              BIT(31)
 #define LPP_PID_MASK           _AC(0xffffffff, UL)
@@ -76,7 +75,6 @@ extern unsigned long mio_wb_bit_mask;
 #define MACHINE_HAS_ESOP       (get_lowcore()->machine_flags & MACHINE_FLAG_ESOP)
 #define MACHINE_HAS_TE         (get_lowcore()->machine_flags & MACHINE_FLAG_TE)
 #define MACHINE_HAS_TLB_GUEST  (get_lowcore()->machine_flags & MACHINE_FLAG_TLB_GUEST)
-#define MACHINE_HAS_SCC                (get_lowcore()->machine_flags & MACHINE_FLAG_SCC)
 
 /*
  * Console mode. Override with conmode=
index a9460bd6555b8b5dd42d14e167e7445497a75844..bed8d0b5a282c051a70e22cbfd207d1fc0a60872 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/preempt.h>
 #include <linux/time64.h>
 #include <asm/lowcore.h>
+#include <asm/machine.h>
 #include <asm/asm.h>
 
 /* The value of the TOD clock for 1.1.1970. */
@@ -267,7 +268,7 @@ static __always_inline u128 eitod_to_ns(u128 todval)
  */
 static inline int tod_after(unsigned long a, unsigned long b)
 {
-       if (MACHINE_HAS_SCC)
+       if (machine_has_scc())
                return (long) a > (long) b;
        return a > b;
 }
@@ -281,7 +282,7 @@ static inline int tod_after(unsigned long a, unsigned long b)
  */
 static inline int tod_after_eq(unsigned long a, unsigned long b)
 {
-       if (MACHINE_HAS_SCC)
+       if (machine_has_scc())
                return (long) a >= (long) b;
        return a >= b;
 }
index 36709112ae7a254a53d3be39c17abe87a869287f..1242e7435647d310d42a4b165f60175a3e3b19f9 100644 (file)
@@ -122,7 +122,6 @@ int main(void)
        OFFSET(__LC_LAST_UPDATE_TIMER, lowcore, last_update_timer);
        OFFSET(__LC_LAST_UPDATE_CLOCK, lowcore, last_update_clock);
        OFFSET(__LC_INT_CLOCK, lowcore, int_clock);
-       OFFSET(__LC_BOOT_CLOCK, lowcore, boot_clock);
        OFFSET(__LC_CURRENT, lowcore, current_task);
        OFFSET(__LC_KERNEL_STACK, lowcore, kernel_stack);
        OFFSET(__LC_ASYNC_STACK, lowcore, async_stack);
index 9e673dab7c1187aedf0d1c7fa2f8daa5ce545294..708f158cc60ef626d62de668c938661ea51088ee 100644 (file)
@@ -64,21 +64,6 @@ static void __init kasan_early_init(void)
 #endif
 }
 
-static void __init reset_tod_clock(void)
-{
-       union tod_clock clk;
-
-       if (store_tod_clock_ext_cc(&clk) == 0)
-               return;
-       /* TOD clock not running. Set the clock to Unix Epoch. */
-       if (set_tod_clock(TOD_UNIX_EPOCH) || store_tod_clock_ext_cc(&clk))
-               disabled_wait();
-
-       memset(&tod_clock_base, 0, sizeof(tod_clock_base));
-       tod_clock_base.tod = TOD_UNIX_EPOCH;
-       get_lowcore()->last_update_clock = TOD_UNIX_EPOCH;
-}
-
 /*
  * Initialize storage key for kernel pages
  */
@@ -243,12 +228,6 @@ static __init void detect_machine_facilities(void)
        }
        if (test_facility(129))
                system_ctl_set_bit(0, CR0_VECTOR_BIT);
-       if (test_facility(139) && (tod_clock_base.tod >> 63)) {
-               /* Enabled signed clock comparator comparisons */
-               get_lowcore()->machine_flags |= MACHINE_FLAG_SCC;
-               clock_comparator_max = -1ULL >> 1;
-               system_ctl_set_bit(0, CR0_CLOCK_COMPARATOR_SIGN_BIT);
-       }
 }
 
 static inline void save_vector_registers(void)
@@ -286,7 +265,6 @@ static void __init sort_amode31_extable(void)
 void __init startup_init(void)
 {
        kasan_early_init();
-       reset_tod_clock();
        time_early_init();
        init_kernel_storage_key();
        lockdep_off();
index 396034b2fe678238c37b1052316f837d4c291cbc..7edb9ded199cee0d9996dc14636580aa54481a08 100644 (file)
 
 __HEAD
 SYM_CODE_START(startup_continue)
-       larl    %r1,tod_clock_base
-       GET_LC  %r2
-       mvc     0(16,%r1),__LC_BOOT_CLOCK(%r2)
 #
 # Setup stack
 #
+       GET_LC  %r2
        larl    %r14,init_task
        stg     %r14,__LC_CURRENT(%r2)
        larl    %r15,init_thread_union+STACK_INIT_OFFSET
index e9f47c3a61978a45c72aee23bc44dcb128113c8c..ac58b1db40e68b02fc739246d5e74be537c1df23 100644 (file)
 #include <asm/cio.h>
 #include "entry.h"
 
-union tod_clock tod_clock_base __section(".data");
+union tod_clock __bootdata_preserved(tod_clock_base);
 EXPORT_SYMBOL_GPL(tod_clock_base);
 
-u64 clock_comparator_max = -1ULL;
+u64 __bootdata_preserved(clock_comparator_max);
 EXPORT_SYMBOL_GPL(clock_comparator_max);
 
 static DEFINE_PER_CPU(struct clock_event_device, comparators);