• Sean Christopherson's avatar
    KVM: x86: Disallow read-only memslots for SEV-ES and SEV-SNP (and TDX) · 66155de9
    Sean Christopherson authored
    Disallow read-only memslots for SEV-{ES,SNP} VM types, as KVM can't
    directly emulate instructions for ES/SNP, and instead the guest must
    explicitly request emulation.  Unless the guest explicitly requests
    emulation without accessing memory, ES/SNP relies on KVM creating an MMIO
    SPTE, with the subsequent #NPF being reflected into the guest as a #VC.
    
    But for read-only memslots, KVM deliberately doesn't create MMIO SPTEs,
    because except for ES/SNP, doing so requires setting reserved bits in the
    SPTE, i.e. the SPTE can't be readable while also generating a #VC on
    writes.  Because KVM never creates MMIO SPTEs and jumps directly to
    emulation, the guest never gets a #VC.  And since KVM simply resumes the
    guest if ES/SNP guests trigger emulation, KVM effectively puts the vCPU
    into an infinite #NPF loop if the vCPU attempts to write read-only memory.
    
    Disallow read-only memory for all VMs with protected state, i.e. for
    upcoming TDX VMs as well as ES/SNP VMs.  For TDX, it's actually possible
    to support read-only memory, as TDX uses EPT Violation #VE to reflect the
    fault into the guest, e.g. KVM could configure read-only SPTEs with RX
    protections and SUPPRESS_VE=0.  But there is no strong use case for
    supporting read-only memslots on TDX, e.g. the main historical usage is
    to emulate option ROMs, but TDX disallows executing from shared memory.
    And if someone comes along with a legitimate, strong use case, the
    restriction can always be lifted for TDX.
    
    Don't bother trying to retroactively apply the restriction to SEV-ES
    VMs that are created as type KVM_X86_DEFAULT_VM.  Read-only memslots can't
    possibly work for SEV-ES, i.e. disallowing such memslots is really just
    means reporting an error to userspace instead of silently hanging vCPUs.
    Trying to deal with the ordering between KVM_SEV_INIT and memslot creation
    isn't worth the marginal benefit it would provide userspace.
    
    Fixes: 26c44aa9 ("KVM: SEV: define VM types for SEV and SEV-ES")
    Fixes: 1dfe571c ("KVM: SEV: Add initial SEV-SNP support")
    Cc: Peter Gonda <pgonda@google.com>
    Cc: Michael Roth <michael.roth@amd.com>
    Cc: Vishal Annapurve <vannapurve@google.com>
    Cc: Ackerly Tng <ackerleytng@google.com>
    Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
    Message-ID: <20240809190319.1710470-2-seanjc@google.com>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    66155de9
kvm_main.c 168 KB