Page MenuHomeFreeBSD

D27223.diff
No OneTemporary

D27223.diff

Index: sys/kern/kern_umtx.c
===================================================================
--- sys/kern/kern_umtx.c
+++ sys/kern/kern_umtx.c
@@ -219,7 +219,7 @@
struct timespec end;
};
-#if defined(COMPAT_FREEBSD32)
+#if defined(COMPAT_FREEBSD32) || defined(__LP64__)
#define NEED_UMTX32
#endif
@@ -4142,6 +4142,36 @@
}
#ifdef NEED_UMTX32
+#if defined(__amd64__)
+struct timespecx32 {
+ int64_t tv_sec;
+ int32_t tv_nsec;
+};
+
+struct umtx_timex32 {
+ struct timespecx32 timeout;
+ uint32_t flags;
+ uint32_t clockid;
+};
+
+#define timespeci386 timespec32
+#define umtx_timei386 umtx_time32
+#else
+struct timespeci386 {
+ int32_t tv_sec;
+ int32_t tv_nsec;
+};
+
+struct umtx_timei386 {
+ struct timespeci386 timeout;
+ uint32_t flags;
+ uint32_t clockid;
+};
+
+#define timespecx32 timespec32
+#define umtx_xtimex32 umtx_time32
+#endif
+
struct umtx_time32 {
struct timespec32 timeout;
uint32_t flags;
@@ -4155,12 +4185,12 @@
};
static inline int
-umtx_copyin_timeout32(const void *addr, struct timespec *tsp)
+umtx_copyin_timeouti386(const void *addr, struct timespec *tsp)
{
- struct timespec32 ts32;
+ struct timespeci386 ts32;
int error;
- error = copyin(addr, &ts32, sizeof(struct timespec32));
+ error = copyin(addr, &ts32, sizeof(struct timespeci386));
if (error == 0) {
if (ts32.tv_sec < 0 ||
ts32.tv_nsec >= 1000000000 ||
@@ -4175,17 +4205,63 @@
}
static inline int
-umtx_copyin_umtx_time32(const void *addr, size_t size, struct _umtx_time *tp)
+umtx_copyin_umtx_timei386(const void *addr, size_t size, struct _umtx_time *tp)
{
- struct umtx_time32 t32;
+ struct umtx_timei386 t32;
int error;
t32.clockid = CLOCK_REALTIME;
t32.flags = 0;
- if (size <= sizeof(struct timespec32))
- error = copyin(addr, &t32.timeout, sizeof(struct timespec32));
- else
- error = copyin(addr, &t32, sizeof(struct umtx_time32));
+ if (size <= sizeof(struct timespeci386)) {
+ error = copyin(addr, &t32.timeout, sizeof(struct timespeci386));
+ } else {
+ error = copyin(addr, &t32, sizeof(struct umtx_timei386));
+ }
+ if (error != 0)
+ return (error);
+ if (t32.timeout.tv_sec < 0 ||
+ t32.timeout.tv_nsec >= 1000000000 || t32.timeout.tv_nsec < 0)
+ return (EINVAL);
+ tp->_timeout.tv_sec = t32.timeout.tv_sec;
+ tp->_timeout.tv_nsec = t32.timeout.tv_nsec;
+ tp->_flags = t32.flags;
+ tp->_clockid = t32.clockid;
+ return (0);
+}
+
+static inline int
+umtx_copyin_timeoutx32(const void *addr, struct timespec *tsp)
+{
+ struct timespecx32 ts32;
+ int error;
+
+ error = copyin(addr, &ts32, sizeof(struct timespecx32));
+ if (error == 0) {
+ if (ts32.tv_sec < 0 ||
+ ts32.tv_nsec >= 1000000000 ||
+ ts32.tv_nsec < 0)
+ error = EINVAL;
+ else {
+ tsp->tv_sec = ts32.tv_sec;
+ tsp->tv_nsec = ts32.tv_nsec;
+ }
+ }
+ return (error);
+}
+
+static inline int
+umtx_copyin_umtx_timex32(const void *addr, size_t size, struct _umtx_time *tp)
+{
+ struct umtx_timex32 t32;
+ int error;
+
+ t32.clockid = CLOCK_REALTIME;
+ t32.flags = 0;
+ if (size <= sizeof(struct timespecx32)) {
+ error = copyin(addr, &t32.timeout, sizeof(struct timespecx32));
+ } else {
+ error = copyin(addr, &t32, sizeof(struct umtx_timex32));
+ }
if (error != 0)
return (error);
if (t32.timeout.tv_sec < 0 ||
@@ -4218,9 +4294,23 @@
}
static int
-umtx_copyout_timeout32(void *addr, size_t sz, struct timespec *tsp)
+umtx_copyout_timeoutx32(void *addr, size_t sz, struct timespec *tsp)
{
- struct timespec32 remain32 = {
+ struct timespecx32 remain32 = {
+ .tv_sec = tsp->tv_sec,
+ .tv_nsec = tsp->tv_nsec,
+ };
+
+ KASSERT(sz >= sizeof(struct timespec32),
+ ("_umtx_copyops specifies incorrect sizes"));
+
+ return (copyout(&remain32, addr, sizeof(struct timespec32)));
+}
+
+static int
+umtx_copyout_timeouti386(void *addr, size_t sz, struct timespec *tsp)
+{
+ struct timespeci386 remain32 = {
.tv_sec = tsp->tv_sec,
.tv_nsec = tsp->tv_nsec,
};
@@ -4280,15 +4370,32 @@
};
#ifdef NEED_UMTX32
-struct _umtx_copyops umtx_native_ops32 = {
- .copyin_timeout = umtx_copyin_timeout32,
- .copyin_umtx_time = umtx_copyin_umtx_time32,
+struct _umtx_copyops umtx_native_opsx32 = {
+ .copyin_timeout = umtx_copyin_timeoutx32,
+ .copyin_umtx_time = umtx_copyin_umtx_timex32,
.copyin_robust_lists = umtx_copyin_robust_lists32,
- .copyout_timeout = umtx_copyout_timeout32,
- .timespec_sz = sizeof(struct timespec32),
- .umtx_time_sz = sizeof(struct umtx_time32),
+ .copyout_timeout = umtx_copyout_timeoutx32,
+ .timespec_sz = sizeof(struct timespecx32),
+ .umtx_time_sz = sizeof(struct umtx_timex32),
};
-#endif
+
+struct _umtx_copyops umtx_native_opsi386 = {
+ .copyin_timeout = umtx_copyin_timeouti386,
+ .copyin_umtx_time = umtx_copyin_umtx_timei386,
+ .copyin_robust_lists = umtx_copyin_robust_lists32,
+ .copyout_timeout = umtx_copyout_timeouti386,
+ .timespec_sz = sizeof(struct timespeci386),
+ .umtx_time_sz = sizeof(struct umtx_timei386),
+};
+
+#ifdef __amd64__
+#define umtx_native_ops32 umtx_native_opsi386
+#else
+#define umtx_native_ops32 umtx_native_opsx86
+#endif /* __amd64__ */
+#endif /* NEED_UMTX32 */
+
+#define UMTX_OP__FLAGS (UMTX_OP__32BIT | UMTX_OP__32BIT_I386)
static int
kern__umtx_op(struct thread *td, void *obj, int op, unsigned long val,
@@ -4296,7 +4403,7 @@
{
struct _umtx_op_args uap = {
.obj = obj,
- .op = op,
+ .op = op & ~UMTX_OP__FLAGS,
.val = val,
.uaddr1 = uaddr1,
.uaddr2 = uaddr2
@@ -4313,6 +4420,18 @@
struct _umtx_copyops *umtx_ops;
umtx_ops = &umtx_native_ops;
+#ifdef __LP64__
+ if ((uap->op & UMTX_OP__32BIT) != 0) {
+ if ((uap->op & UMTX_OP__32BIT_I386) != 0)
+ umtx_ops = &umtx_native_opsi386;
+ else
+ umtx_ops = &umtx_native_opsx32;
+ }
+#else
+ /* We consider UMTX_OP__32BIT a nop on ILP32. */
+ if ((uap->op & UMTX_OP__32BIT_I386) != 0)
+ umtx_ops = &umtx_native_opsi386;
+#endif
return (kern__umtx_op(td, uap->obj, uap->op, uap->val, uap->uaddr1,
uap->uaddr2, umtx_ops));
}
Index: sys/sys/umtx.h
===================================================================
--- sys/sys/umtx.h
+++ sys/sys/umtx.h
@@ -101,6 +101,9 @@
#define UMTX_OP_SHM 25
#define UMTX_OP_ROBUST_LISTS 26
+#define UMTX_OP__32BIT 0x80000000
+#define UMTX_OP__32BIT_I386 0x40000000
+
/* Flags for UMTX_OP_CV_WAIT */
#define CVWAIT_CHECK_UNPARKING 0x01
#define CVWAIT_ABSTIME 0x02

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 15, 10:07 AM (18 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29644652
Default Alt Text
D27223.diff (6 KB)

Event Timeline