[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH for-4.16] x86/shstk: Fix use of shadow stacks with XPTI active
The call to setup_cpu_root_pgt(0) in smp_prepare_cpus() is too early. It clones the BSP's stack while the .data mapping is still in use, causing all mappings to be fully read read/write (and with no guard pages either). This ultimately causes #DF when trying to enter the dom0 kernel for the first time. Defer setting up BSPs XPTI pagetable until reinit_bsp_stack() after we've set up proper shadow stack permissions. Fixes: 60016604739b ("x86/shstk: Rework the stack layout to support shadow stacks") Fixes: b60ab42db2f0 ("x86/shstk: Activate Supervisor Shadow Stacks") Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- CC: Jan Beulich <JBeulich@xxxxxxxx> CC: Roger Pau Monné <roger.pau@xxxxxxxxxx> CC: Wei Liu <wl@xxxxxxx> For 4.16. This is a rare configuration. Real hardware supporting CET-SS is either AMD, or fixed to Meltdown, so doesn't turn on XPTI by default. The bug can be triggered either by booting real CET-SS hardware with `xpti` on the cmdline, or booting Xen in a VM where "fixed to meltdown" isn't advertised. The result when things go wrong is an unconditional crash. Risks are minimal - all the change is doing is reordering some actions during boot. The shadow stack specific aspects are hard for people to independently verify, owing to the fact that CET-SS is only on current-generation CPUs, but I have an example sitting on my desk which is how I discovered this. However, the paths altered are tested thoroughly by OSSTest on every single host boot, in a variety of combinations due to the selection of hardware. --- xen/arch/x86/setup.c | 5 +++++ xen/arch/x86/smpboot.c | 9 ++------- xen/include/xen/smp.h | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index b101565f1431..fea86530f9f2 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -666,6 +666,7 @@ static void noreturn init_done(void) static void __init noreturn reinit_bsp_stack(void) { unsigned long *stack = (void*)(get_stack_bottom() & ~(STACK_SIZE - 1)); + int rc; /* Update TSS and ISTs */ load_system_tables(); @@ -676,6 +677,10 @@ static void __init noreturn reinit_bsp_stack(void) stack_base[0] = stack; memguard_guard_stack(stack); + rc = setup_cpu_root_pgt(0); + if ( rc ) + panic("Error %d setting up PV root page table\n", rc); + if ( IS_ENABLED(CONFIG_XEN_SHSTK) && cpu_has_xen_shstk ) { wrmsrl(MSR_PL0_SSP, diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index 0dce1ae87210..329cfdb6c9f6 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -821,7 +821,7 @@ static root_pgentry_t common_pgt; extern const char _stextentry[], _etextentry[]; -static int setup_cpu_root_pgt(unsigned int cpu) +int setup_cpu_root_pgt(unsigned int cpu) { root_pgentry_t *rpt; unsigned int off; @@ -1138,8 +1138,6 @@ static struct notifier_block cpu_smpboot_nfb = { void __init smp_prepare_cpus(void) { - int rc; - register_cpu_notifier(&cpu_smpboot_nfb); mtrr_aps_sync_begin(); @@ -1153,10 +1151,7 @@ void __init smp_prepare_cpus(void) stack_base[0] = (void *)((unsigned long)stack_start & ~(STACK_SIZE - 1)); - rc = setup_cpu_root_pgt(0); - if ( rc ) - panic("Error %d setting up PV root page table\n", rc); - if ( per_cpu(root_pgt, 0) ) + if ( opt_xpti_hwdom || opt_xpti_domu ) { get_cpu_info()->pv_cr3 = 0; diff --git a/xen/include/xen/smp.h b/xen/include/xen/smp.h index d5a3644611db..0a9219173f0f 100644 --- a/xen/include/xen/smp.h +++ b/xen/include/xen/smp.h @@ -70,5 +70,6 @@ int alloc_cpu_id(void); extern void *stack_base[NR_CPUS]; void initialize_cpu_data(unsigned int cpu); +int setup_cpu_root_pgt(unsigned int cpu); #endif /* __XEN_SMP_H__ */ -- 2.11.0
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |