linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Use descriptor's functions instead of inline assembly
@ 2007-07-20 13:56 Glauber de Oliveira Costa
  2007-07-20 14:23 ` Frederik Deweerdt
  2007-07-21 16:03 ` Jan Engelhardt
  0 siblings, 2 replies; 7+ messages in thread
From: Glauber de Oliveira Costa @ 2007-07-20 13:56 UTC (permalink / raw)
  To: linux-kernel, akpm, ak

This patch provides a new set of functions for managing the descriptor
tables that can be used instead of putting the raw assembly in .c files.
    
Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com>

diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c
index 6c34bdd..dde41d7 100644
--- a/arch/x86_64/kernel/head64.c
+++ b/arch/x86_64/kernel/head64.c
@@ -70,7 +70,7 @@ void __init x86_64_start_kernel(char * real_mode_data)
 
 	for (i = 0; i < IDT_ENTRIES; i++)
 		set_intr_gate(i, early_idt_handler);
-	asm volatile("lidt %0" :: "m" (idt_descr));
+	load_idt((const struct desc_ptr *)&idt_descr);
 
 	early_printk("Kernel alive\n");
 
diff --git a/arch/x86_64/kernel/reboot.c b/arch/x86_64/kernel/reboot.c
index 7503068..7c50a12 100644
--- a/arch/x86_64/kernel/reboot.c
+++ b/arch/x86_64/kernel/reboot.c
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 #include <asm/io.h>
 #include <asm/delay.h>
+#include <asm/desc.h>
 #include <asm/hw_irq.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -132,7 +133,7 @@ void machine_emergency_restart(void)
 		}
 
 		case BOOT_TRIPLE: 
-			__asm__ __volatile__("lidt (%0)": :"r" (&no_idt));
+			load_idt((const struct desc_ptr *)&no_idt);
 			__asm__ __volatile__("int3");
 
 			reboot_type = BOOT_KBD;
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
index 1200aaa..fef7290 100644
--- a/arch/x86_64/kernel/setup64.c
+++ b/arch/x86_64/kernel/setup64.c
@@ -224,8 +224,8 @@ void __cpuinit cpu_init (void)
  		memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE);
 
 	cpu_gdt_descr[cpu].size = GDT_SIZE;
-	asm volatile("lgdt %0" :: "m" (cpu_gdt_descr[cpu]));
-	asm volatile("lidt %0" :: "m" (idt_descr));
+	load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
+	load_idt((const struct desc_ptr *)&idt_descr);
 
 	memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
 	syscall_init();
diff --git a/arch/x86_64/kernel/suspend.c b/arch/x86_64/kernel/suspend.c
index b39d478..65e6720 100644
--- a/arch/x86_64/kernel/suspend.c
+++ b/arch/x86_64/kernel/suspend.c
@@ -32,9 +32,9 @@ void __save_processor_state(struct saved_context *ctxt)
 	/*
 	 * descriptor tables
 	 */
-	asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit));
-	asm volatile ("sidt %0" : "=m" (ctxt->idt_limit));
-	asm volatile ("str %0"  : "=m" (ctxt->tr));
+	store_gdt((struct desc_ptr *)&ctxt->gdt_limit);
+	store_idt((struct desc_ptr *)&ctxt->idt_limit);
+	ctxt->tr = store_tr();
 
 	/* XMM0..XMM15 should be handled by kernel_fpu_begin(). */
 	/*
@@ -91,8 +91,9 @@ void __restore_processor_state(struct saved_context *ctxt)
 	 * now restore the descriptor tables to their proper values
 	 * ltr is done i fix_processor_context().
 	 */
