From: Jan Beulich Date: Wed, 7 Dec 2016 12:55:42 +0000 (+0100) Subject: x86emul: correct PUSHF/POPF X-Git-Tag: archive/raspbian/4.11.1-1+rpi1~1^2~66^2~3252 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=e5c1b8145bccb7fc587ee5b0c95ace6c5e0c7ffd;p=xen.git x86emul: correct PUSHF/POPF Both need to raise #GP(0) when in VM86 mode with IOPL < 3. Additionally PUSHF is documented to clear VM and RF from the value placed onto the stack. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c index 877023df42..5d5b0c35a0 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -3121,13 +3121,20 @@ x86_emulate( } case 0x9c: /* pushf */ - src.val = _regs.eflags; + generate_exception_if((_regs.eflags & EFLG_VM) && + MASK_EXTR(_regs.eflags, EFLG_IOPL) != 3, + EXC_GP, 0); + src.val = _regs.eflags & ~(EFLG_VM | EFLG_RF); goto push; case 0x9d: /* popf */ { uint32_t mask = EFLG_VIP | EFLG_VIF | EFLG_VM; + if ( !mode_ring0() ) { + generate_exception_if((_regs.eflags & EFLG_VM) && + MASK_EXTR(_regs.eflags, EFLG_IOPL) != 3, + EXC_GP, 0); mask |= EFLG_IOPL; if ( !mode_iopl() ) mask |= EFLG_IF;