parisc architecture fixes for kernel 5.15-rc1:
* Build warning fixes in Makefile and Dino PCI driver * Fix when sched_clock is marked unstable * Drop strnlen_user() in favour of generic version * Prevent kernel to write outside userspace signal stack * Remove CONFIG_SET_FS incl. KERNEL_DS and USER_DS from parisc and switch to __get/put_kernel_nofault() -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQS86RI+GtKfB8BJu973ErUQojoPXwUCYTsgrwAKCRD3ErUQojoP X+MNAP0Q3XAta0ySRrEiuuZKACD5lJgFwEglvrHW5MWKA2qTdwD/cJ2hYLb4jMSf ezMaiGvyFAOUf4Krk6Gopbp38wHHGw0= =j26N -----END PGP SIGNATURE----- Merge tag 'for-5.15/parisc-3' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux Pull parisc fixes from Helge Deller: - Build warning fixes in Makefile and Dino PCI driver - Fix when sched_clock is marked unstable - Drop strnlen_user() in favour of generic version - Prevent kernel to write outside userspace signal stack - Remove CONFIG_SET_FS including KERNEL_DS and USER_DS from parisc and switch to __get/put_kernel_nofault() * tag 'for-5.15/parisc-3' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux: parisc: Implement __get/put_kernel_nofault() parisc: Mark sched_clock unstable only if clocks are not syncronized parisc: Move pci_dev_is_behind_card_dino to where it is used parisc: Reduce sigreturn trampoline to 3 instructions parisc: Check user signal stack trampoline is inside TASK_SIZE parisc: Drop useless debug info and comments from signal.c parisc: Drop strnlen_user() in favour of generic version parisc: Add missing FORCE prerequisite in Makefile
This commit is contained in:
commit
23ef827c1b
|
@ -10,7 +10,6 @@ config PARISC
|
|||
select ARCH_HAS_ELF_RANDOMIZE
|
||||
select ARCH_HAS_STRICT_KERNEL_RWX
|
||||
select ARCH_HAS_UBSAN_SANITIZE_ALL
|
||||
select ARCH_HAS_STRNLEN_USER
|
||||
select ARCH_NO_SG_CHAIN
|
||||
select ARCH_SUPPORTS_HUGETLBFS if PA20
|
||||
select ARCH_SUPPORTS_MEMORY_FAILURE
|
||||
|
@ -65,7 +64,6 @@ config PARISC
|
|||
select HAVE_KPROBES_ON_FTRACE
|
||||
select HAVE_DYNAMIC_FTRACE_WITH_REGS
|
||||
select HAVE_SOFTIRQ_ON_OWN_STACK if IRQSTACKS
|
||||
select SET_FS
|
||||
select TRACE_IRQFLAGS_SUPPORT
|
||||
|
||||
help
|
||||
|
|
|
@ -26,7 +26,7 @@ endif
|
|||
OBJECTS += $(obj)/head.o $(obj)/real2.o $(obj)/firmware.o $(obj)/misc.o $(obj)/piggy.o
|
||||
|
||||
LDFLAGS_vmlinux := -X -e startup --as-needed -T
|
||||
$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(LIBGCC)
|
||||
$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(LIBGCC) FORCE
|
||||
$(call if_changed,ld)
|
||||
|
||||
sed-sizes := -e 's/^\([0-9a-fA-F]*\) . \(__bss_start\|_end\|parisc_kernel_start\)$$/\#define SZ\2 0x\1/p'
|
||||
|
@ -34,7 +34,7 @@ sed-sizes := -e 's/^\([0-9a-fA-F]*\) . \(__bss_start\|_end\|parisc_kernel_start\
|
|||
quiet_cmd_sizes = GEN $@
|
||||
cmd_sizes = $(NM) $< | sed -n $(sed-sizes) > $@
|
||||
|
||||
$(obj)/sizes.h: vmlinux
|
||||
$(obj)/sizes.h: vmlinux FORCE
|
||||
$(call if_changed,sizes)
|
||||
|
||||
AFLAGS_head.o += -I$(objtree)/$(obj) -DBOOTLOADER
|
||||
|
@ -70,19 +70,19 @@ suffix-$(CONFIG_KERNEL_LZMA) := lzma
|
|||
suffix-$(CONFIG_KERNEL_LZO) := lzo
|
||||
suffix-$(CONFIG_KERNEL_XZ) := xz
|
||||
|
||||
$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y)
|
||||
$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) FORCE
|
||||
$(call if_changed,gzip)
|
||||
$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y)
|
||||
$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
|
||||
$(call if_changed,bzip2)
|
||||
$(obj)/vmlinux.bin.lz4: $(vmlinux.bin.all-y)
|
||||
$(obj)/vmlinux.bin.lz4: $(vmlinux.bin.all-y) FORCE
|
||||
$(call if_changed,lz4)
|
||||
$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y)
|
||||
$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
|
||||
$(call if_changed,lzma)
|
||||
$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y)
|
||||
$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) FORCE
|
||||
$(call if_changed,lzo)
|
||||
$(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y)
|
||||
$(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) FORCE
|
||||
$(call if_changed,xzkern)
|
||||
|
||||
LDFLAGS_piggy.o := -r --format binary --oformat $(LD_BFD) -T
|
||||
$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y)
|
||||
$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE
|
||||
$(call if_changed,ld)
|
||||
|
|
|
@ -101,10 +101,6 @@ DECLARE_PER_CPU(struct cpuinfo_parisc, cpu_data);
|
|||
|
||||
#define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF)
|
||||
|
||||
typedef struct {
|
||||
int seg;
|
||||
} mm_segment_t;
|
||||
|
||||
#define ARCH_MIN_TASKALIGN 8
|
||||
|
||||
struct thread_struct {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#ifndef _ASM_PARISC_RT_SIGFRAME_H
|
||||
#define _ASM_PARISC_RT_SIGFRAME_H
|
||||
|
||||
#define SIGRETURN_TRAMP 4
|
||||
#define SIGRETURN_TRAMP 3
|
||||
#define SIGRESTARTBLOCK_TRAMP 5
|
||||
#define TRAMP_SIZE (SIGRETURN_TRAMP + SIGRESTARTBLOCK_TRAMP)
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
struct thread_info {
|
||||
struct task_struct *task; /* main task structure */
|
||||
unsigned long flags; /* thread_info flags (see TIF_*) */
|
||||
mm_segment_t addr_limit; /* user-level address space limit */
|
||||
__u32 cpu; /* current CPU */
|
||||
int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */
|
||||
};
|
||||
|
@ -21,7 +20,6 @@ struct thread_info {
|
|||
.task = &tsk, \
|
||||
.flags = 0, \
|
||||
.cpu = 0, \
|
||||
.addr_limit = KERNEL_DS, \
|
||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||
}
|
||||
|
||||
|
|
|
@ -11,14 +11,6 @@
|
|||
#include <linux/bug.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#define KERNEL_DS ((mm_segment_t){0})
|
||||
#define USER_DS ((mm_segment_t){1})
|
||||
|
||||
#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
|
||||
|
||||
#define get_fs() (current_thread_info()->addr_limit)
|
||||
#define set_fs(x) (current_thread_info()->addr_limit = (x))
|
||||
|
||||
/*
|
||||
* Note that since kernel addresses are in a separate address space on
|
||||
* parisc, we don't need to do anything for access_ok().
|
||||
|
@ -33,11 +25,11 @@
|
|||
#define get_user __get_user
|
||||
|
||||
#if !defined(CONFIG_64BIT)
|
||||
#define LDD_USER(val, ptr) __get_user_asm64(val, ptr)
|
||||
#define STD_USER(x, ptr) __put_user_asm64(x, ptr)
|
||||
#define LDD_USER(sr, val, ptr) __get_user_asm64(sr, val, ptr)
|
||||
#define STD_USER(sr, x, ptr) __put_user_asm64(sr, x, ptr)
|
||||
#else
|
||||
#define LDD_USER(val, ptr) __get_user_asm(val, "ldd", ptr)
|
||||
#define STD_USER(x, ptr) __put_user_asm("std", x, ptr)
|
||||
#define LDD_USER(sr, val, ptr) __get_user_asm(sr, val, "ldd", ptr)
|
||||
#define STD_USER(sr, x, ptr) __put_user_asm(sr, "std", x, ptr)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -67,28 +59,15 @@ struct exception_table_entry {
|
|||
#define ASM_EXCEPTIONTABLE_ENTRY_EFAULT( fault_addr, except_addr )\
|
||||
ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr + 1)
|
||||
|
||||
/*
|
||||
* load_sr2() preloads the space register %%sr2 - based on the value of
|
||||
* get_fs() - with either a value of 0 to access kernel space (KERNEL_DS which
|
||||
* is 0), or with the current value of %%sr3 to access user space (USER_DS)
|
||||
* memory. The following __get_user_asm() and __put_user_asm() functions have
|
||||
* %%sr2 hard-coded to access the requested memory.
|
||||
*/
|
||||
#define load_sr2() \
|
||||
__asm__(" or,= %0,%%r0,%%r0\n\t" \
|
||||
" mfsp %%sr3,%0\n\t" \
|
||||
" mtsp %0,%%sr2\n\t" \
|
||||
: : "r"(get_fs()) : )
|
||||
|
||||
#define __get_user_internal(val, ptr) \
|
||||
#define __get_user_internal(sr, val, ptr) \
|
||||
({ \
|
||||
register long __gu_err __asm__ ("r8") = 0; \
|
||||
\
|
||||
switch (sizeof(*(ptr))) { \
|
||||
case 1: __get_user_asm(val, "ldb", ptr); break; \
|
||||
case 2: __get_user_asm(val, "ldh", ptr); break; \
|
||||
case 4: __get_user_asm(val, "ldw", ptr); break; \
|
||||
case 8: LDD_USER(val, ptr); break; \
|
||||
case 1: __get_user_asm(sr, val, "ldb", ptr); break; \
|
||||
case 2: __get_user_asm(sr, val, "ldh", ptr); break; \
|
||||
case 4: __get_user_asm(sr, val, "ldw", ptr); break; \
|
||||
case 8: LDD_USER(sr, val, ptr); break; \
|
||||
default: BUILD_BUG(); \
|
||||
} \
|
||||
\
|
||||
|
@ -97,15 +76,14 @@ struct exception_table_entry {
|
|||
|
||||
#define __get_user(val, ptr) \
|
||||
({ \
|
||||
load_sr2(); \
|
||||
__get_user_internal(val, ptr); \
|
||||
__get_user_internal("%%sr3,", val, ptr); \
|
||||
})
|
||||
|
||||
#define __get_user_asm(val, ldx, ptr) \
|
||||
#define __get_user_asm(sr, val, ldx, ptr) \
|
||||
{ \
|
||||
register long __gu_val; \
|
||||
\
|
||||
__asm__("1: " ldx " 0(%%sr2,%2),%0\n" \
|
||||
__asm__("1: " ldx " 0(" sr "%2),%0\n" \
|
||||
"9:\n" \
|
||||
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
|
||||
: "=r"(__gu_val), "=r"(__gu_err) \
|
||||
|
@ -114,9 +92,22 @@ struct exception_table_entry {
|
|||
(val) = (__force __typeof__(*(ptr))) __gu_val; \
|
||||
}
|
||||
|
||||
#define HAVE_GET_KERNEL_NOFAULT
|
||||
#define __get_kernel_nofault(dst, src, type, err_label) \
|
||||
{ \
|
||||
type __z; \
|
||||
long __err; \
|
||||
__err = __get_user_internal("%%sr0,", __z, (type *)(src)); \
|
||||
if (unlikely(__err)) \
|
||||
goto err_label; \
|
||||
else \
|
||||
*(type *)(dst) = __z; \
|
||||
}
|
||||
|
||||
|
||||
#if !defined(CONFIG_64BIT)
|
||||
|
||||
#define __get_user_asm64(val, ptr) \
|
||||
#define __get_user_asm64(sr, val, ptr) \
|
||||
{ \
|
||||
union { \
|
||||
unsigned long long l; \
|
||||
|
@ -124,8 +115,8 @@ struct exception_table_entry {
|
|||
} __gu_tmp; \
|
||||
\
|
||||
__asm__(" copy %%r0,%R0\n" \
|
||||
"1: ldw 0(%%sr2,%2),%0\n" \
|
||||
"2: ldw 4(%%sr2,%2),%R0\n" \
|
||||
"1: ldw 0(" sr "%2),%0\n" \
|
||||
"2: ldw 4(" sr "%2),%R0\n" \
|
||||
"9:\n" \
|
||||
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
|
||||
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \
|
||||
|
@ -138,16 +129,16 @@ struct exception_table_entry {
|
|||
#endif /* !defined(CONFIG_64BIT) */
|
||||
|
||||
|
||||
#define __put_user_internal(x, ptr) \
|
||||
#define __put_user_internal(sr, x, ptr) \
|
||||
({ \
|
||||
register long __pu_err __asm__ ("r8") = 0; \
|
||||
__typeof__(*(ptr)) __x = (__typeof__(*(ptr)))(x); \
|
||||
\
|
||||
switch (sizeof(*(ptr))) { \
|
||||
case 1: __put_user_asm("stb", __x, ptr); break; \
|
||||
case 2: __put_user_asm("sth", __x, ptr); break; \
|
||||
case 4: __put_user_asm("stw", __x, ptr); break; \
|
||||
case 8: STD_USER(__x, ptr); break; \
|
||||
case 1: __put_user_asm(sr, "stb", __x, ptr); break; \
|
||||
case 2: __put_user_asm(sr, "sth", __x, ptr); break; \
|
||||
case 4: __put_user_asm(sr, "stw", __x, ptr); break; \
|
||||
case 8: STD_USER(sr, __x, ptr); break; \
|
||||
default: BUILD_BUG(); \
|
||||
} \
|
||||
\
|
||||
|
@ -156,10 +147,20 @@ struct exception_table_entry {
|
|||
|
||||
#define __put_user(x, ptr) \
|
||||
({ \
|
||||
load_sr2(); \
|
||||
__put_user_internal(x, ptr); \
|
||||
__put_user_internal("%%sr3,", x, ptr); \
|
||||
})
|
||||
|
||||
#define __put_kernel_nofault(dst, src, type, err_label) \
|
||||
{ \
|
||||
type __z = *(type *)(src); \
|
||||
long __err; \
|
||||
__err = __put_user_internal("%%sr0,", __z, (type *)(dst)); \
|
||||
if (unlikely(__err)) \
|
||||
goto err_label; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* The "__put_user/kernel_asm()" macros tell gcc they read from memory
|
||||
|
@ -170,26 +171,26 @@ struct exception_table_entry {
|
|||
* r8 is already listed as err.
|
||||
*/
|
||||
|
||||
#define __put_user_asm(stx, x, ptr) \
|
||||
__asm__ __volatile__ ( \
|
||||
"1: " stx " %2,0(%%sr2,%1)\n" \
|
||||
"9:\n" \
|
||||
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
|
||||
: "=r"(__pu_err) \
|
||||
#define __put_user_asm(sr, stx, x, ptr) \
|
||||
__asm__ __volatile__ ( \
|
||||
"1: " stx " %2,0(" sr "%1)\n" \
|
||||
"9:\n" \
|
||||
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
|
||||
: "=r"(__pu_err) \
|
||||
: "r"(ptr), "r"(x), "0"(__pu_err))
|
||||
|
||||
|
||||
#if !defined(CONFIG_64BIT)
|
||||
|
||||
#define __put_user_asm64(__val, ptr) do { \
|
||||
__asm__ __volatile__ ( \
|
||||
"1: stw %2,0(%%sr2,%1)\n" \
|
||||
"2: stw %R2,4(%%sr2,%1)\n" \
|
||||
"9:\n" \
|
||||
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
|
||||
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \
|
||||
: "=r"(__pu_err) \
|
||||
: "r"(ptr), "r"(__val), "0"(__pu_err)); \
|
||||
#define __put_user_asm64(sr, __val, ptr) do { \
|
||||
__asm__ __volatile__ ( \
|
||||
"1: stw %2,0(" sr "%1)\n" \
|
||||
"2: stw %R2,4(" sr "%1)\n" \
|
||||
"9:\n" \
|
||||
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
|
||||
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \
|
||||
: "=r"(__pu_err) \
|
||||
: "r"(ptr), "r"(__val), "0"(__pu_err)); \
|
||||
} while (0)
|
||||
|
||||
#endif /* !defined(CONFIG_64BIT) */
|
||||
|
@ -200,14 +201,12 @@ struct exception_table_entry {
|
|||
*/
|
||||
|
||||
extern long strncpy_from_user(char *, const char __user *, long);
|
||||
extern unsigned lclear_user(void __user *, unsigned long);
|
||||
extern long lstrnlen_user(const char __user *, long);
|
||||
extern __must_check unsigned lclear_user(void __user *, unsigned long);
|
||||
extern __must_check long strnlen_user(const char __user *src, long n);
|
||||
/*
|
||||
* Complex access routines -- macros
|
||||
*/
|
||||
#define user_addr_max() (~0UL)
|
||||
|
||||
#define strnlen_user lstrnlen_user
|
||||
#define clear_user lclear_user
|
||||
#define __clear_user lclear_user
|
||||
|
||||
|
|
|
@ -230,7 +230,6 @@ int main(void)
|
|||
DEFINE(TI_TASK, offsetof(struct thread_info, task));
|
||||
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
|
||||
DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
|
||||
DEFINE(TI_SEGMENT, offsetof(struct thread_info, addr_limit));
|
||||
DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
|
||||
DEFINE(THREAD_SZ, sizeof(struct thread_info));
|
||||
/* THREAD_SZ_ALGN includes space for a stack frame. */
|
||||
|
|
|
@ -32,7 +32,6 @@ EXPORT_SYMBOL(__xchg64);
|
|||
|
||||
#include <linux/uaccess.h>
|
||||
EXPORT_SYMBOL(lclear_user);
|
||||
EXPORT_SYMBOL(lstrnlen_user);
|
||||
|
||||
#ifndef CONFIG_64BIT
|
||||
/* Needed so insmod can set dp value */
|
||||
|
|
|
@ -150,8 +150,6 @@ void __init setup_arch(char **cmdline_p)
|
|||
#ifdef CONFIG_PA11
|
||||
dma_ops_init();
|
||||
#endif
|
||||
|
||||
clear_sched_clock_stable();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -237,18 +237,22 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
|
|||
#endif
|
||||
|
||||
usp = (regs->gr[30] & ~(0x01UL));
|
||||
sigframe_size = PARISC_RT_SIGFRAME_SIZE;
|
||||
#ifdef CONFIG_64BIT
|
||||
if (is_compat_task()) {
|
||||
/* The gcc alloca implementation leaves garbage in the upper 32 bits of sp */
|
||||
usp = (compat_uint_t)usp;
|
||||
sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
|
||||
}
|
||||
#endif
|
||||
/*FIXME: frame_size parameter is unused, remove it. */
|
||||
frame = get_sigframe(&ksig->ka, usp, sizeof(*frame));
|
||||
frame = get_sigframe(&ksig->ka, usp, sigframe_size);
|
||||
|
||||
DBG(1,"SETUP_RT_FRAME: START\n");
|
||||
DBG(1,"setup_rt_frame: frame %p info %p\n", frame, ksig->info);
|
||||
|
||||
start = (unsigned long) frame;
|
||||
if (start >= user_addr_max() - sigframe_size)
|
||||
return -EFAULT;
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
|
||||
|
@ -284,32 +288,21 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
|
|||
already in userspace. The first words of tramp are used to
|
||||
save the previous sigrestartblock trampoline that might be
|
||||
on the stack. We start the sigreturn trampoline at
|
||||
SIGRESTARTBLOCK_TRAMP+X. */
|
||||
SIGRESTARTBLOCK_TRAMP. */
|
||||
err |= __put_user(in_syscall ? INSN_LDI_R25_1 : INSN_LDI_R25_0,
|
||||
&frame->tramp[SIGRESTARTBLOCK_TRAMP+0]);
|
||||
err |= __put_user(INSN_LDI_R20,
|
||||
&frame->tramp[SIGRESTARTBLOCK_TRAMP+1]);
|
||||
err |= __put_user(INSN_BLE_SR2_R0,
|
||||
&frame->tramp[SIGRESTARTBLOCK_TRAMP+1]);
|
||||
err |= __put_user(INSN_LDI_R20,
|
||||
&frame->tramp[SIGRESTARTBLOCK_TRAMP+2]);
|
||||
err |= __put_user(INSN_NOP, &frame->tramp[SIGRESTARTBLOCK_TRAMP+3]);
|
||||
|
||||
#if DEBUG_SIG
|
||||
/* Assert that we're flushing in the correct space... */
|
||||
{
|
||||
unsigned long sid;
|
||||
asm ("mfsp %%sr3,%0" : "=r" (sid));
|
||||
DBG(1,"setup_rt_frame: Flushing 64 bytes at space %#x offset %p\n",
|
||||
sid, frame->tramp);
|
||||
}
|
||||
#endif
|
||||
|
||||
start = (unsigned long) &frame->tramp[0];
|
||||
end = (unsigned long) &frame->tramp[TRAMP_SIZE];
|
||||
start = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP+0];
|
||||
end = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP+3];
|
||||
flush_user_dcache_range_asm(start, end);
|
||||
flush_user_icache_range_asm(start, end);
|
||||
|
||||
/* TRAMP Words 0-4, Length 5 = SIGRESTARTBLOCK_TRAMP
|
||||
* TRAMP Words 5-9, Length 4 = SIGRETURN_TRAMP
|
||||
* TRAMP Words 5-7, Length 3 = SIGRETURN_TRAMP
|
||||
* So the SIGRETURN_TRAMP is at the end of SIGRESTARTBLOCK_TRAMP
|
||||
*/
|
||||
rp = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP];
|
||||
|
@ -353,11 +346,6 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
|
|||
|
||||
/* The syscall return path will create IAOQ values from r31.
|
||||
*/
|
||||
sigframe_size = PARISC_RT_SIGFRAME_SIZE;
|
||||
#ifdef CONFIG_64BIT
|
||||
if (is_compat_task())
|
||||
sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
|
||||
#endif
|
||||
if (in_syscall) {
|
||||
regs->gr[31] = haddr;
|
||||
#ifdef CONFIG_64BIT
|
||||
|
@ -501,7 +489,6 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
|
|||
DBG(1,"ERESTARTNOHAND: returning -EINTR\n");
|
||||
regs->gr[28] = -EINTR;
|
||||
break;
|
||||
|
||||
case -ERESTARTSYS:
|
||||
if (!(ka->sa.sa_flags & SA_RESTART)) {
|
||||
DBG(1,"ERESTARTSYS: putting -EINTR\n");
|
||||
|
@ -529,6 +516,10 @@ insert_restart_trampoline(struct pt_regs *regs)
|
|||
unsigned long end = (unsigned long) &usp[5];
|
||||
long err = 0;
|
||||
|
||||
/* check that we don't exceed the stack */
|
||||
if (A(&usp[0]) >= user_addr_max() - 5 * sizeof(int))
|
||||
return;
|
||||
|
||||
/* Setup a trampoline to restart the syscall
|
||||
* with __NR_restart_syscall
|
||||
*
|
||||
|
@ -569,10 +560,6 @@ insert_restart_trampoline(struct pt_regs *regs)
|
|||
}
|
||||
|
||||
/*
|
||||
* Note that 'init' is a special process: it doesn't get signals it doesn't
|
||||
* want to handle. Thus you cannot kill init even with a SIGKILL even by
|
||||
* mistake.
|
||||
*
|
||||
* We need to be able to restore the syscall arguments (r21-r26) to
|
||||
* restart syscalls. Thus, the syscall path should save them in the
|
||||
* pt_regs structure (it's okay to do so since they are caller-save
|
||||
|
|
|
@ -36,7 +36,7 @@ struct compat_regfile {
|
|||
compat_int_t rf_sar;
|
||||
};
|
||||
|
||||
#define COMPAT_SIGRETURN_TRAMP 4
|
||||
#define COMPAT_SIGRETURN_TRAMP 3
|
||||
#define COMPAT_SIGRESTARTBLOCK_TRAMP 5
|
||||
#define COMPAT_TRAMP_SIZE (COMPAT_SIGRETURN_TRAMP + \
|
||||
COMPAT_SIGRESTARTBLOCK_TRAMP)
|
||||
|
|
|
@ -265,6 +265,9 @@ static int __init init_cr16_clocksource(void)
|
|||
(cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc))
|
||||
continue;
|
||||
|
||||
/* mark sched_clock unstable */
|
||||
clear_sched_clock_stable();
|
||||
|
||||
clocksource_cr16.name = "cr16_unstable";
|
||||
clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE;
|
||||
clocksource_cr16.rating = 0;
|
||||
|
@ -272,10 +275,6 @@ static int __init init_cr16_clocksource(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* XXX: We may want to mark sched_clock stable here if cr16 clocks are
|
||||
* in sync:
|
||||
* (clocksource_cr16.flags == CLOCK_SOURCE_IS_CONTINUOUS) */
|
||||
|
||||
/* register at clocksource framework */
|
||||
clocksource_register_hz(&clocksource_cr16,
|
||||
100 * PAGE0->mem_10msec);
|
||||
|
|
|
@ -27,21 +27,6 @@
|
|||
#include <asm/errno.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
/*
|
||||
* get_sr gets the appropriate space value into
|
||||
* sr1 for kernel/user space access, depending
|
||||
* on the flag stored in the task structure.
|
||||
*/
|
||||
|
||||
.macro get_sr
|
||||
mfctl %cr30,%r1
|
||||
ldw TI_SEGMENT(%r1),%r22
|
||||
mfsp %sr3,%r1
|
||||
or,<> %r22,%r0,%r0
|
||||
copy %r0,%r1
|
||||
mtsp %r1,%sr1
|
||||
.endm
|
||||
|
||||
/*
|
||||
* unsigned long lclear_user(void *to, unsigned long n)
|
||||
*
|
||||
|
@ -51,10 +36,9 @@
|
|||
|
||||
ENTRY_CFI(lclear_user)
|
||||
comib,=,n 0,%r25,$lclu_done
|
||||
get_sr
|
||||
$lclu_loop:
|
||||
addib,<> -1,%r25,$lclu_loop
|
||||
1: stbs,ma %r0,1(%sr1,%r26)
|
||||
1: stbs,ma %r0,1(%sr3,%r26)
|
||||
|
||||
$lclu_done:
|
||||
bv %r0(%r2)
|
||||
|
@ -67,40 +51,6 @@ $lclu_done:
|
|||
ENDPROC_CFI(lclear_user)
|
||||
|
||||
|
||||
/*
|
||||
* long lstrnlen_user(char *s, long n)
|
||||
*
|
||||
* Returns 0 if exception before zero byte or reaching N,
|
||||
* N+1 if N would be exceeded,
|
||||
* else strlen + 1 (i.e. includes zero byte).
|
||||
*/
|
||||
|
||||
ENTRY_CFI(lstrnlen_user)
|
||||
comib,= 0,%r25,$lslen_nzero
|
||||
copy %r26,%r24
|
||||
get_sr
|
||||
1: ldbs,ma 1(%sr1,%r26),%r1
|
||||
$lslen_loop:
|
||||
comib,=,n 0,%r1,$lslen_done
|
||||
addib,<> -1,%r25,$lslen_loop
|
||||
2: ldbs,ma 1(%sr1,%r26),%r1
|
||||
$lslen_done:
|
||||
bv %r0(%r2)
|
||||
sub %r26,%r24,%r28
|
||||
|
||||
$lslen_nzero:
|
||||
b $lslen_done
|
||||
ldo 1(%r26),%r26 /* special case for N == 0 */
|
||||
|
||||
3: b $lslen_done
|
||||
copy %r24,%r26 /* reset r26 so 0 is returned on fault */
|
||||
|
||||
ASM_EXCEPTIONTABLE_ENTRY(1b,3b)
|
||||
ASM_EXCEPTIONTABLE_ENTRY(2b,3b)
|
||||
|
||||
ENDPROC_CFI(lstrnlen_user)
|
||||
|
||||
|
||||
/*
|
||||
* unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len)
|
||||
*
|
||||
|
|
|
@ -156,15 +156,6 @@ static inline struct dino_device *DINO_DEV(struct pci_hba_data *hba)
|
|||
return container_of(hba, struct dino_device, hba);
|
||||
}
|
||||
|
||||
/* Check if PCI device is behind a Card-mode Dino. */
|
||||
static int pci_dev_is_behind_card_dino(struct pci_dev *dev)
|
||||
{
|
||||
struct dino_device *dino_dev;
|
||||
|
||||
dino_dev = DINO_DEV(parisc_walk_tree(dev->bus->bridge));
|
||||
return is_card_dino(&dino_dev->hba.dev->id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Dino Configuration Space Accessor Functions
|
||||
*/
|
||||
|
@ -447,6 +438,15 @@ static void quirk_cirrus_cardbus(struct pci_dev *dev)
|
|||
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6832, quirk_cirrus_cardbus );
|
||||
|
||||
#ifdef CONFIG_TULIP
|
||||
/* Check if PCI device is behind a Card-mode Dino. */
|
||||
static int pci_dev_is_behind_card_dino(struct pci_dev *dev)
|
||||
{
|
||||
struct dino_device *dino_dev;
|
||||
|
||||
dino_dev = DINO_DEV(parisc_walk_tree(dev->bus->bridge));
|
||||
return is_card_dino(&dino_dev->hba.dev->id);
|
||||
}
|
||||
|
||||
static void pci_fixup_tulip(struct pci_dev *dev)
|
||||
{
|
||||
if (!pci_dev_is_behind_card_dino(dev))
|
||||
|
|
Loading…
Reference in New Issue