Merge tag 's390-5.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Vasily Gorbik: - Add support for IBM z15 machines. - Add SHA3 and CCA AES cipher key support in zcrypt and pkey refactoring. - Move to arch_stack_walk infrastructure for the stack unwinder. - Various kasan fixes and improvements. - Various command line parsing fixes. - Improve decompressor phase debuggability. - Lift no bss usage restriction for the early code. - Use refcount_t for reference counters for couple of places in mm code. - Logging improvements and return code fix in vfio-ccw code. - Couple of zpci fixes and minor refactoring. - Remove some outdated documentation. - Fix secure boot detection. - Other various minor code clean ups. * tag 's390-5.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (48 commits) s390: remove pointless drivers-y in drivers/s390/Makefile s390/cpum_sf: Fix line length and format string s390/pci: fix MSI message data s390: add support for IBM z15 machines s390/crypto: Support for SHA3 via CPACF (MSA6) s390/startup: add pgm check info printing s390/crypto: xts-aes-s390 fix extra run-time crypto self tests finding vfio-ccw: fix error return code in vfio_ccw_sch_init() s390: vfio-ap: fix warning reset not completed s390/base: remove unused s390_base_mcck_handler s390/sclp: Fix bit checked for has_sipl s390/zcrypt: fix wrong handling of cca cipher keygenflags s390/kasan: add kdump support s390/setup: avoid using strncmp with hardcoded length s390/sclp: avoid using strncmp with hardcoded length s390/module: avoid using strncmp with hardcoded length s390/pci: avoid using strncmp with hardcoded length s390/kaslr: reserve memory for kasan usage s390/mem_detect: provide single get_mem_detect_end s390/cmma: reuse kstrtobool for option value parsing ...
This commit is contained in:
@@ -36,7 +36,7 @@ CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char
|
||||
|
||||
obj-y := head.o als.o startup.o mem_detect.o ipl_parm.o ipl_report.o
|
||||
obj-y += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o
|
||||
obj-y += version.o ctype.o text_dma.o
|
||||
obj-y += version.o pgm_check_info.o ctype.o text_dma.o
|
||||
obj-$(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) += uv.o
|
||||
obj-$(CONFIG_RELOCATABLE) += machine_kexec_reloc.o
|
||||
obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
|
||||
|
@@ -10,6 +10,7 @@ void parse_boot_command_line(void);
|
||||
void setup_memory_end(void);
|
||||
void verify_facilities(void);
|
||||
void print_missing_facilities(void);
|
||||
void print_pgm_check_info(void);
|
||||
unsigned long get_random_base(unsigned long safe_addr);
|
||||
|
||||
extern int kaslr_enabled;
|
||||
|
3
arch/s390/boot/compressed/.gitignore
vendored
3
arch/s390/boot/compressed/.gitignore
vendored
@@ -1,5 +1,2 @@
|
||||
sizes.h
|
||||
vmlinux
|
||||
vmlinux.lds
|
||||
vmlinux.scr.lds
|
||||
vmlinux.bin.full
|
||||
|
@@ -37,9 +37,9 @@ SECTIONS
|
||||
* .dma section for code, data, ex_table that need to stay below 2 GB,
|
||||
* even when the kernel is relocate: above 2 GB.
|
||||
*/
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
_sdma = .;
|
||||
.dma.text : {
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
_stext_dma = .;
|
||||
*(.dma.text)
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
@@ -52,6 +52,7 @@ SECTIONS
|
||||
_stop_dma_ex_table = .;
|
||||
}
|
||||
.dma.data : { *(.dma.data) }
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
_edma = .;
|
||||
|
||||
BOOT_DATA
|
||||
|
@@ -60,8 +60,10 @@ __HEAD
|
||||
.long 0x02000690,0x60000050
|
||||
.long 0x020006e0,0x20000050
|
||||
|
||||
.org 0x1a0
|
||||
.org __LC_RST_NEW_PSW # 0x1a0
|
||||
.quad 0,iplstart
|
||||
.org __LC_PGM_NEW_PSW # 0x1d0
|
||||
.quad 0x0000000180000000,startup_pgm_check_handler
|
||||
|
||||
.org 0x200
|
||||
|
||||
@@ -351,6 +353,34 @@ ENTRY(startup_kdump)
|
||||
|
||||
#include "head_kdump.S"
|
||||
|
||||
#
|
||||
# This program check is active immediately after kernel start
|
||||
# and until early_pgm_check_handler is set in kernel/early.c
|
||||
# It simply saves general/control registers and psw in
|
||||
# the save area and does disabled wait with a faulty address.
|
||||
#
|
||||
ENTRY(startup_pgm_check_handler)
|
||||
stmg %r0,%r15,__LC_SAVE_AREA_SYNC
|
||||
la %r1,4095
|
||||
stctg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r1)
|
||||
mvc __LC_GPREGS_SAVE_AREA-4095(128,%r1),__LC_SAVE_AREA_SYNC
|
||||
mvc __LC_PSW_SAVE_AREA-4095(16,%r1),__LC_PGM_OLD_PSW
|
||||
mvc __LC_RETURN_PSW(16),__LC_PGM_OLD_PSW
|
||||
ni __LC_RETURN_PSW,0xfc # remove IO and EX bits
|
||||
ni __LC_RETURN_PSW+1,0xfb # remove MCHK bit
|
||||
oi __LC_RETURN_PSW+1,0x2 # set wait state bit
|
||||
larl %r2,.Lold_psw_disabled_wait
|
||||
stg %r2,__LC_PGM_NEW_PSW+8
|
||||
l %r15,.Ldump_info_stack-.Lold_psw_disabled_wait(%r2)
|
||||
brasl %r14,print_pgm_check_info
|
||||
.Lold_psw_disabled_wait:
|
||||
la %r1,4095
|
||||
lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)
|
||||
lpswe __LC_RETURN_PSW # disabled wait
|
||||
.Ldump_info_stack:
|
||||
.long 0x5000 + PAGE_SIZE - STACK_FRAME_OVERHEAD
|
||||
ENDPROC(startup_pgm_check_handler)
|
||||
|
||||
#
|
||||
# params at 10400 (setup.h)
|
||||
# Must be keept in sync with struct parmarea in setup.h
|
||||
|
@@ -7,6 +7,7 @@
|
||||
#include <asm/sections.h>
|
||||
#include <asm/boot_data.h>
|
||||
#include <asm/facility.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/uv.h>
|
||||
#include "boot.h"
|
||||
|
||||
@@ -14,6 +15,7 @@ char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
|
||||
struct ipl_parameter_block __bootdata_preserved(ipl_block);
|
||||
int __bootdata_preserved(ipl_block_valid);
|
||||
|
||||
unsigned long __bootdata(vmalloc_size) = VMALLOC_DEFAULT_SIZE;
|
||||
unsigned long __bootdata(memory_end);
|
||||
int __bootdata(memory_end_set);
|
||||
int __bootdata(noexec_disabled);
|
||||
@@ -219,18 +221,21 @@ void parse_boot_command_line(void)
|
||||
while (*args) {
|
||||
args = next_arg(args, ¶m, &val);
|
||||
|
||||
if (!strcmp(param, "mem")) {
|
||||
memory_end = memparse(val, NULL);
|
||||
if (!strcmp(param, "mem") && val) {
|
||||
memory_end = round_down(memparse(val, NULL), PAGE_SIZE);
|
||||
memory_end_set = 1;
|
||||
}
|
||||
|
||||
if (!strcmp(param, "vmalloc") && val)
|
||||
vmalloc_size = round_up(memparse(val, NULL), PAGE_SIZE);
|
||||
|
||||
if (!strcmp(param, "noexec")) {
|
||||
rc = kstrtobool(val, &enabled);
|
||||
if (!rc && !enabled)
|
||||
noexec_disabled = 1;
|
||||
}
|
||||
|
||||
if (!strcmp(param, "facilities"))
|
||||
if (!strcmp(param, "facilities") && val)
|
||||
modify_fac_list(val);
|
||||
|
||||
if (!strcmp(param, "nokaslr"))
|
||||
|
@@ -3,6 +3,7 @@
|
||||
* Copyright IBM Corp. 2019
|
||||
*/
|
||||
#include <asm/mem_detect.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/cpacf.h>
|
||||
#include <asm/timex.h>
|
||||
#include <asm/sclp.h>
|
||||
@@ -90,8 +91,10 @@ static unsigned long get_random(unsigned long limit)
|
||||
|
||||
unsigned long get_random_base(unsigned long safe_addr)
|
||||
{
|
||||
unsigned long memory_limit = memory_end_set ? memory_end : 0;
|
||||
unsigned long base, start, end, kernel_size;
|
||||
unsigned long block_sum, offset;
|
||||
unsigned long kasan_needs;
|
||||
int i;
|
||||
|
||||
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && INITRD_START && INITRD_SIZE) {
|
||||
@@ -100,14 +103,36 @@ unsigned long get_random_base(unsigned long safe_addr)
|
||||
}
|
||||
safe_addr = ALIGN(safe_addr, THREAD_SIZE);
|
||||
|
||||
if ((IS_ENABLED(CONFIG_KASAN))) {
|
||||
/*
|
||||
* Estimate kasan memory requirements, which it will reserve
|
||||
* at the very end of available physical memory. To estimate
|
||||
* that, we take into account that kasan would require
|
||||
* 1/8 of available physical memory (for shadow memory) +
|
||||
* creating page tables for the whole memory + shadow memory
|
||||
* region (1 + 1/8). To keep page tables estimates simple take
|
||||
* the double of combined ptes size.
|
||||
*/
|
||||
memory_limit = get_mem_detect_end();
|
||||
if (memory_end_set && memory_limit > memory_end)
|
||||
memory_limit = memory_end;
|
||||
|
||||
/* for shadow memory */
|
||||
kasan_needs = memory_limit / 8;
|
||||
/* for paging structures */
|
||||
kasan_needs += (memory_limit + kasan_needs) / PAGE_SIZE /
|
||||
_PAGE_ENTRIES * _PAGE_TABLE_SIZE * 2;
|
||||
memory_limit -= kasan_needs;
|
||||
}
|
||||
|
||||
kernel_size = vmlinux.image_size + vmlinux.bss_size;
|
||||
block_sum = 0;
|
||||
for_each_mem_detect_block(i, &start, &end) {
|
||||
if (memory_end_set) {
|
||||
if (start >= memory_end)
|
||||
if (memory_limit) {
|
||||
if (start >= memory_limit)
|
||||
break;
|
||||
if (end > memory_end)
|
||||
end = memory_end;
|
||||
if (end > memory_limit)
|
||||
end = memory_limit;
|
||||
}
|
||||
if (end - start < kernel_size)
|
||||
continue;
|
||||
@@ -125,11 +150,11 @@ unsigned long get_random_base(unsigned long safe_addr)
|
||||
base = safe_addr;
|
||||
block_sum = offset = 0;
|
||||
for_each_mem_detect_block(i, &start, &end) {
|
||||
if (memory_end_set) {
|
||||
if (start >= memory_end)
|
||||
if (memory_limit) {
|
||||
if (start >= memory_limit)
|
||||
break;
|
||||
if (end > memory_end)
|
||||
end = memory_end;
|
||||
if (end > memory_limit)
|
||||
end = memory_limit;
|
||||
}
|
||||
if (end - start < kernel_size)
|
||||
continue;
|
||||
|
@@ -63,13 +63,6 @@ void add_mem_detect_block(u64 start, u64 end)
|
||||
mem_detect.count++;
|
||||
}
|
||||
|
||||
static unsigned long get_mem_detect_end(void)
|
||||
{
|
||||
if (mem_detect.count)
|
||||
return __get_mem_detect_block_ptr(mem_detect.count - 1)->end;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __diag260(unsigned long rx1, unsigned long rx2)
|
||||
{
|
||||
register unsigned long _rx1 asm("2") = rx1;
|
||||
|
90
arch/s390/boot/pgm_check_info.c
Normal file
90
arch/s390/boot/pgm_check_info.c
Normal file
@@ -0,0 +1,90 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <asm/lowcore.h>
|
||||
#include <asm/sclp.h>
|
||||
#include "boot.h"
|
||||
|
||||
const char hex_asc[] = "0123456789abcdef";
|
||||
|
||||
#define add_val_as_hex(dst, val) \
|
||||
__add_val_as_hex(dst, (const unsigned char *)&val, sizeof(val))
|
||||
|
||||
static char *__add_val_as_hex(char *dst, const unsigned char *src, size_t count)
|
||||
{
|
||||
while (count--)
|
||||
dst = hex_byte_pack(dst, *src++);
|
||||
return dst;
|
||||
}
|
||||
|
||||
static char *add_str(char *dst, char *src)
|
||||
{
|
||||
strcpy(dst, src);
|
||||
return dst + strlen(dst);
|
||||
}
|
||||
|
||||
void print_pgm_check_info(void)
|
||||
{
|
||||
struct psw_bits *psw = &psw_bits(S390_lowcore.psw_save_area);
|
||||
unsigned short ilc = S390_lowcore.pgm_ilc >> 1;
|
||||
char buf[256];
|
||||
int row, col;
|
||||
char *p;
|
||||
|
||||
add_str(buf, "Linux version ");
|
||||
strlcat(buf, kernel_version, sizeof(buf));
|
||||
sclp_early_printk(buf);
|
||||
|
||||
p = add_str(buf, "Kernel fault: interruption code ");
|
||||
p = add_val_as_hex(buf + strlen(buf), S390_lowcore.pgm_code);
|
||||
p = add_str(p, " ilc:");
|
||||
*p++ = hex_asc_lo(ilc);
|
||||
add_str(p, "\n");
|
||||
sclp_early_printk(buf);
|
||||
|
||||
p = add_str(buf, "PSW : ");
|
||||
p = add_val_as_hex(p, S390_lowcore.psw_save_area.mask);
|
||||
p = add_str(p, " ");
|
||||
p = add_val_as_hex(p, S390_lowcore.psw_save_area.addr);
|
||||
add_str(p, "\n");
|
||||
sclp_early_printk(buf);
|
||||
|
||||
p = add_str(buf, " R:");
|
||||
*p++ = hex_asc_lo(psw->per);
|
||||
p = add_str(p, " T:");
|
||||
*p++ = hex_asc_lo(psw->dat);
|
||||
p = add_str(p, " IO:");
|
||||
*p++ = hex_asc_lo(psw->io);
|
||||
p = add_str(p, " EX:");
|
||||
*p++ = hex_asc_lo(psw->ext);
|
||||
p = add_str(p, " Key:");
|
||||
*p++ = hex_asc_lo(psw->key);
|
||||
p = add_str(p, " M:");
|
||||
*p++ = hex_asc_lo(psw->mcheck);
|
||||
p = add_str(p, " W:");
|
||||
*p++ = hex_asc_lo(psw->wait);
|
||||
p = add_str(p, " P:");
|
||||
*p++ = hex_asc_lo(psw->pstate);
|
||||
p = add_str(p, " AS:");
|
||||
*p++ = hex_asc_lo(psw->as);
|
||||
p = add_str(p, " CC:");
|
||||
*p++ = hex_asc_lo(psw->cc);
|
||||
p = add_str(p, " PM:");
|
||||
*p++ = hex_asc_lo(psw->pm);
|
||||
p = add_str(p, " RI:");
|
||||
*p++ = hex_asc_lo(psw->ri);
|
||||
p = add_str(p, " EA:");
|
||||
*p++ = hex_asc_lo(psw->eaba);
|
||||
add_str(p, "\n");
|
||||
sclp_early_printk(buf);
|
||||
|
||||
for (row = 0; row < 4; row++) {
|
||||
p = add_str(buf, row == 0 ? "GPRS:" : " ");
|
||||
for (col = 0; col < 4; col++) {
|
||||
p = add_str(p, " ");
|
||||
p = add_val_as_hex(p, S390_lowcore.gpregs_save_area[row * 4 + col]);
|
||||
}
|
||||
add_str(p, "\n");
|
||||
sclp_early_printk(buf);
|
||||
}
|
||||
}
|
@@ -112,6 +112,11 @@ static void handle_relocs(unsigned long offset)
|
||||
}
|
||||
}
|
||||
|
||||
static void clear_bss_section(void)
|
||||
{
|
||||
memset((void *)vmlinux.default_lma + vmlinux.image_size, 0, vmlinux.bss_size);
|
||||
}
|
||||
|
||||
void startup_kernel(void)
|
||||
{
|
||||
unsigned long random_lma;
|
||||
@@ -151,6 +156,7 @@ void startup_kernel(void)
|
||||
} else if (__kaslr_offset)
|
||||
memcpy((void *)vmlinux.default_lma, img, vmlinux.image_size);
|
||||
|
||||
clear_bss_section();
|
||||
copy_bootdata();
|
||||
if (IS_ENABLED(CONFIG_RELOCATABLE))
|
||||
handle_relocs(__kaslr_offset);
|
||||
|
Reference in New Issue
Block a user