OSDN Git Service

s390/mm: allocate Absolute Lowcore Area in decompressor
authorAlexander Gordeev <agordeev@linux.ibm.com>
Mon, 19 Dec 2022 20:08:27 +0000 (21:08 +0100)
committerHeiko Carstens <hca@linux.ibm.com>
Fri, 13 Jan 2023 13:15:06 +0000 (14:15 +0100)
Move Absolute Lowcore Area allocation to the decompressor.
As result, get_abs_lowcore() and put_abs_lowcore() access
brackets become really straight and do not require complex
execution context analysis and LAP and interrupts tackling.

Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
arch/s390/boot/boot.h
arch/s390/boot/vmem.c
arch/s390/include/asm/abs_lowcore.h
arch/s390/kernel/abs_lowcore.c
arch/s390/kernel/ipl.c
arch/s390/kernel/machine_kexec.c
arch/s390/kernel/os_info.c
arch/s390/kernel/setup.c
arch/s390/kernel/smp.c
arch/s390/mm/maccess.c

index 5476144..8abedae 100644 (file)
@@ -66,5 +66,7 @@ extern unsigned char _compressed_end[];
 extern struct vmlinux_info _vmlinux_info;
 #define vmlinux _vmlinux_info
 
+#define __abs_lowcore_pa(x)    (((unsigned long)(x) - __abs_lowcore) % sizeof(struct lowcore))
+
 #endif /* __ASSEMBLY__ */
 #endif /* BOOT_BOOT_H */
index 41ff38a..3bcef4f 100644 (file)
@@ -6,6 +6,7 @@
 #include <asm/sections.h>
 #include <asm/mem_detect.h>
 #include <asm/maccess.h>
+#include <asm/abs_lowcore.h>
 #include "decompressor.h"
 #include "boot.h"
 
@@ -29,6 +30,7 @@ unsigned long __bootdata(pgalloc_low);
 enum populate_mode {
        POPULATE_NONE,
        POPULATE_ONE2ONE,
+       POPULATE_ABS_LOWCORE,
 };
 
 static void boot_check_oom(void)
@@ -102,6 +104,8 @@ static unsigned long _pa(unsigned long addr, enum populate_mode mode)
                return -1;
        case POPULATE_ONE2ONE:
                return addr;
+       case POPULATE_ABS_LOWCORE:
+               return __abs_lowcore_pa(addr);
        default:
                return -1;
        }
@@ -271,6 +275,8 @@ void setup_vmem(unsigned long online_end, unsigned long asce_limit)
        pgtable_populate_begin(online_end);
        pgtable_populate(0, sizeof(struct lowcore), POPULATE_ONE2ONE);
        pgtable_populate(0, online_end, POPULATE_ONE2ONE);
+       pgtable_populate(__abs_lowcore, __abs_lowcore + sizeof(struct lowcore),
+                        POPULATE_ABS_LOWCORE);
        pgtable_populate(__memcpy_real_area, __memcpy_real_area + PAGE_SIZE,
                         POPULATE_NONE);
        memcpy_real_ptep = __virt_to_kpte(__memcpy_real_area);
index 4c61b14..6f264b7 100644 (file)
@@ -7,11 +7,21 @@
 #define ABS_LOWCORE_MAP_SIZE   (NR_CPUS * sizeof(struct lowcore))
 
 extern unsigned long __abs_lowcore;
-extern bool abs_lowcore_mapped;
 
-struct lowcore *get_abs_lowcore(unsigned long *flags);
-void put_abs_lowcore(struct lowcore *lc, unsigned long flags);
 int abs_lowcore_map(int cpu, struct lowcore *lc, bool alloc);
 void abs_lowcore_unmap(int cpu);
 
+static inline struct lowcore *get_abs_lowcore(void)
+{
+       int cpu;
+
+       cpu = get_cpu();
+       return ((struct lowcore *)__abs_lowcore) + cpu;
+}
+
+static inline void put_abs_lowcore(struct lowcore *lc)
+{
+       put_cpu();
+}
+
 #endif /* _ASM_S390_ABS_LOWCORE_H */
index fb92e8e..f9efc54 100644 (file)
@@ -3,12 +3,7 @@
 #include <linux/pgtable.h>
 #include <asm/abs_lowcore.h>
 
-#define ABS_LOWCORE_UNMAPPED   1
-#define ABS_LOWCORE_LAP_ON     2
-#define ABS_LOWCORE_IRQS_ON    4
-
 unsigned long __bootdata_preserved(__abs_lowcore);
-bool __ro_after_init abs_lowcore_mapped;
 
 int abs_lowcore_map(int cpu, struct lowcore *lc, bool alloc)
 {
@@ -49,47 +44,3 @@ void abs_lowcore_unmap(int cpu)
                addr += PAGE_SIZE;
        }
 }
-
-struct lowcore *get_abs_lowcore(unsigned long *flags)
-{
-       unsigned long irq_flags;
-       union ctlreg0 cr0;
-       int cpu;
-
-       *flags = 0;
-       cpu = get_cpu();
-       if (abs_lowcore_mapped) {
-               return ((struct lowcore *)__abs_lowcore) + cpu;
-       } else {
-               if (cpu != 0)
-                       panic("Invalid unmapped absolute lowcore access\n");
-               local_irq_save(irq_flags);
-               if (!irqs_disabled_flags(irq_flags))
-                       *flags |= ABS_LOWCORE_IRQS_ON;
-               __ctl_store(cr0.val, 0, 0);
-               if (cr0.lap) {
-                       *flags |= ABS_LOWCORE_LAP_ON;
-                       __ctl_clear_bit(0, 28);
-               }
-               *flags |= ABS_LOWCORE_UNMAPPED;
-               return lowcore_ptr[0];
-       }
-}
-
-void put_abs_lowcore(struct lowcore *lc, unsigned long flags)
-{
-       if (abs_lowcore_mapped) {
-               if (flags)
-                       panic("Invalid mapped absolute lowcore release\n");
-       } else {
-               if (smp_processor_id() != 0)
-                       panic("Invalid mapped absolute lowcore access\n");
-               if (!(flags & ABS_LOWCORE_UNMAPPED))
-                       panic("Invalid unmapped absolute lowcore release\n");
-               if (flags & ABS_LOWCORE_LAP_ON)
-                       __ctl_set_bit(0, 28);
-               if (flags & ABS_LOWCORE_IRQS_ON)
-                       local_irq_enable();
-       }
-       put_cpu();
-}
index fbd646d..b74b728 100644 (file)
@@ -1986,15 +1986,14 @@ static void dump_reipl_run(struct shutdown_trigger *trigger)
 {
        unsigned long ipib = (unsigned long) reipl_block_actual;
        struct lowcore *abs_lc;
-       unsigned long flags;
        unsigned int csum;
 
        csum = (__force unsigned int)
               csum_partial(reipl_block_actual, reipl_block_actual->hdr.len, 0);
-       abs_lc = get_abs_lowcore(&flags);
+       abs_lc = get_abs_lowcore();
        abs_lc->ipib = ipib;
        abs_lc->ipib_checksum = csum;
-       put_abs_lowcore(abs_lc, flags);
+       put_abs_lowcore(abs_lc);
        dump_run(trigger);
 }
 
index 4579b42..2a8e732 100644 (file)
@@ -224,7 +224,6 @@ void machine_kexec_cleanup(struct kimage *image)
 void arch_crash_save_vmcoreinfo(void)
 {
        struct lowcore *abs_lc;
-       unsigned long flags;
 
        VMCOREINFO_SYMBOL(lowcore_ptr);
        VMCOREINFO_SYMBOL(high_memory);
@@ -232,9 +231,9 @@ void arch_crash_save_vmcoreinfo(void)
        vmcoreinfo_append_str("SAMODE31=%lx\n", __samode31);
        vmcoreinfo_append_str("EAMODE31=%lx\n", __eamode31);
        vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset());
-       abs_lc = get_abs_lowcore(&flags);
+       abs_lc = get_abs_lowcore();
        abs_lc->vmcore_info = paddr_vmcoreinfo_note();
-       put_abs_lowcore(abs_lc, flags);
+       put_abs_lowcore(abs_lc);
 }
 
 void machine_shutdown(void)
index ec0bd94..6e18241 100644 (file)
@@ -59,15 +59,14 @@ void os_info_entry_add(int nr, void *ptr, u64 size)
 void __init os_info_init(void)
 {
        struct lowcore *abs_lc;
-       unsigned long flags;
 
        os_info.version_major = OS_INFO_VERSION_MAJOR;
        os_info.version_minor = OS_INFO_VERSION_MINOR;
        os_info.magic = OS_INFO_MAGIC;
        os_info.csum = os_info_csum(&os_info);
-       abs_lc = get_abs_lowcore(&flags);
+       abs_lc = get_abs_lowcore();
        abs_lc->os_info = __pa(&os_info);
-       put_abs_lowcore(abs_lc, flags);
+       put_abs_lowcore(abs_lc);
 }
 
 #ifdef CONFIG_CRASH_DUMP
