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

Commit d58106c3 authored by Vasily Gorbik's avatar Vasily Gorbik Committed by Martin Schwidefsky
Browse files

s390/kasan: use noexec and large pages



To lower memory footprint and speed up kasan initialisation detect
EDAT availability and use large pages if possible. As we know how
much memory is needed for initialisation, another simplistic large
page allocator is introduced to avoid memory fragmentation.

Since facilities list is retrieved anyhow, detect noexec support and
adjust pages attributes. Handle noexec kernel option to avoid inconsistent
kasan shadow memory pages flags.

Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 793213a8
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ int __bootdata(early_ipl_block_valid);

unsigned long __bootdata(memory_end);
int __bootdata(memory_end_set);
int __bootdata(noexec_disabled);

static inline int __diag308(unsigned long subcode, void *addr)
{
@@ -145,8 +146,10 @@ void setup_boot_command_line(void)
static char command_line_buf[COMMAND_LINE_SIZE] __section(.data);
static void parse_mem_opt(void)
{
	char *args;
	char *param, *val;
	bool enabled;
	char *args;
	int rc;

	args = strcpy(command_line_buf, early_command_line);
	while (*args) {
@@ -156,6 +159,12 @@ static void parse_mem_opt(void)
			memory_end = memparse(val, NULL);
			memory_end_set = 1;
		}

		if (!strcmp(param, "noexec")) {
			rc = kstrtobool(val, &enabled);
			if (!rc && !enabled)
				noexec_disabled = 1;
		}
	}
}

+38 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
#include <linux/ctype.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include "../lib/string.c"

int strncmp(const char *cs, const char *ct, size_t count)
@@ -98,3 +99,40 @@ long simple_strtol(const char *cp, char **endp, unsigned int base)

	return simple_strtoull(cp, endp, base);
}

int kstrtobool(const char *s, bool *res)
{
	if (!s)
		return -EINVAL;

	switch (s[0]) {
	case 'y':
	case 'Y':
	case '1':
		*res = true;
		return 0;
	case 'n':
	case 'N':
	case '0':
		*res = false;
		return 0;
	case 'o':
	case 'O':
		switch (s[1]) {
		case 'n':
		case 'N':
			*res = true;
			return 0;
		case 'f':
		case 'F':
			*res = false;
			return 0;
		default:
			break;
		}
	default:
		break;
	}

	return -EINVAL;
}
+6 −0
Original line number Diff line number Diff line
@@ -468,6 +468,12 @@ static inline int is_module_addr(void *addr)
				 _SEGMENT_ENTRY_YOUNG |	\
				 _SEGMENT_ENTRY_PROTECT | \
				 _SEGMENT_ENTRY_NOEXEC)
#define SEGMENT_KERNEL_EXEC __pgprot(_SEGMENT_ENTRY |	\
				 _SEGMENT_ENTRY_LARGE |	\
				 _SEGMENT_ENTRY_READ |	\
				 _SEGMENT_ENTRY_WRITE | \
				 _SEGMENT_ENTRY_YOUNG |	\
				 _SEGMENT_ENTRY_DIRTY)

/*
 * Region3 entry (large page) protection definitions.
+1 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@
#define OLDMEM_SIZE	(*(unsigned long *)  (OLDMEM_SIZE_OFFSET))
#define COMMAND_LINE	((char *)	     (COMMAND_LINE_OFFSET))

extern int noexec_disabled;
extern int memory_end_set;
extern unsigned long memory_end;
extern unsigned long max_physmem_end;
+1 −0
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ char elf_platform[ELF_PLATFORM_SIZE];

unsigned long int_hwcap = 0;

int __bootdata(noexec_disabled);
int __bootdata(memory_end_set);
unsigned long __bootdata(memory_end);
unsigned long __bootdata(max_physmem_end);
Loading