]> xenbits.xensource.com Git - xen.git/commit
x86/shadow: Correct guest behaviour when creating PTEs above maxphysaddr
authorAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 4 Jul 2016 08:40:34 +0000 (09:40 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 20 Feb 2017 17:03:58 +0000 (17:03 +0000)
commit5dbd60e16a1f29b9f1f84088c5cab1be2dac7a7a
tree5572feb29925d086791cf890c96c7f7670079e32
parent2f5af2c962c05b789bdd65b46c74711e903f86d0
x86/shadow: Correct guest behaviour when creating PTEs above maxphysaddr

XSA-173 (c/s 8b1764833) introduces gfn_bits, and an upper limit which might be
lower than the real maxphysaddr, to avoid overflowing the superpage shadow
backpointer.

However, plenty of hardware has a physical address width less that 44 bits,
and the code added in shadow_domain_init() is a straight assignment.  This
causes gfn_bits to be increased beyond the physical address width on most
Intel consumer hardware (typically a width of 39, which is the number reported
to the guest via CPUID).

If the guest intentionally creates a PTE referencing a physical address
between 39 and 44 bits, the result should be #PF[RSVD] for using the virtual
address.  However, the shadow code accepts the PTE, shadows it, and the
virtual address works normally.

Introduce paging_max_paddr_bits() to calculate the largest guest physical
address supportable by the paging infrastructure, and update
recalculate_cpuid_policy() to take this into account when clamping the guests
cpuid_policy to reality.

There is an existing gfn_valid() in guest_pt.h but it is unused in the
codebase.  Repurpose it to perform a guest-specific maxphysaddr check, which
replaces the users of gfn_bits.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: George Dunlap <george.dunlap@citrix.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Tim Deegan <tim@xen.org>
xen/arch/x86/cpuid.c
xen/arch/x86/hvm/vmx/vvmx.c
xen/arch/x86/mm/guest_walk.c
xen/arch/x86/mm/hap/hap.c
xen/arch/x86/mm/p2m.c
xen/arch/x86/mm/shadow/common.c
xen/arch/x86/mm/shadow/multi.c
xen/include/asm-x86/domain.h
xen/include/asm-x86/guest_pt.h
xen/include/asm-x86/paging.h