Add the RHEL 687.14.1..687.15.1 backports (1270-1284) from centos-stream-9 and
upstream stable, on top of 687.13.1. The dpll/zl3073x and ice RSS-queue series are
consolidated (they carry RHEL kABI wrapping and RHEL-only files). The mlx5 kabi
removal (RHEL-181822) is applied via updated Module.kabi_{aarch64,s390x,x86_64}.
Bump pkgrelease and specrelease to 687.15.1.
87 lines
2.7 KiB
Diff
87 lines
2.7 KiB
Diff
From c29c799bc106385fe74e3a9a51c58087c8f9e725 Mon Sep 17 00:00:00 2001
|
|
From: Ryosuke Yasuoka <ryasuoka@redhat.com>
|
|
Date: Thu, 15 Jan 2026 13:31:39 +0900
|
|
Subject: [PATCH] x86/kvm: Avoid freeing stack-allocated node in
|
|
kvm_async_pf_queue_task
|
|
|
|
JIRA: https://issues.redhat.com/browse/RHEL-125085
|
|
|
|
commit 95cc9e7cf03d3646abce4129d5c013af33a7df99
|
|
Author: Ryosuke Yasuoka <ryasuoka@redhat.com>
|
|
Date: Sat Dec 6 23:09:36 2025 +0900
|
|
|
|
x86/kvm: Avoid freeing stack-allocated node in kvm_async_pf_queue_task
|
|
|
|
kvm_async_pf_queue_task() can incorrectly try to kfree() a node
|
|
allocated on the stack of kvm_async_pf_task_wait_schedule().
|
|
|
|
This occurs when a task requests a PF while another task's PF request
|
|
with the same token is still pending. Since the token is derived from
|
|
the (u32)address in exc_page_fault(), two different tasks can generate
|
|
the same token.
|
|
|
|
Currently, kvm_async_pf_queue_task() assumes that any entry found in the
|
|
list is a dummy entry and tries to kfree() it. To fix this, add a flag
|
|
to the node structure to distinguish stack-allocated nodes, and only
|
|
kfree() the node if it is a dummy entry.
|
|
|
|
Signed-off-by: Ryosuke Yasuoka <ryasuoka@redhat.com>
|
|
Message-ID: <20251206140939.144038-1-ryasuoka@redhat.com>
|
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
|
Signed-off-by: Ryosuke Yasuoka <ryasuoka@redhat.com>
|
|
|
|
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
|
|
index c8b1db5c914c..16d4e504bedf 100644
|
|
--- a/arch/x86/kernel/kvm.c
|
|
+++ b/arch/x86/kernel/kvm.c
|
|
@@ -86,6 +86,7 @@ struct kvm_task_sleep_node {
|
|
struct swait_queue_head wq;
|
|
u32 token;
|
|
int cpu;
|
|
+ bool dummy;
|
|
};
|
|
|
|
static struct kvm_task_sleep_head {
|
|
@@ -117,15 +118,26 @@ static bool kvm_async_pf_queue_task(u32 token, struct kvm_task_sleep_node *n)
|
|
raw_spin_lock(&b->lock);
|
|
e = _find_apf_task(b, token);
|
|
if (e) {
|
|
- /* dummy entry exist -> wake up was delivered ahead of PF */
|
|
- hlist_del(&e->link);
|
|
+ struct kvm_task_sleep_node *dummy = NULL;
|
|
+
|
|
+ /*
|
|
+ * The entry can either be a 'dummy' entry (which is put on the
|
|
+ * list when wake-up happens ahead of APF handling completion)
|
|
+ * or a token from another task which should not be touched.
|
|
+ */
|
|
+ if (e->dummy) {
|
|
+ hlist_del(&e->link);
|
|
+ dummy = e;
|
|
+ }
|
|
+
|
|
raw_spin_unlock(&b->lock);
|
|
- kfree(e);
|
|
+ kfree(dummy);
|
|
return false;
|
|
}
|
|
|
|
n->token = token;
|
|
n->cpu = smp_processor_id();
|
|
+ n->dummy = false;
|
|
init_swait_queue_head(&n->wq);
|
|
hlist_add_head(&n->link, &b->list);
|
|
raw_spin_unlock(&b->lock);
|
|
@@ -228,6 +240,7 @@ void kvm_async_pf_task_wake(u32 token)
|
|
}
|
|
dummy->token = token;
|
|
dummy->cpu = smp_processor_id();
|
|
+ dummy->dummy = true;
|
|
init_swait_queue_head(&dummy->wq);
|
|
hlist_add_head(&dummy->link, &b->list);
|
|
dummy = NULL;
|
|
--
|
|
2.50.1 (Apple Git-155)
|
|
|