[RFC PATCH v2 13/31] KVM: x86: hyperv: Suppress SynIC exits from higher planes

From: David Woodhouse

Date: Fri Nov 13 2026 - 16:34:20 EST


From: David Woodhouse <dwmw@xxxxxxxxxxxx>

Userspace's SynIC device models plane 0 only. A KVM_EXIT_HYPERV_SYNIC
exit from a higher plane's vCPU looks like a plane-0 SIMP or SIEFP
move, and the VMM relocates the overlay it keeps for that page to the
new GPA, carrying stale overlay contents along.

Do not report SynIC MSR changes of a non-zero plane to userspace; the
SynIC of a higher plane is handled in the kernel. api.rst says so in
the KVM_EXIT_HYPERV_SYNIC description.

Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx>
---
Documentation/virt/kvm/api.rst | 3 ++-
arch/x86/kvm/hyperv.c | 9 +++++++++
2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 83daee450284..99e18956f249 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -7503,7 +7503,8 @@ Valid values for 'type' are:

Hyper-V SynIC state change. Notification is used to remap SynIC
event/message pages and to enable/disable SynIC messages/events processing
-in userspace.
+in userspace. Only plane-0 vCPUs exit this way; the SynIC of a
+higher plane is handled in the kernel.

- KVM_EXIT_HYPERV_HCALL -- a hypercall for userspace to handle.

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index d2ad255ae212..5a42d479e936 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -253,6 +253,15 @@ static void synic_exit(struct kvm_vcpu_hv_synic *synic, u32 msr)
struct kvm_vcpu *vcpu = hv_synic_to_vcpu(synic);
struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);

+ /*
+ * Userspace's SynIC device models plane 0 only; a higher plane's
+ * exit would be mistaken for a plane-0 page move and relocate the
+ * overlay the VMM keeps for SIMP/SIEFP. Higher-plane SynICs are
+ * handled fully in-kernel.
+ */
+ if (vcpu->plane_level)
+ return;
+
hv_vcpu->exit.type = KVM_EXIT_HYPERV_SYNIC;
hv_vcpu->exit.plane = vcpu->plane_level;
hv_vcpu->exit.u.synic.msr = msr;
--
2.50.1