Commit ec5a5b68 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 5e8a4a7d 93f8230d
......@@ -18,7 +18,8 @@ KERNELLOAD =0xc000000000000000
LINKFLAGS = -T arch/ppc64/vmlinux.lds -Bstatic \
-e $(KERNELLOAD) -Ttext $(KERNELLOAD)
CFLAGS := $(CFLAGS) -fsigned-char -msoft-float -pipe \
-Wno-uninitialized -mminimal-toc -mtraceback=full
-Wno-uninitialized -mminimal-toc -mtraceback=full \
-Wa,-mpower4
CPP = $(CC) -E $(CFLAGS)
......
......@@ -153,7 +153,7 @@ make_bi_recs(unsigned long addr)
rec = bi_rec_alloc(rec, 2);
rec->tag = BI_MACHTYPE;
rec->data[0] = _MACH_pSeries;
rec->data[0] = PLATFORM_PSERIES;
rec->data[1] = 1;
if ( initrd_size > 0 ) {
......
......@@ -103,8 +103,12 @@ if [ "$CONFIG_SCSI" != "n" ]; then
fi
endmenu
source drivers/message/fusion/Config.in
source drivers/ieee1394/Config.in
source drivers/message/i2o/Config.in
if [ "$CONFIG_NET" = "y" ]; then
mainmenu_option next_comment
comment 'Network device support'
......@@ -181,6 +185,9 @@ if [ "$CONFIG_VIOCD" = "y" ]; then
fi
source drivers/char/Config.in
source drivers/media/Config.in
source fs/Config.in
mainmenu_option next_comment
......@@ -194,6 +201,8 @@ endmenu
source drivers/usb/Config.in
source net/bluetooth/Config.in
mainmenu_option next_comment
comment 'Kernel hacking'
......
......@@ -146,3 +146,8 @@ int cpu_idle(void)
}
#endif /* CONFIG_PPC_ISERIES */
void default_idle(void)
{
barrier();
}
......@@ -3756,6 +3756,7 @@ COMPATIBLE_IOCTL(TCSETSW),
COMPATIBLE_IOCTL(TCSETSF),
COMPATIBLE_IOCTL(TIOCLINUX),
COMPATIBLE_IOCTL(TIOCSTART),
COMPATIBLE_IOCTL(TIOCSTOP),
/* Little t */
COMPATIBLE_IOCTL(TIOCGETD),
COMPATIBLE_IOCTL(TIOCSETD),
......@@ -4336,8 +4337,6 @@ COMPATIBLE_IOCTL(RNDCLEARPOOL),
COMPATIBLE_IOCTL(HCIDEVUP),
COMPATIBLE_IOCTL(HCIDEVDOWN),
COMPATIBLE_IOCTL(HCIDEVRESET),
COMPATIBLE_IOCTL(HCIRESETSTAT),
COMPATIBLE_IOCTL(HCIGETINFO),
COMPATIBLE_IOCTL(HCIGETDEVLIST),
COMPATIBLE_IOCTL(HCISETRAW),
COMPATIBLE_IOCTL(HCISETSCAN),
......
......@@ -359,7 +359,7 @@ static void pSeries_hpte_invalidate(unsigned long slot, unsigned long va,
/* Invalidate the tlb */
if (!large && local && __is_processor(PV_POWER4)) {
_tlbiel(va, large);
_tlbiel(va);
} else {
spin_lock_irqsave(&pSeries_tlbie_lock, flags);
_tlbie(va, large);
......
......@@ -498,6 +498,8 @@ pcibios_init(void)
}
subsys_initcall(pcibios_init);
int __init
pcibios_assign_all_busses(void)
{
......
/*
* linux/arch/ppc64/kernel/signal.c
*
*
*
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
......@@ -107,11 +105,6 @@ long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
struct pt_regs *regs)
{
sigset_t saveset;
PPCDBG(PPCDBG_SYS64X, "sys_sigsuspend - running - pid=%ld current=%lx comm=%s \n",
current->pid, current, current->comm);
mask &= _BLOCKABLE;
spin_lock_irq(&current->sigmask_lock);
......@@ -142,11 +135,7 @@ long sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int
{
sigset_t saveset, newset;
PPCDBG(PPCDBG_SYS64X, "sys_rt_sigsuspend - running - pid=%ld current=%lx comm=%s \n",
current->pid, current, current->comm);
/* XXX: Don't preclude handling different sized sigset_t's. */
/* XXX: Don't preclude handling different sized sigset_t's. */
if (sigsetsize != sizeof(sigset_t))
return -EINVAL;
......@@ -171,14 +160,10 @@ long sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int
asmlinkage 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;
PPCDBG(PPCDBG_SYS64X, "sys_sigaltstack - running - pid=%ld current=%lx comm=%s \n",
current->pid, current, current->comm);
return do_sigaltstack(uss, uoss, regs->gpr[1]);
struct pt_regs *regs = (struct pt_regs *) &uss;
return do_sigaltstack(uss, uoss, regs->gpr[1]);
}
long sys_sigaction(int sig, const struct old_sigaction *act,
......@@ -187,11 +172,6 @@ long sys_sigaction(int sig, const struct old_sigaction *act,
struct k_sigaction new_ka, old_ka;
int ret;
PPCDBG(PPCDBG_SYS64X, "sys_sigaction - running - pid=%ld current=%lx comm=%s \n",
current->pid, current, current->comm);
if (act) {
old_sigset_t mask;
if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
......@@ -203,7 +183,7 @@ long sys_sigaction(int sig, const struct old_sigaction *act,
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 (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
......@@ -214,9 +194,6 @@ long sys_sigaction(int sig, const struct old_sigaction *act,
__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
}
return ret;
}
......@@ -224,13 +201,11 @@ long sys_sigaction(int sig, const struct old_sigaction *act,
* 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
* 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.
*
* XXX ultimately we will have to stack up a siginfo and ucontext
* for each rt signal.
*/
struct sigregs {
elf_gregset_t gp_regs;
......@@ -241,8 +216,6 @@ struct sigregs {
int abigap[72];
};
struct rt_sigframe
{
unsigned long _unused[2];
......@@ -271,7 +244,6 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
struct rt_sigframe *rt_sf;
struct sigcontext_struct sigctx;
struct sigregs *sr;
int ret;
elf_gregset_t saved_regs; /* an array of ELF_NGREG unsigned longs */
sigset_t set;
stack_t st;
......@@ -287,53 +259,29 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
current->blocked = set;
recalc_sigpending();
spin_unlock_irq(&current->sigmask_lock);
if (regs->msr & MSR_FP)
giveup_fpu(current);
rt_sf++; /* Look at next rt_sigframe */
if (rt_sf == (struct rt_sigframe *)(sigctx.regs)) {
/* Last stacked signal - restore registers -
* sigctx is initialized to point to the
* preamble frame (where registers are stored)
* see handle_signal()
*/
sr = (struct sigregs *) sigctx.regs;
if (regs->msr & MSR_FP )
giveup_fpu(current);
if (copy_from_user(saved_regs, &sr->gp_regs,
sizeof(sr->gp_regs)))
goto badframe;
saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
| (saved_regs[PT_MSR] & MSR_USERCHANGE);
saved_regs[PT_SOFTE] = regs->softe;
memcpy(regs, saved_regs, GP_REGS_SIZE);
if (copy_from_user(current->thread.fpr, &sr->fp_regs,
sizeof(sr->fp_regs)))
goto badframe;
/* This function sets back the stack flags into
the current task structure. */
sys_sigaltstack(&st, NULL);
/* restore registers -
* sigctx is initialized to point to the
* preamble frame (where registers are stored)
* see handle_signal()
*/
sr = (struct sigregs *) sigctx.regs;
if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs)))
goto badframe;
saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
| (saved_regs[PT_MSR] & MSR_USERCHANGE);
saved_regs[PT_SOFTE] = regs->softe;
memcpy(regs, saved_regs, GP_REGS_SIZE);
if (copy_from_user(current->thread.fpr, &sr->fp_regs,
sizeof(sr->fp_regs)))
goto badframe;
/* This function sets back the stack flags into
the current task structure. */
sys_sigaltstack(&st, NULL);
ret = regs->result;
} else {
/* More signals to go */
/* Set up registers for next signal handler */
regs->gpr[1] = (unsigned long)rt_sf - __SIGNAL_FRAMESIZE;
if (copy_from_user(&sigctx, &rt_sf->uc.uc_mcontext, sizeof(sigctx)))
goto badframe;
sr = (struct sigregs *) sigctx.regs;
regs->gpr[3] = ret = sigctx.signal;
/* Get the siginfo */
get_user(regs->gpr[4], (unsigned long *)&rt_sf->pinfo);
/* Get the ucontext */
get_user(regs->gpr[5], (unsigned long *)&rt_sf->puc);
regs->gpr[6] = (unsigned long) rt_sf;
regs->link = (unsigned long) &sr->tramp;
regs->nip = sigctx.handler;
if (get_user(prevsp, &sr->gp_regs[PT_R1])
|| put_user(prevsp, (unsigned long *) regs->gpr[1]))
goto badframe;
}
return ret;
return regs->result;
badframe:
do_exit(SIGSEGV);
......@@ -370,6 +318,7 @@ setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
goto badframe;
flush_icache_range((unsigned long) &frame->tramp[0],
(unsigned long) &frame->tramp[2]);
current->thread.fpscr = 0; /* turn off all fp exceptions */
/* Retrieve rt_sigframe from stack and
set up registers for signal handler
......@@ -394,7 +343,6 @@ setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
regs->gpr[6] = (unsigned long) rt_sf;
regs->link = (unsigned long) frame->tramp;
return;
badframe:
......@@ -414,12 +362,11 @@ long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
{
struct sigcontext_struct *sc, sigctx;
struct sigregs *sr;
long ret;
elf_gregset_t saved_regs; /* an array of ELF_NGREG unsigned longs */
sigset_t set;
unsigned long prevsp;
sc = (struct sigcontext_struct *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
sc = (struct sigcontext_struct *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
goto badframe;
......@@ -432,43 +379,23 @@ long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
current->blocked = set;
recalc_sigpending();
spin_unlock_irq(&current->sigmask_lock);
if (regs->msr & MSR_FP )
giveup_fpu(current);
sc++; /* Look at next sigcontext */
if (sc == (struct sigcontext_struct *)(sigctx.regs)) {
/* Last stacked signal - restore registers */
sr = (struct sigregs *) sigctx.regs;
if (regs->msr & MSR_FP )
giveup_fpu(current);
if (copy_from_user(saved_regs, &sr->gp_regs,
sizeof(sr->gp_regs)))
goto badframe;
saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
| (saved_regs[PT_MSR] & MSR_USERCHANGE);
saved_regs[PT_SOFTE] = regs->softe;
memcpy(regs, saved_regs, GP_REGS_SIZE);
if (copy_from_user(current->thread.fpr, &sr->fp_regs,
sizeof(sr->fp_regs)))
goto badframe;
/* restore registers */
sr = (struct sigregs *) sigctx.regs;
if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs)))
goto badframe;
saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
| (saved_regs[PT_MSR] & MSR_USERCHANGE);
saved_regs[PT_SOFTE] = regs->softe;
memcpy(regs, saved_regs, GP_REGS_SIZE);
ret = regs->result;
if (copy_from_user(current->thread.fpr, &sr->fp_regs,
sizeof(sr->fp_regs)))
goto badframe;
} else {
/* More signals to go */
regs->gpr[1] = (unsigned long)sc - __SIGNAL_FRAMESIZE;
if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
goto badframe;
sr = (struct sigregs *) sigctx.regs;
regs->gpr[3] = ret = sigctx.signal;
regs->gpr[4] = (unsigned long) sc;
regs->link = (unsigned long) &sr->tramp;
regs->nip = sigctx.handler;
if (get_user(prevsp, &sr->gp_regs[PT_R1])
|| put_user(prevsp, (unsigned long *) regs->gpr[1]))
goto badframe;
}
return ret;
return regs->result;
badframe:
do_exit(SIGSEGV);
......@@ -479,7 +406,7 @@ long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
*/
static void
setup_frame(struct pt_regs *regs, struct sigregs *frame,
unsigned long newsp)
unsigned long newsp)
{
/* Handler is *really* a pointer to the function descriptor for
......@@ -509,6 +436,7 @@ setup_frame(struct pt_regs *regs, struct sigregs *frame,
goto badframe;
flush_icache_range((unsigned long) &frame->tramp[0],
(unsigned long) &frame->tramp[2]);
current->thread.fpscr = 0; /* turn off all fp exceptions */
newsp -= __SIGNAL_FRAMESIZE;
if ( get_user(temp_ptr, &sc->handler))
......@@ -525,14 +453,9 @@ setup_frame(struct pt_regs *regs, struct sigregs *frame,
regs->gpr[4] = (unsigned long) sc;
regs->link = (unsigned long) frame->tramp;
PPCDBG(PPCDBG_SIGNAL, "setup_frame - returning - regs->gpr[1]=%lx, regs->gpr[4]=%lx, regs->link=%lx \n",
regs->gpr[1], regs->gpr[4], regs->link);
return;
badframe:
PPCDBG(PPCDBG_SIGNAL, "setup_frame - badframe in setup_frame, regs=%p frame=%p newsp=%lx\n", regs, frame, newsp); PPCDBG_ENTER_DEBUGGER();
badframe:
#if DEBUG_SIG
printk("badframe in setup_frame, regs=%p frame=%p newsp=%lx\n",
regs, frame, newsp);
......@@ -549,22 +472,21 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
unsigned long *newspp, unsigned long frame)
{
struct sigcontext_struct *sc;
struct rt_sigframe *rt_sf;
struct rt_sigframe *rt_sf;
if (regs->trap == 0x0C00 /* System Call! */
&& ((int)regs->result == -ERESTARTNOHAND ||
((int)regs->result == -ERESTARTSYS &&
!(ka->sa.sa_flags & SA_RESTART))))
regs->result = -EINTR;
/* Set up Signal Frame */
/* Set up Signal Frame */
if (ka->sa.sa_flags & SA_SIGINFO) {
/* Put a Real Time Context onto stack */
*newspp -= sizeof(*rt_sf);
rt_sf = (struct rt_sigframe *) *newspp;
if (verify_area(VERIFY_WRITE, rt_sf, sizeof(*rt_sf)))
goto badframe;
if (__put_user((unsigned long) ka->sa.sa_handler, &rt_sf->uc.uc_mcontext.handler)
|| __put_user(&rt_sf->info, &rt_sf->pinfo)
......@@ -583,22 +505,21 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
|| __put_user((struct pt_regs *)frame, &rt_sf->uc.uc_mcontext.regs)
|| __put_user(sig, &rt_sf->uc.uc_mcontext.signal))
goto badframe;
} else {
/* Put another sigcontext on the stack */
*newspp -= sizeof(*sc);
sc = (struct sigcontext_struct *) *newspp;
if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
goto badframe;
if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler)
|| __put_user(oldset->sig[0], &sc->oldmask)
/* Put a sigcontext on the stack */
*newspp -= sizeof(*sc);
sc = (struct sigcontext_struct *) *newspp;
if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
goto badframe;
if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler)
|| __put_user(oldset->sig[0], &sc->oldmask)
#if _NSIG_WORDS > 1
|| __put_user(oldset->sig[1], &sc->_unused[3])
|| __put_user(oldset->sig[1], &sc->_unused[3])
#endif
|| __put_user((struct pt_regs *)frame, &sc->regs)
|| __put_user(sig, &sc->signal))
goto badframe;
|| __put_user((struct pt_regs *)frame, &sc->regs)
|| __put_user(sig, &sc->signal))
goto badframe;
}
if (ka->sa.sa_flags & SA_ONESHOT)
......@@ -649,11 +570,9 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
for (;;) {
unsigned long signr;
PPCDBG(PPCDBG_SIGNAL, "do_signal - (pre) dequeueing signal - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
spin_lock_irq(&current->sigmask_lock);
signr = dequeue_signal(&current->blocked, &info);
spin_unlock_irq(&current->sigmask_lock);
PPCDBG(PPCDBG_SIGNAL, "do_signal - (aft) dequeueing signal - signal=%lx - pid=%ld current=%lx comm=%s \n", signr, current->pid, current, current->comm);
if (!signr)
break;
......@@ -691,12 +610,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
}
ka = &current->sig->action[signr-1];
PPCDBG(PPCDBG_SIGNAL, "do_signal - ka=%p, action handler=%lx \n", ka, ka->sa.sa_handler);
if (ka->sa.sa_handler == SIG_IGN) {
PPCDBG(PPCDBG_SIGNAL, "do_signal - into SIG_IGN logic \n");
if (signr != SIGCHLD)
continue;
/* Check for SIGCHLD: it's special. */
......@@ -707,14 +621,13 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
if (ka->sa.sa_handler == SIG_DFL) {
int exit_code = signr;
PPCDBG(PPCDBG_SIGNAL, "do_signal - into SIG_DFL logic \n");
/* Init gets no signals it doesn't want. */
if (current->pid == 1)
continue;
switch (signr) {
case SIGCONT: case SIGCHLD: case SIGWINCH:
case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
continue;
case SIGTSTP: case SIGTTIN: case SIGTTOU:
......@@ -751,35 +664,25 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
newsp = frame = newsp - sizeof(struct sigregs);
/* Whee! Actually deliver the signal. */
PPCDBG(PPCDBG_SIGNAL, "do_signal - GOING TO RUN SIGNAL HANDLER - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
handle_signal(signr, ka, &info, oldset, regs, &newsp, frame);
PPCDBG(PPCDBG_SIGNAL, "do_signal - after running signal handler - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
break;
break;
}
if (regs->trap == 0x0C00 /* System Call! */ &&
((int)regs->result == -ERESTARTNOHAND ||
(int)regs->result == -ERESTARTSYS ||
(int)regs->result == -ERESTARTNOINTR)) {
PPCDBG(PPCDBG_SIGNAL, "do_signal - going to back up & retry system call \n");
regs->gpr[3] = regs->orig_gpr3;
regs->nip -= 4; /* Back up & retry system call */
regs->result = 0;
}
if (newsp == frame)
{
PPCDBG(PPCDBG_SIGNAL, "do_signal - returning w/ no signal delivered \n");
return 0; /* no signals delivered */
}
return 0; /* no signals delivered */
if (ka->sa.sa_flags & SA_SIGINFO)
setup_rt_frame(regs, (struct sigregs *) frame, newsp);
else
setup_frame(regs, (struct sigregs *) frame, newsp);
PPCDBG(PPCDBG_SIGNAL, "do_signal - returning a signal was delivered \n");
if (ka->sa.sa_flags & SA_SIGINFO)
setup_rt_frame(regs, (struct sigregs *) frame, newsp);
else
setup_frame(regs, (struct sigregs *) frame, newsp);
return 1;
}
......@@ -136,8 +136,6 @@ asmlinkage long sys32_sigaction(int sig, struct old_sigaction32 *act, struct old
struct k_sigaction new_ka, old_ka;
int ret;
PPCDBG(PPCDBG_SYS32, "sys32_sigaction - entered - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
if (sig < 0)
{
sig = -sig;
......@@ -153,12 +151,11 @@ asmlinkage long sys32_sigaction(int sig, struct old_sigaction32 *act, struct old
ret |= __get_user(mask, &act->sa_mask);
if (ret)
return ret;
PPCDBG(PPCDBG_SIGNAL, "sys32_sigaction flags =%lx \n", new_ka.sa.sa_flags);
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)
{
......@@ -168,9 +165,6 @@ asmlinkage long sys32_sigaction(int sig, struct old_sigaction32 *act, struct old
ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
}
PPCDBG(PPCDBG_SYS32, "sys32_sigaction - exited - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
return ret;
}
......@@ -185,15 +179,11 @@ asmlinkage long sys32_sigpending(old_sigset_t32 *set)
int ret;
mm_segment_t old_fs = get_fs();
PPCDBG(PPCDBG_SYS32, "sys32_sigpending - entered - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
set_fs (KERNEL_DS);
ret = sys_sigpending(&s);
set_fs (old_fs);
if (put_user (s, set)) return -EFAULT;
PPCDBG(PPCDBG_SYS32, "sys32_sigpending - exited - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
return ret;
}
......@@ -213,8 +203,6 @@ asmlinkage long sys32_sigprocmask(u32 how, old_sigset_t32 *set, old_sigset_t32 *
int ret;
mm_segment_t old_fs = get_fs();
PPCDBG(PPCDBG_SYS32, "sys32_sigprocmask - entered - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
if (set && get_user (s, set)) return -EFAULT;
set_fs (KERNEL_DS);
ret = sys_sigprocmask((int)how, set ? &s : NULL, oset ? &s : NULL);
......@@ -222,8 +210,6 @@ asmlinkage long sys32_sigprocmask(u32 how, old_sigset_t32 *set, old_sigset_t32 *
if (ret) return ret;
if (oset && put_user (s, oset)) return -EFAULT;
PPCDBG(PPCDBG_SYS32, "sys32_sigprocmask - exited - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
return 0;
}
......@@ -255,8 +241,6 @@ long sys32_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
sigset_t set;
unsigned int prevsp;
PPCDBG(PPCDBG_SIGNAL, "sys32_sigreturn - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
sc = (struct sigcontext32_struct *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32);
if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
goto badframe;
......@@ -270,122 +254,99 @@ long sys32_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
recalc_sigpending();
spin_unlock_irq(&current->sigmask_lock);
sc++; /* Look at next sigcontext */
/* If the next sigcontext is actually the sigregs (frame) */
/* - then no more sigcontexts on the user stack */
if (sc == (struct sigcontext32_struct*)(u64)sigctx.regs)
{
/* Last stacked signal - restore registers */
sr = (struct sigregs32*)(u64)sigctx.regs;
if (regs->msr & MSR_FP )
giveup_fpu(current);
/* copy the 32 bit register values off the user stack */
/* into the 32 bit register area */
if (copy_from_user(saved_regs, &sr->gp_regs,sizeof(sr->gp_regs)))
goto badframe;
/**********************************************************************/
/* The saved reg structure in the frame is an elf_grepset_t32, it is */
/* a 32 bit register save of the registers in the pt_regs structure */
/* that was stored on the kernel stack during the system call */
/* when the system call was interrupted for the signal. Only 32 bits*/
/* are saved because the sigcontext contains a pointer to the regs */
/* and the sig context address is passed as a pointer to the signal */
/* handler. */
/* */
/* The entries in the elf_grepset have the same index as the elements */
/* in the pt_regs structure. */
/* */
/**********************************************************************/
saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
| (saved_regs[PT_MSR] & MSR_USERCHANGE);
regs->gpr[0] = (u64)(saved_regs[0]) & 0xFFFFFFFF;
regs->gpr[1] = (u64)(saved_regs[1]) & 0xFFFFFFFF;
/**********************************************************************/
/* Register 2 is the kernel toc - should be reset on any calls into */
/* the kernel */
/**********************************************************************/
regs->gpr[2] = (u64)(saved_regs[2]) & 0xFFFFFFFF;
regs->gpr[3] = (u64)(saved_regs[3]) & 0xFFFFFFFF;
regs->gpr[4] = (u64)(saved_regs[4]) & 0xFFFFFFFF;
regs->gpr[5] = (u64)(saved_regs[5]) & 0xFFFFFFFF;
regs->gpr[6] = (u64)(saved_regs[6]) & 0xFFFFFFFF;
regs->gpr[7] = (u64)(saved_regs[7]) & 0xFFFFFFFF;
regs->gpr[8] = (u64)(saved_regs[8]) & 0xFFFFFFFF;
regs->gpr[9] = (u64)(saved_regs[9]) & 0xFFFFFFFF;
regs->gpr[10] = (u64)(saved_regs[10]) & 0xFFFFFFFF;
regs->gpr[11] = (u64)(saved_regs[11]) & 0xFFFFFFFF;
regs->gpr[12] = (u64)(saved_regs[12]) & 0xFFFFFFFF;
regs->gpr[13] = (u64)(saved_regs[13]) & 0xFFFFFFFF;
regs->gpr[14] = (u64)(saved_regs[14]) & 0xFFFFFFFF;
regs->gpr[15] = (u64)(saved_regs[15]) & 0xFFFFFFFF;
regs->gpr[16] = (u64)(saved_regs[16]) & 0xFFFFFFFF;
regs->gpr[17] = (u64)(saved_regs[17]) & 0xFFFFFFFF;
regs->gpr[18] = (u64)(saved_regs[18]) & 0xFFFFFFFF;
regs->gpr[19] = (u64)(saved_regs[19]) & 0xFFFFFFFF;
regs->gpr[20] = (u64)(saved_regs[20]) & 0xFFFFFFFF;
regs->gpr[21] = (u64)(saved_regs[21]) & 0xFFFFFFFF;
regs->gpr[22] = (u64)(saved_regs[22]) & 0xFFFFFFFF;
regs->gpr[23] = (u64)(saved_regs[23]) & 0xFFFFFFFF;
regs->gpr[24] = (u64)(saved_regs[24]) & 0xFFFFFFFF;
regs->gpr[25] = (u64)(saved_regs[25]) & 0xFFFFFFFF;
regs->gpr[26] = (u64)(saved_regs[26]) & 0xFFFFFFFF;
regs->gpr[27] = (u64)(saved_regs[27]) & 0xFFFFFFFF;
regs->gpr[28] = (u64)(saved_regs[28]) & 0xFFFFFFFF;
regs->gpr[29] = (u64)(saved_regs[29]) & 0xFFFFFFFF;
regs->gpr[30] = (u64)(saved_regs[30]) & 0xFFFFFFFF;
regs->gpr[31] = (u64)(saved_regs[31]) & 0xFFFFFFFF;
/****************************************************/
/* restore the non gpr registers */
/****************************************************/
regs->msr = (u64)(saved_regs[PT_MSR]) & 0xFFFFFFFF;
/* Insure that the interrupt mode is 64 bit, during 32 bit execution.
* (This is necessary because we only saved lower 32 bits of msr.)
*/
regs->msr = regs->msr | MSR_ISF; /* When this thread is interrupted it should run in 64 bit mode. */
regs->nip = (u64)(saved_regs[PT_NIP]) & 0xFFFFFFFF;
regs->orig_gpr3 = (u64)(saved_regs[PT_ORIG_R3]) & 0xFFFFFFFF;
regs->ctr = (u64)(saved_regs[PT_CTR]) & 0xFFFFFFFF;
regs->link = (u64)(saved_regs[PT_LNK]) & 0xFFFFFFFF;
regs->xer = (u64)(saved_regs[PT_XER]) & 0xFFFFFFFF;
regs->ccr = (u64)(saved_regs[PT_CCR]) & 0xFFFFFFFF;
/* regs->softe is left unchanged (like the MSR.EE bit) */
/******************************************************/
/* the DAR and the DSISR are only relevant during a */
/* data or instruction storage interrupt. The value */
/* will be set to zero. */
/******************************************************/
regs->dar = 0;
regs->dsisr = 0;
regs->result = (u64)(saved_regs[PT_RESULT]) & 0xFFFFFFFF;
if (copy_from_user(current->thread.fpr, &sr->fp_regs, sizeof(sr->fp_regs)))
goto badframe;
/* Last stacked signal - restore registers */
sr = (struct sigregs32*)(u64)sigctx.regs;
if (regs->msr & MSR_FP )
giveup_fpu(current);
/* copy the 32 bit register values off the user stack */
/* into the 32 bit register area */
if (copy_from_user(saved_regs, &sr->gp_regs,sizeof(sr->gp_regs)))
goto badframe;
/**********************************************************************/
/* The saved reg structure in the frame is an elf_grepset_t32, it is */
/* a 32 bit register save of the registers in the pt_regs structure */
/* that was stored on the kernel stack during the system call */
/* when the system call was interrupted for the signal. Only 32 bits*/
/* are saved because the sigcontext contains a pointer to the regs */
/* and the sig context address is passed as a pointer to the signal */
/* handler. */
/* */
/* The entries in the elf_grepset have the same index as the elements */
/* in the pt_regs structure. */
/* */
/**********************************************************************/
saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
| (saved_regs[PT_MSR] & MSR_USERCHANGE);
regs->gpr[0] = (u64)(saved_regs[0]) & 0xFFFFFFFF;
regs->gpr[1] = (u64)(saved_regs[1]) & 0xFFFFFFFF;
/**********************************************************************/
/* Register 2 is the kernel toc - should be reset on any calls into */
/* the kernel */
/**********************************************************************/
regs->gpr[2] = (u64)(saved_regs[2]) & 0xFFFFFFFF;
regs->gpr[3] = (u64)(saved_regs[3]) & 0xFFFFFFFF;
regs->gpr[4] = (u64)(saved_regs[4]) & 0xFFFFFFFF;
regs->gpr[5] = (u64)(saved_regs[5]) & 0xFFFFFFFF;
regs->gpr[6] = (u64)(saved_regs[6]) & 0xFFFFFFFF;
regs->gpr[7] = (u64)(saved_regs[7]) & 0xFFFFFFFF;
regs->gpr[8] = (u64)(saved_regs[8]) & 0xFFFFFFFF;
regs->gpr[9] = (u64)(saved_regs[9]) & 0xFFFFFFFF;
regs->gpr[10] = (u64)(saved_regs[10]) & 0xFFFFFFFF;
regs->gpr[11] = (u64)(saved_regs[11]) & 0xFFFFFFFF;
regs->gpr[12] = (u64)(saved_regs[12]) & 0xFFFFFFFF;
regs->gpr[13] = (u64)(saved_regs[13]) & 0xFFFFFFFF;
regs->gpr[14] = (u64)(saved_regs[14]) & 0xFFFFFFFF;
regs->gpr[15] = (u64)(saved_regs[15]) & 0xFFFFFFFF;
regs->gpr[16] = (u64)(saved_regs[16]) & 0xFFFFFFFF;
regs->gpr[17] = (u64)(saved_regs[17]) & 0xFFFFFFFF;
regs->gpr[18] = (u64)(saved_regs[18]) & 0xFFFFFFFF;
regs->gpr[19] = (u64)(saved_regs[19]) & 0xFFFFFFFF;
regs->gpr[20] = (u64)(saved_regs[20]) & 0xFFFFFFFF;
regs->gpr[21] = (u64)(saved_regs[21]) & 0xFFFFFFFF;
regs->gpr[22] = (u64)(saved_regs[22]) & 0xFFFFFFFF;
regs->gpr[23] = (u64)(saved_regs[23]) & 0xFFFFFFFF;
regs->gpr[24] = (u64)(saved_regs[24]) & 0xFFFFFFFF;
regs->gpr[25] = (u64)(saved_regs[25]) & 0xFFFFFFFF;
regs->gpr[26] = (u64)(saved_regs[26]) & 0xFFFFFFFF;
regs->gpr[27] = (u64)(saved_regs[27]) & 0xFFFFFFFF;
regs->gpr[28] = (u64)(saved_regs[28]) & 0xFFFFFFFF;
regs->gpr[29] = (u64)(saved_regs[29]) & 0xFFFFFFFF;
regs->gpr[30] = (u64)(saved_regs[30]) & 0xFFFFFFFF;
regs->gpr[31] = (u64)(saved_regs[31]) & 0xFFFFFFFF;
/****************************************************/
/* restore the non gpr registers */
/****************************************************/
regs->msr = (u64)(saved_regs[PT_MSR]) & 0xFFFFFFFF;
/* Insure that the interrupt mode is 64 bit, during 32 bit execution.
* (This is necessary because we only saved lower 32 bits of msr.)
*/
regs->msr = regs->msr | MSR_ISF; /* When this thread is interrupted it should run in 64 bit mode. */
regs->nip = (u64)(saved_regs[PT_NIP]) & 0xFFFFFFFF;
regs->orig_gpr3 = (u64)(saved_regs[PT_ORIG_R3]) & 0xFFFFFFFF;
regs->ctr = (u64)(saved_regs[PT_CTR]) & 0xFFFFFFFF;
regs->link = (u64)(saved_regs[PT_LNK]) & 0xFFFFFFFF;
regs->xer = (u64)(saved_regs[PT_XER]) & 0xFFFFFFFF;
regs->ccr = (u64)(saved_regs[PT_CCR]) & 0xFFFFFFFF;
/* regs->softe is left unchanged (like the MSR.EE bit) */
/******************************************************/
/* the DAR and the DSISR are only relevant during a */
/* data or instruction storage interrupt. The value */
/* will be set to zero. */
/******************************************************/
regs->dar = 0;
regs->dsisr = 0;
regs->result = (u64)(saved_regs[PT_RESULT]) & 0xFFFFFFFF;
if (copy_from_user(current->thread.fpr, &sr->fp_regs, sizeof(sr->fp_regs)))
goto badframe;
ret = regs->result;
} else {
/* More signals to go */
regs->gpr[1] = (unsigned long)sc - __SIGNAL_FRAMESIZE32;
if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
goto badframe;
sr = (struct sigregs32*)(u64)sigctx.regs;
regs->gpr[3] = ret = sigctx.signal;
regs->gpr[4] = (unsigned long) sc;
regs->link = (unsigned long) &sr->tramp;
regs->nip = sigctx.handler;
if (get_user(prevsp, &sr->gp_regs[PT_R1])
|| put_user(prevsp, (unsigned int*) regs->gpr[1]))
goto badframe;
}
PPCDBG(PPCDBG_SIGNAL, "sys32_sigreturn - normal exit returning %ld - pid=%ld current=%lx comm=%s \n", ret, current->pid, current, current->comm);
ret = regs->result;
return ret;
badframe:
PPCDBG(PPCDBG_SYS32NI, "sys32_sigreturn - badframe - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
do_exit(SIGSEGV);
}
......@@ -487,6 +448,7 @@ setup_frame32(struct pt_regs *regs, struct sigregs32 *frame,
flush_icache_range((unsigned long) &frame->tramp[0],
(unsigned long) &frame->tramp[2]);
current->thread.fpscr = 0; /* turn off all fp exceptions */
newsp -= __SIGNAL_FRAMESIZE32;
if (put_user(regs->gpr[1], (u32*)(u64)newsp)
......@@ -505,8 +467,7 @@ setup_frame32(struct pt_regs *regs, struct sigregs32 *frame,
regs->link = (unsigned long) frame->tramp;
return;
badframe:
udbg_printf("setup_frame32 - badframe in setup_frame, regs=%p frame=%p newsp=%lx\n", regs, frame, newsp); PPCDBG_ENTER_DEBUGGER();
badframe:
#if DEBUG_SIG
printk("badframe in setup_frame32, regs=%p frame=%p newsp=%lx\n",
regs, frame, newsp);
......@@ -552,7 +513,6 @@ long sys32_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
elf_gregset_t32 saved_regs; /* an array of 32 bit register values */
sigset_t signal_set;
stack_t stack;
unsigned int previous_stack;
ret = 0;
/* Adjust the inputted reg1 to point to the first rt signal frame */
......@@ -581,125 +541,90 @@ long sys32_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
/* Set to point to the next rt_sigframe - this is used to determine whether this
* is the last signal to process
*/
rt_stack_frame ++;
if (rt_stack_frame == (struct rt_sigframe_32 *)(u64)(sigctx.regs))
signalregs = (struct sigregs32 *) (u64)sigctx.regs;
/* If currently owning the floating point - give them up */
if (regs->msr & MSR_FP)
{
signalregs = (struct sigregs32 *) (u64)sigctx.regs;
/* If currently owning the floating point - give them up */
if (regs->msr & MSR_FP)
{
giveup_fpu(current);
}
if (copy_from_user(saved_regs,&signalregs->gp_regs,sizeof(signalregs->gp_regs)))
{
goto badframe;
}
/**********************************************************************/
/* The saved reg structure in the frame is an elf_grepset_t32, it is */
/* a 32 bit register save of the registers in the pt_regs structure */
/* that was stored on the kernel stack during the system call */
/* when the system call was interrupted for the signal. Only 32 bits*/
/* are saved because the sigcontext contains a pointer to the regs */
/* and the sig context address is passed as a pointer to the signal */
/* handler. */
/* */
/* The entries in the elf_grepset have the same index as the elements */
/* in the pt_regs structure. */
/* */
/**********************************************************************/
saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
| (saved_regs[PT_MSR] & MSR_USERCHANGE);
regs->gpr[0] = (u64)(saved_regs[0]) & 0xFFFFFFFF;
regs->gpr[1] = (u64)(saved_regs[1]) & 0xFFFFFFFF;
/**********************************************************************/
/* Register 2 is the kernel toc - should be reset on any calls into */
/* the kernel */
/**********************************************************************/
regs->gpr[2] = (u64)(saved_regs[2]) & 0xFFFFFFFF;
regs->gpr[3] = (u64)(saved_regs[3]) & 0xFFFFFFFF;
regs->gpr[4] = (u64)(saved_regs[4]) & 0xFFFFFFFF;
regs->gpr[5] = (u64)(saved_regs[5]) & 0xFFFFFFFF;
regs->gpr[6] = (u64)(saved_regs[6]) & 0xFFFFFFFF;
regs->gpr[7] = (u64)(saved_regs[7]) & 0xFFFFFFFF;
regs->gpr[8] = (u64)(saved_regs[8]) & 0xFFFFFFFF;
regs->gpr[9] = (u64)(saved_regs[9]) & 0xFFFFFFFF;
regs->gpr[10] = (u64)(saved_regs[10]) & 0xFFFFFFFF;
regs->gpr[11] = (u64)(saved_regs[11]) & 0xFFFFFFFF;
regs->gpr[12] = (u64)(saved_regs[12]) & 0xFFFFFFFF;
regs->gpr[13] = (u64)(saved_regs[13]) & 0xFFFFFFFF;
regs->gpr[14] = (u64)(saved_regs[14]) & 0xFFFFFFFF;
regs->gpr[15] = (u64)(saved_regs[15]) & 0xFFFFFFFF;
regs->gpr[16] = (u64)(saved_regs[16]) & 0xFFFFFFFF;
regs->gpr[17] = (u64)(saved_regs[17]) & 0xFFFFFFFF;
regs->gpr[18] = (u64)(saved_regs[18]) & 0xFFFFFFFF;
regs->gpr[19] = (u64)(saved_regs[19]) & 0xFFFFFFFF;
regs->gpr[20] = (u64)(saved_regs[20]) & 0xFFFFFFFF;
regs->gpr[21] = (u64)(saved_regs[21]) & 0xFFFFFFFF;
regs->gpr[22] = (u64)(saved_regs[22]) & 0xFFFFFFFF;
regs->gpr[23] = (u64)(saved_regs[23]) & 0xFFFFFFFF;
regs->gpr[24] = (u64)(saved_regs[24]) & 0xFFFFFFFF;
regs->gpr[25] = (u64)(saved_regs[25]) & 0xFFFFFFFF;
regs->gpr[26] = (u64)(saved_regs[26]) & 0xFFFFFFFF;
regs->gpr[27] = (u64)(saved_regs[27]) & 0xFFFFFFFF;
regs->gpr[28] = (u64)(saved_regs[28]) & 0xFFFFFFFF;
regs->gpr[29] = (u64)(saved_regs[29]) & 0xFFFFFFFF;
regs->gpr[30] = (u64)(saved_regs[30]) & 0xFFFFFFFF;
regs->gpr[31] = (u64)(saved_regs[31]) & 0xFFFFFFFF;
/****************************************************/
/* restore the non gpr registers */
/****************************************************/
regs->msr = (u64)(saved_regs[PT_MSR]) & 0xFFFFFFFF;
regs->nip = (u64)(saved_regs[PT_NIP]) & 0xFFFFFFFF;
regs->orig_gpr3 = (u64)(saved_regs[PT_ORIG_R3]) & 0xFFFFFFFF;
regs->ctr = (u64)(saved_regs[PT_CTR]) & 0xFFFFFFFF;
regs->link = (u64)(saved_regs[PT_LNK]) & 0xFFFFFFFF;
regs->xer = (u64)(saved_regs[PT_XER]) & 0xFFFFFFFF;
regs->ccr = (u64)(saved_regs[PT_CCR]) & 0xFFFFFFFF;
/* regs->softe is left unchanged (like MSR.EE) */
/******************************************************/
/* the DAR and the DSISR are only relevant during a */
/* data or instruction storage interrupt. The value */
/* will be set to zero. */
/******************************************************/
regs->dar = 0;
regs->dsisr = 0;
regs->result = (u64)(saved_regs[PT_RESULT]) & 0xFFFFFFFF;
ret = regs->result;
giveup_fpu(current);
}
else /* more signals to go */
if (copy_from_user(saved_regs,&signalregs->gp_regs,sizeof(signalregs->gp_regs)))
{
udbg_printf("hey should not occur\n");
regs->gpr[1] = (u64)rt_stack_frame - __SIGNAL_FRAMESIZE32;
if (copy_from_user(&sigctx, &rt_stack_frame->uc.uc_mcontext,sizeof(sigctx)))
{
goto badframe;
}
signalregs = (struct sigregs32 *) (u64)sigctx.regs;
/* first parm to signal handler is the signal number */
regs->gpr[3] = ret = sigctx.signal;
/* second parm is a pointer to sig info */
get_user(regs->gpr[4], &rt_stack_frame->pinfo);
/* third parm is a pointer to the ucontext */
get_user(regs->gpr[5], &rt_stack_frame->puc);
/* fourth parm is the stack frame */
regs->gpr[6] = (u64)rt_stack_frame;
/* Set up link register to return to sigreturn when the */
/* signal handler completes */
regs->link = (u64)&signalregs->tramp;
/* Set next instruction to the start fo the signal handler */
regs->nip = sigctx.handler;
/* Set the reg1 to look like a call to the signal handler */
if (get_user(previous_stack,&signalregs->gp_regs[PT_R1])
|| put_user(previous_stack, (unsigned long *)regs->gpr[1]))
{
goto badframe;
}
goto badframe;
}
/**********************************************************************/
/* The saved reg structure in the frame is an elf_grepset_t32, it is */
/* a 32 bit register save of the registers in the pt_regs structure */
/* that was stored on the kernel stack during the system call */
/* when the system call was interrupted for the signal. Only 32 bits*/
/* are saved because the sigcontext contains a pointer to the regs */
/* and the sig context address is passed as a pointer to the signal */
/* handler. */
/* */
/* The entries in the elf_grepset have the same index as the elements */
/* in the pt_regs structure. */
/* */
/**********************************************************************/
saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
| (saved_regs[PT_MSR] & MSR_USERCHANGE);
regs->gpr[0] = (u64)(saved_regs[0]) & 0xFFFFFFFF;
regs->gpr[1] = (u64)(saved_regs[1]) & 0xFFFFFFFF;
/**********************************************************************/
/* Register 2 is the kernel toc - should be reset on any calls into */
/* the kernel */
/**********************************************************************/
regs->gpr[2] = (u64)(saved_regs[2]) & 0xFFFFFFFF;
regs->gpr[3] = (u64)(saved_regs[3]) & 0xFFFFFFFF;
regs->gpr[4] = (u64)(saved_regs[4]) & 0xFFFFFFFF;
regs->gpr[5] = (u64)(saved_regs[5]) & 0xFFFFFFFF;
regs->gpr[6] = (u64)(saved_regs[6]) & 0xFFFFFFFF;
regs->gpr[7] = (u64)(saved_regs[7]) & 0xFFFFFFFF;
regs->gpr[8] = (u64)(saved_regs[8]) & 0xFFFFFFFF;
regs->gpr[9] = (u64)(saved_regs[9]) & 0xFFFFFFFF;
regs->gpr[10] = (u64)(saved_regs[10]) & 0xFFFFFFFF;
regs->gpr[11] = (u64)(saved_regs[11]) & 0xFFFFFFFF;
regs->gpr[12] = (u64)(saved_regs[12]) & 0xFFFFFFFF;
regs->gpr[13] = (u64)(saved_regs[13]) & 0xFFFFFFFF;
regs->gpr[14] = (u64)(saved_regs[14]) & 0xFFFFFFFF;
regs->gpr[15] = (u64)(saved_regs[15]) & 0xFFFFFFFF;
regs->gpr[16] = (u64)(saved_regs[16]) & 0xFFFFFFFF;
regs->gpr[17] = (u64)(saved_regs[17]) & 0xFFFFFFFF;
regs->gpr[18] = (u64)(saved_regs[18]) & 0xFFFFFFFF;
regs->gpr[19] = (u64)(saved_regs[19]) & 0xFFFFFFFF;
regs->gpr[20] = (u64)(saved_regs[20]) & 0xFFFFFFFF;
regs->gpr[21] = (u64)(saved_regs[21]) & 0xFFFFFFFF;
regs->gpr[22] = (u64)(saved_regs[22]) & 0xFFFFFFFF;
regs->gpr[23] = (u64)(saved_regs[23]) & 0xFFFFFFFF;
regs->gpr[24] = (u64)(saved_regs[24]) & 0xFFFFFFFF;
regs->gpr[25] = (u64)(saved_regs[25]) & 0xFFFFFFFF;
regs->gpr[26] = (u64)(saved_regs[26]) & 0xFFFFFFFF;
regs->gpr[27] = (u64)(saved_regs[27]) & 0xFFFFFFFF;
regs->gpr[28] = (u64)(saved_regs[28]) & 0xFFFFFFFF;
regs->gpr[29] = (u64)(saved_regs[29]) & 0xFFFFFFFF;
regs->gpr[30] = (u64)(saved_regs[30]) & 0xFFFFFFFF;
regs->gpr[31] = (u64)(saved_regs[31]) & 0xFFFFFFFF;
/****************************************************/
/* restore the non gpr registers */
/****************************************************/
regs->msr = (u64)(saved_regs[PT_MSR]) & 0xFFFFFFFF;
regs->nip = (u64)(saved_regs[PT_NIP]) & 0xFFFFFFFF;
regs->orig_gpr3 = (u64)(saved_regs[PT_ORIG_R3]) & 0xFFFFFFFF;
regs->ctr = (u64)(saved_regs[PT_CTR]) & 0xFFFFFFFF;
regs->link = (u64)(saved_regs[PT_LNK]) & 0xFFFFFFFF;
regs->xer = (u64)(saved_regs[PT_XER]) & 0xFFFFFFFF;
regs->ccr = (u64)(saved_regs[PT_CCR]) & 0xFFFFFFFF;
/* regs->softe is left unchanged (like MSR.EE) */
/******************************************************/
/* the DAR and the DSISR are only relevant during a */
/* data or instruction storage interrupt. The value */
/* will be set to zero. */
/******************************************************/
regs->dar = 0;
regs->dsisr = 0;
regs->result = (u64)(saved_regs[PT_RESULT]) & 0xFFFFFFFF;
ret = regs->result;
return ret;
......@@ -715,8 +640,6 @@ asmlinkage long sys32_rt_sigaction(int sig, const struct sigaction32 *act, struc
int ret;
sigset32_t set32;
PPCDBG(PPCDBG_SIGNAL, "sys32_rt_sigaction - entered - sig=%x \n", sig);
/* XXX: Don't preclude handling different sized sigset_t's. */
if (sigsetsize != sizeof(sigset32_t))
return -EINVAL;
......@@ -765,8 +688,6 @@ asmlinkage long sys32_rt_sigaction(int sig, const struct sigaction32 *act, struc
ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
}
PPCDBG(PPCDBG_SIGNAL, "sys32_rt_sigaction - exiting - sig=%x \n", sig);
return ret;
}
......@@ -786,8 +707,6 @@ asmlinkage long sys32_rt_sigprocmask(u32 how, sigset32_t *set, sigset32_t *oset,
int ret;
mm_segment_t old_fs = get_fs();
PPCDBG(PPCDBG_SIGNAL, "sys32_rt_sigprocmask - entered how=%x \n", (int)how);
if (set) {
if (copy_from_user (&s32, set, sizeof(sigset32_t)))
return -EFAULT;
......@@ -1145,6 +1064,7 @@ setup_rt_frame32(struct pt_regs *regs, struct sigregs32 *frame,
flush_icache_range((unsigned long) &frame->tramp[0],
(unsigned long) &frame->tramp[2]);
current->thread.fpscr = 0; /* turn off all fp exceptions */
/* Retrieve rt_sigframe from stack and
......@@ -1172,9 +1092,7 @@ setup_rt_frame32(struct pt_regs *regs, struct sigregs32 *frame,
return;
badframe:
udbg_printf("setup_frame32 - badframe in setup_frame, regs=%p frame=%p newsp=%lx\n", regs, frame, newsp); PPCDBG_ENTER_DEBUGGER();
badframe:
#if DEBUG_SIG
printk("badframe in setup_frame32, regs=%p frame=%p newsp=%lx\n",
regs, frame, newsp);
......@@ -1182,7 +1100,6 @@ setup_rt_frame32(struct pt_regs *regs, struct sigregs32 *frame,
do_exit(SIGSEGV);
}
/*
* OK, we're invoking a handler
*/
......@@ -1259,7 +1176,6 @@ handle_signal32(unsigned long sig, struct k_sigaction *ka,
recalc_sigpending();
spin_unlock_irq(&current->sigmask_lock);
}
return;
badframe:
......@@ -1345,14 +1261,10 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
for (;;) {
unsigned long signr;
spin_lock_irq(&current->sigmask_lock);
signr = dequeue_signal(&current->blocked, &info);
spin_unlock_irq(&current->sigmask_lock);
ifppcdebug(PPCDBG_SYS32) {
if (signr)
udbg_printf("do_signal32 - processing signal=%2lx - pid=%ld, comm=%s \n", signr, current->pid, current->comm);
}
if (!signr)
break;
......@@ -1390,7 +1302,6 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
}
ka = &current->sig->action[signr-1];
if (ka->sa.sa_handler == SIG_IGN) {
if (signr != SIGCHLD)
continue;
......@@ -1408,7 +1319,7 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
continue;
switch (signr) {
case SIGCONT: case SIGCHLD: case SIGWINCH:
case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
continue;
case SIGTSTP: case SIGTTIN: case SIGTTOU:
......@@ -1437,19 +1348,10 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
}
}
PPCDBG(PPCDBG_SIGNAL, " do signal :sigaction flags = %lx \n" ,ka->sa.sa_flags);
PPCDBG(PPCDBG_SIGNAL, " do signal :on sig stack = %lx \n" ,on_sig_stack(regs->gpr[1]));
PPCDBG(PPCDBG_SIGNAL, " do signal :reg1 = %lx \n" ,regs->gpr[1]);
PPCDBG(PPCDBG_SIGNAL, " do signal :alt stack = %lx \n" ,current->sas_ss_sp);
PPCDBG(PPCDBG_SIGNAL, " do signal :alt stack size = %lx \n" ,current->sas_ss_size);
if ( (ka->sa.sa_flags & SA_ONSTACK)
&& (! on_sig_stack(regs->gpr[1])))
{
newsp = (current->sas_ss_sp + current->sas_ss_size);
} else
else
newsp = regs->gpr[1];
newsp = frame = newsp - sizeof(struct sigregs32);
......@@ -1468,15 +1370,12 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
}
if (newsp == frame)
{
return 0; /* no signals delivered */
}
// Invoke correct stack setup routine
if (ka->sa.sa_flags & SA_SIGINFO)
/* Invoke correct stack setup routine */
if (ka->sa.sa_flags & SA_SIGINFO)
setup_rt_frame32(regs, (struct sigregs32*)(u64)frame, newsp);
else
setup_frame32(regs, (struct sigregs32*)(u64)frame, newsp);
return 1;
}
......@@ -22,7 +22,7 @@ int make_ste(unsigned long stab,
unsigned long esid, unsigned long vsid);
void make_slbe(unsigned long esid, unsigned long vsid,
int large);
extern struct Naca *naca;
extern struct naca_struct *naca;
/*
* Build an entry for the base kernel segment and put it into
......
......@@ -53,6 +53,7 @@ extern void (*xmon_fault_handler)(struct pt_regs *regs);
#endif
#ifdef CONFIG_XMON
#define CONFIG_DEBUGGER
void (*debugger)(struct pt_regs *regs) = xmon;
int (*debugger_bpt)(struct pt_regs *regs) = xmon_bpt;
int (*debugger_sstep)(struct pt_regs *regs) = xmon_sstep;
......@@ -61,6 +62,7 @@ int (*debugger_dabr_match)(struct pt_regs *regs) = xmon_dabr_match;
void (*debugger_fault_handler)(struct pt_regs *regs);
#else
#ifdef CONFIG_KGDB
#define CONFIG_DEBUGGER
void (*debugger)(struct pt_regs *regs);
int (*debugger_bpt)(struct pt_regs *regs);
int (*debugger_sstep)(struct pt_regs *regs);
......@@ -69,29 +71,46 @@ int (*debugger_dabr_match)(struct pt_regs *regs);
void (*debugger_fault_handler)(struct pt_regs *regs);
#endif
#endif
/*
* Trap & Exception support
*/
void
_exception(int signr, struct pt_regs *regs)
/* Should we panic on bad kernel exceptions or try to recover */
#undef PANIC_ON_ERROR
static spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
void die(const char *str, struct pt_regs *regs, long err)
{
if (!user_mode(regs))
{
show_regs(regs);
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
debugger(regs);
console_verbose();
spin_lock_irq(&die_lock);
bust_spinlocks(1);
printk("Oops: %s, sig: %ld\n", str, err);
show_regs(regs);
print_backtrace((unsigned long *)regs->gpr[1]);
bust_spinlocks(0);
spin_unlock_irq(&die_lock);
#ifdef PANIC_ON_ERROR
panic(str);
#else
do_exit(SIGSEGV);
#endif
print_backtrace((unsigned long *)regs->gpr[1]);
panic("Exception in kernel pc %lx signal %d",regs->nip,signr);
#if defined(CONFIG_PPCDBG) && (defined(CONFIG_XMON) || defined(CONFIG_KGDB))
/* Allow us to catch SIGILLs for 64-bit app/glibc debugging. -Peter */
} else if (signr == SIGILL) {
ifppcdebug(PPCDBG_SIGNALXMON)
}
static void
_exception(int signr, siginfo_t *info, struct pt_regs *regs)
{
if (!user_mode(regs)) {
#ifdef CONFIG_DEBUGGER
if (debugger)
debugger(regs);
#endif
die("Exception in kernel mode\n", regs, signr);
}
force_sig(signr, current);
force_sig_info(signr, info, current);
}
/* Get the error information for errors coming through the
......@@ -130,9 +149,8 @@ static void FWNMI_release_errinfo(void)
void
SystemResetException(struct pt_regs *regs)
{
char *msg = "System Reset in kernel mode.\n";
udbg_printf(msg); printk(msg);
if (fwnmi_active) {
char *msg;
unsigned long *r3 = __va(regs->gpr[3]); /* for FWNMI debug */
struct rtas_error_log *errlog;
......@@ -140,17 +158,33 @@ SystemResetException(struct pt_regs *regs)
udbg_printf(msg, r3); printk(msg, r3);
errlog = FWNMI_get_errinfo(regs);
}
#if defined(CONFIG_XMON)
xmon(regs);
udbg_printf("leaving xmon...\n");
#ifdef CONFIG_DEBUGGER
if (debugger)
debugger(regs);
#endif
#ifdef PANIC_ON_ERROR
panic("System Reset");
#else
for(;;);
/* Must die if the interrupt is not recoverable */
if (!(regs->msr & MSR_RI))
panic("Unrecoverable System Reset");
#endif
/* What should we do here? We could issue a shutdown or hard reset. */
}
static int power4_handle_mce(struct pt_regs *regs)
{
return 0;
}
void
MachineCheckException(struct pt_regs *regs)
{
siginfo_t info;
if (fwnmi_active) {
struct rtas_error_log *errhdr = FWNMI_get_errinfo(regs);
if (errhdr) {
......@@ -158,117 +192,227 @@ MachineCheckException(struct pt_regs *regs)
}
FWNMI_release_errinfo();
}
if ( !user_mode(regs) )
{
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
if (!user_mode(regs)) {
/* Attempt to recover if the interrupt is recoverable */
if (regs->msr & MSR_RI) {
if (__is_processor(PV_POWER4) &&
power4_handle_mce(regs))
return;
}
#ifdef CONFIG_DEBUGGER
if (debugger_fault_handler) {
debugger_fault_handler(regs);
return;
}
if (debugger)
debugger(regs);
#endif
console_verbose();
spin_lock_irq(&die_lock);
bust_spinlocks(1);
printk("Machine check in kernel mode.\n");
printk("Caused by (from SRR1=%lx): ", regs->msr);
show_regs(regs);
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
debugger(regs);
#endif
print_backtrace((unsigned long *)regs->gpr[1]);
panic("machine check");
bust_spinlocks(0);
spin_unlock_irq(&die_lock);
panic("Unrecoverable Machine Check");
}
_exception(SIGSEGV, regs);
}
void
SMIException(struct pt_regs *regs)
{
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
{
debugger(regs);
return;
}
#endif
show_regs(regs);
print_backtrace((unsigned long *)regs->gpr[1]);
panic("System Management Interrupt");
/*
* XXX we should check RI bit on exception exit and kill the
* task if it was cleared
*/
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRERR;
info.si_addr = (void *)regs->nip;
_exception(SIGSEGV, &info, regs);
}
void
UnknownException(struct pt_regs *regs)
{
siginfo_t info;
printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
regs->nip, regs->msr, regs->trap);
_exception(SIGTRAP, regs);
info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = 0;
info.si_addr = 0;
_exception(SIGTRAP, &info, regs);
}
void
InstructionBreakpointException(struct pt_regs *regs)
{
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
if (debugger_iabr_match(regs))
siginfo_t info;
#ifdef CONFIG_DEBUGGER
if (debugger_iabr_match && debugger_iabr_match(regs))
return;
#endif
_exception(SIGTRAP, regs);
info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_BRKPT;
info.si_addr = (void *)regs->nip;
_exception(SIGTRAP, &info, regs);
}
static void parse_fpe(struct pt_regs *regs)
{
siginfo_t info;
unsigned int *tmp;
unsigned int fpscr;
if (regs->msr & MSR_FP)
giveup_fpu(current);
tmp = &current->thread.fpscr;
fpscr = *tmp;
/* Invalid operation */
if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX))
info.si_code = FPE_FLTINV;
/* Overflow */
else if ((fpscr & FPSCR_OE) && (fpscr & FPSCR_OX))
info.si_code = FPE_FLTOVF;
/* Underflow */
else if ((fpscr & FPSCR_UE) && (fpscr & FPSCR_UX))
info.si_code = FPE_FLTUND;
/* Divide by zero */
else if ((fpscr & FPSCR_ZE) && (fpscr & FPSCR_ZX))
info.si_code = FPE_FLTDIV;
/* Inexact result */
else if ((fpscr & FPSCR_XE) && (fpscr & FPSCR_XX))
info.si_code = FPE_FLTRES;
else
info.si_code = 0;
info.si_signo = SIGFPE;
info.si_errno = 0;
info.si_addr = (void *)regs->nip;
_exception(SIGFPE, &info, regs);
}
void
ProgramCheckException(struct pt_regs *regs)
{
siginfo_t info;
if (regs->msr & 0x100000) {
/* IEEE FP exception */
_exception(SIGFPE, regs);
parse_fpe(regs);
} else if (regs->msr & 0x40000) {
/* Privileged instruction */
info.si_signo = SIGILL;
info.si_errno = 0;
info.si_code = ILL_PRVOPC;
info.si_addr = (void *)regs->nip;
_exception(SIGILL, &info, regs);
} else if (regs->msr & 0x20000) {
/* trap exception */
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
if (debugger_bpt(regs))
#ifdef CONFIG_DEBUGGER
if (debugger_bpt && debugger_bpt(regs))
return;
#endif
_exception(SIGTRAP, regs);
info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_BRKPT;
info.si_addr = (void *)regs->nip;
_exception(SIGTRAP, &info, regs);
} else {
_exception(SIGILL, regs);
/* Illegal instruction */
info.si_signo = SIGILL;
info.si_errno = 0;
info.si_code = ILL_ILLTRP;
info.si_addr = (void *)regs->nip;
_exception(SIGILL, &info, regs);
}
}
void
SingleStepException(struct pt_regs *regs)
{
siginfo_t info;
regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
if (debugger_sstep(regs))
#ifdef CONFIG_DEBUGGER
if (debugger_sstep && debugger_sstep(regs))
return;
#endif
_exception(SIGTRAP, regs);
}
/* Dummy handler for Performance Monitor */
info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_TRACE;
info.si_addr = (void *)regs->nip;
_exception(SIGTRAP, &info, regs);
}
void
PerformanceMonitorException(struct pt_regs *regs)
{
_exception(SIGTRAP, regs);
siginfo_t info;
info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_BRKPT;
info.si_addr = 0;
_exception(SIGTRAP, &info, regs);
}
void
AlignmentException(struct pt_regs *regs)
{
int fixed;
siginfo_t info;
fixed = fix_alignment(regs);
if (fixed == 1) {
ifppcdebug(PPCDBG_ALIGNFIXUP)
if (!user_mode(regs))
PPCDBG(PPCDBG_ALIGNFIXUP, "fix alignment at %lx\n", regs->nip);
if (!user_mode(regs))
PPCDBG(PPCDBG_ALIGNFIXUP, "fix alignment at %lx\n",
regs->nip);
regs->nip += 4; /* skip over emulated instruction */
return;
}
/* Operand address was bad */
if (fixed == -EFAULT) {
/* fixed == -EFAULT means the operand address was bad */
if (user_mode(regs))
force_sig(SIGSEGV, current);
else
if (user_mode(regs)) {
info.si_signo = SIGSEGV;
info.si_errno = 0;
info.si_code = SEGV_MAPERR;
info.si_addr = (void *)regs->dar;
force_sig_info(SIGSEGV, &info, current);
} else {
/* Search exception table */
bad_page_fault(regs, regs->dar);
}
return;
}
_exception(SIGBUS, regs);
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRALN;
info.si_addr = (void *)regs->nip;
_exception(SIGBUS, &info, regs);
}
void __init trap_init(void)
......
......@@ -45,9 +45,7 @@ extern int (*debugger_dabr_match)(struct pt_regs *);
int debugger_kernel_faults = 1;
#endif
extern void die_if_kernel(char *, struct pt_regs *, long);
void bad_page_fault(struct pt_regs *, unsigned long);
void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
void bad_page_fault(struct pt_regs *, unsigned long, int);
/*
* For 600- and 800-family processors, the error_code parameter is DSISR
......@@ -86,7 +84,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
#endif /* CONFIG_XMON || CONFIG_KGDB */
if (in_interrupt() || mm == NULL) {
bad_page_fault(regs, address);
bad_page_fault(regs, address, SIGSEGV);
return;
}
down_read(&mm->mmap_sem);
......@@ -143,7 +141,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
bad_area:
up_read(&mm->mmap_sem);
/* User mode accesses cause a SIGSEGV */
if (user_mode(regs)) {
info.si_signo = SIGSEGV;
......@@ -159,7 +157,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
return;
}
bad_page_fault(regs, address);
bad_page_fault(regs, address, SIGSEGV);
return;
/*
......@@ -176,7 +174,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
printk("VM: killing process %s\n", current->comm);
if (user_mode(regs))
do_exit(SIGKILL);
bad_page_fault(regs, address);
bad_page_fault(regs, address, SIGKILL);
return;
do_sigbus:
......@@ -187,7 +185,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
info.si_addr = (void *)address;
force_sig_info (SIGBUS, &info, current);
if (!user_mode(regs))
bad_page_fault(regs, address);
bad_page_fault(regs, address, SIGBUS);
}
/*
......@@ -196,8 +194,10 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
* in traps.c.
*/
void
bad_page_fault(struct pt_regs *regs, unsigned long address)
bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
{
extern void die(const char *, struct pt_regs *, long);
unsigned long fixup;
/* Are we prepared to handle this fault? */
......@@ -207,13 +207,10 @@ bad_page_fault(struct pt_regs *regs, unsigned long address)
}
/* kernel has accessed a bad area */
show_regs(regs);
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
if (debugger_kernel_faults)
debugger(regs);
#endif
print_backtrace( (unsigned long *)regs->gpr[1] );
panic("kernel access of bad area pc %lx lr %lx address %lX tsk %s/%d",
regs->nip,regs->link,address,current->comm,current->pid);
die("Kernel access of bad area", regs, sig);
}
......@@ -247,6 +247,7 @@ static void map_io_page(unsigned long ea, unsigned long pa, int flags)
void
flush_tlb_mm(struct mm_struct *mm)
{
spin_lock(&mm->page_table_lock);
if (mm->map_count) {
struct vm_area_struct *mp;
for (mp = mm->mmap; mp != NULL; mp = mp->vm_next)
......@@ -261,6 +262,7 @@ flush_tlb_mm(struct mm_struct *mm)
/* XXX are there races with checking cpu_vm_mask? - Anton */
mm->cpu_vm_mask = 0;
spin_unlock(&mm->page_table_lock);
}
/*
......@@ -666,6 +668,8 @@ int __hash_page(unsigned long ea, unsigned long access, unsigned long vsid,
* fault has been handled by updating a PTE in the linux page tables.
* We use it to preload an HPTE into the hash table corresponding to
* the updated linux PTE.
*
* This must always be called with the mm->page_table_lock held
*/
void update_mmu_cache(struct vm_area_struct *vma, unsigned long ea,
pte_t pte)
......
......@@ -26,7 +26,7 @@
#define O_DIRECTORY 040000 /* must be a directory */
#define O_NOFOLLOW 0100000 /* don't follow links */
#define O_LARGEFILE 0200000
#define O_DIRECT 0400000 /* direct disk access hint - currently ignored */
#define O_DIRECT 0400000 /* direct disk access hint */
#define F_DUPFD 0 /* dup */
#define F_GETFD 1 /* get close_on_exec */
......
......@@ -50,7 +50,7 @@ static inline void isync(void)
#define HMT_LOW "\tor 1,1,1 # low priority\n"
#define HMT_MEDIUM "\tor 2,2,2 # medium priority\n"
#define HMT_MEDIUM "\tor 3,3,3 # high priority\n"
#define HMT_HIGH "\tor 3,3,3 # high priority\n"
#else
#define HMT_low() do { } while(0)
#define HMT_medium() do { } while(0)
......
......@@ -211,18 +211,11 @@ static inline void _tlbie(unsigned long va, int large)
asm volatile("eieio; tlbsync; ptesync": : :"memory");
}
static inline void _tlbiel(unsigned long va, int large)
static inline void _tlbiel(unsigned long va)
{
asm volatile("ptesync": : :"memory");
if (large) {
asm volatile("clrldi %0,%0,16\n\
tlbiel %0,1" : : "r"(va) : "memory");
} else {
asm volatile("clrldi %0,%0,16\n\
tlbiel %0,0" : : "r"(va) : "memory");
}
asm volatile("clrldi %0,%0,16\n\
tlbiel %0" : : "r"(va) : "memory");
asm volatile("ptesync": : :"memory");
}
......
......@@ -215,11 +215,14 @@ static inline int get_order(unsigned long size)
#define __a2p(x) ((void *) absolute_to_phys(x))
#define __a2v(x) ((void *) __va(absolute_to_phys(x)))
#define virt_to_page(kaddr) (mem_map+(__pa((unsigned long)kaddr) >> PAGE_SHIFT))
#define pfn_to_page(pfn) (mem_map + (pfn))
#define page_to_pfn(pfn) ((unsigned long)((pfn) - mem_map))
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
#define pfn_valid(pfn) ((pfn) < max_mapnr)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
#define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT)
#define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT)
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
......
......@@ -167,24 +167,16 @@ extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
*
* mk_pte_phys takes a physical address as input
*
* mk_pte takes a (struct page *) as input
*/
#define mk_pte_phys(physpage,pgprot) \
({ \
pte_t pte; \
pte_val(pte) = (((physpage)<<(PTE_SHIFT-PAGE_SHIFT)) | pgprot_val(pgprot)); \
pte; \
})
#define mk_pte(page,pgprot) \
({ \
pte_t pte; \
pte_val(pte) = ((unsigned long)((page) - mem_map) << PTE_SHIFT) | \
pgprot_val(pgprot); \
pte; \
#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
#define pfn_pte(pfn,pgprot) \
({ \
pte_t pte; \
pte_val(pte) = ((unsigned long)(pfn) << PTE_SHIFT) | \
pgprot_val(pgprot); \
pte; \
})
#define pte_modify(_pte, newprot) \
......@@ -195,8 +187,8 @@ extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
/* pte_clear moved to later in this file */
#define pte_pagenr(x) ((unsigned long)((pte_val(x) >> PTE_SHIFT)))
#define pte_page(x) (mem_map+pte_pagenr(x))
#define pte_pfn(x) ((unsigned long)((pte_val(x) >> PTE_SHIFT)))
#define pte_page(x) pfn_to_page(pte_pfn(x))
#define pmd_set(pmdp, ptep) (pmd_val(*(pmdp)) = (__ba_to_bpn(ptep)))
#define pmd_none(pmd) (!pmd_val(pmd))
......
......@@ -65,6 +65,8 @@ static inline struct thread_info *current_thread_info(void)
#endif /* __ASSEMBLY__ */
#define PREEMPT_ACTIVE 0x4000000
/*
* thread information flag bit numbers
*/
......
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