patch-2.3.11 linux/include/asm-i386/desc.h

Next file: linux/include/asm-i386/hardirq.h
Previous file: linux/include/asm-arm/system.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.10/linux/include/asm-i386/desc.h linux/include/asm-i386/desc.h
@@ -1,6 +1,46 @@
 #ifndef __ARCH_DESC_H
 #define __ARCH_DESC_H
 
+#include <asm/ldt.h>
+
+/*
+ * The layout of the GDT under Linux:
+ *
+ *   0 - null
+ *   1 - not used
+ *   2 - kernel code segment
+ *   3 - kernel data segment
+ *   4 - user code segment                  <-- new cacheline 
+ *   5 - user data segment
+ *   6 - not used
+ *   7 - not used
+ *   8 - APM BIOS support                   <-- new cacheline 
+ *   9 - APM BIOS support
+ *  10 - APM BIOS support
+ *  11 - APM BIOS support
+ *
+ * The TSS+LDT descriptors are spread out a bit so that every CPU
+ * has an exclusive cacheline for the per-CPU TSS and LDT:
+ *
+ *  12 - CPU#0 TSS                          <-- new cacheline 
+ *  13 - CPU#0 LDT
+ *  14 - not used 
+ *  15 - not used 
+ *  16 - CPU#1 TSS                          <-- new cacheline 
+ *  17 - CPU#1 LDT
+ *  18 - not used 
+ *  19 - not used 
+ *  ... NR_CPUS per-CPU TSS+LDT's if on SMP
+ *
+ * Entry into gdt where to find first TSS.
+ */
+#define __FIRST_TSS_ENTRY 12
+#define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY+1)
+
+#define __TSS(n) (((n)<<2) + __FIRST_TSS_ENTRY)
+#define __LDT(n) (((n)<<2) + __FIRST_LDT_ENTRY)
+
+#ifndef __ASSEMBLY__
 struct desc_struct {
 	unsigned long a,b;
 };
@@ -16,46 +56,33 @@
 #define idt_descr (*(struct Xgt_desc_struct *)((char *)&idt - 2))
 #define gdt_descr (*(struct Xgt_desc_struct *)((char *)&gdt - 2))
 
+#define load_TR(n) __asm__ __volatile__("ltr %%ax"::"a" (__TSS(n)<<3))
+
+#define __load_LDT(n) __asm__ __volatile__("lldt %%ax"::"a" (__LDT(n)<<3))
+
 /*
- * Entry into gdt where to find first TSS. GDT layout:
- *   0 - null
- *   1 - not used
- *   2 - kernel code segment
- *   3 - kernel data segment
- *   4 - user code segment
- *   5 - user data segment
- *   6 - not used
- *   7 - not used
- *   8 - APM BIOS support
- *   9 - APM BIOS support
- *  10 - APM BIOS support
- *  11 - APM BIOS support
- *  12 - TSS #0
- *  13 - LDT #0
- *  14 - TSS #1
- *  15 - LDT #1
+ * This is the ldt that every process will get unless we need
+ * something other than this.
  */
-#define FIRST_TSS_ENTRY 12
-#define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1)
-#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3))
-#define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3))
-#define load_TR(n) __asm__ __volatile__("ltr %%ax": /* no output */ :"a" (_TSS(n)))
-#define load_ldt(n) __asm__ __volatile__("lldt %%ax": /* no output */ :"a" (_LDT(n)))
-#define store_TR(n) \
-__asm__("str %%ax\n\t" \
-	"subl %2,%%eax\n\t" \
-	"shrl $4,%%eax" \
-	:"=a" (n) \
-	:"0" (0),"i" (FIRST_TSS_ENTRY<<3))
-
+extern struct desc_struct default_ldt;
 extern void set_intr_gate(unsigned int irq, void * addr);
 extern void set_ldt_desc(unsigned int n, void *addr, unsigned int size);
 extern void set_tss_desc(unsigned int n, void *addr);
 
 /*
- * This is the ldt that every process will get unless we need
- * something other than this.
+ * load one particular LDT into the current CPU
  */
-extern struct desc_struct default_ldt;
+extern inline void load_LDT (struct mm_struct *mm)
+{
+	int cpu = smp_processor_id();
+
+	if (mm->segments)
+		set_ldt_desc(cpu, mm->segments, LDT_ENTRIES);
+	else
+		set_ldt_desc(cpu, &default_ldt, 1);
+	__load_LDT(cpu);
+}
+
+#endif /* !__ASSEMBLY__ */
 
 #endif

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)