svn commit: r206350 - in stable/8/sys: compat/freebsd32 kern

Konstantin Belousov kib at FreeBSD.org
Wed Apr 7 14:47:56 UTC 2010


Author: kib
Date: Wed Apr  7 14:47:55 2010
New Revision: 206350
URL: http://svn.freebsd.org/changeset/base/206350

Log:
  MFC r205324:
  Implement compat32 shims for ksem syscalls.

Modified:
  stable/8/sys/compat/freebsd32/syscalls.master
  stable/8/sys/kern/uipc_sem.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/compat/freebsd32/syscalls.master
==============================================================================
--- stable/8/sys/compat/freebsd32/syscalls.master	Wed Apr  7 14:46:28 2010	(r206349)
+++ stable/8/sys/compat/freebsd32/syscalls.master	Wed Apr  7 14:47:55 2010	(r206350)
@@ -698,16 +698,19 @@
 398	AUE_FHSTATFS	NOPROTO	{ int fhstatfs(const struct fhandle *u_fhp, \
 				    struct statfs *buf); }
 399	AUE_NULL	UNIMPL	nosys
-; XXX implement these?
-400	AUE_NULL	UNIMPL	ksem_close
-401	AUE_NULL	UNIMPL	ksem_post
-402	AUE_NULL	UNIMPL	ksem_wait
-403	AUE_NULL	UNIMPL	ksem_trywait
-404	AUE_NULL	UNIMPL	ksem_init
-405	AUE_NULL	UNIMPL	ksem_open
-406	AUE_NULL	UNIMPL	ksem_unlink
-407	AUE_NULL	UNIMPL	ksem_getvalue
-408	AUE_NULL	UNIMPL	ksem_destroy
+400	AUE_NULL	NOSTD|NOPROTO	{ int ksem_close(semid_t id); }
+401	AUE_NULL	NOSTD|NOPROTO	{ int ksem_post(semid_t id); }
+402	AUE_NULL	NOSTD|NOPROTO	{ int ksem_wait(semid_t id); }
+403	AUE_NULL	NOSTD|NOPROTO	{ int ksem_trywait(semid_t id); }
+404	AUE_NULL	NOSTD	{ int freebsd32_ksem_init(semid_t *idp, \
+				    unsigned int value); }
+405	AUE_NULL	NOSTD	{ int freebsd32_ksem_open(semid_t *idp, \
+				    const char *name, int oflag, \
+				    mode_t mode, unsigned int value); }
+406	AUE_NULL	NOSTD|NOPROTO	{ int ksem_unlink(const char *name); }
+407	AUE_NULL	NOSTD|NOPROTO	{ int ksem_getvalue(semid_t id, \
+				    int *val); }
+408	AUE_NULL	NOSTD|NOPROTO	{ int ksem_destroy(semid_t id); }
 409	AUE_NULL	UNIMPL	__mac_get_pid
 410	AUE_NULL	UNIMPL	__mac_get_link
 411	AUE_NULL	UNIMPL	__mac_set_link
@@ -766,7 +769,8 @@
 				    const char *path, int attrnamespace, \
 				    void *data, size_t nbytes); }
 440	AUE_NULL	UNIMPL	kse_switchin
-441	AUE_NULL	UNIMPL	ksem_timedwait
+441	AUE_NULL	NOSTD	{ int freebsd32_ksem_timedwait(semid_t id, \
+				    const struct timespec32 *abstime); }
 442	AUE_NULL	STD	{ int freebsd32_thr_suspend( \
 				    const struct timespec32 *timeout); }
 443	AUE_NULL	NOPROTO	{ int thr_wake(long id); }

Modified: stable/8/sys/kern/uipc_sem.c
==============================================================================
--- stable/8/sys/kern/uipc_sem.c	Wed Apr  7 14:46:28 2010	(r206349)
+++ stable/8/sys/kern/uipc_sem.c	Wed Apr  7 14:47:55 2010	(r206350)
@@ -34,6 +34,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_compat.h"
 #include "opt_posix.h"
 
 #include <sys/param.h>
@@ -113,7 +114,7 @@ static struct ksem *ksem_alloc(struct uc
 		    unsigned int value);
 static int	ksem_create(struct thread *td, const char *path,
 		    semid_t *semidp, mode_t mode, unsigned int value,
-		    int flags);
+		    int flags, int compat32);
 static void	ksem_drop(struct ksem *ks);
 static int	ksem_get(struct thread *td, semid_t id, struct file **fpp);
 static struct ksem *ksem_hold(struct ksem *ks);
@@ -375,16 +376,44 @@ ksem_remove(char *path, Fnv32_t fnv, str
 	return (ENOENT);
 }
 
