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 | |
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')
-rw-r--r-- | arch/s390/boot/startup.c | 2 | ||||
-rw-r--r-- | arch/s390/boot/vmem.c | 15 | ||||
-rw-r--r-- | arch/s390/include/asm/maccess.h | 2 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 2 | ||||
-rw-r--r-- | arch/s390/mm/maccess.c | 9 |
5 files changed, 20 insertions, 10 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; diff --git a/arch/s390/include/asm/maccess.h b/arch/s390/include/asm/maccess.h index c7fa838cf6b9..cfec3141fdba 100644 --- a/arch/s390/include/asm/maccess.h +++ b/arch/s390/include/asm/maccess.h @@ -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 diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 1ffaa85cd518..9ae2f6b3042e 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -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. diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c index a6314e259f97..7c66b3ad05e0 100644 --- a/arch/s390/mm/maccess.c +++ b/arch/s390/mm/maccess.c @@ -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; |