Thread (239 messages) 239 messages, 19 authors, 2022-09-19

Re: [PATCH Part2 v5 00/45] Add AMD Secure Nested Paging (SEV-SNP) Hypervisor Support

From: Marc Orr <hidden>
Date: 2021-11-13 01:05:08
Also in: kvm, linux-crypto, linux-mm, lkml

On Fri, Nov 12, 2021 at 4:53 PM Sean Christopherson [off-list ref] wrote:
On Fri, Nov 12, 2021, Peter Gonda wrote:
quoted
On Fri, Nov 12, 2021 at 2:43 PM Marc Orr [off-list ref] wrote:
quoted
On Fri, Nov 12, 2021 at 1:39 PM Andy Lutomirski [off-list ref] wrote:
quoted
Let's consider a very very similar scenario: consider a guest driver
setting up a 1 GB DMA buffer.  The virtual device, implemented as host
process, needs to (1) map (and thus lock *or* be prepared for faults) in
1GB / 4k pages of guest memory (so they're not *freed* while the DMA
write is taking place), (2) write the buffer, and (3) unlock all the
pages.  Or it can lock them at setup time and keep them locked for a long
time if that's appropriate.

Sure, the locking is expensive, but it's nonnegotiable.  The RMP issue is
just a special case of the more general issue that the host MUST NOT
ACCESS GUEST MEMORY AFTER IT'S FREED.
Good point.
Thanks for the responses Andy.

Having a way for userspace to lock pages as shared was an idea I just
proposed the simplest solution to start the conversation.
Assuming you meant that to read:

  Having a way for userspace to lock pages as shared is an alternative idea; I
  just proposed the simplest solution to start the conversation.

The unmapping[*] guest private memory proposal is essentially that, a way for userspace
to "lock" the state of a page by requiring all conversions to be initiated by userspace
and by providing APIs to associate a pfn 1:1 with a KVM instance, i.e. lock a pfn to
a guest.

Andy's DMA example brings up a very good point though.  If the shared and private
variants of a given GPA are _not_ required to point at a single PFN, which is the
case in the current unmapping proposal, userspace doesn't need to do any additional
juggling to track guest conversions across multiple processes.

Any process that's accessing guest (shared!) memory simply does its locking as normal,
which as Andy pointed out, is needed for correctness today.  If the guest requests a
conversion from shared=>private without first ensuring the gfn is unused (by a host
"device"), the host will side will continue accessing the old, shared memory, which it
locked, while the guest will be doing who knows what.  And if the guest provides a GPA
that isn't mapped shared in the VMM's address space, it's conceptually no different
than if the guest provided a completely bogus GPA, which again needs to be handled today.

In other words, if done properly, differentiating private from shared shouldn't be a
heavy lift for host userspace.

[*] Actually unmapping memory may not be strictly necessary for SNP because a
    #PF(RMP) is likely just as good as a #PF(!PRESENT) when both are treated as
    fatal, but the rest of the proposal that allows KVM to understand the stage
    of a page and exit to userspace accordingly applies.
Thanks for this explanation. When you write "while the guest will be
doing who knows what":

Isn't that a large weakness of this proposal? To me, it seems better
for debuggability to corrupt the private memory (i.e., convert the
page to shared) so the guest can detect the issue via a PVALIDATE
failure.

The main issue I see with corrupting the guest memory is that we may
not know whether the host is at fault or the guest. Though, we can
probably in many cases be sure it's the host, if the pid associated
with the page fault is NOT a process associated with virtualization.
But if it is a process associated with virtualization, we legitimately
might not know. (I think if the pid is the kernel itself, it's
probably a host-side bug, but I'm still not confident on this; for
example, the guest might be able to coerce KVM's built-in emulator to
write guest private memory.)
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help