18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Kernel-based Virtual Machine driver for Linux 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Macros and functions to access KVM PTEs (also known as SPTEs) 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Copyright (C) 2006 Qumranet, Inc. 88c2ecf20Sopenharmony_ci * Copyright 2020 Red Hat, Inc. and/or its affiliates. 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <linux/kvm_host.h> 138c2ecf20Sopenharmony_ci#include "mmu.h" 148c2ecf20Sopenharmony_ci#include "mmu_internal.h" 158c2ecf20Sopenharmony_ci#include "x86.h" 168c2ecf20Sopenharmony_ci#include "spte.h" 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include <asm/e820/api.h> 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ciu64 __read_mostly shadow_nx_mask; 218c2ecf20Sopenharmony_ciu64 __read_mostly shadow_x_mask; /* mutual exclusive with nx_mask */ 228c2ecf20Sopenharmony_ciu64 __read_mostly shadow_user_mask; 238c2ecf20Sopenharmony_ciu64 __read_mostly shadow_accessed_mask; 248c2ecf20Sopenharmony_ciu64 __read_mostly shadow_dirty_mask; 258c2ecf20Sopenharmony_ciu64 __read_mostly shadow_mmio_value; 268c2ecf20Sopenharmony_ciu64 __read_mostly shadow_mmio_access_mask; 278c2ecf20Sopenharmony_ciu64 __read_mostly shadow_present_mask; 288c2ecf20Sopenharmony_ciu64 __read_mostly shadow_me_mask; 298c2ecf20Sopenharmony_ciu64 __read_mostly shadow_acc_track_mask; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ciu64 __read_mostly shadow_nonpresent_or_rsvd_mask; 328c2ecf20Sopenharmony_ciu64 __read_mostly shadow_nonpresent_or_rsvd_lower_gfn_mask; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ciu8 __read_mostly shadow_phys_bits; 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistatic u64 generation_mmio_spte_mask(u64 gen) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci u64 mask; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci WARN_ON(gen & ~MMIO_SPTE_GEN_MASK); 418c2ecf20Sopenharmony_ci BUILD_BUG_ON((MMIO_SPTE_GEN_HIGH_MASK | MMIO_SPTE_GEN_LOW_MASK) & SPTE_SPECIAL_MASK); 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci mask = (gen << MMIO_SPTE_GEN_LOW_SHIFT) & MMIO_SPTE_GEN_LOW_MASK; 448c2ecf20Sopenharmony_ci mask |= (gen << MMIO_SPTE_GEN_HIGH_SHIFT) & MMIO_SPTE_GEN_HIGH_MASK; 458c2ecf20Sopenharmony_ci return mask; 468c2ecf20Sopenharmony_ci} 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ciu64 make_mmio_spte(struct kvm_vcpu *vcpu, u64 gfn, unsigned int access) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci u64 gen = kvm_vcpu_memslots(vcpu)->generation & MMIO_SPTE_GEN_MASK; 518c2ecf20Sopenharmony_ci u64 mask = generation_mmio_spte_mask(gen); 528c2ecf20Sopenharmony_ci u64 gpa = gfn << PAGE_SHIFT; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci access &= shadow_mmio_access_mask; 558c2ecf20Sopenharmony_ci mask |= shadow_mmio_value | access; 568c2ecf20Sopenharmony_ci mask |= gpa | shadow_nonpresent_or_rsvd_mask; 578c2ecf20Sopenharmony_ci mask |= (gpa & shadow_nonpresent_or_rsvd_mask) 588c2ecf20Sopenharmony_ci << SHADOW_NONPRESENT_OR_RSVD_MASK_LEN; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci return mask; 618c2ecf20Sopenharmony_ci} 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistatic bool kvm_is_mmio_pfn(kvm_pfn_t pfn) 648c2ecf20Sopenharmony_ci{ 658c2ecf20Sopenharmony_ci if (pfn_valid(pfn)) 668c2ecf20Sopenharmony_ci return !is_zero_pfn(pfn) && PageReserved(pfn_to_page(pfn)) && 678c2ecf20Sopenharmony_ci /* 688c2ecf20Sopenharmony_ci * Some reserved pages, such as those from NVDIMM 698c2ecf20Sopenharmony_ci * DAX devices, are not for MMIO, and can be mapped 708c2ecf20Sopenharmony_ci * with cached memory type for better performance. 718c2ecf20Sopenharmony_ci * However, the above check misconceives those pages 728c2ecf20Sopenharmony_ci * as MMIO, and results in KVM mapping them with UC 738c2ecf20Sopenharmony_ci * memory type, which would hurt the performance. 748c2ecf20Sopenharmony_ci * Therefore, we check the host memory type in addition 758c2ecf20Sopenharmony_ci * and only treat UC/UC-/WC pages as MMIO. 768c2ecf20Sopenharmony_ci */ 778c2ecf20Sopenharmony_ci (!pat_enabled() || pat_pfn_immune_to_uc_mtrr(pfn)); 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci return !e820__mapped_raw_any(pfn_to_hpa(pfn), 808c2ecf20Sopenharmony_ci pfn_to_hpa(pfn + 1) - 1, 818c2ecf20Sopenharmony_ci E820_TYPE_RAM); 828c2ecf20Sopenharmony_ci} 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ciint make_spte(struct kvm_vcpu *vcpu, unsigned int pte_access, int level, 858c2ecf20Sopenharmony_ci gfn_t gfn, kvm_pfn_t pfn, u64 old_spte, bool speculative, 868c2ecf20Sopenharmony_ci bool can_unsync, bool host_writable, bool ad_disabled, 878c2ecf20Sopenharmony_ci u64 *new_spte) 888c2ecf20Sopenharmony_ci{ 898c2ecf20Sopenharmony_ci u64 spte = 0; 908c2ecf20Sopenharmony_ci int ret = 0; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci if (ad_disabled) 938c2ecf20Sopenharmony_ci spte |= SPTE_AD_DISABLED_MASK; 948c2ecf20Sopenharmony_ci else if (kvm_vcpu_ad_need_write_protect(vcpu)) 958c2ecf20Sopenharmony_ci spte |= SPTE_AD_WRPROT_ONLY_MASK; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci /* 988c2ecf20Sopenharmony_ci * For the EPT case, shadow_present_mask is 0 if hardware 998c2ecf20Sopenharmony_ci * supports exec-only page table entries. In that case, 1008c2ecf20Sopenharmony_ci * ACC_USER_MASK and shadow_user_mask are used to represent 1018c2ecf20Sopenharmony_ci * read access. See FNAME(gpte_access) in paging_tmpl.h. 1028c2ecf20Sopenharmony_ci */ 1038c2ecf20Sopenharmony_ci spte |= shadow_present_mask; 1048c2ecf20Sopenharmony_ci if (!speculative) 1058c2ecf20Sopenharmony_ci spte |= spte_shadow_accessed_mask(spte); 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci if (level > PG_LEVEL_4K && (pte_access & ACC_EXEC_MASK) && 1088c2ecf20Sopenharmony_ci is_nx_huge_page_enabled()) { 1098c2ecf20Sopenharmony_ci pte_access &= ~ACC_EXEC_MASK; 1108c2ecf20Sopenharmony_ci } 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci if (pte_access & ACC_EXEC_MASK) 1138c2ecf20Sopenharmony_ci spte |= shadow_x_mask; 1148c2ecf20Sopenharmony_ci else 1158c2ecf20Sopenharmony_ci spte |= shadow_nx_mask; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci if (pte_access & ACC_USER_MASK) 1188c2ecf20Sopenharmony_ci spte |= shadow_user_mask; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci if (level > PG_LEVEL_4K) 1218c2ecf20Sopenharmony_ci spte |= PT_PAGE_SIZE_MASK; 1228c2ecf20Sopenharmony_ci if (tdp_enabled) 1238c2ecf20Sopenharmony_ci spte |= kvm_x86_ops.get_mt_mask(vcpu, gfn, 1248c2ecf20Sopenharmony_ci kvm_is_mmio_pfn(pfn)); 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci if (host_writable) 1278c2ecf20Sopenharmony_ci spte |= SPTE_HOST_WRITEABLE; 1288c2ecf20Sopenharmony_ci else 1298c2ecf20Sopenharmony_ci pte_access &= ~ACC_WRITE_MASK; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci if (!kvm_is_mmio_pfn(pfn)) 1328c2ecf20Sopenharmony_ci spte |= shadow_me_mask; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci spte |= (u64)pfn << PAGE_SHIFT; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci if (pte_access & ACC_WRITE_MASK) { 1378c2ecf20Sopenharmony_ci spte |= PT_WRITABLE_MASK | SPTE_MMU_WRITEABLE; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci /* 1408c2ecf20Sopenharmony_ci * Optimization: for pte sync, if spte was writable the hash 1418c2ecf20Sopenharmony_ci * lookup is unnecessary (and expensive). Write protection 1428c2ecf20Sopenharmony_ci * is responsibility of mmu_get_page / kvm_sync_page. 1438c2ecf20Sopenharmony_ci * Same reasoning can be applied to dirty page accounting. 1448c2ecf20Sopenharmony_ci */ 1458c2ecf20Sopenharmony_ci if (!can_unsync && is_writable_pte(old_spte)) 1468c2ecf20Sopenharmony_ci goto out; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci if (mmu_need_write_protect(vcpu, gfn, can_unsync)) { 1498c2ecf20Sopenharmony_ci pgprintk("%s: found shadow page for %llx, marking ro\n", 1508c2ecf20Sopenharmony_ci __func__, gfn); 1518c2ecf20Sopenharmony_ci ret |= SET_SPTE_WRITE_PROTECTED_PT; 1528c2ecf20Sopenharmony_ci pte_access &= ~ACC_WRITE_MASK; 1538c2ecf20Sopenharmony_ci spte &= ~(PT_WRITABLE_MASK | SPTE_MMU_WRITEABLE); 1548c2ecf20Sopenharmony_ci } 1558c2ecf20Sopenharmony_ci } 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci if (pte_access & ACC_WRITE_MASK) 1588c2ecf20Sopenharmony_ci spte |= spte_shadow_dirty_mask(spte); 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci if (speculative) 1618c2ecf20Sopenharmony_ci spte = mark_spte_for_access_track(spte); 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ciout: 1648c2ecf20Sopenharmony_ci *new_spte = spte; 1658c2ecf20Sopenharmony_ci return ret; 1668c2ecf20Sopenharmony_ci} 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ciu64 make_nonleaf_spte(u64 *child_pt, bool ad_disabled) 1698c2ecf20Sopenharmony_ci{ 1708c2ecf20Sopenharmony_ci u64 spte; 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci spte = __pa(child_pt) | shadow_present_mask | PT_WRITABLE_MASK | 1738c2ecf20Sopenharmony_ci shadow_user_mask | shadow_x_mask | shadow_me_mask; 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci if (ad_disabled) 1768c2ecf20Sopenharmony_ci spte |= SPTE_AD_DISABLED_MASK; 1778c2ecf20Sopenharmony_ci else 1788c2ecf20Sopenharmony_ci spte |= shadow_accessed_mask; 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci return spte; 1818c2ecf20Sopenharmony_ci} 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ciu64 kvm_mmu_changed_pte_notifier_make_spte(u64 old_spte, kvm_pfn_t new_pfn) 1848c2ecf20Sopenharmony_ci{ 1858c2ecf20Sopenharmony_ci u64 new_spte; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci new_spte = old_spte & ~PT64_BASE_ADDR_MASK; 1888c2ecf20Sopenharmony_ci new_spte |= (u64)new_pfn << PAGE_SHIFT; 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci new_spte &= ~PT_WRITABLE_MASK; 1918c2ecf20Sopenharmony_ci new_spte &= ~SPTE_HOST_WRITEABLE; 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci new_spte = mark_spte_for_access_track(new_spte); 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci return new_spte; 1968c2ecf20Sopenharmony_ci} 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_cistatic u8 kvm_get_shadow_phys_bits(void) 1998c2ecf20Sopenharmony_ci{ 2008c2ecf20Sopenharmony_ci /* 2018c2ecf20Sopenharmony_ci * boot_cpu_data.x86_phys_bits is reduced when MKTME or SME are detected 2028c2ecf20Sopenharmony_ci * in CPU detection code, but the processor treats those reduced bits as 2038c2ecf20Sopenharmony_ci * 'keyID' thus they are not reserved bits. Therefore KVM needs to look at 2048c2ecf20Sopenharmony_ci * the physical address bits reported by CPUID. 2058c2ecf20Sopenharmony_ci */ 2068c2ecf20Sopenharmony_ci if (likely(boot_cpu_data.extended_cpuid_level >= 0x80000008)) 2078c2ecf20Sopenharmony_ci return cpuid_eax(0x80000008) & 0xff; 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci /* 2108c2ecf20Sopenharmony_ci * Quite weird to have VMX or SVM but not MAXPHYADDR; probably a VM with 2118c2ecf20Sopenharmony_ci * custom CPUID. Proceed with whatever the kernel found since these features 2128c2ecf20Sopenharmony_ci * aren't virtualizable (SME/SEV also require CPUIDs higher than 0x80000008). 2138c2ecf20Sopenharmony_ci */ 2148c2ecf20Sopenharmony_ci return boot_cpu_data.x86_phys_bits; 2158c2ecf20Sopenharmony_ci} 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ciu64 mark_spte_for_access_track(u64 spte) 2188c2ecf20Sopenharmony_ci{ 2198c2ecf20Sopenharmony_ci if (spte_ad_enabled(spte)) 2208c2ecf20Sopenharmony_ci return spte & ~shadow_accessed_mask; 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci if (is_access_track_spte(spte)) 2238c2ecf20Sopenharmony_ci return spte; 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci /* 2268c2ecf20Sopenharmony_ci * Making an Access Tracking PTE will result in removal of write access 2278c2ecf20Sopenharmony_ci * from the PTE. So, verify that we will be able to restore the write 2288c2ecf20Sopenharmony_ci * access in the fast page fault path later on. 2298c2ecf20Sopenharmony_ci */ 2308c2ecf20Sopenharmony_ci WARN_ONCE((spte & PT_WRITABLE_MASK) && 2318c2ecf20Sopenharmony_ci !spte_can_locklessly_be_made_writable(spte), 2328c2ecf20Sopenharmony_ci "kvm: Writable SPTE is not locklessly dirty-trackable\n"); 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci WARN_ONCE(spte & (SHADOW_ACC_TRACK_SAVED_BITS_MASK << 2358c2ecf20Sopenharmony_ci SHADOW_ACC_TRACK_SAVED_BITS_SHIFT), 2368c2ecf20Sopenharmony_ci "kvm: Access Tracking saved bit locations are not zero\n"); 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci spte |= (spte & SHADOW_ACC_TRACK_SAVED_BITS_MASK) << 2398c2ecf20Sopenharmony_ci SHADOW_ACC_TRACK_SAVED_BITS_SHIFT; 2408c2ecf20Sopenharmony_ci spte &= ~shadow_acc_track_mask; 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci return spte; 2438c2ecf20Sopenharmony_ci} 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_civoid kvm_mmu_set_mmio_spte_mask(u64 mmio_value, u64 access_mask) 2468c2ecf20Sopenharmony_ci{ 2478c2ecf20Sopenharmony_ci BUG_ON((u64)(unsigned)access_mask != access_mask); 2488c2ecf20Sopenharmony_ci WARN_ON(mmio_value & (shadow_nonpresent_or_rsvd_mask << SHADOW_NONPRESENT_OR_RSVD_MASK_LEN)); 2498c2ecf20Sopenharmony_ci WARN_ON(mmio_value & shadow_nonpresent_or_rsvd_lower_gfn_mask); 2508c2ecf20Sopenharmony_ci shadow_mmio_value = mmio_value | SPTE_MMIO_MASK; 2518c2ecf20Sopenharmony_ci shadow_mmio_access_mask = access_mask; 2528c2ecf20Sopenharmony_ci} 2538c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(kvm_mmu_set_mmio_spte_mask); 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci/* 2568c2ecf20Sopenharmony_ci * Sets the shadow PTE masks used by the MMU. 2578c2ecf20Sopenharmony_ci * 2588c2ecf20Sopenharmony_ci * Assumptions: 2598c2ecf20Sopenharmony_ci * - Setting either @accessed_mask or @dirty_mask requires setting both 2608c2ecf20Sopenharmony_ci * - At least one of @accessed_mask or @acc_track_mask must be set 2618c2ecf20Sopenharmony_ci */ 2628c2ecf20Sopenharmony_civoid kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask, 2638c2ecf20Sopenharmony_ci u64 dirty_mask, u64 nx_mask, u64 x_mask, u64 p_mask, 2648c2ecf20Sopenharmony_ci u64 acc_track_mask, u64 me_mask) 2658c2ecf20Sopenharmony_ci{ 2668c2ecf20Sopenharmony_ci BUG_ON(!dirty_mask != !accessed_mask); 2678c2ecf20Sopenharmony_ci BUG_ON(!accessed_mask && !acc_track_mask); 2688c2ecf20Sopenharmony_ci BUG_ON(acc_track_mask & SPTE_SPECIAL_MASK); 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci shadow_user_mask = user_mask; 2718c2ecf20Sopenharmony_ci shadow_accessed_mask = accessed_mask; 2728c2ecf20Sopenharmony_ci shadow_dirty_mask = dirty_mask; 2738c2ecf20Sopenharmony_ci shadow_nx_mask = nx_mask; 2748c2ecf20Sopenharmony_ci shadow_x_mask = x_mask; 2758c2ecf20Sopenharmony_ci shadow_present_mask = p_mask; 2768c2ecf20Sopenharmony_ci shadow_acc_track_mask = acc_track_mask; 2778c2ecf20Sopenharmony_ci shadow_me_mask = me_mask; 2788c2ecf20Sopenharmony_ci} 2798c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(kvm_mmu_set_mask_ptes); 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_civoid kvm_mmu_reset_all_pte_masks(void) 2828c2ecf20Sopenharmony_ci{ 2838c2ecf20Sopenharmony_ci u8 low_phys_bits; 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci shadow_user_mask = 0; 2868c2ecf20Sopenharmony_ci shadow_accessed_mask = 0; 2878c2ecf20Sopenharmony_ci shadow_dirty_mask = 0; 2888c2ecf20Sopenharmony_ci shadow_nx_mask = 0; 2898c2ecf20Sopenharmony_ci shadow_x_mask = 0; 2908c2ecf20Sopenharmony_ci shadow_present_mask = 0; 2918c2ecf20Sopenharmony_ci shadow_acc_track_mask = 0; 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci shadow_phys_bits = kvm_get_shadow_phys_bits(); 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci /* 2968c2ecf20Sopenharmony_ci * If the CPU has 46 or less physical address bits, then set an 2978c2ecf20Sopenharmony_ci * appropriate mask to guard against L1TF attacks. Otherwise, it is 2988c2ecf20Sopenharmony_ci * assumed that the CPU is not vulnerable to L1TF. 2998c2ecf20Sopenharmony_ci * 3008c2ecf20Sopenharmony_ci * Some Intel CPUs address the L1 cache using more PA bits than are 3018c2ecf20Sopenharmony_ci * reported by CPUID. Use the PA width of the L1 cache when possible 3028c2ecf20Sopenharmony_ci * to achieve more effective mitigation, e.g. if system RAM overlaps 3038c2ecf20Sopenharmony_ci * the most significant bits of legal physical address space. 3048c2ecf20Sopenharmony_ci */ 3058c2ecf20Sopenharmony_ci shadow_nonpresent_or_rsvd_mask = 0; 3068c2ecf20Sopenharmony_ci low_phys_bits = boot_cpu_data.x86_phys_bits; 3078c2ecf20Sopenharmony_ci if (boot_cpu_has_bug(X86_BUG_L1TF) && 3088c2ecf20Sopenharmony_ci !WARN_ON_ONCE(boot_cpu_data.x86_cache_bits >= 3098c2ecf20Sopenharmony_ci 52 - SHADOW_NONPRESENT_OR_RSVD_MASK_LEN)) { 3108c2ecf20Sopenharmony_ci low_phys_bits = boot_cpu_data.x86_cache_bits 3118c2ecf20Sopenharmony_ci - SHADOW_NONPRESENT_OR_RSVD_MASK_LEN; 3128c2ecf20Sopenharmony_ci shadow_nonpresent_or_rsvd_mask = 3138c2ecf20Sopenharmony_ci rsvd_bits(low_phys_bits, boot_cpu_data.x86_cache_bits - 1); 3148c2ecf20Sopenharmony_ci } 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci shadow_nonpresent_or_rsvd_lower_gfn_mask = 3178c2ecf20Sopenharmony_ci GENMASK_ULL(low_phys_bits - 1, PAGE_SHIFT); 3188c2ecf20Sopenharmony_ci} 319