All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christoffer Dall <cdall@linaro.org>
To: Alexander Graf <agraf@suse.de>
Cc: kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] KVM: arm/arm64: Handle hva aging while destroying the vm
Date: Mon, 3 Jul 2017 10:03:13 +0200	[thread overview]
Message-ID: <20170703080313.GB4066@cbox> (raw)
In-Reply-To: <1498231319-199734-1-git-send-email-agraf@suse.de>

Hi Alex,

On Fri, Jun 23, 2017 at 05:21:59PM +0200, Alexander Graf wrote:
> If we want to age an HVA while the VM is getting destroyed, we have a
> tiny race window during which we may end up dereferencing an invalid
> kvm->arch.pgd value.
> 
>    CPU0               CPU1
> 
>    kvm_age_hva()
>                       kvm_mmu_notifier_release()
>                       kvm_arch_flush_shadow_all()
>                       kvm_free_stage2_pgd()
>                       <grab mmu_lock>
>    stage2_get_pmd()
>    <wait for mmu_lock>
>                       set kvm->arch.pgd = 0
>                       <free mmu_lock>
>    <grab mmu_lock>
>    stage2_get_pud()
>    <access kvm->arch.pgd>
>    <use incorrect value>

I don't think this sequence, can happen, but I think kvm_age_hva() can
be called with the mmu_lock held and kvm->pgd already being NULL.

Is that possible for the mmu notifiers to be calling clear(_flush)_young
while also calling notifier_release?

If so, the patch below looks good to me.

Thanks,
-Christoffer


> 
> This patch adds a check for that case.
> 
> Signed-off-by: Alexander Graf <agraf@suse.de>
> ---
>  virt/kvm/arm/mmu.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
> index f2d5b6c..227931f 100644
> --- a/virt/kvm/arm/mmu.c
> +++ b/virt/kvm/arm/mmu.c
> @@ -861,6 +861,10 @@ static pud_t *stage2_get_pud(struct kvm *kvm, struct kvm_mmu_memory_cache *cache
>  	pgd_t *pgd;
>  	pud_t *pud;
>  
> +	/* Do we clash with kvm_free_stage2_pgd()? */
> +	if (!kvm->arch.pgd)
> +		return NULL;
> +
>  	pgd = kvm->arch.pgd + stage2_pgd_index(addr);
>  	if (WARN_ON(stage2_pgd_none(*pgd))) {
>  		if (!cache)
> -- 
> 1.8.5.6
> 
> _______________________________________________
> kvmarm mailing list
> kvmarm@lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

WARNING: multiple messages have this Message-ID (diff)
From: Christoffer Dall <cdall@linaro.org>
To: Alexander Graf <agraf@suse.de>
Cc: kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org,
	kvm@vger.kernel.org
Subject: Re: [PATCH] KVM: arm/arm64: Handle hva aging while destroying the vm
Date: Mon, 3 Jul 2017 10:03:13 +0200	[thread overview]
Message-ID: <20170703080313.GB4066@cbox> (raw)
In-Reply-To: <1498231319-199734-1-git-send-email-agraf@suse.de>

Hi Alex,

On Fri, Jun 23, 2017 at 05:21:59PM +0200, Alexander Graf wrote:
> If we want to age an HVA while the VM is getting destroyed, we have a
> tiny race window during which we may end up dereferencing an invalid
> kvm->arch.pgd value.
> 
>    CPU0               CPU1
> 
>    kvm_age_hva()
>                       kvm_mmu_notifier_release()
>                       kvm_arch_flush_shadow_all()
>                       kvm_free_stage2_pgd()
>                       <grab mmu_lock>
>    stage2_get_pmd()
>    <wait for mmu_lock>
>                       set kvm->arch.pgd = 0
>                       <free mmu_lock>
>    <grab mmu_lock>
>    stage2_get_pud()
>    <access kvm->arch.pgd>
>    <use incorrect value>

I don't think this sequence, can happen, but I think kvm_age_hva() can
be called with the mmu_lock held and kvm->pgd already being NULL.

Is that possible for the mmu notifiers to be calling clear(_flush)_young
while also calling notifier_release?

If so, the patch below looks good to me.

Thanks,
-Christoffer


> 
> This patch adds a check for that case.
> 
> Signed-off-by: Alexander Graf <agraf@suse.de>
> ---
>  virt/kvm/arm/mmu.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
> index f2d5b6c..227931f 100644
> --- a/virt/kvm/arm/mmu.c
> +++ b/virt/kvm/arm/mmu.c
> @@ -861,6 +861,10 @@ static pud_t *stage2_get_pud(struct kvm *kvm, struct kvm_mmu_memory_cache *cache
>  	pgd_t *pgd;
>  	pud_t *pud;
>  
> +	/* Do we clash with kvm_free_stage2_pgd()? */
> +	if (!kvm->arch.pgd)
> +		return NULL;
> +
>  	pgd = kvm->arch.pgd + stage2_pgd_index(addr);
>  	if (WARN_ON(stage2_pgd_none(*pgd))) {
>  		if (!cache)
> -- 
> 1.8.5.6
> 
> _______________________________________________
> kvmarm mailing list
> kvmarm@lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

  reply	other threads:[~2017-07-03  8:03 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-23 15:21 [PATCH] KVM: arm/arm64: Handle hva aging while destroying the vm Alexander Graf
2017-07-03  8:03 ` Christoffer Dall [this message]
2017-07-03  8:03   ` Christoffer Dall
2017-07-03  8:48   ` Alexander Graf
2017-07-03  8:48     ` Alexander Graf
2017-07-03 23:41     ` Andrea Arcangeli
2017-07-03 23:41       ` Andrea Arcangeli
2017-07-04  8:35       ` Christoffer Dall
2017-07-04  8:35         ` Christoffer Dall
  -- strict thread matches above, loose matches on Subject: below --
2017-08-10  8:54 Suzuki K Poulose
2017-08-11 21:04 ` Greg KH

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=20170703080313.GB4066@cbox \
    --to=cdall@linaro.org \
    --cc=agraf@suse.de \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=linux-kernel@vger.kernel.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.