mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-03 08:22:44 +00:00
Add compatible code to let 32bit libthr work on 64bit kernel.
This commit is contained in:
parent
e58b17ea53
commit
cda9a0d1c2
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=162551
@ -103,4 +103,18 @@ struct statfs32 {
|
||||
int32_t f_spare[2];
|
||||
};
|
||||
|
||||
struct thr_param32 {
|
||||
uint32_t start_func;
|
||||
uint32_t arg;
|
||||
uint32_t stack_base;
|
||||
uint32_t stack_size;
|
||||
uint32_t tls_base;
|
||||
uint32_t tls_size;
|
||||
uint32_t child_tid;
|
||||
uint32_t parent_tid;
|
||||
int32_t flags;
|
||||
uint32_t rtp;
|
||||
uint32_t spare[3];
|
||||
};
|
||||
|
||||
#endif /* !_COMPAT_FREEBSD32_FREEBSD32_H_ */
|
||||
|
@ -67,7 +67,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/sysent.h>
|
||||
#include <sys/sysproto.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/thr.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/ucontext.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
@ -2121,6 +2123,60 @@ freebsd32_clock_getres(struct thread *td,
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
freebsd32_thr_new(struct thread *td,
|
||||
struct freebsd32_thr_new_args *uap)
|
||||
{
|
||||
struct thr_param32 param32;
|
||||
struct thr_param param;
|
||||
int error;
|
||||
|
||||
if (uap->param_size < 0 ||
|
||||
uap->param_size > sizeof(struct thr_param32))
|
||||
return (EINVAL);
|
||||
bzero(¶m, sizeof(struct thr_param));
|
||||
bzero(¶m32, sizeof(struct thr_param32));
|
||||
error = copyin(uap->param, ¶m32, uap->param_size);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
param.start_func = PTRIN(param32.start_func);
|
||||
param.arg = PTRIN(param32.arg);
|
||||
param.stack_base = PTRIN(param32.stack_base);
|
||||
param.stack_size = param32.stack_size;
|
||||
param.tls_base = PTRIN(param32.tls_base);
|
||||
param.tls_size = param32.tls_size;
|
||||
param.child_tid = PTRIN(param32.child_tid);
|
||||
param.parent_tid = PTRIN(param32.parent_tid);
|
||||
param.flags = param32.flags;
|
||||
param.rtp = PTRIN(param32.rtp);
|
||||
param.spare[0] = PTRIN(param32.spare[0]);
|
||||
param.spare[1] = PTRIN(param32.spare[1]);
|
||||
param.spare[2] = PTRIN(param32.spare[2]);
|
||||
|
||||
return (kern_thr_new(td, ¶m));
|
||||
}
|
||||
|
||||
int
|
||||
freebsd32_thr_suspend(struct thread *td, struct freebsd32_thr_suspend_args *uap)
|
||||
{
|
||||
struct timespec32 ts32;
|
||||
struct timespec ts, *tsp;
|
||||
int error;
|
||||
|
||||
error = 0;
|
||||
tsp = NULL;
|
||||
if (uap->timeout != NULL) {
|
||||
error = copyin((const void *)uap->timeout, (void *)&ts32,
|
||||
sizeof(struct timespec32));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
ts.tv_sec = ts32.tv_sec;
|
||||
ts.tv_nsec = ts32.tv_nsec;
|
||||
tsp = &ts;
|
||||
}
|
||||
return (kern_thr_suspend(td, tsp));
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
int
|
||||
|
@ -715,8 +715,7 @@
|
||||
428 AUE_NULL UNIMPL __acl_aclcheck_link
|
||||
; XXX implement
|
||||
429 AUE_SIGWAIT UNIMPL sigwait
|
||||
430 AUE_NULL NOPROTO { int thr_create(ucontext_t *ctx, long *id, \
|
||||
int flag s); }
|
||||
430 AUE_NULL UNIMPL thr_create;
|
||||
431 AUE_NULL NOPROTO { void thr_exit(long *state); }
|
||||
432 AUE_NULL NOPROTO { int thr_self(long *id); }
|
||||
433 AUE_NULL NOPROTO { int thr_kill(long id, int sig); }
|
||||
@ -728,8 +727,8 @@
|
||||
439 AUE_EXTATTR_LIST_LINK UNIMPL extattr_list_link
|
||||
440 AUE_NULL UNIMPL kse_switchin
|
||||
441 AUE_NULL UNIMPL ksem_timedwait
|
||||
442 AUE_NULL NOPROTO { int thr_suspend( \
|
||||
const struct timespec *timeout); }
|
||||
442 AUE_NULL STD { int freebsd32_thr_suspend( \
|
||||
const struct timespec32 *timeout); }
|
||||
443 AUE_NULL NOPROTO { int thr_wake(long id); }
|
||||
444 AUE_MODUNLOAD NOPROTO { int kldunloadf(int fileid, int flags); }
|
||||
445 AUE_AUDIT UNIMPL audit
|
||||
@ -744,7 +743,9 @@
|
||||
454 AUE_NULL STD { int freebsd32_umtx_op(void *obj, int op,\
|
||||
uintptr_t val, void *uaddr, \
|
||||
void *uaddr2); }
|
||||
455 AUE_NULL UNIMPL thr_new
|
||||
455 AUE_NULL STD { int freebsd32_thr_new( \
|
||||
struct thr_param32 *param, \
|
||||
int param_size); }
|
||||
456 AUE_NULL NOPROTO { int sigqueue(pid_t pid, int signum, \
|
||||
void *value); }
|
||||
457 AUE_NULL UNIMPL kmq_open
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_compat.h"
|
||||
#include "opt_posix.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
@ -51,6 +52,26 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <machine/frame.h>
|
||||
|
||||
#ifdef COMPAT_IA32
|
||||
|
||||
extern struct sysentvec ia32_freebsd_sysvec;
|
||||
|
||||
static inline int
|
||||
suword_lwpid(void *addr, lwpid_t lwpid)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (curproc->p_sysent != &ia32_freebsd_sysvec)
|
||||
error = suword(addr, lwpid);
|
||||
else
|
||||
error = suword32(addr, lwpid);
|
||||
return (error);
|
||||
}
|
||||
|
||||
#else
|
||||
#define suword_lwpid suword
|
||||
#endif
|
||||
|
||||
extern int max_threads_per_proc;
|
||||
|
||||
static int create_thread(struct thread *td, mcontext_t *ctx,
|
||||
@ -83,22 +104,30 @@ thr_new(struct thread *td, struct thr_new_args *uap)
|
||||
/* struct thr_param * */
|
||||
{
|
||||
struct thr_param param;
|
||||
int error;
|
||||
|
||||
if (uap->param_size < 0 || uap->param_size > sizeof(param))
|
||||
return (EINVAL);
|
||||
bzero(¶m, sizeof(param));
|
||||
if ((error = copyin(uap->param, ¶m, uap->param_size)))
|
||||
return (error);
|
||||
return (kern_thr_new(td, ¶m));
|
||||
}
|
||||
|
||||
int
|
||||
kern_thr_new(struct thread *td, struct thr_param *param)
|
||||
{
|
||||
struct rtprio rtp, *rtpp;
|
||||
int error;
|
||||
|
||||
if (uap->param_size < sizeof(param))
|
||||
return (EINVAL);
|
||||
bzero(¶m, sizeof(param));
|
||||
if ((error = copyin(uap->param, ¶m, sizeof(param))))
|
||||
return (error);
|
||||
rtpp = NULL;
|
||||
if (param.rtp != 0) {
|
||||
error = copyin(param.rtp, &rtp, sizeof(struct rtprio));
|
||||
if (param->rtp != 0) {
|
||||
error = copyin(param->rtp, &rtp, sizeof(struct rtprio));
|
||||
rtpp = &rtp;
|
||||
}
|
||||
error = create_thread(td, NULL, param.start_func, param.arg,
|
||||
param.stack_base, param.stack_size, param.tls_base,
|
||||
param.child_tid, param.parent_tid, param.flags,
|
||||
error = create_thread(td, NULL, param->start_func, param->arg,
|
||||
param->stack_base, param->stack_size, param->tls_base,
|
||||
param->child_tid, param->parent_tid, param->flags,
|
||||
rtpp);
|
||||
return (error);
|
||||
}
|
||||
@ -158,12 +187,13 @@ create_thread(struct thread *td, mcontext_t *ctx,
|
||||
*/
|
||||
id = newtd->td_tid;
|
||||
if ((child_tid != NULL &&
|
||||
(error = copyout(&id, child_tid, sizeof(long)))) ||
|
||||
suword_lwpid(child_tid, newtd->td_tid)) ||
|
||||
(parent_tid != NULL &&
|
||||
(error = copyout(&id, parent_tid, sizeof(long))))) {
|
||||
thread_free(newtd);
|
||||
return (error);
|
||||
suword_lwpid(parent_tid, newtd->td_tid))) {
|
||||
thread_free(newtd);
|
||||
return (EFAULT);
|
||||
}
|
||||
|
||||
bzero(&newtd->td_startzero,
|
||||
__rangeof(struct thread, td_startzero, td_endzero));
|
||||
bcopy(&td->td_startcopy, &newtd->td_startcopy,
|
||||
@ -231,13 +261,11 @@ int
|
||||
thr_self(struct thread *td, struct thr_self_args *uap)
|
||||
/* long *id */
|
||||
{
|
||||
long id;
|
||||
int error;
|
||||
|
||||
id = td->td_tid;
|
||||
if ((error = copyout(&id, uap->id, sizeof(long))))
|
||||
return (error);
|
||||
|
||||
error = suword_lwpid(uap->id, (unsigned)td->td_tid);
|
||||
if (error == -1)
|
||||
return (EFAULT);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -251,7 +279,7 @@ thr_exit(struct thread *td, struct thr_exit_args *uap)
|
||||
|
||||
/* Signal userland that it can free the stack. */
|
||||
if ((void *)uap->state != NULL) {
|
||||
suword((void *)uap->state, 1);
|
||||
suword_lwpid(uap->state, 1);
|
||||
kern_umtx_wake(td, uap->state, INT_MAX);
|
||||
}
|
||||
|
||||
@ -320,23 +348,34 @@ int
|
||||
thr_suspend(struct thread *td, struct thr_suspend_args *uap)
|
||||
/* const struct timespec *timeout */
|
||||
{
|
||||
struct timespec ts;
|
||||
struct timeval tv;
|
||||
struct timespec ts, *tsp;
|
||||
int error;
|
||||
int hz;
|
||||
|
||||
hz = 0;
|
||||
error = 0;
|
||||
tsp = NULL;
|
||||
if (uap->timeout != NULL) {
|
||||
error = copyin((const void *)uap->timeout, (void *)&ts,
|
||||
sizeof(struct timespec));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
if (ts.tv_nsec < 0 || ts.tv_nsec > 1000000000)
|
||||
tsp = &ts;
|
||||
}
|
||||
|
||||
return (kern_thr_suspend(td, tsp));
|
||||
}
|
||||
|
||||
int
|
||||
kern_thr_suspend(struct thread *td, struct timespec *tsp)
|
||||
{
|
||||
struct timeval tv;
|
||||
int error = 0, hz = 0;
|
||||
|
||||
if (tsp != NULL) {
|
||||
if (tsp->tv_nsec < 0 || tsp->tv_nsec > 1000000000)
|
||||
return (EINVAL);
|
||||
if (ts.tv_sec == 0 && ts.tv_nsec == 0)
|
||||
if (tsp->tv_sec == 0 && tsp->tv_nsec == 0)
|
||||
return (ETIMEDOUT);
|
||||
TIMESPEC_TO_TIMEVAL(&tv, &ts);
|
||||
TIMESPEC_TO_TIMEVAL(&tv, tsp);
|
||||
hz = tvtohz(&tv);
|
||||
}
|
||||
PROC_LOCK(td->td_proc);
|
||||
|
@ -64,6 +64,10 @@ int thr_kill(long id, int sig);
|
||||
int thr_suspend(const struct timespec *timeout);
|
||||
int thr_wake(long id);
|
||||
int thr_set_name(long id, const char *name);
|
||||
#else
|
||||
struct thread;
|
||||
int kern_thr_new(struct thread *td, struct thr_param *param);
|
||||
int kern_thr_suspend(struct thread *, struct timespec *);
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
#endif /* ! _SYS_THR_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user