2023-01-23 16:51:46

by Jeremi Piotrowski

[permalink] [raw]
Subject: [RFC PATCH v1 0/6] Support nested SNP KVM guests on Hyper-V

This patch series enables SNP-host support when running on Hyper-V, which
allows launching nested SNP guests. No guest or qemu changes are necessary
for this to work.

Patch 1 deals with allocating an RMP table which is not provided by
firmware/hypervisor. Patch 2 implements MSR-based rmpupdate/psmash instructions
which are meant for virtualized environments. Patch 3 maintains the rmptable
for internal kernel page tracking. Patch 4 makes sure that the kernel does not
disable SNP support during early CPU init. Patch 5 allows SNP initialization to
proceed when no iommus are available. Patch 6 adds a quirk in psp command
buffer handling, because of differences in SNP firmware spec interpretation.

This series depends on

- "Add AMD Secure Nested Paging (SEV-SNP) Hypervisor Support" (applies on top of RFC v7)
https://lore.kernel.org/lkml/[email protected]/
- "Support ACPI PSP on Hyper-V"
https://lore.kernel.org/lkml/[email protected]/

Jeremi Piotrowski (6):
x86/hyperv: Allocate RMP table during boot
x86/sev: Add support for NestedVirtSnpMsr
x86/sev: Maintain shadow rmptable on Hyper-V
x86/amd: Configure necessary MSRs for SNP during CPU init when running
as a guest
iommu/amd: Don't fail snp_enable when running virtualized
crypto: ccp - Introduce quirk to always reclaim pages after SEV-legacy
commands

arch/x86/hyperv/hv_init.c | 5 ++
arch/x86/include/asm/cpufeatures.h | 1 +
arch/x86/include/asm/hyperv-tlfs.h | 3 +
arch/x86/include/asm/mshyperv.h | 3 +
arch/x86/include/asm/msr-index.h | 2 +
arch/x86/include/asm/sev.h | 2 +
arch/x86/kernel/cpu/amd.c | 8 +-
arch/x86/kernel/cpu/mshyperv.c | 41 ++++++++++
arch/x86/kernel/sev.c | 122 ++++++++++++++++++++++++++---
drivers/crypto/ccp/sev-dev.c | 6 +-
drivers/crypto/ccp/sp-dev.h | 4 +
drivers/crypto/ccp/sp-platform.c | 1 +
drivers/iommu/amd/init.c | 6 ++
13 files changed, 191 insertions(+), 13 deletions(-)

--
2.25.1



2023-01-23 16:52:21

by Jeremi Piotrowski

[permalink] [raw]
Subject: [RFC PATCH v1 6/6] crypto: ccp - Introduce quirk to always reclaim pages after SEV-legacy commands

On Hyper-V, the rmp_mark_pages_shared() call after a SEV_PLATFORM_STATUS
fails with return code 2 (FAIL_PERMISSION) due to the page having the
immutable bit set in the RMP (SNP has been initialized). The comment
above this spot mentions that firmware automatically clears the
immutable bit, but I can't find any mention of this behavior in the SNP
Firmware ABI Spec.

Introduce a quirk to always attempt the page reclaim and set it for the
platform PSP. It would be possible to make this behavior unconditional
as the firmware spec defines that page reclaim results in success if the
page does not have the immutable bit set.

Signed-off-by: Jeremi Piotrowski <[email protected]>
---
drivers/crypto/ccp/sev-dev.c | 6 +++++-
drivers/crypto/ccp/sp-dev.h | 4 ++++
drivers/crypto/ccp/sp-platform.c | 1 +
3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
index 6c4fdcaed72b..4719c0cafa28 100644
--- a/drivers/crypto/ccp/sev-dev.c
+++ b/drivers/crypto/ccp/sev-dev.c
@@ -658,8 +658,12 @@ static int __snp_cmd_buf_copy(int cmd, void *cmd_buf, bool to_fw, int fw_err)
* no not need to reclaim the page.
*/
if (from_fw && sev_legacy_cmd_buf_writable(cmd)) {
- if (rmp_mark_pages_shared(__pa(cmd_buf), 1))
+ if (psp_master->vdata->quirks & PSP_QUIRK_ALWAYS_RECLAIM) {
+ if (snp_reclaim_pages(__pa(cmd_buf), 1, true))
+ return -EFAULT;
+ } else if (rmp_mark_pages_shared(__pa(cmd_buf), 1)) {
return -EFAULT;
+ }

/* No need to go further if firmware failed to execute command. */
if (fw_err)
diff --git a/drivers/crypto/ccp/sp-dev.h b/drivers/crypto/ccp/sp-dev.h
index 083e57652c7b..6fb065a7d1fd 100644
--- a/drivers/crypto/ccp/sp-dev.h
+++ b/drivers/crypto/ccp/sp-dev.h
@@ -28,6 +28,9 @@
#define CACHE_NONE 0x00
#define CACHE_WB_NO_ALLOC 0xb7

+/* PSP requires a reclaim after every firmware command */
+#define PSP_QUIRK_ALWAYS_RECLAIM BIT(0)
+
/* Structure to hold CCP device data */
struct ccp_device;
struct ccp_vdata {
@@ -59,6 +62,7 @@ struct psp_vdata {
unsigned int feature_reg;
unsigned int inten_reg;
unsigned int intsts_reg;
+ unsigned int quirks;
};

/* Structure to hold SP device data */
diff --git a/drivers/crypto/ccp/sp-platform.c b/drivers/crypto/ccp/sp-platform.c
index d56b34255b97..cae3e7e8f289 100644
--- a/drivers/crypto/ccp/sp-platform.c
+++ b/drivers/crypto/ccp/sp-platform.c
@@ -43,6 +43,7 @@ static struct psp_vdata psp_platform = {
.feature_reg = -1,
.inten_reg = -1,
.intsts_reg = -1,
+ .quirks = PSP_QUIRK_ALWAYS_RECLAIM,
};
#endif

--
2.25.1