From: Pablo Azuaje <pablo45154@gmail.com>
To: Paolo Bonzini <pbonzini@redhat.com>,
Sean Christopherson <seanjc@google.com>
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
Eugene Korenevsky <ekorenevsky@gmail.com>
Subject: [PATCH] KVM: x86: Clamp guest MAXPHYADDR to the architectural maximum
Date: Sun, 18 Oct 2026 13:52:22 +0200 [thread overview]
Message-ID: <20261018115222.315090-1-pablo45154@gmail.com> (raw)
cpuid_query_maxphyaddr() returns CPUID.0x80000008.EAX[7:0] as the
guest's physical-address width without any sanity check. KVM computes
the reserved GPA bits from that value, e.g.
kvm_vcpu_reserved_gpa_bits_raw() is rsvd_bits(maxphyaddr, 63), and
rsvd_bits() returns 0 when the bit range is empty. A VMM that
populates CPUID.0x80000008.EAX above 52 therefore makes KVM stop
treating the upper bits of guest PTEs as reserved: reserved-bit fault
checking on guest page table walks silently degenerates, and garbage
nCR3s/PDPTRs are accepted instead of faulting.
A MAXPHYADDR above 52 is architecturally impossible on x86-64; clamp
the queried value to 52 so that a buggy VMM configuration degrades to a
(very wide) but still meaningful physical-address width instead of
disabling KVM's reserved-bit accounting.
This is hardening rather than a security fix: the actor is the VMM,
which already owns the guest, so an over-wide MAXPHYADDR is not a
privilege boundary crossing. The motivation is correctness, not
containment: a configuration value outside architectural limits should
not silently change how KVM validates guest page tables, and clamping
keeps the degenerate case well-defined instead of subtly disabling a
whole class of fault checks. The unclamped read predates the
introduction of the cached value; no Fixes: tag is attached for that
reason.
Signed-off-by: Pablo Azuaje <pablo45154@gmail.com>
---
arch/x86/kvm/cpuid.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 851f151efb35..f0166072968f 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -477,8 +477,18 @@ int cpuid_query_maxphyaddr(struct kvm_vcpu *vcpu)
if (!best || best->eax < 0x80000008)
goto not_found;
best = kvm_find_cpuid_entry(vcpu, 0x80000008);
- if (best)
- return best->eax & 0xff;
+ if (best) {
+ /*
+ * Clamp MAXPHYADDR to the architectural maximum of 52 bits.
+ * A larger value is a VMM bug: KVM derives the reserved GPA
+ * bits from MAXPHYADDR, e.g. kvm_vcpu_reserved_gpa_bits_raw()
+ * is rsvd_bits(maxphyaddr, 63), and rsvd_bits() returns 0
+ * when the range is empty, i.e. an over-wide MAXPHYADDR
+ * silently disables reserved-bit checks on guest page table
+ * walks.
+ */
+ return min_t(u32, best->eax & 0xff, 52);
+ }
not_found:
return 36;
}
--
2.53.0
next reply other threads:[~2026-10-18 11:52 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-18 11:52 Pablo Azuaje [this message]
2026-10-20 13:39 ` [PATCH] KVM: x86: Clamp guest MAXPHYADDR to the architectural maximum Sean Christopherson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261018115222.315090-1-pablo45154@gmail.com \
--to=pablo45154@gmail.com \
--cc=ekorenevsky@gmail.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.