mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-23 20:24:12 +08:00
s390/mm: allocate Absolute Lowcore Area in decompressor
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>
This commit is contained in:
parent
8e9205d2a5
commit
2154e0b328
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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 = {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user