Commit 66242ef2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull s390 fixes from Vasily Gorbik:

 - remove unused empty CPU alternatives header file

 - fix recently and erroneously removed exception handling when loading
   an invalid floating point register

 - ptdump fixes to reflect the recent changes due to the uncoupling of
   physical vs virtual kernel address spaces

 - changes to avoid the unnecessary splitting of large pages in kernel
   mappings

 - add the missing MODULE_DESCRIPTION for the CIO modules

* tag 's390-6.11-3' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390: Keep inittext section writable
  s390/vmlinux.lds.S: Move ro_after_init section behind rodata section
  s390/mm: Get rid of RELOC_HIDE()
  s390/mm/ptdump: Improve sorting of markers
  s390/mm/ptdump: Add support for relocated lowcore mapping
  s390/mm/ptdump: Fix handling of identity mapping area
  s390/cio: Add missing MODULE_DESCRIPTION() macros
  s390/alternatives: Remove unused empty header file
  s390/fpu: Re-add exception handling in load_fpu_state()
parents 29ccb40f 33bd8d15
Loading
Loading
Loading
Loading

arch/s390/kernel/alternative.h

deleted100644 → 0
+0 −0

Empty file deleted.

+1 −1
Original line number Diff line number Diff line
@@ -113,7 +113,7 @@ void load_fpu_state(struct fpu *state, int flags)
	int mask;

	if (flags & KERNEL_FPC)
		fpu_lfpc(&state->fpc);
		fpu_lfpc_safe(&state->fpc);
	if (!cpu_has_vx()) {
		if (flags & KERNEL_VXR_V0V7)
			load_fp_regs_vx(state->vxrs);
+9 −8
Original line number Diff line number Diff line
@@ -59,14 +59,6 @@ SECTIONS
	} :text = 0x0700

	RO_DATA(PAGE_SIZE)
	.data.rel.ro : {
		*(.data.rel.ro .data.rel.ro.*)
	}
	.got : {
		__got_start = .;
		*(.got)
		__got_end = .;
	}

	. = ALIGN(PAGE_SIZE);
	_sdata = .;		/* Start of data section */
@@ -80,6 +72,15 @@ SECTIONS
	. = ALIGN(PAGE_SIZE);
	__end_ro_after_init = .;

	.data.rel.ro : {
		*(.data.rel.ro .data.rel.ro.*)
	}
	.got : {
		__got_start = .;
		*(.got)
		__got_end = .;
	}

	RW_DATA(0x100, PAGE_SIZE, THREAD_SIZE)
	.data.rel : {
		*(.data.rel*)
+79 −61
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
#include <linux/ptdump.h>
#include <linux/seq_file.h>
#include <linux/debugfs.h>
#include <linux/sort.h>
#include <linux/mm.h>
#include <linux/kfence.h>
#include <linux/kasan.h>
@@ -15,13 +16,15 @@
static unsigned long max_addr;

struct addr_marker {
	int is_start;
	unsigned long start_address;
	const char *name;
};

enum address_markers_idx {
	IDENTITY_BEFORE_NR = 0,
	IDENTITY_BEFORE_END_NR,
	KVA_NR = 0,
	LOWCORE_START_NR,
	LOWCORE_END_NR,
	AMODE31_START_NR,
	AMODE31_END_NR,
	KERNEL_START_NR,
@@ -30,8 +33,8 @@ enum address_markers_idx {
	KFENCE_START_NR,
	KFENCE_END_NR,
#endif
	IDENTITY_AFTER_NR,
	IDENTITY_AFTER_END_NR,
	IDENTITY_START_NR,
	IDENTITY_END_NR,
	VMEMMAP_NR,
	VMEMMAP_END_NR,
	VMALLOC_NR,
@@ -59,43 +62,44 @@ enum address_markers_idx {
};

static struct addr_marker address_markers[] = {
	[IDENTITY_BEFORE_NR]	= {0, "Identity Mapping Start"},
	[IDENTITY_BEFORE_END_NR] = {(unsigned long)_stext, "Identity Mapping End"},
	[AMODE31_START_NR]	= {0, "Amode31 Area Start"},
	[AMODE31_END_NR]	= {0, "Amode31 Area End"},
	[KERNEL_START_NR]	= {(unsigned long)_stext, "Kernel Image Start"},
	[KERNEL_END_NR]		= {(unsigned long)_end, "Kernel Image End"},
	[KVA_NR]		= {0, 0, "Kernel Virtual Address Space"},
	[LOWCORE_START_NR]	= {1, 0, "Lowcore Start"},
	[LOWCORE_END_NR]	= {0, 0, "Lowcore End"},
	[IDENTITY_START_NR]	= {1, 0, "Identity Mapping Start"},
	[IDENTITY_END_NR]	= {0, 0, "Identity Mapping End"},
	[AMODE31_START_NR]	= {1, 0, "Amode31 Area Start"},
	[AMODE31_END_NR]	= {0, 0, "Amode31 Area End"},
	[KERNEL_START_NR]	= {1, (unsigned long)_stext, "Kernel Image Start"},
	[KERNEL_END_NR]		= {0, (unsigned long)_end, "Kernel Image End"},
#ifdef CONFIG_KFENCE
	[KFENCE_START_NR]	= {0, "KFence Pool Start"},
	[KFENCE_END_NR]		= {0, "KFence Pool End"},
	[KFENCE_START_NR]	= {1, 0, "KFence Pool Start"},
	[KFENCE_END_NR]		= {0, 0, "KFence Pool End"},
#endif
	[IDENTITY_AFTER_NR]	= {(unsigned long)_end, "Identity Mapping Start"},
	[IDENTITY_AFTER_END_NR]	= {0, "Identity Mapping End"},
	[VMEMMAP_NR]		= {0, "vmemmap Area Start"},
	[VMEMMAP_END_NR]	= {0, "vmemmap Area End"},
	[VMALLOC_NR]		= {0, "vmalloc Area Start"},
	[VMALLOC_END_NR]	= {0, "vmalloc Area End"},
	[VMEMMAP_NR]		= {1, 0, "vmemmap Area Start"},
	[VMEMMAP_END_NR]	= {0, 0, "vmemmap Area End"},
	[VMALLOC_NR]		= {1, 0, "vmalloc Area Start"},
	[VMALLOC_END_NR]	= {0, 0, "vmalloc Area End"},
#ifdef CONFIG_KMSAN
	[KMSAN_VMALLOC_SHADOW_START_NR]	= {0, "Kmsan vmalloc Shadow Start"},
	[KMSAN_VMALLOC_SHADOW_END_NR]	= {0, "Kmsan vmalloc Shadow End"},
	[KMSAN_VMALLOC_ORIGIN_START_NR]	= {0, "Kmsan vmalloc Origins Start"},
	[KMSAN_VMALLOC_ORIGIN_END_NR]	= {0, "Kmsan vmalloc Origins End"},
	[KMSAN_MODULES_SHADOW_START_NR]	= {0, "Kmsan Modules Shadow Start"},
	[KMSAN_MODULES_SHADOW_END_NR]	= {0, "Kmsan Modules Shadow End"},
	[KMSAN_MODULES_ORIGIN_START_NR]	= {0, "Kmsan Modules Origins Start"},
	[KMSAN_MODULES_ORIGIN_END_NR]	= {0, "Kmsan Modules Origins End"},
	[KMSAN_VMALLOC_SHADOW_START_NR]	= {1, 0, "Kmsan vmalloc Shadow Start"},
	[KMSAN_VMALLOC_SHADOW_END_NR]	= {0, 0, "Kmsan vmalloc Shadow End"},
	[KMSAN_VMALLOC_ORIGIN_START_NR]	= {1, 0, "Kmsan vmalloc Origins Start"},
	[KMSAN_VMALLOC_ORIGIN_END_NR]	= {0, 0, "Kmsan vmalloc Origins End"},
	[KMSAN_MODULES_SHADOW_START_NR]	= {1, 0, "Kmsan Modules Shadow Start"},
	[KMSAN_MODULES_SHADOW_END_NR]	= {0, 0, "Kmsan Modules Shadow End"},
	[KMSAN_MODULES_ORIGIN_START_NR]	= {1, 0, "Kmsan Modules Origins Start"},
	[KMSAN_MODULES_ORIGIN_END_NR]	= {0, 0, "Kmsan Modules Origins End"},
#endif
	[MODULES_NR]		= {0, "Modules Area Start"},
	[MODULES_END_NR]	= {0, "Modules Area End"},
	[ABS_LOWCORE_NR]	= {0, "Lowcore Area Start"},
	[ABS_LOWCORE_END_NR]	= {0, "Lowcore Area End"},
	[MEMCPY_REAL_NR]	= {0, "Real Memory Copy Area Start"},
	[MEMCPY_REAL_END_NR]	= {0, "Real Memory Copy Area End"},
	[MODULES_NR]		= {1, 0, "Modules Area Start"},
	[MODULES_END_NR]	= {0, 0, "Modules Area End"},
	[ABS_LOWCORE_NR]	= {1, 0, "Lowcore Area Start"},
	[ABS_LOWCORE_END_NR]	= {0, 0, "Lowcore Area End"},
	[MEMCPY_REAL_NR]	= {1, 0, "Real Memory Copy Area Start"},
	[MEMCPY_REAL_END_NR]	= {0, 0, "Real Memory Copy Area End"},
#ifdef CONFIG_KASAN
	[KASAN_SHADOW_START_NR]	= {KASAN_SHADOW_START, "Kasan Shadow Start"},
	[KASAN_SHADOW_END_NR]	= {KASAN_SHADOW_END, "Kasan Shadow End"},
	[KASAN_SHADOW_START_NR]	= {1, KASAN_SHADOW_START, "Kasan Shadow Start"},
	[KASAN_SHADOW_END_NR]	= {0, KASAN_SHADOW_END, "Kasan Shadow End"},
#endif
	{ -1, NULL }
	{1, -1UL, NULL}
};

struct pg_state {
@@ -163,6 +167,19 @@ static void note_prot_wx(struct pg_state *st, unsigned long addr)
	st->wx_pages += (addr - st->start_address) / PAGE_SIZE;
}

static void note_page_update_state(struct pg_state *st, unsigned long addr, unsigned int prot, int level)
{
	struct seq_file *m = st->seq;

	while (addr >= st->marker[1].start_address) {
		st->marker++;
		pt_dump_seq_printf(m, "---[ %s ]---\n", st->marker->name);
	}
	st->start_address = addr;
	st->current_prot = prot;
	st->level = level;
}

static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level, u64 val)
{
	int width = sizeof(unsigned long) * 2;
@@ -186,9 +203,7 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
		addr = max_addr;
	if (st->level == -1) {
		pt_dump_seq_printf(m, "---[ %s ]---\n", st->marker->name);
		st->start_address = addr;
		st->current_prot = prot;
		st->level = level;
		note_page_update_state(st, addr, prot, level);
	} else if (prot != st->current_prot || level != st->level ||
		   addr >= st->marker[1].start_address) {
		note_prot_wx(st, addr);
@@ -202,13 +217,7 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
		}
		pt_dump_seq_printf(m, "%9lu%c ", delta, *unit);
		print_prot(m, st->current_prot, st->level);
		while (addr >= st->marker[1].start_address) {
			st->marker++;
			pt_dump_seq_printf(m, "---[ %s ]---\n", st->marker->name);
		}
		st->start_address = addr;
		st->current_prot = prot;
		st->level = level;
		note_page_update_state(st, addr, prot, level);
	}
}

@@ -280,22 +289,25 @@ static int ptdump_show(struct seq_file *m, void *v)
DEFINE_SHOW_ATTRIBUTE(ptdump);
#endif /* CONFIG_PTDUMP_DEBUGFS */

/*
 * Heapsort from lib/sort.c is not a stable sorting algorithm, do a simple
 * insertion sort to preserve the original order of markers with the same
 * start address.
 */
static void sort_address_markers(void)
static int ptdump_cmp(const void *a, const void *b)
{
	struct addr_marker tmp;
	int i, j;
	const struct addr_marker *ama = a;
	const struct addr_marker *amb = b;

	for (i = 1; i < ARRAY_SIZE(address_markers) - 1; i++) {
		tmp = address_markers[i];
		for (j = i - 1; j >= 0 && address_markers[j].start_address > tmp.start_address; j--)
			address_markers[j + 1] = address_markers[j];
		address_markers[j + 1] = tmp;
	}
	if (ama->start_address > amb->start_address)
		return 1;
	if (ama->start_address < amb->start_address)
		return -1;
	/*
	 * If the start addresses of two markers are identical consider the
	 * marker which defines the start of an area higher than the one which
	 * defines the end of an area. This keeps pairs of markers sorted.
	 */
	if (ama->is_start)
		return 1;
	if (amb->is_start)
		return -1;
	return 0;
}

static int pt_dump_init(void)
@@ -303,6 +315,8 @@ static int pt_dump_init(void)
#ifdef CONFIG_KFENCE
	unsigned long kfence_start = (unsigned long)__kfence_pool;
#endif
	unsigned long lowcore = (unsigned long)get_lowcore();

	/*
	 * Figure out the maximum virtual address being accessible with the
	 * kernel ASCE. We need this to keep the page table walker functions
@@ -310,7 +324,10 @@ static int pt_dump_init(void)
	 */
	max_addr = (get_lowcore()->kernel_asce.val & _REGION_ENTRY_TYPE_MASK) >> 2;
	max_addr = 1UL << (max_addr * 11 + 31);
	address_markers[IDENTITY_AFTER_END_NR].start_address = ident_map_size;
	address_markers[LOWCORE_START_NR].start_address = lowcore;
	address_markers[LOWCORE_END_NR].start_address = lowcore + sizeof(struct lowcore);
	address_markers[IDENTITY_START_NR].start_address = __identity_base;
	address_markers[IDENTITY_END_NR].start_address = __identity_base + ident_map_size;
	address_markers[AMODE31_START_NR].start_address = (unsigned long)__samode31;
	address_markers[AMODE31_END_NR].start_address = (unsigned long)__eamode31;
	address_markers[MODULES_NR].start_address = MODULES_VADDR;
@@ -337,7 +354,8 @@ static int pt_dump_init(void)
	address_markers[KMSAN_MODULES_ORIGIN_START_NR].start_address = KMSAN_MODULES_ORIGIN_START;
	address_markers[KMSAN_MODULES_ORIGIN_END_NR].start_address = KMSAN_MODULES_ORIGIN_END;
#endif
	sort_address_markers();
	sort(address_markers, ARRAY_SIZE(address_markers) - 1,
	     sizeof(address_markers[0]), ptdump_cmp, NULL);
#ifdef CONFIG_PTDUMP_DEBUGFS
	debugfs_create_file("kernel_page_tables", 0400, NULL, NULL, &ptdump_fops);
#endif /* CONFIG_PTDUMP_DEBUGFS */
+2 −7
Original line number Diff line number Diff line
@@ -108,6 +108,8 @@ void mark_rodata_ro(void)
{
	unsigned long size = __end_ro_after_init - __start_ro_after_init;

	if (MACHINE_HAS_NX)
		system_ctl_set_bit(0, CR0_INSTRUCTION_EXEC_PROTECTION_BIT);
	__set_memory_ro(__start_ro_after_init, __end_ro_after_init);
	pr_info("Write protected read-only-after-init data: %luk\n", size >> 10);
}
@@ -170,13 +172,6 @@ void __init mem_init(void)
	setup_zero_pages();	/* Setup zeroed pages. */
}

void free_initmem(void)
{
	set_memory_rwnx((unsigned long)_sinittext,
			(unsigned long)(_einittext - _sinittext) >> PAGE_SHIFT);
	free_initmem_default(POISON_FREE_INITMEM);
}

unsigned long memory_block_size_bytes(void)
{
	/*
Loading