AI Trajectory


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

Results:
{
  "EnableConfigs": [
    "KVM",
    "MMU_NOTIFIER"
  ],
  "FocusSymbols": [
    "mmu_notifier_oom_enter",
    "mmu_notifier_barrier",
    "mmu_notifier_oom_callback_fn",
    "kvm_mmu_notifier_after_oom_unregister",
    "kvm_destroy_vm",
    "process_mrelease"
  ],
  "Reasoning": "The patch introduces a new MMU notifier callback `after_oom_unregister` and a mechanism to invoke it asynchronously when an OOM event occurs (`mmu_notifier_oom_enter`). It also implements this callback for KVM and modifies `kvm_destroy_vm` to handle the asynchronous cleanup. This is a functional change to core memory management and KVM, and should be fuzzed to ensure there are no use-after-free or deadlock issues during OOM handling of VMs.",
  "WorthFuzzing": true
}

1/1 2026/07/23 15:29 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 02311d185dbcb6d9da160a9c703ba86f778a4ceb\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Thu Jul 23 15:28:58 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h\nindex a11a44eef521e9..a1820a487854dd 100644\n--- a/include/linux/mmu_notifier.h\n+++ b/include/linux/mmu_notifier.h\n@@ -88,6 +88,14 @@ struct mmu_notifier_ops {\n \tvoid (*release)(struct mmu_notifier *subscription,\n \t\t\tstruct mm_struct *mm);\n \n+\t/*\n+\t * Any mmu notifier that defines this is automatically unregistered\n+\t * when its mm is the subject of an OOM kill.  after_oom_unregister()\n+\t * is invoked after all other outstanding callbacks have terminated.\n+\t */\n+\tvoid (*after_oom_unregister)(struct mmu_notifier *subscription,\n+\t\t\t\t     struct mm_struct *mm);\n+\n \t/*\n \t * clear_flush_young is called after the VM is\n \t * test-and-clearing the young/accessed bitflag in the\n@@ -424,6 +432,8 @@ bool __mmu_notifier_clear_young(struct mm_struct *mm,\n \t\tunsigned long start, unsigned long end);\n bool __mmu_notifier_test_young(struct mm_struct *mm,\n \t\tunsigned long address);\n+void mmu_notifier_oom_enter(struct mm_struct *mm);\n+void mmu_notifier_barrier(void);\n extern int __mmu_notifier_invalidate_range_start(struct mmu_notifier_range *r);\n extern void __mmu_notifier_invalidate_range_end(struct mmu_notifier_range *r);\n extern void __mmu_notifier_arch_invalidate_secondary_tlbs(struct mm_struct *mm,\n@@ -643,6 +653,10 @@ static inline void mmu_notifier_synchronize(void)\n {\n }\n \n+static inline void mmu_notifier_oom_enter(struct mm_struct *mm)\n+{\n+}\n+\n #endif /* CONFIG_MMU_NOTIFIER */\n \n #endif /* _LINUX_MMU_NOTIFIER_H */\ndiff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c\nindex 245b74f39f9122..f30bf95f17c7aa 100644\n--- a/mm/mmu_notifier.c\n+++ b/mm/mmu_notifier.c\n@@ -49,6 +49,37 @@ struct mmu_notifier_subscriptions {\n \tstruct hlist_head deferred_list;\n };\n \n+/*\n+ * Callback structure for asynchronous OOM cleanup.\n+ * Used with call_srcu() to defer after_oom_unregister callbacks\n+ * until after SRCU grace period completes.\n+ */\n+struct mmu_notifier_oom_callback {\n+\tstruct rcu_head rcu;\n+\tstruct mmu_notifier *subscription;\n+\tstruct mm_struct *mm;\n+};\n+\n+/*\n+ * Callback function invoked after SRCU grace period.\n+ * Safely calls after_oom_unregister once all readers have finished.\n+ */\n+static void mmu_notifier_oom_callback_fn(struct rcu_head *rcu)\n+{\n+\tstruct mmu_notifier_oom_callback *cb =\n+\t\tcontainer_of(rcu, struct mmu_notifier_oom_callback, rcu);\n+\n+\t/* Safe - all SRCU readers have finished */\n+\tcb-\u003esubscription-\u003eops-\u003eafter_oom_unregister(cb-\u003esubscription, cb-\u003emm);\n+\n+\t/* Release mm reference taken when callback was scheduled */\n+\tWARN_ON_ONCE(atomic_read(\u0026cb-\u003emm-\u003emm_count) \u003c= 0);\n+\tmmdrop(cb-\u003emm);\n+\n+\t/* Free callback structure */\n+\tkfree(cb);\n+}\n+\n /*\n  * This is a collision-retry read-side/write-side 'lock', a lot like a\n  * seqcount, however this allows multiple write-sides to hold it at\n@@ -385,6 +416,84 @@ void __mmu_notifier_release(struct mm_struct *mm)\n \t\tmn_hlist_release(subscriptions, mm);\n }\n \n+void mmu_notifier_oom_enter(struct mm_struct *mm)\n+{\n+\tstruct mmu_notifier_subscriptions *subscriptions =\n+\t\t\t\t\t\tmm-\u003enotifier_subscriptions;\n+\tstruct mmu_notifier *subscription;\n+\tstruct hlist_node *tmp;\n+\tHLIST_HEAD(oom_list);\n+\tint id;\n+\n+\tif (!subscriptions)\n+\t\treturn;\n+\n+\tid = srcu_read_lock(\u0026srcu);\n+\n+\t/*\n+\t * Prevent further calls to the MMU notifier, except for\n+\t * release and after_oom_unregister.\n+\t */\n+\tspin_lock(\u0026subscriptions-\u003elock);\n+\thlist_for_each_entry_safe(subscription, tmp,\n+\t\t\t\t  \u0026subscriptions-\u003elist, hlist) {\n+\t\tif (!subscription-\u003eops-\u003eafter_oom_unregister)\n+\t\t\tcontinue;\n+\n+\t\t/*\n+\t\t * after_oom_unregister and alloc_notifier are incompatible,\n+\t\t * because there could be other references to allocated\n+\t\t * notifiers.\n+\t\t */\n+\t\tif (WARN_ON(subscription-\u003eops-\u003ealloc_notifier))\n+\t\t\tcontinue;\n+\n+\t\thlist_del_init_rcu(\u0026subscription-\u003ehlist);\n+\t\thlist_add_head(\u0026subscription-\u003ehlist, \u0026oom_list);\n+\t}\n+\tspin_unlock(\u0026subscriptions-\u003elock);\n+\thlist_for_each_entry(subscription, \u0026oom_list, hlist)\n+\t\tif (subscription-\u003eops-\u003erelease)\n+\t\t\tsubscription-\u003eops-\u003erelease(subscription, mm);\n+\n+\tsrcu_read_unlock(\u0026srcu, id);\n+\n+\tif (hlist_empty(\u0026oom_list))\n+\t\treturn;\n+\n+\thlist_for_each_entry_safe(subscription, tmp,\n+\t\t\t\t  \u0026oom_list, hlist) {\n+\t\tstruct mmu_notifier_oom_callback *cb;\n+\t\t/*\n+\t\t * Remove from stack-based oom_list and reset hlist to unhashed state.\n+\t\t * This sets subscription-\u003ehlist.pprev = NULL, so future callers of\n+\t\t * mmu_notifier_unregister() (e.g. kvm_destroy_vm) will see\n+\t\t * hlist_unhashed() == true and take the safe path, avoiding\n+\t\t * use-after-free on the stack-allocated oom_list head.\n+\t\t */\n+\t\thlist_del_init(\u0026subscription-\u003ehlist);\n+\n+\t\t/*\n+\t\t * GFP_ATOMIC failure is exceedingly rare. We cannot sleep\n+\t\t * here (would reintroduce the deadlock this patch fixes)\n+\t\t * and cannot call after_oom_unregister synchronously\n+\t\t * without first waiting for SRCU readers. The subscriber\n+\t\t * will not receive after_oom_unregister but cleanup will\n+\t\t * eventually happen via the unregister path.\n+\t\t */\n+\t\tcb = kmalloc_obj(*cb, GFP_ATOMIC);\n+\t\tif (!cb)\n+\t\t\tcontinue;\n+\n+\t\tcb-\u003esubscription = subscription;\n+\t\tcb-\u003emm = mm;\n+\t\tmmgrab(mm);\n+\n+\t\t/* Schedule callback - returns immediately */\n+\t\tcall_srcu(\u0026srcu, \u0026cb-\u003ercu, mmu_notifier_oom_callback_fn);\n+\t}\n+}\n+\n /*\n  * If no young bitflag is supported by the hardware, -\u003eclear_flush_young can\n  * unmap the address and return 1 or 0 depending if the mapping previously\n@@ -1144,3 +1253,16 @@ void mmu_notifier_synchronize(void)\n \tsynchronize_srcu(\u0026srcu);\n }\n EXPORT_SYMBOL_GPL(mmu_notifier_synchronize);\n+\n+/**\n+ * mmu_notifier_barrier - Wait for all pending MMU notifier callbacks\n+ *\n+ * Waits for all call_srcu() callbacks scheduled by mmu_notifier_oom_enter()\n+ * to complete. Used by subsystems during cleanup to prevent use-after-free\n+ * when destroying structures accessed by the callbacks.\n+ */\n+void mmu_notifier_barrier(void)\n+{\n+\tsrcu_barrier(\u0026srcu);\n+}\n+EXPORT_SYMBOL_GPL(mmu_notifier_barrier);\ndiff --git a/mm/oom_kill.c b/mm/oom_kill.c\nindex 5f372f6e26fa32..66adcd03f36a8e 100644\n--- a/mm/oom_kill.c\n+++ b/mm/oom_kill.c\n@@ -516,6 +516,9 @@ static bool __oom_reap_task_mm(struct mm_struct *mm)\n \tbool ret = true;\n \tMA_STATE(mas, \u0026mm-\u003emm_mt, ULONG_MAX, ULONG_MAX);\n \n+\t/* Notify MMU notifiers about the OOM event */\n+\tmmu_notifier_oom_enter(mm);\n+\n \t/*\n \t * Tell all users of get_user/copy_from_user etc... that the content\n \t * is no longer stable. No barriers really needed because unmapping\ndiff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c\nindex e44c20c049610d..79a4df8a337a2d 100644\n--- a/virt/kvm/kvm_main.c\n+++ b/virt/kvm/kvm_main.c\n@@ -875,6 +875,24 @@ static void kvm_mmu_notifier_release(struct mmu_notifier *mn,\n \tsrcu_read_unlock(\u0026kvm-\u003esrcu, idx);\n }\n \n+static void kvm_mmu_notifier_after_oom_unregister(struct mmu_notifier *mn,\n+\t\t\t\t\t\t  struct mm_struct *mm)\n+{\n+\tstruct kvm *kvm;\n+\n+\tkvm = mmu_notifier_to_kvm(mn);\n+\n+\t/*\n+\t * At this point the unregister has completed and all other callbacks\n+\t * have terminated. Clean up any unbalanced invalidation counts.\n+\t */\n+\tWARN_ON(rcuwait_active(\u0026kvm-\u003emn_memslots_update_rcuwait));\n+\tif (kvm-\u003emn_active_invalidate_count)\n+\t\tkvm-\u003emn_active_invalidate_count = 0;\n+\telse\n+\t\tWARN_ON(kvm-\u003emmu_invalidate_in_progress);\n+}\n+\n static const struct mmu_notifier_ops kvm_mmu_notifier_ops = {\n \t.invalidate_range_start\t= kvm_mmu_notifier_invalidate_range_start,\n \t.invalidate_range_end\t= kvm_mmu_notifier_invalidate_range_end,\n@@ -882,6 +900,7 @@ static const struct mmu_notifier_ops kvm_mmu_notifier_ops = {\n \t.clear_young\t\t= kvm_mmu_notifier_clear_young,\n \t.test_young\t\t= kvm_mmu_notifier_test_young,\n \t.release\t\t= kvm_mmu_notifier_release,\n+\t.after_oom_unregister\t= kvm_mmu_notifier_after_oom_unregister,\n };\n \n static int kvm_init_mmu_notifier(struct kvm *kvm)\n@@ -1273,7 +1292,13 @@ static void kvm_destroy_vm(struct kvm *kvm)\n \t\tkvm-\u003ebuses[i] = NULL;\n \t}\n \tkvm_coalesced_mmio_free(kvm);\n-\tmmu_notifier_unregister(\u0026kvm-\u003emmu_notifier, kvm-\u003emm);\n+\tif (hlist_unhashed(\u0026kvm-\u003emmu_notifier.hlist)) {\n+\t\t/* Subscription removed by OOM. Wait for async callback. */\n+\t\tmmu_notifier_barrier();\n+\t\tmmdrop(kvm-\u003emm);\n+\t} else {\n+\t\tmmu_notifier_unregister(\u0026kvm-\u003emmu_notifier, kvm-\u003emm);\n+\t}\n \t/*\n \t * At this point, pending calls to invalidate_range_start()\n \t * have completed but no more MMU notifiers will run, so\n"
}

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

