mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
[HVM] Avoid mis-optimisation of the SVM/VMX exit handlers
by passing a *pointer* to the register state, instead of 'passing by value'. This should fix the bugs resulting in display of "trying to set reserved bit in EFER" on the Xen console. Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
1 parent
7ce79f6a21
commit
f10e4fdc2a
7 files changed
+111
-106
No files matched your search
+72
-75
@@ -2564,9 +2564,7 @@ void walk_shadow_and_guest_pt(unsigned long gva)
|
||||
#endif /* SVM_WALK_GUEST_PAGES */
|
||||
|
||||
|
||||
|
||||
|
||||
asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs)
|
||||
asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
|
||||
{
|
||||
unsigned int exit_reason;
|
||||
unsigned long eip;
|
||||
@@ -2578,7 +2576,7 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs)
|
||||
ASSERT(vmcb);
|
||||
|
||||
exit_reason = vmcb->exitcode;
|
||||
save_svm_cpu_user_regs(v, ®s);
|
||||
save_svm_cpu_user_regs(v, regs);
|
||||
|
||||
vmcb->tlb_control = 1;
|
||||
|
||||
@@ -2602,26 +2600,26 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs)
|
||||
if (svm_paging_enabled(v) &&
|
||||
!mmio_space(shadow_gva_to_gpa(current, vmcb->exitinfo2)))
|
||||
{
|
||||
printk("I%08ld,ExC=%s(%d),IP=%x:%llx,"
|
||||
"I1=%llx,I2=%llx,INT=%llx, "
|
||||
"gpa=%llx\n", intercepts_counter,
|
||||
exit_reasons[exit_reason], exit_reason, regs.cs,
|
||||
(unsigned long long) regs.rip,
|
||||
(unsigned long long) vmcb->exitinfo1,
|
||||
(unsigned long long) vmcb->exitinfo2,
|
||||
(unsigned long long) vmcb->exitintinfo.bytes,
|
||||
(unsigned long long) shadow_gva_to_gpa(current, vmcb->exitinfo2));
|
||||
printk("I%08ld,ExC=%s(%d),IP=%x:%"PRIx64","
|
||||
"I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64", "
|
||||
"gpa=%"PRIx64"\n", intercepts_counter,
|
||||
exit_reasons[exit_reason], exit_reason, regs->cs,
|
||||
(u64)regs->rip,
|
||||
(u64)vmcb->exitinfo1,
|
||||
(u64)vmcb->exitinfo2,
|
||||
(u64)vmcb->exitintinfo.bytes,
|
||||
(u64)shadow_gva_to_gpa(current, vmcb->exitinfo2));
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("I%08ld,ExC=%s(%d),IP=%x:%llx,"
|
||||
"I1=%llx,I2=%llx,INT=%llx\n",
|
||||
printk("I%08ld,ExC=%s(%d),IP=%x:%"PRIx64","
|
||||
"I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64"\n",
|
||||
intercepts_counter,
|
||||
exit_reasons[exit_reason], exit_reason, regs.cs,
|
||||
(unsigned long long) regs.rip,
|
||||
(unsigned long long) vmcb->exitinfo1,
|
||||
(unsigned long long) vmcb->exitinfo2,
|
||||
(unsigned long long) vmcb->exitintinfo.bytes );
|
||||
exit_reasons[exit_reason], exit_reason, regs->cs,
|
||||
(u64)regs->rip,
|
||||
(u64)vmcb->exitinfo1,
|
||||
(u64)vmcb->exitinfo2,
|
||||
(u64)vmcb->exitintinfo.bytes );
|
||||
}
|
||||
}
|
||||
else if ( svm_dbg_on
|
||||
@@ -2631,24 +2629,24 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs)
|
||||
|
||||
if (exit_reasons[exit_reason])
|
||||
{
|
||||
printk("I%08ld,ExC=%s(%d),IP=%x:%llx,"
|
||||
"I1=%llx,I2=%llx,INT=%llx\n",
|
||||
printk("I%08ld,ExC=%s(%d),IP=%x:%"PRIx64","
|
||||
"I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64"\n",
|
||||
intercepts_counter,
|
||||
exit_reasons[exit_reason], exit_reason, regs.cs,
|
||||
(unsigned long long) regs.rip,
|
||||
(unsigned long long) vmcb->exitinfo1,
|
||||
(unsigned long long) vmcb->exitinfo2,
|
||||
(unsigned long long) vmcb->exitintinfo.bytes);
|
||||
exit_reasons[exit_reason], exit_reason, regs->cs,
|
||||
(u64)regs->rip,
|
||||
(u64)vmcb->exitinfo1,
|
||||
(u64)vmcb->exitinfo2,
|
||||
(u64)vmcb->exitintinfo.bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("I%08ld,ExC=%d(0x%x),IP=%x:%llx,"
|
||||
"I1=%llx,I2=%llx,INT=%llx\n",
|
||||
intercepts_counter, exit_reason, exit_reason, regs.cs,
|
||||
(unsigned long long) regs.rip,
|
||||
(unsigned long long) vmcb->exitinfo1,
|
||||
(unsigned long long) vmcb->exitinfo2,
|
||||
(unsigned long long) vmcb->exitintinfo.bytes);
|
||||
printk("I%08ld,ExC=%d(0x%x),IP=%x:%"PRIx64","
|
||||
"I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64"\n",
|
||||
intercepts_counter, exit_reason, exit_reason, regs->cs,
|
||||
(u64)regs->rip,
|
||||
(u64)vmcb->exitinfo1,
|
||||
(u64)vmcb->exitinfo2,
|
||||
(u64)vmcb->exitintinfo.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2680,7 +2678,7 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs)
|
||||
(int) v->arch.shadow_table.pfn);
|
||||
|
||||
svm_dump_vmcb(__func__, vmcb);
|
||||
svm_dump_regs(__func__, ®s);
|
||||
svm_dump_regs(__func__, regs);
|
||||
svm_dump_inst(svm_rip2pointer(vmcb));
|
||||
}
|
||||
|
||||
@@ -2710,18 +2708,18 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs)
|
||||
case VMEXIT_EXCEPTION_DB:
|
||||
{
|
||||
#ifdef XEN_DEBUGGER
|
||||
svm_debug_save_cpu_user_regs(®s);
|
||||
pdb_handle_exception(1, ®s, 1);
|
||||
svm_debug_restore_cpu_user_regs(®s);
|
||||
svm_debug_save_cpu_user_regs(regs);
|
||||
pdb_handle_exception(1, regs, 1);
|
||||
svm_debug_restore_cpu_user_regs(regs);
|
||||
#else
|
||||
svm_store_cpu_user_regs(®s, v);
|
||||
svm_store_cpu_user_regs(regs, v);
|
||||
domain_pause_for_debugger();
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case VMEXIT_NMI:
|
||||
do_nmi(®s, 0);
|
||||
do_nmi(regs, 0);
|
||||
break;
|
||||
|
||||
case VMEXIT_SMI:
|
||||
@@ -2741,9 +2739,9 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs)
|
||||
|
||||
case VMEXIT_EXCEPTION_BP:
|
||||
#ifdef XEN_DEBUGGER
|
||||
svm_debug_save_cpu_user_regs(®s);
|
||||
pdb_handle_exception(3, ®s, 1);
|
||||
svm_debug_restore_cpu_user_regs(®s);
|
||||
svm_debug_save_cpu_user_regs(regs);
|
||||
pdb_handle_exception(3, regs, 1);
|
||||
svm_debug_restore_cpu_user_regs(regs);
|
||||
#else
|
||||
if ( test_bit(_DOMF_debugging, &v->domain->domain_flags) )
|
||||
domain_pause_for_debugger();
|
||||
@@ -2758,25 +2756,25 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs)
|
||||
|
||||
case VMEXIT_EXCEPTION_GP:
|
||||
/* This should probably not be trapped in the future */
|
||||
regs.error_code = vmcb->exitinfo1;
|
||||
svm_do_general_protection_fault(v, ®s);
|
||||
regs->error_code = vmcb->exitinfo1;
|
||||
svm_do_general_protection_fault(v, regs);
|
||||
break;
|
||||
|
||||
case VMEXIT_EXCEPTION_PF:
|
||||
{
|
||||
unsigned long va;
|
||||
va = vmcb->exitinfo2;
|
||||
regs.error_code = vmcb->exitinfo1;
|
||||
regs->error_code = vmcb->exitinfo1;
|
||||
HVM_DBG_LOG(DBG_LEVEL_VMMU,
|
||||
"eax=%lx, ebx=%lx, ecx=%lx, edx=%lx, esi=%lx, edi=%lx",
|
||||
(unsigned long)regs.eax, (unsigned long)regs.ebx,
|
||||
(unsigned long)regs.ecx, (unsigned long)regs.edx,
|
||||
(unsigned long)regs.esi, (unsigned long)regs.edi);
|
||||
(unsigned long)regs->eax, (unsigned long)regs->ebx,
|
||||
(unsigned long)regs->ecx, (unsigned long)regs->edx,
|
||||
(unsigned long)regs->esi, (unsigned long)regs->edi);
|
||||
|
||||
if (!(error = svm_do_page_fault(va, ®s)))
|
||||
if (!(error = svm_do_page_fault(va, regs)))
|
||||
{
|
||||
/* Inject #PG using Interruption-Information Fields */
|
||||
svm_inject_exception(v, TRAP_page_fault, 1, regs.error_code);
|
||||
svm_inject_exception(v, TRAP_page_fault, 1, regs->error_code);
|
||||
|
||||
v->arch.hvm_svm.cpu_cr2 = va;
|
||||
vmcb->cr2 = va;
|
||||
@@ -2789,7 +2787,7 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs)
|
||||
case VMEXIT_EXCEPTION_DF:
|
||||
/* Debug info to hopefully help debug WHY the guest double-faulted. */
|
||||
svm_dump_vmcb(__func__, vmcb);
|
||||
svm_dump_regs(__func__, ®s);
|
||||
svm_dump_regs(__func__, regs);
|
||||
svm_dump_inst(svm_rip2pointer(vmcb));
|
||||
svm_inject_exception(v, TRAP_double_fault, 1, 0);
|
||||
break;
|
||||
@@ -2806,11 +2804,11 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs)
|
||||
break;
|
||||
|
||||
case VMEXIT_TASK_SWITCH:
|
||||
__hvm_bug(®s);
|
||||
__hvm_bug(regs);
|
||||
break;
|
||||
|
||||
case VMEXIT_CPUID:
|
||||
svm_vmexit_do_cpuid(vmcb, regs.eax, ®s);
|
||||
svm_vmexit_do_cpuid(vmcb, regs->eax, regs);
|
||||
break;
|
||||
|
||||
case VMEXIT_HLT:
|
||||
@@ -2818,60 +2816,60 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs)
|
||||
break;
|
||||
|
||||
case VMEXIT_INVLPG:
|
||||
svm_handle_invlpg(0, ®s);
|
||||
svm_handle_invlpg(0, regs);
|
||||
break;
|
||||
|
||||
case VMEXIT_INVLPGA:
|
||||
svm_handle_invlpg(1, ®s);
|
||||
svm_handle_invlpg(1, regs);
|
||||
break;
|
||||
|
||||
case VMEXIT_VMMCALL:
|
||||
svm_do_vmmcall(v, ®s);
|
||||
svm_do_vmmcall(v, regs);
|
||||
break;
|
||||
|
||||
case VMEXIT_CR0_READ:
|
||||
svm_cr_access(v, 0, TYPE_MOV_FROM_CR, ®s);
|
||||
svm_cr_access(v, 0, TYPE_MOV_FROM_CR, regs);
|
||||
break;
|
||||
|
||||
case VMEXIT_CR2_READ:
|
||||
svm_cr_access(v, 2, TYPE_MOV_FROM_CR, ®s);
|
||||
svm_cr_access(v, 2, TYPE_MOV_FROM_CR, regs);
|
||||
break;
|
||||
|
||||
case VMEXIT_CR3_READ:
|
||||
svm_cr_access(v, 3, TYPE_MOV_FROM_CR, ®s);
|
||||
svm_cr_access(v, 3, TYPE_MOV_FROM_CR, regs);
|
||||
break;
|
||||
|
||||
case VMEXIT_CR4_READ:
|
||||
svm_cr_access(v, 4, TYPE_MOV_FROM_CR, ®s);
|
||||
svm_cr_access(v, 4, TYPE_MOV_FROM_CR, regs);
|
||||
break;
|
||||
|
||||
case VMEXIT_CR8_READ:
|
||||
svm_cr_access(v, 8, TYPE_MOV_FROM_CR, ®s);
|
||||
svm_cr_access(v, 8, TYPE_MOV_FROM_CR, regs);
|
||||
break;
|
||||
|
||||
case VMEXIT_CR0_WRITE:
|
||||
svm_cr_access(v, 0, TYPE_MOV_TO_CR, ®s);
|
||||
svm_cr_access(v, 0, TYPE_MOV_TO_CR, regs);
|
||||
break;
|
||||
|
||||
case VMEXIT_CR2_WRITE:
|
||||
svm_cr_access(v, 2, TYPE_MOV_TO_CR, ®s);
|
||||
svm_cr_access(v, 2, TYPE_MOV_TO_CR, regs);
|
||||
break;
|
||||
|
||||
case VMEXIT_CR3_WRITE:
|
||||
svm_cr_access(v, 3, TYPE_MOV_TO_CR, ®s);
|
||||
svm_cr_access(v, 3, TYPE_MOV_TO_CR, regs);
|
||||
local_flush_tlb();
|
||||
break;
|
||||
|
||||
case VMEXIT_CR4_WRITE:
|
||||
svm_cr_access(v, 4, TYPE_MOV_TO_CR, ®s);
|
||||
svm_cr_access(v, 4, TYPE_MOV_TO_CR, regs);
|
||||
break;
|
||||
|
||||
case VMEXIT_CR8_WRITE:
|
||||
svm_cr_access(v, 8, TYPE_MOV_TO_CR, ®s);
|
||||
svm_cr_access(v, 8, TYPE_MOV_TO_CR, regs);
|
||||
break;
|
||||
|
||||
case VMEXIT_DR0_WRITE ... VMEXIT_DR7_WRITE:
|
||||
svm_dr_access(v, ®s);
|
||||
svm_dr_access(v, regs);
|
||||
break;
|
||||
|
||||
case VMEXIT_IOIO:
|
||||
@@ -2879,7 +2877,7 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs)
|
||||
break;
|
||||
|
||||
case VMEXIT_MSR:
|
||||
svm_do_msr_access(v, ®s);
|
||||
svm_do_msr_access(v, regs);
|
||||
break;
|
||||
|
||||
case VMEXIT_SHUTDOWN:
|
||||
@@ -2888,11 +2886,10 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs)
|
||||
break;
|
||||
|
||||
default:
|
||||
printk("unexpected VMEXIT: exit reason = 0x%x, exitinfo1 = %llx, "
|
||||
"exitinfo2 = %llx\n", exit_reason,
|
||||
(unsigned long long)vmcb->exitinfo1,
|
||||
(unsigned long long)vmcb->exitinfo2);
|
||||
__hvm_bug(®s); /* should not happen */
|
||||
printk("unexpected VMEXIT: exit reason = 0x%x, exitinfo1 = %"PRIx64", "
|
||||
"exitinfo2 = %"PRIx64"\n", exit_reason,
|
||||
(u64)vmcb->exitinfo1, (u64)vmcb->exitinfo2);
|
||||
__hvm_bug(regs); /* should not happen */
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2900,7 +2897,7 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs)
|
||||
if (do_debug)
|
||||
{
|
||||
printk("%s: Done switch on vmexit_code\n", __func__);
|
||||
svm_dump_regs(__func__, ®s);
|
||||
svm_dump_regs(__func__, regs);
|
||||
}
|
||||
|
||||
if (do_debug)
|
||||
|
||||
@@ -126,7 +126,10 @@ ENTRY(svm_asm_do_launch)
|
||||
|
||||
HVM_SAVE_ALL_NOSEGREGS
|
||||
STGI
|
||||
movl %esp,%eax
|
||||
push %eax
|
||||
call svm_vmexit_handler
|
||||
addl $4,%esp
|
||||
jmp svm_asm_do_resume
|
||||
|
||||
ALIGN
|
||||
|
||||
@@ -144,6 +144,7 @@ ENTRY(svm_asm_do_launch)
|
||||
VMLOAD
|
||||
|
||||
STGI
|
||||
movq %rsp,%rdi
|
||||
call svm_vmexit_handler
|
||||
jmp svm_asm_do_resume
|
||||
|
||||
|
||||
+30
-30
@@ -2111,7 +2111,7 @@ static void vmx_reflect_exception(struct vcpu *v)
|
||||
}
|
||||
}
|
||||
|
||||
asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs)
|
||||
asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
|
||||
{
|
||||
unsigned int exit_reason;
|
||||
unsigned long exit_qualification, rip, inst_len = 0;
|
||||
@@ -2182,16 +2182,16 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs)
|
||||
#ifdef XEN_DEBUGGER
|
||||
case TRAP_debug:
|
||||
{
|
||||
save_cpu_user_regs(®s);
|
||||
pdb_handle_exception(1, ®s, 1);
|
||||
restore_cpu_user_regs(®s);
|
||||
save_cpu_user_regs(regs);
|
||||
pdb_handle_exception(1, regs, 1);
|
||||
restore_cpu_user_regs(regs);
|
||||
break;
|
||||
}
|
||||
case TRAP_int3:
|
||||
{
|
||||
save_cpu_user_regs(®s);
|
||||
pdb_handle_exception(3, ®s, 1);
|
||||
restore_cpu_user_regs(®s);
|
||||
save_cpu_user_regs(regs);
|
||||
pdb_handle_exception(3, regs, 1);
|
||||
restore_cpu_user_regs(regs);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
@@ -2201,7 +2201,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs)
|
||||
|
||||
if ( test_bit(_DOMF_debugging, &v->domain->domain_flags) )
|
||||
{
|
||||
store_cpu_user_regs(®s);
|
||||
store_cpu_user_regs(regs);
|
||||
domain_pause_for_debugger();
|
||||
__vm_clear_bit(GUEST_PENDING_DBG_EXCEPTIONS,
|
||||
PENDING_DEBUG_EXC_BS);
|
||||
@@ -2232,29 +2232,29 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs)
|
||||
case TRAP_page_fault:
|
||||
{
|
||||
__vmread(EXIT_QUALIFICATION, &va);
|
||||
__vmread(VM_EXIT_INTR_ERROR_CODE, ®s.error_code);
|
||||
__vmread(VM_EXIT_INTR_ERROR_CODE, ®s->error_code);
|
||||
|
||||
TRACE_VMEXIT(3,regs.error_code);
|
||||
TRACE_VMEXIT(4,va);
|
||||
TRACE_VMEXIT(3, regs->error_code);
|
||||
TRACE_VMEXIT(4, va);
|
||||
|
||||
HVM_DBG_LOG(DBG_LEVEL_VMMU,
|
||||
"eax=%lx, ebx=%lx, ecx=%lx, edx=%lx, esi=%lx, edi=%lx",
|
||||
(unsigned long)regs.eax, (unsigned long)regs.ebx,
|
||||
(unsigned long)regs.ecx, (unsigned long)regs.edx,
|
||||
(unsigned long)regs.esi, (unsigned long)regs.edi);
|
||||
(unsigned long)regs->eax, (unsigned long)regs->ebx,
|
||||
(unsigned long)regs->ecx, (unsigned long)regs->edx,
|
||||
(unsigned long)regs->esi, (unsigned long)regs->edi);
|
||||
|
||||
if ( !vmx_do_page_fault(va, ®s) ) {
|
||||
/*
|
||||
* Inject #PG using Interruption-Information Fields
|
||||
*/
|
||||
vmx_inject_hw_exception(v, TRAP_page_fault, regs.error_code);
|
||||
if ( !vmx_do_page_fault(va, regs) )
|
||||
{
|
||||
/* Inject #PG using Interruption-Information Fields. */
|
||||
vmx_inject_hw_exception(v, TRAP_page_fault, regs->error_code);
|
||||
v->arch.hvm_vmx.cpu_cr2 = va;
|
||||
TRACE_3D(TRC_VMX_INT, v->domain->domain_id, TRAP_page_fault, va);
|
||||
TRACE_3D(TRC_VMX_INT, v->domain->domain_id,
|
||||
TRAP_page_fault, va);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TRAP_nmi:
|
||||
do_nmi(®s);
|
||||
do_nmi(regs);
|
||||
break;
|
||||
default:
|
||||
vmx_reflect_exception(v);
|
||||
@@ -2263,7 +2263,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs)
|
||||
break;
|
||||
}
|
||||
case EXIT_REASON_EXTERNAL_INTERRUPT:
|
||||
vmx_vmexit_do_extint(®s);
|
||||
vmx_vmexit_do_extint(regs);
|
||||
break;
|
||||
case EXIT_REASON_TRIPLE_FAULT:
|
||||
domain_crash_synchronous();
|
||||
@@ -2280,7 +2280,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs)
|
||||
case EXIT_REASON_CPUID:
|
||||
inst_len = __get_instruction_length(); /* Safe: CPUID */
|
||||
__update_guest_eip(inst_len);
|
||||
vmx_vmexit_do_cpuid(®s);
|
||||
vmx_vmexit_do_cpuid(regs);
|
||||
break;
|
||||
case EXIT_REASON_HLT:
|
||||
inst_len = __get_instruction_length(); /* Safe: HLT */
|
||||
@@ -2302,7 +2302,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs)
|
||||
__update_guest_eip(inst_len);
|
||||
__vmread(GUEST_RIP, &rip);
|
||||
__vmread(EXIT_QUALIFICATION, &exit_qualification);
|
||||
hvm_do_hypercall(®s);
|
||||
hvm_do_hypercall(regs);
|
||||
break;
|
||||
}
|
||||
case EXIT_REASON_CR_ACCESS:
|
||||
@@ -2310,15 +2310,15 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs)
|
||||
__vmread(GUEST_RIP, &rip);
|
||||
__vmread(EXIT_QUALIFICATION, &exit_qualification);
|
||||
inst_len = __get_instruction_length(); /* Safe: MOV Cn, LMSW, CLTS */
|
||||
if ( vmx_cr_access(exit_qualification, ®s) )
|
||||
if ( vmx_cr_access(exit_qualification, regs) )
|
||||
__update_guest_eip(inst_len);
|
||||
TRACE_VMEXIT(3,regs.error_code);
|
||||
TRACE_VMEXIT(4,exit_qualification);
|
||||
TRACE_VMEXIT(3, regs->error_code);
|
||||
TRACE_VMEXIT(4, exit_qualification);
|
||||
break;
|
||||
}
|
||||
case EXIT_REASON_DR_ACCESS:
|
||||
__vmread(EXIT_QUALIFICATION, &exit_qualification);
|
||||
vmx_dr_access(exit_qualification, ®s);
|
||||
vmx_dr_access(exit_qualification, regs);
|
||||
break;
|
||||
case EXIT_REASON_IO_INSTRUCTION:
|
||||
__vmread(EXIT_QUALIFICATION, &exit_qualification);
|
||||
@@ -2329,12 +2329,12 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs)
|
||||
case EXIT_REASON_MSR_READ:
|
||||
inst_len = __get_instruction_length(); /* Safe: RDMSR */
|
||||
__update_guest_eip(inst_len);
|
||||
vmx_do_msr_read(®s);
|
||||
vmx_do_msr_read(regs);
|
||||
break;
|
||||
case EXIT_REASON_MSR_WRITE:
|
||||
inst_len = __get_instruction_length(); /* Safe: WRMSR */
|
||||
__update_guest_eip(inst_len);
|
||||
vmx_do_msr_write(®s);
|
||||
vmx_do_msr_write(regs);
|
||||
break;
|
||||
case EXIT_REASON_MWAIT_INSTRUCTION:
|
||||
case EXIT_REASON_MONITOR_INSTRUCTION:
|
||||
|
||||
@@ -82,7 +82,10 @@ ENTRY(vmx_asm_vmexit_handler)
|
||||
/* selectors are restored/saved by VMX */
|
||||
HVM_SAVE_ALL_NOSEGREGS
|
||||
call vmx_trace_vmexit
|
||||
movl %esp,%eax
|
||||
push %eax
|
||||
call vmx_vmexit_handler
|
||||
addl $4,%esp
|
||||
jmp vmx_asm_do_vmentry
|
||||
|
||||
ALIGN
|
||||
|
||||
@@ -93,6 +93,7 @@ ENTRY(vmx_asm_vmexit_handler)
|
||||
/* selectors are restored/saved by VMX */
|
||||
HVM_SAVE_ALL_NOSEGREGS
|
||||
call vmx_trace_vmexit
|
||||
movq %rsp,%rdi
|
||||
call vmx_vmexit_handler
|
||||
jmp vmx_asm_do_vmentry
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ enum hval_bitmaps {
|
||||
extern unsigned int opt_hvm_debug_level;
|
||||
#define HVM_DBG_LOG(level, _f, _a...) \
|
||||
do { \
|
||||
if ( (level) & opt_hvm_debug_level ) \
|
||||
if ( unlikely((level) & opt_hvm_debug_level) ) \
|
||||
printk("[HVM:%d.%d] <%s> " _f "\n", \
|
||||
current->domain->domain_id, current->vcpu_id, __func__, \
|
||||
## _a); \
|
||||
|
||||