| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/06/29 13:45 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": [
"KVM_AMD"
],
"FocusSymbols": [
"nested_svm_vmexit_update_vmcb12",
"nested_svm_exit_handled",
"nested_vmcb02_prepare_control",
"nested_svm_clear_decode_assists",
"nested_svm_copy_decode_assists"
],
"Reasoning": "The patch fixes a bug in nested SVM virtualization where DecodeAssist data could be leaked from a previous exit to a subsequent exit. It modifies core KVM SVM logic for handling nested VM exits and preparing VMCB02 controls. This is functional code reachable from userspace via KVM ioctls (specifically running a nested guest), so it should be fuzzed.",
"WorthFuzzing": true
} |
| 1/1 | 2026/06/29 13:45 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 4e3e3d916a91f4feeddd5ded7ff4dfbabc9c2525\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Mon Jun 29 13:45:00 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c\nindex b340dc9991adb4..50e9ffa5f9fd4d 100644\n--- a/arch/x86/kvm/svm/nested.c\n+++ b/arch/x86/kvm/svm/nested.c\n@@ -33,6 +33,33 @@\n \n #define CC KVM_NESTED_VMENTER_CONSISTENCY_CHECK\n \n+static void nested_svm_clear_decode_assists(struct vmcb *vmcb)\n+{\n+\tvmcb-\u003econtrol.insn_len = 0;\n+\tmemset(vmcb-\u003econtrol.insn_bytes, 0,\n+\t sizeof(vmcb-\u003econtrol.insn_bytes));\n+}\n+\n+static void nested_svm_copy_decode_assists(struct vmcb *to, struct vmcb *from)\n+{\n+\tu8 insn_len = from-\u003econtrol.insn_len;\n+\n+\tnested_svm_clear_decode_assists(to);\n+\n+\t/*\n+\t * Hardware leaves insn_len zero when no DecodeAssist data is available.\n+\t * Keep that as the nested-visible \"no decode info\" marker.\n+\t */\n+\tif (!insn_len)\n+\t\treturn;\n+\n+\tif (WARN_ON_ONCE(insn_len \u003e sizeof(from-\u003econtrol.insn_bytes)))\n+\t\treturn;\n+\n+\tto-\u003econtrol.insn_len = insn_len;\n+\tmemcpy(to-\u003econtrol.insn_bytes, from-\u003econtrol.insn_bytes, insn_len);\n+}\n+\n static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu,\n \t\t\t\t struct x86_exception *fault)\n {\n@@ -838,7 +865,10 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm)\n \t/*\n \t * Filled at exit: exit_code, exit_info_1, exit_info_2, exit_int_info,\n \t * exit_int_info_err, next_rip, insn_len, insn_bytes.\n+\t * Clear stale DecodeAssist data before L2 runs.\n \t */\n+\tnested_svm_clear_decode_assists(vmcb02);\n+\tsvm-\u003enested.decode_assists_valid = false;\n \n \tif (guest_cpu_cap_has(vcpu, X86_FEATURE_VGIF) \u0026\u0026\n \t (vmcb12_ctrl-\u003eint_ctl \u0026 V_GIF_ENABLE_MASK))\n@@ -1251,6 +1281,18 @@ static int nested_svm_vmexit_update_vmcb12(struct kvm_vcpu *vcpu)\n \tif (guest_cpu_cap_has(vcpu, X86_FEATURE_NRIPS))\n \t\tvmcb12-\u003econtrol.next_rip = vmcb02-\u003econtrol.next_rip;\n \n+\t/*\n+\t * Copy DecodeAssist data only for real VMCB02 exits. KVM-synthesized\n+\t * exits report no decode info to L1.\n+\t */\n+\tif (svm-\u003enested.decode_assists_valid \u0026\u0026\n+\t guest_cpu_cap_has(vcpu, X86_FEATURE_DECODEASSISTS))\n+\t\tnested_svm_copy_decode_assists(vmcb12, vmcb02);\n+\telse\n+\t\tnested_svm_clear_decode_assists(vmcb12);\n+\n+\tsvm-\u003enested.decode_assists_valid = false;\n+\n \tif (nested_vmcb12_has_lbrv(vcpu))\n \t\tsvm_copy_lbrs(\u0026vmcb12-\u003esave, \u0026vmcb02-\u003esave);\n \n@@ -1593,8 +1635,11 @@ int nested_svm_exit_handled(struct vcpu_svm *svm)\n \n \tvmexit = nested_svm_intercept(svm);\n \n-\tif (vmexit == NESTED_EXIT_DONE)\n+\tif (vmexit == NESTED_EXIT_DONE) {\n+\t\t/* This path reflects a real VMCB02 exit directly to L1. */\n+\t\tsvm-\u003enested.decode_assists_valid = true;\n \t\tnested_svm_vmexit(svm);\n+\t}\n \n \treturn vmexit;\n }\ndiff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c\nindex e02a38da5296e3..366e7ef787b260 100644\n--- a/arch/x86/kvm/svm/svm.c\n+++ b/arch/x86/kvm/svm/svm.c\n@@ -5470,6 +5470,9 @@ static __init void svm_set_cpu_caps(void)\n \t\t */\n \t\tkvm_cpu_cap_set(X86_FEATURE_FLUSHBYASID);\n \n+\t\tif (boot_cpu_has(X86_FEATURE_DECODEASSISTS))\n+\t\t\tkvm_cpu_cap_set(X86_FEATURE_DECODEASSISTS);\n+\n \t\tif (nrips)\n \t\t\tkvm_cpu_cap_set(X86_FEATURE_NRIPS);\n \ndiff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h\nindex 5137416be593d7..be7fdcd124b742 100644\n--- a/arch/x86/kvm/svm/svm.h\n+++ b/arch/x86/kvm/svm/svm.h\n@@ -238,6 +238,12 @@ struct svm_nested_state {\n \t * on its side.\n \t */\n \tbool force_msr_bitmap_recalc;\n+\n+\t/*\n+\t * True only while reflecting a real VMCB02 exit whose DecodeAssist\n+\t * fields may be copied to VMCB12. KVM-synthesized exits leave it clear.\n+\t */\n+\tbool decode_assists_valid;\n };\n \n struct vcpu_sev_es_state {\ndiff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm\nindex 9118a5a51b89fd..23bf5107439228 100644\n--- a/tools/testing/selftests/kvm/Makefile.kvm\n+++ b/tools/testing/selftests/kvm/Makefile.kvm\n@@ -114,6 +114,7 @@ TEST_GEN_PROGS_x86 += x86/vmx_preemption_timer_test\n TEST_GEN_PROGS_x86 += x86/svm_vmcall_test\n TEST_GEN_PROGS_x86 += x86/svm_int_ctl_test\n TEST_GEN_PROGS_x86 += x86/svm_nested_clear_efer_svme\n+TEST_GEN_PROGS_x86 += x86/svm_nested_decode_assists_test\n TEST_GEN_PROGS_x86 += x86/svm_nested_shutdown_test\n TEST_GEN_PROGS_x86 += x86/svm_nested_soft_inject_test\n TEST_GEN_PROGS_x86 += x86/svm_nested_vmcb12_gpa\ndiff --git a/tools/testing/selftests/kvm/include/x86/processor.h b/tools/testing/selftests/kvm/include/x86/processor.h\nindex 77f576ee7789d8..ee4520ff2f8937 100644\n--- a/tools/testing/selftests/kvm/include/x86/processor.h\n+++ b/tools/testing/selftests/kvm/include/x86/processor.h\n@@ -201,6 +201,7 @@ struct kvm_x86_cpu_feature {\n #define\tX86_FEATURE_LBRV\t\tKVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 1)\n #define\tX86_FEATURE_NRIPS\t\tKVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 3)\n #define X86_FEATURE_TSCRATEMSR KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 4)\n+#define X86_FEATURE_DECODEASSISTS KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 7)\n #define X86_FEATURE_PAUSEFILTER KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 10)\n #define X86_FEATURE_PFTHRESHOLD KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 12)\n #define\tX86_FEATURE_V_VMSAVE_VMLOAD\tKVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 15)\ndiff --git a/tools/testing/selftests/kvm/x86/svm_nested_decode_assists_test.c b/tools/testing/selftests/kvm/x86/svm_nested_decode_assists_test.c\nnew file mode 100644\nindex 00000000000000..6b5d38d9d36c45\n--- /dev/null\n+++ b/tools/testing/selftests/kvm/x86/svm_nested_decode_assists_test.c\n@@ -0,0 +1,99 @@\n+// SPDX-License-Identifier: GPL-2.0-only\n+#include \"test_util.h\"\n+#include \"kvm_util.h\"\n+#include \"processor.h\"\n+#include \"svm_util.h\"\n+\n+#define L2_GUEST_STACK_SIZE 64\n+\n+static uint64_t npf_target __aligned(PAGE_SIZE);\n+\n+static void l2_guest_code(void)\n+{\n+\tasm volatile(\"mov (%0), %%rax\" : : \"r\"(\u0026npf_target) : \"rax\", \"memory\");\n+\tGUEST_FAIL(\"L2 access did not cause a nested page fault\");\n+}\n+\n+static void l2_vmmcall_code(void)\n+{\n+\tasm volatile(\"vmmcall\");\n+\tGUEST_FAIL(\"L2 did not exit on VMMCALL\");\n+}\n+\n+/*\n+ * Whenever hardware reports DecodeAssist information (insn_len != 0), the bytes\n+ * KVM reflects into VMCB12 must be the instruction at the current RIP, never\n+ * stale bytes carried over from a previous L2 exit.\n+ */\n+static void assert_decode_assists_sane(struct vmcb *vmcb)\n+{\n+\tGUEST_ASSERT(vmcb-\u003econtrol.insn_len \u003c=\n+\t\t sizeof(vmcb-\u003econtrol.insn_bytes));\n+\tif (vmcb-\u003econtrol.insn_len)\n+\t\tGUEST_ASSERT(!memcmp(vmcb-\u003econtrol.insn_bytes,\n+\t\t\t\t (void *)vmcb-\u003esave.rip,\n+\t\t\t\t vmcb-\u003econtrol.insn_len));\n+}\n+\n+static void l1_guest_code(struct svm_test_data *svm)\n+{\n+\tunsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];\n+\tstruct vmcb *vmcb = svm-\u003evmcb;\n+\n+\tGUEST_ASSERT(this_cpu_has(X86_FEATURE_DECODEASSISTS));\n+\n+\tgeneric_svm_setup(svm, l2_guest_code,\n+\t\t\t \u0026l2_guest_stack[L2_GUEST_STACK_SIZE]);\n+\n+\t/* A real nested #NPF must reflect valid decode information to L1. */\n+\trun_guest(vmcb, svm-\u003evmcb_gpa);\n+\n+\tGUEST_ASSERT_EQ(vmcb-\u003econtrol.exit_code, SVM_EXIT_NPF);\n+\tGUEST_ASSERT(vmcb-\u003econtrol.insn_len);\n+\tassert_decode_assists_sane(vmcb);\n+\n+\t/*\n+\t * Redirect L2 past the still-faulting access to a VMMCALL. KVM reuses\n+\t * its internal VMCB02, which now holds the #NPF's decode bytes, so this\n+\t * exercises the path that must clear DecodeAssist state and ensures the\n+\t * prior exit's bytes are not leaked into a subsequent exit.\n+\t */\n+\tvmcb-\u003esave.rip = (u64)l2_vmmcall_code;\n+\trun_guest(vmcb, svm-\u003evmcb_gpa);\n+\n+\tGUEST_ASSERT_EQ(vmcb-\u003econtrol.exit_code, SVM_EXIT_VMMCALL);\n+\tassert_decode_assists_sane(vmcb);\n+\n+\tGUEST_DONE();\n+}\n+\n+int main(int argc, char *argv[])\n+{\n+\tgva_t svm_gva, npf_gva;\n+\tgpa_t npf_gpa;\n+\tstruct kvm_vcpu *vcpu;\n+\tstruct kvm_vm *vm;\n+\tu64 *pte;\n+\n+\tTEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SVM));\n+\tTEST_REQUIRE(kvm_cpu_has(X86_FEATURE_NPT));\n+\tTEST_REQUIRE(kvm_cpu_has(X86_FEATURE_DECODEASSISTS));\n+\n+\tvm = vm_create_with_one_vcpu(\u0026vcpu, l1_guest_code);\n+\tvm_enable_npt(vm);\n+\tvcpu_alloc_svm(vm, \u0026svm_gva);\n+\tnpf_gva = (gva_t)\u0026npf_target;\n+\tnpf_gpa = addr_gva2gpa(vm, npf_gva);\n+\n+\ttdp_identity_map_default_memslots(vm);\n+\tpte = tdp_get_pte(vm, npf_gpa);\n+\t*pte \u0026= ~PTE_PRESENT_MASK(\u0026vm-\u003estage2_mmu);\n+\n+\tvcpu_args_set(vcpu, 1, svm_gva);\n+\tvcpu_run(vcpu);\n+\tTEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);\n+\tTEST_ASSERT_EQ(get_ucall(vcpu, NULL), UCALL_DONE);\n+\n+\tkvm_vm_free(vm);\n+\treturn 0;\n+}\n"
} |
| 2/1 | 2026/06/29 13:45 | agent | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: {
"EnableConfigs": [
"KVM_AMD"
],
"FocusSymbols": [
"nested_svm_vmexit_update_vmcb12",
"nested_svm_exit_handled",
"nested_vmcb02_prepare_control",
"nested_svm_clear_decode_assists",
"nested_svm_copy_decode_assists"
],
"Reasoning": "The patch fixes a bug in nested SVM virtualization where DecodeAssist data could be leaked from a previous exit to a subsequent exit. It modifies core KVM SVM logic for handling nested VM exits and preparing VMCB02 controls. This is functional code reachable from userspace via KVM ioctls (specifically running a nested guest), so it should be fuzzed.",
"WorthFuzzing": true
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Do not list too generic configs (we already have them enabled). Only list those that specifically cover the modified code. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit 4e3e3d916a91f4feeddd5ded7ff4dfbabc9c2525
Author: syz-cluster <triage@syzkaller.com>
Date: Mon Jun 29 13:45:00 2026 +0000
syz-cluster: applied patch under review
diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
index b340dc9991adb4..50e9ffa5f9fd4d 100644
--- a/arch/x86/kvm/svm/nested.c
+++ b/arch/x86/kvm/svm/nested.c
@@ -33,6 +33,33 @@
#define CC KVM_NESTED_VMENTER_CONSISTENCY_CHECK
+static void nested_svm_clear_decode_assists(struct vmcb *vmcb)
+{
+ vmcb->control.insn_len = 0;
+ memset(vmcb->control.insn_bytes, 0,
+ sizeof(vmcb->control.insn_bytes));
+}
+
+static void nested_svm_copy_decode_assists(struct vmcb *to, struct vmcb *from)
+{
+ u8 insn_len = from->control.insn_len;
+
+ nested_svm_clear_decode_assists(to);
+
+ /*
+ * Hardware leaves insn_len zero when no DecodeAssist data is available.
+ * Keep that as the nested-visible "no decode info" marker.
+ */
+ if (!insn_len)
+ return;
+
+ if (WARN_ON_ONCE(insn_len > sizeof(from->control.insn_bytes)))
+ return;
+
+ to->control.insn_len = insn_len;
+ memcpy(to->control.insn_bytes, from->control.insn_bytes, insn_len);
+}
+
static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu,
struct x86_exception *fault)
{
@@ -838,7 +865,10 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm)
/*
* Filled at exit: exit_code, exit_info_1, exit_info_2, exit_int_info,
* exit_int_info_err, next_rip, insn_len, insn_bytes.
+ * Clear stale DecodeAssist data before L2 runs.
*/
+ nested_svm_clear_decode_assists(vmcb02);
+ svm->nested.decode_assists_valid = false;
if (guest_cpu_cap_has(vcpu, X86_FEATURE_VGIF) &&
(vmcb12_ctrl->int_ctl & V_GIF_ENABLE_MASK))
@@ -1251,6 +1281,18 @@ static int nested_svm_vmexit_update_vmcb12(struct kvm_vcpu *vcpu)
if (guest_cpu_cap_has(vcpu, X86_FEATURE_NRIPS))
vmcb12->control.next_rip = vmcb02->control.next_rip;
+ /*
+ * Copy DecodeAssist data only for real VMCB02 exits. KVM-synthesized
+ * exits report no decode info to L1.
+ */
+ if (svm->nested.decode_assists_valid &&
+ guest_cpu_cap_has(vcpu, X86_FEATURE_DECODEASSISTS))
+ nested_svm_copy_decode_assists(vmcb12, vmcb02);
+ else
+ nested_svm_clear_decode_assists(vmcb12);
+
+ svm->nested.decode_assists_valid = false;
+
if (nested_vmcb12_has_lbrv(vcpu))
svm_copy_lbrs(&vmcb12->save, &vmcb02->save);
@@ -1593,8 +1635,11 @@ int nested_svm_exit_handled(struct vcpu_svm *svm)
vmexit = nested_svm_intercept(svm);
- if (vmexit == NESTED_EXIT_DONE)
+ if (vmexit == NESTED_EXIT_DONE) {
+ /* This path reflects a real VMCB02 exit directly to L1. */
+ svm->nested.decode_assists_valid = true;
nested_svm_vmexit(svm);
+ }
return vmexit;
}
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index e02a38da5296e3..366e7ef787b260 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -5470,6 +5470,9 @@ static __init void svm_set_cpu_caps(void)
*/
kvm_cpu_cap_set(X86_FEATURE_FLUSHBYASID);
+ if (boot_cpu_has(X86_FEATURE_DECODEASSISTS))
+ kvm_cpu_cap_set(X86_FEATURE_DECODEASSISTS);
+
if (nrips)
kvm_cpu_cap_set(X86_FEATURE_NRIPS);
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 5137416be593d7..be7fdcd124b742 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -238,6 +238,12 @@ struct svm_nested_state {
* on its side.
*/
bool force_msr_bitmap_recalc;
+
+ /*
+ * True only while reflecting a real VMCB02 exit whose DecodeAssist
+ * fields may be copied to VMCB12. KVM-synthesized exits leave it clear.
+ */
+ bool decode_assists_valid;
};
struct vcpu_sev_es_state {
diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index 9118a5a51b89fd..23bf5107439228 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -114,6 +114,7 @@ TEST_GEN_PROGS_x86 += x86/vmx_preemption_timer_test
TEST_GEN_PROGS_x86 += x86/svm_vmcall_test
TEST_GEN_PROGS_x86 += x86/svm_int_ctl_test
TEST_GEN_PROGS_x86 += x86/svm_nested_clear_efer_svme
+TEST_GEN_PROGS_x86 += x86/svm_nested_decode_assists_test
TEST_GEN_PROGS_x86 += x86/svm_nested_shutdown_test
TEST_GEN_PROGS_x86 += x86/svm_nested_soft_inject_test
TEST_GEN_PROGS_x86 += x86/svm_nested_vmcb12_gpa
diff --git a/tools/testing/selftests/kvm/include/x86/processor.h b/tools/testing/selftests/kvm/include/x86/processor.h
index 77f576ee7789d8..ee4520ff2f8937 100644
--- a/tools/testing/selftests/kvm/include/x86/processor.h
+++ b/tools/testing/selftests/kvm/include/x86/processor.h
@@ -201,6 +201,7 @@ struct kvm_x86_cpu_feature {
#define X86_FEATURE_LBRV KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 1)
#define X86_FEATURE_NRIPS KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 3)
#define X86_FEATURE_TSCRATEMSR KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 4)
+#define X86_FEATURE_DECODEASSISTS KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 7)
#define X86_FEATURE_PAUSEFILTER KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 10)
#define X86_FEATURE_PFTHRESHOLD KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 12)
#define X86_FEATURE_V_VMSAVE_VMLOAD KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 15)
diff --git a/tools/testing/selftests/kvm/x86/svm_nested_decode_assists_test.c b/tools/testing/selftests/kvm/x86/svm_nested_decode_assists_test.c
new file mode 100644
index 00000000000000..6b5d38d9d36c45
--- /dev/null
+++ b/tools/testing/selftests/kvm/x86/svm_nested_decode_assists_test.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include "test_util.h"
+#include "kvm_util.h"
+#include "processor.h"
+#include "svm_util.h"
+
+#define L2_GUEST_STACK_SIZE 64
+
+static uint64_t npf_target __aligned(PAGE_SIZE);
+
+static void l2_guest_code(void)
+{
+ asm volatile("mov (%0), %%rax" : : "r"(&npf_target) : "rax", "memory");
+ GUEST_FAIL("L2 access did not cause a nested page fault");
+}
+
+static void l2_vmmcall_code(void)
+{
+ asm volatile("vmmcall");
+ GUEST_FAIL("L2 did not exit on VMMCALL");
+}
+
+/*
+ * Whenever hardware reports DecodeAssist information (insn_len != 0), the bytes
+ * KVM reflects into VMCB12 must be the instruction at the current RIP, never
+ * stale bytes carried over from a previous L2 exit.
+ */
+static void assert_decode_assists_sane(struct vmcb *vmcb)
+{
+ GUEST_ASSERT(vmcb->control.insn_len <=
+ sizeof(vmcb->control.insn_bytes));
+ if (vmcb->control.insn_len)
+ GUEST_ASSERT(!memcmp(vmcb->control.insn_bytes,
+ (void *)vmcb->save.rip,
+ vmcb->control.insn_len));
+}
+
+static void l1_guest_code(struct svm_test_data *svm)
+{
+ unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
+ struct vmcb *vmcb = svm->vmcb;
+
+ GUEST_ASSERT(this_cpu_has(X86_FEATURE_DECODEASSISTS));
+
+ generic_svm_setup(svm, l2_guest_code,
+ &l2_guest_stack[L2_GUEST_STACK_SIZE]);
+
+ /* A real nested #NPF must reflect valid decode information to L1. */
+ run_guest(vmcb, svm->vmcb_gpa);
+
+ GUEST_ASSERT_EQ(vmcb->control.exit_code, SVM_EXIT_NPF);
+ GUEST_ASSERT(vmcb->control.insn_len);
+ assert_decode_assists_sane(vmcb);
+
+ /*
+ * Redirect L2 past the still-faulting access to a VMMCALL. KVM reuses
+ * its internal VMCB02, which now holds the #NPF's decode bytes, so this
+ * exercises the path that must clear DecodeAssist state and ensures the
+ * prior exit's bytes are not leaked into a subsequent exit.
+ */
+ vmcb->save.rip = (u64)l2_vmmcall_code;
+ run_guest(vmcb, svm->vmcb_gpa);
+
+ GUEST_ASSERT_EQ(vmcb->control.exit_code, SVM_EXIT_VMMCALL);
+ assert_decode_assists_sane(vmcb);
+
+ GUEST_DONE();
+}
+
+int main(int argc, char *argv[])
+{
+ gva_t svm_gva, npf_gva;
+ gpa_t npf_gpa;
+ struct kvm_vcpu *vcpu;
+ struct kvm_vm *vm;
+ u64 *pte;
+
+ TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SVM));
+ TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_NPT));
+ TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_DECODEASSISTS));
+
+ vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code);
+ vm_enable_npt(vm);
+ vcpu_alloc_svm(vm, &svm_gva);
+ npf_gva = (gva_t)&npf_target;
+ npf_gpa = addr_gva2gpa(vm, npf_gva);
+
+ tdp_identity_map_default_memslots(vm);
+ pte = tdp_get_pte(vm, npf_gpa);
+ *pte &= ~PTE_PRESENT_MASK(&vm->stage2_mmu);
+
+ vcpu_args_set(vcpu, 1, svm_gva);
+ vcpu_run(vcpu);
+ TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
+ TEST_ASSERT_EQ(get_ucall(vcpu, NULL), UCALL_DONE);
+
+ kvm_vm_free(vm);
+ return 0;
+}
|
| 3/2 | 2026/06/29 13:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 5431 output: 27 thoughts: 343 Thoughts: **Analyzing a KVM Patch for Nested AMD SVM** Okay, so I'm looking at this patch and it's touching `arch/x86/kvm/svm/nested.c` and `arch/x86/kvm/svm/svm.c`. That immediately tells me this is focused on nested virtualization with AMD's Secure Virtual Machine (SVM) technology within KVM. Specifically, I see it's introducing `nested_svm_clear_decode_assists` and `nested_svm_copy_decode_assists`, and modifying `nested_vmcb02_prepare_control`, `nested_svm_vmexit_update_vmcb12`, and `nested_svm_exit_handled`. Plus, it's adding `X86_FEATURE_DECODEASSISTS` to `svm_set_cpu_caps`. This all points towards dealing with DecodeAssist data in a nested SVM environment. Ah, right, this is about fixing a potential leak. It's making sure that DecodeAssist information, like the instruction bytes and lengths, isn't being carried over improperly from one VM exit to the next in the nested scenario. So, it's clearing the assist data before running the Level 2 VM and copying only when it's valid for VMCB02 exits. That's a classic race condition or data corruption fix, trying to ensure proper isolation. Functionally, this impacts the execution flow, which always demands careful scrutiny. The key question is whether this code path is actually *reachable* in a typical setup. I'm thinking about virtualized environments, like GCE or QEMU. Nested virtualization is definitely supported in both, so it's testable, and if it's testable, it's reachable. Wait, wasn't there something about syzkaller? Syzkaller runs in QEMU, and QEMU supports nested SVM... so *yes*, this is definitely reachable and potentially exploitable. Now, let's nail down the configuration prerequisites. We're going to need `CONFIG_KVM` and `CONFIG_KVM_AMD`, obviously. Time to pull up the source and search for those function names, `nested_svm_vmexit_update_vmcb12` and `nested_svm_exit_handled`. I want to see the call graphs and understand the exact contexts this code executes in, the entry and exit points. |
| 4/2 | 2026/06/29 13:45 | tool | grepper |
0mArgs:{
"Expression": "nested_svm_vmexit_update_vmcb12"
}Results: {
"Output": "arch/x86/kvm/svm/nested.c=1218=void svm_copy_vmloadsave_state(struct vmcb *to_vmcb, struct vmcb *from_vmcb)\n--\narch/x86/kvm/svm/nested.c-1233-\narch/x86/kvm/svm/nested.c:1234:static int nested_svm_vmexit_update_vmcb12(struct kvm_vcpu *vcpu)\narch/x86/kvm/svm/nested.c-1235-{\n--\narch/x86/kvm/svm/nested.c=1314=void nested_svm_vmexit(struct vcpu_svm *svm)\n--\narch/x86/kvm/svm/nested.c-1319-\narch/x86/kvm/svm/nested.c:1320:\tif (nested_svm_vmexit_update_vmcb12(vcpu))\narch/x86/kvm/svm/nested.c-1321-\t\tkvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);\n"
} |
| 5/2 | 2026/06/29 13:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 6616 output: 19 thoughts: 12 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience and presented in the first person: **KVM_AMD Configuration Review** Alright, let's dive into the Kconfig files. My initial thought is to specifically target the `KVM_AMD` configuration option. I need to refresh my understanding of its current state and dependencies within the kernel build system. This is where the real work begins, tracing through the nested configurations, looking for potential areas of concern or opportunity. What are the associated features? Are there any newly introduced dependencies or conflicts I should be aware of, especially given the rapid pace of change in both AMD hardware and KVM itself? I'll probably start with a grep to make sure I get a comprehensive overview. |
| 6/2 | 2026/06/29 13:45 | tool | grepper |
0mArgs:{
"Expression": "config KVM_AMD"
}Results: {
"Output": "arch/x86/kvm/Kconfig=134=config KVM_INTEL_TDX\n--\narch/x86/kvm/Kconfig-145-\narch/x86/kvm/Kconfig:146:config KVM_AMD\narch/x86/kvm/Kconfig-147-\ttristate \"KVM for AMD processors support\"\n--\narch/x86/kvm/Kconfig-155-\narch/x86/kvm/Kconfig:156:config KVM_AMD_SEV\narch/x86/kvm/Kconfig-157-\tbool \"AMD Secure Encrypted Virtualization (SEV) support\"\n"
} |
| 7/2 | 2026/06/29 13:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 6988 output: 17 thoughts: 23 Thoughts: Okay, here's my take on those thoughts, framed as my own: **KVM_AMD and Nested SVM Configurations** Alright, so I'm diving into this KVM setup and the first thing that pops into my head is `KVM_AMD`. That seems like the core configuration, the foundation. But I can't help but wonder... is there a *specific* configuration, a particular flag, a special setting, for nested SVM? We're dealing with virtualization within virtualization here, and I know that adds another layer of complexity. I need to make sure I'm not missing anything critical for optimal performance and stability within that nested environment. Time to dig deeper and see if there are any documented or suggested customizations. |
| 8/2 | 2026/06/29 13:45 | tool | grepper |
0mArgs:{
"Expression": "nested_svm"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 536 lines.\nUse more precise expression if possible.\n\narch/x86/kvm/svm/hyperv.c=9=void svm_hv_inject_synthetic_vmexit_post_tlb_flush(struct kvm_vcpu *vcpu)\n--\narch/x86/kvm/svm/hyperv.c-21-\tsvm-\u003evmcb-\u003econtrol.exit_info_2 = 0;\narch/x86/kvm/svm/hyperv.c:22:\tnested_svm_vmexit(svm);\narch/x86/kvm/svm/hyperv.c-23-}\n--\narch/x86/kvm/svm/hyperv.h-14-#ifdef CONFIG_KVM_HYPERV\narch/x86/kvm/svm/hyperv.h:15:static inline void nested_svm_hv_update_vm_vp_ids(struct kvm_vcpu *vcpu)\narch/x86/kvm/svm/hyperv.h-16-{\n--\narch/x86/kvm/svm/hyperv.h-28-\narch/x86/kvm/svm/hyperv.h:29:static inline bool nested_svm_l2_tlb_flush_enabled(struct kvm_vcpu *vcpu)\narch/x86/kvm/svm/hyperv.h-30-{\n--\narch/x86/kvm/svm/hyperv.h-43-\narch/x86/kvm/svm/hyperv.h:44:static inline bool nested_svm_is_l2_tlb_flush_hcall(struct kvm_vcpu *vcpu)\narch/x86/kvm/svm/hyperv.h-45-{\narch/x86/kvm/svm/hyperv.h-46-\treturn guest_hv_cpuid_has_l2_tlb_flush(vcpu) \u0026\u0026\narch/x86/kvm/svm/hyperv.h:47:\t nested_svm_l2_tlb_flush_enabled(vcpu) \u0026\u0026\narch/x86/kvm/svm/hyperv.h-48-\t kvm_hv_is_tlb_flush_hcall(vcpu);\n--\narch/x86/kvm/svm/hyperv.h=51=void svm_hv_inject_synthetic_vmexit_post_tlb_flush(struct kvm_vcpu *vcpu);\narch/x86/kvm/svm/hyperv.h-52-#else /* CONFIG_KVM_HYPERV */\narch/x86/kvm/svm/hyperv.h:53:static inline void nested_svm_hv_update_vm_vp_ids(struct kvm_vcpu *vcpu) {}\narch/x86/kvm/svm/hyperv.h:54:static inline bool nested_svm_is_l2_tlb_flush_hcall(struct kvm_vcpu *vcpu)\narch/x86/kvm/svm/hyperv.h-55-{\n--\narch/x86/kvm/svm/nested.c-35-\narch/x86/kvm/svm/nested.c:36:static void nested_svm_clear_decode_assists(struct vmcb *vmcb)\narch/x86/kvm/svm/nested.c-37-{\n--\narch/x86/kvm/svm/nested.c-42-\narch/x86/kvm/svm/nested.c:43:static void nested_svm_copy_decode_assists(struct vmcb *to, struct vmcb *from)\narch/x86/kvm/svm/nested.c-44-{\n--\narch/x86/kvm/svm/nested.c-46-\narch/x86/kvm/svm/nested.c:47:\tnested_svm_clear_decode_assists(to);\narch/x86/kvm/svm/nested.c-48-\n--\narch/x86/kvm/svm/nested.c-62-\narch/x86/kvm/svm/nested.c:63:static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu,\narch/x86/kvm/svm/nested.c-64-\t\t\t\t struct x86_exception *fault)\n--\narch/x86/kvm/svm/nested.c-81-\narch/x86/kvm/svm/nested.c:82:\tnested_svm_vmexit(svm);\narch/x86/kvm/svm/nested.c-83-}\narch/x86/kvm/svm/nested.c-84-\narch/x86/kvm/svm/nested.c:85:static u64 nested_svm_get_tdp_pdptr(struct kvm_vcpu *vcpu, int index)\narch/x86/kvm/svm/nested.c-86-{\n--\narch/x86/kvm/svm/nested.c-102-\narch/x86/kvm/svm/nested.c:103:static unsigned long nested_svm_get_tdp_cr3(struct kvm_vcpu *vcpu)\narch/x86/kvm/svm/nested.c-104-{\n--\narch/x86/kvm/svm/nested.c-109-\narch/x86/kvm/svm/nested.c:110:static void nested_svm_init_mmu_context(struct kvm_vcpu *vcpu)\narch/x86/kvm/svm/nested.c-111-{\n--\narch/x86/kvm/svm/nested.c-125-\t\t\t\tsvm-\u003enested.ctl.nested_cr3);\narch/x86/kvm/svm/nested.c:126:\tvcpu-\u003earch.mmu-\u003eget_guest_pgd = nested_svm_get_tdp_cr3;\narch/x86/kvm/svm/nested.c:127:\tvcpu-\u003earch.mmu-\u003eget_pdptr = nested_svm_get_tdp_pdptr;\narch/x86/kvm/svm/nested.c:128:\tvcpu-\u003earch.mmu-\u003einject_page_fault = nested_svm_inject_npf_exit;\narch/x86/kvm/svm/nested.c-129-\tvcpu-\u003earch.walk_mmu = \u0026vcpu-\u003earch.nested_mmu;\n--\narch/x86/kvm/svm/nested.c-131-\narch/x86/kvm/svm/nested.c:132:static void nested_svm_uninit_mmu_context(struct kvm_vcpu *vcpu)\narch/x86/kvm/svm/nested.c-133-{\n--\narch/x86/kvm/svm/nested.c=152=void nested_vmcb02_recalc_intercepts(struct vcpu_svm *svm)\n--\narch/x86/kvm/svm/nested.c-222- */\narch/x86/kvm/svm/nested.c:223:static int nested_svm_msrpm_merge_offsets[10] __ro_after_init;\narch/x86/kvm/svm/nested.c:224:static int nested_svm_nr_msrpm_merge_offsets __ro_after_init;\narch/x86/kvm/svm/nested.c-225-typedef unsigned long nsvm_msrpm_merge_t;\narch/x86/kvm/svm/nested.c-226-\narch/x86/kvm/svm/nested.c:227:int __init nested_svm_init_msrpm_merge_offsets(void)\narch/x86/kvm/svm/nested.c-228-{\n--\narch/x86/kvm/svm/nested.c-282-\narch/x86/kvm/svm/nested.c:283:\t\tfor (j = 0; j \u003c nested_svm_nr_msrpm_merge_offsets; j++) {\narch/x86/kvm/svm/nested.c:284:\t\t\tif (nested_svm_msrpm_merge_offsets[j] == offset)\narch/x86/kvm/svm/nested.c-285-\t\t\t\tbreak;\n--\narch/x86/kvm/svm/nested.c-287-\narch/x86/kvm/svm/nested.c:288:\t\tif (j \u003c nested_svm_nr_msrpm_merge_offsets)\narch/x86/kvm/svm/nested.c-289-\t\t\tcontinue;\narch/x86/kvm/svm/nested.c-290-\narch/x86/kvm/svm/nested.c:291:\t\tif (WARN_ON(j \u003e= ARRAY_SIZE(nested_svm_msrpm_merge_offsets)))\narch/x86/kvm/svm/nested.c-292-\t\t\treturn -EIO;\narch/x86/kvm/svm/nested.c-293-\narch/x86/kvm/svm/nested.c:294:\t\tnested_svm_msrpm_merge_offsets[j] = offset;\narch/x86/kvm/svm/nested.c:295:\t\tnested_svm_nr_msrpm_merge_offsets++;\narch/x86/kvm/svm/nested.c-296-\t}\n--\narch/x86/kvm/svm/nested.c-305- */\narch/x86/kvm/svm/nested.c:306:static bool nested_svm_merge_msrpm(struct kvm_vcpu *vcpu)\narch/x86/kvm/svm/nested.c-307-{\n--\narch/x86/kvm/svm/nested.c-334-\narch/x86/kvm/svm/nested.c:335:\tfor (i = 0; i \u003c nested_svm_nr_msrpm_merge_offsets; i++) {\narch/x86/kvm/svm/nested.c:336:\t\tconst int p = nested_svm_msrpm_merge_offsets[i];\narch/x86/kvm/svm/nested.c-337-\t\tnsvm_msrpm_merge_t l1_val;\n--\narch/x86/kvm/svm/nested.c-360- */\narch/x86/kvm/svm/nested.c:361:static bool nested_svm_check_bitmap_pa(struct kvm_vcpu *vcpu, u64 pa, u32 size)\narch/x86/kvm/svm/nested.c-362-{\n--\narch/x86/kvm/svm/nested.c-368-\narch/x86/kvm/svm/nested.c:369:static bool nested_svm_event_inj_valid_exept(struct kvm_vcpu *vcpu, u8 vector)\narch/x86/kvm/svm/nested.c-370-{\n--\narch/x86/kvm/svm/nested.c-397- */\narch/x86/kvm/svm/nested.c:398:static bool nested_svm_check_event_inj(struct kvm_vcpu *vcpu, u32 event_inj)\narch/x86/kvm/svm/nested.c-399-{\n--\narch/x86/kvm/svm/nested.c-410-\tif (type == SVM_EVTINJ_TYPE_EXEPT \u0026\u0026\narch/x86/kvm/svm/nested.c:411:\t !nested_svm_event_inj_valid_exept(vcpu, vector))\narch/x86/kvm/svm/nested.c-412-\t\treturn false;\n--\narch/x86/kvm/svm/nested.c=417=static bool nested_vmcb_check_controls(struct kvm_vcpu *vcpu,\n--\narch/x86/kvm/svm/nested.c-429-\narch/x86/kvm/svm/nested.c:430:\tif (CC(!nested_svm_check_bitmap_pa(vcpu, control-\u003emsrpm_base_pa,\narch/x86/kvm/svm/nested.c-431-\t\t\t\t\t MSRPM_SIZE)))\narch/x86/kvm/svm/nested.c-432-\t\treturn false;\narch/x86/kvm/svm/nested.c:433:\tif (CC(!nested_svm_check_bitmap_pa(vcpu, control-\u003eiopm_base_pa,\narch/x86/kvm/svm/nested.c-434-\t\t\t\t\t IOPM_SIZE)))\n--\narch/x86/kvm/svm/nested.c-441-\narch/x86/kvm/svm/nested.c:442:\tif (CC(!nested_svm_check_event_inj(vcpu, control-\u003eevent_inj)))\narch/x86/kvm/svm/nested.c-443-\t\treturn false;\n--\narch/x86/kvm/svm/nested.c=449=static bool nested_vmcb_check_save(struct kvm_vcpu *vcpu,\n--\narch/x86/kvm/svm/nested.c-487-\narch/x86/kvm/svm/nested.c:488:int nested_svm_check_cached_vmcb12(struct kvm_vcpu *vcpu)\narch/x86/kvm/svm/nested.c-489-{\n--\narch/x86/kvm/svm/nested.c-502- */\narch/x86/kvm/svm/nested.c:503:#define __nested_svm_sanitize_intercept(__vcpu, __control, fname, iname)\t\\\narch/x86/kvm/svm/nested.c-504-do {\t\t\t\t\t\t\t\t\t\t\\\n--\narch/x86/kvm/svm/nested.c-508-\narch/x86/kvm/svm/nested.c:509:#define nested_svm_sanitize_intercept(__vcpu, __control, name)\t\t\t\\\narch/x86/kvm/svm/nested.c:510:\t__nested_svm_sanitize_intercept(__vcpu, __control, name, name)\narch/x86/kvm/svm/nested.c-511-\n--\narch/x86/kvm/svm/nested.c=513=void __nested_copy_vmcb_control_to_cache(struct kvm_vcpu *vcpu,\n--\narch/x86/kvm/svm/nested.c-521-\narch/x86/kvm/svm/nested.c:522:\t__nested_svm_sanitize_intercept(vcpu, to, XSAVE, XSETBV);\narch/x86/kvm/svm/nested.c:523:\tnested_svm_sanitize_intercept(vcpu, to, INVPCID);\narch/x86/kvm/svm/nested.c:524:\tnested_svm_sanitize_intercept(vcpu, to, RDTSCP);\narch/x86/kvm/svm/nested.c:525:\tnested_svm_sanitize_intercept(vcpu, to, SKINIT);\narch/x86/kvm/svm/nested.c:526:\tnested_svm_sanitize_intercept(vcpu, to, RDPRU);\narch/x86/kvm/svm/nested.c-527-\n--\narch/x86/kvm/svm/nested.c=651=static void nested_save_pending_event_to_vmcb12(struct vcpu_svm *svm,\n--\narch/x86/kvm/svm/nested.c-683-\narch/x86/kvm/svm/nested.c:684:static void nested_svm_transition_tlb_flush(struct kvm_vcpu *vcpu)\narch/x86/kvm/svm/nested.c-685-{\n--\narch/x86/kvm/svm/nested.c-709- */\narch/x86/kvm/svm/nested.c:710:static int nested_svm_load_cr3(struct kvm_vcpu *vcpu, unsigned long cr3,\narch/x86/kvm/svm/nested.c-711-\t\t\t bool nested_npt, bool reload_pdptrs)\n--\narch/x86/kvm/svm/nested.c=850=static void nested_vmcb02_prepare_control(struct vcpu_svm *svm)\n--\narch/x86/kvm/svm/nested.c-859-\narch/x86/kvm/svm/nested.c:860:\tnested_svm_transition_tlb_flush(vcpu);\narch/x86/kvm/svm/nested.c-861-\n--\narch/x86/kvm/svm/nested.c-869-\t */\narch/x86/kvm/svm/nested.c:870:\tnested_svm_clear_decode_assists(vmcb02);\narch/x86/kvm/svm/nested.c-871-\tsvm-\u003enested.decode_assists_valid = false;\n--\narch/x86/kvm/svm/nested.c-937-\tif (nested_npt_enabled(svm))\narch/x86/kvm/svm/nested.c:938:\t\tnested_svm_init_mmu_context(vcpu);\narch/x86/kvm/svm/nested.c-939-\n--\narch/x86/kvm/svm/nested.c-947-\t svm-\u003etsc_ratio_msr != kvm_caps.default_tsc_scaling_ratio)\narch/x86/kvm/svm/nested.c:948:\t\tnested_svm_update_tsc_ratio_msr(vcpu);\narch/x86/kvm/svm/nested.c-949-\n--\narch/x86/kvm/svm/nested.c-1016-\narch/x86/kvm/svm/nested.c:1017:static void nested_svm_copy_common_state(struct vmcb *from_vmcb, struct vmcb *to_vmcb)\narch/x86/kvm/svm/nested.c-1018-{\n--\narch/x86/kvm/svm/nested.c=1029=int enter_svm_guest_mode(struct kvm_vcpu *vcpu, u64 vmcb12_gpa, bool from_vmrun)\n--\narch/x86/kvm/svm/nested.c-1057-\narch/x86/kvm/svm/nested.c:1058:\tnested_svm_copy_common_state(svm-\u003evmcb01.ptr, svm-\u003enested.vmcb02.ptr);\narch/x86/kvm/svm/nested.c-1059-\n--\narch/x86/kvm/svm/nested.c-1063-\narch/x86/kvm/svm/nested.c:1064:\tret = nested_svm_load_cr3(\u0026svm-\u003evcpu, svm-\u003enested.save.cr3,\narch/x86/kvm/svm/nested.c-1065-\t\t\t\t nested_npt_enabled(svm), from_vmrun);\n--\narch/x86/kvm/svm/nested.c-1076-\narch/x86/kvm/svm/nested.c:1077:\tnested_svm_hv_update_vm_vp_ids(vcpu);\narch/x86/kvm/svm/nested.c-1078-\n--\narch/x86/kvm/svm/nested.c-1081-\narch/x86/kvm/svm/nested.c:1082:static int nested_svm_copy_vmcb12_to_cache(struct kvm_vcpu *vcpu, u64 vmcb12_gpa)\narch/x86/kvm/svm/nested.c-1083-{\n--\narch/x86/kvm/svm/nested.c-1095-\narch/x86/kvm/svm/nested.c:1096:\tif (nested_svm_check_cached_vmcb12(vcpu) \u003c 0) {\narch/x86/kvm/svm/nested.c-1097-\t\tvmcb12-\u003econtrol.exit_code = SVM_EXIT_ERR;\n--\narch/x86/kvm/svm/nested.c-1109-\narch/x86/kvm/svm/nested.c:1110:int nested_svm_vmrun(struct kvm_vcpu *vcpu)\narch/x86/kvm/svm/nested.c-1111-{\n--\narch/x86/kvm/svm/nested.c-1142-\narch/x86/kvm/svm/nested.c:1143:\tret = nested_svm_copy_vmcb12_to_cache(vcpu, vmcb12_gpa);\narch/x86/kvm/svm/nested.c-1144-\tif (ret) {\n--\narch/x86/kvm/svm/nested.c-1170-\tif (enter_svm_guest_mode(vcpu, vmcb12_gpa, true) ||\narch/x86/kvm/svm/nested.c:1171:\t !nested_svm_merge_msrpm(vcpu)) {\narch/x86/kvm/svm/nested.c-1172-\t\tvcpu-\u003earch.nested_run_pending = 0;\n--\narch/x86/kvm/svm/nested.c-1179-\narch/x86/kvm/svm/nested.c:1180:\t\tnested_svm_vmexit(svm);\narch/x86/kvm/svm/nested.c-1181-\t}\n--\narch/x86/kvm/svm/nested.c=1218=void svm_copy_vmloadsave_state(struct vmcb *to_vmcb, struct vmcb *from_vmcb)\n--\narch/x86/kvm/svm/nested.c-1233-\narch/x86/kvm/svm/nested.c:1234:static int nested_svm_vmexit_update_vmcb12(struct kvm_vcpu *vcpu)\narch/x86/kvm/svm/nested.c-1235-{\n--\narch/x86/kvm/svm/nested.c-1289-\t guest_cpu_cap_has(vcpu, X86_FEATURE_DECODEASSISTS))\narch/x86/kvm/svm/nested.c:1290:\t\tnested_svm_copy_decode_assists(vmcb12, vmcb02);\narch/x86/kvm/svm/nested.c-1291-\telse\narch/x86/kvm/svm/nested.c:1292:\t\tnested_svm_clear_decode_assists(vmcb12);\narch/x86/kvm/svm/nested.c-1293-\n--\narch/x86/kvm/svm/nested.c-1313-\narch/x86/kvm/svm/nested.c:1314:void nested_svm_vmexit(struct vcpu_svm *svm)\narch/x86/kvm/svm/nested.c-1315-{\n--\narch/x86/kvm/svm/nested.c-1319-\narch/x86/kvm/svm/nested.c:1320:\tif (nested_svm_vmexit_update_vmcb12(vcpu))\narch/x86/kvm/svm/nested.c-1321-\t\tkvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);\n--\narch/x86/kvm/svm/nested.c-1340-\narch/x86/kvm/svm/nested.c:1341:\tnested_svm_copy_common_state(svm-\u003enested.vmcb02.ptr, svm-\u003evmcb01.ptr);\narch/x86/kvm/svm/nested.c-1342-\n--\narch/x86/kvm/svm/nested.c-1427-\narch/x86/kvm/svm/nested.c:1428:\tnested_svm_transition_tlb_flush(vcpu);\narch/x86/kvm/svm/nested.c-1429-\narch/x86/kvm/svm/nested.c:1430:\tnested_svm_uninit_mmu_context(vcpu);\narch/x86/kvm/svm/nested.c-1431-\narch/x86/kvm/svm/nested.c:1432:\tif (nested_svm_load_cr3(vcpu, vmcb01-\u003esave.cr3, false, true))\narch/x86/kvm/svm/nested.c-1433-\t\tkvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);\n--\narch/x86/kvm/svm/nested.c-1463-\narch/x86/kvm/svm/nested.c:1464:static void nested_svm_triple_fault(struct kvm_vcpu *vcpu)\narch/x86/kvm/svm/nested.c-1465-{\n--\narch/x86/kvm/svm/nested.c-1471-\tkvm_clear_request(KVM_REQ_TRIPLE_FAULT, vcpu);\narch/x86/kvm/svm/nested.c:1472:\tnested_svm_simple_vmexit(to_svm(vcpu), SVM_EXIT_SHUTDOWN);\narch/x86/kvm/svm/nested.c-1473-}\n--\narch/x86/kvm/svm/nested.c=1526=void svm_leave_nested(struct kvm_vcpu *vcpu)\n--\narch/x86/kvm/svm/nested.c-1537-\narch/x86/kvm/svm/nested.c:1538:\t\tnested_svm_uninit_mmu_context(vcpu);\narch/x86/kvm/svm/nested.c-1539-\t\tvmcb_mark_all_dirty(svm-\u003evmcb);\n--\narch/x86/kvm/svm/nested.c-1549-\narch/x86/kvm/svm/nested.c:1550:static int nested_svm_exit_handled_msr(struct vcpu_svm *svm)\narch/x86/kvm/svm/nested.c-1551-{\n--\narch/x86/kvm/svm/nested.c-1574-\narch/x86/kvm/svm/nested.c:1575:static int nested_svm_intercept_ioio(struct vcpu_svm *svm)\narch/x86/kvm/svm/nested.c-1576-{\n--\narch/x86/kvm/svm/nested.c-1599-\narch/x86/kvm/svm/nested.c:1600:static int nested_svm_intercept(struct vcpu_svm *svm)\narch/x86/kvm/svm/nested.c-1601-{\n--\narch/x86/kvm/svm/nested.c-1609-\tcase SVM_EXIT_MSR:\narch/x86/kvm/svm/nested.c:1610:\t\tvmexit = nested_svm_exit_handled_msr(svm);\narch/x86/kvm/svm/nested.c-1611-\t\tbreak;\narch/x86/kvm/svm/nested.c-1612-\tcase SVM_EXIT_IOIO:\narch/x86/kvm/svm/nested.c:1613:\t\tvmexit = nested_svm_intercept_ioio(svm);\narch/x86/kvm/svm/nested.c-1614-\t\tbreak;\n--\narch/x86/kvm/svm/nested.c-1617-\t\t * Host-intercepted exceptions have been checked already in\narch/x86/kvm/svm/nested.c:1618:\t\t * nested_svm_exit_special. There is nothing to do here,\narch/x86/kvm/svm/nested.c-1619-\t\t * the vmexit is injected by svm_check_nested_events.\n--\narch/x86/kvm/svm/nested.c-1631-\narch/x86/kvm/svm/nested.c:1632:int nested_svm_exit_handled(struct vcpu_svm *svm)\narch/x86/kvm/svm/nested.c-1633-{\n--\narch/x86/kvm/svm/nested.c-1635-\narch/x86/kvm/svm/nested.c:1636:\tvmexit = nested_svm_intercept(svm);\narch/x86/kvm/svm/nested.c-1637-\n--\narch/x86/kvm/svm/nested.c-1640-\t\tsvm-\u003enested.decode_assists_valid = true;\narch/x86/kvm/svm/nested.c:1641:\t\tnested_svm_vmexit(svm);\narch/x86/kvm/svm/nested.c-1642-\t}\n--\narch/x86/kvm/svm/nested.c-1646-\narch/x86/kvm/svm/nested.c:1647:int nested_svm_check_permissions(struct kvm_vcpu *vcpu)\narch/x86/kvm/svm/nested.c-1648-{\n--\narch/x86/kvm/svm/nested.c-1661-\narch/x86/kvm/svm/nested.c:1662:static bool nested_svm_is_exception_vmexit(struct kvm_vcpu *vcpu, u8 vector,\narch/x86/kvm/svm/nested.c-1663-\t\t\t\t\t u32 error_code)\n--\narch/x86/kvm/svm/nested.c-1669-\narch/x86/kvm/svm/nested.c:1670:static void nested_svm_inject_exception_vmexit(struct kvm_vcpu *vcpu)\narch/x86/kvm/svm/nested.c-1671-{\n--\narch/x86/kvm/svm/nested.c-1701-\narch/x86/kvm/svm/nested.c:1702:\tnested_svm_vmexit(svm);\narch/x86/kvm/svm/nested.c-1703-}\n--\narch/x86/kvm/svm/nested.c=1710=static int svm_check_nested_events(struct kvm_vcpu *vcpu)\n--\narch/x86/kvm/svm/nested.c-1734-\t\t\treturn 0;\narch/x86/kvm/svm/nested.c:1735:\t\tnested_svm_simple_vmexit(svm, SVM_EXIT_INIT);\narch/x86/kvm/svm/nested.c-1736-\t\treturn 0;\n--\narch/x86/kvm/svm/nested.c-1741- return -EBUSY;\narch/x86/kvm/svm/nested.c:1742:\t\tnested_svm_inject_exception_vmexit(vcpu);\narch/x86/kvm/svm/nested.c-1743-\t\treturn 0;\n--\narch/x86/kvm/svm/nested.c-1757-\t\t\treturn 0;\narch/x86/kvm/svm/nested.c:1758:\t\tnested_svm_simple_vmexit(svm, SVM_EXIT_SMI);\narch/x86/kvm/svm/nested.c-1759-\t\treturn 0;\n--\narch/x86/kvm/svm/nested.c-1767-\t\t\treturn 0;\narch/x86/kvm/svm/nested.c:1768:\t\tnested_svm_simple_vmexit(svm, SVM_EXIT_NMI);\narch/x86/kvm/svm/nested.c-1769-\t\treturn 0;\n--\narch/x86/kvm/svm/nested.c-1777-\t\ttrace_kvm_nested_intr_vmexit(svm-\u003evmcb-\u003esave.rip);\narch/x86/kvm/svm/nested.c:1778:\t\tnested_svm_simple_vmexit(svm, SVM_EXIT_INTR);\narch/x86/kvm/svm/nested.c-1779-\t\treturn 0;\n--\narch/x86/kvm/svm/nested.c-1784-\narch/x86/kvm/svm/nested.c:1785:int nested_svm_exit_special(struct vcpu_svm *svm)\narch/x86/kvm/svm/nested.c-1786-{\n--\narch/x86/kvm/svm/nested.c-1808-\t\t/* Hyper-V L2 TLB flush hypercall is handled by L0 */\narch/x86/kvm/svm/nested.c:1809:\t\tif (nested_svm_is_l2_tlb_flush_hcall(vcpu))\narch/x86/kvm/svm/nested.c-1810-\t\t\treturn NESTED_EXIT_HOST;\n--\narch/x86/kvm/svm/nested.c-1818-\narch/x86/kvm/svm/nested.c:1819:void nested_svm_update_tsc_ratio_msr(struct kvm_vcpu *vcpu)\narch/x86/kvm/svm/nested.c-1820-{\n--\narch/x86/kvm/svm/nested.c=1932=static int svm_set_nested_state(struct kvm_vcpu *vcpu,\n--\narch/x86/kvm/svm/nested.c-2006-\t * Validate host state saved from before VMRUN (see\narch/x86/kvm/svm/nested.c:2007:\t * nested_svm_check_permissions).\narch/x86/kvm/svm/nested.c-2008-\t */\n--\narch/x86/kvm/svm/nested.c-2055-\t */\narch/x86/kvm/svm/nested.c:2056:\tret = nested_svm_load_cr3(\u0026svm-\u003evcpu, vcpu-\u003earch.cr3,\narch/x86/kvm/svm/nested.c-2057-\t\t\t\t nested_npt_enabled(svm), false);\n--\narch/x86/kvm/svm/nested.c=2075=static bool svm_get_nested_state_pages(struct kvm_vcpu *vcpu)\n--\narch/x86/kvm/svm/nested.c-2089-\narch/x86/kvm/svm/nested.c:2090:\tif (!nested_svm_merge_msrpm(vcpu)) {\narch/x86/kvm/svm/nested.c-2091-\t\tvcpu-\u003erun-\u003eexit_reason = KVM_EXIT_INTERNAL_ERROR;\n--\narch/x86/kvm/svm/nested.c=2104=struct kvm_x86_nested_ops svm_nested_ops = {\narch/x86/kvm/svm/nested.c-2105-\t.leave_nested = svm_leave_nested,\narch/x86/kvm/svm/nested.c:2106:\t.is_exception_vmexit = nested_svm_is_exception_vmexit,\narch/x86/kvm/svm/nested.c-2107-\t.check_events = svm_check_nested_events,\narch/x86/kvm/svm/nested.c:2108:\t.triple_fault = nested_svm_triple_fault,\narch/x86/kvm/svm/nested.c-2109-\t.get_nested_state_pages = svm_get_nested_state_pages,\n--\narch/x86/kvm/svm/svm.c=2199=static int vmload_vmsave_interception(struct kvm_vcpu *vcpu, bool vmload)\n--\narch/x86/kvm/svm/svm.c-2206-\narch/x86/kvm/svm/svm.c:2207:\tif (nested_svm_check_permissions(vcpu))\narch/x86/kvm/svm/svm.c-2208-\t\treturn 1;\n--\narch/x86/kvm/svm/svm.c=2246=static int vmrun_interception(struct kvm_vcpu *vcpu)\narch/x86/kvm/svm/svm.c-2247-{\narch/x86/kvm/svm/svm.c:2248:\tif (nested_svm_check_permissions(vcpu))\narch/x86/kvm/svm/svm.c-2249-\t\treturn 1;\narch/x86/kvm/svm/svm.c-2250-\narch/x86/kvm/svm/svm.c:2251:\treturn nested_svm_vmrun(vcpu);\narch/x86/kvm/svm/svm.c-2252-}\n--\narch/x86/kvm/svm/svm.c=2286=static int gp_interception(struct kvm_vcpu *vcpu)\n--\narch/x86/kvm/svm/svm.c-2305-\narch/x86/kvm/svm/svm.c:2306:\t\tif (nested_svm_check_permissions(vcpu))\narch/x86/kvm/svm/svm.c-2307-\t\t\treturn 1;\n--\narch/x86/kvm/svm/svm.c-2317-\t\t */\narch/x86/kvm/svm/svm.c:2318:\t\tnested_svm_simple_vmexit(svm, svm_exit_code);\narch/x86/kvm/svm/svm.c-2319-\t\treturn 1;\n--\narch/x86/kvm/svm/svm.c=2366=static int stgi_interception(struct kvm_vcpu *vcpu)\n--\narch/x86/kvm/svm/svm.c-2369-\narch/x86/kvm/svm/svm.c:2370:\tif (nested_svm_check_permissions(vcpu))\narch/x86/kvm/svm/svm.c-2371-\t\treturn 1;\n--\narch/x86/kvm/svm/svm.c=2378=static int clgi_interception(struct kvm_vcpu *vcpu)\n--\narch/x86/kvm/svm/svm.c-2381-\narch/x86/kvm/svm/svm.c:2382:\tif (nested_svm_check_permissions(vcpu))\narch/x86/kvm/svm/svm.c-2383-\t\treturn 1;\n--\narch/x86/kvm/svm/svm.c=2390=static int invlpga_interception(struct kvm_vcpu *vcpu)\n--\narch/x86/kvm/svm/svm.c-2394-\narch/x86/kvm/svm/svm.c:2395:\tif (nested_svm_check_permissions(vcpu))\narch/x86/kvm/svm/svm.c-2396-\t\treturn 1;\n--\narch/x86/kvm/svm/svm.c=2531=static bool check_selective_cr0_intercepted(struct kvm_vcpu *vcpu,\n--\narch/x86/kvm/svm/svm.c-2546-\t\tsvm-\u003evmcb-\u003econtrol.exit_code = SVM_EXIT_CR0_SEL_WRITE;\narch/x86/kvm/svm/svm.c:2547:\t\tret = (nested_svm_exit_handled(svm) == NESTED_EXIT_DONE);\narch/x86/kvm/svm/svm.c-2548-\t}\n--\narch/x86/kvm/svm/svm.c=2938=static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)\n--\narch/x86/kvm/svm/svm.c-2975-\t\t is_guest_mode(vcpu))\narch/x86/kvm/svm/svm.c:2976:\t\t\tnested_svm_update_tsc_ratio_msr(vcpu);\narch/x86/kvm/svm/svm.c-2977-\n--\narch/x86/kvm/svm/svm.c-3010-\t\t * The handling of the MSR bitmap for L2 guests is done in\narch/x86/kvm/svm/svm.c:3011:\t\t * nested_svm_merge_msrpm().\narch/x86/kvm/svm/svm.c-3012-\t\t * We update the L1 MSR bit as well since it will end up\n--\narch/x86/kvm/svm/svm.c=3270=static int vmmcall_interception(struct kvm_vcpu *vcpu)\n--\narch/x86/kvm/svm/svm.c-3277-\t */\narch/x86/kvm/svm/svm.c:3278:\tif (is_guest_mode(vcpu) \u0026\u0026 !nested_svm_is_l2_tlb_flush_hcall(vcpu)) {\narch/x86/kvm/svm/svm.c-3279-\t\tkvm_queue_exception(vcpu, UD_VECTOR);\n--\narch/x86/kvm/svm/svm.c=3653=static int svm_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)\n--\narch/x86/kvm/svm/svm.c-3670-\narch/x86/kvm/svm/svm.c:3671:\t\tvmexit = nested_svm_exit_special(svm);\narch/x86/kvm/svm/svm.c-3672-\narch/x86/kvm/svm/svm.c-3673-\t\tif (vmexit == NESTED_EXIT_CONTINUE)\narch/x86/kvm/svm/svm.c:3674:\t\t\tvmexit = nested_svm_exit_handled(svm);\narch/x86/kvm/svm/svm.c-3675-\n--\narch/x86/kvm/svm/svm.c=3903=static void svm_update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr)\n--\narch/x86/kvm/svm/svm.c-3913-\narch/x86/kvm/svm/svm.c:3914:\tif (nested_svm_virtualize_tpr(vcpu))\narch/x86/kvm/svm/svm.c-3915-\t\treturn;\n--\narch/x86/kvm/svm/svm.c=4198=static inline void sync_cr8_to_lapic(struct kvm_vcpu *vcpu)\n--\narch/x86/kvm/svm/svm.c-4201-\narch/x86/kvm/svm/svm.c:4202:\tif (nested_svm_virtualize_tpr(vcpu))\narch/x86/kvm/svm/svm.c-4203-\t\treturn;\n--\narch/x86/kvm/svm/svm.c=4211=static inline void sync_lapic_to_cr8(struct kvm_vcpu *vcpu)\n--\narch/x86/kvm/svm/svm.c-4215-\narch/x86/kvm/svm/svm.c:4216:\tif (nested_svm_virtualize_tpr(vcpu))\narch/x86/kvm/svm/svm.c-4217-\t\treturn;\n--\narch/x86/kvm/svm/svm.c=4757=static int svm_check_intercept(struct kvm_vcpu *vcpu,\n--\narch/x86/kvm/svm/svm.c-4881-\tvmcb-\u003econtrol.exit_code = icpt_info.exit_code;\narch/x86/kvm/svm/svm.c:4882:\tvmexit = nested_svm_exit_handled(svm);\narch/x86/kvm/svm/svm.c-4883-\n--\narch/x86/kvm/svm/svm.c=4939=static int svm_enter_smm(struct kvm_vcpu *vcpu, union kvm_smram *smram)\n--\narch/x86/kvm/svm/svm.c-4961-\narch/x86/kvm/svm/svm.c:4962:\tnested_svm_simple_vmexit(svm, SVM_EXIT_SW);\narch/x86/kvm/svm/svm.c-4963-\n--\narch/x86/kvm/svm/svm.c=4988=static int svm_leave_smm(struct kvm_vcpu *vcpu, const union kvm_smram *smram)\n--\narch/x86/kvm/svm/svm.c-5036-\narch/x86/kvm/svm/svm.c:5037:\tif (nested_svm_check_cached_vmcb12(vcpu) \u003c 0)\narch/x86/kvm/svm/svm.c-5038-\t\tgoto unmap_save;\n--\narch/x86/kvm/svm/svm.c=5545=static __init int svm_hardware_setup(void)\n--\narch/x86/kvm/svm/svm.c-5588-\narch/x86/kvm/svm/svm.c:5589:\t\tr = nested_svm_init_msrpm_merge_offsets();\narch/x86/kvm/svm/svm.c-5590-\t\tif (r)\n--\narch/x86/kvm/svm/svm.h=208=struct svm_nested_state {\n--\narch/x86/kvm/svm/svm.h-226-\t * Note: this struct is not kept up-to-date while L2 runs; it is only\narch/x86/kvm/svm/svm.h:227:\t * valid within nested_svm_vmrun.\n\n"
} |
| 9/2 | 2026/06/29 13:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 19308 output: 21 thoughts: 236 Thoughts: **Analyzing the Nested SVM Patch** Okay, so this patch is clearly touching the nested SVM code, specifically the `nested_svm_vmexit_update_vmcb12` and `nested_svm_exit_handled` functions. It looks like it's designed to be run within a nested SVM environment, which is good. The configuration requirement is `KVM_AMD`, and that's it? I need to double-check that. Let's look at the dependencies for `KVM_AMD`. Ah, it depends on `KVM`, of course. So, confirming `KVM_AMD` alone is enough. Now, let's nail down what functions are important to focus on. We've got: * `nested_svm_vmexit_update_vmcb12` * `nested_svm_exit_handled` * `nested_svm_clear_decode_assists` * `nested_svm_copy_decode_assists` Hmm, wait a minute... I remember those `nested_svm_clear_decode_assists` and `nested_svm_copy_decode_assists` functions. They're both static within `nested.c`. And now I see `nested_svm_vmexit_update_vmcb12` is also static within that same file. This means they are likely internal helper functions within that file. But `nested_svm_exit_handled`...that one's not static. So it's exported and can be called from somewhere else. I'll need to confirm that. |
| 10/2 | 2026/06/29 13:45 | tool | grepper |
0mArgs:{
"Expression": "nested_svm_exit_handled"
}Results: {
"Output": "arch/x86/kvm/svm/nested.c=1526=void svm_leave_nested(struct kvm_vcpu *vcpu)\n--\narch/x86/kvm/svm/nested.c-1549-\narch/x86/kvm/svm/nested.c:1550:static int nested_svm_exit_handled_msr(struct vcpu_svm *svm)\narch/x86/kvm/svm/nested.c-1551-{\n--\narch/x86/kvm/svm/nested.c=1600=static int nested_svm_intercept(struct vcpu_svm *svm)\n--\narch/x86/kvm/svm/nested.c-1609-\tcase SVM_EXIT_MSR:\narch/x86/kvm/svm/nested.c:1610:\t\tvmexit = nested_svm_exit_handled_msr(svm);\narch/x86/kvm/svm/nested.c-1611-\t\tbreak;\n--\narch/x86/kvm/svm/nested.c-1631-\narch/x86/kvm/svm/nested.c:1632:int nested_svm_exit_handled(struct vcpu_svm *svm)\narch/x86/kvm/svm/nested.c-1633-{\n--\narch/x86/kvm/svm/svm.c=2531=static bool check_selective_cr0_intercepted(struct kvm_vcpu *vcpu,\n--\narch/x86/kvm/svm/svm.c-2546-\t\tsvm-\u003evmcb-\u003econtrol.exit_code = SVM_EXIT_CR0_SEL_WRITE;\narch/x86/kvm/svm/svm.c:2547:\t\tret = (nested_svm_exit_handled(svm) == NESTED_EXIT_DONE);\narch/x86/kvm/svm/svm.c-2548-\t}\n--\narch/x86/kvm/svm/svm.c=3653=static int svm_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)\n--\narch/x86/kvm/svm/svm.c-3673-\t\tif (vmexit == NESTED_EXIT_CONTINUE)\narch/x86/kvm/svm/svm.c:3674:\t\t\tvmexit = nested_svm_exit_handled(svm);\narch/x86/kvm/svm/svm.c-3675-\n--\narch/x86/kvm/svm/svm.c=4757=static int svm_check_intercept(struct kvm_vcpu *vcpu,\n--\narch/x86/kvm/svm/svm.c-4881-\tvmcb-\u003econtrol.exit_code = icpt_info.exit_code;\narch/x86/kvm/svm/svm.c:4882:\tvmexit = nested_svm_exit_handled(svm);\narch/x86/kvm/svm/svm.c-4883-\n--\narch/x86/kvm/svm/svm.h=865=static inline void nested_svm_simple_vmexit(struct vcpu_svm *svm, u32 exit_code)\n--\narch/x86/kvm/svm/svm.h-872-\narch/x86/kvm/svm/svm.h:873:int nested_svm_exit_handled(struct vcpu_svm *svm);\narch/x86/kvm/svm/svm.h-874-int nested_svm_check_permissions(struct kvm_vcpu *vcpu);\n"
} |
| 11/2 | 2026/06/29 13:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 20845 output: 24 thoughts: 73 Thoughts: Here's my summary, as the expert: **Current Focus: Nested SVM VM Exit Handling** Okay, so I'm honing in on the nested SVM exit handling code. It looks like `nested_svm_exit_handled` is a good place to start, that seems to be the core function for dealing with the actual VM exit. Then, following that logic, I need to check `nested_svm_vmexit_update_vmcb12`, because, well, that name suggests it's crucial for properly updating the Virtual Machine Control Block, post-VM exit, but for the 1-2 vCPU. I also see that `nested_vmcb02_prepare_control` is getting modified. That one's interesting, as it's the 0-2 vmcb. Let me pivot there first, since it is a fundamental control function. I'll need to understand *how* it's being changed and *why* before going deeper into the exit-handling path. I need to understand what's *being* prepped for the 0-2 vmcb. |
| 12/2 | 2026/06/29 13:45 | tool | grepper |
0mArgs:{
"Expression": "nested_vmcb02_prepare_control"
}Results: {
"Output": "arch/x86/kvm/svm/nested.c=840=static bool is_evtinj_nmi(u32 evtinj)\n--\narch/x86/kvm/svm/nested.c-849-\narch/x86/kvm/svm/nested.c:850:static void nested_vmcb02_prepare_control(struct vcpu_svm *svm)\narch/x86/kvm/svm/nested.c-851-{\n--\narch/x86/kvm/svm/nested.c=1029=int enter_svm_guest_mode(struct kvm_vcpu *vcpu, u64 vmcb12_gpa, bool from_vmrun)\n--\narch/x86/kvm/svm/nested.c-1060-\tsvm_switch_vmcb(svm, \u0026svm-\u003enested.vmcb02);\narch/x86/kvm/svm/nested.c:1061:\tnested_vmcb02_prepare_control(svm);\narch/x86/kvm/svm/nested.c-1062-\tnested_vmcb02_prepare_save(svm);\n--\narch/x86/kvm/svm/nested.c=1932=static int svm_set_nested_state(struct kvm_vcpu *vcpu,\n--\narch/x86/kvm/svm/nested.c-2041-\tsvm_switch_vmcb(svm, \u0026svm-\u003enested.vmcb02);\narch/x86/kvm/svm/nested.c:2042:\tnested_vmcb02_prepare_control(svm);\narch/x86/kvm/svm/nested.c-2043-\n"
} |
| 13/2 | 2026/06/29 13:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 21622 output: 176 thoughts: 247 Thoughts: **My Analysis of the KVM/SVM Patch** Okay, so I've been looking at this KVM/SVM patch. It's clear that `nested_vmcb02_prepare_control` is a critical function to focus on during fuzzing – that seems like a key entry point. Let me double-check if there are any other configuration points to consider. Aha, `KVM_AMD` is the primary one. Now, is there anything analogous to `X86_FEATURE_DECODEASSISTS` in terms of configuration? No, it's a CPU feature, not a kernel configuration option. Got it. Let me summarize my findings. From what I can tell, this is definitely worth fuzzing: `WorthFuzzing: true`. Here's the list of functions that appear most relevant for fuzzing: * `nested_svm_vmexit_update_vmcb12` * `nested_svm_exit_handled` * `nested_vmcb02_prepare_control` * `nested_svm_clear_decode_assists` * `nested_svm_copy_decode_assists` And, we need to make sure `KVM_AMD` is enabled (`EnableConfigs: - KVM_AMD`). The reason for fuzzing is clear: this patch resolves a potential vulnerability related to nested SVM virtualization, specifically with the possibility of DecodeAssist data leakage between VM exits. This impacts core KVM SVM logic, the core function is the code handling nested VM exits and preparing VMCB02 controls. Since this code is directly accessible from userspace through KVM ioctls—that is, running a nested guest—it is absolutely a good target for fuzzing. This patch modifies functional code, reachable through KVM ioctls, making this a clear area to focus my fuzzing efforts. |
| 14/2 | 2026/06/29 13:45 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"KVM_AMD"
],
"FocusSymbols": [
"nested_svm_vmexit_update_vmcb12",
"nested_svm_exit_handled",
"nested_vmcb02_prepare_control",
"nested_svm_clear_decode_assists",
"nested_svm_copy_decode_assists"
],
"Reasoning": "The patch fixes a bug in nested SVM virtualization where DecodeAssist data could be leaked from a previous exit to a subsequent exit. It modifies core KVM SVM logic for handling nested VM exits and preparing VMCB02 controls. This is functional code reachable from userspace via KVM ioctls (specifically running a nested guest), so it should be fuzzed.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"KVM_AMD"
],
"FocusSymbols": [
"nested_svm_vmexit_update_vmcb12",
"nested_svm_exit_handled",
"nested_vmcb02_prepare_control",
"nested_svm_clear_decode_assists",
"nested_svm_copy_decode_assists"
],
"Reasoning": "The patch fixes a bug in nested SVM virtualization where DecodeAssist data could be leaked from a previous exit to a subsequent exit. It modifies core KVM SVM logic for handling nested VM exits and preparing VMCB02 controls. This is functional code reachable from userspace via KVM ioctls (specifically running a nested guest), so it should be fuzzed.",
"WorthFuzzing": true
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|