Commit e52a9027 authored by David S. Miller's avatar David S. Miller

Merge nuts.ninka.net:/home/davem/src/BK/sparcwork-2.5

into nuts.ninka.net:/home/davem/src/BK/sparc-2.5
parents 5a7728c6 130f7f92
......@@ -90,38 +90,6 @@ struct rt_signal_frame {
__siginfo_fpu_t fpu_state;
};
int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
{
if (!access_ok(VERIFY_WRITE, to, sizeof(siginfo_t)))
return -EFAULT;
if (from->si_code < 0)
return __copy_to_user(to, from, sizeof(siginfo_t));
else {
int err;
/* If you change siginfo_t structure, please be sure
this code is fixed accordingly.
It should never copy any pad contained in the structure
to avoid security leaks, but must copy the generic
3 ints plus the relevant union member. */
err = __put_user(from->si_signo, &to->si_signo);
err |= __put_user(from->si_errno, &to->si_errno);
err |= __put_user((short)from->si_code, &to->si_code);
switch (from->si_code >> 16) {
case __SI_CHLD >> 16:
err |= __put_user(from->si_utime, &to->si_utime);
err |= __put_user(from->si_stime, &to->si_stime);
/* case __SI_RT: This is not generated by the kernel as of now. */
err |= __put_user(from->si_status, &to->si_status);
default:
err |= __put_user(from->si_uid, &to->si_uid);
err |= __put_user(from->si_pid, &to->si_pid);
break;
}
return err;
}
}
/* Align macros */
#define SF_ALIGNEDSZ (((sizeof(struct signal_sframe) + 7) & (~7)))
#define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame) + 7) & (~7)))
......
......@@ -36,38 +36,6 @@
static int do_signal(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_o0, int ret_from_syscall);
int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
{
if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
return -EFAULT;
if (from->si_code < 0)
return __copy_to_user(to, from, sizeof(siginfo_t));
else {
int err;
/* If you change siginfo_t structure, please be sure
this code is fixed accordingly.
It should never copy any pad contained in the structure
to avoid security leaks, but must copy the generic
3 ints plus the relevant union member. */
err = __put_user(*(long *)&from->si_signo, (long *)&to->si_signo);
err |= __put_user((short)from->si_code, &to->si_code);
switch (from->si_code >> 16) {
case __SI_CHLD >> 16:
err |= __put_user(from->si_utime, &to->si_utime);
err |= __put_user(from->si_stime, &to->si_stime);
case __SI_FAULT >> 16:
case __SI_POLL >> 16:
err |= __put_user(from->si_trapno, &to->si_trapno);
default:
err |= __put_user(from->si_addr, &to->si_addr);
break;
/* case __SI_RT: This is not generated by the kernel as of now. */
}
return err;
}
}
/* {set, get}context() needed for 64-bit SparcLinux userland. */
asmlinkage void sparc64_set_context(struct pt_regs *regs)
{
......
......@@ -7,6 +7,8 @@
#ifdef __KERNEL__
#include <asm/visasm.h>
#include <asm/asi.h>
#include <asm/dcu.h>
#include <asm/spitfire.h>
#undef SMALL_COPY_USES_FPU
#define EXNV(x,y,a,b) \
98: x,y; \
......@@ -181,6 +183,16 @@ U3copy_from_user_enter:
.align 64
U3copy_from_user_begin:
#ifdef __KERNEL__
.globl U3copy_from_user_nop_1_6
U3copy_from_user_nop_1_6:
ldxa [%g0] ASI_DCU_CONTROL_REG, %g3
sethi %uhi(DCU_PE), %o3
sllx %o3, 32, %o3
or %g3, %o3, %o3
stxa %o3, [%g0] ASI_DCU_CONTROL_REG ! Enable P-cache
membar #Sync
#endif
prefetcha [%o1 + 0x000] %asi, #one_read ! MS Group1
prefetcha [%o1 + 0x040] %asi, #one_read ! MS Group2
andn %o2, (0x40 - 1), %o4 ! A0
......@@ -321,6 +333,13 @@ U3copy_from_user_loopfini:
stda %f16, [%o0] ASI_BLK_P ! MS
add %o0, 0x40, %o0 ! A0
add %o1, 0x40, %o1 ! A1
#ifdef __KERNEL__
.globl U3copy_from_user_nop_2_3
U3copy_from_user_nop_2_3:
mov PRIMARY_CONTEXT, %o3
stxa %g0, [%o3] ASI_DMMU ! Flush P-cache
stxa %g3, [%g0] ASI_DCU_CONTROL_REG ! Disable P-cache
#endif
membar #Sync ! MS Group26 (7-cycle stall)
/* Now we copy the (len modulo 64) bytes at the end.
......
......@@ -7,6 +7,8 @@
#ifdef __KERNEL__
#include <asm/visasm.h>
#include <asm/asi.h>
#include <asm/dcu.h>
#include <asm/spitfire.h>
#undef SMALL_COPY_USES_FPU
#define EXNV(x,y,a,b) \
98: x,y; \
......@@ -228,6 +230,16 @@ U3copy_to_user_enter:
.align 64
U3copy_to_user_begin:
#ifdef __KERNEL__
.globl U3copy_to_user_nop_1_6
U3copy_to_user_nop_1_6:
ldxa [%g0] ASI_DCU_CONTROL_REG, %g3
sethi %uhi(DCU_PE), %o3
sllx %o3, 32, %o3
or %g3, %o3, %o3
stxa %o3, [%g0] ASI_DCU_CONTROL_REG ! Enable P-cache
membar #Sync
#endif
prefetch [%o1 + 0x000], #one_read ! MS Group1
prefetch [%o1 + 0x040], #one_read ! MS Group2
andn %o2, (0x40 - 1), %o4 ! A0
......@@ -368,6 +380,13 @@ U3copy_to_user_loopfini:
EXBLK4(stda %f16, [%o0] ASI_BLK_AIUS) ! MS
add %o0, 0x40, %o0 ! A0
add %o1, 0x40, %o1 ! A1
#ifdef __KERNEL__
.globl U3copy_to_user_nop_2_3
U3copy_to_user_nop_2_3:
mov PRIMARY_CONTEXT, %o3
stxa %g0, [%o3] ASI_DMMU ! Flush P-cache
stxa %g3, [%g0] ASI_DCU_CONTROL_REG ! Disable P-cache
#endif
membar #Sync ! MS Group26 (7-cycle stall)
/* Now we copy the (len modulo 64) bytes at the end.
......
......@@ -7,6 +7,8 @@
#ifdef __KERNEL__
#include <asm/visasm.h>
#include <asm/asi.h>
#include <asm/dcu.h>
#include <asm/spitfire.h>
#undef SMALL_COPY_USES_FPU
#else
#define ASI_BLK_P 0xf0
......@@ -109,6 +111,16 @@ U3memcpy_enter:
.align 64
U3memcpy_begin:
#ifdef __KERNEL__
.globl U3memcpy_nop_1_6
U3memcpy_nop_1_6:
ldxa [%g0] ASI_DCU_CONTROL_REG, %g3
sethi %uhi(DCU_PE), %o3
sllx %o3, 32, %o3
or %g3, %o3, %o3
stxa %o3, [%g0] ASI_DCU_CONTROL_REG ! Enable P-cache
membar #Sync
#endif
prefetch [%o1 + 0x000], #one_read ! MS Group1
prefetch [%o1 + 0x040], #one_read ! MS Group2
andn %o2, (0x40 - 1), %o4 ! A0
......@@ -249,6 +261,13 @@ U3memcpy_loopfini:
stda %f16, [%o0] ASI_BLK_P ! MS
add %o0, 0x40, %o0 ! A0
add %o1, 0x40, %o1 ! A1
#ifdef __KERNEL__
.globl U3memcpy_nop_2_3
U3memcpy_nop_2_3:
mov PRIMARY_CONTEXT, %o3
stxa %g0, [%o3] ASI_DMMU ! Flush P-cache
stxa %g3, [%g0] ASI_DCU_CONTROL_REG ! Disable P-cache
#endif
membar #Sync ! MS Group26 (7-cycle stall)
/* Now we copy the (len modulo 64) bytes at the end.
......
......@@ -368,6 +368,28 @@ bcopy: or %o0, 0, %g3 ! IEU0 Group
or %g3, %lo(NOP), %g3; \
stw %g3, [%g2 + 0x4]; \
flush %g2;
#define ULTRA3_PCACHE_DO_NOP(symbol) \
sethi %hi(symbol##_nop_1_6), %g1; \
or %g1, %lo(symbol##_nop_1_6), %g1; \
sethi %hi(NOP), %g2; \
stw %g2, [%g1 + 0x00]; \
stw %g2, [%g1 + 0x04]; \
flush %g1 + 0x00; \
stw %g2, [%g1 + 0x08]; \
stw %g2, [%g1 + 0x0c]; \
flush %g1 + 0x08; \
stw %g2, [%g1 + 0x10]; \
stw %g2, [%g1 + 0x04]; \
flush %g1 + 0x10; \
sethi %hi(symbol##_nop_2_3), %g1; \
or %g1, %lo(symbol##_nop_2_3), %g1; \
stw %g2, [%g1 + 0x00]; \
stw %g2, [%g1 + 0x04]; \
flush %g1 + 0x00; \
stw %g2, [%g1 + 0x08]; \
flush %g1 + 0x08;
#include <asm/dcu.h>
.globl cheetah_patch_copyops
cheetah_patch_copyops:
......@@ -375,6 +397,17 @@ cheetah_patch_copyops:
ULTRA3_DO_PATCH(__copy_from_user, U3copy_from_user)
ULTRA3_DO_PATCH(__copy_to_user, U3copy_to_user)
ULTRA3_DO_PATCH(__copy_in_user, U3copy_in_user)
ldxa [%g0] ASI_DCU_CONTROL_REG, %g3
sethi %uhi(DCU_PE), %o3
sllx %o3, 32, %o3
andcc %g3, %o3, %g0
be,pn %xcc, pcache_disabled
nop
ULTRA3_PCACHE_DO_NOP(U3memcpy)
ULTRA3_PCACHE_DO_NOP(U3copy_from_user)
ULTRA3_PCACHE_DO_NOP(U3copy_to_user)
ULTRA3_PCACHE_DO_NOP(cheetah_copy_user_page)
pcache_disabled:
retl
nop
#undef BRANCH_ALWAYS
......
......@@ -9,6 +9,8 @@
#include <asm/visasm.h>
#include <asm/thread_info.h>
#include <asm/page.h>
#include <asm/dcu.h>
#include <asm/spitfire.h>
#include <asm/pgtable.h>
#define TOUCH(reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7) \
......@@ -111,6 +113,15 @@ cheetah_patch_1:
nop
cheetah_copy_user_page:
.globl cheetah_copy_user_page_nop_1_6
cheetah_copy_user_page_nop_1_6:
ldxa [%g0] ASI_DCU_CONTROL_REG, %g3
sethi %uhi(DCU_PE), %o2
sllx %o2, 32, %o2
or %g3, %o2, %o2
stxa %o2, [%g0] ASI_DCU_CONTROL_REG ! Enable P-cache
membar #Sync
sethi %hi((PAGE_SIZE/64)-7), %o2 ! A0 Group
prefetch [%o1 + 0x000], #one_read ! MS
or %o2, %lo((PAGE_SIZE/64)-7), %o2 ! A1 Group
......@@ -202,6 +213,11 @@ cheetah_copy_user_page:
fmovd %f12, %f44 ! FGA Group
fmovd %f14, %f46 ! FGA Group
stda %f32, [%o0] ASI_BLK_P ! MS
.globl cheetah_copy_user_page_nop_2_3
cheetah_copy_user_page_nop_2_3:
mov PRIMARY_CONTEXT, %o2
stxa %g0, [%o2] ASI_DMMU ! Flush P-cache
stxa %g3, [%g0] ASI_DCU_CONTROL_REG ! Disable P-cache
ba,a,pt %xcc, copy_user_page_continue
spitfire_copy_user_page:
......
......@@ -8,9 +8,21 @@ typedef union sigval {
void *sival_ptr;
} sigval_t;
/*
* This is the size (including padding) of the part of the
* struct siginfo that is before the union.
*/
#ifndef __ARCH_SI_PREAMBLE_SIZE
#define __ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int))
#endif
#define SI_MAX_SIZE 128
#ifndef SI_PAD_SIZE
#define SI_PAD_SIZE ((SI_MAX_SIZE/sizeof(int)) - 3)
#define SI_PAD_SIZE ((SI_MAX_SIZE - __ARCH_SI_PREAMBLE_SIZE) / sizeof(int))
#endif
#ifndef __ARCH_SI_UID_T
#define __ARCH_SI_UID_T uid_t
#endif
#ifndef HAVE_ARCH_SIGINFO_T
......@@ -26,7 +38,7 @@ typedef struct siginfo {
/* kill() */
struct {
pid_t _pid; /* sender's pid */
uid_t _uid; /* sender's uid */
__ARCH_SI_UID_T _uid; /* sender's uid */
} _kill;
/* POSIX.1b timers */
......@@ -38,14 +50,14 @@ typedef struct siginfo {
/* POSIX.1b signals */
struct {
pid_t _pid; /* sender's pid */
uid_t _uid; /* sender's uid */
__ARCH_SI_UID_T _uid; /* sender's uid */
sigval_t _sigval;
} _rt;
/* SIGCHLD */
struct {
pid_t _pid; /* which child */
uid_t _uid; /* sender's uid */
__ARCH_SI_UID_T _uid; /* sender's uid */
int _status; /* exit code */
clock_t _utime;
clock_t _stime;
......@@ -54,6 +66,9 @@ typedef struct siginfo {
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
struct {
void *_addr; /* faulting insn/memory ref. */
#ifdef __ARCH_SI_TRAPNO
int _trapno; /* TRAP # which caused the signal */
#endif
} _sigfault;
/* SIGPOLL */
......@@ -80,6 +95,9 @@ typedef struct siginfo {
#define si_int _sifields._rt._sigval.sival_int
#define si_ptr _sifields._rt._sigval.sival_ptr
#define si_addr _sifields._sigfault._addr
#ifdef __ARCH_SI_TRAPNO
#define si_trapno _sifields._sigfault._trapno
#endif
#define si_band _sifields._sigpoll._band
#define si_fd _sifields._sigpoll._fd
......@@ -244,7 +262,7 @@ static inline void copy_siginfo(struct siginfo *to, struct siginfo *from)
memcpy(to, from, sizeof(*to));
else
/* _sigchld is currently the largest know union member */
memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
memcpy(to, from, __ARCH_SI_PREAMBLE_SIZE + sizeof(from->_sifields._sigchld));
}
#endif
......
......@@ -5,64 +5,11 @@
#ifndef _SPARC_SIGINFO_H
#define _SPARC_SIGINFO_H
#define HAVE_ARCH_SIGINFO_T
#define HAVE_ARCH_COPY_SIGINFO
#define HAVE_ARCH_COPY_SIGINFO_TO_USER
#define __ARCH_SI_UID_T unsigned int
#define __ARCH_SI_TRAPNO
#include <asm-generic/siginfo.h>
typedef struct siginfo {
int si_signo;
int si_errno;
int si_code;
union {
int _pad[SI_PAD_SIZE];
/* kill() */
struct {
pid_t _pid; /* sender's pid */
unsigned int _uid; /* sender's uid */
} _kill;
/* POSIX.1b timers */
struct {
unsigned int _timer1;
unsigned int _timer2;
} _timer;
/* POSIX.1b signals */
struct {
pid_t _pid; /* sender's pid */
unsigned int _uid; /* sender's uid */
sigval_t _sigval;
} _rt;
/* SIGCHLD */
struct {
pid_t _pid; /* which child */
unsigned int _uid; /* sender's uid */
int _status; /* exit code */
clock_t _utime;
clock_t _stime;
} _sigchld;
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */
struct {
void *_addr; /* faulting insn/memory ref. */
int _trapno; /* TRAP # which caused the signal */
} _sigfault;
/* SIGPOLL */
struct {
int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
int _fd;
} _sigpoll;
} _sifields;
} siginfo_t;
#define si_trapno _sifields._sigfault._trapno
#define SI_NOINFO 32767 /* no information in siginfo_t */
/*
......@@ -71,19 +18,4 @@ typedef struct siginfo {
#define EMT_TAGOVF (__SI_FAULT|1) /* tag overflow */
#define NSIGEMT 1
#ifdef __KERNEL__
#include <linux/string.h>
extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
{
if (from->si_code < 0)
*to = *from;
else
/* _sigchld is currently the largest know union member */
memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
}
#endif /* __KERNEL__ */
#endif /* !(_SPARC_SIGINFO_H) */
#ifndef _SPARC64_SIGINFO_H
#define _SPARC64_SIGINFO_H
#define SI_PAD_SIZE ((SI_MAX_SIZE/sizeof(int)) - 4)
#define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3)
#define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 4)
#define SIGEV_PAD_SIZE32 ((SIGEV_MAX_SIZE/sizeof(int)) - 3)
#define HAVE_ARCH_SIGINFO_T
#define HAVE_ARCH_COPY_SIGINFO
#define HAVE_ARCH_COPY_SIGINFO_TO_USER
#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
#define __ARCH_SI_TRAPNO
#include <asm-generic/siginfo.h>
......@@ -20,60 +18,6 @@ typedef union sigval32 {
u32 sival_ptr;
} sigval_t32;
#endif /* __KERNEL__ */
typedef struct siginfo {
int si_signo;
int si_errno;
int si_code;
union {
int _pad[SI_PAD_SIZE];
/* kill() */
struct {
pid_t _pid; /* sender's pid */
uid_t _uid; /* sender's uid */
} _kill;
/* POSIX.1b timers */
struct {
unsigned int _timer1;
unsigned int _timer2;
} _timer;
/* POSIX.1b signals */
struct {
pid_t _pid; /* sender's pid */
uid_t _uid; /* sender's uid */
sigval_t _sigval;
} _rt;
/* SIGCHLD */
struct {
pid_t _pid; /* which child */
uid_t _uid; /* sender's uid */
int _status; /* exit code */
clock_t _utime;
clock_t _stime;
} _sigchld;
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */
struct {
void *_addr; /* faulting insn/memory ref. */
int _trapno; /* TRAP # which caused the signal */
} _sigfault;
/* SIGPOLL */
struct {
long _band; /* POLL_IN, POLL_OUT, POLL_MSG */
int _fd;
} _sigpoll;
} _sifields;
} siginfo_t;
#ifdef __KERNEL__
typedef struct siginfo32 {
int si_signo;
int si_errno;
......@@ -126,8 +70,6 @@ typedef struct siginfo32 {
#endif /* __KERNEL__ */
#define si_trapno _sifields._sigfault._trapno
#define SI_NOINFO 32767 /* no information in siginfo_t */
/*
......@@ -152,17 +94,6 @@ typedef struct sigevent32 {
} _sigev_un;
} sigevent_t32;
#include <linux/string.h>
static inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
{
if (from->si_code < 0)
*to = *from;
else
/* _sigchld is currently the largest know union member */
memcpy(to, from, 4*sizeof(int) + sizeof(from->_sifields._sigchld));
}
extern int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from);
#endif /* __KERNEL__ */
......
......@@ -1427,6 +1427,9 @@ int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
break;
case __SI_FAULT:
err |= __put_user(from->si_addr, &to->si_addr);
#ifdef __ARCH_SI_TRAPNO
err |= __put_user(from->si_trapno, &to->si_trapno);
#endif
break;
case __SI_CHLD:
err |= __put_user(from->si_pid, &to->si_pid);
......
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