|
@@ -249,6 +249,17 @@ static u64 __read_mostly shadow_nonpresent_or_rsvd_mask;
|
|
|
*/
|
|
|
static const u64 shadow_nonpresent_or_rsvd_mask_len = 5;
|
|
|
|
|
|
+/*
|
|
|
+ * In some cases, we need to preserve the GFN of a non-present or reserved
|
|
|
+ * SPTE when we usurp the upper five bits of the physical address space to
|
|
|
+ * defend against L1TF, e.g. for MMIO SPTEs. To preserve the GFN, we'll
|
|
|
+ * shift bits of the GFN that overlap with shadow_nonpresent_or_rsvd_mask
|
|
|
+ * left into the reserved bits, i.e. the GFN in the SPTE will be split into
|
|
|
+ * high and low parts. This mask covers the lower bits of the GFN.
|
|
|
+ */
|
|
|
+static u64 __read_mostly shadow_nonpresent_or_rsvd_lower_gfn_mask;
|
|
|
+
|
|
|
+
|
|
|
static void mmu_spte_set(u64 *sptep, u64 spte);
|
|
|
static union kvm_mmu_page_role
|
|
|
kvm_mmu_calc_root_page_role(struct kvm_vcpu *vcpu);
|
|
@@ -357,9 +368,7 @@ static bool is_mmio_spte(u64 spte)
|
|
|
|
|
|
static gfn_t get_mmio_spte_gfn(u64 spte)
|
|
|
{
|
|
|
- u64 mask = generation_mmio_spte_mask(MMIO_GEN_MASK) | shadow_mmio_mask |
|
|
|
- shadow_nonpresent_or_rsvd_mask;
|
|
|
- u64 gpa = spte & ~mask;
|
|
|
+ u64 gpa = spte & shadow_nonpresent_or_rsvd_lower_gfn_mask;
|
|
|
|
|
|
gpa |= (spte >> shadow_nonpresent_or_rsvd_mask_len)
|
|
|
& shadow_nonpresent_or_rsvd_mask;
|
|
@@ -423,6 +432,8 @@ EXPORT_SYMBOL_GPL(kvm_mmu_set_mask_ptes);
|
|
|
|
|
|
static void kvm_mmu_reset_all_pte_masks(void)
|
|
|
{
|
|
|
+ u8 low_phys_bits;
|
|
|
+
|
|
|
shadow_user_mask = 0;
|
|
|
shadow_accessed_mask = 0;
|
|
|
shadow_dirty_mask = 0;
|
|
@@ -437,12 +448,17 @@ static void kvm_mmu_reset_all_pte_masks(void)
|
|
|
* appropriate mask to guard against L1TF attacks. Otherwise, it is
|
|
|
* assumed that the CPU is not vulnerable to L1TF.
|
|
|
*/
|
|
|
+ low_phys_bits = boot_cpu_data.x86_phys_bits;
|
|
|
if (boot_cpu_data.x86_phys_bits <
|
|
|
- 52 - shadow_nonpresent_or_rsvd_mask_len)
|
|
|
+ 52 - shadow_nonpresent_or_rsvd_mask_len) {
|
|
|
shadow_nonpresent_or_rsvd_mask =
|
|
|
rsvd_bits(boot_cpu_data.x86_phys_bits -
|
|
|
shadow_nonpresent_or_rsvd_mask_len,
|
|
|
boot_cpu_data.x86_phys_bits - 1);
|
|
|
+ low_phys_bits -= shadow_nonpresent_or_rsvd_mask_len;
|
|
|
+ }
|
|
|
+ shadow_nonpresent_or_rsvd_lower_gfn_mask =
|
|
|
+ GENMASK_ULL(low_phys_bits - 1, PAGE_SHIFT);
|
|
|
}
|
|
|
|
|
|
static int is_cpuid_PSE36(void)
|