Re: [PATCH Part2 RFC v4 15/40] crypto: ccp: Handle the legacy TMR allocation when SNP is enabled
From: Marc Orr
Date: Wed Jul 14 2021 - 14:14:57 EST
> > Should this return a non-zero value -- maybe `-ENODEV`? Otherwise, the
> > `snp_alloc_firmware_page()` API will return a page that the caller
> > believes is suitable to use with FW. My concern is that someone
> > decides to use this API to stash a page very early on during kernel
> > boot and that page becomes a time bomb.
>
> But that means the caller now need to know that SNP is enabled before
> calling the APIs. The idea behind the API was that caller does not need
> to know whether the firmware is in the INIT state. If the firmware has
> initialized the SNP, then it will transparently set the immutable bit in
> the RMP table.
For SNP, isn't that already the case? There are three scenarios:
#1: The PSP driver is loaded and `snp_inited` is `true`: These returns
are never hit.
#2: The PSP driver is not loaded. The first return, `!psp ||
!psp->sev_data` fires. As written, it returns `0`, indicating success.
However, we never called RMPUPDATE on the page. Thus, later, when the
PSP driver is loaded, the page that was previously returned as usable
with FW is in fact not usable with FW. Unless SNP is disabled (e.g.,
SEV, SEV-ES only). In which case I guess the page is OK.
#3 The PSP driver is loaded but the SNP_INIT command has not been
issued. Looking at this again, I guess `return 0` is OK. Because if we
got this far, then `sev_pci_init()` has been called, and the SNP_INIT
command has been issued if we're supporting SNP VMs.
So in summary, I think we should change the first return to return an
error and leave the 2nd return as is.
> > If we initialize `rc` to `-ENODEV` (or something similar), then every
> > return in this function can be `return rc`.
> >
> >> +
> >> + /* If SEV-SNP is initialized then add the page in RMP table. */
> >> + sev = psp->sev_data;
> >> + if (!sev->snp_inited)
> >> + return 0;
> >
> > Ditto. Should this turn a non-zero value?
> >
> >> +
> >> + while (pfn < pfn_end) {
> >> + if (need_reclaim)
> >> + if (snp_reclaim_page(pfn_to_page(pfn), locked))
> >> + return -EFAULT;
> >> +
> >> + rc = rmpupdate(pfn_to_page(pfn), val);
> >> + if (rc)
> >> + return rc;
> >> +
> >> + pfn++;
> >> + }
> >> +
> >> + return 0;
> >> +}