Commit cd4175b1 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'parisc-4.14-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux

Pull parisc fixes from Helge Deller:

 - Unbreak parisc bootloader by avoiding a gcc-7 optimization to convert
   multiple byte-accesses into one word-access.

 - Add missing HWPOISON page fault handler code. I completely missed
   that when I added HWPOISON support during this merge window and it
   only showed up now with the madvise07 LTP test case.

 - Fix backtrace unwinding to stop when stack start has been reached.

 - Issue warning if initrd has been loaded into memory regions with
   broken RAM modules.

 - Fix HPMC handler (parisc hardware fault handler) to comply with
   architecture specification.

 - Avoid compiler warnings about too large frame sizes.

 - Minor init-section fixes.

* 'parisc-4.14-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
  parisc: Unbreak bootloader due to gcc-7 optimizations
  parisc: Reintroduce option to gzip-compress the kernel
  parisc: Add HWPOISON page fault handler code
  parisc: Move init_per_cpu() into init section
  parisc: Check if initrd was loaded into broken RAM
  parisc: Add PDCE_CHECK instruction to HPMC handler
  parisc: Add wrapper for pdc_instr() firmware function
  parisc: Move start_parisc() into init section
  parisc: Stop unwinding at start of stack
  parisc: Fix too large frame size warnings
parents ded85032 8c031ba6
...@@ -257,6 +257,18 @@ config PARISC_PAGE_SIZE_64KB ...@@ -257,6 +257,18 @@ config PARISC_PAGE_SIZE_64KB
endchoice endchoice
config PARISC_SELF_EXTRACT
bool "Build kernel as self-extracting executable"
default y
help
Say Y if you want to build the parisc kernel as a kind of
self-extracting executable.
If you say N here, the kernel will be compressed with gzip
which can be loaded by the palo bootloader directly too.
If you don't know what to do here, say Y.
config SMP config SMP
bool "Symmetric multi-processing support" bool "Symmetric multi-processing support"
---help--- ---help---
......
...@@ -129,8 +129,13 @@ Image: vmlinux ...@@ -129,8 +129,13 @@ Image: vmlinux
bzImage: vmlinux bzImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
ifdef CONFIG_PARISC_SELF_EXTRACT
vmlinuz: bzImage vmlinuz: bzImage
$(OBJCOPY) $(boot)/bzImage $@ $(OBJCOPY) $(boot)/bzImage $@
else
vmlinuz: vmlinux
@gzip -cf -9 $< > $@
endif
install: install:
$(CONFIG_SHELL) $(src)/arch/parisc/install.sh \ $(CONFIG_SHELL) $(src)/arch/parisc/install.sh \
......
...@@ -15,7 +15,7 @@ targets += misc.o piggy.o sizes.h head.o real2.o firmware.o ...@@ -15,7 +15,7 @@ targets += misc.o piggy.o sizes.h head.o real2.o firmware.o
KBUILD_CFLAGS := -D__KERNEL__ -O2 -DBOOTLOADER KBUILD_CFLAGS := -D__KERNEL__ -O2 -DBOOTLOADER
KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
KBUILD_CFLAGS += $(cflags-y) -fno-delete-null-pointer-checks KBUILD_CFLAGS += $(cflags-y) -fno-delete-null-pointer-checks
KBUILD_CFLAGS += -fno-PIE -mno-space-regs -mdisable-fpregs KBUILD_CFLAGS += -fno-PIE -mno-space-regs -mdisable-fpregs -Os
ifndef CONFIG_64BIT ifndef CONFIG_64BIT
KBUILD_CFLAGS += -mfast-indirect-calls KBUILD_CFLAGS += -mfast-indirect-calls
endif endif
......
...@@ -24,7 +24,8 @@ ...@@ -24,7 +24,8 @@
/* Symbols defined by linker scripts */ /* Symbols defined by linker scripts */
extern char input_data[]; extern char input_data[];
extern int input_len; extern int input_len;
extern __le32 output_len; /* at unaligned address, little-endian */ /* output_len is inserted by the linker possibly at an unaligned address */
extern __le32 output_len __aligned(1);
extern char _text, _end; extern char _text, _end;
extern char _bss, _ebss; extern char _bss, _ebss;
extern char _startcode_end; extern char _startcode_end;
......
...@@ -280,6 +280,7 @@ void setup_pdc(void); /* in inventory.c */ ...@@ -280,6 +280,7 @@ void setup_pdc(void); /* in inventory.c */
/* wrapper-functions from pdc.c */ /* wrapper-functions from pdc.c */
int pdc_add_valid(unsigned long address); int pdc_add_valid(unsigned long address);
int pdc_instr(unsigned int *instr);
int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len); int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len);
int pdc_chassis_disp(unsigned long disp); int pdc_chassis_disp(unsigned long disp);
int pdc_chassis_warn(unsigned long *warn); int pdc_chassis_warn(unsigned long *warn);
......
#ifndef __ASM_SMP_H #ifndef __ASM_SMP_H
#define __ASM_SMP_H #define __ASM_SMP_H
extern int init_per_cpu(int cpuid);
#if defined(CONFIG_SMP) #if defined(CONFIG_SMP)
......
...@@ -232,6 +232,26 @@ int pdc_add_valid(unsigned long address) ...@@ -232,6 +232,26 @@ int pdc_add_valid(unsigned long address)
} }
EXPORT_SYMBOL(pdc_add_valid); EXPORT_SYMBOL(pdc_add_valid);
/**
* pdc_instr - Get instruction that invokes PDCE_CHECK in HPMC handler.
* @instr: Pointer to variable which will get instruction opcode.
*
* The return value is PDC_OK (0) in case call succeeded.
*/
int __init pdc_instr(unsigned int *instr)
{
int retval;
unsigned long flags;
spin_lock_irqsave(&pdc_lock, flags);
retval = mem_pdc_call(PDC_INSTR, 0UL, __pa(pdc_result));
convert_to_wide(pdc_result);
*instr = pdc_result[0];
spin_unlock_irqrestore(&pdc_lock, flags);
return retval;
}
/** /**
* pdc_chassis_info - Return chassis information. * pdc_chassis_info - Return chassis information.
* @result: The return buffer. * @result: The return buffer.
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/initrd.h>
#include <asm/pdc.h> #include <asm/pdc.h>
#include <asm/pdcpat.h> #include <asm/pdcpat.h>
...@@ -216,8 +217,16 @@ void __init pdc_pdt_init(void) ...@@ -216,8 +217,16 @@ void __init pdc_pdt_init(void)
} }
for (i = 0; i < pdt_status.pdt_entries; i++) { for (i = 0; i < pdt_status.pdt_entries; i++) {
unsigned long addr;
report_mem_err(pdt_entry[i]); report_mem_err(pdt_entry[i]);
addr = pdt_entry[i] & PDT_ADDR_PHYS_MASK;
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) &&
addr >= initrd_start && addr < initrd_end)
pr_crit("CRITICAL: initrd possibly broken "
"due to bad memory!\n");
/* mark memory page bad */ /* mark memory page bad */
memblock_reserve(pdt_entry[i] & PAGE_MASK, PAGE_SIZE); memblock_reserve(pdt_entry[i] & PAGE_MASK, PAGE_SIZE);
} }
......
...@@ -317,7 +317,7 @@ void __init collect_boot_cpu_data(void) ...@@ -317,7 +317,7 @@ void __init collect_boot_cpu_data(void)
* *
* o Enable CPU profiling hooks. * o Enable CPU profiling hooks.
*/ */
int init_per_cpu(int cpunum) int __init init_per_cpu(int cpunum)
{ {
int ret; int ret;
struct pdc_coproc_cfg coproc_cfg; struct pdc_coproc_cfg coproc_cfg;
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/export.h> #include <linux/export.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/sched/clock.h> #include <linux/sched/clock.h>
#include <linux/start_kernel.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/sections.h> #include <asm/sections.h>
...@@ -48,6 +49,7 @@ ...@@ -48,6 +49,7 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/unwind.h> #include <asm/unwind.h>
#include <asm/smp.h>
static char __initdata command_line[COMMAND_LINE_SIZE]; static char __initdata command_line[COMMAND_LINE_SIZE];
...@@ -115,7 +117,6 @@ void __init dma_ops_init(void) ...@@ -115,7 +117,6 @@ void __init dma_ops_init(void)
} }
#endif #endif
extern int init_per_cpu(int cpuid);
extern void collect_boot_cpu_data(void); extern void collect_boot_cpu_data(void);
void __init setup_arch(char **cmdline_p) void __init setup_arch(char **cmdline_p)
...@@ -398,9 +399,8 @@ static int __init parisc_init(void) ...@@ -398,9 +399,8 @@ static int __init parisc_init(void)
} }
arch_initcall(parisc_init); arch_initcall(parisc_init);
void start_parisc(void) void __init start_parisc(void)
{ {
extern void start_kernel(void);
extern void early_trap_init(void); extern void early_trap_init(void);
int ret, cpunum; int ret, cpunum;
......
...@@ -255,12 +255,11 @@ void arch_send_call_function_single_ipi(int cpu) ...@@ -255,12 +255,11 @@ void arch_send_call_function_single_ipi(int cpu)
static void __init static void __init
smp_cpu_init(int cpunum) smp_cpu_init(int cpunum)
{ {
extern int init_per_cpu(int); /* arch/parisc/kernel/processor.c */
extern void init_IRQ(void); /* arch/parisc/kernel/irq.c */ extern void init_IRQ(void); /* arch/parisc/kernel/irq.c */
extern void start_cpu_itimer(void); /* arch/parisc/kernel/time.c */ extern void start_cpu_itimer(void); /* arch/parisc/kernel/time.c */
/* Set modes and Enable floating point coprocessor */ /* Set modes and Enable floating point coprocessor */
(void) init_per_cpu(cpunum); init_per_cpu(cpunum);
disable_sr_hashing(); disable_sr_hashing();
......
...@@ -817,7 +817,7 @@ void __init initialize_ivt(const void *iva) ...@@ -817,7 +817,7 @@ void __init initialize_ivt(const void *iva)
u32 check = 0; u32 check = 0;
u32 *ivap; u32 *ivap;
u32 *hpmcp; u32 *hpmcp;
u32 length; u32 length, instr;
if (strcmp((const char *)iva, "cows can fly")) if (strcmp((const char *)iva, "cows can fly"))
panic("IVT invalid"); panic("IVT invalid");
...@@ -827,6 +827,14 @@ void __init initialize_ivt(const void *iva) ...@@ -827,6 +827,14 @@ void __init initialize_ivt(const void *iva)
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
*ivap++ = 0; *ivap++ = 0;
/*
* Use PDC_INSTR firmware function to get instruction that invokes
* PDCE_CHECK in HPMC handler. See programming note at page 1-31 of
* the PA 1.1 Firmware Architecture document.
*/
if (pdc_instr(&instr) == PDC_OK)
ivap[0] = instr;
/* Compute Checksum for HPMC handler */ /* Compute Checksum for HPMC handler */
length = os_hpmc_size; length = os_hpmc_size;
ivap[7] = length; ivap[7] = length;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/kallsyms.h> #include <linux/kallsyms.h>
#include <linux/sort.h> #include <linux/sort.h>
#include <linux/sched.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/assembly.h> #include <asm/assembly.h>
...@@ -279,6 +280,17 @@ static void unwind_frame_regs(struct unwind_frame_info *info) ...@@ -279,6 +280,17 @@ static void unwind_frame_regs(struct unwind_frame_info *info)
info->prev_sp = sp - 64; info->prev_sp = sp - 64;
info->prev_ip = 0; info->prev_ip = 0;
/* The stack is at the end inside the thread_union
* struct. If we reach data, we have reached the
* beginning of the stack and should stop unwinding. */
if (info->prev_sp >= (unsigned long) task_thread_info(info->t) &&
info->prev_sp < ((unsigned long) task_thread_info(info->t)
+ THREAD_SZ_ALGN)) {
info->prev_sp = 0;
break;
}
if (get_user(tmp, (unsigned long *)(info->prev_sp - RP_OFFSET))) if (get_user(tmp, (unsigned long *)(info->prev_sp - RP_OFFSET)))
break; break;
info->prev_ip = tmp; info->prev_ip = tmp;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/extable.h> #include <linux/extable.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/hugetlb.h>
#include <asm/traps.h> #include <asm/traps.h>
...@@ -261,7 +262,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code, ...@@ -261,7 +262,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
struct task_struct *tsk; struct task_struct *tsk;
struct mm_struct *mm; struct mm_struct *mm;
unsigned long acc_type; unsigned long acc_type;
int fault; int fault = 0;
unsigned int flags; unsigned int flags;
if (faulthandler_disabled()) if (faulthandler_disabled())
...@@ -315,7 +316,8 @@ void do_page_fault(struct pt_regs *regs, unsigned long code, ...@@ -315,7 +316,8 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
goto out_of_memory; goto out_of_memory;
else if (fault & VM_FAULT_SIGSEGV) else if (fault & VM_FAULT_SIGSEGV)
goto bad_area; goto bad_area;
else if (fault & VM_FAULT_SIGBUS) else if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON|
VM_FAULT_HWPOISON_LARGE))
goto bad_area; goto bad_area;
BUG(); BUG();
} }
...@@ -352,8 +354,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code, ...@@ -352,8 +354,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
if (user_mode(regs)) { if (user_mode(regs)) {
struct siginfo si; struct siginfo si;
unsigned int lsb = 0;
show_signal_msg(regs, code, address, tsk, vma);
switch (code) { switch (code) {
case 15: /* Data TLB miss fault/Data page fault */ case 15: /* Data TLB miss fault/Data page fault */
...@@ -386,6 +387,30 @@ void do_page_fault(struct pt_regs *regs, unsigned long code, ...@@ -386,6 +387,30 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
si.si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR; si.si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR;
break; break;
} }
#ifdef CONFIG_MEMORY_FAILURE
if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) {
printk(KERN_ERR
"MCE: Killing %s:%d due to hardware memory corruption fault at %08lx\n",
tsk->comm, tsk->pid, address);
si.si_signo = SIGBUS;
si.si_code = BUS_MCEERR_AR;
}
#endif
/*
* Either small page or large page may be poisoned.
* In other words, VM_FAULT_HWPOISON_LARGE and
* VM_FAULT_HWPOISON are mutually exclusive.
*/
if (fault & VM_FAULT_HWPOISON_LARGE)
lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault));
else if (fault & VM_FAULT_HWPOISON)
lsb = PAGE_SHIFT;
else
show_signal_msg(regs, code, address, tsk, vma);
si.si_addr_lsb = lsb;
si.si_errno = 0; si.si_errno = 0;
si.si_addr = (void __user *) address; si.si_addr = (void __user *) address;
force_sig_info(si.si_signo, &si, current); force_sig_info(si.si_signo, &si, current);
......
...@@ -219,7 +219,8 @@ config FRAME_WARN ...@@ -219,7 +219,8 @@ config FRAME_WARN
range 0 8192 range 0 8192
default 0 if KASAN default 0 if KASAN
default 2048 if GCC_PLUGIN_LATENT_ENTROPY default 2048 if GCC_PLUGIN_LATENT_ENTROPY
default 1024 if !64BIT default 1280 if (!64BIT && PARISC)
default 1024 if (!64BIT && !PARISC)
default 2048 if 64BIT default 2048 if 64BIT
help help
Tell gcc to warn at build time for stack frames larger than this. Tell gcc to warn at build time for stack frames larger than this.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment