linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] efi: preserve NEON registers on UEFI services calls
@ 2014-06-26 10:09 Ard Biesheuvel
  2014-06-26 10:09 ` [PATCH v2 1/2] efi/x86: move UEFI Runtime Services wrappers to generic code Ard Biesheuvel
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2014-06-26 10:09 UTC (permalink / raw)
  To: linux-arm-kernel

The current UEFI implementation for arm64 fails to preserve/restore the contents
of the NEON register file, which may result in data corruption, especially now
that those contents are lazily restored for user processes.

This series proposes to fix this by wrapping all runtime services calls, and
adding kernel_neon_begin()/kernel_neon_end() pairs to the wrappers.

The first patch moves the existing x86 versions of those wrappers to generic
code, so that the second patch can easily enable them by supplying a definition
for efi_call_virt and adding a call to efi_native_runtime_setup().

Changes since v1:
- rename runtime.c -> runtime-wrappers.c
- make build depend on new Kconfig symbol EFI_RUNTIME_WRAPPERS to fix ia64
  breakage
- remove default #defines for efi_call_virt()/__efi_call_virt(), they are not
  needed anymore now that it is built conditionally
- add references to applicable UEFI/AAPCS spec sections

Ard Biesheuvel (2):
  efi/x86: move UEFI Runtime Services wrappers to generic code
  efi/arm64: preserve FP/SIMD registers on UEFI runtime services calls

 arch/arm64/Kconfig                      |   1 +
 arch/arm64/include/asm/efi.h            |  21 +++++
 arch/arm64/kernel/efi.c                 |  14 +--
 arch/x86/Kconfig                        |   1 +
 arch/x86/platform/efi/efi.c             | 144 +---------------------------
 drivers/firmware/efi/Kconfig            |   7 ++
 drivers/firmware/efi/Makefile           |   1 +
 drivers/firmware/efi/runtime-wrappers.c | 161 ++++++++++++++++++++++++++++++++
 include/linux/efi.h                     |   2 +
 9 files changed, 197 insertions(+), 155 deletions(-)
 create mode 100644 drivers/firmware/efi/runtime-wrappers.c

-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 1/2] efi/x86: move UEFI Runtime Services wrappers to generic code
  2014-06-26 10:09 [PATCH v2 0/2] efi: preserve NEON registers on UEFI services calls Ard Biesheuvel
@ 2014-06-26 10:09 ` Ard Biesheuvel
  2014-07-01 13:30   ` Matt Fleming
  2014-06-26 10:09 ` [PATCH v2 2/2] efi/arm64: preserve FP/SIMD registers on UEFI runtime services calls Ard Biesheuvel
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 15+ messages in thread
From: Ard Biesheuvel @ 2014-06-26 10:09 UTC (permalink / raw)
  To: linux-arm-kernel

In order for other archs (such as arm64) to be able to reuse the virtual mode
function call wrappers, move them to drivers/firmware/efi/runtime-wrappers.c.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/x86/Kconfig                        |   1 +
 arch/x86/platform/efi/efi.c             | 144 +---------------------------
 drivers/firmware/efi/Kconfig            |   7 ++
 drivers/firmware/efi/Makefile           |   1 +
 drivers/firmware/efi/runtime-wrappers.c | 161 ++++++++++++++++++++++++++++++++
 include/linux/efi.h                     |   2 +
 6 files changed, 174 insertions(+), 142 deletions(-)
 create mode 100644 drivers/firmware/efi/runtime-wrappers.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index a8f749ef0fdc..4c3f026aa5ce 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1522,6 +1522,7 @@ config EFI
 	bool "EFI runtime service support"
 	depends on ACPI
 	select UCS2_STRING
+	select EFI_RUNTIME_WRAPPERS
 	---help---
 	  This enables the kernel to use EFI runtime services that are
 	  available (such as the EFI variable services).
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 87fc96bcc13c..36d0835210c3 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -104,130 +104,6 @@ static int __init setup_storage_paranoia(char *arg)
 }
 early_param("efi_no_storage_paranoia", setup_storage_paranoia);
 
