Skip to contentSkip to conversation

Patch "arm64: hibernate: avoid potential TLB conflict" has been added to the 4.7-stable tree

PATCH [email protected] 1 participant 1 message Aug 18, 2016

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

arm64: hibernate: avoid potential TLB conflict

to the 4.7-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
arm64-hibernate-avoid-potential-tlb-conflict.patch
and it can be found in the queue-4.7 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From 0194e760f7d2f42adb5e1db31b27a4331dd89c2f Mon Sep 17 00:00:00 2001

From: Mark Rutland <[email protected]>
Date: Thu, 11 Aug 2016 14:11:05 +0100
Subject: arm64: hibernate: avoid potential TLB conflict

From: Mark Rutland <[email protected]>

commit 0194e760f7d2f42adb5e1db31b27a4331dd89c2f upstream.

In create_safe_exec_page we install a set of global mappings in TTBR0, then subsequently invalidate TLBs. While TTBR0 points at the zero page, and the TLBs should be free of stale global entries, we may have stale ASID-tagged entries (e.g. from the EFI runtime services mappings) for the same VAs. Per the ARM ARM these ASID-tagged entries may conflict with newly-allocated global entries, and we must follow a Break-Before-Make approach to avoid issues resulting from this.

This patch reworks create_safe_exec_page to invalidate TLBs while the zero page is still in place, ensuring that there are no potential conflicts when the new TTBR0 value is installed. As a single CPU is online while this code executes, we do not need to perform broadcast TLB maintenance, and can call local_flush_tlb_all(), which also subsumes some barriers. The remaining assembly is converted to use write_sysreg() and isb().

Other than this, we safely manipulate TTBRs in the hibernate dance. The code we install as part of the new TTBR0 mapping (the hibernated kernel's swsusp_arch_suspend_exit) installs a zero page into TTBR1, invalidates TLBs, then installs its preferred value. Upon being restored to the middle of swsusp_arch_suspend, the new image will call __cpu_suspend_exit, which will call cpu_uninstall_idmap, installing the zero page in TTBR0 and invalidating all TLB entries.

Fixes 82869ac57b5d ("arm64: kernel: Add support for hibernate/suspend-to-disk")
Cc Lorenzo Pieralisi <[email protected]>
Cc Will Deacon <[email protected]>
---
 arch/arm64/kernel/hibernate.c |   23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)
arch/arm64/kernel/hibernate.c +17 -6
@@ -35,6 +35,7 @@
 #include <asm/sections.h>
 #include <asm/smp.h>
 #include <asm/suspend.h>
+#include <asm/sysreg.h>
 #include <asm/virt.h>
 
 /*
@@ -217,12 +218,22 @@ static int create_safe_exec_page(void *s
 	set_pte(pte, __pte(virt_to_phys((void *)dst) |
 			 pgprot_val(PAGE_KERNEL_EXEC)));
 
-	/* Load our new page tables */
-	asm volatile("msr	ttbr0_el1, %0;"
-		     "isb;"
-		     "tlbi	vmalle1is;"
-		     "dsb	ish;"
-		     "isb" : : "r"(virt_to_phys(pgd)));
+	/*
+	 * Load our new page tables. A strict BBM approach requires that we
+	 * ensure that TLBs are free of any entries that may overlap with the
+	 * global mappings we are about to install.
+	 *
+	 * For a real hibernate/resume cycle TTBR0 currently points to a zero
+	 * page, but TLBs may contain stale ASID-tagged entries (e.g. for EFI
+	 * runtime services), while for a userspace-driven test_resume cycle it
+	 * points to userspace page tables (and we must point it at a zero page
+	 * ourselves). Elsewhere we only (un)install the idmap with preemption
+	 * disabled, so T0SZ should be as required regardless.
+	 */
+	cpu_set_reserved_ttbr0();
+	local_flush_tlb_all();
+	write_sysreg(virt_to_phys(pgd), ttbr0_el1);
+	isb();
 
 	*phys_dst_addr = virt_to_phys((void *)dst);
 

Patches currently in stable-queue which might be from [email protected] are

queue-4.7/arm64-hibernate-handle-allocation-failures.patch queue-4.7/arm64-only-select-arm64_module_plts-if-modules-y.patch queue-4.7/arm64-hibernate-avoid-potential-tlb-conflict.patch queue-4.7/arm64-debug-unmask-pstate.d-earlier.patch queue-4.7/arm64-fix-incorrect-per-cpu-usage-for-boot-cpu.patch queue-4.7/arm64-honor-nosmp-kernel-command-line-option.patch queue-4.7/arm64-mm-avoid-fdt_check_header-before-the-fdt-is-fully-mapped.patch