Commit 2154e0b3 authored by Alexander Gordeev's avatar Alexander Gordeev Committed by Heiko Carstens
Browse files

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: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent 8e9205d2
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
@@ -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);
+13 −3
Original line number Diff line number Diff line
@@ -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 */
+0 −49
Original line number Diff line number Diff line
@@ -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();
}
+2 −3
Original line number Diff line number Diff line
@@ -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);
}

Loading