-static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
-{
-	unsigned long flags;
-	efi_status_t status;
-
-	spin_lock_irqsave(&rtc_lock, flags);
-	status = efi_call_virt(get_time, tm, tc);
-	spin_unlock_irqrestore(&rtc_lock, flags);
-	return status;
-}
-
-static efi_status_t virt_efi_set_time(efi_time_t *tm)
-{
-	unsigned long flags;
-	efi_status_t status;
-
-	spin_lock_irqsave(&rtc_lock, flags);
-	status = efi_call_virt(set_time, tm);
-	spin_unlock_irqrestore(&rtc_lock, flags);
-	return status;
-}
-
-static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,
-					     efi_bool_t *pending,
-					     efi_time_t *tm)
-{
-	unsigned long flags;
-	efi_status_t status;
-
-	spin_lock_irqsave(&rtc_lock, flags);
-	status = efi_call_virt(get_wakeup_time, enabled, pending, tm);
-	spin_unlock_irqrestore(&rtc_lock, flags);
-	return status;
-}
-
-static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
-{
-	unsigned long flags;
-	efi_status_t status;
-
-	spin_lock_irqsave(&rtc_lock, flags);
-	status = efi_call_virt(set_wakeup_time, enabled, tm);
-	spin_unlock_irqrestore(&rtc_lock, flags);
-	return status;
-}
-
-static efi_status_t virt_efi_get_variable(efi_char16_t *name,
-					  efi_guid_t *vendor,
-					  u32 *attr,
-					  unsigned long *data_size,
-					  void *data)
-{
-	return efi_call_virt(get_variable,
-			     name, vendor, attr,
-			     data_size, data);
-}
-
-static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
-					       efi_char16_t *name,
-					       efi_guid_t *vendor)
-{
-	return efi_call_virt(get_next_variable,
-			     name_size, name, vendor);
-}
-
-static efi_status_t virt_efi_set_variable(efi_char16_t *name,
-					  efi_guid_t *vendor,
-					  u32 attr,
-					  unsigned long data_size,
-					  void *data)
-{
-	return efi_call_virt(set_variable,
-			     name, vendor, attr,
-			     data_size, data);
-}
-
-static efi_status_t virt_efi_query_variable_info(u32 attr,
-						 u64 *storage_space,
-						 u64 *remaining_space,
-						 u64 *max_variable_size)
-{
-	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
-		return EFI_UNSUPPORTED;
-
-	return efi_call_virt(query_variable_info, attr, storage_space,
-			     remaining_space, max_variable_size);
-}
-
-static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)
-{
-	return efi_call_virt(get_next_high_mono_count, count);
-}
-
-static void virt_efi_reset_system(int reset_type,
-				  efi_status_t status,
-				  unsigned long data_size,
-				  efi_char16_t *data)
-{
-	__efi_call_virt(reset_system, reset_type, status,
-			data_size, data);
-}
-
-static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,
-					    unsigned long count,
-					    unsigned long sg_list)
-{
-	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
-		return EFI_UNSUPPORTED;
-
-	return efi_call_virt(update_capsule, capsules, count, sg_list);
-}
-
-static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,
-						unsigned long count,
-						u64 *max_size,
-						int *reset_type)
-{
-	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
-		return EFI_UNSUPPORTED;
-
-	return efi_call_virt(query_capsule_caps, capsules, count, max_size,
-			     reset_type);
-}
-
 static efi_status_t __init phys_efi_set_virtual_address_map(
 	unsigned long memory_map_size,
 	unsigned long descriptor_size,
@@ -847,22 +723,6 @@ void __init old_map_region(efi_memory_desc_t *md)
 		       (unsigned long long)md->phys_addr);
 }
 
-static void native_runtime_setup(void)
-{
-	efi.get_time = virt_efi_get_time;
-	efi.set_time = virt_efi_set_time;
-	efi.get_wakeup_time = virt_efi_get_wakeup_time;
-	efi.set_wakeup_time = virt_efi_set_wakeup_time;
-	efi.get_variable = virt_efi_get_variable;
-	efi.get_next_variable = virt_efi_get_next_variable;
-	efi.set_variable = virt_efi_set_variable;
-	efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
-	efi.reset_system = virt_efi_reset_system;
-	efi.query_variable_info = virt_efi_query_variable_info;
-	efi.update_capsule = virt_efi_update_capsule;
-	efi.query_capsule_caps = virt_efi_query_capsule_caps;
-}
-
 /* Merge contiguous regions of the same type and attribute */
 static void __init efi_merge_regions(void)
 {
@@ -1049,7 +909,7 @@ static void __init kexec_enter_virtual_mode(void)
 	 */
 	efi.runtime_version = efi_systab.hdr.revision;
 
-	native_runtime_setup();
+	efi_native_runtime_setup();
 
 	efi.set_virtual_address_map = NULL;
 
@@ -1142,7 +1002,7 @@ static void __init __efi_enter_virtual_mode(void)
 	efi.runtime_version = efi_systab.hdr.revision;
 
 	if (efi_is_native())
-		native_runtime_setup();
+		efi_native_runtime_setup();
 	else
 		efi_thunk_runtime_setup();
 
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index d420ae2d3413..04a7af46736a 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -54,6 +54,13 @@ config EFI_PARAMS_FROM_FDT
 	  the EFI runtime support gets system table address, memory
           map address, and other parameters from the device tree.
 
+config EFI_RUNTIME_WRAPPERS
+	bool
+	help
+	  Selected by the arch if it needs to wrap UEFI Runtime Services calls,
+	  in which case it needs to provide #definitions of efi_call_virt and
+	  __efi_call_virt in <asm/efi.h>
+
 endmenu
 
 config UEFI_CPER
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 9553496b0f43..e1096539eedb 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_EFI_VARS)			+= efivars.o
 obj-$(CONFIG_EFI_VARS_PSTORE)		+= efi-pstore.o
 obj-$(CONFIG_UEFI_CPER)			+= cper.o
 obj-$(CONFIG_EFI_RUNTIME_MAP)		+= runtime-map.o
