From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Russell King <rmk+kernel@armlinux.org.uk>,
Giancarlo Ferrari <giancarlo.ferrari89@gmail.com>,
Sasha Levin <sashal@kernel.org>,
linux-arm-kernel@lists.infradead.org
Subject: [PATCH AUTOSEL 5.10 31/36] ARM: kexec: fix oops after TLB are invalidated
Date: Mon, 8 Feb 2021 12:58:01 -0500 [thread overview]
Message-ID: <20210208175806.2091668-31-sashal@kernel.org> (raw)
In-Reply-To: <20210208175806.2091668-1-sashal@kernel.org>
From: Russell King <rmk+kernel@armlinux.org.uk>
[ Upstream commit 4d62e81b60d4025e2dfcd5ea531cc1394ce9226f ]
Giancarlo Ferrari reports the following oops while trying to use kexec:
Unable to handle kernel paging request at virtual address 80112f38
pgd = fd7ef03e
[80112f38] *pgd=0001141e(bad)
Internal error: Oops: 80d [#1] PREEMPT SMP ARM
...
This is caused by machine_kexec() trying to set the kernel text to be
read/write, so it can poke values into the relocation code before
copying it - and an interrupt occuring which changes the page tables.
The subsequent writes then hit read-only sections that trigger a
data abort resulting in the above oops.
Fix this by copying the relocation code, and then writing the variables
into the destination, thereby avoiding the need to make the kernel text
read/write.
Reported-by: Giancarlo Ferrari <giancarlo.ferrari89@gmail.com>
Tested-by: Giancarlo Ferrari <giancarlo.ferrari89@gmail.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm/include/asm/kexec-internal.h | 12 +++++++++
arch/arm/kernel/asm-offsets.c | 5 ++++
arch/arm/kernel/machine_kexec.c | 20 ++++++--------
arch/arm/kernel/relocate_kernel.S | 38 ++++++++-------------------
4 files changed, 36 insertions(+), 39 deletions(-)
create mode 100644 arch/arm/include/asm/kexec-internal.h
diff --git a/arch/arm/include/asm/kexec-internal.h b/arch/arm/include/asm/kexec-internal.h
new file mode 100644
index 0000000000000..ecc2322db7aa1
--- /dev/null
+++ b/arch/arm/include/asm/kexec-internal.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ARM_KEXEC_INTERNAL_H
+#define _ARM_KEXEC_INTERNAL_H
+
+struct kexec_relocate_data {
+ unsigned long kexec_start_address;
+ unsigned long kexec_indirection_page;
+ unsigned long kexec_mach_type;
+ unsigned long kexec_r2;
+};
+
+#endif
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index a1570c8bab25a..be8050b0c3dfb 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -12,6 +12,7 @@
#include <linux/mm.h>
#include <linux/dma-mapping.h>
#include <asm/cacheflush.h>
+#include <asm/kexec-internal.h>
#include <asm/glue-df.h>
#include <asm/glue-pf.h>
#include <asm/mach/arch.h>
@@ -170,5 +171,9 @@ int main(void)
DEFINE(MPU_RGN_PRBAR, offsetof(struct mpu_rgn, prbar));
DEFINE(MPU_RGN_PRLAR, offsetof(struct mpu_rgn, prlar));
#endif
+ DEFINE(KEXEC_START_ADDR, offsetof(struct kexec_relocate_data, kexec_start_address));
+ DEFINE(KEXEC_INDIR_PAGE, offsetof(struct kexec_relocate_data, kexec_indirection_page));
+ DEFINE(KEXEC_MACH_TYPE, offsetof(struct kexec_relocate_data, kexec_mach_type));
+ DEFINE(KEXEC_R2, offsetof(struct kexec_relocate_data, kexec_r2));
return 0;
}
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 5d84ad333f050..2b09dad7935eb 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -13,6 +13,7 @@
#include <linux/of_fdt.h>
#include <asm/mmu_context.h>
#include <asm/cacheflush.h>
+#include <asm/kexec-internal.h>
#include <asm/fncpy.h>
#include <asm/mach-types.h>
#include <asm/smp_plat.h>
@@ -22,11 +23,6 @@
extern void relocate_new_kernel(void);
extern const unsigned int relocate_new_kernel_size;
-extern unsigned long kexec_start_address;
-extern unsigned long kexec_indirection_page;
-extern unsigned long kexec_mach_type;
-extern unsigned long kexec_boot_atags;
-
static atomic_t waiting_for_crash_ipi;
/*
@@ -159,6 +155,7 @@ void (*kexec_reinit)(void);
void machine_kexec(struct kimage *image)
{
unsigned long page_list, reboot_entry_phys;
+ struct kexec_relocate_data *data;
void (*reboot_entry)(void);
void *reboot_code_buffer;
@@ -174,18 +171,17 @@ void machine_kexec(struct kimage *image)
reboot_code_buffer = page_address(image->control_code_page);
- /* Prepare parameters for reboot_code_buffer*/
- set_kernel_text_rw();
- kexec_start_address = image->start;
- kexec_indirection_page = page_list;
- kexec_mach_type = machine_arch_type;
- kexec_boot_atags = image->arch.kernel_r2;
-
/* copy our kernel relocation code to the control code page */
reboot_entry = fncpy(reboot_code_buffer,
&relocate_new_kernel,
relocate_new_kernel_size);
+ data = reboot_code_buffer + relocate_new_kernel_size;
+ data->kexec_start_address = image->start;
+ data->kexec_indirection_page = page_list;
+ data->kexec_mach_type = machine_arch_type;
+ data->kexec_r2 = image->arch.kernel_r2;
+
/* get the identity mapping physical address for the reboot code */
reboot_entry_phys = virt_to_idmap(reboot_entry);
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
index 72a08786e16eb..218d524360fcd 100644
--- a/arch/arm/kernel/relocate_kernel.S
+++ b/arch/arm/kernel/relocate_kernel.S
@@ -5,14 +5,16 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
#include <asm/kexec.h>
.align 3 /* not needed for this code, but keeps fncpy() happy */
ENTRY(relocate_new_kernel)
- ldr r0,kexec_indirection_page
- ldr r1,kexec_start_address
+ adr r7, relocate_new_kernel_end
+ ldr r0, [r7, #KEXEC_INDIR_PAGE]
+ ldr r1, [r7, #KEXEC_START_ADDR]
/*
* If there is no indirection page (we are doing crashdumps)
@@ -57,34 +59,16 @@ ENTRY(relocate_new_kernel)
2:
/* Jump to relocated kernel */
- mov lr,r1
- mov r0,#0
- ldr r1,kexec_mach_type
- ldr r2,kexec_boot_atags
- ARM( ret lr )
- THUMB( bx lr )
-
- .align
-
- .globl kexec_start_address
-kexec_start_address:
- .long 0x0
-
- .globl kexec_indirection_page
-kexec_indirection_page:
- .long 0x0
-
- .globl kexec_mach_type
-kexec_mach_type:
- .long 0x0
-
- /* phy addr of the atags for the new kernel */
- .globl kexec_boot_atags
-kexec_boot_atags:
- .long 0x0
+ mov lr, r1
+ mov r0, #0
+ ldr r1, [r7, #KEXEC_MACH_TYPE]
+ ldr r2, [r7, #KEXEC_R2]
+ ARM( ret lr )
+ THUMB( bx lr )
ENDPROC(relocate_new_kernel)
+ .align 3
relocate_new_kernel_end:
.globl relocate_new_kernel_size
--
2.27.0
next prev parent reply other threads:[~2021-02-08 18:06 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-08 17:57 [PATCH AUTOSEL 5.10 01/36] soc: ti: omap-prm: Fix boot time errors for rst_map_012 bits 0 and 1 Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 02/36] arm64: dts: rockchip: Fix PCIe DT properties on rk3399 Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 03/36] Input: goodix - add support for Goodix GT9286 chip Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 04/36] arm64: dts: qcom: sdm845: Reserve LPASS clocks in gcc Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 05/36] ARM: OMAP2+: Fix suspcious RCU usage splats for omap_enter_idle_coupled Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 06/36] arm64: dts: rockchip: remove interrupt-names property from rk3399 vdec node Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 07/36] kbuild: simplify GCC_PLUGINS enablement in dummy-tools/gcc Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 08/36] Input: xpad - sync supported devices with fork on GitHub Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 09/36] platform/x86: hp-wmi: Disable tablet-mode reporting by default Sasha Levin
2021-02-10 23:22 ` mark gross
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 10/36] arm64: dts: rockchip: Disable display for NanoPi R2S Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 11/36] ovl: perform vfs_getxattr() with mounter creds Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 12/36] cap: fix conversions on getxattr Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 13/36] ovl: skip getxattr of security labels Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 14/36] media: rkisp1: uapi: change hist_bins array type from __u16 to __u32 Sasha Levin
2021-02-08 20:46 ` Hans Verkuil
2021-02-09 12:45 ` Dafna Hirschfeld
2021-02-09 13:02 ` Greg Kroah-Hartman
2021-02-09 13:39 ` Hans Verkuil
2021-02-09 13:44 ` Greg Kroah-Hartman
2021-02-10 15:33 ` Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 15/36] media: rkisp1: stats: remove a wrong cast to u8 Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 16/36] media: rkisp1: stats: mask the hist_bins values Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 17/36] scsi: lpfc: Fix EEH encountering oops with NVMe traffic Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 18/36] x86/split_lock: Enable the split lock feature on another Alder Lake CPU Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 19/36] nvme-pci: ignore the subsysem NQN on Phison E16 Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 20/36] drm/amd/display: Fix DPCD translation for LTTPR AUX_RD_INTERVAL Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 21/36] drm/amd/display: Add more Clock Sources to DCN2.1 Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 22/36] drm/amd/display: Release DSC before acquiring Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 23/36] drm/amd/display: Fix dc_sink kref count in emulated_link_detect Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 24/36] drm/amd/display: Free atomic state after drm_atomic_commit Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 25/36] drm/amd/display: Decrement refcount of dc_sink before reassignment Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 26/36] riscv: virt_addr_valid must check the address belongs to linear mapping Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 27/36] bfq-iosched: Revert "bfq: Fix computation of shallow depth" Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 28/36] ARM: dts: lpc32xx: Revert set default clock rate of HCLK PLL Sasha Levin
2021-02-08 17:57 ` [PATCH AUTOSEL 5.10 29/36] kallsyms: fix nonconverging kallsyms table with lld Sasha Levin
2021-02-08 17:58 ` [PATCH AUTOSEL 5.10 30/36] ARM: ensure the signal page contains defined contents Sasha Levin
2021-02-08 17:58 ` Sasha Levin [this message]
2021-02-08 17:58 ` [PATCH AUTOSEL 5.10 32/36] init/gcov: allow CONFIG_CONSTRUCTORS on UML to fix module gcov Sasha Levin
2021-02-08 17:58 ` [PATCH AUTOSEL 5.10 33/36] kasan: add explicit preconditions to kasan_report() Sasha Levin
2021-02-08 17:58 ` [PATCH AUTOSEL 5.10 34/36] ubsan: implement __ubsan_handle_alignment_assumption Sasha Levin
2021-02-08 17:58 ` [PATCH AUTOSEL 5.10 35/36] Revert "lib: Restrict cpumask_local_spread to houskeeping CPUs" Sasha Levin
2021-02-08 17:58 ` [PATCH AUTOSEL 5.10 36/36] x86/efi: Remove EFI PGD build time checks Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210208175806.2091668-31-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=giancarlo.ferrari89@gmail.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=rmk+kernel@armlinux.org.uk \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox