Do not use struct l_timespec without conversion. While here move
args->timeout handling before acquiring the futex key at FUTEX_WAIT path. Differential Revision: https://reviews.freebsd.org/D1520 Reviewed by: trasz
This commit is contained in:
parent
7e947ccc81
commit
680982281b
@ -65,6 +65,7 @@ __KERNEL_RCSID(1, "$NetBSD: linux_futex.c,v 1.7 2006/07/24 19:01:49 manu Exp $")
|
||||
#include <compat/linux/linux_dtrace.h>
|
||||
#include <compat/linux/linux_emul.h>
|
||||
#include <compat/linux/linux_futex.h>
|
||||
#include <compat/linux/linux_timer.h>
|
||||
#include <compat/linux/linux_util.h>
|
||||
|
||||
/* DTrace init */
|
||||
@ -669,7 +670,8 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
|
||||
struct linux_pemuldata *pem;
|
||||
struct waiting_proc *wp;
|
||||
struct futex *f, *f2;
|
||||
struct l_timespec timeout;
|
||||
struct l_timespec ltimeout;
|
||||
struct timespec timeout;
|
||||
struct timeval utv, ctv;
|
||||
int timeout_hz;
|
||||
int error;
|
||||
@ -713,6 +715,38 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
|
||||
LINUX_CTR3(sys_futex, "WAIT uaddr %p val 0x%x bitset 0x%x",
|
||||
args->uaddr, args->val, args->val3);
|
||||
|
||||
if (args->timeout != NULL) {
|
||||
error = copyin(args->timeout, <imeout, sizeof(ltimeout));
|
||||
if (error) {
|
||||
LIN_SDT_PROBE1(futex, linux_sys_futex, copyin_error,
|
||||
error);
|
||||
LIN_SDT_PROBE1(futex, linux_sys_futex, return, error);
|
||||
return (error);
|
||||
}
|
||||
error = linux_to_native_timespec(&timeout, <imeout);
|
||||
if (error)
|
||||
return (error);
|
||||
TIMESPEC_TO_TIMEVAL(&utv, &timeout);
|
||||
error = itimerfix(&utv);
|
||||
if (error) {
|
||||
LIN_SDT_PROBE1(futex, linux_sys_futex, itimerfix_error,
|
||||
error);
|
||||
LIN_SDT_PROBE1(futex, linux_sys_futex, return, error);
|
||||
return (error);
|
||||
}
|
||||
if (clockrt) {
|
||||
microtime(&ctv);
|
||||
timevalsub(&utv, &ctv);
|
||||
} else if (args->op == LINUX_FUTEX_WAIT_BITSET) {
|
||||
microuptime(&ctv);
|
||||
timevalsub(&utv, &ctv);
|
||||
}
|
||||
if (utv.tv_sec < 0)
|
||||
timevalclear(&utv);
|
||||
timeout_hz = tvtohz(&utv);
|
||||
} else
|
||||
timeout_hz = 0;
|
||||
|
||||
error = futex_get(args->uaddr, &wp, &f,
|
||||
flags | FUTEX_CREATE_WP);
|
||||
if (error) {
|
||||
@ -745,37 +779,6 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
|
||||
return (EWOULDBLOCK);
|
||||
}
|
||||
|
||||
if (args->timeout != NULL) {
|
||||
error = copyin(args->timeout, &timeout, sizeof(timeout));
|
||||
if (error) {
|
||||
LIN_SDT_PROBE1(futex, linux_sys_futex, copyin_error,
|
||||
error);
|
||||
LIN_SDT_PROBE1(futex, linux_sys_futex, return, error);
|
||||
futex_put(f, wp);
|
||||
return (error);
|
||||
}
|
||||
TIMESPEC_TO_TIMEVAL(&utv, &timeout);
|
||||
error = itimerfix(&utv);
|
||||
if (error) {
|
||||
LIN_SDT_PROBE1(futex, linux_sys_futex, itimerfix_error,
|
||||
error);
|
||||
LIN_SDT_PROBE1(futex, linux_sys_futex, return, error);
|
||||
futex_put(f, wp);
|
||||
return (error);
|
||||
}
|
||||
if (clockrt) {
|
||||
microtime(&ctv);
|
||||
timevalsub(&utv, &ctv);
|
||||
} else if (args->op == LINUX_FUTEX_WAIT_BITSET) {
|
||||
microuptime(&ctv);
|
||||
timevalsub(&utv, &ctv);
|
||||
}
|
||||
if (utv.tv_sec < 0)
|
||||
timevalclear(&utv);
|
||||
timeout_hz = tvtohz(&utv);
|
||||
} else
|
||||
timeout_hz = 0;
|
||||
|
||||
error = futex_wait(f, wp, timeout_hz, args->val3);
|
||||
break;
|
||||
|
||||
|
@ -88,6 +88,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <compat/linux/linux_file.h>
|
||||
#include <compat/linux/linux_mib.h>
|
||||
#include <compat/linux/linux_signal.h>
|
||||
#include <compat/linux/linux_timer.h>
|
||||
#include <compat/linux/linux_util.h>
|
||||
#include <compat/linux/linux_sysproto.h>
|
||||
#include <compat/linux/linux_emul.h>
|
||||
@ -2168,8 +2169,9 @@ linux_pselect6(struct thread *td, struct linux_pselect6_args *args)
|
||||
error = copyin(args->tsp, <s, sizeof(lts));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
uts.tv_sec = lts.tv_sec;
|
||||
uts.tv_nsec = lts.tv_nsec;
|
||||
error = linux_to_native_timespec(&uts, <s);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
TIMESPEC_TO_TIMEVAL(&utv, &uts);
|
||||
if (itimerfix(&utv))
|
||||
@ -2201,8 +2203,8 @@ linux_pselect6(struct thread *td, struct linux_pselect6_args *args)
|
||||
timevalclear(&utv);
|
||||
|
||||
TIMEVAL_TO_TIMESPEC(&utv, &uts);
|
||||
lts.tv_sec = uts.tv_sec;
|
||||
lts.tv_nsec = uts.tv_nsec;
|
||||
|
||||
native_to_linux_timespec(<s, &uts);
|
||||
error = copyout(<s, args->tsp, sizeof(lts));
|
||||
}
|
||||
|
||||
@ -2234,8 +2236,9 @@ linux_ppoll(struct thread *td, struct linux_ppoll_args *args)
|
||||
error = copyin(args->tsp, <s, sizeof(lts));
|
||||
if (error)
|
||||
return (error);
|
||||
uts.tv_sec = lts.tv_sec;
|
||||
uts.tv_nsec = lts.tv_nsec;
|
||||
error = linux_to_native_timespec(&uts, <s);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
nanotime(&ts0);
|
||||
tsp = &uts;
|
||||
@ -2254,8 +2257,7 @@ linux_ppoll(struct thread *td, struct linux_ppoll_args *args)
|
||||
} else
|
||||
timespecclear(&uts);
|
||||
|
||||
lts.tv_sec = uts.tv_sec;
|
||||
lts.tv_nsec = uts.tv_nsec;
|
||||
native_to_linux_timespec(<s, &uts);
|
||||
error = copyout(<s, args->tsp, sizeof(lts));
|
||||
}
|
||||
|
||||
@ -2343,8 +2345,7 @@ linux_sched_rr_get_interval(struct thread *td,
|
||||
PROC_UNLOCK(tdt->td_proc);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
lts.tv_sec = ts.tv_sec;
|
||||
lts.tv_nsec = ts.tv_nsec;
|
||||
native_to_linux_timespec(<s, &ts);
|
||||
return (copyout(<s, uap->interval, sizeof(lts)));
|
||||
}
|
||||
|
||||
|
@ -119,13 +119,10 @@ LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_flags, "int");
|
||||
LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_clockid, "int");
|
||||
LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, return, "int");
|
||||
|
||||
static void native_to_linux_timespec(struct l_timespec *,
|
||||
struct timespec *);
|
||||
static int linux_to_native_timespec(struct timespec *,
|
||||
struct l_timespec *);
|
||||
static int linux_to_native_clockid(clockid_t *, clockid_t);
|
||||
|
||||
static void
|
||||
|
||||
void
|
||||
native_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp)
|
||||
{
|
||||
|
||||
@ -137,7 +134,7 @@ native_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp)
|
||||
LIN_SDT_PROBE0(time, native_to_linux_timespec, return);
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
linux_to_native_timespec(struct timespec *ntp, struct l_timespec *ltp)
|
||||
{
|
||||
|
||||
|
@ -111,4 +111,9 @@ struct l_itimerspec {
|
||||
struct l_timespec it_value;
|
||||
};
|
||||
|
||||
void native_to_linux_timespec(struct l_timespec *,
|
||||
struct timespec *);
|
||||
int linux_to_native_timespec(struct timespec *,
|
||||
struct l_timespec *);
|
||||
|
||||
#endif /* _LINUX_TIMER_H */
|
||||
|
Loading…
x
Reference in New Issue
Block a user