Now that i686 PAE and x86_64 Xen DomU support is fully upstream, re-enable it in the stock kernel. The only not-upstream patches we require are to support execshield Also note the Obsoletes/Provides to make upgrades go smoothely. Index: devel/config-x86-generic =================================================================== --- devel.orig/config-x86-generic 2008-07-23 14:06:22.000000000 +0100 +++ devel.orig/config-x86-generic 2008-07-23 14:06:22.000000000 +0100 @@ -340,10 +340,20 @@ CONFIG_PARAVIRT=y # CONFIG_PARAVIRT_DEBUG is not set CONFIG_KVM_CLOCK=y CONFIG_KVM_GUEST=y -# CONFIG_XEN is not set CONFIG_LGUEST_GUEST=y CONFIG_VMI=y +CONFIG_XEN=y +CONFIG_XEN_MAX_DOMAIN_MEMORY=8 +CONFIG_XEN_BALLOON=y +CONFIG_XEN_SCRUB_PAGES=y +CONFIG_XEN_SAVE_RESTORE=y +CONFIG_HVC_XEN=y +CONFIG_XEN_FBDEV_FRONTEND=y +CONFIG_XEN_KBDDEV_FRONTEND=y +CONFIG_XEN_BLKDEV_FRONTEND=m +CONFIG_XEN_NETDEV_FRONTEND=m + CONFIG_MTD_ESB2ROM=m CONFIG_MTD_CK804XROM=m CONFIG_MTD_NAND_CAFE=m Index: devel/config-x86_64-generic =================================================================== --- devel.orig/config-x86_64-generic 2008-07-23 14:06:22.000000000 +0100 +++ devel.orig/config-x86_64-generic 2008-07-23 14:06:22.000000000 +0100 @@ -258,7 +258,17 @@ CONFIG_PARAVIRT=y # CONFIG_PARAVIRT_DEBUG is not set CONFIG_KVM_CLOCK=y CONFIG_KVM_GUEST=y -# CONFIG_XEN is not set + +CONFIG_XEN=y +CONFIG_XEN_MAX_DOMAIN_MEMORY=32 +CONFIG_XEN_BALLOON=y +CONFIG_XEN_SCRUB_PAGES=y +CONFIG_XEN_SAVE_RESTORE=y +CONFIG_HVC_XEN=y +CONFIG_XEN_FBDEV_FRONTEND=y +CONFIG_XEN_KBDDEV_FRONTEND=y +CONFIG_XEN_BLKDEV_FRONTEND=m +CONFIG_XEN_NETDEV_FRONTEND=m CONFIG_DMADEVICES=y CONFIG_INTEL_IOATDMA=m Index: devel/kernel.spec =================================================================== --- devel.orig/kernel.spec 2008-07-23 14:06:22.000000000 +0100 +++ devel.orig/kernel.spec 2008-07-23 14:06:22.000000000 +0100 @@ -372,7 +372,13 @@ Summary: The Linux kernel # upto and including kernel 2.4.9 rpms, the 4Gb+ kernel was called kernel-enterprise # now that the smp kernel offers this capability, obsolete the old kernel %define kernel_smp_obsoletes kernel-enterprise < 2.4.10 -%define kernel_PAE_obsoletes kernel-smp < 2.6.17 +%define kernel_PAE_obsoletes kernel-smp < 2.6.17, kernel-xen <= 2.6.27-0.2.rc0.git6.fc10 +%define kernel_PAE_provides kernel-xen = %{rpmversion}-%{pkg_release} + +%ifarch x86_64 +%define kernel_obsoletes kernel-xen <= 2.6.27-0.2.rc0.git6.fc10 +%define kernel_provides kernel-xen = %{rpmversion}-%{pkg_release} +%endif # We moved the drm include files into kernel-headers, make sure there's # a recent enough libdrm-devel on the system that doesn't have those. @@ -548,6 +554,9 @@ Patch147: linux-2.6-imac-transparent-bri Patch149: linux-2.6-efika-not-chrp.patch Patch160: linux-2.6-execshield.patch +Patch161: linux-2.6-xen-execshield-add-xen-specific-load_user_cs_desc.patch +Patch162: linux-2.6-xen-execshield-fix-endless-gpf-fault-loop.patch +Patch163: linux-2.6-xen-execshield-only-define-load_user_cs_desc-on-32-bit.patch Patch250: linux-2.6-debug-sizeof-structs.patch Patch260: linux-2.6-debug-nmi-timeout.patch Patch270: linux-2.6-debug-taint-vm.patch @@ -987,6 +996,9 @@ ApplyPatch linux-2.6-imac-transparent-br # Exec shield # ApplyPatch linux-2.6-execshield.patch +ApplyPatch linux-2.6-xen-execshield-add-xen-specific-load_user_cs_desc.patch +ApplyPatch linux-2.6-xen-execshield-fix-endless-gpf-fault-loop.patch +ApplyPatch linux-2.6-xen-execshield-only-define-load_user_cs_desc-on-32-bit.patch # # bugfixes to drivers and filesystems Index: devel/linux-2.6-xen-execshield-add-xen-specific-load_user_cs_desc.patch =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -0,0 +1,126 @@ +From cdff48f3077459f1dfaf243db8e402c8202a2693 Mon Sep 17 00:00:00 2001 +From: Stephen Tweedie +Date: Tue, 11 Mar 2008 18:05:30 +0000 +Subject: [PATCH] xen execshield: Add xen-specific load_user_cs_desc() + +x86 32-bit execshield uses load_user_cs_desc() to setup the user CS +descriptor, but the Xen version needs to do this via a hypercall. + +Add this via a new pv_cpu_ops->load_user_cs_desc pv_ops indirection +so that it can be selected appropriately at run-time. + +Signed-off-by: Stephen Tweedie +--- + arch/x86/kernel/paravirt.c | 1 + + arch/x86/xen/enlighten.c | 17 +++++++++++++++++ + include/asm-x86/desc.h | 8 ++++++-- + include/asm-x86/paravirt.h | 6 ++++++ + 4 files changed, 30 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c +index 94da4d5..f2a678c 100644 +--- a/arch/x86/kernel/paravirt.c ++++ b/arch/x86/kernel/paravirt.c +@@ -336,6 +336,7 @@ struct pv_cpu_ops pv_cpu_ops = { + .read_tscp = native_read_tscp, + .load_tr_desc = native_load_tr_desc, + .set_ldt = native_set_ldt, ++ .load_user_cs_desc = native_load_user_cs_desc, + .load_gdt = native_load_gdt, + .load_idt = native_load_idt, + .store_gdt = native_store_gdt, +diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c +index 9ff6e3c..9b95277 100644 +--- a/arch/x86/xen/enlighten.c ++++ b/arch/x86/xen/enlighten.c +@@ -340,6 +340,22 @@ static void xen_set_ldt(const void *addr, unsigned entries) + xen_mc_issue(PARAVIRT_LAZY_CPU); + } + ++static inline void xen_load_user_cs_desc(int cpu, struct mm_struct *mm) ++{ ++ void *gdt; ++ xmaddr_t mgdt; ++ u64 descriptor; ++ struct desc_struct user_cs; ++ ++ gdt = &get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS]; ++ mgdt = virt_to_machine(gdt); ++ ++ user_cs = mm->context.user_cs; ++ descriptor = (u64) user_cs.a | ((u64) user_cs.b) << 32; ++ ++ HYPERVISOR_update_descriptor(mgdt.maddr, descriptor); ++} ++ + static void xen_load_gdt(const struct desc_ptr *dtr) + { + unsigned long *frames; +@@ -1213,6 +1229,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = { + + .load_tr_desc = paravirt_nop, + .set_ldt = xen_set_ldt, ++ .load_user_cs_desc = xen_load_user_cs_desc, + .load_gdt = xen_load_gdt, + .load_idt = xen_load_idt, + .load_tls = xen_load_tls, +diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h +index 3a545b1..713634f 100644 +--- a/include/asm-x86/desc.h ++++ b/include/asm-x86/desc.h +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + + static inline void fill_ldt(struct desc_struct *desc, + const struct user_desc *info) +@@ -90,6 +91,7 @@ static inline int desc_empty(const void *ptr) + + #define load_TLS(t, cpu) native_load_tls(t, cpu) + #define set_ldt native_set_ldt ++#define load_user_cs_desc native_load_user_cs_desc + + #define write_ldt_entry(dt, entry, desc) \ + native_write_ldt_entry(dt, entry, desc) +@@ -380,8 +382,10 @@ static inline void set_user_cs(struct desc_struct *desc, unsigned long limit) + desc->b = (limit & 0xf0000) | 0x00c0fb00; + } + +-#define load_user_cs_desc(cpu, mm) \ +- get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS] = (mm)->context.user_cs ++static inline void native_load_user_cs_desc(int cpu, struct mm_struct *mm) ++{ ++ get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS] = mm->context.user_cs; ++} + + extern void arch_add_exec_range(struct mm_struct *mm, unsigned long limit); + extern void arch_remove_exec_range(struct mm_struct *mm, unsigned long limit); +diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h +index fbbde93..151ac7a 100644 +--- a/include/asm-x86/paravirt.h ++++ b/include/asm-x86/paravirt.h +@@ -113,6 +113,7 @@ struct pv_cpu_ops { + void (*store_gdt)(struct desc_ptr *); + void (*store_idt)(struct desc_ptr *); + void (*set_ldt)(const void *desc, unsigned entries); ++ void (*load_user_cs_desc)(int cpu, struct mm_struct *mm); + unsigned long (*store_tr)(void); + void (*load_tls)(struct thread_struct *t, unsigned int cpu); + #ifdef CONFIG_X86_64 +@@ -840,6 +841,11 @@ static inline void set_ldt(const void *addr, unsigned entries) + { + PVOP_VCALL2(pv_cpu_ops.set_ldt, addr, entries); + } ++static inline void load_user_cs_desc(unsigned int cpu, ++ struct mm_struct *mm) ++{ ++ PVOP_VCALL2(pv_cpu_ops.load_user_cs_desc, cpu, mm); ++} + static inline void store_gdt(struct desc_ptr *dtr) + { + PVOP_VCALL1(pv_cpu_ops.store_gdt, dtr); +-- +1.5.4.1 + Index: devel/linux-2.6-xen-execshield-fix-endless-gpf-fault-loop.patch =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -0,0 +1,52 @@ +From ad6f7a1789fdb94b16952f50ed65964dc206d7be Mon Sep 17 00:00:00 2001 +From: Stephen Tweedie +Date: Tue, 11 Mar 2008 18:07:31 +0000 +Subject: [PATCH] xen execshield: fix endless GPF fault loop + +Under Xen, loading the user_cs descriptor does not necessarily load +the descriptor with the exact same values the kernel requested: some +of the control bits in the descriptor may be modified by the +hypervisor. + +With execshield, the check_lazy_exec_limit() function is needed to +test whether a fault has been caused by the existing user_cs +descriptor being too constrained: if so, it performs a lazy expansion +of the legal cs segment bounds. But it does so via an exact match on +the descriptor values against their current expected values, so if +Xen modifies any control bits in the descriptor, it looks as if the +user_cs is out-of-sync; so check_lazy_exec_limit() resets the +descriptor and retakes the fault unnecessarily. + +This means that a GPF fault can be retried indefinitely, with the +kernel always seeing the wrong values in user_cs and continually +trying to correct them and retake the fault. + +Fix it by masking off the xen-sensitive control bits when checking +that the segment descriptor is up-to-date, and comparing only the +bits which affect the segment base and limit. + +Affects 32-bit only; execshield on 64-bit uses NX for this +functionality. + +Signed-off-by: Stephen Tweedie +--- + arch/x86/kernel/traps_32.c | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c +index d001d55..c932b3e 100644 +--- a/arch/x86/kernel/traps_32.c ++++ b/arch/x86/kernel/traps_32.c +@@ -621,7 +621,8 @@ check_lazy_exec_limit(int cpu, struct pt_regs *regs, long error_code) + desc1 = ¤t->mm->context.user_cs; + desc2 = get_cpu_gdt_table(cpu) + GDT_ENTRY_DEFAULT_USER_CS; + +- if (desc1->a != desc2->a || desc1->b != desc2->b) { ++ if ((desc1->a & 0xff0000ff) != (desc2->a & 0xff0000ff) || ++ desc1->b != desc2->b) { + /* + * The CS was not in sync - reload it and retry the + * instruction. If the instruction still faults then +-- +1.5.4.1 + Index: devel/linux-2.6-xen-execshield-only-define-load_user_cs_desc-on-32-bit.patch =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -0,0 +1,122 @@ +From 226bc4b8f13ece618de046f6f8da88eeb4b8f8da Mon Sep 17 00:00:00 2001 +From: Mark McLoughlin +Date: Tue, 25 Mar 2008 11:56:43 +0000 +Subject: [PATCH] xen execshield: Only define load_user_cs_desc() on 32 bit + +load_user_cs_desc() is only used on 32 bit, so only +define it in that case. + +Fixes compile failure in native_load_user_cs_desc() +since mm_context_t->user_cs is only available on +32 bit. + +Signed-off-by: Mark McLoughlin +--- + arch/x86/kernel/paravirt.c | 2 ++ + arch/x86/xen/enlighten.c | 4 ++++ + include/asm-x86/desc.h | 4 ++++ + include/asm-x86/paravirt.h | 4 ++++ + 4 files changed, 14 insertions(+), 0 deletions(-) + +diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c +index f2a678c..4277d1a 100644 +--- a/arch/x86/kernel/paravirt.c ++++ b/arch/x86/kernel/paravirt.c +@@ -336,7 +336,9 @@ struct pv_cpu_ops pv_cpu_ops = { + .read_tscp = native_read_tscp, + .load_tr_desc = native_load_tr_desc, + .set_ldt = native_set_ldt, ++#ifdef CONFIG_X86_32 + .load_user_cs_desc = native_load_user_cs_desc, ++#endif + .load_gdt = native_load_gdt, + .load_idt = native_load_idt, + .store_gdt = native_store_gdt, +diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c +index 9b95277..c54060c 100644 +--- a/arch/x86/xen/enlighten.c ++++ b/arch/x86/xen/enlighten.c +@@ -340,6 +340,7 @@ static void xen_set_ldt(const void *addr, unsigned entries) + xen_mc_issue(PARAVIRT_LAZY_CPU); + } + ++#ifdef CONFIG_X86_32 + static inline void xen_load_user_cs_desc(int cpu, struct mm_struct *mm) + { + void *gdt; +@@ -355,6 +356,7 @@ static inline void xen_load_user_cs_desc(int cpu, struct mm_struct *mm) + + HYPERVISOR_update_descriptor(mgdt.maddr, descriptor); + } ++#endif + + static void xen_load_gdt(const struct desc_ptr *dtr) + { +@@ -1229,7 +1231,9 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = { + + .load_tr_desc = paravirt_nop, + .set_ldt = xen_set_ldt, ++#ifdef CONFIG_X86_32 + .load_user_cs_desc = xen_load_user_cs_desc, ++#endif + .load_gdt = xen_load_gdt, + .load_idt = xen_load_idt, + .load_tls = xen_load_tls, +diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h +index 713634f..54234ac 100644 +--- a/include/asm-x86/desc.h ++++ b/include/asm-x86/desc.h +@@ -91,7 +91,9 @@ static inline int desc_empty(const void *ptr) + + #define load_TLS(t, cpu) native_load_tls(t, cpu) + #define set_ldt native_set_ldt ++#ifdef CONFIG_X86_32 + #define load_user_cs_desc native_load_user_cs_desc ++#endif + + #define write_ldt_entry(dt, entry, desc) \ + native_write_ldt_entry(dt, entry, desc) +@@ -382,10 +384,12 @@ static inline void set_user_cs(struct desc_struct *desc, unsigned long limit) + desc->b = (limit & 0xf0000) | 0x00c0fb00; + } + ++#ifdef CONFIG_X86_32 + static inline void native_load_user_cs_desc(int cpu, struct mm_struct *mm) + { + get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS] = mm->context.user_cs; + } ++#endif + + extern void arch_add_exec_range(struct mm_struct *mm, unsigned long limit); + extern void arch_remove_exec_range(struct mm_struct *mm, unsigned long limit); +diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h +index 151ac7a..f354748 100644 +--- a/include/asm-x86/paravirt.h ++++ b/include/asm-x86/paravirt.h +@@ -113,7 +113,9 @@ struct pv_cpu_ops { + void (*store_gdt)(struct desc_ptr *); + void (*store_idt)(struct desc_ptr *); + void (*set_ldt)(const void *desc, unsigned entries); ++#ifdef CONFIG_X86_32 + void (*load_user_cs_desc)(int cpu, struct mm_struct *mm); ++#endif + unsigned long (*store_tr)(void); + void (*load_tls)(struct thread_struct *t, unsigned int cpu); + #ifdef CONFIG_X86_64 +@@ -841,11 +843,13 @@ static inline void set_ldt(const void *addr, unsigned entries) + { + PVOP_VCALL2(pv_cpu_ops.set_ldt, addr, entries); + } ++#ifdef CONFIG_X86_32 + static inline void load_user_cs_desc(unsigned int cpu, + struct mm_struct *mm) + { + PVOP_VCALL2(pv_cpu_ops.load_user_cs_desc, cpu, mm); + } ++#endif + static inline void store_gdt(struct desc_ptr *dtr) + { + PVOP_VCALL1(pv_cpu_ops.store_gdt, dtr); +-- +1.5.4.1 + --