index 9ae2f6b..7fad2c0 100644 (file)
@@ -418,7 +418,6 @@ static void __init setup_lowcore(void)
 {
        struct lowcore *lc, *abs_lc;
        unsigned long mcck_stack;
-       unsigned long flags;
 
        /*
         * Setup lowcore for boot cpu
@@ -493,7 +492,7 @@ static void __init setup_lowcore(void)
        lc->kernel_asce = S390_lowcore.kernel_asce;
        lc->user_asce = S390_lowcore.user_asce;
 
-       abs_lc = get_abs_lowcore(&flags);
+       abs_lc = get_abs_lowcore();
        abs_lc->restart_stack = lc->restart_stack;
        abs_lc->restart_fn = lc->restart_fn;
        abs_lc->restart_data = lc->restart_data;
@@ -503,13 +502,12 @@ static void __init setup_lowcore(void)
        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, flags);
+       put_abs_lowcore(abs_lc);
 
        set_prefix(__pa(lc));
        lowcore_ptr[0] = lc;
-       if (abs_lowcore_map(0, lowcore_ptr[0], true))
+       if (abs_lowcore_map(0, lowcore_ptr[0], false))
                panic("Couldn't setup absolute lowcore");
-       abs_lowcore_mapped = true;
 }
 
 static struct resource code_resource = {
index 24f19f1..23c4272 100644 (file)
@@ -323,7 +323,6 @@ static void pcpu_delegate(struct pcpu *pcpu,
 {
        struct lowcore *lc, *abs_lc;
        unsigned int source_cpu;
-       unsigned long flags;
 
        lc = lowcore_ptr[pcpu - pcpu_devices];
        source_cpu = stap();
@@ -341,12 +340,12 @@ static void pcpu_delegate(struct pcpu *pcpu,
                lc->restart_data = (unsigned long)data;
                lc->restart_source = source_cpu;
        } else {
-               abs_lc = get_abs_lowcore(&flags);
+               abs_lc = get_abs_lowcore();
                abs_lc->restart_stack = stack;
                abs_lc->restart_fn = (unsigned long)func;
                abs_lc->restart_data = (unsigned long)data;
                abs_lc->restart_source = source_cpu;
-               put_abs_lowcore(abs_lc, flags);
+               put_abs_lowcore(abs_lc);
        }
        __bpon();
        asm volatile(
@@ -593,7 +592,6 @@ void smp_ctl_set_clear_bit(int cr, int bit, bool set)
 {
        struct ec_creg_mask_parms parms = { .cr = cr, };
        struct lowcore *abs_lc;
-       unsigned long flags;
        u64 ctlreg;
 
        if (set) {
@@ -604,11 +602,11 @@ void smp_ctl_set_clear_bit(int cr, int bit, bool set)
                parms.andval = ~(1UL << bit);
        }
        spin_lock(&ctl_lock);
-       abs_lc = get_abs_lowcore(&flags);
+       abs_lc = get_abs_lowcore();
        ctlreg = abs_lc->cregs_save_area[cr];
        ctlreg = (ctlreg & parms.andval) | parms.orval;
        abs_lc->cregs_save_area[cr] = ctlreg;
-       put_abs_lowcore(abs_lc, flags);
+       put_abs_lowcore(abs_lc);
        spin_unlock(&ctl_lock);
        on_each_cpu(smp_ctl_bit_callback, &parms, 1);
 }
index 7c66b3a..d02a616 100644 (file)
@@ -151,7 +151,6 @@ void *xlate_dev_mem_ptr(phys_addr_t addr)
        void *ptr = phys_to_virt(addr);
        void *bounce = ptr;
        struct lowcore *abs_lc;
-       unsigned long flags;
        unsigned long size;
        int this_cpu, cpu;
 
@@ -167,10 +166,10 @@ void *xlate_dev_mem_ptr(phys_addr_t addr)
                goto out;
        size = PAGE_SIZE - (addr & ~PAGE_MASK);
        if (addr < sizeof(struct lowcore)) {
-               abs_lc = get_abs_lowcore(&flags);
+               abs_lc = get_abs_lowcore();
                ptr = (void *)abs_lc + addr;
                memcpy(bounce, ptr, size);
-               put_abs_lowcore(abs_lc, flags);
+               put_abs_lowcore(abs_lc);
        } else if (cpu == this_cpu) {
                ptr = (void *)(addr - virt_to_phys(lowcore_ptr[cpu]));
                memcpy(bounce, ptr, size);