Args:
null

Results:
{
  "EnableConfigs": [
    "KVM",
    "MMU_NOTIFIER"
  ],
  "FocusSymbols": [
    "mmu_notifier_oom_enter",
    "mmu_notifier_barrier",
    "mmu_notifier_oom_callback_fn",
    "kvm_mmu_notifier_after_oom_unregister",
    "kvm_destroy_vm",
    "process_mrelease"
  ],
  "Reasoning": "The patch introduces a new MMU notifier callback `after_oom_unregister` and a mechanism to invoke it asynchronously when an OOM event occurs (`mmu_notifier_oom_enter`). It also implements this callback for KVM and modifies `kvm_destroy_vm` to handle the asynchronous cleanup. This is a functional change to core memory management and KVM, and should be fuzzed to ensure there are no use-after-free or deadlock issues during OOM handling of VMs.",
  "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 02311d185dbcb6d9da160a9c703ba86f778a4ceb
Author: syz-cluster <triage@syzkaller.com>
Date:   Thu Jul 23 15:28:58 2026 +0000

    syz-cluster: applied patch under review

diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h
index a11a44eef521e9..a1820a487854dd 100644
--- a/include/linux/mmu_notifier.h
+++ b/include/linux/mmu_notifier.h
@@ -88,6 +88,14 @@ struct mmu_notifier_ops {
 	void (*release)(struct mmu_notifier *subscription,
 			struct mm_struct *mm);
 
+	/*
+	 * Any mmu notifier that defines this is automatically unregistered
+	 * when its mm is the subject of an OOM kill.  after_oom_unregister()
+	 * is invoked after all other outstanding callbacks have terminated.
+	 */
+	void (*after_oom_unregister)(struct mmu_notifier *subscription,
+				     struct mm_struct *mm);
+
 	/*
 	 * clear_flush_young is called after the VM is
 	 * test-and-clearing the young/accessed bitflag in the
@@ -424,6 +432,8 @@ bool __mmu_notifier_clear_young(struct mm_struct *mm,
 		unsigned long start, unsigned long end);
 bool __mmu_notifier_test_young(struct mm_struct *mm,
 		unsigned long address);
+void mmu_notifier_oom_enter(struct mm_struct *mm);
+void mmu_notifier_barrier(void);
 extern int __mmu_notifier_invalidate_range_start(struct mmu_notifier_range *r);
 extern void __mmu_notifier_invalidate_range_end(struct mmu_notifier_range *r);
 extern void __mmu_notifier_arch_invalidate_secondary_tlbs(struct mm_struct *mm,
@@ -643,6 +653,10 @@ static inline void mmu_notifier_synchronize(void)
 {
 }
 
+static inline void mmu_notifier_oom_enter(struct mm_struct *mm)
+{
+}
+
 #endif /* CONFIG_MMU_NOTIFIER */
 
 #endif /* _LINUX_MMU_NOTIFIER_H */
diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c
index 245b74f39f9122..f30bf95f17c7aa 100644
--- a/mm/mmu_notifier.c
+++ b/mm/mmu_notifier.c
@@ -49,6 +49,37 @@ struct mmu_notifier_subscriptions {
 	struct hlist_head deferred_list;
 };
 
+/*
+ * Callback structure for asynchronous OOM cleanup.
+ * Used with call_srcu() to defer after_oom_unregister callbacks
+ * until after SRCU grace period completes.
+ */
+struct mmu_notifier_oom_callback {
+	struct rcu_head rcu;
+	struct mmu_notifier *subscription;
+	struct mm_struct *mm;
+};
+
+/*
+ * Callback function invoked after SRCU grace period.
+ * Safely calls after_oom_unregister once all readers have finished.
+ */
+static void mmu_notifier_oom_callback_fn(struct rcu_head *rcu)
+{
+	struct mmu_notifier_oom_callback *cb =
+		container_of(rcu, struct mmu_notifier_oom_callback, rcu);
+
+	/* Safe - all SRCU readers have finished */
+	cb->subscription->ops->after_oom_unregister(cb->subscription, cb->mm);
+
+	/* Release mm reference taken when callback was scheduled */
+	WARN_ON_ONCE(atomic_read(&cb->mm->mm_count) <= 0);
+	mmdrop(cb->mm);
+
+	/* Free callback structure */
+	kfree(cb);
+}
+
 /*
  * This is a collision-retry read-side/write-side 'lock', a lot like a
  * seqcount, however this allows multiple write-sides to hold it at
@@ -385,6 +416,84 @@ void __mmu_notifier_release(struct mm_struct *mm)
 		mn_hlist_release(subscriptions, mm);
 }
 
+void mmu_notifier_oom_enter(struct mm_struct *mm)
+{
+	struct mmu_notifier_subscriptions *subscriptions =
+						mm->notifier_subscriptions;
+	struct mmu_notifier *subscription;
+	struct hlist_node *tmp;
+	HLIST_HEAD(oom_list);
+	int id;
+
+	if (!subscriptions)
+		return;
+
+	id = srcu_read_lock(&srcu);
+
+	/*
+	 * Prevent further calls to the MMU notifier, except for
+	 * release and after_oom_unregister.
+	 */
+	spin_lock(&subscriptions->lock);
+	hlist_for_each_entry_safe(subscription, tmp,
+				  &subscriptions->list, hlist) {
+		if (!subscription->ops->after_oom_unregister)
+			continue;
+
+		/*
+		 * after_oom_unregister and alloc_notifier are incompatible,
+		 * because there could be other references to allocated
+		 * notifiers.
+		 */
+		if (WARN_ON(subscription->ops->alloc_notifier))
+			continue;
+
+		hlist_del_init_rcu(&subscription->hlist);
+		hlist_add_head(&subscription->hlist, &oom_list);
+	}
+	spin_unlock(&subscriptions->lock);
+	hlist_for_each_entry(subscription, &oom_list, hlist)
+		if (subscription->ops->release)
+			subscription->ops->release(subscription, mm);
+
+	srcu_read_unlock(&srcu, id);
+
+	if (hlist_empty(&oom_list))
+		return;
+
+	hlist_for_each_entry_safe(subscription, tmp,
+				  &oom_list, hlist) {
+		struct mmu_notifier_oom_callback *cb;
+		/*
+		 * Remove from stack-based oom_list and reset hlist to unhashed state.
+		 * This sets subscription->hlist.pprev = NULL, so future callers of
+		 * mmu_notifier_unregister() (e.g. kvm_destroy_vm) will see
+		 * hlist_unhashed() == true and take the safe path, avoiding
+		 * use-after-free on the stack-allocated oom_list head.
+		 */
+		hlist_del_init(&subscription->hlist);
+
+		/*
+		 * GFP_ATOMIC failure is exceedingly rare. We cannot sleep
+		 * here (would reintroduce the deadlock this patch fixes)
+		 * and cannot call after_oom_unregister synchronously
+		 * without first waiting for SRCU readers. The subscriber
+		 * will not receive after_oom_unregister but cleanup will
+		 * eventually happen via the unregister path.
+		 */
+		cb = kmalloc_obj(*cb, GFP_ATOMIC);
+		if (!cb)
+			continue;
+
+		cb->subscription = subscription;
+		cb->mm = mm;
+		mmgrab(mm);
+
+		/* Schedule callback - returns immediately */
+		call_srcu(&srcu, &cb->rcu, mmu_notifier_oom_callback_fn);
+	}
+}
+
 /*
  * If no young bitflag is supported by the hardware, ->clear_flush_young can
  * unmap the address and return 1 or 0 depending if the mapping previously
@@ -1144,3 +1253,16 @@ void mmu_notifier_synchronize(void)
 	synchronize_srcu(&srcu);
 }
 EXPORT_SYMBOL_GPL(mmu_notifier_synchronize);
+
+/**
+ * mmu_notifier_barrier - Wait for all pending MMU notifier callbacks
+ *
+ * Waits for all call_srcu() callbacks scheduled by mmu_notifier_oom_enter()
+ * to complete. Used by subsystems during cleanup to prevent use-after-free
+ * when destroying structures accessed by the callbacks.
+ */
+void mmu_notifier_barrier(void)
+{
+	srcu_barrier(&srcu);
+}
+EXPORT_SYMBOL_GPL(mmu_notifier_barrier);
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 5f372f6e26fa32..66adcd03f36a8e 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -516,6 +516,9 @@ static bool __oom_reap_task_mm(struct mm_struct *mm)
 	bool ret = true;
 	MA_STATE(mas, &mm->mm_mt, ULONG_MAX, ULONG_MAX);
 
+	/* Notify MMU notifiers about the OOM event */
+	mmu_notifier_oom_enter(mm);
+
 	/*
 	 * Tell all users of get_user/copy_from_user etc... that the content
 	 * is no longer stable. No barriers really needed because unmapping
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index e44c20c049610d..79a4df8a337a2d 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -875,6 +875,24 @@ static void kvm_mmu_notifier_release(struct mmu_notifier *mn,
 	srcu_read_unlock(&kvm->srcu, idx);
 }
 
+static void kvm_mmu_notifier_after_oom_unregister(struct mmu_notifier *mn,
+						  struct mm_struct *mm)
+{
+	struct kvm *kvm;
+
+	kvm = mmu_notifier_to_kvm(mn);
+
+	/*
+	 * At this point the unregister has completed and all other callbacks
+	 * have terminated. Clean up any unbalanced invalidation counts.
+	 */
+	WARN_ON(rcuwait_active(&kvm->mn_memslots_update_rcuwait));
+	if (kvm->mn_active_invalidate_count)
+		kvm->mn_active_invalidate_count = 0;
+	else
+		WARN_ON(kvm->mmu_invalidate_in_progress);
+}
+
 static const struct mmu_notifier_ops kvm_mmu_notifier_ops = {
 	.invalidate_range_start	= kvm_mmu_notifier_invalidate_range_start,
 	.invalidate_range_end	= kvm_mmu_notifier_invalidate_range_end,
@@ -882,6 +900,7 @@ static const struct mmu_notifier_ops kvm_mmu_notifier_ops = {
 	.clear_young		= kvm_mmu_notifier_clear_young,
 	.test_young		= kvm_mmu_notifier_test_young,
 	.release		= kvm_mmu_notifier_release,
+	.after_oom_unregister	= kvm_mmu_notifier_after_oom_unregister,
 };
 
 static int kvm_init_mmu_notifier(struct kvm *kvm)
@@ -1273,7 +1292,13 @@ static void kvm_destroy_vm(struct kvm *kvm)
 		kvm->buses[i] = NULL;
 	}
 	kvm_coalesced_mmio_free(kvm);
-	mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm);
+	if (hlist_unhashed(&kvm->mmu_notifier.hlist)) {
+		/* Subscription removed by OOM. Wait for async callback. */
+		mmu_notifier_barrier();
+		mmdrop(kvm->mm);
+	} else {
+		mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm);
+	}
 	/*
 	 * At this point, pending calls to invalidate_range_start()
 	 * have completed but no more MMU notifiers will run, so

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

Args:
null

Results:
null

Tokens:
							input: 4779
							output: 21
							thoughts: 317
						

Thoughts:
**Patch Series Evaluation: A KVM and OOM Killer Integration**

Alright, let's dive into this patch series. My initial impression is that this is a potentially significant functional change touching upon the core kernel components: MMU notifiers, the OOM killer, and, importantly, KVM. The modifications span several key files – `include/linux/mmu_notifier.h`, `mm/mmu_notifier.c`, `mm/oom_kill.c`, and `virt/kvm/kvm_main.c` – which immediately flags this as something warranting a thorough review.

Specifically, it looks like a new `mmu_notifier` callback, `after_oom_unregister`, has been introduced. This implies a new interaction point within the MMU notifier framework, triggered after an OOM scenario. Additionally, the new function `mmu_notifier_oom_enter()` is called within `__oom_reap_task_mm()`, indicating a tighter integration between the OOM killer and the MMU notifier infrastructure. The inclusion of `mmu_notifier_barrier()` further suggests synchronization concerns that will need careful scrutiny.

For KVM, the patch implements `after_oom_unregister` within `kvm_main.c`. This is particularly interesting because it suggests a way for KVM to be informed after an OOM event and potentially perform cleanup or recovery operations related to its virtual machines.

Given the scope of these changes, I'm already thinking about fuzzing this thoroughly. The interplay between the OOM killer and KVM is complex, and unexpected interactions could lead to stability issues.

Now, let's move onto the configuration requirements. The relevant code in `mm/mmu_notifier.c` will naturally only be compiled if `CONFIG_MMU_NOTIFIER` is enabled. The KVM-specific code in `virt/kvm/kvm_main.c` obviously requires `CONFIG_KVM`. The code in `mm/oom_kill.c`, however, seems to always be compiled (or perhaps has some implicit dependency on `CONFIG_MMU`). Let's double check that assumptions are correct; I'll use `grepper` to see if there are any subtle configurations that we need to be aware of. I'll focus on `CONFIG_MMU_NOTIFIER` and `CONFIG_KVM` for the initial search to see if any other dependencies come up.



4/2 2026/07/23 15:29 tool grepper
0m Args:
{
  "Expression": "CONFIG_MMU_NOTIFIER"
}

Results:
{
  "Output": "drivers/dma-buf/dma-resv.c=775=static int __init dma_resv_lockdep(void)\n--\ndrivers/dma-buf/dma-resv.c-800-\ti_mmap_unlock_write(\u0026mapping);\ndrivers/dma-buf/dma-resv.c:801:#ifdef CONFIG_MMU_NOTIFIER\ndrivers/dma-buf/dma-resv.c-802-\tlock_map_acquire(\u0026__mmu_notifier_invalidate_range_start_map);\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_object.h-34-\ndrivers/gpu/drm/amd/amdgpu/amdgpu_object.h:35:#ifdef CONFIG_MMU_NOTIFIER\ndrivers/gpu/drm/amd/amdgpu/amdgpu_object.h-36-#include \u003clinux/mmu_notifier.h\u003e\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_object.h=103=struct amdgpu_bo {\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_object.h-116-\ndrivers/gpu/drm/amd/amdgpu/amdgpu_object.h:117:#ifdef CONFIG_MMU_NOTIFIER\ndrivers/gpu/drm/amd/amdgpu/amdgpu_object.h-118-\tstruct mmu_interval_notifier\tnotifier;\n--\ndrivers/gpu/drm/i915/Kconfig=114=config DRM_I915_USERPTR\n--\ndrivers/gpu/drm/i915/Kconfig-119-\thelp\ndrivers/gpu/drm/i915/Kconfig:120:\t  This option selects CONFIG_MMU_NOTIFIER if it isn't already\ndrivers/gpu/drm/i915/Kconfig-121-\t  selected to enabled full userptr support.\n--\ndrivers/gpu/drm/i915/gem/i915_gem_execbuffer.c=2080=static int eb_move_to_gpu(struct i915_execbuffer *eb)\n--\ndrivers/gpu/drm/i915/gem/i915_gem_execbuffer.c-2144-\ndrivers/gpu/drm/i915/gem/i915_gem_execbuffer.c:2145:#ifdef CONFIG_MMU_NOTIFIER\ndrivers/gpu/drm/i915/gem/i915_gem_execbuffer.c-2146-\tif (!err \u0026\u0026 (eb-\u003eargs-\u003eflags \u0026 __EXEC_USERPTR_USED)) {\n--\ndrivers/gpu/drm/i915/gem/i915_gem_object.h=853=void __shmem_writeback(size_t size, struct address_space *mapping);\ndrivers/gpu/drm/i915/gem/i915_gem_object.h-854-\ndrivers/gpu/drm/i915/gem/i915_gem_object.h:855:#ifdef CONFIG_MMU_NOTIFIER\ndrivers/gpu/drm/i915/gem/i915_gem_object.h-856-static inline bool\n--\ndrivers/gpu/drm/i915/gem/i915_gem_object_types.h=239=struct drm_i915_gem_object {\n--\ndrivers/gpu/drm/i915/gem/i915_gem_object_types.h-713-\tunion {\ndrivers/gpu/drm/i915/gem/i915_gem_object_types.h:714:#ifdef CONFIG_MMU_NOTIFIER\ndrivers/gpu/drm/i915/gem/i915_gem_object_types.h-715-\t\tstruct i915_gem_userptr {\n--\ndrivers/gpu/drm/i915/gem/i915_gem_userptr.c-47-\ndrivers/gpu/drm/i915/gem/i915_gem_userptr.c:48:#ifdef CONFIG_MMU_NOTIFIER\ndrivers/gpu/drm/i915/gem/i915_gem_userptr.c-49-\n--\ndrivers/gpu/drm/i915/gem/i915_gem_userptr.c=462=i915_gem_userptr_ioctl(struct drm_device *dev,\n--\ndrivers/gpu/drm/i915/gem/i915_gem_userptr.c-518-\ndrivers/gpu/drm/i915/gem/i915_gem_userptr.c:519:#ifdef CONFIG_MMU_NOTIFIER\ndrivers/gpu/drm/i915/gem/i915_gem_userptr.c-520-\tobj = i915_gem_object_alloc();\n--\ndrivers/gpu/drm/radeon/Kconfig=38=config DRM_RADEON_USERPTR\n--\ndrivers/gpu/drm/radeon/Kconfig-42-\thelp\ndrivers/gpu/drm/radeon/Kconfig:43:\t  This option selects CONFIG_MMU_NOTIFIER if it isn't already\ndrivers/gpu/drm/radeon/Kconfig-44-\t  selected to enabled full userptr support.\n--\ndrivers/gpu/drm/radeon/Makefile=34=radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \\\n--\ndrivers/gpu/drm/radeon/Makefile-53-\ndrivers/gpu/drm/radeon/Makefile:54:radeon-$(CONFIG_MMU_NOTIFIER) += radeon_mn.o\ndrivers/gpu/drm/radeon/Makefile-55-\n--\ndrivers/gpu/drm/radeon/radeon.h-71-\ndrivers/gpu/drm/radeon/radeon.h:72:#ifdef CONFIG_MMU_NOTIFIER\ndrivers/gpu/drm/radeon/radeon.h-73-#include \u003clinux/mmu_notifier.h\u003e\n--\ndrivers/gpu/drm/radeon/radeon.h=483=struct radeon_bo {\n--\ndrivers/gpu/drm/radeon/radeon.h-506-\ndrivers/gpu/drm/radeon/radeon.h:507:#ifdef CONFIG_MMU_NOTIFIER\ndrivers/gpu/drm/radeon/radeon.h-508-\tstruct mmu_interval_notifier\tnotifier;\n--\ndrivers/gpu/drm/radeon/radeon.h=1776=void radeon_test_syncing(struct radeon_device *rdev);\n--\ndrivers/gpu/drm/radeon/radeon.h-1780- */\ndrivers/gpu/drm/radeon/radeon.h:1781:#if defined(CONFIG_MMU_NOTIFIER)\ndrivers/gpu/drm/radeon/radeon.h-1782-int radeon_mn_register(struct radeon_bo *bo, unsigned long addr);\n--\ninclude/linux/mm_types.h=1160=struct mm_struct {\n--\ninclude/linux/mm_types.h-1328-\t\tstruct file __rcu *exe_file;\ninclude/linux/mm_types.h:1329:#ifdef CONFIG_MMU_NOTIFIER\ninclude/linux/mm_types.h-1330-\t\tstruct mmu_notifier_subscriptions *notifier_subscriptions;\n--\ninclude/linux/mmu_notifier.h=298=struct mmu_interval_notifier {\n--\ninclude/linux/mmu_notifier.h-305-\ninclude/linux/mmu_notifier.h:306:#ifdef CONFIG_MMU_NOTIFIER\ninclude/linux/mmu_notifier.h-307-\n--\ninclude/linux/mmu_notifier.h=557=static inline void mmu_notifier_range_init_owner(\n--\ninclude/linux/mmu_notifier.h-566-\ninclude/linux/mmu_notifier.h:567:#else /* CONFIG_MMU_NOTIFIER */\ninclude/linux/mmu_notifier.h-568-\n--\ninclude/linux/mmu_notifier.h=656=static inline void mmu_notifier_oom_enter(struct mm_struct *mm)\n--\ninclude/linux/mmu_notifier.h-659-\ninclude/linux/mmu_notifier.h:660:#endif /* CONFIG_MMU_NOTIFIER */\ninclude/linux/mmu_notifier.h-661-\n--\nmm/Makefile=88=obj-$(CONFIG_SPARSEMEM_VMEMMAP) += sparse-vmemmap.o\nmm/Makefile:89:obj-$(CONFIG_MMU_NOTIFIER) += mmu_notifier.o\nmm/Makefile-90-obj-$(CONFIG_KSM) += ksm.o\n--\nmm/debug.c=175=void dump_mm(const struct mm_struct *mm)\n--\nmm/debug.c-192-\t\t\"exe_file %px\\n\"\nmm/debug.c:193:#ifdef CONFIG_MMU_NOTIFIER\nmm/debug.c-194-\t\t\"notifier_subscriptions %px\\n\"\n--\nmm/debug.c-221-\t\tmm-\u003eexe_file,\nmm/debug.c:222:#ifdef CONFIG_MMU_NOTIFIER\nmm/debug.c-223-\t\tmm-\u003enotifier_subscriptions,\n--\nmm/internal.h=1880=static inline void maybe_rmap_unlock_action(struct vm_area_struct *vma,\n--\nmm/internal.h-1893-\nmm/internal.h:1894:#ifdef CONFIG_MMU_NOTIFIER\nmm/internal.h-1895-static inline bool clear_flush_young_ptes_notify(struct vm_area_struct *vma,\n--\nmm/internal.h=1926=static inline bool pmdp_test_and_clear_young_notify(struct vm_area_struct *vma,\n--\nmm/internal.h-1935-\nmm/internal.h:1936:#else /* CONFIG_MMU_NOTIFIER */\nmm/internal.h-1937-\n--\nmm/internal.h-1942-\nmm/internal.h:1943:#endif /* CONFIG_MMU_NOTIFIER */\nmm/internal.h-1944-\n--\nmm/page_alloc.c=4337=void fs_reclaim_acquire(gfp_t gfp_mask)\n--\nmm/page_alloc.c-4344-\nmm/page_alloc.c:4345:#ifdef CONFIG_MMU_NOTIFIER\nmm/page_alloc.c-4346-\t\tlock_map_acquire(\u0026__mmu_notifier_invalidate_range_start_map);\n"
}

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

Args:
null

Results:
null

Tokens:
							input: 8311
							output: 18
							thoughts: 34
						

Thoughts:
Okay, here's my take on those thoughts, framed as an expert's internal monologue:

**Investigating the Role of `CONFIG_MMU_NOTIFIER`**

Right, let's see... I'm noticing `CONFIG_MMU_NOTIFIER` is a dependency, or at least used, by quite a few significant drivers. DRM, KVM... that's a key area to be aware of. I need to understand this better. Now, what's driving this? Let's drill down into `CONFIG_KVM` specifically and figure out why KVM needs this. It's almost certain to be related to memory management and virtualization. Let me examine the KVM configuration options and related code. I need to understand how the MMU notifier plays into memory management for virtual machines and what the implications are for performance and stability. Okay, let's start digging.



6/2 2026/07/23 15:29 tool grepper
0m Args:
{
  "Expression": "CONFIG_KVM"
}

Results:
{
  "Output": "\nFull output is too long, showing 500 out of 3375 lines.\nUse more precise expression if possible.\n\narch/arm64/Kbuild=6=obj-y\t\t\t+= kernel/ mm/ net/\narch/arm64/Kbuild:7:obj-$(CONFIG_KVM)\t+= kvm/\narch/arm64/Kbuild-8-obj-$(CONFIG_XEN)\t+= xen/\n--\narch/arm64/configs/defconfig=124=CONFIG_VIRTUALIZATION=y\narch/arm64/configs/defconfig:125:CONFIG_KVM=y\narch/arm64/configs/defconfig-126-CONFIG_JUMP_LABEL=y\n--\narch/arm64/include/asm/fixmap.h=36=enum fixed_addresses {\n--\narch/arm64/include/asm/fixmap.h-50-\narch/arm64/include/asm/fixmap.h:51:#ifdef CONFIG_KVM\narch/arm64/include/asm/fixmap.h-52-\t/* One slot per CPU, mapping the guest's VNCR page at EL2. */\n--\narch/arm64/include/asm/kvm_host.h=68=enum kvm_mode {\n--\narch/arm64/include/asm/kvm_host.h-73-};\narch/arm64/include/asm/kvm_host.h:74:#ifdef CONFIG_KVM\narch/arm64/include/asm/kvm_host.h-75-enum kvm_mode kvm_get_mode(void);\n--\narch/arm64/include/asm/kvm_host.h=1464=static inline bool kvm_pmu_counter_deferred(struct perf_event_attr *attr)\n--\narch/arm64/include/asm/kvm_host.h-1468-\narch/arm64/include/asm/kvm_host.h:1469:#ifdef CONFIG_KVM\narch/arm64/include/asm/kvm_host.h-1470-void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr);\n--\narch/arm64/include/asm/kvm_host.h=1531=int kvm_trng_call(struct kvm_vcpu *vcpu);\narch/arm64/include/asm/kvm_host.h:1532:#ifdef CONFIG_KVM\narch/arm64/include/asm/kvm_host.h-1533-extern phys_addr_t hyp_mem_base;\n--\narch/arm64/include/asm/virt.h=91=static inline bool is_pkvm_initialized(void)\narch/arm64/include/asm/virt.h-92-{\narch/arm64/include/asm/virt.h:93:\treturn IS_ENABLED(CONFIG_KVM) \u0026\u0026\narch/arm64/include/asm/virt.h-94-\t       static_branch_likely(\u0026kvm_protected_mode_initialized);\n--\narch/arm64/include/asm/virt.h-96-\narch/arm64/include/asm/virt.h:97:#ifdef CONFIG_KVM\narch/arm64/include/asm/virt.h-98-bool pkvm_force_reclaim_guest_page(phys_addr_t phys);\n--\narch/arm64/kernel/asm-offsets.c=27=int main(void)\n--\narch/arm64/kernel/asm-offsets.c-103-  BLANK();\narch/arm64/kernel/asm-offsets.c:104:#ifdef CONFIG_KVM\narch/arm64/kernel/asm-offsets.c-105-  DEFINE(VCPU_CONTEXT,\t\toffsetof(struct kvm_vcpu, arch.ctxt));\n--\narch/arm64/kernel/cpufeature.c=2433=static void elf_hwcap_fixup(void)\n--\narch/arm64/kernel/cpufeature.c-2440-\narch/arm64/kernel/cpufeature.c:2441:#ifdef CONFIG_KVM\narch/arm64/kernel/cpufeature.c-2442-static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, int __unused)\n--\narch/arm64/kernel/cpufeature.c-2445-}\narch/arm64/kernel/cpufeature.c:2446:#endif /* CONFIG_KVM */\narch/arm64/kernel/cpufeature.c-2447-\n--\narch/arm64/kernel/cpufeature.c=2543=static const struct arm64_cpu_capabilities arm64_features[] = {\n--\narch/arm64/kernel/cpufeature.c-2628-\t},\narch/arm64/kernel/cpufeature.c:2629:#ifdef CONFIG_KVM\narch/arm64/kernel/cpufeature.c-2630-\t{\n--\narch/arm64/kernel/cpufeature.c=3759=static void verify_hyp_capabilities(void)\n--\narch/arm64/kernel/cpufeature.c-3764-\narch/arm64/kernel/cpufeature.c:3765:\tif (!IS_ENABLED(CONFIG_KVM))\narch/arm64/kernel/cpufeature.c-3766-\t\treturn;\n--\narch/arm64/kernel/fpsimd.c=1050=int vec_verify_vq_map(enum vec_type type)\n--\narch/arm64/kernel/fpsimd.c-1064-\narch/arm64/kernel/fpsimd.c:1065:\tif (!IS_ENABLED(CONFIG_KVM) || !is_hyp_mode_available())\narch/arm64/kernel/fpsimd.c-1066-\t\treturn 0;\n--\narch/arm64/kernel/image-vars.h=72=PI_EXPORT_SYM(_data);\narch/arm64/kernel/image-vars.h-73-\narch/arm64/kernel/image-vars.h:74:#ifdef CONFIG_KVM\narch/arm64/kernel/image-vars.h-75-\n--\narch/arm64/kernel/image-vars.h=147=KVM_NVHE_ALIAS(kvm_protected_mode_initialized);\narch/arm64/kernel/image-vars.h-148-\narch/arm64/kernel/image-vars.h:149:#endif /* CONFIG_KVM */\narch/arm64/kernel/image-vars.h-150-\n--\narch/arm64/kernel/smp.c=423=static void __init hyp_mode_check(void)\n--\narch/arm64/kernel/smp.c-431-\t\tpr_info(\"CPU: All CPU(s) started at EL1\\n\");\narch/arm64/kernel/smp.c:432:\tif (IS_ENABLED(CONFIG_KVM) \u0026\u0026 !is_kernel_in_hyp_mode()) {\narch/arm64/kernel/smp.c-433-\t\tkvm_compute_layout();\n--\narch/arm64/kernel/vmlinux.lds.S-8-#include \u003casm/hyp_image.h\u003e\narch/arm64/kernel/vmlinux.lds.S:9:#ifdef CONFIG_KVM\narch/arm64/kernel/vmlinux.lds.S-10-#define HYPERVISOR_EXTABLE\t\t\t\t\t\\\n--\narch/arm64/kernel/vmlinux.lds.S-71-#define SBSS_ALIGN\t\t\tPAGE_SIZE\narch/arm64/kernel/vmlinux.lds.S:72:#else /* CONFIG_KVM */\narch/arm64/kernel/vmlinux.lds.S-73-#define HYPERVISOR_EXTABLE\n--\narch/arm64/kernel/vmlinux.lds.S=411=ASSERT((__entry_tramp_text_end - __entry_tramp_text_start) \u003c= 3*PAGE_SIZE,\n--\narch/arm64/kernel/vmlinux.lds.S-413-#endif\narch/arm64/kernel/vmlinux.lds.S:414:#ifdef CONFIG_KVM\narch/arm64/kernel/vmlinux.lds.S-415-ASSERT(__hyp_bss_start == __bss_start, \"HYP and Host BSS are misaligned\")\n--\narch/arm64/kvm/Makefile=8=include $(srctree)/virt/kvm/Makefile.kvm\narch/arm64/kvm/Makefile-9-\narch/arm64/kvm/Makefile:10:obj-$(CONFIG_KVM) += kvm.o\narch/arm64/kvm/Makefile:11:obj-$(CONFIG_KVM) += hyp/\narch/arm64/kvm/Makefile-12-\n--\narch/arm64/kvm/hyp/Makefile=8=subdir-ccflags-y := -I$(incdir)\narch/arm64/kvm/hyp/Makefile-9-\narch/arm64/kvm/hyp/Makefile:10:obj-$(CONFIG_KVM) += vhe/ nvhe/ pgtable.o\n--\narch/arm64/kvm/hyp/nvhe/host.S=168=SYM_FUNC_END(__host_hvc)\n--\narch/arm64/kvm/hyp/nvhe/host.S-228- *\narch/arm64/kvm/hyp/nvhe/host.S:229: * CONFIG_KVM_INDIRECT_VECTORS is not applied to the host vectors because the\narch/arm64/kvm/hyp/nvhe/host.S-230- * host knows about the EL2 vectors already, and there is no point in hiding\n--\narch/arm64/mm/init.c=193=void __init arm64_memblock_init(void)\n--\narch/arm64/mm/init.c-204-\t */\narch/arm64/mm/init.c:205:\tif (IS_ENABLED(CONFIG_KVM) \u0026\u0026 vabits_actual == 52 \u0026\u0026\narch/arm64/mm/init.c-206-\t    is_hyp_mode_available() \u0026\u0026 !is_kernel_in_hyp_mode()) {\n--\narch/loongarch/Kbuild=4=obj-y += vdso/\narch/loongarch/Kbuild-5-\narch/loongarch/Kbuild:6:obj-$(subst m,y,$(CONFIG_KVM)) += kvm/\narch/loongarch/Kbuild-7-\n--\narch/loongarch/configs/loongson64_defconfig=83=CONFIG_VIRTUALIZATION=y\narch/loongarch/configs/loongson64_defconfig:84:CONFIG_KVM=m\narch/loongarch/configs/loongson64_defconfig-85-CONFIG_JUMP_LABEL=y\n--\narch/loongarch/kvm/Makefile=6=include $(srctree)/virt/kvm/Makefile.kvm\narch/loongarch/kvm/Makefile-7-\narch/loongarch/kvm/Makefile:8:obj-$(CONFIG_KVM) += kvm.o\narch/loongarch/kvm/Makefile-9-\n--\narch/mips/Kbuild=18=obj-y += vdso/\narch/mips/Kbuild-19-\narch/mips/Kbuild:20:ifdef CONFIG_KVM\narch/mips/Kbuild-21-obj-y += kvm/\n--\narch/mips/configs/loongson3_defconfig=39=CONFIG_VIRTUALIZATION=y\narch/mips/configs/loongson3_defconfig:40:CONFIG_KVM=m\narch/mips/configs/loongson3_defconfig-41-CONFIG_KPROBES=y\n--\narch/mips/configs/malta_kvm_defconfig=17=CONFIG_VIRTUALIZATION=y\narch/mips/configs/malta_kvm_defconfig:18:CONFIG_KVM=m\narch/mips/configs/malta_kvm_defconfig:19:CONFIG_KVM_MIPS_DEBUG_COP0_COUNTERS=y\narch/mips/configs/malta_kvm_defconfig-20-CONFIG_VHOST_NET=m\n--\narch/mips/include/asm/kvm_host.h=188=struct mips_coproc {\narch/mips/include/asm/kvm_host.h-189-\tunsigned long reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL];\narch/mips/include/asm/kvm_host.h:190:#ifdef CONFIG_KVM_MIPS_DEBUG_COP0_COUNTERS\narch/mips/include/asm/kvm_host.h-191-\tunsigned long stat[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL];\n--\narch/mips/kvm/Makefile=18=kvm-y\t\t+= vz.o\narch/mips/kvm/Makefile:19:obj-$(CONFIG_KVM)\t+= kvm.o\narch/mips/kvm/Makefile-20-obj-y\t\t\t+= tlb.o\n--\narch/mips/kvm/stats.c=49=void kvm_mips_dump_stats(struct kvm_vcpu *vcpu)\narch/mips/kvm/stats.c-50-{\narch/mips/kvm/stats.c:51:#ifdef CONFIG_KVM_MIPS_DEBUG_COP0_COUNTERS\narch/mips/kvm/stats.c-52-\tint i, j;\n--\narch/mips/kvm/vz.c=875=static enum emulation_result kvm_vz_gpsi_cop0(union mips_instruction inst,\n--\narch/mips/kvm/vz.c-909-\t\tcase mfc_op:\narch/mips/kvm/vz.c:910:#ifdef CONFIG_KVM_MIPS_DEBUG_COP0_COUNTERS\narch/mips/kvm/vz.c-911-\t\t\tcop0-\u003estat[rd][sel]++;\n--\narch/mips/kvm/vz.c-975-\t\tcase mtc_op:\narch/mips/kvm/vz.c:976:#ifdef CONFIG_KVM_MIPS_DEBUG_COP0_COUNTERS\narch/mips/kvm/vz.c-977-\t\t\tcop0-\u003estat[rd][sel]++;\n--\narch/powerpc/Kbuild=14=obj-$(CONFIG_XMON) += xmon/\narch/powerpc/Kbuild:15:obj-$(CONFIG_KVM)  += kvm/\narch/powerpc/Kbuild-16-\n--\narch/powerpc/configs/guest.config=7=CONFIG_VIRTIO_PCI=y\narch/powerpc/configs/guest.config:8:CONFIG_KVM_GUEST=y\narch/powerpc/configs/guest.config-9-CONFIG_EPAPR_PARAVIRT=y\n--\narch/powerpc/configs/mvme5100_defconfig=20=CONFIG_MVME5100=y\narch/powerpc/configs/mvme5100_defconfig:21:CONFIG_KVM_GUEST=y\narch/powerpc/configs/mvme5100_defconfig-22-CONFIG_HZ_100=y\n--\narch/powerpc/configs/powernv_defconfig=330=CONFIG_VIRTUALIZATION=y\narch/powerpc/configs/powernv_defconfig:331:CONFIG_KVM_BOOK3S_64=m\narch/powerpc/configs/powernv_defconfig:332:CONFIG_KVM_BOOK3S_64_HV=m\narch/powerpc/configs/powernv_defconfig-333-CONFIG_VHOST_NET=m\n--\narch/powerpc/configs/ppc64_defconfig=69=CONFIG_VIRTUALIZATION=y\narch/powerpc/configs/ppc64_defconfig:70:CONFIG_KVM_BOOK3S_64=m\narch/powerpc/configs/ppc64_defconfig:71:CONFIG_KVM_BOOK3S_64_HV=m\narch/powerpc/configs/ppc64_defconfig-72-CONFIG_KPROBES=y\n--\narch/powerpc/include/asm/hmi.h-11-\narch/powerpc/include/asm/hmi.h:12:#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE\narch/powerpc/include/asm/hmi.h-13-\n--\narch/powerpc/include/asm/kvm_book3s.h=320=void kvmppc_giveup_fac(struct kvm_vcpu *vcpu, ulong fac);\n--\narch/powerpc/include/asm/kvm_book3s.h-322-\narch/powerpc/include/asm/kvm_book3s.h:323:#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE\narch/powerpc/include/asm/kvm_book3s.h-324-\n--\narch/powerpc/include/asm/kvm_book3s.h=387=static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu)\n--\narch/powerpc/include/asm/kvm_book3s.h-393-\narch/powerpc/include/asm/kvm_book3s.h:394:#ifdef CONFIG_KVM_BOOK3S_32_HANDLER\narch/powerpc/include/asm/kvm_book3s.h-395-#include \u003casm/kvm_book3s_32.h\u003e\narch/powerpc/include/asm/kvm_book3s.h-396-#endif\narch/powerpc/include/asm/kvm_book3s.h:397:#ifdef CONFIG_KVM_BOOK3S_64_HANDLER\narch/powerpc/include/asm/kvm_book3s.h-398-#include \u003casm/kvm_book3s_64.h\u003e\n--\narch/powerpc/include/asm/kvm_book3s_64.h=101=int kvmhv_nested_next_lpid(struct kvm *kvm, int lpid);\n--\narch/powerpc/include/asm/kvm_book3s_64.h-110-\narch/powerpc/include/asm/kvm_book3s_64.h:111:#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE\narch/powerpc/include/asm/kvm_book3s_64.h-112-static inline struct kvmppc_book3s_shadow_vcpu *svcpu_get(struct kvm_vcpu *vcpu)\n--\narch/powerpc/include/asm/kvm_book3s_64.h=118=static inline void svcpu_put(struct kvmppc_book3s_shadow_vcpu *svcpu)\n--\narch/powerpc/include/asm/kvm_book3s_64.h-123-\narch/powerpc/include/asm/kvm_book3s_64.h:124:#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE\narch/powerpc/include/asm/kvm_book3s_64.h-125-\n--\narch/powerpc/include/asm/kvm_book3s_64.h=514=static inline int is_vrma_hpte(unsigned long hpte_v)\n--\narch/powerpc/include/asm/kvm_book3s_64.h-519-\narch/powerpc/include/asm/kvm_book3s_64.h:520:#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE\narch/powerpc/include/asm/kvm_book3s_64.h-521-/*\n--\narch/powerpc/include/asm/kvm_book3s_64.h=696=u64 kvmhv_get_l2_runtime_agg_vcpu(void);\narch/powerpc/include/asm/kvm_book3s_64.h-697-\narch/powerpc/include/asm/kvm_book3s_64.h:698:#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */\narch/powerpc/include/asm/kvm_book3s_64.h-699-\n--\narch/powerpc/include/asm/kvm_book3s_asm.h-24-\narch/powerpc/include/asm/kvm_book3s_asm.h:25:#ifdef CONFIG_KVM_BOOK3S_HANDLER\narch/powerpc/include/asm/kvm_book3s_asm.h-26-\n--\narch/powerpc/include/asm/kvm_book3s_asm.h=49=kvmppc_resume_\\intno:\n--\narch/powerpc/include/asm/kvm_book3s_asm.h-58-\narch/powerpc/include/asm/kvm_book3s_asm.h:59:#endif /* CONFIG_KVM_BOOK3S_HANDLER */\narch/powerpc/include/asm/kvm_book3s_asm.h-60-\n--\narch/powerpc/include/asm/kvm_book3s_asm.h=83=struct kvmppc_host_state {\n--\narch/powerpc/include/asm/kvm_book3s_asm.h-94-\narch/powerpc/include/asm/kvm_book3s_asm.h:95:#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE\narch/powerpc/include/asm/kvm_book3s_asm.h-96-\tu8 hwthread_req;\n--\narch/powerpc/include/asm/kvm_booke.h=109=static inline bool kvmppc_supports_magic_page(struct kvm_vcpu *vcpu)\n--\narch/powerpc/include/asm/kvm_booke.h-111-\t/* Magic page is only supported on e500v2 */\narch/powerpc/include/asm/kvm_booke.h:112:#ifdef CONFIG_KVM_E500V2\narch/powerpc/include/asm/kvm_booke.h-113-\treturn true;\n--\narch/powerpc/include/asm/kvm_booke_hv_asm.h-56-.macro DO_KVM intno srr1\narch/powerpc/include/asm/kvm_booke_hv_asm.h:57:#ifdef CONFIG_KVM_BOOKE_HV\narch/powerpc/include/asm/kvm_booke_hv_asm.h-58-BEGIN_FTR_SECTION\n--\narch/powerpc/include/asm/kvm_guest.h-8-\narch/powerpc/include/asm/kvm_guest.h:9:#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_KVM_GUEST)\narch/powerpc/include/asm/kvm_guest.h-10-#include \u003clinux/jump_label.h\u003e\n--\narch/powerpc/include/asm/kvm_host.h-36-\narch/powerpc/include/asm/kvm_host.h:37:#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE\narch/powerpc/include/asm/kvm_host.h-38-#include \u003casm/kvm_book3s_asm.h\u003e\t\t/* for MAX_SMT_THREADS */\n--\narch/powerpc/include/asm/kvm_host.h-48-#define KVM_MAX_VCPU_IDS\tKVM_MAX_VCPUS\narch/powerpc/include/asm/kvm_host.h:49:#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */\narch/powerpc/include/asm/kvm_host.h-50-\n--\narch/powerpc/include/asm/kvm_host.h=253=struct kvm_arch_memory_slot {\narch/powerpc/include/asm/kvm_host.h:254:#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE\narch/powerpc/include/asm/kvm_host.h-255-\tunsigned long *rmap;\narch/powerpc/include/asm/kvm_host.h:256:#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */\narch/powerpc/include/asm/kvm_host.h-257-};\n--\narch/powerpc/include/asm/kvm_host.h=277=struct kvm_arch {\n--\narch/powerpc/include/asm/kvm_host.h-280-\tunsigned int emul_smt_mode;\t/* emualted SMT mode, on P9 */\narch/powerpc/include/asm/kvm_host.h:281:#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE\narch/powerpc/include/asm/kvm_host.h-282-\tunsigned int tlb_sets;\n--\narch/powerpc/include/asm/kvm_host.h-304-\tstruct kvm_resize_hpt *resize_hpt; /* protected by kvm-\u003elock */\narch/powerpc/include/asm/kvm_host.h:305:#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */\narch/powerpc/include/asm/kvm_host.h:306:#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE\narch/powerpc/include/asm/kvm_host.h-307-\tstruct mutex hpt_mutex;\n--\narch/powerpc/include/asm/kvm_host.h-314-#endif\narch/powerpc/include/asm/kvm_host.h:315:#ifdef CONFIG_KVM_MPIC\narch/powerpc/include/asm/kvm_host.h-316-\tstruct openpic *mpic;\narch/powerpc/include/asm/kvm_host.h-317-#endif\narch/powerpc/include/asm/kvm_host.h:318:#ifdef CONFIG_KVM_XICS\narch/powerpc/include/asm/kvm_host.h-319-\tstruct kvmppc_xics *xics;\n--\narch/powerpc/include/asm/kvm_host.h-328-\tstruct kvmppc_ops *kvm_ops;\narch/powerpc/include/asm/kvm_host.h:329:#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE\narch/powerpc/include/asm/kvm_host.h-330-\tstruct mutex uvmem_lock;\n--\narch/powerpc/include/asm/kvm_host.h=528=struct kvm_vcpu_arch {\n--\narch/powerpc/include/asm/kvm_host.h-559-\narch/powerpc/include/asm/kvm_host.h:560:#ifdef CONFIG_KVM_BOOKE_HV\narch/powerpc/include/asm/kvm_host.h-561-\tu32 host_mas4;\n--\narch/powerpc/include/asm/kvm_host.h-570-#if defined(CONFIG_BOOKE)\narch/powerpc/include/asm/kvm_host.h:571:#if defined(CONFIG_KVM_BOOKE_HV) || defined(CONFIG_64BIT)\narch/powerpc/include/asm/kvm_host.h-572-\tu32 epcr;\n--\narch/powerpc/include/asm/kvm_host.h-692-\narch/powerpc/include/asm/kvm_host.h:693:#ifdef CONFIG_KVM_EXIT_TIMING\narch/powerpc/include/asm/kvm_host.h-694-\tstruct mutex exit_timing_lock;\n--\narch/powerpc/include/asm/kvm_host.h-795-\tstruct kvm_vcpu_arch_shared *shared;\narch/powerpc/include/asm/kvm_host.h:796:#if defined(CONFIG_PPC_BOOK3S_64) \u0026\u0026 defined(CONFIG_KVM_BOOK3S_PR_POSSIBLE)\narch/powerpc/include/asm/kvm_host.h-797-\tbool shared_big_endian;\n--\narch/powerpc/include/asm/kvm_host.h-805-\tstruct openpic *mpic;\t/* KVM_IRQ_MPIC */\narch/powerpc/include/asm/kvm_host.h:806:#ifdef CONFIG_KVM_XICS\narch/powerpc/include/asm/kvm_host.h-807-\tstruct kvmppc_icp *icp; /* XICS presentation controller */\n--\narch/powerpc/include/asm/kvm_host.h-816-\narch/powerpc/include/asm/kvm_host.h:817:#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE\narch/powerpc/include/asm/kvm_host.h-818-\tstruct kvm_vcpu_arch_shared shregs;\n--\narch/powerpc/include/asm/kvm_host.h-854-\narch/powerpc/include/asm/kvm_host.h:855:#ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING\narch/powerpc/include/asm/kvm_host.h-856-\tstruct kvmhv_tb_accumulator *cur_activity;\t/* What we're timing */\narch/powerpc/include/asm/kvm_host.h-857-\tu64\tcur_tb_start;\t\t\t/* when it started */\narch/powerpc/include/asm/kvm_host.h:858:#ifdef CONFIG_KVM_BOOK3S_HV_P9_TIMING\narch/powerpc/include/asm/kvm_host.h-859-\tstruct kvmhv_tb_accumulator vcpu_entry;\n--\narch/powerpc/include/asm/kvm_host.h-872-#endif\narch/powerpc/include/asm/kvm_host.h:873:#endif /* CONFIG_KVM_BOOK3S_HV_EXIT_TIMING */\narch/powerpc/include/asm/kvm_host.h:874:#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE\narch/powerpc/include/asm/kvm_host.h-875-\tu64 l1_to_l2_cs;\n--\narch/powerpc/include/asm/kvm_para.h=15=static inline int kvm_para_available(void)\narch/powerpc/include/asm/kvm_para.h-16-{\narch/powerpc/include/asm/kvm_para.h:17:\treturn IS_ENABLED(CONFIG_KVM_GUEST) \u0026\u0026 is_kvm_guest();\narch/powerpc/include/asm/kvm_para.h-18-}\n--\narch/powerpc/include/asm/kvm_ppc.h-25-#endif\narch/powerpc/include/asm/kvm_ppc.h:26:#ifdef CONFIG_KVM_BOOK3S_64_HANDLER\narch/powerpc/include/asm/kvm_ppc.h-27-#include \u003casm/paca.h\u003e\n--\narch/powerpc/include/asm/kvm_ppc.h=442=struct openpic;\narch/powerpc/include/asm/kvm_ppc.h-443-\narch/powerpc/include/asm/kvm_ppc.h:444:#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE\narch/powerpc/include/asm/kvm_ppc.h-445-extern void kvm_cma_reserve(void) __init;\n--\narch/powerpc/include/asm/kvm_ppc.h=648=static inline int kvmhv_nestedv2_cached_reload(struct kvm_vcpu *vcpu, u16 iden)\n--\narch/powerpc/include/asm/kvm_ppc.h-654-\narch/powerpc/include/asm/kvm_ppc.h:655:#ifdef CONFIG_KVM_XICS\narch/powerpc/include/asm/kvm_ppc.h-656-static inline int kvmppc_xics_enabled(struct kvm_vcpu *vcpu)\n--\narch/powerpc/include/asm/kvm_ppc.h=708=static inline int kvmppc_xive_xics_hcall(struct kvm_vcpu *vcpu, u32 req)\n--\narch/powerpc/include/asm/kvm_ppc.h-711-\narch/powerpc/include/asm/kvm_ppc.h:712:#ifdef CONFIG_KVM_XIVE\narch/powerpc/include/asm/kvm_ppc.h-713-/*\n--\narch/powerpc/include/asm/kvm_ppc.h=790=static inline int kvmppc_xive_native_set_vp(struct kvm_vcpu *vcpu,\n--\narch/powerpc/include/asm/kvm_ppc.h-793-\narch/powerpc/include/asm/kvm_ppc.h:794:#endif /* CONFIG_KVM_XIVE */\narch/powerpc/include/asm/kvm_ppc.h-795-\narch/powerpc/include/asm/kvm_ppc.h:796:#if defined(CONFIG_PPC_POWERNV) \u0026\u0026 defined(CONFIG_KVM_BOOK3S_64_HANDLER)\narch/powerpc/include/asm/kvm_ppc.h-797-static inline bool xics_on_xive(void)\n--\narch/powerpc/include/asm/kvm_ppc.h=875=static inline unsigned long kvmppc_get_epr(struct kvm_vcpu *vcpu)\narch/powerpc/include/asm/kvm_ppc.h-876-{\narch/powerpc/include/asm/kvm_ppc.h:877:#ifdef CONFIG_KVM_BOOKE_HV\narch/powerpc/include/asm/kvm_ppc.h-878-\treturn mfspr(SPRN_GEPR);\n--\narch/powerpc/include/asm/kvm_ppc.h=886=static inline void kvmppc_set_epr(struct kvm_vcpu *vcpu, u32 epr)\narch/powerpc/include/asm/kvm_ppc.h-887-{\narch/powerpc/include/asm/kvm_ppc.h:888:#ifdef CONFIG_KVM_BOOKE_HV\narch/powerpc/include/asm/kvm_ppc.h-889-\tmtspr(SPRN_GEPR, epr);\n--\narch/powerpc/include/asm/kvm_ppc.h-894-\narch/powerpc/include/asm/kvm_ppc.h:895:#ifdef CONFIG_KVM_MPIC\narch/powerpc/include/asm/kvm_ppc.h-896-\n--\narch/powerpc/include/asm/kvm_ppc.h=914=static inline void kvmppc_mpic_disconnect_vcpu(struct openpic *opp,\n--\narch/powerpc/include/asm/kvm_ppc.h-918-\narch/powerpc/include/asm/kvm_ppc.h:919:#endif /* CONFIG_KVM_MPIC */\narch/powerpc/include/asm/kvm_ppc.h-920-\n--\narch/powerpc/include/asm/kvm_ppc.h=952=static inline bool kvmppc_shared_big_endian(struct kvm_vcpu *vcpu)\narch/powerpc/include/asm/kvm_ppc.h-953-{\narch/powerpc/include/asm/kvm_ppc.h:954:#if defined(CONFIG_PPC_BOOK3S_64) \u0026\u0026 defined(CONFIG_KVM_BOOK3S_PR_POSSIBLE)\narch/powerpc/include/asm/kvm_ppc.h-955-\t/* Only Book3S_64 PR supports bi-endian for now */\n--\narch/powerpc/include/asm/kvm_ppc.h=989=static inline void kvmppc_set_##reg(struct kvm_vcpu *vcpu, u##size val)\t\\\n--\narch/powerpc/include/asm/kvm_ppc.h-1007-\narch/powerpc/include/asm/kvm_ppc.h:1008:#ifdef CONFIG_KVM_BOOKE_HV\narch/powerpc/include/asm/kvm_ppc.h-1009-\n--\narch/powerpc/include/asm/kvm_types.h-4-\narch/powerpc/include/asm/kvm_types.h:5:#if IS_MODULE(CONFIG_KVM_BOOK3S_64_PR) \u0026\u0026 IS_MODULE(CONFIG_KVM_BOOK3S_64_HV)\narch/powerpc/include/asm/kvm_types.h-6-#define KVM_SUB_MODULES kvm-pr,kvm-hv\narch/powerpc/include/asm/kvm_types.h:7:#elif IS_MODULE(CONFIG_KVM_BOOK3S_64_PR)\narch/powerpc/include/asm/kvm_types.h-8-#define KVM_SUB_MODULES kvm-pr\narch/powerpc/include/asm/kvm_types.h:9:#elif IS_MODULE(CONFIG_KVM_BOOK3S_64_HV)\narch/powerpc/include/asm/kvm_types.h-10-#define KVM_SUB_MODULES kvm-hv\n--\narch/powerpc/include/asm/mmu_context.h=207=static inline void mm_context_remove_copro(struct mm_struct *mm) { }\n--\narch/powerpc/include/asm/mmu_context.h-209-\narch/powerpc/include/asm/mmu_context.h:210:#if defined(CONFIG_KVM_BOOK3S_HV_POSSIBLE) \u0026\u0026 defined(CONFIG_PPC_RADIX_MMU)\narch/powerpc/include/asm/mmu_context.h-211-void do_h_rpt_invalidate_prt(unsigned long pid, unsigned long lpid,\n--\narch/powerpc/include/asm/paca.h-24-#endif\narch/powerpc/include/asm/paca.h:25:#ifdef CONFIG_KVM_BOOK3S_64_HANDLER\narch/powerpc/include/asm/paca.h-26-#include \u003casm/kvm_book3s_asm.h\u003e\n--\narch/powerpc/include/asm/paca.h=61=struct paca_struct {\n--\narch/powerpc/include/asm/paca.h-176-\tu8 irq_work_pending;\t\t/* IRQ_WORK interrupt while soft-disable */\narch/powerpc/include/asm/paca.h:177:#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE\narch/powerpc/include/asm/paca.h-178-\tu8 pmcregs_in_use;\t\t/* pseries puts this in lppaca */\n--\narch/powerpc/include/asm/paca.h-200-\t\tstruct {\narch/powerpc/include/asm/paca.h:201:#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE\narch/powerpc/include/asm/paca.h-202-\t\t\t/* The PSSCR value that the kernel requested before going to stop */\n--\narch/powerpc/include/asm/paca.h-236-\narch/powerpc/include/asm/paca.h:237:#ifdef CONFIG_KVM_BOOK3S_HANDLER\narch/powerpc/include/asm/paca.h:238:#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE\narch/powerpc/include/asm/paca.h-239-\t/* We use this to store guest state in */\n--\narch/powerpc/include/asm/paca.h-242-\tstruct kvmppc_host_state kvm_hstate;\narch/powerpc/include/asm/paca.h:243:#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE\narch/powerpc/include/asm/paca.h-244-\t/*\n--\narch/powerpc/include/asm/pmc.h=23=static inline void ppc_set_pmu_inuse(int inuse)\narch/powerpc/include/asm/pmc.h-24-{\narch/powerpc/include/asm/pmc.h:25:#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_KVM_BOOK3S_HV_POSSIBLE)\narch/powerpc/include/asm/pmc.h-26-\tif (firmware_has_feature(FW_FEATURE_LPAR)) {\n--\narch/powerpc/include/asm/pmc.h-30-\t}\narch/powerpc/include/asm/pmc.h:31:#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE\narch/powerpc/include/asm/pmc.h-32-\tget_paca()-\u003epmcregs_in_use = inuse;\n--\narch/powerpc/include/asm/pmc.h-36-\narch/powerpc/include/asm/pmc.h:37:#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE\narch/powerpc/include/asm/pmc.h-38-static inline int ppc_get_pmu_inuse(void)\n--\narch/powerpc/include/asm/processor.h=133=struct thread_struct {\n--\narch/powerpc/include/asm/processor.h-225-#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */\narch/powerpc/include/asm/processor.h:226:#ifdef CONFIG_KVM_BOOK3S_32_HANDLER\narch/powerpc/include/asm/processor.h-227-\tvoid*\t\tkvm_shadow_vcpu; /* KVM internal data */\narch/powerpc/include/asm/processor.h:228:#endif /* CONFIG_KVM_BOOK3S_32_HANDLER */\narch/powerpc/include/asm/processor.h:229:#if defined(CONFIG_KVM) \u0026\u0026 defined(CONFIG_BOOKE)\narch/powerpc/include/asm/processor.h-230-\tstruct kvm_vcpu\t*kvm_vcpu;\n--\narch/powerpc/include/asm/time.h=101=static inline u64 timer_get_next_tb(void)\n--\narch/powerpc/include/asm/time.h-105-\narch/powerpc/include/asm/time.h:106:#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE\narch/powerpc/include/asm/time.h-107-void timer_rearm_host_dec(u64 now);\n--\narch/powerpc/kernel/Makefile=162=obj-$(CONFIG_EPAPR_PARAVIRT)\t+= epapr_paravirt.o epapr_hcalls.o\narch/powerpc/kernel/Makefile:163:obj-$(CONFIG_KVM_GUEST)\t\t+= kvm.o kvm_emul.o\narch/powerpc/kernel/Makefile-164-ifneq ($(CONFIG_PPC_POWERNV)$(CONFIG_PPC_SVM),)\n--\narch/powerpc/kernel/asm-offsets.c-48-#endif\narch/powerpc/kernel/asm-offsets.c:49:#if defined(CONFIG_KVM) || defined(CONFIG_KVM_GUEST)\narch/powerpc/kernel/asm-offsets.c-50-#include \u003clinux/kvm_host.h\u003e\narch/powerpc/kernel/asm-offsets.c-51-#endif\narch/powerpc/kernel/asm-offsets.c:52:#if defined(CONFIG_KVM) \u0026\u0026 defined(CONFIG_PPC_BOOK3S)\narch/powerpc/kernel/asm-offsets.c-53-#include \u003casm/kvm_book3s.h\u003e\n--\narch/powerpc/kernel/asm-offsets.c=78=int main(void)\n--\narch/powerpc/kernel/asm-offsets.c-150-#endif /* CONFIG_PPC64 */\narch/powerpc/kernel/asm-offsets.c:151:#ifdef CONFIG_KVM_BOOK3S_32_HANDLER\narch/powerpc/kernel/asm-offsets.c-152-\tOFFSET(THREAD_KVM_SVCPU, thread_struct, kvm_shadow_vcpu);\narch/powerpc/kernel/asm-offsets.c-153-#endif\narch/powerpc/kernel/asm-offsets.c:154:#if defined(CONFIG_KVM) \u0026\u0026 defined(CONFIG_BOOKE)\narch/powerpc/kernel/asm-offsets.c-155-\tOFFSET(THREAD_KVM_VCPU, thread_struct, kvm_vcpu);\n--\narch/powerpc/kernel/asm-offsets.c-230-\tOFFSET(LPPACA_PMCINUSE, lppaca, pmcregs_in_use);\narch/powerpc/kernel/asm-offsets.c:231:#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE\narch/powerpc/kernel/asm-offsets.c-232-\tOFFSET(PACA_PMCINUSE, paca_struct, pmcregs_in_use);\n--\narch/powerpc/kernel/asm-offsets.c-353-\n\n"
}

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

