Skip to content

Commit 48b0894

Browse files
ZideChen0lijinxia
authored andcommitted
hv: relocate trampoline code to the dynamically allocated memory
- Also update all the references that need the absolute HPA with the actual load addresses - Save the trampoline code address to trampline_start16_paddr 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@intel.com> Acked-by: Xu, Anthony <anthony.xu@intel.com>
1 parent 2a1a6ad commit 48b0894

File tree

2 files changed

+62
-18
lines changed

2 files changed

+62
-18
lines changed

hypervisor/arch/x86/cpu.c

Lines changed: 59 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
#include <schedule.h>
99
#include <version.h>
1010

11+
#ifdef CONFIG_EFI_STUB
12+
#include <acrn_efi.h>
13+
#endif
14+
1115
spinlock_t trampline_spinlock = {
1216
.head = 0,
1317
.tail = 0
@@ -608,30 +612,66 @@ int cpu_find_logical_id(uint32_t lapic_id)
608612
return -1;
609613
}
610614

611-
extern uint16_t trampline_fixup_cs[];
612-
extern uint16_t trampline_fixup_ip[];
613-
extern uint32_t trampline_fixup_target;
614-
void prepare_trampline(void)
615+
static void update_trampline_code_refs(uint64_t dest_pa)
615616
{
617+
void *ptr;
616618
uint64_t val;
617-
618-
/*Copy segment for AP initialization code below 1MB */
619-
memcpy_s(_ld_trampline_start,
620-
(unsigned long)&_ld_trampline_size,
621-
_ld_trampline_load,
622-
(unsigned long)&_ld_trampline_size);
619+
int i;
623620

624621
/*
625622
* calculate the fixup CS:IP according to fixup target address
626623
* dynamically.
627624
*
628-
* FIXME:
629-
* the val should be set to runtime address of trampline code
630-
* after trampline relocation is enabled.
625+
* trampline code starts in real mode,
626+
* so the target addres is HPA
631627
*/
632-
val = (uint64_t) &trampline_fixup_target;
633-
trampline_fixup_cs[0] = (uint16_t)(val >> 4) & 0xFFFF;
634-
trampline_fixup_ip[0] = (uint16_t)(val & 0xf);
628+
val = dest_pa + (uint64_t)trampline_fixup_target;
629+
630+
ptr = HPA2HVA(dest_pa + (uint64_t)trampline_fixup_cs);
631+
*(uint16_t *)(ptr) = (uint16_t)(val >> 4) & 0xFFFF;
632+
633+
ptr = HPA2HVA(dest_pa + (uint64_t)trampline_fixup_ip);
634+
*(uint16_t *)(ptr) = (uint16_t)(val & 0xf);
635+
636+
/* Update temporary page tables */
637+
ptr = HPA2HVA(dest_pa + (uint64_t)CPU_Boot_Page_Tables_ptr);
638+
*(uint32_t *)(ptr) += dest_pa;
639+
640+
ptr = HPA2HVA(dest_pa + (uint64_t)CPU_Boot_Page_Tables_Start);
641+
*(uint64_t *)(ptr) += dest_pa;
642+
643+
ptr = HPA2HVA(dest_pa + (uint64_t)trampline_pdpt_addr);
644+
for (i = 0; i < 4; i++)
645+
*(uint64_t *)(ptr + sizeof(uint64_t) * i) += dest_pa;
646+
647+
/* update the gdt base pointer with relocated offset */
648+
ptr = HPA2HVA(dest_pa + (uint64_t)trampline_gdt_ptr);
649+
*(uint64_t *)(ptr + 2) += dest_pa;
650+
651+
/* update trampline jump pointer with relocated offset */
652+
ptr = HPA2HVA(dest_pa + (uint64_t)trampline_start64_fixup);
653+
*(uint32_t *)ptr += dest_pa;
654+
}
655+
656+
static uint64_t prepare_trampline(void)
657+
{
658+
uint64_t size, dest_pa;
659+
660+
size = (uint64_t)_ld_trampline_end - (uint64_t)trampline_start16;
661+
#ifndef CONFIG_EFI_STUB
662+
dest_pa = e820_alloc_low_memory(CONFIG_LOW_RAM_SIZE);
663+
#else
664+
dest_pa = (uint64_t)get_ap_trampline_buf();
665+
#endif
666+
667+
pr_dbg("trampline code: %llx size %x", dest_pa, size);
668+
669+
/* Copy segment for AP initialization code below 1MB */
670+
memcpy_s(HPA2HVA(dest_pa), size, _ld_trampline_load, size);
671+
update_trampline_code_refs(dest_pa);
672+
trampline_start16_paddr = dest_pa;
673+
674+
return dest_pa;
635675
}
636676

637677
/*
@@ -641,8 +681,9 @@ void start_cpus()
641681
{
642682
uint32_t timeout;
643683
uint32_t expected_up;
684+
uint64_t startup_paddr;
644685

645-
prepare_trampline();
686+
startup_paddr = prepare_trampline();
646687

647688
/* Set flag showing number of CPUs expected to be up to all
648689
* cpus
@@ -651,7 +692,7 @@ void start_cpus()
651692

652693
/* Broadcast IPIs to all other CPUs */
653694
send_startup_ipi(INTR_CPU_STARTUP_ALL_EX_SELF,
654-
-1U, ((uint64_t) trampline_start16));
695+
-1U, startup_paddr);
655696

656697
/* Wait until global count is equal to expected CPU up count or
657698
* configured time-out has expired

hypervisor/include/arch/x86/cpu.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@ extern const uint64_t _ld_trampline_size;
163163
extern uint8_t _ld_bss_start[];
164164
extern uint8_t _ld_bss_end[];
165165

166+
extern uint8_t trampline_fixup_cs[];
167+
extern uint8_t trampline_fixup_ip[];
168+
extern uint8_t trampline_fixup_target[];
166169
extern uint8_t CPU_Boot_Page_Tables_Start[];
167170
extern uint8_t CPU_Boot_Page_Tables_ptr[];
168171
extern uint8_t trampline_pdpt_addr[];

0 commit comments

Comments
 (0)