linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3] KVM: x86: fix DR6 delivery for various cases of #DB injection
@ 2020-05-06  9:23 Paolo Bonzini
  2020-05-06 22:01 ` kbuild test robot
  0 siblings, 1 reply; 2+ messages in thread
From: Paolo Bonzini @ 2020-05-06  9:23 UTC (permalink / raw)
  To: linux-kernel, kvm

Go through kvm_queue_exception_p so that the payload is correctly delivered
through the exit qualification, and add a kvm_update_dr6 call to
kvm_deliver_exception_payload that is needed on AMD.

Reported-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 arch/x86/kvm/vmx/vmx.c | 8 ++------
 arch/x86/kvm/x86.c     | 6 +++---
 2 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index c2c6335a998c..bb5a527e49d9 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -4677,12 +4677,10 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu)
 		dr6 = vmcs_readl(EXIT_QUALIFICATION);
 		if (!(vcpu->guest_debug &
 		      (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) {
-			vcpu->arch.dr6 &= ~DR_TRAP_BITS;
-			vcpu->arch.dr6 |= dr6 | DR6_RTM;
 			if (is_icebp(intr_info))
 				WARN_ON(!skip_emulated_instruction(vcpu));
 
-			kvm_queue_exception(vcpu, DB_VECTOR);
+			kvm_queue_exception_p(vcpu, DB_VECTOR, dr6);
 			return 1;
 		}
 		kvm_run->debug.arch.dr6 = dr6 | DR6_FIXED_1;
@@ -4936,9 +4934,7 @@ static int handle_dr(struct kvm_vcpu *vcpu)
 			vcpu->run->exit_reason = KVM_EXIT_DEBUG;
 			return 0;
 		} else {
-			vcpu->arch.dr6 &= ~DR_TRAP_BITS;
-			vcpu->arch.dr6 |= DR6_BD | DR6_RTM;
-			kvm_queue_exception(vcpu, DB_VECTOR);
+			kvm_queue_exception_p(vcpu, DB_VECTOR, DR6_BD);
 			return 1;
 		}
 	}
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index c5835f9cb9ad..f571e40de438 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -104,6 +104,7 @@ static u64 __read_mostly cr4_reserved_bits = CR4_RESERVED_BITS;
                                     KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK)
 
 static void update_cr8_intercept(struct kvm_vcpu *vcpu);
+static void kvm_update_dr6(struct kvm_vcpu *vcpu);
 static void process_nmi(struct kvm_vcpu *vcpu);
 static void enter_smm(struct kvm_vcpu *vcpu);
 static void __kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags);
@@ -473,6 +474,7 @@ void kvm_deliver_exception_payload(struct kvm_vcpu *vcpu)
 		 * breakpoint), it is reserved and must be zero in DR6.
 		 */
 		vcpu->arch.dr6 &= ~BIT(12);
+		kvm_update_dr6(vcpu);
 		break;
 	case PF_VECTOR:
 		vcpu->arch.cr2 = payload;
@@ -6731,9 +6733,7 @@ static bool kvm_vcpu_check_breakpoint(struct kvm_vcpu *vcpu, int *r)
 					   vcpu->arch.db);
 
 		if (dr6 != 0) {
-			vcpu->arch.dr6 &= ~DR_TRAP_BITS;
-			vcpu->arch.dr6 |= dr6 | DR6_RTM;
-			kvm_queue_exception(vcpu, DB_VECTOR);
+			kvm_queue_exception_p(vcpu, DB_VECTOR, dr6);
 			*r = 1;
 			return true;
 		}
-- 
2.18.2


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v3] KVM: x86: fix DR6 delivery for various cases of #DB injection
  2020-05-06  9:23 [PATCH v3] KVM: x86: fix DR6 delivery for various cases of #DB injection Paolo Bonzini
@ 2020-05-06 22:01 ` kbuild test robot
  0 siblings, 0 replies; 2+ messages in thread
From: kbuild test robot @ 2020-05-06 22:01 UTC (permalink / raw)
  To: Paolo Bonzini, linux-kernel, kvm; +Cc: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 5788 bytes --]

Hi Paolo,

I love your patch! Yet something to improve:

[auto build test ERROR on tip/auto-latest]
[also build test ERROR on linus/master v5.7-rc4 next-20200505]
[cannot apply to kvm/linux-next linux/master]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Paolo-Bonzini/KVM-x86-fix-DR6-delivery-for-various-cases-of-DB-injection/20200507-022910
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 5545b0d34f37831e20cb401ae8160284d20bba30
config: i386-allyesconfig (attached as .config)
compiler: gcc-7 (Ubuntu 7.5.0-6ubuntu2) 7.5.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   arch/x86/kvm/vmx/vmx.c: In function 'handle_exception_nmi':
>> arch/x86/kvm/vmx/vmx.c:4683:4: error: implicit declaration of function 'kvm_queue_exception_p'; did you mean 'kvm_queue_exception_e'? [-Werror=implicit-function-declaration]
       kvm_queue_exception_p(vcpu, DB_VECTOR, dr6);
       ^~~~~~~~~~~~~~~~~~~~~
       kvm_queue_exception_e
   cc1: some warnings being treated as errors

vim +4683 arch/x86/kvm/vmx/vmx.c

  4610	
  4611	static int handle_exception_nmi(struct kvm_vcpu *vcpu)
  4612	{
  4613		struct vcpu_vmx *vmx = to_vmx(vcpu);
  4614		struct kvm_run *kvm_run = vcpu->run;
  4615		u32 intr_info, ex_no, error_code;
  4616		unsigned long cr2, rip, dr6;
  4617		u32 vect_info;
  4618	
  4619		vect_info = vmx->idt_vectoring_info;
  4620		intr_info = vmx->exit_intr_info;
  4621	
  4622		if (is_machine_check(intr_info) || is_nmi(intr_info))
  4623			return 1; /* handled by handle_exception_nmi_irqoff() */
  4624	
  4625		if (is_invalid_opcode(intr_info))
  4626			return handle_ud(vcpu);
  4627	
  4628		error_code = 0;
  4629		if (intr_info & INTR_INFO_DELIVER_CODE_MASK)
  4630			error_code = vmcs_read32(VM_EXIT_INTR_ERROR_CODE);
  4631	
  4632		if (!vmx->rmode.vm86_active && is_gp_fault(intr_info)) {
  4633			WARN_ON_ONCE(!enable_vmware_backdoor);
  4634	
  4635			/*
  4636			 * VMware backdoor emulation on #GP interception only handles
  4637			 * IN{S}, OUT{S}, and RDPMC, none of which generate a non-zero
  4638			 * error code on #GP.
  4639			 */
  4640			if (error_code) {
  4641				kvm_queue_exception_e(vcpu, GP_VECTOR, error_code);
  4642				return 1;
  4643			}
  4644			return kvm_emulate_instruction(vcpu, EMULTYPE_VMWARE_GP);
  4645		}
  4646	
  4647		/*
  4648		 * The #PF with PFEC.RSVD = 1 indicates the guest is accessing
  4649		 * MMIO, it is better to report an internal error.
  4650		 * See the comments in vmx_handle_exit.
  4651		 */
  4652		if ((vect_info & VECTORING_INFO_VALID_MASK) &&
  4653		    !(is_page_fault(intr_info) && !(error_code & PFERR_RSVD_MASK))) {
  4654			vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
  4655			vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_SIMUL_EX;
  4656			vcpu->run->internal.ndata = 3;
  4657			vcpu->run->internal.data[0] = vect_info;
  4658			vcpu->run->internal.data[1] = intr_info;
  4659			vcpu->run->internal.data[2] = error_code;
  4660			return 0;
  4661		}
  4662	
  4663		if (is_page_fault(intr_info)) {
  4664			cr2 = vmcs_readl(EXIT_QUALIFICATION);
  4665			/* EPT won't cause page fault directly */
  4666			WARN_ON_ONCE(!vcpu->arch.apf.host_apf_reason && enable_ept);
  4667			return kvm_handle_page_fault(vcpu, error_code, cr2, NULL, 0);
  4668		}
  4669	
  4670		ex_no = intr_info & INTR_INFO_VECTOR_MASK;
  4671	
  4672		if (vmx->rmode.vm86_active && rmode_exception(vcpu, ex_no))
  4673			return handle_rmode_exception(vcpu, ex_no, error_code);
  4674	
  4675		switch (ex_no) {
  4676		case DB_VECTOR:
  4677			dr6 = vmcs_readl(EXIT_QUALIFICATION);
  4678			if (!(vcpu->guest_debug &
  4679			      (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) {
  4680				if (is_icebp(intr_info))
  4681					WARN_ON(!skip_emulated_instruction(vcpu));
  4682	
> 4683				kvm_queue_exception_p(vcpu, DB_VECTOR, dr6);
  4684				return 1;
  4685			}
  4686			kvm_run->debug.arch.dr6 = dr6 | DR6_FIXED_1;
  4687			kvm_run->debug.arch.dr7 = vmcs_readl(GUEST_DR7);
  4688			/* fall through */
  4689		case BP_VECTOR:
  4690			/*
  4691			 * Update instruction length as we may reinject #BP from
  4692			 * user space while in guest debugging mode. Reading it for
  4693			 * #DB as well causes no harm, it is not used in that case.
  4694			 */
  4695			vmx->vcpu.arch.event_exit_inst_len =
  4696				vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
  4697			kvm_run->exit_reason = KVM_EXIT_DEBUG;
  4698			rip = kvm_rip_read(vcpu);
  4699			kvm_run->debug.arch.pc = vmcs_readl(GUEST_CS_BASE) + rip;
  4700			kvm_run->debug.arch.exception = ex_no;
  4701			break;
  4702		case AC_VECTOR:
  4703			if (guest_inject_ac(vcpu)) {
  4704				kvm_queue_exception_e(vcpu, AC_VECTOR, error_code);
  4705				return 1;
  4706			}
  4707	
  4708			/*
  4709			 * Handle split lock. Depending on detection mode this will
  4710			 * either warn and disable split lock detection for this
  4711			 * task or force SIGBUS on it.
  4712			 */
  4713			if (handle_guest_split_lock(kvm_rip_read(vcpu)))
  4714				return 1;
  4715			fallthrough;
  4716		default:
  4717			kvm_run->exit_reason = KVM_EXIT_EXCEPTION;
  4718			kvm_run->ex.exception = ex_no;
  4719			kvm_run->ex.error_code = error_code;
  4720			break;
  4721		}
  4722		return 0;
  4723	}
  4724	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 72239 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-05-06 22:02 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-06  9:23 [PATCH v3] KVM: x86: fix DR6 delivery for various cases of #DB injection Paolo Bonzini
2020-05-06 22:01 ` kbuild test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).