Args:
null

Results:
null

Tokens:
							input: 20198
							output: 23
							thoughts: 653
						

Thoughts:
**Analyzing the KVM OOM Notifier Patch for Fuzzing**

Okay, let's break this down for fuzzing purposes. First, the core of this patch revolves around `mmu_notifier` integration, specifically in the context of Out-Of-Memory (OOM) situations, with a KVM-specific implementation. I see that `CONFIG_KVM` is, of course, a given, and this patch relies on `mmu_notifier` functionality, requiring `CONFIG_MMU_NOTIFIER`.  Since `__oom_reap_task_mm` calls `mmu_notifier_oom_enter` which requires `CONFIG_MMU`, and `CONFIG_MMU` is nearly ubiquitous, we're likely good on the base configs.

My focus has to be on the new and modified functions. So, the key functions that are added or have changed within this patch are: `mmu_notifier_oom_enter`, `mmu_notifier_barrier`, `mmu_notifier_oom_callback_fn`, `kvm_mmu_notifier_after_oom_unregister`, `kvm_destroy_vm` (modified), and `__oom_reap_task_mm` (modified).

Now, to determine the most effective fuzzing targets, I need to map their call paths. `mmu_notifier_oom_enter` is called by `__oom_reap_task_mm`. `kvm_mmu_notifier_after_oom_unregister` is called by `mmu_notifier_oom_callback_fn`. And `mmu_notifier_barrier` is called by `kvm_destroy_vm`. That's a good start. I can also focus on `__oom_reap_task_mm` because it's the entry point to the new OOM logic, even though `mmu_notifier_oom_enter` is a more specific target. Similarly, `kvm_destroy_vm` is interesting because of the modifications to handle the unhashed hlist.

