[PATCH] arm64/kvm: correct the error report in kvm_handle_guest_abort

Jianyong Wu Jianyong.Wu at arm.com
Tue Jan 26 03:10:25 EST 2021


Hi Marc,

>   		/*
> -		 * 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:
>   		 *
> -		 * So let's assume that the guest is just being
> -		 * cautious, and skip the instruction.
> +		 * - 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, clean/invalidate the whole memslot. We
> +		 *   should special-case DC IVAC and inject a
> +		 *   permission fault, but we can't really identify it
> +		 *   in this context.
>   		 */
> -		if (kvm_is_error_hva(hva) && kvm_vcpu_dabt_is_cm(vcpu))
> {
> +		if (kvm_vcpu_dabt_is_cm(vcpu)) {
> +			if (!kvm_is_error_hva(hva)) {
> +				spin_lock(&vcpu->kvm->mmu_lock);
> +				stage2_flush_memslot(vcpu->kvm,
> memslot);

Maybe we should not flush the whole memslot here as every "dc ivac" only work on a range of memory with cache line size. So what about using:
stage2_apply_range_resched(vcpu->kvm, fault_ipa, fault_ipa + cache_line_size(), kvm_pgtable_stage2_flush) instead. It will a bit faster than flush the whole memslot.
Also I test your idea of "unmap after flush" using:
	stage2_apply_range_resched(vcpu->kvm, fault_ipa, fault_ipa + cache_line_size(), kvm_pgtable_stage2_flush);
	stage2_apply_range(vcpu->kvm, fault_ipa, fault_ipa + cache_line_size(), kvm_pgtable_stage2_unmap, true);
then I do "dc ivac" on the rom of 128M twice and got the double time of around 11s. it means that there is no optimization when do the second "dc ivac".
I'm not sure if there is something wrong in my test.

So what about just using " stage2_apply_range_resched(vcpu->kvm, fault_ipa, fault_ipa + cache_line_size(), kvm_pgtable_stage2_flush);" instead of 
" stage2_flush_memslot(vcpu->kvm, memslot);" and let the guest bears the disadvantage of low performance. 

Thanks
Jianyong

> +				spin_unlock(&vcpu->kvm->mmu_lock);
> +			}
> +
>   			kvm_incr_pc(vcpu);
>   			ret = 1;
>   			goto out_unlock;
> 
> --
> Jazz is not dead. It just smells funny...



More information about the linux-arm-kernel mailing list