ia64/xen-unstable

changeset 16850:dbb5a7983775

vmx realmode: Faster emulation of REP INS and REP OUTS.
This makes, in particular, reading files via the BIOS disk abstraction
much much much faster.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jan 22 17:18:51 2008 +0000 (2008-01-22)
parents a878752a83f9
children 7eafc6e84188
files xen/arch/x86/hvm/vmx/realmode.c
line diff
     1.1 --- a/xen/arch/x86/hvm/vmx/realmode.c	Tue Jan 22 17:18:02 2008 +0000
     1.2 +++ b/xen/arch/x86/hvm/vmx/realmode.c	Tue Jan 22 17:18:51 2008 +0000
     1.3 @@ -223,6 +223,64 @@ realmode_emulate_cmpxchg(
     1.4      return realmode_emulate_write(seg, offset, new, bytes, ctxt);
     1.5  }
     1.6  
     1.7 +static int 
     1.8 +realmode_rep_ins(
     1.9 +    uint16_t src_port,
    1.10 +    enum x86_segment dst_seg,
    1.11 +    unsigned long dst_offset,
    1.12 +    unsigned int bytes_per_rep,
    1.13 +    unsigned long *reps,
    1.14 +    struct x86_emulate_ctxt *ctxt)
    1.15 +{
    1.16 +    struct realmode_emulate_ctxt *rm_ctxt =
    1.17 +        container_of(ctxt, struct realmode_emulate_ctxt, ctxt);
    1.18 +    struct vcpu *curr = current;
    1.19 +    uint32_t paddr = rm_ctxt->seg_reg[dst_seg].base + dst_offset;
    1.20 +
    1.21 +    if ( curr->arch.hvm_vmx.real_mode_io_in_progress )
    1.22 +        return X86EMUL_UNHANDLEABLE;
    1.23 +
    1.24 +    if ( !curr->arch.hvm_vmx.real_mode_io_completed )
    1.25 +    {
    1.26 +        curr->arch.hvm_vmx.real_mode_io_in_progress = 1;
    1.27 +        send_pio_req(src_port, *reps, bytes_per_rep,
    1.28 +                     paddr, IOREQ_READ,
    1.29 +                     !!(ctxt->regs->eflags & X86_EFLAGS_DF), 1);
    1.30 +    }
    1.31 +
    1.32 +    if ( !curr->arch.hvm_vmx.real_mode_io_completed )
    1.33 +        return X86EMUL_RETRY;
    1.34 +
    1.35 +    curr->arch.hvm_vmx.real_mode_io_completed = 0;
    1.36 +
    1.37 +    return X86EMUL_OKAY;
    1.38 +}
    1.39 +
    1.40 +static int 
    1.41 +realmode_rep_outs(
    1.42 +    enum x86_segment src_seg,
    1.43 +    unsigned long src_offset,
    1.44 +    uint16_t dst_port,
    1.45 +    unsigned int bytes_per_rep,
    1.46 +    unsigned long *reps,
    1.47 +    struct x86_emulate_ctxt *ctxt)
    1.48 +{
    1.49 +    struct realmode_emulate_ctxt *rm_ctxt =
    1.50 +        container_of(ctxt, struct realmode_emulate_ctxt, ctxt);
    1.51 +    struct vcpu *curr = current;
    1.52 +    uint32_t paddr = rm_ctxt->seg_reg[src_seg].base + src_offset;
    1.53 +
    1.54 +    if ( curr->arch.hvm_vmx.real_mode_io_in_progress )
    1.55 +        return X86EMUL_UNHANDLEABLE;
    1.56 +
    1.57 +    curr->arch.hvm_vmx.real_mode_io_in_progress = 1;
    1.58 +    send_pio_req(dst_port, *reps, bytes_per_rep,
    1.59 +                 paddr, IOREQ_WRITE,
    1.60 +                 !!(ctxt->regs->eflags & X86_EFLAGS_DF), 1);
    1.61 +
    1.62 +    return X86EMUL_OKAY;
    1.63 +}
    1.64 +
    1.65  static int
    1.66  realmode_read_segment(
    1.67      enum x86_segment seg,
    1.68 @@ -420,6 +478,8 @@ static struct x86_emulate_ops realmode_e
    1.69      .insn_fetch    = realmode_emulate_insn_fetch,
    1.70      .write         = realmode_emulate_write,
    1.71      .cmpxchg       = realmode_emulate_cmpxchg,
    1.72 +    .rep_ins       = realmode_rep_ins,
    1.73 +    .rep_outs      = realmode_rep_outs,
    1.74      .read_segment  = realmode_read_segment,
    1.75      .write_segment = realmode_write_segment,
    1.76      .read_io       = realmode_read_io,