Commit 7d59d129 authored by Anton Blanchard's avatar Anton Blanchard

Merge samba.org:/scratch/anton/linux-2.5

into samba.org:/scratch/anton/for-alan
parents 613b4ade 75fb58ee
......@@ -233,7 +233,7 @@ need_resched:
#endif
/* Points to after the "sysenter" instruction in the vsyscall page */
#define SYSENTER_RETURN 0xffffe009
#define SYSENTER_RETURN 0xffffe00a
# sysenter call handler stub
ALIGN
......
......@@ -9,6 +9,7 @@
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/thread_info.h>
#include <linux/sched.h>
#include <linux/gfp.h>
#include <linux/string.h>
......@@ -18,24 +19,55 @@
extern asmlinkage void sysenter_entry(void);
/*
* Create a per-cpu fake "SEP thread" stack, so that we can
* enter the kernel without having to worry about things like
* "current" etc not working (debug traps and NMI's can happen
* before we can switch over to the "real" thread).
*
* Return the resulting fake stack pointer.
*/
struct fake_sep_struct {
struct thread_info thread;
struct task_struct task;
unsigned char trampoline[32] __attribute__((aligned(1024)));
unsigned char stack[0];
} __attribute__((aligned(8192)));
static struct fake_sep_struct *alloc_sep_thread(int cpu)
{
struct fake_sep_struct *entry;
entry = (struct fake_sep_struct *) __get_free_pages(GFP_ATOMIC, 1);
if (!entry)
return NULL;
memset(entry, 0, PAGE_SIZE<<1);
entry->thread.task = &entry->task;
entry->task.thread_info = &entry->thread;
entry->thread.preempt_count = 1;
entry->thread.cpu = cpu;
return entry;
}
static void __init enable_sep_cpu(void *info)
{
unsigned long page = __get_free_page(GFP_ATOMIC);
int cpu = get_cpu();
struct fake_sep_struct *sep = alloc_sep_thread(cpu);
unsigned long *esp0_ptr = &(init_tss + cpu)->esp0;
unsigned long rel32;
rel32 = (unsigned long) sysenter_entry - (page+11);
rel32 = (unsigned long) sysenter_entry - (unsigned long) (sep->trampoline+11);
*(short *) (page+0) = 0x258b; /* movl xxxxx,%esp */
*(long **) (page+2) = esp0_ptr;
*(char *) (page+6) = 0xe9; /* jmp rl32 */
*(long *) (page+7) = rel32;
*(short *) (sep->trampoline+0) = 0x258b; /* movl xxxxx,%esp */
*(long **) (sep->trampoline+2) = esp0_ptr;
*(char *) (sep->trampoline+6) = 0xe9; /* jmp rl32 */
*(long *) (sep->trampoline+7) = rel32;
wrmsr(0x174, __KERNEL_CS, 0); /* SYSENTER_CS_MSR */
wrmsr(0x175, page+PAGE_SIZE, 0); /* SYSENTER_ESP_MSR */
wrmsr(0x176, page, 0); /* SYSENTER_EIP_MSR */
wrmsr(0x175, PAGE_SIZE*2 + (unsigned long) sep, 0); /* SYSENTER_ESP_MSR */
wrmsr(0x176, (unsigned long) &sep->trampoline, 0); /* SYSENTER_EIP_MSR */
printk("Enabling SEP on CPU %d\n", cpu);
put_cpu();
......@@ -48,6 +80,7 @@ static int __init sysenter_setup(void)
0xc3 /* ret */
};
static const char sysent[] = {
0x9c, /* pushf */
0x51, /* push %ecx */
0x52, /* push %edx */
0x55, /* push %ebp */
......@@ -59,6 +92,7 @@ static int __init sysenter_setup(void)
0x5d, /* pop %ebp */
0x5a, /* pop %edx */
0x59, /* pop %ecx */
0x9d, /* popf - restore TF */
0xc3 /* ret */
};
unsigned long page = get_zeroed_page(GFP_ATOMIC);
......
......@@ -5,7 +5,7 @@
obj-$(CONFIG_INTERMEZZO_FS) += intermezzo.o
intermezzo-objs := cache.o dcache.o dir.o ext_attr.o file.o fileset.o \
inode.o io_daemon.o journal.o journal_ext2.o journal_ext3.o \
inode.o journal.o journal_ext2.o journal_ext3.o \
journal_obdfs.o journal_reiserfs.o journal_tmpfs.o journal_xfs.o \
kml_reint.o kml_unpack.o methods.o presto.o psdev.o replicator.o \
super.o sysctl.o upcall.o vfs.o
......@@ -65,9 +65,9 @@
#define GDT_ENTRY_APMBIOS_BASE (GDT_ENTRY_KERNEL_BASE + 11)
/*
* The GDT has 23 entries but we pad it to cacheline boundary:
* The GDT has 25 entries but we pad it to cacheline boundary:
*/
#define GDT_ENTRIES 24
#define GDT_ENTRIES 28
#define GDT_SIZE (GDT_ENTRIES * 8)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment