]> git.baikalelectronics.ru Git - kernel.git/commitdiff
x86/compressed: Register GHCB memory when SEV-SNP is active
authorBrijesh Singh <brijesh.singh@amd.com>
Wed, 9 Feb 2022 18:10:10 +0000 (12:10 -0600)
committerBorislav Petkov <bp@suse.de>
Wed, 6 Apr 2022 11:14:24 +0000 (13:14 +0200)
The SEV-SNP guest is required by the GHCB spec to register the GHCB's
Guest Physical Address (GPA). This is because the hypervisor may prefer
that a guest use a consistent and/or specific GPA for the GHCB associated
with a vCPU. For more information, see the GHCB specification section
"GHCB GPA Registration".

If hypervisor can not work with the guest provided GPA then terminate the
guest boot.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Venu Busireddy <venu.busireddy@oracle.com>
Link: https://lore.kernel.org/r/20220307213356.2797205-17-brijesh.singh@amd.com
arch/x86/boot/compressed/sev.c
arch/x86/include/asm/sev-common.h
arch/x86/kernel/sev-shared.c

index 5f2c26860df723781f9d586e339367ac1d0e4899..f31b434e2ce43bc659954c290992e3c2dc2a64f5 100644 (file)
@@ -175,6 +175,10 @@ static bool early_setup_ghcb(void)
        /* Initialize lookup tables for the instruction decoder */
        inat_init_tables();
 
+       /* SNP guest requires the GHCB GPA must be registered */
+       if (sev_snp_enabled())
+               snp_register_ghcb_early(__pa(&boot_ghcb_page));
+
        return true;
 }
 
index fe7fe16e5fd516f760891f9dc86f0849a5dc873b..f077a6c95e67149e0ef0c71da9231cde7f4c4005 100644 (file)
 #define GHCB_MSR_AP_RESET_HOLD_REQ     0x006
 #define GHCB_MSR_AP_RESET_HOLD_RESP    0x007
 
+/* GHCB GPA Register */
+#define GHCB_MSR_REG_GPA_REQ           0x012
+#define GHCB_MSR_REG_GPA_REQ_VAL(v)                    \
+       /* GHCBData[63:12] */                           \
+       (((u64)((v) & GENMASK_ULL(51, 0)) << 12) |      \
+       /* GHCBData[11:0] */                            \
+       GHCB_MSR_REG_GPA_REQ)
+
+#define GHCB_MSR_REG_GPA_RESP          0x013
+#define GHCB_MSR_REG_GPA_RESP_VAL(v)                   \
+       /* GHCBData[63:12] */                           \
+       (((u64)(v) & GENMASK_ULL(63, 12)) >> 12)
+
 /*
  * SNP Page State Change Operation
  *
index 4a876e684f674ab6cc3e0fa4ba6b30535fb5c2d7..e9ff13cd90b0757c6be568ff97954ddb55c77570 100644 (file)
@@ -68,6 +68,22 @@ static u64 get_hv_features(void)
        return GHCB_MSR_HV_FT_RESP_VAL(val);
 }
 
+static void __maybe_unused snp_register_ghcb_early(unsigned long paddr)
+{
+       unsigned long pfn = paddr >> PAGE_SHIFT;
+       u64 val;
+
+       sev_es_wr_ghcb_msr(GHCB_MSR_REG_GPA_REQ_VAL(pfn));
+       VMGEXIT();
+
+       val = sev_es_rd_ghcb_msr();
+
+       /* If the response GPA is not ours then abort the guest */
+       if ((GHCB_RESP_CODE(val) != GHCB_MSR_REG_GPA_RESP) ||
+           (GHCB_MSR_REG_GPA_RESP_VAL(val) != pfn))
+               sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_REGISTER);
+}
+
 static bool sev_es_negotiate_protocol(void)
 {
        u64 val;