Hi Marc,

> 
>  From 8f2a919d6f13d36445974794c76821fbb6b40f88 Mon Sep 17 00:00:00
> 2001
>  From: Marc Zyngier <[email protected]>
> Date: Sat, 16 Jan 2021 10:53:21 +0000
> Subject: [PATCH] CMO on RO memslot
> 
> Signed-off-by: Marc Zyngier <[email protected]>
> ---
>   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...
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

Reply via email to