mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 04:31:50 +00:00
s390/mm: allocate Real Memory Copy Area in decompressor
Move Real Memory Copy Area allocation to the decompressor. As result, memcpy_real() and memcpy_real_iter() movers become usable since the very moment the kernel starts. 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
e0e0a87b4b
commit
8e9205d2a5
@ -3,6 +3,7 @@
|
||||
#include <linux/elf.h>
|
||||
#include <asm/boot_data.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/maccess.h>
|
||||
#include <asm/cpu_mf.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/kasan.h>
|
||||
@ -19,6 +20,7 @@
|
||||
unsigned long __bootdata_preserved(__kaslr_offset);
|
||||
unsigned long __bootdata_preserved(__abs_lowcore);
|
||||
unsigned long __bootdata_preserved(__memcpy_real_area);
|
||||
pte_t *__bootdata_preserved(memcpy_real_ptep);
|
||||
unsigned long __bootdata(__amode31_base);
|
||||
unsigned long __bootdata_preserved(VMALLOC_START);
|
||||
unsigned long __bootdata_preserved(VMALLOC_END);
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <asm/facility.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/mem_detect.h>
|
||||
#include <asm/maccess.h>
|
||||
#include "decompressor.h"
|
||||
#include "boot.h"
|
||||
|
||||
@ -12,12 +13,21 @@
|
||||
#define swapper_pg_dir vmlinux.swapper_pg_dir_off
|
||||
#define invalid_pg_dir vmlinux.invalid_pg_dir_off
|
||||
|
||||
/*
|
||||
* Mimic virt_to_kpte() in lack of init_mm symbol. Skip pmd NULL check though.
|
||||
*/
|
||||
static inline pte_t *__virt_to_kpte(unsigned long va)
|
||||
{
|
||||
return pte_offset_kernel(pmd_offset(pud_offset(p4d_offset(pgd_offset_k(va), va), va), va), va);
|
||||
}
|
||||
|
||||
unsigned long __bootdata_preserved(s390_invalid_asce);
|
||||
unsigned long __bootdata(pgalloc_pos);
|
||||
unsigned long __bootdata(pgalloc_end);
|
||||
unsigned long __bootdata(pgalloc_low);
|
||||
|
||||
enum populate_mode {
|
||||
POPULATE_NONE,
|
||||
POPULATE_ONE2ONE,
|
||||
};
|
||||
|
||||
@ -88,6 +98,8 @@ static pte_t *boot_pte_alloc(void)
|
||||
static unsigned long _pa(unsigned long addr, enum populate_mode mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case POPULATE_NONE:
|
||||
return -1;
|
||||
case POPULATE_ONE2ONE:
|
||||
return addr;
|
||||
default:
|
||||
@ -259,6 +271,9 @@ 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(__memcpy_real_area, __memcpy_real_area + PAGE_SIZE,
|
||||
POPULATE_NONE);
|
||||
memcpy_real_ptep = __virt_to_kpte(__memcpy_real_area);
|
||||
pgtable_populate_end();
|
||||
|
||||
S390_lowcore.kernel_asce = swapper_pg_dir | asce_bits;
|
||||
|
@ -7,7 +7,7 @@
|
||||
struct iov_iter;
|
||||
|
||||
extern unsigned long __memcpy_real_area;
|
||||
void memcpy_real_init(void);
|
||||
extern pte_t *memcpy_real_ptep;
|
||||
size_t memcpy_real_iter(struct iov_iter *iter, unsigned long src, size_t count);
|
||||
int memcpy_real(void *dest, unsigned long src, size_t count);
|
||||
#ifdef CONFIG_CRASH_DUMP
|
||||
|
@ -1046,7 +1046,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
* Create kernel page tables.
|
||||
*/
|
||||
paging_init();
|
||||
memcpy_real_init();
|
||||
|
||||
/*
|
||||
* After paging_init created the kernel page table, the new PSWs
|
||||
* in lowcore can now run with DAT enabled.
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <asm/maccess.h>
|
||||
|
||||
unsigned long __bootdata_preserved(__memcpy_real_area);
|
||||
static __ro_after_init pte_t *memcpy_real_ptep;
|
||||
pte_t *__bootdata_preserved(memcpy_real_ptep);
|
||||
static DEFINE_MUTEX(memcpy_real_mutex);
|
||||
|
||||
static notrace long s390_kernel_write_odd(void *dst, const void *src, size_t size)
|
||||
@ -79,13 +79,6 @@ notrace void *s390_kernel_write(void *dst, const void *src, size_t size)
|
||||
return dst;
|
||||
}
|
||||
|
||||
void __init memcpy_real_init(void)
|
||||
{
|
||||
memcpy_real_ptep = vmem_get_alloc_pte(__memcpy_real_area, true);
|
||||
if (!memcpy_real_ptep)
|
||||
panic("Couldn't setup memcpy real area");
|
||||
}
|
||||
|
||||
size_t memcpy_real_iter(struct iov_iter *iter, unsigned long src, size_t count)
|
||||
{
|
||||
size_t len, copied, res = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user