We wish to make use of opt_fred earlier on boot, which involves moving traps_init() earlier, but this comes with several ordering complications.
The feature word containing FRED needs collecting in early_cpu_init(), and legacy_syscall_init() cannot be called that early because it relies on the stubs being allocated, yet must be called ahead of cpu_init() so the SYSCALL linkage MSRs are set up before being cached. Delaying legacy_syscall_init() is easy enough based on a system_state check. Reuse bsp_traps_reinit() to cause a call to legacy_syscall_init() to occur at the same point as previously. Signed-off-by: Andrew Cooper <[email protected]> --- CC: Jan Beulich <[email protected]> CC: Roger Pau Monné <[email protected]> v4: * New I don't particualrly like this solution, but the layout of these functions change for FRED. Any adjustments need to consider the logic at the end of the series, not at this point. --- xen/arch/x86/cpu/common.c | 4 +++- xen/arch/x86/setup.c | 4 +++- xen/arch/x86/traps-setup.c | 12 +++++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index bfa63fcfb721..5d0523a78b52 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -407,7 +407,9 @@ void __init early_cpu_init(bool verbose) } if (max_subleaf >= 1) - cpuid_count(7, 1, &eax, &ebx, &ecx, + cpuid_count(7, 1, + &c->x86_capability[FEATURESET_7a1], + &ebx, &ecx, &c->x86_capability[FEATURESET_7d1]); } diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 675de3a649ea..0816a713e1c8 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -1386,6 +1386,8 @@ void asmlinkage __init noreturn __start_xen(void) else panic("Bootloader provided no memory information\n"); + traps_init(); + /* Choose shadow stack early, to set infrastructure up appropriately. */ if ( !boot_cpu_has(X86_FEATURE_CET_SS) ) opt_xen_shstk = 0; @@ -2078,7 +2080,7 @@ void asmlinkage __init noreturn __start_xen(void) &this_cpu(stubs).mfn); BUG_ON(!this_cpu(stubs.addr)); - traps_init(); /* Needs stubs allocated, must be before presmp_initcalls. */ + bsp_traps_reinit(); /* Needs stubs allocated, must be before presmp_initcalls. */ cpu_init(); diff --git a/xen/arch/x86/traps-setup.c b/xen/arch/x86/traps-setup.c index c5fc71c75bca..b2c161943d1e 100644 --- a/xen/arch/x86/traps-setup.c +++ b/xen/arch/x86/traps-setup.c @@ -346,6 +346,10 @@ void __init traps_init(void) /* * Re-initialise all state referencing the early-boot stack. + * + * This is called twice during boot, first to ensure legacy_syscall_init() has + * run (deferred from earlier), and second when the virtual address of the BSP + * stack changes. */ void __init bsp_traps_reinit(void) { @@ -359,7 +363,13 @@ void __init bsp_traps_reinit(void) */ void percpu_traps_init(void) { - legacy_syscall_init(); + /* + * Skip legacy_syscall_init() at early boot. It requires the stubs being + * allocated, limiting the placement of the traps_init() call, and gets + * re-done anyway by bsp_traps_reinit(). + */ + if ( system_state > SYS_STATE_early_boot ) + legacy_syscall_init(); if ( cpu_has_xen_lbr ) wrmsrl(MSR_IA32_DEBUGCTLMSR, IA32_DEBUGCTLMSR_LBR); -- 2.39.5
