Browse Source

efi_loader: implement EFI_RT_PROPERTIES_TABLE

UEFI spec 2.8 errata A replaces the RuntimeServicesSupported variable
defined in UEFI spec 2.8 by the configuration table
EFI_RT_PROPERTIES_TABLE. So let's follow suit.

Cc: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Tested-by: Ard Biesheuvel <ardb@kernel.org>
Heinrich Schuchardt 4 years ago
parent
commit
76be687288
4 changed files with 48 additions and 12 deletions
  1. 4 0
      cmd/efidebug.c
  2. 12 0
      include/efi_api.h
  3. 28 8
      lib/efi_loader/efi_runtime.c
  4. 4 4
      lib/efi_loader/efi_setup.c

+ 4 - 0
cmd/efidebug.c

@@ -264,6 +264,10 @@ static const struct {
 		"SMBIOS table",
 		SMBIOS_TABLE_GUID,
 	},
+	{
+		"Runtime properties",
+		EFI_RT_PROPERTIES_TABLE_GUID,
+	},
 };
 
 /**

+ 12 - 0
include/efi_api.h

@@ -228,6 +228,18 @@ struct efi_capsule_header {
 #define EFI_RT_SUPPORTED_QUERY_CAPSULE_CAPABILITIES	0x1000
 #define EFI_RT_SUPPORTED_QUERY_VARIABLE_INFO		0x2000
 
+#define EFI_RT_PROPERTIES_TABLE_GUID \
+	EFI_GUID(0xeb66918a, 0x7eef, 0x402a, 0x84, 0x2e, \
+		 0x93, 0x1d, 0x21, 0xc3, 0x8a, 0xe9)
+
+#define EFI_RT_PROPERTIES_TABLE_VERSION	0x1
+
+struct efi_rt_properties_table {
+	u16 version;
+	u16 length;
+	u32 runtime_services_supported;
+};
+
 struct efi_runtime_services {
 	struct efi_table_hdr hdr;
 	efi_status_t (EFIAPI *get_time)(struct efi_time *time,

+ 28 - 8
lib/efi_loader/efi_runtime.c

@@ -18,6 +18,10 @@
 /* For manual relocation support */
 DECLARE_GLOBAL_DATA_PTR;
 
+/* GUID of the runtime properties table */
+static const efi_guid_t efi_rt_properties_table_guid =
+				EFI_RT_PROPERTIES_TABLE_GUID;
+
 struct efi_runtime_mmio_list {
 	struct list_head link;
 	void **ptr;
@@ -94,9 +98,28 @@ static __efi_runtime_data efi_uintn_t efi_descriptor_size;
  * handle a good number of runtime callbacks
  */
 
+/**
+ * efi_init_runtime_supported() - create runtime properties table
+ *
+ * Create a configuration table specifying which services are available at
+ * runtime.
+ *
+ * Return:	status code
+ */
 efi_status_t efi_init_runtime_supported(void)
 {
-	u16 efi_runtime_services_supported =
+	efi_status_t ret;
+	struct efi_rt_properties_table *rt_table;
+
+	ret = efi_allocate_pool(EFI_RUNTIME_SERVICES_DATA,
+				sizeof(struct efi_rt_properties_table),
+				(void **)&rt_table);
+	if (ret != EFI_SUCCESS)
+		return ret;
+
+	rt_table->version = EFI_RT_PROPERTIES_TABLE_VERSION;
+	rt_table->length = sizeof(struct efi_rt_properties_table);
+	rt_table->runtime_services_supported =
 				EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP |
 				EFI_RT_SUPPORTED_CONVERT_POINTER;
 
@@ -105,15 +128,12 @@ efi_status_t efi_init_runtime_supported(void)
 	 * as well as efi_runtime_services.
 	 */
 #ifdef CONFIG_EFI_HAVE_RUNTIME_RESET
-	efi_runtime_services_supported |= EFI_RT_SUPPORTED_RESET_SYSTEM;
+	rt_table->runtime_services_supported |= EFI_RT_SUPPORTED_RESET_SYSTEM;
 #endif
 
-	return EFI_CALL(efi_set_variable(L"RuntimeServicesSupported",
-					 &efi_global_variable_guid,
-					 EFI_VARIABLE_BOOTSERVICE_ACCESS |
-					 EFI_VARIABLE_RUNTIME_ACCESS,
-					 sizeof(efi_runtime_services_supported),
-					 &efi_runtime_services_supported));
+	ret = efi_install_configuration_table(&efi_rt_properties_table_guid,
+					      rt_table);
+	return ret;
 }
 
 /**

+ 4 - 4
lib/efi_loader/efi_setup.c

@@ -122,13 +122,13 @@ efi_status_t efi_init_obj_list(void)
 	if (ret != EFI_SUCCESS)
 		goto out;
 
-	/* Indicate supported runtime services */
-	ret = efi_init_runtime_supported();
+	/* Initialize system table */
+	ret = efi_initialize_system_table();
 	if (ret != EFI_SUCCESS)
 		goto out;
 
-	/* Initialize system table */
-	ret = efi_initialize_system_table();
+	/* Indicate supported runtime services */
+	ret = efi_init_runtime_supported();
 	if (ret != EFI_SUCCESS)
 		goto out;