So, taking all of this into account, I'm going to prioritize these symbols for fuzzing: `mmu_notifier_oom_enter`, `mmu_notifier_barrier`, `mmu_notifier_oom_callback_fn`, `kvm_mmu_notifier_after_oom_unregister`, and `kvm_destroy_vm`. I'm confident in those names as they appear.

Finally, let me just verify that `__oom_reap_task_mm` doesn't have any conditional compilation directives that would make it unavailable under certain configurations. Since it lives in `mm/oom_kill.c`, I'll quickly check for that.



8/2 2026/07/23 15:29 tool grepper
0m Args:
{
  "Expression": "__oom_reap_task_mm"
}

Results:
{
  "Output": "mm/oom_kill.c=511=static DEFINE_SPINLOCK(oom_reaper_lock);\nmm/oom_kill.c-512-\nmm/oom_kill.c:513:static bool __oom_reap_task_mm(struct mm_struct *mm)\nmm/oom_kill.c-514-{\n--\nmm/oom_kill.c=565=static bool oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm)\n--\nmm/oom_kill.c-587-\t/* failed to reap part of the address space. Try again later */\nmm/oom_kill.c:588:\tret = __oom_reap_task_mm(mm);\nmm/oom_kill.c-589-\tif (!ret)\n--\nmm/oom_kill.c=1198=SYSCALL_DEFINE2(process_mrelease, int, pidfd, unsigned int, flags)\n--\nmm/oom_kill.c-1247-\t */\nmm/oom_kill.c:1248:\tif (!mm_flags_test(MMF_OOM_SKIP, mm) \u0026\u0026 !__oom_reap_task_mm(mm))\nmm/oom_kill.c-1249-\t\tret = -EAGAIN;\n"
}

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

Args:
null

Results:
null

Tokens:
							input: 21795
							output: 20
							thoughts: 94
						

Thoughts:
**Analyzing the Role of `__oom_reap_task_mm`**

Okay, so `__oom_reap_task_mm` lives within `mm/oom_kill.c`, which, if I recall correctly, is always compiled or at least depends on the MMU. That makes sense, given the function's name. I need to understand its context within the kernel configuration. I remember the enabling configs are `MMU_NOTIFIER` and `KVM`, specifically.

Now, my line of inquiry is clear: Is `MMU_NOTIFIER` directly user-selectable, or is it a dependency of another config? I'll head over to `mm/Kconfig` or a similar configuration file in the memory management subtree. That should be the definitive place to track down the relationship and ensure I understand how this component is actually enabled in different builds. I need a clear picture of its configurability.



10/2 2026/07/23 15:29 tool grepper
0m Args:
{
  "Expression": "config MMU_NOTIFIER"
}

Results:
{
  "Output": "mm/Kconfig=733=config PHYS_ADDR_T_64BIT\n--\nmm/Kconfig-735-\nmm/Kconfig:736:config MMU_NOTIFIER\nmm/Kconfig-737-\tbool\n"
}

11/2 2026/07/23 15:29 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 22176
							output: 20
							thoughts: 77
						

Thoughts:
Okay, let's see, I'm looking at this `MMU_NOTIFIER` option. It's a `bool` and I don't see any associated prompt with it, which means it's likely being selected by other configurations. Right, that makes sense.

**Analyzing the Configuration Dependency**

The strategy here is to just list `MMU_NOTIFIER` in the configuration. The syzkaller config system should handle the rest - it will either enable `MMU_NOTIFIER` directly or enable another configuration option that selects it, based on the dependencies. Now, hang on a second... is `KVM` actually one of the options that selects `MMU_NOTIFIER`? That's a reasonable assumption, but I should probably confirm it to be certain. Let's dig deeper and verify that. It's always best to be precise when dealing with kernel configuration.



12/2 2026/07/23 15:29 tool grepper
0m Args:
{
  "Expression": "select MMU_NOTIFIER"
}

Results:
{
  "Output": "arch/powerpc/platforms/powernv/Kconfig=2=config PPC_POWERNV\n--\narch/powerpc/platforms/powernv/Kconfig-17-\tselect PPC_DOORBELL\narch/powerpc/platforms/powernv/Kconfig:18:\tselect MMU_NOTIFIER\narch/powerpc/platforms/powernv/Kconfig-19-\tselect FORCE_SMP\n--\narch/x86/Kconfig=1827=config X86_SGX\n--\narch/x86/Kconfig-1830-\tselect CRYPTO_LIB_SHA256\narch/x86/Kconfig:1831:\tselect MMU_NOTIFIER\narch/x86/Kconfig-1832-\tselect NUMA_KEEP_MEMINFO if NUMA\n--\ndrivers/gpu/drm/Kconfig=228=config DRM_GPUSVM\n--\ndrivers/gpu/drm/Kconfig-231-\tselect HMM_MIRROR\ndrivers/gpu/drm/Kconfig:232:\tselect MMU_NOTIFIER\ndrivers/gpu/drm/Kconfig-233-\thelp\n--\ndrivers/gpu/drm/amd/amdgpu/Kconfig=75=config DRM_AMDGPU_USERPTR\n--\ndrivers/gpu/drm/amd/amdgpu/Kconfig-78-\tselect HMM_MIRROR\ndrivers/gpu/drm/amd/amdgpu/Kconfig:79:\tselect MMU_NOTIFIER\ndrivers/gpu/drm/amd/amdgpu/Kconfig-80-\thelp\n--\ndrivers/gpu/drm/amd/amdkfd/Kconfig=6=config HSA_AMD\n--\ndrivers/gpu/drm/amd/amdkfd/Kconfig-9-\tselect HMM_MIRROR\ndrivers/gpu/drm/amd/amdkfd/Kconfig:10:\tselect MMU_NOTIFIER\ndrivers/gpu/drm/amd/amdkfd/Kconfig-11-\tselect DRM_AMDGPU_USERPTR\n--\ndrivers/gpu/drm/amd/amdkfd/Kconfig=15=config HSA_AMD_SVM\n--\ndrivers/gpu/drm/amd/amdkfd/Kconfig-19-\tselect HMM_MIRROR\ndrivers/gpu/drm/amd/amdkfd/Kconfig:20:\tselect MMU_NOTIFIER\ndrivers/gpu/drm/amd/amdkfd/Kconfig-21-\thelp\n--\ndrivers/gpu/drm/i915/Kconfig=114=config DRM_I915_USERPTR\n--\ndrivers/gpu/drm/i915/Kconfig-116-\tdepends on DRM_I915\ndrivers/gpu/drm/i915/Kconfig:117:\tselect MMU_NOTIFIER\ndrivers/gpu/drm/i915/Kconfig-118-\tdefault y\n--\ndrivers/gpu/drm/nouveau/Kconfig=94=config DRM_NOUVEAU_SVM\n--\ndrivers/gpu/drm/nouveau/Kconfig-99-\tselect HMM_MIRROR\ndrivers/gpu/drm/nouveau/Kconfig:100:\tselect MMU_NOTIFIER\ndrivers/gpu/drm/nouveau/Kconfig-101-\tdefault n\n--\ndrivers/gpu/drm/radeon/Kconfig=38=config DRM_RADEON_USERPTR\n--\ndrivers/gpu/drm/radeon/Kconfig-40-\tdepends on DRM_RADEON\ndrivers/gpu/drm/radeon/Kconfig:41:\tselect MMU_NOTIFIER\ndrivers/gpu/drm/radeon/Kconfig-42-\thelp\n--\ndrivers/gpu/drm/xe/Kconfig=2=config DRM_XE\n--\ndrivers/gpu/drm/xe/Kconfig-44-\tselect DRM_SCHED\ndrivers/gpu/drm/xe/Kconfig:45:\tselect MMU_NOTIFIER\ndrivers/gpu/drm/xe/Kconfig-46-\tselect WANT_DEV_COREDUMP\n--\ndrivers/hv/Kconfig=68=config MSHV_ROOT\n--\ndrivers/hv/Kconfig-80-\tselect HMM_MIRROR\ndrivers/hv/Kconfig:81:\tselect MMU_NOTIFIER\ndrivers/hv/Kconfig-82-\tdefault n\n--\ndrivers/infiniband/Kconfig=51=config INFINIBAND_ON_DEMAND_PAGING\n--\ndrivers/infiniband/Kconfig-53-\tdepends on INFINIBAND_USER_MEM\ndrivers/infiniband/Kconfig:54:\tselect MMU_NOTIFIER\ndrivers/infiniband/Kconfig-55-\tselect INTERVAL_TREE\n--\ndrivers/infiniband/hw/hfi1/Kconfig=2=config INFINIBAND_HFI1\n--\ndrivers/infiniband/hw/hfi1/Kconfig-4-\tdepends on X86_64 \u0026\u0026 INFINIBAND_RDMAVT \u0026\u0026 I2C \u0026\u0026 !UML\ndrivers/infiniband/hw/hfi1/Kconfig:5:\tselect MMU_NOTIFIER\ndrivers/infiniband/hw/hfi1/Kconfig-6-\tselect CRC32\n--\ndrivers/iommu/amd/Kconfig=3=config AMD_IOMMU\n--\ndrivers/iommu/amd/Kconfig-10-\tselect IRQ_MSI_LIB\ndrivers/iommu/amd/Kconfig:11:\tselect MMU_NOTIFIER\ndrivers/iommu/amd/Kconfig-12-\tselect IOMMU_API\n--\ndrivers/iommu/arm/Kconfig=91=config ARM_SMMU_V3_SVA\n--\ndrivers/iommu/arm/Kconfig-94-\tselect IOMMU_IOPF\ndrivers/iommu/arm/Kconfig:95:\tselect MMU_NOTIFIER\ndrivers/iommu/arm/Kconfig-96-\thelp\n--\ndrivers/iommu/intel/Kconfig=53=config INTEL_IOMMU_SVM\n--\ndrivers/iommu/intel/Kconfig-55-\tdepends on X86_64\ndrivers/iommu/intel/Kconfig:56:\tselect MMU_NOTIFIER\ndrivers/iommu/intel/Kconfig-57-\tselect IOMMU_SVA\n--\ndrivers/misc/Kconfig=313=config SGI_GRU\n--\ndrivers/misc/Kconfig-315-\tdepends on X86_UV \u0026\u0026 SMP\ndrivers/misc/Kconfig:316:\tselect MMU_NOTIFIER\ndrivers/misc/Kconfig-317-\thelp\n--\ndrivers/xen/Kconfig=136=config XEN_GNTDEV\n--\ndrivers/xen/Kconfig-139-\tdefault m\ndrivers/xen/Kconfig:140:\tselect MMU_NOTIFIER\ndrivers/xen/Kconfig-141-\tselect FIND_NORMAL_PAGE\n--\nlib/Kconfig.debug=3354=config TEST_HMM\n--\nlib/Kconfig.debug-3358-\tselect HMM_MIRROR\nlib/Kconfig.debug:3359:\tselect MMU_NOTIFIER\nlib/Kconfig.debug-3360-\thelp\n--\nvirt/kvm/Kconfig=4=config KVM_COMMON\n--\nvirt/kvm/Kconfig-7-       select INTERVAL_TREE\nvirt/kvm/Kconfig:8:       select MMU_NOTIFIER\nvirt/kvm/Kconfig-9-       select PREEMPT_NOTIFIERS\n"
}

13/2 2026/07/23 15:29 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 24325
							output: 209
							thoughts: 994
						

Thoughts:
**Focusing the Fuzz: KVM and OOM Cleanup**

Okay, let's break this down for fuzzing. It looks like `KVM_COMMON` selects `MMU_NOTIFIER`, and `KVM` selects `KVM_COMMON`. Therefore, enabling `KVM` is definitely the right config to get everything related to the patch enabled.  `KVM` is pretty standard, so we can just list that.

The patch itself touches `virt/kvm/kvm_main.c`, which tells me that `KVM` is necessary to test the KVM-specific implementation of `after_oom_unregister`. The central logic is in `mm/mmu_notifier.c` and `mm/oom_kill.c`, so `KVM` should be sufficient to enable `MMU_NOTIFIER` and test the whole flow.

Now, let's nail down the key symbols. We have: `mmu_notifier_oom_enter`, `mmu_notifier_barrier`, `mmu_notifier_oom_callback_fn`, `kvm_mmu_notifier_after_oom_unregister`, and `kvm_destroy_vm`.

Okay, digging a bit deeper, `mmu_notifier_oom_enter` is called from `__oom_reap_task_mm`. `__oom_reap_task_mm` is in turn called from `oom_reap_task_mm` and `process_mrelease`.  `process_mrelease` is a syscall.  Interesting. So, fuzzing `process_mrelease` should be a path to trigger `mmu_notifier_oom_enter`. Syzkaller will already fuzz `process_mrelease` since it's a syscall, but let's add it to the focus symbols to encourage the fuzzer to give it some extra attention. Yep, `process_mrelease` looks like a good entry point since it's a syscall. Let's add that to the list.

Let's double-check how `__oom_reap_task_mm` is called. It's called from `oom_reap_task_mm`, which is called by the oom_reaper kthread. Also from the `process_mrelease` syscall. This reinforces the idea that `process_mrelease` is the key to trigger this from userspace.

`kvm_destroy_vm` is called when a KVM VM is destroyed. Creating and destroying VMs will likely trigger this.

So the complete set of focus symbols is:
*   `mmu_notifier_oom_enter`
*   `mmu_notifier_barrier`
*   `mmu_notifier_oom_callback_fn`
*   `kvm_mmu_notifier_after_oom_unregister`
*   `kvm_destroy_vm`
*   `process_mrelease`

`mmu_notifier_oom_callback_fn` is static, and called via `call_srcu`, but it should still be included since it's on the call stack, even if it's called asynchronously.

`kvm_destroy_vm` is static in `virt/kvm/kvm_main.c` and called from `kvm_put_kvm`. `mmu_notifier_barrier` is exported, and `mmu_notifier_oom_enter` is not exported, but it is global.

The reasoning here is that this patch modifies both core memory management and KVM. It introduces an asynchronous callback, triggered by OOM events, and implements it for KVM. The change modifies `kvm_destroy_vm` to handle asynchronous cleanup. It's crucial to fuzz this to check for use-after-free or deadlock bugs during VM OOM handling.

Just to be absolutely sure, `KVM` is the config name, not `CONFIG_KVM`.  Yep, `KVM`.

Also, `CONFIG_MMU_NOTIFIER` is selected by `KVM_COMMON` which is selected by `KVM`. So just `KVM` is sufficient, but listing both will make it more explicit.

Now, let's put this into a proper summary.



14/2 2026/07/23 15:29 tool set-results
0m Args:
{
  "EnableConfigs": [
    "KVM",
    "MMU_NOTIFIER"
  ],
  "FocusSymbols": [
    "mmu_notifier_oom_enter",
    "mmu_notifier_barrier",
    "mmu_notifier_oom_callback_fn",
    "kvm_mmu_notifier_after_oom_unregister",
    "kvm_destroy_vm",
    "process_mrelease"
  ],
  "Reasoning": "The patch introduces a new MMU notifier callback `after_oom_unregister` and a mechanism to invoke it asynchronously when an OOM event occurs (`mmu_notifier_oom_enter`). It also implements this callback for KVM and modifies `kvm_destroy_vm` to handle the asynchronous cleanup. This is a functional change to core memory management and KVM, and should be fuzzed to ensure there are no use-after-free or deadlock issues during OOM handling of VMs.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "KVM",
    "MMU_NOTIFIER"
  ],
  "FocusSymbols": [
    "mmu_notifier_oom_enter",
    "mmu_notifier_barrier",
    "mmu_notifier_oom_callback_fn",
    "kvm_mmu_notifier_after_oom_unregister",
    "kvm_destroy_vm",
    "process_mrelease"
  ],
  "Reasoning": "The patch introduces a new MMU notifier callback `after_oom_unregister` and a mechanism to invoke it asynchronously when an OOM event occurs (`mmu_notifier_oom_enter`). It also implements this callback for KVM and modifies `kvm_destroy_vm` to handle the asynchronous cleanup. This is a functional change to core memory management and KVM, and should be fuzzed to ensure there are no use-after-free or deadlock issues during OOM handling of VMs.",
  "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)