# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID 16a91d8dd8ed1193f6d58a61d85929ea81fc946c
# Parent f97dd89691e7b1f737410a70d229f252883b6b95
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@xxxxxxxxxx>
Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>
diff -r f97dd89691e7 -r 16a91d8dd8ed linux-2.6-xen-sparse/arch/i386/Kconfig
--- a/linux-2.6-xen-sparse/arch/i386/Kconfig Mon Feb 20 14:37:13 2006
+++ b/linux-2.6-xen-sparse/arch/i386/Kconfig Mon Feb 20 14:46:14 2006
@@ -780,7 +780,7 @@
config DOUBLEFAULT
default y
bool "Enable doublefault exception handler" if EMBEDDED
- depends on !XEN
+ depends on !X86_NO_TSS
help
This option allows trapping of rare doublefault exceptions that
would otherwise cause a system to silently reboot. Disabling this
@@ -1176,6 +1176,16 @@
depends on X86_SMP || (X86_VOYAGER && SMP)
default y
+config X86_NO_TSS
+ bool
+ depends on X86_XEN
+ default y
+
+config X86_SYSENTER
+ bool
+ depends on !X86_NO_TSS
+ default y
+
config KTIME_SCALAR
bool
default y
diff -r f97dd89691e7 -r 16a91d8dd8ed
linux-2.6-xen-sparse/arch/i386/kernel/Makefile
--- a/linux-2.6-xen-sparse/arch/i386/kernel/Makefile Mon Feb 20 14:37:13 2006
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/Makefile Mon Feb 20 14:46:14 2006
@@ -49,11 +49,13 @@
vsyscall_note := vsyscall-note.o
endif
+VSYSCALL_TYPES-y := int80
+VSYSCALL_TYPES-$(CONFIG_X86_SYSENTER) += sysenter
# vsyscall.o contains the vsyscall DSO images as __initdata.
# We must build both images before we can assemble it.
# Note: kbuild does not track this dependency due to usage of .incbin
-$(obj)/vsyscall.o: $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so
-targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so)
+$(obj)/vsyscall.o: $(foreach F,$(VSYSCALL_TYPES-y),$(obj)/vsyscall-$F.so)
+targets += $(foreach F,$(VSYSCALL_TYPES-y),vsyscall-$F.o vsyscall-$F.so)
targets += $(vsyscall_note) vsyscall.lds
# The DSO images are built using a special linker script.
@@ -81,7 +83,8 @@
SYSCFLAGS_vsyscall-syms.o = -r
$(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \
- $(obj)/vsyscall-sysenter.o $(obj)/$(vsyscall_note) FORCE
+ $(foreach F,$(VSYSCALL_TYPES-y),$(obj)/vsyscall-$F.o) \
+ $(obj)/$(vsyscall_note) FORCE
$(call if_changed,syscall)
ifdef CONFIG_XEN
diff -r f97dd89691e7 -r 16a91d8dd8ed
linux-2.6-xen-sparse/arch/i386/kernel/asm-offsets.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/asm-offsets.c Mon Feb 20
14:37:13 2006
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/asm-offsets.c Mon Feb 20
14:46:14 2006
@@ -63,9 +63,11 @@
OFFSET(pbe_orig_address, pbe, orig_address);
OFFSET(pbe_next, pbe, next);
+#ifdef CONFIG_X86_SYSENTER
/* 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));
diff -r f97dd89691e7 -r 16a91d8dd8ed
linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c Mon Feb 20
14:37:13 2006
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c Mon Feb 20
14:46:14 2006
@@ -595,7 +595,9 @@
void __cpuinit cpu_init(void)
{
int cpu = smp_processor_id();
+#ifdef CONFIG_DOUBLEFAULT
struct tss_struct * t = &per_cpu(init_tss, cpu);
+#endif
struct thread_struct *thread = ¤t->thread;
if (cpu_test_and_set(cpu, cpu_initialized)) {
diff -r f97dd89691e7 -r 16a91d8dd8ed
linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S
--- a/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S Mon Feb 20 14:37:13 2006
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S Mon Feb 20 14:46:14 2006
@@ -223,6 +223,7 @@
jmp need_resched
#endif
+#ifdef CONFIG_X86_SYSENTER
/* SYSENTER_RETURN points to after the "sysenter" instruction in
the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */
@@ -270,6 +271,7 @@
xorl %ebp,%ebp
sti
sysexit
+#endif /* CONFIG_X86_SYSENTER */
# system call handler stub
@@ -662,6 +664,7 @@
call math_state_restore
jmp ret_from_exception
+#ifdef CONFIG_X86_SYSENTER
/*
* 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 @@
pushfl; \
pushl $__KERNEL_CS; \
pushl $sysenter_past_esp
+#endif /* CONFIG_X86_SYSENTER */
KPROBE_ENTRY(debug)
+#ifdef CONFIG_X86_SYSENTER
cmpl $sysenter_entry,(%esp)
jne debug_stack_correct
FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
debug_stack_correct:
+#endif /* !CONFIG_X86_SYSENTER */
pushl $-1 # mark this as an int
SAVE_ALL
xorl %edx,%edx # error code 0
diff -r f97dd89691e7 -r 16a91d8dd8ed
linux-2.6-xen-sparse/arch/i386/kernel/init_task-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/init_task-xen.c Mon Feb 20
14:37:13 2006
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/init_task-xen.c Mon Feb 20
14:46:14 2006
@@ -41,9 +41,11 @@
EXPORT_SYMBOL(init_task);
+#ifndef CONFIG_X86_NO_TSS
/*
* 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
diff -r f97dd89691e7 -r 16a91d8dd8ed
linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c Mon Feb 20
14:37:13 2006
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c Mon Feb 20
14:46:14 2006
@@ -518,7 +518,9 @@
struct thread_struct *prev = &prev_p->thread,
*next = &next_p->thread;
int cpu = smp_processor_id();
+#ifndef CONFIG_X86_NO_TSS
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 @@
* 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++;
/*
diff -r f97dd89691e7 -r 16a91d8dd8ed
linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c Mon Feb 20 14:37:13 2006
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c Mon Feb 20 14:46:14 2006
@@ -23,6 +23,7 @@
void enable_sep_cpu(void)
{
+#ifdef CONFIG_X86_SYSENTER
int cpu = get_cpu();
struct tss_struct *tss = &per_cpu(init_tss, cpu);
@@ -37,6 +38,7 @@
wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp1, 0);
wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0);
put_cpu();
+#endif
}
/*
@@ -52,16 +54,18 @@
__set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY_EXEC);
- if (!boot_cpu_has(X86_FEATURE_SEP)) {
+#ifdef CONFIG_X86_SYSENTER
+ if (boot_cpu_has(X86_FEATURE_SEP)) {
memcpy(page,
- &vsyscall_int80_start,
- &vsyscall_int80_end - &vsyscall_int80_start);
+ &vsyscall_sysenter_start,
+ &vsyscall_sysenter_end - &vsyscall_sysenter_start);
return 0;
}
+#endif
memcpy(page,
- &vsyscall_sysenter_start,
- &vsyscall_sysenter_end - &vsyscall_sysenter_start);
+ &vsyscall_int80_start,
+ &vsyscall_int80_end - &vsyscall_int80_start);
return 0;
}
diff -r f97dd89691e7 -r 16a91d8dd8ed
linux-2.6-xen-sparse/arch/i386/kernel/vm86.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/vm86.c Mon Feb 20 14:37:13 2006
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/vm86.c Mon Feb 20 14:46:14 2006
@@ -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_X86_NO_TSS
struct tss_struct *tss;
+#endif
struct pt_regs *ret;
unsigned long tmp;
@@ -122,7 +124,9 @@
do_exit(SIGSEGV);
}
+#ifndef CONFIG_X86_NO_TSS
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,9 @@
static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct
*tsk)
{
+#ifndef CONFIG_X86_NO_TSS
struct tss_struct *tss;
+#endif
/*
* make sure the vm86() system call doesn't try to do anything silly
*/
@@ -295,7 +301,9 @@
savesegment(fs, tsk->thread.saved_fs);
savesegment(gs, tsk->thread.saved_gs);
+#ifndef CONFIG_X86_NO_TSS
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;
diff -r f97dd89691e7 -r 16a91d8dd8ed
linux-2.6-xen-sparse/arch/i386/kernel/vsyscall.S
--- a/linux-2.6-xen-sparse/arch/i386/kernel/vsyscall.S Mon Feb 20 14:37:13 2006
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/vsyscall.S Mon Feb 20 14:46:14 2006
@@ -7,9 +7,11 @@
.incbin "arch/i386/kernel/vsyscall-int80.so"
vsyscall_int80_end:
+#ifdef CONFIG_X86_SYSENTER
.globl vsyscall_sysenter_start, vsyscall_sysenter_end
vsyscall_sysenter_start:
.incbin "arch/i386/kernel/vsyscall-sysenter.so"
vsyscall_sysenter_end:
+#endif
__FINIT
diff -r f97dd89691e7 -r 16a91d8dd8ed
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/desc.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/desc.h Mon Feb 20
14:37:13 2006
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/desc.h Mon Feb 20
14:46:14 2006
@@ -61,6 +61,7 @@
"rorl $16,%1" \
: "=m"(*(n)) : "q" (addr), "r"(n), "ir"(limit), "i"(type))
+#ifndef CONFIG_X86_NO_TSS
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,
@@ -68,6 +69,7 @@
}
#define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
+#endif
static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int
size)
{
diff -r f97dd89691e7 -r 16a91d8dd8ed
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h Mon Feb
20 14:37:13 2006
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h Mon Feb
20 14:46:14 2006
@@ -91,8 +91,10 @@
extern struct cpuinfo_x86 boot_cpu_data;
extern struct cpuinfo_x86 new_cpu_data;
+#ifndef CONFIG_X86_NO_TSS
extern struct tss_struct doublefault_tss;
DECLARE_PER_CPU(struct tss_struct, init_tss);
+#endif
#ifdef CONFIG_SMP
extern struct cpuinfo_x86 cpu_data[];
@@ -343,7 +345,9 @@
#define IO_BITMAP_BITS 65536
#define IO_BITMAP_BYTES (IO_BITMAP_BITS/8)
#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))
+#ifndef CONFIG_X86_NO_TSS
#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
+#endif
#define INVALID_IO_BITMAP_OFFSET 0x8000
#define INVALID_IO_BITMAP_OFFSET_LAZY 0x9000
@@ -401,6 +405,7 @@
struct thread_struct;
+#ifndef CONFIG_X86_NO_TSS
struct tss_struct {
unsigned short back_link,__blh;
unsigned long esp0;
@@ -446,6 +451,7 @@
*/
unsigned long stack[64];
} __attribute__((packed));
+#endif
#define ARCH_MIN_TASKALIGN 16
@@ -482,6 +488,7 @@
.io_bitmap_ptr = NULL, \
}
+#ifndef CONFIG_X86_NO_TSS
/*
* 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
@@ -504,8 +511,11 @@
tss->ss1 = thread->sysenter_cs;
wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0);
}
- HYPERVISOR_stack_switch(tss->ss0, tss->esp0);
-}
+}
+#else
+#define load_esp0(tss, thread) \
+ HYPERVISOR_stack_switch(__KERNEL_DS, (thread)->esp0)
+#endif
#define start_thread(regs, new_eip, new_esp) do { \
__asm__("movl %0,%%fs ; movl %0,%%gs": :"r" (0)); \
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|