[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v5 14/16] x86/hvm: use ioreq_t to track in-flight state
Use an ioreq_t rather than open coded state, size, dir and data fields in struct hvm_vcpu_io. This also allows PIO completion to be handled similarly to MMIO completion by re-issuing the handle_pio() call. Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> Cc: Keir Fraser <keir@xxxxxxx> Cc: Jan Beulich <jbeulich@xxxxxxxx> Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- xen/arch/x86/hvm/emulate.c | 35 +++++++++++++++++++++-------------- xen/arch/x86/hvm/hvm.c | 13 +++++-------- xen/arch/x86/hvm/svm/nestedsvm.c | 2 +- xen/arch/x86/hvm/vmx/realmode.c | 4 ++-- xen/include/asm-x86/hvm/vcpu.h | 12 ++++-------- 5 files changed, 33 insertions(+), 33 deletions(-) diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c index 4c696d1..b5fb0da 100644 --- a/xen/arch/x86/hvm/emulate.c +++ b/xen/arch/x86/hvm/emulate.c @@ -91,6 +91,7 @@ static int hvmemul_do_io( .df = df, .data = data, .data_is_ptr = data_is_addr, /* ioreq_t field name is misleading */ + .state = STATE_IOREQ_READY, }; void *p_data = (void *)data; int rc; @@ -128,12 +129,24 @@ static int hvmemul_do_io( } } - switch ( vio->io_state ) + switch ( vio->io_req.state ) { case STATE_IOREQ_NONE: break; case STATE_IORESP_READY: - vio->io_state = STATE_IOREQ_NONE; + vio->io_req.state = STATE_IOREQ_NONE; + p = vio->io_req; + + /* Verify the emulation request has been correctly re-issued */ + if ( (p.type != is_mmio ? IOREQ_TYPE_COPY : IOREQ_TYPE_PIO) || + (p.addr != addr) || + (p.size != size) || + (p.count != reps) || + (p.dir != dir) || + (p.df != df) || + (p.data_is_ptr != data_is_addr) ) + domain_crash(curr->domain); + if ( data_is_addr || dir == IOREQ_WRITE ) return X86EMUL_UNHANDLEABLE; goto finish_access; @@ -141,11 +154,6 @@ static int hvmemul_do_io( return X86EMUL_UNHANDLEABLE; } - vio->io_state = STATE_IOREQ_READY; - vio->io_size = size; - vio->io_dir = dir; - vio->io_data_is_addr = data_is_addr; - if ( dir == IOREQ_WRITE ) { if ( !data_is_addr ) @@ -154,13 +162,14 @@ static int hvmemul_do_io( hvmtrace_io_assist(&p); } + vio->io_req = p; + rc = hvm_io_intercept(&p); switch ( rc ) { case X86EMUL_OKAY: - vio->io_data = p.data; - vio->io_state = STATE_IOREQ_NONE; + vio->io_req.state = STATE_IOREQ_NONE; break; case X86EMUL_UNHANDLEABLE: { @@ -171,15 +180,13 @@ static int hvmemul_do_io( if ( !s ) { rc = hvm_process_io_intercept(&null_handler, &p); - if ( rc == X86EMUL_OKAY ) - vio->io_data = p.data; - vio->io_state = STATE_IOREQ_NONE; + vio->io_req.state = STATE_IOREQ_NONE; } else { rc = hvm_send_assist_req(s, &p); if ( rc != X86EMUL_RETRY || curr->domain->is_shutting_down ) - vio->io_state = STATE_IOREQ_NONE; + vio->io_req.state = STATE_IOREQ_NONE; else if ( data_is_addr || dir == IOREQ_WRITE ) rc = X86EMUL_OKAY; } @@ -198,7 +205,7 @@ static int hvmemul_do_io( hvmtrace_io_assist(&p); if ( !data_is_addr ) - memcpy(p_data, &vio->io_data, size); + memcpy(p_data, &p.data, size); } if ( is_mmio && !data_is_addr ) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 32b0d32..901f9a8 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -421,11 +421,11 @@ static void hvm_io_assist(ioreq_t *p) if ( hvm_vcpu_io_need_completion(vio) ) { - vio->io_state = STATE_IORESP_READY; - vio->io_data = p->data; + vio->io_req.state = STATE_IORESP_READY; + vio->io_req.data = p->data; } else - vio->io_state = STATE_IOREQ_NONE; + vio->io_req.state = STATE_IOREQ_NONE; msix_write_completion(curr); vcpu_end_shutdown_deferral(curr); @@ -501,11 +501,8 @@ void hvm_do_resume(struct vcpu *v) (void)handle_mmio(); break; case HVMIO_pio_completion: - if ( vio->io_size == 4 ) /* Needs zero extension. */ - guest_cpu_user_regs()->rax = (uint32_t)vio->io_data; - else - memcpy(&guest_cpu_user_regs()->rax, &vio->io_data, vio->io_size); - vio->io_state = STATE_IOREQ_NONE; + (void)handle_pio(vio->io_req.addr, vio->io_req.size, + vio->io_req.dir); break; case HVMIO_realmode_completion: { diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c index 8b165c6..78667a2 100644 --- a/xen/arch/x86/hvm/svm/nestedsvm.c +++ b/xen/arch/x86/hvm/svm/nestedsvm.c @@ -1231,7 +1231,7 @@ enum hvm_intblk nsvm_intr_blocked(struct vcpu *v) * Delay the injection because this would result in delivering * an interrupt *within* the execution of an instruction. */ - if ( v->arch.hvm_vcpu.hvm_io.io_state != STATE_IOREQ_NONE ) + if ( v->arch.hvm_vcpu.hvm_io.io_req.state != STATE_IOREQ_NONE ) return hvm_intblk_shadow; if ( !nv->nv_vmexit_pending && n2vmcb->exitintinfo.bytes != 0 ) { diff --git a/xen/arch/x86/hvm/vmx/realmode.c b/xen/arch/x86/hvm/vmx/realmode.c index 25533dc..e83a61f 100644 --- a/xen/arch/x86/hvm/vmx/realmode.c +++ b/xen/arch/x86/hvm/vmx/realmode.c @@ -205,7 +205,7 @@ void vmx_realmode(struct cpu_user_regs *regs) vmx_realmode_emulate_one(&hvmemul_ctxt); - if ( vio->io_state != STATE_IOREQ_NONE || vio->mmio_retry ) + if ( vio->io_req.state != STATE_IOREQ_NONE || vio->mmio_retry ) break; /* Stop emulating unless our segment state is not safe */ @@ -219,7 +219,7 @@ void vmx_realmode(struct cpu_user_regs *regs) } /* Need to emulate next time if we've started an IO operation */ - if ( vio->io_state != STATE_IOREQ_NONE ) + if ( vio->io_req.state != STATE_IOREQ_NONE ) curr->arch.hvm_vmx.vmx_emulate = 1; if ( !curr->arch.hvm_vmx.vmx_emulate && !curr->arch.hvm_vmx.vmx_realmode ) diff --git a/xen/include/asm-x86/hvm/vcpu.h b/xen/include/asm-x86/hvm/vcpu.h index 9ca96d0..7ffa28a 100644 --- a/xen/include/asm-x86/hvm/vcpu.h +++ b/xen/include/asm-x86/hvm/vcpu.h @@ -44,12 +44,8 @@ struct hvm_vcpu_asid { struct hvm_vcpu_io { /* I/O request in flight to device model. */ - uint8_t io_state; - unsigned long io_data; - unsigned int io_size; + ioreq_t io_req; enum hvm_io_completion io_completion; - uint8_t io_dir; - uint8_t io_data_is_addr; /* * HVM emulation: @@ -84,9 +80,9 @@ struct hvm_vcpu_io { static inline bool_t hvm_vcpu_io_need_completion(const struct hvm_vcpu_io *vio) { - return (vio->io_state == STATE_IOREQ_READY) && - !vio->io_data_is_addr && - (vio->io_dir == IOREQ_READ); + return (vio->io_req.state == STATE_IOREQ_READY) && + !vio->io_req.data_is_ptr && + (vio->io_req.dir == IOREQ_READ); } #define VMCX_EADDR (~0ULL) -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |