mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-03-21 06:24:12 +00:00
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
This commit is contained in:
commit
cd4175b116
15 changed files with 108 additions and 14 deletions
|
@ -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
|
||||||
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
|
||||||
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 @@
|
||||||
/* 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 */
|
||||||
/* 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);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#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)
|
||||||
}
|
}
|
||||||
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 @@
|
||||||
#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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
*
|
*
|
||||||
* 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 @@
|
||||||
#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 @@
|
||||||
#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)
|
||||||
}
|
}
|
||||||
#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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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 @@
|
||||||
#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)
|
||||||
|
|
||||||
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 @@
|
||||||
#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,
|
||||||
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 @@ good_area:
|
||||||
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 @@ bad_area:
|
||||||
|
|
||||||
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 @@ bad_area:
|
||||||
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
|
||||||
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.
|
||||||
|
|
Loading…
Add table
Reference in a new issue