[Openmcl-cvs-notifications] r10727 - /trunk/source/lisp-kernel/thread_manager.c
gb at clozure.com
gb at clozure.com
Sat Sep 13 03:12:19 EDT 2008
Author: gb
Date: Sat Sep 13 03:12:18 2008
New Revision: 10727
Log:
Provide LDT setup/free stuff for ia32 Linux.
Modified:
trunk/source/lisp-kernel/thread_manager.c
Modified: trunk/source/lisp-kernel/thread_manager.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/source/lisp-kernel/thread_manager.c (original)
+++ trunk/source/lisp-kernel/thread_manager.c Sat Sep 13 03:12:18 2008
@@ -867,6 +867,88 @@
perror("i386_set_ldt");
tcr->ldt_selector =3D NULL_SEL;
}
+#endif
+
+#ifdef LINUX
+
+#include <asm/ldt.h>
+#include <sys/syscall.h>
+
+/* see desc_struct in kernel/include/asm-i386/processor.h */
+typedef struct {
+ uint32_t a;
+ uint32_t b;
+} linux_desc_struct;
+
+
+#define desc_avail(d) (((d)->a) =3D=3D 0)
+
+linux_desc_struct linux_ldt_entries[LDT_ENTRIES];
+
+/* We have to ask the Linux kernel for a copy of the ldt table
+ and manage it ourselves. It's not clear that this is =
+ thread-safe in general, but we can at least ensure that
+ it's thread-safe wrt lisp threads. */
+
+pthread_mutex_t ldt_lock =3D PTHREAD_MUTEX_INITIALIZER; /* simple, non-re=
cursive mutex */
+
+int
+modify_ldt(int func, void *ptr, unsigned long bytecount)
+{
+ return syscall(__NR_modify_ldt, func, ptr, bytecount);
+}
+
+
+void
+setup_tcr_extra_segment(TCR *tcr)
+{
+ int i, n;
+ short sel;
+ struct user_desc u =3D {1, 0, 0, 1, MODIFY_LDT_CONTENTS_DATA, 0, 0, 0, 1=
};
+ linux_desc_struct *d =3D linux_ldt_entries;
+
+ pthread_mutex_lock(&ldt_lock);
+ n =3D modify_ldt(0,d,LDT_ENTRIES*LDT_ENTRY_SIZE)/LDT_ENTRY_SIZE;
+ for (i =3D 0; i < n; i++,d++) {
+ if (desc_avail(d)) {
+ break;
+ }
+ }
+ if (i =3D=3D LDT_ENTRIES) {
+ pthread_mutex_unlock(&ldt_lock);
+ fprintf(stderr, "All 8192 ldt entries in use ?\n");
+ _exit(1);
+ }
+ u.entry_number =3D i;
+ u.base_addr =3D (uint32_t)tcr;
+ u.limit =3D sizeof(tcr);
+ u.limit_in_pages =3D 0;
+ if (modify_ldt(1,&u,sizeof(struct user_desc)) !=3D 0) {
+ pthread_mutex_unlock(&ldt_lock);
+ fprintf(stderr,"Can't assign LDT entry\n");
+ _exit(1);
+ }
+ sel =3D (i << 3) | 7;
+ tcr->ldt_selector =3D sel;
+ pthread_mutex_unlock(&ldt_lock);
+}
+
+void
+free_tcr_extra_segment(TCR *tcr)
+{
+ struct user_desc u =3D {0, 0, 0, 0, MODIFY_LDT_CONTENTS_DATA, 0, 0, 0, 0=
};
+ short sel =3D tcr->ldt_selector;
+
+ pthread_mutex_lock(&ldt_lock);
+ /* load %fs with null segement selector */
+ __asm__ volatile ("mov %0,%%fs" : : "r"(0));
+ tcr->ldt_selector =3D 0;
+ u.entry_number =3D (sel>>3);
+ modify_ldt(1,&u,sizeof(struct user_desc));
+ pthread_mutex_unlock(&ldt_lock);
+ =
+}
+
#endif
=
#ifdef WINDOWS
More information about the Openmcl-cvs-notifications
mailing list