Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm

Pull kvm fixes from Paolo Bonzini:
"A new testcase for guest debugging (gdbstub) that exposed a bunch of
bugs, mostly for AMD processors. And a few other x86 fixes"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
KVM: x86: Fix off-by-one error in kvm_vcpu_ioctl_x86_setup_mce
KVM: x86: Fix pkru save/restore when guest CR4.PKE=0, move it to x86.c
KVM: SVM: Disable AVIC before setting V_IRQ
KVM: Introduce kvm_make_all_cpus_request_except()
KVM: VMX: pass correct DR6 for GD userspace exit
KVM: x86, SVM: isolate vcpu->arch.dr6 from vmcb->save.dr6
KVM: SVM: keep DR6 synchronized with vcpu->arch.dr6
KVM: nSVM: trap #DB and #BP to userspace if guest debugging is on
KVM: selftests: Add KVM_SET_GUEST_DEBUG test
KVM: X86: Fix single-step with KVM_SET_GUEST_DEBUG
KVM: X86: Set RTM for DB_VECTOR too for KVM_EXIT_DEBUG
KVM: x86: fix DR6 delivery for various cases of #DB injection
KVM: X86: Declare KVM_CAP_SET_GUEST_DEBUG properly

+325 -88
+2 -2
arch/x86/include/asm/kvm_host.h
··· 578 578 unsigned long cr4; 579 579 unsigned long cr4_guest_owned_bits; 580 580 unsigned long cr8; 581 + u32 host_pkru; 581 582 u32 pkru; 582 583 u32 hflags; 583 584 u64 efer; ··· 1094 1093 void (*set_idt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); 1095 1094 void (*get_gdt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); 1096 1095 void (*set_gdt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); 1097 - u64 (*get_dr6)(struct kvm_vcpu *vcpu); 1098 - void (*set_dr6)(struct kvm_vcpu *vcpu, unsigned long value); 1099 1096 void (*sync_dirty_debug_regs)(struct kvm_vcpu *vcpu); 1100 1097 void (*set_dr7)(struct kvm_vcpu *vcpu, unsigned long value); 1101 1098 void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg); ··· 1448 1449 1449 1450 void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr); 1450 1451 void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); 1452 + void kvm_queue_exception_p(struct kvm_vcpu *vcpu, unsigned nr, unsigned long payload); 1451 1453 void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr); 1452 1454 void kvm_requeue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); 1453 1455 void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault);
+1 -1
arch/x86/kvm/hyperv.c
··· 1427 1427 */ 1428 1428 kvm_make_vcpus_request_mask(kvm, 1429 1429 KVM_REQ_TLB_FLUSH | KVM_REQUEST_NO_WAKEUP, 1430 - vcpu_mask, &hv_vcpu->tlb_flush); 1430 + NULL, vcpu_mask, &hv_vcpu->tlb_flush); 1431 1431 1432 1432 ret_success: 1433 1433 /* We always do full TLB flush, set rep_done = rep_cnt. */
+31 -8
arch/x86/kvm/svm/nested.c
··· 19 19 #include <linux/kernel.h> 20 20 21 21 #include <asm/msr-index.h> 22 + #include <asm/debugreg.h> 22 23 23 24 #include "kvm_emulate.h" 24 25 #include "trace.h" ··· 268 267 svm->vmcb->save.rsp = nested_vmcb->save.rsp; 269 268 svm->vmcb->save.rip = nested_vmcb->save.rip; 270 269 svm->vmcb->save.dr7 = nested_vmcb->save.dr7; 271 - svm->vmcb->save.dr6 = nested_vmcb->save.dr6; 270 + svm->vcpu.arch.dr6 = nested_vmcb->save.dr6; 272 271 svm->vmcb->save.cpl = nested_vmcb->save.cpl; 273 272 274 273 svm->nested.vmcb_msrpm = nested_vmcb->control.msrpm_base_pa & ~0x0fffULL; ··· 483 482 nested_vmcb->save.rsp = vmcb->save.rsp; 484 483 nested_vmcb->save.rax = vmcb->save.rax; 485 484 nested_vmcb->save.dr7 = vmcb->save.dr7; 486 - nested_vmcb->save.dr6 = vmcb->save.dr6; 485 + nested_vmcb->save.dr6 = svm->vcpu.arch.dr6; 487 486 nested_vmcb->save.cpl = vmcb->save.cpl; 488 487 489 488 nested_vmcb->control.int_ctl = vmcb->control.int_ctl; ··· 607 606 /* DB exceptions for our internal use must not cause vmexit */ 608 607 static int nested_svm_intercept_db(struct vcpu_svm *svm) 609 608 { 610 - unsigned long dr6; 609 + unsigned long dr6 = svm->vmcb->save.dr6; 610 + 611 + /* Always catch it and pass it to userspace if debugging. */ 612 + if (svm->vcpu.guest_debug & 613 + (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) 614 + return NESTED_EXIT_HOST; 611 615 612 616 /* if we're not singlestepping, it's not ours */ 613 617 if (!svm->nmi_singlestep) 614 - return NESTED_EXIT_DONE; 618 + goto reflected_db; 615 619 616 620 /* if it's not a singlestep exception, it's not ours */ 617 - if (kvm_get_dr(&svm->vcpu, 6, &dr6)) 618 - return NESTED_EXIT_DONE; 619 621 if (!(dr6 & DR6_BS)) 620 - return NESTED_EXIT_DONE; 622 + goto reflected_db; 621 623 622 624 /* if the guest is singlestepping, it should get the vmexit */ 623 625 if (svm->nmi_singlestep_guest_rflags & X86_EFLAGS_TF) { 624 626 disable_nmi_singlestep(svm); 625 - return NESTED_EXIT_DONE; 627 + goto reflected_db; 626 628 } 627 629 628 630 /* it's ours, the nested hypervisor must not see this one */ 629 631 return NESTED_EXIT_HOST; 632 + 633 + reflected_db: 634 + /* 635 + * Synchronize guest DR6 here just like in kvm_deliver_exception_payload; 636 + * it will be moved into the nested VMCB by nested_svm_vmexit. Once 637 + * exceptions will be moved to svm_check_nested_events, all this stuff 638 + * will just go away and we could just return NESTED_EXIT_HOST 639 + * unconditionally. db_interception will queue the exception, which 640 + * will be processed by svm_check_nested_events if a nested vmexit is 641 + * required, and we will just use kvm_deliver_exception_payload to copy 642 + * the payload to DR6 before vmexit. 643 + */ 644 + WARN_ON(svm->vcpu.arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT); 645 + svm->vcpu.arch.dr6 &= ~(DR_TRAP_BITS | DR6_RTM); 646 + svm->vcpu.arch.dr6 |= dr6 & ~DR6_FIXED_1; 647 + return NESTED_EXIT_DONE; 630 648 } 631 649 632 650 static int nested_svm_intercept_ioio(struct vcpu_svm *svm) ··· 702 682 if (svm->nested.intercept_exceptions & excp_bits) { 703 683 if (exit_code == SVM_EXIT_EXCP_BASE + DB_VECTOR) 704 684 vmexit = nested_svm_intercept_db(svm); 685 + else if (exit_code == SVM_EXIT_EXCP_BASE + BP_VECTOR && 686 + svm->vcpu.guest_debug & KVM_GUESTDBG_USE_SW_BP) 687 + vmexit = NESTED_EXIT_HOST; 705 688 else 706 689 vmexit = NESTED_EXIT_DONE; 707 690 }
+22 -14
arch/x86/kvm/svm/svm.c
··· 1672 1672 mark_dirty(svm->vmcb, VMCB_ASID); 1673 1673 } 1674 1674 1675 - static u64 svm_get_dr6(struct kvm_vcpu *vcpu) 1675 + static void svm_set_dr6(struct vcpu_svm *svm, unsigned long value) 1676 1676 { 1677 - return to_svm(vcpu)->vmcb->save.dr6; 1678 - } 1677 + struct vmcb *vmcb = svm->vmcb; 1679 1678 1680 - static void svm_set_dr6(struct kvm_vcpu *vcpu, unsigned long value) 1681 - { 1682 - struct vcpu_svm *svm = to_svm(vcpu); 1683 - 1684 - svm->vmcb->save.dr6 = value; 1685 - mark_dirty(svm->vmcb, VMCB_DR); 1679 + if (unlikely(value != vmcb->save.dr6)) { 1680 + vmcb->save.dr6 = value; 1681 + mark_dirty(vmcb, VMCB_DR); 1682 + } 1686 1683 } 1687 1684 1688 1685 static void svm_sync_dirty_debug_regs(struct kvm_vcpu *vcpu) ··· 1690 1693 get_debugreg(vcpu->arch.db[1], 1); 1691 1694 get_debugreg(vcpu->arch.db[2], 2); 1692 1695 get_debugreg(vcpu->arch.db[3], 3); 1693 - vcpu->arch.dr6 = svm_get_dr6(vcpu); 1696 + /* 1697 + * We cannot reset svm->vmcb->save.dr6 to DR6_FIXED_1|DR6_RTM here, 1698 + * because db_interception might need it. We can do it before vmentry. 1699 + */ 1700 + vcpu->arch.dr6 = svm->vmcb->save.dr6; 1694 1701 vcpu->arch.dr7 = svm->vmcb->save.dr7; 1695 - 1696 1702 vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_WONT_EXIT; 1697 1703 set_dr_intercepts(svm); 1698 1704 } ··· 1739 1739 if (!(svm->vcpu.guest_debug & 1740 1740 (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) && 1741 1741 !svm->nmi_singlestep) { 1742 - kvm_queue_exception(&svm->vcpu, DB_VECTOR); 1742 + u32 payload = (svm->vmcb->save.dr6 ^ DR6_RTM) & ~DR6_FIXED_1; 1743 + kvm_queue_exception_p(&svm->vcpu, DB_VECTOR, payload); 1743 1744 return 1; 1744 1745 } 1745 1746 ··· 3318 3317 3319 3318 svm->vmcb->save.cr2 = vcpu->arch.cr2; 3320 3319 3320 + /* 3321 + * Run with all-zero DR6 unless needed, so that we can get the exact cause 3322 + * of a #DB. 3323 + */ 3324 + if (unlikely(svm->vcpu.arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)) 3325 + svm_set_dr6(svm, vcpu->arch.dr6); 3326 + else 3327 + svm_set_dr6(svm, DR6_FIXED_1 | DR6_RTM); 3328 + 3321 3329 clgi(); 3322 3330 kvm_load_guest_xsave_state(vcpu); 3323 3331 ··· 3941 3931 .set_idt = svm_set_idt, 3942 3932 .get_gdt = svm_get_gdt, 3943 3933 .set_gdt = svm_set_gdt, 3944 - .get_dr6 = svm_get_dr6, 3945 - .set_dr6 = svm_set_dr6, 3946 3934 .set_dr7 = svm_set_dr7, 3947 3935 .sync_dirty_debug_regs = svm_sync_dirty_debug_regs, 3948 3936 .cache_reg = svm_cache_reg,
+4 -37
arch/x86/kvm/vmx/vmx.c
··· 1372 1372 1373 1373 vmx_vcpu_pi_load(vcpu, cpu); 1374 1374 1375 - vmx->host_pkru = read_pkru(); 1376 1375 vmx->host_debugctlmsr = get_debugctlmsr(); 1377 1376 } 1378 1377 ··· 4676 4677 dr6 = vmcs_readl(EXIT_QUALIFICATION); 4677 4678 if (!(vcpu->guest_debug & 4678 4679 (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) { 4679 - vcpu->arch.dr6 &= ~DR_TRAP_BITS; 4680 - vcpu->arch.dr6 |= dr6 | DR6_RTM; 4681 4680 if (is_icebp(intr_info)) 4682 4681 WARN_ON(!skip_emulated_instruction(vcpu)); 4683 4682 4684 - kvm_queue_exception(vcpu, DB_VECTOR); 4683 + kvm_queue_exception_p(vcpu, DB_VECTOR, dr6); 4685 4684 return 1; 4686 4685 } 4687 - kvm_run->debug.arch.dr6 = dr6 | DR6_FIXED_1; 4686 + kvm_run->debug.arch.dr6 = dr6 | DR6_FIXED_1 | DR6_RTM; 4688 4687 kvm_run->debug.arch.dr7 = vmcs_readl(GUEST_DR7); 4689 4688 /* fall through */ 4690 4689 case BP_VECTOR: ··· 4926 4929 * guest debugging itself. 4927 4930 */ 4928 4931 if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) { 4929 - vcpu->run->debug.arch.dr6 = vcpu->arch.dr6; 4932 + vcpu->run->debug.arch.dr6 = DR6_BD | DR6_RTM | DR6_FIXED_1; 4930 4933 vcpu->run->debug.arch.dr7 = dr7; 4931 4934 vcpu->run->debug.arch.pc = kvm_get_linear_rip(vcpu); 4932 4935 vcpu->run->debug.arch.exception = DB_VECTOR; 4933 4936 vcpu->run->exit_reason = KVM_EXIT_DEBUG; 4934 4937 return 0; 4935 4938 } else { 4936 - vcpu->arch.dr6 &= ~DR_TRAP_BITS; 4937 - vcpu->arch.dr6 |= DR6_BD | DR6_RTM; 4938 - kvm_queue_exception(vcpu, DB_VECTOR); 4939 + kvm_queue_exception_p(vcpu, DB_VECTOR, DR6_BD); 4939 4940 return 1; 4940 4941 } 4941 4942 } ··· 4962 4967 return 1; 4963 4968 4964 4969 return kvm_skip_emulated_instruction(vcpu); 4965 - } 4966 - 4967 - static u64 vmx_get_dr6(struct kvm_vcpu *vcpu) 4968 - { 4969 - return vcpu->arch.dr6; 4970 - } 4971 - 4972 - static void vmx_set_dr6(struct kvm_vcpu *vcpu, unsigned long val) 4973 - { 4974 4970 } 4975 4971 4976 4972 static void vmx_sync_dirty_debug_regs(struct kvm_vcpu *vcpu) ··· 6563 6577 6564 6578 kvm_load_guest_xsave_state(vcpu); 6565 6579 6566 - if (static_cpu_has(X86_FEATURE_PKU) && 6567 - kvm_read_cr4_bits(vcpu, X86_CR4_PKE) && 6568 - vcpu->arch.pkru != vmx->host_pkru) 6569 - __write_pkru(vcpu->arch.pkru); 6570 - 6571 6580 pt_guest_enter(vmx); 6572 6581 6573 6582 if (vcpu_to_pmu(vcpu)->version) ··· 6651 6670 vcpu->arch.regs_dirty = 0; 6652 6671 6653 6672 pt_guest_exit(vmx); 6654 - 6655 - /* 6656 - * eager fpu is enabled if PKEY is supported and CR4 is switched 6657 - * back on host, so it is safe to read guest PKRU from current 6658 - * XSAVE. 6659 - */ 6660 - if (static_cpu_has(X86_FEATURE_PKU) && 6661 - kvm_read_cr4_bits(vcpu, X86_CR4_PKE)) { 6662 - vcpu->arch.pkru = rdpkru(); 6663 - if (vcpu->arch.pkru != vmx->host_pkru) 6664 - __write_pkru(vmx->host_pkru); 6665 - } 6666 6673 6667 6674 kvm_load_host_xsave_state(vcpu); 6668 6675 ··· 7709 7740 .set_idt = vmx_set_idt, 7710 7741 .get_gdt = vmx_get_gdt, 7711 7742 .set_gdt = vmx_set_gdt, 7712 - .get_dr6 = vmx_get_dr6, 7713 - .set_dr6 = vmx_set_dr6, 7714 7743 .set_dr7 = vmx_set_dr7, 7715 7744 .sync_dirty_debug_regs = vmx_sync_dirty_debug_regs, 7716 7745 .cache_reg = vmx_cache_reg,
+37 -23
arch/x86/kvm/x86.c
··· 572 572 } 573 573 EXPORT_SYMBOL_GPL(kvm_requeue_exception); 574 574 575 - static void kvm_queue_exception_p(struct kvm_vcpu *vcpu, unsigned nr, 576 - unsigned long payload) 575 + void kvm_queue_exception_p(struct kvm_vcpu *vcpu, unsigned nr, 576 + unsigned long payload) 577 577 { 578 578 kvm_multiple_exception(vcpu, nr, false, 0, true, payload, false); 579 579 } 580 + EXPORT_SYMBOL_GPL(kvm_queue_exception_p); 580 581 581 582 static void kvm_queue_exception_e_p(struct kvm_vcpu *vcpu, unsigned nr, 582 583 u32 error_code, unsigned long payload) ··· 837 836 vcpu->arch.ia32_xss != host_xss) 838 837 wrmsrl(MSR_IA32_XSS, vcpu->arch.ia32_xss); 839 838 } 839 + 840 + if (static_cpu_has(X86_FEATURE_PKU) && 841 + (kvm_read_cr4_bits(vcpu, X86_CR4_PKE) || 842 + (vcpu->arch.xcr0 & XFEATURE_MASK_PKRU)) && 843 + vcpu->arch.pkru != vcpu->arch.host_pkru) 844 + __write_pkru(vcpu->arch.pkru); 840 845 } 841 846 EXPORT_SYMBOL_GPL(kvm_load_guest_xsave_state); 842 847 843 848 void kvm_load_host_xsave_state(struct kvm_vcpu *vcpu) 844 849 { 850 + if (static_cpu_has(X86_FEATURE_PKU) && 851 + (kvm_read_cr4_bits(vcpu, X86_CR4_PKE) || 852 + (vcpu->arch.xcr0 & XFEATURE_MASK_PKRU))) { 853 + vcpu->arch.pkru = rdpkru(); 854 + if (vcpu->arch.pkru != vcpu->arch.host_pkru) 855 + __write_pkru(vcpu->arch.host_pkru); 856 + } 857 + 845 858 if (kvm_read_cr4_bits(vcpu, X86_CR4_OSXSAVE)) { 846 859 847 860 if (vcpu->arch.xcr0 != host_xcr0) ··· 1060 1045 } 1061 1046 } 1062 1047 1063 - static void kvm_update_dr6(struct kvm_vcpu *vcpu) 1064 - { 1065 - if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) 1066 - kvm_x86_ops.set_dr6(vcpu, vcpu->arch.dr6); 1067 - } 1068 - 1069 1048 static void kvm_update_dr7(struct kvm_vcpu *vcpu) 1070 1049 { 1071 1050 unsigned long dr7; ··· 1099 1090 if (val & 0xffffffff00000000ULL) 1100 1091 return -1; /* #GP */ 1101 1092 vcpu->arch.dr6 = (val & DR6_VOLATILE) | kvm_dr6_fixed(vcpu); 1102 - kvm_update_dr6(vcpu); 1103 1093 break; 1104 1094 case 5: 1105 1095 /* fall through */ ··· 1134 1126 case 4: 1135 1127 /* fall through */ 1136 1128 case 6: 1137 - if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) 1138 - *val = vcpu->arch.dr6; 1139 - else 1140 - *val = kvm_x86_ops.get_dr6(vcpu); 1129 + *val = vcpu->arch.dr6; 1141 1130 break; 1142 1131 case 5: 1143 1132 /* fall through */ ··· 3563 3558 3564 3559 kvm_x86_ops.vcpu_load(vcpu, cpu); 3565 3560 3561 + /* Save host pkru register if supported */ 3562 + vcpu->arch.host_pkru = read_pkru(); 3563 + 3566 3564 /* Apply any externally detected TSC adjustments (due to suspend) */ 3567 3565 if (unlikely(vcpu->arch.tsc_offset_adjustment)) { 3568 3566 adjust_tsc_offset_host(vcpu, vcpu->arch.tsc_offset_adjustment); ··· 3759 3751 unsigned bank_num = mcg_cap & 0xff, bank; 3760 3752 3761 3753 r = -EINVAL; 3762 - if (!bank_num || bank_num >= KVM_MAX_MCE_BANKS) 3754 + if (!bank_num || bank_num > KVM_MAX_MCE_BANKS) 3763 3755 goto out; 3764 3756 if (mcg_cap & ~(kvm_mce_cap_supported | 0xff | 0xff0000)) 3765 3757 goto out; ··· 4017 4009 memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db)); 4018 4010 kvm_update_dr0123(vcpu); 4019 4011 vcpu->arch.dr6 = dbgregs->dr6; 4020 - kvm_update_dr6(vcpu); 4021 4012 vcpu->arch.dr7 = dbgregs->dr7; 4022 4013 kvm_update_dr7(vcpu); 4023 4014 ··· 6666 6659 6667 6660 if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { 6668 6661 kvm_run->debug.arch.dr6 = DR6_BS | DR6_FIXED_1 | DR6_RTM; 6669 - kvm_run->debug.arch.pc = vcpu->arch.singlestep_rip; 6662 + kvm_run->debug.arch.pc = kvm_get_linear_rip(vcpu); 6670 6663 kvm_run->debug.arch.exception = DB_VECTOR; 6671 6664 kvm_run->exit_reason = KVM_EXIT_DEBUG; 6672 6665 return 0; ··· 6726 6719 vcpu->arch.db); 6727 6720 6728 6721 if (dr6 != 0) { 6729 - vcpu->arch.dr6 &= ~DR_TRAP_BITS; 6730 - vcpu->arch.dr6 |= dr6 | DR6_RTM; 6731 - kvm_queue_exception(vcpu, DB_VECTOR); 6722 + kvm_queue_exception_p(vcpu, DB_VECTOR, dr6); 6732 6723 *r = 1; 6733 6724 return true; 6734 6725 } ··· 8047 8042 zalloc_cpumask_var(&cpus, GFP_ATOMIC); 8048 8043 8049 8044 kvm_make_vcpus_request_mask(kvm, KVM_REQ_SCAN_IOAPIC, 8050 - vcpu_bitmap, cpus); 8045 + NULL, vcpu_bitmap, cpus); 8051 8046 8052 8047 free_cpumask_var(cpus); 8053 8048 } ··· 8077 8072 */ 8078 8073 void kvm_request_apicv_update(struct kvm *kvm, bool activate, ulong bit) 8079 8074 { 8075 + struct kvm_vcpu *except; 8080 8076 unsigned long old, new, expected; 8081 8077 8082 8078 if (!kvm_x86_ops.check_apicv_inhibit_reasons || ··· 8102 8096 trace_kvm_apicv_update_request(activate, bit); 8103 8097 if (kvm_x86_ops.pre_update_apicv_exec_ctrl) 8104 8098 kvm_x86_ops.pre_update_apicv_exec_ctrl(kvm, activate); 8105 - kvm_make_all_cpus_request(kvm, KVM_REQ_APICV_UPDATE); 8099 + 8100 + /* 8101 + * Sending request to update APICV for all other vcpus, 8102 + * while update the calling vcpu immediately instead of 8103 + * waiting for another #VMEXIT to handle the request. 8104 + */ 8105 + except = kvm_get_running_vcpu(); 8106 + kvm_make_all_cpus_request_except(kvm, KVM_REQ_APICV_UPDATE, 8107 + except); 8108 + if (except) 8109 + kvm_vcpu_update_apicv(except); 8106 8110 } 8107 8111 EXPORT_SYMBOL_GPL(kvm_request_apicv_update); 8108 8112 ··· 8436 8420 WARN_ON(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP); 8437 8421 kvm_x86_ops.sync_dirty_debug_regs(vcpu); 8438 8422 kvm_update_dr0123(vcpu); 8439 - kvm_update_dr6(vcpu); 8440 8423 kvm_update_dr7(vcpu); 8441 8424 vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD; 8442 8425 } ··· 9496 9481 memset(vcpu->arch.db, 0, sizeof(vcpu->arch.db)); 9497 9482 kvm_update_dr0123(vcpu); 9498 9483 vcpu->arch.dr6 = DR6_INIT; 9499 - kvm_update_dr6(vcpu); 9500 9484 vcpu->arch.dr7 = DR7_FIXED_1; 9501 9485 kvm_update_dr7(vcpu); 9502 9486
+3
include/linux/kvm_host.h
··· 813 813 void kvm_reload_remote_mmus(struct kvm *kvm); 814 814 815 815 bool kvm_make_vcpus_request_mask(struct kvm *kvm, unsigned int req, 816 + struct kvm_vcpu *except, 816 817 unsigned long *vcpu_bitmap, cpumask_var_t tmp); 817 818 bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req); 819 + bool kvm_make_all_cpus_request_except(struct kvm *kvm, unsigned int req, 820 + struct kvm_vcpu *except); 818 821 bool kvm_make_cpus_request_mask(struct kvm *kvm, unsigned int req, 819 822 unsigned long *vcpu_bitmap); 820 823
+1
tools/testing/selftests/kvm/Makefile
··· 54 54 TEST_GEN_PROGS_x86_64 += x86_64/vmx_set_nested_state_test 55 55 TEST_GEN_PROGS_x86_64 += x86_64/vmx_tsc_adjust_test 56 56 TEST_GEN_PROGS_x86_64 += x86_64/xss_msr_test 57 + TEST_GEN_PROGS_x86_64 += x86_64/debug_regs 57 58 TEST_GEN_PROGS_x86_64 += clear_dirty_log_test 58 59 TEST_GEN_PROGS_x86_64 += demand_paging_test 59 60 TEST_GEN_PROGS_x86_64 += dirty_log_test
+2
tools/testing/selftests/kvm/include/kvm_util.h
··· 143 143 void vcpu_run(struct kvm_vm *vm, uint32_t vcpuid); 144 144 int _vcpu_run(struct kvm_vm *vm, uint32_t vcpuid); 145 145 void vcpu_run_complete_io(struct kvm_vm *vm, uint32_t vcpuid); 146 + void vcpu_set_guest_debug(struct kvm_vm *vm, uint32_t vcpuid, 147 + struct kvm_guest_debug *debug); 146 148 void vcpu_set_mp_state(struct kvm_vm *vm, uint32_t vcpuid, 147 149 struct kvm_mp_state *mp_state); 148 150 void vcpu_regs_get(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_regs *regs);
+9
tools/testing/selftests/kvm/lib/kvm_util.c
··· 1201 1201 ret, errno); 1202 1202 } 1203 1203 1204 + void vcpu_set_guest_debug(struct kvm_vm *vm, uint32_t vcpuid, 1205 + struct kvm_guest_debug *debug) 1206 + { 1207 + struct vcpu *vcpu = vcpu_find(vm, vcpuid); 1208 + int ret = ioctl(vcpu->fd, KVM_SET_GUEST_DEBUG, debug); 1209 + 1210 + TEST_ASSERT(ret == 0, "KVM_SET_GUEST_DEBUG failed: %d", ret); 1211 + } 1212 + 1204 1213 /* 1205 1214 * VM VCPU Set MP State 1206 1215 *
+202
tools/testing/selftests/kvm/x86_64/debug_regs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * KVM guest debug register tests 4 + * 5 + * Copyright (C) 2020, Red Hat, Inc. 6 + */ 7 + #include <stdio.h> 8 + #include <string.h> 9 + #include "kvm_util.h" 10 + #include "processor.h" 11 + 12 + #define VCPU_ID 0 13 + 14 + #define DR6_BD (1 << 13) 15 + #define DR7_GD (1 << 13) 16 + 17 + /* For testing data access debug BP */ 18 + uint32_t guest_value; 19 + 20 + extern unsigned char sw_bp, hw_bp, write_data, ss_start, bd_start; 21 + 22 + static void guest_code(void) 23 + { 24 + /* 25 + * Software BP tests. 26 + * 27 + * NOTE: sw_bp need to be before the cmd here, because int3 is an 28 + * exception rather than a normal trap for KVM_SET_GUEST_DEBUG (we 29 + * capture it using the vcpu exception bitmap). 30 + */ 31 + asm volatile("sw_bp: int3"); 32 + 33 + /* Hardware instruction BP test */ 34 + asm volatile("hw_bp: nop"); 35 + 36 + /* Hardware data BP test */ 37 + asm volatile("mov $1234,%%rax;\n\t" 38 + "mov %%rax,%0;\n\t write_data:" 39 + : "=m" (guest_value) : : "rax"); 40 + 41 + /* Single step test, covers 2 basic instructions and 2 emulated */ 42 + asm volatile("ss_start: " 43 + "xor %%rax,%%rax\n\t" 44 + "cpuid\n\t" 45 + "movl $0x1a0,%%ecx\n\t" 46 + "rdmsr\n\t" 47 + : : : "rax", "ecx"); 48 + 49 + /* DR6.BD test */ 50 + asm volatile("bd_start: mov %%dr0, %%rax" : : : "rax"); 51 + GUEST_DONE(); 52 + } 53 + 54 + #define CLEAR_DEBUG() memset(&debug, 0, sizeof(debug)) 55 + #define APPLY_DEBUG() vcpu_set_guest_debug(vm, VCPU_ID, &debug) 56 + #define CAST_TO_RIP(v) ((unsigned long long)&(v)) 57 + #define SET_RIP(v) do { \ 58 + vcpu_regs_get(vm, VCPU_ID, &regs); \ 59 + regs.rip = (v); \ 60 + vcpu_regs_set(vm, VCPU_ID, &regs); \ 61 + } while (0) 62 + #define MOVE_RIP(v) SET_RIP(regs.rip + (v)); 63 + 64 + int main(void) 65 + { 66 + struct kvm_guest_debug debug; 67 + unsigned long long target_dr6, target_rip; 68 + struct kvm_regs regs; 69 + struct kvm_run *run; 70 + struct kvm_vm *vm; 71 + struct ucall uc; 72 + uint64_t cmd; 73 + int i; 74 + /* Instruction lengths starting at ss_start */ 75 + int ss_size[4] = { 76 + 3, /* xor */ 77 + 2, /* cpuid */ 78 + 5, /* mov */ 79 + 2, /* rdmsr */ 80 + }; 81 + 82 + if (!kvm_check_cap(KVM_CAP_SET_GUEST_DEBUG)) { 83 + print_skip("KVM_CAP_SET_GUEST_DEBUG not supported"); 84 + return 0; 85 + } 86 + 87 + vm = vm_create_default(VCPU_ID, 0, guest_code); 88 + vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid()); 89 + run = vcpu_state(vm, VCPU_ID); 90 + 91 + /* Test software BPs - int3 */ 92 + CLEAR_DEBUG(); 93 + debug.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP; 94 + APPLY_DEBUG(); 95 + vcpu_run(vm, VCPU_ID); 96 + TEST_ASSERT(run->exit_reason == KVM_EXIT_DEBUG && 97 + run->debug.arch.exception == BP_VECTOR && 98 + run->debug.arch.pc == CAST_TO_RIP(sw_bp), 99 + "INT3: exit %d exception %d rip 0x%llx (should be 0x%llx)", 100 + run->exit_reason, run->debug.arch.exception, 101 + run->debug.arch.pc, CAST_TO_RIP(sw_bp)); 102 + MOVE_RIP(1); 103 + 104 + /* Test instruction HW BP over DR[0-3] */ 105 + for (i = 0; i < 4; i++) { 106 + CLEAR_DEBUG(); 107 + debug.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP; 108 + debug.arch.debugreg[i] = CAST_TO_RIP(hw_bp); 109 + debug.arch.debugreg[7] = 0x400 | (1UL << (2*i+1)); 110 + APPLY_DEBUG(); 111 + vcpu_run(vm, VCPU_ID); 112 + target_dr6 = 0xffff0ff0 | (1UL << i); 113 + TEST_ASSERT(run->exit_reason == KVM_EXIT_DEBUG && 114 + run->debug.arch.exception == DB_VECTOR && 115 + run->debug.arch.pc == CAST_TO_RIP(hw_bp) && 116 + run->debug.arch.dr6 == target_dr6, 117 + "INS_HW_BP (DR%d): exit %d exception %d rip 0x%llx " 118 + "(should be 0x%llx) dr6 0x%llx (should be 0x%llx)", 119 + i, run->exit_reason, run->debug.arch.exception, 120 + run->debug.arch.pc, CAST_TO_RIP(hw_bp), 121 + run->debug.arch.dr6, target_dr6); 122 + } 123 + /* Skip "nop" */ 124 + MOVE_RIP(1); 125 + 126 + /* Test data access HW BP over DR[0-3] */ 127 + for (i = 0; i < 4; i++) { 128 + CLEAR_DEBUG(); 129 + debug.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP; 130 + debug.arch.debugreg[i] = CAST_TO_RIP(guest_value); 131 + debug.arch.debugreg[7] = 0x00000400 | (1UL << (2*i+1)) | 132 + (0x000d0000UL << (4*i)); 133 + APPLY_DEBUG(); 134 + vcpu_run(vm, VCPU_ID); 135 + target_dr6 = 0xffff0ff0 | (1UL << i); 136 + TEST_ASSERT(run->exit_reason == KVM_EXIT_DEBUG && 137 + run->debug.arch.exception == DB_VECTOR && 138 + run->debug.arch.pc == CAST_TO_RIP(write_data) && 139 + run->debug.arch.dr6 == target_dr6, 140 + "DATA_HW_BP (DR%d): exit %d exception %d rip 0x%llx " 141 + "(should be 0x%llx) dr6 0x%llx (should be 0x%llx)", 142 + i, run->exit_reason, run->debug.arch.exception, 143 + run->debug.arch.pc, CAST_TO_RIP(write_data), 144 + run->debug.arch.dr6, target_dr6); 145 + /* Rollback the 4-bytes "mov" */ 146 + MOVE_RIP(-7); 147 + } 148 + /* Skip the 4-bytes "mov" */ 149 + MOVE_RIP(7); 150 + 151 + /* Test single step */ 152 + target_rip = CAST_TO_RIP(ss_start); 153 + target_dr6 = 0xffff4ff0ULL; 154 + vcpu_regs_get(vm, VCPU_ID, &regs); 155 + for (i = 0; i < (sizeof(ss_size) / sizeof(ss_size[0])); i++) { 156 + target_rip += ss_size[i]; 157 + CLEAR_DEBUG(); 158 + debug.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP; 159 + debug.arch.debugreg[7] = 0x00000400; 160 + APPLY_DEBUG(); 161 + vcpu_run(vm, VCPU_ID); 162 + TEST_ASSERT(run->exit_reason == KVM_EXIT_DEBUG && 163 + run->debug.arch.exception == DB_VECTOR && 164 + run->debug.arch.pc == target_rip && 165 + run->debug.arch.dr6 == target_dr6, 166 + "SINGLE_STEP[%d]: exit %d exception %d rip 0x%llx " 167 + "(should be 0x%llx) dr6 0x%llx (should be 0x%llx)", 168 + i, run->exit_reason, run->debug.arch.exception, 169 + run->debug.arch.pc, target_rip, run->debug.arch.dr6, 170 + target_dr6); 171 + } 172 + 173 + /* Finally test global disable */ 174 + CLEAR_DEBUG(); 175 + debug.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP; 176 + debug.arch.debugreg[7] = 0x400 | DR7_GD; 177 + APPLY_DEBUG(); 178 + vcpu_run(vm, VCPU_ID); 179 + target_dr6 = 0xffff0ff0 | DR6_BD; 180 + TEST_ASSERT(run->exit_reason == KVM_EXIT_DEBUG && 181 + run->debug.arch.exception == DB_VECTOR && 182 + run->debug.arch.pc == CAST_TO_RIP(bd_start) && 183 + run->debug.arch.dr6 == target_dr6, 184 + "DR7.GD: exit %d exception %d rip 0x%llx " 185 + "(should be 0x%llx) dr6 0x%llx (should be 0x%llx)", 186 + run->exit_reason, run->debug.arch.exception, 187 + run->debug.arch.pc, target_rip, run->debug.arch.dr6, 188 + target_dr6); 189 + 190 + /* Disable all debug controls, run to the end */ 191 + CLEAR_DEBUG(); 192 + APPLY_DEBUG(); 193 + 194 + vcpu_run(vm, VCPU_ID); 195 + TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, "KVM_EXIT_IO"); 196 + cmd = get_ucall(vm, VCPU_ID, &uc); 197 + TEST_ASSERT(cmd == UCALL_DONE, "UCALL_DONE"); 198 + 199 + kvm_vm_free(vm); 200 + 201 + return 0; 202 + }
+11 -3
virt/kvm/kvm_main.c
··· 259 259 } 260 260 261 261 bool kvm_make_vcpus_request_mask(struct kvm *kvm, unsigned int req, 262 + struct kvm_vcpu *except, 262 263 unsigned long *vcpu_bitmap, cpumask_var_t tmp) 263 264 { 264 265 int i, cpu, me; ··· 269 268 me = get_cpu(); 270 269 271 270 kvm_for_each_vcpu(i, vcpu, kvm) { 272 - if (vcpu_bitmap && !test_bit(i, vcpu_bitmap)) 271 + if ((vcpu_bitmap && !test_bit(i, vcpu_bitmap)) || 272 + vcpu == except) 273 273 continue; 274 274 275 275 kvm_make_request(req, vcpu); ··· 290 288 return called; 291 289 } 292 290 293 - bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req) 291 + bool kvm_make_all_cpus_request_except(struct kvm *kvm, unsigned int req, 292 + struct kvm_vcpu *except) 294 293 { 295 294 cpumask_var_t cpus; 296 295 bool called; 297 296 298 297 zalloc_cpumask_var(&cpus, GFP_ATOMIC); 299 298 300 - called = kvm_make_vcpus_request_mask(kvm, req, NULL, cpus); 299 + called = kvm_make_vcpus_request_mask(kvm, req, except, NULL, cpus); 301 300 302 301 free_cpumask_var(cpus); 303 302 return called; 303 + } 304 + 305 + bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req) 306 + { 307 + return kvm_make_all_cpus_request_except(kvm, req, NULL); 304 308 } 305 309 306 310 #ifndef CONFIG_HAVE_KVM_ARCH_TLB_FLUSH_ALL