Page MenuHomeFreeBSD

D6772.1778271740.diff
No OneTemporary

Size
8 KB
Referenced Files
None
Subscribers
None

D6772.1778271740.diff

Index: sys/arm/linux/linux_machdep.c
===================================================================
--- sys/arm/linux/linux_machdep.c
+++ sys/arm/linux/linux_machdep.c
@@ -256,6 +256,59 @@
return (linux_select(td, &newsel));
}
+struct timeval32 {
+ uint32_t tv_sec;
+ uint32_t tv_usec;
+};
+
+int
+linux_gettimeofday(struct thread *td, struct linux_gettimeofday_args *uap)
+{
+ struct timeval atv;
+ struct timeval32 atv32;
+ struct timezone rtz;
+ int error = 0;
+
+ if (uap->tp) {
+ microtime(&atv);
+ atv32.tv_sec = atv.tv_sec;
+ atv32.tv_usec = atv.tv_usec;
+ error = copyout(&atv32, uap->tp, sizeof(atv32));
+ }
+ if (error == 0 && uap->tzp != NULL) {
+ rtz.tz_minuteswest = tz_minuteswest;
+ rtz.tz_dsttime = tz_dsttime;
+ error = copyout(&rtz, uap->tzp, sizeof(rtz));
+ }
+ return (error);
+}
+
+int
+linux_settimeofday(struct thread *td, struct linux_settimeofday_args *uap)
+{
+ struct timeval32 atv32;
+ struct timeval atv, *tvp;
+ struct timezone atz, *tzp;
+ int error;
+
+ if (uap->tp) {
+ error = copyin(uap->tp, &atv32, sizeof(atv32));
+ if (error)
+ return (error);
+ atv.tv_sec = atv32.tv_sec;
+ atv.tv_usec = atv32.tv_usec;
+ tvp = &atv;
+ } else
+ tvp = NULL;
+ if (uap->tzp) {
+ error = copyin(uap->tzp, &atz, sizeof(atz));
+ if (error)
+ return (error);
+ tzp = &atz;
+ } else
+ tzp = NULL;
+ return (kern_settimeofday(td, tvp, tzp));
+}
int
linux_set_cloned_tls(struct thread *td, void *desc)
{
@@ -535,98 +588,6 @@
}
int
-linux_ioperm(struct thread *td, struct linux_ioperm_args *args)
-{
- int error;
- struct i386_ioperm_args iia;
-
- iia.start = args->start;
- iia.length = args->length;
- iia.enable = args->enable;
- error = i386_set_ioperm(td, &iia);
- return (error);
-}
-
-int
-linux_iopl(struct thread *td, struct linux_iopl_args *args)
-{
- int error;
-
- if (args->level < 0 || args->level > 3)
- return (EINVAL);
- if ((error = priv_check(td, PRIV_IO)) != 0)
- return (error);
- if ((error = securelevel_gt(td->td_ucred, 0)) != 0)
- return (error);
- td->td_frame->tf_eflags = (td->td_frame->tf_eflags & ~PSL_IOPL) |
- (args->level * (PSL_IOPL / 3));
- return (0);
-}
-
-int
-linux_modify_ldt(struct thread *td, struct linux_modify_ldt_args *uap)
-{
- int error;
- struct i386_ldt_args ldt;
- struct l_descriptor ld;
- union descriptor desc;
- int size, written;
-
- switch (uap->func) {
- case 0x00: /* read_ldt */
- ldt.start = 0;
- ldt.descs = uap->ptr;
- ldt.num = uap->bytecount / sizeof(union descriptor);
- error = i386_get_ldt(td, &ldt);
- td->td_retval[0] *= sizeof(union descriptor);
- break;
- case 0x02: /* read_default_ldt = 0 */
- size = 5*sizeof(struct l_desc_struct);
- if (size > uap->bytecount)
- size = uap->bytecount;
- for (written = error = 0; written < size && error == 0; written++)
- error = subyte((char *)uap->ptr + written, 0);
- td->td_retval[0] = written;
- break;
- case 0x01: /* write_ldt */
- case 0x11: /* write_ldt */
- if (uap->bytecount != sizeof(ld))
- return (EINVAL);
-
- error = copyin(uap->ptr, &ld, sizeof(ld));
- if (error)
- return (error);
-
- ldt.start = ld.entry_number;
- ldt.descs = &desc;
- ldt.num = 1;
- desc.sd.sd_lolimit = (ld.limit & 0x0000ffff);
- desc.sd.sd_hilimit = (ld.limit & 0x000f0000) >> 16;
- desc.sd.sd_lobase = (ld.base_addr & 0x00ffffff);
- desc.sd.sd_hibase = (ld.base_addr & 0xff000000) >> 24;
- desc.sd.sd_type = SDT_MEMRO | ((ld.read_exec_only ^ 1) << 1) |
- (ld.contents << 2);
- desc.sd.sd_dpl = 3;
- desc.sd.sd_p = (ld.seg_not_present ^ 1);
- desc.sd.sd_xx = 0;
- desc.sd.sd_def32 = ld.seg_32bit;
- desc.sd.sd_gran = ld.limit_in_pages;
- error = i386_set_ldt(td, &ldt, &desc);
- break;
- default:
- error = ENOSYS;
- break;
- }
-
- if (error == EOPNOTSUPP) {
- printf("linux: modify_ldt needs kernel option USER_LDT\n");
- error = ENOSYS;
- }
-
- return (error);
-}
-
-int
linux_sigaction(struct thread *td, struct linux_sigaction_args *args)
{
l_osigaction_t osa;
@@ -775,155 +736,6 @@
return sys_ftruncate(td, &sa);
}
-int
-linux_set_thread_area(struct thread *td, struct linux_set_thread_area_args *args)
-{
- struct l_user_desc info;
- int error;
- int idx;
- int a[2];
- struct segment_descriptor sd;
-
- error = copyin(args->desc, &info, sizeof(struct l_user_desc));
- if (error)
- return (error);
-
-#ifdef DEBUG
- if (ldebug(set_thread_area))
- printf(ARGS(set_thread_area, "%i, %x, %x, %i, %i, %i, %i, %i, %i\n"),
- info.entry_number,
- info.base_addr,
- info.limit,
- info.seg_32bit,
- info.contents,
- info.read_exec_only,
- info.limit_in_pages,
- info.seg_not_present,
- info.useable);
-#endif
-
- idx = info.entry_number;
- /*
- * Semantics of linux version: every thread in the system has array of
- * 3 tls descriptors. 1st is GLIBC TLS, 2nd is WINE, 3rd unknown. This
- * syscall loads one of the selected tls decriptors with a value and
- * also loads GDT descriptors 6, 7 and 8 with the content of the
- * per-thread descriptors.
- *
- * Semantics of fbsd version: I think we can ignore that linux has 3
- * per-thread descriptors and use just the 1st one. The tls_array[]
- * is used only in set/get-thread_area() syscalls and for loading the
- * GDT descriptors. In fbsd we use just one GDT descriptor for TLS so
- * we will load just one.
- *
- * XXX: this doesn't work when a user space process tries to use more
- * than 1 TLS segment. Comment in the linux sources says wine might do
- * this.
- */
-
- /*
- * we support just GLIBC TLS now
- * we should let 3 proceed as well because we use this segment so
- * if code does two subsequent calls it should succeed
- */
- if (idx != 6 && idx != -1 && idx != 3)
- return (EINVAL);
-
- /*
- * we have to copy out the GDT entry we use
- * FreeBSD uses GDT entry #3 for storing %gs so load that
- *
- * XXX: what if a user space program doesn't check this value and tries
- * to use 6, 7 or 8?
- */
- idx = info.entry_number = 3;
- error = copyout(&info, args->desc, sizeof(struct l_user_desc));
- if (error)
- return (error);
-
- if (LINUX_LDT_empty(&info)) {
- a[0] = 0;
- a[1] = 0;
- } else {
- a[0] = LINUX_LDT_entry_a(&info);
- a[1] = LINUX_LDT_entry_b(&info);
- }
-
- memcpy(&sd, &a, sizeof(a));
-#ifdef DEBUG
- if (ldebug(set_thread_area))
- printf("Segment created in set_thread_area: lobase: %x, hibase: %x, lolimit: %x, hilimit: %x, type: %i, dpl: %i, p: %i, xx: %i, def32: %i, gran: %i\n", sd.sd_lobase,
- sd.sd_hibase,
- sd.sd_lolimit,
- sd.sd_hilimit,
- sd.sd_type,
- sd.sd_dpl,
- sd.sd_p,
- sd.sd_xx,
- sd.sd_def32,
- sd.sd_gran);
-#endif
-
- /* this is taken from i386 version of cpu_set_user_tls() */
- critical_enter();
- /* set %gs */
- td->td_pcb->pcb_gsd = sd;
- PCPU_GET(fsgs_gdt)[1] = sd;
- load_gs(GSEL(GUGS_SEL, SEL_UPL));
- critical_exit();
-
- return (0);
-}
-
-int
-linux_get_thread_area(struct thread *td, struct linux_get_thread_area_args *args)
-{
-
- struct l_user_desc info;
- int error;
- int idx;
- struct l_desc_struct desc;
- struct segment_descriptor sd;
-
-#ifdef DEBUG
- if (ldebug(get_thread_area))
- printf(ARGS(get_thread_area, "%p"), args->desc);
-#endif
-
- error = copyin(args->desc, &info, sizeof(struct l_user_desc));
- if (error)
- return (error);
-
- idx = info.entry_number;
- /* XXX: I am not sure if we want 3 to be allowed too. */
- if (idx != 6 && idx != 3)
- return (EINVAL);
-
- idx = 3;
-
- memset(&info, 0, sizeof(info));
-
- sd = PCPU_GET(fsgs_gdt)[1];
-
- memcpy(&desc, &sd, sizeof(desc));
-
- info.entry_number = idx;
- info.base_addr = LINUX_GET_BASE(&desc);
- info.limit = LINUX_GET_LIMIT(&desc);
- info.seg_32bit = LINUX_GET_32BIT(&desc);
- info.contents = LINUX_GET_CONTENTS(&desc);
- info.read_exec_only = !LINUX_GET_WRITABLE(&desc);
- info.limit_in_pages = LINUX_GET_LIMIT_PAGES(&desc);
- info.seg_not_present = !LINUX_GET_PRESENT(&desc);
- info.useable = LINUX_GET_USEABLE(&desc);
-
- error = copyout(&info, args->desc, sizeof(struct l_user_desc));
- if (error)
- return (EFAULT);
-
- return (0);
-}
-
/* XXX: this wont work with module - convert it */
int
linux_mq_open(struct thread *td, struct linux_mq_open_args *args)
@@ -984,3 +796,14 @@
return (ENOSYS);
#endif
}
+
+int
+linux_set_tls(struct thread *td, struct linux_set_tls_args *args)
+{
+
+ td->td_md.md_tp = (register_t)args->tls;
+ // Do it ??
+ set_tls(args->tls);
+
+ return (0);
+}
\ No newline at end of file

File Metadata

Mime Type
text/plain
Expires
Fri, May 8, 8:22 PM (2 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28597120
Default Alt Text
D6772.1778271740.diff (8 KB)

Event Timeline