summaryrefslogtreecommitdiff
path: root/arch/s390/boot
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/boot')
-rw-r--r--arch/s390/boot/Makefile7
-rw-r--r--arch/s390/boot/alternative.c5
-rw-r--r--arch/s390/boot/ipl_parm.c28
-rw-r--r--arch/s390/boot/mem.S2
-rw-r--r--arch/s390/boot/physmem_info.c2
-rw-r--r--arch/s390/boot/string.c6
-rw-r--r--arch/s390/boot/vmem.c32
-rw-r--r--arch/s390/boot/vmlinux.lds.S1
8 files changed, 42 insertions, 41 deletions
diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
index a1e719a79d38..10b75e053a6f 100644
--- a/arch/s390/boot/Makefile
+++ b/arch/s390/boot/Makefile
@@ -25,8 +25,13 @@ KBUILD_CFLAGS += $(call cc-option, -Wno-default-const-init-unsafe)
CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char
+# string.o implements standard library functions like memset/memcpy etc.
+# Use -ffreestanding to ensure that the compiler does not try to "optimize"
+# them into calls to themselves.
+CFLAGS_string.o = -ffreestanding
+
obj-y := head.o als.o startup.o physmem_info.o ipl_parm.o ipl_report.o vmem.o
-obj-y += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o
+obj-y += string.o ebcdic.o sclp_early_core.o ipl_vmparm.o cmdline.o
obj-y += version.o pgm_check.o ctype.o ipl_data.o relocs.o alternative.o
obj-y += uv.o printk.o trampoline.o
obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
diff --git a/arch/s390/boot/alternative.c b/arch/s390/boot/alternative.c
index 19ea7934b918..77e8bad560c5 100644
--- a/arch/s390/boot/alternative.c
+++ b/arch/s390/boot/alternative.c
@@ -45,11 +45,12 @@ static void alt_debug_modify(int type, unsigned int nr, bool clear)
static char *alt_debug_parse(int type, char *str)
{
- unsigned long val, endval;
+ unsigned long val, endval, limit;
char *endp;
bool clear;
int i;
+ limit = type == ALT_TYPE_FACILITY ? MAX_FACILITY_BIT : MAX_MFEATURE_BIT;
if (*str == ':') {
str++;
} else {
@@ -73,7 +74,7 @@ static char *alt_debug_parse(int type, char *str)
if (str == endp)
break;
str = endp;
- while (val <= endval) {
+ while (val <= endval && val < limit) {
alt_debug_modify(type, val, clear);
val++;
}
diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c
index 6bc950b92be7..c1b43e5e688a 100644
--- a/arch/s390/boot/ipl_parm.c
+++ b/arch/s390/boot/ipl_parm.c
@@ -23,6 +23,7 @@ struct parmarea parmarea __section(".parmarea") = {
};
char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
+static char command_line_buf[COMMAND_LINE_SIZE];
unsigned int __bootdata_preserved(zlib_dfltcc_support) = ZLIB_DFLTCC_FULL;
struct ipl_parameter_block __bootdata_preserved(ipl_block);
@@ -135,31 +136,29 @@ out:
static void append_ipl_block_parm(void)
{
- char *parm, *delim;
- size_t len, rc = 0;
+ size_t len, extra = 0;
+ char *delim;
len = strlen(early_command_line);
-
- delim = early_command_line + len; /* '\0' character position */
- parm = early_command_line + len + 1; /* append right after '\0' */
+ delim = early_command_line + len; /* '\0' character position */
switch (ipl_block.pb0_hdr.pbt) {
case IPL_PBT_CCW:
- rc = ipl_block_get_ascii_vmparm(
- parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);
+ extra = ipl_block_get_ascii_vmparm(command_line_buf, sizeof(command_line_buf), &ipl_block);
break;
case IPL_PBT_FCP:
case IPL_PBT_NVME:
case IPL_PBT_ECKD:
- rc = ipl_block_get_ascii_scpdata(
- parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);
+ extra = ipl_block_get_ascii_scpdata(command_line_buf, sizeof(command_line_buf), &ipl_block);
break;
}
- if (rc) {
- if (*parm == '=')
- memmove(early_command_line, parm + 1, rc);
- else
+ if (extra) {
+ if (command_line_buf[0] == '=') {
+ memmove(early_command_line, command_line_buf + 1, extra);
+ } else if (len < COMMAND_LINE_SIZE - 2) {
*delim = ' '; /* replace '\0' with space */
+ sized_strscpy(delim + 1, command_line_buf, COMMAND_LINE_SIZE - len - 1);
+ }
}
}
@@ -231,7 +230,7 @@ static void modify_fac_list(char *str)
if (str == endp)
break;
str = endp;
- while (val <= endval) {
+ while (val <= endval && val < MAX_FACILITY_BIT) {
modify_facility(val, clear);
val++;
}
@@ -245,7 +244,6 @@ static void modify_fac_list(char *str)
check_cleared_facilities();
}
-static char command_line_buf[COMMAND_LINE_SIZE];
void parse_boot_command_line(void)
{
char *param, *val;
diff --git a/arch/s390/boot/mem.S b/arch/s390/boot/mem.S
deleted file mode 100644
index b33463633f03..000000000000
--- a/arch/s390/boot/mem.S
+++ /dev/null
@@ -1,2 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include "../lib/mem.S"
diff --git a/arch/s390/boot/physmem_info.c b/arch/s390/boot/physmem_info.c
index 1f2ca5435838..0ebb2174713f 100644
--- a/arch/s390/boot/physmem_info.c
+++ b/arch/s390/boot/physmem_info.c
@@ -141,7 +141,7 @@ static int tprot(unsigned long addr)
static unsigned long search_mem_end(void)
{
- unsigned long range = 1 << (MAX_PHYSMEM_BITS - 20); /* in 1MB blocks */
+ unsigned long range = 1UL << (MAX_PHYSMEM_BITS - 20); /* in 1MB blocks */
unsigned long offset = 0;
unsigned long pivot;
diff --git a/arch/s390/boot/string.c b/arch/s390/boot/string.c
index bd68161434a6..e4ad196cb720 100644
--- a/arch/s390/boot/string.c
+++ b/arch/s390/boot/string.c
@@ -43,11 +43,7 @@ ssize_t sized_strscpy(char *dst, const char *src, size_t count)
void *memset64(uint64_t *s, uint64_t v, size_t count)
{
- uint64_t *xs = s;
-
- while (count--)
- *xs++ = v;
- return s;
+ return __memset64(s, v, count * sizeof(v));
}
char *skip_spaces(const char *str)
diff --git a/arch/s390/boot/vmem.c b/arch/s390/boot/vmem.c
index 7d6cc4c85af0..ff6d58a476ba 100644
--- a/arch/s390/boot/vmem.c
+++ b/arch/s390/boot/vmem.c
@@ -338,7 +338,7 @@ static void pgtable_pte_populate(pmd_t *pmd, unsigned long addr, unsigned long e
pte = pte_offset_kernel(pmd, addr);
for (; addr < end; addr += PAGE_SIZE, pte++) {
- if (pte_none(*pte)) {
+ if (pte_none(ptep_get(pte))) {
if (kasan_pte_populate_zero_shadow(pte, mode))
continue;
entry = __pte(resolve_pa_may_alloc(addr, PAGE_SIZE, mode));
@@ -355,26 +355,27 @@ static void pgtable_pmd_populate(pud_t *pud, unsigned long addr, unsigned long e
enum populate_mode mode)
{
unsigned long pa, next, pages = 0;
- pmd_t *pmd, entry;
+ pmd_t *pmd, entry, large_entry;
pte_t *pte;
pmd = pmd_offset(pud, addr);
for (; addr < end; addr = next, pmd++) {
next = pmd_addr_end(addr, end);
- if (pmd_none(*pmd)) {
+ entry = pmdp_get(pmd);
+ if (pmd_none(entry)) {
if (kasan_pmd_populate_zero_shadow(pmd, addr, next, mode))
continue;
pa = try_get_large_pmd_pa(pmd, addr, next, mode);
if (pa != INVALID_PHYS_ADDR) {
- entry = __pmd(pa);
- entry = set_pmd_bit(entry, SEGMENT_KERNEL);
- set_pmd(pmd, entry);
+ large_entry = __pmd(pa);
+ large_entry = set_pmd_bit(large_entry, SEGMENT_KERNEL);
+ set_pmd(pmd, large_entry);
pages++;
continue;
}
pte = boot_pte_alloc();
pmd_populate(&init_mm, pmd, pte);
- } else if (pmd_leaf(*pmd)) {
+ } else if (pmd_leaf(entry)) {
continue;
}
pgtable_pte_populate(pmd, addr, next, mode);
@@ -387,26 +388,27 @@ static void pgtable_pud_populate(p4d_t *p4d, unsigned long addr, unsigned long e
enum populate_mode mode)
{
unsigned long pa, next, pages = 0;
- pud_t *pud, entry;
+ pud_t *pud, entry, large_entry;
pmd_t *pmd;
pud = pud_offset(p4d, addr);
for (; addr < end; addr = next, pud++) {
next = pud_addr_end(addr, end);
- if (pud_none(*pud)) {
+ entry = pudp_get(pud);
+ if (pud_none(entry)) {
if (kasan_pud_populate_zero_shadow(pud, addr, next, mode))
continue;
pa = try_get_large_pud_pa(pud, addr, next, mode);
if (pa != INVALID_PHYS_ADDR) {
- entry = __pud(pa);
- entry = set_pud_bit(entry, REGION3_KERNEL);
- set_pud(pud, entry);
+ large_entry = __pud(pa);
+ large_entry = set_pud_bit(large_entry, REGION3_KERNEL);
+ set_pud(pud, large_entry);
pages++;
continue;
}
pmd = boot_crst_alloc(_SEGMENT_ENTRY_EMPTY);
pud_populate(&init_mm, pud, pmd);
- } else if (pud_leaf(*pud)) {
+ } else if (pud_leaf(entry)) {
continue;
}
pgtable_pmd_populate(pud, addr, next, mode);
@@ -425,7 +427,7 @@ static void pgtable_p4d_populate(pgd_t *pgd, unsigned long addr, unsigned long e
p4d = p4d_offset(pgd, addr);
for (; addr < end; addr = next, p4d++) {
next = p4d_addr_end(addr, end);
- if (p4d_none(*p4d)) {
+ if (p4d_none(p4dp_get(p4d))) {
if (kasan_p4d_populate_zero_shadow(p4d, addr, next, mode))
continue;
pud = boot_crst_alloc(_REGION3_ENTRY_EMPTY);
@@ -451,7 +453,7 @@ static void pgtable_populate(unsigned long addr, unsigned long end, enum populat
pgd = pgd_offset(&init_mm, addr);
for (; addr < end; addr = next, pgd++) {
next = pgd_addr_end(addr, end);
- if (pgd_none(*pgd)) {
+ if (pgd_none(pgdp_get(pgd))) {
if (kasan_pgd_populate_zero_shadow(pgd, addr, next, mode))
continue;
p4d = boot_crst_alloc(_REGION2_ENTRY_EMPTY);
diff --git a/arch/s390/boot/vmlinux.lds.S b/arch/s390/boot/vmlinux.lds.S
index 070bc18babd0..d44964592541 100644
--- a/arch/s390/boot/vmlinux.lds.S
+++ b/arch/s390/boot/vmlinux.lds.S
@@ -31,6 +31,7 @@ SECTIONS
_text = .; /* Text */
*(.text)
*(.text.*)
+ *(.noinstr.text)
INIT_TEXT
_etext = . ;
}