Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 79980
b: refs/heads/master
c: 54cd0ea
h: refs/heads/master
v: v3
  • Loading branch information
Glauber de Oliveira Costa authored and Ingo Molnar committed Jan 30, 2008
1 parent 78b6834 commit 5829248
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 227 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cc6978528cbd475d952e0eb5073375839dfb600e
refs/heads/master: 54cd0eac7286b83ef1a657d2dddd74e0556209e7
169 changes: 169 additions & 0 deletions trunk/include/asm-x86/desc.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <asm/desc_defs.h>
#include <asm/ldt.h>
#include <asm/mmu.h>
#include <linux/smp.h>

static inline void fill_ldt(struct desc_struct *desc, struct user_desc *info)
{
Expand All @@ -27,6 +28,174 @@ static inline void fill_ldt(struct desc_struct *desc, struct user_desc *info)
extern struct desc_ptr idt_descr;
extern gate_desc idt_table[];

#ifdef CONFIG_X86_64
extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
extern struct desc_ptr cpu_gdt_descr[];
/* the cpu gdt accessor */
#define get_cpu_gdt_table(x) ((struct desc_struct *)cpu_gdt_descr[x].address)
#else
struct gdt_page {
struct desc_struct gdt[GDT_ENTRIES];
} __attribute__((aligned(PAGE_SIZE)));
DECLARE_PER_CPU(struct gdt_page, gdt_page);

static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
{
return per_cpu(gdt_page, cpu).gdt;
}
#endif

#ifdef CONFIG_PARAVIRT
#include <asm/paravirt.h>
#else
#define load_TR_desc() native_load_tr_desc()
#define load_gdt(dtr) native_load_gdt(dtr)
#define load_idt(dtr) native_load_idt(dtr)
#define load_tr(tr) __asm__ __volatile("ltr %0"::"m" (tr))
#define load_ldt(ldt) __asm__ __volatile("lldt %0"::"m" (ldt))

#define store_gdt(dtr) native_store_gdt(dtr)
#define store_idt(dtr) native_store_idt(dtr)
#define store_tr(tr) (tr = native_store_tr())
#define store_ldt(ldt) __asm__ ("sldt %0":"=m" (ldt))

#define load_TLS(t, cpu) native_load_tls(t, cpu)
#define set_ldt native_set_ldt

#define write_ldt_entry(dt, entry, desc) \
native_write_ldt_entry(dt, entry, desc)
#define write_gdt_entry(dt, entry, desc, type) \
native_write_gdt_entry(dt, entry, desc, type)
#define write_idt_entry(dt, entry, g) native_write_idt_entry(dt, entry, g)
#endif

static inline void native_write_idt_entry(gate_desc *idt, int entry,
const gate_desc *gate)
{
memcpy(&idt[entry], gate, sizeof(*gate));
}

static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
const void *desc)
{
memcpy(&ldt[entry], desc, 8);
}

static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
const void *desc, int type)
{
unsigned int size;
switch (type) {
case DESC_TSS:
size = sizeof(tss_desc);
break;
case DESC_LDT:
size = sizeof(ldt_desc);
break;
default:
size = sizeof(struct desc_struct);
break;
}
memcpy(&gdt[entry], desc, size);
}

static inline void set_tssldt_descriptor(struct ldttss_desc64 *d,
unsigned long tss, unsigned type,
unsigned size)
{
memset(d, 0, sizeof(*d));
d->limit0 = size & 0xFFFF;
d->base0 = PTR_LOW(tss);
d->base1 = PTR_MIDDLE(tss) & 0xFF;
d->type = type;
d->p = 1;
d->limit1 = (size >> 16) & 0xF;
d->base2 = (PTR_MIDDLE(tss) >> 8) & 0xFF;
d->base3 = PTR_HIGH(tss);
}

static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
unsigned long limit, unsigned char type,
unsigned char flags)
{
desc->a = ((base & 0xffff) << 16) | (limit & 0xffff);
desc->b = (base & 0xff000000) | ((base & 0xff0000) >> 16) |
(limit & 0x000f0000) | ((type & 0xff) << 8) |
((flags & 0xf) << 20);
desc->p = 1;
}

static inline void pack_ldt(ldt_desc *ldt, unsigned long addr,
unsigned size)
{

#ifdef CONFIG_X86_64
set_tssldt_descriptor(ldt,
addr, DESC_LDT, size);
#else
pack_descriptor(ldt, (unsigned long)addr,
size,
0x80 | DESC_LDT, 0);
#endif
}

static inline void native_set_ldt(const void *addr, unsigned int entries)
{
if (likely(entries == 0))
__asm__ __volatile__("lldt %w0"::"q" (0));
else {
unsigned cpu = smp_processor_id();
ldt_desc ldt;

pack_ldt(&ldt, (unsigned long)addr,
entries * sizeof(ldt) - 1);
write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT,
&ldt, DESC_LDT);
__asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8));
}
}

static inline void native_load_tr_desc(void)
{
asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
}

static inline void native_load_gdt(const struct desc_ptr *dtr)
{
asm volatile("lgdt %0"::"m" (*dtr));
}

static inline void native_load_idt(const struct desc_ptr *dtr)
{
asm volatile("lidt %0"::"m" (*dtr));
}

static inline void native_store_gdt(struct desc_ptr *dtr)
{
asm volatile("sgdt %0":"=m" (*dtr));
}

static inline void native_store_idt(struct desc_ptr *dtr)
{
asm volatile("sidt %0":"=m" (*dtr));
}

static inline unsigned long native_store_tr(void)
{
unsigned long tr;
asm volatile("str %0":"=r" (tr));
return tr;
}

static inline void native_load_tls(struct thread_struct *t, unsigned int cpu)
{
unsigned int i;
struct desc_struct *gdt = get_cpu_gdt_table(cpu);

for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
}

#ifdef CONFIG_X86_32
# include "desc_32.h"
#else
Expand Down
130 changes: 0 additions & 130 deletions trunk/include/asm-x86/desc_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,147 +8,17 @@
#ifndef __ASSEMBLY__

#include <linux/preempt.h>
#include <linux/smp.h>
#include <linux/percpu.h>

struct gdt_page
{
struct desc_struct gdt[GDT_ENTRIES];
} __attribute__((aligned(PAGE_SIZE)));
DECLARE_PER_CPU(struct gdt_page, gdt_page);

static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
{
return per_cpu(gdt_page, cpu).gdt;
}

extern void set_intr_gate(unsigned int irq, void * addr);

static inline void pack_descriptor(struct desc_struct *desc,
unsigned long base, unsigned long limit, unsigned char type, unsigned char flags)
{
desc->a = ((base & 0xffff) << 16) | (limit & 0xffff);
desc->b = (base & 0xff000000) | ((base & 0xff0000) >> 16) |
(limit & 0x000f0000) | ((type & 0xff) << 8) | ((flags & 0xf) << 20);
desc->p = 1;
}

static inline void pack_gate(gate_desc *gate,
unsigned long base, unsigned short seg, unsigned char type, unsigned char flags)
{
gate->a = (seg << 16) | (base & 0xffff);
gate->b = (base & 0xffff0000) | ((type & 0xff) << 8) | (flags & 0xff);
}

#ifdef CONFIG_PARAVIRT
#include <asm/paravirt.h>
#else
#define load_TR_desc() native_load_tr_desc()
#define load_gdt(dtr) native_load_gdt(dtr)
#define load_idt(dtr) native_load_idt(dtr)
#define load_tr(tr) __asm__ __volatile("ltr %0"::"m" (tr))
#define load_ldt(ldt) __asm__ __volatile("lldt %0"::"m" (ldt))

#define store_gdt(dtr) native_store_gdt(dtr)
#define store_idt(dtr) native_store_idt(dtr)
#define store_tr(tr) (tr = native_store_tr())
#define store_ldt(ldt) __asm__ ("sldt %0":"=m" (ldt))

#define load_TLS(t, cpu) native_load_tls(t, cpu)
#define set_ldt native_set_ldt

#define write_ldt_entry(dt, entry, desc) \
native_write_ldt_entry(dt, entry, desc)
#define write_gdt_entry(dt, entry, desc, type) \
native_write_gdt_entry(dt, entry, desc, type)
#define write_idt_entry(dt, entry, g) native_write_idt_entry(dt, entry, g)
#endif

static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
const void *desc)
{
memcpy(&ldt[entry], desc, sizeof(struct desc_struct));
}

static inline void native_write_idt_entry(gate_desc *idt, int entry,
const gate_desc *gate)
{
memcpy(&idt[entry], gate, sizeof(*gate));
}

static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
const void *desc, int type)
{
memcpy(&gdt[entry], desc, sizeof(struct desc_struct));
}

static inline void write_dt_entry(struct desc_struct *dt,
int entry, u32 entry_low, u32 entry_high)
{
dt[entry].a = entry_low;
dt[entry].b = entry_high;
}


static inline void native_set_ldt(const void *addr, unsigned int entries)
{
if (likely(entries == 0))
__asm__ __volatile__("lldt %w0"::"q" (0));
else {
unsigned cpu = smp_processor_id();
ldt_desc ldt;

pack_descriptor(&ldt, (unsigned long)addr,
entries * sizeof(struct desc_struct) - 1,
DESC_LDT, 0);
write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT,
&ldt, DESC_LDT);
__asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8));
}
}


static inline void native_load_tr_desc(void)
{
asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
}

static inline void native_load_gdt(const struct desc_ptr *dtr)
{
asm volatile("lgdt %0"::"m" (*dtr));
}

static inline void native_load_idt(const struct desc_ptr *dtr)
{
asm volatile("lidt %0"::"m" (*dtr));
}

static inline void native_store_gdt(struct desc_ptr *dtr)
{
asm ("sgdt %0":"=m" (*dtr));
}

static inline void native_store_idt(struct desc_ptr *dtr)
{
asm ("sidt %0":"=m" (*dtr));
}

static inline unsigned long native_store_tr(void)
{
unsigned long tr;
asm ("str %0":"=r" (tr));
return tr;
}

static inline void native_load_tls(struct thread_struct *t, unsigned int cpu)
{
unsigned int i;
struct desc_struct *gdt = get_cpu_gdt_table(cpu);

for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
}

static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg)
{
gate_desc g;
Expand Down
Loading

0 comments on commit 5829248

Please sign in to comment.