lkml.org 
[lkml]   [2023]   [Feb]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v12 026/106] KVM: x86/mmu: Allow non-zero value for non-present SPTE and removed SPTE
    Date
    From: Sean Christopherson <sean.j.christopherson@intel.com>

    For TD guest, the current way to emulate MMIO doesn't work any more, as KVM
    is not able to access the private memory of TD guest and do the emulation.
    Instead, TD guest expects to receive #VE when it accesses the MMIO and then
    it can explicitly make hypercall to KVM to get the expected information.

    To achieve this, the TDX module always enables "EPT-violation #VE" in the
    VMCS control. And accordingly, for the MMIO spte for the shared GPA,
    1. KVM needs to set "suppress #VE" bit for the non-present SPTE so that EPT
    violation happens on TD accessing MMIO range. 2. On EPT violation, KVM
    sets the MMIO spte to clear "suppress #VE" bit so the TD guest can receive
    the #VE instead of EPT misconfigration unlike VMX case. For the shared GPA
    that is not populated yet, EPT violation need to be triggered when TD guest
    accesses such shared GPA. The non-present SPTE value for shared GPA should
    set "suppress #VE" bit.

    Add "suppress #VE" bit (bit 63) to SHADOW_NONPRESENT_VALUE and
    REMOVED_SPTE. Unconditionally set the "suppress #VE" bit (which is bit 63)
    for both AMD and Intel as: 1) AMD hardware doesn't use this bit when
    present bit is off; 2) for normal VMX guest, KVM never enables the
    "EPT-violation #VE" in VMCS control and "suppress #VE" bit is ignored by
    hardware.

    Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
    Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
    ---
    arch/x86/kvm/mmu/spte.h | 15 ++++++++++++++-
    1 file changed, 14 insertions(+), 1 deletion(-)

    diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h
    index f190eaf6b2b5..471378ee9071 100644
    --- a/arch/x86/kvm/mmu/spte.h
    +++ b/arch/x86/kvm/mmu/spte.h
    @@ -148,7 +148,20 @@ static_assert(MMIO_SPTE_GEN_LOW_BITS == 8 && MMIO_SPTE_GEN_HIGH_BITS == 11);

    #define MMIO_SPTE_GEN_MASK GENMASK_ULL(MMIO_SPTE_GEN_LOW_BITS + MMIO_SPTE_GEN_HIGH_BITS - 1, 0)

    +/*
    + * Non-present SPTE value for both VMX and SVM for TDP MMU.
    + * For SVM NPT, for non-present spte (bit 0 = 0), other bits are ignored.
    + * For VMX EPT, bit 63 is ignored if #VE is disabled. (EPT_VIOLATION_VE=0)
    + * bit 63 is #VE suppress if #VE is enabled. (EPT_VIOLATION_VE=1)
    + * For TDX:
    + * TDX module sets EPT_VIOLATION_VE for Secure-EPT and conventional EPT
    + */
    +#ifdef CONFIG_X86_64
    +#define SHADOW_NONPRESENT_VALUE BIT_ULL(63)
    +static_assert(!(SHADOW_NONPRESENT_VALUE & SPTE_MMU_PRESENT_MASK));
    +#else
    #define SHADOW_NONPRESENT_VALUE 0ULL
    +#endif

    extern u64 __read_mostly shadow_host_writable_mask;
    extern u64 __read_mostly shadow_mmu_writable_mask;
    @@ -195,7 +208,7 @@ extern u64 __read_mostly shadow_nonpresent_or_rsvd_mask;
    *
    * Only used by the TDP MMU.
    */
    -#define REMOVED_SPTE 0x5a0ULL
    +#define REMOVED_SPTE (SHADOW_NONPRESENT_VALUE | 0x5a0ULL)

    /* Removed SPTEs must not be misconstrued as shadow present PTEs. */
    static_assert(!(REMOVED_SPTE & SPTE_MMU_PRESENT_MASK));
    --
    2.25.1
    \
     
     \ /
      Last update: 2023-03-27 00:36    [W:4.175 / U:0.120 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site