Skip to content

Commit cd4175b

Browse files
committed
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
2 parents ded8503 + 8c031ba commit cd4175b

File tree

15 files changed

+108
-14
lines changed

15 files changed

+108
-14
lines changed

arch/parisc/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,18 @@ config PARISC_PAGE_SIZE_64KB
257257

258258
endchoice
259259

260+
config PARISC_SELF_EXTRACT
261+
bool "Build kernel as self-extracting executable"
262+
default y
263+
help
264+
Say Y if you want to build the parisc kernel as a kind of
265+
self-extracting executable.
266+
267+
If you say N here, the kernel will be compressed with gzip
268+
which can be loaded by the palo bootloader directly too.
269+
270+
If you don't know what to do here, say Y.
271+
260272
config SMP
261273
bool "Symmetric multi-processing support"
262274
---help---

arch/parisc/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,13 @@ Image: vmlinux
129129
bzImage: vmlinux
130130
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
131131

132+
ifdef CONFIG_PARISC_SELF_EXTRACT
132133
vmlinuz: bzImage
133134
$(OBJCOPY) $(boot)/bzImage $@
135+
else
136+
vmlinuz: vmlinux
137+
@gzip -cf -9 $< > $@
138+
endif
134139

135140
install:
136141
$(CONFIG_SHELL) $(src)/arch/parisc/install.sh \

arch/parisc/boot/compressed/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ targets += misc.o piggy.o sizes.h head.o real2.o firmware.o
1515
KBUILD_CFLAGS := -D__KERNEL__ -O2 -DBOOTLOADER
1616
KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
1717
KBUILD_CFLAGS += $(cflags-y) -fno-delete-null-pointer-checks
18-
KBUILD_CFLAGS += -fno-PIE -mno-space-regs -mdisable-fpregs
18+
KBUILD_CFLAGS += -fno-PIE -mno-space-regs -mdisable-fpregs -Os
1919
ifndef CONFIG_64BIT
2020
KBUILD_CFLAGS += -mfast-indirect-calls
2121
endif

arch/parisc/boot/compressed/misc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
/* Symbols defined by linker scripts */
2525
extern char input_data[];
2626
extern int input_len;
27-
extern __le32 output_len; /* at unaligned address, little-endian */
27+
/* output_len is inserted by the linker possibly at an unaligned address */
28+
extern __le32 output_len __aligned(1);
2829
extern char _text, _end;
2930
extern char _bss, _ebss;
3031
extern char _startcode_end;

arch/parisc/include/asm/pdc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ void setup_pdc(void); /* in inventory.c */
280280
/* wrapper-functions from pdc.c */
281281

282282
int pdc_add_valid(unsigned long address);
283+
int pdc_instr(unsigned int *instr);
283284
int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len);
284285
int pdc_chassis_disp(unsigned long disp);
285286
int pdc_chassis_warn(unsigned long *warn);

arch/parisc/include/asm/smp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef __ASM_SMP_H
22
#define __ASM_SMP_H
33

4+
extern int init_per_cpu(int cpuid);
45

56
#if defined(CONFIG_SMP)
67

arch/parisc/kernel/firmware.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,26 @@ int pdc_add_valid(unsigned long address)
232232
}
233233
EXPORT_SYMBOL(pdc_add_valid);
234234

235+
/**
236+
* pdc_instr - Get instruction that invokes PDCE_CHECK in HPMC handler.
237+
* @instr: Pointer to variable which will get instruction opcode.
238+
*
239+
* The return value is PDC_OK (0) in case call succeeded.
240+
*/
241+
int __init pdc_instr(unsigned int *instr)
242+
{
243+
int retval;
244+
unsigned long flags;
245+
246+
spin_lock_irqsave(&pdc_lock, flags);
247+
retval = mem_pdc_call(PDC_INSTR, 0UL, __pa(pdc_result));
248+
convert_to_wide(pdc_result);
249+
*instr = pdc_result[0];
250+
spin_unlock_irqrestore(&pdc_lock, flags);
251+
252+
return retval;
253+
}
254+
235255
/**
236256
* pdc_chassis_info - Return chassis information.
237257
* @result: The return buffer.

arch/parisc/kernel/pdt.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/memblock.h>
1616
#include <linux/seq_file.h>
1717
#include <linux/kthread.h>
18+
#include <linux/initrd.h>
1819

1920
#include <asm/pdc.h>
2021
#include <asm/pdcpat.h>
@@ -216,8 +217,16 @@ void __init pdc_pdt_init(void)
216217
}
217218

218219
for (i = 0; i < pdt_status.pdt_entries; i++) {
220+
unsigned long addr;
221+
219222
report_mem_err(pdt_entry[i]);
220223

224+
addr = pdt_entry[i] & PDT_ADDR_PHYS_MASK;
225+
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) &&
226+
addr >= initrd_start && addr < initrd_end)
227+
pr_crit("CRITICAL: initrd possibly broken "
228+
"due to bad memory!\n");
229+
221230
/* mark memory page bad */
222231
memblock_reserve(pdt_entry[i] & PAGE_MASK, PAGE_SIZE);
223232
}

arch/parisc/kernel/processor.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ void __init collect_boot_cpu_data(void)
317317
*
318318
* o Enable CPU profiling hooks.
319319
*/
320-
int init_per_cpu(int cpunum)
320+
int __init init_per_cpu(int cpunum)
321321
{
322322
int ret;
323323
struct pdc_coproc_cfg coproc_cfg;

arch/parisc/kernel/setup.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <linux/export.h>
3939
#include <linux/sched.h>
4040
#include <linux/sched/clock.h>
41+
#include <linux/start_kernel.h>
4142

4243
#include <asm/processor.h>
4344
#include <asm/sections.h>
@@ -48,6 +49,7 @@
4849
#include <asm/io.h>
4950
#include <asm/setup.h>
5051
#include <asm/unwind.h>
52+
#include <asm/smp.h>
5153

5254
static char __initdata command_line[COMMAND_LINE_SIZE];
5355

@@ -115,7 +117,6 @@ void __init dma_ops_init(void)
115117
}
116118
#endif
117119

118-
extern int init_per_cpu(int cpuid);
119120
extern void collect_boot_cpu_data(void);
120121

121122
void __init setup_arch(char **cmdline_p)
@@ -398,9 +399,8 @@ static int __init parisc_init(void)
398399
}
399400
arch_initcall(parisc_init);
400401

401-
void start_parisc(void)
402+
void __init start_parisc(void)
402403
{
403-
extern void start_kernel(void);
404404
extern void early_trap_init(void);
405405

406406
int ret, cpunum;

arch/parisc/kernel/smp.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,12 +255,11 @@ void arch_send_call_function_single_ipi(int cpu)
255255
static void __init
256256
smp_cpu_init(int cpunum)
257257
{
258-
extern int init_per_cpu(int); /* arch/parisc/kernel/processor.c */
259258
extern void init_IRQ(void); /* arch/parisc/kernel/irq.c */
260259
extern void start_cpu_itimer(void); /* arch/parisc/kernel/time.c */
261260

262261
/* Set modes and Enable floating point coprocessor */
263-
(void) init_per_cpu(cpunum);
262+
init_per_cpu(cpunum);
264263

265264
disable_sr_hashing();
266265

arch/parisc/kernel/traps.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -817,7 +817,7 @@ void __init initialize_ivt(const void *iva)
817817
u32 check = 0;
818818
u32 *ivap;
819819
u32 *hpmcp;
820-
u32 length;
820+
u32 length, instr;
821821

822822
if (strcmp((const char *)iva, "cows can fly"))
823823
panic("IVT invalid");
@@ -827,6 +827,14 @@ void __init initialize_ivt(const void *iva)
827827
for (i = 0; i < 8; i++)
828828
*ivap++ = 0;
829829

830+
/*
831+
* Use PDC_INSTR firmware function to get instruction that invokes
832+
* PDCE_CHECK in HPMC handler. See programming note at page 1-31 of
833+
* the PA 1.1 Firmware Architecture document.
834+
*/
835+
if (pdc_instr(&instr) == PDC_OK)
836+
ivap[0] = instr;
837+
830838
/* Compute Checksum for HPMC handler */
831839
length = os_hpmc_size;
832840
ivap[7] = length;

arch/parisc/kernel/unwind.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/slab.h>
1515
#include <linux/kallsyms.h>
1616
#include <linux/sort.h>
17+
#include <linux/sched.h>
1718

1819
#include <linux/uaccess.h>
1920
#include <asm/assembly.h>
@@ -279,6 +280,17 @@ static void unwind_frame_regs(struct unwind_frame_info *info)
279280

280281
info->prev_sp = sp - 64;
281282
info->prev_ip = 0;
283+
284+
/* The stack is at the end inside the thread_union
285+
* struct. If we reach data, we have reached the
286+
* beginning of the stack and should stop unwinding. */
287+
if (info->prev_sp >= (unsigned long) task_thread_info(info->t) &&
288+
info->prev_sp < ((unsigned long) task_thread_info(info->t)
289+
+ THREAD_SZ_ALGN)) {
290+
info->prev_sp = 0;
291+
break;
292+
}
293+
282294
if (get_user(tmp, (unsigned long *)(info->prev_sp - RP_OFFSET)))
283295
break;
284296
info->prev_ip = tmp;

arch/parisc/mm/fault.c

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/interrupt.h>
1818
#include <linux/extable.h>
1919
#include <linux/uaccess.h>
20+
#include <linux/hugetlb.h>
2021

2122
#include <asm/traps.h>
2223

@@ -261,7 +262,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
261262
struct task_struct *tsk;
262263
struct mm_struct *mm;
263264
unsigned long acc_type;
264-
int fault;
265+
int fault = 0;
265266
unsigned int flags;
266267

267268
if (faulthandler_disabled())
@@ -315,7 +316,8 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
315316
goto out_of_memory;
316317
else if (fault & VM_FAULT_SIGSEGV)
317318
goto bad_area;
318-
else if (fault & VM_FAULT_SIGBUS)
319+
else if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON|
320+
VM_FAULT_HWPOISON_LARGE))
319321
goto bad_area;
320322
BUG();
321323
}
@@ -352,8 +354,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
352354

353355
if (user_mode(regs)) {
354356
struct siginfo si;
355-
356-
show_signal_msg(regs, code, address, tsk, vma);
357+
unsigned int lsb = 0;
357358

358359
switch (code) {
359360
case 15: /* Data TLB miss fault/Data page fault */
@@ -386,6 +387,30 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
386387
si.si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR;
387388
break;
388389
}
390+
391+
#ifdef CONFIG_MEMORY_FAILURE
392+
if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) {
393+
printk(KERN_ERR
394+
"MCE: Killing %s:%d due to hardware memory corruption fault at %08lx\n",
395+
tsk->comm, tsk->pid, address);
396+
si.si_signo = SIGBUS;
397+
si.si_code = BUS_MCEERR_AR;
398+
}
399+
#endif
400+
401+
/*
402+
* Either small page or large page may be poisoned.
403+
* In other words, VM_FAULT_HWPOISON_LARGE and
404+
* VM_FAULT_HWPOISON are mutually exclusive.
405+
*/
406+
if (fault & VM_FAULT_HWPOISON_LARGE)
407+
lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault));
408+
else if (fault & VM_FAULT_HWPOISON)
409+
lsb = PAGE_SHIFT;
410+
else
411+
show_signal_msg(regs, code, address, tsk, vma);
412+
si.si_addr_lsb = lsb;
413+
389414
si.si_errno = 0;
390415
si.si_addr = (void __user *) address;
391416
force_sig_info(si.si_signo, &si, current);

lib/Kconfig.debug

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,8 @@ config FRAME_WARN
219219
range 0 8192
220220
default 0 if KASAN
221221
default 2048 if GCC_PLUGIN_LATENT_ENTROPY
222-
default 1024 if !64BIT
222+
default 1280 if (!64BIT && PARISC)
223+
default 1024 if (!64BIT && !PARISC)
223224
default 2048 if 64BIT
224225
help
225226
Tell gcc to warn at build time for stack frames larger than this.

0 commit comments

Comments
 (0)