Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ce3dc447 authored by Martin Schwidefsky's avatar Martin Schwidefsky
Browse files

s390: add support for virtually mapped kernel stacks



With virtually mapped kernel stacks the kernel stack overflow detection
is now fault based, every stack has a guard page in the vmalloc space.
The panic_stack is renamed to nodat_stack and is used for all function
that need to run without DAT, e.g. memcpy_real or do_start_kdump.

The main effect is a reduction in the kernel image size as with vmap
stacks the old style overflow checking that adds two instructions per
function is not needed anymore. Result from bloat-o-meter:

add/remove: 20/1 grow/shrink: 13/26854 up/down: 2198/-216240 (-214042)

In regard to performance the micro-benchmark for fork has a hit of a
few microseconds, allocating 4 pages in vmalloc space is more expensive
compare to an order-2 page allocation. But with real workload I could
not find a noticeable difference.

Acked-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent ff340d24
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -125,6 +125,7 @@ config S390
	select HAVE_ARCH_SOFT_DIRTY
	select HAVE_ARCH_SOFT_DIRTY
	select HAVE_ARCH_TRACEHOOK
	select HAVE_ARCH_TRACEHOOK
	select HAVE_ARCH_TRANSPARENT_HUGEPAGE
	select HAVE_ARCH_TRANSPARENT_HUGEPAGE
	select HAVE_ARCH_VMAP_STACK
	select HAVE_EBPF_JIT if PACK_STACK && HAVE_MARCH_Z196_FEATURES
	select HAVE_EBPF_JIT if PACK_STACK && HAVE_MARCH_Z196_FEATURES
	select HAVE_CMPXCHG_DOUBLE
	select HAVE_CMPXCHG_DOUBLE
	select HAVE_CMPXCHG_LOCAL
	select HAVE_CMPXCHG_LOCAL
@@ -649,6 +650,7 @@ config PACK_STACK


config CHECK_STACK
config CHECK_STACK
	def_bool y
	def_bool y
	depends on !VMAP_STACK
	prompt "Detect kernel stack overflow"
	prompt "Detect kernel stack overflow"
	help
	help
	  This option enables the compiler option -mstack-guard and
	  This option enables the compiler option -mstack-guard and
+2 −2
Original line number Original line Diff line number Diff line
@@ -102,9 +102,9 @@ struct lowcore {
	__u64	current_task;			/* 0x0338 */
	__u64	current_task;			/* 0x0338 */
	__u64	kernel_stack;			/* 0x0340 */
	__u64	kernel_stack;			/* 0x0340 */


	/* Interrupt, panic and restart stack. */
	/* Interrupt, DAT-off and restartstack. */
	__u64	async_stack;			/* 0x0348 */
	__u64	async_stack;			/* 0x0348 */
	__u64	panic_stack;			/* 0x0350 */
	__u64	nodat_stack;			/* 0x0350 */
	__u64	restart_stack;			/* 0x0358 */
	__u64	restart_stack;			/* 0x0358 */


	/* Restart function and parameter. */
	/* Restart function and parameter. */
+8 −0
Original line number Original line Diff line number Diff line
@@ -162,6 +162,14 @@ struct thread_struct {


typedef struct thread_struct thread_struct;
typedef struct thread_struct thread_struct;


/*
 * General size of a stack
 */
#define STACK_ORDER 2
#define STACK_SIZE (PAGE_SIZE << STACK_ORDER)
#define STACK_INIT_OFFSET \
	(STACK_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs))

/*
/*
 * Stack layout of a C stack frame.
 * Stack layout of a C stack frame.
 */
 */
+0 −3
Original line number Original line Diff line number Diff line
@@ -14,10 +14,7 @@
 * Size of kernel stack for each process
 * Size of kernel stack for each process
 */
 */
#define THREAD_SIZE_ORDER 2
#define THREAD_SIZE_ORDER 2
#define ASYNC_ORDER  2

#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
#define ASYNC_SIZE  (PAGE_SIZE << ASYNC_ORDER)


#ifndef __ASSEMBLY__
#ifndef __ASSEMBLY__
#include <asm/lowcore.h>
#include <asm/lowcore.h>
+1 −1
Original line number Original line Diff line number Diff line
@@ -159,7 +159,7 @@ int main(void)
	OFFSET(__LC_CURRENT, lowcore, current_task);
	OFFSET(__LC_CURRENT, lowcore, current_task);
	OFFSET(__LC_KERNEL_STACK, lowcore, kernel_stack);
	OFFSET(__LC_KERNEL_STACK, lowcore, kernel_stack);
	OFFSET(__LC_ASYNC_STACK, lowcore, async_stack);
	OFFSET(__LC_ASYNC_STACK, lowcore, async_stack);
	OFFSET(__LC_PANIC_STACK, lowcore, panic_stack);
	OFFSET(__LC_NODAT_STACK, lowcore, nodat_stack);
	OFFSET(__LC_RESTART_STACK, lowcore, restart_stack);
	OFFSET(__LC_RESTART_STACK, lowcore, restart_stack);
	OFFSET(__LC_RESTART_FN, lowcore, restart_fn);
	OFFSET(__LC_RESTART_FN, lowcore, restart_fn);
	OFFSET(__LC_RESTART_DATA, lowcore, restart_data);
	OFFSET(__LC_RESTART_DATA, lowcore, restart_data);
Loading