AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/07/10 08:52 flow patch-triage
0m Args:
null

Results:
{
  "EnableConfigs": [
    "KVM"
  ],
  "FocusSymbols": [
    "kvm_riscv_mmu_map",
    "pfnmap_mapping_size",
    "fault_supports_gstage_huge_mapping"
  ],
  "Reasoning": "The patch modifies the KVM MMU page fault handler on RISC-V to support huge page mappings (PMD_SIZE) for device memory (VM_PFNMAP). This is a functional change in the core virtualization memory management logic and should be fuzzed to ensure it doesn't introduce memory corruption or host crashes when handling malicious or edge-case guest page faults.",
  "WorthFuzzing": true
}

1/1 2026/07/10 08:52 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit fac09795ef7d306ca98e712153e30ea538a01ccf\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Fri Jul 10 08:52:38 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/arch/riscv/kvm/mmu.c b/arch/riscv/kvm/mmu.c\nindex 2d3def024270c0..53fb34d4b76d09 100644\n--- a/arch/riscv/kvm/mmu.c\n+++ b/arch/riscv/kvm/mmu.c\n@@ -16,6 +16,8 @@\n #include \u003casm/kvm_mmu.h\u003e\n #include \u003casm/kvm_nacl.h\u003e\n \n+#include \"trace.h\"\n+\n static void mmu_wp_memory_region(struct kvm *kvm, int slot)\n {\n \tstruct kvm_memslots *slots = kvm_memslots(kvm);\n@@ -286,7 +288,7 @@ bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)\n }\n \n static bool fault_supports_gstage_huge_mapping(struct kvm_memory_slot *memslot,\n-\t\t\t\t\t       unsigned long hva)\n+\t\t\t\t\t       unsigned long hva, unsigned long map_size)\n {\n \thva_t uaddr_start, uaddr_end;\n \tgpa_t gpa_start;\n@@ -321,7 +323,7 @@ static bool fault_supports_gstage_huge_mapping(struct kvm_memory_slot *memslot,\n \t *   e -\u003e g\n \t *   f -\u003e h\n \t */\n-\tif ((gpa_start \u0026 (PMD_SIZE - 1)) != (uaddr_start \u0026 (PMD_SIZE - 1)))\n+\tif ((gpa_start \u0026 (map_size - 1)) != (uaddr_start \u0026 (map_size - 1)))\n \t\treturn false;\n \n \t/*\n@@ -336,7 +338,7 @@ static bool fault_supports_gstage_huge_mapping(struct kvm_memory_slot *memslot,\n \t * userspace_addr or the base_gfn, as both are equally aligned (per\n \t * the check above) and equally sized.\n \t */\n-\treturn (hva \u003e= ALIGN(uaddr_start, PMD_SIZE)) \u0026\u0026 (hva \u003c ALIGN_DOWN(uaddr_end, PMD_SIZE));\n+\treturn (hva \u003e= ALIGN(uaddr_start, map_size)) \u0026\u0026 (hva \u003c ALIGN_DOWN(uaddr_end, map_size));\n }\n \n static int get_hva_mapping_size(struct kvm *kvm,\n@@ -404,7 +406,7 @@ static unsigned long transparent_hugepage_adjust(struct kvm *kvm,\n \t * sure that the HVA and GPA are sufficiently aligned and that the\n \t * block map is contained within the memslot.\n \t */\n-\tif (fault_supports_gstage_huge_mapping(memslot, hva)) {\n+\tif (fault_supports_gstage_huge_mapping(memslot, hva, PMD_SIZE)) {\n \t\tint sz;\n \n \t\tsz = get_hva_mapping_size(kvm, hva);\n@@ -421,6 +423,31 @@ static unsigned long transparent_hugepage_adjust(struct kvm *kvm,\n \treturn PAGE_SIZE;\n }\n \n+/*\n+ * Determine the G-stage mapping size for a VM_PFNMAP (e.g. host device\n+ * MMIO) fault.  Unlike arm64's original implementation, we never derive the\n+ * host physical address from vma-\u003evm_pgoff (which is unreliable since the\n+ * VFIO unmap_mapping_range() changes).  Instead we walk the host page tables\n+ * via get_hva_mapping_size(): if the host itself installed a leaf block for\n+ * this address, physical contiguity within that block is already guaranteed\n+ * by the host mm.  The memory type stays correct because RISC-V derives it\n+ * from the physical address' PMA, independent of the G-stage PTE size.\n+ *\n+ * Be conservative for now and only promote to PMD-sized blocks; PUD-sized\n+ * device blocks are left as future work.  Fall back to PAGE_SIZE whenever\n+ * contiguity or HVA/GPA alignment cannot be proven.\n+ */\n+static unsigned long pfnmap_mapping_size(struct kvm *kvm,\n+\t\t\t\t\t struct kvm_memory_slot *memslot,\n+\t\t\t\t\t unsigned long hva)\n+{\n+\tif (get_hva_mapping_size(kvm, hva) \u003e= PMD_SIZE \u0026\u0026\n+\t    fault_supports_gstage_huge_mapping(memslot, hva, PMD_SIZE))\n+\t\treturn PMD_SIZE;\n+\n+\treturn PAGE_SIZE;\n+}\n+\n int kvm_riscv_mmu_map(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot,\n \t\t      gpa_t gpa, unsigned long hva, bool is_write,\n \t\t      struct kvm_gstage_mapping *out_map)\n@@ -465,11 +492,14 @@ int kvm_riscv_mmu_map(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot,\n \telse\n \t\tvma_pageshift = PAGE_SHIFT;\n \tvma_pagesize = 1ULL \u003c\u003c vma_pageshift;\n-\tif (logging || (vma-\u003evm_flags \u0026 VM_PFNMAP))\n+\n+\tif (logging)\n \t\tvma_pagesize = PAGE_SIZE;\n+\telse if (vma-\u003evm_flags \u0026 VM_PFNMAP)\n+\t\tvma_pagesize = pfnmap_mapping_size(kvm, memslot, hva);\n \n \tif (vma_pagesize == PMD_SIZE || vma_pagesize == PUD_SIZE)\n-\t\tgfn = (gpa \u0026 huge_page_mask(hstate_vma(vma))) \u003e\u003e PAGE_SHIFT;\n+\t\tgfn = (gpa \u0026 ~(vma_pagesize - 1)) \u003e\u003e PAGE_SHIFT;\n \n \t/*\n \t * Read mmu_invalidate_seq so that KVM can detect if the results of\n@@ -515,6 +545,9 @@ int kvm_riscv_mmu_map(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot,\n \tif (!logging \u0026\u0026 (vma_pagesize == PAGE_SIZE))\n \t\tvma_pagesize = transparent_hugepage_adjust(kvm, memslot, hva, \u0026hfn, \u0026gpa);\n \n+\ttrace_kvm_mmu_map(gpa, hva, hfn, vma_pagesize,\n+\t\t\t  !!(vma-\u003evm_flags \u0026 VM_PFNMAP));\n+\n \tif (writable) {\n \t\tmark_page_dirty_in_slot(kvm, memslot, gfn);\n \t\tret = kvm_riscv_gstage_map_page(\u0026gstage, pcache, gpa, hfn \u003c\u003c PAGE_SHIFT,\ndiff --git a/arch/riscv/kvm/trace.h b/arch/riscv/kvm/trace.h\nindex 3d54175d805cbc..db2d28f1d71483 100644\n--- a/arch/riscv/kvm/trace.h\n+++ b/arch/riscv/kvm/trace.h\n@@ -56,6 +56,35 @@ TRACE_EVENT(kvm_exit,\n \t\t__entry-\u003ehtinst)\n );\n \n+TRACE_EVENT(kvm_mmu_map,\n+\tTP_PROTO(unsigned long gpa, unsigned long hva, unsigned long hfn,\n+\t\t unsigned long map_size, bool is_pfnmap),\n+\tTP_ARGS(gpa, hva, hfn, map_size, is_pfnmap),\n+\n+\tTP_STRUCT__entry(\n+\t\t__field(unsigned long, gpa)\n+\t\t__field(unsigned long, hva)\n+\t\t__field(unsigned long, hfn)\n+\t\t__field(unsigned long, map_size)\n+\t\t__field(bool, is_pfnmap)\n+\t),\n+\n+\tTP_fast_assign(\n+\t\t__entry-\u003egpa\t\t= gpa;\n+\t\t__entry-\u003ehva\t\t= hva;\n+\t\t__entry-\u003ehfn\t\t= hfn;\n+\t\t__entry-\u003emap_size\t= map_size;\n+\t\t__entry-\u003eis_pfnmap\t= is_pfnmap;\n+\t),\n+\n+\tTP_printk(\"GPA:0x%lx, HVA:0x%lx, HFN:0x%lx, size:%luKB, pfnmap:%d\",\n+\t\t__entry-\u003egpa,\n+\t\t__entry-\u003ehva,\n+\t\t__entry-\u003ehfn,\n+\t\t__entry-\u003emap_size \u003e\u003e 10,\n+\t\t__entry-\u003eis_pfnmap)\n+);\n+\n #endif /* _TRACE_RSICV_KVM_H */\n \n #undef TRACE_INCLUDE_PATH\n"
}

