direct-io.hg

changeset 15413:899a44cb6ef6

x86: clear guest's EFLAGS.RF after emulating instructions
Signed-off-by: Jan Beulich <jbeulich@novell.com>
author kfraser@localhost.localdomain
date Thu Jun 21 14:03:57 2007 +0100 (2007-06-21)
parents acb7aa72fac7
children 3cf5052ba5e5
files xen/arch/x86/hvm/io.c xen/arch/x86/hvm/platform.c xen/arch/x86/hvm/vmx/vmx.c xen/arch/x86/traps.c xen/arch/x86/x86_emulate.c xen/include/asm-x86/hvm/svm/emulate.h
line diff
     1.1 --- a/xen/arch/x86/hvm/io.c	Thu Jun 21 12:13:06 2007 +0100
     1.2 +++ b/xen/arch/x86/hvm/io.c	Thu Jun 21 14:03:57 2007 +0100
     1.3 @@ -858,6 +858,7 @@ void hvm_io_assist(void)
     1.4      }
     1.5  
     1.6      /* Copy register changes back into current guest state. */
     1.7 +    regs->eflags &= ~X86_EFLAGS_RF;
     1.8      hvm_load_cpu_guest_regs(v, regs);
     1.9      memcpy(guest_cpu_user_regs(), regs, HVM_CONTEXT_STACK_BYTES);
    1.10  
     2.1 --- a/xen/arch/x86/hvm/platform.c	Thu Jun 21 12:13:06 2007 +0100
     2.2 +++ b/xen/arch/x86/hvm/platform.c	Thu Jun 21 14:03:57 2007 +0100
     2.3 @@ -1065,6 +1065,7 @@ void handle_mmio(unsigned long gpa)
     2.4      }
     2.5  
     2.6      regs->eip += inst_len; /* advance %eip */
     2.7 +    regs->eflags &= ~X86_EFLAGS_RF;
     2.8  
     2.9      switch ( mmio_op->instr ) {
    2.10      case INSTR_MOV:
    2.11 @@ -1122,6 +1123,7 @@ void handle_mmio(unsigned long gpa)
    2.12              /* IO read --> memory write */
    2.13              if ( dir == IOREQ_READ ) errcode |= PFEC_write_access;
    2.14              regs->eip -= inst_len; /* do not advance %eip */
    2.15 +            regs->eflags |= X86_EFLAGS_RF; /* RF was set by original #PF */
    2.16              hvm_inject_exception(TRAP_page_fault, errcode, addr);
    2.17              return;
    2.18          }
    2.19 @@ -1150,6 +1152,7 @@ void handle_mmio(unsigned long gpa)
    2.20                          /* Failed on the page-spanning copy.  Inject PF into
    2.21                           * the guest for the address where we failed */
    2.22                          regs->eip -= inst_len; /* do not advance %eip */
    2.23 +                        regs->eflags |= X86_EFLAGS_RF; /* RF was set by #PF */
    2.24                          /* Must set CR2 at the failing address */ 
    2.25                          addr += size - rv;
    2.26                          gdprintk(XENLOG_DEBUG, "Pagefault on non-io side of a "
     3.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Thu Jun 21 12:13:06 2007 +0100
     3.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Thu Jun 21 14:03:57 2007 +0100
     3.3 @@ -1315,16 +1315,20 @@ static int __get_instruction_length(void
     3.4  
     3.5  static void inline __update_guest_eip(unsigned long inst_len)
     3.6  {
     3.7 -    unsigned long current_eip, intr_shadow;
     3.8 -
     3.9 -    current_eip = __vmread(GUEST_RIP);
    3.10 -    __vmwrite(GUEST_RIP, current_eip + inst_len);
    3.11 -
    3.12 -    intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO);
    3.13 -    if ( intr_shadow & (VMX_INTR_SHADOW_STI | VMX_INTR_SHADOW_MOV_SS) )
    3.14 +    unsigned long x;
    3.15 +
    3.16 +    x = __vmread(GUEST_RIP);
    3.17 +    __vmwrite(GUEST_RIP, x + inst_len);
    3.18 +
    3.19 +    x = __vmread(GUEST_RFLAGS);
    3.20 +    if ( x & X86_EFLAGS_RF )
    3.21 +        __vmwrite(GUEST_RFLAGS, x & ~X86_EFLAGS_RF);
    3.22 +
    3.23 +    x = __vmread(GUEST_INTERRUPTIBILITY_INFO);
    3.24 +    if ( x & (VMX_INTR_SHADOW_STI | VMX_INTR_SHADOW_MOV_SS) )
    3.25      {
    3.26 -        intr_shadow &= ~(VMX_INTR_SHADOW_STI | VMX_INTR_SHADOW_MOV_SS);
    3.27 -        __vmwrite(GUEST_INTERRUPTIBILITY_INFO, intr_shadow);
    3.28 +        x &= ~(VMX_INTR_SHADOW_STI | VMX_INTR_SHADOW_MOV_SS);
    3.29 +        __vmwrite(GUEST_INTERRUPTIBILITY_INFO, x);
    3.30      }
    3.31  }
    3.32  
    3.33 @@ -1896,7 +1900,7 @@ static void vmx_world_save(struct vcpu *
    3.34      c->eip += __get_instruction_length(); /* Safe: MOV Cn, LMSW, CLTS */
    3.35  
    3.36      c->esp = __vmread(GUEST_RSP);
    3.37 -    c->eflags = __vmread(GUEST_RFLAGS);
    3.38 +    c->eflags = __vmread(GUEST_RFLAGS) & ~X86_EFLAGS_RF;
    3.39  
    3.40      c->cr0 = v->arch.hvm_vmx.cpu_shadow_cr0;
    3.41      c->cr3 = v->arch.hvm_vmx.cpu_cr3;
    3.42 @@ -2272,7 +2276,6 @@ static int vmx_set_cr0(unsigned long val
    3.43                      "Enabling CR0.PE at %%eip 0x%lx", eip);
    3.44          if ( vmx_assist(v, VMX_ASSIST_RESTORE) )
    3.45          {
    3.46 -            eip = __vmread(GUEST_RIP);
    3.47              HVM_DBG_LOG(DBG_LEVEL_1,
    3.48                          "Restoring to %%eip 0x%lx", eip);
    3.49              return 0; /* do not update eip! */
     4.1 --- a/xen/arch/x86/traps.c	Thu Jun 21 12:13:06 2007 +0100
     4.2 +++ b/xen/arch/x86/traps.c	Thu Jun 21 14:03:57 2007 +0100
     4.3 @@ -631,6 +631,7 @@ static int emulate_forced_invalid_op(str
     4.4      regs->ecx = c;
     4.5      regs->edx = d;
     4.6      regs->eip = eip;
     4.7 +    regs->eflags &= ~X86_EFLAGS_RF;
     4.8  
     4.9      return EXCRET_fault_fixed;
    4.10  }
    4.11 @@ -1787,6 +1788,7 @@ static int emulate_privileged_op(struct 
    4.12  
    4.13   done:
    4.14      regs->eip = eip;
    4.15 +    regs->eflags &= ~X86_EFLAGS_RF;
    4.16      return EXCRET_fault_fixed;
    4.17  
    4.18   fail:
     5.1 --- a/xen/arch/x86/x86_emulate.c	Thu Jun 21 12:13:06 2007 +0100
     5.2 +++ b/xen/arch/x86/x86_emulate.c	Thu Jun 21 14:03:57 2007 +0100
     5.3 @@ -1630,6 +1630,7 @@ x86_emulate(
     5.4      }
     5.5  
     5.6      /* Commit shadow register state. */
     5.7 +    _regs.eflags &= ~EF_RF;
     5.8      *ctxt->regs = _regs;
     5.9  
    5.10   done:
     6.1 --- a/xen/include/asm-x86/hvm/svm/emulate.h	Thu Jun 21 12:13:06 2007 +0100
     6.2 +++ b/xen/include/asm-x86/hvm/svm/emulate.h	Thu Jun 21 14:03:57 2007 +0100
     6.3 @@ -138,6 +138,7 @@ static void inline __update_guest_eip(
     6.4  {
     6.5      ASSERT(inst_len > 0);
     6.6      vmcb->rip += inst_len;
     6.7 +    vmcb->rflags &= ~X86_EFLAGS_RF;
     6.8  }
     6.9  
    6.10  #endif /* __ASM_X86_HVM_SVM_EMULATE_H__ */