On Tue Aug 15, 2023 at 8:18 PM EEST, wrote: > From: Michael Roth <michael.roth@xxxxxxx> > > All gmem pages are expected to be 'private' as defined by a particular > arch/platform. Platforms like SEV-SNP require additional operations to > move these pages into a private state, so implement a hook that can be > used to prepare this memory prior to mapping it into a guest. > > In the case of SEV-SNP, whether or not a 2MB page can be mapped via a > 2MB mapping in the guest's nested page table depends on whether or not > any subpages within the range have already been initialized as private > in the RMP table, so this hook will also be used by the KVM MMU to clamp > the maximum mapping size accordingly. > > Signed-off-by: Michael Roth <michael.roth@xxxxxxx> > Link: https://lore.kernel.org/r/20230612042559.375660-2-michael.roth@xxxxxxx > > --- > Changes v2 -> v3: > - Newly added > --- > arch/x86/include/asm/kvm-x86-ops.h | 1 + > arch/x86/include/asm/kvm_host.h | 3 +++ > arch/x86/kvm/mmu/mmu.c | 12 ++++++++++-- > 3 files changed, 14 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h > index 13bc212cd4bc..439ba4beb5af 100644 > --- a/arch/x86/include/asm/kvm-x86-ops.h > +++ b/arch/x86/include/asm/kvm-x86-ops.h > @@ -133,6 +133,7 @@ KVM_X86_OP(msr_filter_changed) > KVM_X86_OP(complete_emulated_msr) > KVM_X86_OP(vcpu_deliver_sipi_vector) > KVM_X86_OP_OPTIONAL_RET0(vcpu_get_apicv_inhibit_reasons); > +KVM_X86_OP_OPTIONAL_RET0(gmem_prepare) > > #undef KVM_X86_OP > #undef KVM_X86_OP_OPTIONAL > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h > index bbefd79b7950..2bc42f2887fa 100644 > --- a/arch/x86/include/asm/kvm_host.h > +++ b/arch/x86/include/asm/kvm_host.h > @@ -1732,6 +1732,9 @@ struct kvm_x86_ops { > * Returns vCPU specific APICv inhibit reasons > */ > unsigned long (*vcpu_get_apicv_inhibit_reasons)(struct kvm_vcpu *vcpu); > + > + int (*gmem_prepare)(struct kvm *kvm, struct kvm_memory_slot *slot, > + kvm_pfn_t pfn, gfn_t gfn, u8 *max_level); > }; > > struct kvm_x86_nested_ops { > diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c > index 05943ccb55a4..06900b01b8f0 100644 > --- a/arch/x86/kvm/mmu/mmu.c > +++ b/arch/x86/kvm/mmu/mmu.c > @@ -4352,6 +4352,7 @@ static int kvm_faultin_pfn_private(struct kvm_vcpu *vcpu, > struct kvm_page_fault *fault) > { > int max_order, r; > + u8 max_level; > > if (!kvm_slot_can_be_private(fault->slot)) > return kvm_do_memory_fault_exit(vcpu, fault); > @@ -4361,8 +4362,15 @@ static int kvm_faultin_pfn_private(struct kvm_vcpu *vcpu, > if (r) > return r; > > - fault->max_level = min(kvm_max_level_for_order(max_order), > - fault->max_level); > + max_level = kvm_max_level_for_order(max_order); > + r = static_call(kvm_x86_gmem_prepare)(vcpu->kvm, fault->slot, fault->pfn, > + fault->gfn, &max_level); > + if (r) { > + kvm_release_pfn_clean(fault->pfn); > + return r; > + } > + > + fault->max_level = min(max_level, fault->max_level); > fault->map_writable = !(fault->slot->flags & KVM_MEM_READONLY); > return RET_PF_CONTINUE; > } > -- > 2.25.1 Acked-by: Jarkko Sakkinen <jarkko@xxxxxxxxxx> BR, Jarkko