Skip to content

Commit 56871d4

Browse files
committed
KVM: x86: fix overlap between SPTE_MMIO_MASK and generation
The SPTE_MMIO_MASK overlaps with the bits used to track MMIO generation number. A high enough generation number would overwrite the SPTE_SPECIAL_MASK region and cause the MMIO SPTE to be misinterpreted. Likewise, setting bits 52 and 53 would also cause an incorrect generation number to be read from the PTE, though this was partially mitigated by the (useless if it weren't for the bug) removal of SPTE_SPECIAL_MASK from the spte in get_mmio_spte_generation. Drop that removal, and replace it with a compile-time assertion. Fixes: 6eeb4ef ("KVM: x86: assign two bits to track SPTE kinds") Reported-by: Ben Gardon <bgardon@google.com> Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 09cbcef commit 56871d4

File tree

1 file changed

+5
-5
lines changed

1 file changed

+5
-5
lines changed

arch/x86/kvm/mmu/mmu.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -418,22 +418,24 @@ static inline bool is_access_track_spte(u64 spte)
418418
* requires a full MMU zap). The flag is instead explicitly queried when
419419
* checking for MMIO spte cache hits.
420420
*/
421-
#define MMIO_SPTE_GEN_MASK GENMASK_ULL(18, 0)
421+
#define MMIO_SPTE_GEN_MASK GENMASK_ULL(17, 0)
422422

423423
#define MMIO_SPTE_GEN_LOW_START 3
424424
#define MMIO_SPTE_GEN_LOW_END 11
425425
#define MMIO_SPTE_GEN_LOW_MASK GENMASK_ULL(MMIO_SPTE_GEN_LOW_END, \
426426
MMIO_SPTE_GEN_LOW_START)
427427

428-
#define MMIO_SPTE_GEN_HIGH_START 52
429-
#define MMIO_SPTE_GEN_HIGH_END 61
428+
#define MMIO_SPTE_GEN_HIGH_START PT64_SECOND_AVAIL_BITS_SHIFT
429+
#define MMIO_SPTE_GEN_HIGH_END 62
430430
#define MMIO_SPTE_GEN_HIGH_MASK GENMASK_ULL(MMIO_SPTE_GEN_HIGH_END, \
431431
MMIO_SPTE_GEN_HIGH_START)
432+
432433
static u64 generation_mmio_spte_mask(u64 gen)
433434
{
434435
u64 mask;
435436

436437
WARN_ON(gen & ~MMIO_SPTE_GEN_MASK);
438+
BUILD_BUG_ON((MMIO_SPTE_GEN_HIGH_MASK | MMIO_SPTE_GEN_LOW_MASK) & SPTE_SPECIAL_MASK);
437439

438440
mask = (gen << MMIO_SPTE_GEN_LOW_START) & MMIO_SPTE_GEN_LOW_MASK;
439441
mask |= (gen << MMIO_SPTE_GEN_HIGH_START) & MMIO_SPTE_GEN_HIGH_MASK;
@@ -444,8 +446,6 @@ static u64 get_mmio_spte_generation(u64 spte)
444446
{
445447
u64 gen;
446448

447-
spte &= ~shadow_mmio_mask;
448-
449449
gen = (spte & MMIO_SPTE_GEN_LOW_MASK) >> MMIO_SPTE_GEN_LOW_START;
450450
gen |= (spte & MMIO_SPTE_GEN_HIGH_MASK) >> MMIO_SPTE_GEN_HIGH_START;
451451
return gen;

0 commit comments

Comments
 (0)