2/1 2026/07/10 08:52 agent patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
{
  "EnableConfigs": [
    "KVM"
  ],
  "FocusSymbols": [
    "kvm_riscv_mmu_map",
    "pfnmap_mapping_size",
    "fault_supports_gstage_huge_mapping"
  ],
  "Reasoning": "The patch modifies the KVM MMU page fault handler on RISC-V to support huge page mappings (PMD_SIZE) for device memory (VM_PFNMAP). This is a functional change in the core virtualization memory management logic and should be fuzzed to ensure it doesn't introduce memory corruption or host crashes when handling malicious or edge-case guest page faults.",
  "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 fac09795ef7d306ca98e712153e30ea538a01ccf
Author: syz-cluster <triage@syzkaller.com>
Date:   Fri Jul 10 08:52:38 2026 +0000

    syz-cluster: applied patch under review

diff --git a/arch/riscv/kvm/mmu.c b/arch/riscv/kvm/mmu.c
index 2d3def024270c0..53fb34d4b76d09 100644
--- a/arch/riscv/kvm/mmu.c
+++ b/arch/riscv/kvm/mmu.c
@@ -16,6 +16,8 @@
 #include <asm/kvm_mmu.h>
 #include <asm/kvm_nacl.h>
 
+#include "trace.h"
+
 static void mmu_wp_memory_region(struct kvm *kvm, int slot)
 {
 	struct kvm_memslots *slots = kvm_memslots(kvm);
@@ -286,7 +288,7 @@ bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
 }
 
 static bool fault_supports_gstage_huge_mapping(struct kvm_memory_slot *memslot,
-					       unsigned long hva)
+					       unsigned long hva, unsigned long map_size)
 {
 	hva_t uaddr_start, uaddr_end;
 	gpa_t gpa_start;
@@ -321,7 +323,7 @@ static bool fault_supports_gstage_huge_mapping(struct kvm_memory_slot *memslot,
 	 *   e -> g
 	 *   f -> h
 	 */
-	if ((gpa_start & (PMD_SIZE - 1)) != (uaddr_start & (PMD_SIZE - 1)))
+	if ((gpa_start & (map_size - 1)) != (uaddr_start & (map_size - 1)))
 		return false;
 
 	/*
@@ -336,7 +338,7 @@ static bool fault_supports_gstage_huge_mapping(struct kvm_memory_slot *memslot,
 	 * userspace_addr or the base_gfn, as both are equally aligned (per
 	 * the check above) and equally sized.
 	 */
-	return (hva >= ALIGN(uaddr_start, PMD_SIZE)) && (hva < ALIGN_DOWN(uaddr_end, PMD_SIZE));
+	return (hva >= ALIGN(uaddr_start, map_size)) && (hva < ALIGN_DOWN(uaddr_end, map_size));
 }
 
 static int get_hva_mapping_size(struct kvm *kvm,
@@ -404,7 +406,7 @@ static unsigned long transparent_hugepage_adjust(struct kvm *kvm,
 	 * sure that the HVA and GPA are sufficiently aligned and that the
 	 * block map is contained within the memslot.
 	 */
-	if (fault_supports_gstage_huge_mapping(memslot, hva)) {
+	if (fault_supports_gstage_huge_mapping(memslot, hva, PMD_SIZE)) {
 		int sz;
 
 		sz = get_hva_mapping_size(kvm, hva);
@@ -421,6 +423,31 @@ static unsigned long transparent_hugepage_adjust(struct kvm *kvm,
 	return PAGE_SIZE;
 }
 
+/*
+ * Determine the G-stage mapping size for a VM_PFNMAP (e.g. host device
+ * MMIO) fault.  Unlike arm64's original implementation, we never derive the
+ * host physical address from vma->vm_pgoff (which is unreliable since the
+ * VFIO unmap_mapping_range() changes).  Instead we walk the host page tables
+ * via get_hva_mapping_size(): if the host itself installed a leaf block for
+ * this address, physical contiguity within that block is already guaranteed
+ * by the host mm.  The memory type stays correct because RISC-V derives it
+ * from the physical address' PMA, independent of the G-stage PTE size.
+ *
+ * Be conservative for now and only promote to PMD-sized blocks; PUD-sized
+ * device blocks are left as future work.  Fall back to PAGE_SIZE whenever
+ * contiguity or HVA/GPA alignment cannot be proven.
+ */
+static unsigned long pfnmap_mapping_size(struct kvm *kvm,
+					 struct kvm_memory_slot *memslot,
+					 unsigned long hva)
+{
+	if (get_hva_mapping_size(kvm, hva) >= PMD_SIZE &&
+	    fault_supports_gstage_huge_mapping(memslot, hva, PMD_SIZE))
+		return PMD_SIZE;
+
+	return PAGE_SIZE;
+}
+
 int kvm_riscv_mmu_map(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot,
 		      gpa_t gpa, unsigned long hva, bool is_write,
 		      struct kvm_gstage_mapping *out_map)
@@ -465,11 +492,14 @@ int kvm_riscv_mmu_map(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot,
 	else
 		vma_pageshift = PAGE_SHIFT;
 	vma_pagesize = 1ULL << vma_pageshift;
-	if (logging || (vma->vm_flags & VM_PFNMAP))
+
+	if (logging)
 		vma_pagesize = PAGE_SIZE;
+	else if (vma->vm_flags & VM_PFNMAP)
+		vma_pagesize = pfnmap_mapping_size(kvm, memslot, hva);
 
 	if (vma_pagesize == PMD_SIZE || vma_pagesize == PUD_SIZE)
-		gfn = (gpa & huge_page_mask(hstate_vma(vma))) >> PAGE_SHIFT;
+		gfn = (gpa & ~(vma_pagesize - 1)) >> PAGE_SHIFT;
 
 	/*
 	 * Read mmu_invalidate_seq so that KVM can detect if the results of
@@ -515,6 +545,9 @@ int kvm_riscv_mmu_map(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot,
 	if (!logging && (vma_pagesize == PAGE_SIZE))
 		vma_pagesize = transparent_hugepage_adjust(kvm, memslot, hva, &hfn, &gpa);
 
+	trace_kvm_mmu_map(gpa, hva, hfn, vma_pagesize,
+			  !!(vma->vm_flags & VM_PFNMAP));
+
 	if (writable) {
 		mark_page_dirty_in_slot(kvm, memslot, gfn);
 		ret = kvm_riscv_gstage_map_page(&gstage, pcache, gpa, hfn << PAGE_SHIFT,
diff --git a/arch/riscv/kvm/trace.h b/arch/riscv/kvm/trace.h
index 3d54175d805cbc..db2d28f1d71483 100644
--- a/arch/riscv/kvm/trace.h
+++ b/arch/riscv/kvm/trace.h
@@ -56,6 +56,35 @@ TRACE_EVENT(kvm_exit,
 		__entry->htinst)
 );
 
+TRACE_EVENT(kvm_mmu_map,
+	TP_PROTO(unsigned long gpa, unsigned long hva, unsigned long hfn,
+		 unsigned long map_size, bool is_pfnmap),
+	TP_ARGS(gpa, hva, hfn, map_size, is_pfnmap),
+
+	TP_STRUCT__entry(
+		__field(unsigned long, gpa)
+		__field(unsigned long, hva)
+		__field(unsigned long, hfn)
+		__field(unsigned long, map_size)
+		__field(bool, is_pfnmap)
+	),
+
+	TP_fast_assign(
+		__entry->gpa		= gpa;
+		__entry->hva		= hva;
+		__entry->hfn		= hfn;
+		__entry->map_size	= map_size;
+		__entry->is_pfnmap	= is_pfnmap;
+	),
+
+	TP_printk("GPA:0x%lx, HVA:0x%lx, HFN:0x%lx, size:%luKB, pfnmap:%d",
+		__entry->gpa,
+		__entry->hva,
+		__entry->hfn,
+		__entry->map_size >> 10,
+		__entry->is_pfnmap)
+);
+
 #endif /* _TRACE_RSICV_KVM_H */
 
 #undef TRACE_INCLUDE_PATH

3/2 2026/07/10 08:52 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 3877
							output: 28
							thoughts: 692
						

Thoughts:
**Evaluating the Patch for Fuzzing Potential**

Okay, so I need to assess whether this patch introduces functional changes in the kernel that warrant fuzzing. The provided information tells me it modifies `arch/riscv/kvm/mmu.c` and `arch/riscv/kvm/trace.h`. Specifically, the change to `mmu.c` is the key. The patch alters the behavior of `kvm_riscv_mmu_map` concerning `VM_PFNMAP`. The original code always used `PAGE_SIZE` for `VM_PFNMAP` if logging was enabled or the `VM_PFNMAP` flag was set. Now, it seems that if logging is disabled, and the `VM_PFNMAP` flag is set, it checks for `pfnmap_mapping_size`, which can potentially return `PMD_SIZE` or larger mappings instead of just `PAGE_SIZE`. This introduces a functional change in how the RISC-V KVM MMU handles the mapping size, particularly for device memory.

This is significant. I need to figure out if this code path is reachable in a virtualized environment. RISC-V KVM, as a core virtualization feature, is a natural target. And, yes, Syzkaller does indeed support RISC-V KVM, which is good. Can I trigger it in something like GCE or QEMU? Yes, QEMU does support RISC-V KVM, either through nested virtualization or running it on an actual RISC-V host. Syzkaller can run in a RISC-V QEMU with KVM enabled.

The prompt specified that I shouldn't consider code paths unreachable in virtualized environments like GCE or QEMU, even with software emulated hardware. KVM is reachable here. Nested virtualization works. Or, if we are running on bare-metal, it's fine. QEMU also emulates RISC-V with KVM support, so it's all good. Syzkaller runs QEMU with KVM enabled if the host supports it, but can test KVM via `/dev/kvm` even if the host doesn't have hardware KVM. In fact, Syzkaller heavily tests KVM in general.

Now, to make sure, I will check the Kconfig options for RISC-V KVM, just to verify how it's enabled. I'll use `grepper` to locate the relevant Kconfig settings.



4/2 2026/07/10 08:52 tool grepper
0m Args:
{
  "Expression": "config KVM",
  "PathPrefix": "arch/riscv/"
}

Results:
{
  "Output": "arch/riscv/kvm/Kconfig=18=if VIRTUALIZATION\narch/riscv/kvm/Kconfig-19-\narch/riscv/kvm/Kconfig:20:config KVM\narch/riscv/kvm/Kconfig-21-\ttristate \"Kernel-based Virtual Machine (KVM) support\"\n"
}

5/2 2026/07/10 08:52 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 5224
							output: 36
							thoughts: 35
						

Thoughts:
Okay, let's see...

**KVM Configuration Deep Dive**

Alright, so I'm diving into this `KVM` configuration. The initial thought is, "Okay, `KVM` is the config file that manages the kernel-based virtual machine support, got it." But hold on a second... is that really *all* there is to it? I need to be absolutely sure.

I'm thinking, "Let's double-check the source." The definitive place to verify the scope of the KVM configuration would be in the code itself, right? Specifically, I need to look at `arch/riscv/kvm/Kconfig`. That's where all the detailed configuration options for RISC-V KVM are laid out. I need to make sure I'm not missing any subtle dependencies, or relevant sub-options by only considering the name of the top-level KVM.



6/2 2026/07/10 08:52 tool read-file
0m Args:
{
  "File": "arch/riscv/kvm/Kconfig",
  "FirstLine": 1,
  "LineCount": 50
}

Results:
{
  "Contents": "   1:\t# SPDX-License-Identifier: GPL-2.0\n   2:\t#\n   3:\t# KVM configuration\n   4:\t#\n   5:\t\n   6:\tsource \"virt/kvm/Kconfig\"\n   7:\t\n   8:\tmenuconfig VIRTUALIZATION\n   9:\t\tbool \"Virtualization\"\n  10:\t\thelp\n  11:\t\t  Say Y here to get to see options for using your Linux host to run\n  12:\t\t  other operating systems inside virtual machines (guests).\n  13:\t\t  This option alone does not add any kernel code.\n  14:\t\n  15:\t\t  If you say N, all options in this submenu will be skipped and\n  16:\t\t  disabled.\n  17:\t\n  18:\tif VIRTUALIZATION\n  19:\t\n  20:\tconfig KVM\n  21:\t\ttristate \"Kernel-based Virtual Machine (KVM) support\"\n  22:\t\tdepends on RISCV_SBI \u0026\u0026 MMU\n  23:\t\tselect HAVE_KVM_IRQCHIP\n  24:\t\tselect HAVE_KVM_IRQ_ROUTING\n  25:\t\tselect HAVE_KVM_MSI\n  26:\t\tselect HAVE_KVM_READONLY_MEM\n  27:\t\tselect HAVE_KVM_DIRTY_RING_ACQ_REL\n  28:\t\tselect KVM_COMMON\n  29:\t\tselect KVM_GENERIC_DIRTYLOG_READ_PROTECT\n  30:\t\tselect KVM_GENERIC_HARDWARE_ENABLING\n  31:\t\tselect KVM_MMIO\n  32:\t\tselect VIRT_XFER_TO_GUEST_WORK\n  33:\t\tselect SCHED_INFO\n  34:\t\tselect GUEST_PERF_EVENTS if PERF_EVENTS\n  35:\t\thelp\n  36:\t\t  Support hosting virtualized guest machines.\n  37:\t\n  38:\t\t  If unsure, say N.\n  39:\t\n  40:\tendif # VIRTUALIZATION\n"
}

7/2 2026/07/10 08:52 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 6004
							output: 38
							thoughts: 132
						

Thoughts:
**Analyzing KVM Memory Mapping**

Okay, so the current configuration is clearly KVM. My primary targets here are `pfnmap_mapping_size` and `kvm_riscv_mmu_map`. Wait a second… I see `kvm_riscv_mmu_map` has been modified and `pfnmap_mapping_size` has been added. My spider sense is tingling, I need to figure out the significance of those changes, especially with `kvm_riscv_mmu_map`.

Right, let's establish if `kvm_riscv_mmu_map` is a performance-critical path. Bingo, it's called during memory mapping for KVM guests. And further, it's actually the page fault handler *within* KVM. Definitely a hotspot. So, where is this handler triggered? I need to trace the call graph now to understand the interaction and determine if the modification improves or degrades performance.



8/2 2026/07/10 08:52 tool grepper
0m Args:
{
  "Expression": "kvm_riscv_mmu_map",
  "PathPrefix": "arch/riscv/kvm/"
}

Results:
{
  "Output": "arch/riscv/kvm/mmu.c=440=static unsigned long pfnmap_mapping_size(struct kvm *kvm,\n--\narch/riscv/kvm/mmu.c-450-\narch/riscv/kvm/mmu.c:451:int kvm_riscv_mmu_map(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot,\narch/riscv/kvm/mmu.c-452-\t\t      gpa_t gpa, unsigned long hva, bool is_write,\n--\narch/riscv/kvm/vcpu_exit.c=15=static int gstage_page_fault(struct kvm_vcpu *vcpu, struct kvm_run *run,\n--\narch/riscv/kvm/vcpu_exit.c-45-\narch/riscv/kvm/vcpu_exit.c:46:\tret = kvm_riscv_mmu_map(vcpu, memslot, fault_addr, hva,\narch/riscv/kvm/vcpu_exit.c-47-\t\t\t\t(trap-\u003escause == EXC_STORE_GUEST_PAGE_FAULT) ? true : false,\n"
}

9/2 2026/07/10 08:52 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 6691
							output: 148
							thoughts: 582
						

Thoughts:
**My Analysis of the RISC-V KVM Page Fault Handling**

Okay, so this is triggered by `gstage_page_fault`, the guest page fault handler. It's a hot path, but what's changed is specific. My initial thought is to zero in on `pfnmap_mapping_size` and `kvm_riscv_mmu_map`. Wait, `pfnmap_mapping_size` is a static function, so it's probably inlined... Let's also consider `fault_supports_gstage_huge_mapping`, which was also modified and is *also* static. This strongly suggests that `kvm_riscv_mmu_map` is the main entry point for the new logic.

Now, I need to understand the conditions that trigger this code path. Is there something in particular that I need to enable? Ah, `VM_PFNMAP` is related to device memory mapping, like VFIO. My intuition tells me VFIO is relevant here. The comments mention "Determine the G-stage mapping size for a VM_PFNMAP (e.g. host device MMIO) fault." To trigger this, we need a `VM_PFNMAP` VMA. This is created by mapping device memory, which is exactly what VFIO and other drivers using `remap_pfn_range` do. Syzkaller can probably map `/dev/kvm` or similar devices to set up `VM_PFNMAP` and pass it to KVM as a memory slot. So the key config here is `KVM`.

Let me double-check... Yes, `KVM` enables `arch/riscv/kvm/mmu.c`. The patch *is* in `arch/riscv/kvm/mmu.c`, which makes it RISC-V specific. And Syzkaller fuzzes RISC-V... perfect!

So, to summarize for fuzzing:

*   **WorthFuzzing:** Absolutely!
*   **FocusSymbols:** `kvm_riscv_mmu_map` (the main function of interest), `pfnmap_mapping_size` (the new, helper function), and `fault_supports_gstage_huge_mapping` (the modified check).
*   **EnableConfigs:** `KVM`
*   **Reasoning:** The patch modifies the RISC-V KVM MMU page fault handler to support huge page mappings (PMD_SIZE) for device memory (VM_PFNMAP). This represents a functional change in the core virtualization memory management logic, and as such, it *must* be fuzzed to prevent potential memory corruption or host crashes resulting from malicious or edge-case guest page faults.

I'm setting `kvm_riscv_mmu_map` as the core symbol. `pfnmap_mapping_size` is a new function and `fault_supports_gstage_huge_mapping` is also modified. I'll make sure to note all of this.



10/2 2026/07/10 08:53 tool set-results
0m Args:
{
  "EnableConfigs": [
    "KVM"
  ],
  "FocusSymbols": [
    "kvm_riscv_mmu_map",
    "pfnmap_mapping_size",
    "fault_supports_gstage_huge_mapping"
  ],
  "Reasoning": "The patch modifies the KVM MMU page fault handler on RISC-V to support huge page mappings (PMD_SIZE) for device memory (VM_PFNMAP). This is a functional change in the core virtualization memory management logic and should be fuzzed to ensure it doesn't introduce memory corruption or host crashes when handling malicious or edge-case guest page faults.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "KVM"
  ],
  "FocusSymbols": [
    "kvm_riscv_mmu_map",
    "pfnmap_mapping_size",
    "fault_supports_gstage_huge_mapping"
  ],
  "Reasoning": "The patch modifies the KVM MMU page fault handler on RISC-V to support huge page mappings (PMD_SIZE) for device memory (VM_PFNMAP). This is a functional change in the core virtualization memory management logic and should be fuzzed to ensure it doesn't introduce memory corruption or host crashes when handling malicious or edge-case guest page faults.",
  "WorthFuzzing": true
}

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)