From: jbeulich@xxxxxxxxxx Subject: eliminate init_tss $subject says it all. Index: head-2006-02-13/arch/i386/kernel/asm-offsets.c =================================================================== --- head-2006-02-13.orig/arch/i386/kernel/asm-offsets.c 2006-02-13 11:38:07.000000000 +0100 +++ head-2006-02-13/arch/i386/kernel/asm-offsets.c 2006-02-13 15:09:38.000000000 +0100 @@ -63,9 +63,11 @@ void foo(void) OFFSET(pbe_orig_address, pbe, orig_address); OFFSET(pbe_next, pbe, next); +#ifndef CONFIG_XEN /* Offset from the sysenter stack to tss.esp0 */ DEFINE(TSS_sysenter_esp0, offsetof(struct tss_struct, esp0) - sizeof(struct tss_struct)); +#endif DEFINE(PAGE_SIZE_asm, PAGE_SIZE); DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL)); Index: head-2006-02-13/arch/i386/kernel/sysenter.c =================================================================== --- head-2006-02-13.orig/arch/i386/kernel/sysenter.c 2006-02-13 11:38:07.000000000 +0100 +++ head-2006-02-13/arch/i386/kernel/sysenter.c 2006-02-13 15:09:38.000000000 +0100 @@ -23,6 +23,7 @@ extern asmlinkage void sysenter_entry(vo void enable_sep_cpu(void) { +#ifndef CONFIG_XEN int cpu = get_cpu(); struct tss_struct *tss = &per_cpu(init_tss, cpu); @@ -37,6 +38,7 @@ void enable_sep_cpu(void) wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp1, 0); wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0); put_cpu(); +#endif } /* Index: head-2006-02-13/arch/i386/kernel/vm86.c =================================================================== --- head-2006-02-13.orig/arch/i386/kernel/vm86.c 2006-02-13 11:38:07.000000000 +0100 +++ head-2006-02-13/arch/i386/kernel/vm86.c 2006-02-13 15:09:38.000000000 +0100 @@ -97,7 +97,9 @@ struct pt_regs * FASTCALL(save_v86_state(struct kernel_vm86_regs * regs)); struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs) { +#ifndef CONFIG_XEN struct tss_struct *tss; +#endif struct pt_regs *ret; unsigned long tmp; @@ -122,7 +124,9 @@ struct pt_regs * fastcall save_v86_state do_exit(SIGSEGV); } +#ifndef CONFIG_XEN tss = &per_cpu(init_tss, get_cpu()); +#endif current->thread.esp0 = current->thread.saved_esp0; current->thread.sysenter_cs = __KERNEL_CS; load_esp0(tss, ¤t->thread); @@ -251,7 +255,10 @@ out: static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk) { +#ifndef CONFIG_XEN struct tss_struct *tss; +#endif + /* * make sure the vm86() system call doesn't try to do anything silly */ @@ -295,7 +302,9 @@ static void do_sys_vm86(struct kernel_vm savesegment(fs, tsk->thread.saved_fs); savesegment(gs, tsk->thread.saved_gs); +#ifndef CONFIG_XEN tss = &per_cpu(init_tss, get_cpu()); +#endif tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; if (cpu_has_sep) tsk->thread.sysenter_cs = 0; Index: head-2006-02-13/arch/i386/kernel/cpu/common-xen.c =================================================================== --- head-2006-02-13.orig/arch/i386/kernel/cpu/common-xen.c 2006-02-13 15:07:48.000000000 +0100 +++ head-2006-02-13/arch/i386/kernel/cpu/common-xen.c 2006-02-13 15:09:38.000000000 +0100 @@ -598,7 +598,9 @@ void __cpuinit cpu_gdt_init(struct Xgt_d void __cpuinit cpu_init(void) { int cpu = smp_processor_id(); +#ifndef CONFIG_XEN struct tss_struct * t = &per_cpu(init_tss, cpu); +#endif struct thread_struct *thread = ¤t->thread; if (cpu_test_and_set(cpu, cpu_initialized)) { Index: head-2006-02-13/arch/i386/kernel/entry-xen.S =================================================================== --- head-2006-02-13.orig/arch/i386/kernel/entry-xen.S 2006-02-13 12:17:53.000000000 +0100 +++ head-2006-02-13/arch/i386/kernel/entry-xen.S 2006-02-13 15:09:38.000000000 +0100 @@ -223,6 +223,7 @@ need_resched: jmp need_resched #endif +#if 0 /* XEN */ /* SYSENTER_RETURN points to after the "sysenter" instruction in the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */ @@ -270,6 +271,7 @@ sysenter_past_esp: xorl %ebp,%ebp sti sysexit +#endif /* XEN */ # system call handler stub @@ -662,6 +664,7 @@ ENTRY(device_not_available) call math_state_restore jmp ret_from_exception +#if 0 /* XEN */ /* * Debug traps and NMI can happen at the one SYSENTER instruction * that sets up the real kernel stack. Check here, since we can't @@ -683,12 +686,15 @@ label: \ pushfl; \ pushl $__KERNEL_CS; \ pushl $sysenter_past_esp +#endif /* XEN */ KPROBE_ENTRY(debug) +#if 0 /* XEN */ cmpl $sysenter_entry,(%esp) jne debug_stack_correct FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn) debug_stack_correct: +#endif /* XEN */ pushl $-1 # mark this as an int SAVE_ALL xorl %edx,%edx # error code 0 Index: head-2006-02-13/arch/i386/kernel/init_task-xen.c =================================================================== --- head-2006-02-13.orig/arch/i386/kernel/init_task-xen.c 2006-02-13 12:17:53.000000000 +0100 +++ head-2006-02-13/arch/i386/kernel/init_task-xen.c 2006-02-13 15:09:38.000000000 +0100 @@ -41,9 +41,10 @@ struct task_struct init_task = INIT_TASK EXPORT_SYMBOL(init_task); +#ifndef CONFIG_XEN /* * per-CPU TSS segments. Threads are completely 'soft' on Linux, * no more per-task TSS's. */ DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS; - +#endif Index: head-2006-02-13/arch/i386/kernel/process-xen.c =================================================================== --- head-2006-02-13.orig/arch/i386/kernel/process-xen.c 2006-02-13 14:41:01.000000000 +0100 +++ head-2006-02-13/arch/i386/kernel/process-xen.c 2006-02-13 15:09:38.000000000 +0100 @@ -518,7 +518,9 @@ struct task_struct fastcall * __switch_t struct thread_struct *prev = &prev_p->thread, *next = &next_p->thread; int cpu = smp_processor_id(); +#ifndef CONFIG_XEN struct tss_struct *tss = &per_cpu(init_tss, cpu); +#endif physdev_op_t iopl_op, iobmp_op; multicall_entry_t _mcl[8], *mcl = _mcl; @@ -543,10 +545,9 @@ struct task_struct fastcall * __switch_t * Reload esp0. * This is load_esp0(tss, next) with a multicall. */ - tss->esp0 = next->esp0; mcl->op = __HYPERVISOR_stack_switch; - mcl->args[0] = tss->ss0; - mcl->args[1] = tss->esp0; + mcl->args[0] = __KERNEL_DS; + mcl->args[1] = next->esp0; mcl++; /* Index: head-2006-02-13/include/asm-i386/mach-xen/asm/desc.h =================================================================== --- head-2006-02-13.orig/include/asm-i386/mach-xen/asm/desc.h 2006-02-13 14:41:00.000000000 +0100 +++ head-2006-02-13/include/asm-i386/mach-xen/asm/desc.h 2006-02-13 15:09:38.000000000 +0100 @@ -61,14 +61,6 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\ "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(&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(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82); Index: head-2006-02-13/include/asm-i386/mach-xen/asm/processor.h =================================================================== --- head-2006-02-13.orig/include/asm-i386/mach-xen/asm/processor.h 2006-02-13 12:17:53.000000000 +0100 +++ head-2006-02-13/include/asm-i386/mach-xen/asm/processor.h 2006-02-13 15:10:35.000000000 +0100 @@ -91,8 +91,6 @@ struct cpuinfo_x86 { extern struct cpuinfo_x86 boot_cpu_data; extern struct cpuinfo_x86 new_cpu_data; -extern struct tss_struct doublefault_tss; -DECLARE_PER_CPU(struct tss_struct, init_tss); #ifdef CONFIG_SMP extern struct cpuinfo_x86 cpu_data[]; @@ -343,7 +341,6 @@ extern int bootloader_type; #define IO_BITMAP_BITS 65536 #define IO_BITMAP_BYTES (IO_BITMAP_BITS/8) #define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long)) -#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap) #define INVALID_IO_BITMAP_OFFSET 0x8000 #define INVALID_IO_BITMAP_OFFSET_LAZY 0x9000 @@ -401,52 +398,6 @@ typedef struct { struct thread_struct; -struct tss_struct { - unsigned short back_link,__blh; - unsigned long esp0; - unsigned short ss0,__ss0h; - unsigned long esp1; - unsigned short ss1,__ss1h; /* ss1 is used to cache MSR_IA32_SYSENTER_CS */ - unsigned long esp2; - unsigned short ss2,__ss2h; - unsigned long __cr3; - unsigned long eip; - unsigned long eflags; - unsigned long eax,ecx,edx,ebx; - unsigned long esp; - unsigned long ebp; - unsigned long esi; - unsigned long edi; - unsigned short es, __esh; - unsigned short cs, __csh; - unsigned short ss, __ssh; - unsigned short ds, __dsh; - unsigned short fs, __fsh; - unsigned short gs, __gsh; - unsigned short ldt, __ldth; - unsigned short trace, io_bitmap_base; - /* - * The extra 1 is there because the CPU will access an - * additional byte beyond the end of the IO permission - * bitmap. The extra byte must be all 1 bits, and must - * be within the limit. - */ - unsigned long io_bitmap[IO_BITMAP_LONGS + 1]; - /* - * Cache the current maximum and the last task that used the bitmap: - */ - unsigned long io_bitmap_max; - struct thread_struct *io_bitmap_owner; - /* - * pads the TSS to be cacheline-aligned (size is 0x100) - */ - unsigned long __cacheline_filler[35]; - /* - * .. and then another 0x100 bytes for emergency kernel stack - */ - unsigned long stack[64]; -} __attribute__((packed)); - #define ARCH_MIN_TASKALIGN 16 struct thread_struct { @@ -482,30 +433,8 @@ struct thread_struct { .io_bitmap_ptr = NULL, \ } -/* - * Note that the .io_bitmap member must be extra-big. This is because - * the CPU will access an additional byte beyond the end of the IO - * permission bitmap. The extra byte must be all 1 bits, and must - * be within the limit. - */ -#define INIT_TSS { \ - .esp0 = sizeof(init_stack) + (long)&init_stack, \ - .ss0 = __KERNEL_DS, \ - .ss1 = __KERNEL_CS, \ - .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \ - .io_bitmap = { [ 0 ... IO_BITMAP_LONGS] = ~0 }, \ -} - -static inline void load_esp0(struct tss_struct *tss, struct thread_struct *thread) -{ - tss->esp0 = thread->esp0; - /* This can only happen when SEP is enabled, no need to test "SEP"arately */ - if (unlikely(tss->ss1 != thread->sysenter_cs)) { - tss->ss1 = thread->sysenter_cs; - wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); - } - HYPERVISOR_stack_switch(tss->ss0, tss->esp0); -} +#define load_esp0(tss, thread) \ + HYPERVISOR_stack_switch(__KERNEL_DS, (thread)->esp0) #define start_thread(regs, new_eip, new_esp) do { \ __asm__("movl %0,%%fs ; movl %0,%%gs": :"r" (0)); \