* [BUG/RFC] KVM: nVMX: nested_get_vmcs12_pages() kills the VM when the APIC-access page is unbacked, unlike its sibling pointers
@ 2026-10-16 23:52 Amirmohammad Eftekhar
2026-10-17 0:53 ` Sean Christopherson
0 siblings, 1 reply; 2+ messages in thread
From: Amirmohammad Eftekhar @ 2026-10-16 23:52 UTC (permalink / raw)
To: seanjc, pbonzini; +Cc: kvm, linux-kernel
Hi,
nested_get_vmcs12_pages() (arch/x86/kvm/vmx/nested.c:3448) maps three
L1-supplied guest-physical pointers into vmcs02 on nested VM-entry. Each is
VALIDATE-checked for format only (page_address_valid / legal-aligned-gpa),
never for backing, so a legal-format GPA with no memslot passes every
consistency check and can only fail at the kvm_vcpu_map() step. When that map
fails, the three pointers are handled three incompatible ways:
apic_access_addr -> vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR,
suberror EMULATION, return false. The VM dies
(every userspace VMM treats INTERNAL_ERROR as fatal).
virtual_apic_page_addr -> clears CPU_BASED_TPR_SHADOW, or writes INVALID_GPA
to force a clean VM-entry failure -> L1 gets a
well-formed VMfail.
posted_intr_desc_addr -> pi_desc = NULL; clears PIN_BASED_POSTED_INTR and
runs L2 anyway, with no signal to L1.
Same function, same fault cause, three outcomes: kill the VM / clean VMfail /
silent feature-drop. For an architecturally legal vmcs12 (L1 is free to name an
unbacked but well-formed GPA), the apic_access arm turns a guest-controlled
condition into a fatal KVM_EXIT_INTERNAL_ERROR, which reads as a robustness bug
next to the sibling behaviours: a nested-entry input problem caused by L1 should
surface to L1 as a VM-entry failure, not tear down the VM.
This is a fidelity/robustness inconsistency (E2), not a privilege-boundary or
memory-safety issue: no host crash, no host-side WARN, no cross-VM effect. The
scarier sibling -- deleting a memslot that a live nested map has pinned -- was
probed separately and is a verified negative on the default
allow_unsafe_mappings=0 (the pin holds, no splat).
Currency: c1214f293d77 ("KVM: x86: Fill kvm_run exit fields in common
get_nested_state_pages() error paths", Cc: stable) relocated the
KVM_EXIT_INTERNAL_ERROR fill out of the per-site arm into the common caller, and
10180a277549 ("KVM: x86: Re-pend GET_NESTED_STATE_PAGES if getting said pages
fails", Cc: stable) hardened the stale-PFN seam -- but neither changes the
map-failure *policy* divergence, which is what this report is about. The
apic_access arm still returns false -> KVM_EXIT_INTERNAL_ERROR.
Question / suggested direction: should the apic_access arm be made to fail the
nested entry cleanly (as virtual_apic does), rather than kill the VM? The same
three-way divergence exists on AMD inside nested_svm_merge_msrpm /
nested_get_vmcs12_pages equivalents, worth aligning in one pass. Happy to send a
patch once the intended policy is confirmed.
A reproducer aims exactly one pointer at a legal-but-unbacked GPA
(0x1_0000_0000, page/64-aligned, <= MAXPHYADDR, no memslot) with an
otherwise valid-by-construction vmcs12 and a backed-GPA control arm per field,
reading the native outcome plus the run anomaly from the kernel; deterministic
across runs on Intel 7.2-rc3.
Thanks,
Amirmohammad
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [BUG/RFC] KVM: nVMX: nested_get_vmcs12_pages() kills the VM when the APIC-access page is unbacked, unlike its sibling pointers
2026-10-16 23:52 [BUG/RFC] KVM: nVMX: nested_get_vmcs12_pages() kills the VM when the APIC-access page is unbacked, unlike its sibling pointers Amirmohammad Eftekhar
@ 2026-10-17 0:53 ` Sean Christopherson
0 siblings, 0 replies; 2+ messages in thread
From: Sean Christopherson @ 2026-10-17 0:53 UTC (permalink / raw)
To: Amirmohammad Eftekhar; +Cc: pbonzini, kvm, linux-kernel
On Sat, Oct 17, 2026, Amirmohammad Eftekhar wrote:
> Hi,
>
> nested_get_vmcs12_pages() (arch/x86/kvm/vmx/nested.c:3448) maps three
> L1-supplied guest-physical pointers into vmcs02 on nested VM-entry. Each is
> VALIDATE-checked for format only (page_address_valid / legal-aligned-gpa),
> never for backing, so a legal-format GPA with no memslot passes every
> consistency check and can only fail at the kvm_vcpu_map() step. When that map
> fails, the three pointers are handled three incompatible ways:
>
> apic_access_addr -> vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR,
> suberror EMULATION, return false. The VM dies
> (every userspace VMM treats INTERNAL_ERROR as fatal).
> virtual_apic_page_addr -> clears CPU_BASED_TPR_SHADOW, or writes INVALID_GPA
> to force a clean VM-entry failure -> L1 gets a
> well-formed VMfail.
> posted_intr_desc_addr -> pi_desc = NULL; clears PIN_BASED_POSTED_INTR and
> runs L2 anyway, with no signal to L1.
...
> Question / suggested direction: should the apic_access arm be made to fail the
> nested entry cleanly (as virtual_apic does), rather than kill the VM?
No. KVM goes out of its way to limp along if the vAPIC or PID pages are bad,
mostly to play nice with tests and pedantic developers. AFAIK, there's no good
option to allow the VM to limp along. If someone has a strong use case *and* a
"fix", they are more than welcome to post it.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-17 0:53 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-16 23:52 [BUG/RFC] KVM: nVMX: nested_get_vmcs12_pages() kills the VM when the APIC-access page is unbacked, unlike its sibling pointers Amirmohammad Eftekhar
2026-10-17 0:53 ` Sean Christopherson
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.