From: Oliver Upton <oliver.upton@linux.dev>
To: "Thomson, Jack" <jackabt.amazon@gmail.com>
Cc: maz@kernel.org, pbonzini@redhat.com, joey.gouly@arm.com,
suzuki.poulose@arm.com, yuzenghui@huawei.com,
catalin.marinas@arm.com, will@kernel.org, shuah@kernel.org,
linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org,
isaku.yamahata@intel.com, roypat@amazon.co.uk,
kalyazin@amazon.co.uk, jackabt@amazon.com
Subject: Re: [PATCH 3/6] KVM: arm64: Add pre_fault_memory implementation
Date: Mon, 29 Sep 2025 17:53:54 -0700 [thread overview]
Message-ID: <aNsqIsbYyROCjShQ@linux.dev> (raw)
In-Reply-To: <7d109638-3d26-443a-b24d-eb7a0059b80f@gmail.com>
On Mon, Sep 29, 2025 at 02:59:35PM +0100, Thomson, Jack wrote:
> Hi Oliver,
>
> Thanks for reviewing!
>
> On 11/09/2025 7:42 pm, Oliver Upton wrote:
> > On Thu, Sep 11, 2025 at 02:46:45PM +0100, Jack Thomson wrote:
> > > @@ -1607,7 +1611,7 @@ static int __user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
> > > struct kvm_s2_trans *nested,
> > > struct kvm_memory_slot *memslot,
> > > long *page_size, unsigned long hva,
> > > - bool fault_is_perm)
> > > + bool fault_is_perm, bool pre_fault)
> > > {
> > > int ret = 0;
> > > bool topup_memcache;
> > > @@ -1631,10 +1635,13 @@ static int __user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
> > > vm_flags_t vm_flags;
> > > enum kvm_pgtable_walk_flags flags = KVM_PGTABLE_WALK_MEMABORT_FLAGS;
> > > + if (pre_fault)
> > > + flags |= KVM_PGTABLE_WALK_PRE_FAULT;
> > > +
> > > if (fault_is_perm)
> > > fault_granule = kvm_vcpu_trap_get_perm_fault_granule(vcpu);
> > > - write_fault = kvm_is_write_fault(vcpu);
> > > - exec_fault = kvm_vcpu_trap_is_exec_fault(vcpu);
> > > + write_fault = !pre_fault && kvm_is_write_fault(vcpu);
> > > + exec_fault = !pre_fault && kvm_vcpu_trap_is_exec_fault(vcpu);
> >
> > I'm not a fan of this. While user_mem_abort() is already a sloppy mess,
> > one thing we could reliably assume is the presence of a valid fault
> > context. Now we need to remember to special-case our interpretation of a
> > fault on whether or not we're getting invoked for a pre-fault.
> >
> > I'd rather see the pre-fault infrastructure compose a synthetic fault
> > context (HPFAR_EL2, ESR_EL2, etc.). It places the complexity where it
> > belongs and the rest of the abort handling code should 'just work'.
> >
>
> Agreed, it looks much better with the synthetic abort. Is this the
> approach you had in mind?
Pretty much. Thanks for taking a moment to fiddle with it.
> +long kvm_arch_vcpu_pre_fault_memory(struct kvm_vcpu *vcpu,
> + struct kvm_pre_fault_memory *range)
> +{
> + int ret, idx;
> + hva_t hva;
> + phys_addr_t end;
> + u64 esr, hpfar;
> + struct kvm_memory_slot *memslot;
> + struct kvm_vcpu_fault_info *fault_info;
> +
> + long page_size = PAGE_SIZE;
> + phys_addr_t ipa = range->gpa;
> + gfn_t gfn = gpa_to_gfn(range->gpa);
> +
> + idx = srcu_read_lock(&vcpu->kvm->srcu);
> +
> + if (ipa >= kvm_phys_size(vcpu->arch.hw_mmu)) {
> + ret = -ENOENT;
> + goto out_unlock;
> + }
> +
> + memslot = gfn_to_memslot(vcpu->kvm, gfn);
> + if (!memslot) {
> + ret = -ENOENT;
> + goto out_unlock;
> + }
> +
> + fault_info = &vcpu->arch.fault;
> +
> + esr = fault_info->esr_el2;
> + hpfar = fault_info->hpfar_el2;
nit: Just snapshot the entire struct, makes this forward-compatible with
new fields showing up.
> +
> + fault_info->esr_el2 = ESR_ELx_FSC_ACCESS_L(KVM_PGTABLE_LAST_LEVEL);
A translation fault would be a more accurate representation what you're
trying to do Access flag faults aren't expected in user_mem_abort() and
instead handled in handle_access_fault().
You're also missing the rest of the ESR fields that are relevant here,
such as ESR_ELx.EC which would actually indicate a data abort. I think
you'd also want to communicate this as a nISV fault (i.e.
ESR_ELx.ISV=0).
> + fault_info->hpfar_el2 = HPFAR_EL2_NS |
> + ((ipa >> (12 - HPFAR_EL2_FIPA_SHIFT)) & HPFAR_EL2_FIPA_MASK);
FIELD_PREP()?
> +
> + if (kvm_slot_has_gmem(memslot)) {
> + ret = gmem_abort(vcpu, ipa, NULL, memslot, false);
> + } else {
> + hva = gfn_to_hva_memslot_prot(memslot, gfn, NULL);
> + if (kvm_is_error_hva(hva)) {
> + ret = -EFAULT;
> + goto out;
> + }
> + ret = user_mem_abort(vcpu, ipa, NULL, memslot, &page_size, hva,
> + false);
> + }
> +
> + if (ret < 0)
> + goto out;
> +
> + end = (range->gpa & ~(page_size - 1)) + page_size;
> + ret = min(range->size, end - range->gpa);
> +
> +out:
> + fault_info->esr_el2 = esr;
> + fault_info->hpfar_el2 = hpfar;
> +out_unlock:
> + srcu_read_unlock(&vcpu->kvm->srcu, idx);
> + return ret;
> +}
Thanks,
Oliver
next prev parent reply other threads:[~2025-09-30 0:54 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-11 13:46 [PATCH 0/6] KVM ARM64 pre_fault_memory Jack Thomson
2025-09-11 13:46 ` [PATCH 1/6] KVM: arm64: Add __gmem_abort and __user_mem_abort Jack Thomson
2025-09-11 18:27 ` Oliver Upton
2025-09-11 13:46 ` [PATCH 2/6] KVM: arm64: Add KVM_PGTABLE_WALK_PRE_FAULT walk flag Jack Thomson
2025-09-11 13:46 ` [PATCH 3/6] KVM: arm64: Add pre_fault_memory implementation Jack Thomson
2025-09-11 18:42 ` Oliver Upton
2025-09-29 13:59 ` Thomson, Jack
2025-09-30 0:53 ` Oliver Upton [this message]
2025-09-11 13:46 ` [PATCH 4/6] KVM: selftests: Fix unaligned mmap allocations Jack Thomson
2025-09-11 13:46 ` [PATCH 5/6] KVM: selftests: Enable pre_fault_memory_test for arm64 Jack Thomson
2025-09-11 13:46 ` [PATCH 6/6] KVM: selftests: Add option for different backing in pre-fault tests Jack Thomson
2025-09-11 18:56 ` [PATCH 0/6] KVM ARM64 pre_fault_memory Oliver Upton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aNsqIsbYyROCjShQ@linux.dev \
--to=oliver.upton@linux.dev \
--cc=catalin.marinas@arm.com \
--cc=isaku.yamahata@intel.com \
--cc=jackabt.amazon@gmail.com \
--cc=jackabt@amazon.com \
--cc=joey.gouly@arm.com \
--cc=kalyazin@amazon.co.uk \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=maz@kernel.org \
--cc=pbonzini@redhat.com \
--cc=roypat@amazon.co.uk \
--cc=shuah@kernel.org \
--cc=suzuki.poulose@arm.com \
--cc=will@kernel.org \
--cc=yuzenghui@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.