[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-3.0.3-testing] [HVM] Avoid mis-optimisation of the SVM/VMX exit handlers
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1159439115 -3600 # Node ID 88418d7f22f2021daa5f7d4041dde6b22d84cada # Parent e759cc598822206629c2cfc149f5208be5528763 [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@xxxxxxxxxxxxx> --- xen/arch/x86/hvm/svm/svm.c | 149 +++++++++++++++++------------------- xen/arch/x86/hvm/svm/x86_32/exits.S | 3 xen/arch/x86/hvm/svm/x86_64/exits.S | 1 xen/arch/x86/hvm/vmx/vmx.c | 64 +++++++-------- xen/arch/x86/hvm/vmx/x86_32/exits.S | 3 xen/arch/x86/hvm/vmx/x86_64/exits.S | 1 xen/include/asm-x86/hvm/support.h | 2 7 files changed, 114 insertions(+), 109 deletions(-) diff -r e759cc598822 -r 88418d7f22f2 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Thu Sep 28 10:10:59 2006 +0100 +++ b/xen/arch/x86/hvm/svm/svm.c Thu Sep 28 11:25:15 2006 +0100 @@ -2564,9 +2564,7 @@ void walk_shadow_and_guest_pt(unsigned l #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(struc 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(struc 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(struc 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(struc (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(struc 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(struc 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(struc 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); - - if (!(error = svm_do_page_fault(va, ®s))) + (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, 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(struc 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(struc 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(struc 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(struc 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(struc 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(struc 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) diff -r e759cc598822 -r 88418d7f22f2 xen/arch/x86/hvm/svm/x86_32/exits.S --- a/xen/arch/x86/hvm/svm/x86_32/exits.S Thu Sep 28 10:10:59 2006 +0100 +++ b/xen/arch/x86/hvm/svm/x86_32/exits.S Thu Sep 28 11:25:15 2006 +0100 @@ -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 diff -r e759cc598822 -r 88418d7f22f2 xen/arch/x86/hvm/svm/x86_64/exits.S --- a/xen/arch/x86/hvm/svm/x86_64/exits.S Thu Sep 28 10:10:59 2006 +0100 +++ b/xen/arch/x86/hvm/svm/x86_64/exits.S Thu Sep 28 11:25:15 2006 +0100 @@ -144,6 +144,7 @@ ENTRY(svm_asm_do_launch) VMLOAD STGI + movq %rsp,%rdi call svm_vmexit_handler jmp svm_asm_do_resume diff -r e759cc598822 -r 88418d7f22f2 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Thu Sep 28 10:10:59 2006 +0100 +++ b/xen/arch/x86/hvm/vmx/vmx.c Thu Sep 28 11:25:15 2006 +0100 @@ -2111,7 +2111,7 @@ static void vmx_reflect_exception(struct } } -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(struc #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(struc 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(struc case TRAP_page_fault: { __vmread(EXIT_QUALIFICATION, &va); - __vmread(VM_EXIT_INTR_ERROR_CODE, ®s.error_code); - - TRACE_VMEXIT(3,regs.error_code); - TRACE_VMEXIT(4,va); + __vmread(VM_EXIT_INTR_ERROR_CODE, ®s->error_code); + + 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); - - if ( !vmx_do_page_fault(va, ®s) ) { - /* - * Inject #PG using Interruption-Information Fields - */ - vmx_inject_hw_exception(v, TRAP_page_fault, regs.error_code); + (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, 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(struc 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(struc 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(struc __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(struc __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(struc 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: diff -r e759cc598822 -r 88418d7f22f2 xen/arch/x86/hvm/vmx/x86_32/exits.S --- a/xen/arch/x86/hvm/vmx/x86_32/exits.S Thu Sep 28 10:10:59 2006 +0100 +++ b/xen/arch/x86/hvm/vmx/x86_32/exits.S Thu Sep 28 11:25:15 2006 +0100 @@ -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 diff -r e759cc598822 -r 88418d7f22f2 xen/arch/x86/hvm/vmx/x86_64/exits.S --- a/xen/arch/x86/hvm/vmx/x86_64/exits.S Thu Sep 28 10:10:59 2006 +0100 +++ b/xen/arch/x86/hvm/vmx/x86_64/exits.S Thu Sep 28 11:25:15 2006 +0100 @@ -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 diff -r e759cc598822 -r 88418d7f22f2 xen/include/asm-x86/hvm/support.h --- a/xen/include/asm-x86/hvm/support.h Thu Sep 28 10:10:59 2006 +0100 +++ b/xen/include/asm-x86/hvm/support.h Thu Sep 28 11:25:15 2006 +0100 @@ -118,7 +118,7 @@ extern unsigned int opt_hvm_debug_level; 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); \ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |