x86: use descriptor's functions instead of inline assembly
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. [ tglx: arch/x86 adaptation ] Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com> Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
9d975ebda5
commit
9d1c6e7c86
5 changed files with 41 additions and 9 deletions
|
@ -58,7 +58,7 @@ void __init x86_64_start_kernel(char * real_mode_data)
|
||||||
|
|
||||||
for (i = 0; i < IDT_ENTRIES; i++)
|
for (i = 0; i < IDT_ENTRIES; i++)
|
||||||
set_intr_gate(i, early_idt_handler);
|
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");
|
early_printk("Kernel alive\n");
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/delay.h>
|
#include <asm/delay.h>
|
||||||
|
#include <asm/desc.h>
|
||||||
#include <asm/hw_irq.h>
|
#include <asm/hw_irq.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/pgtable.h>
|
#include <asm/pgtable.h>
|
||||||
|
@ -136,7 +137,7 @@ void machine_emergency_restart(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
case BOOT_TRIPLE:
|
case BOOT_TRIPLE:
|
||||||
__asm__ __volatile__("lidt (%0)": :"r" (&no_idt));
|
load_idt((const struct desc_ptr *)&no_idt);
|
||||||
__asm__ __volatile__("int3");
|
__asm__ __volatile__("int3");
|
||||||
|
|
||||||
reboot_type = BOOT_KBD;
|
reboot_type = BOOT_KBD;
|
||||||
|
|
|
@ -230,8 +230,8 @@ void __cpuinit cpu_init (void)
|
||||||
memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE);
|
memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE);
|
||||||
|
|
||||||
cpu_gdt_descr[cpu].size = GDT_SIZE;
|
cpu_gdt_descr[cpu].size = GDT_SIZE;
|
||||||
asm volatile("lgdt %0" :: "m" (cpu_gdt_descr[cpu]));
|
load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
|
||||||
asm volatile("lidt %0" :: "m" (idt_descr));
|
load_idt((const struct desc_ptr *)&idt_descr);
|
||||||
|
|
||||||
memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
|
memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
|
||||||
syscall_init();
|
syscall_init();
|
||||||
|
|
|
@ -32,9 +32,9 @@ void __save_processor_state(struct saved_context *ctxt)
|
||||||
/*
|
/*
|
||||||
* descriptor tables
|
* descriptor tables
|
||||||
*/
|
*/
|
||||||
asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit));
|
store_gdt((struct desc_ptr *)&ctxt->gdt_limit);
|
||||||
asm volatile ("sidt %0" : "=m" (ctxt->idt_limit));
|
store_idt((struct desc_ptr *)&ctxt->idt_limit);
|
||||||
asm volatile ("str %0" : "=m" (ctxt->tr));
|
store_tr(ctxt->tr);
|
||||||
|
|
||||||
/* XMM0..XMM15 should be handled by kernel_fpu_begin(). */
|
/* 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
|
* now restore the descriptor tables to their proper values
|
||||||
* ltr is done i fix_processor_context().
|
* ltr is done i fix_processor_context().
|
||||||
*/
|
*/
|
||||||
asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit));
|
load_gdt((const struct desc_ptr *)&ctxt->gdt_limit);
|
||||||
asm volatile ("lidt %0" :: "m" (ctxt->idt_limit));
|
load_idt((const struct desc_ptr *)&ctxt->idt_limit);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* segment registers
|
* segment registers
|
||||||
|
|
|
@ -20,6 +20,16 @@ extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
|
||||||
#define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8))
|
#define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8))
|
||||||
#define clear_LDT() asm volatile("lldt %w0"::"r" (0))
|
#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
|
* This is the ldt that every process will get unless we need
|
||||||
* something other than this.
|
* something other than this.
|
||||||
|
@ -31,6 +41,16 @@ extern struct desc_ptr cpu_gdt_descr[];
|
||||||
/* the cpu gdt accessor */
|
/* the cpu gdt accessor */
|
||||||
#define cpu_gdt(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address)
|
#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)
|
static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist)
|
||||||
{
|
{
|
||||||
struct gate_struct s;
|
struct gate_struct s;
|
||||||
|
@ -71,6 +91,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);
|
_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,
|
static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, unsigned type,
|
||||||
unsigned size)
|
unsigned size)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue