Skip to contentSkip to conversation

5/8 Move descriptor table management into the sub-arch layer

PATCH In review Zachary Amsden 3 participants 4 messages Aug 6, 2005 – Aug 8, 2005

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 5/8 Move descriptor table management into the sub-arch layer

i386 Transparent paravirtualization subarch patch #5

This change encapsulates descriptor and task register management.

Diffs against: 2.6.13-rc4-mm1

include/asm-i386/desc.h +1 -41
Index: linux-2.6.13/include/asm-i386/desc.h
===================================================================
@@ -27,19 +27,6 @@
 
 extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
 
-#define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8))
-#define load_LDT_desc() __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8))
-
-#define load_gdt(dtr) __asm__ __volatile("lgdt %0"::"m" (*dtr))
-#define load_idt(dtr) __asm__ __volatile("lidt %0"::"m" (*dtr))
-#define load_tr(tr) __asm__ __volatile("ltr %0"::"mr" (tr))
-#define load_ldt(ldt) __asm__ __volatile("lldt %0"::"mr" (ldt))
-
-#define store_gdt(dtr) __asm__ ("sgdt %0":"=m" (*dtr))
-#define store_idt(dtr) __asm__ ("sidt %0":"=m" (*dtr))
-#define store_tr(tr) __asm__ ("str %0":"=mr" (tr))
-#define store_ldt(ldt) __asm__ ("sldt %0":"=mr" (ldt))
-
 /*
  * This is the ldt that every process will get unless we need
  * something other than this.
@@ -58,19 +45,10 @@
 	"rorl $16,%1" \
 	: "=m"(*(n)) : "q" (addr), "r"(n), "ir"(limit), "i"(type))
 
-static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
-{
-	_set_tssldt_desc(&per_cpu(cpu_gdt_table, cpu)[entry], (int)addr,
-		offsetof(struct tss_struct, __cacheline_filler) - 1, 0x89);
-}
+#include <mach_desc.h>
 
 #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
 
-static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
-{
-	_set_tssldt_desc(&per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
-}
-
 #define LDT_entry_a(info) \
 	((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
 
@@ -96,24 +74,6 @@
 	(info)->seg_not_present	== 1	&& \
 	(info)->useable		== 0	)
 
-static inline void write_ldt_entry(void *ldt, int entry, __u32 entry_a, __u32 entry_b)
-{
-	__u32 *lp = (__u32 *)((char *)ldt + entry*8);
-	*lp = entry_a;
-	*(lp+1) = entry_b;
-}
-
-#if TLS_SIZE != 24
-# error update this code.
-#endif
-
-static inline void load_TLS(struct thread_struct *t, unsigned int cpu)
-{
-#define C(i) per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]
-	C(0); C(1); C(2);
-#undef C
-}
-
 static inline void clear_LDT(void)
 {
 	int cpu = get_cpu();
include/asm-i386/mach-default/mach_desc.h +83 -0

83 lines not on this page · raw message

#1 lore raw
Quoted 1 line · * Zachary Amsden ([email protected]) wrote:

This change encapsulates descriptor and task register management.

These will need some merging together, will take a stab tomorrow.

include/asm-i386/desc.h +2 -52
@@ -14,9 +14,6 @@
 
 #include <asm/mmu.h>
 
-extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
-DECLARE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);
-
 DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
 
 struct Xgt_desc_struct {
@@ -37,30 +34,16 @@ extern struct Xgt_desc_struct idt_descr,
 extern struct desc_struct default_ldt[];
 extern void set_intr_gate(unsigned int irq, void * addr);
 
-#define _set_tssldt_desc(n,addr,limit,type) \
-__asm__ __volatile__ ("movw %w3,0(%2)\n\t" \
-	"movw %%ax,2(%2)\n\t" \
-	"rorl $16,%%eax\n\t" \
-	"movb %%al,4(%2)\n\t" \
-	"movb %4,5(%2)\n\t" \
-	"movb $0,6(%2)\n\t" \
-	"movb %%ah,7(%2)\n\t" \
-	"rorl $16,%%eax" \
-	: "=m"(*(n)) : "a" (addr), "r"(n), "ir"(limit), "i"(type))
+#include <mach_desc.h>
 
 static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
 {
-	_set_tssldt_desc(&per_cpu(cpu_gdt_table, cpu)[entry], (int)addr,
+	_set_tssldt_desc(&get_cpu_gdt_table(cpu)[entry], (int)addr,
 		offsetof(struct tss_struct, __cacheline_filler) - 1, 0x89);
 }
 
 #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
 
-static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
-{
-	_set_tssldt_desc(&per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
-}
-
 #define LDT_entry_a(info) \
 	((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
 
@@ -90,39 +73,6 @@ static inline void set_ldt_desc(unsigned
 # error update this code.
 #endif
 
-static inline void load_TLS(struct thread_struct *t, unsigned int cpu)
-{
-#define C(i) per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]
-	C(0); C(1); C(2);
-#undef C
-}
-
-static inline void clear_LDT(void)
-{
-	int cpu = get_cpu();
-
-	set_ldt_desc(cpu, &default_ldt[0], 5);
-	load_LDT_desc();
-	put_cpu();
-}
-
-/*
- * load one particular LDT into the current CPU
- */
-static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
-{
-	void *segments = pc->ldt;
-	int count = pc->size;
-
-	if (likely(!count)) {
-		segments = &default_ldt[0];
-		count = 5;
-	}
-		
-	set_ldt_desc(cpu, segments, count);
-	load_LDT_desc();
-}
-
 static inline void load_LDT(mm_context_t *pc)
 {
 	int cpu = get_cpu();
include/asm-i386/mach-default/mach_desc.h new file +57 -0

57 lines not on this page · raw message

#2 lore raw
Quoted 13 lines · Chris Wright
Quoted 3 lines · * Zachary Amsden ([email protected]) wrote:

This change encapsulates descriptor and task register management.

These will need some merging together, will take a stab tomorrow.

include/asm-i386/desc.h line 19

Quoted 7 lines
include/asm-i386/desc.h +1 -1
@@ -14,9 +14,6 @@
 
 static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
 {
-	_set_tssldt_desc(&per_cpu(cpu_gdt_table, cpu)[entry], (int)addr,
+	_set_tssldt_desc(&get_cpu_gdt_table(cpu)[entry], (int)addr,
 
 

What is Xen doing for the GDT on SMP? Does Xen have 16 pages of GDT per CPU?

Quoted 11 lines
include/asm-i386/desc.h +8 -0
+++ linux-2.6.12-xen0-arch/include/asm-i386/mach-default/mach_desc.h
@@ -0,0 +1,57 @@
+#ifndef __ASM_MACH_DESC_H
+#define __ASM_MACH_DESC_H
+
+extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
+DECLARE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);
+#define get_cpu_gdt_table(_cpu) per_cpu(cpu_gdt_table, cpu)
+

include/asm-i386/desc.h line 17

Quoted 10 lines
include/asm-i386/desc.h +10 -0
+#define _set_tssldt_desc(n,addr,limit,type) \
+__asm__ __volatile__ ("movw %w3,0(%2)\n\t" \
+	"movw %%ax,2(%2)\n\t" \
+	"rorl $16,%%eax\n\t" \
+	"movb %%al,4(%2)\n\t" \
+	"movb %4,5(%2)\n\t" \
+	"movb $0,6(%2)\n\t" \
+	"movb %%ah,7(%2)\n\t" \
+	"rorl $16,%%eax" \
+	: "=m"(*(n)) : "a" (addr), "r"(n), "ir"(limit), "i"(type))

This actually doesn't need to move into sub-arch. You can redefine the call sites (set_ldt_desc / set_tss_desc) to operate on stack (implicit register) values instead and then notify the hypervisor about GDT updates. Course, which way is cleaner looks still TBD.

Quoted 19 lines
include/asm-i386/desc.h +17 -0
+static inline void clear_LDT(void)
+{
+	int cpu = get_cpu();
+
+	set_ldt_desc(cpu, &default_ldt[0], 5);
+	load_LDT_desc();
+	put_cpu();
+}
+
+/*
+ * load one particular LDT into the current CPU
+ */
+static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
+{
+	void *segments = pc->ldt;
+	int count = pc->size;
+

include/asm-i386/desc.h line 44

Quoted 10 lines
include/asm-i386/desc.h +10 -0
+	if (likely(!count)) {
+		segments = &default_ldt[0];
+		count = 5;
+	}
+		
+	set_ldt_desc(cpu, segments, count);
+	load_LDT_desc();
+}
+
+#endif

These two don't actually need to move into sub-arch ; they can call functions that have already moved.

So far looks like we are pretty much on the same page, with mostly cosmetic differences.

Zach

#3 lore raw
In reply to Zachary Amsden

Hi!

Quoted 12 lines

i386 Transparent paravirtualization subarch patch #5

This change encapsulates descriptor and task register management.

Diffs against: 2.6.13-rc4-mm1

Index: linux-2.6.13/include/asm-i386/desc.h
===================================================================

include/asm-i386/desc.h line 31

Quoted 5 lines
include/asm-i386/desc.h +0 -2
@@ -27,19 +27,6 @@
 
 extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
 
-#define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8))
-#define load_LDT_desc() __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8))

Is not asm volatile (no underscores) enough?

include/asm-i386/desc.h line 34

Quoted 2 lines
include/asm-i386/desc.h +0 -2
-#define load_gdt(dtr) __asm__ __volatile("lgdt %0"::"m" (*dtr))
-#define load_idt(dtr) __asm__ __volatile("lidt %0"::"m" (*dtr))

Eh, I think volatile should be either "volatile" or "__volatile__", but you not "__volatile".

Signature · 1 line
if you have sharp zaurus hardware you don't need... you know my address