[PATCH] arm64/kvm: correct the error report in kvm_handle_guest_abort
Jianyong Wu
Jianyong.Wu at arm.com
Thu Jan 28 04:55:43 EST 2021
> -----Original Message-----
> From: Marc Zyngier <maz at kernel.org>
> Sent: Thursday, January 28, 2021 5:07 PM
> To: Jianyong Wu <Jianyong.Wu at arm.com>
> Cc: James Morse <James.Morse at arm.com>; will at kernel.org; Suzuki
> Poulose <Suzuki.Poulose at arm.com>; linux-arm-kernel at lists.infradead.org;
> kvmarm at lists.cs.columbia.edu; Steve Capper <Steve.Capper at arm.com>;
> Justin He <Justin.He at arm.com>; nd <nd at arm.com>
> Subject: Re: [PATCH] arm64/kvm: correct the error report in
> kvm_handle_guest_abort
>
> On 2021-01-28 03:01, Jianyong Wu wrote:
> > Hi Marc,
> >
> >>
> >> From 8f2a919d6f13d36445974794c76821fbb6b40f88 Mon Sep 17 00:00:00
> >> 2001
> >> From: Marc Zyngier <maz at kernel.org>
> >> Date: Sat, 16 Jan 2021 10:53:21 +0000
> >> Subject: [PATCH] CMO on RO memslot
> >>
> >> Signed-off-by: Marc Zyngier <maz at kernel.org>
> >> ---
> >> arch/arm64/kvm/mmu.c | 51
> +++++++++++++++++++++++++++++++++----
> >> -------
> >> 1 file changed, 39 insertions(+), 12 deletions(-)
> >>
> >> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index
> >> 7d2257cc5438..3c176b5b0a28 100644
> >> --- a/arch/arm64/kvm/mmu.c
> >> +++ b/arch/arm64/kvm/mmu.c
> >> @@ -760,7 +760,15 @@ static int user_mem_abort(struct kvm_vcpu
> *vcpu,
> >> phys_addr_t fault_ipa,
> >> struct kvm_pgtable *pgt;
> >>
> >> fault_granule = 1UL <<
> >> ARM64_HW_PGTABLE_LEVEL_SHIFT(fault_level);
> >> - write_fault = kvm_is_write_fault(vcpu);
> >> + /*
> >> + * Treat translation faults on CMOs as read faults. Should
> >> + * this further generate a permission fault, it will be caught
> >> + * in kvm_handle_guest_abort(), with prejudice...
> >> + */
> >> + if (fault_status == FSC_FAULT && kvm_vcpu_dabt_is_cm(vcpu))
> >> + write_fault = false;
> >> + else
> >> + write_fault = kvm_is_write_fault(vcpu);
> >> exec_fault = kvm_vcpu_trap_is_exec_fault(vcpu);
> >> VM_BUG_ON(write_fault && exec_fault);
> >>
> >> @@ -1013,19 +1021,37 @@ int kvm_handle_guest_abort(struct
> kvm_vcpu
> >> *vcpu)
> >> }
> >>
> >> /*
> >> - * Check for a cache maintenance operation. Since we
> >> - * ended-up here, we know it is outside of any memory
> >> - * slot. But we can't find out if that is for a device,
> >> - * or if the guest is just being stupid. The only thing
> >> - * we know for sure is that this range cannot be cached.
> >> + * Check for a cache maintenance operation. Two cases:
> >> + *
> >> + * - It is outside of any memory slot. But we can't find out
> >> + * if that is for a device, or if the guest is just being
> >> + * stupid. The only thing we know for sure is that this
> >> + * range cannot be cached. So let's assume that the guest
> >> + * is just being cautious, and skip the instruction.
> >> + *
> >> + * - Otherwise, check whether this is a permission fault.
> >> + * If so, that's a DC IVAC on a R/O memslot, which is a
> >> + * pretty bad idea, and we tell the guest so.
> >> *
> >> - * So let's assume that the guest is just being
> >> - * cautious, and skip the instruction.
> >> + * - If this wasn't a permission fault, pass it along for
> >> + * further handling (including faulting the page in
> >> if it
> >> + * was a translation fault).
> >> */
> >> - if (kvm_is_error_hva(hva) && kvm_vcpu_dabt_is_cm(vcpu))
> >> {
> >> - kvm_incr_pc(vcpu);
> >> - ret = 1;
> >> - goto out_unlock;
> >> + if (kvm_vcpu_dabt_is_cm(vcpu)) {
> >> + if (kvm_is_error_hva(hva)) {
> >> + kvm_incr_pc(vcpu);
> >> + ret = 1;
> >> + goto out_unlock;
> >> + }
> >> +
> >> + if (fault_status == FSC_PERM) {
> >> + /* DC IVAC on a R/O memslot */
> >> + kvm_inject_dabt(vcpu,
> >> kvm_vcpu_get_hfar(vcpu));
> >
> > One question:
> > In general, the "DC" ops show up very early in guest. So what if the
> > guest do this before interrupt initialization? If so, the guest may
> > stuck here.
>
> I don't understand your question. Do you mean "what if the guest does this
> without being able to handle an exception"?
>
> If that's your question, then the answer is "don't do that".
> The architecture is clear that DC IVAC needs write permission, and will result
> in an abort being delivered if there is no writable mapping (and there can't be,
> the memslot is R/O).
>
> DC CIVAC doesn't have that requirement, and will not generate an exception.
>
OK, get it.
I have tested the patch above using my test case. It works well for "dc civac" and for "dc ivac" , a "Synchronous External Abort" occurs in guest as expected.
Thanks
Jianyong
> Thanks,
>
> M.
> --
> Jazz is not dead. It just smells funny...
More information about the linux-arm-kernel
mailing list