linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [GIT PULL 00/11] EFI updates for v4.20
@ 2018-09-27  8:50 Ard Biesheuvel
  2018-09-27  8:50 ` [PATCH 01/11] efi: honour memory reservations passed via a linux specific config table Ard Biesheuvel
                   ` (11 more replies)
  0 siblings, 12 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2018-09-27  8:50 UTC (permalink / raw)
  To: linux-kernel, Ingo Molnar, Thomas Gleixner
  Cc: Ard Biesheuvel, linux-efi, Aaron Ma, Alistair Strachan,
	Ben Hutchings, Bhupesh Sharma, Hans de Goede, Ivan Hu,
	Jeremy Linton, Marc Zyngier, Matt Fleming, Peter Robinson,
	Sai Praneeth Prakhya, Sebastian Andrzej Siewior, Stefan Agner

Thomas, Ingo,

Please pull/cherry-pick the below. Note that the first three patches will
be depended upon by an irqchip series that Marc Zyngier has sent out last
week, and that targets the next release as well. So please advise how to
proceed with that: we could simply apply those patches first and use the
resulting commit in tip.git as a stable branch, I suppose, but I'll let
Marc chime in in case he has any other ideas.

Thanks,
Ard. 

[0] https://lore.kernel.org/lkml/20180921195954.21574-1-marc.zyngier@arm.com/

The following changes since commit 11da3a7f84f19c26da6f86af878298694ede0804:

  Linux 4.19-rc3 (2018-09-09 17:26:43 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git tags/efi-next

for you to fetch changes up to 9c1442a9d039a1a3302fa93e9a11001c5f23b624:

  x86: boot: Fix EFI stub alignment (2018-09-26 12:15:01 +0200)

----------------------------------------------------------------
EFI updates for v4.20:
- Add support for enlisting the help of the EFI firmware to create memory
  reservations that persist across kexec.
- Add page fault handling to the runtime services support code on x86 so
  we can gracefully recover from buggy EFI firmware.
- Fix command line handling on x86 for the boot path that omits the stub's
  PE/COFF entry point.
- Other assorted fixes.

----------------------------------------------------------------
Aaron Ma (1):
      efi/x86: earlyprintk - Add 64bit efi fb address support

Alistair Strachan (1):
      efi/libstub: arm: support building with clang

Ard Biesheuvel (3):
      efi: honour memory reservations passed via a linux specific config table
      efi/arm: libstub: add a root memreserve config table
      efi: add API to reserve memory persistently across kexec reboot

Ben Hutchings (1):
      x86: boot: Fix EFI stub alignment

Hans de Goede (1):
      efi/x86: Call efi_parse_options() from efi_main()

Ivan Hu (1):
      efi/efi_test: add exporting ResetSystem runtime service

Sai Praneeth (2):
      efi: Make efi_rts_work accessible to efi page fault handler
      efi/x86: Handle page faults occurring while running EFI runtime services

Sebastian Andrzej Siewior (1):
      efi/x86: drop task_lock() from efi_switch_mm()

 arch/x86/boot/compressed/eboot.c        | 10 +++++
 arch/x86/boot/tools/build.c             |  7 +++
 arch/x86/include/asm/efi.h              |  1 +
 arch/x86/mm/fault.c                     |  9 ++++
 arch/x86/platform/efi/early_printk.c    |  8 +++-
 arch/x86/platform/efi/efi_64.c          | 10 ++---
 arch/x86/platform/efi/quirks.c          | 78 +++++++++++++++++++++++++++++++++
 drivers/firmware/efi/efi.c              | 59 ++++++++++++++++++++++++-
 drivers/firmware/efi/libstub/Makefile   |  3 +-
 drivers/firmware/efi/libstub/arm-stub.c | 27 ++++++++++++
 drivers/firmware/efi/runtime-wrappers.c | 61 +++++++-------------------
 drivers/firmware/efi/test/efi_test.c    | 27 ++++++++++++
 drivers/firmware/efi/test/efi_test.h    | 10 +++++
 include/linux/efi.h                     | 51 +++++++++++++++++++++
 14 files changed, 307 insertions(+), 54 deletions(-)

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

* [PATCH 01/11] efi: honour memory reservations passed via a linux specific config table
  2018-09-27  8:50 [GIT PULL 00/11] EFI updates for v4.20 Ard Biesheuvel
@ 2018-09-27  8:50 ` Ard Biesheuvel
  2018-09-27  8:50 ` [PATCH 02/11] efi/arm: libstub: add a root memreserve " Ard Biesheuvel
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2018-09-27  8:50 UTC (permalink / raw)
  To: linux-kernel, Ingo Molnar, Thomas Gleixner
  Cc: Ard Biesheuvel, linux-efi, Aaron Ma, Alistair Strachan,
	Ben Hutchings, Bhupesh Sharma, Hans de Goede, Ivan Hu,
	Jeremy Linton, Marc Zyngier, Matt Fleming, Peter Robinson,
	Sai Praneeth Prakhya, Sebastian Andrzej Siewior, Stefan Agner

In order to allow the OS to reserve memory persistently across a
kexec, introduce a Linux-specific UEFI configuration table that
points to the head of a linked list in memory, allowing each kernel
to add list items describing memory regions that the next kernel
should treat as reserved.

This is useful, e.g., for GICv3 based ARM systems that cannot disable
DMA access to the LPI tables, forcing them to reuse the same memory
region again after a kexec reboot.

Tested-by: Jeremy Linton <jeremy.linton@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 drivers/firmware/efi/efi.c | 27 ++++++++++++++++++++++++++-
 include/linux/efi.h        |  8 ++++++++
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 2a29dd9c986d..688132ac8a0a 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -52,7 +52,8 @@ struct efi __read_mostly efi = {
 	.properties_table	= EFI_INVALID_TABLE_ADDR,
 	.mem_attr_table		= EFI_INVALID_TABLE_ADDR,
 	.rng_seed		= EFI_INVALID_TABLE_ADDR,
-	.tpm_log		= EFI_INVALID_TABLE_ADDR
+	.tpm_log		= EFI_INVALID_TABLE_ADDR,
+	.mem_reserve		= EFI_INVALID_TABLE_ADDR,
 };
 EXPORT_SYMBOL(efi);
 
@@ -484,6 +485,7 @@ static __initdata efi_config_table_type_t common_tables[] = {
 	{EFI_MEMORY_ATTRIBUTES_TABLE_GUID, "MEMATTR", &efi.mem_attr_table},
 	{LINUX_EFI_RANDOM_SEED_TABLE_GUID, "RNG", &efi.rng_seed},
 	{LINUX_EFI_TPM_EVENT_LOG_GUID, "TPMEventLog", &efi.tpm_log},
+	{LINUX_EFI_MEMRESERVE_TABLE_GUID, "MEMRESERVE", &efi.mem_reserve},
 	{NULL_GUID, NULL, NULL},
 };
 
@@ -591,6 +593,29 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz,
 		early_memunmap(tbl, sizeof(*tbl));
 	}
 
+	if (efi.mem_reserve != EFI_INVALID_TABLE_ADDR) {
+		unsigned long prsv = efi.mem_reserve;
+
+		while (prsv) {
+			struct linux_efi_memreserve *rsv;
+
+			/* reserve the entry itself */
+			memblock_reserve(prsv, sizeof(*rsv));
+
+			rsv = early_memremap(prsv, sizeof(*rsv));
+			if (rsv == NULL) {
+				pr_err("Could not map UEFI memreserve entry!\n");
+				return -ENOMEM;
+			}
+
+			if (rsv->size)
+				memblock_reserve(rsv->base, rsv->size);
+
+			prsv = rsv->next;
+			early_memunmap(rsv, sizeof(*rsv));
+		}
+	}
+
 	return 0;
 }
 
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 401e4b254e30..a5cb580472c5 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -672,6 +672,7 @@ void efi_native_runtime_setup(void);
 #define LINUX_EFI_LOADER_ENTRY_GUID		EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf,  0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f)
 #define LINUX_EFI_RANDOM_SEED_TABLE_GUID	EFI_GUID(0x1ce1e5bc, 0x7ceb, 0x42f2,  0x81, 0xe5, 0x8a, 0xad, 0xf1, 0x80, 0xf5, 0x7b)
 #define LINUX_EFI_TPM_EVENT_LOG_GUID		EFI_GUID(0xb7799cb0, 0xeca2, 0x4943,  0x96, 0x67, 0x1f, 0xae, 0x07, 0xb7, 0x47, 0xfa)
+#define LINUX_EFI_MEMRESERVE_TABLE_GUID		EFI_GUID(0x888eb0c6, 0x8ede, 0x4ff5,  0xa8, 0xf0, 0x9a, 0xee, 0x5c, 0xb9, 0x77, 0xc2)
 
 typedef struct {
 	efi_guid_t guid;
@@ -957,6 +958,7 @@ extern struct efi {
 	unsigned long mem_attr_table;	/* memory attributes table */
 	unsigned long rng_seed;		/* UEFI firmware random seed */
 	unsigned long tpm_log;		/* TPM2 Event Log table */
+	unsigned long mem_reserve;	/* Linux EFI memreserve table */
 	efi_get_time_t *get_time;
 	efi_set_time_t *set_time;
 	efi_get_wakeup_time_t *get_wakeup_time;
@@ -1662,4 +1664,10 @@ extern int efi_tpm_eventlog_init(void);
 /* Workqueue to queue EFI Runtime Services */
 extern struct workqueue_struct *efi_rts_wq;
 
+struct linux_efi_memreserve {
+	phys_addr_t	next;
+	phys_addr_t	base;
+	phys_addr_t	size;
+};
+
 #endif /* _LINUX_EFI_H */
-- 
2.18.0


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

* [PATCH 02/11] efi/arm: libstub: add a root memreserve config table
  2018-09-27  8:50 [GIT PULL 00/11] EFI updates for v4.20 Ard Biesheuvel
  2018-09-27  8:50 ` [PATCH 01/11] efi: honour memory reservations passed via a linux specific config table Ard Biesheuvel
@ 2018-09-27  8:50 ` Ard Biesheuvel
  2018-09-27  8:50 ` [PATCH 03/11] efi: add API to reserve memory persistently across kexec reboot Ard Biesheuvel
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2018-09-27  8:50 UTC (permalink / raw)
  To: linux-kernel, Ingo Molnar, Thomas Gleixner
  Cc: Ard Biesheuvel, linux-efi, Aaron Ma, Alistair Strachan,
	Ben Hutchings, Bhupesh Sharma, Hans de Goede, Ivan Hu,
	Jeremy Linton, Marc Zyngier, Matt Fleming, Peter Robinson,
	Sai Praneeth Prakhya, Sebastian Andrzej Siewior, Stefan Agner

Installing UEFI configuration tables can only be done before calling
ExitBootServices(), so if we want to use the new MEMRESRVE config table
from the kernel proper, we need to install a dummy entry from the stub.

Tested-by: Jeremy Linton <jeremy.linton@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 drivers/firmware/efi/libstub/arm-stub.c | 27 +++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c
index 6920033de6d4..30ac0c975f8a 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -69,6 +69,31 @@ static struct screen_info *setup_graphics(efi_system_table_t *sys_table_arg)
 	return si;
 }
 
+void install_memreserve_table(efi_system_table_t *sys_table_arg)
+{
+	struct linux_efi_memreserve *rsv;
+	efi_guid_t memreserve_table_guid = LINUX_EFI_MEMRESERVE_TABLE_GUID;
+	efi_status_t status;
+
+	status = efi_call_early(allocate_pool, EFI_LOADER_DATA, sizeof(*rsv),
+				(void **)&rsv);
+	if (status != EFI_SUCCESS) {
+		pr_efi_err(sys_table_arg, "Failed to allocate memreserve entry!\n");
+		return;
+	}
+
+	rsv->next = 0;
+	rsv->base = 0;
+	rsv->size = 0;
+
+	status = efi_call_early(install_configuration_table,
+				&memreserve_table_guid,
+				rsv);
+	if (status != EFI_SUCCESS)
+		pr_efi_err(sys_table_arg, "Failed to install memreserve config table!\n");
+}
+
+
 /*
  * This function handles the architcture specific differences between arm and
  * arm64 regarding where the kernel image must be loaded and any memory that
@@ -235,6 +260,8 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
 		}
 	}
 
+	install_memreserve_table(sys_table);
+
 	new_fdt_addr = fdt_addr;
 	status = allocate_new_fdt_and_exit_boot(sys_table, handle,
 				&new_fdt_addr, efi_get_max_fdt_addr(dram_base),
-- 
2.18.0


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

* [PATCH 03/11] efi: add API to reserve memory persistently across kexec reboot
  2018-09-27  8:50 [GIT PULL 00/11] EFI updates for v4.20 Ard Biesheuvel
  2018-09-27  8:50 ` [PATCH 01/11] efi: honour memory reservations passed via a linux specific config table Ard Biesheuvel
  2018-09-27  8:50 ` [PATCH 02/11] efi/arm: libstub: add a root memreserve " Ard Biesheuvel
@ 2018-09-27  8:50 ` Ard Biesheuvel
  2018-09-27  8:50 ` [PATCH 04/11] efi/libstub: arm: support building with clang Ard Biesheuvel
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2018-09-27  8:50 UTC (permalink / raw)
  To: linux-kernel, Ingo Molnar, Thomas Gleixner
  Cc: Ard Biesheuvel, linux-efi, Aaron Ma, Alistair Strachan,
	Ben Hutchings, Bhupesh Sharma, Hans de Goede, Ivan Hu,
	Jeremy Linton, Marc Zyngier, Matt Fleming, Peter Robinson,
	Sai Praneeth Prakhya, Sebastian Andrzej Siewior, Stefan Agner

Add kernel plumbing to reserve memory regions persistently on a EFI
system by adding entries to the MEMRESERVE linked list.

Tested-by: Jeremy Linton <jeremy.linton@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 drivers/firmware/efi/efi.c | 32 ++++++++++++++++++++++++++++++++
 include/linux/efi.h        |  1 +
 2 files changed, 33 insertions(+)

diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 688132ac8a0a..249eb70691b0 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -962,6 +962,38 @@ bool efi_is_table_address(unsigned long phys_addr)
 	return false;
 }
 
+static DEFINE_SPINLOCK(efi_mem_reserve_persistent_lock);
+
+int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
+{
+	struct linux_efi_memreserve *rsv, *parent;
+
+	if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR)
+		return -ENODEV;
+
+	rsv = kmalloc(sizeof(*rsv), GFP_KERNEL);
+	if (!rsv)
+		return -ENOMEM;
+
+	parent = memremap(efi.mem_reserve, sizeof(*rsv), MEMREMAP_WB);
+	if (!parent) {
+		kfree(rsv);
+		return -ENOMEM;
+	}
+
+	rsv->base = addr;
+	rsv->size = size;
+
+	spin_lock(&efi_mem_reserve_persistent_lock);
+	rsv->next = parent->next;
+	parent->next = __pa(rsv);
+	spin_unlock(&efi_mem_reserve_persistent_lock);
+
+	memunmap(parent);
+
+	return 0;
+}
+
 #ifdef CONFIG_KEXEC
 static int update_efi_random_seed(struct notifier_block *nb,
 				  unsigned long code, void *unused)
diff --git a/include/linux/efi.h b/include/linux/efi.h
index a5cb580472c5..22e4de9d3700 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1043,6 +1043,7 @@ extern int __init efi_uart_console_only (void);
 extern u64 efi_mem_desc_end(efi_memory_desc_t *md);
 extern int efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md);
 extern void efi_mem_reserve(phys_addr_t addr, u64 size);
+extern int efi_mem_reserve_persistent(phys_addr_t addr, u64 size);
 extern void efi_initialize_iomem_resources(struct resource *code_resource,
 		struct resource *data_resource, struct resource *bss_resource);
 extern void efi_reserve_boot_services(void);
-- 
2.18.0


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

* [PATCH 04/11] efi/libstub: arm: support building with clang
  2018-09-27  8:50 [GIT PULL 00/11] EFI updates for v4.20 Ard Biesheuvel
                   ` (2 preceding siblings ...)
  2018-09-27  8:50 ` [PATCH 03/11] efi: add API to reserve memory persistently across kexec reboot Ard Biesheuvel
@ 2018-09-27  8:50 ` Ard Biesheuvel
  2018-09-27  8:50 ` [PATCH 05/11] efi/efi_test: add exporting ResetSystem runtime service Ard Biesheuvel
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2018-09-27  8:50 UTC (permalink / raw)
  To: linux-kernel, Ingo Molnar, Thomas Gleixner
  Cc: Ard Biesheuvel, linux-efi, Aaron Ma, Alistair Strachan,
	Ben Hutchings, Bhupesh Sharma, Hans de Goede, Ivan Hu,
	Jeremy Linton, Marc Zyngier, Matt Fleming, Peter Robinson,
	Sai Praneeth Prakhya, Sebastian Andrzej Siewior, Stefan Agner

From: Alistair Strachan <astrachan@google.com>

When building with CONFIG_EFI and CONFIG_EFI_STUB on ARM, the libstub
Makefile would use -mno-single-pic-base without checking it was
supported by the compiler. As the ARM (32-bit) clang backend does not
support this flag, the build would fail.

This changes the Makefile to check the compiler's support for
-mno-single-pic-base before using it, similar to c1c386681bd7 ("ARM:
8767/1: add support for building ARM kernel with clang").

Signed-off-by: Alistair Strachan <astrachan@google.com>
Reviewed-by: Stefan Agner <stefan@agner.ch>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 drivers/firmware/efi/libstub/Makefile | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index 14c40a7750d1..c51627660dbb 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -16,7 +16,8 @@ cflags-$(CONFIG_X86)		+= -m$(BITS) -D__KERNEL__ -O2 \
 cflags-$(CONFIG_ARM64)		:= $(subst -pg,,$(KBUILD_CFLAGS)) -fpie \
 				   $(DISABLE_STACKLEAK_PLUGIN)
 cflags-$(CONFIG_ARM)		:= $(subst -pg,,$(KBUILD_CFLAGS)) \
-				   -fno-builtin -fpic -mno-single-pic-base
+				   -fno-builtin -fpic \
+				   $(call cc-option,-mno-single-pic-base)
 
 cflags-$(CONFIG_EFI_ARMSTUB)	+= -I$(srctree)/scripts/dtc/libfdt
 
-- 
2.18.0


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

* [PATCH 05/11] efi/efi_test: add exporting ResetSystem runtime service
  2018-09-27  8:50 [GIT PULL 00/11] EFI updates for v4.20 Ard Biesheuvel
                   ` (3 preceding siblings ...)
  2018-09-27  8:50 ` [PATCH 04/11] efi/libstub: arm: support building with clang Ard Biesheuvel
@ 2018-09-27  8:50 ` Ard Biesheuvel
  2018-09-27  8:50 ` [PATCH 06/11] efi: Make efi_rts_work accessible to efi page fault handler Ard Biesheuvel
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2018-09-27  8:50 UTC (permalink / raw)
  To: linux-kernel, Ingo Molnar, Thomas Gleixner
  Cc: Ard Biesheuvel, linux-efi, Aaron Ma, Alistair Strachan,
	Ben Hutchings, Bhupesh Sharma, Hans de Goede, Ivan Hu,
	Jeremy Linton, Marc Zyngier, Matt Fleming, Peter Robinson,
	Sai Praneeth Prakhya, Sebastian Andrzej Siewior, Stefan Agner

From: Ivan Hu <ivan.hu@canonical.com>

Add exporting the UEFI runtime service ResetSystem for upper application or test
tools to use.

Signed-off-by: Ivan Hu <ivan.hu@canonical.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 drivers/firmware/efi/test/efi_test.c | 27 +++++++++++++++++++++++++++
 drivers/firmware/efi/test/efi_test.h | 10 ++++++++++
 2 files changed, 37 insertions(+)

diff --git a/drivers/firmware/efi/test/efi_test.c b/drivers/firmware/efi/test/efi_test.c
index 41c48a1e8baa..769640940c9f 100644
--- a/drivers/firmware/efi/test/efi_test.c
+++ b/drivers/firmware/efi/test/efi_test.c
@@ -542,6 +542,30 @@ static long efi_runtime_get_nexthighmonocount(unsigned long arg)
 	return 0;
 }
 
+static long efi_runtime_reset_system(unsigned long arg)
+{
+	struct efi_resetsystem __user *resetsystem_user;
+	struct efi_resetsystem resetsystem;
+	void *data = NULL;
+
+	resetsystem_user = (struct efi_resetsystem __user *)arg;
+	if (copy_from_user(&resetsystem, resetsystem_user,
+						sizeof(resetsystem)))
+		return -EFAULT;
+	if (resetsystem.data_size != 0) {
+		data = memdup_user((void *)resetsystem.data,
+						resetsystem.data_size);
+		if (IS_ERR(data))
+			return PTR_ERR(data);
+	}
+
+	efi.reset_system(resetsystem.reset_type, resetsystem.status,
+				resetsystem.data_size, (efi_char16_t *)data);
+
+	kfree(data);
+	return 0;
+}
+
 static long efi_runtime_query_variableinfo(unsigned long arg)
 {
 	struct efi_queryvariableinfo __user *queryvariableinfo_user;
@@ -682,6 +706,9 @@ static long efi_test_ioctl(struct file *file, unsigned int cmd,
 
 	case EFI_RUNTIME_QUERY_CAPSULECAPABILITIES:
 		return efi_runtime_query_capsulecaps(arg);
+
+	case EFI_RUNTIME_RESET_SYSTEM:
+		return efi_runtime_reset_system(arg);
 	}
 
 	return -ENOTTY;
diff --git a/drivers/firmware/efi/test/efi_test.h b/drivers/firmware/efi/test/efi_test.h
index 9812c6a02b40..5f4818bf112f 100644
--- a/drivers/firmware/efi/test/efi_test.h
+++ b/drivers/firmware/efi/test/efi_test.h
@@ -81,6 +81,13 @@ struct efi_querycapsulecapabilities {
 	efi_status_t		*status;
 } __packed;
 
+struct efi_resetsystem {
+	int			reset_type;
+	efi_status_t		status;
+	unsigned long		data_size;
+	efi_char16_t		*data;
+} __packed;
+
 #define EFI_RUNTIME_GET_VARIABLE \
 	_IOWR('p', 0x01, struct efi_getvariable)
 #define EFI_RUNTIME_SET_VARIABLE \
@@ -108,4 +115,7 @@ struct efi_querycapsulecapabilities {
 #define EFI_RUNTIME_QUERY_CAPSULECAPABILITIES \
 	_IOR('p', 0x0A, struct efi_querycapsulecapabilities)
 
+#define EFI_RUNTIME_RESET_SYSTEM \
+	_IOW('p', 0x0B, struct efi_resetsystem)
+
 #endif /* _DRIVERS_FIRMWARE_EFI_TEST_H_ */
-- 
2.18.0


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

* [PATCH 06/11] efi: Make efi_rts_work accessible to efi page fault handler
  2018-09-27  8:50 [GIT PULL 00/11] EFI updates for v4.20 Ard Biesheuvel
                   ` (4 preceding siblings ...)
  2018-09-27  8:50 ` [PATCH 05/11] efi/efi_test: add exporting ResetSystem runtime service Ard Biesheuvel
@ 2018-09-27  8:50 ` Ard Biesheuvel
  2018-09-27  8:50 ` [PATCH 07/11] efi/x86: Handle page faults occurring while running EFI runtime services Ard Biesheuvel
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2018-09-27  8:50 UTC (permalink / raw)
  To: linux-kernel, Ingo Molnar, Thomas Gleixner
  Cc: Ard Biesheuvel, linux-efi, Aaron Ma, Alistair Strachan,
	Ben Hutchings, Bhupesh Sharma, Hans de Goede, Ivan Hu,
	Jeremy Linton, Marc Zyngier, Matt Fleming, Peter Robinson,
	Sai Praneeth Prakhya, Sebastian Andrzej Siewior, Stefan Agner

From: Sai Praneeth <sai.praneeth.prakhya@intel.com>

After the kernel has booted, if any accesses by firmware causes a page
fault, the efi page fault handler would freeze efi_rts_wq and schedules
a new process. To do this, the efi page fault handler needs
efi_rts_work. Hence, make it accessible.

There will be no race conditions in accessing this structure, because
all the calls to efi runtime services are already serialized.

Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
Suggested-by: Matt Fleming <matt@codeblueprint.co.uk>
Based-on-code-from: Ricardo Neri <ricardo.neri@intel.com>
Signed-off-by: Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 drivers/firmware/efi/runtime-wrappers.c | 53 +++++--------------------
 include/linux/efi.h                     | 36 +++++++++++++++++
 2 files changed, 45 insertions(+), 44 deletions(-)

diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c
index aa66cbf23512..b18b2d864c2c 100644
--- a/drivers/firmware/efi/runtime-wrappers.c
+++ b/drivers/firmware/efi/runtime-wrappers.c
@@ -45,39 +45,7 @@
 #define __efi_call_virt(f, args...) \
 	__efi_call_virt_pointer(efi.systab->runtime, f, args)
 
-/* efi_runtime_service() function identifiers */
-enum efi_rts_ids {
-	GET_TIME,
-	SET_TIME,
-	GET_WAKEUP_TIME,
-	SET_WAKEUP_TIME,
-	GET_VARIABLE,
-	GET_NEXT_VARIABLE,
-	SET_VARIABLE,
-	QUERY_VARIABLE_INFO,
-	GET_NEXT_HIGH_MONO_COUNT,
-	UPDATE_CAPSULE,
-	QUERY_CAPSULE_CAPS,
-};
-
-/*
- * efi_runtime_work:	Details of EFI Runtime Service work
- * @arg<1-5>:		EFI Runtime Service function arguments
- * @status:		Status of executing EFI Runtime Service
- * @efi_rts_id:		EFI Runtime Service function identifier
- * @efi_rts_comp:	Struct used for handling completions
- */
-struct efi_runtime_work {
-	void *arg1;
-	void *arg2;
-	void *arg3;
-	void *arg4;
-	void *arg5;
-	efi_status_t status;
-	struct work_struct work;
-	enum efi_rts_ids efi_rts_id;
-	struct completion efi_rts_comp;
-};
+struct efi_runtime_work efi_rts_work;
 
 /*
  * efi_queue_work:	Queue efi_runtime_service() and wait until it's done
@@ -91,7 +59,6 @@ struct efi_runtime_work {
  */
 #define efi_queue_work(_rts, _arg1, _arg2, _arg3, _arg4, _arg5)		\
 ({									\
-	struct efi_runtime_work efi_rts_work;				\
 	efi_rts_work.status = EFI_ABORTED;				\
 									\
 	init_completion(&efi_rts_work.efi_rts_comp);			\
@@ -184,18 +151,16 @@ static DEFINE_SEMAPHORE(efi_runtime_lock);
  */
 static void efi_call_rts(struct work_struct *work)
 {
-	struct efi_runtime_work *efi_rts_work;
 	void *arg1, *arg2, *arg3, *arg4, *arg5;
 	efi_status_t status = EFI_NOT_FOUND;
 
-	efi_rts_work = container_of(work, struct efi_runtime_work, work);
-	arg1 = efi_rts_work->arg1;
-	arg2 = efi_rts_work->arg2;
-	arg3 = efi_rts_work->arg3;
-	arg4 = efi_rts_work->arg4;
-	arg5 = efi_rts_work->arg5;
+	arg1 = efi_rts_work.arg1;
+	arg2 = efi_rts_work.arg2;
+	arg3 = efi_rts_work.arg3;
+	arg4 = efi_rts_work.arg4;
+	arg5 = efi_rts_work.arg5;
 
-	switch (efi_rts_work->efi_rts_id) {
+	switch (efi_rts_work.efi_rts_id) {
 	case GET_TIME:
 		status = efi_call_virt(get_time, (efi_time_t *)arg1,
 				       (efi_time_cap_t *)arg2);
@@ -253,8 +218,8 @@ static void efi_call_rts(struct work_struct *work)
 		 */
 		pr_err("Requested executing invalid EFI Runtime Service.\n");
 	}
-	efi_rts_work->status = status;
-	complete(&efi_rts_work->efi_rts_comp);
+	efi_rts_work.status = status;
+	complete(&efi_rts_work.efi_rts_comp);
 }
 
 static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 22e4de9d3700..a929d2bf41fa 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1662,6 +1662,42 @@ struct linux_efi_tpm_eventlog {
 
 extern int efi_tpm_eventlog_init(void);
 
+/* efi_runtime_service() function identifiers */
+enum efi_rts_ids {
+	GET_TIME,
+	SET_TIME,
+	GET_WAKEUP_TIME,
+	SET_WAKEUP_TIME,
+	GET_VARIABLE,
+	GET_NEXT_VARIABLE,
+	SET_VARIABLE,
+	QUERY_VARIABLE_INFO,
+	GET_NEXT_HIGH_MONO_COUNT,
+	UPDATE_CAPSULE,
+	QUERY_CAPSULE_CAPS,
+};
+
+/*
+ * efi_runtime_work:	Details of EFI Runtime Service work
+ * @arg<1-5>:		EFI Runtime Service function arguments
+ * @status:		Status of executing EFI Runtime Service
+ * @efi_rts_id:		EFI Runtime Service function identifier
+ * @efi_rts_comp:	Struct used for handling completions
+ */
+struct efi_runtime_work {
+	void *arg1;
+	void *arg2;
+	void *arg3;
+	void *arg4;
+	void *arg5;
+	efi_status_t status;
+	struct work_struct work;
+	enum efi_rts_ids efi_rts_id;
+	struct completion efi_rts_comp;
+};
+
+extern struct efi_runtime_work efi_rts_work;
+
 /* Workqueue to queue EFI Runtime Services */
 extern struct workqueue_struct *efi_rts_wq;
 
-- 
2.18.0


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

* [PATCH 07/11] efi/x86: Handle page faults occurring while running EFI runtime services
  2018-09-27  8:50 [GIT PULL 00/11] EFI updates for v4.20 Ard Biesheuvel
                   ` (5 preceding siblings ...)
  2018-09-27  8:50 ` [PATCH 06/11] efi: Make efi_rts_work accessible to efi page fault handler Ard Biesheuvel
@ 2018-09-27  8:50 ` Ard Biesheuvel
  2018-09-27  8:50 ` [PATCH 08/11] efi/x86: drop task_lock() from efi_switch_mm() Ard Biesheuvel
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2018-09-27  8:50 UTC (permalink / raw)
  To: linux-kernel, Ingo Molnar, Thomas Gleixner
  Cc: Ard Biesheuvel, linux-efi, Aaron Ma, Alistair Strachan,
	Ben Hutchings, Bhupesh Sharma, Hans de Goede, Ivan Hu,
	Jeremy Linton, Marc Zyngier, Matt Fleming, Peter Robinson,
	Sai Praneeth Prakhya, Sebastian Andrzej Siewior, Stefan Agner

From: Sai Praneeth <sai.praneeth.prakhya@intel.com>

Memory accesses performed by UEFI runtime services should be limited to:
- reading/executing from EFI_RUNTIME_SERVICES_CODE memory regions
- reading/writing from/to EFI_RUNTIME_SERVICES_DATA memory regions
- reading/writing by-ref arguments
- reading/writing from/to the stack.

Accesses outside these regions may cause the kernel to hang because the
memory region requested by the firmware isn't mapped in efi_pgd, which
causes a page fault in ring 0 and the kernel fails to handle it, leading
to die(). To save kernel from hanging, add an EFI specific page fault
handler which recovers from such faults by
1. If the efi runtime service is efi_reset_system(), reboot the machine
   through BIOS.
2. If the efi runtime service is _not_ efi_reset_system(), then freeze
   efi_rts_wq and schedule a new process.

The EFI page fault handler offers us two advantages:
1. Avoid potential hangs caused by buggy firmware.
2. Shout loud that the firmware is buggy and hence is not a kernel bug.

Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
Suggested-by: Matt Fleming <matt@codeblueprint.co.uk>
Based-on-code-from: Ricardo Neri <ricardo.neri@intel.com>
Signed-off-by: Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
[ardb: clarify commit log]
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/x86/include/asm/efi.h              |  1 +
 arch/x86/mm/fault.c                     |  9 +++
 arch/x86/platform/efi/quirks.c          | 78 +++++++++++++++++++++++++
 drivers/firmware/efi/runtime-wrappers.c |  8 +++
 include/linux/efi.h                     |  8 ++-
 5 files changed, 103 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index cec5fae23eb3..eea40d52ca78 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -140,6 +140,7 @@ extern void __init efi_apply_memmap_quirks(void);
 extern int __init efi_reuse_config(u64 tables, int nr_tables);
 extern void efi_delete_dummy_variable(void);
 extern void efi_switch_mm(struct mm_struct *mm);
+extern void efi_recover_from_page_fault(unsigned long phys_addr);
 
 struct efi_setup_data {
 	u64 fw_vendor;
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 47bebfe6efa7..a5b9ddb0f1fe 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -16,6 +16,7 @@
 #include <linux/prefetch.h>		/* prefetchw			*/
 #include <linux/context_tracking.h>	/* exception_enter(), ...	*/
 #include <linux/uaccess.h>		/* faulthandler_disabled()	*/
+#include <linux/efi.h>			/* efi_recover_from_page_fault()*/
 #include <linux/mm_types.h>
 
 #include <asm/cpufeature.h>		/* boot_cpu_has, ...		*/
@@ -25,6 +26,7 @@
 #include <asm/vsyscall.h>		/* emulate_vsyscall		*/
 #include <asm/vm86.h>			/* struct vm86			*/
 #include <asm/mmu_context.h>		/* vma_pkey()			*/
+#include <asm/efi.h>			/* efi_recover_from_page_fault()*/
 
 #define CREATE_TRACE_POINTS
 #include <asm/trace/exceptions.h>
@@ -788,6 +790,13 @@ no_context(struct pt_regs *regs, unsigned long error_code,
 	if (is_errata93(regs, address))
 		return;
 
+	/*
+	 * Buggy firmware could access regions which might page fault, try to
+	 * recover from such faults.
+	 */
+	if (IS_ENABLED(CONFIG_EFI))
+		efi_recover_from_page_fault(address);
+
 	/*
 	 * Oops. The kernel tried to access some bad page. We'll have to
 	 * terminate things with extreme prejudice:
diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
index 844d31cb8a0c..669babcaf245 100644
--- a/arch/x86/platform/efi/quirks.c
+++ b/arch/x86/platform/efi/quirks.c
@@ -16,6 +16,7 @@
 #include <asm/efi.h>
 #include <asm/uv/uv.h>
 #include <asm/cpu_device_id.h>
+#include <asm/reboot.h>
 
 #define EFI_MIN_RESERVE 5120
 
@@ -654,3 +655,80 @@ int efi_capsule_setup_info(struct capsule_info *cap_info, void *kbuff,
 }
 
 #endif
+
+/*
+ * If any access by any efi runtime service causes a page fault, then,
+ * 1. If it's efi_reset_system(), reboot through BIOS.
+ * 2. If any other efi runtime service, then
+ *    a. Return error status to the efi caller process.
+ *    b. Disable EFI Runtime Services forever and
+ *    c. Freeze efi_rts_wq and schedule new process.
+ *
+ * @return: Returns, if the page fault is not handled. This function
+ * will never return if the page fault is handled successfully.
+ */
+void efi_recover_from_page_fault(unsigned long phys_addr)
+{
+	if (!IS_ENABLED(CONFIG_X86_64))
+		return;
+
+	/*
+	 * Make sure that an efi runtime service caused the page fault.
+	 * "efi_mm" cannot be used to check if the page fault had occurred
+	 * in the firmware context because efi=old_map doesn't use efi_pgd.
+	 */
+	if (efi_rts_work.efi_rts_id == NONE)
+		return;
+
+	/*
+	 * Address range 0x0000 - 0x0fff is always mapped in the efi_pgd, so
+	 * page faulting on these addresses isn't expected.
+	 */
+	if (phys_addr >= 0x0000 && phys_addr <= 0x0fff)
+		return;
+
+	/*
+	 * Print stack trace as it might be useful to know which EFI Runtime
+	 * Service is buggy.
+	 */
+	WARN(1, FW_BUG "Page fault caused by firmware at PA: 0x%lx\n",
+	     phys_addr);
+
+	/*
+	 * Buggy efi_reset_system() is handled differently from other EFI
+	 * Runtime Services as it doesn't use efi_rts_wq. Although,
+	 * native_machine_emergency_restart() says that machine_real_restart()
+	 * could fail, it's better not to compilcate this fault handler
+	 * because this case occurs *very* rarely and hence could be improved
+	 * on a need by basis.
+	 */
+	if (efi_rts_work.efi_rts_id == RESET_SYSTEM) {
+		pr_info("efi_reset_system() buggy! Reboot through BIOS\n");
+		machine_real_restart(MRR_BIOS);
+		return;
+	}
+
+	/*
+	 * Before calling EFI Runtime Service, the kernel has switched the
+	 * calling process to efi_mm. Hence, switch back to task_mm.
+	 */
+	arch_efi_call_virt_teardown();
+
+	/* Signal error status to the efi caller process */
+	efi_rts_work.status = EFI_ABORTED;
+	complete(&efi_rts_work.efi_rts_comp);
+
+	clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
+	pr_info("Froze efi_rts_wq and disabled EFI Runtime Services\n");
+
+	/*
+	 * Call schedule() in an infinite loop, so that any spurious wake ups
+	 * will never run efi_rts_wq again.
+	 */
+	for (;;) {
+		set_current_state(TASK_IDLE);
+		schedule();
+	}
+
+	return;
+}
diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c
index b18b2d864c2c..a19d845bdb06 100644
--- a/drivers/firmware/efi/runtime-wrappers.c
+++ b/drivers/firmware/efi/runtime-wrappers.c
@@ -61,6 +61,11 @@ struct efi_runtime_work efi_rts_work;
 ({									\
 	efi_rts_work.status = EFI_ABORTED;				\
 									\
+	if (!efi_enabled(EFI_RUNTIME_SERVICES)) {			\
+		pr_warn_once("EFI Runtime Services are disabled!\n");	\
+		goto exit;						\
+	}								\
+									\
 	init_completion(&efi_rts_work.efi_rts_comp);			\
 	INIT_WORK_ONSTACK(&efi_rts_work.work, efi_call_rts);		\
 	efi_rts_work.arg1 = _arg1;					\
@@ -79,6 +84,8 @@ struct efi_runtime_work efi_rts_work;
 	else								\
 		pr_err("Failed to queue work to efi_rts_wq.\n");	\
 									\
+exit:									\
+	efi_rts_work.efi_rts_id = NONE;					\
 	efi_rts_work.status;						\
 })
 
@@ -393,6 +400,7 @@ static void virt_efi_reset_system(int reset_type,
 			"could not get exclusive access to the firmware\n");
 		return;
 	}
+	efi_rts_work.efi_rts_id = RESET_SYSTEM;
 	__efi_call_virt(reset_system, reset_type, status, data_size, data);
 	up(&efi_runtime_lock);
 }
diff --git a/include/linux/efi.h b/include/linux/efi.h
index a929d2bf41fa..845174e113ce 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1662,8 +1662,13 @@ struct linux_efi_tpm_eventlog {
 
 extern int efi_tpm_eventlog_init(void);
 
-/* efi_runtime_service() function identifiers */
+/*
+ * efi_runtime_service() function identifiers.
+ * "NONE" is used by efi_recover_from_page_fault() to check if the page
+ * fault happened while executing an efi runtime service.
+ */
 enum efi_rts_ids {
+	NONE,
 	GET_TIME,
 	SET_TIME,
 	GET_WAKEUP_TIME,
@@ -1673,6 +1678,7 @@ enum efi_rts_ids {
 	SET_VARIABLE,
 	QUERY_VARIABLE_INFO,
 	GET_NEXT_HIGH_MONO_COUNT,
+	RESET_SYSTEM,
 	UPDATE_CAPSULE,
 	QUERY_CAPSULE_CAPS,
 };
-- 
2.18.0


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

* [PATCH 08/11] efi/x86: drop task_lock() from efi_switch_mm()
  2018-09-27  8:50 [GIT PULL 00/11] EFI updates for v4.20 Ard Biesheuvel
                   ` (6 preceding siblings ...)
  2018-09-27  8:50 ` [PATCH 07/11] efi/x86: Handle page faults occurring while running EFI runtime services Ard Biesheuvel
@ 2018-09-27  8:50 ` Ard Biesheuvel
  2018-09-27  8:50 ` [PATCH 09/11] efi/x86: earlyprintk - Add 64bit efi fb address support Ard Biesheuvel
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2018-09-27  8:50 UTC (permalink / raw)
  To: linux-kernel, Ingo Molnar, Thomas Gleixner
  Cc: Ard Biesheuvel, linux-efi, Aaron Ma, Alistair Strachan,
	Ben Hutchings, Bhupesh Sharma, Hans de Goede, Ivan Hu,
	Jeremy Linton, Marc Zyngier, Matt Fleming, Peter Robinson,
	Sai Praneeth Prakhya, Sebastian Andrzej Siewior, Stefan Agner

From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

efi_switch_mm() is a wrapper around switch_mm() which saves current's
->active_mm, sets the requests mm as ->active_mm and invokes
switch_mm().
I don't think that task_lock() is required during that procedure. It
protects ->mm which isn't changed here.

It needs to be mentioned that during the whole procedure (switch to
EFI's mm and back) the preemption needs to be disabled. A context switch
at this point would reset the cr3 value based on current->mm. Also, this
function may not be invoked at the same time on a different CPU because
it would overwrite the efi_scratch.prev_mm information.

Remove task_lock() and also update the comment to reflect it.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/x86/platform/efi/efi_64.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index ee5d08f25ce4..e8da7f492970 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -619,18 +619,16 @@ void __init efi_dump_pagetable(void)
 
 /*
  * Makes the calling thread switch to/from efi_mm context. Can be used
- * for SetVirtualAddressMap() i.e. current->active_mm == init_mm as well
- * as during efi runtime calls i.e current->active_mm == current_mm.
- * We are not mm_dropping()/mm_grabbing() any mm, because we are not
- * losing/creating any references.
+ * in a kernel thread and user context. Preemption needs to remain disabled
+ * while the EFI-mm is borrowed. mmgrab()/mmdrop() is not used because the mm
+ * can not change under us.
+ * It should be ensured that there are no concurent calls to this function.
  */
 void efi_switch_mm(struct mm_struct *mm)
 {
-	task_lock(current);
 	efi_scratch.prev_mm = current->active_mm;
 	current->active_mm = mm;
 	switch_mm(efi_scratch.prev_mm, mm, NULL);
-	task_unlock(current);
 }
 
 #ifdef CONFIG_EFI_MIXED
-- 
2.18.0


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

* [PATCH 09/11] efi/x86: earlyprintk - Add 64bit efi fb address support
  2018-09-27  8:50 [GIT PULL 00/11] EFI updates for v4.20 Ard Biesheuvel
                   ` (7 preceding siblings ...)
  2018-09-27  8:50 ` [PATCH 08/11] efi/x86: drop task_lock() from efi_switch_mm() Ard Biesheuvel
@ 2018-09-27  8:50 ` Ard Biesheuvel
  2018-09-27  8:50 ` [PATCH 10/11] efi/x86: Call efi_parse_options() from efi_main() Ard Biesheuvel
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2018-09-27  8:50 UTC (permalink / raw)
  To: linux-kernel, Ingo Molnar, Thomas Gleixner
  Cc: Ard Biesheuvel, linux-efi, Aaron Ma, Alistair Strachan,
	Ben Hutchings, Bhupesh Sharma, Hans de Goede, Ivan Hu,
	Jeremy Linton, Marc Zyngier, Matt Fleming, Peter Robinson,
	Sai Praneeth Prakhya, Sebastian Andrzej Siewior, Stefan Agner

From: Aaron Ma <aaron.ma@canonical.com>

EFI GOP uses 64-bit frame buffer address in some BIOS.
Add 64bit address support in efi earlyprintk.

Signed-off-by: Aaron Ma <aaron.ma@canonical.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/x86/platform/efi/early_printk.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/x86/platform/efi/early_printk.c b/arch/x86/platform/efi/early_printk.c
index 5fdacb322ceb..7476b3b097e1 100644
--- a/arch/x86/platform/efi/early_printk.c
+++ b/arch/x86/platform/efi/early_printk.c
@@ -26,12 +26,14 @@ static bool early_efi_keep;
  */
 static __init int early_efi_map_fb(void)
 {
-	unsigned long base, size;
+	u64 base, size;
 
 	if (!early_efi_keep)
 		return 0;
 
 	base = boot_params.screen_info.lfb_base;
+	if (boot_params.screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
+		base |= (u64)boot_params.screen_info.ext_lfb_base << 32;
 	size = boot_params.screen_info.lfb_size;
 	efi_fb = ioremap(base, size);
 
@@ -46,9 +48,11 @@ early_initcall(early_efi_map_fb);
  */
 static __ref void *early_efi_map(unsigned long start, unsigned long len)
 {
-	unsigned long base;
+	u64 base;
 
 	base = boot_params.screen_info.lfb_base;
+	if (boot_params.screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
+		base |= (u64)boot_params.screen_info.ext_lfb_base << 32;
 
 	if (efi_fb)
 		return (efi_fb + start);
-- 
2.18.0


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

* [PATCH 10/11] efi/x86: Call efi_parse_options() from efi_main()
  2018-09-27  8:50 [GIT PULL 00/11] EFI updates for v4.20 Ard Biesheuvel
                   ` (8 preceding siblings ...)
  2018-09-27  8:50 ` [PATCH 09/11] efi/x86: earlyprintk - Add 64bit efi fb address support Ard Biesheuvel
@ 2018-09-27  8:50 ` Ard Biesheuvel
  2018-09-27  8:50 ` [PATCH 11/11] x86: boot: Fix EFI stub alignment Ard Biesheuvel
  2018-09-27  9:07 ` [GIT PULL 00/11] EFI updates for v4.20 Marc Zyngier
  11 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2018-09-27  8:50 UTC (permalink / raw)
  To: linux-kernel, Ingo Molnar, Thomas Gleixner
  Cc: Ard Biesheuvel, linux-efi, Aaron Ma, Alistair Strachan,
	Ben Hutchings, Bhupesh Sharma, Hans de Goede, Ivan Hu,
	Jeremy Linton, Marc Zyngier, Matt Fleming, Peter Robinson,
	Sai Praneeth Prakhya, Sebastian Andrzej Siewior, Stefan Agner

From: Hans de Goede <hdegoede@redhat.com>

Before this commit we were only calling efi_parse_options() from
make_boot_params(), but make_boot_params() only gets called if the
kernel gets booted directly as an EFI executable. So when booted through
e.g. grub we ended up not parsing the commandline in the boot code.

This makes the drivers/firmware/efi/libstub code ignore the "quiet"
commandline argument resulting in the following message being printed:
"EFI stub: UEFI Secure Boot is enabled."

Despite the quiet request. This commits adds an extra call to
efi_parse_options() to efi_main() to make sure that the options are
always processed. This fixes quiet not working.

This also fixes the libstub code ignoring nokaslr and efi=nochunk.

Reported-by: Peter Robinson <pbrobinson@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/x86/boot/compressed/eboot.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 1458b1700fc7..8b4c5e001157 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -738,6 +738,7 @@ efi_main(struct efi_config *c, struct boot_params *boot_params)
 	struct desc_struct *desc;
 	void *handle;
 	efi_system_table_t *_table;
+	unsigned long cmdline_paddr;
 
 	efi_early = c;
 
@@ -755,6 +756,15 @@ efi_main(struct efi_config *c, struct boot_params *boot_params)
 	else
 		setup_boot_services32(efi_early);
 
+	/*
+	 * make_boot_params() may have been called before efi_main(), in which
+	 * case this is the second time we parse the cmdline. This is ok,
+	 * parsing the cmdline multiple times does not have side-effects.
+	 */
+	cmdline_paddr = ((u64)hdr->cmd_line_ptr |
+			 ((u64)boot_params->ext_cmd_line_ptr << 32));
+	efi_parse_options((char *)cmdline_paddr);
+
 	/*
 	 * If the boot loader gave us a value for secure_boot then we use that,
 	 * otherwise we ask the BIOS.
-- 
2.18.0


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

* [PATCH 11/11] x86: boot: Fix EFI stub alignment
  2018-09-27  8:50 [GIT PULL 00/11] EFI updates for v4.20 Ard Biesheuvel
                   ` (9 preceding siblings ...)
  2018-09-27  8:50 ` [PATCH 10/11] efi/x86: Call efi_parse_options() from efi_main() Ard Biesheuvel
@ 2018-09-27  8:50 ` Ard Biesheuvel
  2018-09-27  9:07 ` [GIT PULL 00/11] EFI updates for v4.20 Marc Zyngier
  11 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2018-09-27  8:50 UTC (permalink / raw)
  To: linux-kernel, Ingo Molnar, Thomas Gleixner
  Cc: Ard Biesheuvel, linux-efi, Aaron Ma, Alistair Strachan,
	Ben Hutchings, Bhupesh Sharma, Hans de Goede, Ivan Hu,
	Jeremy Linton, Marc Zyngier, Matt Fleming, Peter Robinson,
	Sai Praneeth Prakhya, Sebastian Andrzej Siewior, Stefan Agner

From: Ben Hutchings <ben@decadent.org.uk>

We currently align the end of the compressed image to a multiple of
16.  However, the PE-COFF header included in the EFI stub says that
the file alignment is 32 bytes, and when adding an EFI signature to
the file it must first be padded to this alignment.

sbsigntool commands warn about this:

  warning: file-aligned section .text extends beyond end of file
  warning: checksum areas are greater than image size. Invalid section table?

Worse, pesign -at least when creating a detached signature- uses the
hash of the unpadded file, resulting in an invalid signature if
padding is required.

Avoid both these problems by increasing alignment to 32 bytes when
CONFIG_EFI_STUB is enabled.

Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/x86/boot/tools/build.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c
index d4e6cd4577e5..bf0e82400358 100644
--- a/arch/x86/boot/tools/build.c
+++ b/arch/x86/boot/tools/build.c
@@ -391,6 +391,13 @@ int main(int argc, char ** argv)
 		die("Unable to mmap '%s': %m", argv[2]);
 	/* Number of 16-byte paragraphs, including space for a 4-byte CRC */
 	sys_size = (sz + 15 + 4) / 16;
+#ifdef CONFIG_EFI_STUB
+	/*
+	 * COFF requires minimum 32-byte alignment of sections, and
+	 * adding a signature is problematic without that alignment.
+	 */
+	sys_size = (sys_size + 1) & ~1;
+#endif
 
 	/* Patch the setup code with the appropriate size parameters */
 	buf[0x1f1] = setup_sectors-1;
-- 
2.18.0


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

* Re: [GIT PULL 00/11] EFI updates for v4.20
  2018-09-27  8:50 [GIT PULL 00/11] EFI updates for v4.20 Ard Biesheuvel
                   ` (10 preceding siblings ...)
  2018-09-27  8:50 ` [PATCH 11/11] x86: boot: Fix EFI stub alignment Ard Biesheuvel
@ 2018-09-27  9:07 ` Marc Zyngier
  2018-10-02  8:34   ` Ingo Molnar
  11 siblings, 1 reply; 17+ messages in thread
From: Marc Zyngier @ 2018-09-27  9:07 UTC (permalink / raw)
  To: Ard Biesheuvel, linux-kernel, Ingo Molnar, Thomas Gleixner
  Cc: linux-efi, Aaron Ma, Alistair Strachan, Ben Hutchings,
	Bhupesh Sharma, Hans de Goede, Ivan Hu, Jeremy Linton,
	Matt Fleming, Peter Robinson, Sai Praneeth Prakhya,
	Sebastian Andrzej Siewior, Stefan Agner

Hi all,

On 27/09/18 09:50, Ard Biesheuvel wrote:
> Thomas, Ingo,
> 
> Please pull/cherry-pick the below. Note that the first three patches will
> be depended upon by an irqchip series that Marc Zyngier has sent out last
> week, and that targets the next release as well. So please advise how to
> proceed with that: we could simply apply those patches first and use the
> resulting commit in tip.git as a stable branch, I suppose, but I'll let
> Marc chime in in case he has any other ideas.

A stable branch with these three patches would be great. The irqchip 
code will also end-up in tip, so it should all be quite easy to manage 
anyway.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

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

* Re: [GIT PULL 00/11] EFI updates for v4.20
  2018-09-27  9:07 ` [GIT PULL 00/11] EFI updates for v4.20 Marc Zyngier
@ 2018-10-02  8:34   ` Ingo Molnar
  2018-10-02  8:38     ` Ingo Molnar
  0 siblings, 1 reply; 17+ messages in thread
From: Ingo Molnar @ 2018-10-02  8:34 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Ard Biesheuvel, linux-kernel, Thomas Gleixner, linux-efi,
	Aaron Ma, Alistair Strachan, Ben Hutchings, Bhupesh Sharma,
	Hans de Goede, Ivan Hu, Jeremy Linton, Matt Fleming,
	Peter Robinson, Sai Praneeth Prakhya, Sebastian Andrzej Siewior,
	Stefan Agner


* Marc Zyngier <marc.zyngier@arm.com> wrote:

> Hi all,
> 
> On 27/09/18 09:50, Ard Biesheuvel wrote:
> > Thomas, Ingo,
> > 
> > Please pull/cherry-pick the below. Note that the first three patches will
> > be depended upon by an irqchip series that Marc Zyngier has sent out last
> > week, and that targets the next release as well. So please advise how to
> > proceed with that: we could simply apply those patches first and use the
> > resulting commit in tip.git as a stable branch, I suppose, but I'll let
> > Marc chime in in case he has any other ideas.
> 
> A stable branch with these three patches would be great. The irqchip code
> will also end-up in tip, so it should all be quite easy to manage anyway.

Yeah - nevertheless, to keep it all separated nicely, I've created a new
topic tree for this: tip:efi/irqchip (2e3ac98133a3), with just these three
patches on top of latest -git.

That way it can then all be iterated separately.

Does this approach work for you?

Thanks,

	Ingo

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

* Re: [GIT PULL 00/11] EFI updates for v4.20
  2018-10-02  8:34   ` Ingo Molnar
@ 2018-10-02  8:38     ` Ingo Molnar
  2018-10-02  9:26       ` Ard Biesheuvel
  2018-10-02  9:29       ` Marc Zyngier
  0 siblings, 2 replies; 17+ messages in thread
From: Ingo Molnar @ 2018-10-02  8:38 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Ard Biesheuvel, linux-kernel, Thomas Gleixner, linux-efi,
	Aaron Ma, Alistair Strachan, Ben Hutchings, Bhupesh Sharma,
	Hans de Goede, Ivan Hu, Jeremy Linton, Matt Fleming,
	Peter Robinson, Sai Praneeth Prakhya, Sebastian Andrzej Siewior,
	Stefan Agner


* Ingo Molnar <mingo@kernel.org> wrote:

> 
> * Marc Zyngier <marc.zyngier@arm.com> wrote:
> 
> > Hi all,
> > 
> > On 27/09/18 09:50, Ard Biesheuvel wrote:
> > > Thomas, Ingo,
> > > 
> > > Please pull/cherry-pick the below. Note that the first three patches will
> > > be depended upon by an irqchip series that Marc Zyngier has sent out last
> > > week, and that targets the next release as well. So please advise how to
> > > proceed with that: we could simply apply those patches first and use the
> > > resulting commit in tip.git as a stable branch, I suppose, but I'll let
> > > Marc chime in in case he has any other ideas.
> > 
> > A stable branch with these three patches would be great. The irqchip code
> > will also end-up in tip, so it should all be quite easy to manage anyway.
> 
> Yeah - nevertheless, to keep it all separated nicely, I've created a new
> topic tree for this: tip:efi/irqchip (2e3ac98133a3), with just these three
> patches on top of latest -git.
> 
> That way it can then all be iterated separately.
> 
> Does this approach work for you?

It's a23d3bb05ccb - i.e. the commit ID of Ard's tree, so if you already based your work on top 
of that then you won't even need to rebase anything.

Thanks,

	Ingo

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

* Re: [GIT PULL 00/11] EFI updates for v4.20
  2018-10-02  8:38     ` Ingo Molnar
@ 2018-10-02  9:26       ` Ard Biesheuvel
  2018-10-02  9:29       ` Marc Zyngier
  1 sibling, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2018-10-02  9:26 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Marc Zyngier, Linux Kernel Mailing List, Thomas Gleixner,
	linux-efi, Aaron Ma, Alistair Strachan, Ben Hutchings,
	Bhupesh Sharma, Hans de Goede, Ivan Hu, Jeremy Linton,
	Matt Fleming, Peter Robinson, Sai Praneeth Prakhya,
	Sebastian Andrzej Siewior, Stefan Agner

On 2 October 2018 at 10:38, Ingo Molnar <mingo@kernel.org> wrote:
>
> * Ingo Molnar <mingo@kernel.org> wrote:
>
>>
>> * Marc Zyngier <marc.zyngier@arm.com> wrote:
>>
>> > Hi all,
>> >
>> > On 27/09/18 09:50, Ard Biesheuvel wrote:
>> > > Thomas, Ingo,
>> > >
>> > > Please pull/cherry-pick the below. Note that the first three patches will
>> > > be depended upon by an irqchip series that Marc Zyngier has sent out last
>> > > week, and that targets the next release as well. So please advise how to
>> > > proceed with that: we could simply apply those patches first and use the
>> > > resulting commit in tip.git as a stable branch, I suppose, but I'll let
>> > > Marc chime in in case he has any other ideas.
>> >
>> > A stable branch with these three patches would be great. The irqchip code
>> > will also end-up in tip, so it should all be quite easy to manage anyway.
>>
>> Yeah - nevertheless, to keep it all separated nicely, I've created a new
>> topic tree for this: tip:efi/irqchip (2e3ac98133a3), with just these three
>> patches on top of latest -git.
>>
>> That way it can then all be iterated separately.
>>
>> Does this approach work for you?
>
> It's a23d3bb05ccb - i.e. the commit ID of Ard's tree, so if you already based your work on top
> of that then you won't even need to rebase anything.
>

Thanks Ingo

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

* Re: [GIT PULL 00/11] EFI updates for v4.20
  2018-10-02  8:38     ` Ingo Molnar
  2018-10-02  9:26       ` Ard Biesheuvel
@ 2018-10-02  9:29       ` Marc Zyngier
  1 sibling, 0 replies; 17+ messages in thread
From: Marc Zyngier @ 2018-10-02  9:29 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Ard Biesheuvel, linux-kernel, Thomas Gleixner, linux-efi,
	Aaron Ma, Alistair Strachan, Ben Hutchings, Bhupesh Sharma,
	Hans de Goede, Ivan Hu, Jeremy Linton, Matt Fleming,
	Peter Robinson, Sai Praneeth Prakhya, Sebastian Andrzej Siewior,
	Stefan Agner

On Tue, 02 Oct 2018 09:38:17 +0100,
Ingo Molnar <mingo@kernel.org> wrote:
> 
> 
> * Ingo Molnar <mingo@kernel.org> wrote:
> 
> > 
> > * Marc Zyngier <marc.zyngier@arm.com> wrote:
> > 
> > > Hi all,
> > > 
> > > On 27/09/18 09:50, Ard Biesheuvel wrote:
> > > > Thomas, Ingo,
> > > > 
> > > > Please pull/cherry-pick the below. Note that the first three patches will
> > > > be depended upon by an irqchip series that Marc Zyngier has sent out last
> > > > week, and that targets the next release as well. So please advise how to
> > > > proceed with that: we could simply apply those patches first and use the
> > > > resulting commit in tip.git as a stable branch, I suppose, but I'll let
> > > > Marc chime in in case he has any other ideas.
> > > 
> > > A stable branch with these three patches would be great. The irqchip code
> > > will also end-up in tip, so it should all be quite easy to manage anyway.
> > 
> > Yeah - nevertheless, to keep it all separated nicely, I've created a new
> > topic tree for this: tip:efi/irqchip (2e3ac98133a3), with just these three
> > patches on top of latest -git.
> > 
> > That way it can then all be iterated separately.
> > 
> > Does this approach work for you?
> 
> It's a23d3bb05ccb - i.e. the commit ID of Ard's tree, so if you
> already based your work on top of that then you won't even need to
> rebase anything.

No, it was already based on the tip/efi/core. Never mind, I'll rebase
it.

Thanks,

	M.

-- 
Jazz is not dead, it just smell funny.

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

end of thread, other threads:[~2018-10-02  9:30 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-27  8:50 [GIT PULL 00/11] EFI updates for v4.20 Ard Biesheuvel
2018-09-27  8:50 ` [PATCH 01/11] efi: honour memory reservations passed via a linux specific config table Ard Biesheuvel
2018-09-27  8:50 ` [PATCH 02/11] efi/arm: libstub: add a root memreserve " Ard Biesheuvel
2018-09-27  8:50 ` [PATCH 03/11] efi: add API to reserve memory persistently across kexec reboot Ard Biesheuvel
2018-09-27  8:50 ` [PATCH 04/11] efi/libstub: arm: support building with clang Ard Biesheuvel
2018-09-27  8:50 ` [PATCH 05/11] efi/efi_test: add exporting ResetSystem runtime service Ard Biesheuvel
2018-09-27  8:50 ` [PATCH 06/11] efi: Make efi_rts_work accessible to efi page fault handler Ard Biesheuvel
2018-09-27  8:50 ` [PATCH 07/11] efi/x86: Handle page faults occurring while running EFI runtime services Ard Biesheuvel
2018-09-27  8:50 ` [PATCH 08/11] efi/x86: drop task_lock() from efi_switch_mm() Ard Biesheuvel
2018-09-27  8:50 ` [PATCH 09/11] efi/x86: earlyprintk - Add 64bit efi fb address support Ard Biesheuvel
2018-09-27  8:50 ` [PATCH 10/11] efi/x86: Call efi_parse_options() from efi_main() Ard Biesheuvel
2018-09-27  8:50 ` [PATCH 11/11] x86: boot: Fix EFI stub alignment Ard Biesheuvel
2018-09-27  9:07 ` [GIT PULL 00/11] EFI updates for v4.20 Marc Zyngier
2018-10-02  8:34   ` Ingo Molnar
2018-10-02  8:38     ` Ingo Molnar
2018-10-02  9:26       ` Ard Biesheuvel
2018-10-02  9:29       ` Marc Zyngier

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).