On Mon, Oct 16, 2023, Michael Roth wrote: > For KVM_X86_SNP_VM, only the PFERR_GUEST_ENC_MASK flag is needed to > determine with an #NPF is due to a private/shared access by the guest. > Implement that handling here. Also add handling needed to deal with > SNP guests which in some cases will make MMIO accesses with the > encryption bit. ... > @@ -4356,12 +4357,19 @@ static int __kvm_faultin_pfn(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault > return RET_PF_EMULATE; > } > > - if (fault->is_private != kvm_mem_is_private(vcpu->kvm, fault->gfn)) { > + /* > + * In some cases SNP guests will make MMIO accesses with the encryption > + * bit set. Handle these via the normal MMIO fault path. > + */ > + if (!slot && private_fault && kvm_is_vm_type(vcpu->kvm, KVM_X86_SNP_VM)) > + private_fault = false; Why? This is inarguably a guest bug. > + if (private_fault != kvm_mem_is_private(vcpu->kvm, fault->gfn)) { > kvm_mmu_prepare_memory_fault_exit(vcpu, fault); > return -EFAULT; > } > > - if (fault->is_private) > + if (private_fault) > return kvm_faultin_pfn_private(vcpu, fault); > > async = false; > diff --git a/arch/x86/kvm/mmu/mmu_internal.h b/arch/x86/kvm/mmu/mmu_internal.h > index 759c8b718201..e5b973051ad9 100644 > --- a/arch/x86/kvm/mmu/mmu_internal.h > +++ b/arch/x86/kvm/mmu/mmu_internal.h > @@ -251,6 +251,24 @@ struct kvm_page_fault { > > int kvm_tdp_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault); > > +static bool kvm_mmu_fault_is_private(struct kvm *kvm, gpa_t gpa, u64 err) > +{ > + bool private_fault = false; > + > + if (kvm_is_vm_type(kvm, KVM_X86_SNP_VM)) { > + private_fault = !!(err & PFERR_GUEST_ENC_MASK); > + } else if (kvm_is_vm_type(kvm, KVM_X86_SW_PROTECTED_VM)) { > + /* > + * This handling is for gmem self-tests and guests that treat > + * userspace as the authority on whether a fault should be > + * private or not. > + */ > + private_fault = kvm_mem_is_private(kvm, gpa >> PAGE_SHIFT); > + } This can be more simply: if (kvm_is_vm_type(kvm, KVM_X86_SNP_VM)) return !!(err & PFERR_GUEST_ENC_MASK); if (kvm_is_vm_type(kvm, KVM_X86_SW_PROTECTED_VM)) return kvm_mem_is_private(kvm, gpa >> PAGE_SHIFT);