Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git

Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
Steve French 2006-01-23 12:51:00 -08:00
commit 4c8af5254e
45 changed files with 545 additions and 661 deletions

View File

@ -52,9 +52,9 @@
#include <linux/compat.h>
#include <linux/vfs.h>
#include <linux/mman.h>
#include <linux/mutex.h>
#include <asm/intrinsics.h>
#include <asm/semaphore.h>
#include <asm/types.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@ -86,7 +86,7 @@
* while doing so.
*/
/* XXX make per-mm: */
static DECLARE_MUTEX(ia32_mmap_sem);
static DEFINE_MUTEX(ia32_mmap_mutex);
asmlinkage long
sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp,
@ -895,11 +895,11 @@ ia32_do_mmap (struct file *file, unsigned long addr, unsigned long len, int prot
prot = get_prot32(prot);
#if PAGE_SHIFT > IA32_PAGE_SHIFT
down(&ia32_mmap_sem);
mutex_lock(&ia32_mmap_mutex);
{
addr = emulate_mmap(file, addr, len, prot, flags, offset);
}
up(&ia32_mmap_sem);
mutex_unlock(&ia32_mmap_mutex);
#else
down_write(&current->mm->mmap_sem);
{
@ -1000,11 +1000,9 @@ sys32_munmap (unsigned int start, unsigned int len)
if (start >= end)
return 0;
down(&ia32_mmap_sem);
{
ret = sys_munmap(start, end - start);
}
up(&ia32_mmap_sem);
mutex_lock(&ia32_mmap_mutex);
ret = sys_munmap(start, end - start);
mutex_unlock(&ia32_mmap_mutex);
#endif
return ret;
}
@ -1056,7 +1054,7 @@ sys32_mprotect (unsigned int start, unsigned int len, int prot)
if (retval < 0)
return retval;
down(&ia32_mmap_sem);
mutex_lock(&ia32_mmap_mutex);
{
if (offset_in_page(start)) {
/* start address is 4KB aligned but not page aligned. */
@ -1080,7 +1078,7 @@ sys32_mprotect (unsigned int start, unsigned int len, int prot)
retval = sys_mprotect(start, end - start, prot);
}
out:
up(&ia32_mmap_sem);
mutex_unlock(&ia32_mmap_mutex);
return retval;
#endif
}
@ -1124,11 +1122,9 @@ sys32_mremap (unsigned int addr, unsigned int old_len, unsigned int new_len,
old_len = PAGE_ALIGN(old_end) - addr;
new_len = PAGE_ALIGN(new_end) - addr;
down(&ia32_mmap_sem);
{
ret = sys_mremap(addr, old_len, new_len, flags, new_addr);
}
up(&ia32_mmap_sem);
mutex_lock(&ia32_mmap_mutex);
ret = sys_mremap(addr, old_len, new_len, flags, new_addr);
mutex_unlock(&ia32_mmap_mutex);
if ((ret >= 0) && (old_len < new_len)) {
/* mremap expanded successfully */

View File

@ -40,6 +40,7 @@
#include <linux/bitops.h>
#include <linux/capability.h>
#include <linux/rcupdate.h>
#include <linux/completion.h>
#include <asm/errno.h>
#include <asm/intrinsics.h>
@ -286,7 +287,7 @@ typedef struct pfm_context {
unsigned long ctx_ovfl_regs[4]; /* which registers overflowed (notification) */
struct semaphore ctx_restart_sem; /* use for blocking notification mode */
struct completion ctx_restart_done; /* use for blocking notification mode */
unsigned long ctx_used_pmds[4]; /* bitmask of PMD used */
unsigned long ctx_all_pmds[4]; /* bitmask of all accessible PMDs */
@ -1991,7 +1992,7 @@ pfm_close(struct inode *inode, struct file *filp)
/*
* force task to wake up from MASKED state
*/
up(&ctx->ctx_restart_sem);
complete(&ctx->ctx_restart_done);
DPRINT(("waking up ctx_state=%d\n", state));
@ -2706,7 +2707,7 @@ pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg
/*
* init restart semaphore to locked
*/
sema_init(&ctx->ctx_restart_sem, 0);
init_completion(&ctx->ctx_restart_done);
/*
* activation is used in SMP only
@ -3687,7 +3688,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
*/
if (CTX_OVFL_NOBLOCK(ctx) == 0 && state == PFM_CTX_MASKED) {
DPRINT(("unblocking [%d] \n", task->pid));
up(&ctx->ctx_restart_sem);
complete(&ctx->ctx_restart_done);
} else {
DPRINT(("[%d] armed exit trap\n", task->pid));
@ -5089,7 +5090,7 @@ pfm_handle_work(void)
* may go through without blocking on SMP systems
* if restart has been received already by the time we call down()
*/
ret = down_interruptible(&ctx->ctx_restart_sem);
ret = wait_for_completion_interruptible(&ctx->ctx_restart_done);
DPRINT(("after block sleeping ret=%d\n", ret));

View File

@ -210,6 +210,7 @@ uncached_build_memmap(unsigned long start, unsigned long end, void *arg)
dprintk(KERN_ERR "uncached_build_memmap(%lx %lx)\n", start, end);
touch_softlockup_watchdog();
memset((char *)start, 0, length);
node = paddr_to_nid(start - __IA64_UNCACHED_OFFSET);

View File

@ -51,6 +51,15 @@ struct sn_flush_device_kernel {
struct sn_flush_device_common *common;
};
/* 01/16/06 This struct is the old PROM/kernel struct and needs to be included
* for older official PROMs to function on the new kernel base. This struct
* will be removed when the next official PROM release occurs. */
struct sn_flush_device_war {
struct sn_flush_device_common common;
u32 filler; /* older PROMs expect the default size of a spinlock_t */
};
/*
* **widget_p - Used as an array[wid_num][device] of sn_flush_device_kernel.
*/

View File

@ -165,8 +165,45 @@ sn_pcidev_info_get(struct pci_dev *dev)
return NULL;
}
/* Older PROM flush WAR
*
* 01/16/06 -- This war will be in place until a new official PROM is released.
* Additionally note that the struct sn_flush_device_war also has to be
* removed from arch/ia64/sn/include/xtalk/hubdev.h
*/
static u8 war_implemented = 0;
static void sn_device_fixup_war(u64 nasid, u64 widget, int device,
struct sn_flush_device_common *common)
{
struct sn_flush_device_war *war_list;
struct sn_flush_device_war *dev_entry;
struct ia64_sal_retval isrv = {0,0,0,0};
if (!war_implemented) {
printk(KERN_WARNING "PROM version < 4.50 -- implementing old "
"PROM flush WAR\n");
war_implemented = 1;
}
war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL);
if (!war_list)
BUG();
SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST,
nasid, widget, __pa(war_list), 0, 0, 0 ,0);
if (isrv.status)
panic("sn_device_fixup_war failed: %s\n",
ia64_sal_strerror(isrv.status));
dev_entry = war_list + device;
memcpy(common,dev_entry, sizeof(*common));
kfree(war_list);
}
/*
* sn_fixup_ionodes() - This routine initializes the HUB data strcuture for
* sn_fixup_ionodes() - This routine initializes the HUB data strcuture for
* each node in the system.
*/
static void sn_fixup_ionodes(void)
@ -246,8 +283,19 @@ static void sn_fixup_ionodes(void)
widget,
device,
(u64)(dev_entry->common));
if (status)
BUG();
if (status) {
if (sn_sal_rev() < 0x0450) {
/* shortlived WAR for older
* PROM images
*/
sn_device_fixup_war(nasid,
widget,
device,
dev_entry->common);
}
else
BUG();
}
spin_lock_init(&dev_entry->sfdl_flush_lock);
}

View File

@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/vmalloc.h>
#include <linux/mutex.h>
#include <asm/mca.h>
#include <asm/sal.h>
#include <asm/sn/sn_sal.h>
@ -27,7 +28,7 @@ void sn_init_cpei_timer(void);
/* Printing oemdata from mca uses data that is not passed through SAL, it is
* global. Only one user at a time.
*/
static DECLARE_MUTEX(sn_oemdata_mutex);
static DEFINE_MUTEX(sn_oemdata_mutex);
static u8 **sn_oemdata;
static u64 *sn_oemdata_size, sn_oemdata_bufsize;
@ -89,7 +90,7 @@ static int
sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata,
u64 * oemdata_size)
{
down(&sn_oemdata_mutex);
mutex_lock(&sn_oemdata_mutex);
sn_oemdata = oemdata;
sn_oemdata_size = oemdata_size;
sn_oemdata_bufsize = 0;
@ -107,7 +108,7 @@ sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata,
*sn_oemdata_size = 0;
ia64_sn_plat_specific_err_print(print_hook, (char *)sect_header);
}
up(&sn_oemdata_mutex);
mutex_unlock(&sn_oemdata_mutex);
return 0;
}

View File

@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <asm/sn/intr.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/xp.h>
@ -136,13 +137,13 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
registration = &xpc_registrations[ch_number];
if (down_interruptible(&registration->sema) != 0) {
if (mutex_lock_interruptible(&registration->mutex) != 0) {
return xpcInterrupted;
}
/* if XPC_CHANNEL_REGISTERED(ch_number) */
if (registration->func != NULL) {
up(&registration->sema);
mutex_unlock(&registration->mutex);
return xpcAlreadyRegistered;
}
@ -154,7 +155,7 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
registration->key = key;
registration->func = func;
up(&registration->sema);
mutex_unlock(&registration->mutex);
xpc_interface.connect(ch_number);
@ -190,11 +191,11 @@ xpc_disconnect(int ch_number)
* figured XPC's users will just turn around and call xpc_disconnect()
* again anyways, so we might as well wait, if need be.
*/
down(&registration->sema);
mutex_lock(&registration->mutex);
/* if !XPC_CHANNEL_REGISTERED(ch_number) */
if (registration->func == NULL) {
up(&registration->sema);
mutex_unlock(&registration->mutex);
return;
}
@ -208,7 +209,7 @@ xpc_disconnect(int ch_number)
xpc_interface.disconnect(ch_number);
up(&registration->sema);
mutex_unlock(&registration->mutex);
return;
}
@ -250,9 +251,9 @@ xp_init(void)
xp_nofault_PIOR_target = SH1_IPI_ACCESS;
}
/* initialize the connection registration semaphores */
/* initialize the connection registration mutex */
for (ch_number = 0; ch_number < XPC_NCHANNELS; ch_number++) {
sema_init(&xpc_registrations[ch_number].sema, 1); /* mutex */
mutex_init(&xpc_registrations[ch_number].mutex);
}
return 0;

View File

@ -22,6 +22,8 @@
#include <linux/cache.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/completion.h>
#include <asm/sn/bte.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/xpc.h>
@ -56,8 +58,8 @@ xpc_initialize_channels(struct xpc_partition *part, partid_t partid)
atomic_set(&ch->n_to_notify, 0);
spin_lock_init(&ch->lock);
sema_init(&ch->msg_to_pull_sema, 1); /* mutex */
sema_init(&ch->wdisconnect_sema, 0); /* event wait */
mutex_init(&ch->msg_to_pull_mutex);
init_completion(&ch->wdisconnect_wait);
atomic_set(&ch->n_on_msg_allocate_wq, 0);
init_waitqueue_head(&ch->msg_allocate_wq);
@ -534,7 +536,6 @@ static enum xpc_retval
xpc_allocate_msgqueues(struct xpc_channel *ch)
{
unsigned long irq_flags;
int i;
enum xpc_retval ret;
@ -552,11 +553,6 @@ xpc_allocate_msgqueues(struct xpc_channel *ch)
return ret;
}
for (i = 0; i < ch->local_nentries; i++) {
/* use a semaphore as an event wait queue */
sema_init(&ch->notify_queue[i].sema, 0);
}
spin_lock_irqsave(&ch->lock, irq_flags);
ch->flags |= XPC_C_SETUP;
spin_unlock_irqrestore(&ch->lock, irq_flags);
@ -799,10 +795,8 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
}
if (ch->flags & XPC_C_WDISCONNECT) {
spin_unlock_irqrestore(&ch->lock, *irq_flags);
up(&ch->wdisconnect_sema);
spin_lock_irqsave(&ch->lock, *irq_flags);
/* we won't lose the CPU since we're holding ch->lock */
complete(&ch->wdisconnect_wait);
} else if (ch->delayed_IPI_flags) {
if (part->act_state != XPC_P_DEACTIVATING) {
/* time to take action on any delayed IPI flags */
@ -1092,12 +1086,12 @@ xpc_connect_channel(struct xpc_channel *ch)
struct xpc_registration *registration = &xpc_registrations[ch->number];
if (down_trylock(&registration->sema) != 0) {
if (mutex_trylock(&registration->mutex) == 0) {
return xpcRetry;
}
if (!XPC_CHANNEL_REGISTERED(ch->number)) {
up(&registration->sema);
mutex_unlock(&registration->mutex);
return xpcUnregistered;
}
@ -1108,7 +1102,7 @@ xpc_connect_channel(struct xpc_channel *ch)
if (ch->flags & XPC_C_DISCONNECTING) {
spin_unlock_irqrestore(&ch->lock, irq_flags);
up(&registration->sema);
mutex_unlock(&registration->mutex);
return ch->reason;
}
@ -1140,7 +1134,7 @@ xpc_connect_channel(struct xpc_channel *ch)
* channel lock be locked and will unlock and relock
* the channel lock as needed.
*/
up(&registration->sema);
mutex_unlock(&registration->mutex);
XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes,
&irq_flags);
spin_unlock_irqrestore(&ch->lock, irq_flags);
@ -1155,7 +1149,7 @@ xpc_connect_channel(struct xpc_channel *ch)
atomic_inc(&xpc_partitions[ch->partid].nchannels_active);
}
up(&registration->sema);
mutex_unlock(&registration->mutex);
/* initiate the connection */
@ -2089,7 +2083,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
enum xpc_retval ret;
if (down_interruptible(&ch->msg_to_pull_sema) != 0) {
if (mutex_lock_interruptible(&ch->msg_to_pull_mutex) != 0) {
/* we were interrupted by a signal */
return NULL;
}
@ -2125,7 +2119,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
XPC_DEACTIVATE_PARTITION(part, ret);
up(&ch->msg_to_pull_sema);
mutex_unlock(&ch->msg_to_pull_mutex);
return NULL;
}
@ -2134,7 +2128,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
ch->next_msg_to_pull += nmsgs;
}
up(&ch->msg_to_pull_sema);
mutex_unlock(&ch->msg_to_pull_mutex);
/* return the message we were looking for */
msg_offset = (get % ch->remote_nentries) * ch->msg_size;

View File

@ -55,6 +55,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/completion.h>
#include <asm/sn/intr.h>
#include <asm/sn/sn_sal.h>
#include <asm/kdebug.h>
@ -177,10 +178,10 @@ static DECLARE_WAIT_QUEUE_HEAD(xpc_act_IRQ_wq);
static unsigned long xpc_hb_check_timeout;
/* notification that the xpc_hb_checker thread has exited */
static DECLARE_MUTEX_LOCKED(xpc_hb_checker_exited);
static DECLARE_COMPLETION(xpc_hb_checker_exited);
/* notification that the xpc_discovery thread has exited */
static DECLARE_MUTEX_LOCKED(xpc_discovery_exited);
static DECLARE_COMPLETION(xpc_discovery_exited);
static struct timer_list xpc_hb_timer;
@ -321,7 +322,7 @@ xpc_hb_checker(void *ignore)
/* mark this thread as having exited */
up(&xpc_hb_checker_exited);
complete(&xpc_hb_checker_exited);
return 0;
}
@ -341,7 +342,7 @@ xpc_initiate_discovery(void *ignore)
dev_dbg(xpc_part, "discovery thread is exiting\n");
/* mark this thread as having exited */
up(&xpc_discovery_exited);
complete(&xpc_discovery_exited);
return 0;
}
@ -893,7 +894,7 @@ xpc_disconnect_wait(int ch_number)
continue;
}
(void) down(&ch->wdisconnect_sema);
wait_for_completion(&ch->wdisconnect_wait);
spin_lock_irqsave(&ch->lock, irq_flags);
DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED));
@ -946,10 +947,10 @@ xpc_do_exit(enum xpc_retval reason)
free_irq(SGI_XPC_ACTIVATE, NULL);
/* wait for the discovery thread to exit */
down(&xpc_discovery_exited);
wait_for_completion(&xpc_discovery_exited);
/* wait for the heartbeat checker thread to exit */
down(&xpc_hb_checker_exited);
wait_for_completion(&xpc_hb_checker_exited);
/* sleep for a 1/3 of a second or so */
@ -1367,7 +1368,7 @@ xpc_init(void)
dev_err(xpc_part, "failed while forking discovery thread\n");
/* mark this new thread as a non-starter */
up(&xpc_discovery_exited);
complete(&xpc_discovery_exited);
xpc_do_exit(xpcUnloading);
return -EBUSY;

View File

@ -24,13 +24,15 @@ sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp)
{
struct ia64_sal_retval ret_stuff;
u64 busnum;
u64 segment;
ret_stuff.status = 0;
ret_stuff.v0 = 0;
segment = soft->pbi_buscommon.bs_persist_segment;
busnum = soft->pbi_buscommon.bs_persist_busnum;
SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, (u64) busnum,
(u64) device, (u64) resp, 0, 0, 0, 0);
SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, segment,
busnum, (u64) device, (u64) resp, 0, 0, 0);
return (int)ret_stuff.v0;
}
@ -41,14 +43,16 @@ sal_pcibr_slot_disable(struct pcibus_info *soft, int device, int action,
{
struct ia64_sal_retval ret_stuff;
u64 busnum;
u64 segment;
ret_stuff.status = 0;
ret_stuff.v0 = 0;
segment = soft->pbi_buscommon.bs_persist_segment;
busnum = soft->pbi_buscommon.bs_persist_busnum;
SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_DISABLE,
(u64) busnum, (u64) device, (u64) action,
(u64) resp, 0, 0, 0);
segment, busnum, (u64) device, (u64) action,
(u64) resp, 0, 0);
return (int)ret_stuff.v0;
}

