# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1182431037 -3600
# Node ID 899a44cb6ef605d0920acf68cfd55c72b112c033
# Parent acb7aa72fac70e60c4b1aa9679834976e3788530
x86: clear guest's EFLAGS.RF after emulating instructions
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
---
xen/arch/x86/hvm/io.c | 1 +
xen/arch/x86/hvm/platform.c | 3 +++
xen/arch/x86/hvm/vmx/vmx.c | 27 +++++++++++++++------------
xen/arch/x86/traps.c | 2 ++
xen/arch/x86/x86_emulate.c | 1 +
xen/include/asm-x86/hvm/svm/emulate.h | 1 +
6 files changed, 23 insertions(+), 12 deletions(-)
diff -r acb7aa72fac7 -r 899a44cb6ef6 xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c Thu Jun 21 12:13:06 2007 +0100
+++ b/xen/arch/x86/hvm/io.c Thu Jun 21 14:03:57 2007 +0100
@@ -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);
diff -r acb7aa72fac7 -r 899a44cb6ef6 xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c Thu Jun 21 12:13:06 2007 +0100
+++ b/xen/arch/x86/hvm/platform.c Thu Jun 21 14:03:57 2007 +0100
@@ -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; /* RF was set by original #PF */
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; /* RF was set by #PF */
/* Must set CR2 at the failing address */
addr += size - rv;
gdprintk(XENLOG_DEBUG, "Pagefault on non-io side of a "
diff -r acb7aa72fac7 -r 899a44cb6ef6 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Thu Jun 21 12:13:06 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c Thu Jun 21 14:03:57 2007 +0100
@@ -1315,16 +1315,20 @@ static int __get_instruction_length(void
static void inline __update_guest_eip(unsigned long inst_len)
{
- unsigned long current_eip, intr_shadow;
-
- current_eip = __vmread(GUEST_RIP);
- __vmwrite(GUEST_RIP, current_eip + inst_len);
-
- intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO);
- if ( intr_shadow & (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);
+ unsigned long x;
+
+ x = __vmread(GUEST_RIP);
+ __vmwrite(GUEST_RIP, x + inst_len);
+
+ x = __vmread(GUEST_RFLAGS);
+ if ( x & X86_EFLAGS_RF )
+ __vmwrite(GUEST_RFLAGS, x & ~X86_EFLAGS_RF);
+
+ x = __vmread(GUEST_INTERRUPTIBILITY_INFO);
+ if ( x & (VMX_INTR_SHADOW_STI | VMX_INTR_SHADOW_MOV_SS) )
+ {
+ x &= ~(VMX_INTR_SHADOW_STI | VMX_INTR_SHADOW_MOV_SS);
+ __vmwrite(GUEST_INTERRUPTIBILITY_INFO, x);
}
}
@@ -1896,7 +1900,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;
@@ -2272,7 +2276,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! */
diff -r acb7aa72fac7 -r 899a44cb6ef6 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c Thu Jun 21 12:13:06 2007 +0100
+++ b/xen/arch/x86/traps.c Thu Jun 21 14:03:57 2007 +0100
@@ -631,6 +631,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;
}
@@ -1787,6 +1788,7 @@ static int emulate_privileged_op(struct
done:
regs->eip = eip;
+ regs->eflags &= ~X86_EFLAGS_RF;
return EXCRET_fault_fixed;
fail:
diff -r acb7aa72fac7 -r 899a44cb6ef6 xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c Thu Jun 21 12:13:06 2007 +0100
+++ b/xen/arch/x86/x86_emulate.c Thu Jun 21 14:03:57 2007 +0100
@@ -1630,6 +1630,7 @@ x86_emulate(
}
/* Commit shadow register state. */
+ _regs.eflags &= ~EF_RF;
*ctxt->regs = _regs;
done:
diff -r acb7aa72fac7 -r 899a44cb6ef6 xen/include/asm-x86/hvm/svm/emulate.h
--- a/xen/include/asm-x86/hvm/svm/emulate.h Thu Jun 21 12:13:06 2007 +0100
+++ b/xen/include/asm-x86/hvm/svm/emulate.h Thu Jun 21 14:03:57 2007 +0100
@@ -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-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|