Commit 20237c4d authored by Anton Blanchard's avatar Anton Blanchard

Merge samba.org:/scratch/anton/linux-2.5

into samba.org:/scratch/anton/linux-2.5_ppc64
parents 50da7d0e dfe6d4c0
...@@ -59,15 +59,14 @@ unsigned long eeh_token(unsigned long phb, unsigned long bus, unsigned long devf ...@@ -59,15 +59,14 @@ unsigned long eeh_token(unsigned long phb, unsigned long bus, unsigned long devf
return ((IO_UNMAPPED_REGION_ID << 60) | (phb << 48UL) | ((bus & 0xff) << 40UL) | (devfn << 32UL) | (offset & 0xffffffff)); return ((IO_UNMAPPED_REGION_ID << 60) | (phb << 48UL) | ((bus & 0xff) << 40UL) | (devfn << 32UL) | (offset & 0xffffffff));
} }
int eeh_get_state(unsigned long ea)
{
int eeh_get_state(unsigned long ea) {
return 0; return 0;
} }
/* Check for an eeh failure at the given token address. /* Check for an eeh failure at the given token address.
* The given value has been read and it should be 1's (0xff, 0xffff or 0xffffffff). * The given value has been read and it should be 1's (0xff, 0xffff or
* 0xffffffff).
* *
* Probe to determine if an error actually occurred. If not return val. * Probe to determine if an error actually occurred. If not return val.
* Otherwise panic. * Otherwise panic.
...@@ -113,7 +112,8 @@ unsigned long eeh_check_failure(void *token, unsigned long val) ...@@ -113,7 +112,8 @@ unsigned long eeh_check_failure(void *token, unsigned long val)
return val; /* good case */ return val; /* good case */
} }
void eeh_init(void) { void eeh_init(void)
{
extern char cmd_line[]; /* Very early cmd line parse. Cheap, but works. */ extern char cmd_line[]; /* Very early cmd line parse. Cheap, but works. */
char *eeh_force_off = strstr(cmd_line, "eeh-force-off"); char *eeh_force_off = strstr(cmd_line, "eeh-force-off");
char *eeh_force_on = strstr(cmd_line, "eeh-force-on"); char *eeh_force_on = strstr(cmd_line, "eeh-force-on");
...@@ -121,7 +121,7 @@ void eeh_init(void) { ...@@ -121,7 +121,7 @@ void eeh_init(void) {
ibm_set_eeh_option = rtas_token("ibm,set-eeh-option"); ibm_set_eeh_option = rtas_token("ibm,set-eeh-option");
ibm_set_slot_reset = rtas_token("ibm,set-slot-reset"); ibm_set_slot_reset = rtas_token("ibm,set-slot-reset");
ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state"); ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state");
if (ibm_set_eeh_option != RTAS_UNKNOWN_SERVICE && naca->platform == PLATFORM_PSERIES_LPAR) if (ibm_set_eeh_option != RTAS_UNKNOWN_SERVICE)
eeh_implemented = 1; eeh_implemented = 1;
if (eeh_force_off > eeh_force_on) { if (eeh_force_off > eeh_force_on) {
...@@ -334,6 +334,7 @@ static int __init eehoff_parm(char *str) ...@@ -334,6 +334,7 @@ static int __init eehoff_parm(char *str)
{ {
return eeh_parm(str, 0); return eeh_parm(str, 0);
} }
static int __init eehon_parm(char *str) static int __init eehon_parm(char *str)
{ {
return eeh_parm(str, 1); return eeh_parm(str, 1);
......
...@@ -353,7 +353,7 @@ recheck: ...@@ -353,7 +353,7 @@ recheck:
li r4,0 li r4,0
ori r4,r4,MSR_EE|MSR_RI ori r4,r4,MSR_EE|MSR_RI
andc r10,r10,r4 /* clear MSR_EE and MSR_RI */ andc r10,r10,r4 /* clear MSR_EE and MSR_RI */
mtmsrd r10 /* Update machine state */ mtmsrd r10,1 /* Update machine state */
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
#error fix iSeries soft disable #error fix iSeries soft disable
...@@ -411,7 +411,7 @@ restore: ...@@ -411,7 +411,7 @@ restore:
do_work: do_work:
/* Enable interrupts */ /* Enable interrupts */
ori r10,r10,MSR_EE|MSR_RI ori r10,r10,MSR_EE|MSR_RI
mtmsrd r10 mtmsrd r10,1
andi. r0,r3,_TIF_NEED_RESCHED andi. r0,r3,_TIF_NEED_RESCHED
beq 1f beq 1f
......
...@@ -45,9 +45,7 @@ ...@@ -45,9 +45,7 @@
#include <asm/lmb.h> #include <asm/lmb.h>
#include <asm/abs_addr.h> #include <asm/abs_addr.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#ifdef CONFIG_PPC_EEH
#include <asm/eeh.h> #include <asm/eeh.h>
#endif
/* /*
* Note: pte --> Linux PTE * Note: pte --> Linux PTE
...@@ -346,13 +344,11 @@ int hash_page(unsigned long ea, unsigned long access) ...@@ -346,13 +344,11 @@ int hash_page(unsigned long ea, unsigned long access)
mm = &init_mm; mm = &init_mm;
vsid = get_kernel_vsid(ea); vsid = get_kernel_vsid(ea);
break; break;
#ifdef CONFIG_PPC_EEH
case IO_UNMAPPED_REGION_ID: case IO_UNMAPPED_REGION_ID:
udbg_printf("EEH Error ea = 0x%lx\n", ea); udbg_printf("EEH Error ea = 0x%lx\n", ea);
PPCDBG_ENTER_DEBUGGER(); PPCDBG_ENTER_DEBUGGER();
panic("EEH Error ea = 0x%lx\n", ea); panic("EEH Error ea = 0x%lx\n", ea);
break; break;
#endif
case KERNEL_REGION_ID: case KERNEL_REGION_ID:
/* /*
* As htab_initialize is now, we shouldn't ever get here since * As htab_initialize is now, we shouldn't ever get here since
......
...@@ -100,9 +100,6 @@ void proc_ppc64_init(void) ...@@ -100,9 +100,6 @@ void proc_ppc64_init(void)
if (!proc_ppc64_root) return; if (!proc_ppc64_root) return;
spin_unlock(&proc_ppc64_lock); spin_unlock(&proc_ppc64_lock);
#ifdef CONFIG_PPC_EEH
eeh_init_proc(proc_ppc64_root);
#endif
proc_ppc64_pmc_root = proc_mkdir("pmc", proc_ppc64_root); proc_ppc64_pmc_root = proc_mkdir("pmc", proc_ppc64_root);
......
...@@ -26,8 +26,6 @@ ...@@ -26,8 +26,6 @@
#include <linux/unistd.h> #include <linux/unistd.h>
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/elf.h> #include <linux/elf.h>
#include <linux/tty.h>
#include <linux/binfmts.h>
#include <asm/ppc32.h> #include <asm/ppc32.h>
#include <asm/sigcontext.h> #include <asm/sigcontext.h>
#include <asm/ucontext.h> #include <asm/ucontext.h>
...@@ -59,9 +57,36 @@ ...@@ -59,9 +57,36 @@
*/ */
#define MSR_USERCHANGE (MSR_FE0 | MSR_FE1) #define MSR_USERCHANGE (MSR_FE0 | MSR_FE1)
int do_signal(sigset_t *oldset, struct pt_regs *regs); /*
extern long sys_wait4(pid_t pid, unsigned int *stat_addr, * When we have signals to deliver, we set up on the
int options, /*unsigned long*/ struct rusage *ru); * user stack, going down from the original stack pointer:
* a sigregs struct
* one or more sigcontext structs with
* a gap of __SIGNAL_FRAMESIZE bytes
*
* Each of these things must be a multiple of 16 bytes in size.
*
*/
struct sigregs {
elf_gregset_t gp_regs;
double fp_regs[ELF_NFPREG];
unsigned int tramp[2];
/* 64 bit API allows for 288 bytes below sp before
decrementing it. */
int abigap[72];
};
struct rt_sigframe
{
unsigned long _unused[2];
struct siginfo *pinfo;
void *puc;
struct siginfo info;
struct ucontext uc;
};
extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
/* /*
* Atomically swap in the new signal mask, and wait for a signal. * Atomically swap in the new signal mask, and wait for a signal.
...@@ -127,7 +152,7 @@ long sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int ...@@ -127,7 +152,7 @@ long sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int
long sys_sigaltstack(const stack_t *uss, stack_t *uoss) long sys_sigaltstack(const stack_t *uss, stack_t *uoss)
{ {
struct pt_regs *regs = (struct pt_regs *) &uss; struct pt_regs *regs = (struct pt_regs *)&uss;
return do_sigaltstack(uss, uoss, regs->gpr[1]); return do_sigaltstack(uss, uoss, regs->gpr[1]);
} }
...@@ -139,6 +164,7 @@ long sys_sigaction(int sig, const struct old_sigaction *act, ...@@ -139,6 +164,7 @@ long sys_sigaction(int sig, const struct old_sigaction *act,
if (act) { if (act) {
old_sigset_t mask; old_sigset_t mask;
if (verify_area(VERIFY_READ, act, sizeof(*act)) || if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
__get_user(new_ka.sa.sa_handler, &act->sa_handler) || __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
__get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
...@@ -148,8 +174,7 @@ long sys_sigaction(int sig, const struct old_sigaction *act, ...@@ -148,8 +174,7 @@ long sys_sigaction(int sig, const struct old_sigaction *act,
siginitset(&new_ka.sa.sa_mask, mask); siginitset(&new_ka.sa.sa_mask, mask);
} }
ret = do_sigaction(sig, (act? &new_ka: NULL), (oact? &old_ka: NULL)); ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
if (!ret && oact) { if (!ret && oact) {
if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
__put_user(old_ka.sa.sa_handler, &oact->sa_handler) || __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
...@@ -162,35 +187,6 @@ long sys_sigaction(int sig, const struct old_sigaction *act, ...@@ -162,35 +187,6 @@ long sys_sigaction(int sig, const struct old_sigaction *act,
return ret; return ret;
} }
/*
* When we have signals to deliver, we set up on the
* user stack, going down from the original stack pointer:
* a sigregs struct
* one or more sigcontext structs with
* a gap of __SIGNAL_FRAMESIZE bytes
*
* Each of these things must be a multiple of 16 bytes in size.
*
*/
struct sigregs {
elf_gregset_t gp_regs;
double fp_regs[ELF_NFPREG];
unsigned int tramp[2];
/* 64 bit API allows for 288 bytes below sp before
decrementing it. */
int abigap[72];
};
struct rt_sigframe
{
unsigned long _unused[2];
struct siginfo *pinfo;
void *puc;
struct siginfo info;
struct ucontext uc;
};
/* /*
* When we have rt signals to deliver, we set up on the * When we have rt signals to deliver, we set up on the
* user stack, going down from the original stack pointer: * user stack, going down from the original stack pointer:
...@@ -231,7 +227,7 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, ...@@ -231,7 +227,7 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
* preamble frame (where registers are stored) * preamble frame (where registers are stored)
* see handle_signal() * see handle_signal()
*/ */
sr = (struct sigregs *) sigctx.regs; sr = (struct sigregs *)sigctx.regs;
if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs))) if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs)))
goto badframe; goto badframe;
saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE) saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
...@@ -251,11 +247,10 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, ...@@ -251,11 +247,10 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
do_exit(SIGSEGV); do_exit(SIGSEGV);
} }
static void static void setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
signed long newsp) signed long newsp)
{ {
struct rt_sigframe *rt_sf = (struct rt_sigframe *) newsp; struct rt_sigframe *rt_sf = (struct rt_sigframe *)newsp;
/* Handler is *really* a pointer to the function descriptor for /* Handler is *really* a pointer to the function descriptor for
* the signal routine. The first entry in the function * the signal routine. The first entry in the function
* descriptor is the entry address of signal and the second * descriptor is the entry address of signal and the second
...@@ -277,11 +272,13 @@ setup_rt_frame(struct pt_regs *regs, struct sigregs *frame, ...@@ -277,11 +272,13 @@ setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE) if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
|| __copy_to_user(&frame->fp_regs, current->thread.fpr, || __copy_to_user(&frame->fp_regs, current->thread.fpr,
ELF_NFPREG * sizeof(double)) ELF_NFPREG * sizeof(double))
|| __put_user(0x38000000UL + __NR_rt_sigreturn, &frame->tramp[0]) /* li r0, __NR_rt_sigreturn */ /* li r0, __NR_rt_sigreturn */
|| __put_user(0x44000002UL, &frame->tramp[1])) /* sc */ || __put_user(0x38000000UL + __NR_rt_sigreturn, &frame->tramp[0])
/* sc */
|| __put_user(0x44000002UL, &frame->tramp[1]))
goto badframe; goto badframe;
flush_icache_range((unsigned long) &frame->tramp[0], flush_icache_range((unsigned long)&frame->tramp[0],
(unsigned long) &frame->tramp[2]); (unsigned long)&frame->tramp[2]);
current->thread.fpscr = 0; /* turn off all fp exceptions */ current->thread.fpscr = 0; /* turn off all fp exceptions */
/* Retrieve rt_sigframe from stack and /* Retrieve rt_sigframe from stack and
...@@ -289,11 +286,11 @@ setup_rt_frame(struct pt_regs *regs, struct sigregs *frame, ...@@ -289,11 +286,11 @@ setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
*/ */
newsp -= __SIGNAL_FRAMESIZE; newsp -= __SIGNAL_FRAMESIZE;
if ( get_user(temp_ptr, &rt_sf->uc.uc_mcontext.handler)) { if (get_user(temp_ptr, &rt_sf->uc.uc_mcontext.handler)) {
goto badframe; goto badframe;
} }
funct_desc_ptr = ( struct funct_descr_entry *) temp_ptr; funct_desc_ptr = (struct funct_descr_entry *)temp_ptr;
if (put_user(regs->gpr[1], (unsigned long *)newsp) if (put_user(regs->gpr[1], (unsigned long *)newsp)
|| get_user(regs->nip, &funct_desc_ptr->entry) || get_user(regs->nip, &funct_desc_ptr->entry)
...@@ -304,8 +301,8 @@ setup_rt_frame(struct pt_regs *regs, struct sigregs *frame, ...@@ -304,8 +301,8 @@ setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
goto badframe; goto badframe;
regs->gpr[1] = newsp; regs->gpr[1] = newsp;
regs->gpr[6] = (unsigned long) rt_sf; regs->gpr[6] = (unsigned long)rt_sf;
regs->link = (unsigned long) frame->tramp; regs->link = (unsigned long)frame->tramp;
return; return;
...@@ -342,11 +339,11 @@ long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, ...@@ -342,11 +339,11 @@ long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
current->blocked = set; current->blocked = set;
recalc_sigpending(); recalc_sigpending();
spin_unlock_irq(&current->sigmask_lock); spin_unlock_irq(&current->sigmask_lock);
if (regs->msr & MSR_FP ) if (regs->msr & MSR_FP)
giveup_fpu(current); giveup_fpu(current);
/* restore registers */ /* restore registers */
sr = (struct sigregs *) sigctx.regs; sr = (struct sigregs *)sigctx.regs;
if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs))) if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs)))
goto badframe; goto badframe;
saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE) saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
...@@ -367,8 +364,7 @@ long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, ...@@ -367,8 +364,7 @@ long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
/* /*
* Set up a signal frame. * Set up a signal frame.
*/ */
static void static void setup_frame(struct pt_regs *regs, struct sigregs *frame,
setup_frame(struct pt_regs *regs, struct sigregs *frame,
unsigned long newsp) unsigned long newsp)
{ {
...@@ -385,7 +381,7 @@ setup_frame(struct pt_regs *regs, struct sigregs *frame, ...@@ -385,7 +381,7 @@ setup_frame(struct pt_regs *regs, struct sigregs *frame,
struct funct_descr_entry * funct_desc_ptr; struct funct_descr_entry * funct_desc_ptr;
unsigned long temp_ptr; unsigned long temp_ptr;
struct sigcontext_struct *sc = (struct sigcontext_struct *) newsp; struct sigcontext_struct *sc = (struct sigcontext_struct *)newsp;
if (verify_area(VERIFY_WRITE, frame, sizeof(*frame))) if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
goto badframe; goto badframe;
...@@ -394,27 +390,29 @@ setup_frame(struct pt_regs *regs, struct sigregs *frame, ...@@ -394,27 +390,29 @@ setup_frame(struct pt_regs *regs, struct sigregs *frame,
if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE) if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
|| __copy_to_user(&frame->fp_regs, current->thread.fpr, || __copy_to_user(&frame->fp_regs, current->thread.fpr,
ELF_NFPREG * sizeof(double)) ELF_NFPREG * sizeof(double))
|| __put_user(0x38000000UL + __NR_sigreturn, &frame->tramp[0]) /* li r0, __NR_sigreturn */ /* li r0, __NR_sigreturn */
|| __put_user(0x44000002UL, &frame->tramp[1])) /* sc */ || __put_user(0x38000000UL + __NR_sigreturn, &frame->tramp[0])
/* sc */
|| __put_user(0x44000002UL, &frame->tramp[1]))
goto badframe; goto badframe;
flush_icache_range((unsigned long) &frame->tramp[0], flush_icache_range((unsigned long)&frame->tramp[0],
(unsigned long) &frame->tramp[2]); (unsigned long)&frame->tramp[2]);
current->thread.fpscr = 0; /* turn off all fp exceptions */ current->thread.fpscr = 0; /* turn off all fp exceptions */
newsp -= __SIGNAL_FRAMESIZE; newsp -= __SIGNAL_FRAMESIZE;
if ( get_user(temp_ptr, &sc->handler)) if (get_user(temp_ptr, &sc->handler))
goto badframe; goto badframe;
funct_desc_ptr = ( struct funct_descr_entry *) temp_ptr; funct_desc_ptr = (struct funct_descr_entry *)temp_ptr;
if (put_user(regs->gpr[1], (unsigned long *)newsp) if (put_user(regs->gpr[1], (unsigned long *)newsp)
|| get_user(regs->nip, & funct_desc_ptr ->entry) || get_user(regs->nip, &funct_desc_ptr ->entry)
|| get_user(regs->gpr[2],& funct_desc_ptr->toc) || get_user(regs->gpr[2],&funct_desc_ptr->toc)
|| get_user(regs->gpr[3], &sc->signal)) || get_user(regs->gpr[3], &sc->signal))
goto badframe; goto badframe;
regs->gpr[1] = newsp; regs->gpr[1] = newsp;
regs->gpr[4] = (unsigned long) sc; regs->gpr[4] = (unsigned long)sc;
regs->link = (unsigned long) frame->tramp; regs->link = (unsigned long)frame->tramp;
return; return;
...@@ -429,8 +427,7 @@ setup_frame(struct pt_regs *regs, struct sigregs *frame, ...@@ -429,8 +427,7 @@ setup_frame(struct pt_regs *regs, struct sigregs *frame,
/* /*
* OK, we're invoking a handler * OK, we're invoking a handler
*/ */
static void static void handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
struct pt_regs * regs, unsigned long *newspp, unsigned long frame) struct pt_regs * regs, unsigned long *newspp, unsigned long frame)
{ {
struct sigcontext_struct *sc; struct sigcontext_struct *sc;
...@@ -447,11 +444,12 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset, ...@@ -447,11 +444,12 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
if (ka->sa.sa_flags & SA_SIGINFO) { if (ka->sa.sa_flags & SA_SIGINFO) {
/* Put a Real Time Context onto stack */ /* Put a Real Time Context onto stack */
*newspp -= sizeof(*rt_sf); *newspp -= sizeof(*rt_sf);
rt_sf = (struct rt_sigframe *) *newspp; rt_sf = (struct rt_sigframe *)*newspp;
if (verify_area(VERIFY_WRITE, rt_sf, sizeof(*rt_sf))) if (verify_area(VERIFY_WRITE, rt_sf, sizeof(*rt_sf)))
goto badframe; goto badframe;
if (__put_user((unsigned long) ka->sa.sa_handler, &rt_sf->uc.uc_mcontext.handler) if (__put_user((unsigned long)ka->sa.sa_handler,
&rt_sf->uc.uc_mcontext.handler)
|| __put_user(&rt_sf->info, &rt_sf->pinfo) || __put_user(&rt_sf->info, &rt_sf->pinfo)
|| __put_user(&rt_sf->uc, &rt_sf->puc) || __put_user(&rt_sf->uc, &rt_sf->puc)
/* Put the siginfo */ /* Put the siginfo */
...@@ -462,8 +460,10 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset, ...@@ -462,8 +460,10 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
|| __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp) || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
|| __put_user(sas_ss_flags(regs->gpr[1]), || __put_user(sas_ss_flags(regs->gpr[1]),
&rt_sf->uc.uc_stack.ss_flags) &rt_sf->uc.uc_stack.ss_flags)
|| __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size) || __put_user(current->sas_ss_size,
|| __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset)) &rt_sf->uc.uc_stack.ss_size)
|| __copy_to_user(&rt_sf->uc.uc_sigmask,
oldset, sizeof(*oldset))
/* mcontext.regs points to preamble register frame */ /* mcontext.regs points to preamble register frame */
|| __put_user((struct pt_regs *)frame, &rt_sf->uc.uc_mcontext.regs) || __put_user((struct pt_regs *)frame, &rt_sf->uc.uc_mcontext.regs)
|| __put_user(sig, &rt_sf->uc.uc_mcontext.signal)) || __put_user(sig, &rt_sf->uc.uc_mcontext.signal))
...@@ -471,11 +471,11 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset, ...@@ -471,11 +471,11 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
} else { } else {
/* Put a sigcontext on the stack */ /* Put a sigcontext on the stack */
*newspp -= sizeof(*sc); *newspp -= sizeof(*sc);
sc = (struct sigcontext_struct *) *newspp; sc = (struct sigcontext_struct *)*newspp;
if (verify_area(VERIFY_WRITE, sc, sizeof(*sc))) if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
goto badframe; goto badframe;
if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler) if (__put_user((unsigned long)ka->sa.sa_handler, &sc->handler)
|| __put_user(oldset->sig[0], &sc->oldmask) || __put_user(oldset->sig[0], &sc->oldmask)
#if _NSIG_WORDS > 1 #if _NSIG_WORDS > 1
|| __put_user(oldset->sig[1], &sc->_unused[3]) || __put_user(oldset->sig[1], &sc->_unused[3])
...@@ -512,6 +512,7 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset, ...@@ -512,6 +512,7 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
* mistake. * mistake.
*/ */
extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
int do_signal(sigset_t *oldset, struct pt_regs *regs) int do_signal(sigset_t *oldset, struct pt_regs *regs)
{ {
siginfo_t info; siginfo_t info;
...@@ -534,8 +535,8 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) ...@@ -534,8 +535,8 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
signr = get_signal_to_deliver(&info, regs); signr = get_signal_to_deliver(&info, regs);
if (signr > 0) { if (signr > 0) {
ka = &current->sig->action[signr-1]; ka = &current->sig->action[signr-1];
if ( (ka->sa.sa_flags & SA_ONSTACK) if ((ka->sa.sa_flags & SA_ONSTACK)
&& (! on_sig_stack(regs->gpr[1]))) && (!on_sig_stack(regs->gpr[1])))
newsp = (current->sas_ss_sp + current->sas_ss_size); newsp = (current->sas_ss_sp + current->sas_ss_size);
else else
newsp = regs->gpr[1]; newsp = regs->gpr[1];
...@@ -557,9 +558,10 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) ...@@ -557,9 +558,10 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
if (newsp == frame) if (newsp == frame)
return 0; /* no signals delivered */ return 0; /* no signals delivered */
/* Invoke correct stack setup routine */
if (ka->sa.sa_flags & SA_SIGINFO) if (ka->sa.sa_flags & SA_SIGINFO)
setup_rt_frame(regs, (struct sigregs *) frame, newsp); setup_rt_frame(regs, (struct sigregs *)frame, newsp);
else else
setup_frame(regs, (struct sigregs *) frame, newsp); setup_frame(regs, (struct sigregs *)frame, newsp);
return 1; return 1;
} }
...@@ -14,43 +14,19 @@ ...@@ -14,43 +14,19 @@
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
*/ */
#include <asm/ptrace.h>
#include <linux/kernel.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/fs.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/file.h>
#include <linux/signal.h>
#include <linux/utime.h>
#include <linux/resource.h>
#include <linux/times.h>
#include <linux/utsname.h>
#include <linux/timex.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/sem.h> #include <linux/kernel.h>
#include <linux/msg.h> #include <linux/signal.h>
#include <linux/shm.h> #include <linux/errno.h>
#include <linux/slab.h>
#include <linux/uio.h>
#include <linux/nfs_fs.h>
#include <linux/smb_fs.h>
#include <linux/smb_mount.h>
#include <linux/ncp_fs.h>
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/personality.h>
#include <linux/stat.h>
#include <linux/filter.h>
#include <linux/tty.h>
#include <linux/binfmts.h>
#include <linux/elf.h> #include <linux/elf.h>
#include <asm/types.h>
#include <asm/ipc.h>
#include <asm/uaccess.h>
#include <asm/ppc32.h> #include <asm/ppc32.h>
#include <asm/uaccess.h>
#include <asm/ppcdebug.h> #include <asm/ppcdebug.h>
#include <asm/unistd.h> #include <asm/unistd.h>
#include <asm/cacheflush.h>
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
/* /*
...@@ -112,9 +88,6 @@ struct rt_sigframe_32 { ...@@ -112,9 +88,6 @@ struct rt_sigframe_32 {
}; };
extern asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr,
int options, struct rusage * ru);
/* /*
* Start of nonRT signal support * Start of nonRT signal support
...@@ -133,7 +106,7 @@ extern asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, ...@@ -133,7 +106,7 @@ extern asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr,
* setup_frame32 * setup_frame32
*/ */
asmlinkage long sys32_sigaction(int sig, struct old_sigaction32 *act, long sys32_sigaction(int sig, struct old_sigaction32 *act,
struct old_sigaction32 *oact) struct old_sigaction32 *oact)
{ {
struct k_sigaction new_ka, old_ka; struct k_sigaction new_ka, old_ka;
...@@ -145,32 +118,30 @@ asmlinkage long sys32_sigaction(int sig, struct old_sigaction32 *act, ...@@ -145,32 +118,30 @@ asmlinkage long sys32_sigaction(int sig, struct old_sigaction32 *act,
if (act) { if (act) {
old_sigset_t32 mask; old_sigset_t32 mask;
ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler); if (get_user((long)new_ka.sa.sa_handler, &act->sa_handler) ||
ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer); __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer) ||
ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
ret |= __get_user(mask, &act->sa_mask); __get_user(mask, &act->sa_mask))
if (ret) return -EFAULT;
return ret;
siginitset(&new_ka.sa.sa_mask, mask); siginitset(&new_ka.sa.sa_mask, mask);
} }
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
if (!ret && oact) { if (!ret && oact) {
ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler); if (put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) ||
ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer); __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) ||
ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
return -EFAULT;
} }
return ret; return ret;
} }
extern long sys_sigpending(old_sigset_t *set);
long sys32_sigpending(old_sigset_t32 *set)
extern asmlinkage long sys_sigpending(old_sigset_t *set);
asmlinkage long sys32_sigpending(old_sigset_t32 *set)
{ {
old_sigset_t s; old_sigset_t s;
int ret; int ret;
...@@ -185,9 +156,7 @@ asmlinkage long sys32_sigpending(old_sigset_t32 *set) ...@@ -185,9 +156,7 @@ asmlinkage long sys32_sigpending(old_sigset_t32 *set)
} }
extern long sys_sigprocmask(int how, old_sigset_t *set,
extern asmlinkage long sys_sigprocmask(int how, old_sigset_t *set,
old_sigset_t *oset); old_sigset_t *oset);
/* /*
...@@ -197,7 +166,7 @@ extern asmlinkage long sys_sigprocmask(int how, old_sigset_t *set, ...@@ -197,7 +166,7 @@ extern asmlinkage long sys_sigprocmask(int how, old_sigset_t *set,
* of a signed int (msr in 32-bit mode) and the register representation * of a signed int (msr in 32-bit mode) and the register representation
* of a signed int (msr in 64-bit mode) is performed. * of a signed int (msr in 64-bit mode) is performed.
*/ */
asmlinkage long sys32_sigprocmask(u32 how, old_sigset_t32 *set, long sys32_sigprocmask(u32 how, old_sigset_t32 *set,
old_sigset_t32 *oset) old_sigset_t32 *oset)
{ {
old_sigset_t s; old_sigset_t s;
...@@ -252,23 +221,21 @@ long sys32_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, ...@@ -252,23 +221,21 @@ long sys32_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
* Note that PPC32 puts the upper 32 bits of the sigmask in the * Note that PPC32 puts the upper 32 bits of the sigmask in the
* unused part of the signal stackframe * unused part of the signal stackframe
*/ */
set.sig[0] = sigctx.oldmask + ((long)(sigctx._unused[3])<< 32); set.sig[0] = sigctx.oldmask + ((long)(sigctx._unused[3]) << 32);
sigdelsetmask(&set, ~_BLOCKABLE); sigdelsetmask(&set, ~_BLOCKABLE);
spin_lock_irq(&current->sigmask_lock); spin_lock_irq(&current->sigmask_lock);
current->blocked = set; current->blocked = set;
recalc_sigpending(); recalc_sigpending();
spin_unlock_irq(&current->sigmask_lock); spin_unlock_irq(&current->sigmask_lock);
/* Last stacked signal - restore registers */
sr = (struct sigregs32*)(u64)sigctx.regs;
if (regs->msr & MSR_FP ) if (regs->msr & MSR_FP )
giveup_fpu(current); giveup_fpu(current);
/* Last stacked signal - restore registers */
sr = (struct sigregs32*)(u64)sigctx.regs;
/* /*
* copy the 32 bit register values off the user stack * copy the 32 bit register values off the user stack
* into the 32 bit register area * into the 32 bit register area
*/ */
if (copy_from_user(saved_regs, &sr->gp_regs, if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs)))
sizeof(sr->gp_regs)))
goto badframe; goto badframe;
/* /*
* The saved reg structure in the frame is an elf_grepset_t32, * The saved reg structure in the frame is an elf_grepset_t32,
...@@ -323,7 +290,6 @@ long sys32_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, ...@@ -323,7 +290,6 @@ long sys32_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
goto badframe; goto badframe;
ret = regs->result; ret = regs->result;
return ret; return ret;
badframe: badframe:
...@@ -387,12 +353,13 @@ static void setup_frame32(struct pt_regs *regs, struct sigregs32 *frame, ...@@ -387,12 +353,13 @@ static void setup_frame32(struct pt_regs *regs, struct sigregs32 *frame,
*/ */
if (__copy_to_user(&frame->fp_regs, current->thread.fpr, if (__copy_to_user(&frame->fp_regs, current->thread.fpr,
ELF_NFPREG * sizeof(double)) ELF_NFPREG * sizeof(double))
|| __put_user(0x38000000U + __NR_sigreturn, &frame->tramp[0]) /* li r0, __NR_sigreturn */ /* li r0, __NR_sigreturn */
|| __put_user(0x44000002U, &frame->tramp[1])) /* sc */ || __put_user(0x38000000U + __NR_sigreturn, &frame->tramp[0])
/* sc */
|| __put_user(0x44000002U, &frame->tramp[1]))
goto badframe; goto badframe;
flush_icache_range((unsigned long)&frame->tramp[0],
flush_icache_range((unsigned long) &frame->tramp[0], (unsigned long)&frame->tramp[2]);
(unsigned long) &frame->tramp[2]);
current->thread.fpscr = 0; /* turn off all fp exceptions */ current->thread.fpscr = 0; /* turn off all fp exceptions */
newsp -= __SIGNAL_FRAMESIZE32; newsp -= __SIGNAL_FRAMESIZE32;
...@@ -438,7 +405,7 @@ static void setup_frame32(struct pt_regs *regs, struct sigregs32 *frame, ...@@ -438,7 +405,7 @@ static void setup_frame32(struct pt_regs *regs, struct sigregs32 *frame,
* *
* Other routines * Other routines
* setup_rt_frame32 * setup_rt_frame32
* siginfo64to32 * copy_siginfo_to_user32
* siginfo32to64 * siginfo32to64
*/ */
...@@ -451,50 +418,45 @@ long sys32_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, ...@@ -451,50 +418,45 @@ long sys32_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7, unsigned long r8, unsigned long r6, unsigned long r7, unsigned long r8,
struct pt_regs * regs) struct pt_regs * regs)
{ {
struct rt_sigframe_32 *rt_stack_frame; struct rt_sigframe_32 *rt_sf;
struct sigcontext32_struct sigctx; struct sigcontext32_struct sigctx;
struct sigregs32 *signalregs; struct sigregs32 *sr;
int ret; int ret;
elf_gregset_t32 saved_regs; /* an array of 32 bit register values */ elf_gregset_t32 saved_regs; /* an array of 32 bit register values */
sigset_t signal_set; sigset_t set;
stack_t stack; stack_t st;
int i; int i;
ret = 0;
/* Adjust the inputted reg1 to point to the first rt signal frame */ /* Adjust the inputted reg1 to point to the first rt signal frame */
rt_stack_frame = (struct rt_sigframe_32 *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32); rt_sf = (struct rt_sigframe_32 *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32);
/* Copy the information from the user stack */ /* Copy the information from the user stack */
if (copy_from_user(&sigctx, &rt_stack_frame->uc.uc_mcontext, if (copy_from_user(&sigctx, &rt_sf->uc.uc_mcontext, sizeof(sigctx))
sizeof(sigctx)) || copy_from_user(&set, &rt_sf->uc.uc_sigmask, sizeof(set))
|| copy_from_user(&signal_set, &rt_stack_frame->uc.uc_sigmask, || copy_from_user(&st,&rt_sf->uc.uc_stack, sizeof(st)))
sizeof(signal_set))
|| copy_from_user(&stack,&rt_stack_frame->uc.uc_stack,
sizeof(stack)))
goto badframe; goto badframe;
/* /*
* Unblock the signal that was processed * Unblock the signal that was processed
* After a signal handler runs - * After a signal handler runs -
* if the signal is blockable - the signal will be unblocked * if the signal is blockable - the signal will be unblocked
* ( sigkill and sigstop are not blockable) * (sigkill and sigstop are not blockable)
*/ */
sigdelsetmask(&signal_set, ~_BLOCKABLE); sigdelsetmask(&set, ~_BLOCKABLE);
/* update the current based on the sigmask found in the rt_stackframe */ /* update the current based on the sigmask found in the rt_stackframe */
spin_lock_irq(&current->sigmask_lock); spin_lock_irq(&current->sigmask_lock);
current->blocked = signal_set; current->blocked = set;
recalc_sigpending(); recalc_sigpending();
spin_unlock_irq(&current->sigmask_lock); spin_unlock_irq(&current->sigmask_lock);
/* If currently owning the floating point - give them up */
if (regs->msr & MSR_FP)
giveup_fpu(current);
/* /*
* Set to point to the next rt_sigframe - this is used to * Set to point to the next rt_sigframe - this is used to
* determine whether this is the last signal to process * determine whether this is the last signal to process
*/ */
signalregs = (struct sigregs32 *) (u64)sigctx.regs; sr = (struct sigregs32 *)(u64)sigctx.regs;
/* If currently owning the floating point - give them up */ if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs)))
if (regs->msr & MSR_FP)
giveup_fpu(current);
if (copy_from_user(saved_regs, &signalregs->gp_regs,
sizeof(signalregs->gp_regs)))
goto badframe; goto badframe;
/* /*
* The saved reg structure in the frame is an elf_grepset_t32, * The saved reg structure in the frame is an elf_grepset_t32,
...@@ -544,7 +506,7 @@ long sys32_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, ...@@ -544,7 +506,7 @@ long sys32_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
asmlinkage long sys32_rt_sigaction(int sig, const struct sigaction32 *act, long sys32_rt_sigaction(int sig, const struct sigaction32 *act,
struct sigaction32 *oact, size_t sigsetsize) struct sigaction32 *oact, size_t sigsetsize)
{ {
struct k_sigaction new_ka, old_ka; struct k_sigaction new_ka, old_ka;
...@@ -599,7 +561,7 @@ asmlinkage long sys32_rt_sigaction(int sig, const struct sigaction32 *act, ...@@ -599,7 +561,7 @@ asmlinkage long sys32_rt_sigaction(int sig, const struct sigaction32 *act,
} }
extern asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set, extern long sys_rt_sigprocmask(int how, sigset_t *set,
sigset_t *oset, size_t sigsetsize); sigset_t *oset, size_t sigsetsize);
/* /*
...@@ -609,7 +571,7 @@ extern asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set, ...@@ -609,7 +571,7 @@ extern asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set,
* of a signed int (msr in 32-bit mode) and the register representation * of a signed int (msr in 32-bit mode) and the register representation
* of a signed int (msr in 64-bit mode) is performed. * of a signed int (msr in 64-bit mode) is performed.
*/ */
asmlinkage long sys32_rt_sigprocmask(u32 how, sigset32_t *set, long sys32_rt_sigprocmask(u32 how, sigset32_t *set,
sigset32_t *oset, size_t sigsetsize) sigset32_t *oset, size_t sigsetsize)
{ {
sigset_t s; sigset_t s;
...@@ -649,10 +611,10 @@ asmlinkage long sys32_rt_sigprocmask(u32 how, sigset32_t *set, ...@@ -649,10 +611,10 @@ asmlinkage long sys32_rt_sigprocmask(u32 how, sigset32_t *set,
} }
extern asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize); extern long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
asmlinkage long sys32_rt_sigpending(sigset32_t *set, long sys32_rt_sigpending(sigset32_t *set,
__kernel_size_t32 sigsetsize) __kernel_size_t32 sigsetsize)
{ {
sigset_t s; sigset_t s;
...@@ -677,50 +639,54 @@ asmlinkage long sys32_rt_sigpending(sigset32_t *set, ...@@ -677,50 +639,54 @@ asmlinkage long sys32_rt_sigpending(sigset32_t *set,
} }
siginfo_t32 *siginfo64to32(siginfo_t32 *d, siginfo_t *s) static int copy_siginfo_to_user32(siginfo_t32 *d, siginfo_t *s)
{ {
memset (d, 0, sizeof(siginfo_t32)); int err;
d->si_signo = s->si_signo;
d->si_errno = s->si_errno; if (!access_ok (VERIFY_WRITE, d, sizeof(*d)))
/* XXX why dont we just implement copy_siginfo_to_user32? - Anton */ return -EFAULT;
d->si_code = s->si_code & 0xffff;
err = __put_user(s->si_signo, &d->si_signo);
err |= __put_user(s->si_errno, &d->si_errno);
err |= __put_user((short)s->si_code, &d->si_code);
if (s->si_signo >= SIGRTMIN) { if (s->si_signo >= SIGRTMIN) {
d->si_pid = s->si_pid; err |= __put_user(s->si_pid, &d->si_pid);
d->si_uid = s->si_uid; err |= __put_user(s->si_uid, &d->si_uid);
d->si_int = s->si_int; err |= __put_user(s->si_int, &d->si_int);
} else { } else {
switch (s->si_signo) { switch (s->si_signo) {
/* XXX: What about POSIX1.b timers */ /* XXX: What about POSIX1.b timers */
case SIGCHLD: case SIGCHLD:
d->si_pid = s->si_pid; err |= __put_user(s->si_pid, &d->si_pid);
d->si_status = s->si_status; err |= __put_user(s->si_status, &d->si_status);
d->si_utime = s->si_utime; err |= __put_user(s->si_utime, &d->si_utime);
d->si_stime = s->si_stime; err |= __put_user(s->si_stime, &d->si_stime);
break; break;
case SIGSEGV: case SIGSEGV:
case SIGBUS: case SIGBUS:
case SIGFPE: case SIGFPE:
case SIGILL: case SIGILL:
d->si_addr = (long)(s->si_addr); err |= __put_user((long)(s->si_addr), &d->si_addr);
break; break;
case SIGPOLL: case SIGPOLL:
d->si_band = s->si_band; err |= __put_user(s->si_band, &d->si_band);
d->si_fd = s->si_fd; err |= __put_user(s->si_fd, &d->si_fd);
break; break;
default: default:
d->si_pid = s->si_pid; err |= __put_user(s->si_pid, &d->si_pid);
d->si_uid = s->si_uid; err |= __put_user(s->si_uid, &d->si_uid);
break; break;
} }
} }
return d; return err;
} }
extern asmlinkage long sys_rt_sigtimedwait(const sigset_t *uthese,
extern long sys_rt_sigtimedwait(const sigset_t *uthese,
siginfo_t *uinfo, const struct timespec *uts, siginfo_t *uinfo, const struct timespec *uts,
size_t sigsetsize); size_t sigsetsize);
asmlinkage long sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo, long sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo,
struct timespec32 *uts, __kernel_size_t32 sigsetsize) struct timespec32 *uts, __kernel_size_t32 sigsetsize)
{ {
sigset_t s; sigset_t s;
...@@ -729,7 +695,6 @@ asmlinkage long sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo, ...@@ -729,7 +695,6 @@ asmlinkage long sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo,
int ret; int ret;
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
siginfo_t info; siginfo_t info;
siginfo_t32 info32;
if (copy_from_user(&s32, uthese, sizeof(sigset32_t))) if (copy_from_user(&s32, uthese, sizeof(sigset32_t)))
return -EFAULT; return -EFAULT;
...@@ -753,8 +718,7 @@ asmlinkage long sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo, ...@@ -753,8 +718,7 @@ asmlinkage long sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo,
sigsetsize); sigsetsize);
set_fs(old_fs); set_fs(old_fs);
if (ret >= 0 && uinfo) { if (ret >= 0 && uinfo) {
if (copy_to_user (uinfo, siginfo64to32(&info32, &info), if (copy_siginfo_to_user32(uinfo, &info))
sizeof(siginfo_t32)))
return -EFAULT; return -EFAULT;
} }
return ret; return ret;
...@@ -762,7 +726,7 @@ asmlinkage long sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo, ...@@ -762,7 +726,7 @@ asmlinkage long sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo,
siginfo_t * siginfo32to64(siginfo_t *d, siginfo_t32 *s) static siginfo_t * siginfo32to64(siginfo_t *d, siginfo_t32 *s)
{ {
d->si_signo = s->si_signo; d->si_signo = s->si_signo;
d->si_errno = s->si_errno; d->si_errno = s->si_errno;
...@@ -800,7 +764,7 @@ siginfo_t * siginfo32to64(siginfo_t *d, siginfo_t32 *s) ...@@ -800,7 +764,7 @@ siginfo_t * siginfo32to64(siginfo_t *d, siginfo_t32 *s)
} }
extern asmlinkage long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo); extern long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
/* /*
* Note: it is necessary to treat pid and sig as unsigned ints, with the * Note: it is necessary to treat pid and sig as unsigned ints, with the
...@@ -809,7 +773,7 @@ extern asmlinkage long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo); ...@@ -809,7 +773,7 @@ extern asmlinkage long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
* (msr in 32-bit mode) and the register representation of a signed int * (msr in 32-bit mode) and the register representation of a signed int
* (msr in 64-bit mode) is performed. * (msr in 64-bit mode) is performed.
*/ */
asmlinkage long sys32_rt_sigqueueinfo(u32 pid, u32 sig, siginfo_t32 *uinfo) long sys32_rt_sigqueueinfo(u32 pid, u32 sig, siginfo_t32 *uinfo)
{ {
siginfo_t info; siginfo_t info;
siginfo_t32 info32; siginfo_t32 info32;
...@@ -974,8 +938,7 @@ static void handle_signal32(unsigned long sig, siginfo_t *info, ...@@ -974,8 +938,7 @@ static void handle_signal32(unsigned long sig, siginfo_t *info,
unsigned int frame) unsigned int frame)
{ {
struct sigcontext32_struct *sc; struct sigcontext32_struct *sc;
struct rt_sigframe_32 *rt_stack_frame; struct rt_sigframe_32 *rt_sf;
siginfo_t32 siginfo32bit;
struct k_sigaction *ka = &current->sig->action[sig-1]; struct k_sigaction *ka = &current->sig->action[sig-1];
if (regs->trap == 0x0C00 /* System Call! */ if (regs->trap == 0x0C00 /* System Call! */
...@@ -986,42 +949,35 @@ static void handle_signal32(unsigned long sig, siginfo_t *info, ...@@ -986,42 +949,35 @@ static void handle_signal32(unsigned long sig, siginfo_t *info,
/* /*
* Set up the signal frame * Set up the signal frame
* Determine if an real time frame - siginfo required * Determine if a real time frame and a siginfo is required
*/ */
if (ka->sa.sa_flags & SA_SIGINFO) { if (ka->sa.sa_flags & SA_SIGINFO) {
siginfo64to32(&siginfo32bit,info); *newspp -= sizeof(*rt_sf);
*newspp -= sizeof(*rt_stack_frame); rt_sf = (struct rt_sigframe_32 *)(u64)(*newspp);
rt_stack_frame = (struct rt_sigframe_32 *)(u64)(*newspp); if (verify_area(VERIFY_WRITE, rt_sf, sizeof(*rt_sf)))
if (verify_area(VERIFY_WRITE, rt_stack_frame,
sizeof(*rt_stack_frame)))
goto badframe; goto badframe;
if (__put_user((u32)(u64)ka->sa.sa_handler, if (__put_user((u32)(u64)ka->sa.sa_handler,
&rt_stack_frame->uc.uc_mcontext.handler) &rt_sf->uc.uc_mcontext.handler)
|| __put_user((u32)(u64)&rt_stack_frame->info, || __put_user((u32)(u64)&rt_sf->info, &rt_sf->pinfo)
&rt_stack_frame->pinfo) || __put_user((u32)(u64)&rt_sf->uc, &rt_sf->puc)
|| __put_user((u32)(u64)&rt_stack_frame->uc,
&rt_stack_frame->puc)
/* put the siginfo on the user stack */ /* put the siginfo on the user stack */
|| __copy_to_user(&rt_stack_frame->info, &siginfo32bit, || copy_siginfo_to_user32(&rt_sf->info, info)
sizeof(siginfo32bit))
/* set the ucontext on the user stack */ /* set the ucontext on the user stack */
|| __put_user(0, &rt_stack_frame->uc.uc_flags) || __put_user(0, &rt_sf->uc.uc_flags)
|| __put_user(0, &rt_stack_frame->uc.uc_link) || __put_user(0, &rt_sf->uc.uc_link)
|| __put_user(current->sas_ss_sp, || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
&rt_stack_frame->uc.uc_stack.ss_sp)
|| __put_user(sas_ss_flags(regs->gpr[1]), || __put_user(sas_ss_flags(regs->gpr[1]),
&rt_stack_frame->uc.uc_stack.ss_flags) &rt_sf->uc.uc_stack.ss_flags)
|| __put_user(current->sas_ss_size, || __put_user(current->sas_ss_size,
&rt_stack_frame->uc.uc_stack.ss_size) &rt_sf->uc.uc_stack.ss_size)
|| __copy_to_user(&rt_stack_frame->uc.uc_sigmask, || __copy_to_user(&rt_sf->uc.uc_sigmask,
oldset, sizeof(*oldset)) oldset, sizeof(*oldset))
/* point the mcontext.regs to the pramble register frame */ /* point the mcontext.regs to the pramble register frame */
|| __put_user(frame, &rt_stack_frame->uc.uc_mcontext.regs) || __put_user(frame, &rt_sf->uc.uc_mcontext.regs)
|| __put_user(sig,&rt_stack_frame->uc.uc_mcontext.signal)) || __put_user(sig,&rt_sf->uc.uc_mcontext.signal))
goto badframe; goto badframe;
} else { } else {
/* Put another sigcontext on the stack */ /* Put a sigcontext on the stack */
*newspp -= sizeof(*sc); *newspp -= sizeof(*sc);
sc = (struct sigcontext32_struct *)(u64)*newspp; sc = (struct sigcontext32_struct *)(u64)*newspp;
if (verify_area(VERIFY_WRITE, sc, sizeof(*sc))) if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
...@@ -1048,7 +1004,6 @@ static void handle_signal32(unsigned long sig, siginfo_t *info, ...@@ -1048,7 +1004,6 @@ static void handle_signal32(unsigned long sig, siginfo_t *info,
recalc_sigpending(); recalc_sigpending();
spin_unlock_irq(&current->sigmask_lock); spin_unlock_irq(&current->sigmask_lock);
} }
return; return;
badframe: badframe:
...@@ -1068,7 +1023,7 @@ static void handle_signal32(unsigned long sig, siginfo_t *info, ...@@ -1068,7 +1023,7 @@ static void handle_signal32(unsigned long sig, siginfo_t *info,
* sigaltatck sys32_sigaltstack * sigaltatck sys32_sigaltstack
*/ */
asmlinkage int sys32_sigaltstack(u32 newstack, u32 oldstack, int p3, int sys32_sigaltstack(u32 newstack, u32 oldstack, int p3,
int p4, int p6, int p7, struct pt_regs *regs) int p4, int p6, int p7, struct pt_regs *regs)
{ {
stack_t uss, uoss; stack_t uss, uoss;
...@@ -1114,7 +1069,7 @@ asmlinkage int sys32_sigaltstack(u32 newstack, u32 oldstack, int p3, ...@@ -1114,7 +1069,7 @@ asmlinkage int sys32_sigaltstack(u32 newstack, u32 oldstack, int p3,
/* /*
* Start of do_signal32 routine * Start of do_signal32 routine
* *
* This routine gets control when a pemding signal needs to be processed * This routine gets control when a pending signal needs to be processed
* in the 32 bit target thread - * in the 32 bit target thread -
* *
* It handles both rt and non-rt signals * It handles both rt and non-rt signals
...@@ -1141,13 +1096,13 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs) ...@@ -1141,13 +1096,13 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
signr = get_signal_to_deliver(&info, regs); signr = get_signal_to_deliver(&info, regs);
if (signr > 0) { if (signr > 0) {
ka = &current->sig->action[signr-1]; ka = &current->sig->action[signr-1];
if ((ka->sa.sa_flags & SA_ONSTACK)
if ((ka->sa.sa_flags & SA_ONSTACK) && && (!on_sig_stack(regs->gpr[1])))
(!on_sig_stack(regs->gpr[1])))
newsp = (current->sas_ss_sp + current->sas_ss_size); newsp = (current->sas_ss_sp + current->sas_ss_size);
else else
newsp = regs->gpr[1]; newsp = regs->gpr[1];
newsp = frame = newsp - sizeof(struct sigregs32); newsp = frame = newsp - sizeof(struct sigregs32);
/* Whee! Actually deliver the signal. */ /* Whee! Actually deliver the signal. */
handle_signal32(signr, &info, oldset, regs, &newsp, frame); handle_signal32(signr, &info, oldset, regs, &newsp, frame);
} }
...@@ -1169,6 +1124,5 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs) ...@@ -1169,6 +1124,5 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
setup_rt_frame32(regs, (struct sigregs32*)(u64)frame, newsp); setup_rt_frame32(regs, (struct sigregs32*)(u64)frame, newsp);
else else
setup_frame32(regs, (struct sigregs32*)(u64)frame, newsp); setup_frame32(regs, (struct sigregs32*)(u64)frame, newsp);
return 1; return 1;
} }
/* /*
*
*
* PowerPC version * PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
* *
...@@ -62,8 +60,6 @@ ...@@ -62,8 +60,6 @@
#include <asm/ppcdebug.h> #include <asm/ppcdebug.h>
#define PGTOKB(pages) (((pages) * PAGE_SIZE) >> 10)
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
#include <asm/iSeries/iSeries_dma.h> #include <asm/iSeries/iSeries_dma.h>
#endif #endif
...@@ -78,13 +74,10 @@ extern pgd_t swapper_pg_dir[]; ...@@ -78,13 +74,10 @@ extern pgd_t swapper_pg_dir[];
extern char __init_begin, __init_end; extern char __init_begin, __init_end;
extern char __chrp_begin, __chrp_end; extern char __chrp_begin, __chrp_end;
extern char __openfirmware_begin, __openfirmware_end; extern char __openfirmware_begin, __openfirmware_end;
extern struct _of_tce_table of_tce_table[];
extern char _start[], _end[]; extern char _start[], _end[];
extern char _stext[], etext[]; extern char _stext[], etext[];
extern struct task_struct *current_set[NR_CPUS]; extern struct task_struct *current_set[NR_CPUS];
void mm_init_ppc64(void);
extern pgd_t ioremap_dir[]; extern pgd_t ioremap_dir[];
pgd_t * ioremap_pgd = (pgd_t *)&ioremap_dir; pgd_t * ioremap_pgd = (pgd_t *)&ioremap_dir;
...@@ -463,7 +456,6 @@ void __init do_init_bootmem(void) ...@@ -463,7 +456,6 @@ void __init do_init_bootmem(void)
unsigned long start, bootmap_pages; unsigned long start, bootmap_pages;
unsigned long total_pages = lmb_end_of_DRAM() >> PAGE_SHIFT; unsigned long total_pages = lmb_end_of_DRAM() >> PAGE_SHIFT;
PPCDBG(PPCDBG_MMINIT, "do_init_bootmem: start\n");
/* /*
* Find an area to use for the bootmem bitmap. Calculate the size of * Find an area to use for the bootmem bitmap. Calculate the size of
* bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE. * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
...@@ -472,21 +464,16 @@ void __init do_init_bootmem(void) ...@@ -472,21 +464,16 @@ void __init do_init_bootmem(void)
bootmap_pages = bootmem_bootmap_pages(total_pages); bootmap_pages = bootmem_bootmap_pages(total_pages);
start = (unsigned long)__a2p(lmb_alloc(bootmap_pages<<PAGE_SHIFT, PAGE_SIZE)); start = (unsigned long)__a2p(lmb_alloc(bootmap_pages<<PAGE_SHIFT, PAGE_SIZE));
if( start == 0 ) { if (start == 0) {
udbg_printf("do_init_bootmem: failed to allocate a bitmap.\n"); udbg_printf("do_init_bootmem: failed to allocate a bitmap.\n");
udbg_printf("\tbootmap_pages = 0x%lx.\n", bootmap_pages); udbg_printf("\tbootmap_pages = 0x%lx.\n", bootmap_pages);
PPCDBG_ENTER_DEBUGGER(); PPCDBG_ENTER_DEBUGGER();
} }
PPCDBG(PPCDBG_MMINIT, "\tstart = 0x%lx\n", start);
PPCDBG(PPCDBG_MMINIT, "\tbootmap_pages = 0x%lx\n", bootmap_pages);
PPCDBG(PPCDBG_MMINIT, "\tphysicalMemorySize = 0x%lx\n", naca->physicalMemorySize);
boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages); boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages);
PPCDBG(PPCDBG_MMINIT, "\tboot_mapsize = 0x%lx\n", boot_mapsize);
/* add all physical memory to the bootmem map */ /* add all physical memory to the bootmem map */
for (i=0; i < lmb.memory.cnt ;i++) { for (i=0; i < lmb.memory.cnt; i++) {
unsigned long physbase, size; unsigned long physbase, size;
unsigned long type = lmb.memory.region[i].type; unsigned long type = lmb.memory.region[i].type;
...@@ -497,19 +484,14 @@ void __init do_init_bootmem(void) ...@@ -497,19 +484,14 @@ void __init do_init_bootmem(void)
size = lmb.memory.region[i].size; size = lmb.memory.region[i].size;
free_bootmem(physbase, size); free_bootmem(physbase, size);
} }
/* reserve the sections we're already using */ /* reserve the sections we're already using */
for (i=0; i < lmb.reserved.cnt ;i++) { for (i=0; i < lmb.reserved.cnt; i++) {
unsigned long physbase = lmb.reserved.region[i].physbase; unsigned long physbase = lmb.reserved.region[i].physbase;
unsigned long size = lmb.reserved.region[i].size; unsigned long size = lmb.reserved.region[i].size;
#if 0 /* PPPBBB */
if ( (physbase == 0) && (size < (16<<20)) ) {
size = 16 << 20;
}
#endif
reserve_bootmem(physbase, size); reserve_bootmem(physbase, size);
} }
PPCDBG(PPCDBG_MMINIT, "do_init_bootmem: end\n");
} }
/* /*
...@@ -522,7 +504,7 @@ void __init paging_init(void) ...@@ -522,7 +504,7 @@ void __init paging_init(void)
/* /*
* All pages are DMA-able so we put them all in the DMA zone. * All pages are DMA-able so we put them all in the DMA zone.
*/ */
zones_size[0] = lmb_end_of_DRAM() >> PAGE_SHIFT; zones_size[ZONE_DMA] = lmb_end_of_DRAM() >> PAGE_SHIFT;
for (i = 1; i < MAX_NR_ZONES; i++) for (i = 1; i < MAX_NR_ZONES; i++)
zones_size[i] = 0; zones_size[i] = 0;
free_area_init(zones_size); free_area_init(zones_size);
...@@ -554,14 +536,6 @@ void __init mem_init(void) ...@@ -554,14 +536,6 @@ void __init mem_init(void)
totalram_pages += free_all_bootmem(); totalram_pages += free_all_bootmem();
ifppcdebug(PPCDBG_MMINIT) {
udbg_printf("mem_init: totalram_pages = 0x%lx\n", totalram_pages);
udbg_printf("mem_init: va_rtas_base = 0x%lx\n", va_rtas_base);
udbg_printf("mem_init: va_rtas_end = 0x%lx\n", PAGE_ALIGN(va_rtas_base+rtas.size));
udbg_printf("mem_init: pinned start = 0x%lx\n", __va(0));
udbg_printf("mem_init: pinned end = 0x%lx\n", PAGE_ALIGN(klimit));
}
if ( sysmap_size ) if ( sysmap_size )
for (addr = (unsigned long)sysmap; for (addr = (unsigned long)sysmap;
addr < PAGE_ALIGN((unsigned long)sysmap+sysmap_size) ; addr < PAGE_ALIGN((unsigned long)sysmap+sysmap_size) ;
...@@ -620,12 +594,13 @@ void flush_icache_page(struct vm_area_struct *vma, struct page *page) ...@@ -620,12 +594,13 @@ void flush_icache_page(struct vm_area_struct *vma, struct page *page)
} }
} }
void clear_user_page(void *page, unsigned long vaddr) void clear_user_page(void *page, unsigned long vaddr, struct page *pg)
{ {
clear_page(page); clear_page(page);
} }
void copy_user_page(void *vto, void *vfrom, unsigned long vaddr) void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
struct page *pg)
{ {
copy_page(vto, vfrom); copy_page(vto, vfrom);
__flush_dcache_icache(vto); __flush_dcache_icache(vto);
......
...@@ -70,8 +70,8 @@ static __inline__ void clear_page(void *addr) ...@@ -70,8 +70,8 @@ static __inline__ void clear_page(void *addr)
extern void copy_page(void *to, void *from); extern void copy_page(void *to, void *from);
struct page; struct page;
extern void clear_user_page(void *page, unsigned long vaddr); extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg);
extern void copy_user_page(void *to, void *from, unsigned long vaddr); extern void copy_user_page(void *to, void *from, unsigned long vaddr, struct page *p);
#ifdef STRICT_MM_TYPECHECKS #ifdef STRICT_MM_TYPECHECKS
/* /*
......
...@@ -53,6 +53,8 @@ pmd_free(pmd_t *pmd) ...@@ -53,6 +53,8 @@ pmd_free(pmd_t *pmd)
free_page((unsigned long)pmd); free_page((unsigned long)pmd);
} }
#define pmd_free_tlb(tlb, pmd) pmd_free(pmd)
#define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, pte) #define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, pte)
#define pmd_populate(mm, pmd, pte_page) \ #define pmd_populate(mm, pmd, pte_page) \
pmd_populate_kernel(mm, pmd, page_address(pte_page)) pmd_populate_kernel(mm, pmd, page_address(pte_page))
...@@ -86,6 +88,7 @@ pte_free_kernel(pte_t *pte) ...@@ -86,6 +88,7 @@ pte_free_kernel(pte_t *pte)
} }
#define pte_free(pte_page) pte_free_kernel(page_address(pte_page)) #define pte_free(pte_page) pte_free_kernel(page_address(pte_page))
#define pte_free_tlb(tlb, pte) pte_free(pte)
#define check_pgt_cache() do { } while (0) #define check_pgt_cache() do { } while (0)
......
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