Skip to content

Commit b9d5cf6

Browse files
committed
KVM: TDX: WARN if mirror SPTE doesn't have full RWX when creating S-EPT mapping
Pass in the mirror_spte to kvm_x86_ops.set_external_spte() to provide symmetry with .remove_external_spte(), and assert in TDX that the mirror SPTE is shadow-present with full RWX permissions (the TDX-Module doesn't allow the hypervisor to control protections). Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com> Reviewed-by: Kai Huang <kai.huang@intel.com> Reviewed-by: Yan Zhao <yan.y.zhao@intel.com> Tested-by: Yan Zhao <yan.y.zhao@intel.com> Tested-by: Kai Huang <kai.huang@intel.com> Link: https://patch.msgid.link/20251030200951.3402865-13-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 7139c86 commit b9d5cf6

File tree

3 files changed

+7
-4
lines changed

3 files changed

+7
-4
lines changed

arch/x86/include/asm/kvm_host.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1848,7 +1848,7 @@ struct kvm_x86_ops {
18481848
void *external_spt);
18491849
/* Update the external page table from spte getting set. */
18501850
int (*set_external_spte)(struct kvm *kvm, gfn_t gfn, enum pg_level level,
1851-
kvm_pfn_t pfn_for_gfn);
1851+
u64 mirror_spte);
18521852

18531853
/* Update external page tables for page table about to be freed. */
18541854
int (*free_external_spt)(struct kvm *kvm, gfn_t gfn, enum pg_level level,

arch/x86/kvm/mmu/tdp_mmu.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,6 @@ static int __must_check set_external_spte_present(struct kvm *kvm, tdp_ptep_t sp
515515
bool was_present = is_shadow_present_pte(old_spte);
516516
bool is_present = is_shadow_present_pte(new_spte);
517517
bool is_leaf = is_present && is_last_spte(new_spte, level);
518-
kvm_pfn_t new_pfn = spte_to_pfn(new_spte);
519518
int ret = 0;
520519

521520
KVM_BUG_ON(was_present, kvm);
@@ -534,7 +533,7 @@ static int __must_check set_external_spte_present(struct kvm *kvm, tdp_ptep_t sp
534533
* external page table, or leaf.
535534
*/
536535
if (is_leaf) {
537-
ret = kvm_x86_call(set_external_spte)(kvm, gfn, level, new_pfn);
536+
ret = kvm_x86_call(set_external_spte)(kvm, gfn, level, new_spte);
538537
} else {
539538
void *external_spt = get_external_spt(gfn, new_spte, level);
540539

arch/x86/kvm/vmx/tdx.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1629,14 +1629,18 @@ static int tdx_mem_page_record_premap_cnt(struct kvm *kvm, gfn_t gfn,
16291629
}
16301630

16311631
static int tdx_sept_set_private_spte(struct kvm *kvm, gfn_t gfn,
1632-
enum pg_level level, kvm_pfn_t pfn)
1632+
enum pg_level level, u64 mirror_spte)
16331633
{
16341634
struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm);
1635+
kvm_pfn_t pfn = spte_to_pfn(mirror_spte);
16351636

16361637
/* TODO: handle large pages. */
16371638
if (KVM_BUG_ON(level != PG_LEVEL_4K, kvm))
16381639
return -EIO;
16391640

1641+
WARN_ON_ONCE(!is_shadow_present_pte(mirror_spte) ||
1642+
(mirror_spte & VMX_EPT_RWX_MASK) != VMX_EPT_RWX_MASK);
1643+
16401644
/*
16411645
* Read 'pre_fault_allowed' before 'kvm_tdx->state'; see matching
16421646
* barrier in tdx_td_finalize().

0 commit comments

Comments
 (0)