-	asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit));
-	asm volatile ("lidt %0" :: "m" (ctxt->idt_limit));
+	load_gdt((const struct desc_ptr *)&ctxt->gdt_limit);
+	load_idt((const struct desc_ptr *)&ctxt->idt_limit);
+	
 
 	/*
 	 * segment registers
diff --git a/include/asm-x86_64/desc.h b/include/asm-x86_64/desc.h
index ac991b5..4d58b3c 100644
--- a/include/asm-x86_64/desc.h
+++ b/include/asm-x86_64/desc.h
@@ -20,6 +20,13 @@ extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
 #define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8))
 #define clear_LDT()  asm volatile("lldt %w0"::"r" (0))
 
+static inline unsigned long store_tr(void)
+{
+       unsigned long tr;
+       asm volatile ("str %w0":"=r" (tr));
+       return tr;
+}
+
 /*
  * This is the ldt that every process will get unless we need
  * something other than this.
@@ -31,6 +38,16 @@ extern struct desc_ptr cpu_gdt_descr[];
 /* the cpu gdt accessor */
 #define cpu_gdt(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address)
 
+static inline void load_gdt(const struct desc_ptr *ptr)
+{
+	asm volatile("lgdt %w0"::"m" (*ptr));
+}
+
+static inline void store_gdt(struct desc_ptr *ptr)
+{
+       asm ("sgdt %w0":"=m" (*ptr));
+}
+
 static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist)  
 {
 	struct gate_struct s; 	
@@ -71,6 +88,16 @@ static inline void set_system_gate_ist(int nr, void *func, unsigned ist)
 	_set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, ist);
 }
 
+static inline void load_idt(const struct desc_ptr *ptr)
+{
+	asm volatile("lidt %w0"::"m" (*ptr));
+}
+
+static inline void store_idt(struct desc_ptr *dtr)
+{
+       asm ("sidt %w0":"=m" (*dtr));
+}
+
 static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, unsigned type, 
 					 unsigned size) 
 { 



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] Use descriptor's functions instead of inline assembly
  2007-07-20 13:56 [PATCH] Use descriptor's functions instead of inline assembly Glauber de Oliveira Costa
@ 2007-07-20 14:23 ` Frederik Deweerdt
  2007-07-20 15:14   ` Glauber de Oliveira Costa
  2007-07-20 23:05   ` Brian Gerst
  2007-07-21 16:03 ` Jan Engelhardt
  1 sibling, 2 replies; 7+ messages in thread
From: Frederik Deweerdt @ 2007-07-20 14:23 UTC (permalink / raw)
  To: Glauber de Oliveira Costa; +Cc: linux-kernel, akpm, ak

On Fri, Jul 20, 2007 at 10:56:01AM -0300, Glauber de Oliveira Costa wrote:
> This patch provides a new set of functions for managing the descriptor
> tables that can be used instead of putting the raw assembly in .c files.
>     
> Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com>
> 
> -	asm volatile ("str %0"  : "=m" (ctxt->tr));
> +	store_gdt((struct desc_ptr *)&ctxt->gdt_limit);
> +	store_idt((struct desc_ptr *)&ctxt->idt_limit);
> +	ctxt->tr = store_tr();
>  
Would'nt a store_tr(&ctxt->tr) be more homogeneous here?

Regards,
Frederik

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Use descriptor's functions instead of inline assembly
  2007-07-20 14:23 ` Frederik Deweerdt
@ 2007-07-20 15:14   ` Glauber de Oliveira Costa
  2007-07-20 23:05   ` Brian Gerst
  1 sibling, 0 replies; 7+ messages in thread
From: Glauber de Oliveira Costa @ 2007-07-20 15:14 UTC (permalink / raw)
  To: Frederik Deweerdt; +Cc: linux-kernel, akpm, ak

On Fri, 2007-07-20 at 16:23 +0200, Frederik Deweerdt wrote:
> On Fri, Jul 20, 2007 at 10:56:01AM -0300, Glauber de Oliveira Costa wrote:
> > This patch provides a new set of functions for managing the descriptor
> > tables that can be used instead of putting the raw assembly in .c files.
> >     
> > Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com>
> > 
> > -	asm volatile ("str %0"  : "=m" (ctxt->tr));
> > +	store_gdt((struct desc_ptr *)&ctxt->gdt_limit);
> > +	store_idt((struct desc_ptr *)&ctxt->idt_limit);
> > +	ctxt->tr = store_tr();
> > 
> Would'nt a store_tr(&ctxt->tr) be more homogeneous here?
Indeed, it would. The main reason I let it this way was to keep it closer to
the i386 paravirt code (which is the main reason I'm sending this
patches - to pave the way for the x86_64 one), but they seem to be
getting an argument for store_tr in current tree. So there's no arguable
advantage on doing it my way at all ;-)

Thanks


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Use descriptor's functions instead of inline assembly
  2007-07-20 14:23 ` Frederik Deweerdt
  2007-07-20 15:14   ` Glauber de Oliveira Costa
@ 2007-07-20 23:05   ` Brian Gerst
  1 sibling, 0 replies; 7+ messages in thread
From: Brian Gerst @ 2007-07-20 23:05 UTC (permalink / raw)
  To: Frederik Deweerdt; +Cc: Glauber de Oliveira Costa, linux-kernel, akpm, ak

Frederik Deweerdt wrote:
> On Fri, Jul 20, 2007 at 10:56:01AM -0300, Glauber de Oliveira Costa wrote:
>> This patch provides a new set of functions for managing the descriptor
>> tables that can be used instead of putting the raw assembly in .c files.
>>     
>> Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com>
>>
>> -	asm volatile ("str %0"  : "=m" (ctxt->tr));
>> +	store_gdt((struct desc_ptr *)&ctxt->gdt_limit);
>> +	store_idt((struct desc_ptr *)&ctxt->idt_limit);
>> +	ctxt->tr = store_tr();
>>  
> Would'nt a store_tr(&ctxt->tr) be more homogeneous here?

Not really.  The task register is a segment number (a simple integer),
while the sidt/sgdt instructions write the cached descriptor to memory.

--
				Brian Gerst

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Use descriptor's functions instead of inline assembly
  2007-07-20 13:56 [PATCH] Use descriptor's functions instead of inline assembly Glauber de Oliveira Costa
  2007-07-20 14:23 ` Frederik Deweerdt
@ 2007-07-21 16:03 ` Jan Engelhardt
  1 sibling, 0 replies; 7+ messages in thread
From: Jan Engelhardt @ 2007-07-21 16:03 UTC (permalink / raw)
  To: Glauber de Oliveira Costa; +Cc: linux-kernel, akpm, ak


On Jul 20 2007 10:56, Glauber de Oliveira Costa wrote:
>diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c
>index 6c34bdd..dde41d7 100644
>--- a/arch/x86_64/kernel/head64.c
>+++ b/arch/x86_64/kernel/head64.c
>@@ -70,7 +70,7 @@ void __init x86_64_start_kernel(char * real_mode_data)
> 
> 	for (i = 0; i < IDT_ENTRIES; i++)
> 		set_intr_gate(i, early_idt_handler);
>-	asm volatile("lidt %0" :: "m" (idt_descr));
>+	load_idt((const struct desc_ptr *)&idt_descr);

Cast is not required, &idt_descr is already 'struct desc_ptr *'. (Also
elsewhere)


	Jan
-- 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Use descriptor's functions instead of inline assembly
  2007-07-20 18:14 Glauber de Oliveira Costa
@ 2007-07-21  3:38 ` Chris Wright
  0 siblings, 0 replies; 7+ messages in thread
From: Chris Wright @ 2007-07-21  3:38 UTC (permalink / raw)
  To: Glauber de Oliveira Costa; +Cc: linux-kernel, ak, akpm, rostedt, chrisw

* Glauber de Oliveira Costa (gcosta@redhat.com) wrote:
> This patch provides a new set of functions for managing the descriptor
> tables that can be used instead of putting the raw assembly in .c files.

Looks alright, some cleanups below

> Remodeling of store_tr() suggested by Frederik Deweerdt.
>     
> Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com>
> 
> diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c
> index 6c34bdd..dde41d7 100644
> --- a/arch/x86_64/kernel/head64.c
> +++ b/arch/x86_64/kernel/head64.c
> @@ -70,7 +70,7 @@ void __init x86_64_start_kernel(char * real_mode_data)
>  
>  	for (i = 0; i < IDT_ENTRIES; i++)
>  		set_intr_gate(i, early_idt_handler);
> -	asm volatile("lidt %0" :: "m" (idt_descr));
> +	load_idt((const struct desc_ptr *)&idt_descr);

No need for extra casting

>  	early_printk("Kernel alive\n");
>  
> diff --git a/arch/x86_64/kernel/reboot.c b/arch/x86_64/kernel/reboot.c
> index 7503068..7c50a12 100644
> --- a/arch/x86_64/kernel/reboot.c
> +++ b/arch/x86_64/kernel/reboot.c
> @@ -11,6 +11,7 @@
>  #include <linux/sched.h>
>  #include <asm/io.h>
>  #include <asm/delay.h>
> +#include <asm/desc.h>
>  #include <asm/hw_irq.h>
>  #include <asm/system.h>
>  #include <asm/pgtable.h>
> @@ -132,7 +133,7 @@ void machine_emergency_restart(void)
>  		}
>  
>  		case BOOT_TRIPLE: 
> -			__asm__ __volatile__("lidt (%0)": :"r" (&no_idt));
> +			load_idt((const struct desc_ptr *)&no_idt);

same here, plus opportunity for cleanup

>  			__asm__ __volatile__("int3");
>  
>  			reboot_type = BOOT_KBD;
> diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
> index 1200aaa..fef7290 100644
> --- a/arch/x86_64/kernel/setup64.c
> +++ b/arch/x86_64/kernel/setup64.c
> @@ -224,8 +224,8 @@ void __cpuinit cpu_init (void)
>   		memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE);
>  
>  	cpu_gdt_descr[cpu].size = GDT_SIZE;
> -	asm volatile("lgdt %0" :: "m" (cpu_gdt_descr[cpu]));
> -	asm volatile("lidt %0" :: "m" (idt_descr));
> +	load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
> +	load_idt((const struct desc_ptr *)&idt_descr);

same here

>  	memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
>  	syscall_init();
> diff --git a/arch/x86_64/kernel/suspend.c b/arch/x86_64/kernel/suspend.c
> index b39d478..ddedadf 100644
> --- a/arch/x86_64/kernel/suspend.c
> +++ b/arch/x86_64/kernel/suspend.c
> @@ -32,9 +32,9 @@ void __save_processor_state(struct saved_context *ctxt)
>  	/*
>  	 * descriptor tables
>  	 */
> -	asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit));
> -	asm volatile ("sidt %0" : "=m" (ctxt->idt_limit));
> -	asm volatile ("str %0"  : "=m" (ctxt->tr));
> +	store_gdt((struct desc_ptr *)&ctxt->gdt_limit);
> +	store_idt((struct desc_ptr *)&ctxt->idt_limit);

same here, opportunity for cleanup

> +	store_tr(ctxt->tr);
>  
>  	/* XMM0..XMM15 should be handled by kernel_fpu_begin(). */
>  	/*
> @@ -91,8 +91,9 @@ void __restore_processor_state(struct saved_context *ctxt)
>  	 * now restore the descriptor tables to their proper values
>  	 * ltr is done i fix_processor_context().
>  	 */
> -	asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit));
> -	asm volatile ("lidt %0" :: "m" (ctxt->idt_limit));
> +	load_gdt((const struct desc_ptr *)&ctxt->gdt_limit);
> +	load_idt((const struct desc_ptr *)&ctxt->idt_limit);
> +	
>  
>  	/*
>  	 * segment registers
> diff --git a/include/asm-x86_64/desc.h b/include/asm-x86_64/desc.h
> index ac991b5..f2b0a6f 100644
> --- a/include/asm-x86_64/desc.h
> +++ b/include/asm-x86_64/desc.h
> @@ -20,6 +20,15 @@ extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
>  #define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8))
>  #define clear_LDT()  asm volatile("lldt %w0"::"r" (0))
>  
> +static inline unsigned long __store_tr(void)
> +{
> +       unsigned long tr;
> +       asm volatile ("str %w0":"=r" (tr));
> +       return tr;
> +}

native_store_tr (although I've no objection to just fixing the interface)


Index: linus-2.6/arch/x86_64/kernel/head64.c
===================================================================
--- linus-2.6.orig/arch/x86_64/kernel/head64.c
+++ linus-2.6/arch/x86_64/kernel/head64.c
@@ -70,7 +70,7 @@ void __init x86_64_start_kernel(char * r
 
 	for (i = 0; i < IDT_ENTRIES; i++)
 		set_intr_gate(i, early_idt_handler);
-	load_idt((const struct desc_ptr *)&idt_descr);
+	load_idt(&idt_descr);
 
 	early_printk("Kernel alive\n");
 
Index: linus-2.6/arch/x86_64/kernel/reboot.c
===================================================================
--- linus-2.6.orig/arch/x86_64/kernel/reboot.c
+++ linus-2.6/arch/x86_64/kernel/reboot.c
@@ -24,7 +24,7 @@
 void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
 
-static long no_idt[3];
+static struct desc_ptr no_idt;
 static enum { 
 	BOOT_TRIPLE = 't',
 	BOOT_KBD = 'k'
@@ -133,7 +133,7 @@ void machine_emergency_restart(void)
 		}
 
 		case BOOT_TRIPLE: 
-			load_idt((const struct desc_ptr *)&no_idt);
+			load_idt(&no_idt);
 			__asm__ __volatile__("int3");
 
 			reboot_type = BOOT_KBD;
Index: linus-2.6/arch/x86_64/kernel/setup64.c
===================================================================
--- linus-2.6.orig/arch/x86_64/kernel/setup64.c
+++ linus-2.6/arch/x86_64/kernel/setup64.c
@@ -224,8 +224,8 @@ void __cpuinit cpu_init (void)
  		memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE);
 
 	cpu_gdt_descr[cpu].size = GDT_SIZE;
-	load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
-	load_idt((const struct desc_ptr *)&idt_descr);
+	load_gdt(&cpu_gdt_descr[cpu]);
+	load_idt(&idt_descr);
 
 	memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
 	syscall_init();
Index: linus-2.6/arch/x86_64/kernel/suspend.c
===================================================================
--- linus-2.6.orig/arch/x86_64/kernel/suspend.c
+++ linus-2.6/arch/x86_64/kernel/suspend.c
@@ -32,8 +32,8 @@ void __save_processor_state(struct saved
 	/*
 	 * descriptor tables
 	 */
-	store_gdt((struct desc_ptr *)&ctxt->gdt_limit);
-	store_idt((struct desc_ptr *)&ctxt->idt_limit);
+	store_gdt(&ctxt->gdt);
+	store_idt(&ctxt->idt);
 	store_tr(ctxt->tr);
 
 	/* XMM0..XMM15 should be handled by kernel_fpu_begin(). */
@@ -91,8 +91,8 @@ void __restore_processor_state(struct sa
 	 * now restore the descriptor tables to their proper values
 	 * ltr is done i fix_processor_context().
 	 */
-	load_gdt((const struct desc_ptr *)&ctxt->gdt_limit);
-	load_idt((const struct desc_ptr *)&ctxt->idt_limit);
+	load_gdt(&ctxt->gdt);
+	load_idt(&ctxt->idt);
 	
 
 	/*
Index: linus-2.6/include/asm-x86_64/desc.h
===================================================================
--- linus-2.6.orig/include/asm-x86_64/desc.h
+++ linus-2.6/include/asm-x86_64/desc.h
@@ -20,14 +20,14 @@ extern struct desc_struct cpu_gdt_table[
 #define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8))
 #define clear_LDT()  asm volatile("lldt %w0"::"r" (0))
 
-static inline unsigned long __store_tr(void)
+static inline unsigned long native_store_tr(void)
 {
        unsigned long tr;
        asm volatile ("str %w0":"=r" (tr));
        return tr;
 }
 
-#define store_tr(tr) (tr) = __store_tr()
+#define store_tr(tr) (tr) = native_store_tr()
 
 /*
  * This is the ldt that every process will get unless we need
Index: linus-2.6/arch/x86_64/kernel/machine_kexec.c
===================================================================
--- linus-2.6.orig/arch/x86_64/kernel/machine_kexec.c
+++ linus-2.6/arch/x86_64/kernel/machine_kexec.c
@@ -119,11 +119,8 @@ static void set_idt(void *newidt, u16 li
 	/* x86-64 supports unaliged loads & stores */
 	curidt.size    = limit;
 	curidt.address = (unsigned long)newidt;
-
-	__asm__ __volatile__ (
-		"lidtq %0\n"
-		: : "m" (curidt)
-		);
+	
+	load_idt(&curidt);
 };
 
 
@@ -135,10 +132,7 @@ static void set_gdt(void *newgdt, u16 li
 	curgdt.size    = limit;
 	curgdt.address = (unsigned long)newgdt;
 
-	__asm__ __volatile__ (
-		"lgdtq %0\n"
-		: : "m" (curgdt)
-		);
+	load_gdt(&curgdt);
 };
 
 static void load_segments(void)
Index: linus-2.6/include/asm-x86_64/suspend.h
===================================================================
--- linus-2.6.orig/include/asm-x86_64/suspend.h
+++ linus-2.6/include/asm-x86_64/suspend.h
@@ -18,12 +18,8 @@ struct saved_context {
 	unsigned long gs_base, gs_kernel_base, fs_base;
 	unsigned long cr0, cr2, cr3, cr4, cr8;
 	unsigned long efer;
-	u16 gdt_pad;
-	u16 gdt_limit;
-	unsigned long gdt_base;
-	u16 idt_pad;
-	u16 idt_limit;
-	unsigned long idt_base;
+	struct desc_ptr gdt;
+	struct desc_ptr idt;
 	u16 ldt;
 	u16 tss;
 	unsigned long tr;

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH] Use descriptor's functions instead of inline assembly
@ 2007-07-20 18:14 Glauber de Oliveira Costa
  2007-07-21  3:38 ` Chris Wright
  0 siblings, 1 reply; 7+ messages in thread
From: Glauber de Oliveira Costa @ 2007-07-20 18:14 UTC (permalink / raw)
  To: linux-kernel, ak, akpm, rostedt, chrisw

This patch provides a new set of functions for managing the descriptor
tables that can be used instead of putting the raw assembly in .c files.
    
Remodeling of store_tr() suggested by Frederik Deweerdt.
    
Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com>

diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c
index 6c34bdd..dde41d7 100644
--- a/arch/x86_64/kernel/head64.c
+++ b/arch/x86_64/kernel/head64.c
@@ -70,7 +70,7 @@ void __init x86_64_start_kernel(char * real_mode_data)
 
 	for (i = 0; i < IDT_ENTRIES; i++)
 		set_intr_gate(i, early_idt_handler);
-	asm volatile("lidt %0" :: "m" (idt_descr));
+	load_idt((const struct desc_ptr *)&idt_descr);
 
 	early_printk("Kernel alive\n");
 
diff --git a/arch/x86_64/kernel/reboot.c b/arch/x86_64/kernel/reboot.c
index 7503068..7c50a12 100644
--- a/arch/x86_64/kernel/reboot.c
+++ b/arch/x86_64/kernel/reboot.c
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 #include <asm/io.h>
 #include <asm/delay.h>
+#include <asm/desc.h>
 #include <asm/hw_irq.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -132,7 +133,7 @@ void machine_emergency_restart(void)
 		}
 
 		case BOOT_TRIPLE: 
-			__asm__ __volatile__("lidt (%0)": :"r" (&no_idt));
+			load_idt((const struct desc_ptr *)&no_idt);
 			__asm__ __volatile__("int3");
 
 			reboot_type = BOOT_KBD;
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
index 1200aaa..fef7290 100644
--- a/arch/x86_64/kernel/setup64.c
+++ b/arch/x86_64/kernel/setup64.c
@@ -224,8 +224,8 @@ void __cpuinit cpu_init (void)
  		memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE);
 
 	cpu_gdt_descr[cpu].size = GDT_SIZE;
-	asm volatile("lgdt %0" :: "m" (cpu_gdt_descr[cpu]));
-	asm volatile("lidt %0" :: "m" (idt_descr));
+	load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
+	load_idt((const struct desc_ptr *)&idt_descr);
 
 	memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
 	syscall_init();
diff --git a/arch/x86_64/kernel/suspend.c b/arch/x86_64/kernel/suspend.c
index b39d478..ddedadf 100644
--- a/arch/x86_64/kernel/suspend.c
+++ b/arch/x86_64/kernel/suspend.c
@@ -32,9 +32,9 @@ void __save_processor_state(struct saved_context *ctxt)
 	/*
 	 * descriptor tables
 	 */
-	asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit));
-	asm volatile ("sidt %0" : "=m" (ctxt->idt_limit));
-	asm volatile ("str %0"  : "=m" (ctxt->tr));
+	store_gdt((struct desc_ptr *)&ctxt->gdt_limit);
+	store_idt((struct desc_ptr *)&ctxt->idt_limit);
+	store_tr(ctxt->tr);
 
 	/* XMM0..XMM15 should be handled by kernel_fpu_begin(). */
 	/*
@@ -91,8 +91,9 @@ void __restore_processor_state(struct saved_context *ctxt)
 	 * now restore the descriptor tables to their proper values
 	 * ltr is done i fix_processor_context().
 	 */
