Am 19.03.2009 schrieb Avi Kivity:
This bit is broken. The original code:
if (vcpu->arch.rmode.active &&
handle_rmode_exception(vcpu, intr_info & INTR_INFO_VECTOR_MASK,
error_code)) {
Only executes handle_rmode_exception() if rmode.active is true. Your
code executes it unconditionally.
You can write it as
if (vcpu->arch.rmode.active &&
(retval = handle_rmode_exception(vcpu, intr_info &
INTR_INFO_VECTOR_MASK,
error_code))) {
Please check for other cases as well. As it happens, the guest crashed
immediately after entering protected mode (so rmode.active became false,
triggering the bug).
ooooooops - stupid mistake :-I
that was it...
vmx.c now looks as this :
....
2637 static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2638 {
2639 struct vcpu_vmx *vmx = to_vmx(vcpu);
2640 u32 intr_info, ex_no, error_code;
2641 unsigned long cr2, rip, dr6;
2642 u32 vect_info;
2643 enum emulation_result er;
2644
2645 vect_info = vmx->idt_vectoring_info;
2646 intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
2647
2648 printk(KERN_ERR "vmx->handle_exception 00 : giving some infos\n");
2649 printk(KERN_ERR "vmx->handle_exception 01 : vect_info: 0x%x\n",vect_info);
2650 printk(KERN_ERR "vmx->handle_exception 02 : intr_info: 0x%x, is_page_fault()==%i\n",intr_info,is_page_fault(intr_info));
2651
2652 if ((vect_info & VECTORING_INFO_VALID_MASK) &&
2653 !is_page_fault(intr_info))
2654 printk(KERN_ERR "%s: unexpected, vectoring info 0x%x "
2655 "intr info 0x%x\n", __func__, vect_info, intr_info);
2656
2657 printk(KERN_ERR "vmx->handle_exception 03 : irq_chip_in_kernel()==%i\n",irqchip_in_kernel(vcpu->kvm));
2658 printk(KERN_ERR "vmx->handle_exception 04 : is_external_interrupt()==%i\n",is_external_interrupt(vect_info));
2659 if (!irqchip_in_kernel(vcpu->kvm) && is_external_interrupt(vect_info)) {
2660 int irq = vect_info & VECTORING_INFO_VECTOR_MASK;
2661 printk(KERN_ERR "vmx->handle_exception 05 : irq: 0x%x\n",irq);
2662 set_bit(irq, vcpu->arch.irq_pending);
2663 set_bit(irq / BITS_PER_LONG, &vcpu->arch.irq_summary);
2664 }
2665
2666 if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR){
2667 printk(KERN_ERR "vmx->handle_exception 06 : already handled by vmx_vcpu_run()\n");
2668 return 1; /* already handled by vmx_vcpu_run() */
2669 }
2670
2671 if (is_no_device(intr_info)) {
2672 printk(KERN_ERR "vmx->handle_exception 07 : is_no_device(intr_info)\n");
2673 vmx_fpu_activate(vcpu);
2674 return 1;
2675 }
2676
2677 if (is_invalid_opcode(intr_info)) {
2678 printk(KERN_ERR "vmx->handle_exception 08 : is_invalid_opcode(intr_info)\n");
2679 er = emulate_instruction(vcpu, kvm_run, 0, 0, EMULTYPE_TRAP_UD);
2680 if (er != EMULATE_DONE) {
2681 printk(KERN_ERR "vmx->handle_exception 09 : emulation not done. enqueueing exception\n");
2682 kvm_queue_exception(vcpu, UD_VECTOR);
2683 }
2684 return 1;
2685 }
2686
2687 error_code = 0;
2688 rip = kvm_rip_read(vcpu);
2689 printk(KERN_ERR "vmx->handle_exception 0a : kvm_rip_read(vcpu) returned 0x%lx\n",rip);
2690 if (intr_info & INTR_INFO_DELIVER_CODE_MASK)
2691 error_code = vmcs_read32(VM_EXIT_INTR_ERROR_CODE);
2692 if (is_page_fault(intr_info)) {
2693 printk(KERN_ERR "vmx->handle_exception 0b : is_page_fault(intr_info) returned 0x%x\n",is_page_fault(intr_info));
2694 /* EPT won't cause page fault directly */
2695 if (vm_need_ept())
2696 BUG();
2697 cr2 = vmcs_readl(EXIT_QUALIFICATION);
2698 printk(KERN_ERR "vmx->handle_exception 0c : vmcs_readl(EXIT_QUALIFICATION) returned 0x%lx\n",cr2);
2699 KVMTRACE_3D(PAGE_FAULT, vcpu, error_code, (u32)cr2,
2700 (u32)((u64)cr2 >> 32), handler);
2701 if (vcpu->arch.interrupt.pending || vcpu->arch.exception.pending){
2702 printk(KERN_ERR "vmx->handle_exception 0d : interrupt.pending or exception.pending\n");
2703 kvm_mmu_unprotect_page_virt(vcpu, cr2);
2704 }
2705 int retval = kvm_mmu_page_fault(vcpu, cr2, error_code);
2706 printk(KERN_ERR "vmx->handle_exception 0e : kvm_mmu_page_fault(vcpu, cr2, error_code) returned 0x%x\n",retval);
2707 //return kvm_mmu_page_fault(vcpu, cr2, error_code);
2708 return retval;
2709 }
2710
2711 printk(KERN_ERR "vmx->handle_exception 0f : vcpu->arch.rmode.active: 0x%x\n",vcpu->arch.rmode.active);
2712 int debug_handle_rmode_exception = 0;
2713 if (vcpu->arch.rmode.active && (debug_handle_rmode_exception = handle_rmode_exception(vcpu, intr_info & INTR_INFO_VECTOR_MASK, error_code))) {
2714 printk(KERN_ERR "vmx->handle_exception 10 : handle_rmode_exception(vcpu, intr_info & INTR_INFO_VECTOR_MASK, error_code) returned 0x%x\n",debug_handle_rmode_exception);
2715 if (vcpu->arch.halt_request) {
2716 printk(KERN_ERR "vmx->handle_exception 11 : vcpu->arch.halt_request: 0x%x, resetting to 0\n",vcpu->arch.halt_request);
2717 vcpu->arch.halt_request = 0;
2718 int retval = kvm_emulate_halt(vcpu);
2719 printk(KERN_ERR "vmx->handle_exception 12 : kvm_emulate_halt(vcpu) returned 0x%x\n",retval);
2720 // return kvm_emulate_halt(vcpu);
2721 return retval;
2722 }
2723 return 1;
2724 }
2725
2726 ex_no = intr_info & INTR_INFO_VECTOR_MASK;
2727 switch (ex_no) {
2728 case DB_VECTOR:
2729 dr6 = vmcs_readl(EXIT_QUALIFICATION);
2730 printk(KERN_ERR "vmx->handle_exception 13 : ex_no==DB_VECTOR==0x%x, vmcs_readl(EXIT_QUALIFICATION) returned 0x%lx\n",ex_no,dr6);
2731 if (!(vcpu->guest_debug &
2732 (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) {
2733 vcpu->arch.dr6 = dr6 | DR6_FIXED_1;
2734 printk(KERN_ERR "vmx->handle_exception 14 : enqueuing exception\n");
2735 kvm_queue_exception(vcpu, DB_VECTOR);
2736 return 1;
2737 }
2738 kvm_run->debug.arch.dr6 = dr6 | DR6_FIXED_1;
2739 kvm_run->debug.arch.dr7 = vmcs_readl(GUEST_DR7);
2740 /* fall through */
2741 case BP_VECTOR:
2742 if(ex_no == BP_VECTOR)printk(KERN_ERR "vmx->handle_exception 15 : ex_no==BP_VECTOR==0x%x\n",ex_no);
2743 kvm_run->exit_reason = KVM_EXIT_DEBUG;
2744 unsigned long debug_vmcs_readl = vmcs_readl(GUEST_CS_BASE);
2745 printk(KERN_ERR "vmx->handle_exception 16 : vmcs_readl(GUEST_CS_BASE) returned 0x%lx\n",debug_vmcs_readl);
2746 kvm_run->debug.arch.pc = debug_vmcs_readl + rip;
2747 kvm_run->debug.arch.exception = ex_no;
2748 break;
2749 default:
2750 printk(KERN_ERR "vmx->handle_exception 17 : unknown ex_no: 0x%x, error_code: 0x%x\n",ex_no,error_code);
2751 kvm_run->exit_reason = KVM_EXIT_EXCEPTION;
2752 kvm_run->ex.exception = ex_no;
2753 kvm_run->ex.error_code = error_code;
2754 break;
2755 }
2756 printk(KERN_ERR "vmx->handle_exception 18 : reached end of handle_exception - returning 0\n");
2757 return 0;
2758 }
....
# dmesg :
.....
[101324.097856] vmx->handle_exception 00 : giving some infos
[101324.097861] vmx->handle_exception 01 : vect_info: 0x0
[101324.097865] vmx->handle_exception 02 : intr_info: 0x80000b0d, is_page_fault()==0
[101324.097871] vmx->handle_exception 03 : irq_chip_in_kernel()==1
[101324.097876] vmx->handle_exception 04 : is_external_interrupt()==0
[101324.097881] vmx->handle_exception 0a : kvm_rip_read(vcpu) returned 0x3154
[101324.097886] vmx->handle_exception 0f : vcpu->arch.rmode.active: 0x1
[101324.097891] vmx->handle_exception 10 : handle_rmode_exception(vcpu, intr_info & INTR_INFO_VECTOR_MASK, error_code) returned 0x1
[101324.097898] returning from kvm_handle_exit, cause 3, retval = 1, exit_reason = 0
[101324.097912] vmx->handle_exception 00 : giving some infos
[101324.097917] vmx->handle_exception 01 : vect_info: 0x0
[101324.097922] vmx->handle_exception 02 : intr_info: 0x80000b0d, is_page_fault()==0
[101324.097927] vmx->handle_exception 03 : irq_chip_in_kernel()==1
[101324.097932] vmx->handle_exception 04 : is_external_interrupt()==0
[101324.097937] vmx->handle_exception 0a : kvm_rip_read(vcpu) returned 0x3154
[101324.097942] vmx->handle_exception 0f : vcpu->arch.rmode.active: 0x1
[101324.097947] vmx->handle_exception 10 : handle_rmode_exception(vcpu, intr_info & INTR_INFO_VECTOR_MASK, error_code) returned 0x1
[101324.097955] returning from kvm_handle_exit, cause 3, retval = 1, exit_reason = 0
[101324.097968] vmx->handle_exception 00 : giving some infos
[101324.097973] vmx->handle_exception 01 : vect_info: 0x0
[101324.097978] vmx->handle_exception 02 : intr_info: 0x80000b0d, is_page_fault()==0
[101324.097983] vmx->handle_exception 03 : irq_chip_in_kernel()==1
[101324.097988] vmx->handle_exception 04 : is_external_interrupt()==0
[101324.097993] vmx->handle_exception 0a : kvm_rip_read(vcpu) returned 0x3154
[101324.097998] vmx->handle_exception 0f : vcpu->arch.rmode.active: 0x1
[101324.098039] vmx->handle_exception 10 : handle_rmode_exception(vcpu, intr_info & INTR_INFO_VECTOR_MASK, error_code) returned 0x1
[101324.098050] returning from kvm_handle_exit, cause 3, retval = 1, exit_reason = 0
.... until kvm get's killed