ia64/xen-unstable

changeset 8927:16a91d8dd8ed

Eliminate tss - tss is meaningless in a paravirtualized kernel
and consumes 25% of the per-cpu area.
Add CONFIG_X86_NO_TSS to exclude all code which references tss.
Add CONFIG_X86_SYSENTER to conditionally include support for sysenter.
Change CONFIG_DOUBLEFAULT to depend on !CONFIG_X86_NO_TSS.
(sysenter and doublefault need tss).

Based on a patch by Jan Beulich <JBeulich@novell.com>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Mon Feb 20 14:46:14 2006 +0000 (2006-02-20)
parents f97dd89691e7
children f0a8a0a9a6f5
files linux-2.6-xen-sparse/arch/i386/Kconfig linux-2.6-xen-sparse/arch/i386/kernel/Makefile linux-2.6-xen-sparse/arch/i386/kernel/asm-offsets.c linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S linux-2.6-xen-sparse/arch/i386/kernel/init_task-xen.c linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c linux-2.6-xen-sparse/arch/i386/kernel/vm86.c linux-2.6-xen-sparse/arch/i386/kernel/vsyscall.S linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/desc.h linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/i386/Kconfig	Mon Feb 20 14:37:13 2006 +0000
     1.2 +++ b/linux-2.6-xen-sparse/arch/i386/Kconfig	Mon Feb 20 14:46:14 2006 +0000
     1.3 @@ -780,7 +780,7 @@ config HOTPLUG_CPU
     1.4  config DOUBLEFAULT
     1.5  	default y
     1.6  	bool "Enable doublefault exception handler" if EMBEDDED
     1.7 -	depends on !XEN
     1.8 +	depends on !X86_NO_TSS
     1.9  	help
    1.10            This option allows trapping of rare doublefault exceptions that
    1.11            would otherwise cause a system to silently reboot. Disabling this
    1.12 @@ -1176,6 +1176,16 @@ config X86_TRAMPOLINE
    1.13  	depends on X86_SMP || (X86_VOYAGER && SMP)
    1.14  	default y
    1.15  
    1.16 +config X86_NO_TSS
    1.17 +	bool
    1.18 +	depends on X86_XEN
    1.19 +	default y
    1.20 +
    1.21 +config X86_SYSENTER
    1.22 +	bool
    1.23 +	depends on !X86_NO_TSS
    1.24 +	default y
    1.25 +
    1.26  config KTIME_SCALAR
    1.27  	bool
    1.28  	default y
     2.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/Makefile	Mon Feb 20 14:37:13 2006 +0000
     2.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/Makefile	Mon Feb 20 14:46:14 2006 +0000
     2.3 @@ -49,11 +49,13 @@ else
     2.4  vsyscall_note := vsyscall-note.o
     2.5  endif
     2.6  
     2.7 +VSYSCALL_TYPES-y			:= int80
     2.8 +VSYSCALL_TYPES-$(CONFIG_X86_SYSENTER)	+= sysenter
     2.9  # vsyscall.o contains the vsyscall DSO images as __initdata.
    2.10  # We must build both images before we can assemble it.
    2.11  # Note: kbuild does not track this dependency due to usage of .incbin
    2.12 -$(obj)/vsyscall.o: $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so
    2.13 -targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so)
    2.14 +$(obj)/vsyscall.o: $(foreach F,$(VSYSCALL_TYPES-y),$(obj)/vsyscall-$F.so)
    2.15 +targets += $(foreach F,$(VSYSCALL_TYPES-y),vsyscall-$F.o vsyscall-$F.so)
    2.16  targets += $(vsyscall_note) vsyscall.lds
    2.17  
    2.18  # The DSO images are built using a special linker script.
    2.19 @@ -81,7 +83,8 @@ extra-y += vsyscall-syms.o
    2.20  
    2.21  SYSCFLAGS_vsyscall-syms.o = -r
    2.22  $(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \
    2.23 -			$(obj)/vsyscall-sysenter.o $(obj)/$(vsyscall_note) FORCE
    2.24 +			$(foreach F,$(VSYSCALL_TYPES-y),$(obj)/vsyscall-$F.o) \
    2.25 +			$(obj)/$(vsyscall_note) FORCE
    2.26  	$(call if_changed,syscall)
    2.27  
    2.28  ifdef CONFIG_XEN
     3.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/asm-offsets.c	Mon Feb 20 14:37:13 2006 +0000
     3.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/asm-offsets.c	Mon Feb 20 14:46:14 2006 +0000
     3.3 @@ -63,9 +63,11 @@ void foo(void)
     3.4  	OFFSET(pbe_orig_address, pbe, orig_address);
     3.5  	OFFSET(pbe_next, pbe, next);
     3.6  
     3.7 +#ifdef CONFIG_X86_SYSENTER
     3.8  	/* Offset from the sysenter stack to tss.esp0 */
     3.9  	DEFINE(TSS_sysenter_esp0, offsetof(struct tss_struct, esp0) -
    3.10  		 sizeof(struct tss_struct));
    3.11 +#endif
    3.12  
    3.13  	DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
    3.14  	DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL));
     4.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c	Mon Feb 20 14:37:13 2006 +0000
     4.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c	Mon Feb 20 14:46:14 2006 +0000
     4.3 @@ -595,7 +595,9 @@ void __cpuinit cpu_gdt_init(struct Xgt_d
     4.4  void __cpuinit cpu_init(void)
     4.5  {
     4.6  	int cpu = smp_processor_id();
     4.7 +#ifdef CONFIG_DOUBLEFAULT
     4.8  	struct tss_struct * t = &per_cpu(init_tss, cpu);
     4.9 +#endif
    4.10  	struct thread_struct *thread = &current->thread;
    4.11  
    4.12  	if (cpu_test_and_set(cpu, cpu_initialized)) {
     5.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S	Mon Feb 20 14:37:13 2006 +0000
     5.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S	Mon Feb 20 14:46:14 2006 +0000
     5.3 @@ -223,6 +223,7 @@ need_resched:
     5.4  	jmp need_resched
     5.5  #endif
     5.6  
     5.7 +#ifdef CONFIG_X86_SYSENTER
     5.8  /* SYSENTER_RETURN points to after the "sysenter" instruction in
     5.9     the vsyscall page.  See vsyscall-sysentry.S, which defines the symbol.  */
    5.10  
    5.11 @@ -270,6 +271,7 @@ 1:	movl (%ebp),%ebp
    5.12  	xorl %ebp,%ebp
    5.13  	sti
    5.14  	sysexit
    5.15 +#endif /* CONFIG_X86_SYSENTER */
    5.16  
    5.17  
    5.18  	# system call handler stub
    5.19 @@ -662,6 +664,7 @@ ENTRY(device_not_available)
    5.20  	call math_state_restore
    5.21  	jmp ret_from_exception
    5.22  
    5.23 +#ifdef CONFIG_X86_SYSENTER
    5.24  /*
    5.25   * Debug traps and NMI can happen at the one SYSENTER instruction
    5.26   * that sets up the real kernel stack. Check here, since we can't
    5.27 @@ -683,12 +686,15 @@ label:						\
    5.28  	pushfl;					\
    5.29  	pushl $__KERNEL_CS;			\
    5.30  	pushl $sysenter_past_esp
    5.31 +#endif /* CONFIG_X86_SYSENTER */
    5.32  
    5.33  KPROBE_ENTRY(debug)
    5.34 +#ifdef CONFIG_X86_SYSENTER
    5.35  	cmpl $sysenter_entry,(%esp)
    5.36  	jne debug_stack_correct
    5.37  	FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
    5.38  debug_stack_correct:
    5.39 +#endif /* !CONFIG_X86_SYSENTER */
    5.40  	pushl $-1			# mark this as an int
    5.41  	SAVE_ALL
    5.42  	xorl %edx,%edx			# error code 0
     6.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/init_task-xen.c	Mon Feb 20 14:37:13 2006 +0000
     6.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/init_task-xen.c	Mon Feb 20 14:46:14 2006 +0000
     6.3 @@ -41,9 +41,11 @@ struct task_struct init_task = INIT_TASK
     6.4  
     6.5  EXPORT_SYMBOL(init_task);
     6.6  
     6.7 +#ifndef CONFIG_X86_NO_TSS
     6.8  /*
     6.9   * per-CPU TSS segments. Threads are completely 'soft' on Linux,
    6.10   * no more per-task TSS's.
    6.11   */ 
    6.12  DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
    6.13 +#endif
    6.14  
     7.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c	Mon Feb 20 14:37:13 2006 +0000
     7.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c	Mon Feb 20 14:46:14 2006 +0000
     7.3 @@ -518,7 +518,9 @@ struct task_struct fastcall * __switch_t
     7.4  	struct thread_struct *prev = &prev_p->thread,
     7.5  				 *next = &next_p->thread;
     7.6  	int cpu = smp_processor_id();
     7.7 +#ifndef CONFIG_X86_NO_TSS
     7.8  	struct tss_struct *tss = &per_cpu(init_tss, cpu);
     7.9 +#endif
    7.10  	physdev_op_t iopl_op, iobmp_op;
    7.11  	multicall_entry_t _mcl[8], *mcl = _mcl;
    7.12  
    7.13 @@ -543,10 +545,9 @@ struct task_struct fastcall * __switch_t
    7.14  	 * Reload esp0.
    7.15  	 * This is load_esp0(tss, next) with a multicall.
    7.16  	 */
    7.17 -	tss->esp0 = next->esp0;
    7.18  	mcl->op      = __HYPERVISOR_stack_switch;
    7.19 -	mcl->args[0] = tss->ss0;
    7.20 -	mcl->args[1] = tss->esp0;
    7.21 +	mcl->args[0] = __KERNEL_DS;
    7.22 +	mcl->args[1] = next->esp0;
    7.23  	mcl++;
    7.24  
    7.25  	/*
     8.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c	Mon Feb 20 14:37:13 2006 +0000
     8.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c	Mon Feb 20 14:46:14 2006 +0000
     8.3 @@ -23,6 +23,7 @@ extern asmlinkage void sysenter_entry(vo
     8.4  
     8.5  void enable_sep_cpu(void)
     8.6  {
     8.7 +#ifdef CONFIG_X86_SYSENTER
     8.8  	int cpu = get_cpu();
     8.9  	struct tss_struct *tss = &per_cpu(init_tss, cpu);
    8.10  
    8.11 @@ -37,6 +38,7 @@ void enable_sep_cpu(void)
    8.12  	wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp1, 0);
    8.13  	wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0);
    8.14  	put_cpu();	
    8.15 +#endif
    8.16  }
    8.17  
    8.18  /*
    8.19 @@ -52,16 +54,18 @@ int __init sysenter_setup(void)
    8.20  
    8.21  	__set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY_EXEC);
    8.22  
    8.23 -	if (!boot_cpu_has(X86_FEATURE_SEP)) {
    8.24 +#ifdef CONFIG_X86_SYSENTER
    8.25 +	if (boot_cpu_has(X86_FEATURE_SEP)) {
    8.26  		memcpy(page,
    8.27 -		       &vsyscall_int80_start,
    8.28 -		       &vsyscall_int80_end - &vsyscall_int80_start);
    8.29 +		       &vsyscall_sysenter_start,
    8.30 +		       &vsyscall_sysenter_end - &vsyscall_sysenter_start);
    8.31  		return 0;
    8.32  	}
    8.33 +#endif
    8.34  
    8.35  	memcpy(page,
    8.36 -	       &vsyscall_sysenter_start,
    8.37 -	       &vsyscall_sysenter_end - &vsyscall_sysenter_start);
    8.38 +	       &vsyscall_int80_start,
    8.39 +	       &vsyscall_int80_end - &vsyscall_int80_start);
    8.40  
    8.41  	return 0;
    8.42  }
     9.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/vm86.c	Mon Feb 20 14:37:13 2006 +0000
     9.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/vm86.c	Mon Feb 20 14:46:14 2006 +0000
     9.3 @@ -97,7 +97,9 @@
     9.4  struct pt_regs * FASTCALL(save_v86_state(struct kernel_vm86_regs * regs));
     9.5  struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs)
     9.6  {
     9.7 +#ifndef CONFIG_X86_NO_TSS
     9.8  	struct tss_struct *tss;
     9.9 +#endif
    9.10  	struct pt_regs *ret;
    9.11  	unsigned long tmp;
    9.12  
    9.13 @@ -122,7 +124,9 @@ struct pt_regs * fastcall save_v86_state
    9.14  		do_exit(SIGSEGV);
    9.15  	}
    9.16  
    9.17 +#ifndef CONFIG_X86_NO_TSS
    9.18  	tss = &per_cpu(init_tss, get_cpu());
    9.19 +#endif
    9.20  	current->thread.esp0 = current->thread.saved_esp0;
    9.21  	current->thread.sysenter_cs = __KERNEL_CS;
    9.22  	load_esp0(tss, &current->thread);
    9.23 @@ -251,7 +255,9 @@ out:
    9.24  
    9.25  static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk)
    9.26  {
    9.27 +#ifndef CONFIG_X86_NO_TSS
    9.28  	struct tss_struct *tss;
    9.29 +#endif
    9.30  /*
    9.31   * make sure the vm86() system call doesn't try to do anything silly
    9.32   */
    9.33 @@ -295,7 +301,9 @@ static void do_sys_vm86(struct kernel_vm
    9.34  	savesegment(fs, tsk->thread.saved_fs);
    9.35  	savesegment(gs, tsk->thread.saved_gs);
    9.36  
    9.37 +#ifndef CONFIG_X86_NO_TSS
    9.38  	tss = &per_cpu(init_tss, get_cpu());
    9.39 +#endif
    9.40  	tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
    9.41  	if (cpu_has_sep)
    9.42  		tsk->thread.sysenter_cs = 0;
    10.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/vsyscall.S	Mon Feb 20 14:37:13 2006 +0000
    10.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/vsyscall.S	Mon Feb 20 14:46:14 2006 +0000
    10.3 @@ -7,9 +7,11 @@ vsyscall_int80_start:
    10.4  	.incbin "arch/i386/kernel/vsyscall-int80.so"
    10.5  vsyscall_int80_end:
    10.6  
    10.7 +#ifdef CONFIG_X86_SYSENTER
    10.8  	.globl vsyscall_sysenter_start, vsyscall_sysenter_end
    10.9  vsyscall_sysenter_start:
   10.10  	.incbin "arch/i386/kernel/vsyscall-sysenter.so"
   10.11  vsyscall_sysenter_end:
   10.12 +#endif
   10.13  
   10.14  __FINIT
    11.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/desc.h	Mon Feb 20 14:37:13 2006 +0000
    11.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/desc.h	Mon Feb 20 14:46:14 2006 +0000
    11.3 @@ -61,6 +61,7 @@ extern void set_intr_gate(unsigned int i
    11.4  	"rorl $16,%1" \
    11.5  	: "=m"(*(n)) : "q" (addr), "r"(n), "ir"(limit), "i"(type))
    11.6  
    11.7 +#ifndef CONFIG_X86_NO_TSS
    11.8  static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
    11.9  {
   11.10  	_set_tssldt_desc(&get_cpu_gdt_table(cpu)[entry], (int)addr,
   11.11 @@ -68,6 +69,7 @@ static inline void __set_tss_desc(unsign
   11.12  }
   11.13  
   11.14  #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
   11.15 +#endif
   11.16  
   11.17  static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
   11.18  {
    12.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h	Mon Feb 20 14:37:13 2006 +0000
    12.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h	Mon Feb 20 14:46:14 2006 +0000
    12.3 @@ -91,8 +91,10 @@ struct cpuinfo_x86 {
    12.4  
    12.5  extern struct cpuinfo_x86 boot_cpu_data;
    12.6  extern struct cpuinfo_x86 new_cpu_data;
    12.7 +#ifndef CONFIG_X86_NO_TSS
    12.8  extern struct tss_struct doublefault_tss;
    12.9  DECLARE_PER_CPU(struct tss_struct, init_tss);
   12.10 +#endif
   12.11  
   12.12  #ifdef CONFIG_SMP
   12.13  extern struct cpuinfo_x86 cpu_data[];
   12.14 @@ -343,7 +345,9 @@ extern int bootloader_type;
   12.15  #define IO_BITMAP_BITS  65536
   12.16  #define IO_BITMAP_BYTES (IO_BITMAP_BITS/8)
   12.17  #define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))
   12.18 +#ifndef CONFIG_X86_NO_TSS
   12.19  #define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
   12.20 +#endif
   12.21  #define INVALID_IO_BITMAP_OFFSET 0x8000
   12.22  #define INVALID_IO_BITMAP_OFFSET_LAZY 0x9000
   12.23  
   12.24 @@ -401,6 +405,7 @@ typedef struct {
   12.25  
   12.26  struct thread_struct;
   12.27  
   12.28 +#ifndef CONFIG_X86_NO_TSS
   12.29  struct tss_struct {
   12.30  	unsigned short	back_link,__blh;
   12.31  	unsigned long	esp0;
   12.32 @@ -446,6 +451,7 @@ struct tss_struct {
   12.33  	 */
   12.34  	unsigned long stack[64];
   12.35  } __attribute__((packed));
   12.36 +#endif
   12.37  
   12.38  #define ARCH_MIN_TASKALIGN	16
   12.39  
   12.40 @@ -482,6 +488,7 @@ struct thread_struct {
   12.41  	.io_bitmap_ptr = NULL,						\
   12.42  }
   12.43  
   12.44 +#ifndef CONFIG_X86_NO_TSS
   12.45  /*
   12.46   * Note that the .io_bitmap member must be extra-big. This is because
   12.47   * the CPU will access an additional byte beyond the end of the IO
   12.48 @@ -504,8 +511,11 @@ static inline void load_esp0(struct tss_
   12.49  		tss->ss1 = thread->sysenter_cs;
   12.50  		wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0);
   12.51  	}
   12.52 -	HYPERVISOR_stack_switch(tss->ss0, tss->esp0);
   12.53  }
   12.54 +#else
   12.55 +#define load_esp0(tss, thread) \
   12.56 +	HYPERVISOR_stack_switch(__KERNEL_DS, (thread)->esp0)
   12.57 +#endif
   12.58  
   12.59  #define start_thread(regs, new_eip, new_esp) do {		\
   12.60  	__asm__("movl %0,%%fs ; movl %0,%%gs": :"r" (0));	\