+obj-$(CONFIG_EFI_RUNTIME_WRAPPERS)	+= runtime-wrappers.o
diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c
new file mode 100644
index 000000000000..10daa4bbb258
--- /dev/null
+++ b/drivers/firmware/efi/runtime-wrappers.c
@@ -0,0 +1,161 @@
+/*
+ * runtime-wrappers.c - Runtime Services function call wrappers
+ *
+ * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ *
+ * Split off from arch/x86/platform/efi/efi.c
+ *
+ * Copyright (C) 1999 VA Linux Systems
+ * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
+ * Copyright (C) 1999-2002 Hewlett-Packard Co.
+ * Copyright (C) 2005-2008 Intel Co.
+ * Copyright (C) 2013 SuSE Labs
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/efi.h>
+#include <linux/spinlock.h>             /* spinlock_t */
+#include <asm/efi.h>
+
+/*
+ * As per commit ef68c8f87ed1 ("x86: Serialize EFI time accesses on rtc_lock"),
+ * the EFI specification requires that callers of the time related runtime
+ * functions serialize with other CMOS accesses in the kernel, as the EFI time
+ * functions may choose to also use the legacy CMOS RTC.
+ */
+__weak DEFINE_SPINLOCK(rtc_lock);
+
+static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
+{
+	unsigned long flags;
+	efi_status_t status;
+
+	spin_lock_irqsave(&rtc_lock, flags);
+	status = efi_call_virt(get_time, tm, tc);
+	spin_unlock_irqrestore(&rtc_lock, flags);
+	return status;
+}
+
+static efi_status_t virt_efi_set_time(efi_time_t *tm)
+{
+	unsigned long flags;
+	efi_status_t status;
+
+	spin_lock_irqsave(&rtc_lock, flags);
+	status = efi_call_virt(set_time, tm);
+	spin_unlock_irqrestore(&rtc_lock, flags);
+	return status;
+}
+
+static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,
+					     efi_bool_t *pending,
+					     efi_time_t *tm)
+{
+	unsigned long flags;
+	efi_status_t status;
+
+	spin_lock_irqsave(&rtc_lock, flags);
+	status = efi_call_virt(get_wakeup_time, enabled, pending, tm);
+	spin_unlock_irqrestore(&rtc_lock, flags);
+	return status;
+}
+
+static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
+{
+	unsigned long flags;
+	efi_status_t status;
+
+	spin_lock_irqsave(&rtc_lock, flags);
+	status = efi_call_virt(set_wakeup_time, enabled, tm);
+	spin_unlock_irqrestore(&rtc_lock, flags);
+	return status;
+}
+
+static efi_status_t virt_efi_get_variable(efi_char16_t *name,
+					  efi_guid_t *vendor,
+					  u32 *attr,
+					  unsigned long *data_size,
+					  void *data)
+{
+	return efi_call_virt(get_variable, name, vendor, attr, data_size, data);
+}
+
+static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
+					       efi_char16_t *name,
+					       efi_guid_t *vendor)
+{
+	return efi_call_virt(get_next_variable, name_size, name, vendor);
+}
+
+static efi_status_t virt_efi_set_variable(efi_char16_t *name,
+					  efi_guid_t *vendor,
+					  u32 attr,
+					  unsigned long data_size,
+					  void *data)
+{
+	return efi_call_virt(set_variable, name, vendor, attr, data_size, data);
+}
+
+static efi_status_t virt_efi_query_variable_info(u32 attr,
+						 u64 *storage_space,
+						 u64 *remaining_space,
+						 u64 *max_variable_size)
+{
+	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
+		return EFI_UNSUPPORTED;
+
+	return efi_call_virt(query_variable_info, attr, storage_space,
+			     remaining_space, max_variable_size);
+}
+
+static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)
+{
+	return efi_call_virt(get_next_high_mono_count, count);
+}
+
+static void virt_efi_reset_system(int reset_type,
+				  efi_status_t status,
+				  unsigned long data_size,
+				  efi_char16_t *data)
+{
+	__efi_call_virt(reset_system, reset_type, status, data_size, data);
+}
+
+static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,
+					    unsigned long count,
+					    unsigned long sg_list)
+{
+	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
+		return EFI_UNSUPPORTED;
+
+	return efi_call_virt(update_capsule, capsules, count, sg_list);
+}
+
+static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,
+						unsigned long count,
+						u64 *max_size,
+						int *reset_type)
+{
+	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
+		return EFI_UNSUPPORTED;
+
+	return efi_call_virt(query_capsule_caps, capsules, count, max_size,
+			     reset_type);
+}
+
+void efi_native_runtime_setup(void)
+{
+	efi.get_time = virt_efi_get_time;
+	efi.set_time = virt_efi_set_time;
+	efi.get_wakeup_time = virt_efi_get_wakeup_time;
+	efi.set_wakeup_time = virt_efi_set_wakeup_time;
+	efi.get_variable = virt_efi_get_variable;
+	efi.get_next_variable = virt_efi_get_next_variable;
+	efi.set_variable = virt_efi_set_variable;
+	efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
+	efi.reset_system = virt_efi_reset_system;
+	efi.query_variable_info = virt_efi_query_variable_info;
+	efi.update_capsule = virt_efi_update_capsule;
+	efi.query_capsule_caps = virt_efi_query_capsule_caps;
+}
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 41bbf8ba4ba8..0ceb816bdfc2 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -521,6 +521,8 @@ typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules,
 					      int *reset_type);
 typedef efi_status_t efi_query_variable_store_t(u32 attributes, unsigned long size);
 
+void efi_native_runtime_setup(void);
+
 /*
  *  EFI Configuration Table and GUID definitions
  */
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 2/2] efi/arm64: preserve FP/SIMD registers on UEFI runtime services calls
  2014-06-26 10:09 [PATCH v2 0/2] efi: preserve NEON registers on UEFI services calls Ard Biesheuvel
  2014-06-26 10:09 ` [PATCH v2 1/2] efi/x86: move UEFI Runtime Services wrappers to generic code Ard Biesheuvel
@ 2014-06-26 10:09 ` Ard Biesheuvel
  2014-07-04 15:45   ` Catalin Marinas
  2014-06-26 13:58 ` [PATCH v2 0/2] efi: preserve NEON registers on UEFI " Mark Salter
  2014-07-01 13:26 ` Matt Fleming
  3 siblings, 1 reply; 15+ messages in thread
From: Ard Biesheuvel @ 2014-06-26 10:09 UTC (permalink / raw)
  To: linux-arm-kernel

According to the UEFI spec section 2.3.6.4, the use of FP/SIMD instructions is
allowed, and should adhere to the AAPCS64 calling convention, which states that
'only the bottom 64 bits of each value stored in registers v8-v15 need to be
preserved' (section 5.1.2).

This applies equally to UEFI Runtime Services called by the kernel, so make sure
the FP/SIMD register file is preserved in this case.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/Kconfig           |  1 +
 arch/arm64/include/asm/efi.h | 21 +++++++++++++++++++++
 arch/arm64/kernel/efi.c      | 14 +-------------
 3 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index a474de346be6..93e11f4d9513 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -299,6 +299,7 @@ config EFI
 	select LIBFDT
 	select UCS2_STRING
 	select EFI_PARAMS_FROM_FDT
+	select EFI_RUNTIME_WRAPPERS
 	default y
 	help
 	  This option provides support for runtime services provided
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index 5a46c4e7f539..375ba342dca6 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -2,6 +2,7 @@
 #define _ASM_EFI_H
 
 #include <asm/io.h>
+#include <asm/neon.h>
 
 #ifdef CONFIG_EFI
 extern void efi_init(void);
@@ -11,4 +12,24 @@ extern void efi_idmap_init(void);
 #define efi_idmap_init()
 #endif
 
+#define efi_call_virt(f, ...)						\
+({									\
+	efi_##f##_t *__f = efi.systab->runtime->f;			\
+	efi_status_t __s;						\
+									\
+	kernel_neon_begin();						\
+	__s = __f(__VA_ARGS__);						\
+	kernel_neon_end();						\
+	__s;								\
+})
+
+#define __efi_call_virt(f, ...)						\
+({									\
+	efi_##f##_t *__f = efi.systab->runtime->f;			\
+									\
+	kernel_neon_begin();						\
+	__f(__VA_ARGS__);						\
+	kernel_neon_end();						\
+})
+
 #endif /* _ASM_EFI_H */
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 14db1f6e8d7f..56c3327bbf79 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -449,19 +449,7 @@ static int __init arm64_enter_virtual_mode(void)
 
 	/* Set up runtime services function pointers */
 	runtime = efi.systab->runtime;
-	efi.get_time = runtime->get_time;
-	efi.set_time = runtime->set_time;
-	efi.get_wakeup_time = runtime->get_wakeup_time;
-	efi.set_wakeup_time = runtime->set_wakeup_time;
-	efi.get_variable = runtime->get_variable;
-	efi.get_next_variable = runtime->get_next_variable;
-	efi.set_variable = runtime->set_variable;
-	efi.query_variable_info = runtime->query_variable_info;
-	efi.update_capsule = runtime->update_capsule;
-	efi.query_capsule_caps = runtime->query_capsule_caps;
-	efi.get_next_high_mono_count = runtime->get_next_high_mono_count;
-	efi.reset_system = runtime->reset_system;
-
+	efi_native_runtime_setup();
 	set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
 
 	return 0;
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 0/2] efi: preserve NEON registers on UEFI services calls
  2014-06-26 10:09 [PATCH v2 0/2] efi: preserve NEON registers on UEFI services calls Ard Biesheuvel
  2014-06-26 10:09 ` [PATCH v2 1/2] efi/x86: move UEFI Runtime Services wrappers to generic code Ard Biesheuvel
  2014-06-26 10:09 ` [PATCH v2 2/2] efi/arm64: preserve FP/SIMD registers on UEFI runtime services calls Ard Biesheuvel
@ 2014-06-26 13:58 ` Mark Salter
  2014-06-26 14:22   ` Ard Biesheuvel
  2014-07-01 13:26 ` Matt Fleming
  3 siblings, 1 reply; 15+ messages in thread
From: Mark Salter @ 2014-06-26 13:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 2014-06-26 at 12:09 +0200, Ard Biesheuvel wrote:
> The current UEFI implementation for arm64 fails to preserve/restore the contents
> of the NEON register file,

Does the current implementation actually use NEON registers?
I know there are some at least, which build with -mgeneral-regs-only
to keep gcc from using NEON registers.

Not that that means we don't need this. Just curious.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 0/2] efi: preserve NEON registers on UEFI services calls
  2014-06-26 13:58 ` [PATCH v2 0/2] efi: preserve NEON registers on UEFI " Mark Salter
@ 2014-06-26 14:22   ` Ard Biesheuvel
  0 siblings, 0 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2014-06-26 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

On 26 June 2014 15:58, Mark Salter <msalter@redhat.com> wrote:
> On Thu, 2014-06-26 at 12:09 +0200, Ard Biesheuvel wrote:
>> The current UEFI implementation for arm64 fails to preserve/restore the contents
>> of the NEON register file,
>
> Does the current implementation actually use NEON registers?
> I know there are some at least, which build with -mgeneral-regs-only
> to keep gcc from using NEON registers.
>

Tianocore/EDK2 does not use -mgeneral-regs-only when building for
AArch64, and my current build shows that, for instance, GCC starts
spilling to FP registers when compiling the LZMA decoder, and it is
likely to do the same for the crypto bits once I start enabling them
(although, interestingly enough, the OpenSSL SHA-1 C implementation
runs 60% faster with -mgeneral-regs-only set)

> Not that that means we don't need this. Just curious.
>

The spec does not forbid it, so we will need it anyhow ...

-- 
Ard.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 0/2] efi: preserve NEON registers on UEFI services calls
  2014-06-26 10:09 [PATCH v2 0/2] efi: preserve NEON registers on UEFI services calls Ard Biesheuvel
                   ` (2 preceding siblings ...)
  2014-06-26 13:58 ` [PATCH v2 0/2] efi: preserve NEON registers on UEFI " Mark Salter
@ 2014-07-01 13:26 ` Matt Fleming
  2014-07-01 13:46   ` Ard Biesheuvel
  3 siblings, 1 reply; 15+ messages in thread
From: Matt Fleming @ 2014-07-01 13:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 26 Jun, at 12:09:04PM, Ard Biesheuvel wrote:
> The current UEFI implementation for arm64 fails to preserve/restore the contents
> of the NEON register file, which may result in data corruption, especially now
> that those contents are lazily restored for user processes.
> 
> This series proposes to fix this by wrapping all runtime services calls, and
> adding kernel_neon_begin()/kernel_neon_end() pairs to the wrappers.
> 
> The first patch moves the existing x86 versions of those wrappers to generic
> code, so that the second patch can easily enable them by supplying a definition
> for efi_call_virt and adding a call to efi_native_runtime_setup().
> 
> Changes since v1:
> - rename runtime.c -> runtime-wrappers.c
> - make build depend on new Kconfig symbol EFI_RUNTIME_WRAPPERS to fix ia64
>   breakage
> - remove default #defines for efi_call_virt()/__efi_call_virt(), they are not
>   needed anymore now that it is built conditionally
> - add references to applicable UEFI/AAPCS spec sections
> 
> Ard Biesheuvel (2):
>   efi/x86: move UEFI Runtime Services wrappers to generic code
>   efi/arm64: preserve FP/SIMD registers on UEFI runtime services calls

Thanks Ard. These patches look OK to me, and I've now pulled them into
my 'next' branch.

It'd be nice if we could get some ACKs from other people since this is
an ABI issue.

-- 
Matt Fleming, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 1/2] efi/x86: move UEFI Runtime Services wrappers to generic code
  2014-06-26 10:09 ` [PATCH v2 1/2] efi/x86: move UEFI Runtime Services wrappers to generic code Ard Biesheuvel
@ 2014-07-01 13:30   ` Matt Fleming
  2014-07-01 13:35     ` Ard Biesheuvel
  0 siblings, 1 reply; 15+ messages in thread
From: Matt Fleming @ 2014-07-01 13:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 26 Jun, at 12:09:05PM, Ard Biesheuvel wrote:
> In order for other archs (such as arm64) to be able to reuse the virtual mode
> function call wrappers, move them to drivers/firmware/efi/runtime-wrappers.c.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

[...]

> @@ -54,6 +54,13 @@ config EFI_PARAMS_FROM_FDT
>  	  the EFI runtime support gets system table address, memory
>            map address, and other parameters from the device tree.
>  
> +config EFI_RUNTIME_WRAPPERS
> +	bool
> +	help
> +	  Selected by the arch if it needs to wrap UEFI Runtime Services calls,
> +	  in which case it needs to provide #definitions of efi_call_virt and
> +	  __efi_call_virt in <asm/efi.h>
> +
>  endmenu

Actually, could we drop this help text?

That may seem like a backwards step, but I have concerns that we'll fail
to keep this help text in sync with the code. Furthermore, by providing
help text that kinda says, "casual users need the help text to
understand when to enable this feature". Clearly that's not what this
Kconfig symbol is for.

Most of the other guard Kconfig symbols don't provide this kind of text,
and I think there's good reason to follow suit.

What do you think?

-- 
Matt Fleming, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 1/2] efi/x86: move UEFI Runtime Services wrappers to generic code
  2014-07-01 13:30   ` Matt Fleming
@ 2014-07-01 13:35     ` Ard Biesheuvel
  2014-07-01 13:48       ` Matt Fleming
  0 siblings, 1 reply; 15+ messages in thread
From: Ard Biesheuvel @ 2014-07-01 13:35 UTC (permalink / raw)
  To: linux-arm-kernel

On 1 July 2014 15:30, Matt Fleming <matt@console-pimps.org> wrote:
> On Thu, 26 Jun, at 12:09:05PM, Ard Biesheuvel wrote:
>> In order for other archs (such as arm64) to be able to reuse the virtual mode
>> function call wrappers, move them to drivers/firmware/efi/runtime-wrappers.c.
>>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>
> [...]
>
>> @@ -54,6 +54,13 @@ config EFI_PARAMS_FROM_FDT
>>         the EFI runtime support gets system table address, memory
>>            map address, and other parameters from the device tree.
>>
>> +config EFI_RUNTIME_WRAPPERS
>> +     bool
>> +     help
>> +       Selected by the arch if it needs to wrap UEFI Runtime Services calls,
>> +       in which case it needs to provide #definitions of efi_call_virt and
>> +       __efi_call_virt in <asm/efi.h>
>> +
>>  endmenu
>
> Actually, could we drop this help text?
>
> That may seem like a backwards step, but I have concerns that we'll fail
> to keep this help text in sync with the code. Furthermore, by providing
> help text that kinda says, "casual users need the help text to
> understand when to enable this feature". Clearly that's not what this
> Kconfig symbol is for.
>
> Most of the other guard Kconfig symbols don't provide this kind of text,
> and I think there's good reason to follow suit.
>
> What do you think?
>

I agree, but I kind of followed the example of the Kconfig symbols in
the vicinity.
So sure, rip it out. Or would you like me to do a v(n+1)?

-- 
Ard.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 0/2] efi: preserve NEON registers on UEFI services calls
  2014-07-01 13:26 ` Matt Fleming
@ 2014-07-01 13:46   ` Ard Biesheuvel
  2014-07-08 15:33     ` Olivier Martin
  0 siblings, 1 reply; 15+ messages in thread
From: Ard Biesheuvel @ 2014-07-01 13:46 UTC (permalink / raw)
  To: linux-arm-kernel

On 1 July 2014 15:26, Matt Fleming <matt@console-pimps.org> wrote:
> On Thu, 26 Jun, at 12:09:04PM, Ard Biesheuvel wrote:
>> The current UEFI implementation for arm64 fails to preserve/restore the contents
>> of the NEON register file, which may result in data corruption, especially now
>> that those contents are lazily restored for user processes.
>>
>> This series proposes to fix this by wrapping all runtime services calls, and
>> adding kernel_neon_begin()/kernel_neon_end() pairs to the wrappers.
>>
>> The first patch moves the existing x86 versions of those wrappers to generic
>> code, so that the second patch can easily enable them by supplying a definition
>> for efi_call_virt and adding a call to efi_native_runtime_setup().
>>
>> Changes since v1:
>> - rename runtime.c -> runtime-wrappers.c
>> - make build depend on new Kconfig symbol EFI_RUNTIME_WRAPPERS to fix ia64
>>   breakage
>> - remove default #defines for efi_call_virt()/__efi_call_virt(), they are not
>>   needed anymore now that it is built conditionally
>> - add references to applicable UEFI/AAPCS spec sections
>>
>> Ard Biesheuvel (2):
>>   efi/x86: move UEFI Runtime Services wrappers to generic code
>>   efi/arm64: preserve FP/SIMD registers on UEFI runtime services calls
>
> Thanks Ard. These patches look OK to me, and I've now pulled them into
> my 'next' branch.
>
> It'd be nice if we could get some ACKs from other people since this is
> an ABI issue.

Yes, they have been awfully quiet, haven't they?

At least Roy has volunteered to get involved in the USWG to get the
spec clarified.

@Leif, Catalin, Olivier: care to chime in?

-- 
Ard.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 1/2] efi/x86: move UEFI Runtime Services wrappers to generic code
  2014-07-01 13:35     ` Ard Biesheuvel
@ 2014-07-01 13:48       ` Matt Fleming
  0 siblings, 0 replies; 15+ messages in thread
From: Matt Fleming @ 2014-07-01 13:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 01 Jul, at 03:35:09PM, Ard Biesheuvel wrote:
> 
> I agree, but I kind of followed the example of the Kconfig symbols in
> the vicinity.
> So sure, rip it out. Or would you like me to do a v(n+1)?

Thanks. Nah, no need for another version, I'ved fixed this up in 'next',
but please do check the commits to make sure nothing untoward has
occurred.

-- 
Matt Fleming, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 2/2] efi/arm64: preserve FP/SIMD registers on UEFI runtime services calls
  2014-06-26 10:09 ` [PATCH v2 2/2] efi/arm64: preserve FP/SIMD registers on UEFI runtime services calls Ard Biesheuvel
@ 2014-07-04 15:45   ` Catalin Marinas
  2014-07-04 15:51     ` Ard Biesheuvel
  0 siblings, 1 reply; 15+ messages in thread