-	asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit));
-	asm volatile ("lidt %0" :: "m" (ctxt->idt_limit));
+	load_gdt((const struct desc_ptr *)&ctxt->gdt_limit);
+	load_idt((const struct desc_ptr *)&ctxt->idt_limit);
+	
 
 	/*
 	 * segment registers
diff --git a/include/asm-x86_64/desc.h b/include/asm-x86_64/desc.h
index ac991b5..f2b0a6f 100644
--- a/include/asm-x86_64/desc.h
+++ b/include/asm-x86_64/desc.h
@@ -20,6 +20,15 @@ extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
 #define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8))
 #define clear_LDT()  asm volatile("lldt %w0"::"r" (0))
 
+static inline unsigned long __store_tr(void)
+{
+       unsigned long tr;
+       asm volatile ("str %w0":"=r" (tr));
+       return tr;
+}
+
+#define store_tr(tr) (tr) = __store_tr()
+
 /*
  * This is the ldt that every process will get unless we need
  * something other than this.
@@ -31,6 +40,16 @@ extern struct desc_ptr cpu_gdt_descr[];
 /* the cpu gdt accessor */
 #define cpu_gdt(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address)
 
+static inline void load_gdt(const struct desc_ptr *ptr)
+{
+	asm volatile("lgdt %w0"::"m" (*ptr));
+}
+
+static inline void store_gdt(struct desc_ptr *ptr)
+{
+       asm ("sgdt %w0":"=m" (*ptr));
+}
+
 static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist)  
 {
 	struct gate_struct s; 	
@@ -71,6 +90,16 @@ static inline void set_system_gate_ist(int nr, void *func, unsigned ist)
 	_set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, ist);
 }
 
+static inline void load_idt(const struct desc_ptr *ptr)
+{
+	asm volatile("lidt %w0"::"m" (*ptr));
+}
+
+static inline void store_idt(struct desc_ptr *dtr)
+{
+       asm ("sidt %w0":"=m" (*dtr));
+}
+
 static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, unsigned type, 
 					 unsigned size) 
 { 



^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2007-07-21 16:03 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-07-20 13:56 [PATCH] Use descriptor's functions instead of inline assembly Glauber de Oliveira Costa
2007-07-20 14:23 ` Frederik Deweerdt
2007-07-20 15:14   ` Glauber de Oliveira Costa
2007-07-20 23:05   ` Brian Gerst
2007-07-21 16:03 ` Jan Engelhardt
2007-07-20 18:14 Glauber de Oliveira Costa
2007-07-21  3:38 ` Chris Wright

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).