Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F145619932
D6772.1778319181.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D6772.1778319181.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Sat, May 9, 9:33 AM (5 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28597120
Default Alt Text
D6772.1778319181.diff (8 KB)
Attached To
Mode
D6772: Linux ARM 15/16
Attached
Detach File
Event Timeline
Log In to Comment