debuggers.hg
changeset 16504: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>
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);