From: Hou Wenlong <houwenlong.hwl@xxxxxxxxxxxx> For a PIE kernel, it runs in a high virtual address in the PVH entry, so it needs to relocate the kernel image early in the PVH entry for the PVM guest. Signed-off-by: Hou Wenlong <houwenlong.hwl@xxxxxxxxxxxx> Signed-off-by: Lai Jiangshan <jiangshan.ljs@xxxxxxxxxxxx> --- arch/x86/include/asm/init.h | 5 +++++ arch/x86/kernel/head64_identity.c | 5 ----- arch/x86/platform/pvh/enlighten.c | 22 ++++++++++++++++++++++ arch/x86/platform/pvh/head.S | 4 ++++ 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/init.h b/arch/x86/include/asm/init.h index cc9ccf61b6bd..f78edef60253 100644 --- a/arch/x86/include/asm/init.h +++ b/arch/x86/include/asm/init.h @@ -4,6 +4,11 @@ #define __head __section(".head.text") +#define SYM_ABS_VA(sym) ({ \ + unsigned long __v; \ + asm("movabsq $" __stringify(sym) ", %0":"=r"(__v)); \ + __v; }) + struct x86_mapping_info { void *(*alloc_pgt_page)(void *); /* allocate buf for page table */ void *context; /* context for alloc_pgt_page */ diff --git a/arch/x86/kernel/head64_identity.c b/arch/x86/kernel/head64_identity.c index 4e6a073d9e6c..f69f9904003c 100644 --- a/arch/x86/kernel/head64_identity.c +++ b/arch/x86/kernel/head64_identity.c @@ -82,11 +82,6 @@ static void __head set_kernel_map_base(unsigned long text_base) } #endif -#define SYM_ABS_VA(sym) ({ \ - unsigned long __v; \ - asm("movabsq $" __stringify(sym) ", %0":"=r"(__v)); \ - __v; }) - static unsigned long __head sme_postprocess_startup(struct boot_params *bp, pmdval_t *pmd) { unsigned long vaddr, vaddr_end; diff --git a/arch/x86/platform/pvh/enlighten.c b/arch/x86/platform/pvh/enlighten.c index 00a92cb2c814..8c64c31c971b 100644 --- a/arch/x86/platform/pvh/enlighten.c +++ b/arch/x86/platform/pvh/enlighten.c @@ -1,8 +1,10 @@ // SPDX-License-Identifier: GPL-2.0 #include <linux/acpi.h> +#include <linux/pgtable.h> #include <xen/hvc-console.h> +#include <asm/init.h> #include <asm/io_apic.h> #include <asm/hypervisor.h> #include <asm/e820/api.h> @@ -113,6 +115,26 @@ static void __init hypervisor_specific_init(bool xen_guest) xen_pvh_init(&pvh_bootparams); } +#ifdef CONFIG_PVM_GUEST +void pvm_relocate_kernel(unsigned long physbase); + +void __init pvm_update_pgtable(unsigned long physbase) +{ + pgdval_t *pgd; + pudval_t *pud; + unsigned long base; + + pvm_relocate_kernel(physbase); + + pgd = (pgdval_t *)init_top_pgt; + base = SYM_ABS_VA(_text); + pgd[pgd_index(base)] = pgd[0]; + pgd[pgd_index(page_offset_base)] = pgd[0]; + pud = (pudval_t *)level3_ident_pgt; + pud[pud_index(base)] = (unsigned long)level2_ident_pgt + _KERNPG_TABLE_NOENC; +} +#endif + /* * This routine (and those that it might call) should not use * anything that lives in .bss since that segment will be cleared later. diff --git a/arch/x86/platform/pvh/head.S b/arch/x86/platform/pvh/head.S index baaa3fe34a00..127f297f7257 100644 --- a/arch/x86/platform/pvh/head.S +++ b/arch/x86/platform/pvh/head.S @@ -109,6 +109,10 @@ SYM_CODE_START_LOCAL(pvh_start_xen) wrmsr #ifdef CONFIG_X86_PIE +#ifdef CONFIG_PVM_GUEST + leaq _text(%rip), %rdi + call pvm_update_pgtable +#endif movabs $2f, %rax ANNOTATE_RETPOLINE_SAFE jmp *%rax -- 2.19.1.6.gb485710b