ia64/xen-unstable

changeset 17011:8e4cd0658c41

vmx realmode: Add REP MOVS handler.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Feb 07 18:57:12 2008 +0000 (2008-02-07)
parents 5e08872c24f7
children 1b750b9cf431
files xen/arch/x86/hvm/vmx/realmode.c
line diff
     1.1 --- a/xen/arch/x86/hvm/vmx/realmode.c	Thu Feb 07 18:56:47 2008 +0000
     1.2 +++ b/xen/arch/x86/hvm/vmx/realmode.c	Thu Feb 07 18:57:12 2008 +0000
     1.3 @@ -13,6 +13,7 @@
     1.4  #include <xen/init.h>
     1.5  #include <xen/lib.h>
     1.6  #include <xen/sched.h>
     1.7 +#include <xen/paging.h>
     1.8  #include <asm/event.h>
     1.9  #include <asm/hvm/hvm.h>
    1.10  #include <asm/hvm/support.h>
    1.11 @@ -313,6 +314,57 @@ realmode_rep_outs(
    1.12      return X86EMUL_OKAY;
    1.13  }
    1.14  
    1.15 +static int 
    1.16 +realmode_rep_movs(
    1.17 +   enum x86_segment src_seg,
    1.18 +   unsigned long src_offset,
    1.19 +   enum x86_segment dst_seg,
    1.20 +   unsigned long dst_offset,
    1.21 +   unsigned int bytes_per_rep,
    1.22 +   unsigned long *reps,
    1.23 +   struct x86_emulate_ctxt *ctxt)
    1.24 +{
    1.25 +    struct realmode_emulate_ctxt *rm_ctxt =
    1.26 +        container_of(ctxt, struct realmode_emulate_ctxt, ctxt);
    1.27 +    struct vcpu *curr = current;
    1.28 +    uint32_t saddr = virtual_to_linear(src_seg, src_offset, rm_ctxt);
    1.29 +    uint32_t daddr = virtual_to_linear(dst_seg, dst_offset, rm_ctxt);
    1.30 +    p2m_type_t p2mt;
    1.31 +
    1.32 +    if ( (curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE) ||
    1.33 +         curr->arch.hvm_vmx.real_mode_io_in_progress )
    1.34 +        return X86EMUL_UNHANDLEABLE;
    1.35 +
    1.36 +    mfn_x(gfn_to_mfn_current(saddr >> PAGE_SHIFT, &p2mt));
    1.37 +    if ( !p2m_is_ram(p2mt) )
    1.38 +    {
    1.39 +        if ( !curr->arch.hvm_vmx.real_mode_io_completed )
    1.40 +        {
    1.41 +            curr->arch.hvm_vmx.real_mode_io_in_progress = 1;
    1.42 +            send_mmio_req(IOREQ_TYPE_COPY, saddr, *reps, bytes_per_rep,
    1.43 +                      daddr, IOREQ_READ,
    1.44 +                      !!(ctxt->regs->eflags & X86_EFLAGS_DF), 1);
    1.45 +        }
    1.46 +
    1.47 +        if ( !curr->arch.hvm_vmx.real_mode_io_completed )
    1.48 +            return X86EMUL_RETRY;
    1.49 +
    1.50 +        curr->arch.hvm_vmx.real_mode_io_completed = 0;
    1.51 +    }
    1.52 +    else
    1.53 +    {
    1.54 +        mfn_x(gfn_to_mfn_current(daddr >> PAGE_SHIFT, &p2mt));
    1.55 +        if ( p2m_is_ram(p2mt) )
    1.56 +            return X86EMUL_UNHANDLEABLE;
    1.57 +        curr->arch.hvm_vmx.real_mode_io_in_progress = 1;
    1.58 +        send_mmio_req(IOREQ_TYPE_COPY, daddr, *reps, bytes_per_rep,
    1.59 +                      saddr, IOREQ_WRITE,
    1.60 +                      !!(ctxt->regs->eflags & X86_EFLAGS_DF), 1);
    1.61 +    }
    1.62 +
    1.63 +    return X86EMUL_OKAY;
    1.64 +}
    1.65 +
    1.66  static int
    1.67  realmode_read_segment(
    1.68      enum x86_segment seg,
    1.69 @@ -600,6 +652,7 @@ static struct x86_emulate_ops realmode_e
    1.70      .cmpxchg       = realmode_emulate_cmpxchg,
    1.71      .rep_ins       = realmode_rep_ins,
    1.72      .rep_outs      = realmode_rep_outs,
    1.73 +    .rep_movs      = realmode_rep_movs,
    1.74      .read_segment  = realmode_read_segment,
    1.75      .write_segment = realmode_write_segment,
    1.76      .read_io       = realmode_read_io,