[PATCH] arm64/kvm: correct the error report in kvm_handle_guest_abort
Jianyong Wu
Jianyong.Wu at arm.com
Wed Jan 27 22:01:53 EST 2021
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.
Thanks
Jianyong
> + ret = 1;
> + goto out_unlock;
> + }
> +
> + goto handle_access;
> }
>
> /*
> @@ -1039,6 +1065,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu
> *vcpu)
> goto out_unlock;
> }
>
> +handle_access:
> /* Userspace should not be able to register out-of-bounds IPAs */
> VM_BUG_ON(fault_ipa >= kvm_phys_size(vcpu->kvm));
>
> --
> 2.29.2
>
>
> --
> Jazz is not dead. It just smells funny...
More information about the linux-arm-kernel
mailing list