ia64/xen-unstable

changeset 16466:bb961bda7eff

vmx realmode: Detect and correctly plumb mmio accesses from emulated
realmode. Also correctly handle debug output to I/O port 0xe9.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Sun Nov 25 21:24:48 2007 +0000 (2007-11-25)
parents 6d129d093394
children dc3a566f9e44
files xen/arch/x86/hvm/platform.c xen/arch/x86/hvm/vmx/realmode.c xen/include/asm-x86/hvm/io.h
line diff
     1.1 --- a/xen/arch/x86/hvm/platform.c	Sun Nov 25 18:07:33 2007 +0000
     1.2 +++ b/xen/arch/x86/hvm/platform.c	Sun Nov 25 21:24:48 2007 +0000
     1.3 @@ -885,9 +885,9 @@ void send_pio_req(unsigned long port, un
     1.4      hvm_send_assist_req(v);
     1.5  }
     1.6  
     1.7 -static void send_mmio_req(unsigned char type, unsigned long gpa,
     1.8 -                          unsigned long count, int size, paddr_t value,
     1.9 -                          int dir, int df, int value_is_ptr)
    1.10 +void send_mmio_req(unsigned char type, unsigned long gpa,
    1.11 +                   unsigned long count, int size, paddr_t value,
    1.12 +                   int dir, int df, int value_is_ptr)
    1.13  {
    1.14      struct vcpu *v = current;
    1.15      vcpu_iodata_t *vio;
     2.1 --- a/xen/arch/x86/hvm/vmx/realmode.c	Sun Nov 25 18:07:33 2007 +0000
     2.2 +++ b/xen/arch/x86/hvm/vmx/realmode.c	Sun Nov 25 21:24:48 2007 +0000
     2.3 @@ -108,8 +108,39 @@ realmode_read(
     2.4      struct realmode_emulate_ctxt *rm_ctxt)
     2.5  {
     2.6      uint32_t addr = rm_ctxt->seg_reg[seg].base + offset;
     2.7 +    int todo;
     2.8 +
     2.9      *val = 0;
    2.10 -    (void)hvm_copy_from_guest_phys(val, addr, bytes);
    2.11 +    todo = hvm_copy_from_guest_phys(val, addr, bytes);
    2.12 +
    2.13 +    if ( todo )
    2.14 +    {
    2.15 +        struct vcpu *curr = current;
    2.16 +
    2.17 +        if ( todo != bytes )
    2.18 +        {
    2.19 +            gdprintk(XENLOG_WARNING, "RM: Partial read at %08x (%d/%d)\n",
    2.20 +                     addr, todo, bytes);
    2.21 +            return X86EMUL_UNHANDLEABLE;
    2.22 +        }
    2.23 +
    2.24 +        if ( curr->arch.hvm_vmx.real_mode_io_in_progress )
    2.25 +            return X86EMUL_UNHANDLEABLE;
    2.26 +
    2.27 +        if ( !curr->arch.hvm_vmx.real_mode_io_completed )
    2.28 +        {
    2.29 +            curr->arch.hvm_vmx.real_mode_io_in_progress = 1;
    2.30 +            send_mmio_req(IOREQ_TYPE_COPY, addr, 1, bytes,
    2.31 +                          0, IOREQ_READ, 0, 0);
    2.32 +        }
    2.33 +
    2.34 +        if ( !curr->arch.hvm_vmx.real_mode_io_completed )
    2.35 +            return X86EMUL_UNHANDLEABLE;
    2.36 +
    2.37 +        *val = curr->arch.hvm_vmx.real_mode_io_data;
    2.38 +        curr->arch.hvm_vmx.real_mode_io_completed = 0;
    2.39 +    }
    2.40 +
    2.41      return X86EMUL_OKAY;
    2.42  }
    2.43  
    2.44 @@ -161,7 +192,29 @@ realmode_emulate_write(
    2.45      struct realmode_emulate_ctxt *rm_ctxt =
    2.46          container_of(ctxt, struct realmode_emulate_ctxt, ctxt);
    2.47      uint32_t addr = rm_ctxt->seg_reg[seg].base + offset;
    2.48 -    (void)hvm_copy_to_guest_phys(addr, &val, bytes);
    2.49 +    int todo;
    2.50 +
    2.51 +    todo = hvm_copy_to_guest_phys(addr, &val, bytes);
    2.52 +
    2.53 +    if ( todo )
    2.54 +    {
    2.55 +        struct vcpu *curr = current;
    2.56 +
    2.57 +        if ( todo != bytes )
    2.58 +        {
    2.59 +            gdprintk(XENLOG_WARNING, "RM: Partial write at %08x (%d/%d)\n",
    2.60 +                     addr, todo, bytes);
    2.61 +            return X86EMUL_UNHANDLEABLE;
    2.62 +        }
    2.63 +
    2.64 +        if ( curr->arch.hvm_vmx.real_mode_io_in_progress )
    2.65 +            return X86EMUL_UNHANDLEABLE;
    2.66 +
    2.67 +        curr->arch.hvm_vmx.real_mode_io_in_progress = 1;
    2.68 +        send_mmio_req(IOREQ_TYPE_COPY, addr, 1, bytes,
    2.69 +                      val, IOREQ_WRITE, 0, 0);
    2.70 +    }
    2.71 +
    2.72      return X86EMUL_OKAY;
    2.73  }
    2.74  
    2.75 @@ -244,6 +297,12 @@ static int realmode_write_io(
    2.76  {
    2.77      struct vcpu *curr = current;
    2.78  
    2.79 +    if ( port == 0xe9 )
    2.80 +    {
    2.81 +        hvm_print_line(curr, val);
    2.82 +        return X86EMUL_OKAY;
    2.83 +    }
    2.84 +
    2.85      if ( curr->arch.hvm_vmx.real_mode_io_in_progress )
    2.86          return X86EMUL_UNHANDLEABLE;
    2.87  
     3.1 --- a/xen/include/asm-x86/hvm/io.h	Sun Nov 25 18:07:33 2007 +0000
     3.2 +++ b/xen/include/asm-x86/hvm/io.h	Sun Nov 25 21:24:48 2007 +0000
     3.3 @@ -149,8 +149,11 @@ static inline int register_buffered_io_h
     3.4      return register_io_handler(d, addr, size, action, HVM_BUFFERED_IO);
     3.5  }
     3.6  
     3.7 -extern void send_pio_req(unsigned long port, unsigned long count, int size,
     3.8 -                         paddr_t value, int dir, int df, int value_is_ptr);
     3.9 +void send_mmio_req(unsigned char type, unsigned long gpa,
    3.10 +                   unsigned long count, int size, paddr_t value,
    3.11 +                   int dir, int df, int value_is_ptr);
    3.12 +void send_pio_req(unsigned long port, unsigned long count, int size,
    3.13 +                  paddr_t value, int dir, int df, int value_is_ptr);
    3.14  void send_timeoffset_req(unsigned long timeoff);
    3.15  void send_invalidate_req(void);
    3.16  extern void handle_mmio(unsigned long gpa);