[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC][PATCH 1/1] Add IOREQ_TYPE_VMWARE_PORT
Signed-off-by: Don Slutz <dslutz@xxxxxxxxxxx> --- xen/arch/x86/hvm/emulate.c | 58 +++++++++++++++++++++++++++++++++++++++ xen/arch/x86/hvm/io.c | 19 +++++++++++++ xen/arch/x86/hvm/vmware/vmport.c | 24 +++++++++++++++- xen/include/asm-x86/hvm/emulate.h | 2 ++ xen/include/asm-x86/hvm/vcpu.h | 1 + xen/include/public/hvm/ioreq.h | 5 ++++ 6 files changed, 108 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c index 6ab06e0..e442070 100644 --- a/xen/arch/x86/hvm/emulate.c +++ b/xen/arch/x86/hvm/emulate.c @@ -49,6 +49,64 @@ static void hvmtrace_io_assist(int is_mmio, ioreq_t *p) trace_var(event, 0/*!cycles*/, size, buffer); } +int hvmemul_do_vmport(struct cpu_user_regs *regs) +{ + struct vcpu *curr = current; + struct hvm_vcpu_io *vio = &curr->arch.hvm_vcpu.hvm_io; + ioreq_t p = { + .type = IOREQ_TYPE_VMWARE_PORT, + .dir = IOREQ_READ, + .addr = ((uint64_t)regs->rax << 32) | (uint32_t)regs->rbx, + .count = regs->rcx, + .size = regs->rdx, + .data = ((uint64_t)regs->rsi << 32) | (uint32_t)regs->rdi, + .df = 0, + .data_is_ptr = 0, + }; + + switch ( vio->io_state ) + { + case HVMIO_none: + break; + case HVMIO_completed: + vio->io_state = HVMIO_none; + goto finish_access_vmport; + case HVMIO_dispatched: + /* May have to wait for previous cycle of a multi-write to complete. */ + default: + return X86EMUL_UNHANDLEABLE; + } + + if ( hvm_io_pending(curr) ) + { + gdprintk(XENLOG_WARNING, "WARNING: io already pending?\n"); + return X86EMUL_UNHANDLEABLE; + } + + vio->io_state = HVMIO_handle_vmport_awaiting_completion; + vio->io_size = 4; + + /* If there is no backing DM, just ignore accesses */ + if ( !hvm_has_dm(curr->domain) ) + { + vio->io_state = HVMIO_none; + vio->io_data = ~0ul; + } + else + { + if ( !hvm_send_assist_req(&p) ) + vio->io_state = HVMIO_none; + return X86EMUL_RETRY; + } + + finish_access_vmport: + hvmtrace_io_assist(0, &p); + + memcpy(®s->rax, &vio->io_data, vio->io_size); + + return X86EMUL_OKAY; +} + static int hvmemul_do_io( int is_mmio, paddr_t addr, unsigned long *reps, int size, paddr_t ram_gpa, int dir, int df, void *p_data) diff --git a/xen/arch/x86/hvm/io.c b/xen/arch/x86/hvm/io.c index 9f565d6..96ef3ff 100644 --- a/xen/arch/x86/hvm/io.c +++ b/xen/arch/x86/hvm/io.c @@ -206,6 +206,25 @@ void hvm_io_assist(ioreq_t *p) else memcpy(&guest_cpu_user_regs()->rax, &p->data, vio->io_size); break; + case HVMIO_handle_vmport_awaiting_completion: + { + struct cpu_user_regs *regs = guest_cpu_user_regs(); + + /* Always zero extension for eax */ + regs->rax = (uint32_t)(p->addr >> 32); + /* Only zero extension if 32bit register changed */ + if ( (uint32_t)regs->rbx != (uint32_t)p->addr ) + regs->rbx = (uint32_t)p->addr; + if ( (uint32_t)regs->rcx != (uint32_t)p->count ) + regs->rcx = (uint32_t)p->count; + if ( (uint32_t)regs->rdx != (uint32_t)p->size ) + regs->rdx = (uint32_t)p->size; + if ( (uint32_t)regs->rsi != (uint32_t)(p->data >> 32) ) + regs->rsi = (uint32_t)(p->data >> 32); + if ( (uint32_t)regs->rdi != (uint32_t)p->data ) + regs->rdi = (uint32_t)p->data; + } + break; default: break; } diff --git a/xen/arch/x86/hvm/vmware/vmport.c b/xen/arch/x86/hvm/vmware/vmport.c index 962ee32..f79295e 100644 --- a/xen/arch/x86/hvm/vmware/vmport.c +++ b/xen/arch/x86/hvm/vmware/vmport.c @@ -147,9 +147,31 @@ int vmport_ioport(int dir, uint32_t port, uint32_t bytes, uint32_t *val) regs->rax = 0x0; break; default: + { /* Let backing DM handle */ + int rc; + HVMTRACE_ND(VMPORT_UNKNOWN, 0, 1/*cycles*/, 6, - (bytes << 8) + dir, cmd, regs->rbx, + (bytes << 8) | dir, cmd, regs->rbx, regs->rcx, regs->rsi, regs->rdi); + rc = hvmemul_do_vmport(regs); + switch (rc) + { + case X86EMUL_OKAY: + break; + case X86EMUL_RETRY: + { + struct hvm_vcpu_io *vio = ¤t->arch.hvm_vcpu.hvm_io; + + if ( vio->io_state != HVMIO_handle_vmport_awaiting_completion ) + return 0; + break; + } + default: + gdprintk(XENLOG_ERR, "Weird HVM ioemulation status %d.\n", rc); + domain_crash(current->domain); + break; + } + } break; } diff --git a/xen/include/asm-x86/hvm/emulate.h b/xen/include/asm-x86/hvm/emulate.h index efff97e..9887f7e 100644 --- a/xen/include/asm-x86/hvm/emulate.h +++ b/xen/include/asm-x86/hvm/emulate.h @@ -55,4 +55,6 @@ int hvmemul_do_pio( unsigned long port, unsigned long *reps, int size, paddr_t ram_gpa, int dir, int df, void *p_data); +int hvmemul_do_vmport(struct cpu_user_regs *regs); + #endif /* __ASM_X86_HVM_EMULATE_H__ */ diff --git a/xen/include/asm-x86/hvm/vcpu.h b/xen/include/asm-x86/hvm/vcpu.h index 01e0665..1e63d7f 100644 --- a/xen/include/asm-x86/hvm/vcpu.h +++ b/xen/include/asm-x86/hvm/vcpu.h @@ -36,6 +36,7 @@ enum hvm_io_state { HVMIO_awaiting_completion, HVMIO_handle_mmio_awaiting_completion, HVMIO_handle_pio_awaiting_completion, + HVMIO_handle_vmport_awaiting_completion, HVMIO_completed }; diff --git a/xen/include/public/hvm/ioreq.h b/xen/include/public/hvm/ioreq.h index 5b5fedf..ddb4cce 100644 --- a/xen/include/public/hvm/ioreq.h +++ b/xen/include/public/hvm/ioreq.h @@ -35,6 +35,7 @@ #define IOREQ_TYPE_PIO 0 /* pio */ #define IOREQ_TYPE_COPY 1 /* mmio ops */ #define IOREQ_TYPE_PCI_CONFIG 2 +#define IOREQ_TYPE_VMWARE_PORT 3 #define IOREQ_TYPE_TIMEOFFSET 7 #define IOREQ_TYPE_INVALIDATE 8 /* mapcache */ @@ -48,6 +49,10 @@ * * 63....48|47..40|39..35|34..32|31........0 * SEGMENT |BUS |DEV |FN |OFFSET + * + * For I/O type IOREQ_TYPE_VMWARE_PORT the 4 fields addr, data, + * count and size are used to transport the 32bit parts of eax, ebx, + * ecx, edx, esi, and edi. */ struct ioreq { uint64_t addr; /* physical address */ -- 1.8.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |