[xen stable-4.8] x86/dom0: Fix shadowing of PV guests with 2M superpages

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[xen stable-4.8] x86/dom0: Fix shadowing of PV guests with 2M superpages

patchbot
commit 70294dbe2ad3e50a110b20defe995994976c99c4
Author:     Andrew Cooper <[hidden email]>
AuthorDate: Tue Nov 20 15:59:55 2018 +0100
Commit:     Jan Beulich <[hidden email]>
CommitDate: Tue Nov 20 15:59:55 2018 +0100

    x86/dom0: Fix shadowing of PV guests with 2M superpages
   
    This is a minimal backport of pieces of:
   
     c/s 28d9a9a2d41759b9e5163037b759ac557aea767c
     c/s 4c5d78a10dc89427140a50a1df5a0b8e9f073e82
   
    to fix a PV shadowing problem which I hadn't anticipated at the time these
    fixes were first accepted.
   
    Having opt_allow_superpage disabled causes guest_supports_superpages() to
    return false for PV guests.  Returning false causes guest_walk_tables() to
    ignore L2 superpages, and read under them.
   
    This ignoring behaviour is correct for 2-level paging when CR4.PSE is clear,
    but isn't correct for 3- or 4-level paging.
   
    When opt_allow_superpage is clear, PV domU's can't have superpages, but dom0
    will still have its initial P2M constructed with 2M superpages.
   
    The end result is that, if dom0 becomes shadowed (e.g. PV-L1TF), the next
    memory access touching a P2M superpage will cause the shadow code to read
    under the P2M superpage and attempt to shadow junk.
   
    Signed-off-by: Andrew Cooper <[hidden email]>
    Reviewed-by: Jan Beulich <[hidden email]>
---
 xen/arch/x86/mm/guest_walk.c   | 15 ++++++++++++++-
 xen/include/asm-x86/guest_pt.h | 20 ++++++++++++--------
 2 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/xen/arch/x86/mm/guest_walk.c b/xen/arch/x86/mm/guest_walk.c
index 868e9090e5..f4c992110e 100644
--- a/xen/arch/x86/mm/guest_walk.c
+++ b/xen/arch/x86/mm/guest_walk.c
@@ -324,9 +324,20 @@ guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m,
         rc |= _PAGE_PRESENT;
         goto out;
     }
+
+    /*
+     * In 2-level paging without CR0.PSE, there are no reserved bits, and the
+     * PAT/PSE bit is ignored.
+     */
+    if ( GUEST_PAGING_LEVELS == 2 && !guest_supports_superpages(v) )
+    {
+        gw->l2e.l2 &= ~_PAGE_PSE;
+        gflags &= ~_PAGE_PSE;
+    }
+
     rc |= ((gflags & mflags) ^ mflags);
 
-    pse2M = (gflags & _PAGE_PSE) && guest_supports_superpages(v);
+    pse2M = !!(gflags & _PAGE_PSE);
 
     if ( pse2M )
     {
@@ -348,6 +359,8 @@ guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m,
             /* _PAGE_PSE_PAT not set: remove _PAGE_PAT from flags. */
             flags &= ~_PAGE_PAT;
 
+        if ( !guest_supports_superpages(v) )
+            rc |= _PAGE_PSE | _PAGE_INVALID_BIT;
         if ( gfn_x(start) & GUEST_L2_GFN_MASK & ~0x1 )
             rc |= _PAGE_INVALID_BITS;
 
diff --git a/xen/include/asm-x86/guest_pt.h b/xen/include/asm-x86/guest_pt.h
index 79ed4ff561..6bdb7ca1c1 100644
--- a/xen/include/asm-x86/guest_pt.h
+++ b/xen/include/asm-x86/guest_pt.h
@@ -179,14 +179,18 @@ static inline guest_l4e_t guest_l4e_from_gfn(gfn_t gfn, u32 flags)
 static inline int
 guest_supports_superpages(struct vcpu *v)
 {
-    /* The _PAGE_PSE bit must be honoured in HVM guests, whenever
-     * CR4.PSE is set or the guest is in PAE or long mode.
-     * It's also used in the dummy PT for vcpus with CR4.PG cleared. */
-    return (is_pv_vcpu(v)
-            ? opt_allow_superpage
-            : (GUEST_PAGING_LEVELS != 2
-               || !hvm_paging_enabled(v)
-               || (v->arch.hvm_vcpu.guest_cr[4] & X86_CR4_PSE)));
+    /*
+     * PV guests use Xen's paging settings.  Being 4-level, 2M
+     * superpages are unconditionally supported.
+     *
+     * The L2 _PAGE_PSE bit must be honoured in HVM guests, whenever
+     * CR4.PSE is set or the guest is in PAE or long mode.
+     * It's also used in the dummy PT for vcpus with CR0.PG cleared.
+     */
+    return (is_pv_vcpu(v) ||
+            GUEST_PAGING_LEVELS != 2 ||
+            !hvm_paging_enabled(v) ||
+            (v->arch.hvm_vcpu.guest_cr[4] & X86_CR4_PSE));
 }
 
 static inline int
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.8

_______________________________________________
Xen-changelog mailing list
[hidden email]
https://lists.xenproject.org/xen-changelog