mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 04:33:26 +02:00
Merge tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm
Pull ARM development updates from Russell King: - Rename "mod_init" and "mod_exit" so that initcall debug output is actually useful (Randy Dunlap) - Update maintainers entries for linux-arm-kernel to indicate it is moderated for non-subscribers (Randy Dunlap) - Move install rules to arch/arm/Makefile (Masahiro Yamada) - Drop unnecessary ARCH_NR_GPIOS definition (Linus Walleij) - Don't warn about atags_to_fdt() stack size (David Heidelberg) - Speed up unaligned copy_{from,to}_kernel_nofault (Arnd Bergmann) - Get rid of set_fs() usage (Arnd Bergmann) - Remove checks for GCC prior to v4.6 (Geert Uytterhoeven) * tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm: ARM: 9118/1: div64: Remove always-true __div64_const32_is_OK() duplicate ARM: 9117/1: asm-generic: div64: Remove always-true __div64_const32_is_OK() ARM: 9116/1: unified: Remove check for gcc < 4 ARM: 9110/1: oabi-compat: fix oabi epoll sparse warning ARM: 9113/1: uaccess: remove set_fs() implementation ARM: 9112/1: uaccess: add __{get,put}_kernel_nofault ARM: 9111/1: oabi-compat: rework fcntl64() emulation ARM: 9114/1: oabi-compat: rework sys_semtimedop emulation ARM: 9108/1: oabi-compat: rework epoll_wait/epoll_pwait emulation ARM: 9107/1: syscall: always store thread_info->abi_syscall ARM: 9109/1: oabi-compat: add epoll_pwait handler ARM: 9106/1: traps: use get_kernel_nofault instead of set_fs() ARM: 9115/1: mm/maccess: fix unaligned copy_{from,to}_kernel_nofault ARM: 9105/1: atags_to_fdt: don't warn about stack size ARM: 9103/1: Drop ARCH_NR_GPIOS definition ARM: 9102/1: move theinstall rules to arch/arm/Makefile ARM: 9100/1: MAINTAINERS: mark all linux-arm-kernel@infradead list as moderated ARM: 9099/1: crypto: rename 'mod_init' & 'mod_exit' functions to be module-specific
This commit is contained in:
85
ipc/sem.c
85
ipc/sem.c
@@ -1984,47 +1984,34 @@ out:
|
||||
return un;
|
||||
}
|
||||
|
||||
static long do_semtimedop(int semid, struct sembuf __user *tsops,
|
||||
unsigned nsops, const struct timespec64 *timeout)
|
||||
long __do_semtimedop(int semid, struct sembuf *sops,
|
||||
unsigned nsops, const struct timespec64 *timeout,
|
||||
struct ipc_namespace *ns)
|
||||
{
|
||||
int error = -EINVAL;
|
||||
struct sem_array *sma;
|
||||
struct sembuf fast_sops[SEMOPM_FAST];
|
||||
struct sembuf *sops = fast_sops, *sop;
|
||||
struct sembuf *sop;
|
||||
struct sem_undo *un;
|
||||
int max, locknum;
|
||||
bool undos = false, alter = false, dupsop = false;
|
||||
struct sem_queue queue;
|
||||
unsigned long dup = 0, jiffies_left = 0;
|
||||
struct ipc_namespace *ns;
|
||||
|
||||
ns = current->nsproxy->ipc_ns;
|
||||
|
||||
if (nsops < 1 || semid < 0)
|
||||
return -EINVAL;
|
||||
if (nsops > ns->sc_semopm)
|
||||
return -E2BIG;
|
||||
if (nsops > SEMOPM_FAST) {
|
||||
sops = kvmalloc_array(nsops, sizeof(*sops),
|
||||
GFP_KERNEL_ACCOUNT);
|
||||
if (sops == NULL)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (copy_from_user(sops, tsops, nsops * sizeof(*tsops))) {
|
||||
error = -EFAULT;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (timeout) {
|
||||
if (timeout->tv_sec < 0 || timeout->tv_nsec < 0 ||
|
||||
timeout->tv_nsec >= 1000000000L) {
|
||||
error = -EINVAL;
|
||||
goto out_free;
|
||||
goto out;
|
||||
}
|
||||
jiffies_left = timespec64_to_jiffies(timeout);
|
||||
}
|
||||
|
||||
|
||||
max = 0;
|
||||
for (sop = sops; sop < sops + nsops; sop++) {
|
||||
unsigned long mask = 1ULL << ((sop->sem_num) % BITS_PER_LONG);
|
||||
@@ -2053,7 +2040,7 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops,
|
||||
un = find_alloc_undo(ns, semid);
|
||||
if (IS_ERR(un)) {
|
||||
error = PTR_ERR(un);
|
||||
goto out_free;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
un = NULL;
|
||||
@@ -2064,25 +2051,25 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops,
|
||||
if (IS_ERR(sma)) {
|
||||
rcu_read_unlock();
|
||||
error = PTR_ERR(sma);
|
||||
goto out_free;
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = -EFBIG;
|
||||
if (max >= sma->sem_nsems) {
|
||||
rcu_read_unlock();
|
||||
goto out_free;
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = -EACCES;
|
||||
if (ipcperms(ns, &sma->sem_perm, alter ? S_IWUGO : S_IRUGO)) {
|
||||
rcu_read_unlock();
|
||||
goto out_free;
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = security_sem_semop(&sma->sem_perm, sops, nsops, alter);
|
||||
if (error) {
|
||||
rcu_read_unlock();
|
||||
goto out_free;
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = -EIDRM;
|
||||
@@ -2096,7 +2083,7 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops,
|
||||
* entangled here and why it's RMID race safe on comments at sem_lock()
|
||||
*/
|
||||
if (!ipc_valid_object(&sma->sem_perm))
|
||||
goto out_unlock_free;
|
||||
goto out_unlock;
|
||||
/*
|
||||
* semid identifiers are not unique - find_alloc_undo may have
|
||||
* allocated an undo structure, it was invalidated by an RMID
|
||||
@@ -2105,7 +2092,7 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops,
|
||||
* "un" itself is guaranteed by rcu.
|
||||
*/
|
||||
if (un && un->semid == -1)
|
||||
goto out_unlock_free;
|
||||
goto out_unlock;
|
||||
|
||||
queue.sops = sops;
|
||||
queue.nsops = nsops;
|
||||
@@ -2131,10 +2118,10 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops,
|
||||
rcu_read_unlock();
|
||||
wake_up_q(&wake_q);
|
||||
|
||||
goto out_free;
|
||||
goto out;
|
||||
}
|
||||
if (error < 0) /* non-blocking error path */
|
||||
goto out_unlock_free;
|
||||
goto out_unlock;
|
||||
|
||||
/*
|
||||
* We need to sleep on this operation, so we put the current
|
||||
@@ -2199,14 +2186,14 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops,
|
||||
if (error != -EINTR) {
|
||||
/* see SEM_BARRIER_2 for purpose/pairing */
|
||||
smp_acquire__after_ctrl_dep();
|
||||
goto out_free;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
locknum = sem_lock(sma, sops, nsops);
|
||||
|
||||
if (!ipc_valid_object(&sma->sem_perm))
|
||||
goto out_unlock_free;
|
||||
goto out_unlock;
|
||||
|
||||
/*
|
||||
* No necessity for any barrier: We are protect by sem_lock()
|
||||
@@ -2218,7 +2205,7 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops,
|
||||
* Leave without unlink_queue(), but with sem_unlock().
|
||||
*/
|
||||
if (error != -EINTR)
|
||||
goto out_unlock_free;
|
||||
goto out_unlock;
|
||||
|
||||
/*
|
||||
* If an interrupt occurred we have to clean up the queue.
|
||||
@@ -2229,13 +2216,45 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops,
|
||||
|
||||
unlink_queue(sma, &queue);
|
||||
|
||||
out_unlock_free:
|
||||
out_unlock:
|
||||
sem_unlock(sma, locknum);
|
||||
rcu_read_unlock();
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
static long do_semtimedop(int semid, struct sembuf __user *tsops,
|
||||
unsigned nsops, const struct timespec64 *timeout)
|
||||
{
|
||||
struct sembuf fast_sops[SEMOPM_FAST];
|
||||
struct sembuf *sops = fast_sops;
|
||||
struct ipc_namespace *ns;
|
||||
int ret;
|
||||
|
||||
ns = current->nsproxy->ipc_ns;
|
||||
if (nsops > ns->sc_semopm)
|
||||
return -E2BIG;
|
||||
if (nsops < 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (nsops > SEMOPM_FAST) {
|
||||
sops = kvmalloc_array(nsops, sizeof(*sops), GFP_KERNEL_ACCOUNT);
|
||||
if (sops == NULL)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (copy_from_user(sops, tsops, nsops * sizeof(*tsops))) {
|
||||
ret = -EFAULT;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
ret = __do_semtimedop(semid, sops, nsops, timeout, ns);
|
||||
|
||||
out_free:
|
||||
if (sops != fast_sops)
|
||||
kvfree(sops);
|
||||
return error;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
long ksys_semtimedop(int semid, struct sembuf __user *tsops,
|
||||
|
Reference in New Issue
Block a user