<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/linux.git/virt/kvm/pfncache.c, branch linux-7.1.y</title>
<subtitle>Linux kernel stable tree (mirror)</subtitle>
<id>https://git.radix-linux.su/kernel/linux.git/atom?h=linux-7.1.y</id>
<link rel='self' href='https://git.radix-linux.su/kernel/linux.git/atom?h=linux-7.1.y'/>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/'/>
<updated>2024-10-25T16:57:59+00:00</updated>
<entry>
<title>KVM: pfncache: Precisely track refcounted pages</title>
<updated>2024-10-25T16:57:59+00:00</updated>
<author>
<name>Sean Christopherson</name>
<email>seanjc@google.com</email>
</author>
<published>2024-10-10T18:23:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=3154ddcb6a9016f314a2f5f1293808ad07c5fab9'/>
<id>urn:sha1:3154ddcb6a9016f314a2f5f1293808ad07c5fab9</id>
<content type='text'>
Track refcounted struct page memory using kvm_follow_pfn.refcounted_page
instead of relying on kvm_release_pfn_clean() to correctly detect that the
pfn is associated with a struct page.

Tested-by: Alex Bennée &lt;alex.bennee@linaro.org&gt;
Signed-off-by: Sean Christopherson &lt;seanjc@google.com&gt;
Tested-by: Dmitry Osipenko &lt;dmitry.osipenko@collabora.com&gt;
Signed-off-by: Paolo Bonzini &lt;pbonzini@redhat.com&gt;
Message-ID: &lt;20241010182427.1434605-30-seanjc@google.com&gt;
</content>
</entry>
<entry>
<title>KVM: Introduce kvm_follow_pfn() to eventually replace "gfn_to_pfn" APIs</title>
<updated>2024-10-25T16:57:59+00:00</updated>
<author>
<name>David Stevens</name>
<email>stevensd@chromium.org</email>
</author>
<published>2024-10-10T18:23:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=c0461f20630b457f7fdb80ec8bb03156f2d6fc84'/>
<id>urn:sha1:c0461f20630b457f7fdb80ec8bb03156f2d6fc84</id>
<content type='text'>
Introduce kvm_follow_pfn() to eventually supplant the various "gfn_to_pfn"
APIs, albeit by adding more wrappers.  The primary motivation of the new
helper is to pass a structure instead of an ever changing set of parameters,
e.g. so that tweaking the behavior, inputs, and/or outputs of the "to pfn"
helpers doesn't require churning half of KVM.

In the more distant future, the APIs exposed to arch code could also
follow suit, e.g. by adding something akin to x86's "struct kvm_page_fault"
when faulting in guest memory.  But for now, the goal is purely to clean
up KVM's "internal" MMU code.

As part of the conversion, replace the write_fault, interruptible, and
no-wait boolean flags with FOLL_WRITE, FOLL_INTERRUPTIBLE, and FOLL_NOWAIT
respectively.  Collecting the various FOLL_* flags into a single field
will again ease the pain of passing new flags.

Tested-by: Alex Bennée &lt;alex.bennee@linaro.org&gt;
Signed-off-by: David Stevens &lt;stevensd@chromium.org&gt;
Co-developed-by: Sean Christopherson &lt;seanjc@google.com&gt;
Signed-off-by: Sean Christopherson &lt;seanjc@google.com&gt;
Tested-by: Dmitry Osipenko &lt;dmitry.osipenko@collabora.com&gt;
Signed-off-by: Paolo Bonzini &lt;pbonzini@redhat.com&gt;
Message-ID: &lt;20241010182427.1434605-20-seanjc@google.com&gt;
</content>
</entry>
<entry>
<title>KVM: Replace "async" pointer in gfn=&gt;pfn with "no_wait" and error code</title>
<updated>2024-10-25T16:57:58+00:00</updated>
<author>
<name>David Stevens</name>
<email>stevensd@chromium.org</email>
</author>
<published>2024-10-10T18:23:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=6769d1bcd3509ad2d2ee04da122c465a11a165b4'/>
<id>urn:sha1:6769d1bcd3509ad2d2ee04da122c465a11a165b4</id>
<content type='text'>
Add a pfn error code to communicate that hva_to_pfn() failed because I/O
was needed and disallowed, and convert @async to a constant @no_wait
boolean.  This will allow eliminating the @no_wait param by having callers
pass in FOLL_NOWAIT along with other FOLL_* flags.

