Skip to content

Commit b7d97f6

Browse files
sean-jcbonzini
authored andcommitted
KVM: x86/mmu: Extend guest_memfd's max mapping level to shared mappings
Rework kvm_mmu_max_mapping_level() to consult guest_memfd for all mappings, not just private mappings, so that hugepage support plays nice with the upcoming support for backing non-private memory with guest_memfd. In addition to getting the max order from guest_memfd for gmem-only memslots, update TDX's hook to effectively ignore shared mappings, as TDX's restrictions on page size only apply to Secure EPT mappings. Do nothing for SNP, as RMP restrictions apply to both private and shared memory. Suggested-by: Ackerley Tng <ackerleytng@google.com> Signed-off-by: Sean Christopherson <seanjc@google.com> Reviewed-by: David Hildenbrand <david@redhat.com> Reviewed-by: Fuad Tabba <tabba@google.com> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com> Message-ID: <20250729225455.670324-16-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent a3522ac commit b7d97f6

7 files changed

Lines changed: 19 additions & 13 deletions

File tree

arch/x86/include/asm/kvm_host.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1922,7 +1922,7 @@ struct kvm_x86_ops {
19221922
void *(*alloc_apic_backing_page)(struct kvm_vcpu *vcpu);
19231923
int (*gmem_prepare)(struct kvm *kvm, kvm_pfn_t pfn, gfn_t gfn, int max_order);
19241924
void (*gmem_invalidate)(kvm_pfn_t start, kvm_pfn_t end);
1925-
int (*gmem_max_mapping_level)(struct kvm *kvm, kvm_pfn_t pfn);
1925+
int (*gmem_max_mapping_level)(struct kvm *kvm, kvm_pfn_t pfn, bool is_private);
19261926
};
19271927

19281928
struct kvm_x86_nested_ops {

arch/x86/kvm/mmu/mmu.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3302,8 +3302,9 @@ static u8 kvm_max_level_for_order(int order)
33023302
return PG_LEVEL_4K;
33033303
}
33043304

3305-
static u8 kvm_max_private_mapping_level(struct kvm *kvm, struct kvm_page_fault *fault,
3306-
const struct kvm_memory_slot *slot, gfn_t gfn)
3305+
static u8 kvm_gmem_max_mapping_level(struct kvm *kvm, struct kvm_page_fault *fault,
3306+
const struct kvm_memory_slot *slot, gfn_t gfn,
3307+
bool is_private)
33073308
{
33083309
u8 max_level, coco_level;
33093310
kvm_pfn_t pfn;
@@ -3327,7 +3328,7 @@ static u8 kvm_max_private_mapping_level(struct kvm *kvm, struct kvm_page_fault *
33273328
* restrictions. A return of '0' means "no additional restrictions", to
33283329
* allow for using an optional "ret0" static call.
33293330
*/
3330-
coco_level = kvm_x86_call(gmem_max_mapping_level)(kvm, pfn);
3331+
coco_level = kvm_x86_call(gmem_max_mapping_level)(kvm, pfn, is_private);
33313332
if (coco_level)
33323333
max_level = min(max_level, coco_level);
33333334

@@ -3361,8 +3362,9 @@ int kvm_mmu_max_mapping_level(struct kvm *kvm, struct kvm_page_fault *fault,
33613362
if (max_level == PG_LEVEL_4K)
33623363
return PG_LEVEL_4K;
33633364

3364-
if (is_private)
3365-
host_level = kvm_max_private_mapping_level(kvm, fault, slot, gfn);
3365+
if (is_private || kvm_memslot_is_gmem_only(slot))
3366+
host_level = kvm_gmem_max_mapping_level(kvm, fault, slot, gfn,
3367+
is_private);
33663368
else
33673369
host_level = host_pfn_mapping_level(kvm, gfn, slot);
33683370
return min(host_level, max_level);

arch/x86/kvm/svm/sev.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4943,7 +4943,7 @@ void sev_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end)
49434943
}
49444944
}
49454945

4946-
int sev_gmem_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn)
4946+
int sev_gmem_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn, bool is_private)
49474947
{
49484948
int level, rc;
49494949
bool assigned;

arch/x86/kvm/svm/svm.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -866,7 +866,7 @@ void sev_handle_rmp_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u64 error_code);
866866
void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu);
867867
int sev_gmem_prepare(struct kvm *kvm, kvm_pfn_t pfn, gfn_t gfn, int max_order);
868868
void sev_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end);
869-
int sev_gmem_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn);
869+
int sev_gmem_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn, bool is_private);
870870
struct vmcb_save_area *sev_decrypt_vmsa(struct kvm_vcpu *vcpu);
871871
void sev_free_decrypted_vmsa(struct kvm_vcpu *vcpu, struct vmcb_save_area *vmsa);
872872
#else
@@ -895,7 +895,7 @@ static inline int sev_gmem_prepare(struct kvm *kvm, kvm_pfn_t pfn, gfn_t gfn, in
895895
return 0;
896896
}
897897
static inline void sev_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end) {}
898-
static inline int sev_gmem_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn)
898+
static inline int sev_gmem_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn, bool is_private)
899899
{
900900
return 0;
901901
}

arch/x86/kvm/vmx/main.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -831,10 +831,11 @@ static int vt_vcpu_mem_enc_ioctl(struct kvm_vcpu *vcpu, void __user *argp)
831831
return tdx_vcpu_ioctl(vcpu, argp);
832832
}
833833

834-
static int vt_gmem_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn)
834+
static int vt_gmem_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn,
835+
bool is_private)
835836
{
836837
if (is_td(kvm))
837-
return tdx_gmem_max_mapping_level(kvm, pfn);
838+
return tdx_gmem_max_mapping_level(kvm, pfn, is_private);
838839

839840
return 0;
840841
}

arch/x86/kvm/vmx/tdx.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3318,8 +3318,11 @@ int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp)
33183318
return ret;
33193319
}
33203320

3321-
int tdx_gmem_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn)
3321+
int tdx_gmem_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn, bool is_private)
33223322
{
3323+
if (!is_private)
3324+
return 0;
3325+
33233326
return PG_LEVEL_4K;
33243327
}
33253328

arch/x86/kvm/vmx/x86_ops.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp);
153153
void tdx_flush_tlb_current(struct kvm_vcpu *vcpu);
154154
void tdx_flush_tlb_all(struct kvm_vcpu *vcpu);
155155
void tdx_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level);
156-
int tdx_gmem_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn);
156+
int tdx_gmem_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn, bool is_private);
157157
#endif
158158

159159
#endif /* __KVM_X86_VMX_X86_OPS_H */

0 commit comments

Comments
 (0)