All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marc Zyngier <marc.zyngier@arm.com>
To: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: kvm@vger.kernel.org, lersek@redhat.com,
	christoffer.dall@linaro.org,
	linux-arm-kernel@lists.infradead.org,
	kvmarm@lists.cs.columbia.edu
Subject: Re: [PATCH] ARM/arm64: KVM: fix use of WnR bit in kvm_is_write_fault()
Date: Tue, 09 Sep 2014 10:35:45 +0100	[thread overview]
Message-ID: <ed95e7484d2ade8345683a29670a9c5d@www.loen.fr> (raw)
In-Reply-To: <1410208167-32532-1-git-send-email-ard.biesheuvel@linaro.org>

Hi Ard,

On 2014-09-08 21:29, Ard Biesheuvel wrote:
> The ISS encoding for an exception from a Data Abort has a WnR
> bit[6] that indicates whether the Data Abort was caused by a
> read or a write instruction. While there are several fields
> in the encoding that are only valid if the ISV bit[24] is set,
> WnR is not one of them, so we can read it unconditionally.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>
> This fixes an issue I observed with UEFI running under QEMU/KVM using
> NOR flash emulation and the upcoming KVM_CAP_READONLY_MEM support, 
> where
> NOR flash reads were mistaken for NOR flash writes, resulting in all 
> read
> accesses to go through the MMIO emulation layer.
>
>  arch/arm/include/asm/kvm_mmu.h   | 5 +----
>  arch/arm64/include/asm/kvm_mmu.h | 5 +----
>  2 files changed, 2 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm/include/asm/kvm_mmu.h 
> b/arch/arm/include/asm/kvm_mmu.h
> index 5cc0b0f5f72f..fad5648980ad 100644
> --- a/arch/arm/include/asm/kvm_mmu.h
> +++ b/arch/arm/include/asm/kvm_mmu.h
> @@ -83,10 +83,7 @@ static inline bool kvm_is_write_fault(unsigned 
> long hsr)
>  	unsigned long hsr_ec = hsr >> HSR_EC_SHIFT;
>  	if (hsr_ec == HSR_EC_IABT)
>  		return false;
> -	else if ((hsr & HSR_ISV) && !(hsr & HSR_WNR))
> -		return false;
> -	else
> -		return true;
> +	return hsr & HSR_WNR;
>  }
>
>  static inline void kvm_clean_pgd(pgd_t *pgd)
> diff --git a/arch/arm64/include/asm/kvm_mmu.h
> b/arch/arm64/include/asm/kvm_mmu.h
> index 8e138c7c53ac..09fd9e4c13d8 100644
> --- a/arch/arm64/include/asm/kvm_mmu.h
> +++ b/arch/arm64/include/asm/kvm_mmu.h
> @@ -100,10 +100,7 @@ static inline bool kvm_is_write_fault(unsigned 
> long esr)
>  	if (esr_ec == ESR_EL2_EC_IABT)
>  		return false;
>
> -	if ((esr & ESR_EL2_ISV) && !(esr & ESR_EL2_WNR))
> -		return false;
> -
> -	return true;
> +	return esr & ESR_EL2_WNR;
>  }
>
>  static inline void kvm_clean_pgd(pgd_t *pgd) {}

Nice catch. One thing though.

This is a case where code duplication has led to this glaring bug:
On both arm and arm64, kvm_emulate.h has code that implements this 
correctly, just that we failed to use it. Blame me.

I think this should be rewritten entierely in mmu.c, with something 
like this (fully untested, of course):

static bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
{
         if (kvm_vcpu_trap_is_iabt(vcpu))
                 return false;

         return kvm_vcpu_dabt_iswrite(vcpu);
}

Care to respin it?

Thanks,

         M.
-- 
Fast, cheap, reliable. Pick two.

WARNING: multiple messages have this Message-ID (diff)
From: marc.zyngier@arm.com (Marc Zyngier)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] ARM/arm64: KVM: fix use of WnR bit in kvm_is_write_fault()
Date: Tue, 09 Sep 2014 10:35:45 +0100	[thread overview]
Message-ID: <ed95e7484d2ade8345683a29670a9c5d@www.loen.fr> (raw)
In-Reply-To: <1410208167-32532-1-git-send-email-ard.biesheuvel@linaro.org>