View File

@ -1276,62 +1276,6 @@ sys_sigstack:
call do_sys_sigstack
mov %l5, %o7
.align 4
.globl sys_sigpause
sys_sigpause:
/* Note: %o0 already has correct value... */
call do_sigpause
add %sp, STACKFRAME_SZ, %o1
ld [%curptr + TI_FLAGS], %l5
andcc %l5, _TIF_SYSCALL_TRACE, %g0
be 1f
nop
call syscall_trace
nop
1:
/* We are returning to a signal handler. */
RESTORE_ALL
.align 4
.globl sys_sigsuspend
sys_sigsuspend:
call do_sigsuspend
add %sp, STACKFRAME_SZ, %o0
ld [%curptr + TI_FLAGS], %l5
andcc %l5, _TIF_SYSCALL_TRACE, %g0
be 1f
nop
call syscall_trace
nop
1:
/* We are returning to a signal handler. */
RESTORE_ALL
.align 4
.globl sys_rt_sigsuspend
sys_rt_sigsuspend:
/* Note: %o0, %o1 already have correct value... */
call do_rt_sigsuspend
add %sp, STACKFRAME_SZ, %o2
ld [%curptr + TI_FLAGS], %l5
andcc %l5, _TIF_SYSCALL_TRACE, %g0
be 1f
nop
call syscall_trace
nop
1:
/* We are returning to a signal handler. */
RESTORE_ALL
.align 4
.globl sys_sigreturn
sys_sigreturn:

View File

@ -68,15 +68,14 @@ ret_trap_lockless_ipi:
ld [%curptr + TI_FLAGS], %g2
signal_p:
andcc %g2, (_TIF_NOTIFY_RESUME|_TIF_SIGPENDING), %g0
andcc %g2, (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %g0
bz,a ret_trap_continue
ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr
clr %o0
mov %l5, %o2
mov %l6, %o3
mov %l5, %o1
mov %l6, %o2
call do_signal
add %sp, STACKFRAME_SZ, %o1 ! pt_regs ptr
add %sp, STACKFRAME_SZ, %o0 ! pt_regs ptr
/* Fall through. */
ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr

View File

@ -35,9 +35,6 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
void *fpqueue, unsigned long *fpqdepth);
extern void fpload(unsigned long *fpregs, unsigned long *fsr);
asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_o0, int restart_syscall);
/* Signal frames: the original one (compatible with SunOS):
*
* Set up a signal frame... Make the stack look the way SunOS
@ -95,98 +92,30 @@ struct rt_signal_frame {
#define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame) + 7) & (~7)))
#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7)))
/*
* atomically swap in the new signal mask, and wait for a signal.
* This is really tricky on the Sparc, watch out...
*/
asmlinkage void _sigpause_common(old_sigset_t set, struct pt_regs *regs)
static int _sigpause_common(old_sigset_t set)
{
sigset_t saveset;
set &= _BLOCKABLE;
spin_lock_irq(&current->sighand->siglock);
saveset = current->blocked;
current->saved_sigmask = current->blocked;
siginitset(&current->blocked, set);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
regs->pc = regs->npc;
regs->npc += 4;
current->state = TASK_INTERRUPTIBLE;
schedule();
set_thread_flag(TIF_RESTORE_SIGMASK);
/* Condition codes and return value where set here for sigpause,
* and so got used by setup_frame, which again causes sigreturn()
* to return -EINTR.
*/
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
/*
* Return -EINTR and set condition code here,
* so the interrupted system call actually returns
* these.
*/
regs->psr |= PSR_C;
regs->u_regs[UREG_I0] = EINTR;
if (do_signal(&saveset, regs, 0, 0))
return;
}
return -ERESTARTNOHAND;
}
asmlinkage void do_sigpause(unsigned int set, struct pt_regs *regs)
asmlinkage int sys_sigpause(unsigned int set)
{
_sigpause_common(set, regs);
return _sigpause_common(set);
}
asmlinkage void do_sigsuspend (struct pt_regs *regs)
asmlinkage int sys_sigsuspend(old_sigset_t set)
{
_sigpause_common(regs->u_regs[UREG_I0], regs);
}
asmlinkage void do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize,
struct pt_regs *regs)
{
sigset_t oldset, set;
/* XXX: Don't preclude handling different sized sigset_t's. */
if (sigsetsize != sizeof(sigset_t)) {
regs->psr |= PSR_C;
regs->u_regs[UREG_I0] = EINVAL;
return;
}
if (copy_from_user(&set, uset, sizeof(set))) {
regs->psr |= PSR_C;
regs->u_regs[UREG_I0] = EFAULT;
return;
}
sigdelsetmask(&set, ~_BLOCKABLE);
spin_lock_irq(&current->sighand->siglock);
oldset = current->blocked;
current->blocked = set;
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
regs->pc = regs->npc;
regs->npc += 4;
/* Condition codes and return value where set here for sigpause,
* and so got used by setup_frame, which again causes sigreturn()
* to return -EINTR.
*/
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
/*
* Return -EINTR and set condition code here,
* so the interrupted system call actually returns
* these.
*/
regs->psr |= PSR_C;
regs->u_regs[UREG_I0] = EINTR;
if (do_signal(&oldset, regs, 0, 0))
return;
}
return _sigpause_common(set);
}
static inline int
@ -1067,13 +996,13 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
* want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake.
*/
asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_i0, int restart_syscall)
asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int restart_syscall)
{
siginfo_t info;
struct sparc_deliver_cookie cookie;
struct k_sigaction ka;
int signr;
sigset_t *oldset;
/*
* XXX Disable svr4 signal handling until solaris emulation works.
@ -1089,7 +1018,9 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
cookie.restart_syscall = restart_syscall;
cookie.orig_i0 = orig_i0;
if (!oldset)
if (test_thread_flag(TIF_RESTORE_SIGMASK))
oldset = &current->saved_sigmask;
else
oldset = &current->blocked;
signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
@ -1098,7 +1029,14 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
syscall_restart(cookie.orig_i0, regs, &ka.sa);
handle_signal(signr, &ka, &info, oldset,
regs, svr4_signal);
return 1;
/* a signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag.
*/
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
return;
}
if (cookie.restart_syscall &&
(regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
@ -1115,7 +1053,14 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
regs->pc -= 4;
regs->npc -= 4;
}
return 0;
/* if there's no signal to deliver, we just put the saved sigmask
* back
*/
if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
clear_thread_flag(TIF_RESTORE_SIGMASK);
sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
}
}
asmlinkage int

View File

@ -66,7 +66,6 @@ struct poll {
extern int svr4_getcontext (svr4_ucontext_t *, struct pt_regs *);
extern int svr4_setcontext (svr4_ucontext_t *, struct pt_regs *);
void _sigpause_common (unsigned int set, struct pt_regs *);
extern void (*__copy_1page)(void *, const void *);
extern void __memmove(void *, const void *, __kernel_size_t);
extern void (*bzero_1page)(void *);
@ -227,7 +226,6 @@ EXPORT_SYMBOL(kunmap_atomic);
/* Solaris/SunOS binary compatibility */
EXPORT_SYMBOL(svr4_setcontext);
EXPORT_SYMBOL(svr4_getcontext);
EXPORT_SYMBOL(_sigpause_common);
EXPORT_SYMBOL(dump_thread);

View File

@ -75,7 +75,10 @@ sys_call_table:
/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
/*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
/*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
/*280*/ .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl
/*280*/ .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat
/*285*/ .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_newfstatat
/*290*/ .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
/*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll
#ifdef CONFIG_SUNOS_EMUL
/* Now the SunOS syscall table. */
@ -181,6 +184,11 @@ sunos_sys_table:
.long sunos_nosys, sunos_nosys, sunos_nosys
.long sunos_nosys
/*280*/ .long sunos_nosys, sunos_nosys, sunos_nosys
.long sunos_nosys, sunos_nosys, sunos_nosys
.long sunos_nosys, sunos_nosys, sunos_nosys
.long sunos_nosys
/*290*/ .long sunos_nosys, sunos_nosys, sunos_nosys
.long sunos_nosys, sunos_nosys, sunos_nosys
.long sunos_nosys, sunos_nosys, sunos_nosys
#endif

View File

@ -1416,7 +1416,6 @@ execve_merge:
add %sp, PTREGS_OFF, %o0
.globl sys_pipe, sys_sigpause, sys_nis_syscall
.globl sys_sigsuspend, sys_rt_sigsuspend
.globl sys_rt_sigreturn
.globl sys_ptrace
.globl sys_sigaltstack
@ -1440,28 +1439,6 @@ sys32_sigaltstack:
mov %i6, %o2
#endif
.align 32
sys_sigsuspend: add %sp, PTREGS_OFF, %o0
call do_sigsuspend
add %o7, 1f-.-4, %o7
nop
sys_rt_sigsuspend: /* NOTE: %o0,%o1 have a correct value already */
add %sp, PTREGS_OFF, %o2
call do_rt_sigsuspend
add %o7, 1f-.-4, %o7
nop
#ifdef CONFIG_COMPAT
.globl sys32_rt_sigsuspend
sys32_rt_sigsuspend: /* NOTE: %o0,%o1 have a correct value already */
srl %o0, 0, %o0
add %sp, PTREGS_OFF, %o2
call do_rt_sigsuspend32
add %o7, 1f-.-4, %o7
#endif
/* NOTE: %o0 has a correct value already */
sys_sigpause: add %sp, PTREGS_OFF, %o1
call do_sigpause
add %o7, 1f-.-4, %o7
nop
#ifdef CONFIG_COMPAT
.globl sys32_sigreturn
sys32_sigreturn:

View File

@ -53,14 +53,13 @@ __handle_user_windows:
wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
ldx [%g6 + TI_FLAGS], %l0
1: andcc %l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0
1: andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0
be,pt %xcc, __handle_user_windows_continue
nop
clr %o0
mov %l5, %o2
mov %l6, %o3
add %sp, PTREGS_OFF, %o1
mov %l0, %o4
mov %l5, %o1
mov %l6, %o2
add %sp, PTREGS_OFF, %o0
mov %l0, %o3
call do_notify_resume
wrpr %g0, RTRAP_PSTATE, %pstate
@ -96,15 +95,14 @@ __handle_perfctrs:
wrpr %g0, RTRAP_PSTATE, %pstate
wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
ldx [%g6 + TI_FLAGS], %l0
1: andcc %l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0
1: andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0
be,pt %xcc, __handle_perfctrs_continue
sethi %hi(TSTATE_PEF), %o0
clr %o0
mov %l5, %o2
mov %l6, %o3
add %sp, PTREGS_OFF, %o1
mov %l0, %o4
mov %l5, %o1
mov %l6, %o2
add %sp, PTREGS_OFF, %o0
mov %l0, %o3
call do_notify_resume
wrpr %g0, RTRAP_PSTATE, %pstate
@ -129,11 +127,10 @@ __handle_userfpu:
ba,a,pt %xcc, __handle_userfpu_continue
__handle_signal:
clr %o0
mov %l5, %o2
mov %l6, %o3
add %sp, PTREGS_OFF, %o1
mov %l0, %o4
mov %l5, %o1
mov %l6, %o2
add %sp, PTREGS_OFF, %o0
mov %l0, %o3
call do_notify_resume
wrpr %g0, RTRAP_PSTATE, %pstate
wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
@ -200,7 +197,7 @@ __handle_preemption_continue:
andcc %l1, %o0, %g0
andcc %l0, _TIF_NEED_RESCHED, %g0
bne,pn %xcc, __handle_preemption
andcc %l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0
andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0
bne,pn %xcc, __handle_signal
__handle_signal_continue:
ldub [%g6 + TI_WSAVED], %o2

View File

@ -36,9 +36,6 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
static int do_signal(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_o0, int ret_from_syscall);
/* {set, get}context() needed for 64-bit SparcLinux userland. */
asmlinkage void sparc64_set_context(struct pt_regs *regs)
{
@ -242,114 +239,29 @@ struct rt_signal_frame {
/* Align macros */
#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7)))
/*
* atomically swap in the new signal mask, and wait for a signal.
* This is really tricky on the Sparc, watch out...
*/
asmlinkage void _sigpause_common(old_sigset_t set, struct pt_regs *regs)
static long _sigpause_common(old_sigset_t set)
{
sigset_t saveset;
#ifdef CONFIG_SPARC32_COMPAT
if (test_thread_flag(TIF_32BIT)) {
extern asmlinkage void _sigpause32_common(compat_old_sigset_t,
struct pt_regs *);
_sigpause32_common(set, regs);
return;
}
#endif
set &= _BLOCKABLE;
spin_lock_irq(&current->sighand->siglock);
saveset = current->blocked;
current->saved_sigmask = current->blocked;
siginitset(&current->blocked, set);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
if (test_thread_flag(TIF_32BIT)) {
regs->tpc = (regs->tnpc & 0xffffffff);
regs->tnpc = (regs->tnpc + 4) & 0xffffffff;
} else {
regs->tpc = regs->tnpc;
regs->tnpc += 4;
}
/* Condition codes and return value where set here for sigpause,
* and so got used by setup_frame, which again causes sigreturn()
* to return -EINTR.
*/
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
/*
* Return -EINTR and set condition code here,
* so the interrupted system call actually returns
* these.
*/
regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
regs->u_regs[UREG_I0] = EINTR;
if (do_signal(&saveset, regs, 0, 0))
return;
}
current->state = TASK_INTERRUPTIBLE;
schedule();
set_thread_flag(TIF_RESTORE_SIGMASK);
return -ERESTARTNOHAND;
}
asmlinkage void do_sigpause(unsigned int set, struct pt_regs *regs)
asmlinkage long sys_sigpause(unsigned int set)
{
_sigpause_common(set, regs);
return _sigpause_common(set);
}
asmlinkage void do_sigsuspend(struct pt_regs *regs)
asmlinkage long sys_sigsuspend(old_sigset_t set)
{
_sigpause_common(regs->u_regs[UREG_I0], regs);
}
asmlinkage void do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, struct pt_regs *regs)
{
sigset_t oldset, set;
/* XXX: Don't preclude handling different sized sigset_t's. */
if (sigsetsize != sizeof(sigset_t)) {
regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
regs->u_regs[UREG_I0] = EINVAL;
return;
}
if (copy_from_user(&set, uset, sizeof(set))) {
regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
regs->u_regs[UREG_I0] = EFAULT;
return;
}
sigdelsetmask(&set, ~_BLOCKABLE);
spin_lock_irq(&current->sighand->siglock);
oldset = current->blocked;
current->blocked = set;
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
if (test_thread_flag(TIF_32BIT)) {
regs->tpc = (regs->tnpc & 0xffffffff);
regs->tnpc = (regs->tnpc + 4) & 0xffffffff;
} else {
regs->tpc = regs->tnpc;
regs->tnpc += 4;
}
/* Condition codes and return value where set here for sigpause,
* and so got used by setup_frame, which again causes sigreturn()
* to return -EINTR.
*/
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
/*
* Return -EINTR and set condition code here,
* so the interrupted system call actually returns
* these.
*/
regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
regs->u_regs[UREG_I0] = EINTR;
if (do_signal(&oldset, regs, 0, 0))
return;
}
return _sigpause_common(set);
}
static inline int
@ -607,26 +519,29 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
* want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake.
*/
static int do_signal(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_i0, int restart_syscall)
static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall)
{
siginfo_t info;
struct signal_deliver_cookie cookie;
struct k_sigaction ka;
int signr;
sigset_t *oldset;
cookie.restart_syscall = restart_syscall;
cookie.orig_i0 = orig_i0;
if (!oldset)
if (test_thread_flag(TIF_RESTORE_SIGMASK))
oldset = &current->saved_sigmask;
else
oldset = &current->blocked;
#ifdef CONFIG_SPARC32_COMPAT
if (test_thread_flag(TIF_32BIT)) {
extern int do_signal32(sigset_t *, struct pt_regs *,
unsigned long, int);
return do_signal32(oldset, regs, orig_i0,
cookie.restart_syscall);
extern void do_signal32(sigset_t *, struct pt_regs *,
unsigned long, int);
do_signal32(oldset, regs, orig_i0,
cookie.restart_syscall);
return;
}
#endif
@ -635,7 +550,15 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
if (cookie.restart_syscall)
syscall_restart(orig_i0, regs, &ka.sa);
handle_signal(signr, &ka, &info, oldset, regs);
return 1;
/* a signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag.
*/
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
return;
}
if (cookie.restart_syscall &&
(regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
@ -652,15 +575,21 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
regs->tpc -= 4;
regs->tnpc -= 4;
}
return 0;
/* if there's no signal to deliver, we just put the saved sigmask
* back
*/
if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
clear_thread_flag(TIF_RESTORE_SIGMASK);
sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
}
}
void do_notify_resume(sigset_t *oldset, struct pt_regs *regs,
unsigned long orig_i0, int restart_syscall,
void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall,
unsigned long thread_info_flags)
{
if (thread_info_flags & _TIF_SIGPENDING)
do_signal(oldset, regs, orig_i0, restart_syscall);
if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
do_signal(regs, orig_i0, restart_syscall);
}
void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)

View File

