* [PATCH 0/3] XEN: fix vmx exception mistake
@ 2012-05-24 19:06 Xudong Hao
2012-05-24 19:06 ` [PATCH 1/3] xen: Add instruction length parameter in function hvm_inject_exception Xudong Hao
2012-05-24 19:06 ` [PATCH 2/3] VMX: Fix the mistake of exception execution Xudong Hao
0 siblings, 2 replies; 12+ messages in thread
From: Xudong Hao @ 2012-05-24 19:06 UTC (permalink / raw)
To: JBeulich; +Cc: aravindh, keir.xen, eddie.dong, Ian.Jackson, xen-devel
This series of patches fix the mistake for debug exception(#DB), overflow
exception(#OF) and INT3(#BP), INTn instruction emulation.
Introduce new function vmx_inject_sw_exception() which deliver the software
excetion, software interrupt and privileged software exception. Split hardware
exception as a seperate function(old function vmx_inject_hw_exception()).
Also Passed down intruction length to exception emulation handler function.
And supply a interface for userspace to inject trap.
PATCH 1: Pass the instruction length field down to exception emulation,
by changing hypercall parameter and adding a parameter in fucntion
hvm_inject_exception(), so that exception emulation can set correct
instruction length.
PATCH 2: Fix the mistake for debug exception(#DB), overflow exception(#OF) and
INT3(#BP), INTn instruction emulation.
Introduce new function vmx_inject_sw_exception() which deliver the software
excetion, software interrupt and privileged software exception. Split hardware
exception as a seperate function(old function vmx_inject_hw_exception()).
PATCH 3: Add a parameter to represent instruction length in function
xc_hvm_inject_trap(), user should set this value when this
function is called.
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/3] xen: Add instruction length parameter in function hvm_inject_exception
2012-05-24 19:06 [PATCH 0/3] XEN: fix vmx exception mistake Xudong Hao
@ 2012-05-24 19:06 ` Xudong Hao
2012-05-25 8:53 ` Keir Fraser
2012-05-24 19:06 ` [PATCH 2/3] VMX: Fix the mistake of exception execution Xudong Hao
1 sibling, 1 reply; 12+ messages in thread
From: Xudong Hao @ 2012-05-24 19:06 UTC (permalink / raw)
To: JBeulich
Cc: aravindh, eddie.dong, xen-devel, keir.xen, Xudong Hao,
Ian.Jackson, Xiantao Zhang
VMX exception: Pass the instruction length field down to exception emulation,
by changing hypercall parameter and adding a parameter in fucntion
hvm_inject_exception(), so that exception emulation can set correct
instruction length.
Signed-off-by: Xudong Hao <xudong.hao@intel.com>
Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
---
xen/arch/x86/hvm/emulate.c | 4 +-
xen/arch/x86/hvm/hvm.c | 40 +++++++++++++++++++------------------
xen/arch/x86/hvm/io.c | 2 +-
xen/arch/x86/hvm/svm/emulate.c | 4 +-
xen/arch/x86/hvm/svm/nestedsvm.c | 6 ++--
xen/arch/x86/hvm/svm/svm.c | 34 ++++++++++++++++----------------
xen/arch/x86/hvm/vmx/vmx.c | 2 +-
xen/arch/x86/hvm/vmx/vvmx.c | 6 ++--
xen/arch/x86/mm/shadow/common.c | 2 +-
xen/arch/x86/mm/shadow/multi.c | 2 +-
xen/include/asm-x86/hvm/hvm.h | 4 +-
xen/include/asm-x86/hvm/vcpu.h | 1 +
xen/include/public/hvm/hvm_op.h | 2 +
13 files changed, 57 insertions(+), 52 deletions(-)
diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
index 2b50670..b6d1984 100644
--- a/xen/arch/x86/hvm/emulate.c
+++ b/xen/arch/x86/hvm/emulate.c
@@ -326,7 +326,7 @@ static int hvmemul_linear_to_phys(
{
if ( pfec == PFEC_page_paged || pfec == PFEC_page_shared )
return X86EMUL_RETRY;
- hvm_inject_exception(TRAP_page_fault, pfec, addr);
+ hvm_inject_exception(TRAP_page_fault, 0, pfec, addr);
return X86EMUL_EXCEPTION;
}
@@ -349,7 +349,7 @@ static int hvmemul_linear_to_phys(
ASSERT(!reverse);
if ( npfn != INVALID_GFN )
return X86EMUL_UNHANDLEABLE;
- hvm_inject_exception(TRAP_page_fault, pfec, addr & PAGE_MASK);
+ hvm_inject_exception(TRAP_page_fault, 0, pfec, addr & PAGE_MASK);
return X86EMUL_EXCEPTION;
}
*reps = done;
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index efd5587..fa8b220 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -350,6 +350,7 @@ void hvm_do_resume(struct vcpu *v)
if (v->arch.hvm_vcpu.inject_trap != -1)
{
hvm_inject_exception(v->arch.hvm_vcpu.inject_trap,
+ v->arch.hvm_vcpu.instruction_len,
v->arch.hvm_vcpu.inject_error_code,
v->arch.hvm_vcpu.inject_cr2);
v->arch.hvm_vcpu.inject_trap = -1;
@@ -1194,7 +1195,7 @@ void hvm_triple_fault(void)
domain_shutdown(v->domain, SHUTDOWN_reboot);
}
-void hvm_inject_exception(unsigned int trapnr, int errcode, unsigned long cr2)
+void hvm_inject_exception(unsigned int trapnr, int inslen, int errcode, unsigned long cr2)
{
struct vcpu *curr = current;
@@ -1221,7 +1222,7 @@ void hvm_inject_exception(unsigned int trapnr, int errcode, unsigned long cr2)
}
}
- hvm_funcs.inject_exception(trapnr, errcode, cr2);
+ hvm_funcs.inject_exception(trapnr, inslen, errcode, cr2);
}
int hvm_hap_nested_page_fault(unsigned long gpa,
@@ -1270,7 +1271,7 @@ int hvm_hap_nested_page_fault(unsigned long gpa,
return -1;
case NESTEDHVM_PAGEFAULT_MMIO:
if ( !handle_mmio() )
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_exception(TRAP_gp_fault, 0, 0, 0);
return 1;
}
}
@@ -1337,7 +1338,7 @@ int hvm_hap_nested_page_fault(unsigned long gpa,
{
put_gfn(p2m->domain, gfn);
if ( !handle_mmio() )
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_exception(TRAP_gp_fault, 0, 0, 0);
rc = 1;
goto out;
}
@@ -1380,7 +1381,7 @@ int hvm_hap_nested_page_fault(unsigned long gpa,
{
gdprintk(XENLOG_WARNING,
"trying to write to read-only grant mapping\n");
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_exception(TRAP_gp_fault, 0, 0, 0);
rc = 1;
goto out_put_gfn;
}
@@ -1441,7 +1442,7 @@ int hvm_handle_xsetbv(u64 new_bv)
return 0;
err:
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_exception(TRAP_gp_fault, 0, 0, 0);
return -1;
}
@@ -1457,7 +1458,7 @@ int hvm_set_efer(uint64_t value)
{
gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
"EFER: 0x%"PRIx64"\n", value);
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_exception(TRAP_gp_fault, 0, 0, 0);
return X86EMUL_EXCEPTION;
}
@@ -1466,7 +1467,7 @@ int hvm_set_efer(uint64_t value)
{
gdprintk(XENLOG_WARNING,
"Trying to change EFER.LME with paging enabled\n");
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_exception(TRAP_gp_fault, 0, 0, 0);
return X86EMUL_EXCEPTION;
}
@@ -1722,7 +1723,7 @@ int hvm_set_cr0(unsigned long value)
return X86EMUL_OKAY;
gpf:
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_exception(TRAP_gp_fault, 0, 0, 0);
return X86EMUL_EXCEPTION;
}
@@ -1808,7 +1809,7 @@ int hvm_set_cr4(unsigned long value)
return X86EMUL_OKAY;
gpf:
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_exception(TRAP_gp_fault, 0, 0, 0);
return X86EMUL_EXCEPTION;
}
@@ -2104,7 +2105,7 @@ static int hvm_load_segment_selector(
unmap_and_fail:
hvm_unmap_entry(pdesc);
fail:
- hvm_inject_exception(fault_type, sel & 0xfffc, 0);
+ hvm_inject_exception(fault_type, 0, sel & 0xfffc, 0);
hvm_map_fail:
return 1;
}
@@ -2139,7 +2140,7 @@ void hvm_task_switch(
{
hvm_inject_exception((taskswitch_reason == TSW_iret) ?
TRAP_invalid_tss : TRAP_gp_fault,
- tss_sel & 0xfff8, 0);
+ 0, tss_sel & 0xfff8, 0);
goto out;
}
@@ -2164,7 +2165,7 @@ void hvm_task_switch(
if ( !tr.attr.fields.p )
{
- hvm_inject_exception(TRAP_no_segment, tss_sel & 0xfff8, 0);
+ hvm_inject_exception(TRAP_no_segment, 0, tss_sel & 0xfff8, 0);
goto out;
}
@@ -2172,13 +2173,13 @@ void hvm_task_switch(
{
hvm_inject_exception(
(taskswitch_reason == TSW_iret) ? TRAP_invalid_tss : TRAP_gp_fault,
- tss_sel & 0xfff8, 0);
+ 0, tss_sel & 0xfff8, 0);
goto out;
}
if ( tr.limit < (sizeof(tss)-1) )
{
- hvm_inject_exception(TRAP_invalid_tss, tss_sel & 0xfff8, 0);
+ hvm_inject_exception(TRAP_invalid_tss, 0, tss_sel & 0xfff8, 0);
goto out;
}
@@ -2283,7 +2284,7 @@ void hvm_task_switch(
goto out;
if ( (tss.trace & 1) && !exn_raised )
- hvm_inject_exception(TRAP_debug, tss_sel & 0xfff8, 0);
+ hvm_inject_exception(TRAP_debug, 0, tss_sel & 0xfff8, 0);
tr.attr.fields.type = 0xb; /* busy 32-bit tss */
hvm_set_segment_register(v, x86_seg_tr, &tr);
@@ -2362,7 +2363,7 @@ static enum hvm_copy_result __hvm_copy(
if ( pfec == PFEC_page_shared )
return HVMCOPY_gfn_shared;
if ( flags & HVMCOPY_fault )
- hvm_inject_exception(TRAP_page_fault, pfec, addr);
+ hvm_inject_exception(TRAP_page_fault, 0, pfec, addr);
return HVMCOPY_bad_gva_to_gfn;
}
}
@@ -2849,7 +2850,7 @@ int hvm_msr_read_intercept(unsigned int msr, uint64_t *msr_content)
return ret;
gp_fault:
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_exception(TRAP_gp_fault, 0, 0, 0);
ret = X86EMUL_EXCEPTION;
*msr_content = -1ull;
goto out;
@@ -2962,7 +2963,7 @@ int hvm_msr_write_intercept(unsigned int msr, uint64_t msr_content)
return ret;
gp_fault:
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_exception(TRAP_gp_fault, 0, 0, 0);
return X86EMUL_EXCEPTION;
}
@@ -4272,6 +4273,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
else
{
v->arch.hvm_vcpu.inject_trap = tr.trap;
+ v->arch.hvm_vcpu.instruction_len = tr.inslen;
v->arch.hvm_vcpu.inject_error_code = tr.error_code;
v->arch.hvm_vcpu.inject_cr2 = tr.cr2;
}
diff --git a/xen/arch/x86/hvm/io.c b/xen/arch/x86/hvm/io.c
index 41a2ede..bd856fd 100644
--- a/xen/arch/x86/hvm/io.c
+++ b/xen/arch/x86/hvm/io.c
@@ -200,7 +200,7 @@ int handle_mmio(void)
return 0;
case X86EMUL_EXCEPTION:
if ( ctxt.exn_pending )
- hvm_inject_exception(ctxt.exn_vector, ctxt.exn_error_code, 0);
+ hvm_inject_exception(ctxt.exn_vector, ctxt.exn_insn_len, ctxt.exn_error_code, 0);
break;
default:
break;
diff --git a/xen/arch/x86/hvm/svm/emulate.c b/xen/arch/x86/hvm/svm/emulate.c
index 6000bff..8b67f2f 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_exception(TRAP_gp_fault, 0, 0, 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_exception(TRAP_gp_fault, 0, 0, 0);
return 0;
done:
diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c
index 8714bb0..ac04f3b 100644
--- a/xen/arch/x86/hvm/svm/nestedsvm.c
+++ b/xen/arch/x86/hvm/svm/nestedsvm.c
@@ -735,7 +735,7 @@ 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);
+ hvm_inject_exception(TRAP_invalid_op, 0, HVM_DELIVER_NO_ERROR_CODE, 0);
/* Must happen after hvm_inject_exception or it doesn't work right. */
nv->nv_vmswitch_in_progress = 0;
return 1;
@@ -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_exception(TRAP_invalid_op, 0, HVM_DELIVER_NO_ERROR_CODE, 0);
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_exception(TRAP_invalid_op, 0, HVM_DELIVER_NO_ERROR_CODE, 0);
return;
}
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index e717dda..87fb8a1 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_exception(TRAP_debug, 0, HVM_DELIVER_NO_ERROR_CODE, 0);
}
static void svm_cpu_down(void)
@@ -1067,7 +1067,7 @@ static void svm_vcpu_destroy(struct vcpu *v)
}
static void svm_inject_exception(
- unsigned int trapnr, int errcode, unsigned long cr2)
+ unsigned int trapnr, int inslen, int errcode, unsigned long cr2)
{
struct vcpu *curr = current;
struct vmcb_struct *vmcb = curr->arch.hvm_svm.vmcb;
@@ -1361,7 +1361,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_exception(TRAP_no_device, 0, HVM_DELIVER_NO_ERROR_CODE, 0);
else
vmcb_set_cr0(n1vmcb, vmcb_get_cr0(n1vmcb) & ~X86_CR0_TS);
return;
@@ -1579,7 +1579,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_exception(TRAP_gp_fault, 0, 0, 0);
return X86EMUL_EXCEPTION;
}
@@ -1708,7 +1708,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_exception(TRAP_gp_fault, 0, 0, 0);
return X86EMUL_EXCEPTION;
}
@@ -1784,13 +1784,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_exception(TRAP_invalid_op, 0, HVM_DELIVER_NO_ERROR_CODE, 0);
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_exception(TRAP_invalid_op, 0, HVM_DELIVER_NO_ERROR_CODE, 0);
return;
}
@@ -1830,7 +1830,7 @@ svm_vmexit_do_vmload(struct vmcb_struct *vmcb,
return;
inject:
- hvm_inject_exception(ret, HVM_DELIVER_NO_ERROR_CODE, 0);
+ hvm_inject_exception(ret, 0, HVM_DELIVER_NO_ERROR_CODE, 0);
return;
}
@@ -1864,7 +1864,7 @@ svm_vmexit_do_vmsave(struct vmcb_struct *vmcb,
return;
inject:
- hvm_inject_exception(ret, HVM_DELIVER_NO_ERROR_CODE, 0);
+ hvm_inject_exception(ret, 0, HVM_DELIVER_NO_ERROR_CODE, 0);
return;
}
@@ -1880,11 +1880,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_exception(TRAP_invalid_op, 0, HVM_DELIVER_NO_ERROR_CODE, 0);
break;
case X86EMUL_EXCEPTION:
if ( ctxt.exn_pending )
- hvm_inject_exception(ctxt.exn_vector, ctxt.exn_error_code, 0);
+ hvm_inject_exception(ctxt.exn_vector, ctxt.exn_insn_len, ctxt.exn_error_code, 0);
/* fall through */
default:
hvm_emulate_writeback(&ctxt);
@@ -2212,7 +2212,7 @@ void svm_vmexit_handler(struct cpu_user_regs *regs)
break;
}
- hvm_inject_exception(TRAP_page_fault, regs->error_code, va);
+ hvm_inject_exception(TRAP_page_fault, 0, regs->error_code, va);
break;
}
@@ -2285,7 +2285,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_exception(TRAP_gp_fault, 0, 0, 0);
break;
case VMEXIT_CR0_READ ... VMEXIT_CR15_READ:
@@ -2293,7 +2293,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_exception(TRAP_gp_fault, 0, 0, 0);
break;
case VMEXIT_INVLPG:
@@ -2303,7 +2303,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_exception(TRAP_gp_fault, 0, 0, 0);
break;
case VMEXIT_INVLPGA:
@@ -2349,7 +2349,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_exception(TRAP_invalid_op, 0, HVM_DELIVER_NO_ERROR_CODE, 0);
break;
case VMEXIT_VMRUN:
@@ -2368,7 +2368,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_exception(TRAP_invalid_op, 0, HVM_DELIVER_NO_ERROR_CODE, 0);
break;
case VMEXIT_XSETBV:
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index d5cb279..e15b7a4 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -2226,7 +2226,7 @@ static void vmx_vmexit_ud_intercept(struct cpu_user_regs *regs)
break;
case X86EMUL_EXCEPTION:
if ( ctxt.exn_pending )
- hvm_inject_exception(ctxt.exn_vector, ctxt.exn_error_code, 0);
+ hvm_inject_exception(ctxt.exn_vector, ctxt.exn_insn_len, ctxt.exn_error_code, 0);
/* fall through */
default:
hvm_emulate_writeback(&ctxt);
diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c
index b0ae0ee..6a55edb 100644
--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -304,12 +304,12 @@ vmexit:
invalid_op:
gdprintk(XENLOG_ERR, "vmx_inst_check_privilege: invalid_op\n");
- hvm_inject_exception(TRAP_invalid_op, 0, 0);
+ hvm_inject_exception(TRAP_invalid_op, 0, 0, 0);
return X86EMUL_EXCEPTION;
gp_fault:
gdprintk(XENLOG_ERR, "vmx_inst_check_privilege: gp_fault\n");
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_exception(TRAP_gp_fault, 0, 0, 0);
return X86EMUL_EXCEPTION;
}
@@ -386,7 +386,7 @@ static int decode_vmx_inst(struct cpu_user_regs *regs,
return X86EMUL_OKAY;
gp_fault:
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_exception(TRAP_gp_fault, 0, 0, 0);
return X86EMUL_EXCEPTION;
}
diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c
index 59be993..8b864d2 100644
--- a/xen/arch/x86/mm/shadow/common.c
+++ b/xen/arch/x86/mm/shadow/common.c
@@ -135,7 +135,7 @@ static int hvm_translate_linear_addr(
if ( !okay )
{
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_exception(TRAP_gp_fault, 0, 0, 0);
return X86EMUL_EXCEPTION;
}
diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c
index 9368385..199bd85 100644
--- a/xen/arch/x86/mm/shadow/multi.c
+++ b/xen/arch/x86/mm/shadow/multi.c
@@ -4825,7 +4825,7 @@ static mfn_t emulate_gva_to_mfn(struct vcpu *v,
if ( gfn == INVALID_GFN )
{
if ( is_hvm_vcpu(v) )
- hvm_inject_exception(TRAP_page_fault, pfec, vaddr);
+ hvm_inject_exception(TRAP_page_fault, 0, pfec, vaddr);
else
propagate_page_fault(vaddr, pfec);
return _mfn(BAD_GVA_TO_GFN);
diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h
index 22f9451..3ba1615 100644
--- a/xen/include/asm-x86/hvm/hvm.h
+++ b/xen/include/asm-x86/hvm/hvm.h
@@ -124,7 +124,7 @@ struct hvm_function_table {
void (*set_tsc_offset)(struct vcpu *v, u64 offset);
- void (*inject_exception)(unsigned int trapnr, int errcode,
+ void (*inject_exception)(unsigned int trapnr, int inslen, int errcode,
unsigned long cr2);
void (*init_hypercall_page)(struct domain *d, void *hypercall_page);
@@ -320,7 +320,7 @@ void hvm_migrate_timers(struct vcpu *v);
void hvm_do_resume(struct vcpu *v);
void hvm_migrate_pirqs(struct vcpu *v);
-void hvm_inject_exception(unsigned int trapnr, int errcode, unsigned long cr2);
+void hvm_inject_exception(unsigned int trapnr, int inslen, int errcode, unsigned long cr2);
static inline int hvm_event_pending(struct vcpu *v)
{
diff --git a/xen/include/asm-x86/hvm/vcpu.h b/xen/include/asm-x86/hvm/vcpu.h
index 537da96..c325fd1 100644
--- a/xen/include/asm-x86/hvm/vcpu.h
+++ b/xen/include/asm-x86/hvm/vcpu.h
@@ -166,6 +166,7 @@ struct hvm_vcpu {
void *fpu_exception_callback_arg;
/* Pending hw/sw interrupt */
int inject_trap; /* -1 for nothing to inject */
+ int instruction_len;
int inject_error_code;
unsigned long inject_cr2;
diff --git a/xen/include/public/hvm/hvm_op.h b/xen/include/public/hvm/hvm_op.h
index 6a78f75..4bafd88 100644
--- a/xen/include/public/hvm/hvm_op.h
+++ b/xen/include/public/hvm/hvm_op.h
@@ -219,6 +219,8 @@ struct xen_hvm_inject_trap {
uint32_t vcpuid;
/* Trap number */
uint32_t trap;
+ /* Intruction length */
+ uint32_t inslen;
/* Error code, or -1 to skip */
uint32_t error_code;
/* CR2 for page faults */
--
1.5.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/3] VMX: Fix the mistake of exception execution
2012-05-24 19:06 [PATCH 0/3] XEN: fix vmx exception mistake Xudong Hao
2012-05-24 19:06 ` [PATCH 1/3] xen: Add instruction length parameter in function hvm_inject_exception Xudong Hao
@ 2012-05-24 19:06 ` Xudong Hao
1 sibling, 0 replies; 12+ messages in thread
From: Xudong Hao @ 2012-05-24 19:06 UTC (permalink / raw)
To: JBeulich
Cc: aravindh, eddie.dong, xen-devel, keir.xen, Xudong Hao,
Ian.Jackson, Xiantao Zhang
Fix the mistake for debug exception(#DB), overflow exception(#OF) and
INT3(#BP), INTn instruction emulation.
Introduce new function vmx_inject_sw_exception() which deliver the software
excetion, software interrupt and privileged software exception. Split hardware
exception as a seperate function(old function vmx_inject_hw_exception()).
According to instruction length, to distinguish INT3 is generated by opcode
'CC' or 'CD ib =3', so do INTO and #DB(debug exception).
Note:
* For INTn (CD ib), it should use type 4 (software interrupt).
* For INT3 (CC; NOT CD ib with ib=3) and INTO (CE; NOT CD ib with ib=4),
it should use type 6 (software exception).
* For other exceptions (#DE, #DB, #BR, #UD, #NM, #TS, #NP, #SS, #GP, #PF, #MF,
#AC, #MC, and #XM), it should use type 3 (hardware exception).
* In the unlikely event that you are emulating the undocumented opcode F1
(informally called INT1 or ICEBP), it would use type 5 (privileged software
exception).
Signed-off-by: Xudong Hao <xudong.hao@intel.com>
Signed-off-by: Eddie Dong <eddie.dong@intel.com>
Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
---
xen/arch/x86/hvm/vmx/vmx.c | 141 +++++++++++++++++++++++++++++++------
xen/include/asm-x86/hvm/hvm.h | 1 +
xen/include/asm-x86/hvm/vmx/vmx.h | 1 +
3 files changed, 122 insertions(+), 21 deletions(-)
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index e15b7a4..8d78ffa 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -1344,12 +1344,27 @@ static void __vmx_inject_exception(int trap, int type, int error_code)
curr->arch.hvm_vmx.vmx_emulate = 1;
}
-void vmx_inject_hw_exception(int trap, int error_code)
+/*
+ * Generate the virtual event to guest.
+ * NOTE:
+ * This is for processor execution generated exceptions,
+ * and handle all software exception/interrupt, which include:
+ * - INT 3(CC), INTO (CE) instruction emulation, which should
+ * use X86_EVENTTYPE_SW_EXCEPTION;
+ * - INT nn (CD nn) instruction emulation, which should use
+ * X86_EVENTTYPE_SW_INTERRUPT as interrupt type;
+ * - opcode 0xf1 generated #DB should use privileged software
+ * exception.
+ *
+ * The caller of this function should set correct instruction
+ * length.
+ */
+void vmx_inject_sw_exception(int trap, int inslen, int error_code)
{
unsigned long intr_info;
struct vcpu *curr = current;
- int type = X86_EVENTTYPE_HW_EXCEPTION;
+ int type = X86_EVENTTYPE_SW_EXCEPTION;
if ( nestedhvm_vcpu_in_guestmode(curr) )
intr_info = vcpu_2_nvmx(curr).intr.intr_info;
@@ -1358,17 +1373,6 @@ void vmx_inject_hw_exception(int trap, int error_code)
switch ( trap )
{
- case TRAP_debug:
- type = X86_EVENTTYPE_SW_EXCEPTION;
- if ( guest_cpu_user_regs()->eflags & X86_EFLAGS_TF )
- {
- __restore_debug_registers(curr);
- write_debugreg(6, read_debugreg(6) | 0x4000);
- }
- if ( cpu_has_monitor_trap_flag )
- break;
- /* fall through */
-
case TRAP_int3:
if ( curr->domain->debugger_attached )
{
@@ -1377,16 +1381,75 @@ void vmx_inject_hw_exception(int trap, int error_code)
return;
}
- type = X86_EVENTTYPE_SW_EXCEPTION;
- __vmwrite(VM_ENTRY_INSTRUCTION_LEN, 1); /* int3 */
+ if ( inslen == 2 )
+ type = X86_EVENTTYPE_SW_INTERRUPT; /* CD ib with ib=3 */
+ break;
+
+ case TRAP_overflow:
+ if ( inslen == 2 )
+ type = X86_EVENTTYPE_SW_INTERRUPT; /* CD ib with ib=4 */
+ break;
+
+ case TRAP_debug:
+ /* Handle DB generated by 0xf1 */
+ type = X86_EVENTTYPE_PRI_SW_EXCEPTION;
break;
default:
- if ( trap > TRAP_last_reserved )
+ if ( trap > TRAP_last_reserved ) /* int imm8 */
+ {
+ type = X86_EVENTTYPE_SW_INTERRUPT;
+ }
+ break;
+
+ __vmwrite(VM_ENTRY_INSTRUCTION_LEN, inslen);
+
+ }
+
+ if ( nestedhvm_vcpu_in_guestmode(curr) &&
+ nvmx_intercepts_exception(curr, trap, error_code) )
+ {
+ nvmx_enqueue_n2_exceptions (curr,
+ INTR_INFO_VALID_MASK | (type<<8) | trap,
+ error_code);
+ return;
+ }
+ else
+ __vmx_inject_exception(trap, type, error_code);
+
+ HVMTRACE_2D(INJ_EXC, trap, error_code);
+}
+
+/*
+ * Generate the virtual event to guest.
+ * NOTE:
+ * This is only for hardware exceptions type delivery.
+ */
+void vmx_inject_hw_exception(int trap, int error_code)
+{
+ unsigned long intr_info;
+ struct vcpu *curr = current;
+
+ int type = X86_EVENTTYPE_HW_EXCEPTION;
+
+ if ( nestedhvm_vcpu_in_guestmode(curr) )
+ intr_info = vcpu_2_nvmx(curr).intr.intr_info;
+ else
+ intr_info = __vmread(VM_ENTRY_INTR_INFO);
+
+ switch ( trap )
+ {
+ case TRAP_debug:
+ if ( guest_cpu_user_regs()->eflags & X86_EFLAGS_TF )
{
- type = X86_EVENTTYPE_SW_EXCEPTION;
- __vmwrite(VM_ENTRY_INSTRUCTION_LEN, 2); /* int imm8 */
+ __restore_debug_registers(curr);
+ write_debugreg(6, read_debugreg(6) | 0x4000);
}
+ if ( cpu_has_monitor_trap_flag )
+ break;
+ /* fall through */
+
+ default:
break;
}
@@ -1455,12 +1518,47 @@ void vmx_inject_nmi(void)
}
static void vmx_inject_exception(
- unsigned int trapnr, int errcode, unsigned long cr2)
+ unsigned int trapnr, int inslen, int errcode, unsigned long cr2)
{
if ( trapnr == TRAP_page_fault )
current->arch.hvm_vcpu.guest_cr[2] = cr2;
- vmx_inject_hw_exception(trapnr, errcode);
+ switch(trapnr)
+ {
+ case TRAP_divide_error:
+ case TRAP_bounds:
+ case TRAP_invalid_op:
+ case TRAP_no_device:
+ case TRAP_invalid_tss:
+ case TRAP_no_segment:
+ case TRAP_stack_error:
+ case TRAP_gp_fault:
+ case TRAP_page_fault:
+ case TRAP_copro_error:
+ case TRAP_alignment_check:
+ case TRAP_machine_check:
+ case TRAP_simd_error:
+ vmx_inject_hw_exception(trapnr, errcode);
+ break;
+
+ case TRAP_debug:
+ if ( inslen != 0 )
+ /* icebp: opcode 0xf1 generate #DB, should be a privileged
+ * software exception */
+ vmx_inject_sw_exception(trapnr, inslen, errcode);
+ else
+ vmx_inject_hw_exception(trapnr, errcode);
+ break;
+
+ case TRAP_int3:
+ case TRAP_overflow:
+ vmx_inject_sw_exception(trapnr, inslen, errcode);
+ break;
+
+ default:
+ vmx_inject_sw_exception(trapnr, inslen, errcode);
+ break;
+ }
}
static int vmx_event_pending(struct vcpu *v)
@@ -2440,7 +2538,8 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
if ( handled < 0 )
{
- vmx_inject_exception(TRAP_int3, HVM_DELIVER_NO_ERROR_CODE, 0);
+ vmx_inject_exception(TRAP_int3,
+ __vmread(VM_EXIT_INSTRUCTION_LEN), HVM_DELIVER_NO_ERROR_CODE, 0);
break;
}
else if ( handled )
diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h
index 3ba1615..c65ad09 100644
--- a/xen/include/asm-x86/hvm/hvm.h
+++ b/xen/include/asm-x86/hvm/hvm.h
@@ -370,6 +370,7 @@ static inline int hvm_do_pmu_interrupt(struct cpu_user_regs *regs)
#define X86_EVENTTYPE_NMI 2 /* NMI */
#define X86_EVENTTYPE_HW_EXCEPTION 3 /* hardware exception */
#define X86_EVENTTYPE_SW_INTERRUPT 4 /* software interrupt */
+#define X86_EVENTTYPE_PRI_SW_EXCEPTION 5 /* privileged software exception */
#define X86_EVENTTYPE_SW_EXCEPTION 6 /* software exception */
int hvm_event_needs_reinjection(uint8_t type, uint8_t vector);
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h
index f003f84..61078a6 100644
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -387,6 +387,7 @@ static inline int __vmxon(u64 addr)
return rc;
}
+void vmx_inject_sw_exception(int trap, int inslen, int error_code);
void vmx_inject_hw_exception(int trap, int error_code);
void vmx_inject_extint(int trap);
void vmx_inject_nmi(void);
--
1.5.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] xen: Add instruction length parameter in function hvm_inject_exception
2012-05-24 19:06 ` [PATCH 1/3] xen: Add instruction length parameter in function hvm_inject_exception Xudong Hao
@ 2012-05-25 8:53 ` Keir Fraser
2012-05-25 19:17 ` Aravindh Puthiyaparambil
2012-05-28 6:24 ` Hao, Xudong
0 siblings, 2 replies; 12+ messages in thread
From: Keir Fraser @ 2012-05-25 8:53 UTC (permalink / raw)
To: Xudong Hao, JBeulich
Cc: Aravindh Puthiyaparambil, eddie.dong, Ian Jackson, Xiantao Zhang,
xen-devel
[-- Attachment #1: Type: text/plain, Size: 1097 bytes --]
On 24/05/2012 20:06, "Xudong Hao" <xudong.hao@intel.com> wrote:
> VMX exception: Pass the instruction length field down to exception emulation,
> by changing hypercall parameter and adding a parameter in fucntion
> hvm_inject_exception(), so that exception emulation can set correct
> instruction length.
>
> Signed-off-by: Xudong Hao <xudong.hao@intel.com>
> Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
I don't like adding yet another parameter for all callers, especially as we
should also be passing down the event type (sw interrupt, hw exception, ...)
and that would bloat the parameter list further.
I attach a cleanup patch which packs everything into a new struct and
renames hvm_inject_exception to hvm_inject_trap. I then define a couple of
wrappers around that function for existing callers, so that their parameter
lists actually *shrink*.
Let me know what you think. If it looks acceptable I can check it in and we
can build on top of this restructuring. The aim being to keep
hvm/vmx_inject_trap dumb, and push down the knowledge from the callers into
it.
-- Keir
[-- Attachment #2: 00-inject-cleanup --]
[-- Type: application/octet-stream, Size: 40010 bytes --]
diff -r 53e0571f94e4 xen/arch/x86/hvm/emulate.c
--- a/xen/arch/x86/hvm/emulate.c Fri May 25 08:21:25 2012 +0100
+++ b/xen/arch/x86/hvm/emulate.c Fri May 25 09:45:00 2012 +0100
@@ -326,7 +326,7 @@ static int hvmemul_linear_to_phys(
{
if ( pfec == PFEC_page_paged || pfec == PFEC_page_shared )
return X86EMUL_RETRY;
- hvm_inject_exception(TRAP_page_fault, pfec, addr);
+ hvm_inject_page_fault(pfec, addr);
return X86EMUL_EXCEPTION;
}
@@ -349,7 +349,7 @@ static int hvmemul_linear_to_phys(
ASSERT(!reverse);
if ( npfn != INVALID_GFN )
return X86EMUL_UNHANDLEABLE;
- hvm_inject_exception(TRAP_page_fault, pfec, addr & PAGE_MASK);
+ hvm_inject_page_fault(pfec, addr & PAGE_MASK);
return X86EMUL_EXCEPTION;
}
*reps = done;
diff -r 53e0571f94e4 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Fri May 25 08:21:25 2012 +0100
+++ b/xen/arch/x86/hvm/hvm.c Fri May 25 09:45:00 2012 +0100
@@ -347,12 +347,10 @@ void hvm_do_resume(struct vcpu *v)
}
/* Inject pending hw/sw trap */
- if (v->arch.hvm_vcpu.inject_trap != -1)
+ if ( v->arch.hvm_vcpu.inject_trap.vector != -1 )
{
- hvm_inject_exception(v->arch.hvm_vcpu.inject_trap,
- v->arch.hvm_vcpu.inject_error_code,
- v->arch.hvm_vcpu.inject_cr2);
- v->arch.hvm_vcpu.inject_trap = -1;
+ hvm_inject_trap(&v->arch.hvm_vcpu.inject_trap);
+ v->arch.hvm_vcpu.inject_trap.vector = -1;
}
}
@@ -1047,7 +1045,7 @@ int hvm_vcpu_initialise(struct vcpu *v)
spin_lock_init(&v->arch.hvm_vcpu.tm_lock);
INIT_LIST_HEAD(&v->arch.hvm_vcpu.tm_list);
- v->arch.hvm_vcpu.inject_trap = -1;
+ v->arch.hvm_vcpu.inject_trap.vector = -1;
#ifdef CONFIG_COMPAT
rc = setup_compat_arg_xlat(v);
@@ -1194,18 +1192,19 @@ void hvm_triple_fault(void)
domain_shutdown(v->domain, SHUTDOWN_reboot);
}
-void hvm_inject_exception(unsigned int trapnr, int errcode, unsigned long cr2)
+void hvm_inject_trap(struct hvm_trap *trap)
{
struct vcpu *curr = current;
if ( nestedhvm_enabled(curr->domain) &&
!nestedhvm_vmswitch_in_progress(curr) &&
nestedhvm_vcpu_in_guestmode(curr) &&
- nhvm_vmcx_guest_intercepts_trap(curr, trapnr, errcode) )
+ nhvm_vmcx_guest_intercepts_trap(
+ curr, trap->vector, trap->error_code) )
{
enum nestedhvm_vmexits nsret;
- nsret = nhvm_vcpu_vmexit_trap(curr, trapnr, errcode, cr2);
+ nsret = nhvm_vcpu_vmexit_trap(curr, trap);
switch ( nsret )
{
@@ -1221,7 +1220,26 @@ void hvm_inject_exception(unsigned int t
}
}
- hvm_funcs.inject_exception(trapnr, errcode, cr2);
+ hvm_funcs.inject_trap(trap);
+}
+
+void hvm_inject_hw_exception(unsigned int trapnr, int errcode)
+{
+ struct hvm_trap trap = {
+ .vector = trapnr,
+ .type = X86_EVENTTYPE_HW_EXCEPTION,
+ .error_code = errcode };
+ hvm_inject_trap(&trap);
+}
+
+void hvm_inject_page_fault(int errcode, unsigned long cr2)
+{
+ struct hvm_trap trap = {
+ .vector = TRAP_page_fault,
+ .type = X86_EVENTTYPE_HW_EXCEPTION,
+ .error_code = errcode,
+ .cr2 = cr2 };
+ hvm_inject_trap(&trap);
}
int hvm_hap_nested_page_fault(unsigned long gpa,
@@ -1270,7 +1288,7 @@ int hvm_hap_nested_page_fault(unsigned l
return -1;
case NESTEDHVM_PAGEFAULT_MMIO:
if ( !handle_mmio() )
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
return 1;
}
}
@@ -1337,7 +1355,7 @@ int hvm_hap_nested_page_fault(unsigned l
{
put_gfn(p2m->domain, gfn);
if ( !handle_mmio() )
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
rc = 1;
goto out;
}
@@ -1380,7 +1398,7 @@ int hvm_hap_nested_page_fault(unsigned l
{
gdprintk(XENLOG_WARNING,
"trying to write to read-only grant mapping\n");
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
rc = 1;
goto out_put_gfn;
}
@@ -1441,7 +1459,7 @@ int hvm_handle_xsetbv(u64 new_bv)
return 0;
err:
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
return -1;
}
@@ -1457,7 +1475,7 @@ int hvm_set_efer(uint64_t value)
{
gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
"EFER: 0x%"PRIx64"\n", value);
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
return X86EMUL_EXCEPTION;
}
@@ -1466,7 +1484,7 @@ int hvm_set_efer(uint64_t value)
{
gdprintk(XENLOG_WARNING,
"Trying to change EFER.LME with paging enabled\n");
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
return X86EMUL_EXCEPTION;
}
@@ -1722,7 +1740,7 @@ int hvm_set_cr0(unsigned long value)
return X86EMUL_OKAY;
gpf:
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
return X86EMUL_EXCEPTION;
}
@@ -1808,7 +1826,7 @@ int hvm_set_cr4(unsigned long value)
return X86EMUL_OKAY;
gpf:
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
return X86EMUL_EXCEPTION;
}
@@ -2104,7 +2122,7 @@ static int hvm_load_segment_selector(
unmap_and_fail:
hvm_unmap_entry(pdesc);
fail:
- hvm_inject_exception(fault_type, sel & 0xfffc, 0);
+ hvm_inject_hw_exception(fault_type, sel & 0xfffc);
hvm_map_fail:
return 1;
}
@@ -2137,9 +2155,9 @@ void hvm_task_switch(
if ( ((tss_sel & 0xfff8) + 7) > gdt.limit )
{
- hvm_inject_exception((taskswitch_reason == TSW_iret) ?
+ hvm_inject_hw_exception((taskswitch_reason == TSW_iret) ?
TRAP_invalid_tss : TRAP_gp_fault,
- tss_sel & 0xfff8, 0);
+ tss_sel & 0xfff8);
goto out;
}
@@ -2164,21 +2182,21 @@ void hvm_task_switch(
if ( !tr.attr.fields.p )
{
- hvm_inject_exception(TRAP_no_segment, tss_sel & 0xfff8, 0);
+ hvm_inject_hw_exception(TRAP_no_segment, tss_sel & 0xfff8);
goto out;
}
if ( tr.attr.fields.type != ((taskswitch_reason == TSW_iret) ? 0xb : 0x9) )
{
- hvm_inject_exception(
+ hvm_inject_hw_exception(
(taskswitch_reason == TSW_iret) ? TRAP_invalid_tss : TRAP_gp_fault,
- tss_sel & 0xfff8, 0);
+ tss_sel & 0xfff8);
goto out;
}
if ( tr.limit < (sizeof(tss)-1) )
{
- hvm_inject_exception(TRAP_invalid_tss, tss_sel & 0xfff8, 0);
+ hvm_inject_hw_exception(TRAP_invalid_tss, tss_sel & 0xfff8);
goto out;
}
@@ -2283,7 +2301,7 @@ void hvm_task_switch(
goto out;
if ( (tss.trace & 1) && !exn_raised )
- hvm_inject_exception(TRAP_debug, tss_sel & 0xfff8, 0);
+ hvm_inject_hw_exception(TRAP_debug, tss_sel & 0xfff8);
tr.attr.fields.type = 0xb; /* busy 32-bit tss */
hvm_set_segment_register(v, x86_seg_tr, &tr);
@@ -2362,7 +2380,7 @@ static enum hvm_copy_result __hvm_copy(
if ( pfec == PFEC_page_shared )
return HVMCOPY_gfn_shared;
if ( flags & HVMCOPY_fault )
- hvm_inject_exception(TRAP_page_fault, pfec, addr);
+ hvm_inject_page_fault(pfec, addr);
return HVMCOPY_bad_gva_to_gfn;
}
}
@@ -2849,7 +2867,7 @@ int hvm_msr_read_intercept(unsigned int
return ret;
gp_fault:
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
ret = X86EMUL_EXCEPTION;
*msr_content = -1ull;
goto out;
@@ -2962,7 +2980,7 @@ int hvm_msr_write_intercept(unsigned int
return ret;
gp_fault:
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
return X86EMUL_EXCEPTION;
}
@@ -4267,13 +4285,13 @@ long do_hvm_op(unsigned long op, XEN_GUE
if ( tr.vcpuid >= d->max_vcpus || (v = d->vcpu[tr.vcpuid]) == NULL )
goto param_fail8;
- if ( v->arch.hvm_vcpu.inject_trap != -1 )
+ if ( v->arch.hvm_vcpu.inject_trap.vector != -1 )
rc = -EBUSY;
else
{
- v->arch.hvm_vcpu.inject_trap = tr.trap;
- v->arch.hvm_vcpu.inject_error_code = tr.error_code;
- v->arch.hvm_vcpu.inject_cr2 = tr.cr2;
+ v->arch.hvm_vcpu.inject_trap.vector = tr.trap;
+ v->arch.hvm_vcpu.inject_trap.error_code = tr.error_code;
+ v->arch.hvm_vcpu.inject_trap.cr2 = tr.cr2;
}
param_fail8:
@@ -4431,11 +4449,9 @@ int nhvm_vcpu_vmexit(struct vcpu *v, str
return -EOPNOTSUPP;
}
-int
-nhvm_vcpu_vmexit_trap(struct vcpu *v, unsigned int trapnr,
- int errcode, unsigned long cr2)
+int nhvm_vcpu_vmexit_trap(struct vcpu *v, struct hvm_trap *trap)
{
- return hvm_funcs.nhvm_vcpu_vmexit_trap(v, trapnr, errcode, cr2);
+ return hvm_funcs.nhvm_vcpu_vmexit_trap(v, trap);
}
uint64_t nhvm_vcpu_guestcr3(struct vcpu *v)
diff -r 53e0571f94e4 xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c Fri May 25 08:21:25 2012 +0100
+++ b/xen/arch/x86/hvm/io.c Fri May 25 09:45:00 2012 +0100
@@ -200,7 +200,7 @@ int handle_mmio(void)
return 0;
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);
break;
default:
break;
diff -r 53e0571f94e4 xen/arch/x86/hvm/svm/emulate.c
--- a/xen/arch/x86/hvm/svm/emulate.c Fri May 25 08:21:25 2012 +0100
+++ b/xen/arch/x86/hvm/svm/emulate.c Fri May 25 09:45:00 2012 +0100
@@ -147,7 +147,7 @@ static int fetch(struct vcpu *v, u8 *buf
/* 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(s
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 -r 53e0571f94e4 xen/arch/x86/hvm/svm/nestedsvm.c
--- a/xen/arch/x86/hvm/svm/nestedsvm.c Fri May 25 08:21:25 2012 +0100
+++ b/xen/arch/x86/hvm/svm/nestedsvm.c Fri May 25 09:45:00 2012 +0100
@@ -735,7 +735,7 @@ nsvm_vcpu_vmrun(struct vcpu *v, struct c
default:
gdprintk(XENLOG_ERR,
"nsvm_vcpu_vmentry 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);
/* Must happen after hvm_inject_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,
}
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
}
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_
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_
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 -r 53e0571f94e4 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Fri May 25 08:21:25 2012 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c Fri May 25 09:45:00 2012 +0100
@@ -109,7 +109,7 @@ void __update_guest_eip(struct cpu_user_
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
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(unsign
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(unsig
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
{
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
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
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(stru
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_
.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_
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_
__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_
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_
__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_
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_
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:
diff -r 53e0571f94e4 xen/arch/x86/hvm/vmx/intr.c
--- a/xen/arch/x86/hvm/vmx/intr.c Fri May 25 08:21:25 2012 +0100
+++ b/xen/arch/x86/hvm/vmx/intr.c Fri May 25 09:45:00 2012 +0100
@@ -251,7 +251,7 @@ void vmx_intr_assist(void)
}
else if ( intack.source == hvm_intsrc_mce )
{
- vmx_inject_hw_exception(TRAP_machine_check, HVM_DELIVER_NO_ERROR_CODE);
+ hvm_inject_hw_exception(TRAP_machine_check, HVM_DELIVER_NO_ERROR_CODE);
}
else
{
diff -r 53e0571f94e4 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Fri May 25 08:21:25 2012 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c Fri May 25 09:45:00 2012 +0100
@@ -268,7 +268,7 @@ long_mode_do_msr_write(unsigned int msr,
uncanonical_address:
HVM_DBG_LOG(DBG_LEVEL_0, "Not cano address of msr write %x", msr);
- vmx_inject_hw_exception(TRAP_gp_fault, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
return HNDL_exception_raised;
}
@@ -1310,10 +1310,9 @@ void nvmx_enqueue_n2_exceptions(struct v
nvmx->intr.intr_info, nvmx->intr.error_code);
}
-static int nvmx_vmexit_exceptions(struct vcpu *v, unsigned int trapnr,
- int errcode, unsigned long cr2)
+static int nvmx_vmexit_trap(struct vcpu *v, struct hvm_trap *trap)
{
- nvmx_enqueue_n2_exceptions(v, trapnr, errcode);
+ nvmx_enqueue_n2_exceptions(v, trap->vector, trap->error_code);
return NESTEDHVM_VMEXIT_DONE;
}
@@ -1344,78 +1343,6 @@ static void __vmx_inject_exception(int t
curr->arch.hvm_vmx.vmx_emulate = 1;
}
-void vmx_inject_hw_exception(int trap, int error_code)
-{
- unsigned long intr_info;
- struct vcpu *curr = current;
-
- int type = X86_EVENTTYPE_HW_EXCEPTION;
-
- if ( nestedhvm_vcpu_in_guestmode(curr) )
- intr_info = vcpu_2_nvmx(curr).intr.intr_info;
- else
- intr_info = __vmread(VM_ENTRY_INTR_INFO);
-
- switch ( trap )
- {
- case TRAP_debug:
- type = X86_EVENTTYPE_SW_EXCEPTION;
- if ( guest_cpu_user_regs()->eflags & X86_EFLAGS_TF )
- {
- __restore_debug_registers(curr);
- write_debugreg(6, read_debugreg(6) | 0x4000);
- }
- if ( cpu_has_monitor_trap_flag )
- break;
- /* fall through */
-
- case TRAP_int3:
- if ( curr->domain->debugger_attached )
- {
- /* Debug/Int3: Trap to debugger. */
- domain_pause_for_debugger();
- return;
- }
-
- type = X86_EVENTTYPE_SW_EXCEPTION;
- __vmwrite(VM_ENTRY_INSTRUCTION_LEN, 1); /* int3 */
- break;
-
- default:
- if ( trap > TRAP_last_reserved )
- {
- type = X86_EVENTTYPE_SW_EXCEPTION;
- __vmwrite(VM_ENTRY_INSTRUCTION_LEN, 2); /* int imm8 */
- }
- break;
- }
-
- if ( unlikely(intr_info & INTR_INFO_VALID_MASK) &&
- (((intr_info >> 8) & 7) == X86_EVENTTYPE_HW_EXCEPTION) )
- {
- trap = hvm_combine_hw_exceptions((uint8_t)intr_info, trap);
- if ( trap == TRAP_double_fault )
- error_code = 0;
- }
-
- if ( nestedhvm_vcpu_in_guestmode(curr) &&
- nvmx_intercepts_exception(curr, trap, error_code) )
- {
- nvmx_enqueue_n2_exceptions (curr,
- INTR_INFO_VALID_MASK | (type<<8) | trap,
- error_code);
- return;
- }
- else
- __vmx_inject_exception(trap, type, error_code);
-
- if ( trap == TRAP_page_fault )
- HVMTRACE_LONG_2D(PF_INJECT, error_code,
- TRC_PAR_LONG(current->arch.hvm_vcpu.guest_cr[2]));
- else
- HVMTRACE_2D(INJ_EXC, trap, error_code);
-}
-
void vmx_inject_extint(int trap)
{
struct vcpu *v = current;
@@ -1454,13 +1381,67 @@ void vmx_inject_nmi(void)
HVM_DELIVER_NO_ERROR_CODE);
}
-static void vmx_inject_exception(
- unsigned int trapnr, int errcode, unsigned long cr2)
+static void vmx_inject_trap(struct hvm_trap *trap)
{
- if ( trapnr == TRAP_page_fault )
- current->arch.hvm_vcpu.guest_cr[2] = cr2;
-
- vmx_inject_hw_exception(trapnr, errcode);
+ unsigned long intr_info;
+ struct vcpu *curr = current;
+ struct hvm_trap _trap = *trap;
+
+ if ( (_trap.vector == TRAP_page_fault) &&
+ (_trap.type == X86_EVENTTYPE_HW_EXCEPTION) )
+ current->arch.hvm_vcpu.guest_cr[2] = _trap.cr2;
+
+ if ( nestedhvm_vcpu_in_guestmode(curr) )
+ intr_info = vcpu_2_nvmx(curr).intr.intr_info;
+ else
+ intr_info = __vmread(VM_ENTRY_INTR_INFO);
+
+ switch ( _trap.vector )
+ {
+ case TRAP_debug:
+ if ( guest_cpu_user_regs()->eflags & X86_EFLAGS_TF )
+ {
+ __restore_debug_registers(curr);
+ write_debugreg(6, read_debugreg(6) | 0x4000);
+ }
+ if ( cpu_has_monitor_trap_flag )
+ break;
+ /* fall through */
+ case TRAP_int3:
+ if ( curr->domain->debugger_attached )
+ {
+ /* Debug/Int3: Trap to debugger. */
+ domain_pause_for_debugger();
+ return;
+ }
+ }
+
+ if ( unlikely(intr_info & INTR_INFO_VALID_MASK) &&
+ (((intr_info >> 8) & 7) == X86_EVENTTYPE_HW_EXCEPTION) )
+ {
+ _trap.vector = hvm_combine_hw_exceptions(
+ (uint8_t)intr_info, _trap.vector);
+ if ( _trap.vector == TRAP_double_fault )
+ _trap.error_code = 0;
+ }
+
+ if ( nestedhvm_vcpu_in_guestmode(curr) &&
+ nvmx_intercepts_exception(curr, _trap.vector, _trap.error_code) )
+ {
+ nvmx_enqueue_n2_exceptions (curr,
+ INTR_INFO_VALID_MASK | (_trap.type<<8) | _trap.vector,
+ _trap.error_code);
+ return;
+ }
+ else
+ __vmx_inject_exception(_trap.vector, _trap.type, _trap.error_code);
+
+ if ( (_trap.vector == TRAP_page_fault) &&
+ (_trap.type == X86_EVENTTYPE_HW_EXCEPTION) )
+ HVMTRACE_LONG_2D(PF_INJECT, _trap.error_code,
+ TRC_PAR_LONG(current->arch.hvm_vcpu.guest_cr[2]));
+ else
+ HVMTRACE_2D(INJ_EXC, _trap.vector, _trap.error_code);
}
static int vmx_event_pending(struct vcpu *v)
@@ -1532,7 +1513,7 @@ static struct hvm_function_table __read_
.set_guest_pat = vmx_set_guest_pat,
.get_guest_pat = vmx_get_guest_pat,
.set_tsc_offset = vmx_set_tsc_offset,
- .inject_exception = vmx_inject_exception,
+ .inject_trap = vmx_inject_trap,
.init_hypercall_page = vmx_init_hypercall_page,
.event_pending = vmx_event_pending,
.do_pmu_interrupt = vmx_do_pmu_interrupt,
@@ -1554,7 +1535,7 @@ static struct hvm_function_table __read_
.nhvm_vcpu_hostcr3 = nvmx_vcpu_hostcr3,
.nhvm_vcpu_asid = nvmx_vcpu_asid,
.nhvm_vmcx_guest_intercepts_trap = nvmx_intercepts_exception,
- .nhvm_vcpu_vmexit_trap = nvmx_vmexit_exceptions,
+ .nhvm_vcpu_vmexit_trap = nvmx_vmexit_trap,
.nhvm_intr_blocked = nvmx_intr_blocked
};
@@ -1618,7 +1599,7 @@ static void update_guest_eip(void)
}
if ( regs->eflags & X86_EFLAGS_TF )
- vmx_inject_hw_exception(TRAP_debug, HVM_DELIVER_NO_ERROR_CODE);
+ hvm_inject_hw_exception(TRAP_debug, HVM_DELIVER_NO_ERROR_CODE);
}
static void vmx_fpu_dirty_intercept(void)
@@ -1922,7 +1903,7 @@ done:
return X86EMUL_OKAY;
gp_fault:
- vmx_inject_hw_exception(TRAP_gp_fault, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
return X86EMUL_EXCEPTION;
}
@@ -2030,7 +2011,7 @@ static int vmx_msr_write_intercept(unsig
if ( (rc < 0) ||
(vmx_add_host_load_msr(msr) < 0) )
- vmx_inject_hw_exception(TRAP_machine_check, 0);
+ hvm_inject_hw_exception(TRAP_machine_check, 0);
else
{
__vmwrite(GUEST_IA32_DEBUGCTL, msr_content);
@@ -2073,7 +2054,7 @@ static int vmx_msr_write_intercept(unsig
return X86EMUL_OKAY;
gp_fault:
- vmx_inject_hw_exception(TRAP_gp_fault, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
return X86EMUL_EXCEPTION;
}
@@ -2222,11 +2203,11 @@ static void vmx_vmexit_ud_intercept(stru
switch ( rc )
{
case X86EMUL_UNHANDLEABLE:
- vmx_inject_hw_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE);
+ 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);
@@ -2440,7 +2421,12 @@ void vmx_vmexit_handler(struct cpu_user_
if ( handled < 0 )
{
- vmx_inject_exception(TRAP_int3, HVM_DELIVER_NO_ERROR_CODE, 0);
+ struct hvm_trap trap = {
+ .vector = TRAP_int3,
+ .type = X86_EVENTTYPE_SW_EXCEPTION,
+ .error_code = HVM_DELIVER_NO_ERROR_CODE
+ };
+ hvm_inject_trap(&trap);
break;
}
else if ( handled )
@@ -2476,8 +2462,7 @@ void vmx_vmexit_handler(struct cpu_user_
break;
}
- v->arch.hvm_vcpu.guest_cr[2] = exit_qualification;
- vmx_inject_hw_exception(TRAP_page_fault, regs->error_code);
+ hvm_inject_page_fault(regs->error_code, exit_qualification);
break;
case TRAP_nmi:
if ( (intr_info & INTR_INFO_INTR_TYPE_MASK) !=
@@ -2658,7 +2643,7 @@ void vmx_vmexit_handler(struct cpu_user_
* as far as vmexit.
*/
WARN_ON(exit_reason == EXIT_REASON_GETSEC);
- vmx_inject_hw_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE);
+ hvm_inject_hw_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE);
break;
case EXIT_REASON_TPR_BELOW_THRESHOLD:
@@ -2666,7 +2651,7 @@ void vmx_vmexit_handler(struct cpu_user_
case EXIT_REASON_APIC_ACCESS:
if ( !vmx_handle_eoi_write() && !handle_mmio() )
- vmx_inject_hw_exception(TRAP_gp_fault, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
break;
case EXIT_REASON_IO_INSTRUCTION:
@@ -2675,7 +2660,7 @@ void vmx_vmexit_handler(struct cpu_user_
{
/* INS, OUTS */
if ( !handle_mmio() )
- vmx_inject_hw_exception(TRAP_gp_fault, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
}
else
{
diff -r 53e0571f94e4 xen/arch/x86/hvm/vmx/vpmu_core2.c
--- a/xen/arch/x86/hvm/vmx/vpmu_core2.c Fri May 25 08:21:25 2012 +0100
+++ b/xen/arch/x86/hvm/vmx/vpmu_core2.c Fri May 25 09:45:00 2012 +0100
@@ -421,7 +421,7 @@ static int core2_vpmu_do_wrmsr(unsigned
if ( vpmu_is_set(vpmu, VPMU_CPU_HAS_BTS) )
return 1;
gdprintk(XENLOG_WARNING, "Debug Store is not supported on this cpu\n");
- vmx_inject_hw_exception(TRAP_gp_fault, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
return 0;
}
}
@@ -437,7 +437,7 @@ static int core2_vpmu_do_wrmsr(unsigned
case MSR_CORE_PERF_GLOBAL_STATUS:
gdprintk(XENLOG_INFO, "Can not write readonly MSR: "
"MSR_PERF_GLOBAL_STATUS(0x38E)!\n");
- vmx_inject_hw_exception(TRAP_gp_fault, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
return 1;
case MSR_IA32_PEBS_ENABLE:
if ( msr_content & 1 )
@@ -452,7 +452,7 @@ static int core2_vpmu_do_wrmsr(unsigned
gdprintk(XENLOG_WARNING,
"Illegal address for IA32_DS_AREA: %#" PRIx64 "x\n",
msr_content);
- vmx_inject_hw_exception(TRAP_gp_fault, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
return 1;
}
core2_vpmu_cxt->pmu_enable->ds_area_enable = msr_content ? 1 : 0;
@@ -544,7 +544,7 @@ static int core2_vpmu_do_wrmsr(unsigned
break;
}
if (inject_gp)
- vmx_inject_hw_exception(TRAP_gp_fault, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
else
wrmsrl(msr, msr_content);
}
diff -r 53e0571f94e4 xen/arch/x86/hvm/vmx/vvmx.c
--- a/xen/arch/x86/hvm/vmx/vvmx.c Fri May 25 08:21:25 2012 +0100
+++ b/xen/arch/x86/hvm/vmx/vvmx.c Fri May 25 09:45:00 2012 +0100
@@ -304,12 +304,12 @@ vmexit:
invalid_op:
gdprintk(XENLOG_ERR, "vmx_inst_check_privilege: invalid_op\n");
- hvm_inject_exception(TRAP_invalid_op, 0, 0);
+ hvm_inject_hw_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE);
return X86EMUL_EXCEPTION;
gp_fault:
gdprintk(XENLOG_ERR, "vmx_inst_check_privilege: gp_fault\n");
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
return X86EMUL_EXCEPTION;
}
@@ -386,7 +386,7 @@ static int decode_vmx_inst(struct cpu_us
return X86EMUL_OKAY;
gp_fault:
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
return X86EMUL_EXCEPTION;
}
diff -r 53e0571f94e4 xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c Fri May 25 08:21:25 2012 +0100
+++ b/xen/arch/x86/mm/shadow/common.c Fri May 25 09:45:00 2012 +0100
@@ -135,7 +135,7 @@ static int hvm_translate_linear_addr(
if ( !okay )
{
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
return X86EMUL_EXCEPTION;
}
diff -r 53e0571f94e4 xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c Fri May 25 08:21:25 2012 +0100
+++ b/xen/arch/x86/mm/shadow/multi.c Fri May 25 09:45:00 2012 +0100
@@ -4825,7 +4825,7 @@ static mfn_t emulate_gva_to_mfn(struct v
if ( gfn == INVALID_GFN )
{
if ( is_hvm_vcpu(v) )
- hvm_inject_exception(TRAP_page_fault, pfec, vaddr);
+ hvm_inject_page_fault(pfec, vaddr);
else
propagate_page_fault(vaddr, pfec);
return _mfn(BAD_GVA_TO_GFN);
diff -r 53e0571f94e4 xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h Fri May 25 08:21:25 2012 +0100
+++ b/xen/include/asm-x86/hvm/hvm.h Fri May 25 09:45:00 2012 +0100
@@ -71,6 +71,13 @@ enum hvm_intblk {
#define HVM_HAP_SUPERPAGE_2MB 0x00000001
#define HVM_HAP_SUPERPAGE_1GB 0x00000002
+struct hvm_trap {
+ int vector;
+ unsigned int type; /* X86_EVENTTYPE_* */
+ int error_code; /* HVM_DELIVER_NO_ERROR_CODE if n/a */
+ unsigned long cr2; /* Only for TRAP_page_fault h/w exception */
+};
+
/*
* The hardware virtual machine (HVM) interface abstracts away from the
* x86/x86_64 CPU virtualization assist specifics. Currently this interface
@@ -124,8 +131,7 @@ struct hvm_function_table {
void (*set_tsc_offset)(struct vcpu *v, u64 offset);
- void (*inject_exception)(unsigned int trapnr, int errcode,
- unsigned long cr2);
+ void (*inject_trap)(struct hvm_trap *trap);
void (*init_hypercall_page)(struct domain *d, void *hypercall_page);
@@ -162,10 +168,7 @@ struct hvm_function_table {
struct cpu_user_regs *regs);
int (*nhvm_vcpu_vmexit)(struct vcpu *v, struct cpu_user_regs *regs,
uint64_t exitcode);
- int (*nhvm_vcpu_vmexit_trap)(struct vcpu *v,
- unsigned int trapnr,
- int errcode,
- unsigned long cr2);
+ int (*nhvm_vcpu_vmexit_trap)(struct vcpu *v, struct hvm_trap *trap);
uint64_t (*nhvm_vcpu_guestcr3)(struct vcpu *v);
uint64_t (*nhvm_vcpu_hostcr3)(struct vcpu *v);
uint32_t (*nhvm_vcpu_asid)(struct vcpu *v);
@@ -320,7 +323,9 @@ void hvm_migrate_timers(struct vcpu *v);
void hvm_do_resume(struct vcpu *v);
void hvm_migrate_pirqs(struct vcpu *v);
-void hvm_inject_exception(unsigned int trapnr, int errcode, unsigned long cr2);
+void hvm_inject_trap(struct hvm_trap *trap);
+void hvm_inject_hw_exception(unsigned int trapnr, int errcode);
+void hvm_inject_page_fault(int errcode, unsigned long cr2);
static inline int hvm_event_pending(struct vcpu *v)
{
@@ -479,8 +484,7 @@ int nhvm_vcpu_vmexit(struct vcpu *v, str
/* inject vmexit into l1 guest. l1 guest will see a VMEXIT due to
* 'trapnr' exception.
*/
-int nhvm_vcpu_vmexit_trap(struct vcpu *v,
- unsigned int trapnr, int errcode, unsigned long cr2);
+int nhvm_vcpu_vmexit_trap(struct vcpu *v, struct hvm_trap *trap);
/* returns l2 guest cr3 in l2 guest physical address space. */
uint64_t nhvm_vcpu_guestcr3(struct vcpu *v);
diff -r 53e0571f94e4 xen/include/asm-x86/hvm/svm/nestedsvm.h
--- a/xen/include/asm-x86/hvm/svm/nestedsvm.h Fri May 25 08:21:25 2012 +0100
+++ b/xen/include/asm-x86/hvm/svm/nestedsvm.h Fri May 25 09:45:00 2012 +0100
@@ -114,8 +114,7 @@ int nsvm_vcpu_hostrestore(struct vcpu *v
int nsvm_vcpu_vmrun(struct vcpu *v, struct cpu_user_regs *regs);
int nsvm_vcpu_vmexit_inject(struct vcpu *v, struct cpu_user_regs *regs,
uint64_t exitcode);
-int nsvm_vcpu_vmexit_trap(struct vcpu *v, unsigned int trapnr,
- int errcode, unsigned long cr2);
+int nsvm_vcpu_vmexit_trap(struct vcpu *v, struct hvm_trap *trap);
uint64_t nsvm_vcpu_guestcr3(struct vcpu *v);
uint64_t nsvm_vcpu_hostcr3(struct vcpu *v);
uint32_t nsvm_vcpu_asid(struct vcpu *v);
diff -r 53e0571f94e4 xen/include/asm-x86/hvm/vcpu.h
--- a/xen/include/asm-x86/hvm/vcpu.h Fri May 25 08:21:25 2012 +0100
+++ b/xen/include/asm-x86/hvm/vcpu.h Fri May 25 09:45:00 2012 +0100
@@ -164,10 +164,9 @@ struct hvm_vcpu {
/* Callback into x86_emulate when emulating FPU/MMX/XMM instructions. */
void (*fpu_exception_callback)(void *, struct cpu_user_regs *);
void *fpu_exception_callback_arg;
- /* Pending hw/sw interrupt */
- int inject_trap; /* -1 for nothing to inject */
- int inject_error_code;
- unsigned long inject_cr2;
+
+ /* Pending hw/sw interrupt (.vector = -1 means nothing pending). */
+ struct hvm_trap inject_trap;
struct viridian_vcpu viridian;
};
diff -r 53e0571f94e4 xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Fri May 25 08:21:25 2012 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Fri May 25 09:45:00 2012 +0100
@@ -387,7 +387,6 @@ static inline int __vmxon(u64 addr)
return rc;
}
-void vmx_inject_hw_exception(int trap, int error_code);
void vmx_inject_extint(int trap);
void vmx_inject_nmi(void);
[-- Attachment #3: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] xen: Add instruction length parameter in function hvm_inject_exception
2012-05-25 8:53 ` Keir Fraser
@ 2012-05-25 19:17 ` Aravindh Puthiyaparambil
2012-05-25 20:42 ` Keir Fraser
2012-05-28 6:24 ` Hao, Xudong
1 sibling, 1 reply; 12+ messages in thread
From: Aravindh Puthiyaparambil @ 2012-05-25 19:17 UTC (permalink / raw)
To: Keir Fraser
Cc: Xudong Hao, eddie.dong, xen-devel, JBeulich, Ian Jackson,
Xiantao Zhang
On Fri, May 25, 2012 at 1:53 AM, Keir Fraser <keir@xen.org> wrote:
> On 24/05/2012 20:06, "Xudong Hao" <xudong.hao@intel.com> wrote:
>
>> VMX exception: Pass the instruction length field down to exception emulation,
>> by changing hypercall parameter and adding a parameter in fucntion
>> hvm_inject_exception(), so that exception emulation can set correct
>> instruction length.
>>
>> Signed-off-by: Xudong Hao <xudong.hao@intel.com>
>> Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
>
> I don't like adding yet another parameter for all callers, especially as we
> should also be passing down the event type (sw interrupt, hw exception, ...)
> and that would bloat the parameter list further.
>
> I attach a cleanup patch which packs everything into a new struct and
> renames hvm_inject_exception to hvm_inject_trap. I then define a couple of
> wrappers around that function for existing callers, so that their parameter
> lists actually *shrink*.
>
> Let me know what you think. If it looks acceptable I can check it in and we
> can build on top of this restructuring. The aim being to keep
> hvm/vmx_inject_trap dumb, and push down the knowledge from the callers into
> it.
So I take it that with just this patch injecting of software
interrupts will not work and I should hold off on testing that out.
What is the plan for injecting software interrupts? Add another libxc
API for that?
Thanks,
Aravindh
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] xen: Add instruction length parameter in function hvm_inject_exception
2012-05-25 19:17 ` Aravindh Puthiyaparambil
@ 2012-05-25 20:42 ` Keir Fraser
2012-05-28 6:37 ` Hao, Xudong
0 siblings, 1 reply; 12+ messages in thread
From: Keir Fraser @ 2012-05-25 20:42 UTC (permalink / raw)
To: Aravindh Puthiyaparambil
Cc: Xudong Hao, eddie.dong, xen-devel, JBeulich, Ian Jackson,
Xiantao Zhang
On 25/05/2012 20:17, "Aravindh Puthiyaparambil" <aravindh@virtuata.com>
wrote:
>> I don't like adding yet another parameter for all callers, especially as we
>> should also be passing down the event type (sw interrupt, hw exception, ...)
>> and that would bloat the parameter list further.
>>
>> I attach a cleanup patch which packs everything into a new struct and
>> renames hvm_inject_exception to hvm_inject_trap. I then define a couple of
>> wrappers around that function for existing callers, so that their parameter
>> lists actually *shrink*.
>>
>> Let me know what you think. If it looks acceptable I can check it in and we
>> can build on top of this restructuring. The aim being to keep
>> hvm/vmx_inject_trap dumb, and push down the knowledge from the callers into
>> it.
>
> So I take it that with just this patch injecting of software
> interrupts will not work and I should hold off on testing that out.
> What is the plan for injecting software interrupts? Add another libxc
> API for that?
Yes, everything represented in my 'struct hvm_trap', plus instruction
length, which my patch doesn't add, should be part of the trap injection API
through hvm_op hypercall and libxc. So the toolstack can inject an arbitrary
trap type, on an arbitrary vector, specify an error code (and cr2 for page
fault), and specify an increment for rIP when the trap is successfully
injected. All through one API function.
But as you say, my patch is just a proposed refactoring basis for Xudong's
patches. It actually almost certainly reverts some behaviour that you guys
actually want, which then gets added back in more sanely in patches that go
on top.
-- Keir
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] xen: Add instruction length parameter in function hvm_inject_exception
2012-05-25 8:53 ` Keir Fraser
2012-05-25 19:17 ` Aravindh Puthiyaparambil
@ 2012-05-28 6:24 ` Hao, Xudong
2012-05-28 6:49 ` Keir Fraser
1 sibling, 1 reply; 12+ messages in thread
From: Hao, Xudong @ 2012-05-28 6:24 UTC (permalink / raw)
To: Keir Fraser, JBeulich@suse.com
Cc: Aravindh Puthiyaparambil, Dong, Eddie, Ian Jackson,
Zhang, Xiantao, xen-devel@lists.xen.org
> -----Original Message-----
> From: Keir Fraser [mailto:keir.xen@gmail.com] On Behalf Of Keir Fraser
> Sent: Friday, May 25, 2012 4:53 PM
> To: Hao, Xudong; JBeulich@suse.com
> Cc: xen-devel@lists.xen.org; Dong, Eddie; Aravindh Puthiyaparambil; Ian
> Jackson; Zhang, Xiantao
> Subject: Re: [PATCH 1/3] xen: Add instruction length parameter in function
> hvm_inject_exception
>
> On 24/05/2012 20:06, "Xudong Hao" <xudong.hao@intel.com> wrote:
>
> > VMX exception: Pass the instruction length field down to exception
> emulation,
> > by changing hypercall parameter and adding a parameter in fucntion
> > hvm_inject_exception(), so that exception emulation can set correct
> > instruction length.
> >
> > Signed-off-by: Xudong Hao <xudong.hao@intel.com>
> > Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
>
> I don't like adding yet another parameter for all callers, especially as we
> should also be passing down the event type (sw interrupt, hw exception, ...)
> and that would bloat the parameter list further.
>
> I attach a cleanup patch which packs everything into a new struct and
> renames hvm_inject_exception to hvm_inject_trap. I then define a couple of
> wrappers around that function for existing callers, so that their parameter
> lists actually *shrink*.
>
> Let me know what you think. If it looks acceptable I can check it in and we
> can build on top of this restructuring. The aim being to keep
> hvm/vmx_inject_trap dumb, and push down the knowledge from the callers
> into
> it.
Hi, Keir
This patch is fine to me, just one small comments: the note below the hvm_inject_hw_exception(TRAP*) should change to hvm_inject_hw_exception from hvm_inject_exception.
--- a/xen/arch/x86/hvm/svm/nestedsvm.c Fri May 25 08:21:25 2012 +0100
+++ b/xen/arch/x86/hvm/svm/nestedsvm.c Fri May 25 09:45:00 2012 +0100
@@ -735,7 +735,7 @@ nsvm_vcpu_vmrun(struct vcpu *v, struct c
default:
gdprintk(XENLOG_ERR,
"nsvm_vcpu_vmentry 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);
/* Must happen after hvm_inject_exception or it doesn't work right. */
And I'll add instruction length represented in 'struct hvm_trap', and correct the _trap.type in new function vmx_inject_trap() based on the restructuring.
>
> -- Keir
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] xen: Add instruction length parameter in function hvm_inject_exception
2012-05-25 20:42 ` Keir Fraser
@ 2012-05-28 6:37 ` Hao, Xudong
0 siblings, 0 replies; 12+ messages in thread
From: Hao, Xudong @ 2012-05-28 6:37 UTC (permalink / raw)
To: Keir Fraser, Aravindh Puthiyaparambil
Cc: Ian Jackson, Dong, Eddie, Zhang, Xiantao, JBeulich@suse.com,
xen-devel@lists.xen.org
> -----Original Message-----
> From: Keir Fraser [mailto:keir.xen@gmail.com] On Behalf Of Keir Fraser
> Sent: Saturday, May 26, 2012 4:42 AM
> To: Aravindh Puthiyaparambil
> Cc: Hao, Xudong; JBeulich@suse.com; xen-devel@lists.xen.org; Dong, Eddie;
> Ian Jackson; Zhang, Xiantao
> Subject: Re: [PATCH 1/3] xen: Add instruction length parameter in function
> hvm_inject_exception
>
> On 25/05/2012 20:17, "Aravindh Puthiyaparambil" <aravindh@virtuata.com>
> wrote:
>
> >> I don't like adding yet another parameter for all callers, especially as we
> >> should also be passing down the event type (sw interrupt, hw exception, ...)
> >> and that would bloat the parameter list further.
> >>
> >> I attach a cleanup patch which packs everything into a new struct and
> >> renames hvm_inject_exception to hvm_inject_trap. I then define a couple of
> >> wrappers around that function for existing callers, so that their parameter
> >> lists actually *shrink*.
> >>
> >> Let me know what you think. If it looks acceptable I can check it in and we
> >> can build on top of this restructuring. The aim being to keep
> >> hvm/vmx_inject_trap dumb, and push down the knowledge from the callers
> into
> >> it.
> >
> > So I take it that with just this patch injecting of software
> > interrupts will not work and I should hold off on testing that out.
> > What is the plan for injecting software interrupts? Add another libxc
> > API for that?
>
I'll write libxc API and correct the new function vmx_inject_trap() based on Keir's restructuring.
> Yes, everything represented in my 'struct hvm_trap', plus instruction
> length, which my patch doesn't add, should be part of the trap injection API
> through hvm_op hypercall and libxc.
I can add instruction length in hvm_trap.
> So the toolstack can inject an arbitrary
> trap type, on an arbitrary vector, specify an error code (and cr2 for page
> fault), and specify an increment for rIP when the trap is successfully
> injected. All through one API function.
>
> But as you say, my patch is just a proposed refactoring basis for Xudong's
> patches. It actually almost certainly reverts some behaviour that you guys
> actually want, which then gets added back in more sanely in patches that go
> on top.
>
Sure, I'll finish our things.
> -- Keir
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] xen: Add instruction length parameter in function hvm_inject_exception
2012-05-28 6:24 ` Hao, Xudong
@ 2012-05-28 6:49 ` Keir Fraser
2012-05-29 8:55 ` Hao, Xudong
0 siblings, 1 reply; 12+ messages in thread
From: Keir Fraser @ 2012-05-28 6:49 UTC (permalink / raw)
To: Hao, Xudong, JBeulich@suse.com
Cc: Aravindh Puthiyaparambil, Dong, Eddie, Ian Jackson,
Zhang, Xiantao, xen-devel@lists.xen.org
On 28/05/2012 07:24, "Hao, Xudong" <xudong.hao@intel.com> wrote:
> Hi, Keir
>
> This patch is fine to me, just one small comments: the note below the
> hvm_inject_hw_exception(TRAP*) should change to hvm_inject_hw_exception from
> hvm_inject_exception.
Yes indeed. Thanks!
-- Keir
> --- a/xen/arch/x86/hvm/svm/nestedsvm.c Fri May 25 08:21:25 2012 +0100
> +++ b/xen/arch/x86/hvm/svm/nestedsvm.c Fri May 25 09:45:00 2012 +0100
> @@ -735,7 +735,7 @@ nsvm_vcpu_vmrun(struct vcpu *v, struct c
> default:
> gdprintk(XENLOG_ERR,
> "nsvm_vcpu_vmentry 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);
> /* Must happen after hvm_inject_exception or it doesn't work right.
> */
>
> And I'll add instruction length represented in 'struct hvm_trap', and correct
> the _trap.type in new function vmx_inject_trap() based on the restructuring.
>
>>
>> -- Keir
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] xen: Add instruction length parameter in function hvm_inject_exception
2012-05-28 6:49 ` Keir Fraser
@ 2012-05-29 8:55 ` Hao, Xudong
2012-05-29 12:38 ` Keir Fraser
0 siblings, 1 reply; 12+ messages in thread
From: Hao, Xudong @ 2012-05-29 8:55 UTC (permalink / raw)
To: Keir Fraser, JBeulich@suse.com
Cc: Aravindh Puthiyaparambil, Dong, Eddie, Ian Jackson,
Zhang, Xiantao, xen-devel@lists.xen.org
> -----Original Message-----
> From: Keir Fraser [mailto:keir.xen@gmail.com]
> Sent: Monday, May 28, 2012 2:50 PM
> To: Hao, Xudong; JBeulich@suse.com
> Cc: xen-devel@lists.xen.org; Dong, Eddie; Aravindh Puthiyaparambil; Ian
> Jackson; Zhang, Xiantao
> Subject: Re: [PATCH 1/3] xen: Add instruction length parameter in function
> hvm_inject_exception
>
> On 28/05/2012 07:24, "Hao, Xudong" <xudong.hao@intel.com> wrote:
>
> > Hi, Keir
> >
> > This patch is fine to me, just one small comments: the note below the
> > hvm_inject_hw_exception(TRAP*) should change to
> hvm_inject_hw_exception from
> > hvm_inject_exception.
>
> Yes indeed. Thanks!
>
Hi, Keir
Can you check your patch in? then I can send my patches out based you.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] xen: Add instruction length parameter in function hvm_inject_exception
2012-05-29 8:55 ` Hao, Xudong
@ 2012-05-29 12:38 ` Keir Fraser
2012-05-30 0:58 ` Hao, Xudong
0 siblings, 1 reply; 12+ messages in thread
From: Keir Fraser @ 2012-05-29 12:38 UTC (permalink / raw)
To: Hao, Xudong, JBeulich@suse.com
Cc: Aravindh Puthiyaparambil, Dong, Eddie, Ian Jackson,
Zhang, Xiantao, xen-devel@lists.xen.org
On 29/05/2012 09:55, "Hao, Xudong" <xudong.hao@intel.com> wrote:
>> -----Original Message-----
>> From: Keir Fraser [mailto:keir.xen@gmail.com]
>> Sent: Monday, May 28, 2012 2:50 PM
>> To: Hao, Xudong; JBeulich@suse.com
>> Cc: xen-devel@lists.xen.org; Dong, Eddie; Aravindh Puthiyaparambil; Ian
>> Jackson; Zhang, Xiantao
>> Subject: Re: [PATCH 1/3] xen: Add instruction length parameter in function
>> hvm_inject_exception
>>
>> On 28/05/2012 07:24, "Hao, Xudong" <xudong.hao@intel.com> wrote:
>>
>>> Hi, Keir
>>>
>>> This patch is fine to me, just one small comments: the note below the
>>> hvm_inject_hw_exception(TRAP*) should change to
>> hvm_inject_hw_exception from
>>> hvm_inject_exception.
>>
>> Yes indeed. Thanks!
>>
>
> Hi, Keir
>
> Can you check your patch in? then I can send my patches out based you.
Please make my patch the first of your series. You can add my s-o-b line:
Signed-off-by: Keir Fraser <keir@xen.org>
-- Keir
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] xen: Add instruction length parameter in function hvm_inject_exception
2012-05-29 12:38 ` Keir Fraser
@ 2012-05-30 0:58 ` Hao, Xudong
0 siblings, 0 replies; 12+ messages in thread
From: Hao, Xudong @ 2012-05-30 0:58 UTC (permalink / raw)
To: Keir Fraser, JBeulich@suse.com
Cc: Aravindh Puthiyaparambil, Dong, Eddie, Ian Jackson,
Zhang, Xiantao, xen-devel@lists.xen.org
> -----Original Message-----
> From: Keir Fraser [mailto:keir.xen@gmail.com]
> Sent: Tuesday, May 29, 2012 8:39 PM
> To: Hao, Xudong; JBeulich@suse.com
> Cc: xen-devel@lists.xen.org; Dong, Eddie; Aravindh Puthiyaparambil; Ian
> Jackson; Zhang, Xiantao
> Subject: Re: [PATCH 1/3] xen: Add instruction length parameter in function
> hvm_inject_exception
>
> On 29/05/2012 09:55, "Hao, Xudong" <xudong.hao@intel.com> wrote:
>
> >> -----Original Message-----
> >> From: Keir Fraser [mailto:keir.xen@gmail.com]
> >> Sent: Monday, May 28, 2012 2:50 PM
> >> To: Hao, Xudong; JBeulich@suse.com
> >> Cc: xen-devel@lists.xen.org; Dong, Eddie; Aravindh Puthiyaparambil; Ian
> >> Jackson; Zhang, Xiantao
> >> Subject: Re: [PATCH 1/3] xen: Add instruction length parameter in function
> >> hvm_inject_exception
> >>
> >> On 28/05/2012 07:24, "Hao, Xudong" <xudong.hao@intel.com> wrote:
> >>
> >>> Hi, Keir
> >>>
> >>> This patch is fine to me, just one small comments: the note below the
> >>> hvm_inject_hw_exception(TRAP*) should change to
> >> hvm_inject_hw_exception from
> >>> hvm_inject_exception.
> >>
> >> Yes indeed. Thanks!
> >>
> >
> > Hi, Keir
> >
> > Can you check your patch in? then I can send my patches out based you.
>
> Please make my patch the first of your series. You can add my s-o-b line:
> Signed-off-by: Keir Fraser <keir@xen.org>
>
Okay.
> -- Keir
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2012-05-30 0:58 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-05-24 19:06 [PATCH 0/3] XEN: fix vmx exception mistake Xudong Hao
2012-05-24 19:06 ` [PATCH 1/3] xen: Add instruction length parameter in function hvm_inject_exception Xudong Hao
2012-05-25 8:53 ` Keir Fraser
2012-05-25 19:17 ` Aravindh Puthiyaparambil
2012-05-25 20:42 ` Keir Fraser
2012-05-28 6:37 ` Hao, Xudong
2012-05-28 6:24 ` Hao, Xudong
2012-05-28 6:49 ` Keir Fraser
2012-05-29 8:55 ` Hao, Xudong
2012-05-29 12:38 ` Keir Fraser
2012-05-30 0:58 ` Hao, Xudong
2012-05-24 19:06 ` [PATCH 2/3] VMX: Fix the mistake of exception execution Xudong Hao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).