Hi Ard,

On 2014-09-08 21:29, Ard Biesheuvel wrote:
> The ISS encoding for an exception from a Data Abort has a WnR
> bit[6] that indicates whether the Data Abort was caused by a
> read or a write instruction. While there are several fields
> in the encoding that are only valid if the ISV bit[24] is set,
> WnR is not one of them, so we can read it unconditionally.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>
> This fixes an issue I observed with UEFI running under QEMU/KVM using
> NOR flash emulation and the upcoming KVM_CAP_READONLY_MEM support, 
> where
> NOR flash reads were mistaken for NOR flash writes, resulting in all 
> read
> accesses to go through the MMIO emulation layer.
>
>  arch/arm/include/asm/kvm_mmu.h   | 5 +----
>  arch/arm64/include/asm/kvm_mmu.h | 5 +----
>  2 files changed, 2 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm/include/asm/kvm_mmu.h 
> b/arch/arm/include/asm/kvm_mmu.h
> index 5cc0b0f5f72f..fad5648980ad 100644
> --- a/arch/arm/include/asm/kvm_mmu.h
> +++ b/arch/arm/include/asm/kvm_mmu.h
> @@ -83,10 +83,7 @@ static inline bool kvm_is_write_fault(unsigned 
> long hsr)
>  	unsigned long hsr_ec = hsr >> HSR_EC_SHIFT;
>  	if (hsr_ec == HSR_EC_IABT)
>  		return false;
> -	else if ((hsr & HSR_ISV) && !(hsr & HSR_WNR))
> -		return false;
> -	else
> -		return true;
> +	return hsr & HSR_WNR;
>  }
>
>  static inline void kvm_clean_pgd(pgd_t *pgd)
> diff --git a/arch/arm64/include/asm/kvm_mmu.h
> b/arch/arm64/include/asm/kvm_mmu.h
> index 8e138c7c53ac..09fd9e4c13d8 100644
> --- a/arch/arm64/include/asm/kvm_mmu.h
> +++ b/arch/arm64/include/asm/kvm_mmu.h
> @@ -100,10 +100,7 @@ static inline bool kvm_is_write_fault(unsigned 
> long esr)
>  	if (esr_ec == ESR_EL2_EC_IABT)
>  		return false;
>
> -	if ((esr & ESR_EL2_ISV) && !(esr & ESR_EL2_WNR))
> -		return false;
> -
> -	return true;
> +	return esr & ESR_EL2_WNR;
>  }
>
>  static inline void kvm_clean_pgd(pgd_t *pgd) {}

Nice catch. One thing though.

This is a case where code duplication has led to this glaring bug:
On both arm and arm64, kvm_emulate.h has code that implements this 
correctly, just that we failed to use it. Blame me.

I think this should be rewritten entierely in mmu.c, with something 
like this (fully untested, of course):

static bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
{
         if (kvm_vcpu_trap_is_iabt(vcpu))
                 return false;

         return kvm_vcpu_dabt_iswrite(vcpu);
}

Care to respin it?

Thanks,

         M.
-- 
Fast, cheap, reliable. Pick two.

  parent reply	other threads:[~2014-09-09  9:35 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-08 20:29 [PATCH] ARM/arm64: KVM: fix use of WnR bit in kvm_is_write_fault() Ard Biesheuvel
2014-09-08 20:29 ` Ard Biesheuvel
2014-09-08 20:52 ` Laszlo Ersek
2014-09-08 20:52   ` Laszlo Ersek
2014-09-09  9:35 ` Marc Zyngier [this message]
2014-09-09  9:35   ` Marc Zyngier
2014-09-09 10:01   ` Ard Biesheuvel
2014-09-09 10:01     ` Ard Biesheuvel

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=ed95e7484d2ade8345683a29670a9c5d@www.loen.fr \
    --to=marc.zyngier@arm.com \
    --cc=ard.biesheuvel@linaro.org \
    --cc=christoffer.dall@linaro.org \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=lersek@redhat.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /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.