Re: [PATCH RFC v8 15/56] x86/sev: Invalidate pages from the direct map when adding them to the RMP table

From: Michael Roth
Date: Tue Mar 28 2023 - 19:34:20 EST


On Wed, Mar 01, 2023 at 08:15:46AM -0800, Dave Hansen wrote:
> On 2/20/23 10:38, Michael Roth wrote:
> > From: Brijesh Singh <brijesh.singh@xxxxxxx>
> >
> > The integrity guarantee of SEV-SNP is enforced through the RMP table.
> > The RMP is used with standard x86 and IOMMU page tables to enforce
> > memory restrictions and page access rights. The RMP check is enforced as
> > soon as SEV-SNP is enabled globally in the system. When hardware
> > encounters an RMP-check failure, it raises a page-fault exception.
> >
> > The rmp_make_private() and rmp_make_shared() helpers are used to add
> > or remove the pages from the RMP table. Improve the rmp_make_private()
> > to invalidate state so that pages cannot be used in the direct-map after
> > they are added the RMP table, and restored to their default valid
> > permission after the pages are removed from the RMP table.
>
> This is a purely "what" changelog. It doesn't explain the "why" at all.
>
> Could you please elaborate on why this unmapping operation is necessary?
>

Here's my attempt at an updated changelog that explains why this handling
is needed:

With SEV-SNP, if a host attempts to write to a page that is owned by a
guest (according to the SEV-SNP RMP table), the host will get a #PF with
a bit set to indicate that an RMP violation occurred. This shouldn't
normally occur, since guest-owned pages are encrypted, so any attempt to
write to them would just result in garbage being written.

However, if a host writes to a page via a 2M/1G mapping in the host
process' page table, the above #PF condition will trigger if *any*
4K sub-pages mapped by that PTE are guest-owned, even if the write
is only to 4K pages that are owned by the host.

This becomes an issue with the kernel directmap, which provides a
static/linear mapping of all kernel memory and defaults to using 2M
pages. In cases where a page from one of these 2M ranges gets assigned
to a guest, the kernel can inadvertantly trigger #PF by writing to some
other page in that 2M region via the virtual addresses provided by the
directmap.

Address this by removing directmap mappings for these PFNs before
marking them as guest-owned in the RMP table, which will result in the
original 2M mapping being split and ensure that guest-owned pages can't
be written to via the kernel directmap.

-Mike