diff options
author | Keir Fraser <keir@xen.org> | 2012-05-30 09:27:51 +0100 |
---|---|---|
committer | Keir Fraser <keir@xen.org> | 2012-05-30 09:27:51 +0100 |
commit | 284f43f4fd6dccfff3b72afded0be03b3fe45091 (patch) | |
tree | af609cd27c2e4854d0eac101a0a31907d7d42fbc /xen/arch/x86/hvm/svm | |
parent | de0e85188ca9e240e774f4598139ba92ee5ce4f8 (diff) | |
download | xen-284f43f4fd6dccfff3b72afded0be03b3fe45091.tar.gz xen-284f43f4fd6dccfff3b72afded0be03b3fe45091.tar.bz2 xen-284f43f4fd6dccfff3b72afded0be03b3fe45091.zip |
xen: Define new struct hvm_trap and cleanup vmx exception
Define new struct hvm_trap to represent information of trap, and
renames hvm_inject_exception to hvm_inject_trap, then define a couple
of wrappers around that function for existing callers.
Signed-off-by: Keir Fraser <keir@xen.org>
Signed-off-by: Xudong Hao <xudong.hao@intel.com>
Committed-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/arch/x86/hvm/svm')
-rw-r--r-- | xen/arch/x86/hvm/svm/emulate.c | 4 | ||||
-rw-r--r-- | xen/arch/x86/hvm/svm/nestedsvm.c | 16 | ||||
-rw-r--r-- | xen/arch/x86/hvm/svm/svm.c | 66 |
3 files changed, 45 insertions, 41 deletions
diff --git a/xen/arch/x86/hvm/svm/emulate.c b/xen/arch/x86/hvm/svm/emulate.c index 6000bffd53..0c72f00798 100644 --- a/xen/arch/x86/hvm/svm/emulate.c +++ b/xen/arch/x86/hvm/svm/emulate.c @@ -147,7 +147,7 @@ static int fetch(struct vcpu *v, u8 *buf, unsigned long addr, int len) /* Not OK: fetches from non-RAM pages are not supportable. */ gdprintk(XENLOG_WARNING, "Bad instruction fetch at %#lx (%#lx)\n", (unsigned long) guest_cpu_user_regs()->eip, addr); - hvm_inject_exception(TRAP_gp_fault, 0, 0); + hvm_inject_hw_exception(TRAP_gp_fault, 0); return 0; } return 1; @@ -216,7 +216,7 @@ int __get_instruction_length_from_list(struct vcpu *v, gdprintk(XENLOG_WARNING, "%s: Mismatch between expected and actual instruction bytes: " "eip = %lx\n", __func__, (unsigned long)vmcb->rip); - hvm_inject_exception(TRAP_gp_fault, 0, 0); + hvm_inject_hw_exception(TRAP_gp_fault, 0); return 0; done: diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c index 8714bb0d44..6ed32604cf 100644 --- a/xen/arch/x86/hvm/svm/nestedsvm.c +++ b/xen/arch/x86/hvm/svm/nestedsvm.c @@ -735,8 +735,8 @@ nsvm_vcpu_vmrun(struct vcpu *v, struct cpu_user_regs *regs) default: gdprintk(XENLOG_ERR, "nsvm_vcpu_vmentry failed, injecting #UD\n"); - hvm_inject_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE, 0); - /* Must happen after hvm_inject_exception or it doesn't work right. */ + hvm_inject_hw_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE); + /* Must happen after hvm_inject_hw_exception or it doesn't work right. */ nv->nv_vmswitch_in_progress = 0; return 1; } @@ -796,12 +796,12 @@ nsvm_vcpu_vmexit_inject(struct vcpu *v, struct cpu_user_regs *regs, } int -nsvm_vcpu_vmexit_trap(struct vcpu *v, unsigned int trapnr, - int errcode, unsigned long cr2) +nsvm_vcpu_vmexit_trap(struct vcpu *v, struct hvm_trap *trap) { ASSERT(vcpu_nestedhvm(v).nv_vvmcx != NULL); - nestedsvm_vmexit_defer(v, VMEXIT_EXCEPTION_DE + trapnr, errcode, cr2); + nestedsvm_vmexit_defer(v, VMEXIT_EXCEPTION_DE + trap->vector, + trap->error_code, trap->cr2); return NESTEDHVM_VMEXIT_DONE; } @@ -1176,7 +1176,7 @@ enum hvm_intblk nsvm_intr_blocked(struct vcpu *v) } if ( nv->nv_vmexit_pending ) { - /* hvm_inject_exception() must have run before. + /* hvm_inject_hw_exception() must have run before. * exceptions have higher priority than interrupts. */ return hvm_intblk_rflags_ie; @@ -1509,7 +1509,7 @@ void svm_vmexit_do_stgi(struct cpu_user_regs *regs, struct vcpu *v) unsigned int inst_len; if ( !nestedhvm_enabled(v->domain) ) { - hvm_inject_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE, 0); + hvm_inject_hw_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE); return; } @@ -1529,7 +1529,7 @@ void svm_vmexit_do_clgi(struct cpu_user_regs *regs, struct vcpu *v) vintr_t intr; if ( !nestedhvm_enabled(v->domain) ) { - hvm_inject_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE, 0); + hvm_inject_hw_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE); return; } diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index e717dda8dd..e568e33815 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -109,7 +109,7 @@ void __update_guest_eip(struct cpu_user_regs *regs, unsigned int inst_len) curr->arch.hvm_svm.vmcb->interrupt_shadow = 0; if ( regs->eflags & X86_EFLAGS_TF ) - hvm_inject_exception(TRAP_debug, HVM_DELIVER_NO_ERROR_CODE, 0); + hvm_inject_hw_exception(TRAP_debug, HVM_DELIVER_NO_ERROR_CODE); } static void svm_cpu_down(void) @@ -1066,14 +1066,14 @@ static void svm_vcpu_destroy(struct vcpu *v) passive_domain_destroy(v); } -static void svm_inject_exception( - unsigned int trapnr, int errcode, unsigned long cr2) +static void svm_inject_trap(struct hvm_trap *trap) { struct vcpu *curr = current; struct vmcb_struct *vmcb = curr->arch.hvm_svm.vmcb; eventinj_t event = vmcb->eventinj; + struct hvm_trap _trap = *trap; - switch ( trapnr ) + switch ( _trap.vector ) { case TRAP_debug: if ( guest_cpu_user_regs()->eflags & X86_EFLAGS_TF ) @@ -1081,6 +1081,9 @@ static void svm_inject_exception( __restore_debug_registers(curr); vmcb_set_dr6(vmcb, vmcb_get_dr6(vmcb) | 0x4000); } + if ( cpu_has_monitor_trap_flag ) + break; + /* fall through */ case TRAP_int3: if ( curr->domain->debugger_attached ) { @@ -1093,29 +1096,30 @@ static void svm_inject_exception( if ( unlikely(event.fields.v) && (event.fields.type == X86_EVENTTYPE_HW_EXCEPTION) ) { - trapnr = hvm_combine_hw_exceptions(event.fields.vector, trapnr); - if ( trapnr == TRAP_double_fault ) - errcode = 0; + _trap.vector = hvm_combine_hw_exceptions( + event.fields.vector, _trap.vector); + if ( _trap.vector == TRAP_double_fault ) + _trap.error_code = 0; } event.bytes = 0; event.fields.v = 1; event.fields.type = X86_EVENTTYPE_HW_EXCEPTION; - event.fields.vector = trapnr; - event.fields.ev = (errcode != HVM_DELIVER_NO_ERROR_CODE); - event.fields.errorcode = errcode; + event.fields.vector = _trap.vector; + event.fields.ev = (_trap.error_code != HVM_DELIVER_NO_ERROR_CODE); + event.fields.errorcode = _trap.error_code; vmcb->eventinj = event; - if ( trapnr == TRAP_page_fault ) + if ( _trap.vector == TRAP_page_fault ) { - curr->arch.hvm_vcpu.guest_cr[2] = cr2; - vmcb_set_cr2(vmcb, cr2); - HVMTRACE_LONG_2D(PF_INJECT, errcode, TRC_PAR_LONG(cr2)); + curr->arch.hvm_vcpu.guest_cr[2] = _trap.cr2; + vmcb_set_cr2(vmcb, _trap.cr2); + HVMTRACE_LONG_2D(PF_INJECT, _trap.error_code, TRC_PAR_LONG(_trap.cr2)); } else { - HVMTRACE_2D(INJ_EXC, trapnr, errcode); + HVMTRACE_2D(INJ_EXC, _trap.vector, _trap.error_code); } } @@ -1361,7 +1365,7 @@ static void svm_fpu_dirty_intercept(void) { /* Check if l1 guest must make FPU ready for the l2 guest */ if ( v->arch.hvm_vcpu.guest_cr[0] & X86_CR0_TS ) - hvm_inject_exception(TRAP_no_device, HVM_DELIVER_NO_ERROR_CODE, 0); + hvm_inject_hw_exception(TRAP_no_device, HVM_DELIVER_NO_ERROR_CODE); else vmcb_set_cr0(n1vmcb, vmcb_get_cr0(n1vmcb) & ~X86_CR0_TS); return; @@ -1579,7 +1583,7 @@ static int svm_msr_read_intercept(unsigned int msr, uint64_t *msr_content) return X86EMUL_OKAY; gpf: - hvm_inject_exception(TRAP_gp_fault, 0, 0); + hvm_inject_hw_exception(TRAP_gp_fault, 0); return X86EMUL_EXCEPTION; } @@ -1708,7 +1712,7 @@ static int svm_msr_write_intercept(unsigned int msr, uint64_t msr_content) return X86EMUL_OKAY; gpf: - hvm_inject_exception(TRAP_gp_fault, 0, 0); + hvm_inject_hw_exception(TRAP_gp_fault, 0); return X86EMUL_EXCEPTION; } @@ -1784,13 +1788,13 @@ svm_vmexit_do_vmrun(struct cpu_user_regs *regs, { if (!nestedhvm_enabled(v->domain)) { gdprintk(XENLOG_ERR, "VMRUN: nestedhvm disabled, injecting #UD\n"); - hvm_inject_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE, 0); + hvm_inject_hw_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE); return; } if (!nestedsvm_vmcb_map(v, vmcbaddr)) { gdprintk(XENLOG_ERR, "VMRUN: mapping vmcb failed, injecting #UD\n"); - hvm_inject_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE, 0); + hvm_inject_hw_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE); return; } @@ -1830,7 +1834,7 @@ svm_vmexit_do_vmload(struct vmcb_struct *vmcb, return; inject: - hvm_inject_exception(ret, HVM_DELIVER_NO_ERROR_CODE, 0); + hvm_inject_hw_exception(ret, HVM_DELIVER_NO_ERROR_CODE); return; } @@ -1864,7 +1868,7 @@ svm_vmexit_do_vmsave(struct vmcb_struct *vmcb, return; inject: - hvm_inject_exception(ret, HVM_DELIVER_NO_ERROR_CODE, 0); + hvm_inject_hw_exception(ret, HVM_DELIVER_NO_ERROR_CODE); return; } @@ -1880,11 +1884,11 @@ static void svm_vmexit_ud_intercept(struct cpu_user_regs *regs) switch ( rc ) { case X86EMUL_UNHANDLEABLE: - hvm_inject_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE, 0); + hvm_inject_hw_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE); break; case X86EMUL_EXCEPTION: if ( ctxt.exn_pending ) - hvm_inject_exception(ctxt.exn_vector, ctxt.exn_error_code, 0); + hvm_inject_hw_exception(ctxt.exn_vector, ctxt.exn_error_code); /* fall through */ default: hvm_emulate_writeback(&ctxt); @@ -1998,7 +2002,7 @@ static struct hvm_function_table __read_mostly svm_function_table = { .set_guest_pat = svm_set_guest_pat, .get_guest_pat = svm_get_guest_pat, .set_tsc_offset = svm_set_tsc_offset, - .inject_exception = svm_inject_exception, + .inject_trap = svm_inject_trap, .init_hypercall_page = svm_init_hypercall_page, .event_pending = svm_event_pending, .do_pmu_interrupt = svm_do_pmu_interrupt, @@ -2212,7 +2216,7 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) break; } - hvm_inject_exception(TRAP_page_fault, regs->error_code, va); + hvm_inject_page_fault(regs->error_code, va); break; } @@ -2285,7 +2289,7 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) __update_guest_eip(regs, vmcb->exitinfo2 - vmcb->rip); } else if ( !handle_mmio() ) - hvm_inject_exception(TRAP_gp_fault, 0, 0); + hvm_inject_hw_exception(TRAP_gp_fault, 0); break; case VMEXIT_CR0_READ ... VMEXIT_CR15_READ: @@ -2293,7 +2297,7 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) if ( cpu_has_svm_decode && (vmcb->exitinfo1 & (1ULL << 63)) ) svm_vmexit_do_cr_access(vmcb, regs); else if ( !handle_mmio() ) - hvm_inject_exception(TRAP_gp_fault, 0, 0); + hvm_inject_hw_exception(TRAP_gp_fault, 0); break; case VMEXIT_INVLPG: @@ -2303,7 +2307,7 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) __update_guest_eip(regs, vmcb->nextrip - vmcb->rip); } else if ( !handle_mmio() ) - hvm_inject_exception(TRAP_gp_fault, 0, 0); + hvm_inject_hw_exception(TRAP_gp_fault, 0); break; case VMEXIT_INVLPGA: @@ -2349,7 +2353,7 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) case VMEXIT_MONITOR: case VMEXIT_MWAIT: - hvm_inject_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE, 0); + hvm_inject_hw_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE); break; case VMEXIT_VMRUN: @@ -2368,7 +2372,7 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) svm_vmexit_do_clgi(regs, v); break; case VMEXIT_SKINIT: - hvm_inject_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE, 0); + hvm_inject_hw_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE); break; case VMEXIT_XSETBV: |