@ -32,9 +32,6 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
int do_signal32(sigset_t *oldset, struct pt_regs *regs,
unsigned long orig_o0, int ret_from_syscall);
/* Signal frames: the original one (compatible with SunOS):
*
* Set up a signal frame... Make the stack look the way SunOS
@ -226,102 +223,6 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
return 0;
}
/*
* atomically swap in the new signal mask, and wait for a signal.
* This is really tricky on the Sparc, watch out...
*/
asmlinkage void _sigpause32_common(compat_old_sigset_t set, struct pt_regs *regs)
{
sigset_t saveset;
set &= _BLOCKABLE;
spin_lock_irq(&current->sighand->siglock);
saveset = current->blocked;
siginitset(&current->blocked, set);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
regs->tpc = regs->tnpc;
regs->tnpc += 4;
if (test_thread_flag(TIF_32BIT)) {
regs->tpc &= 0xffffffff;
regs->tnpc &= 0xffffffff;
}
/* Condition codes and return value where set here for sigpause,
* and so got used by setup_frame, which again causes sigreturn()
* to return -EINTR.
*/
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
/*
* Return -EINTR and set condition code here,
* so the interrupted system call actually returns
* these.
*/
regs->tstate |= TSTATE_ICARRY;
regs->u_regs[UREG_I0] = EINTR;
if (do_signal32(&saveset, regs, 0, 0))
return;
}
}
asmlinkage void do_rt_sigsuspend32(u32 uset, size_t sigsetsize, struct pt_regs *regs)
{
sigset_t oldset, set;
compat_sigset_t set32;
/* XXX: Don't preclude handling different sized sigset_t's. */
if (((compat_size_t)sigsetsize) != sizeof(sigset_t)) {
regs->tstate |= TSTATE_ICARRY;
regs->u_regs[UREG_I0] = EINVAL;
return;
}
if (copy_from_user(&set32, compat_ptr(uset), sizeof(set32))) {
regs->tstate |= TSTATE_ICARRY;
regs->u_regs[UREG_I0] = EFAULT;
return;
}
switch (_NSIG_WORDS) {
case 4: set.sig[3] = set32.sig[6] + (((long)set32.sig[7]) << 32);
case 3: set.sig[2] = set32.sig[4] + (((long)set32.sig[5]) << 32);
case 2: set.sig[1] = set32.sig[2] + (((long)set32.sig[3]) << 32);
case 1: set.sig[0] = set32.sig[0] + (((long)set32.sig[1]) << 32);
}
sigdelsetmask(&set, ~_BLOCKABLE);
spin_lock_irq(&current->sighand->siglock);
oldset = current->blocked;
current->blocked = set;
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
regs->tpc = regs->tnpc;
regs->tnpc += 4;
if (test_thread_flag(TIF_32BIT)) {
regs->tpc &= 0xffffffff;
regs->tnpc &= 0xffffffff;
}
/* Condition codes and return value where set here for sigpause,
* and so got used by setup_frame, which again causes sigreturn()
* to return -EINTR.
*/
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
/*
* Return -EINTR and set condition code here,
* so the interrupted system call actually returns
* these.
*/
regs->tstate |= TSTATE_ICARRY;
regs->u_regs[UREG_I0] = EINTR;
if (do_signal32(&oldset, regs, 0, 0))
return;
}
}
static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
{
unsigned long *fpregs = current_thread_info()->fpregs;
@ -1362,8 +1263,8 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs
* want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake.
*/
int do_signal32(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_i0, int restart_syscall)
void do_signal32(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_i0, int restart_syscall)
{
siginfo_t info;
struct signal_deliver_cookie cookie;
@ -1380,7 +1281,15 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
syscall_restart32(orig_i0, regs, &ka.sa);
handle_signal32(signr, &ka, &info, oldset,
regs, svr4_signal);
return 1;
/* a signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag.
*/
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
return;
}
if (cookie.restart_syscall &&
(regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
@ -1397,7 +1306,14 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
regs->tpc -= 4;
regs->tnpc -= 4;
}
return 0;
/* if there's no signal to deliver, we just put the saved sigmask
* back
*/
if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
clear_thread_flag(TIF_RESTORE_SIGMASK);
sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
}
}
struct sigstack32 {

View File

@ -69,7 +69,6 @@ struct poll {
extern void die_if_kernel(char *str, struct pt_regs *regs);
extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
void _sigpause_common (unsigned int set, struct pt_regs *);
extern void *__bzero(void *, size_t);
extern void *__memscan_zero(void *, size_t);
extern void *__memscan_generic(void *, int, size_t);
@ -236,9 +235,10 @@ EXPORT_SYMBOL(pci_dma_supported);
/* I/O device mmaping on Sparc64. */
EXPORT_SYMBOL(io_remap_pfn_range);
#ifdef CONFIG_COMPAT
/* Solaris/SunOS binary compatibility */
EXPORT_SYMBOL(_sigpause_common);
EXPORT_SYMBOL(verify_compat_iovec);
#endif
EXPORT_SYMBOL(dump_fpu);
EXPORT_SYMBOL(pte_alloc_one_kernel);

View File

@ -41,7 +41,7 @@ sys_call_table32:
/*90*/ .word sys_dup2, sys_setfsuid, compat_sys_fcntl, sys32_select, sys_setfsgid
.word sys_fsync, sys32_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
/*100*/ .word sys32_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending
.word compat_sys_rt_sigtimedwait, sys32_rt_sigqueueinfo, sys32_rt_sigsuspend, sys_setresuid, sys_getresuid
.word compat_sys_rt_sigtimedwait, sys32_rt_sigqueueinfo, compat_sys_rt_sigsuspend, sys_setresuid, sys_getresuid
/*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall
.word sys32_getgroups, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
/*120*/ .word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod
@ -76,7 +76,10 @@ sys_call_table32:
.word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
/*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink
.word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
/*280*/ .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl
/*280*/ .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat
.word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_newfstatat
/*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
.word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll
#endif /* CONFIG_COMPAT */
@ -142,7 +145,10 @@ sys_call_table:
.word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy
/*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
.word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
/*280*/ .word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl
/*280*/ .word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat
.word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, compat_sys_newfstatat
/*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
.word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll
#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
defined(CONFIG_SOLARIS_EMUL_MODULE)
@ -239,13 +245,20 @@ sunos_sys_table:
/*250*/ .word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys
/*260*/ .word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys
/*270*/ .word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys
/*280*/ .word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys
/*290*/ .word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
#endif

View File

@ -180,6 +180,8 @@ solaris_sigsuspend:
nop
call sys_sigsuspend
stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
b,pt %xcc, ret_from_solaris
nop
.globl solaris_getpid
solaris_getpid:

View File

@ -6,7 +6,7 @@
* driver for that.
*
*
* Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved.
* Copyright (c) 2004-2006 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License
@ -829,8 +829,8 @@ static int __init sn_sal_module_init(void)
misc.name = DEVICE_NAME_DYNAMIC;
retval = misc_register(&misc);
if (retval != 0) {
printk
("Failed to register console device using misc_register.\n");
printk(KERN_WARNING "Failed to register console "
"device using misc_register.\n");
return -ENODEV;
}
sal_console_uart.major = MISC_MAJOR;
@ -942,88 +942,75 @@ sn_sal_console_write(struct console *co, const char *s, unsigned count)
{
unsigned long flags = 0;
struct sn_cons_port *port = &sal_console_port;
#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
static int stole_lock = 0;
#endif
BUG_ON(!port->sc_is_asynch);
/* We can't look at the xmit buffer if we're not registered with serial core
* yet. So only do the fancy recovery after registering
*/
if (port->sc_port.info) {
if (!port->sc_port.info) {
/* Not yet registered with serial core - simple case */
puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count);
return;
}
/* somebody really wants this output, might be an
* oops, kdb, panic, etc. make sure they get it. */
#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
if (spin_is_locked(&port->sc_port.lock)) {
int lhead = port->sc_port.info->xmit.head;
int ltail = port->sc_port.info->xmit.tail;
int counter, got_lock = 0;
/* somebody really wants this output, might be an
* oops, kdb, panic, etc. make sure they get it. */
if (spin_is_locked(&port->sc_port.lock)) {
int lhead = port->sc_port.info->xmit.head;
int ltail = port->sc_port.info->xmit.tail;
int counter, got_lock = 0;
/*
* We attempt to determine if someone has died with the
* lock. We wait ~20 secs after the head and tail ptrs
* stop moving and assume the lock holder is not functional
* and plow ahead. If the lock is freed within the time out
* period we re-get the lock and go ahead normally. We also
* remember if we have plowed ahead so that we don't have
* to wait out the time out period again - the asumption
* is that we will time out again.
*/
/*
* We attempt to determine if someone has died with the
* lock. We wait ~20 secs after the head and tail ptrs
* stop moving and assume the lock holder is not functional
* and plow ahead. If the lock is freed within the time out
* period we re-get the lock and go ahead normally. We also
* remember if we have plowed ahead so that we don't have
* to wait out the time out period again - the asumption
* is that we will time out again.
*/
for (counter = 0; counter < 150; mdelay(125), counter++) {
if (!spin_is_locked(&port->sc_port.lock)
|| stole_lock) {
if (!stole_lock) {
spin_lock_irqsave(&port->
sc_port.lock,
flags);
got_lock = 1;
}
break;
} else {
/* still locked */
if ((lhead !=
port->sc_port.info->xmit.head)
|| (ltail !=
port->sc_port.info->xmit.
tail)) {
lhead =
port->sc_port.info->xmit.
head;
ltail =
port->sc_port.info->xmit.
tail;
counter = 0;
}
for (counter = 0; counter < 150; mdelay(125), counter++) {
if (!spin_is_locked(&port->sc_port.lock)
|| stole_lock) {
if (!stole_lock) {
spin_lock_irqsave(&port->sc_port.lock,
flags);
got_lock = 1;
}
break;
} else {
/* still locked */
if ((lhead != port->sc_port.info->xmit.head)
|| (ltail !=
port->sc_port.info->xmit.tail)) {
lhead =
port->sc_port.info->xmit.head;
ltail =
port->sc_port.info->xmit.tail;
counter = 0;
}
}
/* flush anything in the serial core xmit buffer, raw */
sn_transmit_chars(port, 1);
if (got_lock) {
spin_unlock_irqrestore(&port->sc_port.lock,
flags);
stole_lock = 0;
} else {
/* fell thru */
stole_lock = 1;
}
puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count);
} else {
stole_lock = 0;
#endif
spin_lock_irqsave(&port->sc_port.lock, flags);
sn_transmit_chars(port, 1);
spin_unlock_irqrestore(&port->sc_port.lock, flags);
puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count);
#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
}
#endif
}
else {
/* Not yet registered with serial core - simple case */
/* flush anything in the serial core xmit buffer, raw */
sn_transmit_chars(port, 1);
if (got_lock) {
spin_unlock_irqrestore(&port->sc_port.lock, flags);
stole_lock = 0;
} else {
/* fell thru */
stole_lock = 1;
}
puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count);
} else {
stole_lock = 0;
spin_lock_irqsave(&port->sc_port.lock, flags);
sn_transmit_chars(port, 1);
spin_unlock_irqrestore(&port->sc_port.lock, flags);
puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count);
}
}

View File

@ -1743,7 +1743,7 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS)
timeout = -1; /* infinite */
else {
timeout = ROUND_UP(tv.tv_sec, 1000000/HZ);
timeout = ROUND_UP(tv.tv_usec, 1000000/HZ);
timeout += tv.tv_sec * HZ;
}
}
@ -1884,7 +1884,7 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
/* We assume that ts.tv_sec is always lower than
the number of seconds that can be expressed in
an s64. Otherwise the compiler bitches at us */
timeout = ROUND_UP(ts.tv_sec, 1000000000/HZ);
timeout = ROUND_UP(ts.tv_nsec, 1000000000/HZ);
timeout += ts.tv_sec * HZ;
}

