Re: [PATCH 03/22] KVM: x86/mmu: adjust MMIO generation bit allocation and allowed mask
From: Huang, Kai
Date: Mon Mar 23 2026 - 23:48:49 EST
> /*
> - * Due to limited space in PTEs, the MMIO generation is a 19 bit subset of
> + * Due to limited space in PTEs, the MMIO generation is an 18 bit subset of
> * the memslots generation and is derived as follows:
Is "a -> an" unintentional change?
> *
> - * Bits 0-7 of the MMIO generation are propagated to spte bits 3-10
> - * Bits 8-18 of the MMIO generation are propagated to spte bits 52-62
> + * Bits 0-6 of the MMIO generation are propagated to spte bits 3-9
> + * Bits 7-17 of the MMIO generation are propagated to spte bits 52-62
> *
> * The KVM_MEMSLOT_GEN_UPDATE_IN_PROGRESS flag is intentionally not included in
> * the MMIO generation number, as doing so would require stealing a bit from
> @@ -111,7 +111,7 @@ static_assert(!(EPT_SPTE_MMU_WRITABLE & SHADOW_ACC_TRACK_SAVED_MASK));
> */
>
> #define MMIO_SPTE_GEN_LOW_START 3
> -#define MMIO_SPTE_GEN_LOW_END 10
> +#define MMIO_SPTE_GEN_LOW_END 9
>
> #define MMIO_SPTE_GEN_HIGH_START 52
> #define MMIO_SPTE_GEN_HIGH_END 62
> @@ -133,7 +133,8 @@ static_assert(!(SPTE_MMU_PRESENT_MASK &
> * and so they're off-limits for generation; additional checks ensure the mask
> * doesn't overlap legal PA bits), and bit 63 (carved out for future usage).
> */
> -#define SPTE_MMIO_ALLOWED_MASK (BIT_ULL(63) | GENMASK_ULL(51, 12) | GENMASK_ULL(2, 0))
> +#define SPTE_MMIO_ALLOWED_MASK (BIT_ULL(63) | GENMASK_ULL(51, 12) | \
> + BIT_ULL(10) | GENMASK_ULL(2, 0))
> static_assert(!(SPTE_MMIO_ALLOWED_MASK &
> (SPTE_MMU_PRESENT_MASK | MMIO_SPTE_GEN_LOW_MASK | MMIO_SPTE_GEN_HIGH_MASK)));
>
> @@ -141,7 +142,7 @@ static_assert(!(SPTE_MMIO_ALLOWED_MASK &
> #define MMIO_SPTE_GEN_HIGH_BITS (MMIO_SPTE_GEN_HIGH_END - MMIO_SPTE_GEN_HIGH_START + 1)
>
> /* remember to adjust the comment above as well if you change these */
> -static_assert(MMIO_SPTE_GEN_LOW_BITS == 8 && MMIO_SPTE_GEN_HIGH_BITS == 11);
> +static_assert(MMIO_SPTE_GEN_LOW_BITS == 7 && MMIO_SPTE_GEN_HIGH_BITS == 11);
>
> #define MMIO_SPTE_GEN_LOW_SHIFT (MMIO_SPTE_GEN_LOW_START - 0)
> #define MMIO_SPTE_GEN_HIGH_SHIFT (MMIO_SPTE_GEN_HIGH_START - MMIO_SPTE_GEN_LOW_BITS)
Besides the changes to MMIO_GEN, the FROZEN_SPTE seems to have bit 10 set:
#define FROZEN_SPTE (SHADOW_NONPRESENT_VALUE | 0x5a0ULL)
When MBEC is enabled, IIUC such SPTE will be treated as present by hardware
if CPU supports execution-only SPTE.
Also, when MBEC is enabled, per SDM if CPU doesn't support execution-only,
an SPTE with bit 0 clear but with bit 10 set will trigger EPT
miscofiguration, rather than EPT violation.
So seems we should exclude bit 10 from FROZEN_SPTE.