Merge tag 'lkdtm-next' of https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux...
[linux-2.6-microblaze.git] / arch / x86 / kvm / mmu.h
index e6cae6f..a335e7f 100644 (file)
@@ -65,6 +65,30 @@ static __always_inline u64 rsvd_bits(int s, int e)
        return ((2ULL << (e - s)) - 1) << s;
 }
 
+/*
+ * The number of non-reserved physical address bits irrespective of features
+ * that repurpose legal bits, e.g. MKTME.
+ */
+extern u8 __read_mostly shadow_phys_bits;
+
+static inline gfn_t kvm_mmu_max_gfn(void)
+{
+       /*
+        * Note that this uses the host MAXPHYADDR, not the guest's.
+        * EPT/NPT cannot support GPAs that would exceed host.MAXPHYADDR;
+        * assuming KVM is running on bare metal, guest accesses beyond
+        * host.MAXPHYADDR will hit a #PF(RSVD) and never cause a vmexit
+        * (either EPT Violation/Misconfig or #NPF), and so KVM will never
+        * install a SPTE for such addresses.  If KVM is running as a VM
+        * itself, on the other hand, it might see a MAXPHYADDR that is less
+        * than hardware's real MAXPHYADDR.  Using the host MAXPHYADDR
+        * disallows such SPTEs entirely and simplifies the TDP MMU.
+        */
+       int max_gpa_bits = likely(tdp_enabled) ? shadow_phys_bits : 52;
+
+       return (1ULL << (max_gpa_bits - PAGE_SHIFT)) - 1;
+}
+
 void kvm_mmu_set_mmio_spte_mask(u64 mmio_value, u64 mmio_mask, u64 access_mask);
 void kvm_mmu_set_ept_masks(bool has_ad_bits, bool has_exec_only);