Re: [PATCH 10/22] KVM: x86/mmu: split XS/XU bits for MBEC
From: Huang, Kai
Date: Tue Mar 24 2026 - 06:52:47 EST
On Sat, 2026-03-21 at 01:09 +0100, Paolo Bonzini wrote:
> When EPT is in use, replace ACC_USER_MASK with ACC_USER_EXEC_MASK,
> so that supervisor and user-mode execution can be controlled
> independently (ACC_USER_MASK would not allow a setting similar to
> XU=0 XS=1 W=1 R=1).
>
> Replace shadow_x_mask with shadow_xs_mask/shadow_xu_mask, to allow
> setting XS and XU bits separately in EPT entries.
>
> Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
> ---
> arch/x86/include/asm/vmx.h | 1 +
> arch/x86/kvm/mmu/mmu.c | 15 ++++++++---
> arch/x86/kvm/mmu/mmutrace.h | 6 ++---
> arch/x86/kvm/mmu/paging_tmpl.h | 4 +++
> arch/x86/kvm/mmu/spte.c | 47 ++++++++++++++++++++++------------
> arch/x86/kvm/mmu/spte.h | 8 +++---
> 6 files changed, 55 insertions(+), 26 deletions(-)
>
> diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
> index 4a0804cc7c82..0041f8a77447 100644
> --- a/arch/x86/include/asm/vmx.h
> +++ b/arch/x86/include/asm/vmx.h
> @@ -538,6 +538,7 @@ enum vmcs_field {
> #define VMX_EPT_IPAT_BIT (1ull << 6)
> #define VMX_EPT_ACCESS_BIT (1ull << 8)
> #define VMX_EPT_DIRTY_BIT (1ull << 9)
> +#define VMX_EPT_USER_EXECUTABLE_MASK (1ull << 10)
> #define VMX_EPT_SUPPRESS_VE_BIT (1ull << 63)
> #define VMX_EPT_RWX_MASK (VMX_EPT_READABLE_MASK | \
> VMX_EPT_WRITABLE_MASK | \
Should we include VMX_EPT_USER_EXECUTABLE_MASK to VMX_EPT_RWX_MASK?
[...]
> @@ -496,7 +507,8 @@ void kvm_mmu_set_ept_masks(bool has_ad_bits)
> shadow_accessed_mask = VMX_EPT_ACCESS_BIT;
> shadow_dirty_mask = VMX_EPT_DIRTY_BIT;
> shadow_nx_mask = 0ull;
> - shadow_x_mask = VMX_EPT_EXECUTABLE_MASK;
> + shadow_xs_mask = VMX_EPT_EXECUTABLE_MASK;
> + shadow_xu_mask = VMX_EPT_EXECUTABLE_MASK;
Shouldn't 'shadow_xu_mask' be VMX_EPT_USER_EXECUTABLE_MASK?
Btw, with MBEC it's a bit weird to me that we continue to just use
110 (R=0,W=1,X=1) to trigger EPT misconfig for MMIO caching:
/*
* EPT Misconfigurations are generated if the value of bits 2:0
* of an EPT paging-structure entry is 110b (write/execute).
*/
kvm_mmu_set_mmio_spte_mask(VMX_EPT_MISCONFIG_WX_VALUE,
VMX_EPT_RWX_MASK | VMX_EPT_SUPPRESS_VE_BIT,
0);
Per SDM, R=0 and W=1 is always guaranteed to trigger EPT misconfig (see
30.3.3.1 EPT Misconfigurations). Maybe we can just use that for MMIO
caching?
We can then remove both X and XU bit from mmio_mask too.