LKML Archive on lore.kernel.org
 help / color / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org,
	Giancarlo Ferrari <giancarlo.ferrari89@gmail.com>,
	Russell King <rmk+kernel@armlinux.org.uk>,
	Sasha Levin <sashal@kernel.org>
Subject: [PATCH 4.19 15/50] ARM: kexec: fix oops after TLB are invalidated
Date: Mon, 22 Feb 2021 13:13:06 +0100
Message-ID: <20210222121022.452888385@linuxfoundation.org> (raw)
In-Reply-To: <20210222121019.925481519@linuxfoundation.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 3968d6c22455b..ae85f67a63520 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -18,6 +18,7 @@
 #include <linux/kvm_host.h>
 #endif
 #include <asm/cacheflush.h>
+#include <asm/kexec-internal.h>
 #include <asm/glue-df.h>
 #include <asm/glue-pf.h>
 #include <asm/mach/arch.h>
@@ -189,5 +190,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 76300f3813e89..734adeb42df87 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -15,6 +15,7 @@
 #include <asm/pgalloc.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>
@@ -24,11 +25,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;
 
 /*
@@ -161,6 +157,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;
 
@@ -176,18 +173,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 7eaa2ae7aff58..5e15b5912cb05 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




  parent reply index

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-22 12:12 [PATCH 4.19 00/50] 4.19.177-rc1 review Greg Kroah-Hartman
2021-02-22 12:12 ` [PATCH 4.19 01/50] tracing: Do not count ftrace events in top level enable output Greg Kroah-Hartman
2021-02-22 12:12 ` [PATCH 4.19 02/50] tracing: Check length before giving out the filter buffer Greg Kroah-Hartman
2021-02-22 12:12 ` [PATCH 4.19 03/50] arm/xen: Dont probe xenbus as part of an early initcall Greg Kroah-Hartman
2021-02-22 12:12 ` [PATCH 4.19 04/50] arm64: dts: rockchip: Fix PCIe DT properties on rk3399 Greg Kroah-Hartman
2021-02-22 12:12 ` [PATCH 4.19 05/50] platform/x86: hp-wmi: Disable tablet-mode reporting by default Greg Kroah-Hartman
2021-02-22 12:12 ` [PATCH 4.19 06/50] ovl: perform vfs_getxattr() with mounter creds Greg Kroah-Hartman
2021-02-22 12:12 ` [PATCH 4.19 07/50] cap: fix conversions on getxattr Greg Kroah-Hartman
2021-02-22 12:12 ` [PATCH 4.19 08/50] ovl: skip getxattr of security labels Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 09/50] drm/amd/display: Fix dc_sink kref count in emulated_link_detect Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 10/50] drm/amd/display: Free atomic state after drm_atomic_commit Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 11/50] riscv: virt_addr_valid must check the address belongs to linear mapping Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 12/50] bfq-iosched: Revert "bfq: Fix computation of shallow depth" Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 13/50] ARM: dts: lpc32xx: Revert set default clock rate of HCLK PLL Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 14/50] ARM: ensure the signal page contains defined contents Greg Kroah-Hartman
2021-02-22 12:13 ` Greg Kroah-Hartman [this message]
2021-02-22 12:13 ` [PATCH 4.19 16/50] mt76: dma: fix a possible memory leak in mt76_add_fragment() Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 17/50] bpf: Check for integer overflow when using roundup_pow_of_two() Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 18/50] netfilter: xt_recent: Fix attempt to update deleted entry Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 19/50] netfilter: flowtable: fix tcp and udp header checksum update Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 20/50] xen/netback: avoid race in xenvif_rx_ring_slots_available() Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 21/50] net: stmmac: set TxQ mode back to DCB after disabling CBS Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 22/50] netfilter: conntrack: skip identical origin tuple in same zone only Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 23/50] net: hns3: add a check for queue_id in hclge_reset_vf_queue() Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 24/50] firmware_loader: align .builtin_fw to 8 Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 25/50] i2c: stm32f7: fix configuration of the digital filter Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 26/50] h8300: fix PREEMPTION build, TI_PRE_COUNT undefined Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 27/50] usb: dwc3: ulpi: fix checkpatch warning Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 28/50] usb: dwc3: ulpi: Replace CPU-based busyloop with Protocol-based one Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 29/50] net: fix iteration for sctp transport seq_files Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 30/50] net/vmw_vsock: improve locking in vsock_connect_timeout() Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 31/50] net: watchdog: hold device global xmit lock during tx disable Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 32/50] vsock/virtio: update credit only if socket is not closed Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 33/50] vsock: fix locking in vsock_shutdown() Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 34/50] net/rds: restrict iovecs length for RDS_CMSG_RDMA_ARGS Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 35/50] net/qrtr: restrict user-controlled length in qrtr_tun_write_iter() Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 36/50] ovl: expand warning in ovl_d_real() Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 37/50] x86/build: Disable CET instrumentation in the kernel for 32-bit too Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 38/50] KVM: SEV: fix double locking due to incorrect backport Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 39/50] net: qrtr: Fix port ID for control messages Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 40/50] Xen/x86: dont bail early from clear_foreign_p2m_mapping() Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 41/50] Xen/x86: also check kernel mapping in set_foreign_p2m_mapping() Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 42/50] Xen/gntdev: correct dev_bus_addr handling in gntdev_map_grant_pages() Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 43/50] Xen/gntdev: correct error checking " Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 44/50] xen/arm: dont ignore return errors from set_phys_to_machine Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 45/50] xen-blkback: dont "handle" error by BUG() Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 46/50] xen-netback: " Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 47/50] xen-scsiback: " Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 48/50] xen-blkback: fix error handling in xen_blkbk_map() Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 49/50] scsi: qla2xxx: Fix crash during driver load on big endian machines Greg Kroah-Hartman
2021-02-22 12:13 ` [PATCH 4.19 50/50] kvm: check tlbs_dirty directly Greg Kroah-Hartman
2021-02-22 18:40 ` [PATCH 4.19 00/50] 4.19.177-rc1 review Pavel Machek
2021-02-22 21:28 ` Guenter Roeck
2021-02-22 21:49 ` Igor
2021-02-23 10:10 ` Naresh Kamboju
2021-02-23 21:17 ` Shuah Khan

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=20210222121022.452888385@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=giancarlo.ferrari89@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rmk+kernel@armlinux.org.uk \
    --cc=sashal@kernel.org \
    --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

LKML Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/lkml/0 lkml/git/0.git
	git clone --mirror https://lore.kernel.org/lkml/1 lkml/git/1.git
	git clone --mirror https://lore.kernel.org/lkml/2 lkml/git/2.git
	git clone --mirror https://lore.kernel.org/lkml/3 lkml/git/3.git
	git clone --mirror https://lore.kernel.org/lkml/4 lkml/git/4.git
	git clone --mirror https://lore.kernel.org/lkml/5 lkml/git/5.git
	git clone --mirror https://lore.kernel.org/lkml/6 lkml/git/6.git
	git clone --mirror https://lore.kernel.org/lkml/7 lkml/git/7.git
	git clone --mirror https://lore.kernel.org/lkml/8 lkml/git/8.git
	git clone --mirror https://lore.kernel.org/lkml/9 lkml/git/9.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 lkml lkml/ https://lore.kernel.org/lkml \
		linux-kernel@vger.kernel.org
	public-inbox-index lkml

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-kernel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git