From: Roger Pau Monne Date: Fri, 21 Jun 2024 13:28:49 +0000 (+0200) Subject: (no commit message) X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=0d26d222dbc9c44cf9e5c9f02b6e4d4f8e02c46e;p=people%2Froyger%2Fxen.git --- diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S index 04bb62ae86..af78548201 100644 --- a/xen/arch/x86/boot/x86_64.S +++ b/xen/arch/x86/boot/x86_64.S @@ -15,6 +15,17 @@ ENTRY(__high_start) mov $XEN_MINIMAL_CR4,%rcx mov %rcx,%cr4 + /* + * Possibly switch to the per-CPU idle page-tables. Note we cannot + * switch earlier as the per-CPU page-tables might be above 4G, and + * hence need to load them from 64bit code. + */ + mov ap_cr3(%rip), %rax + test %rax, %rax + jz .L_skip_cr3 + mov %rax, %cr3 +.L_skip_cr3: + mov stack_start(%rip),%rsp /* Reset EFLAGS (subsumes CLI and CLD). */ diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 7ea2439b5c..410d295c3c 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -555,6 +555,7 @@ void arch_vcpu_regs_init(struct vcpu *v) int arch_vcpu_create(struct vcpu *v) { struct domain *d = v->domain; + root_pgentry_t *pgt = NULL; int rc; v->arch.flags = TF_kernel_mode; @@ -589,7 +590,23 @@ int arch_vcpu_create(struct vcpu *v) else { /* Idle domain */ - v->arch.cr3 = __pa(idle_pg_table); + if ( (opt_asi_pv || opt_asi_hvm) && v->vcpu_id ) + { + pgt = alloc_xenheap_page(); + + /* + * For the idle vCPU 0 (the BSP idle vCPU) use idle_pg_table + * directly, there's no need to create yet another copy. + */ + rc = -ENOMEM; + if ( !pgt ) + goto fail; + + copy_page(pgt, idle_pg_table); + v->arch.cr3 = __pa(pgt); + } + else + v->arch.cr3 = __pa(idle_pg_table); rc = 0; v->arch.msrs = ZERO_BLOCK_PTR; /* Catch stray misuses */ } @@ -611,6 +628,7 @@ int arch_vcpu_create(struct vcpu *v) vcpu_destroy_fpu(v); xfree(v->arch.msrs); v->arch.msrs = NULL; + free_xenheap_page(pgt); return rc; } diff --git a/xen/arch/x86/domain_page.c b/xen/arch/x86/domain_page.c index eac5e3304f..99b78af90f 100644 --- a/xen/arch/x86/domain_page.c +++ b/xen/arch/x86/domain_page.c @@ -51,7 +51,7 @@ static inline struct vcpu *mapcache_current_vcpu(void) if ( (v = idle_vcpu[smp_processor_id()]) == current ) sync_local_execstate(); /* We must now be running on the idle page table. */ - ASSERT(cr3_pa(read_cr3()) == __pa(idle_pg_table)); + ASSERT(cr3_pa(read_cr3()) == cr3_pa(v->arch.cr3)); } return v; diff --git a/xen/arch/x86/include/asm/setup.h b/xen/arch/x86/include/asm/setup.h index d75589178b..a8452fce8f 100644 --- a/xen/arch/x86/include/asm/setup.h +++ b/xen/arch/x86/include/asm/setup.h @@ -14,6 +14,7 @@ extern unsigned long xenheap_initial_phys_start; extern uint64_t boot_tsc_stamp; extern void *stack_start; +extern unsigned long ap_cr3; void early_cpu_init(bool verbose); void early_time_init(void); diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index eee20bb175..c4f6dbcb61 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -158,6 +158,9 @@ char asmlinkage __section(".init.bss.stack_aligned") __aligned(STACK_SIZE) /* Used by the BSP/AP paths to find the higher half stack mapping to use. */ void *stack_start = cpu0_stack + STACK_SIZE - sizeof(struct cpu_info); +/* cr3 value for the AP to load on boot. */ +unsigned long ap_cr3; + /* Used by the boot asm to stash the relocated multiboot info pointer. */ unsigned int asmlinkage __initdata multiboot_ptr; diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index 8fc8710ec8..302b1a0c75 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -581,6 +581,13 @@ static int do_boot_cpu(int apicid, int cpu) stack_start = stack_base[cpu] + STACK_SIZE - sizeof(struct cpu_info); + /* + * If per-CPU idle root page table has been allocated, switch to it as + * part of the AP bringup trampoline. + */ + ap_cr3 = idle_vcpu[cpu]->arch.cr3 != __pa(idle_pg_table) ? + idle_vcpu[cpu]->arch.cr3 : 0; + /* This grunge runs the startup process for the targeted processor. */ set_cpu_state(CPU_STATE_INIT);