Skip to content

Commit fe6397d

Browse files
ZideChen0jren1
authored andcommitted
HV: Make AP trampoline code relocatable
V3->V4: Updated function/variable names for accurancy V2->V3: Changed a few function/variable names to make it less confusing V1->V2: removed the unneccesary cache flushing - For UEFI boot, allocate memory for trampoline code in ACRN EFI, and pass the pointer to HV through efi_ctx - For other boot, scan E820 to allocate memory in HV run time - update_trampoline_code_refs() updates all the references that need the absolute PA with the actual load address Signed-off-by: Zheng, Gen <gen.zheng@intel.com> Signed-off-by: Jason Chen CJ <jason.cj.chen@intel.com> Signed-off-by: Zide Chen <zide.chen@intel.com> Acked-by: Eddie Dong <eddie.dong> Acked-by: Xu, Anthony <anthony.xu@intel.com>
1 parent ceb3076 commit fe6397d

File tree

6 files changed

+79
-18
lines changed

6 files changed

+79
-18
lines changed

hypervisor/arch/x86/cpu.c

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include <hypervisor.h>
3232
#include <hv_lib.h>
33+
#include <acrn_hv_defs.h>
3334
#include <acrn_common.h>
3435
#include <bsp_extern.h>
3536
#include <hv_arch.h>
@@ -38,9 +39,12 @@
3839
#include <hv_debug.h>
3940

4041
#ifdef CONFIG_EFI_STUB
42+
#include <acrn_efi.h>
4143
extern uint32_t efi_physical_available_ap_bitmap;
4244
#endif
4345

46+
uint64_t trampoline_code_paddr = 0;
47+
4448
spinlock_t cpu_secondary_spinlock = {
4549
.head = 0,
4650
.tail = 0
@@ -88,6 +92,7 @@ int cpu_find_logical_id(uint32_t lapic_id);
8892
#ifndef CONFIG_EFI_STUB
8993
static void start_cpus(void);
9094
#endif
95+
static uint64_t relocate_trampoline_code(void);
9196
static void pcpu_sync_sleep(unsigned long *sync, int mask_bit);
9297
int ibrs_type;
9398

@@ -548,10 +553,7 @@ void bsp_boot_init(void)
548553
/* Trigger event to allow secondary CPUs to continue */
549554
bitmap_set(0, &pcpu_sync);
550555
#else
551-
memcpy_s(_ld_cpu_secondary_reset_start,
552-
(unsigned long)&_ld_cpu_secondary_reset_size,
553-
_ld_cpu_secondary_reset_load,
554-
(unsigned long)&_ld_cpu_secondary_reset_size);
556+
relocate_trampoline_code();
555557
#endif
556558

557559
ASSERT(get_cpu_id() == CPU_BOOT_ID, "");
@@ -660,12 +662,9 @@ static void start_cpus()
660662
{
661663
uint32_t timeout;
662664
uint32_t expected_up;
665+
uint64_t startup_paddr;
663666

664-
/*Copy segment for AP initialization code below 1MB */
665-
memcpy_s(_ld_cpu_secondary_reset_start,
666-
(unsigned long)&_ld_cpu_secondary_reset_size,
667-
_ld_cpu_secondary_reset_load,
668-
(unsigned long)&_ld_cpu_secondary_reset_size);
667+
startup_paddr = relocate_trampoline_code();
669668

670669
/* Set flag showing number of CPUs expected to be up to all
671670
* cpus
@@ -674,7 +673,7 @@ static void start_cpus()
674673

675674
/* Broadcast IPIs to all other CPUs */
676675
send_startup_ipi(INTR_CPU_STARTUP_ALL_EX_SELF,
677-
-1U, ((uint64_t) cpu_secondary_reset));
676+
-1U, startup_paddr);
678677

679678
/* Wait until global count is equal to expected CPU up count or
680679
* configured time-out has expired
@@ -700,6 +699,53 @@ static void start_cpus()
700699
}
701700
#endif
702701

702+
static void update_trampoline_code_refs(uint64_t dest_pa)
703+
{
704+
void *ptr;
705+
int i;
706+
707+
if (dest_pa == 0)
708+
return;
709+
710+
/* Update temporary page tables */
711+
ptr = HPA2HVA(dest_pa + (uint64_t)CPU_Boot_Page_Tables_ptr);
712+
*(uint32_t *)(ptr) += dest_pa;
713+
714+
ptr = HPA2HVA(dest_pa + (uint64_t)CPU_Boot_Page_Tables_Start);
715+
*(uint64_t *)(ptr) += dest_pa;
716+
717+
ptr = HPA2HVA(dest_pa + (uint64_t)cpu_secondary_pdpt_addr);
718+
for (i = 0; i < 4; i++ ) {
719+
*(uint64_t *)(ptr + sizeof(uint64_t) * i) += dest_pa;
720+
}
721+
722+
/* update the gdt base pointer with relocated offset */
723+
ptr = HPA2HVA(dest_pa + (uint64_t)cpu_secondary_gdt_ptr);
724+
*(uint64_t *)(ptr + 2) += dest_pa;
725+
726+
/* update trampoline jump pointer with relocated offset */
727+
ptr = HPA2HVA(dest_pa + (uint64_t)ap_long_mode_jump_ref);
728+
*(uint32_t *)ptr += dest_pa;
729+
}
730+
731+
static uint64_t relocate_trampoline_code(void)
732+
{
733+
uint64_t size, dest_pa;
734+
735+
size = (uint64_t)_ld_cpu_secondary_reset_end - (uint64_t)cpu_secondary_reset;
736+
#ifndef CONFIG_EFI_STUB
737+
dest_pa = e820_alloc_low_memory(CONFIG_LOW_RAM_SIZE);
738+
#else
739+
dest_pa = (uint64_t)get_ap_trampoline_buf();
740+
#endif
741+
742+
/* printf("AP trampoline code: %llx size %x\n", dest_pa, size); */
743+
memcpy_s(HPA2HVA(dest_pa), size, _ld_cpu_secondary_reset_load, size);
744+
update_trampoline_code_refs(dest_pa);
745+
trampoline_code_paddr = dest_pa;
746+
return dest_pa;
747+
}
748+
703749
void cpu_dead(uint32_t logical_id)
704750
{
705751
/* For debug purposes, using a stack variable in the while loop enables

hypervisor/bsp/uefi/efi/boot.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,6 @@ construct_mbi(struct multiboot_info **mbi_ret, struct efi_ctx *efi_ctx)
189189
mmap[j].mm_type = E820_RAM;
190190
j++;
191191

192-
/* reserve secondary memory region(0x1000 ~ 0x10000) for hv */
193-
err = __emalloc(CONFIG_LOW_RAM_SIZE, CONFIG_LOW_RAM_START,
194-
&addr, EfiReservedMemoryType);
195-
if (err != EFI_SUCCESS)
196-
goto out;
197-
198192
mbi->mi_flags |= MULTIBOOT_INFO_HAS_MMAP | MULTIBOOT_INFO_HAS_CMDLINE;
199193
mbi->mi_mmap_length = j*sizeof(struct multiboot_mmap);
200194

@@ -228,6 +222,13 @@ switch_to_guest_mode(EFI_HANDLE image)
228222

229223
efi_ctx = (struct efi_ctx *)(UINTN)addr;
230224

225+
/* reserve secondary memory region for hv */
226+
err = emalloc_for_low_mem(&addr, CONFIG_LOW_RAM_SIZE);
227+
if (err != EFI_SUCCESS)
228+
goto out;
229+
230+
efi_ctx->ap_trampoline_buf = (void *)addr;
231+
231232
config_table = sys_table->ConfigurationTable;
232233

233234
for (i = 0; i < sys_table->NumberOfTableEntries; i++) {

hypervisor/bsp/uefi/efi/boot.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ struct e820_entry {
9696
struct efi_ctx {
9797
uint64_t rip;
9898
VOID *rsdp;
99+
VOID *ap_trampoline_buf;
99100
dt_addr_t gdt;
100101
dt_addr_t idt;
101102
uint16_t tr_sel;

hypervisor/bsp/uefi/uefi.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ int sipi_from_efi_boot_service_exit(uint32_t dest, uint32_t mode, uint32_t vec)
100100
return 0;
101101
}
102102

103+
void *get_ap_trampoline_buf(void)
104+
{
105+
return efi_ctx->ap_trampoline_buf;
106+
}
107+
103108
void efi_deferred_wakeup_pcpu(int cpu_id)
104109
{
105110
uint32_t timeout;
@@ -114,7 +119,7 @@ void efi_deferred_wakeup_pcpu(int cpu_id)
114119
expected_up = up_count + 1;
115120

116121
send_startup_ipi(INTR_CPU_STARTUP_USE_DEST,
117-
cpu_id, (uint64_t)cpu_secondary_reset);
122+
cpu_id, (uint64_t)get_ap_trampoline_buf());
118123

119124
timeout = CPU_UP_TIMEOUT * 1000;
120125

hypervisor/include/arch/x86/cpu.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,17 @@ int cpu_find_logical_id(uint32_t lapic_id);
157157
/**********************************/
158158
extern const uint8_t _ld_cpu_secondary_reset_load[];
159159
extern uint8_t _ld_cpu_secondary_reset_start[];
160+
extern uint8_t _ld_cpu_secondary_reset_end[];
160161
extern const uint64_t _ld_cpu_secondary_reset_size;
161162
extern uint8_t _ld_bss_start[];
162163
extern uint8_t _ld_bss_end[];
163-
extern uint8_t _ld_cpu_data_start[];
164+
extern uint8_t _ld_cpu_data_start[];
164165
extern uint8_t _ld_cpu_data_end[];
166+
extern uint8_t CPU_Boot_Page_Tables_Start[];
167+
extern uint8_t CPU_Boot_Page_Tables_ptr[];
168+
extern uint8_t cpu_secondary_pdpt_addr[];
169+
extern uint8_t cpu_secondary_gdt_ptr[];
170+
extern uint8_t ap_long_mode_jump_ref[];
165171

166172
extern int ibrs_type;
167173

hypervisor/include/common/acrn_efi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ typedef struct {
3939
struct efi_ctx {
4040
uint64_t rip;
4141
void *rsdp;
42+
void *ap_trampoline_buf;
4243
dt_addr_t gdt;
4344
dt_addr_t idt;
4445
uint16_t tr_sel;
@@ -74,5 +75,6 @@ struct efi_ctx {
7475
}__attribute__((packed));
7576

7677
void *get_rsdp_from_uefi(void);
78+
void *get_ap_trampoline_buf(void);
7779

7880
#endif /* UEFI_H*/

0 commit comments

Comments
 (0)