AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/07/23 00:45 flow patch-triage
0m Args:
null

Results:
{
  "EnableConfigs": [
    "KVM",
    "CPU_PM"
  ],
  "FocusSymbols": [
    "kvm_riscv_aia_enable",
    "kvm_riscv_aia_disable",
    "kvm_riscv_cpu_pm_notifier",
    "kvm_riscv_clear_former_vcpu"
  ],
  "Reasoning": "The patch modifies RISC-V KVM to properly handle CPU power management (idle non-retention states) by saving and restoring AIA (Advanced Interrupt Architecture) and hypervisor CSR state. This is core KVM logic and should be fuzzed to ensure no state is lost or corrupted during CPU idle transitions.",
  "WorthFuzzing": true
}

1/1 2026/07/23 00:45 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit bb80813fbe3334909b512716e5f82cd0b59297b0\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Thu Jul 23 00:45:26 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/arch/riscv/include/asm/kvm_aia.h b/arch/riscv/include/asm/kvm_aia.h\nindex c67ec5ac0a146b..7c1c3250598fb0 100644\n--- a/arch/riscv/include/asm/kvm_aia.h\n+++ b/arch/riscv/include/asm/kvm_aia.h\n@@ -165,8 +165,19 @@ int kvm_riscv_aia_alloc_hgei(int cpu, struct kvm_vcpu *owner,\n \t\t\t     void __iomem **hgei_va, phys_addr_t *hgei_pa);\n void kvm_riscv_aia_free_hgei(int cpu, int hgei);\n \n-void kvm_riscv_aia_enable(void);\n-void kvm_riscv_aia_disable(void);\n+/**\n+ * kvm_riscv_aia_enable() - Enable AIA support on current CPU\n+ * @full_cleanup: true = full hardware init (CPU hotplug/module load),\n+ *                false = lightweight CSR restore (CPU non-retention idle resume)\n+ */\n+void kvm_riscv_aia_enable(bool full_cleanup);\n+\n+/**\n+ * kvm_riscv_aia_disable() - Disable AIA support on current CPU\n+ * @full_cleanup: true = full hardware cleanup (CPU hotplug/module exit),\n+ *                false = lightweight CSR save (CPU non-retention idle entry)\n+ */\n+void kvm_riscv_aia_disable(bool full_cleanup);\n int kvm_riscv_aia_init(void);\n void kvm_riscv_aia_exit(void);\n \ndiff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h\nindex 60017ceec9d2af..808b4ee1bd10ac 100644\n--- a/arch/riscv/include/asm/kvm_host.h\n+++ b/arch/riscv/include/asm/kvm_host.h\n@@ -319,6 +319,8 @@ bool kvm_riscv_vcpu_stopped(struct kvm_vcpu *vcpu);\n \n void kvm_riscv_vcpu_record_steal_time(struct kvm_vcpu *vcpu);\n \n+void kvm_riscv_clear_former_vcpu(void);\n+\n /* Flags representing implementation specific details */\n DECLARE_STATIC_KEY_FALSE(kvm_riscv_vsstage_tlb_no_gpa);\n \ndiff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c\nindex bafb009c5ce559..4cf351f91c643f 100644\n--- a/arch/riscv/kvm/aia.c\n+++ b/arch/riscv/kvm/aia.c\n@@ -25,6 +25,7 @@ struct aia_hgei_control {\n \tunsigned long free_bitmap;\n \tstruct kvm_vcpu *owners[BITS_PER_LONG];\n \tunsigned int nr_hgei;\n+\tunsigned long saved_value;\n };\n static DEFINE_PER_CPU(struct aia_hgei_control, aia_hgei);\n static int hgei_parent_irq;\n@@ -532,50 +533,59 @@ static void aia_hgei_exit(void)\n \tfree_percpu_irq(hgei_parent_irq, \u0026aia_hgei);\n }\n \n-void kvm_riscv_aia_enable(void)\n+void kvm_riscv_aia_enable(bool full_cleanup)\n {\n-\tconst struct imsic_global_config *gc;\n-\tconst struct imsic_local_config *lc;\n \tstruct aia_hgei_control *hgctrl;\n \tunsigned long flags;\n-\tint aia_nr_hgei;\n \n \tif (!kvm_riscv_aia_available())\n \t\treturn;\n \n-\tgc = imsic_get_global_config();\n-\tlc = (gc) ? this_cpu_ptr(gc-\u003elocal) : NULL;\n \thgctrl = this_cpu_ptr(\u0026aia_hgei);\n \n-\t/* Figure-out number of bits in HGEIE */\n-\tcsr_write(CSR_HGEIE, -1UL);\n-\thgctrl-\u003enr_hgei = fls_long(csr_read(CSR_HGEIE));\n-\tcsr_write(CSR_HGEIE, 0);\n-\tif (hgctrl-\u003enr_hgei)\n-\t\thgctrl-\u003enr_hgei--;\n+\tif (full_cleanup) {\n+\t\tconst struct imsic_global_config *gc;\n+\t\tconst struct imsic_local_config *lc;\n+\t\tint aia_nr_hgei;\n \n-\t/*\n-\t * Number of usable per-HART HGEI lines should be minimum of\n-\t * per-HART IMSIC guest files and number of bits in HGEIE.\n-\t */\n-\tif (lc)\n-\t\thgctrl-\u003enr_hgei = min((ulong)hgctrl-\u003enr_hgei, lc-\u003enr_guest_files);\n-\telse\n-\t\thgctrl-\u003enr_hgei = 0;\n+\t\tgc = imsic_get_global_config();\n+\t\tlc = (gc) ? this_cpu_ptr(gc-\u003elocal) : NULL;\n \n-\t/* Update the number of IMSIC guest files across all HARTs */\n-\taia_nr_hgei = atomic_read(\u0026kvm_riscv_aia_nr_hgei);\n-\tdo {\n-\t\tif (aia_nr_hgei \u003c= hgctrl-\u003enr_hgei)\n-\t\t\tbreak;\n-\t} while (!atomic_try_cmpxchg(\u0026kvm_riscv_aia_nr_hgei, \u0026aia_nr_hgei, hgctrl-\u003enr_hgei));\n+\t\t/* Figure-out number of bits in HGEIE */\n+\t\tcsr_write(CSR_HGEIE, -1UL);\n+\t\thgctrl-\u003enr_hgei = fls_long(csr_read(CSR_HGEIE));\n+\t\tcsr_write(CSR_HGEIE, 0);\n+\t\tif (hgctrl-\u003enr_hgei)\n+\t\t\thgctrl-\u003enr_hgei--;\n \n-\traw_spin_lock_irqsave(\u0026hgctrl-\u003elock, flags);\n-\tif (!hgctrl-\u003efree_bitmap_initialized) {\n-\t\thgctrl-\u003efree_bitmap = (hgctrl-\u003enr_hgei) ? GENMASK_ULL(hgctrl-\u003enr_hgei, 1) : 0;\n-\t\thgctrl-\u003efree_bitmap_initialized = true;\n+\t\t/*\n+\t\t * Number of usable per-HART HGEI lines should be minimum of\n+\t\t * per-HART IMSIC guest files and number of bits in HGEIE.\n+\t\t */\n+\t\tif (lc)\n+\t\t\thgctrl-\u003enr_hgei = min((ulong)hgctrl-\u003enr_hgei, lc-\u003enr_guest_files);\n+\t\telse\n+\t\t\thgctrl-\u003enr_hgei = 0;\n+\n+\t\t/* Update the number of IMSIC guest files across all HARTs */\n+\t\taia_nr_hgei = atomic_read(\u0026kvm_riscv_aia_nr_hgei);\n+\t\tdo {\n+\t\t\tif (aia_nr_hgei \u003c= hgctrl-\u003enr_hgei)\n+\t\t\t\tbreak;\n+\t\t} while (!atomic_try_cmpxchg(\u0026kvm_riscv_aia_nr_hgei, \u0026aia_nr_hgei,\n+\t\t\t\t\t     hgctrl-\u003enr_hgei));\n+\n+\t\traw_spin_lock_irqsave(\u0026hgctrl-\u003elock, flags);\n+\t\tif (!hgctrl-\u003efree_bitmap_initialized) {\n+\t\t\thgctrl-\u003efree_bitmap = (hgctrl-\u003enr_hgei) ?\n+\t\t\t\t\t      GENMASK_ULL(hgctrl-\u003enr_hgei, 1) :\n+\t\t\t\t\t      0;\n+\t\t\thgctrl-\u003efree_bitmap_initialized = true;\n+\t\t}\n+\t\traw_spin_unlock_irqrestore(\u0026hgctrl-\u003elock, flags);\n+\t} else {\n+\t\tcsr_write(CSR_HGEIE, hgctrl-\u003esaved_value);\n \t}\n-\traw_spin_unlock_irqrestore(\u0026hgctrl-\u003elock, flags);\n \n \tcsr_write(CSR_HVICTL, aia_hvictl_value(false));\n \tcsr_write(CSR_HVIPRIO1, 0x0);\n@@ -587,16 +597,17 @@ void kvm_riscv_aia_enable(void)\n \tcsr_write(CSR_HVIPRIO2H, 0x0);\n #endif\n \n-\t/* Enable per-CPU SGEI interrupt */\n-\tenable_percpu_irq(hgei_parent_irq,\n-\t\t\t  irq_get_trigger_type(hgei_parent_irq));\n+\tif (full_cleanup)\n+\t\tenable_percpu_irq(hgei_parent_irq,\n+\t\t\t\t  irq_get_trigger_type(hgei_parent_irq));\n \tcsr_set(CSR_HIE, BIT(IRQ_S_GEXT));\n+\n \t/* Enable IRQ filtering for overflow interrupt only if sscofpmf is present */\n \tif (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_SSCOFPMF))\n \t\tcsr_set(CSR_HVIEN, BIT(IRQ_PMU_OVF));\n }\n \n-void kvm_riscv_aia_disable(void)\n+void kvm_riscv_aia_disable(bool full_cleanup)\n {\n \tint i;\n \tunsigned long flags;\n@@ -609,42 +620,49 @@ void kvm_riscv_aia_disable(void)\n \n \tif (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_SSCOFPMF))\n \t\tcsr_clear(CSR_HVIEN, BIT(IRQ_PMU_OVF));\n-\t/* Disable per-CPU SGEI interrupt */\n-\tcsr_clear(CSR_HIE, BIT(IRQ_S_GEXT));\n-\tdisable_percpu_irq(hgei_parent_irq);\n \n-\tcsr_write(CSR_HVICTL, aia_hvictl_value(false));\n-\n-\traw_spin_lock_irqsave(\u0026hgctrl-\u003elock, flags);\n-\n-\tfor (i = 0; i \u003c= hgctrl-\u003enr_hgei; i++) {\n-\t\tvcpu = hgctrl-\u003eowners[i];\n-\t\tif (!vcpu)\n-\t\t\tcontinue;\n+\tif (full_cleanup) {\n+\t\t/* Disable per-CPU SGEI interrupt */\n+\t\tcsr_clear(CSR_HIE, BIT(IRQ_S_GEXT));\n+\t\tdisable_percpu_irq(hgei_parent_irq);\n+\t}\n \n-\t\t/*\n-\t\t * We release hgctrl-\u003elock before notifying IMSIC\n-\t\t * so that we don't have lock ordering issues.\n-\t\t */\n-\t\traw_spin_unlock_irqrestore(\u0026hgctrl-\u003elock, flags);\n+\tcsr_write(CSR_HVICTL, aia_hvictl_value(false));\n \n-\t\t/* Notify IMSIC */\n-\t\tkvm_riscv_vcpu_aia_imsic_release(vcpu);\n+\tif (full_cleanup) {\n+\t\traw_spin_lock_irqsave(\u0026hgctrl-\u003elock, flags);\n \n-\t\t/*\n-\t\t * Wakeup VCPU if it was blocked so that it can\n-\t\t * run on other HARTs\n-\t\t */\n-\t\tif (csr_read(CSR_HGEIE) \u0026 BIT(i)) {\n-\t\t\tcsr_clear(CSR_HGEIE, BIT(i));\n-\t\t\tkvm_vcpu_kick(vcpu);\n+\t\tfor (i = 0; i \u003c= hgctrl-\u003enr_hgei; i++) {\n+\t\t\tvcpu = hgctrl-\u003eowners[i];\n+\t\t\tif (!vcpu)\n+\t\t\t\tcontinue;\n+\n+\t\t\t/*\n+\t\t\t * We release hgctrl-\u003elock before notifying IMSIC\n+\t\t\t * so that we don't have lock ordering issues.\n+\t\t\t */\n+\t\t\traw_spin_unlock_irqrestore(\u0026hgctrl-\u003elock, flags);\n+\n+\t\t\t/* Notify IMSIC */\n+\t\t\tkvm_riscv_vcpu_aia_imsic_release(vcpu);\n+\n+\t\t\t/*\n+\t\t\t * Wakeup VCPU if it was blocked so that it can\n+\t\t\t * run on other HARTs\n+\t\t\t */\n+\t\t\tif (csr_read(CSR_HGEIE) \u0026 BIT(i)) {\n+\t\t\t\tcsr_clear(CSR_HGEIE, BIT(i));\n+\t\t\t\tkvm_vcpu_kick(vcpu);\n+\t\t\t}\n+\n+\t\t\traw_spin_lock_irqsave(\u0026hgctrl-\u003elock, flags);\n \t\t}\n \n-\t\traw_spin_lock_irqsave(\u0026hgctrl-\u003elock, flags);\n+\t\traw_spin_unlock_irqrestore(\u0026hgctrl-\u003elock, flags);\n+\t} else {\n+\t\thgctrl-\u003esaved_value = csr_read(CSR_HGEIE);\n \t}\n \n-\traw_spin_unlock_irqrestore(\u0026hgctrl-\u003elock, flags);\n-\n \tput_cpu_ptr(\u0026aia_hgei);\n }\n \ndiff --git a/arch/riscv/kvm/main.c b/arch/riscv/kvm/main.c\nindex 0924c75100a2d0..b48bbd1855c1e2 100644\n--- a/arch/riscv/kvm/main.c\n+++ b/arch/riscv/kvm/main.c\n@@ -10,6 +10,7 @@\n #include \u003clinux/err.h\u003e\n #include \u003clinux/module.h\u003e\n #include \u003clinux/kvm_host.h\u003e\n+#include \u003clinux/cpu_pm.h\u003e\n #include \u003casm/cpufeature.h\u003e\n #include \u003casm/kvm_mmu.h\u003e\n #include \u003casm/kvm_nacl.h\u003e\n@@ -33,14 +34,9 @@ long kvm_arch_dev_ioctl(struct file *filp,\n \treturn -EINVAL;\n }\n \n-int kvm_arch_enable_virtualization_cpu(void)\n+/* Initialize hypervisor CSRs - called during CPU online and non-retention idle resume */\n+static void kvm_riscv_csr_enable(void)\n {\n-\tint rc;\n-\n-\trc = kvm_riscv_nacl_enable();\n-\tif (rc)\n-\t\treturn rc;\n-\n \tcsr_write(CSR_HEDELEG, 0);\n \tcsr_write(CSR_HIDELEG, 0);\n \n@@ -48,16 +44,11 @@ int kvm_arch_enable_virtualization_cpu(void)\n \tcsr_write(CSR_HCOUNTEREN, 0x02);\n \n \tcsr_write(CSR_HVIP, 0);\n-\n-\tkvm_riscv_aia_enable();\n-\n-\treturn 0;\n }\n \n-void kvm_arch_disable_virtualization_cpu(void)\n+/* Clear hypervisor CSRs - called during CPU offline and non-retention idle entry */\n+static void kvm_riscv_csr_disable(void)\n {\n-\tkvm_riscv_aia_disable();\n-\n \t/*\n \t * After clearing the hideleg CSR, the host kernel will receive\n \t * spurious interrupts if hvip CSR has pending interrupts and the\n@@ -69,9 +60,53 @@ void kvm_arch_disable_virtualization_cpu(void)\n \tcsr_write(CSR_HEDELEG, 0);\n \tcsr_write(CSR_HIDELEG, 0);\n \n+\tkvm_riscv_clear_former_vcpu();\n+}\n+\n+int kvm_arch_enable_virtualization_cpu(void)\n+{\n+\tint rc;\n+\n+\trc = kvm_riscv_nacl_enable();\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tkvm_riscv_csr_enable();\n+\tkvm_riscv_aia_enable(true);\n+\n+\treturn 0;\n+}\n+\n+void kvm_arch_disable_virtualization_cpu(void)\n+{\n+\tkvm_riscv_aia_disable(true);\n+\tkvm_riscv_csr_disable();\n \tkvm_riscv_nacl_disable();\n }\n \n+static int kvm_riscv_cpu_pm_notifier(struct notifier_block *self, unsigned long cmd, void *v)\n+{\n+\tswitch (cmd) {\n+\tcase CPU_PM_EXIT:\n+\tcase CPU_PM_ENTER_FAILED:\n+\t\tkvm_riscv_csr_enable();\n+\t\tkvm_riscv_aia_enable(false);\n+\t\treturn NOTIFY_OK;\n+\tcase CPU_PM_ENTER:\n+\t\tkvm_riscv_aia_disable(false);\n+\t\tkvm_riscv_csr_disable();\n+\t\treturn NOTIFY_OK;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\treturn NOTIFY_DONE;\n+}\n+\n+static struct notifier_block kvm_riscv_cpu_pm_nb = {\n+\t.notifier_call = kvm_riscv_cpu_pm_notifier,\n+};\n+\n static void kvm_riscv_teardown(void)\n {\n \tkvm_riscv_aia_exit();\n@@ -172,22 +207,40 @@ static int __init riscv_kvm_init(void)\n \n \tkvm_register_perf_callbacks();\n \n-\trc = kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);\n-\tif (rc) {\n-\t\tkvm_riscv_teardown();\n-\t\treturn rc;\n+\t/* Register CPU PM notifier for CPU idle non-retention states */\n+\tif (IS_ENABLED(CONFIG_CPU_PM)) {\n+\t\trc = cpu_pm_register_notifier(\u0026kvm_riscv_cpu_pm_nb);\n+\t\tif (rc) {\n+\t\t\tkvm_err(\"Failed to register CPU PM notifier: %d\\n\", rc);\n+\t\t\tgoto err_teardown;\n+\t\t}\n \t}\n \n+\trc = kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);\n+\tif (rc)\n+\t\tgoto err_unregister_cpu_pm;\n+\n \tif (kvm_riscv_aia_available())\n \t\tkvm_info(\"AIA available with %d guest external interrupts\\n\",\n \t\t\t atomic_read(\u0026kvm_riscv_aia_nr_hgei));\n \n \treturn 0;\n+\n+err_unregister_cpu_pm:\n+\tif (IS_ENABLED(CONFIG_CPU_PM))\n+\t\tcpu_pm_unregister_notifier(\u0026kvm_riscv_cpu_pm_nb);\n+err_teardown:\n+\tkvm_riscv_teardown();\n+\treturn rc;\n }\n module_init(riscv_kvm_init);\n \n static void __exit riscv_kvm_exit(void)\n {\n+\t/* Unregister CPU PM notifier */\n+\tif (IS_ENABLED(CONFIG_CPU_PM))\n+\t\tcpu_pm_unregister_notifier(\u0026kvm_riscv_cpu_pm_nb);\n+\n \tkvm_exit();\n \n \tkvm_riscv_teardown();\ndiff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c\nindex cf6e231e76e254..e48338f907f488 100644\n--- a/arch/riscv/kvm/vcpu.c\n+++ b/arch/riscv/kvm/vcpu.c\n@@ -26,6 +26,17 @@\n \n static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_former_vcpu);\n \n+void kvm_riscv_clear_former_vcpu(void)\n+{\n+\t/*\n+\t * Clear the per-CPU former VCPU pointer because hypervisor CSR state\n+\t * will be lost. This ensures that the next VCPU entry will properly\n+\t * restore all CSRs instead of incorrectly skipping CSR restoration\n+\t * via the fast-path optimization.\n+\t */\n+\t__this_cpu_write(kvm_former_vcpu, NULL);\n+}\n+\n const struct kvm_stats_desc kvm_vcpu_stats_desc[] = {\n \tKVM_GENERIC_VCPU_STATS(),\n \tSTATS_DESC_COUNTER(VCPU, ecall_exit_stat),\n"
}

2/1 2026/07/23 00:45 agent patch-evaluator
0m Model:
best-expensive

Args:
null

Results:
{
  "EnableConfigs": [
    "KVM",
    "CPU_PM"
  ],
  "FocusSymbols": [
    "kvm_riscv_aia_enable",
    "kvm_riscv_aia_disable",
    "kvm_riscv_cpu_pm_notifier",
    "kvm_riscv_clear_former_vcpu"
  ],
  "Reasoning": "The patch modifies RISC-V KVM to properly handle CPU power management (idle non-retention states) by saving and restoring AIA (Advanced Interrupt Architecture) and hypervisor CSR state. This is core KVM logic and should be fuzzed to ensure no state is lost or corrupted during CPU idle transitions.",
  "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 bb80813fbe3334909b512716e5f82cd0b59297b0
Author: syz-cluster <triage@syzkaller.com>
Date:   Thu Jul 23 00:45:26 2026 +0000

    syz-cluster: applied patch under review

diff --git a/arch/riscv/include/asm/kvm_aia.h b/arch/riscv/include/asm/kvm_aia.h
index c67ec5ac0a146b..7c1c3250598fb0 100644
--- a/arch/riscv/include/asm/kvm_aia.h
+++ b/arch/riscv/include/asm/kvm_aia.h
@@ -165,8 +165,19 @@ int kvm_riscv_aia_alloc_hgei(int cpu, struct kvm_vcpu *owner,
 			     void __iomem **hgei_va, phys_addr_t *hgei_pa);
 void kvm_riscv_aia_free_hgei(int cpu, int hgei);
 
-void kvm_riscv_aia_enable(void);
-void kvm_riscv_aia_disable(void);
+/**
+ * kvm_riscv_aia_enable() - Enable AIA support on current CPU
+ * @full_cleanup: true = full hardware init (CPU hotplug/module load),
+ *                false = lightweight CSR restore (CPU non-retention idle resume)
+ */
+void kvm_riscv_aia_enable(bool full_cleanup);
+
+/**
+ * kvm_riscv_aia_disable() - Disable AIA support on current CPU
+ * @full_cleanup: true = full hardware cleanup (CPU hotplug/module exit),
+ *                false = lightweight CSR save (CPU non-retention idle entry)
+ */
+void kvm_riscv_aia_disable(bool full_cleanup);
 int kvm_riscv_aia_init(void);
 void kvm_riscv_aia_exit(void);
 
diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h
index 60017ceec9d2af..808b4ee1bd10ac 100644
--- a/arch/riscv/include/asm/kvm_host.h
+++ b/arch/riscv/include/asm/kvm_host.h
@@ -319,6 +319,8 @@ bool kvm_riscv_vcpu_stopped(struct kvm_vcpu *vcpu);
 
 void kvm_riscv_vcpu_record_steal_time(struct kvm_vcpu *vcpu);
 
+void kvm_riscv_clear_former_vcpu(void);
+
 /* Flags representing implementation specific details */
 DECLARE_STATIC_KEY_FALSE(kvm_riscv_vsstage_tlb_no_gpa);
 
diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c
index bafb009c5ce559..4cf351f91c643f 100644
--- a/arch/riscv/kvm/aia.c
+++ b/arch/riscv/kvm/aia.c
@@ -25,6 +25,7 @@ struct aia_hgei_control {
 	unsigned long free_bitmap;
 	struct kvm_vcpu *owners[BITS_PER_LONG];
 	unsigned int nr_hgei;
+	unsigned long saved_value;
 };
 static DEFINE_PER_CPU(struct aia_hgei_control, aia_hgei);
 static int hgei_parent_irq;
@@ -532,50 +533,59 @@ static void aia_hgei_exit(void)
 	free_percpu_irq(hgei_parent_irq, &aia_hgei);
 }
 
-void kvm_riscv_aia_enable(void)
+void kvm_riscv_aia_enable(bool full_cleanup)
 {
-	const struct imsic_global_config *gc;
-	const struct imsic_local_config *lc;
 	struct aia_hgei_control *hgctrl;
 	unsigned long flags;
-	int aia_nr_hgei;
 
 	if (!kvm_riscv_aia_available())
 		return;
 
-	gc = imsic_get_global_config();
-	lc = (gc) ? this_cpu_ptr(gc->local) : NULL;
 	hgctrl = this_cpu_ptr(&aia_hgei);
 
-	/* Figure-out number of bits in HGEIE */
-	csr_write(CSR_HGEIE, -1UL);
-	hgctrl->nr_hgei = fls_long(csr_read(CSR_HGEIE));
-	csr_write(CSR_HGEIE, 0);
-	if (hgctrl->nr_hgei)
-		hgctrl->nr_hgei--;
+	if (full_cleanup) {
+		const struct imsic_global_config *gc;
+		const struct imsic_local_config *lc;
+		int aia_nr_hgei;
 
-	/*
-	 * Number of usable per-HART HGEI lines should be minimum of
-	 * per-HART IMSIC guest files and number of bits in HGEIE.
-	 */
-	if (lc)
-		hgctrl->nr_hgei = min((ulong)hgctrl->nr_hgei, lc->nr_guest_files);
-	else
-		hgctrl->nr_hgei = 0;
+		gc = imsic_get_global_config();
+		lc = (gc) ? this_cpu_ptr(gc->local) : NULL;
 
-	/* Update the number of IMSIC guest files across all HARTs */
-	aia_nr_hgei = atomic_read(&kvm_riscv_aia_nr_hgei);
-	do {
-		if (aia_nr_hgei <= hgctrl->nr_hgei)
-			break;
-	} while (!atomic_try_cmpxchg(&kvm_riscv_aia_nr_hgei, &aia_nr_hgei, hgctrl->nr_hgei));
+		/* Figure-out number of bits in HGEIE */
+		csr_write(CSR_HGEIE, -1UL);
+		hgctrl->nr_hgei = fls_long(csr_read(CSR_HGEIE));
+		csr_write(CSR_HGEIE, 0);
+		if (hgctrl->nr_hgei)
+			hgctrl->nr_hgei--;
 
-	raw_spin_lock_irqsave(&hgctrl->lock, flags);
-	if (!hgctrl->free_bitmap_initialized) {
-		hgctrl->free_bitmap = (hgctrl->nr_hgei) ? GENMASK_ULL(hgctrl->nr_hgei, 1) : 0;
-		hgctrl->free_bitmap_initialized = true;
+		/*
+		 * Number of usable per-HART HGEI lines should be minimum of
+		 * per-HART IMSIC guest files and number of bits in HGEIE.
+		 */
+		if (lc)
+			hgctrl->nr_hgei = min((ulong)hgctrl->nr_hgei, lc->nr_guest_files);
+		else
+			hgctrl->nr_hgei = 0;
+
+		/* Update the number of IMSIC guest files across all HARTs */
+		aia_nr_hgei = atomic_read(&kvm_riscv_aia_nr_hgei);
+		do {
+			if (aia_nr_hgei <= hgctrl->nr_hgei)
+				break;
+		} while (!atomic_try_cmpxchg(&kvm_riscv_aia_nr_hgei, &aia_nr_hgei,
+					     hgctrl->nr_hgei));
+
+		raw_spin_lock_irqsave(&hgctrl->lock, flags);
+		if (!hgctrl->free_bitmap_initialized) {
+			hgctrl->free_bitmap = (hgctrl->nr_hgei) ?
+					      GENMASK_ULL(hgctrl->nr_hgei, 1) :
+					      0;
+			hgctrl->free_bitmap_initialized = true;
+		}
+		raw_spin_unlock_irqrestore(&hgctrl->lock, flags);
+	} else {
+		csr_write(CSR_HGEIE, hgctrl->saved_value);
 	}
-	raw_spin_unlock_irqrestore(&hgctrl->lock, flags);
 
 	csr_write(CSR_HVICTL, aia_hvictl_value(false));
 	csr_write(CSR_HVIPRIO1, 0x0);
@@ -587,16 +597,17 @@ void kvm_riscv_aia_enable(void)
 	csr_write(CSR_HVIPRIO2H, 0x0);
 #endif
 
-	/* Enable per-CPU SGEI interrupt */
-	enable_percpu_irq(hgei_parent_irq,
-			  irq_get_trigger_type(hgei_parent_irq));
+	if (full_cleanup)
+		enable_percpu_irq(hgei_parent_irq,
+				  irq_get_trigger_type(hgei_parent_irq));
 	csr_set(CSR_HIE, BIT(IRQ_S_GEXT));
+
 	/* Enable IRQ filtering for overflow interrupt only if sscofpmf is present */
 	if (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_SSCOFPMF))
 		csr_set(CSR_HVIEN, BIT(IRQ_PMU_OVF));
 }
 
-void kvm_riscv_aia_disable(void)
+void kvm_riscv_aia_disable(bool full_cleanup)
 {
 	int i;
 	unsigned long flags;
@@ -609,42 +620,49 @@ void kvm_riscv_aia_disable(void)
 
 	if (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_SSCOFPMF))
 		csr_clear(CSR_HVIEN, BIT(IRQ_PMU_OVF));
-	/* Disable per-CPU SGEI interrupt */
-	csr_clear(CSR_HIE, BIT(IRQ_S_GEXT));
-	disable_percpu_irq(hgei_parent_irq);
 
-	csr_write(CSR_HVICTL, aia_hvictl_value(false));
-
-	raw_spin_lock_irqsave(&hgctrl->lock, flags);
-
-	for (i = 0; i <= hgctrl->nr_hgei; i++) {
-		vcpu = hgctrl->owners[i];
-		if (!vcpu)
-			continue;
+	if (full_cleanup) {
+		/* Disable per-CPU SGEI interrupt */
+		csr_clear(CSR_HIE, BIT(IRQ_S_GEXT));
+		disable_percpu_irq(hgei_parent_irq);
+	}
 
-		/*
-		 * We release hgctrl->lock before notifying IMSIC
-		 * so that we don't have lock ordering issues.
-		 */
-		raw_spin_unlock_irqrestore(&hgctrl->lock, flags);
+	csr_write(CSR_HVICTL, aia_hvictl_value(false));
 
-		/* Notify IMSIC */
-		kvm_riscv_vcpu_aia_imsic_release(vcpu);
+	if (full_cleanup) {
+		raw_spin_lock_irqsave(&hgctrl->lock, flags);
 
-		/*
-		 * Wakeup VCPU if it was blocked so that it can
-		 * run on other HARTs
-		 */
-		if (csr_read(CSR_HGEIE) & BIT(i)) {
-			csr_clear(CSR_HGEIE, BIT(i));
-			kvm_vcpu_kick(vcpu);
+		for (i = 0; i <= hgctrl->nr_hgei; i++) {
+			vcpu = hgctrl->owners[i];
+			if (!vcpu)
+				continue;
+
+			/*
+			 * We release hgctrl->lock before notifying IMSIC
+			 * so that we don't have lock ordering issues.
+			 */
+			raw_spin_unlock_irqrestore(&hgctrl->lock, flags);
+
+			/* Notify IMSIC */
+			kvm_riscv_vcpu_aia_imsic_release(vcpu);
+
+			/*
+			 * Wakeup VCPU if it was blocked so that it can
+			 * run on other HARTs
+			 */
+			if (csr_read(CSR_HGEIE) & BIT(i)) {
+				csr_clear(CSR_HGEIE, BIT(i));
+				kvm_vcpu_kick(vcpu);
+			}
+
+			raw_spin_lock_irqsave(&hgctrl->lock, flags);
 		}
 
-		raw_spin_lock_irqsave(&hgctrl->lock, flags);
+		raw_spin_unlock_irqrestore(&hgctrl->lock, flags);
+	} else {
+		hgctrl->saved_value = csr_read(CSR_HGEIE);
 	}
 
-	raw_spin_unlock_irqrestore(&hgctrl->lock, flags);
-
 	put_cpu_ptr(&aia_hgei);
 }
 
diff --git a/arch/riscv/kvm/main.c b/arch/riscv/kvm/main.c
index 0924c75100a2d0..b48bbd1855c1e2 100644
--- a/arch/riscv/kvm/main.c
+++ b/arch/riscv/kvm/main.c
@@ -10,6 +10,7 @@
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/kvm_host.h>
+#include <linux/cpu_pm.h>
 #include <asm/cpufeature.h>
 #include <asm/kvm_mmu.h>
 #include <asm/kvm_nacl.h>
@@ -33,14 +34,9 @@ long kvm_arch_dev_ioctl(struct file *filp,
 	return -EINVAL;
 }
 
-int kvm_arch_enable_virtualization_cpu(void)
+/* Initialize hypervisor CSRs - called during CPU online and non-retention idle resume */
+static void kvm_riscv_csr_enable(void)
 {
-	int rc;
-
-	rc = kvm_riscv_nacl_enable();
-	if (rc)
-		return rc;
-
 	csr_write(CSR_HEDELEG, 0);
 	csr_write(CSR_HIDELEG, 0);
 
@@ -48,16 +44,11 @@ int kvm_arch_enable_virtualization_cpu(void)
 	csr_write(CSR_HCOUNTEREN, 0x02);
 
 	csr_write(CSR_HVIP, 0);
-
-	kvm_riscv_aia_enable();
-
-	return 0;
 }
 
-void kvm_arch_disable_virtualization_cpu(void)
+/* Clear hypervisor CSRs - called during CPU offline and non-retention idle entry */
+static void kvm_riscv_csr_disable(void)
 {
-	kvm_riscv_aia_disable();
-
 	/*
 	 * After clearing the hideleg CSR, the host kernel will receive
 	 * spurious interrupts if hvip CSR has pending interrupts and the
@@ -69,9 +60,53 @@ void kvm_arch_disable_virtualization_cpu(void)
 	csr_write(CSR_HEDELEG, 0);
 	csr_write(CSR_HIDELEG, 0);
 
+	kvm_riscv_clear_former_vcpu();
+}
+
+int kvm_arch_enable_virtualization_cpu(void)
+{
+	int rc;
+
+	rc = kvm_riscv_nacl_enable();
+	if (rc)
+		return rc;
+
+	kvm_riscv_csr_enable();
+	kvm_riscv_aia_enable(true);
+
+	return 0;
+}
+
+void kvm_arch_disable_virtualization_cpu(void)
+{
+	kvm_riscv_aia_disable(true);
+	kvm_riscv_csr_disable();
 	kvm_riscv_nacl_disable();
 }
 
+static int kvm_riscv_cpu_pm_notifier(struct notifier_block *self, unsigned long cmd, void *v)
+{
+	switch (cmd) {
+	case CPU_PM_EXIT:
+	case CPU_PM_ENTER_FAILED:
+		kvm_riscv_csr_enable();
+		kvm_riscv_aia_enable(false);
+		return NOTIFY_OK;
+	case CPU_PM_ENTER:
+		kvm_riscv_aia_disable(false);
+		kvm_riscv_csr_disable();
+		return NOTIFY_OK;
+	default:
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block kvm_riscv_cpu_pm_nb = {
+	.notifier_call = kvm_riscv_cpu_pm_notifier,
+};
+
 static void kvm_riscv_teardown(void)
 {
 	kvm_riscv_aia_exit();
@@ -172,22 +207,40 @@ static int __init riscv_kvm_init(void)
 
 	kvm_register_perf_callbacks();
 
-	rc = kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);
-	if (rc) {
-		kvm_riscv_teardown();
-		return rc;
+	/* Register CPU PM notifier for CPU idle non-retention states */
+	if (IS_ENABLED(CONFIG_CPU_PM)) {
+		rc = cpu_pm_register_notifier(&kvm_riscv_cpu_pm_nb);
+		if (rc) {
+			kvm_err("Failed to register CPU PM notifier: %d\n", rc);
+			goto err_teardown;
+		}
 	}
 
+	rc = kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);
+	if (rc)
+		goto err_unregister_cpu_pm;
+
 	if (kvm_riscv_aia_available())
 		kvm_info("AIA available with %d guest external interrupts\n",
 			 atomic_read(&kvm_riscv_aia_nr_hgei));
 
 	return 0;
+
+err_unregister_cpu_pm:
+	if (IS_ENABLED(CONFIG_CPU_PM))
+		cpu_pm_unregister_notifier(&kvm_riscv_cpu_pm_nb);
+err_teardown:
+	kvm_riscv_teardown();
+	return rc;
 }
 module_init(riscv_kvm_init);
 
 static void __exit riscv_kvm_exit(void)
 {
+	/* Unregister CPU PM notifier */
+	if (IS_ENABLED(CONFIG_CPU_PM))
+		cpu_pm_unregister_notifier(&kvm_riscv_cpu_pm_nb);
+
 	kvm_exit();
 
 	kvm_riscv_teardown();
diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c
index cf6e231e76e254..e48338f907f488 100644
--- a/arch/riscv/kvm/vcpu.c
+++ b/arch/riscv/kvm/vcpu.c
@@ -26,6 +26,17 @@
 
 static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_former_vcpu);
 
+void kvm_riscv_clear_former_vcpu(void)
+{
+	/*
+	 * Clear the per-CPU former VCPU pointer because hypervisor CSR state
+	 * will be lost. This ensures that the next VCPU entry will properly
+	 * restore all CSRs instead of incorrectly skipping CSR restoration
+	 * via the fast-path optimization.
+	 */
+	__this_cpu_write(kvm_former_vcpu, NULL);
+}
+
 const struct kvm_stats_desc kvm_vcpu_stats_desc[] = {
 	KVM_GENERIC_VCPU_STATS(),
 	STATS_DESC_COUNTER(VCPU, ecall_exit_stat),

3/2 2026/07/23 00:45 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 6983
							output: 33
							thoughts: 418
						

Thoughts:
**Analyzing the RISC-V KVM AIA Patch**

Okay, so I'm looking at this patch for RISC-V KVM, and my initial thought is, "Alright, let's see what we've got here." It modifies the AIA (Advanced Interrupt Architecture) handling, specifically the enable/disable functions (`kvm_riscv_aia_enable` and `kvm_riscv_aia_disable`) to take a `full_cleanup` boolean. Clever, a targeted approach to cleanups. It also seems like we're integrating CPU PM notifiers to handle AIA state saving and restoring during CPU idle non-retention states. And I see a clear of `kvm_former_vcpu` during CPU offline and non-retention idle entry. This is smart; ensures a clean state transition.

My immediate reaction is to assess its reachability and functionality. The changes are neatly isolated within `arch/riscv/kvm/aia.c` and `arch/riscv/kvm/main.c`, which makes it easier to review. This `kvm_riscv_cpu_pm_notifier`, which handles `CPU_PM_EXIT`, `CPU_PM_ENTER_FAILED`, and `CPU_PM_ENTER`, looks solid. It's clearly handling CPU power management, particularly idle states, for KVM on RISC-V. No surprises there.

Now, the fuzzing question. CPU PM states within a VM... that's a bit of a challenge. It's not the easiest thing to trigger reliably. However, since this patch touches core KVM logic, it's definitely worth considering. The patch modifies `kvm_arch_enable_virtualization_cpu` and `kvm_arch_disable_virtualization_cpu`, that's a key area. And the addition of that CPU PM notifier means it's now directly intertwined. Can syzkaller trigger CPU PM states? Actually, yeah, it can, potentially through sysfs writes, or just plain old idle time. Plus, KVM ioctls like VM and VCPU creation will definitely interact with this logic. Time to check the configs...

The configurations I'll look at are `CONFIG_KVM`, `CONFIG_RISCV`, and `CONFIG_CPU_PM`. I need to verify that these are correctly set and accounted for.

Finally, I need to focus on specific functions for deeper analysis: `kvm_riscv_aia_enable`, `kvm_riscv_aia_disable`, `kvm_riscv_cpu_pm_notifier`, and `kvm_riscv_clear_former_vcpu`. These are the core elements I'll be targeting to verify this patch's integrity. The usual drill.



4/2 2026/07/23 00:45 tool grepper
0m Args:
{
  "Expression": "CONFIG_CPU_PM",
  "PathPrefix": "arch/riscv/kvm/"
}

Results:
{
  "Output": "arch/riscv/kvm/main.c=117=static int __init riscv_kvm_init(void)\n--\narch/riscv/kvm/main.c-210-\t/* Register CPU PM notifier for CPU idle non-retention states */\narch/riscv/kvm/main.c:211:\tif (IS_ENABLED(CONFIG_CPU_PM)) {\narch/riscv/kvm/main.c-212-\t\trc = cpu_pm_register_notifier(\u0026kvm_riscv_cpu_pm_nb);\n--\narch/riscv/kvm/main.c-229-err_unregister_cpu_pm:\narch/riscv/kvm/main.c:230:\tif (IS_ENABLED(CONFIG_CPU_PM))\narch/riscv/kvm/main.c-231-\t\tcpu_pm_unregister_notifier(\u0026kvm_riscv_cpu_pm_nb);\n--\narch/riscv/kvm/main.c=238=static void __exit riscv_kvm_exit(void)\n--\narch/riscv/kvm/main.c-240-\t/* Unregister CPU PM notifier */\narch/riscv/kvm/main.c:241:\tif (IS_ENABLED(CONFIG_CPU_PM))\narch/riscv/kvm/main.c-242-\t\tcpu_pm_unregister_notifier(\u0026kvm_riscv_cpu_pm_nb);\n"
}

5/2 2026/07/23 00:45 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 8391
							output: 33
							thoughts: 193
						

Thoughts:
**My Initial Assessment of the KVM/RISC-V Patch**

Okay, so this patch is clearly introducing some significant functional changes to KVM, specifically around how it handles CPU power management and idle states on RISC-V. The mention of AIA (Advanced Interrupt Architecture) is a key detail - that's definitely a point of focus. And the fact that it's touching general hypervisor CSRs just makes it even more interesting from a security perspective. My initial thought? Absolutely, this needs to be thoroughly fuzzed. Potential attack surface is almost guaranteed to be there.

Let's quickly identify the key functions this patch is modifying. I see `kvm_riscv_aia_enable`, `kvm_riscv_aia_disable`, `kvm_riscv_cpu_pm_notifier`, and `kvm_riscv_clear_former_vcpu` mentioned. These are my primary focus symbols for further analysis. They are definitely going to be the places where things can go wrong.

Now, let's look at the configuration dependencies. The patch's configuration requirements are `KVM` and `CPU_PM`. Obviously, since it's working with KVM, `KVM` is going to be required. The notifier registration specifically implies that `CPU_PM` must be enabled. I wonder if there are any *other* configs that need to be considered. Given that the code's located in `arch/riscv/kvm/`, I'll quickly check the Kconfig for RISC-V KVM to make sure I haven't missed anything obvious. I'll need to check the dependencies and ensure there aren't any further constraints.



6/2 2026/07/23 00:45 tool grepper
0m Args:
{
  "Expression": "config KVM",
  "PathPrefix": "arch/riscv/kvm/Kconfig"
}

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"
}

7/2 2026/07/23 00:45 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 9070
							output: 30
							thoughts: 20
						

Thoughts:
Here's my take on those thoughts:

**KVM Configuration Deep Dive**

Okay, so I'm focusing in on the configuration related to `KVM`. My initial thought is that it's the central element I need to understand for this particular scenario. Now, before I proceed further, I need to make absolutely sure I'm clear on the interrelationship between `KVM` and other elements, such as the `CPU_PM` module. Let me go back and re-examine the `CPU_PM` elements in the config, and ensure everything ties back in the correct manner. I want to make sure I am grasping the dependencies as a whole.



8/2 2026/07/23 00:45 tool grepper
0m Args:
{
  "Expression": "config CPU_PM",
  "PathPrefix": "kernel/power/Kconfig"
}

Results:
{
  "Output": "kernel/power/Kconfig=385=config PM_GENERIC_DOMAINS_OF\n--\nkernel/power/Kconfig-388-\nkernel/power/Kconfig:389:config CPU_PM\nkernel/power/Kconfig-390-\tbool\n"
}

9/2 2026/07/23 00:45 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 9338
							output: 157
							thoughts: 17
						

Thoughts:
Okay, here's my interpretation of those thoughts, tailored for an expert audience, presented in the first person:

**CPU_PM Configuration Analysis**

Alright, so `CPU_PM` is a boolean configuration option. Simple enough. My goal here is to determine its implications and decide on the appropriate settings based on the system's needs, performance requirements, and power profiles. I'm going to carefully analyze the impacts of enabling or disabling it, considering the specific architecture and workloads at hand. I'll need to examine how it interacts with other power management features and device drivers. Then, I'll document my findings and set the resulting configuration, making sure the changes are justified and properly tested. I'll need to consider whether default values are appropriate, or whether this should be altered for each specific machine.



10/2 2026/07/23 00:45 tool set-results
0m Args:
{
  "EnableConfigs": [
    "KVM",
    "CPU_PM"
  ],
  "FocusSymbols": [
    "kvm_riscv_aia_enable",
    "kvm_riscv_aia_disable",
    "kvm_riscv_cpu_pm_notifier",
    "kvm_riscv_clear_former_vcpu"
  ],
  "Reasoning": "The patch modifies RISC-V KVM to properly handle CPU power management (idle non-retention states) by saving and restoring AIA (Advanced Interrupt Architecture) and hypervisor CSR state. This is core KVM logic and should be fuzzed to ensure no state is lost or corrupted during CPU idle transitions.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "KVM",
    "CPU_PM"
  ],
  "FocusSymbols": [
    "kvm_riscv_aia_enable",
    "kvm_riscv_aia_disable",
    "kvm_riscv_cpu_pm_notifier",
    "kvm_riscv_clear_former_vcpu"
  ],
  "Reasoning": "The patch modifies RISC-V KVM to properly handle CPU power management (idle non-retention states) by saving and restoring AIA (Advanced Interrupt Architecture) and hypervisor CSR state. This is core KVM logic and should be fuzzed to ensure no state is lost or corrupted during CPU idle transitions.",
  "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)