Date: Wed, 18 Apr 2007 12:19:10 -0500 From: "Scot Hetzel" <swhetzel@gmail.com> To: "Divacky Roman" <rdivacky@freebsd.org>, "Alexander Leidinger" <Alexander@leidinger.net> Cc: freebsd-emulation@freebsd.org Subject: Re: linuxolator: implement settimeofday call on FreeBSD/amd64 Message-ID: <790a9fff0704181019m37456143o36c82bd24f7dfe9c@mail.gmail.com> In-Reply-To: <20061219180156.GA87609@stud.fit.vutbr.cz> References: <790a9fff0612190922t1f4a3fa1m44092944485297f7@mail.gmail.com> <20061219180156.GA87609@stud.fit.vutbr.cz>
index | next in thread | previous in thread | raw e-mail
[-- Attachment #1 --]
On 12/19/06, Divacky Roman <xdivac02@stud.fit.vutbr.cz> wrote:
> On Tue, Dec 19, 2006 at 11:22:56AM -0600, Scot Hetzel wrote:
> > I noticed that the settimeofday call in the linuxolator is implemented
> > on FreeBSD/i386, but it is missing from FreeBSD/amd64. The attached
> > patch implements the function on FreeBSD/amd64.
>
> makes me wonder... what is MD on this code? I dont see anything
>
I finally figured out what is MD for the settimeofday call.
On FreeBSD/i386:
struct l_timeval = struct timeval
for FreeBSD/amd64
struct l_timeval < struct timeval
The reason for this difference is tv_sec is 32 bits on i386 and 64
bits on amd64.
amd64/include/_types.h:
typedef __int64_t __time_t; /* time()... */
i386/include/_types.h:
typedef __int32_t __time_t; /* time()... */
sys/_types.h:
typedef long __suseconds_t; /* microseconds (signed) */
sys/_timeval.h:
typedef __time_t time_t;
typedef __suseconds_t suseconds_t; /* microseconds (signed) */
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* and microseconds */
};
The reason we can't use freebsd's settimeofday call directly (as done
in the i386 linuxolator) in the linuxolator for amd64 is that the
freebsd settimeofday function uses copyin, and since the l_timeval
stuct is < timeval struct, it ends up copying the tv_usec value into
tv_sec.
Attached is the current patch to add the settimeofday call to the
linuxolator for amd64.
Scot
--
DISCLAIMER:
No electrons were mamed while sending this message. Only slightly bruised.
[-- Attachment #2 --]
diff -ru amd64/linux32/linux32_dummy.c.orig amd64/linux32/linux32_dummy.c
--- amd64/linux32/linux32_dummy.c.orig Fri Mar 30 10:25:23 2007
+++ amd64/linux32/linux32_dummy.c Sat Apr 14 02:06:22 2007
@@ -63,7 +63,6 @@
DUMMY(mincore);
DUMMY(fadvise64);
DUMMY(ptrace);
-DUMMY(settimeofday);
DUMMY(lookup_dcookie);
DUMMY(epoll_create);
DUMMY(epoll_ctl);
diff -ru amd64/linux32/linux32_machdep.c.orig amd64/linux32/linux32_machdep.c
--- amd64/linux32/linux32_machdep.c.orig Wed Apr 4 12:33:26 2007
+++ amd64/linux32/linux32_machdep.c Fri Mar 30 21:55:34 2007
@@ -526,7 +526,9 @@
td2 = FIRST_THREAD_IN_PROC(p2);
- /* make it run */
+ /*
+ * Make this runnable after we are finished with it.
+ */
mtx_lock_spin(&sched_lock);
TD_SET_CAN_RUN(td2);
sched_add(td2, SRQ_BORING);
@@ -572,8 +574,8 @@
/*
* XXX: In Linux, sharing of fs info (chroot/cwd/umask)
* and open files is independant. In FreeBSD, its in one
- * structure but in reality it does not make any problems
- * because both of these flags are set at once usually.
+ * structure but in reality it does not cause any problems
+ * because both of these flags are usually set together.
*/
if (!(args->flags & (LINUX_CLONE_FILES | LINUX_CLONE_FS)))
ff |= RFFDG;
@@ -660,15 +662,15 @@
if (args->flags & LINUX_CLONE_SETTLS) {
struct user_segment_descriptor sd;
struct l_user_desc info;
- int a[2];
+ int a[2];
- error = copyin((void *)td->td_frame->tf_rsi, &info,
+ error = copyin((void *)td->td_frame->tf_rsi, &info,
sizeof(struct l_user_desc));
if (error) {
printf(LMSG("copyin failed!"));
} else {
/* We might copy out the entry_number as GUGS32_SEL. */
- info.entry_number = GUGS32_SEL;
+ info.entry_number = GUGS32_SEL;
error = copyout(&info, (void *)td->td_frame->tf_rsi,
sizeof(struct l_user_desc));
if (error)
@@ -871,7 +873,7 @@
*
* Our mmap with MAP_STACK takes addr as the maximum
* downsize limit on BOS, and as len the max size of
- * the region. It them maps the top SGROWSIZ bytes,
+ * the region. It then maps the top SGROWSIZ bytes,
* and auto grows the region down, up to the limit
* in addr.
*
@@ -1178,6 +1180,33 @@
}
int
+linux_settimeofday(struct thread *td, struct linux_settimeofday_args *uap)
+{
+ l_timeval tv32;
+ struct timeval tv, *tvp;
+ struct timezone tz, *tzp;
+ int error;
+
+ if (uap->tp) {
+ error = copyin(uap->tp, &tv32, sizeof(tv32));
+ if (error)
+ return (error);
+ tv.tv_sec = tv32.tv_sec;
+ tv.tv_usec = tv32.tv_usec;
+ tvp = &tv;
+ } else
+ tvp = NULL;
+ if (uap->tzp) {
+ error = copyin(uap->tzp, &tz, sizeof(tz));
+ if (error)
+ return (error);
+ tzp = &tz;
+ } else
+ tzp = NULL;
+ return (kern_settimeofday(td, tvp, tzp));
+}
+
+int
linux_getrusage(struct thread *td, struct linux_getrusage_args *uap)
{
struct l_rusage s32;
@@ -1242,7 +1271,7 @@
#ifdef DEBUG
if (ldebug(set_thread_area))
- printf(ARGS(set_thread_area, "%i, %x, %x, %i, %i, %i, "
+ printf(ARGS(set_thread_area, "%i, %x, %x, %i, %i, %i, "
"%i, %i, %i"), info.entry_number, info.base_addr,
info.limit, info.seg_32bit, info.contents,
info.read_exec_only, info.limit_in_pages,
@@ -1261,9 +1290,10 @@
* The tls_array[] is used only in [gs]et_thread_area() syscalls and
* for loading the GDT descriptors. We use just one GDT descriptor
* for TLS, so we will load just one.
- * XXX: This doesnt work when user-space process tries to use more
+ *
+ * XXX: This doesn't work when a user space process tries to use more
* than one TLS segment. Comment in the Linux source says wine might
- * do that.
+ * do this.
*/
/*
@@ -1284,8 +1314,9 @@
/*
* We have to copy out the GDT entry we use.
- * XXX: What if userspace program does not check return value and
- * tries to use 6, 7 or 8?
+ *
+ * XXX: What if a user space program does not check the return value
+ * and tries to use 6, 7 or 8?
*/
error = copyout(&info, args->desc, sizeof(struct l_user_desc));
if (error)
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?790a9fff0704181019m37456143o36c82bd24f7dfe9c>
