All of lore.kernel.org
 help / color / mirror / Atom feed
* [GIT PULL 0/1] EFI fix for v4.20
@ 2018-11-23 21:51 Ard Biesheuvel
  2018-11-23 21:51 ` [PATCH 1/1] efi: prevent GICv3 WARN() by mapping memreserve table before first use Ard Biesheuvel
  0 siblings, 1 reply; 3+ messages in thread
From: Ard Biesheuvel @ 2018-11-23 21:51 UTC (permalink / raw)
  To: linux-efi, Ingo Molnar, Thomas Gleixner
  Cc: Ard Biesheuvel, linux-kernel, Jan Glauber, John Garry, Marc Zyngier

The following changes since commit 63eb322d89c8505af9b4a3d703e85e42281ebaa0:

  efi: Permit calling efi_mem_reserve_persistent() from atomic context (2018-11-15 10:04:47 +0100)

are available in the Git repository at:

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

for you to fetch changes up to 57e56580724370056aadd0e4e331ec5445ebf9e1:

  efi: prevent GICv3 WARN() by mapping memreserve table before first use (2018-11-23 20:21:12 +0100)

----------------------------------------------------------------
Apply a fix on top of the efi_mem_reserve_persistent() fix that was
merged last week to allow the function to be called earlier.

----------------------------------------------------------------
Ard Biesheuvel (1):
      efi: prevent GICv3 WARN() by mapping memreserve table before first use

 drivers/firmware/efi/efi.c | 36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)

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

* [PATCH 1/1] efi: prevent GICv3 WARN() by mapping memreserve table before first use
  2018-11-23 21:51 [GIT PULL 0/1] EFI fix for v4.20 Ard Biesheuvel
@ 2018-11-23 21:51 ` Ard Biesheuvel
  2018-11-27 13:30   ` [tip:efi/urgent] efi: Prevent GICv3 WARN() by mapping the " tip-bot for Ard Biesheuvel
  0 siblings, 1 reply; 3+ messages in thread
From: Ard Biesheuvel @ 2018-11-23 21:51 UTC (permalink / raw)
  To: linux-efi, Ingo Molnar, Thomas Gleixner; +Cc: Ard Biesheuvel, linux-kernel

Mapping the MEMRESERVE EFI configuration table from an early initcall
is too late: the GICv3 ITS code that creates persistent reservations
for the boot CPU's LPI tables is invoked from init_IRQ(), which runs
much earlier than the handling of the initcalls. This results in a
WARN() splat because the LPI tables cannot be reserved persistently,
which will result in silent memory corruption after a kexec reboot.

So instead, invoke the initialization performed by the initcall from
efi_mem_reserve_persistent() itself as well, but keep the initcall so
that the init is guaranteed to have been called before SMP boot.

Fixes: 63eb322d89c8 ("efi: Permit calling efi_mem_reserve_persistent() ...")
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Marc Zyngier <marc.zyngier@arm.com>
Tested-by: Jan Glauber <jglauber@cavium.com>
Tested-by: John Garry <john.garry@huawei.com>
---
 drivers/firmware/efi/efi.c | 36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index fad7c62cfc0e..415849bab233 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -969,13 +969,33 @@ bool efi_is_table_address(unsigned long phys_addr)
 static DEFINE_SPINLOCK(efi_mem_reserve_persistent_lock);
 static struct linux_efi_memreserve *efi_memreserve_root __ro_after_init;
 
-int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
+static int __init efi_memreserve_map_root(void)
+{
+	if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR)
+		return -ENODEV;
+
+	efi_memreserve_root = memremap(efi.mem_reserve,
+				       sizeof(*efi_memreserve_root),
+				       MEMREMAP_WB);
+	if (WARN_ON_ONCE(!efi_memreserve_root))
+		return -ENOMEM;
+	return 0;
+}
+
+int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
 {
 	struct linux_efi_memreserve *rsv;
+	int rc;
 
-	if (!efi_memreserve_root)
+	if (efi_memreserve_root == (void *)ULONG_MAX)
 		return -ENODEV;
 
+	if (!efi_memreserve_root) {
+		rc = efi_memreserve_map_root();
+		if (rc)
+			return rc;
+	}
+
 	rsv = kmalloc(sizeof(*rsv), GFP_ATOMIC);
 	if (!rsv)
 		return -ENOMEM;
@@ -993,14 +1013,10 @@ int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
 
 static int __init efi_memreserve_root_init(void)
 {
-	if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR)
-		return -ENODEV;
-
-	efi_memreserve_root = memremap(efi.mem_reserve,
-				       sizeof(*efi_memreserve_root),
-				       MEMREMAP_WB);
-	if (!efi_memreserve_root)
-		return -ENOMEM;
+	if (efi_memreserve_root)
+		return 0;
+	if (efi_memreserve_map_root())
+		efi_memreserve_root = (void *)ULONG_MAX;
 	return 0;
 }
 early_initcall(efi_memreserve_root_init);
-- 
2.19.1


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

* [tip:efi/urgent] efi: Prevent GICv3 WARN() by mapping the memreserve table before first use
  2018-11-23 21:51 ` [PATCH 1/1] efi: prevent GICv3 WARN() by mapping memreserve table before first use Ard Biesheuvel