+static int
+ksem_create_copyout_semid(struct thread *td, semid_t *semidp, int fd,
+    int compat32)
+{
+	semid_t semid;
+#ifdef COMPAT_FREEBSD32
+	int32_t semid32;
+#endif
+	void *ptr;
+	size_t ptrs;
+
+#ifdef COMPAT_FREEBSD32
+	if (compat32) {
+		semid32 = fd;
+		ptr = &semid32;
+		ptrs = sizeof(semid32);
+	} else {
+#endif
+		semid = fd;
+		ptr = &semid;
+		ptrs = sizeof(semid);
+		compat32 = 0; /* silence gcc */
+#ifdef COMPAT_FREEBSD32
+	}
+#endif
+
+	return (copyout(ptr, semidp, ptrs));
+}
+
 /* Other helper routines. */
 static int
 ksem_create(struct thread *td, const char *name, semid_t *semidp, mode_t mode,
-    unsigned int value, int flags)
+    unsigned int value, int flags, int compat32)
 {
 	struct filedesc *fdp;
 	struct ksem *ks;
 	struct file *fp;
 	char *path;
-	semid_t semid;
 	Fnv32_t fnv;
 	int error, fd;
 
@@ -405,8 +434,7 @@ ksem_create(struct thread *td, const cha
 	 * premature, but it is a lot easier to handle errors as opposed
 	 * to later when we've possibly created a new semaphore, etc.
 	 */
-	semid = fd;
-	error = copyout(&semid, semidp, sizeof(semid));
+	error = ksem_create_copyout_semid(td, semidp, fd, compat32);
 	if (error) {
 		fdclose(fdp, fp, fd, td);
 		fdrop(fp, td);
@@ -531,7 +559,7 @@ ksem_init(struct thread *td, struct ksem
 {
 
 	return (ksem_create(td, NULL, uap->idp, S_IRWXU | S_IRWXG, uap->value,
-	    0));
+	    0, 0));
 }
 
 #ifndef _SYS_SYSPROTO_H_
@@ -552,7 +580,7 @@ ksem_open(struct thread *td, struct ksem
 	if ((uap->oflag & ~(O_CREAT | O_EXCL)) != 0)
 		return (EINVAL);
 	return (ksem_create(td, uap->name, uap->idp, uap->mode, uap->value,
-	    uap->oflag));
+	    uap->oflag, 0));
 }
 
 #ifndef _SYS_SYSPROTO_H_
@@ -833,38 +861,85 @@ err:
 	return (error);
 }
 
