]> git.baikalelectronics.ru Git - kernel.git/commitdiff
efi: Save location of EFI confidential computing area
authorDov Murik <dovmurik@linux.ibm.com>
Tue, 12 Apr 2022 21:21:24 +0000 (21:21 +0000)
committerArd Biesheuvel <ardb@kernel.org>
Wed, 13 Apr 2022 17:11:18 +0000 (19:11 +0200)
Confidential computing (coco) hardware such as AMD SEV (Secure Encrypted
Virtualization) allows a guest owner to inject secrets into the VMs
memory without the host/hypervisor being able to read them.

Firmware support for secret injection is available in OVMF, which
reserves a memory area for secret injection and includes a pointer to it
the in EFI config table entry LINUX_EFI_COCO_SECRET_TABLE_GUID.

If EFI exposes such a table entry, uefi_init() will keep a pointer to
the EFI config table entry in efi.coco_secret, so it can be used later
by the kernel (specifically drivers/virt/coco/efi_secret).  It will also
appear in the kernel log as "CocoSecret=ADDRESS"; for example:

    [    0.000000] efi: EFI v2.70 by EDK II
    [    0.000000] efi: CocoSecret=0x7f22e680 SMBIOS=0x7f541000 ACPI=0x7f77e000 ACPI 2.0=0x7f77e014 MEMATTR=0x7ea0c018

The new functionality can be enabled with CONFIG_EFI_COCO_SECRET=y.

Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Link: https://lore.kernel.org/r/20220412212127.154182-2-dovmurik@linux.ibm.com
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
arch/x86/platform/efi/efi.c
drivers/firmware/efi/Kconfig
drivers/firmware/efi/efi.c
include/linux/efi.h

index 147c30a81f15b8fc0fbdb61f632ecf42f36f04ce..1591d67e0bcde3e1b6a97789e1f05ed0b6ea2a5b 100644 (file)
@@ -93,6 +93,9 @@ static const unsigned long * const efi_tables[] = {
 #ifdef CONFIG_LOAD_UEFI_KEYS
        &efi.mokvar_table,
 #endif
+#ifdef CONFIG_EFI_COCO_SECRET
+       &efi.coco_secret,
+#endif
 };
 
 u64 efi_setup;         /* efi setup_data physical address */
index 243882f5e5f99384da8890e99ce9894684e5609a..f8ddd2259ba08e2820f8f7a8e26b7277b84773ff 100644 (file)
@@ -299,3 +299,19 @@ config EFI_DISABLE_RUNTIME
          an issue for Real-Time kernels.
 
          This default can be overridden by using the efi=runtime option.
+
+config EFI_COCO_SECRET
+       bool "EFI Confidential Computing Secret Area Support"
+       depends on EFI
+       help
+         Confidential Computing platforms (such as AMD SEV) allow the
+         Guest Owner to securely inject secrets during guest VM launch.
+         The secrets are placed in a designated EFI reserved memory area.
+
+         In order to use the secrets in the kernel, the location of the secret
+         area (as published in the EFI config table) must be kept.
+
+         If you say Y here, the address of the EFI secret area will be kept
+         for usage inside the kernel.  This will allow the
+         virt/coco/efi_secret module to access the secrets, which in turn
+         allows userspace programs to access the injected secrets.
index ff57db8f8d059d0839f768c6d57075d9b4eb703e..e0f43262d451d0bb5fc6f8a3068688f50af44659 100644 (file)
@@ -46,6 +46,9 @@ struct efi __read_mostly efi = {
 #ifdef CONFIG_LOAD_UEFI_KEYS
        .mokvar_table           = EFI_INVALID_TABLE_ADDR,
 #endif
+#ifdef CONFIG_EFI_COCO_SECRET
+       .coco_secret            = EFI_INVALID_TABLE_ADDR,
+#endif
 };
 EXPORT_SYMBOL(efi);
 
@@ -528,6 +531,9 @@ static const efi_config_table_type_t common_tables[] __initconst = {
 #endif
 #ifdef CONFIG_LOAD_UEFI_KEYS
        {LINUX_EFI_MOK_VARIABLE_TABLE_GUID,     &efi.mokvar_table,      "MOKvar"        },
+#endif
+#ifdef CONFIG_EFI_COCO_SECRET
+       {LINUX_EFI_COCO_SECRET_AREA_GUID,       &efi.coco_secret,       "CocoSecret"    },
 #endif
        {},
 };
index ccd4d3f91c98c247cb772df2a94e104b231a6bf7..771d4cd06b561a4aef81151a1f6916ad5a3f4e98 100644 (file)
@@ -405,6 +405,7 @@ void efi_native_runtime_setup(void);
 #define LINUX_EFI_MEMRESERVE_TABLE_GUID                EFI_GUID(0x888eb0c6, 0x8ede, 0x4ff5,  0xa8, 0xf0, 0x9a, 0xee, 0x5c, 0xb9, 0x77, 0xc2)
 #define LINUX_EFI_INITRD_MEDIA_GUID            EFI_GUID(0x5568e427, 0x68fc, 0x4f3d,  0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68)
 #define LINUX_EFI_MOK_VARIABLE_TABLE_GUID      EFI_GUID(0xc451ed2b, 0x9694, 0x45d3,  0xba, 0xba, 0xed, 0x9f, 0x89, 0x88, 0xa3, 0x89)
+#define LINUX_EFI_COCO_SECRET_AREA_GUID                EFI_GUID(0xadf956ad, 0xe98c, 0x484c,  0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47)
 
 /* OEM GUIDs */
 #define DELLEMC_EFI_RCI2_TABLE_GUID            EFI_GUID(0x2d9f28a2, 0xa886, 0x456a,  0x97, 0xa8, 0xf1, 0x1e, 0xf2, 0x4f, 0xf4, 0x55)
@@ -596,6 +597,7 @@ extern struct efi {
        unsigned long                   tpm_log;                /* TPM2 Event Log table */
        unsigned long                   tpm_final_log;          /* TPM2 Final Events Log table */
        unsigned long                   mokvar_table;           /* MOK variable config table */
+       unsigned long                   coco_secret;            /* Confidential computing secret table */
 
        efi_get_time_t                  *get_time;
        efi_set_time_t                  *set_time;
@@ -1335,4 +1337,12 @@ extern void efifb_setup_from_dmi(struct screen_info *si, const char *opt);
 static inline void efifb_setup_from_dmi(struct screen_info *si, const char *opt) { }
 #endif
 
+struct linux_efi_coco_secret_area {
+       u64     base_pa;
+       u64     size;
+};
+
+/* Header of a populated EFI secret area */
+#define EFI_SECRET_TABLE_HEADER_GUID   EFI_GUID(0x1e74f542, 0x71dd, 0x4d66,  0x96, 0x3e, 0xef, 0x42, 0x87, 0xff, 0x17, 0x3b)
+
 #endif /* _LINUX_EFI_H */