From: Sean Christopherson <seanjc@google.com>
To: Lai Jiangshan <jiangshanlai@gmail.com>
Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
Lai Jiangshan <laijs@linux.alibaba.com>,
Paolo Bonzini <pbonzini@redhat.com>
Subject: Re: [PATCH] kvm: don't lose the higher 32 bits of tlbs_dirty
Date: Mon, 14 Dec 2020 09:20:45 -0800 [thread overview]
Message-ID: <X9ee7RzW+Dhv1aoW@google.com> (raw)
In-Reply-To: <20201213044913.15137-1-jiangshanlai@gmail.com>
On Sun, Dec 13, 2020, Lai Jiangshan wrote:
> From: Lai Jiangshan <laijs@linux.alibaba.com>
>
> In kvm_mmu_notifier_invalidate_range_start(), tlbs_dirty is used as:
> need_tlb_flush |= kvm->tlbs_dirty;
> with need_tlb_flush's type being int and tlbs_dirty's type being long.
>
> It means that tlbs_dirty is always used as int and the higher 32 bits
> is useless.
It's probably worth noting in the changelog that it's _extremely_ unlikely this
bug can cause problems in practice. It would require encountering tlbs_dirty
on a 4 billion count boundary, and KVM would need to be using shadow paging or
be running a nested guest.
> We can just change need_tlb_flush's type to long to
> make full use of tlbs_dirty.
Hrm, this does solve the problem, but I'm not a fan of continuing to use an
integer variable as a boolean. Rather than propagate tlbs_dirty to
need_tlb_flush, what if this bug fix patch checks tlbs_dirty directly, and then
a follow up patch converts need_tlb_flush to a bool and removes the unnecessary
initialization (see below).
E.g. the net result of both patches would be:
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 3abcb2ce5b7d..93b6986d3dfc 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -473,7 +473,8 @@ static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
const struct mmu_notifier_range *range)
{
struct kvm *kvm = mmu_notifier_to_kvm(mn);
- int need_tlb_flush = 0, idx;
+ bool need_tlb_flush;
+ int idx;
idx = srcu_read_lock(&kvm->srcu);
spin_lock(&kvm->mmu_lock);
@@ -483,11 +484,10 @@ static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
* count is also read inside the mmu_lock critical section.
*/
kvm->mmu_notifier_count++;
- need_tlb_flush = kvm_unmap_hva_range(kvm, range->start, range->end,
- range->flags);
- need_tlb_flush |= kvm->tlbs_dirty;
+ need_tlb_flush = !!kvm_unmap_hva_range(kvm, range->start, range->end,
+ range->flags);
/* we've to flush the tlb before the pages can be freed */
- if (need_tlb_flush)
+ if (need_tlb_flush || kvm->tlbs_dirty)
kvm_flush_remote_tlbs(kvm);
spin_unlock(&kvm->mmu_lock);
Cc: stable@vger.kernel.org
Fixes: a4ee1ca4a36e ("KVM: MMU: delay flush all tlbs on sync_page path")
> Signed-off-by: Lai Jiangshan <laijs@linux.alibaba.com>
> ---
> virt/kvm/kvm_main.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 2541a17ff1c4..4e519a517e9f 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -470,7 +470,8 @@ static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
> const struct mmu_notifier_range *range)
> {
> struct kvm *kvm = mmu_notifier_to_kvm(mn);
> - int need_tlb_flush = 0, idx;
> + long need_tlb_flush = 0;
need_tlb_flush doesn't need to be initialized here, it's explicitly set via the
call to kvm_unmap_hva_range().
> + int idx;
>
> idx = srcu_read_lock(&kvm->srcu);
> spin_lock(&kvm->mmu_lock);
> --
> 2.19.1.6.gb485710b
>
next prev parent reply other threads:[~2020-12-14 17:21 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-13 4:49 [PATCH] kvm: don't lose the higher 32 bits of tlbs_dirty Lai Jiangshan
2020-12-14 17:20 ` Sean Christopherson [this message]
2020-12-15 5:14 ` Lai Jiangshan
2020-12-15 10:32 ` Paolo Bonzini
2020-12-15 14:52 ` [PATCH V2] kvm: check tlbs_dirty directly Lai Jiangshan
2020-12-15 18:44 ` Sean Christopherson
2020-12-16 9:46 ` Greg KH
2020-12-16 16:37 ` Paolo Bonzini
2020-12-17 15:41 ` [PATCH V3] " Lai Jiangshan
2020-12-21 18:31 ` Paolo Bonzini
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=X9ee7RzW+Dhv1aoW@google.com \
--to=seanjc@google.com \
--cc=jiangshanlai@gmail.com \
--cc=kvm@vger.kernel.org \
--cc=laijs@linux.alibaba.com \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
/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.