-#define	SYSCALL_DATA(syscallname)				\
-static int syscallname##_syscall = SYS_##syscallname;		\
-static int syscallname##_registered;				\
-static struct sysent syscallname##_old_sysent;			\
-MAKE_SYSENT(syscallname);
-
-#define	SYSCALL_REGISTER(syscallname) do {				\
-	error = syscall_register(& syscallname##_syscall,		\
-	    & syscallname##_sysent, & syscallname##_old_sysent);	\
-	if (error)							\
-		return (error);						\
-	syscallname##_registered = 1;					\
-} while(0)
-
-#define	SYSCALL_DEREGISTER(syscallname) do {				\
-	if (syscallname##_registered) {					\
-		syscallname##_registered = 0;				\
-		syscall_deregister(& syscallname##_syscall,		\
-		    & syscallname##_old_sysent);			\
-	}								\
-} while(0)
-
-SYSCALL_DATA(ksem_init);
-SYSCALL_DATA(ksem_open);
-SYSCALL_DATA(ksem_unlink);
-SYSCALL_DATA(ksem_close);
-SYSCALL_DATA(ksem_post);
-SYSCALL_DATA(ksem_wait);
-SYSCALL_DATA(ksem_timedwait);
-SYSCALL_DATA(ksem_trywait);
-SYSCALL_DATA(ksem_getvalue);
-SYSCALL_DATA(ksem_destroy);
+static struct syscall_helper_data ksem_syscalls[] = {
+	SYSCALL_INIT_HELPER(ksem_init),
+	SYSCALL_INIT_HELPER(ksem_open),
+	SYSCALL_INIT_HELPER(ksem_unlink),
+	SYSCALL_INIT_HELPER(ksem_close),
+	SYSCALL_INIT_HELPER(ksem_post),
+	SYSCALL_INIT_HELPER(ksem_wait),
+	SYSCALL_INIT_HELPER(ksem_timedwait),
+	SYSCALL_INIT_HELPER(ksem_trywait),
+	SYSCALL_INIT_HELPER(ksem_getvalue),
+	SYSCALL_INIT_HELPER(ksem_destroy),
+	SYSCALL_INIT_LAST
+};
+
+#ifdef COMPAT_FREEBSD32
+#include <compat/freebsd32/freebsd32.h>
+#include <compat/freebsd32/freebsd32_proto.h>
+#include <compat/freebsd32/freebsd32_signal.h>
+#include <compat/freebsd32/freebsd32_syscall.h>
+#include <compat/freebsd32/freebsd32_util.h>
+
+int
+freebsd32_ksem_init(struct thread *td, struct freebsd32_ksem_init_args *uap)
+{
+
+	return (ksem_create(td, NULL, uap->idp, S_IRWXU | S_IRWXG, uap->value,
+	    0, 1));
+}
+
+int
+freebsd32_ksem_open(struct thread *td, struct freebsd32_ksem_open_args *uap)
+{
+
+	if ((uap->oflag & ~(O_CREAT | O_EXCL)) != 0)
+		return (EINVAL);
+	return (ksem_create(td, uap->name, uap->idp, uap->mode, uap->value,
+	    uap->oflag, 1));
+}
+
+int
+freebsd32_ksem_timedwait(struct thread *td,
+    struct freebsd32_ksem_timedwait_args *uap)
+{
+	struct timespec32 abstime32;
+	struct timespec *ts, abstime;
+	int error;
+
+	/*
+	 * We allow a null timespec (wait forever).
+	 */
+	if (uap->abstime == NULL)
+		ts = NULL;
+	else {
+		error = copyin(uap->abstime, &abstime32, sizeof(abstime32));
+		if (error != 0)
+			return (error);
+		CP(abstime32, abstime, tv_sec);
+		CP(abstime32, abstime, tv_nsec);
+		if (abstime.tv_nsec >= 1000000000 || abstime.tv_nsec < 0)
+			return (EINVAL);
+		ts = &abstime;
+	}
+	return (kern_sem_wait(td, uap->id, 0, ts));
+}
+
+static struct syscall_helper_data ksem32_syscalls[] = {
+	SYSCALL32_INIT_HELPER(freebsd32_ksem_init),
+	SYSCALL32_INIT_HELPER(freebsd32_ksem_open),
+	SYSCALL32_INIT_HELPER(ksem_unlink),
+	SYSCALL32_INIT_HELPER(ksem_close),
+	SYSCALL32_INIT_HELPER(ksem_post),
+	SYSCALL32_INIT_HELPER(ksem_wait),
+	SYSCALL32_INIT_HELPER(freebsd32_ksem_timedwait),
+	SYSCALL32_INIT_HELPER(ksem_trywait),
+	SYSCALL32_INIT_HELPER(ksem_getvalue),
+	SYSCALL32_INIT_HELPER(ksem_destroy),
+	SYSCALL_INIT_LAST
+};
+#endif
 
 static int
 ksem_module_init(void)
@@ -878,16 +953,14 @@ ksem_module_init(void)
 	p31b_setcfg(CTL_P1003_1B_SEM_NSEMS_MAX, SEM_MAX);
 	p31b_setcfg(CTL_P1003_1B_SEM_VALUE_MAX, SEM_VALUE_MAX);
 
-	SYSCALL_REGISTER(ksem_init);
-	SYSCALL_REGISTER(ksem_open);
-	SYSCALL_REGISTER(ksem_unlink);
-	SYSCALL_REGISTER(ksem_close);
-	SYSCALL_REGISTER(ksem_post);
-	SYSCALL_REGISTER(ksem_wait);
-	SYSCALL_REGISTER(ksem_timedwait);
-	SYSCALL_REGISTER(ksem_trywait);
-	SYSCALL_REGISTER(ksem_getvalue);
-	SYSCALL_REGISTER(ksem_destroy);
+	error = syscall_helper_register(ksem_syscalls);
+	if (error)
+		return (error);
+#ifdef COMPAT_FREEBSD32
+	error = syscall32_helper_register(ksem32_syscalls);
+	if (error)
+		return (error);
+#endif
 	return (0);
 }
 
@@ -895,16 +968,10 @@ static void
 ksem_module_destroy(void)
 {
 
-	SYSCALL_DEREGISTER(ksem_init);
-	SYSCALL_DEREGISTER(ksem_open);
-	SYSCALL_DEREGISTER(ksem_unlink);
-	SYSCALL_DEREGISTER(ksem_close);
-	SYSCALL_DEREGISTER(ksem_post);
-	SYSCALL_DEREGISTER(ksem_wait);
-	SYSCALL_DEREGISTER(ksem_timedwait);
-	SYSCALL_DEREGISTER(ksem_trywait);
-	SYSCALL_DEREGISTER(ksem_getvalue);
-	SYSCALL_DEREGISTER(ksem_destroy);
+#ifdef COMPAT_FREEBSD32
+	syscall32_helper_unregister(ksem32_syscalls);
+#endif
+	syscall_helper_unregister(ksem_syscalls);
 
 	hashdestroy(ksem_dictionary, M_KSEM, ksem_hash);
 	sx_destroy(&ksem_dict_lock);


More information about the svn-src-all mailing list