On Wed, May 01, 2024 at 03:51:52AM -0500, Michael Roth <michael.roth@xxxxxxx> wrote: ... > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h > index c6c5018376be..87265b73906a 100644 > --- a/arch/x86/include/asm/kvm_host.h > +++ b/arch/x86/include/asm/kvm_host.h > @@ -1816,6 +1816,7 @@ struct kvm_x86_ops { > void *(*alloc_apic_backing_page)(struct kvm_vcpu *vcpu); > int (*gmem_prepare)(struct kvm *kvm, kvm_pfn_t pfn, gfn_t gfn, int max_order); > void (*gmem_invalidate)(kvm_pfn_t start, kvm_pfn_t end); > + int (*private_max_mapping_level)(struct kvm *kvm, kvm_pfn_t pfn); Explicit private prefix is nice. > }; > > struct kvm_x86_nested_ops { > diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c > index 510eb1117012..0d556da052f6 100644 > --- a/arch/x86/kvm/mmu/mmu.c > +++ b/arch/x86/kvm/mmu/mmu.c > @@ -4271,6 +4271,20 @@ static inline u8 kvm_max_level_for_order(int order) > return PG_LEVEL_4K; > } > > +static u8 kvm_max_private_mapping_level(struct kvm *kvm, kvm_pfn_t pfn, > + u8 max_level, int gmem_order) > +{ > + if (max_level == PG_LEVEL_4K) > + return PG_LEVEL_4K; > + > + max_level = min(kvm_max_level_for_order(gmem_order), max_level); > + if (max_level == PG_LEVEL_4K) > + return PG_LEVEL_4K; > + > + return min(max_level, > + static_call(kvm_x86_private_max_mapping_level)(kvm, pfn)); If we don't implement this hook, OPTIONAL_RET0 causes always PG_LEVEL_NONE. Anyway when TDX implements the hook, we can remove OPTIONAL_RET0. This hook works for TDX by "return PG_LEVEL_4K;". Reviewed-by: Isaku Yamahata <isaku.yamahata@xxxxxxxxx> -- Isaku Yamahata <isaku.yamahata@xxxxxxxxx>