Thread (148 messages) 148 messages, 14 authors, 2024-04-26

Re: [PATCH v13 20/35] KVM: x86/mmu: Handle page fault for private memory

From: Xu Yilun <hidden>
Date: 2023-11-06 13:30:55
Also in: kvm, kvm-riscv, kvmarm, linux-arm-kernel, linux-fsdevel, linux-mips, linux-mm, linux-riscv, lkml

On Sun, Nov 05, 2023 at 05:19:36PM +0100, Paolo Bonzini wrote:
On Sun, Nov 5, 2023 at 2:04 PM Xu Yilun [off-list ref] wrote:
quoted
quoted
+static void kvm_mmu_prepare_memory_fault_exit(struct kvm_vcpu *vcpu,
+                                           struct kvm_page_fault *fault)
+{
+     kvm_prepare_memory_fault_exit(vcpu, fault->gfn << PAGE_SHIFT,
+                                   PAGE_SIZE, fault->write, fault->exec,
+                                   fault->is_private);
+}
+
+static int kvm_faultin_pfn_private(struct kvm_vcpu *vcpu,
+                                struct kvm_page_fault *fault)
+{
+     int max_order, r;
+
+     if (!kvm_slot_can_be_private(fault->slot)) {
+             kvm_mmu_prepare_memory_fault_exit(vcpu, fault);
+             return -EFAULT;
+     }
+
+     r = kvm_gmem_get_pfn(vcpu->kvm, fault->slot, fault->gfn, &fault->pfn,
+                          &max_order);
+     if (r) {
+             kvm_mmu_prepare_memory_fault_exit(vcpu, fault);
+             return r;
Why report KVM_EXIT_MEMORY_FAULT here? even with a ret != -EFAULT?
The cases are EFAULT, EHWPOISON (which can report
KVM_EXIT_MEMORY_FAULT) and ENOMEM. I think it's fine
that even -ENOMEM can return KVM_EXIT_MEMORY_FAULT,
and it doesn't violate the documentation.  The docs tell you "what
can you do if error if EFAULT or EHWPOISON?"; they don't
exclude that other errnos result in KVM_EXIT_MEMORY_FAULT,
it's just that you're not supposed to look at it
Thanks, it's OK for ENOMEM + KVM_EXIT_MEMORY_FAULT.

Another concern is, now 3 places to report EFAULT + KVM_EXIT_MEMORY_FAULT:

  if (!kvm_slot_can_be_private(fault->slot)) {
	kvm_mmu_prepare_memory_fault_exit(vcpu, fault);
	return -EFAULT;
  }

  file = kvm_gmem_get_file(slot);
  if (!file)
	return -EFAULT;

  if (fault->is_private != kvm_mem_is_private(vcpu->kvm, fault->gfn)) {
	kvm_mmu_prepare_memory_fault_exit(vcpu, fault);
	return -EFAULT;
  }

They are different cases, and seems userspace should handle them
differently, but not enough information to distinguish them.

Thanks,
Yilun
Paolo
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help