? autom4te.cache
Index: ChangeLog
===================================================================
RCS file: /cvsroot/hurd/gnumach/ChangeLog,v
retrieving revision 1.128.2.159
diff -u -r1.128.2.159 ChangeLog
--- ChangeLog	4 Nov 2006 23:32:21 -0000	1.128.2.159
+++ ChangeLog	5 Nov 2006 02:15:05 -0000
@@ -1,3 +1,17 @@
+2006-11-04  Barry deFreese  <bddebian@comcast.net>
+
+        * [Savannah task 5878] Port i386_{set,get}_gdt from gnumach-2 branch
+        Written by Roland McGrath
+        * i386/include/mach/i386/mach_i386.defs (i386_set_gdt, i386_get_gdt):
+        New routines.
+        * i386/i386/user_ldt.c (i386_set_gdt, i386_get_gdt): New functions.
+        * i386/i386/gdt.h (USER_GDT, USER_GDT_SLOTS): New macros.
+		Recalculate GDTSZ
+        * i386/i386/thread.h (struct i386_machine_state): New member user_gdt.
+		Include gdt.h
+        * i386/i386/pcb.c (switch_ktss): Copy those slots into the GDT.
+        * Thanks to Samuel Thibault for fix ups and testing!
+
 2006-11-05  Samuel Thibault  <samuel.thibault@ens-lyon.org>
 
 	Drop PS2 architecture support.
Index: i386/i386/gdt.h
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386/gdt.h,v
retrieving revision 1.2.2.1
diff -u -r1.2.2.1 gdt.h
--- i386/i386/gdt.h	4 Nov 2006 23:32:21 -0000	1.2.2.1
+++ i386/i386/gdt.h	5 Nov 2006 02:15:25 -0000
@@ -49,8 +49,9 @@
 #define	USER_FPREGS	0x40		/* user-mode access to saved
 					   floating-point registers */
 
-#define	GDTSZ		11
-
+#define USER_GDT	0x48
+#define USER_GDT_SLOTS 2
+#define	GDTSZ		(USER_GDT/8 + USER_GDT_SLOTS)
 
 extern struct real_descriptor gdt[GDTSZ];
 
Index: i386/i386/pcb.c
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386/pcb.c,v
retrieving revision 1.2.4.1
diff -u -r1.2.4.1 pcb.c
--- i386/i386/pcb.c	15 Oct 2006 14:59:03 -0000	1.2.4.1
+++ i386/i386/pcb.c	5 Nov 2006 02:15:25 -0000
@@ -189,6 +189,13 @@
 	    set_ldt(USER_LDT);
 	}
     }
+
+    /* Copy in the per-thread GDT slots.  No reloading is necessary
+       because just restoring the segment registers on the way back to
+       user mode reloads the shadow registers from the in-memory GDT.  */
+    memcpy (gdt_desc_p (mycpu, USER_GDT),
+        pcb->ims.user_gdt, sizeof pcb->ims.user_gdt);
+
 	/*
 	 * Load the floating-point context, if necessary.
 	 */
Index: i386/i386/thread.h
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386/thread.h,v
retrieving revision 1.3
diff -u -r1.3 thread.h
--- i386/i386/thread.h	5 Apr 2001 06:39:20 -0000	1.3
+++ i386/i386/thread.h	5 Nov 2006 02:15:25 -0000
@@ -41,6 +41,7 @@
 
 #include <i386/iopb.h>
 #include <i386/tss.h>
+#include "gdt.h"
 
 /*
  *	i386_saved_state:
@@ -161,6 +162,7 @@
 	struct user_ldt	*	ldt;
 	struct i386_fpsave_state *ifps;
 	struct v86_assist_state	v86s;
+	struct real_descriptor user_gdt[USER_GDT_SLOTS];
 };
 
 typedef struct pcb {
Index: i386/i386/user_ldt.c
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386/user_ldt.c,v
retrieving revision 1.2.4.1
diff -u -r1.2.4.1 user_ldt.c
--- i386/i386/user_ldt.c	26 Jan 2006 14:53:56 -0000	1.2.4.1
+++ i386/i386/user_ldt.c	5 Nov 2006 02:15:25 -0000
@@ -399,3 +399,57 @@
 		user_ldt->desc.limit_low + 1
 		+ sizeof(struct real_descriptor));
 }
+
+
+kern_return_t
+i386_set_gdt (thread_t thread, int *selector, struct real_descriptor desc)
+{
+  int idx;
+
+  if (thread == THREAD_NULL)
+    return KERN_INVALID_ARGUMENT;
+
+  if (*selector == -1)
+    {
+      for (idx = 0; idx < USER_GDT_SLOTS; ++idx)
+        if ((thread->pcb->ims.user_gdt[idx].access & ACC_P) == 0)
+          {
+            *selector = ((idx + sel_idx(USER_GDT)) << 3) | SEL_PL_U;
+            break;
+          }
+      if (idx == USER_GDT_SLOTS)
+        return KERN_NO_SPACE;   /* ? */
+    }
+  else if ((*selector & (SEL_LDT|SEL_PL)) != SEL_PL_U
+           || sel_idx (*selector) < sel_idx(USER_GDT)
+           || sel_idx (*selector) >= sel_idx(USER_GDT) + USER_GDT_SLOTS)
+    return KERN_INVALID_ARGUMENT;
+  else
+    idx = sel_idx (*selector) - sel_idx(USER_GDT);
+
+  if ((desc.access & ACC_P) == 0)
+    memset (&thread->pcb->ims.user_gdt[idx], 0,
+            sizeof thread->pcb->ims.user_gdt[idx]);
+  else if ((desc.access & (ACC_TYPE_USER|ACC_PL)) != (ACC_TYPE_USER|ACC_PL_U))
+    return KERN_INVALID_ARGUMENT;
+  else
+    thread->pcb->ims.user_gdt[idx] = desc;
+
+  return KERN_SUCCESS;
+}
+
+kern_return_t
+i386_get_gdt (thread_t thread, int selector, struct real_descriptor *desc)
+{
+  if (thread == THREAD_NULL)
+    return KERN_INVALID_ARGUMENT;
+
+  if ((selector & (SEL_LDT|SEL_PL)) != SEL_PL_U
+      || sel_idx (selector) < sel_idx(USER_GDT)
+      || sel_idx (selector) >= sel_idx(USER_GDT) + USER_GDT_SLOTS)
+    return KERN_INVALID_ARGUMENT;
+
+  *desc = thread->pcb->ims.user_gdt[sel_idx (selector) - sel_idx(USER_GDT)];
+
+  return KERN_SUCCESS;
+}
Index: i386/include/mach/i386/mach_i386.defs
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/include/mach/i386/mach_i386.defs,v
retrieving revision 1.2
diff -u -r1.2 mach_i386.defs
--- i386/include/mach/i386/mach_i386.defs	5 Apr 2001 06:39:21 -0000	1.2
+++ i386/include/mach/i386/mach_i386.defs	5 Nov 2006 02:15:25 -0000
@@ -66,3 +66,19 @@
 		first_selector	: int;
 		selector_count	: int;
 	out	desc_list	: descriptor_list_t);
+
+/* Modify one of a few available thread-specific segment descriptor slots.
+   The SELECTOR must be a value from a previous call (on any thread),
+   or -1 to allocate an available slot and return the segment selector for it.
+   These slots are copied into the CPU on each thread switch.
+   Returns KERN_NO_SPACE when there are no more slots available.  */
+routine i386_set_gdt(
+                target_thread   : thread_t;
+        inout   selector        : int;
+                desc            : descriptor_t);
+
+/* Fetch a segment descriptor set with a prior i386_set_gdt call.  */
+routine i386_get_gdt(
+                target_thread   : thread_t;
+                selector        : int;
+        out     desc            : descriptor_t);
Index: linux/src/include/linux/head.h
===================================================================
RCS file: /cvsroot/hurd/gnumach/linux/src/include/linux/Attic/head.h,v
retrieving revision 1.1
diff -u -r1.1 head.h
--- linux/src/include/linux/head.h	26 Apr 1999 05:56:28 -0000	1.1
+++ linux/src/include/linux/head.h	5 Nov 2006 02:15:27 -0000
@@ -5,7 +5,10 @@
 	unsigned long a,b;
 } desc_table[256];
 
-extern desc_table idt,gdt;
+/* XXX Linux code shouldn't use idt/gdt directly */
+/*
+ * extern desc_table idt,gdt;
+ */
 
 #define GDT_NUL 0
 #define GDT_CODE 1
