HV: Prepare cpu_secondary.S for AP trampoline code relocation

V1->V2: removed CONFIG_LOW_RAM_START and added ".org 0" to
cpu_secondary.S

The assumption is trampoline code is relocated while HV is not, so:

trampoline code is built at address 0, and CS register is updated
by SIPI to reflect the correct vector

in real mode part, added extra pointers for page tables and long jump buffer
so it's possible for HV code to patch the relocation offset

in long mode part, use absolute addressing when referring HV symbols,
and use relative addressing for symbols within trampoline code

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>
This commit is contained in:
Zide Chen 2018-05-02 23:09:19 -07:00 committed by Jack Ren
parent 8c06b69622
commit 9323f811ea
4 changed files with 25 additions and 16 deletions

View File

@ -46,6 +46,7 @@
.align 4 .align 4
.code16 .code16
.global cpu_secondary_reset .global cpu_secondary_reset
.org 0
cpu_secondary_reset: cpu_secondary_reset:
/* Disable local interrupts */ /* Disable local interrupts */
@ -61,8 +62,9 @@ cpu_secondary_reset:
/* Set CR3 to PML4 table address */ /* Set CR3 to PML4 table address */
movl $CPU_Boot_Page_Tables_Start, %edi movl $CPU_Boot_Page_Tables_ptr, %ebx
mov %edi, %cr3 mov (%ebx), %eax
mov %eax, %cr3
/* Set LME bit in EFER */ /* Set LME bit in EFER */
@ -83,7 +85,14 @@ cpu_secondary_reset:
/* Perform a long jump based to start executing in 64-bit mode */ /* Perform a long jump based to start executing in 64-bit mode */
data32 ljmp $HOST_GDT_RING0_CODE_SEL, $cpu_secondary_long_mode movl $ap_long_mode_jump_ref, %ebx
ljmpl *(%ebx)
.align 8
.global ap_long_mode_jump_ref
ap_long_mode_jump_ref:
.long cpu_secondary_long_mode
.word HOST_GDT_RING0_CODE_SEL
.code64 .code64
cpu_secondary_long_mode: cpu_secondary_long_mode:
@ -100,7 +109,8 @@ cpu_secondary_long_mode:
/* Obtain secondary CPU spin-lock to serialize /* Obtain secondary CPU spin-lock to serialize
booting of secondary cores for a bit */ booting of secondary cores for a bit */
spinlock_obtain(cpu_secondary_spinlock) mov $cpu_secondary_spinlock, %rdi
spinlock_obtain(%rdi)
/* Initialize temporary stack pointer /* Initialize temporary stack pointer
NOTE: Using the PML4 memory (PDPT address is top of memory NOTE: Using the PML4 memory (PDPT address is top of memory
@ -110,21 +120,15 @@ cpu_secondary_long_mode:
the top of this page. This stack is only the top of this page. This stack is only
used for a VERY short period of time, so used for a VERY short period of time, so
this reuse of PML4 memory should be acceptable. */ this reuse of PML4 memory should be acceptable. */
lea cpu_secondary_pdpt_addr(%rip), %rsp
movq $cpu_secondary_pdpt_addr, %rsp
/* Push sp magic to top of stack for call trace */ /* Push sp magic to top of stack for call trace */
pushq $SP_BOTTOM_MAGIC pushq $SP_BOTTOM_MAGIC
/* Jump to C entry for the AP */ /* Jump to C entry for the AP */
call cpu_secondary_init mov $cpu_secondary_init, %rax
jmp *%rax
cpu_secondary_error:
/* Error condition trap */
jmp cpu_secondary_error
/* GDT table */ /* GDT table */
.align 4 .align 4
@ -136,17 +140,23 @@ cpu_secondary_gdt_end:
/* GDT pointer */ /* GDT pointer */
.align 2 .align 2
.global cpu_secondary_gdt_ptr
cpu_secondary_gdt_ptr: cpu_secondary_gdt_ptr:
.short (cpu_secondary_gdt_end - cpu_secondary_gdt) - 1 .short (cpu_secondary_gdt_end - cpu_secondary_gdt) - 1
.quad cpu_secondary_gdt .quad cpu_secondary_gdt
/* PML4, PDPT, and PD tables initialized to map first 4 GBytes of memory */ /* PML4, PDPT, and PD tables initialized to map first 4 GBytes of memory */
.align 4
.global CPU_Boot_Page_Tables_ptr
CPU_Boot_Page_Tables_ptr:
.long CPU_Boot_Page_Tables_Start
.align CPU_PAGE_SIZE .align CPU_PAGE_SIZE
.global CPU_Boot_Page_Tables_Start .global CPU_Boot_Page_Tables_Start
CPU_Boot_Page_Tables_Start: CPU_Boot_Page_Tables_Start:
.quad cpu_secondary_pdpt_addr + (IA32E_COMM_P_BIT | IA32E_COMM_RW_BIT) .quad cpu_secondary_pdpt_addr + (IA32E_COMM_P_BIT | IA32E_COMM_RW_BIT)
.align CPU_PAGE_SIZE .align CPU_PAGE_SIZE
.global cpu_secondary_pdpt_addr
cpu_secondary_pdpt_addr: cpu_secondary_pdpt_addr:
address = 0 address = 0
.rept 4 .rept 4

View File

@ -5,7 +5,7 @@ ENTRY(cpu_primary_start_32)
MEMORY MEMORY
{ {
/* Low 1MB of memory for secondary processor start-up */ /* Low 1MB of memory for secondary processor start-up */
lowram : ORIGIN = CONFIG_LOW_RAM_START, LENGTH = CONFIG_LOW_RAM_SIZE lowram : ORIGIN = 0, LENGTH = CONFIG_LOW_RAM_SIZE
/* 32 MBytes of RAM for HV */ /* 32 MBytes of RAM for HV */
ram : ORIGIN = CONFIG_RAM_START, LENGTH = CONFIG_RAM_SIZE ram : ORIGIN = CONFIG_RAM_START, LENGTH = CONFIG_RAM_SIZE
@ -43,6 +43,7 @@ SECTIONS
.cpu_secondary : AT (_ld_cpu_secondary_reset_load) .cpu_secondary : AT (_ld_cpu_secondary_reset_load)
{ {
/* entry point of AP wakeup, must be at the beginning of this section*/
_ld_cpu_secondary_reset_start = .; _ld_cpu_secondary_reset_start = .;
*(.cpu_secondary_reset); *(.cpu_secondary_reset);
. = ALIGN(4); . = ALIGN(4);

View File

@ -41,7 +41,6 @@
#define HEAP_SIZE 0x100000 #define HEAP_SIZE 0x100000
#define CONSOLE_LOGLEVEL_DEFAULT 2 #define CONSOLE_LOGLEVEL_DEFAULT 2
#define MEM_LOGLEVEL_DEFAULT 4 #define MEM_LOGLEVEL_DEFAULT 4
#define CONFIG_LOW_RAM_START 0x00001000
#define CONFIG_LOW_RAM_SIZE 0x000CF000 #define CONFIG_LOW_RAM_SIZE 0x000CF000
#define CONFIG_RAM_START 0x6E000000 #define CONFIG_RAM_START 0x6E000000
#define CONFIG_RAM_SIZE 0x02000000 /* 32M */ #define CONFIG_RAM_SIZE 0x02000000 /* 32M */

View File

@ -41,7 +41,6 @@
#define HEAP_SIZE 0x100000 #define HEAP_SIZE 0x100000
#define CONSOLE_LOGLEVEL_DEFAULT 2 #define CONSOLE_LOGLEVEL_DEFAULT 2
#define MEM_LOGLEVEL_DEFAULT 4 #define MEM_LOGLEVEL_DEFAULT 4
#define CONFIG_LOW_RAM_START 0x00008000
#define CONFIG_LOW_RAM_SIZE 0x00010000 #define CONFIG_LOW_RAM_SIZE 0x00010000
#define CONFIG_RAM_START 0x20000000 #define CONFIG_RAM_START 0x20000000
#define CONFIG_RAM_SIZE 0x02000000 /* 32M */ #define CONFIG_RAM_SIZE 0x02000000 /* 32M */