@ 2018-11-27 13:30   ` tip-bot for Ard Biesheuvel
  0 siblings, 0 replies; 3+ messages in thread
From: tip-bot for Ard Biesheuvel @ 2018-11-27 13:30 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, ard.biesheuvel, tglx, jglauber, peterz, john.garry,
	marc.zyngier, hpa, mingo, torvalds

Commit-ID:  976b489120cdab2b1b3a41ffa14661db43d58190
Gitweb:     https://git.kernel.org/tip/976b489120cdab2b1b3a41ffa14661db43d58190
Author:     Ard Biesheuvel <ard.biesheuvel@linaro.org>
AuthorDate: Fri, 23 Nov 2018 22:51:32 +0100
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Tue, 27 Nov 2018 13:50:20 +0100

efi: Prevent GICv3 WARN() by mapping the memreserve table before first use

Mapping the MEMRESERVE EFI configuration table from an early initcall
is too late: the GICv3 ITS code that creates persistent reservations
for the boot CPU's LPI tables is invoked from init_IRQ(), which runs
much earlier than the handling of the initcalls. This results in a
WARN() splat because the LPI tables cannot be reserved persistently,
which will result in silent memory corruption after a kexec reboot.

So instead, invoke the initialization performed by the initcall from
efi_mem_reserve_persistent() itself as well, but keep the initcall so
that the init is guaranteed to have been called before SMP boot.

Tested-by: Marc Zyngier <marc.zyngier@arm.com>
Tested-by: Jan Glauber <jglauber@cavium.com>
Tested-by: John Garry <john.garry@huawei.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Fixes: 63eb322d89c8 ("efi: Permit calling efi_mem_reserve_persistent() ...")
Link: http://lkml.kernel.org/r/20181123215132.7951-2-ard.biesheuvel@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/firmware/efi/efi.c | 36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index fad7c62cfc0e..415849bab233 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -969,13 +969,33 @@ bool efi_is_table_address(unsigned long phys_addr)
 static DEFINE_SPINLOCK(efi_mem_reserve_persistent_lock);
 static struct linux_efi_memreserve *efi_memreserve_root __ro_after_init;
 
-int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
+static int __init efi_memreserve_map_root(void)
+{
+	if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR)
+		return -ENODEV;
+
+	efi_memreserve_root = memremap(efi.mem_reserve,
+				       sizeof(*efi_memreserve_root),
+				       MEMREMAP_WB);
+	if (WARN_ON_ONCE(!efi_memreserve_root))
+		return -ENOMEM;
+	return 0;
+}
+
+int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
 {
 	struct linux_efi_memreserve *rsv;
+	int rc;
 
-	if (!efi_memreserve_root)
+	if (efi_memreserve_root == (void *)ULONG_MAX)
 		return -ENODEV;
 
+	if (!efi_memreserve_root) {
+		rc = efi_memreserve_map_root();
+		if (rc)
+			return rc;
+	}
+
 	rsv = kmalloc(sizeof(*rsv), GFP_ATOMIC);
 	if (!rsv)
 		return -ENOMEM;
@@ -993,14 +1013,10 @@ int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
 
 static int __init efi_memreserve_root_init(void)
 {
-	if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR)
-		return -ENODEV;
-
-	efi_memreserve_root = memremap(efi.mem_reserve,
-				       sizeof(*efi_memreserve_root),
-				       MEMREMAP_WB);
-	if (!efi_memreserve_root)
-		return -ENOMEM;
+	if (efi_memreserve_root)
+		return 0;
+	if (efi_memreserve_map_root())
+		efi_memreserve_root = (void *)ULONG_MAX;
 	return 0;
 }
 early_initcall(efi_memreserve_root_init);

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

end of thread, other threads:[~2018-11-27 13:31 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-23 21:51 [GIT PULL 0/1] EFI fix for v4.20 Ard Biesheuvel
2018-11-23 21:51 ` [PATCH 1/1] efi: prevent GICv3 WARN() by mapping memreserve table before first use Ard Biesheuvel
2018-11-27 13:30   ` [tip:efi/urgent] efi: Prevent GICv3 WARN() by mapping the " tip-bot for Ard Biesheuvel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.