diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index da74172776..a684519a20 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -770,7 +770,13 @@ void load_system_tables(void) tss->ist[IST_MCE - 1] = stack_top + (1 + IST_MCE) * PAGE_SIZE; tss->ist[IST_NMI - 1] = stack_top + (1 + IST_NMI) * PAGE_SIZE; tss->ist[IST_DB - 1] = stack_top + (1 + IST_DB) * PAGE_SIZE; - tss->ist[IST_DF - 1] = stack_top + (1 + IST_DF) * PAGE_SIZE; + /* + * Gross bodge. The #DF handler uses the vm86 fields of cpu_user_regs + * beyond the hardware frame. Adjust the stack entrypoint so this + * doesn't manifest as an OoB write which hits the guard page. + */ + tss->ist[IST_DF - 1] = stack_top + (1 + IST_DF) * PAGE_SIZE - + (sizeof(struct cpu_user_regs) - offsetof(struct cpu_user_regs, es)); tss->bitmap = IOBMP_INVALID_OFFSET; /* All other stack pointers poisioned. */