Skip to content

Commit 6eeb4ef

Browse files
committed
KVM: x86: assign two bits to track SPTE kinds
Currently, we are overloading SPTE_SPECIAL_MASK to mean both "A/D bits unavailable" and MMIO, where the difference between the two is determined by mio_mask and mmio_value. However, the next patch will need two bits to distinguish availability of A/D bits from write protection. So, while at it give MMIO its own bit pattern, and move the two bits from bit 62 to bits 52..53 since Intel is allocating EPT page table bits from the top. Reviewed-by: Junaid Shahid <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 504ce19 commit 6eeb4ef

File tree

2 files changed

+18
-17
lines changed

2 files changed

+18
-17
lines changed

arch/x86/include/asm/kvm_host.h

-7
Original file line numberDiff line numberDiff line change
@@ -219,13 +219,6 @@ enum {
219219
PFERR_WRITE_MASK | \
220220
PFERR_PRESENT_MASK)
221221

222-
/*
223-
* The mask used to denote special SPTEs, which can be either MMIO SPTEs or
224-
* Access Tracking SPTEs. We use bit 62 instead of bit 63 to avoid conflicting
225-
* with the SVE bit in EPT PTEs.
226-
*/
227-
#define SPTE_SPECIAL_MASK (1ULL << 62)
228-
229222
/* apic attention bits */
230223
#define KVM_APIC_CHECK_VAPIC 0
231224
/*

arch/x86/kvm/mmu.c

+18-10
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,16 @@ module_param(dbg, bool, 0644);
8383
#define PTE_PREFETCH_NUM 8
8484

8585
#define PT_FIRST_AVAIL_BITS_SHIFT 10
86-
#define PT64_SECOND_AVAIL_BITS_SHIFT 52
86+
#define PT64_SECOND_AVAIL_BITS_SHIFT 54
87+
88+
/*
89+
* The mask used to denote special SPTEs, which can be either MMIO SPTEs or
90+
* Access Tracking SPTEs.
91+
*/
92+
#define SPTE_SPECIAL_MASK (3ULL << 52)
93+
#define SPTE_AD_ENABLED_MASK (0ULL << 52)
94+
#define SPTE_AD_DISABLED_MASK (1ULL << 52)
95+
#define SPTE_MMIO_MASK (3ULL << 52)
8796

8897
#define PT64_LEVEL_BITS 9
8998

@@ -219,12 +228,11 @@ static u64 __read_mostly shadow_present_mask;
219228
static u64 __read_mostly shadow_me_mask;
220229

221230
/*
222-
* SPTEs used by MMUs without A/D bits are marked with shadow_acc_track_value.
223-
* Non-present SPTEs with shadow_acc_track_value set are in place for access
224-
* tracking.
231+
* SPTEs used by MMUs without A/D bits are marked with SPTE_AD_DISABLED_MASK;
232+
* shadow_acc_track_mask is the set of bits to be cleared in non-accessed
233+
* pages.
225234
*/
226235
static u64 __read_mostly shadow_acc_track_mask;
227-
static const u64 shadow_acc_track_value = SPTE_SPECIAL_MASK;
228236

229237
/*
230238
* The mask/shift to use for saving the original R/X bits when marking the PTE
@@ -304,7 +312,7 @@ void kvm_mmu_set_mmio_spte_mask(u64 mmio_mask, u64 mmio_value, u64 access_mask)
304312
{
305313
BUG_ON((u64)(unsigned)access_mask != access_mask);
306314
BUG_ON((mmio_mask & mmio_value) != mmio_value);
307-
shadow_mmio_value = mmio_value | SPTE_SPECIAL_MASK;
315+
shadow_mmio_value = mmio_value | SPTE_MMIO_MASK;
308316
shadow_mmio_mask = mmio_mask | SPTE_SPECIAL_MASK;
309317
shadow_mmio_access_mask = access_mask;
310318
}
@@ -323,7 +331,7 @@ static inline bool sp_ad_disabled(struct kvm_mmu_page *sp)
323331
static inline bool spte_ad_enabled(u64 spte)
324332
{
325333
MMU_WARN_ON(is_mmio_spte(spte));
326-
return !(spte & shadow_acc_track_value);
334+
return (spte & SPTE_SPECIAL_MASK) == SPTE_AD_ENABLED_MASK;
327335
}
328336

329337
static inline u64 spte_shadow_accessed_mask(u64 spte)
@@ -461,7 +469,7 @@ void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask,
461469
{
462470
BUG_ON(!dirty_mask != !accessed_mask);
463471
BUG_ON(!accessed_mask && !acc_track_mask);
464-
BUG_ON(acc_track_mask & shadow_acc_track_value);
472+
BUG_ON(acc_track_mask & SPTE_SPECIAL_MASK);
465473

466474
shadow_user_mask = user_mask;
467475
shadow_accessed_mask = accessed_mask;
@@ -2622,7 +2630,7 @@ static void link_shadow_page(struct kvm_vcpu *vcpu, u64 *sptep,
26222630
shadow_user_mask | shadow_x_mask | shadow_me_mask;
26232631

26242632
if (sp_ad_disabled(sp))
2625-
spte |= shadow_acc_track_value;
2633+
spte |= SPTE_AD_DISABLED_MASK;
26262634
else
26272635
spte |= shadow_accessed_mask;
26282636

@@ -2968,7 +2976,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
29682976

29692977
sp = page_header(__pa(sptep));
29702978
if (sp_ad_disabled(sp))
2971-
spte |= shadow_acc_track_value;
2979+
spte |= SPTE_AD_DISABLED_MASK;
29722980

29732981
/*
29742982
* For the EPT case, shadow_present_mask is 0 if hardware

0 commit comments

Comments
 (0)