diff options
author | Alexander Gordeev <agordeev@linux.ibm.com> | 2022-12-11 08:18:57 +0100 |
---|---|---|
committer | Heiko Carstens <hca@linux.ibm.com> | 2023-01-13 14:15:06 +0100 |
commit | 8e9205d2a58989aff46000ef47021633146ca493 (patch) | |
tree | 8e3bbfa1a53d106fec806f8c85412133b47a0f9d /arch/s390/boot | |
parent | e0e0a87b4b85ac3bbf76327fc030e6134b657068 (diff) |
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>
Diffstat (limited to 'arch/s390/boot')
-rw-r--r-- | arch/s390/boot/startup.c | 2 | ||||
-rw-r--r-- | arch/s390/boot/vmem.c | 15 |
2 files changed, 17 insertions, 0 deletions
diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c index c5d59df9fa62..cb4b743a5e17 100644 --- a/arch/s390/boot/startup.c +++ b/arch/s390/boot/startup.c @@ -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); diff --git a/arch/s390/boot/vmem.c b/arch/s390/boot/vmem.c index af9124c8c19c..41ff38a0e2dd 100644 --- a/arch/s390/boot/vmem.c +++ b/arch/s390/boot/vmem.c @@ -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; |