Jan Beulich
2007-Jun-19 09:53 UTC
[Xen-devel] [PATCH] x86: clear guest''s EFLAGS.RF after emulating instructions
Signed-off-by: Jan Beulich <jbeulich@novell.com> Index: 2007-06-18/xen/arch/x86/hvm/io.c ==================================================================--- 2007-06-18.orig/xen/arch/x86/hvm/io.c 2007-06-18 11:26:06.000000000 +0200 +++ 2007-06-18/xen/arch/x86/hvm/io.c 2007-06-18 11:12:47.000000000 +0200 @@ -858,6 +858,7 @@ void hvm_io_assist(void) } /* Copy register changes back into current guest state. */ + regs->eflags &= ~X86_EFLAGS_RF; hvm_load_cpu_guest_regs(v, regs); memcpy(guest_cpu_user_regs(), regs, HVM_CONTEXT_STACK_BYTES); Index: 2007-06-18/xen/arch/x86/hvm/platform.c ==================================================================--- 2007-06-18.orig/xen/arch/x86/hvm/platform.c 2007-06-18 11:26:06.000000000 +0200 +++ 2007-06-18/xen/arch/x86/hvm/platform.c 2007-06-18 11:12:47.000000000 +0200 @@ -1065,6 +1065,7 @@ void handle_mmio(unsigned long gpa) } regs->eip += inst_len; /* advance %eip */ + regs->eflags &= ~X86_EFLAGS_RF; switch ( mmio_op->instr ) { case INSTR_MOV: @@ -1122,6 +1123,7 @@ void handle_mmio(unsigned long gpa) /* IO read --> memory write */ if ( dir == IOREQ_READ ) errcode |= PFEC_write_access; regs->eip -= inst_len; /* do not advance %eip */ + regs->eflags |= X86_EFLAGS_RF; hvm_inject_exception(TRAP_page_fault, errcode, addr); return; } @@ -1150,6 +1152,7 @@ void handle_mmio(unsigned long gpa) /* Failed on the page-spanning copy. Inject PF into * the guest for the address where we failed */ regs->eip -= inst_len; /* do not advance %eip */ + regs->eflags |= X86_EFLAGS_RF; /* Must set CR2 at the failing address */ addr += size - rv; gdprintk(XENLOG_DEBUG, "Pagefault on non-io side of a " Index: 2007-06-18/xen/arch/x86/hvm/vmx/vmx.c ==================================================================--- 2007-06-18.orig/xen/arch/x86/hvm/vmx/vmx.c 2007-06-18 11:26:06.000000000 +0200 +++ 2007-06-18/xen/arch/x86/hvm/vmx/vmx.c 2007-06-18 11:14:48.000000000 +0200 @@ -1300,16 +1300,20 @@ static int __get_instruction_length(void static void inline __update_guest_eip(unsigned long inst_len) { - unsigned long current_eip, intr_shadow; + unsigned long curr; - current_eip = __vmread(GUEST_RIP); - __vmwrite(GUEST_RIP, current_eip + inst_len); + curr = __vmread(GUEST_RIP); + __vmwrite(GUEST_RIP, curr + inst_len); - intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO); - if ( intr_shadow & (VMX_INTR_SHADOW_STI | VMX_INTR_SHADOW_MOV_SS) ) + curr = __vmread(GUEST_RFLAGS); + if (curr & X86_EFLAGS_RF) + __vmwrite(GUEST_RFLAGS, curr & ~X86_EFLAGS_RF); + + curr = __vmread(GUEST_INTERRUPTIBILITY_INFO); + if ( curr & (VMX_INTR_SHADOW_STI | VMX_INTR_SHADOW_MOV_SS) ) { - intr_shadow &= ~(VMX_INTR_SHADOW_STI | VMX_INTR_SHADOW_MOV_SS); - __vmwrite(GUEST_INTERRUPTIBILITY_INFO, intr_shadow); + curr &= ~(VMX_INTR_SHADOW_STI | VMX_INTR_SHADOW_MOV_SS); + __vmwrite(GUEST_INTERRUPTIBILITY_INFO, curr); } } @@ -1881,7 +1885,7 @@ static void vmx_world_save(struct vcpu * c->eip += __get_instruction_length(); /* Safe: MOV Cn, LMSW, CLTS */ c->esp = __vmread(GUEST_RSP); - c->eflags = __vmread(GUEST_RFLAGS); + c->eflags = __vmread(GUEST_RFLAGS) & ~X86_EFLAGS_RF; c->cr0 = v->arch.hvm_vmx.cpu_shadow_cr0; c->cr3 = v->arch.hvm_vmx.cpu_cr3; @@ -2257,7 +2261,6 @@ static int vmx_set_cr0(unsigned long val "Enabling CR0.PE at %%eip 0x%lx", eip); if ( vmx_assist(v, VMX_ASSIST_RESTORE) ) { - eip = __vmread(GUEST_RIP); HVM_DBG_LOG(DBG_LEVEL_1, "Restoring to %%eip 0x%lx", eip); return 0; /* do not update eip! */ Index: 2007-06-18/xen/arch/x86/traps.c ==================================================================--- 2007-06-18.orig/xen/arch/x86/traps.c 2007-06-18 11:26:06.000000000 +0200 +++ 2007-06-18/xen/arch/x86/traps.c 2007-06-18 11:12:47.000000000 +0200 @@ -621,6 +621,7 @@ static int emulate_forced_invalid_op(str regs->ecx = c; regs->edx = d; regs->eip = eip; + regs->eflags &= ~X86_EFLAGS_RF; return EXCRET_fault_fixed; } @@ -1777,6 +1778,7 @@ static int emulate_privileged_op(struct done: regs->eip = eip; + regs->eflags &= ~X86_EFLAGS_RF; return EXCRET_fault_fixed; fail: Index: 2007-06-18/xen/arch/x86/x86_emulate.c ==================================================================--- 2007-06-18.orig/xen/arch/x86/x86_emulate.c 2007-06-18 11:26:06.000000000 +0200 +++ 2007-06-18/xen/arch/x86/x86_emulate.c 2007-06-18 11:26:45.000000000 +0200 @@ -1630,6 +1630,7 @@ x86_emulate( } /* Commit shadow register state. */ + _regs.eflags &= ~EF_RF; *ctxt->regs = _regs; done: Index: 2007-06-18/xen/include/asm-x86/hvm/svm/emulate.h ==================================================================--- 2007-06-18.orig/xen/include/asm-x86/hvm/svm/emulate.h 2007-06-18 11:26:06.000000000 +0200 +++ 2007-06-18/xen/include/asm-x86/hvm/svm/emulate.h 2007-06-18 11:12:47.000000000 +0200 @@ -138,6 +138,7 @@ static void inline __update_guest_eip( { ASSERT(inst_len > 0); vmcb->rip += inst_len; + vmcb->rflags &= ~X86_EFLAGS_RF; } #endif /* __ASM_X86_HVM_SVM_EMULATE_H__ */ _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2007-Jun-19 09:59 UTC
Re: [Xen-devel] [PATCH] x86: clear guest''s EFLAGS.RF after emulating instructions
On 19/6/07 10:53, "Jan Beulich" <jbeulich@novell.com> wrote:> Signed-off-by: Jan Beulich <jbeulich@novell.com>You set EFLAGS.RF in a few places when injecting #PF. Why would you do that? It isn''t Xen''s job to set that flag ever afaics, and since the original trap into Xen was not due to #DB you''re not avoiding an infinite loop. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jan Beulich
2007-Jun-19 10:09 UTC
Re: [Xen-devel] [PATCH] x86: clear guest''s EFLAGS.RF after emulating instructions
>You set EFLAGS.RF in a few places when injecting #PF. Why would you do that? >It isn''t Xen''s job to set that flag ever afaics, and since the original trap >into Xen was not due to #DB you''re not avoiding an infinite loop.This is only in handle_mmio() where I cleared the flag earlier - since #PF has lower priority than #DB, .RF must have been set when the exception was reported, and hence I must re-set it when forwarding the exception. Jan _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2007-Jun-19 10:19 UTC
Re: [Xen-devel] [PATCH] x86: clear guest''s EFLAGS.RF after emulating instructions
On 19/6/07 11:09, "Jan Beulich" <jbeulich@novell.com> wrote:>> You set EFLAGS.RF in a few places when injecting #PF. Why would you do that? >> It isn''t Xen''s job to set that flag ever afaics, and since the original trap >> into Xen was not due to #DB you''re not avoiding an infinite loop. > > This is only in handle_mmio() where I cleared the flag earlier - since #PF has > lower > priority than #DB, .RF must have been set when the exception was reported, and > hence I must re-set it when forwarding the exception.Oh, I see. I''m not too familiar with #DB or EFLAGS.RF, but this does appear to make sense given the info in the reference manual. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel