[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] vmx realmode: Detect and correctly plumb mmio accesses from emulated
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1196025888 0 # Node ID bb961bda7eff2bec637a23990caa9cf1bdaf596a # Parent 6d129d0933942ca2ff672c1f23cf26379c1db129 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@xxxxxxxxxx> --- xen/arch/x86/hvm/platform.c | 6 +-- xen/arch/x86/hvm/vmx/realmode.c | 63 ++++++++++++++++++++++++++++++++++++++-- xen/include/asm-x86/hvm/io.h | 7 +++- 3 files changed, 69 insertions(+), 7 deletions(-) diff -r 6d129d093394 -r bb961bda7eff xen/arch/x86/hvm/platform.c --- a/xen/arch/x86/hvm/platform.c Sun Nov 25 18:07:33 2007 +0000 +++ b/xen/arch/x86/hvm/platform.c Sun Nov 25 21:24:48 2007 +0000 @@ -885,9 +885,9 @@ void send_pio_req(unsigned long port, un hvm_send_assist_req(v); } -static void send_mmio_req(unsigned char type, unsigned long gpa, - unsigned long count, int size, paddr_t value, - int dir, int df, int value_is_ptr) +void send_mmio_req(unsigned char type, unsigned long gpa, + unsigned long count, int size, paddr_t value, + int dir, int df, int value_is_ptr) { struct vcpu *v = current; vcpu_iodata_t *vio; diff -r 6d129d093394 -r bb961bda7eff xen/arch/x86/hvm/vmx/realmode.c --- a/xen/arch/x86/hvm/vmx/realmode.c Sun Nov 25 18:07:33 2007 +0000 +++ b/xen/arch/x86/hvm/vmx/realmode.c Sun Nov 25 21:24:48 2007 +0000 @@ -108,8 +108,39 @@ realmode_read( struct realmode_emulate_ctxt *rm_ctxt) { uint32_t addr = rm_ctxt->seg_reg[seg].base + offset; + int todo; + *val = 0; - (void)hvm_copy_from_guest_phys(val, addr, bytes); + todo = hvm_copy_from_guest_phys(val, addr, bytes); + + if ( todo ) + { + struct vcpu *curr = current; + + if ( todo != bytes ) + { + gdprintk(XENLOG_WARNING, "RM: Partial read at %08x (%d/%d)\n", + addr, todo, bytes); + return X86EMUL_UNHANDLEABLE; + } + + if ( curr->arch.hvm_vmx.real_mode_io_in_progress ) + return X86EMUL_UNHANDLEABLE; + + if ( !curr->arch.hvm_vmx.real_mode_io_completed ) + { + curr->arch.hvm_vmx.real_mode_io_in_progress = 1; + send_mmio_req(IOREQ_TYPE_COPY, addr, 1, bytes, + 0, IOREQ_READ, 0, 0); + } + + if ( !curr->arch.hvm_vmx.real_mode_io_completed ) + return X86EMUL_UNHANDLEABLE; + + *val = curr->arch.hvm_vmx.real_mode_io_data; + curr->arch.hvm_vmx.real_mode_io_completed = 0; + } + return X86EMUL_OKAY; } @@ -161,7 +192,29 @@ realmode_emulate_write( struct realmode_emulate_ctxt *rm_ctxt = container_of(ctxt, struct realmode_emulate_ctxt, ctxt); uint32_t addr = rm_ctxt->seg_reg[seg].base + offset; - (void)hvm_copy_to_guest_phys(addr, &val, bytes); + int todo; + + todo = hvm_copy_to_guest_phys(addr, &val, bytes); + + if ( todo ) + { + struct vcpu *curr = current; + + if ( todo != bytes ) + { + gdprintk(XENLOG_WARNING, "RM: Partial write at %08x (%d/%d)\n", + addr, todo, bytes); + return X86EMUL_UNHANDLEABLE; + } + + if ( curr->arch.hvm_vmx.real_mode_io_in_progress ) + return X86EMUL_UNHANDLEABLE; + + curr->arch.hvm_vmx.real_mode_io_in_progress = 1; + send_mmio_req(IOREQ_TYPE_COPY, addr, 1, bytes, + val, IOREQ_WRITE, 0, 0); + } + return X86EMUL_OKAY; } @@ -243,6 +296,12 @@ static int realmode_write_io( struct x86_emulate_ctxt *ctxt) { struct vcpu *curr = current; + + if ( port == 0xe9 ) + { + hvm_print_line(curr, val); + return X86EMUL_OKAY; + } if ( curr->arch.hvm_vmx.real_mode_io_in_progress ) return X86EMUL_UNHANDLEABLE; diff -r 6d129d093394 -r bb961bda7eff xen/include/asm-x86/hvm/io.h --- a/xen/include/asm-x86/hvm/io.h Sun Nov 25 18:07:33 2007 +0000 +++ b/xen/include/asm-x86/hvm/io.h Sun Nov 25 21:24:48 2007 +0000 @@ -149,8 +149,11 @@ static inline int register_buffered_io_h return register_io_handler(d, addr, size, action, HVM_BUFFERED_IO); } -extern void send_pio_req(unsigned long port, unsigned long count, int size, - paddr_t value, int dir, int df, int value_is_ptr); +void send_mmio_req(unsigned char type, unsigned long gpa, + unsigned long count, int size, paddr_t value, + int dir, int df, int value_is_ptr); +void send_pio_req(unsigned long port, unsigned long count, int size, + paddr_t value, int dir, int df, int value_is_ptr); void send_timeoffset_req(unsigned long timeoff); void send_invalidate_req(void); extern void handle_mmio(unsigned long gpa); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |