From: Sean Christopherson <seanjc@google.com>
To: David Matlack <dmatlack@google.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
Vitaly Kuznetsov <vkuznets@redhat.com>,
Wanpeng Li <wanpengli@tencent.com>,
Jim Mattson <jmattson@google.com>, Joerg Roedel <joro@8bytes.org>,
Ben Gardon <bgardon@google.com>,
kvm@vger.kernel.org
Subject: Re: [PATCH v2 3/4] KVM: x86/mmu: Document and enforce MMU-writable and Host-writable invariants
Date: Fri, 14 Jan 2022 22:29:22 +0000 [thread overview]
Message-ID: <YeH5QlwgGcpStZyp@google.com> (raw)
In-Reply-To: <20220113233020.3986005-4-dmatlack@google.com>
On Thu, Jan 13, 2022, David Matlack wrote:
> +/*
> + * *_SPTE_HOST_WRITEABLE (aka Host-writable) indicates whether the host permits
> + * writes to the guest page mapped by the SPTE. This bit is cleared on SPTEs
> + * that map guest pages in read-only memslots and read-only VMAs.
> + *
> + * Invariants:
> + * - If Host-writable is clear, PT_WRITABLE_MASK must be clear.
> + *
> + *
> + * *_SPTE_MMU_WRITEABLE (aka MMU-writable) indicates whether the shadow MMU
> + * allows writes to the guest page mapped by the SPTE. This bit is cleared when
> + * the guest page mapped by the SPTE contains a page table that is being
> + * monitored for shadow paging. In this case the SPTE can only be made writable
> + * by unsyncing the shadow page under the mmu_lock.
> + *
> + * Invariants:
> + * - If MMU-writable is clear, PT_WRITABLE_MASK must be clear.
> + * - If MMU-writable is set, Host-writable must be set.
> + *
> + * If MMU-writable is set, PT_WRITABLE_MASK is normally set but can be cleared
> + * to track writes for dirty logging. For such SPTEs, KVM will locklessly set
> + * PT_WRITABLE_MASK upon the next write from the guest and record the write in
> + * the dirty log (see fast_page_fault()).
> + */
> +
> +/* Bits 9 and 10 are ignored by all non-EPT PTEs. */
> +#define DEFAULT_SPTE_HOST_WRITEABLE BIT_ULL(9)
> +#define DEFAULT_SPTE_MMU_WRITEABLE BIT_ULL(10)
Ha, so there's a massive comment above is_writable_pte() that covers a lot of
the same material. More below.
> +
> /*
> * Low ignored bits are at a premium for EPT, use high ignored bits, taking care
> * to not overlap the A/D type mask or the saved access bits of access-tracked
> @@ -316,8 +341,13 @@ static __always_inline bool is_rsvd_spte(struct rsvd_bits_validate *rsvd_check,
>
> static inline bool spte_can_locklessly_be_made_writable(u64 spte)
> {
> - return (spte & shadow_host_writable_mask) &&
> - (spte & shadow_mmu_writable_mask);
> + if (spte & shadow_mmu_writable_mask) {
> + WARN_ON_ONCE(!(spte & shadow_host_writable_mask));
> + return true;
> + }
> +
> + WARN_ON_ONCE(spte & PT_WRITABLE_MASK);
I don't like having the WARNs here. This is a moderately hot path, there are a
decent number of call sites, and the WARNs won't actually help detect the offender,
i.e. whoever wrote the bad SPTE long since got away.
And for whatever reason, I had a hell of a time (correctly) reading the second WARN :-)
Lastly, there's also an "overlapping" WARN in mark_spte_for_access_track().
> + return false;
To kill a few birds with fewer stones, what if we:
a. Move is_writable_pte() into spte.h, somewhat close to the HOST/MMU_WRITABLE
definitions.
b. Add a new helper, spte_check_writable_invariants(), to enforce that a SPTE
is WRITABLE iff it's MMU-Writable, and that a SPTE is MMU-Writable iff it's
HOST-Writable.
c. Drop the WARN in mark_spte_for_access_track().
d. Call spte_check_writable_invariants() when setting SPTEs.
e. Document everything in a comment above spte_check_writable_invariants().
next prev parent reply other threads:[~2022-01-14 22:29 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-13 23:30 [PATCH v2 0/4] KVM: x86/mmu: Fix write-protection bug in the TDP MMU David Matlack
2022-01-13 23:30 ` [PATCH v2 1/4] KVM: x86/mmu: Fix write-protection of PTs mapped by " David Matlack
2022-01-14 23:38 ` Sean Christopherson
2022-01-13 23:30 ` [PATCH v2 2/4] KVM: x86/mmu: Clear MMU-writable during changed_pte notifier David Matlack
2022-01-14 23:41 ` Sean Christopherson
2022-01-13 23:30 ` [PATCH v2 3/4] KVM: x86/mmu: Document and enforce MMU-writable and Host-writable invariants David Matlack
2022-01-14 22:29 ` Sean Christopherson [this message]
2022-01-18 17:45 ` David Matlack
2022-01-13 23:30 ` [PATCH v2 4/4] KVM: x86/mmu: Improve TLB flush comment in kvm_mmu_slot_remove_write_access() David Matlack
2022-01-14 23:58 ` Sean Christopherson
2022-01-17 17:59 ` [PATCH v2 0/4] KVM: x86/mmu: Fix write-protection bug in the TDP MMU Paolo Bonzini
2022-01-18 17:38 ` David Matlack
2022-01-18 17:41 ` 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=YeH5QlwgGcpStZyp@google.com \
--to=seanjc@google.com \
--cc=bgardon@google.com \
--cc=dmatlack@google.com \
--cc=jmattson@google.com \
--cc=joro@8bytes.org \
--cc=kvm@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=vkuznets@redhat.com \
--cc=wanpengli@tencent.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.