View File

@ -61,7 +61,7 @@ static inline void
down (struct semaphore *sem)
{
might_sleep();
if (atomic_dec_return(&sem->count) < 0)
if (ia64_fetchadd(-1, &sem->count.counter, acq) < 1)
__down(sem);
}
@ -75,7 +75,7 @@ down_interruptible (struct semaphore * sem)
int ret = 0;
might_sleep();
if (atomic_dec_return(&sem->count) < 0)
if (ia64_fetchadd(-1, &sem->count.counter, acq) < 1)
ret = __down_interruptible(sem);
return ret;
}
@ -85,7 +85,7 @@ down_trylock (struct semaphore *sem)
{
int ret = 0;
if (atomic_dec_return(&sem->count) < 0)
if (ia64_fetchadd(-1, &sem->count.counter, acq) < 1)
ret = __down_trylock(sem);
return ret;
}
@ -93,7 +93,7 @@ down_trylock (struct semaphore *sem)
static inline void
up (struct semaphore * sem)
{
if (atomic_inc_return(&sem->count) <= 0)
if (ia64_fetchadd(1, &sem->count.counter, rel) <= -1)
__up(sem);
}

View File

@ -18,6 +18,7 @@
#include <linux/cache.h>
#include <linux/hardirq.h>
#include <linux/mutex.h>
#include <asm/sn/types.h>
#include <asm/sn/bte.h>
@ -359,7 +360,7 @@ typedef void (*xpc_notify_func)(enum xpc_retval reason, partid_t partid,
* the channel.
*/
struct xpc_registration {
struct semaphore sema;
struct mutex mutex;
xpc_channel_func func; /* function to call */
void *key; /* pointer to user's key */
u16 nentries; /* #of msg entries in local msg queue */

View File

@ -19,6 +19,8 @@
#include <linux/interrupt.h>
#include <linux/sysctl.h>
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/completion.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/sn/bte.h>
@ -335,8 +337,7 @@ struct xpc_openclose_args {
* and consumed by the intended recipient.
*/
struct xpc_notify {
struct semaphore sema; /* notify semaphore */
volatile u8 type; /* type of notification */
volatile u8 type; /* type of notification */
/* the following two fields are only used if type == XPC_N_CALL */
xpc_notify_func func; /* user's notify function */
@ -465,8 +466,8 @@ struct xpc_channel {
xpc_channel_func func; /* user's channel function */
void *key; /* pointer to user's key */
struct semaphore msg_to_pull_sema; /* next msg to pull serialization */
struct semaphore wdisconnect_sema; /* wait for channel disconnect */
struct mutex msg_to_pull_mutex; /* next msg to pull serialization */
struct completion wdisconnect_wait; /* wait for channel disconnect */
struct xpc_openclose_args *local_openclose_args; /* args passed on */
/* opening or closing of channel */

View File

@ -18,6 +18,10 @@
#include <asm/smp.h>
#ifdef CONFIG_NUMA
/* Nodes w/o CPUs are preferred for memory allocations, see build_zonelists */
#define PENALTY_FOR_NODE_WITH_CPUS 255
/*
* Returns the number of the node containing CPU 'cpu'
*/

View File

@ -164,6 +164,7 @@ enum prom_input_device {
PROMDEV_IKBD, /* input from keyboard */
PROMDEV_ITTYA, /* input from ttya */
PROMDEV_ITTYB, /* input from ttyb */
PROMDEV_IRSC, /* input from rsc */
PROMDEV_I_UNK,
};
@ -175,6 +176,7 @@ enum prom_output_device {
PROMDEV_OSCREEN, /* to screen */
PROMDEV_OTTYA, /* to ttya */
PROMDEV_OTTYB, /* to ttyb */
PROMDEV_ORSC, /* to rsc */
PROMDEV_O_UNK,
};

View File

@ -128,9 +128,10 @@ BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)
* thread information flag bit numbers
*/
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */
/* flag bit 1 is available */
#define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_RESTORE_SIGMASK 4 /* restore signal mask in do_signal() */
#define TIF_USEDFPU 8 /* FPU was used by this task
* this quantum (SMP) */
#define TIF_POLLING_NRFLAG 9 /* true if poll_idle() is polling
@ -139,9 +140,9 @@ BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)
/* as above, but as bit values */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)

View File

@ -300,11 +300,26 @@
#define __NR_add_key 281
#define __NR_request_key 282
#define __NR_keyctl 283
#define __NR_openat 284
#define __NR_mkdirat 285
#define __NR_mknodat 286
#define __NR_fchownat 287
#define __NR_futimesat 288
#define __NR_newfstatat 289
#define __NR_unlinkat 290
#define __NR_renameat 291
#define __NR_linkat 292
#define __NR_symlinkat 293
#define __NR_readlinkat 294
#define __NR_fchmodat 295
#define __NR_faccessat 296
#define __NR_pselect6 297
#define __NR_ppoll 298
/* WARNING: You MAY NOT add syscall numbers larger than 283, since
/* WARNING: You MAY NOT add syscall numbers larger than 298, since
* all of the syscall tables in the Sparc kernel are
* sized to have 283 entries (starting at zero). Therefore
* find a free slot in the 0-282 range.
* sized to have 298 entries (starting at zero). Therefore
* find a free slot in the 0-298 range.
*/
#define _syscall0(type,name) \
@ -458,6 +473,7 @@ return -1; \
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
#endif
#ifdef __KERNEL_SYSCALLS__

View File

@ -221,7 +221,7 @@ register struct thread_info *current_thread_info_reg asm("g6");
* nop
*/
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */
#define TIF_RESTORE_SIGMASK 1 /* restore signal mask in do_signal() */
#define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_PERFCTR 4 /* performance counters active */
@ -241,7 +241,6 @@ register struct thread_info *current_thread_info_reg asm("g6");
#define TIF_POLLING_NRFLAG 14
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_PERFCTR (1<<TIF_PERFCTR)
@ -250,11 +249,12 @@ register struct thread_info *current_thread_info_reg asm("g6");
#define _TIF_32BIT (1<<TIF_32BIT)
#define _TIF_SECCOMP (1<<TIF_SECCOMP)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_USER_WORK_MASK ((0xff << TI_FLAG_WSAVED_SHIFT) | \
(_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | \
_TIF_NEED_RESCHED | _TIF_PERFCTR))
#endif /* __KERNEL__ */

View File

@ -302,11 +302,26 @@
#define __NR_add_key 281
#define __NR_request_key 282
#define __NR_keyctl 283
#define __NR_openat 284
#define __NR_mkdirat 285
#define __NR_mknodat 286
#define __NR_fchownat 287
#define __NR_futimesat 288
#define __NR_newfstatat 289
#define __NR_unlinkat 290
#define __NR_renameat 291
#define __NR_linkat 292
#define __NR_symlinkat 293
#define __NR_readlinkat 294
#define __NR_fchmodat 295
#define __NR_faccessat 296
#define __NR_pselect6 297
#define __NR_ppoll 298
/* WARNING: You MAY NOT add syscall numbers larger than 283, since
/* WARNING: You MAY NOT add syscall numbers larger than 298, since
* all of the syscall tables in the Sparc kernel are
* sized to have 283 entries (starting at zero). Therefore
* find a free slot in the 0-282 range.
* sized to have 298 entries (starting at zero). Therefore
* find a free slot in the 0-298 range.
*/
#define _syscall0(type,name) \
@ -501,6 +516,8 @@ asmlinkage long sys_rt_sigaction(int sig,
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
#endif
/*

View File

@ -19,7 +19,7 @@ struct xt_get_revision
/* For standard target */
#define XT_RETURN (-NF_REPEAT - 1)
#define XT_ALIGN(s) (((s) + (__alignof__(void *)-1)) & ~(__alignof__(void *)-1))
#define XT_ALIGN(s) (((s) + (__alignof__(u_int64_t)-1)) & ~(__alignof__(u_int64_t)-1))
/* Standard return verdict, or do jump. */
#define XT_STANDARD_TARGET ""

View File

@ -175,6 +175,8 @@ void sctp_icmp_frag_needed(struct sock *, struct sctp_association *,
void sctp_icmp_proto_unreachable(struct sock *sk,
struct sctp_association *asoc,
struct sctp_transport *t);
void sctp_backlog_migrate(struct sctp_association *assoc,
struct sock *oldsk, struct sock *newsk);
/*
* Section: Macros, externs, and inlines

View File

@ -127,9 +127,9 @@ extern struct sctp_globals {
* RTO.Alpha - 1/8 (3 when converted to right shifts.)
* RTO.Beta - 1/4 (2 when converted to right shifts.)
*/
__u32 rto_initial;
__u32 rto_min;
__u32 rto_max;
unsigned long rto_initial;
unsigned long rto_min;
unsigned long rto_max;
/* Note: rto_alpha and rto_beta are really defined as inverse
* powers of two to facilitate integer operations.
@ -140,12 +140,18 @@ extern struct sctp_globals {
/* Max.Burst - 4 */
int max_burst;
/* Valid.Cookie.Life - 60 seconds */
int valid_cookie_life;
/* Whether Cookie Preservative is enabled(1) or not(0) */
int cookie_preserve_enable;
/* Valid.Cookie.Life - 60 seconds */
unsigned long valid_cookie_life;
/* Delayed SACK timeout 200ms default*/
unsigned long sack_timeout;
/* HB.interval - 30 seconds */
unsigned long hb_interval;
/* Association.Max.Retrans - 10 attempts
* Path.Max.Retrans - 5 attempts (per destination address)
* Max.Init.Retransmits - 8 attempts
@ -168,12 +174,6 @@ extern struct sctp_globals {
*/
int rcvbuf_policy;
/* Delayed SACK timeout 200ms default*/
int sack_timeout;
/* HB.interval - 30 seconds */
int hb_interval;
/* The following variables are implementation specific. */
/* Default initialization values to be applied to new associations. */
@ -405,8 +405,9 @@ struct sctp_cookie {
/* The format of our cookie that we send to our peer. */
struct sctp_signed_cookie {
__u8 signature[SCTP_SECRET_SIZE];
__u32 __pad; /* force sctp_cookie alignment to 64 bits */
struct sctp_cookie c;
};
} __attribute__((packed));
/* This is another convenience type to allocate memory for address
* params for the maximum size and pass such structures around
@ -827,7 +828,7 @@ struct sctp_transport {
__u32 rtt; /* This is the most recent RTT. */
/* RTO : The current retransmission timeout value. */
__u32 rto;
unsigned long rto;
/* RTTVAR : The current RTT variation. */
__u32 rttvar;
@ -877,22 +878,10 @@ struct sctp_transport {
/* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
* the destination address every heartbeat interval.
*/
__u32 hbinterval;
/* This is the max_retrans value for the transport and will
* be initialized from the assocs value. This can be changed
* using SCTP_SET_PEER_ADDR_PARAMS socket option.
*/
__u16 pathmaxrxt;
/* PMTU : The current known path MTU. */
__u32 pathmtu;
unsigned long hbinterval;
/* SACK delay timeout */
__u32 sackdelay;
/* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
__u32 param_flags;
unsigned long sackdelay;
/* When was the last time (in jiffies) that we heard from this
* transport? We use this to pick new active and retran paths.
@ -904,6 +893,18 @@ struct sctp_transport {
*/
unsigned long last_time_ecne_reduced;
/* This is the max_retrans value for the transport and will
* be initialized from the assocs value. This can be changed
* using SCTP_SET_PEER_ADDR_PARAMS socket option.
*/
__u16 pathmaxrxt;
/* PMTU : The current known path MTU. */
__u32 pathmtu;
/* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
__u32 param_flags;
/* The number of times INIT has been sent on this transport. */
int init_sent_count;
@ -1249,6 +1250,14 @@ struct sctp_endpoint {
int last_key;
int key_changed_at;
/* digest: This is a digest of the sctp cookie. This field is
* only used on the receive path when we try to validate
* that the cookie has not been tampered with. We put
* this here so we pre-allocate this once and can re-use
* on every receive.
*/
__u8 digest[SCTP_SIGNATURE_SIZE];
/* sendbuf acct. policy. */
__u32 sndbuf_policy;
@ -1499,9 +1508,9 @@ struct sctp_association {
* These values will be initialized by system defaults, but can
* be modified via the SCTP_RTOINFO socket option.
*/
__u32 rto_initial;
__u32 rto_max;
__u32 rto_min;
unsigned long rto_initial;
unsigned long rto_max;
unsigned long rto_min;
/* Maximum number of new data packets that can be sent in a burst. */
int max_burst;
@ -1519,13 +1528,13 @@ struct sctp_association {
__u16 init_retries;
/* The largest timeout or RTO value to use in attempting an INIT */
__u16 max_init_timeo;
unsigned long max_init_timeo;
/* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
* the destination address every heartbeat interval. This value
* will be inherited by all new transports.
*/
__u32 hbinterval;
unsigned long hbinterval;
/* This is the max_retrans value for new transports in the
* association.
@ -1537,13 +1546,14 @@ struct sctp_association {
*/
__u32 pathmtu;
/* SACK delay timeout */
__u32 sackdelay;
/* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
__u32 param_flags;
int timeouts[SCTP_NUM_TIMEOUT_TYPES];
/* SACK delay timeout */
unsigned long sackdelay;
unsigned long timeouts[SCTP_NUM_TIMEOUT_TYPES];
struct timer_list timers[SCTP_NUM_TIMEOUT_TYPES];
/* Transport to which SHUTDOWN chunk was last sent. */
@ -1648,7 +1658,10 @@ struct sctp_association {
/* How many duplicated TSNs have we seen? */
int numduptsns;
/* Number of seconds of idle time before an association is closed. */
/* Number of seconds of idle time before an association is closed.
* In the association context, this is really used as a boolean
* since the real timeout is stored in the timeouts array
*/
__u32 autoclose;
/* These are to support

View File

@ -257,20 +257,26 @@ int sctp_rcv(struct sk_buff *skb)
*/
sctp_bh_lock_sock(sk);
/* It is possible that the association could have moved to a different
* socket if it is peeled off. If so, update the sk.
*/
if (sk != rcvr->sk) {
sctp_bh_lock_sock(rcvr->sk);
sctp_bh_unlock_sock(sk);
sk = rcvr->sk;
}
if (sock_owned_by_user(sk))
sk_add_backlog(sk, skb);
else
sctp_backlog_rcv(sk, skb);
/* Release the sock and any reference counts we took in the
* lookup calls.
/* Release the sock and the sock ref we took in the lookup calls.
* The asoc/ep ref will be released in sctp_backlog_rcv.
*/
sctp_bh_unlock_sock(sk);
if (asoc)
sctp_association_put(asoc);
else
sctp_endpoint_put(ep);
sock_put(sk);
return ret;
discard_it:
@ -296,12 +302,50 @@ discard_release:
int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb)
{
struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk;
struct sctp_inq *inqueue = &chunk->rcvr->inqueue;
struct sctp_inq *inqueue = NULL;
struct sctp_ep_common *rcvr = NULL;
sctp_inq_push(inqueue, chunk);
rcvr = chunk->rcvr;
BUG_TRAP(rcvr->sk == sk);
if (rcvr->dead) {
sctp_chunk_free(chunk);
} else {
inqueue = &chunk->rcvr->inqueue;
sctp_inq_push(inqueue, chunk);
}
/* Release the asoc/ep ref we took in the lookup calls in sctp_rcv. */
if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type)
sctp_association_put(sctp_assoc(rcvr));
else
sctp_endpoint_put(sctp_ep(rcvr));
return 0;
}
void sctp_backlog_migrate(struct sctp_association *assoc,
struct sock *oldsk, struct sock *newsk)
{
struct sk_buff *skb;
struct sctp_chunk *chunk;
skb = oldsk->sk_backlog.head;
oldsk->sk_backlog.head = oldsk->sk_backlog.tail = NULL;
while (skb != NULL) {
struct sk_buff *next = skb->next;
chunk = SCTP_INPUT_CB(skb)->chunk;
skb->next = NULL;
if (&assoc->base == chunk->rcvr)
sk_add_backlog(newsk, skb);
else
sk_add_backlog(oldsk, skb);
skb = next;
}
}
/* Handle icmp frag needed error. */
void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
struct sctp_transport *t, __u32 pmtu)
@ -544,10 +588,16 @@ int sctp_rcv_ootb(struct sk_buff *skb)
sctp_errhdr_t *err;
ch = (sctp_chunkhdr_t *) skb->data;
ch_end = ((__u8 *) ch) + WORD_ROUND(ntohs(ch->length));
/* Scan through all the chunks in the packet. */
while (ch_end > (__u8 *)ch && ch_end < skb->tail) {
do {
/* Break out if chunk length is less then minimal. */
if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t))
break;
ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
if (ch_end > skb->tail)
break;
/* RFC 8.4, 2) If the OOTB packet contains an ABORT chunk, the
* receiver MUST silently discard the OOTB packet and take no
@ -578,8 +628,7 @@ int sctp_rcv_ootb(struct sk_buff *skb)
}
ch = (sctp_chunkhdr_t *) ch_end;
ch_end = ((__u8 *) ch) + WORD_ROUND(ntohs(ch->length));
}
} while (ch_end < skb->tail);
return 0;

View File

@ -73,8 +73,10 @@ void sctp_inq_free(struct sctp_inq *queue)
/* If there is a packet which is currently being worked on,
* free it as well.
*/
if (queue->in_progress)
if (queue->in_progress) {
sctp_chunk_free(queue->in_progress);
queue->in_progress = NULL;
}
if (queue->malloced) {
/* Dump the master memory segment. */

View File

@ -176,7 +176,7 @@ static void sctp_seq_dump_remote_addrs(struct seq_file *seq, struct sctp_associa
static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos)
{
if (*pos > sctp_ep_hashsize)
if (*pos >= sctp_ep_hashsize)
return NULL;
if (*pos < 0)
@ -185,8 +185,6 @@ static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos)
if (*pos == 0)
seq_printf(seq, " ENDPT SOCK STY SST HBKT LPORT UID INODE LADDRS\n");
++*pos;
return (void *)pos;
}
@ -198,11 +196,9 @@ static void sctp_eps_seq_stop(struct seq_file *seq, void *v)
static void * sctp_eps_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
if (*pos > sctp_ep_hashsize)
if (++*pos >= sctp_ep_hashsize)
return NULL;
++*pos;
return pos;
}
@ -214,19 +210,19 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)
struct sctp_ep_common *epb;
struct sctp_endpoint *ep;
struct sock *sk;
int hash = *(int *)v;
int hash = *(loff_t *)v;
if (hash > sctp_ep_hashsize)
if (hash >= sctp_ep_hashsize)
return -ENOMEM;
head = &sctp_ep_hashtable[hash-1];
head = &sctp_ep_hashtable[hash];
sctp_local_bh_disable();
read_lock(&head->lock);
for (epb = head->chain; epb; epb = epb->next) {
ep = sctp_ep(epb);
sk = epb->sk;
seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk,
sctp_sk(sk)->type, sk->sk_state, hash-1,
sctp_sk(sk)->type, sk->sk_state, hash,
epb->bind_addr.port,
sock_i_uid(sk), sock_i_ino(sk));
@ -283,7 +279,7 @@ void sctp_eps_proc_exit(void)
static void * sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos)
{
if (*pos > sctp_assoc_hashsize)
if (*pos >= sctp_assoc_hashsize)
return NULL;
if (*pos < 0)
@ -293,8 +289,6 @@ static void * sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos)
seq_printf(seq, " ASSOC SOCK STY SST ST HBKT ASSOC-ID TX_QUEUE RX_QUEUE UID INODE LPORT "
"RPORT LADDRS <-> RADDRS\n");
++*pos;
return (void *)pos;
}
@ -306,11 +300,9 @@ static void sctp_assocs_seq_stop(struct seq_file *seq, void *v)
static void * sctp_assocs_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
if (*pos > sctp_assoc_hashsize)
if (++*pos >= sctp_assoc_hashsize)
return NULL;
++*pos;
return pos;
}
@ -321,12 +313,12 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
struct sctp_ep_common *epb;
struct sctp_association *assoc;
struct sock *sk;
int hash = *(int *)v;
int hash = *(loff_t *)v;
if (hash > sctp_assoc_hashsize)
if (hash >= sctp_assoc_hashsize)
return -ENOMEM;
head = &sctp_assoc_hashtable[hash-1];
head = &sctp_assoc_hashtable[hash];
sctp_local_bh_disable();
read_lock(&head->lock);
for (epb = head->chain; epb; epb = epb->next) {
@ -335,7 +327,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
seq_printf(seq,
"%8p %8p %-3d %-3d %-2d %-4d %4d %8d %8d %7d %5lu %-5d %5d ",
assoc, sk, sctp_sk(sk)->type, sk->sk_state,
assoc->state, hash-1, assoc->assoc_id,
assoc->state, hash, assoc->assoc_id,
(sk->sk_rcvbuf - assoc->rwnd),
assoc->sndbuf_used,
sock_i_uid(sk), sock_i_ino(sk),

View File

@ -1275,7 +1275,12 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
unsigned int keylen;
char *key;
headersize = sizeof(sctp_paramhdr_t) + SCTP_SECRET_SIZE;
/* Header size is static data prior to the actual cookie, including
* any padding.
*/
headersize = sizeof(sctp_paramhdr_t) +
(sizeof(struct sctp_signed_cookie) -
sizeof(struct sctp_cookie));
bodysize = sizeof(struct sctp_cookie)
+ ntohs(init_chunk->chunk_hdr->length) + addrs_len;
@ -1354,7 +1359,7 @@ struct sctp_association *sctp_unpack_cookie(
struct sctp_signed_cookie *cookie;
struct sctp_cookie *bear_cookie;
int headersize, bodysize, fixed_size;
__u8 digest[SCTP_SIGNATURE_SIZE];
__u8 *digest = ep->digest;
struct scatterlist sg;
unsigned int keylen, len;
char *key;
@ -1362,7 +1367,12 @@ struct sctp_association *sctp_unpack_cookie(
struct sk_buff *skb = chunk->skb;
struct timeval tv;
headersize = sizeof(sctp_chunkhdr_t) + SCTP_SECRET_SIZE;
/* Header size is static data prior to the actual cookie, including
* any padding.
*/
headersize = sizeof(sctp_chunkhdr_t) +
(sizeof(struct sctp_signed_cookie) -
sizeof(struct sctp_cookie));
bodysize = ntohs(chunk->chunk_hdr->length) - headersize;
fixed_size = headersize + sizeof(struct sctp_cookie);

View File

@ -1300,7 +1300,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
"T1 INIT Timeout adjustment"
" init_err_counter: %d"
" cycle: %d"
" timeout: %d\n",
" timeout: %ld\n",
asoc->init_err_counter,
asoc->init_cycle,
asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT]);
@ -1328,7 +1328,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
SCTP_DEBUG_PRINTK(
"T1 COOKIE Timeout adjustment"
" init_err_counter: %d"
" timeout: %d\n",
" timeout: %ld\n",
asoc->init_err_counter,
asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE]);

View File

@ -3090,6 +3090,8 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
break;
ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
if (ch_end > skb->tail)
break;
if (SCTP_CID_SHUTDOWN_ACK == ch->type)
ootb_shut_ack = 1;

View File

@ -2995,7 +2995,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
sp->hbinterval = jiffies_to_msecs(sctp_hb_interval);
sp->pathmaxrxt = sctp_max_retrans_path;
sp->pathmtu = 0; // allow default discovery
sp->sackdelay = sctp_sack_timeout;
sp->sackdelay = jiffies_to_msecs(sctp_sack_timeout);
sp->param_flags = SPP_HB_ENABLE |
SPP_PMTUD_ENABLE |
SPP_SACKDELAY_ENABLE;
@ -5602,8 +5602,12 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
*/
newsp->type = type;
spin_lock_bh(&oldsk->sk_lock.slock);
/* Migrate the backlog from oldsk to newsk. */
sctp_backlog_migrate(assoc, oldsk, newsk);
/* Migrate the association to the new socket. */
sctp_assoc_migrate(assoc, newsk);
spin_unlock_bh(&oldsk->sk_lock.slock);
/* If the association on the newsk is already closed before accept()
* is called, set RCV_SHUTDOWN flag.

View File

@ -159,12 +159,9 @@ static ctl_table sctp_table[] = {
.ctl_name = NET_SCTP_PRESERVE_ENABLE,
.procname = "cookie_preserve_enable",
.data = &sctp_cookie_preserve_enable,
.maxlen = sizeof(long),
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_doulongvec_ms_jiffies_minmax,
.strategy = &sctp_sysctl_jiffies_ms,
.extra1 = &rto_timer_min,
.extra2 = &rto_timer_max
.proc_handler = &proc_dointvec
},
{
.ctl_name = NET_SCTP_RTO_ALPHA,

View File

@ -350,7 +350,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
tp->rto_pending = 0;
SCTP_DEBUG_PRINTK("%s: transport: %p, rtt: %d, srtt: %d "
"rttvar: %d, rto: %d\n", __FUNCTION__,
"rttvar: %d, rto: %ld\n", __FUNCTION__,
tp, rtt, tp->srtt, tp->rttvar, tp->rto);
}