diff options
Diffstat (limited to 'ipc/sem.c')
-rw-r--r-- | ipc/sem.c | 27 |
1 files changed, 18 insertions, 9 deletions
@@ -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: | |||
984 | static void set_semotime(struct sem_array *sma, struct sembuf *sops) | 985 | static 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 | ||
2170 | long ksys_semtimedop(int semid, struct sembuf __user *tsops, | 2179 | long 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 | ||
2182 | SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, | 2191 | SYSCALL_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 |
2189 | long compat_ksys_semtimedop(int semid, struct sembuf __user *tsems, | 2198 | long 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) |