Skip to content

Commit 961f844

Browse files
sean-jcbonzini
authored andcommitted
KVM: x86/mmu: Add helpers to do full reserved SPTE checks w/ generic MMU
Extract the reserved SPTE check and print helpers in get_mmio_spte() to new helpers so that KVM can also WARN on reserved badness when making a SPTE. Tag the checking helper with __always_inline to improve the probability of the compiler generating optimal code for the checking loop, e.g. gcc appears to avoid using %rbp when the helper is tagged with a vanilla "inline". No functional change intended. Signed-off-by: Sean Christopherson <seanjc@google.com> Message-Id: <20210622175739.3610207-48-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 36f2678 commit 961f844

2 files changed

Lines changed: 34 additions & 21 deletions

File tree

arch/x86/kvm/mmu/mmu.c

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3594,19 +3594,6 @@ static gpa_t nonpaging_gva_to_gpa_nested(struct kvm_vcpu *vcpu, gpa_t vaddr,
35943594
return vcpu->arch.nested_mmu.translate_gpa(vcpu, vaddr, access, exception);
35953595
}
35963596

3597-
static bool
3598-
__is_rsvd_bits_set(struct rsvd_bits_validate *rsvd_check, u64 pte, int level)
3599-
{
3600-
int bit7 = (pte >> 7) & 1;
3601-
3602-
return pte & rsvd_check->rsvd_bits_mask[bit7][level-1];
3603-
}
3604-
3605-
static bool __is_bad_mt_xwr(struct rsvd_bits_validate *rsvd_check, u64 pte)
3606-
{
3607-
return rsvd_check->bad_mt_xwr & BIT_ULL(pte & 0x3f);
3608-
}
3609-
36103597
static bool mmio_info_in_cache(struct kvm_vcpu *vcpu, u64 addr, bool direct)
36113598
{
36123599
/*
@@ -3684,21 +3671,15 @@ static bool get_mmio_spte(struct kvm_vcpu *vcpu, u64 addr, u64 *sptep)
36843671
rsvd_check = &vcpu->arch.mmu->shadow_zero_check;
36853672

36863673
for (level = root; level >= leaf; level--)
3687-
/*
3688-
* Use a bitwise-OR instead of a logical-OR to aggregate the
3689-
* reserved bit and EPT's invalid memtype/XWR checks to avoid
3690-
* adding a Jcc in the loop.
3691-
*/
3692-
reserved |= __is_bad_mt_xwr(rsvd_check, sptes[level]) |
3693-
__is_rsvd_bits_set(rsvd_check, sptes[level], level);
3674+
reserved |= is_rsvd_spte(rsvd_check, sptes[level], level);
36943675

36953676
if (reserved) {
36963677
pr_err("%s: reserved bits set on MMU-present spte, addr 0x%llx, hierarchy:\n",
36973678
__func__, addr);
36983679
for (level = root; level >= leaf; level--)
36993680
pr_err("------ spte = 0x%llx level = %d, rsvd bits = 0x%llx",
37003681
sptes[level], level,
3701-
rsvd_check->rsvd_bits_mask[(sptes[level] >> 7) & 1][level-1]);
3682+
get_rsvd_bits(rsvd_check, sptes[level], level));
37023683
}
37033684

37043685
return reserved;

arch/x86/kvm/mmu/spte.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,38 @@ static inline bool is_dirty_spte(u64 spte)
293293
return dirty_mask ? spte & dirty_mask : spte & PT_WRITABLE_MASK;
294294
}
295295

296+
static inline u64 get_rsvd_bits(struct rsvd_bits_validate *rsvd_check, u64 pte,
297+
int level)
298+
{
299+
int bit7 = (pte >> 7) & 1;
300+
301+
return rsvd_check->rsvd_bits_mask[bit7][level-1];
302+
}
303+
304+
static inline bool __is_rsvd_bits_set(struct rsvd_bits_validate *rsvd_check,
305+
u64 pte, int level)
306+
{
307+
return pte & get_rsvd_bits(rsvd_check, pte, level);
308+
}
309+
310+
static inline bool __is_bad_mt_xwr(struct rsvd_bits_validate *rsvd_check,
311+
u64 pte)
312+
{
313+
return rsvd_check->bad_mt_xwr & BIT_ULL(pte & 0x3f);
314+
}
315+
316+
static __always_inline bool is_rsvd_spte(struct rsvd_bits_validate *rsvd_check,
317+
u64 spte, int level)
318+
{
319+
/*
320+
* Use a bitwise-OR instead of a logical-OR to aggregate the reserved
321+
* bits and EPT's invalid memtype/XWR checks to avoid an extra Jcc
322+
* (this is extremely unlikely to be short-circuited as true).
323+
*/
324+
return __is_bad_mt_xwr(rsvd_check, spte) |
325+
__is_rsvd_bits_set(rsvd_check, spte, level);
326+
}
327+
296328
static inline bool spte_can_locklessly_be_made_writable(u64 spte)
297329
{
298330
return (spte & shadow_host_writable_mask) &&

0 commit comments

Comments
 (0)