diff --git a/hypervisor/arch/x86/cpu.c b/hypervisor/arch/x86/cpu.c index 734d6bfd1..471fb6d06 100644 --- a/hypervisor/arch/x86/cpu.c +++ b/hypervisor/arch/x86/cpu.c @@ -9,10 +9,6 @@ #include #include -#ifdef CONFIG_EFI_STUB -#include -#endif - spinlock_t trampoline_spinlock = { .head = 0U, .tail = 0U @@ -31,8 +27,6 @@ volatile uint16_t up_count = 0U; /* physical cpu active bitmap, support up to 64 cpus */ uint64_t pcpu_active_bitmap = 0UL; -uint64_t trampoline_start16_paddr; - /* TODO: add more capability per requirement */ /*APICv features*/ #define VAPIC_FEATURE_VIRT_ACCESS (1U << 0) @@ -650,76 +644,6 @@ static uint16_t get_cpu_id_from_lapic_id(uint8_t lapic_id) return INVALID_CPU_ID; } -static void update_trampoline_code_refs(uint64_t dest_pa) -{ - void *ptr; - uint64_t val; - int i; - - /* - * calculate the fixup CS:IP according to fixup target address - * dynamically. - * - * trampoline code starts in real mode, - * so the target addres is HPA - */ - val = dest_pa + trampoline_relo_addr(trampoline_fixup_target); - - ptr = HPA2HVA(dest_pa + trampoline_relo_addr(trampoline_fixup_cs)); - *(uint16_t *)(ptr) = (uint16_t)((val >> 4) & 0xFFFFU); - - ptr = HPA2HVA(dest_pa + trampoline_relo_addr(trampoline_fixup_ip)); - *(uint16_t *)(ptr) = (uint16_t)(val & 0xfU); - - /* Update temporary page tables */ - ptr = HPA2HVA(dest_pa + trampoline_relo_addr(CPU_Boot_Page_Tables_ptr)); - *(uint32_t *)(ptr) += dest_pa; - - ptr = HPA2HVA(dest_pa + trampoline_relo_addr(CPU_Boot_Page_Tables_Start)); - *(uint64_t *)(ptr) += dest_pa; - - ptr = HPA2HVA(dest_pa + trampoline_relo_addr(trampoline_pdpt_addr)); - for (i = 0; i < 4; i++) - *(uint64_t *)(ptr + sizeof(uint64_t) * i) += dest_pa; - - /* update the gdt base pointer with relocated offset */ - ptr = HPA2HVA(dest_pa + trampoline_relo_addr(trampoline_gdt_ptr)); - *(uint64_t *)(ptr + 2) += dest_pa; - - /* update trampoline jump pointer with relocated offset */ - ptr = HPA2HVA(dest_pa + trampoline_relo_addr(trampoline_start64_fixup)); - *(uint32_t *)ptr += (uint32_t)dest_pa; - - /* update trampoline's main entry pointer */ - ptr = HPA2HVA(dest_pa + trampoline_relo_addr(main_entry)); - *(uint64_t *)ptr += get_hv_image_delta(); - - /* update trampoline's spinlock pointer */ - ptr = HPA2HVA(dest_pa + trampoline_relo_addr(trampoline_spinlock_ptr)); - *(uint64_t *)ptr += get_hv_image_delta(); -} - -static uint64_t prepare_trampoline(void) -{ - uint64_t size, dest_pa; - - size = (uint64_t)_ld_trampoline_end - (uint64_t)_ld_trampoline_start; -#ifndef CONFIG_EFI_STUB - dest_pa = e820_alloc_low_memory(CONFIG_LOW_RAM_SIZE); -#else - dest_pa = (uint64_t)get_ap_trampoline_buf(); -#endif - - pr_dbg("trampoline code: %llx size %x", dest_pa, size); - - /* Copy segment for AP initialization code below 1MB */ - (void)memcpy_s(HPA2HVA(dest_pa), (size_t)size, _ld_trampoline_load, (size_t)size); - update_trampoline_code_refs(dest_pa); - trampoline_start16_paddr = dest_pa; - - return dest_pa; -} - /* * Start all secondary CPUs. */ diff --git a/hypervisor/boot/include/reloc.h b/hypervisor/boot/include/reloc.h index 367af155d..ac6de5f1a 100755 --- a/hypervisor/boot/include/reloc.h +++ b/hypervisor/boot/include/reloc.h @@ -9,16 +9,30 @@ extern void _relocate(void); extern uint64_t get_hv_image_delta(void); extern uint64_t get_hv_image_base(void); -extern uint64_t trampoline_relo_addr(void *addr); extern uint64_t read_trampoline_sym(void *sym); extern void write_trampoline_sym(void *sym, uint64_t val); +extern uint64_t prepare_trampoline(void); /* external symbols that are helpful for relocation */ extern uint8_t _DYNAMIC[]; +extern const uint8_t _ld_trampoline_load[]; +extern uint8_t _ld_trampoline_start[]; +extern uint8_t _ld_trampoline_end[]; +extern const uint64_t _ld_trampoline_size; extern uint8_t cpu_primary_start_32[]; extern uint8_t cpu_primary_start_64[]; +extern uint8_t trampoline_fixup_cs[]; +extern uint8_t trampoline_fixup_ip[]; +extern uint8_t trampoline_fixup_target[]; +extern uint8_t CPU_Boot_Page_Tables_Start[]; +extern uint8_t CPU_Boot_Page_Tables_ptr[]; +extern uint8_t trampoline_pdpt_addr[]; +extern uint8_t trampoline_gdt_ptr[]; +extern uint8_t trampoline_start64_fixup[]; extern uint8_t trampoline_spinlock_ptr[]; +extern uint64_t trampoline_start16_paddr; + #endif /* RELOCATE_H */ diff --git a/hypervisor/boot/reloc.c b/hypervisor/boot/reloc.c index 3cbc4d8a9..4bb6b5be3 100644 --- a/hypervisor/boot/reloc.c +++ b/hypervisor/boot/reloc.c @@ -6,6 +6,9 @@ #include #include +#ifdef CONFIG_EFI_STUB +#include +#endif struct Elf64_Dyn { uint64_t d_tag; @@ -26,6 +29,8 @@ struct Elf64_Rel { #define ELF64_R_TYPE(i) ((i) & 0xffffffff) #define R_X86_64_RELATIVE 8 +uint64_t trampoline_start16_paddr; + /* get the delta between CONFIG_RAM_START and the actual load address */ uint64_t get_hv_image_delta(void) { @@ -58,7 +63,7 @@ uint64_t get_hv_image_base(void) * - The HV code is always relocated to higher address, compared * with CONFIG_RAM_START */ -uint64_t trampoline_relo_addr(void *addr) +static uint64_t trampoline_relo_addr(void *addr) { return (uint64_t)addr - get_hv_image_delta(); } @@ -147,3 +152,73 @@ void write_trampoline_sym(void *sym, uint64_t val) hva = HPA2HVA(trampoline_start16_paddr) + trampoline_relo_addr(sym); *hva = val; } + +static void update_trampoline_code_refs(uint64_t dest_pa) +{ + void *ptr; + uint64_t val; + int i; + + /* + * calculate the fixup CS:IP according to fixup target address + * dynamically. + * + * trampoline code starts in real mode, + * so the target addres is HPA + */ + val = dest_pa + trampoline_relo_addr(trampoline_fixup_target); + + ptr = HPA2HVA(dest_pa + trampoline_relo_addr(trampoline_fixup_cs)); + *(uint16_t *)(ptr) = (uint16_t)((val >> 4) & 0xFFFFU); + + ptr = HPA2HVA(dest_pa + trampoline_relo_addr(trampoline_fixup_ip)); + *(uint16_t *)(ptr) = (uint16_t)(val & 0xfU); + + /* Update temporary page tables */ + ptr = HPA2HVA(dest_pa + trampoline_relo_addr(CPU_Boot_Page_Tables_ptr)); + *(uint32_t *)(ptr) += (uint32_t)dest_pa; + + ptr = HPA2HVA(dest_pa + trampoline_relo_addr(CPU_Boot_Page_Tables_Start)); + *(uint64_t *)(ptr) += dest_pa; + + ptr = HPA2HVA(dest_pa + trampoline_relo_addr(trampoline_pdpt_addr)); + for (i = 0; i < 4; i++) + *(uint64_t *)(ptr + sizeof(uint64_t) * i) += dest_pa; + + /* update the gdt base pointer with relocated offset */ + ptr = HPA2HVA(dest_pa + trampoline_relo_addr(trampoline_gdt_ptr)); + *(uint64_t *)(ptr + 2) += dest_pa; + + /* update trampoline jump pointer with relocated offset */ + ptr = HPA2HVA(dest_pa + trampoline_relo_addr(trampoline_start64_fixup)); + *(uint32_t *)ptr += dest_pa; + + /* update trampoline's main entry pointer */ + ptr = HPA2HVA(dest_pa + trampoline_relo_addr(main_entry)); + *(uint64_t *)ptr += get_hv_image_delta(); + + /* update trampoline's spinlock pointer */ + ptr = HPA2HVA(dest_pa + trampoline_relo_addr(trampoline_spinlock_ptr)); + *(uint64_t *)ptr += get_hv_image_delta(); +} + +uint64_t prepare_trampoline(void) +{ + uint64_t size, dest_pa; + + size = (uint64_t)_ld_trampoline_end - (uint64_t)_ld_trampoline_start; +#ifndef CONFIG_EFI_STUB + dest_pa = e820_alloc_low_memory(CONFIG_LOW_RAM_SIZE); +#else + dest_pa = (uint64_t)get_ap_trampoline_buf(); +#endif + + pr_dbg("trampoline code: %llx size %x", dest_pa, size); + + /* Copy segment for AP initialization code below 1MB */ + memcpy_s(HPA2HVA(dest_pa), (size_t)size, _ld_trampoline_load, (size_t)size); + update_trampoline_code_refs(dest_pa); + trampoline_start16_paddr = dest_pa; + + return dest_pa; +} diff --git a/hypervisor/include/arch/x86/cpu.h b/hypervisor/include/arch/x86/cpu.h index fe3917e90..032e6ca80 100644 --- a/hypervisor/include/arch/x86/cpu.h +++ b/hypervisor/include/arch/x86/cpu.h @@ -149,26 +149,12 @@ /**********************************/ /* EXTERNAL VARIABLES */ /**********************************/ -extern const uint8_t _ld_trampoline_load[]; -extern uint8_t _ld_trampoline_start[]; -extern uint8_t _ld_trampoline_end[]; -extern const uint64_t _ld_trampoline_size; extern uint8_t _ld_bss_start[]; extern uint8_t _ld_bss_end[]; -extern uint8_t trampoline_fixup_cs[]; -extern uint8_t trampoline_fixup_ip[]; -extern uint8_t trampoline_fixup_target[]; -extern uint8_t CPU_Boot_Page_Tables_Start[]; -extern uint8_t CPU_Boot_Page_Tables_ptr[]; -extern uint8_t trampoline_pdpt_addr[]; -extern uint8_t trampoline_gdt_ptr[]; -extern uint8_t trampoline_start64_fixup[]; - /* In trampoline range, hold the jump target which trampline will jump to */ extern uint64_t main_entry[1]; -extern uint64_t trampoline_start16_paddr; extern int ibrs_type; extern spinlock_t trampoline_spinlock;