From: Sean Christopherson <seanjc@google.com>
To: David Stevens <stevensd@chromium.org>
Cc: Wanpeng Li <wanpengli@tencent.com>,
kvm@vger.kernel.org, Marc Zyngier <maz@kernel.org>,
Joerg Roedel <joro@8bytes.org>,
linux-kernel@vger.kernel.org, Paolo Bonzini <pbonzini@redhat.com>,
Will Deacon <will@kernel.org>,
kvmarm@lists.cs.columbia.edu,
linux-arm-kernel@lists.infradead.org,
Jim Mattson <jmattson@google.com>
Subject: Re: [PATCH v5 4/4] KVM: mmu: remove over-aggressive warnings
Date: Thu, 30 Dec 2021 19:22:03 +0000 [thread overview]
Message-ID: <Yc4G23rrSxS59br5@google.com> (raw)
In-Reply-To: <20211129034317.2964790-5-stevensd@google.com>
On Mon, Nov 29, 2021, David Stevens wrote:
> From: David Stevens <stevensd@chromium.org>
>
> Remove two warnings that require ref counts for pages to be non-zero, as
> mapped pfns from follow_pfn may not have an initialized ref count.
>
> Signed-off-by: David Stevens <stevensd@chromium.org>
> ---
> arch/x86/kvm/mmu/mmu.c | 7 -------
> virt/kvm/kvm_main.c | 2 +-
> 2 files changed, 1 insertion(+), 8 deletions(-)
>
> diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
> index 0626395ff1d9..7c4c7fededf0 100644
> --- a/arch/x86/kvm/mmu/mmu.c
> +++ b/arch/x86/kvm/mmu/mmu.c
> @@ -621,13 +621,6 @@ static int mmu_spte_clear_track_bits(struct kvm *kvm, u64 *sptep)
>
> pfn = spte_to_pfn(old_spte);
>
> - /*
> - * KVM does not hold the refcount of the page used by
> - * kvm mmu, before reclaiming the page, we should
> - * unmap it from mmu first.
> - */
> - WARN_ON(!kvm_is_reserved_pfn(pfn) && !page_count(pfn_to_page(pfn)));
> -
> if (is_accessed_spte(old_spte))
> kvm_set_pfn_accessed(pfn);
>
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 16a8a71f20bf..d81edcb3e107 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -170,7 +170,7 @@ bool kvm_is_zone_device_pfn(kvm_pfn_t pfn)
> * the device has been pinned, e.g. by get_user_pages(). WARN if the
> * page_count() is zero to help detect bad usage of this helper.
Stale comment.
> */
> - if (!pfn_valid(pfn) || WARN_ON_ONCE(!page_count(pfn_to_page(pfn))))
> + if (!pfn_valid(pfn) || !page_count(pfn_to_page(pfn)))
Hrm, I know the whole point of this series is to support pages without an elevated
refcount, but this WARN was extremely helpful in catching several use-after-free
bugs in the TDP MMU. We talked about burying a slow check behind MMU_WARN_ON, but
that isn't very helpful because no one runs with MMU_WARN_ON, and this is also a
type of check that's most useful if it runs in production.
IIUC, this series explicitly disallows using pfns that have a struct page without
refcounting, and the issue with the WARN here is that kvm_is_zone_device_pfn() is
called by kvm_is_reserved_pfn() before ensure_pfn_ref() rejects problematic pages,
i.e. triggers false positive.
So, can't we preserve the use-after-free benefits of the check by moving it to
where KVM releases the PFN? I.e.
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index fbca2e232e94..675b835525fa 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2904,15 +2904,19 @@ EXPORT_SYMBOL_GPL(kvm_release_pfn_dirty);
void kvm_set_pfn_dirty(kvm_pfn_t pfn)
{
- if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn))
+ if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn)) {
+ WARN_ON_ONCE(!page_count(pfn_to_page(pfn)));
SetPageDirty(pfn_to_page(pfn));
+ }
}
EXPORT_SYMBOL_GPL(kvm_set_pfn_dirty);
void kvm_set_pfn_accessed(kvm_pfn_t pfn)
{
- if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn))
+ if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn)) {
+ WARN_ON_ONCE(!page_count(pfn_to_page(pfn)));
mark_page_accessed(pfn_to_page(pfn));
+ }
}
EXPORT_SYMBOL_GPL(kvm_set_pfn_accessed);
In a way, that's even better than the current check as it makes it more obvious
that the WARN is due to a use-after-free.
_______________________________________________
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: Sean Christopherson <seanjc@google.com>
To: David Stevens <stevensd@chromium.org>
Cc: Marc Zyngier <maz@kernel.org>,
Paolo Bonzini <pbonzini@redhat.com>,
James Morse <james.morse@arm.com>,
Alexandru Elisei <alexandru.elisei@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Will Deacon <will@kernel.org>, Wanpeng Li <wanpengli@tencent.com>,
Jim Mattson <jmattson@google.com>, Joerg Roedel <joro@8bytes.org>,
linux-arm-kernel@lists.infradead.org,
kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org,
kvm@vger.kernel.org
Subject: Re: [PATCH v5 4/4] KVM: mmu: remove over-aggressive warnings
Date: Thu, 30 Dec 2021 19:22:03 +0000 [thread overview]
Message-ID: <Yc4G23rrSxS59br5@google.com> (raw)
In-Reply-To: <20211129034317.2964790-5-stevensd@google.com>
On Mon, Nov 29, 2021, David Stevens wrote:
> From: David Stevens <stevensd@chromium.org>
>
> Remove two warnings that require ref counts for pages to be non-zero, as
> mapped pfns from follow_pfn may not have an initialized ref count.
>
> Signed-off-by: David Stevens <stevensd@chromium.org>
> ---
> arch/x86/kvm/mmu/mmu.c | 7 -------
> virt/kvm/kvm_main.c | 2 +-
> 2 files changed, 1 insertion(+), 8 deletions(-)
>
> diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
> index 0626395ff1d9..7c4c7fededf0 100644
> --- a/arch/x86/kvm/mmu/mmu.c
> +++ b/arch/x86/kvm/mmu/mmu.c
> @@ -621,13 +621,6 @@ static int mmu_spte_clear_track_bits(struct kvm *kvm, u64 *sptep)
>
> pfn = spte_to_pfn(old_spte);
>
> - /*
> - * KVM does not hold the refcount of the page used by
> - * kvm mmu, before reclaiming the page, we should
> - * unmap it from mmu first.
> - */
> - WARN_ON(!kvm_is_reserved_pfn(pfn) && !page_count(pfn_to_page(pfn)));
> -
> if (is_accessed_spte(old_spte))
> kvm_set_pfn_accessed(pfn);
>
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 16a8a71f20bf..d81edcb3e107 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -170,7 +170,7 @@ bool kvm_is_zone_device_pfn(kvm_pfn_t pfn)
> * the device has been pinned, e.g. by get_user_pages(). WARN if the
> * page_count() is zero to help detect bad usage of this helper.
Stale comment.
> */
> - if (!pfn_valid(pfn) || WARN_ON_ONCE(!page_count(pfn_to_page(pfn))))
> + if (!pfn_valid(pfn) || !page_count(pfn_to_page(pfn)))
Hrm, I know the whole point of this series is to support pages without an elevated
refcount, but this WARN was extremely helpful in catching several use-after-free
bugs in the TDP MMU. We talked about burying a slow check behind MMU_WARN_ON, but
that isn't very helpful because no one runs with MMU_WARN_ON, and this is also a
type of check that's most useful if it runs in production.
IIUC, this series explicitly disallows using pfns that have a struct page without
refcounting, and the issue with the WARN here is that kvm_is_zone_device_pfn() is
called by kvm_is_reserved_pfn() before ensure_pfn_ref() rejects problematic pages,
i.e. triggers false positive.
So, can't we preserve the use-after-free benefits of the check by moving it to
where KVM releases the PFN? I.e.
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index fbca2e232e94..675b835525fa 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2904,15 +2904,19 @@ EXPORT_SYMBOL_GPL(kvm_release_pfn_dirty);
void kvm_set_pfn_dirty(kvm_pfn_t pfn)
{
- if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn))
+ if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn)) {
+ WARN_ON_ONCE(!page_count(pfn_to_page(pfn)));
SetPageDirty(pfn_to_page(pfn));
+ }
}
EXPORT_SYMBOL_GPL(kvm_set_pfn_dirty);
void kvm_set_pfn_accessed(kvm_pfn_t pfn)
{
- if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn))
+ if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn)) {
+ WARN_ON_ONCE(!page_count(pfn_to_page(pfn)));
mark_page_accessed(pfn_to_page(pfn));
+ }
}
EXPORT_SYMBOL_GPL(kvm_set_pfn_accessed);
In a way, that's even better than the current check as it makes it more obvious
that the WARN is due to a use-after-free.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
WARNING: multiple messages have this Message-ID (diff)
From: Sean Christopherson <seanjc@google.com>
To: David Stevens <stevensd@chromium.org>
Cc: Marc Zyngier <maz@kernel.org>,
Paolo Bonzini <pbonzini@redhat.com>,
James Morse <james.morse@arm.com>,
Alexandru Elisei <alexandru.elisei@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Will Deacon <will@kernel.org>, Wanpeng Li <wanpengli@tencent.com>,
Jim Mattson <jmattson@google.com>, Joerg Roedel <joro@8bytes.org>,
linux-arm-kernel@lists.infradead.org,
kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org,
kvm@vger.kernel.org
Subject: Re: [PATCH v5 4/4] KVM: mmu: remove over-aggressive warnings
Date: Thu, 30 Dec 2021 19:22:03 +0000 [thread overview]
Message-ID: <Yc4G23rrSxS59br5@google.com> (raw)
In-Reply-To: <20211129034317.2964790-5-stevensd@google.com>
On Mon, Nov 29, 2021, David Stevens wrote:
> From: David Stevens <stevensd@chromium.org>
>
> Remove two warnings that require ref counts for pages to be non-zero, as
> mapped pfns from follow_pfn may not have an initialized ref count.
>
> Signed-off-by: David Stevens <stevensd@chromium.org>
> ---
> arch/x86/kvm/mmu/mmu.c | 7 -------
> virt/kvm/kvm_main.c | 2 +-
> 2 files changed, 1 insertion(+), 8 deletions(-)
>
> diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
> index 0626395ff1d9..7c4c7fededf0 100644
> --- a/arch/x86/kvm/mmu/mmu.c
> +++ b/arch/x86/kvm/mmu/mmu.c
> @@ -621,13 +621,6 @@ static int mmu_spte_clear_track_bits(struct kvm *kvm, u64 *sptep)
>
> pfn = spte_to_pfn(old_spte);
>
> - /*
> - * KVM does not hold the refcount of the page used by
> - * kvm mmu, before reclaiming the page, we should
> - * unmap it from mmu first.
> - */
> - WARN_ON(!kvm_is_reserved_pfn(pfn) && !page_count(pfn_to_page(pfn)));
> -
> if (is_accessed_spte(old_spte))
> kvm_set_pfn_accessed(pfn);
>
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 16a8a71f20bf..d81edcb3e107 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -170,7 +170,7 @@ bool kvm_is_zone_device_pfn(kvm_pfn_t pfn)
> * the device has been pinned, e.g. by get_user_pages(). WARN if the
> * page_count() is zero to help detect bad usage of this helper.
Stale comment.
> */
> - if (!pfn_valid(pfn) || WARN_ON_ONCE(!page_count(pfn_to_page(pfn))))
> + if (!pfn_valid(pfn) || !page_count(pfn_to_page(pfn)))
Hrm, I know the whole point of this series is to support pages without an elevated
refcount, but this WARN was extremely helpful in catching several use-after-free
bugs in the TDP MMU. We talked about burying a slow check behind MMU_WARN_ON, but
that isn't very helpful because no one runs with MMU_WARN_ON, and this is also a
type of check that's most useful if it runs in production.
IIUC, this series explicitly disallows using pfns that have a struct page without
refcounting, and the issue with the WARN here is that kvm_is_zone_device_pfn() is
called by kvm_is_reserved_pfn() before ensure_pfn_ref() rejects problematic pages,
i.e. triggers false positive.
So, can't we preserve the use-after-free benefits of the check by moving it to
where KVM releases the PFN? I.e.
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index fbca2e232e94..675b835525fa 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2904,15 +2904,19 @@ EXPORT_SYMBOL_GPL(kvm_release_pfn_dirty);
void kvm_set_pfn_dirty(kvm_pfn_t pfn)
{
- if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn))
+ if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn)) {
+ WARN_ON_ONCE(!page_count(pfn_to_page(pfn)));
SetPageDirty(pfn_to_page(pfn));
+ }
}
EXPORT_SYMBOL_GPL(kvm_set_pfn_dirty);
void kvm_set_pfn_accessed(kvm_pfn_t pfn)
{
- if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn))
+ if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn)) {
+ WARN_ON_ONCE(!page_count(pfn_to_page(pfn)));
mark_page_accessed(pfn_to_page(pfn));
+ }
}
EXPORT_SYMBOL_GPL(kvm_set_pfn_accessed);
In a way, that's even better than the current check as it makes it more obvious
that the WARN is due to a use-after-free.
next prev parent reply other threads:[~2021-12-30 19:22 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-29 3:43 [PATCH v5 0/4] KVM: allow mapping non-refcounted pages David Stevens
2021-11-29 3:43 ` David Stevens
2021-11-29 3:43 ` David Stevens
2021-11-29 3:43 ` [PATCH v5 1/4] KVM: mmu: introduce new gfn_to_pfn_page functions David Stevens
2021-11-29 3:43 ` David Stevens
2021-11-29 3:43 ` David Stevens
2021-12-30 19:26 ` Sean Christopherson
2021-12-30 19:26 ` Sean Christopherson
2021-12-30 19:26 ` Sean Christopherson
2021-11-29 3:43 ` [PATCH v5 2/4] KVM: x86/mmu: use gfn_to_pfn_page David Stevens
2021-11-29 3:43 ` David Stevens
2021-11-29 3:43 ` David Stevens
2021-12-30 19:30 ` Sean Christopherson
2021-12-30 19:30 ` Sean Christopherson
2021-12-30 19:30 ` Sean Christopherson
2021-11-29 3:43 ` [PATCH v5 3/4] KVM: arm64/mmu: " David Stevens
2021-11-29 3:43 ` David Stevens
2021-11-29 3:43 ` David Stevens
2021-12-30 19:45 ` Sean Christopherson
2021-12-30 19:45 ` Sean Christopherson
2021-12-30 19:45 ` Sean Christopherson
2021-11-29 3:43 ` [PATCH v5 4/4] KVM: mmu: remove over-aggressive warnings David Stevens
2021-11-29 3:43 ` David Stevens
2021-11-29 3:43 ` David Stevens
2021-12-30 19:22 ` Sean Christopherson [this message]
2021-12-30 19:22 ` Sean Christopherson
2021-12-30 19:22 ` Sean Christopherson
2022-01-05 7:14 ` David Stevens
2022-01-05 7:14 ` David Stevens
2022-01-05 7:14 ` David Stevens
2022-01-05 19:02 ` Sean Christopherson
2022-01-05 19:02 ` Sean Christopherson
2022-01-05 19:02 ` Sean Christopherson
2022-01-05 19:19 ` Sean Christopherson
2022-01-05 19:19 ` Sean Christopherson
2022-01-05 19:19 ` Sean Christopherson
2022-01-06 2:42 ` David Stevens
2022-01-06 2:42 ` David Stevens
2022-01-06 2:42 ` David Stevens
2022-01-06 17:38 ` Sean Christopherson
2022-01-06 17:38 ` Sean Christopherson
2022-01-06 17:38 ` Sean Christopherson
2022-01-07 2:21 ` David Stevens
2022-01-07 2:21 ` David Stevens
2022-01-07 2:21 ` David Stevens
2022-01-07 16:31 ` Sean Christopherson
2022-01-07 16:31 ` Sean Christopherson
2022-01-07 16:31 ` Sean Christopherson
2022-01-07 16:46 ` Sean Christopherson
2022-01-07 16:46 ` Sean Christopherson
2022-01-07 16:46 ` Sean Christopherson
2022-01-10 23:47 ` David Stevens
2022-01-10 23:47 ` David Stevens
2022-01-10 23:47 ` David Stevens
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=Yc4G23rrSxS59br5@google.com \
--to=seanjc@google.com \
--cc=jmattson@google.com \
--cc=joro@8bytes.org \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maz@kernel.org \
--cc=pbonzini@redhat.com \
--cc=stevensd@chromium.org \
--cc=wanpengli@tencent.com \
--cc=will@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.