On Thu, Jan 23, 2020 at 12:50 AM Paolo Bonzini <pbonzini@xxxxxxxxxx> wrote: > > 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: 6eeb4ef049e7 ("KVM: x86: assign two bits to track SPTE kinds") > Reported-by: Ben Gardon <bgardon@xxxxxxxxxx> > Cc: stable@xxxxxxxxxxxxxxx > Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> Reviewed-by: Ben Gardon <bgardon@xxxxxxxxxx> > --- > arch/x86/kvm/mmu/mmu.c | 10 +++++----- > 1 file changed, 5 insertions(+), 5 deletions(-) > > diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c > index 57e4dbddba72..b9052c7ba43d 100644 > --- a/arch/x86/kvm/mmu/mmu.c > +++ b/arch/x86/kvm/mmu/mmu.c > @@ -418,22 +418,24 @@ static inline bool is_access_track_spte(u64 spte) > * requires a full MMU zap). The flag is instead explicitly queried when > * checking for MMIO spte cache hits. > */ > -#define MMIO_SPTE_GEN_MASK GENMASK_ULL(18, 0) > +#define MMIO_SPTE_GEN_MASK GENMASK_ULL(17, 0) > > #define MMIO_SPTE_GEN_LOW_START 3 > #define MMIO_SPTE_GEN_LOW_END 11 > #define MMIO_SPTE_GEN_LOW_MASK GENMASK_ULL(MMIO_SPTE_GEN_LOW_END, \ > MMIO_SPTE_GEN_LOW_START) > > -#define MMIO_SPTE_GEN_HIGH_START 52 > -#define MMIO_SPTE_GEN_HIGH_END 61 > +#define MMIO_SPTE_GEN_HIGH_START PT64_SECOND_AVAIL_BITS_SHIFT > +#define MMIO_SPTE_GEN_HIGH_END 62 > #define MMIO_SPTE_GEN_HIGH_MASK GENMASK_ULL(MMIO_SPTE_GEN_HIGH_END, \ > MMIO_SPTE_GEN_HIGH_START) > + > static u64 generation_mmio_spte_mask(u64 gen) > { > u64 mask; > > WARN_ON(gen & ~MMIO_SPTE_GEN_MASK); > + BUILD_BUG_ON((MMIO_SPTE_GEN_HIGH_MASK | MMIO_SPTE_GEN_LOW_MASK) & SPTE_SPECIAL_MASK); > > mask = (gen << MMIO_SPTE_GEN_LOW_START) & MMIO_SPTE_GEN_LOW_MASK; > mask |= (gen << MMIO_SPTE_GEN_HIGH_START) & MMIO_SPTE_GEN_HIGH_MASK; > @@ -444,8 +446,6 @@ static u64 get_mmio_spte_generation(u64 spte) > { > u64 gen; > > - spte &= ~shadow_mmio_mask; > - > gen = (spte & MMIO_SPTE_GEN_LOW_MASK) >> MMIO_SPTE_GEN_LOW_START; > gen |= (spte & MMIO_SPTE_GEN_HIGH_MASK) >> MMIO_SPTE_GEN_HIGH_START; > return gen; > -- > 1.8.3.1 >