Skip to content

Commit

Permalink
Merge branch 'parisc-4.9-1' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/deller/parisc-linux

Pull parisc updates from Helge Deller:
 "Changes include:

   - Fix boot of 32bit SMP kernel (initial kernel mapping was too small)

   - Added hardened usercopy checks

   - Drop bootmem and switch to memblock and NO_BOOTMEM implementation

   - Drop the BROKEN_RODATA config option (and thus remove the relevant
     code from the generic headers and files because parisc was the last
     architecture which used this config option)

   - Improve segfault reporting by printing human readable error strings

   - Various smaller changes, e.g. dwarf debug support for assembly
     code, update comments regarding copy_user_page_asm, switch to
     kmalloc_array()"

* 'parisc-4.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
  parisc: Increase KERNEL_INITIAL_SIZE for 32-bit SMP kernels
  parisc: Drop bootmem and switch to memblock
  parisc: Add hardened usercopy feature
  parisc: Add cfi_startproc and cfi_endproc to assembly code
  parisc: Move hpmc stack into page aligned bss section
  parisc: Fix self-detected CPU stall warnings on Mako machines
  parisc: Report trap type as human readable string
  parisc: Update comment regarding implementation of copy_user_page_asm
  parisc: Use kmalloc_array() in add_system_map_addresses()
  parisc: Check return value of smp_boot_one_cpu()
  parisc: Drop BROKEN_RODATA config option
  • Loading branch information
torvalds committed Oct 8, 2016
2 parents 2c34ff1 + 690d097 commit 997b611
Show file tree
Hide file tree
Showing 21 changed files with 308 additions and 207 deletions.
4 changes: 3 additions & 1 deletion arch/parisc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ config PARISC
select RTC_CLASS
select RTC_DRV_GENERIC
select INIT_ALL_POSSIBLE
select HAVE_MEMBLOCK
select NO_BOOTMEM
select BUG
select BUILDTIME_EXTABLE_SORT
select HAVE_PERF_EVENTS
select GENERIC_ATOMIC64 if !64BIT
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select BROKEN_RODATA
select GENERIC_IRQ_PROBE
select GENERIC_PCI_IOMAP
select ARCH_HAVE_NMI_SAFE_CMPXCHG
Expand All @@ -24,6 +25,7 @@ config PARISC
select SYSCTL_ARCH_UNALIGN_ALLOW
select SYSCTL_EXCEPTION_TRACE
select HAVE_MOD_ARCH_SPECIFIC
select HAVE_ARCH_HARDENED_USERCOPY
select VIRT_TO_BUS
select MODULES_USE_ELF_RELA
select CLONE_BACKWARDS
Expand Down
23 changes: 23 additions & 0 deletions arch/parisc/include/asm/dwarf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (C) 2016 Helge Deller <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#ifndef _ASM_PARISC_DWARF_H
#define _ASM_PARISC_DWARF_H

#ifdef __ASSEMBLY__

#define CFI_STARTPROC .cfi_startproc
#define CFI_ENDPROC .cfi_endproc
#define CFI_DEF_CFA .cfi_def_cfa
#define CFI_REGISTER .cfi_register
#define CFI_REL_OFFSET .cfi_rel_offset
#define CFI_UNDEFINED .cfi_undefined

#endif /* __ASSEMBLY__ */

#endif /* _ASM_PARISC_DWARF_H */
12 changes: 12 additions & 0 deletions arch/parisc/include/asm/linkage.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef __ASM_PARISC_LINKAGE_H
#define __ASM_PARISC_LINKAGE_H

#include <asm/dwarf.h>

#ifndef __ALIGN
#define __ALIGN .align 4
#define __ALIGN_STR ".align 4"
Expand All @@ -10,6 +12,8 @@
* In parisc assembly a semicolon marks a comment while a
* exclamation mark is used to separate independent lines.
*/
#define ASM_NL !

#ifdef __ASSEMBLY__

#define ENTRY(name) \
Expand All @@ -26,6 +30,14 @@
END(name)
#endif

#define ENTRY_CFI(name) \
ENTRY(name) ASM_NL\
CFI_STARTPROC

#define ENDPROC_CFI(name) \
ENDPROC(name) ASM_NL\
CFI_ENDPROC

#endif /* __ASSEMBLY__ */

#endif /* __ASM_PARISC_LINKAGE_H */
2 changes: 1 addition & 1 deletion arch/parisc/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e))

/* This is the size of the initially mapped kernel memory */
#ifdef CONFIG_64BIT
#if defined(CONFIG_64BIT) || defined(CONFIG_SMP)
#define KERNEL_INITIAL_ORDER 25 /* 1<<25 = 32MB */
#else
#define KERNEL_INITIAL_ORDER 24 /* 1<<24 = 16MB */
Expand Down
48 changes: 34 additions & 14 deletions arch/parisc/include/asm/uaccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <linux/bug.h>
#include <linux/string.h>
#include <linux/thread_info.h>

#define VERIFY_READ 0
#define VERIFY_WRITE 1
Expand Down Expand Up @@ -201,10 +202,12 @@ extern long lstrnlen_user(const char __user *, long);
#define clear_user lclear_user
#define __clear_user lclear_user

unsigned long copy_to_user(void __user *dst, const void *src, unsigned long len);
#define __copy_to_user copy_to_user
unsigned long __copy_from_user(void *dst, const void __user *src, unsigned long len);
unsigned long copy_in_user(void __user *dst, const void __user *src, unsigned long len);
unsigned long __must_check __copy_to_user(void __user *dst, const void *src,
unsigned long len);
unsigned long __must_check __copy_from_user(void *dst, const void __user *src,
unsigned long len);
unsigned long copy_in_user(void __user *dst, const void __user *src,
unsigned long len);
#define __copy_in_user copy_in_user
#define __copy_to_user_inatomic __copy_to_user
#define __copy_from_user_inatomic __copy_from_user
Expand All @@ -217,23 +220,40 @@ static inline void copy_user_overflow(int size, unsigned long count)
WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count);
}

static inline unsigned long __must_check copy_from_user(void *to,
const void __user *from,
unsigned long n)
static __always_inline unsigned long __must_check
copy_from_user(void *to, const void __user *from, unsigned long n)
{
int sz = __compiletime_object_size(to);
unsigned long ret = n;
int sz = __compiletime_object_size(to);
unsigned long ret = n;

if (likely(sz == -1 || sz >= n))
ret = __copy_from_user(to, from, n);
else if (!__builtin_constant_p(n))
if (likely(sz < 0 || sz >= n)) {
check_object_size(to, n, false);
ret = __copy_from_user(to, from, n);
} else if (!__builtin_constant_p(n))
copy_user_overflow(sz, n);
else
__bad_copy_user();
__bad_copy_user();

if (unlikely(ret))
memset(to + (n - ret), 0, ret);
return ret;

return ret;
}

static __always_inline unsigned long __must_check
copy_to_user(void __user *to, const void *from, unsigned long n)
{
int sz = __compiletime_object_size(from);

if (likely(sz < 0 || sz >= n)) {
check_object_size(from, n, true);
n = __copy_to_user(to, from, n);
} else if (!__builtin_constant_p(n))
copy_user_overflow(sz, n);
else
__bad_copy_user();

return n;
}

struct pt_regs;
Expand Down
46 changes: 24 additions & 22 deletions arch/parisc/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,7 @@ ENTRY(end_fault_vector)
* copy_thread moved args into task save area.
*/

ENTRY(ret_from_kernel_thread)
ENTRY_CFI(ret_from_kernel_thread)

/* Call schedule_tail first though */
BL schedule_tail, %r2
Expand All @@ -782,15 +782,15 @@ ENTRY(ret_from_kernel_thread)
copy %r31, %r2
b finish_child_return
nop
ENDPROC(ret_from_kernel_thread)
ENDPROC_CFI(ret_from_kernel_thread)


/*
* struct task_struct *_switch_to(struct task_struct *prev,
* struct task_struct *next)
*
* switch kernel stacks and return prev */
ENTRY(_switch_to)
ENTRY_CFI(_switch_to)
STREG %r2, -RP_OFFSET(%r30)

callee_save_float
Expand All @@ -815,7 +815,7 @@ _switch_to_ret:
LDREG -RP_OFFSET(%r30), %r2
bv %r0(%r2)
copy %r26, %r28
ENDPROC(_switch_to)
ENDPROC_CFI(_switch_to)

/*
* Common rfi return path for interruptions, kernel execve, and
Expand All @@ -833,7 +833,7 @@ ENDPROC(_switch_to)

.align PAGE_SIZE

ENTRY(syscall_exit_rfi)
ENTRY_CFI(syscall_exit_rfi)
mfctl %cr30,%r16
LDREG TI_TASK(%r16), %r16 /* thread_info -> task_struct */
ldo TASK_REGS(%r16),%r16
Expand Down Expand Up @@ -1037,12 +1037,12 @@ intr_extint:

b do_cpu_irq_mask
ldo R%intr_return(%r2), %r2 /* return to intr_return, not here */
ENDPROC(syscall_exit_rfi)
ENDPROC_CFI(syscall_exit_rfi)


/* Generic interruptions (illegal insn, unaligned, page fault, etc) */

ENTRY(intr_save) /* for os_hpmc */
ENTRY_CFI(intr_save) /* for os_hpmc */
mfsp %sr7,%r16
cmpib,COND(=),n 0,%r16,1f
get_stack_use_cr30
Expand Down Expand Up @@ -1117,7 +1117,7 @@ skip_save_ior:

b handle_interruption
ldo R%intr_check_sig(%r2), %r2
ENDPROC(intr_save)
ENDPROC_CFI(intr_save)


/*
Expand Down Expand Up @@ -1720,23 +1720,23 @@ dtlb_fault:
.endm

.macro fork_like name
ENTRY(sys_\name\()_wrapper)
ENTRY_CFI(sys_\name\()_wrapper)
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
ldo TASK_REGS(%r1),%r1
reg_save %r1
mfctl %cr27, %r28
ldil L%sys_\name, %r31
be R%sys_\name(%sr4,%r31)
STREG %r28, PT_CR27(%r1)
ENDPROC(sys_\name\()_wrapper)
ENDPROC_CFI(sys_\name\()_wrapper)
.endm

fork_like clone
fork_like fork
fork_like vfork

/* Set the return value for the child */
ENTRY(child_return)
ENTRY_CFI(child_return)
BL schedule_tail, %r2
nop
finish_child_return:
Expand All @@ -1748,9 +1748,9 @@ finish_child_return:
reg_restore %r1
b syscall_exit
copy %r0,%r28
ENDPROC(child_return)
ENDPROC_CFI(child_return)

ENTRY(sys_rt_sigreturn_wrapper)
ENTRY_CFI(sys_rt_sigreturn_wrapper)
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26
ldo TASK_REGS(%r26),%r26 /* get pt regs */
/* Don't save regs, we are going to restore them from sigcontext. */
Expand Down Expand Up @@ -1778,9 +1778,9 @@ ENTRY(sys_rt_sigreturn_wrapper)
*/
bv %r0(%r2)
LDREG PT_GR28(%r1),%r28 /* reload original r28 for syscall_exit */
ENDPROC(sys_rt_sigreturn_wrapper)
ENDPROC_CFI(sys_rt_sigreturn_wrapper)

ENTRY(syscall_exit)
ENTRY_CFI(syscall_exit)
/* NOTE: Not all syscalls exit this way. rt_sigreturn will exit
* via syscall_exit_rfi if the signal was received while the process
* was running.
Expand Down Expand Up @@ -1979,7 +1979,7 @@ syscall_do_resched:
#else
nop
#endif
ENDPROC(syscall_exit)
ENDPROC_CFI(syscall_exit)


#ifdef CONFIG_FUNCTION_TRACER
Expand Down Expand Up @@ -2023,7 +2023,7 @@ ENDPROC(mcount)
.align 8
.globl return_to_handler
.type return_to_handler, @function
ENTRY(return_to_handler)
ENTRY_CFI(return_to_handler)
.proc
.callinfo caller,frame=FRAME_SIZE
.entry
Expand Down Expand Up @@ -2067,7 +2067,7 @@ parisc_return_to_handler:
LDREGM -FRAME_SIZE(%sp),%r3
.exit
.procend
ENDPROC(return_to_handler)
ENDPROC_CFI(return_to_handler)

#endif /* CONFIG_FUNCTION_GRAPH_TRACER */

Expand All @@ -2076,7 +2076,7 @@ ENDPROC(return_to_handler)
#ifdef CONFIG_IRQSTACKS
/* void call_on_stack(unsigned long param1, void *func,
unsigned long new_stack) */
ENTRY(call_on_stack)
ENTRY_CFI(call_on_stack)
copy %sp, %r1

/* Regarding the HPPA calling conventions for function pointers,
Expand Down Expand Up @@ -2112,10 +2112,10 @@ ENTRY(call_on_stack)
bv (%rp)
LDREG -68(%sp), %sp
# endif /* CONFIG_64BIT */
ENDPROC(call_on_stack)
ENDPROC_CFI(call_on_stack)
#endif /* CONFIG_IRQSTACKS */

get_register:
ENTRY_CFI(get_register)
/*
* get_register is used by the non access tlb miss handlers to
* copy the value of the general register specified in r8 into
Expand Down Expand Up @@ -2192,9 +2192,10 @@ get_register:
copy %r30,%r1
bv %r0(%r25) /* r31 */
copy %r31,%r1
ENDPROC_CFI(get_register)


set_register:
ENTRY_CFI(set_register)
/*
* set_register is used by the non access tlb miss handlers to
* copy the value of r1 into the general register specified in
Expand Down Expand Up @@ -2266,4 +2267,5 @@ set_register:
copy %r1,%r30
bv %r0(%r25) /* r31 */
copy %r1,%r31
ENDPROC_CFI(set_register)

Loading

0 comments on commit 997b611

Please sign in to comment.