Tested-by: Alex Bennée &lt;alex.bennee@linaro.org&gt;
Signed-off-by: David Stevens &lt;stevensd@chromium.org&gt;
Co-developed-by: Sean Christopherson &lt;seanjc@google.com&gt;
Signed-off-by: Sean Christopherson &lt;seanjc@google.com&gt;
Tested-by: Dmitry Osipenko &lt;dmitry.osipenko@collabora.com&gt;
Signed-off-by: Paolo Bonzini &lt;pbonzini@redhat.com&gt;
Message-ID: &lt;20241010182427.1434605-17-seanjc@google.com&gt;
</content>
</entry>
<entry>
<title>KVM: Drop @atomic param from gfn=&gt;pfn and hva=&gt;pfn APIs</title>
<updated>2024-10-25T16:57:58+00:00</updated>
<author>
<name>Sean Christopherson</name>
<email>seanjc@google.com</email>
</author>
<published>2024-10-10T18:23:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=e2d2ca71ac03c748dbc44e0dd7dc1557befb1ab6'/>
<id>urn:sha1:e2d2ca71ac03c748dbc44e0dd7dc1557befb1ab6</id>
<content type='text'>
Drop @atomic from the myriad "to_pfn" APIs now that all callers pass
"false", and remove a comment blurb about KVM running only the "GUP fast"
part in atomic context.

No functional change intended.

Reviewed-by: Alex Bennée &lt;alex.bennee@linaro.org&gt;
Tested-by: Alex Bennée &lt;alex.bennee@linaro.org&gt;
Signed-off-by: Sean Christopherson &lt;seanjc@google.com&gt;
Tested-by: Dmitry Osipenko &lt;dmitry.osipenko@collabora.com&gt;
Signed-off-by: Paolo Bonzini &lt;pbonzini@redhat.com&gt;
Message-ID: &lt;20241010182427.1434605-13-seanjc@google.com&gt;
</content>
</entry>
<entry>
<title>KVM: Validate hva in kvm_gpc_activate_hva() to fix __kvm_gpc_refresh() WARN</title>
<updated>2024-06-28T15:31:46+00:00</updated>
<author>
<name>Pei Li</name>
<email>peili.dev@gmail.com</email>
</author>
<published>2024-06-27T15:03:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=ebbdf37ce9abb597015fa85df6630ebfa7d0a97f'/>
<id>urn:sha1:ebbdf37ce9abb597015fa85df6630ebfa7d0a97f</id>
<content type='text'>
Check that the virtual address is "ok" when activating a gfn_to_pfn_cache
with a host VA to ensure that KVM never attempts to use a bad address.

This fixes a bug where KVM fails to check the incoming address when
handling KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO_HVA in kvm_xen_vcpu_set_attr().

Reported-by: syzbot+fd555292a1da3180fc82@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=fd555292a1da3180fc82
Tested-by: syzbot+fd555292a1da3180fc82@syzkaller.appspotmail.com
Signed-off-by: Pei Li &lt;peili.dev@gmail.com&gt;
Reviewed-by: Paul Durrant &lt;paul@xen.org&gt;
Reviewed-by: David Woodhouse &lt;dwmw@amazon.co.uk&gt;
Link: https://lore.kernel.org/r/20240627-bug5-v2-1-2c63f7ee6739@gmail.com
[sean: rewrite changelog with --verbose]
Signed-off-by: Sean Christopherson &lt;seanjc@google.com&gt;
</content>
</entry>
<entry>
<title>KVM: Drop unused @may_block param from gfn_to_pfn_cache_invalidate_start()</title>
<updated>2024-04-11T19:58:53+00:00</updated>
<author>
<name>Sean Christopherson</name>
<email>seanjc@google.com</email>
</author>
<published>2024-03-05T00:37:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=eefb85b3f0310c2f4149c50cb9b13094ed1dde25'/>
<id>urn:sha1:eefb85b3f0310c2f4149c50cb9b13094ed1dde25</id>
<content type='text'>
Remove gfn_to_pfn_cache_invalidate_start()'s unused @may_block parameter,
which was leftover from KVM's abandoned (for now) attempt to support guest
usage of gfn_to_pfn caches.

Fixes: a4bff3df5147 ("KVM: pfncache: remove KVM_GUEST_USES_PFN usage")
Reported-by: Like Xu &lt;like.xu.linux@gmail.com&gt;
Cc: Paul Durrant &lt;paul@xen.org&gt;
Cc: David Woodhouse &lt;dwmw2@infradead.org&gt;
Reviewed-by: Paul Durrant &lt;paul@xen.org&gt;
Reviewed-by: David Woodhouse &lt;dwmw@amazon.co.uk&gt;
Link: https://lore.kernel.org/r/20240305003742.245767-1-seanjc@google.com
Signed-off-by: Sean Christopherson &lt;seanjc@google.com&gt;
</content>
</entry>
<entry>
<title>KVM: Explicitly disallow activatating a gfn_to_pfn_cache with INVALID_GPA</title>
<updated>2024-04-08T20:20:24+00:00</updated>
<author>
<name>Sean Christopherson</name>
<email>seanjc@google.com</email>
</author>
<published>2024-03-20T00:15:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=fc62a4e8dee2d1a9037e8cdeaa52ba67457f7300'/>
<id>urn:sha1:fc62a4e8dee2d1a9037e8cdeaa52ba67457f7300</id>
<content type='text'>
Explicit disallow activating a gfn_to_pfn_cache with an error gpa, i.e.
INVALID_GPA, to ensure that KVM doesn't mistake a GPA-based cache for an
HVA-based cache (KVM uses INVALID_GPA as a magic value to differentiate
between GPA-based and HVA-based caches).

WARN if KVM attempts to activate a cache with INVALID_GPA, purely so that
new caches need to at least consider what to do with a "bad" GPA, as all
existing usage of kvm_gpc_activate() guarantees gpa != INVALID_GPA.  I.e.
removing the WARN in the future is completely reasonable if doing so would
yield cleaner/better code overall.

Reviewed-by: David Woodhouse &lt;dwmw@amazon.co.uk&gt;
Reviewed-by: Paul Durrant &lt;paul@xen.org&gt;
Link: https://lore.kernel.org/r/20240320001542.3203871-4-seanjc@google.com
Signed-off-by: Sean Christopherson &lt;seanjc@google.com&gt;
</content>
</entry>
<entry>
<title>KVM: Check validity of offset+length of gfn_to_pfn_cache prior to activation</title>
<updated>2024-04-08T20:20:24+00:00</updated>
<author>
<name>Sean Christopherson</name>
<email>seanjc@google.com</email>
</author>
<published>2024-03-20T00:15:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=5c9ca4ed890889a2b7c300c4f63f3baf3f63383f'/>
<id>urn:sha1:5c9ca4ed890889a2b7c300c4f63f3baf3f63383f</id>
<content type='text'>
When activating a gfn_to_pfn_cache, verify that the offset+length is sane
and usable before marking the cache active.  Letting __kvm_gpc_refresh()
detect the problem results in a cache being marked active without setting
the GPA (or any other fields), which in turn results in KVM trying to
refresh a cache with INVALID_GPA.

Attempting to refresh a cache with INVALID_GPA isn't functionally
problematic, but it runs afoul of the sanity check that exactly one of
GPA or userspace HVA is valid, i.e. that a cache is either GPA-based or
HVA-based.

Reported-by: syzbot+106a4f72b0474e1d1b33@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/0000000000005fa5cc0613f1cebd@google.com
Fixes: 721f5b0dda78 ("KVM: pfncache: allow a cache to be activated with a fixed (userspace) HVA")
Cc: David Woodhouse &lt;dwmw2@infradead.org&gt;
Cc: Paul Durrant &lt;paul@xen.org&gt;
Reviewed-by: Paul Durrant &lt;paul@xen.org&gt;
Reviewed-by: David Woodhouse &lt;dwmw@amazon.co.uk&gt;
Link: https://lore.kernel.org/r/20240320001542.3203871-3-seanjc@google.com
Signed-off-by: Sean Christopherson &lt;seanjc@google.com&gt;
</content>
</entry>
<entry>
<title>KVM: Add helpers to consolidate gfn_to_pfn_cache's page split check</title>
<updated>2024-04-08T20:20:23+00:00</updated>
<author>
<name>Sean Christopherson</name>
<email>seanjc@google.com</email>
</author>
<published>2024-03-20T00:15:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=18f06e97692516d28c3cdc577fb5c501d690b303'/>
<id>urn:sha1:18f06e97692516d28c3cdc577fb5c501d690b303</id>
<content type='text'>
Add a helper to check that the incoming length for a gfn_to_pfn_cache is
valid with respect to the cache's GPA and/or HVA.  To avoid activating a
cache with a bogus GPA, a future fix will fork the page split check in
the inner refresh path into activate() and the public rerfresh() APIs, at
which point KVM will check the length in three separate places.

Deliberately keep the "page offset" logic open coded, as the only other
path that consumes the offset, __kvm_gpc_refresh(), already needs to
differentiate between GPA-based and HVA-based caches, and it's not obvious
that using a helper is a net positive in overall code readability.

Note, for GPA-based caches, this has a subtle side effect of using the GPA
instead of the resolved HVA in the check() path, but that should be a nop
as the HVA offset is derived from the GPA, i.e. the two offsets are
identical, barring a KVM bug.

Reviewed-by: Paul Durrant &lt;paul@xen.org&gt;
Reviewed-by: David Woodhouse &lt;dwmw@amazon.co.uk&gt;
Link: https://lore.kernel.org/r/20240320001542.3203871-2-seanjc@google.com
Signed-off-by: Sean Christopherson &lt;seanjc@google.com&gt;
</content>
</entry>
<entry>
<title>KVM: pfncache: simplify locking and make more self-contained</title>
<updated>2024-03-05T00:22:38+00:00</updated>
<author>
<name>David Woodhouse</name>
<email>dwmw@amazon.co.uk</email>
</author>
<published>2024-02-27T11:49:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=6addfcf27139da1356493f2a440af1252b5b7dbe'/>
<id>urn:sha1:6addfcf27139da1356493f2a440af1252b5b7dbe</id>
<content type='text'>
The locking on the gfn_to_pfn_cache is... interesting. And awful.

There is a rwlock in -&gt;lock which readers take to ensure protection
against concurrent changes. But __kvm_gpc_refresh() makes assumptions
that certain fields will not change even while it drops the write lock
and performs MM operations to revalidate the target PFN and kernel
mapping.

Commit 93984f19e7bc ("KVM: Fully serialize gfn=&gt;pfn cache refresh via
mutex") partly addressed that — not by fixing it, but by adding a new
mutex, -&gt;refresh_lock. This prevented concurrent __kvm_gpc_refresh()
calls on a given gfn_to_pfn_cache, but is still only a partial solution.

There is still a theoretical race where __kvm_gpc_refresh() runs in
parallel with kvm_gpc_deactivate(). While __kvm_gpc_refresh() has
dropped the write lock, kvm_gpc_deactivate() clears the -&gt;active flag
and unmaps -&gt;khva. Then __kvm_gpc_refresh() determines that the previous
-&gt;pfn and -&gt;khva are still valid, and reinstalls those values into the
structure. This leaves the gfn_to_pfn_cache with the -&gt;valid bit set,
but -&gt;active clear. And a -&gt;khva which looks like a reasonable kernel
address but is actually unmapped.

All it takes is a subsequent reactivation to cause that -&gt;khva to be
dereferenced. This would theoretically cause an oops which would look
something like this:

[1724749.564994] BUG: unable to handle page fault for address: ffffaa3540ace0e0
[1724749.565039] RIP: 0010:__kvm_xen_has_interrupt+0x8b/0xb0

I say "theoretically" because theoretically, that oops that was seen in
production cannot happen. The code which uses the gfn_to_pfn_cache is
supposed to have its *own* locking, to further paper over the fact that
the gfn_to_pfn_cache's own papering-over (-&gt;refresh_lock) of its own
rwlock abuse is not sufficient.

For the Xen vcpu_info that external lock is the vcpu-&gt;mutex, and for the
shared info it's kvm-&gt;arch.xen.xen_lock. Those locks ought to protect
the gfn_to_pfn_cache against concurrent deactivation vs. refresh in all
but the cases where the vcpu or kvm object is being *destroyed*, in
which case the subsequent reactivation should never happen.

Theoretically.

Nevertheless, this locking abuse is awful and should be fixed, even if
no clear explanation can be found for how the oops happened. So expand
the use of the -&gt;refresh_lock mutex to ensure serialization of
activate/deactivate vs. refresh and make the pfncache locking entirely
self-sufficient.

This means that a future commit can simplify the locking in the callers,
such as the Xen emulation code which has an outstanding problem with
recursive locking of kvm-&gt;arch.xen.xen_lock, which will no longer be
necessary.

The rwlock abuse described above is still not best practice, although
it's harmless now that the -&gt;refresh_lock is held for the entire duration
while the offending code drops the write lock, does some other stuff,
then takes the write lock again and assumes nothing changed. That can
also be fixed^W cleaned up in a subsequent commit, but this commit is
a simpler basis for the Xen deadlock fix mentioned above.

Signed-off-by: David Woodhouse &lt;dwmw@amazon.co.uk&gt;
Reviewed-by: Paul Durrant &lt;paul@xen.org&gt;
Link: https://lore.kernel.org/r/20240227115648.3104-5-dwmw2@infradead.org
[sean: use guard(mutex) to fix a missed unlock]
Signed-off-by: Sean Christopherson &lt;seanjc@google.com&gt;
</content>
</entry>
</feed>