From: Catalin Marinas @ 2014-07-04 15:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 26, 2014 at 11:09:06AM +0100, Ard Biesheuvel wrote:
> According to the UEFI spec section 2.3.6.4, the use of FP/SIMD instructions is
> allowed, and should adhere to the AAPCS64 calling convention, which states that
> 'only the bottom 64 bits of each value stored in registers v8-v15 need to be
> preserved' (section 5.1.2).
> 
> This applies equally to UEFI Runtime Services called by the kernel, so make sure
> the FP/SIMD register file is preserved in this case.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

While the code looks fine, I think there is a mismatch between what the
subject says and what the patch does (enabling EFI_RUNTIME_WRAPPERS).

-- 
Catalin

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 2/2] efi/arm64: preserve FP/SIMD registers on UEFI runtime services calls
  2014-07-04 15:45   ` Catalin Marinas
@ 2014-07-04 15:51     ` Ard Biesheuvel
  2014-07-04 16:59       ` Catalin Marinas
  0 siblings, 1 reply; 15+ messages in thread
From: Ard Biesheuvel @ 2014-07-04 15:51 UTC (permalink / raw)
  To: linux-arm-kernel

On 4 July 2014 17:45, Catalin Marinas <catalin.marinas@arm.com> wrote:
> On Thu, Jun 26, 2014 at 11:09:06AM +0100, Ard Biesheuvel wrote:
>> According to the UEFI spec section 2.3.6.4, the use of FP/SIMD instructions is
>> allowed, and should adhere to the AAPCS64 calling convention, which states that
>> 'only the bottom 64 bits of each value stored in registers v8-v15 need to be
>> preserved' (section 5.1.2).
>>
>> This applies equally to UEFI Runtime Services called by the kernel, so make sure
>> the FP/SIMD register file is preserved in this case.
>>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>
> While the code looks fine, I think there is a mismatch between what the
> subject says and what the patch does (enabling EFI_RUNTIME_WRAPPERS).
>

Not entirely. In order to be able to insert calls to
kernel_neon_begin()/end() into the runtime services calls, we need
a) to supply definitions for efi_call_virt() and __efi_call_virt()
that contain those calls to kernel_neon_begin()/end()
b) to enable runtime wrappers (which is what uses those definitions)

Would you prefer those to be split in 2 patches?

--
Ard.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 2/2] efi/arm64: preserve FP/SIMD registers on UEFI runtime services calls
  2014-07-04 15:51     ` Ard Biesheuvel
@ 2014-07-04 16:59       ` Catalin Marinas
  2014-07-04 17:15         ` Ard Biesheuvel
  0 siblings, 1 reply; 15+ messages in thread
From: Catalin Marinas @ 2014-07-04 16:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jul 04, 2014 at 04:51:31PM +0100, Ard Biesheuvel wrote:
> On 4 July 2014 17:45, Catalin Marinas <catalin.marinas@arm.com> wrote:
> > On Thu, Jun 26, 2014 at 11:09:06AM +0100, Ard Biesheuvel wrote:
> >> According to the UEFI spec section 2.3.6.4, the use of FP/SIMD instructions is
> >> allowed, and should adhere to the AAPCS64 calling convention, which states that
> >> 'only the bottom 64 bits of each value stored in registers v8-v15 need to be
> >> preserved' (section 5.1.2).
> >>
> >> This applies equally to UEFI Runtime Services called by the kernel, so make sure
> >> the FP/SIMD register file is preserved in this case.
> >>
> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> >
> > While the code looks fine, I think there is a mismatch between what the
> > subject says and what the patch does (enabling EFI_RUNTIME_WRAPPERS).
> >
> 
> Not entirely. In order to be able to insert calls to
> kernel_neon_begin()/end() into the runtime services calls, we need
> a) to supply definitions for efi_call_virt() and __efi_call_virt()
> that contain those calls to kernel_neon_begin()/end()
> b) to enable runtime wrappers (which is what uses those definitions)
> 
> Would you prefer those to be split in 2 patches?

No, that's fine. You could just add the above explanation to the commit
log. Otherwise:

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 2/2] efi/arm64: preserve FP/SIMD registers on UEFI runtime services calls
  2014-07-04 16:59       ` Catalin Marinas
@ 2014-07-04 17:15         ` Ard Biesheuvel
  0 siblings, 0 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2014-07-04 17:15 UTC (permalink / raw)
  To: linux-arm-kernel

On 4 July 2014 18:59, Catalin Marinas <catalin.marinas@arm.com> wrote:
> On Fri, Jul 04, 2014 at 04:51:31PM +0100, Ard Biesheuvel wrote:
>> On 4 July 2014 17:45, Catalin Marinas <catalin.marinas@arm.com> wrote:
>> > On Thu, Jun 26, 2014 at 11:09:06AM +0100, Ard Biesheuvel wrote:
>> >> According to the UEFI spec section 2.3.6.4, the use of FP/SIMD instructions is
>> >> allowed, and should adhere to the AAPCS64 calling convention, which states that
>> >> 'only the bottom 64 bits of each value stored in registers v8-v15 need to be
>> >> preserved' (section 5.1.2).
>> >>
>> >> This applies equally to UEFI Runtime Services called by the kernel, so make sure
>> >> the FP/SIMD register file is preserved in this case.
>> >>
>> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> >
>> > While the code looks fine, I think there is a mismatch between what the
>> > subject says and what the patch does (enabling EFI_RUNTIME_WRAPPERS).
>> >
>>
>> Not entirely. In order to be able to insert calls to
>> kernel_neon_begin()/end() into the runtime services calls, we need
>> a) to supply definitions for efi_call_virt() and __efi_call_virt()
>> that contain those calls to kernel_neon_begin()/end()
>> b) to enable runtime wrappers (which is what uses those definitions)
>>
>> Would you prefer those to be split in 2 patches?
>
> No, that's fine. You could just add the above explanation to the commit
> log. Otherwise:
>
> Acked-by: Catalin Marinas <catalin.marinas@arm.com>

OK, thanks. I will add your ack and ask Matt to take it.

-- 
Ard.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 0/2] efi: preserve NEON registers on UEFI services calls
  2014-07-01 13:46   ` Ard Biesheuvel
@ 2014-07-08 15:33     ` Olivier Martin
  0 siblings, 0 replies; 15+ messages in thread
From: Olivier Martin @ 2014-07-08 15:33 UTC (permalink / raw)
  To: linux-arm-kernel

It is correct the UEFI 2.4 spec says 'Floating point and SIMD instructions may be used'. And it is also correct these registers are not preserved in the current UEFI EDK2 implementation.
I will keep track in ARM UEFI todo list.

Acked-by: Olivier Martin <olivier.martin@arm.com>

Thanks Ard for your patch,
Olivier

> -----Original Message-----
> From: Ard Biesheuvel [mailto:ard.biesheuvel at linaro.org]
> Sent: 01 July 2014 14:46
> To: Matt Fleming
> Cc: Matt Fleming; x86 at kernel.org; Catalin Marinas; linux-
> efi at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> hpa at zytor.com; Leif Lindholm; Roy Franz; msalter at redhat.com; Olivier
> Martin
> Subject: Re: [PATCH v2 0/2] efi: preserve NEON registers on UEFI
> services calls
> 
> On 1 July 2014 15:26, Matt Fleming <matt@console-pimps.org> wrote:
> > On Thu, 26 Jun, at 12:09:04PM, Ard Biesheuvel wrote:
> >> The current UEFI implementation for arm64 fails to preserve/restore
> the contents
> >> of the NEON register file, which may result in data corruption,
> especially now
> >> that those contents are lazily restored for user processes.
> >>
> >> This series proposes to fix this by wrapping all runtime services
> calls, and
> >> adding kernel_neon_begin()/kernel_neon_end() pairs to the wrappers.
> >>
> >> The first patch moves the existing x86 versions of those wrappers to
> generic
> >> code, so that the second patch can easily enable them by supplying a
> definition
> >> for efi_call_virt and adding a call to efi_native_runtime_setup().
> >>
> >> Changes since v1:
> >> - rename runtime.c -> runtime-wrappers.c
> >> - make build depend on new Kconfig symbol EFI_RUNTIME_WRAPPERS to
> fix ia64
> >>   breakage
> >> - remove default #defines for efi_call_virt()/__efi_call_virt(),
> they are not
> >>   needed anymore now that it is built conditionally
> >> - add references to applicable UEFI/AAPCS spec sections
> >>
> >> Ard Biesheuvel (2):
> >>   efi/x86: move UEFI Runtime Services wrappers to generic code
> >>   efi/arm64: preserve FP/SIMD registers on UEFI runtime services
> calls
> >
> > Thanks Ard. These patches look OK to me, and I've now pulled them
> into
> > my 'next' branch.
> >
> > It'd be nice if we could get some ACKs from other people since this
> is
> > an ABI issue.
> 
> Yes, they have been awfully quiet, haven't they?
> 
> At least Roy has volunteered to get involved in the USWG to get the
> spec clarified.
> 
> @Leif, Catalin, Olivier: care to chime in?
> 
> --
> Ard.

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2014-07-08 15:33 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-26 10:09 [PATCH v2 0/2] efi: preserve NEON registers on UEFI services calls Ard Biesheuvel
2014-06-26 10:09 ` [PATCH v2 1/2] efi/x86: move UEFI Runtime Services wrappers to generic code Ard Biesheuvel
2014-07-01 13:30   ` Matt Fleming
2014-07-01 13:35     ` Ard Biesheuvel
2014-07-01 13:48       ` Matt Fleming
2014-06-26 10:09 ` [PATCH v2 2/2] efi/arm64: preserve FP/SIMD registers on UEFI runtime services calls Ard Biesheuvel
2014-07-04 15:45   ` Catalin Marinas
2014-07-04 15:51     ` Ard Biesheuvel
2014-07-04 16:59       ` Catalin Marinas
2014-07-04 17:15         ` Ard Biesheuvel
2014-06-26 13:58 ` [PATCH v2 0/2] efi: preserve NEON registers on UEFI " Mark Salter
2014-06-26 14:22   ` Ard Biesheuvel
2014-07-01 13:26 ` Matt Fleming
2014-07-01 13:46   ` Ard Biesheuvel
2014-07-08 15:33     ` Olivier Martin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).