On 07/05/20 21:28, Peter Xu wrote: >> - svm->vcpu.arch.dr6 = dr6; >> + WARN_ON(svm->vcpu.arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT); >> + svm->vcpu.arch.dr6 &= ~(DR_TRAP_BITS | DR6_RTM); >> + svm->vcpu.arch.dr6 |= dr6 & ~DR6_FIXED_1; > I failed to figure out what the above calculation is going to do... The calculation is merging the cause of the #DB with the guest DR6. It's basically the same effect as kvm_deliver_exception_payload. The payload has DR6_RTM flipped compared to DR6, so you have the following simplfications: payload = (dr6 ^ DR6_RTM) & ~DR6_FIXED_1; /* This is kvm_deliver_exception_payload: */ vcpu->arch.dr6 &= ~DR_TRAP_BITS; vcpu->arch.dr6 |= DR6_RTM; /* copy dr6 bits other than RTM */ vcpu->arch.dr6 |= payload; /* copy flipped RTM bit */ vcpu->arch.dr6 ^= payload & DR6_RTM; -> payload = (dr6 ^ DR6_RTM) & ~DR6_FIXED_1; /* clear RTM here, so that we can OR it below */ vcpu->arch.dr6 &= ~(DR_TRAP_BITS | DR6_RTM); /* copy dr6 bits other than RTM */ vcpu->arch.dr6 |= payload & ~DR6_RTM; /* copy flipped RTM bit */ vcpu->arch.dr6 |= (payload ^ DR6_RTM) & DR6_RTM; -> /* we can drop the double XOR of DR6_RTM */ dr6 &= ~DR6_FIXED_1; vcpu->arch.dr6 &= ~(DR_TRAP_BITS | DR6_RTM); vcpu->arch.dr6 |= dr6 & ~DR6_RTM; vcpu->arch.dr6 |= dr6 & DR6_RTM; -> /* we can do the two ORs with a single operation */ vcpu->arch.dr6 &= ~(DR_TRAP_BITS | DR6_RTM); vcpu->arch.dr6 |= dr6 & ~DR6_FIXED_1; > E.g., I > think the old "BT|BS|BD" bits in the old arch.dr6 cache will be leftover even > if none of them is set in save.dr6, while we shouldn't? Those bits should be kept; this is covered for example by the "hw breakpoint (test that dr6.BS is not cleared)" testcase in kvm-unit-tests x86/debug.c. Thanks, Paolo