From nobody Tue Dec 2 01:06:11 2025 Received: from out-174.mta0.migadu.com (out-174.mta0.migadu.com [91.218.175.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A1CA0302766 for ; Fri, 21 Nov 2025 19:32:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763753549; cv=none; b=AR9FoBRfJQW8Qux+DgNV9/WUfeoBtAMIGK47AyH21FdIAD7guuEiJWva9hJ650ohsly63JZijREMr5eKShV7sswE2Wuu7HSfBBgiLxwbTPj5vxrbk+SmRyS1huS8vvWDc7VoDKgq72Yi8DByj1g6NovL4Imh+yCiMf+fxt4ttpg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763753549; c=relaxed/simple; bh=q4779enIlpIZ/M7xTWWkuOCJtBgoZfGwhoeNudGanw4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gg5/ydlor/76EAOzLv/PKkPHruMmPvedbkuCOnq/4j7WGXJhC9lEE23NhlLT6l6rjt3T8PsEvBckvfARtrpoiwzBahELP8+Sikh6QyY8roF3+s81k/OIoe22b9mcPq8FvntrmsW9OMZL+WDMX0SN93LYXKzAvJtcdWeXuzYx0DM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=Li3eok0Y; arc=none smtp.client-ip=91.218.175.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="Li3eok0Y" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1763753545; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=MUQekoanX4MF7SAslz8LER0NkRAktod+nMDf79bvmH4=; b=Li3eok0YbZP/MvK9X/blz5vRG7nnTCdj+p10pIMsd+Ek+Wb51TuYpC1n5HqX7W8ttq0Duv xYUgXuFa7nCSjqYjVP1P8VL6PvCGIT9RPWxCNtqEFAE6XHfMP70A7bD50Y6K+WSRCeW4v3 CGXNfaNes+/ZjUx0yT0hInc/DM1+UJo= From: Yosry Ahmed To: Sean Christopherson Cc: Paolo Bonzini , Ken Hofsass , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Yosry Ahmed Subject: [PATCH 1/3] KVM: x86: Add CR3 to guest debug info Date: Fri, 21 Nov 2025 19:32:02 +0000 Message-ID: <20251121193204.952988-2-yosry.ahmed@linux.dev> In-Reply-To: <20251121193204.952988-1-yosry.ahmed@linux.dev> References: <20251121193204.952988-1-yosry.ahmed@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Add the value of CR3 to the information returned to userspace on KVM_EXIT_DEBUG. Use KVM_CAP_X86_GUEST_DEBUG_CR3 to advertise this. During guest debugging, the value of CR3 can be used by VM debuggers to (roughly) identify the process running in the guest. This can be used to index debugging events by process, or filter events from some processes and quickly skip them. Currently, debuggers would need to use the KVM_GET_SREGS ioctl on every event to get the value of CR3, which considerably slows things down. This can be easily avoided by adding the value of CR3 to the captured debugging info. Signed-off-by: Ken Hofsass Co-developed-by: Ken Hofsass Signed-off-by: Yosry Ahmed --- arch/x86/include/uapi/asm/kvm.h | 1 + arch/x86/kvm/svm/svm.c | 2 ++ arch/x86/kvm/vmx/vmx.c | 2 ++ arch/x86/kvm/x86.c | 3 +++ include/uapi/linux/kvm.h | 1 + 5 files changed, 9 insertions(+) diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kv= m.h index 7ceff6583652..c351e458189b 100644 --- a/arch/x86/include/uapi/asm/kvm.h +++ b/arch/x86/include/uapi/asm/kvm.h @@ -293,6 +293,7 @@ struct kvm_debug_exit_arch { __u64 pc; __u64 dr6; __u64 dr7; + __u64 cr3; }; =20 #define KVM_GUESTDBG_USE_SW_BP 0x00010000 diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index f56c2d895011..85982e96b927 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1920,6 +1920,7 @@ static int db_interception(struct kvm_vcpu *vcpu) kvm_run->debug.arch.dr7 =3D svm->vmcb->save.dr7; kvm_run->debug.arch.pc =3D svm->vmcb->save.cs.base + svm->vmcb->save.rip; + kvm_run->debug.arch.cr3 =3D svm->vmcb->save.cr3; kvm_run->debug.arch.exception =3D DB_VECTOR; return 0; } @@ -1934,6 +1935,7 @@ static int bp_interception(struct kvm_vcpu *vcpu) =20 kvm_run->exit_reason =3D KVM_EXIT_DEBUG; kvm_run->debug.arch.pc =3D svm->vmcb->save.cs.base + svm->vmcb->save.rip; + kvm_run->debug.arch.cr3 =3D svm->vmcb->save.cr3; kvm_run->debug.arch.exception =3D BP_VECTOR; return 0; } diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 4cbe8c84b636..9fd8a6140af4 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -5454,6 +5454,7 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu) kvm_run->exit_reason =3D KVM_EXIT_DEBUG; kvm_run->debug.arch.pc =3D kvm_get_linear_rip(vcpu); kvm_run->debug.arch.exception =3D ex_no; + kvm_run->debug.arch.cr3 =3D kvm_read_cr3(vcpu); break; case AC_VECTOR: if (vmx_guest_inject_ac(vcpu)) { @@ -5685,6 +5686,7 @@ static int handle_dr(struct kvm_vcpu *vcpu) vcpu->run->debug.arch.dr6 =3D DR6_BD | DR6_ACTIVE_LOW; vcpu->run->debug.arch.dr7 =3D dr7; vcpu->run->debug.arch.pc =3D kvm_get_linear_rip(vcpu); + vcpu->run->debug.arch.cr3 =3D kvm_read_cr3(vcpu); vcpu->run->debug.arch.exception =3D DB_VECTOR; vcpu->run->exit_reason =3D KVM_EXIT_DEBUG; return 0; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0c6d899d53dd..636ad63ac34a 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4855,6 +4855,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, lon= g ext) case KVM_CAP_MEMORY_FAULT_INFO: case KVM_CAP_X86_GUEST_MODE: case KVM_CAP_ONE_REG: + case KVM_CAP_X86_GUEST_DEBUG_CR3: r =3D 1; break; case KVM_CAP_PRE_FAULT_MEMORY: @@ -9195,6 +9196,7 @@ static int kvm_vcpu_do_singlestep(struct kvm_vcpu *vc= pu) if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { kvm_run->debug.arch.dr6 =3D DR6_BS | DR6_ACTIVE_LOW; kvm_run->debug.arch.pc =3D kvm_get_linear_rip(vcpu); + kvm_run->debug.arch.cr3 =3D kvm_read_cr3(vcpu); kvm_run->debug.arch.exception =3D DB_VECTOR; kvm_run->exit_reason =3D KVM_EXIT_DEBUG; return 0; @@ -9277,6 +9279,7 @@ static bool kvm_vcpu_check_code_breakpoint(struct kvm= _vcpu *vcpu, if (dr6 !=3D 0) { kvm_run->debug.arch.dr6 =3D dr6 | DR6_ACTIVE_LOW; kvm_run->debug.arch.pc =3D eip; + kvm_run->debug.arch.cr3 =3D kvm_read_cr3(vcpu); kvm_run->debug.arch.exception =3D DB_VECTOR; kvm_run->exit_reason =3D KVM_EXIT_DEBUG; *r =3D 0; diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 52f6000ab020..58842b74fca1 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -963,6 +963,7 @@ struct kvm_enable_cap { #define KVM_CAP_RISCV_MP_STATE_RESET 242 #define KVM_CAP_ARM_CACHEABLE_PFNMAP_SUPPORTED 243 #define KVM_CAP_GUEST_MEMFD_FLAGS 244 +#define KVM_CAP_X86_GUEST_DEBUG_CR3 245 =20 struct kvm_irq_routing_irqchip { __u32 irqchip; --=20 2.52.0.rc2.455.g230fcf2819-goog From nobody Tue Dec 2 01:06:11 2025 Received: from out-185.mta0.migadu.com (out-185.mta0.migadu.com [91.218.175.185]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9CA61301466 for ; Fri, 21 Nov 2025 19:32:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.185 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763753553; cv=none; b=Xzxmpban0MUOePn7RgNI+SeNtJugOuSbQO9mnBOT6I8lKyUADZKdbvtvm6wvxSs5fl6H0Eeu6X3RWNE4yR1SwGftHDxgNs03Ye5DxESHxUGD/Kds69lEWOmxcYMxBgpcF+52VuXUpZbvZqNnVRnyHnKTczMWvdJUZIkZ5vF4Hw8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763753553; c=relaxed/simple; bh=yWgRTXXeJZU1v0pITpCzPJB/oUhQrczlGMOlkF7tLF4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IBlAvXE5Rczzxwk721nLCPZJdnkAsC49mXXhFtErjQUKil/AvaYVgR4702L4rKXxgTzA5CdsamScDL3y8xwYbNE+aeDQ5lHzy5mvFXstKsIV+M3LtvjFqAZ4A+ZpFXYQqAMFZu6NLhLYinelsrTUcfK3ThznI4RP1EkjrLEahL8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=PuWJ0Tt+; arc=none smtp.client-ip=91.218.175.185 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="PuWJ0Tt+" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1763753547; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9C9XfX+UY14sw/5vUVA6fyLzyZRFAVFX0tjWpm79IXc=; b=PuWJ0Tt+28oCCxCxw/ndtUo1oAvd/scT4LiQajCzrPArGxriJxRl0CWhmcKxIkfuYHra9D 5KOSUF3S0ySGrrcf/FJATAo7gNtaEtvj4RaTxLOMGKSLRGH7PgOcQC1tI2mOPZbKyXXSDf NBOc/jjrUpnN8jhbSzpFUpl64awBaaE= From: Yosry Ahmed To: Sean Christopherson Cc: Paolo Bonzini , Ken Hofsass , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Yosry Ahmed Subject: [PATCH 2/3] KVM: selftests: Use TEST_ASSERT_EQ() in debug_regs Date: Fri, 21 Nov 2025 19:32:03 +0000 Message-ID: <20251121193204.952988-3-yosry.ahmed@linux.dev> In-Reply-To: <20251121193204.952988-1-yosry.ahmed@linux.dev> References: <20251121193204.952988-1-yosry.ahmed@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" The test currently uses calls of TEST_ASSERT() that combine all checked conditions for every test case. This makes it unclear which value is incorrect without visually parsing the output. The only useful content in the error message is the test case, especially for test cases running in loops where even the line number of the failed assertion does not provide full information. Switch to using TEST_ASSERT_EQ(), and print the test case currently being asserted to keep the information intact. The test output is a lot more verbose now, but debuggability trumps conciseness (right?). Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/x86/debug_regs.c | 66 +++++++------------- 1 file changed, 24 insertions(+), 42 deletions(-) diff --git a/tools/testing/selftests/kvm/x86/debug_regs.c b/tools/testing/s= elftests/kvm/x86/debug_regs.c index 2d814c1d1dc4..563e52217cdd 100644 --- a/tools/testing/selftests/kvm/x86/debug_regs.c +++ b/tools/testing/selftests/kvm/x86/debug_regs.c @@ -104,20 +104,19 @@ int main(void) run =3D vcpu->run; =20 /* Test software BPs - int3 */ + pr_info("Testing INT3\n"); memset(&debug, 0, sizeof(debug)); debug.control =3D KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP; vcpu_guest_debug_set(vcpu, &debug); vcpu_run(vcpu); - TEST_ASSERT(run->exit_reason =3D=3D KVM_EXIT_DEBUG && - run->debug.arch.exception =3D=3D BP_VECTOR && - run->debug.arch.pc =3D=3D CAST_TO_RIP(sw_bp), - "INT3: exit %d exception %d rip 0x%llx (should be 0x%llx)", - run->exit_reason, run->debug.arch.exception, - run->debug.arch.pc, CAST_TO_RIP(sw_bp)); + TEST_ASSERT_EQ(run->exit_reason, KVM_EXIT_DEBUG); + TEST_ASSERT_EQ(run->debug.arch.exception, BP_VECTOR); + TEST_ASSERT_EQ(run->debug.arch.pc, CAST_TO_RIP(sw_bp)); vcpu_skip_insn(vcpu, 1); =20 /* Test instruction HW BP over DR[0-3] */ for (i =3D 0; i < 4; i++) { + pr_info("Testing INS_HW_BP DR[%d]\n", i); memset(&debug, 0, sizeof(debug)); debug.control =3D KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP; debug.arch.debugreg[i] =3D CAST_TO_RIP(hw_bp); @@ -125,21 +124,17 @@ int main(void) vcpu_guest_debug_set(vcpu, &debug); vcpu_run(vcpu); target_dr6 =3D 0xffff0ff0 | (1UL << i); - TEST_ASSERT(run->exit_reason =3D=3D KVM_EXIT_DEBUG && - run->debug.arch.exception =3D=3D DB_VECTOR && - run->debug.arch.pc =3D=3D CAST_TO_RIP(hw_bp) && - run->debug.arch.dr6 =3D=3D target_dr6, - "INS_HW_BP (DR%d): exit %d exception %d rip 0x%llx " - "(should be 0x%llx) dr6 0x%llx (should be 0x%llx)", - i, run->exit_reason, run->debug.arch.exception, - run->debug.arch.pc, CAST_TO_RIP(hw_bp), - run->debug.arch.dr6, target_dr6); + TEST_ASSERT_EQ(run->exit_reason, KVM_EXIT_DEBUG); + TEST_ASSERT_EQ(run->debug.arch.exception, DB_VECTOR); + TEST_ASSERT_EQ(run->debug.arch.pc, CAST_TO_RIP(hw_bp)); + TEST_ASSERT_EQ(run->debug.arch.dr6, target_dr6); } /* Skip "nop" */ vcpu_skip_insn(vcpu, 1); =20 /* Test data access HW BP over DR[0-3] */ for (i =3D 0; i < 4; i++) { + pr_info("Testing DATA_HW_BP DR[%d]\n", i); memset(&debug, 0, sizeof(debug)); debug.control =3D KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP; debug.arch.debugreg[i] =3D CAST_TO_RIP(guest_value); @@ -148,15 +143,10 @@ int main(void) vcpu_guest_debug_set(vcpu, &debug); vcpu_run(vcpu); target_dr6 =3D 0xffff0ff0 | (1UL << i); - TEST_ASSERT(run->exit_reason =3D=3D KVM_EXIT_DEBUG && - run->debug.arch.exception =3D=3D DB_VECTOR && - run->debug.arch.pc =3D=3D CAST_TO_RIP(write_data) && - run->debug.arch.dr6 =3D=3D target_dr6, - "DATA_HW_BP (DR%d): exit %d exception %d rip 0x%llx " - "(should be 0x%llx) dr6 0x%llx (should be 0x%llx)", - i, run->exit_reason, run->debug.arch.exception, - run->debug.arch.pc, CAST_TO_RIP(write_data), - run->debug.arch.dr6, target_dr6); + TEST_ASSERT_EQ(run->exit_reason, KVM_EXIT_DEBUG); + TEST_ASSERT_EQ(run->debug.arch.exception, DB_VECTOR); + TEST_ASSERT_EQ(run->debug.arch.pc, CAST_TO_RIP(write_data)); + TEST_ASSERT_EQ(run->debug.arch.dr6, target_dr6); /* Rollback the 4-bytes "mov" */ vcpu_skip_insn(vcpu, -7); } @@ -167,6 +157,7 @@ int main(void) target_rip =3D CAST_TO_RIP(ss_start); target_dr6 =3D 0xffff4ff0ULL; for (i =3D 0; i < ARRAY_SIZE(ss_size); i++) { + pr_info("Testing SINGLE_STEP (%d)\n", i); target_rip +=3D ss_size[i]; memset(&debug, 0, sizeof(debug)); debug.control =3D KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP | @@ -174,33 +165,24 @@ int main(void) debug.arch.debugreg[7] =3D 0x00000400; vcpu_guest_debug_set(vcpu, &debug); vcpu_run(vcpu); - TEST_ASSERT(run->exit_reason =3D=3D KVM_EXIT_DEBUG && - run->debug.arch.exception =3D=3D DB_VECTOR && - run->debug.arch.pc =3D=3D target_rip && - run->debug.arch.dr6 =3D=3D target_dr6, - "SINGLE_STEP[%d]: exit %d exception %d rip 0x%llx " - "(should be 0x%llx) dr6 0x%llx (should be 0x%llx)", - i, run->exit_reason, run->debug.arch.exception, - run->debug.arch.pc, target_rip, run->debug.arch.dr6, - target_dr6); + TEST_ASSERT_EQ(run->exit_reason, KVM_EXIT_DEBUG); + TEST_ASSERT_EQ(run->debug.arch.exception, DB_VECTOR); + TEST_ASSERT_EQ(run->debug.arch.pc, target_rip); + TEST_ASSERT_EQ(run->debug.arch.dr6, target_dr6); } =20 /* Finally test global disable */ + pr_info("Testing DR7.GD\n"); memset(&debug, 0, sizeof(debug)); debug.control =3D KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP; debug.arch.debugreg[7] =3D 0x400 | DR7_GD; vcpu_guest_debug_set(vcpu, &debug); vcpu_run(vcpu); target_dr6 =3D 0xffff0ff0 | DR6_BD; - TEST_ASSERT(run->exit_reason =3D=3D KVM_EXIT_DEBUG && - run->debug.arch.exception =3D=3D DB_VECTOR && - run->debug.arch.pc =3D=3D CAST_TO_RIP(bd_start) && - run->debug.arch.dr6 =3D=3D target_dr6, - "DR7.GD: exit %d exception %d rip 0x%llx " - "(should be 0x%llx) dr6 0x%llx (should be 0x%llx)", - run->exit_reason, run->debug.arch.exception, - run->debug.arch.pc, target_rip, run->debug.arch.dr6, - target_dr6); + TEST_ASSERT_EQ(run->exit_reason, KVM_EXIT_DEBUG); + TEST_ASSERT_EQ(run->debug.arch.exception, DB_VECTOR); + TEST_ASSERT_EQ(run->debug.arch.pc, CAST_TO_RIP(bd_start)); + TEST_ASSERT_EQ(run->debug.arch.dr6, target_dr6); =20 /* Disable all debug controls, run to the end */ memset(&debug, 0, sizeof(debug)); --=20 2.52.0.rc2.455.g230fcf2819-goog From nobody Tue Dec 2 01:06:11 2025 Received: from out-182.mta0.migadu.com (out-182.mta0.migadu.com [91.218.175.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E33503002A6; Fri, 21 Nov 2025 19:32:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763753553; cv=none; b=gpVjGJQUs8mYKH9RENqWYRurF4Y2u03fvoQIJcXodssvK8lJvPoueYz9J/4swsClCsOHD6c3fFeqw1GpxKlEYu01084eS9ypWTCLJzTpQlZzStzLhsxD4kd9wGRc6D25DppedIWNNp60e2PBW2w0BVhCubzanVh6YCrX1MYN4FE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763753553; c=relaxed/simple; bh=XTcT2aRIC+bx02fSkf5olHtJ8KjSKocOAdwnrpK8srA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ORpY81RpHaTukZGYAUWQhzhpxX/fteOprm9aSU5lPGwozYeLJEKWAGQMYaDjihfTVV9OdcXNKFDBVehd+4G3TZOVOQa8a2PSdACSAlhdpSmm/eMJNug11l/swRsHAnwHdznl5eM0Lhdtag3kxJYdsauxfhrOIQLOKB0N1V3PDcE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=n5AxN8lJ; arc=none smtp.client-ip=91.218.175.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="n5AxN8lJ" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1763753548; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3DqFdYkdQ+nHqF3kgNLYzHfTDGHGl4q58gU1CFuLCXk=; b=n5AxN8lJ67yEwn2BfR3jw7OIm296RqyTe+falzjel5zEwqvjMHAsNos77Zgop2qB8pnfjp bNPgysusRbLlQRxXCMctkF38Ko3XcgyLaaOHjJmgdgTJG/Dh8I53v9ErJliDVVZscoyvHI 4QWaCPyX34fZW19Uo5FPTNHQWeVhy6I= From: Yosry Ahmed To: Sean Christopherson Cc: Paolo Bonzini , Ken Hofsass , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Yosry Ahmed Subject: [PATCH 3/3] KVM: selftests: Verify CR3 in debug_regs Date: Fri, 21 Nov 2025 19:32:04 +0000 Message-ID: <20251121193204.952988-4-yosry.ahmed@linux.dev> In-Reply-To: <20251121193204.952988-1-yosry.ahmed@linux.dev> References: <20251121193204.952988-1-yosry.ahmed@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" If KVM_CAP_X86_GUEST_DEBUG_CR3 is set, check that the value of CR3 in struct kvm_run on KVM_EXIT_DEBUG matches that returned by KVM_GET_SREGS. Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/x86/debug_regs.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/kvm/x86/debug_regs.c b/tools/testing/s= elftests/kvm/x86/debug_regs.c index 563e52217cdd..ecad92789182 100644 --- a/tools/testing/selftests/kvm/x86/debug_regs.c +++ b/tools/testing/selftests/kvm/x86/debug_regs.c @@ -80,8 +80,9 @@ static void vcpu_skip_insn(struct kvm_vcpu *vcpu, int ins= n_len) =20 int main(void) { + unsigned long long target_dr6, target_rip, target_cr3; struct kvm_guest_debug debug; - unsigned long long target_dr6, target_rip; + struct kvm_sregs sregs; struct kvm_vcpu *vcpu; struct kvm_run *run; struct kvm_vm *vm; @@ -103,6 +104,14 @@ int main(void) vm =3D vm_create_with_one_vcpu(&vcpu, guest_code); run =3D vcpu->run; =20 + if (kvm_has_cap(KVM_CAP_X86_GUEST_DEBUG_CR3)) { + pr_info("Debug info includes guest CR3\n"); + vcpu_sregs_get(vcpu, &sregs); + target_cr3 =3D sregs.cr3; + } else { + target_cr3 =3D 0; + } + /* Test software BPs - int3 */ pr_info("Testing INT3\n"); memset(&debug, 0, sizeof(debug)); @@ -112,6 +121,7 @@ int main(void) TEST_ASSERT_EQ(run->exit_reason, KVM_EXIT_DEBUG); TEST_ASSERT_EQ(run->debug.arch.exception, BP_VECTOR); TEST_ASSERT_EQ(run->debug.arch.pc, CAST_TO_RIP(sw_bp)); + TEST_ASSERT_EQ(run->debug.arch.cr3, target_cr3); vcpu_skip_insn(vcpu, 1); =20 /* Test instruction HW BP over DR[0-3] */ @@ -128,6 +138,7 @@ int main(void) TEST_ASSERT_EQ(run->debug.arch.exception, DB_VECTOR); TEST_ASSERT_EQ(run->debug.arch.pc, CAST_TO_RIP(hw_bp)); TEST_ASSERT_EQ(run->debug.arch.dr6, target_dr6); + TEST_ASSERT_EQ(run->debug.arch.cr3, target_cr3); } /* Skip "nop" */ vcpu_skip_insn(vcpu, 1); @@ -147,6 +158,7 @@ int main(void) TEST_ASSERT_EQ(run->debug.arch.exception, DB_VECTOR); TEST_ASSERT_EQ(run->debug.arch.pc, CAST_TO_RIP(write_data)); TEST_ASSERT_EQ(run->debug.arch.dr6, target_dr6); + TEST_ASSERT_EQ(run->debug.arch.cr3, target_cr3); /* Rollback the 4-bytes "mov" */ vcpu_skip_insn(vcpu, -7); } @@ -169,6 +181,7 @@ int main(void) TEST_ASSERT_EQ(run->debug.arch.exception, DB_VECTOR); TEST_ASSERT_EQ(run->debug.arch.pc, target_rip); TEST_ASSERT_EQ(run->debug.arch.dr6, target_dr6); + TEST_ASSERT_EQ(run->debug.arch.cr3, target_cr3); } =20 /* Finally test global disable */ @@ -183,6 +196,7 @@ int main(void) TEST_ASSERT_EQ(run->debug.arch.exception, DB_VECTOR); TEST_ASSERT_EQ(run->debug.arch.pc, CAST_TO_RIP(bd_start)); TEST_ASSERT_EQ(run->debug.arch.dr6, target_dr6); + TEST_ASSERT_EQ(run->debug.arch.cr3, target_cr3); =20 /* Disable all debug controls, run to the end */ memset(&debug, 0, sizeof(debug)); --=20 2.52.0.rc2.455.g230fcf2819-goog