aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/sem.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/sem.c')
-rw-r--r--ipc/sem.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/ipc/sem.c b/ipc/sem.c
index 06be75d9217a..cfd94d48a9aa 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -70,6 +70,7 @@
70 * The worst-case behavior is nevertheless O(N^2) for N wakeups. 70 * The worst-case behavior is nevertheless O(N^2) for N wakeups.
71 */ 71 */
72 72
73#include <linux/compat.h>
73#include <linux/slab.h> 74#include <linux/slab.h>
74#include <linux/spinlock.h> 75#include <linux/spinlock.h>
75#include <linux/init.h> 76#include <linux/init.h>
@@ -104,7 +105,7 @@ struct sem {
104 /* that alter the semaphore */ 105 /* that alter the semaphore */
105 struct list_head pending_const; /* pending single-sop operations */ 106 struct list_head pending_const; /* pending single-sop operations */
106 /* that do not alter the semaphore*/ 107 /* that do not alter the semaphore*/
107 time_t sem_otime; /* candidate for sem_otime */ 108 time64_t sem_otime; /* candidate for sem_otime */
108} ____cacheline_aligned_in_smp; 109} ____cacheline_aligned_in_smp;
109 110
110/* One sem_array data structure for each set of semaphores in the system. */ 111/* One sem_array data structure for each set of semaphores in the system. */
@@ -984,10 +985,10 @@ again:
984static void set_semotime(struct sem_array *sma, struct sembuf *sops) 985static void set_semotime(struct sem_array *sma, struct sembuf *sops)
985{ 986{
986 if (sops == NULL) { 987 if (sops == NULL) {
987 sma->sems[0].sem_otime = get_seconds(); 988 sma->sems[0].sem_otime = ktime_get_real_seconds();
988 } else { 989 } else {
989 sma->sems[sops[0].sem_num].sem_otime = 990 sma->sems[sops[0].sem_num].sem_otime =
990 get_seconds(); 991 ktime_get_real_seconds();
991 } 992 }
992} 993}
993 994
@@ -1214,6 +1215,7 @@ static int semctl_stat(struct ipc_namespace *ns, int semid,
1214 int cmd, struct semid64_ds *semid64) 1215 int cmd, struct semid64_ds *semid64)
1215{ 1216{
1216 struct sem_array *sma; 1217 struct sem_array *sma;
1218 time64_t semotime;
1217 int id = 0; 1219 int id = 0;
1218 int err; 1220 int err;
1219 1221
@@ -1257,8 +1259,13 @@ static int semctl_stat(struct ipc_namespace *ns, int semid,
1257 } 1259 }
1258 1260
1259 kernel_to_ipc64_perm(&sma->sem_perm, &semid64->sem_perm); 1261 kernel_to_ipc64_perm(&sma->sem_perm, &semid64->sem_perm);
1260 semid64->sem_otime = get_semotime(sma); 1262 semotime = get_semotime(sma);
1263 semid64->sem_otime = semotime;
1261 semid64->sem_ctime = sma->sem_ctime; 1264 semid64->sem_ctime = sma->sem_ctime;
1265#ifndef CONFIG_64BIT
1266 semid64->sem_otime_high = semotime >> 32;
1267 semid64->sem_ctime_high = sma->sem_ctime >> 32;
1268#endif
1262 semid64->sem_nsems = sma->sem_nsems; 1269 semid64->sem_nsems = sma->sem_nsems;
1263 1270
1264 ipc_unlock_object(&sma->sem_perm); 1271 ipc_unlock_object(&sma->sem_perm);
@@ -1704,8 +1711,10 @@ static int copy_compat_semid_to_user(void __user *buf, struct semid64_ds *in,
1704 struct compat_semid64_ds v; 1711 struct compat_semid64_ds v;
1705 memset(&v, 0, sizeof(v)); 1712 memset(&v, 0, sizeof(v));
1706 to_compat_ipc64_perm(&v.sem_perm, &in->sem_perm); 1713 to_compat_ipc64_perm(&v.sem_perm, &in->sem_perm);
1707 v.sem_otime = in->sem_otime; 1714 v.sem_otime = lower_32_bits(in->sem_otime);
1708 v.sem_ctime = in->sem_ctime; 1715 v.sem_otime_high = upper_32_bits(in->sem_otime);
1716 v.sem_ctime = lower_32_bits(in->sem_ctime);
1717 v.sem_ctime_high = upper_32_bits(in->sem_ctime);
1709 v.sem_nsems = in->sem_nsems; 1718 v.sem_nsems = in->sem_nsems;
1710 return copy_to_user(buf, &v, sizeof(v)); 1719 return copy_to_user(buf, &v, sizeof(v));
1711 } else { 1720 } else {
@@ -2168,7 +2177,7 @@ out_free:
2168} 2177}
2169 2178
2170long ksys_semtimedop(int semid, struct sembuf __user *tsops, 2179long ksys_semtimedop(int semid, struct sembuf __user *tsops,
2171 unsigned int nsops, const struct timespec __user *timeout) 2180 unsigned int nsops, const struct __kernel_timespec __user *timeout)
2172{ 2181{
2173 if (timeout) { 2182 if (timeout) {
2174 struct timespec64 ts; 2183 struct timespec64 ts;
@@ -2180,12 +2189,12 @@ long ksys_semtimedop(int semid, struct sembuf __user *tsops,
2180} 2189}
2181 2190
2182SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, 2191SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
2183 unsigned int, nsops, const struct timespec __user *, timeout) 2192 unsigned int, nsops, const struct __kernel_timespec __user *, timeout)
2184{ 2193{
2185 return ksys_semtimedop(semid, tsops, nsops, timeout); 2194 return ksys_semtimedop(semid, tsops, nsops, timeout);
2186} 2195}
2187 2196
2188#ifdef CONFIG_COMPAT 2197#ifdef CONFIG_COMPAT_32BIT_TIME
2189long compat_ksys_semtimedop(int semid, struct sembuf __user *tsems, 2198long compat_ksys_semtimedop(int semid, struct sembuf __user *tsems,
2190 unsigned int nsops, 2199 unsigned int nsops,
2191 const struct compat_timespec __user *timeout) 2200 const struct compat_timespec __user *timeout)