Commit 12274189 authored by Dov Murik's avatar Dov Murik Committed by Ard Biesheuvel
Browse files

efi: Save location of EFI confidential computing area



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: default avatarDov Murik <dovmurik@linux.ibm.com>
Reviewed-by: default avatarGerd Hoffmann <kraxel@redhat.com>
Link: https://lore.kernel.org/r/20220412212127.154182-2-dovmurik@linux.ibm.com


Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
parent a031651f
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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 */
+16 −0
Original line number Diff line number Diff line
@@ -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.
+6 −0
Original line number Diff line number Diff line
@@ -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
	{},
};
+10 −0
Original line number Diff line number Diff line
@@ -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 */