ia64/xen-unstable

changeset 18373:493a0a87919e

x86 hvm: Emulate RAM-to-RAM REP MOVS copies efficiently.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Aug 26 14:10:17 2008 +0100 (2008-08-26)
parents 62b904dcf88c
children c5a7ceb199cd
files xen/arch/x86/hvm/emulate.c
line diff
     1.1 --- a/xen/arch/x86/hvm/emulate.c	Tue Aug 26 13:00:43 2008 +0100
     1.2 +++ b/xen/arch/x86/hvm/emulate.c	Tue Aug 26 14:10:17 2008 +0100
     1.3 @@ -575,7 +575,8 @@ static int hvmemul_rep_movs(
     1.4      paddr_t sgpa, dgpa;
     1.5      uint32_t pfec = PFEC_page_present;
     1.6      p2m_type_t p2mt;
     1.7 -    int rc;
     1.8 +    int rc, df = !!(ctxt->regs->eflags & X86_EFLAGS_DF);
     1.9 +    char *buf;
    1.10  
    1.11      rc = hvmemul_virtual_to_linear(
    1.12          src_seg, src_offset, bytes_per_rep, reps, hvm_access_read,
    1.13 @@ -606,15 +607,29 @@ static int hvmemul_rep_movs(
    1.14      (void)gfn_to_mfn_current(sgpa >> PAGE_SHIFT, &p2mt);
    1.15      if ( !p2m_is_ram(p2mt) )
    1.16          return hvmemul_do_mmio(
    1.17 -            sgpa, reps, bytes_per_rep, dgpa, IOREQ_READ,
    1.18 -            !!(ctxt->regs->eflags & X86_EFLAGS_DF), NULL);
    1.19 +            sgpa, reps, bytes_per_rep, dgpa, IOREQ_READ, df, NULL);
    1.20  
    1.21      (void)gfn_to_mfn_current(dgpa >> PAGE_SHIFT, &p2mt);
    1.22 -    if ( p2m_is_ram(p2mt) )
    1.23 +    if ( !p2m_is_ram(p2mt) )
    1.24 +        return hvmemul_do_mmio(
    1.25 +            dgpa, reps, bytes_per_rep, sgpa, IOREQ_WRITE, df, NULL);
    1.26 +
    1.27 +    if ( df )
    1.28 +    {
    1.29 +        sgpa -= (*reps - 1) * bytes_per_rep;
    1.30 +        dgpa -= (*reps - 1) * bytes_per_rep;
    1.31 +    }
    1.32 +
    1.33 +    buf = xmalloc_bytes(*reps * bytes_per_rep);
    1.34 +    if ( buf == NULL )
    1.35          return X86EMUL_UNHANDLEABLE;
    1.36 -    return hvmemul_do_mmio(
    1.37 -        dgpa, reps, bytes_per_rep, sgpa, IOREQ_WRITE,
    1.38 -        !!(ctxt->regs->eflags & X86_EFLAGS_DF), NULL);
    1.39 +
    1.40 +    hvm_copy_from_guest_phys(buf, sgpa, *reps * bytes_per_rep);
    1.41 +    hvm_copy_to_guest_phys(dgpa, buf, *reps * bytes_per_rep);
    1.42 +
    1.43 +    xfree(buf);
    1.44 +
    1.45 +    return X86EMUL_OKAY;
    1.46  }
    1.47  
    1.48  static int hvmemul_read_segment(