]> xenbits.xensource.com Git - people/tklengyel/xen.git/commitdiff
x86/shadow: suppress "fast fault path" optimization when running virtualized
authorJan Beulich <jbeulich@suse.com>
Mon, 8 Mar 2021 09:41:50 +0000 (10:41 +0100)
committerJan Beulich <jbeulich@suse.com>
Mon, 8 Mar 2021 09:41:50 +0000 (10:41 +0100)
We can't make correctness of our own behavior dependent upon a
hypervisor underneath us correctly telling us the true physical address
with hardware uses. Without knowing this, we can't be certain reserved
bit faults can actually be observed. Therefore, besides evaluating the
number of address bits when deciding whether to use the optimization,
also check whether we're running virtualized ourselves. (Note that since
we may get migrated when running virtualized, the number of address bits
may also change.)

Requested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
Release-Acked-by: Ian Jackson <iwj@xenproject.org>
xen/arch/x86/mm/shadow/types.h

index 901645560a45b9634d2d40b872b55ae6f5d92c15..27de593d87737d77164f1ab4c824e11c8aab3431 100644 (file)
@@ -282,10 +282,16 @@ static inline shadow_l4e_t shadow_l4e_from_mfn(mfn_t mfn, u32 flags)
  *
  * This is only feasible for PAE and 64bit Xen: 32-bit non-PAE PTEs don't
  * have reserved bits that we can use for this.  And even there it can only
- * be used if the processor doesn't use all 52 address bits.
+ * be used if we can be certain the processor doesn't use all 52 address bits.
  */
 
 #define SH_L1E_MAGIC 0xffffffff00000001ULL
+
+static inline bool sh_have_pte_rsvd_bits(void)
+{
+    return paddr_bits < PADDR_BITS && !cpu_has_hypervisor;
+}
+
 static inline bool sh_l1e_is_magic(shadow_l1e_t sl1e)
 {
     return (sl1e.l1 & SH_L1E_MAGIC) == SH_L1E_MAGIC;
@@ -303,7 +309,7 @@ static inline shadow_l1e_t sh_l1e_gnp(void)
      * On systems with no reserved physical address bits we can't engage the
      * fast fault path.
      */
-    return paddr_bits < PADDR_BITS ? sh_l1e_gnp_raw()
+    return sh_have_pte_rsvd_bits() ? sh_l1e_gnp_raw()
                                    : shadow_l1e_empty();
 }
 
@@ -326,7 +332,7 @@ static inline shadow_l1e_t sh_l1e_mmio(gfn_t gfn, u32 gflags)
 {
     unsigned long gfn_val = MASK_INSR(gfn_x(gfn), SH_L1E_MMIO_GFN_MASK);
 
-    if ( paddr_bits >= PADDR_BITS ||
+    if ( !sh_have_pte_rsvd_bits() ||
          gfn_x(gfn) != MASK_EXTR(gfn_val, SH_L1E_MMIO_GFN_MASK) )
         return shadow_l1e_empty();