ia64/xen-unstable
changeset 9058:5262bd9e9d19
Merged.
author | emellor@leeni.uk.xensource.com |
---|---|
date | Mon Feb 27 18:44:38 2006 +0100 (2006-02-27) |
parents | c028ba081c84 b470657718fe |
children | a2dce576313f |
files |
line diff
1.1 --- a/buildconfigs/mk.linux-2.6-xen Mon Feb 27 17:26:16 2006 +0100 1.2 +++ b/buildconfigs/mk.linux-2.6-xen Mon Feb 27 18:44:38 2006 +0100 1.3 @@ -2,8 +2,8 @@ 1.4 OS = linux 1.5 1.6 LINUX_SERIES = 2.6 1.7 -LINUX_VER = 2.6.16-rc4 1.8 -LINUX_SRCS = linux-2.6.15.tar.bz2 patch-2.6.16-rc4.bz2 1.9 +LINUX_VER = 2.6.16-rc5 1.10 +LINUX_SRCS = linux-2.6.15.tar.bz2 patch-2.6.16-rc5.bz2 1.11 LINUX_PDIR = linux-$(LINUX_VER) 1.12 1.13 EXTRAVERSION ?= xen 1.14 @@ -34,7 +34,7 @@ pristine-$(LINUX_PDIR)/.valid-srcs: $(LI 1.15 touch $(@D)/.hgskip 1.16 touch $@ 1.17 1.18 -pristine-linux-%.16-rc4/.valid-pristine: pristine-$(LINUX_PDIR)/.valid-srcs 1.19 +pristine-linux-%.16-rc5/.valid-pristine: pristine-$(LINUX_PDIR)/.valid-srcs 1.20 touch $@ # update timestamp to avoid rebuild 1.21 1.22 $(LINUX_DIR)/include/linux/autoconf.h: ref-$(OS)-$(LINUX_VER)/.valid-ref
2.1 --- a/linux-2.6-xen-sparse/arch/i386/Kconfig Mon Feb 27 17:26:16 2006 +0100 2.2 +++ b/linux-2.6-xen-sparse/arch/i386/Kconfig Mon Feb 27 18:44:38 2006 +0100 2.3 @@ -770,7 +770,7 @@ config PHYSICAL_START 2.4 2.5 config HOTPLUG_CPU 2.6 bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" 2.7 - depends on SMP && HOTPLUG && EXPERIMENTAL 2.8 + depends on SMP && HOTPLUG && EXPERIMENTAL && !X86_VOYAGER 2.9 ---help--- 2.10 Say Y here to experiment with turning CPUs off and on. CPUs 2.11 can be controlled through /sys/devices/system/cpu. 2.12 @@ -1122,6 +1122,7 @@ endif 2.13 2.14 config KPROBES 2.15 bool "Kprobes (EXPERIMENTAL)" 2.16 + depends on EXPERIMENTAL && MODULES 2.17 help 2.18 Kprobes allows you to trap at almost any kernel address and 2.19 execute a callback function. register_kprobe() establishes
3.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/Makefile Mon Feb 27 17:26:16 2006 +0100 3.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/Makefile Mon Feb 27 18:44:38 2006 +0100 3.3 @@ -7,7 +7,7 @@ extra-y := head.o init_task.o vmlinux.ld 3.4 obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ 3.5 ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ 3.6 pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \ 3.7 - quirks.o i8237.o 3.8 + quirks.o i8237.o topology.o 3.9 3.10 obj-y += cpu/ 3.11 obj-y += timers/
4.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/acpi/boot-xen.c Mon Feb 27 17:26:16 2006 +0100 4.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/acpi/boot-xen.c Mon Feb 27 18:44:38 2006 +0100 4.3 @@ -44,9 +44,6 @@ extern void __init clustered_apic_check( 4.4 extern int gsi_irq_sharing(int gsi); 4.5 #include <asm/proto.h> 4.6 4.7 -static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return 0; } 4.8 - 4.9 - 4.10 #else /* X86 */ 4.11 4.12 #ifdef CONFIG_X86_LOCAL_APIC
5.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c Mon Feb 27 17:26:16 2006 +0100 5.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c Mon Feb 27 18:44:38 2006 +0100 5.3 @@ -4,6 +4,7 @@ 5.4 #include <linux/smp.h> 5.5 #include <linux/module.h> 5.6 #include <linux/percpu.h> 5.7 +#include <linux/bootmem.h> 5.8 #include <asm/semaphore.h> 5.9 #include <asm/processor.h> 5.10 #include <asm/i387.h> 5.11 @@ -19,6 +20,9 @@ 5.12 5.13 #include "cpu.h" 5.14 5.15 +DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr); 5.16 +EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr); 5.17 + 5.18 #ifndef CONFIG_XEN 5.19 DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); 5.20 EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); 5.21 @@ -598,6 +602,8 @@ void __cpuinit cpu_init(void) 5.22 struct tss_struct * t = &per_cpu(init_tss, cpu); 5.23 #endif 5.24 struct thread_struct *thread = ¤t->thread; 5.25 + struct desc_struct *gdt; 5.26 + struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); 5.27 5.28 if (cpu_test_and_set(cpu, cpu_initialized)) { 5.29 printk(KERN_WARNING "CPU#%d already initialized!\n", cpu); 5.30 @@ -614,7 +620,54 @@ void __cpuinit cpu_init(void) 5.31 set_in_cr4(X86_CR4_TSD); 5.32 } 5.33 5.34 - cpu_gdt_init(&cpu_gdt_descr[cpu]); 5.35 +#ifndef CONFIG_XEN 5.36 + /* 5.37 + * This is a horrible hack to allocate the GDT. The problem 5.38 + * is that cpu_init() is called really early for the boot CPU 5.39 + * (and hence needs bootmem) but much later for the secondary 5.40 + * CPUs, when bootmem will have gone away 5.41 + */ 5.42 + if (NODE_DATA(0)->bdata->node_bootmem_map) { 5.43 + gdt = (struct desc_struct *)alloc_bootmem_pages(PAGE_SIZE); 5.44 + /* alloc_bootmem_pages panics on failure, so no check */ 5.45 + memset(gdt, 0, PAGE_SIZE); 5.46 + } else { 5.47 + gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL); 5.48 + if (unlikely(!gdt)) { 5.49 + printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu); 5.50 + for (;;) 5.51 + local_irq_enable(); 5.52 + } 5.53 + } 5.54 + 5.55 + /* 5.56 + * Initialize the per-CPU GDT with the boot GDT, 5.57 + * and set up the GDT descriptor: 5.58 + */ 5.59 + memcpy(gdt, cpu_gdt_table, GDT_SIZE); 5.60 + 5.61 + /* Set up GDT entry for 16bit stack */ 5.62 + *(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |= 5.63 + ((((__u64)stk16_off) << 16) & 0x000000ffffff0000ULL) | 5.64 + ((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) | 5.65 + (CPU_16BIT_STACK_SIZE - 1); 5.66 + 5.67 + cpu_gdt_descr->size = GDT_SIZE - 1; 5.68 + cpu_gdt_descr->address = (unsigned long)gdt; 5.69 +#else 5.70 + if (cpu == 0 && cpu_gdt_descr->address == 0) { 5.71 + gdt = (struct desc_struct *)alloc_bootmem_pages(PAGE_SIZE); 5.72 + /* alloc_bootmem_pages panics on failure, so no check */ 5.73 + memset(gdt, 0, PAGE_SIZE); 5.74 + 5.75 + memcpy(gdt, cpu_gdt_table, GDT_SIZE); 5.76 + 5.77 + cpu_gdt_descr->size = GDT_SIZE; 5.78 + cpu_gdt_descr->address = (unsigned long)gdt; 5.79 + } 5.80 +#endif 5.81 + 5.82 + cpu_gdt_init(cpu_gdt_descr); 5.83 5.84 /* 5.85 * Set up and load the per-CPU TSS and LDT
6.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S Mon Feb 27 17:26:16 2006 +0100 6.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S Mon Feb 27 18:44:38 2006 +0100 6.3 @@ -87,19 +87,9 @@ ENTRY(empty_zero_page) 6.4 */ 6.5 .data 6.6 6.7 - ALIGN 6.8 - .word 0 # 32 bit align gdt_desc.address 6.9 - .globl cpu_gdt_descr 6.10 -cpu_gdt_descr: 6.11 - .word GDT_SIZE 6.12 - .long cpu_gdt_table 6.13 - 6.14 - .fill NR_CPUS-1,8,0 # space for the other GDT descriptors 6.15 - 6.16 /* 6.17 * The Global Descriptor Table contains 28 quadwords, per-CPU. 6.18 */ 6.19 - .align PAGE_SIZE_asm 6.20 ENTRY(cpu_gdt_table) 6.21 .quad 0x0000000000000000 /* NULL descriptor */ 6.22 .quad 0x0000000000000000 /* 0x0b reserved */ 6.23 @@ -148,10 +138,6 @@ ENTRY(cpu_gdt_table) 6.24 .quad 0x0000000000000000 /* 0xf0 - unused */ 6.25 .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */ 6.26 6.27 - /* Be sure this is zeroed to avoid false validations in Xen */ 6.28 - .fill PAGE_SIZE_asm / 8 - GDT_ENTRIES,8,0 6.29 - 6.30 - 6.31 /* 6.32 * __xen_guest information 6.33 */
7.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c Mon Feb 27 17:26:16 2006 +0100 7.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c Mon Feb 27 18:44:38 2006 +0100 7.3 @@ -2634,8 +2634,10 @@ int __init io_apic_get_unique_id (int io 7.4 spin_unlock_irqrestore(&ioapic_lock, flags); 7.5 7.6 /* Sanity check */ 7.7 - if (reg_00.bits.ID != apic_id) 7.8 - panic("IOAPIC[%d]: Unable change apic_id!\n", ioapic); 7.9 + if (reg_00.bits.ID != apic_id) { 7.10 + printk("IOAPIC[%d]: Unable to change apic_id!\n", ioapic); 7.11 + return -1; 7.12 + } 7.13 } 7.14 7.15 apic_printk(APIC_VERBOSE, KERN_INFO
8.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/mpparse-xen.c Mon Feb 27 17:26:16 2006 +0100 8.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/mpparse-xen.c Mon Feb 27 18:44:38 2006 +0100 8.3 @@ -935,6 +935,7 @@ void __init mp_register_ioapic ( 8.4 u32 gsi_base) 8.5 { 8.6 int idx = 0; 8.7 + int tmpid; 8.8 8.9 if (nr_ioapics >= MAX_IO_APICS) { 8.10 printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " 8.11 @@ -957,9 +958,14 @@ void __init mp_register_ioapic ( 8.12 set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); 8.13 #endif 8.14 if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 < 15)) 8.15 - mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id); 8.16 + tmpid = io_apic_get_unique_id(idx, id); 8.17 else 8.18 - mp_ioapics[idx].mpc_apicid = id; 8.19 + tmpid = id; 8.20 + if (tmpid == -1) { 8.21 + nr_ioapics--; 8.22 + return; 8.23 + } 8.24 + mp_ioapics[idx].mpc_apicid = tmpid; 8.25 mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); 8.26 8.27 /*
9.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/smpboot.c Mon Feb 27 17:26:16 2006 +0100 9.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/smpboot.c Mon Feb 27 18:44:38 2006 +0100 9.3 @@ -898,12 +898,6 @@ static int __devinit do_boot_cpu(int api 9.4 unsigned long start_eip; 9.5 unsigned short nmi_high = 0, nmi_low = 0; 9.6 9.7 - if (!cpu_gdt_descr[cpu].address && 9.8 - !(cpu_gdt_descr[cpu].address = get_zeroed_page(GFP_KERNEL))) { 9.9 - printk("Failed to allocate GDT for CPU %d\n", cpu); 9.10 - return 1; 9.11 - } 9.12 - 9.13 ++cpucount; 9.14 9.15 /*
10.1 --- a/linux-2.6-xen-sparse/arch/i386/mach-xen/Makefile Mon Feb 27 17:26:16 2006 +0100 10.2 +++ b/linux-2.6-xen-sparse/arch/i386/mach-xen/Makefile Mon Feb 27 18:44:38 2006 +0100 10.3 @@ -2,6 +2,4 @@ 10.4 # Makefile for the linux kernel. 10.5 # 10.6 10.7 -obj-y := setup.o topology.o 10.8 - 10.9 -topology-y := ../mach-default/topology.o 10.10 +obj-y := setup.o
11.1 --- a/linux-2.6-xen-sparse/arch/x86_64/Kconfig Mon Feb 27 17:26:16 2006 +0100 11.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/Kconfig Mon Feb 27 18:44:38 2006 +0100 11.3 @@ -381,21 +381,6 @@ config HPET_TIMER 11.4 as it is off-chip. You can find the HPET spec at 11.5 <http://www.intel.com/hardwaredesign/hpetspec.htm>. 11.6 11.7 -config X86_PM_TIMER 11.8 - bool "PM timer" if EMBEDDED 11.9 - depends on ACPI && !X86_64_XEN 11.10 - default y 11.11 - help 11.12 - Support the ACPI PM timer for time keeping. This is slow, 11.13 - but is useful on some chipsets without HPET on systems with more 11.14 - than one CPU. On a single processor or single socket multi core 11.15 - system it is normally not required. 11.16 - When the PM timer is active 64bit vsyscalls are disabled 11.17 - and should not be enabled (/proc/sys/kernel/vsyscall64 should 11.18 - not be changed). 11.19 - The kernel selects the PM timer only as a last resort, so it is 11.20 - useful to enable just in case. 11.21 - 11.22 config HPET_EMULATE_RTC 11.23 bool "Provide RTC interrupt" 11.24 depends on HPET_TIMER && RTC=y 11.25 @@ -640,6 +625,7 @@ source "arch/x86_64/oprofile/Kconfig" 11.26 11.27 config KPROBES 11.28 bool "Kprobes (EXPERIMENTAL)" 11.29 + depends on EXPERIMENTAL && MODULES 11.30 help 11.31 Kprobes allows you to trap at almost any kernel address and 11.32 execute a callback function. register_kprobe() establishes
12.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/Makefile Mon Feb 27 17:26:16 2006 +0100 12.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/Makefile Mon Feb 27 18:44:38 2006 +0100 12.3 @@ -45,7 +45,7 @@ CFLAGS_vsyscall.o := $(PROFILING) -g0 12.4 12.5 bootflag-y += ../../i386/kernel/bootflag.o 12.6 cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o 12.7 -topology-y += ../../i386/mach-default/topology.o 12.8 +topology-y += ../../i386/kernel/topology.o 12.9 microcode-$(subst m,y,$(CONFIG_MICROCODE)) += ../../i386/kernel/microcode.o 12.10 intel_cacheinfo-y += ../../i386/kernel/cpu/intel_cacheinfo.o 12.11 quirks-y += ../../i386/kernel/quirks.o
13.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/apic-xen.c Mon Feb 27 17:26:16 2006 +0100 13.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/apic-xen.c Mon Feb 27 18:44:38 2006 +0100 13.3 @@ -114,6 +114,8 @@ void smp_apic_timer_interrupt(struct pt_ 13.4 irq_exit(); 13.5 } 13.6 13.7 +int __initdata unsync_tsc_on_multicluster; 13.8 + 13.9 /* 13.10 * This interrupt should _never_ happen with our APIC/SMP architecture 13.11 */
14.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c Mon Feb 27 17:26:16 2006 +0100 14.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c Mon Feb 27 18:44:38 2006 +0100 14.3 @@ -51,6 +51,8 @@ static int no_timer_check; 14.4 int disable_timer_pin_1 __initdata; 14.5 14.6 #ifndef CONFIG_XEN 14.7 +int timer_over_8254 __initdata = 1; 14.8 + 14.9 /* Where if anywhere is the i8259 connect in external int mode */ 14.10 static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; 14.11 #endif 14.12 @@ -301,6 +303,22 @@ static int __init enable_ioapic_setup(ch 14.13 __setup("noapic", disable_ioapic_setup); 14.14 __setup("apic", enable_ioapic_setup); 14.15 14.16 +#ifndef CONFIG_XEN 14.17 +static int __init setup_disable_8254_timer(char *s) 14.18 +{ 14.19 + timer_over_8254 = -1; 14.20 + return 1; 14.21 +} 14.22 +static int __init setup_enable_8254_timer(char *s) 14.23 +{ 14.24 + timer_over_8254 = 2; 14.25 + return 1; 14.26 +} 14.27 + 14.28 +__setup("disable_8254_timer", setup_disable_8254_timer); 14.29 +__setup("enable_8254_timer", setup_enable_8254_timer); 14.30 +#endif /* !CONFIG_XEN */ 14.31 + 14.32 #include <asm/pci-direct.h> 14.33 #include <linux/pci_ids.h> 14.34 #include <linux/pci.h> 14.35 @@ -360,28 +378,21 @@ void __init check_ioapic(void) 14.36 /* RED-PEN skip them on mptables too? */ 14.37 return; 14.38 case PCI_VENDOR_ID_ATI: 14.39 + 14.40 + /* This should be actually default, but 14.41 + for 2.6.16 let's do it for ATI only where 14.42 + it's really needed. */ 14.43 #ifndef CONFIG_XEN 14.44 - if (apic_runs_main_timer != 0) 14.45 - break; 14.46 -#ifdef CONFIG_ACPI 14.47 - /* Don't do this for laptops right 14.48 - right now because their timer 14.49 - doesn't necessarily tick in C2/3 */ 14.50 - if (acpi_fadt.revision >= 3 && 14.51 - (acpi_fadt.plvl2_lat + acpi_fadt.plvl3_lat) < 1100) { 14.52 - printk(KERN_INFO 14.53 -"ATI board detected, but seems to be a laptop. Timer might be shakey, sorry\n"); 14.54 - break; 14.55 - } 14.56 -#endif 14.57 + if (timer_over_8254 == 1) { 14.58 + timer_over_8254 = 0; 14.59 printk(KERN_INFO 14.60 - "ATI board detected. Using APIC/PM timer.\n"); 14.61 - apic_runs_main_timer = 1; 14.62 - nohpet = 1; 14.63 + "ATI board detected. Disabling timer routing over 8254.\n"); 14.64 + } 14.65 #endif 14.66 return; 14.67 } 14.68 14.69 + 14.70 /* No multi-function device? */ 14.71 type = read_pci_config_byte(num,slot,func, 14.72 PCI_HEADER_TYPE); 14.73 @@ -1848,6 +1859,8 @@ static inline void unlock_ExtINT_logic(v 14.74 * a wide range of boards and BIOS bugs. Fortunately only the timer IRQ 14.75 * is so screwy. Thanks to Brian Perkins for testing/hacking this beast 14.76 * fanatically on his truly buggy board. 14.77 + * 14.78 + * FIXME: really need to revamp this for modern platforms only. 14.79 */ 14.80 static inline void check_timer(void) 14.81 { 14.82 @@ -1870,7 +1883,8 @@ static inline void check_timer(void) 14.83 */ 14.84 apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); 14.85 init_8259A(1); 14.86 - enable_8259A_irq(0); 14.87 + if (timer_over_8254 > 0) 14.88 + enable_8259A_irq(0); 14.89 14.90 pin1 = find_isa_irq_pin(0, mp_INT); 14.91 apic1 = find_isa_irq_apic(0, mp_INT); 14.92 @@ -1925,7 +1939,7 @@ static inline void check_timer(void) 14.93 } 14.94 printk(" failed.\n"); 14.95 14.96 - if (nmi_watchdog) { 14.97 + if (nmi_watchdog == NMI_IO_APIC) { 14.98 printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n"); 14.99 nmi_watchdog = 0; 14.100 }
15.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Mon Feb 27 17:26:16 2006 +0100 15.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Mon Feb 27 18:44:38 2006 +0100 15.3 @@ -462,6 +462,12 @@ static __init void parse_cmdline_early ( 15.4 else if(!memcmp(from, "elfcorehdr=", 11)) 15.5 elfcorehdr_addr = memparse(from+11, &from); 15.6 #endif 15.7 + 15.8 +#if defined(CONFIG_HOTPLUG_CPU) && !defined(CONFIG_XEN) 15.9 + else if (!memcmp(from, "additional_cpus=", 16)) 15.10 + setup_additional_cpus(from+16); 15.11 +#endif 15.12 + 15.13 next_char: 15.14 c = *(from++); 15.15 if (!c)
16.1 --- a/linux-2.6-xen-sparse/drivers/acpi/Kconfig Mon Feb 27 17:26:16 2006 +0100 16.2 +++ b/linux-2.6-xen-sparse/drivers/acpi/Kconfig Mon Feb 27 18:44:38 2006 +0100 16.3 @@ -247,7 +247,7 @@ config ACPI_CUSTOM_DSDT_FILE 16.4 Enter the full path name to the file wich includes the AmlCode declaration. 16.5 16.6 config ACPI_BLACKLIST_YEAR 16.7 - int "Disable ACPI for systems before Jan 1st this year" if X86 16.8 + int "Disable ACPI for systems before Jan 1st this year" if X86_32 16.9 default 0 16.10 help 16.11 enter a 4-digit year, eg. 2001 to disable ACPI by default 16.12 @@ -285,9 +285,9 @@ config ACPI_SYSTEM 16.13 dump your ACPI DSDT table using /proc/acpi/dsdt. 16.14 16.15 config X86_PM_TIMER 16.16 - bool "Power Management Timer Support" 16.17 + bool "Power Management Timer Support" if EMBEDDED 16.18 depends on X86 16.19 - depends on !X86_64 16.20 + depends on !XEN 16.21 default y 16.22 help 16.23 The Power Management Timer is available on all ACPI-capable, 16.24 @@ -298,9 +298,8 @@ config X86_PM_TIMER 16.25 voltage scaling, unlike the commonly used Time Stamp Counter 16.26 (TSC) timing source. 16.27 16.28 - So, if you see messages like 'Losing too many ticks!' in the 16.29 - kernel logs, and/or you are using this on a notebook which 16.30 - does not yet have an HPET, you should say "Y" here. 16.31 + You should nearly always say Y here because many modern 16.32 + systems require this timer. 16.33 16.34 config ACPI_CONTAINER 16.35 tristate "ACPI0004,PNP0A05 and PNP0A06 Container Driver (EXPERIMENTAL)"
17.1 --- a/linux-2.6-xen-sparse/drivers/video/Kconfig Mon Feb 27 17:26:16 2006 +0100 17.2 +++ b/linux-2.6-xen-sparse/drivers/video/Kconfig Mon Feb 27 18:44:38 2006 +0100 17.3 @@ -520,7 +520,7 @@ config FB_GBE 17.4 config FB_GBE_MEM 17.5 int "Video memory size in MB" 17.6 depends on FB_GBE 17.7 - default 8 17.8 + default 4 17.9 help 17.10 This is the amount of memory reserved for the framebuffer, 17.11 which can be any value between 1MB and 8MB.
18.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c Mon Feb 27 17:26:16 2006 +0100 18.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c Mon Feb 27 18:44:38 2006 +0100 18.3 @@ -150,6 +150,11 @@ void vcpu_prepare(int vcpu) 18.4 { 18.5 vcpu_guest_context_t ctxt; 18.6 struct task_struct *idle = idle_task(vcpu); 18.7 +#ifdef __x86_64__ 18.8 + struct desc_ptr *gdt_descr = &cpu_gdt_descr[vcpu]; 18.9 +#else 18.10 + struct Xgt_desc_struct *gdt_descr = &per_cpu(cpu_gdt_descr, vcpu); 18.11 +#endif 18.12 18.13 if (vcpu == 0) 18.14 return; 18.15 @@ -171,8 +176,8 @@ void vcpu_prepare(int vcpu) 18.16 18.17 ctxt.ldt_ents = 0; 18.18 18.19 - ctxt.gdt_frames[0] = virt_to_mfn(cpu_gdt_descr[vcpu].address); 18.20 - ctxt.gdt_ents = cpu_gdt_descr[vcpu].size / 8; 18.21 + ctxt.gdt_frames[0] = virt_to_mfn(gdt_descr->address); 18.22 + ctxt.gdt_ents = gdt_descr->size / 8; 18.23 18.24 #ifdef __i386__ 18.25 ctxt.user_regs.cs = __KERNEL_CS; 18.26 @@ -210,6 +215,11 @@ void __init smp_prepare_cpus(unsigned in 18.27 { 18.28 int cpu; 18.29 struct task_struct *idle; 18.30 +#ifdef __x86_64__ 18.31 + struct desc_ptr *gdt_descr; 18.32 +#else 18.33 + struct Xgt_desc_struct *gdt_descr; 18.34 +#endif 18.35 18.36 cpu_data[0] = boot_cpu_data; 18.37 18.38 @@ -226,6 +236,22 @@ void __init smp_prepare_cpus(unsigned in 18.39 if (cpu == 0) 18.40 continue; 18.41 18.42 +#ifdef __x86_64__ 18.43 + gdt_descr = &cpu_gdt_descr[cpu]; 18.44 +#else 18.45 + gdt_descr = &per_cpu(cpu_gdt_descr, cpu); 18.46 +#endif 18.47 + gdt_descr->address = get_zeroed_page(GFP_KERNEL); 18.48 + if (unlikely(!gdt_descr->address)) { 18.49 + printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu); 18.50 + continue; 18.51 + } 18.52 + gdt_descr->size = GDT_SIZE; 18.53 + memcpy((void *)gdt_descr->address, cpu_gdt_table, GDT_SIZE); 18.54 + make_page_readonly( 18.55 + (void *)gdt_descr->address, 18.56 + XENFEAT_writable_descriptor_tables); 18.57 + 18.58 cpu_data[cpu] = boot_cpu_data; 18.59 cpu_2_logical_apicid[cpu] = cpu; 18.60 x86_cpu_to_apicid[cpu] = cpu; 18.61 @@ -242,17 +268,6 @@ void __init smp_prepare_cpus(unsigned in 18.62 18.63 irq_ctx_init(cpu); 18.64 18.65 - cpu_gdt_descr[cpu].address = 18.66 - __get_free_page(GFP_KERNEL|__GFP_ZERO); 18.67 - BUG_ON(cpu_gdt_descr[0].size > PAGE_SIZE); 18.68 - cpu_gdt_descr[cpu].size = cpu_gdt_descr[0].size; 18.69 - memcpy((void *)cpu_gdt_descr[cpu].address, 18.70 - (void *)cpu_gdt_descr[0].address, 18.71 - cpu_gdt_descr[0].size); 18.72 - make_page_readonly( 18.73 - (void *)cpu_gdt_descr[cpu].address, 18.74 - XENFEAT_writable_descriptor_tables); 18.75 - 18.76 #ifdef CONFIG_HOTPLUG_CPU 18.77 if (xen_start_info->flags & SIF_INITDOMAIN) 18.78 cpu_set(cpu, cpu_present_map);
19.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/desc.h Mon Feb 27 17:26:16 2006 +0100 19.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/desc.h Mon Feb 27 18:44:38 2006 +0100 19.3 @@ -23,11 +23,13 @@ struct Xgt_desc_struct { 19.4 unsigned short pad; 19.5 } __attribute__ ((packed)); 19.6 19.7 -extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS]; 19.8 +extern struct Xgt_desc_struct idt_descr; 19.9 +DECLARE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr); 19.10 + 19.11 19.12 static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) 19.13 { 19.14 - return ((struct desc_struct *)cpu_gdt_descr[cpu].address); 19.15 + return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address; 19.16 } 19.17 19.18 #define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8))
20.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pci.h Mon Feb 27 17:26:16 2006 +0100 20.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pci.h Mon Feb 27 18:44:38 2006 +0100 20.3 @@ -19,8 +19,6 @@ extern unsigned int pcibios_assign_all_b 20.4 #endif 20.5 #define pcibios_scan_all_fns(a, b) 0 20.6 20.7 -extern int no_iommu, force_iommu; 20.8 - 20.9 extern unsigned long pci_mem_start; 20.10 #define PCIBIOS_MIN_IO 0x1000 20.11 #define PCIBIOS_MIN_MEM (pci_mem_start)
21.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h Mon Feb 27 17:26:16 2006 +0100 21.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h Mon Feb 27 18:44:38 2006 +0100 21.3 @@ -169,7 +169,7 @@ static inline pte_t ptep_get_and_clear_f 21.4 #define PGDIR_SIZE (1UL << PGDIR_SHIFT) 21.5 #define PGDIR_MASK (~(PGDIR_SIZE-1)) 21.6 21.7 -#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) 21.8 +#define USER_PTRS_PER_PGD ((TASK_SIZE-1)/PGDIR_SIZE+1) 21.9 #define FIRST_USER_ADDRESS 0 21.10 21.11 #ifndef __ASSEMBLY__
22.1 --- a/linux-2.6-xen-sparse/include/linux/mm.h Mon Feb 27 17:26:16 2006 +0100 22.2 +++ b/linux-2.6-xen-sparse/include/linux/mm.h Mon Feb 27 18:44:38 2006 +0100 22.3 @@ -1064,7 +1064,11 @@ int shrink_slab(unsigned long scanned, g 22.4 void drop_pagecache(void); 22.5 void drop_slab(void); 22.6 22.7 +#ifndef CONFIG_MMU 22.8 +#define randomize_va_space 0 22.9 +#else 22.10 extern int randomize_va_space; 22.11 +#endif 22.12 22.13 #endif /* __KERNEL__ */ 22.14 #endif /* _LINUX_MM_H */
23.1 --- a/linux-2.6-xen-sparse/mm/page_alloc.c Mon Feb 27 17:26:16 2006 +0100 23.2 +++ b/linux-2.6-xen-sparse/mm/page_alloc.c Mon Feb 27 18:44:38 2006 +0100 23.3 @@ -1017,7 +1017,7 @@ rebalance: 23.4 if (page) 23.5 goto got_pg; 23.6 23.7 - out_of_memory(gfp_mask, order); 23.8 + out_of_memory(zonelist, gfp_mask, order); 23.9 goto restart; 23.10 } 23.11
24.1 --- a/linux-2.6-xen-sparse/net/core/skbuff.c Mon Feb 27 17:26:16 2006 +0100 24.2 +++ b/linux-2.6-xen-sparse/net/core/skbuff.c Mon Feb 27 18:44:38 2006 +0100 24.3 @@ -434,6 +434,9 @@ struct sk_buff *skb_clone(struct sk_buff 24.4 C(pkt_type); 24.5 C(ip_summed); 24.6 C(priority); 24.7 +#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) 24.8 + C(ipvs_property); 24.9 +#endif 24.10 C(protocol); 24.11 n->destructor = NULL; 24.12 #ifdef CONFIG_NETFILTER 24.13 @@ -445,13 +448,6 @@ struct sk_buff *skb_clone(struct sk_buff 24.14 C(nfct_reasm); 24.15 nf_conntrack_get_reasm(skb->nfct_reasm); 24.16 #endif 24.17 -#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) 24.18 - C(ipvs_property); 24.19 -#endif 24.20 -#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 24.21 - C(nfct_reasm); 24.22 - nf_conntrack_get_reasm(skb->nfct_reasm); 24.23 -#endif 24.24 #ifdef CONFIG_BRIDGE_NETFILTER 24.25 C(nf_bridge); 24.26 nf_bridge_get(skb->nf_bridge);
25.1 --- a/patches/linux-2.6.16-rc4/i386-mach-io-check-nmi.patch Mon Feb 27 17:26:16 2006 +0100 25.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 25.3 @@ -1,45 +0,0 @@ 25.4 -diff -pruN ../pristine-linux-2.6.16-rc3/arch/i386/kernel/traps.c ./arch/i386/kernel/traps.c 25.5 ---- ../pristine-linux-2.6.16-rc3/arch/i386/kernel/traps.c 2006-02-15 20:38:51.000000000 +0000 25.6 -+++ ./arch/i386/kernel/traps.c 2006-02-15 20:40:43.000000000 +0000 25.7 -@@ -567,18 +567,11 @@ static void mem_parity_error(unsigned ch 25.8 - 25.9 - static void io_check_error(unsigned char reason, struct pt_regs * regs) 25.10 - { 25.11 -- unsigned long i; 25.12 -- 25.13 - printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n"); 25.14 - show_registers(regs); 25.15 - 25.16 - /* Re-enable the IOCK line, wait for a few seconds */ 25.17 -- reason = (reason & 0xf) | 8; 25.18 -- outb(reason, 0x61); 25.19 -- i = 2000; 25.20 -- while (--i) udelay(1000); 25.21 -- reason &= ~8; 25.22 -- outb(reason, 0x61); 25.23 -+ clear_io_check_error(reason); 25.24 - } 25.25 - 25.26 - static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) 25.27 -diff -pruN ../pristine-linux-2.6.16-rc3/include/asm-i386/mach-default/mach_traps.h ./include/asm-i386/mach-default/mach_traps.h 25.28 ---- ../pristine-linux-2.6.16-rc3/include/asm-i386/mach-default/mach_traps.h 2006-01-03 03:21:10.000000000 +0000 25.29 -+++ ./include/asm-i386/mach-default/mach_traps.h 2006-02-15 20:40:43.000000000 +0000 25.30 -@@ -15,6 +15,18 @@ static inline void clear_mem_error(unsig 25.31 - outb(reason, 0x61); 25.32 - } 25.33 - 25.34 -+static inline void clear_io_check_error(unsigned char reason) 25.35 -+{ 25.36 -+ unsigned long i; 25.37 -+ 25.38 -+ reason = (reason & 0xf) | 8; 25.39 -+ outb(reason, 0x61); 25.40 -+ i = 2000; 25.41 -+ while (--i) udelay(1000); 25.42 -+ reason &= ~8; 25.43 -+ outb(reason, 0x61); 25.44 -+} 25.45 -+ 25.46 - static inline unsigned char get_nmi_reason(void) 25.47 - { 25.48 - return inb(0x61);
26.1 --- a/patches/linux-2.6.16-rc4/net-csum.patch Mon Feb 27 17:26:16 2006 +0100 26.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 26.3 @@ -1,41 +0,0 @@ 26.4 -diff -pruN ../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_tcp.c ./net/ipv4/netfilter/ip_nat_proto_tcp.c 26.5 ---- ../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_tcp.c 2006-02-02 17:39:51.000000000 +0000 26.6 -+++ ./net/ipv4/netfilter/ip_nat_proto_tcp.c 2006-02-02 17:44:18.000000000 +0000 26.7 -@@ -129,10 +129,14 @@ tcp_manip_pkt(struct sk_buff **pskb, 26.8 - if (hdrsize < sizeof(*hdr)) 26.9 - return 1; 26.10 - 26.11 -- hdr->check = ip_nat_cheat_check(~oldip, newip, 26.12 -+ if ((*pskb)->proto_csum_blank) { 26.13 -+ hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check); 26.14 -+ } else { 26.15 -+ hdr->check = ip_nat_cheat_check(~oldip, newip, 26.16 - ip_nat_cheat_check(oldport ^ 0xFFFF, 26.17 - newport, 26.18 - hdr->check)); 26.19 -+ } 26.20 - return 1; 26.21 - } 26.22 - 26.23 -diff -pruN ../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_udp.c ./net/ipv4/netfilter/ip_nat_proto_udp.c 26.24 ---- ../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_udp.c 2006-02-02 17:39:51.000000000 +0000 26.25 -+++ ./net/ipv4/netfilter/ip_nat_proto_udp.c 2006-02-02 17:44:18.000000000 +0000 26.26 -@@ -113,11 +113,16 @@ udp_manip_pkt(struct sk_buff **pskb, 26.27 - newport = tuple->dst.u.udp.port; 26.28 - portptr = &hdr->dest; 26.29 - } 26.30 -- if (hdr->check) /* 0 is a special case meaning no checksum */ 26.31 -- hdr->check = ip_nat_cheat_check(~oldip, newip, 26.32 -+ if (hdr->check) { /* 0 is a special case meaning no checksum */ 26.33 -+ if ((*pskb)->proto_csum_blank) { 26.34 -+ hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check); 26.35 -+ } else { 26.36 -+ hdr->check = ip_nat_cheat_check(~oldip, newip, 26.37 - ip_nat_cheat_check(*portptr ^ 0xFFFF, 26.38 - newport, 26.39 - hdr->check)); 26.40 -+ } 26.41 -+ } 26.42 - *portptr = newport; 26.43 - return 1; 26.44 - }
27.1 --- a/patches/linux-2.6.16-rc4/pmd-shared.patch Mon Feb 27 17:26:16 2006 +0100 27.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 27.3 @@ -1,111 +0,0 @@ 27.4 -diff -pruN ../pristine-linux-2.6.16-rc1-git4/arch/i386/mm/pageattr.c ./arch/i386/mm/pageattr.c 27.5 ---- ../pristine-linux-2.6.16-rc1-git4/arch/i386/mm/pageattr.c 2006-02-02 17:39:29.000000000 +0000 27.6 -+++ ./arch/i386/mm/pageattr.c 2006-02-02 17:45:14.000000000 +0000 27.7 -@@ -78,7 +78,7 @@ static void set_pmd_pte(pte_t *kpte, uns 27.8 - unsigned long flags; 27.9 - 27.10 - set_pte_atomic(kpte, pte); /* change init_mm */ 27.11 -- if (PTRS_PER_PMD > 1) 27.12 -+ if (HAVE_SHARED_KERNEL_PMD) 27.13 - return; 27.14 - 27.15 - spin_lock_irqsave(&pgd_lock, flags); 27.16 -diff -pruN ../pristine-linux-2.6.16-rc1-git4/arch/i386/mm/pgtable.c ./arch/i386/mm/pgtable.c 27.17 ---- ../pristine-linux-2.6.16-rc1-git4/arch/i386/mm/pgtable.c 2006-01-03 03:21:10.000000000 +0000 27.18 -+++ ./arch/i386/mm/pgtable.c 2006-02-02 17:45:14.000000000 +0000 27.19 -@@ -215,9 +215,10 @@ void pgd_ctor(void *pgd, kmem_cache_t *c 27.20 - spin_lock_irqsave(&pgd_lock, flags); 27.21 - } 27.22 - 27.23 -- clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD, 27.24 -- swapper_pg_dir + USER_PTRS_PER_PGD, 27.25 -- KERNEL_PGD_PTRS); 27.26 -+ if (PTRS_PER_PMD == 1 || HAVE_SHARED_KERNEL_PMD) 27.27 -+ clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD, 27.28 -+ swapper_pg_dir + USER_PTRS_PER_PGD, 27.29 -+ KERNEL_PGD_PTRS); 27.30 - if (PTRS_PER_PMD > 1) 27.31 - return; 27.32 - 27.33 -@@ -249,6 +250,30 @@ pgd_t *pgd_alloc(struct mm_struct *mm) 27.34 - goto out_oom; 27.35 - set_pgd(&pgd[i], __pgd(1 + __pa(pmd))); 27.36 - } 27.37 -+ 27.38 -+ if (!HAVE_SHARED_KERNEL_PMD) { 27.39 -+ unsigned long flags; 27.40 -+ 27.41 -+ for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) { 27.42 -+ pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL); 27.43 -+ if (!pmd) 27.44 -+ goto out_oom; 27.45 -+ set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd))); 27.46 -+ } 27.47 -+ 27.48 -+ spin_lock_irqsave(&pgd_lock, flags); 27.49 -+ for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) { 27.50 -+ unsigned long v = (unsigned long)i << PGDIR_SHIFT; 27.51 -+ pgd_t *kpgd = pgd_offset_k(v); 27.52 -+ pud_t *kpud = pud_offset(kpgd, v); 27.53 -+ pmd_t *kpmd = pmd_offset(kpud, v); 27.54 -+ pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1); 27.55 -+ memcpy(pmd, kpmd, PAGE_SIZE); 27.56 -+ } 27.57 -+ pgd_list_add(pgd); 27.58 -+ spin_unlock_irqrestore(&pgd_lock, flags); 27.59 -+ } 27.60 -+ 27.61 - return pgd; 27.62 - 27.63 - out_oom: 27.64 -@@ -263,9 +288,23 @@ void pgd_free(pgd_t *pgd) 27.65 - int i; 27.66 - 27.67 - /* in the PAE case user pgd entries are overwritten before usage */ 27.68 -- if (PTRS_PER_PMD > 1) 27.69 -- for (i = 0; i < USER_PTRS_PER_PGD; ++i) 27.70 -- kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1)); 27.71 -+ if (PTRS_PER_PMD > 1) { 27.72 -+ for (i = 0; i < USER_PTRS_PER_PGD; ++i) { 27.73 -+ pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1); 27.74 -+ kmem_cache_free(pmd_cache, pmd); 27.75 -+ } 27.76 -+ if (!HAVE_SHARED_KERNEL_PMD) { 27.77 -+ unsigned long flags; 27.78 -+ spin_lock_irqsave(&pgd_lock, flags); 27.79 -+ pgd_list_del(pgd); 27.80 -+ spin_unlock_irqrestore(&pgd_lock, flags); 27.81 -+ for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) { 27.82 -+ pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1); 27.83 -+ memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t)); 27.84 -+ kmem_cache_free(pmd_cache, pmd); 27.85 -+ } 27.86 -+ } 27.87 -+ } 27.88 - /* in the non-PAE case, free_pgtables() clears user pgd entries */ 27.89 - kmem_cache_free(pgd_cache, pgd); 27.90 - } 27.91 -diff -pruN ../pristine-linux-2.6.16-rc1-git4/include/asm-i386/pgtable-2level-defs.h ./include/asm-i386/pgtable-2level-defs.h 27.92 ---- ../pristine-linux-2.6.16-rc1-git4/include/asm-i386/pgtable-2level-defs.h 2006-01-03 03:21:10.000000000 +0000 27.93 -+++ ./include/asm-i386/pgtable-2level-defs.h 2006-02-02 17:45:14.000000000 +0000 27.94 -@@ -1,6 +1,8 @@ 27.95 - #ifndef _I386_PGTABLE_2LEVEL_DEFS_H 27.96 - #define _I386_PGTABLE_2LEVEL_DEFS_H 27.97 - 27.98 -+#define HAVE_SHARED_KERNEL_PMD 0 27.99 -+ 27.100 - /* 27.101 - * traditional i386 two-level paging structure: 27.102 - */ 27.103 -diff -pruN ../pristine-linux-2.6.16-rc1-git4/include/asm-i386/pgtable-3level-defs.h ./include/asm-i386/pgtable-3level-defs.h 27.104 ---- ../pristine-linux-2.6.16-rc1-git4/include/asm-i386/pgtable-3level-defs.h 2006-01-03 03:21:10.000000000 +0000 27.105 -+++ ./include/asm-i386/pgtable-3level-defs.h 2006-02-02 17:45:14.000000000 +0000 27.106 -@@ -1,6 +1,8 @@ 27.107 - #ifndef _I386_PGTABLE_3LEVEL_DEFS_H 27.108 - #define _I386_PGTABLE_3LEVEL_DEFS_H 27.109 - 27.110 -+#define HAVE_SHARED_KERNEL_PMD 1 27.111 -+ 27.112 - /* 27.113 - * PGDIR_SHIFT determines what a top-level page table entry can map 27.114 - */
28.1 --- a/patches/linux-2.6.16-rc4/smp-alts.patch Mon Feb 27 17:26:16 2006 +0100 28.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 28.3 @@ -1,591 +0,0 @@ 28.4 -diff -pruN ../pristine-linux-2.6.16-rc3/arch/i386/Kconfig ./arch/i386/Kconfig 28.5 ---- ../pristine-linux-2.6.16-rc3/arch/i386/Kconfig 2006-02-15 20:38:51.000000000 +0000 28.6 -+++ ./arch/i386/Kconfig 2006-02-15 20:45:57.000000000 +0000 28.7 -@@ -202,6 +202,19 @@ config SMP 28.8 - 28.9 - If you don't know what to do here, say N. 28.10 - 28.11 -+config SMP_ALTERNATIVES 28.12 -+ bool "SMP alternatives support (EXPERIMENTAL)" 28.13 -+ depends on SMP && EXPERIMENTAL 28.14 -+ help 28.15 -+ Try to reduce the overhead of running an SMP kernel on a uniprocessor 28.16 -+ host slightly by replacing certain key instruction sequences 28.17 -+ according to whether we currently have more than one CPU available. 28.18 -+ This should provide a noticeable boost to performance when 28.19 -+ running SMP kernels on UP machines, and have negligible impact 28.20 -+ when running on an true SMP host. 28.21 -+ 28.22 -+ If unsure, say N. 28.23 -+ 28.24 - config NR_CPUS 28.25 - int "Maximum number of CPUs (2-255)" 28.26 - range 2 255 28.27 -diff -pruN ../pristine-linux-2.6.16-rc3/arch/i386/kernel/Makefile ./arch/i386/kernel/Makefile 28.28 ---- ../pristine-linux-2.6.16-rc3/arch/i386/kernel/Makefile 2006-02-15 20:38:51.000000000 +0000 28.29 -+++ ./arch/i386/kernel/Makefile 2006-02-15 20:45:57.000000000 +0000 28.30 -@@ -37,6 +37,7 @@ obj-$(CONFIG_EFI) += efi.o efi_stub.o 28.31 - obj-$(CONFIG_DOUBLEFAULT) += doublefault.o 28.32 - obj-$(CONFIG_VM86) += vm86.o 28.33 - obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 28.34 -+obj-$(CONFIG_SMP_ALTERNATIVES) += smpalts.o 28.35 - 28.36 - EXTRA_AFLAGS := -traditional 28.37 - 28.38 -diff -pruN ../pristine-linux-2.6.16-rc3/arch/i386/kernel/smpalts.c ./arch/i386/kernel/smpalts.c 28.39 ---- ../pristine-linux-2.6.16-rc3/arch/i386/kernel/smpalts.c 1970-01-01 01:00:00.000000000 +0100 28.40 -+++ ./arch/i386/kernel/smpalts.c 2006-02-15 20:45:57.000000000 +0000 28.41 -@@ -0,0 +1,85 @@ 28.42 -+#include <linux/kernel.h> 28.43 -+#include <asm/system.h> 28.44 -+#include <asm/smp_alt.h> 28.45 -+#include <asm/processor.h> 28.46 -+#include <asm/string.h> 28.47 -+ 28.48 -+struct smp_replacement_record { 28.49 -+ unsigned char targ_size; 28.50 -+ unsigned char smp1_size; 28.51 -+ unsigned char smp2_size; 28.52 -+ unsigned char up_size; 28.53 -+ unsigned char feature; 28.54 -+ unsigned char data[0]; 28.55 -+}; 28.56 -+ 28.57 -+struct smp_alternative_record { 28.58 -+ void *targ_start; 28.59 -+ struct smp_replacement_record *repl; 28.60 -+}; 28.61 -+ 28.62 -+extern struct smp_alternative_record __start_smp_alternatives_table, 28.63 -+ __stop_smp_alternatives_table; 28.64 -+extern unsigned long __init_begin, __init_end; 28.65 -+ 28.66 -+void prepare_for_smp(void) 28.67 -+{ 28.68 -+ struct smp_alternative_record *r; 28.69 -+ printk(KERN_INFO "Enabling SMP...\n"); 28.70 -+ for (r = &__start_smp_alternatives_table; 28.71 -+ r != &__stop_smp_alternatives_table; 28.72 -+ r++) { 28.73 -+ BUG_ON(r->repl->targ_size < r->repl->smp1_size); 28.74 -+ BUG_ON(r->repl->targ_size < r->repl->smp2_size); 28.75 -+ BUG_ON(r->repl->targ_size < r->repl->up_size); 28.76 -+ if (system_state == SYSTEM_RUNNING && 28.77 -+ r->targ_start >= (void *)&__init_begin && 28.78 -+ r->targ_start < (void *)&__init_end) 28.79 -+ continue; 28.80 -+ if (r->repl->feature != (unsigned char)-1 && 28.81 -+ boot_cpu_has(r->repl->feature)) { 28.82 -+ memcpy(r->targ_start, 28.83 -+ r->repl->data + r->repl->smp1_size, 28.84 -+ r->repl->smp2_size); 28.85 -+ memset(r->targ_start + r->repl->smp2_size, 28.86 -+ 0x90, 28.87 -+ r->repl->targ_size - r->repl->smp2_size); 28.88 -+ } else { 28.89 -+ memcpy(r->targ_start, 28.90 -+ r->repl->data, 28.91 -+ r->repl->smp1_size); 28.92 -+ memset(r->targ_start + r->repl->smp1_size, 28.93 -+ 0x90, 28.94 -+ r->repl->targ_size - r->repl->smp1_size); 28.95 -+ } 28.96 -+ } 28.97 -+ /* Paranoia */ 28.98 -+ asm volatile ("jmp 1f\n1:"); 28.99 -+ mb(); 28.100 -+} 28.101 -+ 28.102 -+void unprepare_for_smp(void) 28.103 -+{ 28.104 -+ struct smp_alternative_record *r; 28.105 -+ printk(KERN_INFO "Disabling SMP...\n"); 28.106 -+ for (r = &__start_smp_alternatives_table; 28.107 -+ r != &__stop_smp_alternatives_table; 28.108 -+ r++) { 28.109 -+ BUG_ON(r->repl->targ_size < r->repl->smp1_size); 28.110 -+ BUG_ON(r->repl->targ_size < r->repl->smp2_size); 28.111 -+ BUG_ON(r->repl->targ_size < r->repl->up_size); 28.112 -+ if (system_state == SYSTEM_RUNNING && 28.113 -+ r->targ_start >= (void *)&__init_begin && 28.114 -+ r->targ_start < (void *)&__init_end) 28.115 -+ continue; 28.116 -+ memcpy(r->targ_start, 28.117 -+ r->repl->data + r->repl->smp1_size + r->repl->smp2_size, 28.118 -+ r->repl->up_size); 28.119 -+ memset(r->targ_start + r->repl->up_size, 28.120 -+ 0x90, 28.121 -+ r->repl->targ_size - r->repl->up_size); 28.122 -+ } 28.123 -+ /* Paranoia */ 28.124 -+ asm volatile ("jmp 1f\n1:"); 28.125 -+ mb(); 28.126 -+} 28.127 -diff -pruN ../pristine-linux-2.6.16-rc3/arch/i386/kernel/smpboot.c ./arch/i386/kernel/smpboot.c 28.128 ---- ../pristine-linux-2.6.16-rc3/arch/i386/kernel/smpboot.c 2006-02-15 20:38:51.000000000 +0000 28.129 -+++ ./arch/i386/kernel/smpboot.c 2006-02-15 20:45:57.000000000 +0000 28.130 -@@ -1214,6 +1214,11 @@ static void __init smp_boot_cpus(unsigne 28.131 - if (max_cpus <= cpucount+1) 28.132 - continue; 28.133 - 28.134 -+#ifdef CONFIG_SMP_ALTERNATIVES 28.135 -+ if (kicked == 1) 28.136 -+ prepare_for_smp(); 28.137 -+#endif 28.138 -+ 28.139 - if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu)) 28.140 - printk("CPU #%d not responding - cannot use it.\n", 28.141 - apicid); 28.142 -@@ -1392,6 +1397,11 @@ int __devinit __cpu_up(unsigned int cpu) 28.143 - return -EIO; 28.144 - } 28.145 - 28.146 -+#ifdef CONFIG_SMP_ALTERNATIVES 28.147 -+ if (num_online_cpus() == 1) 28.148 -+ prepare_for_smp(); 28.149 -+#endif 28.150 -+ 28.151 - local_irq_enable(); 28.152 - per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; 28.153 - /* Unleash the CPU! */ 28.154 -diff -pruN ../pristine-linux-2.6.16-rc3/arch/i386/kernel/vmlinux.lds.S ./arch/i386/kernel/vmlinux.lds.S 28.155 ---- ../pristine-linux-2.6.16-rc3/arch/i386/kernel/vmlinux.lds.S 2006-01-03 03:21:10.000000000 +0000 28.156 -+++ ./arch/i386/kernel/vmlinux.lds.S 2006-02-15 20:45:57.000000000 +0000 28.157 -@@ -34,6 +34,13 @@ SECTIONS 28.158 - __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) } 28.159 - __stop___ex_table = .; 28.160 - 28.161 -+ . = ALIGN(16); 28.162 -+ __start_smp_alternatives_table = .; 28.163 -+ __smp_alternatives : { *(__smp_alternatives) } 28.164 -+ __stop_smp_alternatives_table = .; 28.165 -+ 28.166 -+ __smp_replacements : { *(__smp_replacements) } 28.167 -+ 28.168 - RODATA 28.169 - 28.170 - /* writeable */ 28.171 -diff -pruN ../pristine-linux-2.6.16-rc3/include/asm-i386/atomic.h ./include/asm-i386/atomic.h 28.172 ---- ../pristine-linux-2.6.16-rc3/include/asm-i386/atomic.h 2006-02-15 20:38:57.000000000 +0000 28.173 -+++ ./include/asm-i386/atomic.h 2006-02-15 20:45:57.000000000 +0000 28.174 -@@ -4,18 +4,13 @@ 28.175 - #include <linux/config.h> 28.176 - #include <linux/compiler.h> 28.177 - #include <asm/processor.h> 28.178 -+#include <asm/smp_alt.h> 28.179 - 28.180 - /* 28.181 - * Atomic operations that C can't guarantee us. Useful for 28.182 - * resource counting etc.. 28.183 - */ 28.184 - 28.185 --#ifdef CONFIG_SMP 28.186 --#define LOCK "lock ; " 28.187 --#else 28.188 --#define LOCK "" 28.189 --#endif 28.190 -- 28.191 - /* 28.192 - * Make sure gcc doesn't try to be clever and move things around 28.193 - * on us. We need to use _exactly_ the address the user gave us, 28.194 -diff -pruN ../pristine-linux-2.6.16-rc3/include/asm-i386/bitops.h ./include/asm-i386/bitops.h 28.195 ---- ../pristine-linux-2.6.16-rc3/include/asm-i386/bitops.h 2006-02-15 20:38:57.000000000 +0000 28.196 -+++ ./include/asm-i386/bitops.h 2006-02-15 20:45:57.000000000 +0000 28.197 -@@ -7,6 +7,7 @@ 28.198 - 28.199 - #include <linux/config.h> 28.200 - #include <linux/compiler.h> 28.201 -+#include <asm/smp_alt.h> 28.202 - 28.203 - /* 28.204 - * These have to be done with inline assembly: that way the bit-setting 28.205 -@@ -16,12 +17,6 @@ 28.206 - * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). 28.207 - */ 28.208 - 28.209 --#ifdef CONFIG_SMP 28.210 --#define LOCK_PREFIX "lock ; " 28.211 --#else 28.212 --#define LOCK_PREFIX "" 28.213 --#endif 28.214 -- 28.215 - #define ADDR (*(volatile long *) addr) 28.216 - 28.217 - /** 28.218 -@@ -41,7 +36,7 @@ 28.219 - */ 28.220 - static inline void set_bit(int nr, volatile unsigned long * addr) 28.221 - { 28.222 -- __asm__ __volatile__( LOCK_PREFIX 28.223 -+ __asm__ __volatile__( LOCK 28.224 - "btsl %1,%0" 28.225 - :"+m" (ADDR) 28.226 - :"Ir" (nr)); 28.227 -@@ -76,7 +71,7 @@ static inline void __set_bit(int nr, vol 28.228 - */ 28.229 - static inline void clear_bit(int nr, volatile unsigned long * addr) 28.230 - { 28.231 -- __asm__ __volatile__( LOCK_PREFIX 28.232 -+ __asm__ __volatile__( LOCK 28.233 - "btrl %1,%0" 28.234 - :"+m" (ADDR) 28.235 - :"Ir" (nr)); 28.236 -@@ -121,7 +116,7 @@ static inline void __change_bit(int nr, 28.237 - */ 28.238 - static inline void change_bit(int nr, volatile unsigned long * addr) 28.239 - { 28.240 -- __asm__ __volatile__( LOCK_PREFIX 28.241 -+ __asm__ __volatile__( LOCK 28.242 - "btcl %1,%0" 28.243 - :"+m" (ADDR) 28.244 - :"Ir" (nr)); 28.245 -@@ -140,7 +135,7 @@ static inline int test_and_set_bit(int n 28.246 - { 28.247 - int oldbit; 28.248 - 28.249 -- __asm__ __volatile__( LOCK_PREFIX 28.250 -+ __asm__ __volatile__( LOCK 28.251 - "btsl %2,%1\n\tsbbl %0,%0" 28.252 - :"=r" (oldbit),"+m" (ADDR) 28.253 - :"Ir" (nr) : "memory"); 28.254 -@@ -180,7 +175,7 @@ static inline int test_and_clear_bit(int 28.255 - { 28.256 - int oldbit; 28.257 - 28.258 -- __asm__ __volatile__( LOCK_PREFIX 28.259 -+ __asm__ __volatile__( LOCK 28.260 - "btrl %2,%1\n\tsbbl %0,%0" 28.261 - :"=r" (oldbit),"+m" (ADDR) 28.262 - :"Ir" (nr) : "memory"); 28.263 -@@ -231,7 +226,7 @@ static inline int test_and_change_bit(in 28.264 - { 28.265 - int oldbit; 28.266 - 28.267 -- __asm__ __volatile__( LOCK_PREFIX 28.268 -+ __asm__ __volatile__( LOCK 28.269 - "btcl %2,%1\n\tsbbl %0,%0" 28.270 - :"=r" (oldbit),"+m" (ADDR) 28.271 - :"Ir" (nr) : "memory"); 28.272 -diff -pruN ../pristine-linux-2.6.16-rc3/include/asm-i386/futex.h ./include/asm-i386/futex.h 28.273 ---- ../pristine-linux-2.6.16-rc3/include/asm-i386/futex.h 2006-02-15 20:38:57.000000000 +0000 28.274 -+++ ./include/asm-i386/futex.h 2006-02-15 20:45:57.000000000 +0000 28.275 -@@ -28,7 +28,7 @@ 28.276 - "1: movl %2, %0\n\ 28.277 - movl %0, %3\n" \ 28.278 - insn "\n" \ 28.279 --"2: " LOCK_PREFIX "cmpxchgl %3, %2\n\ 28.280 -+"2: " LOCK "cmpxchgl %3, %2\n\ 28.281 - jnz 1b\n\ 28.282 - 3: .section .fixup,\"ax\"\n\ 28.283 - 4: mov %5, %1\n\ 28.284 -@@ -68,7 +68,7 @@ futex_atomic_op_inuser (int encoded_op, 28.285 - #endif 28.286 - switch (op) { 28.287 - case FUTEX_OP_ADD: 28.288 -- __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, 28.289 -+ __futex_atomic_op1(LOCK "xaddl %0, %2", ret, 28.290 - oldval, uaddr, oparg); 28.291 - break; 28.292 - case FUTEX_OP_OR: 28.293 -diff -pruN ../pristine-linux-2.6.16-rc3/include/asm-i386/rwsem.h ./include/asm-i386/rwsem.h 28.294 ---- ../pristine-linux-2.6.16-rc3/include/asm-i386/rwsem.h 2006-01-03 03:21:10.000000000 +0000 28.295 -+++ ./include/asm-i386/rwsem.h 2006-02-15 20:45:57.000000000 +0000 28.296 -@@ -40,6 +40,7 @@ 28.297 - 28.298 - #include <linux/list.h> 28.299 - #include <linux/spinlock.h> 28.300 -+#include <asm/smp_alt.h> 28.301 - 28.302 - struct rwsem_waiter; 28.303 - 28.304 -@@ -99,7 +100,7 @@ static inline void __down_read(struct rw 28.305 - { 28.306 - __asm__ __volatile__( 28.307 - "# beginning down_read\n\t" 28.308 --LOCK_PREFIX " incl (%%eax)\n\t" /* adds 0x00000001, returns the old value */ 28.309 -+LOCK " incl (%%eax)\n\t" /* adds 0x00000001, returns the old value */ 28.310 - " js 2f\n\t" /* jump if we weren't granted the lock */ 28.311 - "1:\n\t" 28.312 - LOCK_SECTION_START("") 28.313 -@@ -130,7 +131,7 @@ static inline int __down_read_trylock(st 28.314 - " movl %1,%2\n\t" 28.315 - " addl %3,%2\n\t" 28.316 - " jle 2f\n\t" 28.317 --LOCK_PREFIX " cmpxchgl %2,%0\n\t" 28.318 -+LOCK " cmpxchgl %2,%0\n\t" 28.319 - " jnz 1b\n\t" 28.320 - "2:\n\t" 28.321 - "# ending __down_read_trylock\n\t" 28.322 -@@ -150,7 +151,7 @@ static inline void __down_write(struct r 28.323 - tmp = RWSEM_ACTIVE_WRITE_BIAS; 28.324 - __asm__ __volatile__( 28.325 - "# beginning down_write\n\t" 28.326 --LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */ 28.327 -+LOCK " xadd %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */ 28.328 - " testl %%edx,%%edx\n\t" /* was the count 0 before? */ 28.329 - " jnz 2f\n\t" /* jump if we weren't granted the lock */ 28.330 - "1:\n\t" 28.331 -@@ -188,7 +189,7 @@ static inline void __up_read(struct rw_s 28.332 - __s32 tmp = -RWSEM_ACTIVE_READ_BIAS; 28.333 - __asm__ __volatile__( 28.334 - "# beginning __up_read\n\t" 28.335 --LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */ 28.336 -+LOCK " xadd %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */ 28.337 - " js 2f\n\t" /* jump if the lock is being waited upon */ 28.338 - "1:\n\t" 28.339 - LOCK_SECTION_START("") 28.340 -@@ -214,7 +215,7 @@ static inline void __up_write(struct rw_ 28.341 - __asm__ __volatile__( 28.342 - "# beginning __up_write\n\t" 28.343 - " movl %2,%%edx\n\t" 28.344 --LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */ 28.345 -+LOCK " xaddl %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */ 28.346 - " jnz 2f\n\t" /* jump if the lock is being waited upon */ 28.347 - "1:\n\t" 28.348 - LOCK_SECTION_START("") 28.349 -@@ -239,7 +240,7 @@ static inline void __downgrade_write(str 28.350 - { 28.351 - __asm__ __volatile__( 28.352 - "# beginning __downgrade_write\n\t" 28.353 --LOCK_PREFIX " addl %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */ 28.354 -+LOCK " addl %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */ 28.355 - " js 2f\n\t" /* jump if the lock is being waited upon */ 28.356 - "1:\n\t" 28.357 - LOCK_SECTION_START("") 28.358 -@@ -263,7 +264,7 @@ LOCK_PREFIX " addl %2,(%%eax)\n\t" 28.359 - static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) 28.360 - { 28.361 - __asm__ __volatile__( 28.362 --LOCK_PREFIX "addl %1,%0" 28.363 -+LOCK "addl %1,%0" 28.364 - : "=m"(sem->count) 28.365 - : "ir"(delta), "m"(sem->count)); 28.366 - } 28.367 -@@ -276,7 +277,7 @@ static inline int rwsem_atomic_update(in 28.368 - int tmp = delta; 28.369 - 28.370 - __asm__ __volatile__( 28.371 --LOCK_PREFIX "xadd %0,(%2)" 28.372 -+LOCK "xadd %0,(%2)" 28.373 - : "+r"(tmp), "=m"(sem->count) 28.374 - : "r"(sem), "m"(sem->count) 28.375 - : "memory"); 28.376 -diff -pruN ../pristine-linux-2.6.16-rc3/include/asm-i386/smp_alt.h ./include/asm-i386/smp_alt.h 28.377 ---- ../pristine-linux-2.6.16-rc3/include/asm-i386/smp_alt.h 1970-01-01 01:00:00.000000000 +0100 28.378 -+++ ./include/asm-i386/smp_alt.h 2006-02-15 20:45:57.000000000 +0000 28.379 -@@ -0,0 +1,32 @@ 28.380 -+#ifndef __ASM_SMP_ALT_H__ 28.381 -+#define __ASM_SMP_ALT_H__ 28.382 -+ 28.383 -+#include <linux/config.h> 28.384 -+ 28.385 -+#ifdef CONFIG_SMP 28.386 -+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE) 28.387 -+#define LOCK \ 28.388 -+ "6677: nop\n" \ 28.389 -+ ".section __smp_alternatives,\"a\"\n" \ 28.390 -+ ".long 6677b\n" \ 28.391 -+ ".long 6678f\n" \ 28.392 -+ ".previous\n" \ 28.393 -+ ".section __smp_replacements,\"a\"\n" \ 28.394 -+ "6678: .byte 1\n" \ 28.395 -+ ".byte 1\n" \ 28.396 -+ ".byte 0\n" \ 28.397 -+ ".byte 1\n" \ 28.398 -+ ".byte -1\n" \ 28.399 -+ "lock\n" \ 28.400 -+ "nop\n" \ 28.401 -+ ".previous\n" 28.402 -+void prepare_for_smp(void); 28.403 -+void unprepare_for_smp(void); 28.404 -+#else 28.405 -+#define LOCK "lock ; " 28.406 -+#endif 28.407 -+#else 28.408 -+#define LOCK "" 28.409 -+#endif 28.410 -+ 28.411 -+#endif /* __ASM_SMP_ALT_H__ */ 28.412 -diff -pruN ../pristine-linux-2.6.16-rc3/include/asm-i386/spinlock.h ./include/asm-i386/spinlock.h 28.413 ---- ../pristine-linux-2.6.16-rc3/include/asm-i386/spinlock.h 2006-01-03 03:21:10.000000000 +0000 28.414 -+++ ./include/asm-i386/spinlock.h 2006-02-15 20:45:57.000000000 +0000 28.415 -@@ -6,6 +6,7 @@ 28.416 - #include <asm/page.h> 28.417 - #include <linux/config.h> 28.418 - #include <linux/compiler.h> 28.419 -+#include <asm/smp_alt.h> 28.420 - 28.421 - /* 28.422 - * Your basic SMP spinlocks, allowing only a single CPU anywhere 28.423 -@@ -23,7 +24,8 @@ 28.424 - 28.425 - #define __raw_spin_lock_string \ 28.426 - "\n1:\t" \ 28.427 -- "lock ; decb %0\n\t" \ 28.428 -+ LOCK \ 28.429 -+ "decb %0\n\t" \ 28.430 - "jns 3f\n" \ 28.431 - "2:\t" \ 28.432 - "rep;nop\n\t" \ 28.433 -@@ -34,7 +36,8 @@ 28.434 - 28.435 - #define __raw_spin_lock_string_flags \ 28.436 - "\n1:\t" \ 28.437 -- "lock ; decb %0\n\t" \ 28.438 -+ LOCK \ 28.439 -+ "decb %0\n\t" \ 28.440 - "jns 4f\n\t" \ 28.441 - "2:\t" \ 28.442 - "testl $0x200, %1\n\t" \ 28.443 -@@ -65,10 +68,34 @@ static inline void __raw_spin_lock_flags 28.444 - static inline int __raw_spin_trylock(raw_spinlock_t *lock) 28.445 - { 28.446 - char oldval; 28.447 -+#ifdef CONFIG_SMP_ALTERNATIVES 28.448 - __asm__ __volatile__( 28.449 -- "xchgb %b0,%1" 28.450 -+ "1:movb %1,%b0\n" 28.451 -+ "movb $0,%1\n" 28.452 -+ "2:" 28.453 -+ ".section __smp_alternatives,\"a\"\n" 28.454 -+ ".long 1b\n" 28.455 -+ ".long 3f\n" 28.456 -+ ".previous\n" 28.457 -+ ".section __smp_replacements,\"a\"\n" 28.458 -+ "3: .byte 2b - 1b\n" 28.459 -+ ".byte 5f-4f\n" 28.460 -+ ".byte 0\n" 28.461 -+ ".byte 6f-5f\n" 28.462 -+ ".byte -1\n" 28.463 -+ "4: xchgb %b0,%1\n" 28.464 -+ "5: movb %1,%b0\n" 28.465 -+ "movb $0,%1\n" 28.466 -+ "6:\n" 28.467 -+ ".previous\n" 28.468 - :"=q" (oldval), "=m" (lock->slock) 28.469 - :"0" (0) : "memory"); 28.470 -+#else 28.471 -+ __asm__ __volatile__( 28.472 -+ "xchgb %b0,%1\n" 28.473 -+ :"=q" (oldval), "=m" (lock->slock) 28.474 -+ :"0" (0) : "memory"); 28.475 -+#endif 28.476 - return oldval > 0; 28.477 - } 28.478 - 28.479 -@@ -178,12 +205,12 @@ static inline int __raw_write_trylock(ra 28.480 - 28.481 - static inline void __raw_read_unlock(raw_rwlock_t *rw) 28.482 - { 28.483 -- asm volatile("lock ; incl %0" :"=m" (rw->lock) : : "memory"); 28.484 -+ asm volatile(LOCK "incl %0" :"=m" (rw->lock) : : "memory"); 28.485 - } 28.486 - 28.487 - static inline void __raw_write_unlock(raw_rwlock_t *rw) 28.488 - { 28.489 -- asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ", %0" 28.490 -+ asm volatile(LOCK "addl $" RW_LOCK_BIAS_STR ", %0" 28.491 - : "=m" (rw->lock) : : "memory"); 28.492 - } 28.493 - 28.494 -diff -pruN ../pristine-linux-2.6.16-rc3/include/asm-i386/system.h ./include/asm-i386/system.h 28.495 ---- ../pristine-linux-2.6.16-rc3/include/asm-i386/system.h 2006-02-15 20:38:57.000000000 +0000 28.496 -+++ ./include/asm-i386/system.h 2006-02-15 20:45:57.000000000 +0000 28.497 -@@ -5,7 +5,7 @@ 28.498 - #include <linux/kernel.h> 28.499 - #include <asm/segment.h> 28.500 - #include <asm/cpufeature.h> 28.501 --#include <linux/bitops.h> /* for LOCK_PREFIX */ 28.502 -+#include <asm/smp_alt.h> 28.503 - 28.504 - #ifdef __KERNEL__ 28.505 - 28.506 -@@ -271,19 +271,19 @@ static inline unsigned long __cmpxchg(vo 28.507 - unsigned long prev; 28.508 - switch (size) { 28.509 - case 1: 28.510 -- __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2" 28.511 -+ __asm__ __volatile__(LOCK "cmpxchgb %b1,%2" 28.512 - : "=a"(prev) 28.513 - : "q"(new), "m"(*__xg(ptr)), "0"(old) 28.514 - : "memory"); 28.515 - return prev; 28.516 - case 2: 28.517 -- __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2" 28.518 -+ __asm__ __volatile__(LOCK "cmpxchgw %w1,%2" 28.519 - : "=a"(prev) 28.520 - : "r"(new), "m"(*__xg(ptr)), "0"(old) 28.521 - : "memory"); 28.522 - return prev; 28.523 - case 4: 28.524 -- __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2" 28.525 -+ __asm__ __volatile__(LOCK "cmpxchgl %1,%2" 28.526 - : "=a"(prev) 28.527 - : "r"(new), "m"(*__xg(ptr)), "0"(old) 28.528 - : "memory"); 28.529 -@@ -336,7 +336,7 @@ static inline unsigned long long __cmpxc 28.530 - unsigned long long new) 28.531 - { 28.532 - unsigned long long prev; 28.533 -- __asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3" 28.534 -+ __asm__ __volatile__(LOCK "cmpxchg8b %3" 28.535 - : "=A"(prev) 28.536 - : "b"((unsigned long)new), 28.537 - "c"((unsigned long)(new >> 32)), 28.538 -@@ -503,11 +503,55 @@ struct alt_instr { 28.539 - #endif 28.540 - 28.541 - #ifdef CONFIG_SMP 28.542 -+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE) 28.543 -+#define smp_alt_mb(instr) \ 28.544 -+__asm__ __volatile__("6667:\nnop\nnop\nnop\nnop\nnop\nnop\n6668:\n" \ 28.545 -+ ".section __smp_alternatives,\"a\"\n" \ 28.546 -+ ".long 6667b\n" \ 28.547 -+ ".long 6673f\n" \ 28.548 -+ ".previous\n" \ 28.549 -+ ".section __smp_replacements,\"a\"\n" \ 28.550 -+ "6673:.byte 6668b-6667b\n" \ 28.551 -+ ".byte 6670f-6669f\n" \ 28.552 -+ ".byte 6671f-6670f\n" \ 28.553 -+ ".byte 0\n" \ 28.554 -+ ".byte %c0\n" \ 28.555 -+ "6669:lock;addl $0,0(%%esp)\n" \ 28.556 -+ "6670:" instr "\n" \ 28.557 -+ "6671:\n" \ 28.558 -+ ".previous\n" \ 28.559 -+ : \ 28.560 -+ : "i" (X86_FEATURE_XMM2) \ 28.561 -+ : "memory") 28.562 -+#define smp_rmb() smp_alt_mb("lfence") 28.563 -+#define smp_mb() smp_alt_mb("mfence") 28.564 -+#define set_mb(var, value) do { \ 28.565 -+unsigned long __set_mb_temp; \ 28.566 -+__asm__ __volatile__("6667:movl %1, %0\n6668:\n" \ 28.567 -+ ".section __smp_alternatives,\"a\"\n" \ 28.568 -+ ".long 6667b\n" \ 28.569 -+ ".long 6673f\n" \ 28.570 -+ ".previous\n" \ 28.571 -+ ".section __smp_replacements,\"a\"\n" \ 28.572 -+ "6673: .byte 6668b-6667b\n" \ 28.573 -+ ".byte 6670f-6669f\n" \ 28.574 -+ ".byte 0\n" \ 28.575 -+ ".byte 6671f-6670f\n" \ 28.576 -+ ".byte -1\n" \ 28.577 -+ "6669: xchg %1, %0\n" \ 28.578 -+ "6670:movl %1, %0\n" \ 28.579 -+ "6671:\n" \ 28.580 -+ ".previous\n" \ 28.581 -+ : "=m" (var), "=r" (__set_mb_temp) \ 28.582 -+ : "1" (value) \ 28.583 -+ : "memory"); } while (0) 28.584 -+#else 28.585 - #define smp_mb() mb() 28.586 - #define smp_rmb() rmb() 28.587 -+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0) 28.588 -+#endif 28.589 - #define smp_wmb() wmb() 28.590 - #define smp_read_barrier_depends() read_barrier_depends() 28.591 --#define set_mb(var, value) do { (void) xchg(&var, value); } while (0) 28.592 - #else 28.593 - #define smp_mb() barrier() 28.594 - #define smp_rmb() barrier()
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/patches/linux-2.6.16-rc5/i386-mach-io-check-nmi.patch Mon Feb 27 18:44:38 2006 +0100 29.3 @@ -0,0 +1,45 @@ 29.4 +diff -pruN ../pristine-linux-2.6.16-rc5/arch/i386/kernel/traps.c ./arch/i386/kernel/traps.c 29.5 +--- ../pristine-linux-2.6.16-rc5/arch/i386/kernel/traps.c 2006-02-27 15:46:58.000000000 +0000 29.6 ++++ ./arch/i386/kernel/traps.c 2006-02-27 15:55:23.000000000 +0000 29.7 +@@ -567,18 +567,11 @@ static void mem_parity_error(unsigned ch 29.8 + 29.9 + static void io_check_error(unsigned char reason, struct pt_regs * regs) 29.10 + { 29.11 +- unsigned long i; 29.12 +- 29.13 + printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n"); 29.14 + show_registers(regs); 29.15 + 29.16 + /* Re-enable the IOCK line, wait for a few seconds */ 29.17 +- reason = (reason & 0xf) | 8; 29.18 +- outb(reason, 0x61); 29.19 +- i = 2000; 29.20 +- while (--i) udelay(1000); 29.21 +- reason &= ~8; 29.22 +- outb(reason, 0x61); 29.23 ++ clear_io_check_error(reason); 29.24 + } 29.25 + 29.26 + static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) 29.27 +diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/mach-default/mach_traps.h ./include/asm-i386/mach-default/mach_traps.h 29.28 +--- ../pristine-linux-2.6.16-rc5/include/asm-i386/mach-default/mach_traps.h 2006-01-03 03:21:10.000000000 +0000 29.29 ++++ ./include/asm-i386/mach-default/mach_traps.h 2006-02-27 15:55:23.000000000 +0000 29.30 +@@ -15,6 +15,18 @@ static inline void clear_mem_error(unsig 29.31 + outb(reason, 0x61); 29.32 + } 29.33 + 29.34 ++static inline void clear_io_check_error(unsigned char reason) 29.35 ++{ 29.36 ++ unsigned long i; 29.37 ++ 29.38 ++ reason = (reason & 0xf) | 8; 29.39 ++ outb(reason, 0x61); 29.40 ++ i = 2000; 29.41 ++ while (--i) udelay(1000); 29.42 ++ reason &= ~8; 29.43 ++ outb(reason, 0x61); 29.44 ++} 29.45 ++ 29.46 + static inline unsigned char get_nmi_reason(void) 29.47 + { 29.48 + return inb(0x61);
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/patches/linux-2.6.16-rc5/net-csum.patch Mon Feb 27 18:44:38 2006 +0100 30.3 @@ -0,0 +1,41 @@ 30.4 +diff -pruN ../pristine-linux-2.6.16-rc5/net/ipv4/netfilter/ip_nat_proto_tcp.c ./net/ipv4/netfilter/ip_nat_proto_tcp.c 30.5 +--- ../pristine-linux-2.6.16-rc5/net/ipv4/netfilter/ip_nat_proto_tcp.c 2006-02-27 15:47:38.000000000 +0000 30.6 ++++ ./net/ipv4/netfilter/ip_nat_proto_tcp.c 2006-02-27 15:55:25.000000000 +0000 30.7 +@@ -129,10 +129,14 @@ tcp_manip_pkt(struct sk_buff **pskb, 30.8 + if (hdrsize < sizeof(*hdr)) 30.9 + return 1; 30.10 + 30.11 +- hdr->check = ip_nat_cheat_check(~oldip, newip, 30.12 ++ if ((*pskb)->proto_csum_blank) { 30.13 ++ hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check); 30.14 ++ } else { 30.15 ++ hdr->check = ip_nat_cheat_check(~oldip, newip, 30.16 + ip_nat_cheat_check(oldport ^ 0xFFFF, 30.17 + newport, 30.18 + hdr->check)); 30.19 ++ } 30.20 + return 1; 30.21 + } 30.22 + 30.23 +diff -pruN ../pristine-linux-2.6.16-rc5/net/ipv4/netfilter/ip_nat_proto_udp.c ./net/ipv4/netfilter/ip_nat_proto_udp.c 30.24 +--- ../pristine-linux-2.6.16-rc5/net/ipv4/netfilter/ip_nat_proto_udp.c 2006-02-27 15:47:38.000000000 +0000 30.25 ++++ ./net/ipv4/netfilter/ip_nat_proto_udp.c 2006-02-27 15:55:25.000000000 +0000 30.26 +@@ -113,11 +113,16 @@ udp_manip_pkt(struct sk_buff **pskb, 30.27 + newport = tuple->dst.u.udp.port; 30.28 + portptr = &hdr->dest; 30.29 + } 30.30 +- if (hdr->check) /* 0 is a special case meaning no checksum */ 30.31 +- hdr->check = ip_nat_cheat_check(~oldip, newip, 30.32 ++ if (hdr->check) { /* 0 is a special case meaning no checksum */ 30.33 ++ if ((*pskb)->proto_csum_blank) { 30.34 ++ hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check); 30.35 ++ } else { 30.36 ++ hdr->check = ip_nat_cheat_check(~oldip, newip, 30.37 + ip_nat_cheat_check(*portptr ^ 0xFFFF, 30.38 + newport, 30.39 + hdr->check)); 30.40 ++ } 30.41 ++ } 30.42 + *portptr = newport; 30.43 + return 1; 30.44 + }
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/patches/linux-2.6.16-rc5/pmd-shared.patch Mon Feb 27 18:44:38 2006 +0100 31.3 @@ -0,0 +1,111 @@ 31.4 +diff -pruN ../pristine-linux-2.6.16-rc5/arch/i386/mm/pageattr.c ./arch/i386/mm/pageattr.c 31.5 +--- ../pristine-linux-2.6.16-rc5/arch/i386/mm/pageattr.c 2006-02-27 15:46:58.000000000 +0000 31.6 ++++ ./arch/i386/mm/pageattr.c 2006-02-27 15:55:31.000000000 +0000 31.7 +@@ -78,7 +78,7 @@ static void set_pmd_pte(pte_t *kpte, uns 31.8 + unsigned long flags; 31.9 + 31.10 + set_pte_atomic(kpte, pte); /* change init_mm */ 31.11 +- if (PTRS_PER_PMD > 1) 31.12 ++ if (HAVE_SHARED_KERNEL_PMD) 31.13 + return; 31.14 + 31.15 + spin_lock_irqsave(&pgd_lock, flags); 31.16 +diff -pruN ../pristine-linux-2.6.16-rc5/arch/i386/mm/pgtable.c ./arch/i386/mm/pgtable.c 31.17 +--- ../pristine-linux-2.6.16-rc5/arch/i386/mm/pgtable.c 2006-01-03 03:21:10.000000000 +0000 31.18 ++++ ./arch/i386/mm/pgtable.c 2006-02-27 15:55:31.000000000 +0000 31.19 +@@ -215,9 +215,10 @@ void pgd_ctor(void *pgd, kmem_cache_t *c 31.20 + spin_lock_irqsave(&pgd_lock, flags); 31.21 + } 31.22 + 31.23 +- clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD, 31.24 +- swapper_pg_dir + USER_PTRS_PER_PGD, 31.25 +- KERNEL_PGD_PTRS); 31.26 ++ if (PTRS_PER_PMD == 1 || HAVE_SHARED_KERNEL_PMD) 31.27 ++ clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD, 31.28 ++ swapper_pg_dir + USER_PTRS_PER_PGD, 31.29 ++ KERNEL_PGD_PTRS); 31.30 + if (PTRS_PER_PMD > 1) 31.31 + return; 31.32 + 31.33 +@@ -249,6 +250,30 @@ pgd_t *pgd_alloc(struct mm_struct *mm) 31.34 + goto out_oom; 31.35 + set_pgd(&pgd[i], __pgd(1 + __pa(pmd))); 31.36 + } 31.37 ++ 31.38 ++ if (!HAVE_SHARED_KERNEL_PMD) { 31.39 ++ unsigned long flags; 31.40 ++ 31.41 ++ for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) { 31.42 ++ pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL); 31.43 ++ if (!pmd) 31.44 ++ goto out_oom; 31.45 ++ set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd))); 31.46 ++ } 31.47 ++ 31.48 ++ spin_lock_irqsave(&pgd_lock, flags); 31.49 ++ for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) { 31.50 ++ unsigned long v = (unsigned long)i << PGDIR_SHIFT; 31.51 ++ pgd_t *kpgd = pgd_offset_k(v); 31.52 ++ pud_t *kpud = pud_offset(kpgd, v); 31.53 ++ pmd_t *kpmd = pmd_offset(kpud, v); 31.54 ++ pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1); 31.55 ++ memcpy(pmd, kpmd, PAGE_SIZE); 31.56 ++ } 31.57 ++ pgd_list_add(pgd); 31.58 ++ spin_unlock_irqrestore(&pgd_lock, flags); 31.59 ++ } 31.60 ++ 31.61 + return pgd; 31.62 + 31.63 + out_oom: 31.64 +@@ -263,9 +288,23 @@ void pgd_free(pgd_t *pgd) 31.65 + int i; 31.66 + 31.67 + /* in the PAE case user pgd entries are overwritten before usage */ 31.68 +- if (PTRS_PER_PMD > 1) 31.69 +- for (i = 0; i < USER_PTRS_PER_PGD; ++i) 31.70 +- kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1)); 31.71 ++ if (PTRS_PER_PMD > 1) { 31.72 ++ for (i = 0; i < USER_PTRS_PER_PGD; ++i) { 31.73 ++ pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1); 31.74 ++ kmem_cache_free(pmd_cache, pmd); 31.75 ++ } 31.76 ++ if (!HAVE_SHARED_KERNEL_PMD) { 31.77 ++ unsigned long flags; 31.78 ++ spin_lock_irqsave(&pgd_lock, flags); 31.79 ++ pgd_list_del(pgd); 31.80 ++ spin_unlock_irqrestore(&pgd_lock, flags); 31.81 ++ for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) { 31.82 ++ pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1); 31.83 ++ memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t)); 31.84 ++ kmem_cache_free(pmd_cache, pmd); 31.85 ++ } 31.86 ++ } 31.87 ++ } 31.88 + /* in the non-PAE case, free_pgtables() clears user pgd entries */ 31.89 + kmem_cache_free(pgd_cache, pgd); 31.90 + } 31.91 +diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/pgtable-2level-defs.h ./include/asm-i386/pgtable-2level-defs.h 31.92 +--- ../pristine-linux-2.6.16-rc5/include/asm-i386/pgtable-2level-defs.h 2006-01-03 03:21:10.000000000 +0000 31.93 ++++ ./include/asm-i386/pgtable-2level-defs.h 2006-02-27 15:55:31.000000000 +0000 31.94 +@@ -1,6 +1,8 @@ 31.95 + #ifndef _I386_PGTABLE_2LEVEL_DEFS_H 31.96 + #define _I386_PGTABLE_2LEVEL_DEFS_H 31.97 + 31.98 ++#define HAVE_SHARED_KERNEL_PMD 0 31.99 ++ 31.100 + /* 31.101 + * traditional i386 two-level paging structure: 31.102 + */ 31.103 +diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/pgtable-3level-defs.h ./include/asm-i386/pgtable-3level-defs.h 31.104 +--- ../pristine-linux-2.6.16-rc5/include/asm-i386/pgtable-3level-defs.h 2006-01-03 03:21:10.000000000 +0000 31.105 ++++ ./include/asm-i386/pgtable-3level-defs.h 2006-02-27 15:55:31.000000000 +0000 31.106 +@@ -1,6 +1,8 @@ 31.107 + #ifndef _I386_PGTABLE_3LEVEL_DEFS_H 31.108 + #define _I386_PGTABLE_3LEVEL_DEFS_H 31.109 + 31.110 ++#define HAVE_SHARED_KERNEL_PMD 1 31.111 ++ 31.112 + /* 31.113 + * PGDIR_SHIFT determines what a top-level page table entry can map 31.114 + */
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/patches/linux-2.6.16-rc5/smp-alts.patch Mon Feb 27 18:44:38 2006 +0100 32.3 @@ -0,0 +1,591 @@ 32.4 +diff -pruN ../pristine-linux-2.6.16-rc5/arch/i386/Kconfig ./arch/i386/Kconfig 32.5 +--- ../pristine-linux-2.6.16-rc5/arch/i386/Kconfig 2006-02-27 15:46:58.000000000 +0000 32.6 ++++ ./arch/i386/Kconfig 2006-02-27 15:55:34.000000000 +0000 32.7 +@@ -202,6 +202,19 @@ config SMP 32.8 + 32.9 + If you don't know what to do here, say N. 32.10 + 32.11 ++config SMP_ALTERNATIVES 32.12 ++ bool "SMP alternatives support (EXPERIMENTAL)" 32.13 ++ depends on SMP && EXPERIMENTAL 32.14 ++ help 32.15 ++ Try to reduce the overhead of running an SMP kernel on a uniprocessor 32.16 ++ host slightly by replacing certain key instruction sequences 32.17 ++ according to whether we currently have more than one CPU available. 32.18 ++ This should provide a noticeable boost to performance when 32.19 ++ running SMP kernels on UP machines, and have negligible impact 32.20 ++ when running on an true SMP host. 32.21 ++ 32.22 ++ If unsure, say N. 32.23 ++ 32.24 + config NR_CPUS 32.25 + int "Maximum number of CPUs (2-255)" 32.26 + range 2 255 32.27 +diff -pruN ../pristine-linux-2.6.16-rc5/arch/i386/kernel/Makefile ./arch/i386/kernel/Makefile 32.28 +--- ../pristine-linux-2.6.16-rc5/arch/i386/kernel/Makefile 2006-02-27 15:46:58.000000000 +0000 32.29 ++++ ./arch/i386/kernel/Makefile 2006-02-27 15:55:34.000000000 +0000 32.30 +@@ -37,6 +37,7 @@ obj-$(CONFIG_EFI) += efi.o efi_stub.o 32.31 + obj-$(CONFIG_DOUBLEFAULT) += doublefault.o 32.32 + obj-$(CONFIG_VM86) += vm86.o 32.33 + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 32.34 ++obj-$(CONFIG_SMP_ALTERNATIVES) += smpalts.o 32.35 + 32.36 + EXTRA_AFLAGS := -traditional 32.37 + 32.38 +diff -pruN ../pristine-linux-2.6.16-rc5/arch/i386/kernel/smpalts.c ./arch/i386/kernel/smpalts.c 32.39 +--- ../pristine-linux-2.6.16-rc5/arch/i386/kernel/smpalts.c 1970-01-01 01:00:00.000000000 +0100 32.40 ++++ ./arch/i386/kernel/smpalts.c 2006-02-27 15:55:34.000000000 +0000 32.41 +@@ -0,0 +1,85 @@ 32.42 ++#include <linux/kernel.h> 32.43 ++#include <asm/system.h> 32.44 ++#include <asm/smp_alt.h> 32.45 ++#include <asm/processor.h> 32.46 ++#include <asm/string.h> 32.47 ++ 32.48 ++struct smp_replacement_record { 32.49 ++ unsigned char targ_size; 32.50 ++ unsigned char smp1_size; 32.51 ++ unsigned char smp2_size; 32.52 ++ unsigned char up_size; 32.53 ++ unsigned char feature; 32.54 ++ unsigned char data[0]; 32.55 ++}; 32.56 ++ 32.57 ++struct smp_alternative_record { 32.58 ++ void *targ_start; 32.59 ++ struct smp_replacement_record *repl; 32.60 ++}; 32.61 ++ 32.62 ++extern struct smp_alternative_record __start_smp_alternatives_table, 32.63 ++ __stop_smp_alternatives_table; 32.64 ++extern unsigned long __init_begin, __init_end; 32.65 ++ 32.66 ++void prepare_for_smp(void) 32.67 ++{ 32.68 ++ struct smp_alternative_record *r; 32.69 ++ printk(KERN_INFO "Enabling SMP...\n"); 32.70 ++ for (r = &__start_smp_alternatives_table; 32.71 ++ r != &__stop_smp_alternatives_table; 32.72 ++ r++) { 32.73 ++ BUG_ON(r->repl->targ_size < r->repl->smp1_size); 32.74 ++ BUG_ON(r->repl->targ_size < r->repl->smp2_size); 32.75 ++ BUG_ON(r->repl->targ_size < r->repl->up_size); 32.76 ++ if (system_state == SYSTEM_RUNNING && 32.77 ++ r->targ_start >= (void *)&__init_begin && 32.78 ++ r->targ_start < (void *)&__init_end) 32.79 ++ continue; 32.80 ++ if (r->repl->feature != (unsigned char)-1 && 32.81 ++ boot_cpu_has(r->repl->feature)) { 32.82 ++ memcpy(r->targ_start, 32.83 ++ r->repl->data + r->repl->smp1_size, 32.84 ++ r->repl->smp2_size); 32.85 ++ memset(r->targ_start + r->repl->smp2_size, 32.86 ++ 0x90, 32.87 ++ r->repl->targ_size - r->repl->smp2_size); 32.88 ++ } else { 32.89 ++ memcpy(r->targ_start, 32.90 ++ r->repl->data, 32.91 ++ r->repl->smp1_size); 32.92 ++ memset(r->targ_start + r->repl->smp1_size, 32.93 ++ 0x90, 32.94 ++ r->repl->targ_size - r->repl->smp1_size); 32.95 ++ } 32.96 ++ } 32.97 ++ /* Paranoia */ 32.98 ++ asm volatile ("jmp 1f\n1:"); 32.99 ++ mb(); 32.100 ++} 32.101 ++ 32.102 ++void unprepare_for_smp(void) 32.103 ++{ 32.104 ++ struct smp_alternative_record *r; 32.105 ++ printk(KERN_INFO "Disabling SMP...\n"); 32.106 ++ for (r = &__start_smp_alternatives_table; 32.107 ++ r != &__stop_smp_alternatives_table; 32.108 ++ r++) { 32.109 ++ BUG_ON(r->repl->targ_size < r->repl->smp1_size); 32.110 ++ BUG_ON(r->repl->targ_size < r->repl->smp2_size); 32.111 ++ BUG_ON(r->repl->targ_size < r->repl->up_size); 32.112 ++ if (system_state == SYSTEM_RUNNING && 32.113 ++ r->targ_start >= (void *)&__init_begin && 32.114 ++ r->targ_start < (void *)&__init_end) 32.115 ++ continue; 32.116 ++ memcpy(r->targ_start, 32.117 ++ r->repl->data + r->repl->smp1_size + r->repl->smp2_size, 32.118 ++ r->repl->up_size); 32.119 ++ memset(r->targ_start + r->repl->up_size, 32.120 ++ 0x90, 32.121 ++ r->repl->targ_size - r->repl->up_size); 32.122 ++ } 32.123 ++ /* Paranoia */ 32.124 ++ asm volatile ("jmp 1f\n1:"); 32.125 ++ mb(); 32.126 ++} 32.127 +diff -pruN ../pristine-linux-2.6.16-rc5/arch/i386/kernel/smpboot.c ./arch/i386/kernel/smpboot.c 32.128 +--- ../pristine-linux-2.6.16-rc5/arch/i386/kernel/smpboot.c 2006-02-27 15:46:58.000000000 +0000 32.129 ++++ ./arch/i386/kernel/smpboot.c 2006-02-27 15:55:34.000000000 +0000 32.130 +@@ -1208,6 +1208,11 @@ static void __init smp_boot_cpus(unsigne 32.131 + if (max_cpus <= cpucount+1) 32.132 + continue; 32.133 + 32.134 ++#ifdef CONFIG_SMP_ALTERNATIVES 32.135 ++ if (kicked == 1) 32.136 ++ prepare_for_smp(); 32.137 ++#endif 32.138 ++ 32.139 + if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu)) 32.140 + printk("CPU #%d not responding - cannot use it.\n", 32.141 + apicid); 32.142 +@@ -1386,6 +1391,11 @@ int __devinit __cpu_up(unsigned int cpu) 32.143 + return -EIO; 32.144 + } 32.145 + 32.146 ++#ifdef CONFIG_SMP_ALTERNATIVES 32.147 ++ if (num_online_cpus() == 1) 32.148 ++ prepare_for_smp(); 32.149 ++#endif 32.150 ++ 32.151 + local_irq_enable(); 32.152 + per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; 32.153 + /* Unleash the CPU! */ 32.154 +diff -pruN ../pristine-linux-2.6.16-rc5/arch/i386/kernel/vmlinux.lds.S ./arch/i386/kernel/vmlinux.lds.S 32.155 +--- ../pristine-linux-2.6.16-rc5/arch/i386/kernel/vmlinux.lds.S 2006-01-03 03:21:10.000000000 +0000 32.156 ++++ ./arch/i386/kernel/vmlinux.lds.S 2006-02-27 15:55:34.000000000 +0000 32.157 +@@ -34,6 +34,13 @@ SECTIONS 32.158 + __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) } 32.159 + __stop___ex_table = .; 32.160 + 32.161 ++ . = ALIGN(16); 32.162 ++ __start_smp_alternatives_table = .; 32.163 ++ __smp_alternatives : { *(__smp_alternatives) } 32.164 ++ __stop_smp_alternatives_table = .; 32.165 ++ 32.166 ++ __smp_replacements : { *(__smp_replacements) } 32.167 ++ 32.168 + RODATA 32.169 + 32.170 + /* writeable */ 32.171 +diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/atomic.h ./include/asm-i386/atomic.h 32.172 +--- ../pristine-linux-2.6.16-rc5/include/asm-i386/atomic.h 2006-02-27 15:47:25.000000000 +0000 32.173 ++++ ./include/asm-i386/atomic.h 2006-02-27 15:55:34.000000000 +0000 32.174 +@@ -4,18 +4,13 @@ 32.175 + #include <linux/config.h> 32.176 + #include <linux/compiler.h> 32.177 + #include <asm/processor.h> 32.178 ++#include <asm/smp_alt.h> 32.179 + 32.180 + /* 32.181 + * Atomic operations that C can't guarantee us. Useful for 32.182 + * resource counting etc.. 32.183 + */ 32.184 + 32.185 +-#ifdef CONFIG_SMP 32.186 +-#define LOCK "lock ; " 32.187 +-#else 32.188 +-#define LOCK "" 32.189 +-#endif 32.190 +- 32.191 + /* 32.192 + * Make sure gcc doesn't try to be clever and move things around 32.193 + * on us. We need to use _exactly_ the address the user gave us, 32.194 +diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/bitops.h ./include/asm-i386/bitops.h 32.195 +--- ../pristine-linux-2.6.16-rc5/include/asm-i386/bitops.h 2006-02-27 15:47:25.000000000 +0000 32.196 ++++ ./include/asm-i386/bitops.h 2006-02-27 15:55:34.000000000 +0000 32.197 +@@ -7,6 +7,7 @@ 32.198 + 32.199 + #include <linux/config.h> 32.200 + #include <linux/compiler.h> 32.201 ++#include <asm/smp_alt.h> 32.202 + 32.203 + /* 32.204 + * These have to be done with inline assembly: that way the bit-setting 32.205 +@@ -16,12 +17,6 @@ 32.206 + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). 32.207 + */ 32.208 + 32.209 +-#ifdef CONFIG_SMP 32.210 +-#define LOCK_PREFIX "lock ; " 32.211 +-#else 32.212 +-#define LOCK_PREFIX "" 32.213 +-#endif 32.214 +- 32.215 + #define ADDR (*(volatile long *) addr) 32.216 + 32.217 + /** 32.218 +@@ -41,7 +36,7 @@ 32.219 + */ 32.220 + static inline void set_bit(int nr, volatile unsigned long * addr) 32.221 + { 32.222 +- __asm__ __volatile__( LOCK_PREFIX 32.223 ++ __asm__ __volatile__( LOCK 32.224 + "btsl %1,%0" 32.225 + :"+m" (ADDR) 32.226 + :"Ir" (nr)); 32.227 +@@ -76,7 +71,7 @@ static inline void __set_bit(int nr, vol 32.228 + */ 32.229 + static inline void clear_bit(int nr, volatile unsigned long * addr) 32.230 + { 32.231 +- __asm__ __volatile__( LOCK_PREFIX 32.232 ++ __asm__ __volatile__( LOCK 32.233 + "btrl %1,%0" 32.234 + :"+m" (ADDR) 32.235 + :"Ir" (nr)); 32.236 +@@ -121,7 +116,7 @@ static inline void __change_bit(int nr, 32.237 + */ 32.238 + static inline void change_bit(int nr, volatile unsigned long * addr) 32.239 + { 32.240 +- __asm__ __volatile__( LOCK_PREFIX 32.241 ++ __asm__ __volatile__( LOCK 32.242 + "btcl %1,%0" 32.243 + :"+m" (ADDR) 32.244 + :"Ir" (nr)); 32.245 +@@ -140,7 +135,7 @@ static inline int test_and_set_bit(int n 32.246 + { 32.247 + int oldbit; 32.248 + 32.249 +- __asm__ __volatile__( LOCK_PREFIX 32.250 ++ __asm__ __volatile__( LOCK 32.251 + "btsl %2,%1\n\tsbbl %0,%0" 32.252 + :"=r" (oldbit),"+m" (ADDR) 32.253 + :"Ir" (nr) : "memory"); 32.254 +@@ -180,7 +175,7 @@ static inline int test_and_clear_bit(int 32.255 + { 32.256 + int oldbit; 32.257 + 32.258 +- __asm__ __volatile__( LOCK_PREFIX 32.259 ++ __asm__ __volatile__( LOCK 32.260 + "btrl %2,%1\n\tsbbl %0,%0" 32.261 + :"=r" (oldbit),"+m" (ADDR) 32.262 + :"Ir" (nr) : "memory"); 32.263 +@@ -231,7 +226,7 @@ static inline int test_and_change_bit(in 32.264 + { 32.265 + int oldbit; 32.266 + 32.267 +- __asm__ __volatile__( LOCK_PREFIX 32.268 ++ __asm__ __volatile__( LOCK 32.269 + "btcl %2,%1\n\tsbbl %0,%0" 32.270 + :"=r" (oldbit),"+m" (ADDR) 32.271 + :"Ir" (nr) : "memory"); 32.272 +diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/futex.h ./include/asm-i386/futex.h 32.273 +--- ../pristine-linux-2.6.16-rc5/include/asm-i386/futex.h 2006-02-27 15:47:25.000000000 +0000 32.274 ++++ ./include/asm-i386/futex.h 2006-02-27 15:55:34.000000000 +0000 32.275 +@@ -28,7 +28,7 @@ 32.276 + "1: movl %2, %0\n\ 32.277 + movl %0, %3\n" \ 32.278 + insn "\n" \ 32.279 +-"2: " LOCK_PREFIX "cmpxchgl %3, %2\n\ 32.280 ++"2: " LOCK "cmpxchgl %3, %2\n\ 32.281 + jnz 1b\n\ 32.282 + 3: .section .fixup,\"ax\"\n\ 32.283 + 4: mov %5, %1\n\ 32.284 +@@ -68,7 +68,7 @@ futex_atomic_op_inuser (int encoded_op, 32.285 + #endif 32.286 + switch (op) { 32.287 + case FUTEX_OP_ADD: 32.288 +- __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, 32.289 ++ __futex_atomic_op1(LOCK "xaddl %0, %2", ret, 32.290 + oldval, uaddr, oparg); 32.291 + break; 32.292 + case FUTEX_OP_OR: 32.293 +diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/rwsem.h ./include/asm-i386/rwsem.h 32.294 +--- ../pristine-linux-2.6.16-rc5/include/asm-i386/rwsem.h 2006-01-03 03:21:10.000000000 +0000 32.295 ++++ ./include/asm-i386/rwsem.h 2006-02-27 15:55:34.000000000 +0000 32.296 +@@ -40,6 +40,7 @@ 32.297 + 32.298 + #include <linux/list.h> 32.299 + #include <linux/spinlock.h> 32.300 ++#include <asm/smp_alt.h> 32.301 + 32.302 + struct rwsem_waiter; 32.303 + 32.304 +@@ -99,7 +100,7 @@ static inline void __down_read(struct rw 32.305 + { 32.306 + __asm__ __volatile__( 32.307 + "# beginning down_read\n\t" 32.308 +-LOCK_PREFIX " incl (%%eax)\n\t" /* adds 0x00000001, returns the old value */ 32.309 ++LOCK " incl (%%eax)\n\t" /* adds 0x00000001, returns the old value */ 32.310 + " js 2f\n\t" /* jump if we weren't granted the lock */ 32.311 + "1:\n\t" 32.312 + LOCK_SECTION_START("") 32.313 +@@ -130,7 +131,7 @@ static inline int __down_read_trylock(st 32.314 + " movl %1,%2\n\t" 32.315 + " addl %3,%2\n\t" 32.316 + " jle 2f\n\t" 32.317 +-LOCK_PREFIX " cmpxchgl %2,%0\n\t" 32.318 ++LOCK " cmpxchgl %2,%0\n\t" 32.319 + " jnz 1b\n\t" 32.320 + "2:\n\t" 32.321 + "# ending __down_read_trylock\n\t" 32.322 +@@ -150,7 +151,7 @@ static inline void __down_write(struct r 32.323 + tmp = RWSEM_ACTIVE_WRITE_BIAS; 32.324 + __asm__ __volatile__( 32.325 + "# beginning down_write\n\t" 32.326 +-LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */ 32.327 ++LOCK " xadd %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */ 32.328 + " testl %%edx,%%edx\n\t" /* was the count 0 before? */ 32.329 + " jnz 2f\n\t" /* jump if we weren't granted the lock */ 32.330 + "1:\n\t" 32.331 +@@ -188,7 +189,7 @@ static inline void __up_read(struct rw_s 32.332 + __s32 tmp = -RWSEM_ACTIVE_READ_BIAS; 32.333 + __asm__ __volatile__( 32.334 + "# beginning __up_read\n\t" 32.335 +-LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */ 32.336 ++LOCK " xadd %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */ 32.337 + " js 2f\n\t" /* jump if the lock is being waited upon */ 32.338 + "1:\n\t" 32.339 + LOCK_SECTION_START("") 32.340 +@@ -214,7 +215,7 @@ static inline void __up_write(struct rw_ 32.341 + __asm__ __volatile__( 32.342 + "# beginning __up_write\n\t" 32.343 + " movl %2,%%edx\n\t" 32.344 +-LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */ 32.345 ++LOCK " xaddl %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */ 32.346 + " jnz 2f\n\t" /* jump if the lock is being waited upon */ 32.347 + "1:\n\t" 32.348 + LOCK_SECTION_START("") 32.349 +@@ -239,7 +240,7 @@ static inline void __downgrade_write(str 32.350 + { 32.351 + __asm__ __volatile__( 32.352 + "# beginning __downgrade_write\n\t" 32.353 +-LOCK_PREFIX " addl %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */ 32.354 ++LOCK " addl %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */ 32.355 + " js 2f\n\t" /* jump if the lock is being waited upon */ 32.356 + "1:\n\t" 32.357 + LOCK_SECTION_START("") 32.358 +@@ -263,7 +264,7 @@ LOCK_PREFIX " addl %2,(%%eax)\n\t" 32.359 + static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) 32.360 + { 32.361 + __asm__ __volatile__( 32.362 +-LOCK_PREFIX "addl %1,%0" 32.363 ++LOCK "addl %1,%0" 32.364 + : "=m"(sem->count) 32.365 + : "ir"(delta), "m"(sem->count)); 32.366 + } 32.367 +@@ -276,7 +277,7 @@ static inline int rwsem_atomic_update(in 32.368 + int tmp = delta; 32.369 + 32.370 + __asm__ __volatile__( 32.371 +-LOCK_PREFIX "xadd %0,(%2)" 32.372 ++LOCK "xadd %0,(%2)" 32.373 + : "+r"(tmp), "=m"(sem->count) 32.374 + : "r"(sem), "m"(sem->count) 32.375 + : "memory"); 32.376 +diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/smp_alt.h ./include/asm-i386/smp_alt.h 32.377 +--- ../pristine-linux-2.6.16-rc5/include/asm-i386/smp_alt.h 1970-01-01 01:00:00.000000000 +0100 32.378 ++++ ./include/asm-i386/smp_alt.h 2006-02-27 15:55:34.000000000 +0000 32.379 +@@ -0,0 +1,32 @@ 32.380 ++#ifndef __ASM_SMP_ALT_H__ 32.381 ++#define __ASM_SMP_ALT_H__ 32.382 ++ 32.383 ++#include <linux/config.h> 32.384 ++ 32.385 ++#ifdef CONFIG_SMP 32.386 ++#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE) 32.387 ++#define LOCK \ 32.388 ++ "6677: nop\n" \ 32.389 ++ ".section __smp_alternatives,\"a\"\n" \ 32.390 ++ ".long 6677b\n" \ 32.391 ++ ".long 6678f\n" \ 32.392 ++ ".previous\n" \ 32.393 ++ ".section __smp_replacements,\"a\"\n" \ 32.394 ++ "6678: .byte 1\n" \ 32.395 ++ ".byte 1\n" \ 32.396 ++ ".byte 0\n" \ 32.397 ++ ".byte 1\n" \ 32.398 ++ ".byte -1\n" \ 32.399 ++ "lock\n" \ 32.400 ++ "nop\n" \ 32.401 ++ ".previous\n" 32.402 ++void prepare_for_smp(void); 32.403 ++void unprepare_for_smp(void); 32.404 ++#else 32.405 ++#define LOCK "lock ; " 32.406 ++#endif 32.407 ++#else 32.408 ++#define LOCK "" 32.409 ++#endif 32.410 ++ 32.411 ++#endif /* __ASM_SMP_ALT_H__ */ 32.412 +diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/spinlock.h ./include/asm-i386/spinlock.h 32.413 +--- ../pristine-linux-2.6.16-rc5/include/asm-i386/spinlock.h 2006-01-03 03:21:10.000000000 +0000 32.414 ++++ ./include/asm-i386/spinlock.h 2006-02-27 15:55:34.000000000 +0000 32.415 +@@ -6,6 +6,7 @@ 32.416 + #include <asm/page.h> 32.417 + #include <linux/config.h> 32.418 + #include <linux/compiler.h> 32.419 ++#include <asm/smp_alt.h> 32.420 + 32.421 + /* 32.422 + * Your basic SMP spinlocks, allowing only a single CPU anywhere 32.423 +@@ -23,7 +24,8 @@ 32.424 + 32.425 + #define __raw_spin_lock_string \ 32.426 + "\n1:\t" \ 32.427 +- "lock ; decb %0\n\t" \ 32.428 ++ LOCK \ 32.429 ++ "decb %0\n\t" \ 32.430 + "jns 3f\n" \ 32.431 + "2:\t" \ 32.432 + "rep;nop\n\t" \ 32.433 +@@ -34,7 +36,8 @@ 32.434 + 32.435 + #define __raw_spin_lock_string_flags \ 32.436 + "\n1:\t" \ 32.437 +- "lock ; decb %0\n\t" \ 32.438 ++ LOCK \ 32.439 ++ "decb %0\n\t" \ 32.440 + "jns 4f\n\t" \ 32.441 + "2:\t" \ 32.442 + "testl $0x200, %1\n\t" \ 32.443 +@@ -65,10 +68,34 @@ static inline void __raw_spin_lock_flags 32.444 + static inline int __raw_spin_trylock(raw_spinlock_t *lock) 32.445 + { 32.446 + char oldval; 32.447 ++#ifdef CONFIG_SMP_ALTERNATIVES 32.448 + __asm__ __volatile__( 32.449 +- "xchgb %b0,%1" 32.450 ++ "1:movb %1,%b0\n" 32.451 ++ "movb $0,%1\n" 32.452 ++ "2:" 32.453 ++ ".section __smp_alternatives,\"a\"\n" 32.454 ++ ".long 1b\n" 32.455 ++ ".long 3f\n" 32.456 ++ ".previous\n" 32.457 ++ ".section __smp_replacements,\"a\"\n" 32.458 ++ "3: .byte 2b - 1b\n" 32.459 ++ ".byte 5f-4f\n" 32.460 ++ ".byte 0\n" 32.461 ++ ".byte 6f-5f\n" 32.462 ++ ".byte -1\n" 32.463 ++ "4: xchgb %b0,%1\n" 32.464 ++ "5: movb %1,%b0\n" 32.465 ++ "movb $0,%1\n" 32.466 ++ "6:\n" 32.467 ++ ".previous\n" 32.468 + :"=q" (oldval), "=m" (lock->slock) 32.469 + :"0" (0) : "memory"); 32.470 ++#else 32.471 ++ __asm__ __volatile__( 32.472 ++ "xchgb %b0,%1\n" 32.473 ++ :"=q" (oldval), "=m" (lock->slock) 32.474 ++ :"0" (0) : "memory"); 32.475 ++#endif 32.476 + return oldval > 0; 32.477 + } 32.478 + 32.479 +@@ -178,12 +205,12 @@ static inline int __raw_write_trylock(ra 32.480 + 32.481 + static inline void __raw_read_unlock(raw_rwlock_t *rw) 32.482 + { 32.483 +- asm volatile("lock ; incl %0" :"=m" (rw->lock) : : "memory"); 32.484 ++ asm volatile(LOCK "incl %0" :"=m" (rw->lock) : : "memory"); 32.485 + } 32.486 + 32.487 + static inline void __raw_write_unlock(raw_rwlock_t *rw) 32.488 + { 32.489 +- asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ", %0" 32.490 ++ asm volatile(LOCK "addl $" RW_LOCK_BIAS_STR ", %0" 32.491 + : "=m" (rw->lock) : : "memory"); 32.492 + } 32.493 + 32.494 +diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/system.h ./include/asm-i386/system.h 32.495 +--- ../pristine-linux-2.6.16-rc5/include/asm-i386/system.h 2006-02-27 15:47:25.000000000 +0000 32.496 ++++ ./include/asm-i386/system.h 2006-02-27 15:55:34.000000000 +0000 32.497 +@@ -5,7 +5,7 @@ 32.498 + #include <linux/kernel.h> 32.499 + #include <asm/segment.h> 32.500 + #include <asm/cpufeature.h> 32.501 +-#include <linux/bitops.h> /* for LOCK_PREFIX */ 32.502 ++#include <asm/smp_alt.h> 32.503 + 32.504 + #ifdef __KERNEL__ 32.505 + 32.506 +@@ -271,19 +271,19 @@ static inline unsigned long __cmpxchg(vo 32.507 + unsigned long prev; 32.508 + switch (size) { 32.509 + case 1: 32.510 +- __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2" 32.511 ++ __asm__ __volatile__(LOCK "cmpxchgb %b1,%2" 32.512 + : "=a"(prev) 32.513 + : "q"(new), "m"(*__xg(ptr)), "0"(old) 32.514 + : "memory"); 32.515 + return prev; 32.516 + case 2: 32.517 +- __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2" 32.518 ++ __asm__ __volatile__(LOCK "cmpxchgw %w1,%2" 32.519 + : "=a"(prev) 32.520 + : "r"(new), "m"(*__xg(ptr)), "0"(old) 32.521 + : "memory"); 32.522 + return prev; 32.523 + case 4: 32.524 +- __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2" 32.525 ++ __asm__ __volatile__(LOCK "cmpxchgl %1,%2" 32.526 + : "=a"(prev) 32.527 + : "r"(new), "m"(*__xg(ptr)), "0"(old) 32.528 + : "memory"); 32.529 +@@ -336,7 +336,7 @@ static inline unsigned long long __cmpxc 32.530 + unsigned long long new) 32.531 + { 32.532 + unsigned long long prev; 32.533 +- __asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3" 32.534 ++ __asm__ __volatile__(LOCK "cmpxchg8b %3" 32.535 + : "=A"(prev) 32.536 + : "b"((unsigned long)new), 32.537 + "c"((unsigned long)(new >> 32)), 32.538 +@@ -503,11 +503,55 @@ struct alt_instr { 32.539 + #endif 32.540 + 32.541 + #ifdef CONFIG_SMP 32.542 ++#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE) 32.543 ++#define smp_alt_mb(instr) \ 32.544 ++__asm__ __volatile__("6667:\nnop\nnop\nnop\nnop\nnop\nnop\n6668:\n" \ 32.545 ++ ".section __smp_alternatives,\"a\"\n" \ 32.546 ++ ".long 6667b\n" \ 32.547 ++ ".long 6673f\n" \ 32.548 ++ ".previous\n" \ 32.549 ++ ".section __smp_replacements,\"a\"\n" \ 32.550 ++ "6673:.byte 6668b-6667b\n" \ 32.551 ++ ".byte 6670f-6669f\n" \ 32.552 ++ ".byte 6671f-6670f\n" \ 32.553 ++ ".byte 0\n" \ 32.554 ++ ".byte %c0\n" \ 32.555 ++ "6669:lock;addl $0,0(%%esp)\n" \ 32.556 ++ "6670:" instr "\n" \ 32.557 ++ "6671:\n" \ 32.558 ++ ".previous\n" \ 32.559 ++ : \ 32.560 ++ : "i" (X86_FEATURE_XMM2) \ 32.561 ++ : "memory") 32.562 ++#define smp_rmb() smp_alt_mb("lfence") 32.563 ++#define smp_mb() smp_alt_mb("mfence") 32.564 ++#define set_mb(var, value) do { \ 32.565 ++unsigned long __set_mb_temp; \ 32.566 ++__asm__ __volatile__("6667:movl %1, %0\n6668:\n" \ 32.567 ++ ".section __smp_alternatives,\"a\"\n" \ 32.568 ++ ".long 6667b\n" \ 32.569 ++ ".long 6673f\n" \ 32.570 ++ ".previous\n" \ 32.571 ++ ".section __smp_replacements,\"a\"\n" \ 32.572 ++ "6673: .byte 6668b-6667b\n" \ 32.573 ++ ".byte 6670f-6669f\n" \ 32.574 ++ ".byte 0\n" \ 32.575 ++ ".byte 6671f-6670f\n" \ 32.576 ++ ".byte -1\n" \ 32.577 ++ "6669: xchg %1, %0\n" \ 32.578 ++ "6670:movl %1, %0\n" \ 32.579 ++ "6671:\n" \ 32.580 ++ ".previous\n" \ 32.581 ++ : "=m" (var), "=r" (__set_mb_temp) \ 32.582 ++ : "1" (value) \ 32.583 ++ : "memory"); } while (0) 32.584 ++#else 32.585 + #define smp_mb() mb() 32.586 + #define smp_rmb() rmb() 32.587 ++#define set_mb(var, value) do { (void) xchg(&var, value); } while (0) 32.588 ++#endif 32.589 + #define smp_wmb() wmb() 32.590 + #define smp_read_barrier_depends() read_barrier_depends() 32.591 +-#define set_mb(var, value) do { (void) xchg(&var, value); } while (0) 32.592 + #else 32.593 + #define smp_mb() barrier() 32.594 + #define smp_rmb() barrier()
33.1 --- a/tools/libxc/xc_linux_build.c Mon Feb 27 17:26:16 2006 +0100 33.2 +++ b/tools/libxc/xc_linux_build.c Mon Feb 27 18:44:38 2006 +0100 33.3 @@ -46,6 +46,77 @@ 33.4 #define probe_aout9(image,image_size,load_funcs) 1 33.5 #endif 33.6 33.7 +static const char *feature_names[XENFEAT_NR_SUBMAPS*32] = { 33.8 + [XENFEAT_writable_page_tables] = "writable_page_tables", 33.9 + [XENFEAT_writable_descriptor_tables] = "writable_descriptor_tables", 33.10 + [XENFEAT_auto_translated_physmap] = "auto_translated_physmap", 33.11 + [XENFEAT_supervisor_mode_kernel] = "supervisor_mode_kernel", 33.12 + [XENFEAT_pae_pgdir_above_4gb] = "pae_pgdir_above_4gb" 33.13 +}; 33.14 + 33.15 +static inline void set_feature_bit (int nr, uint32_t *addr) 33.16 +{ 33.17 + addr[nr>>5] |= (1<<(nr&31)); 33.18 +} 33.19 + 33.20 +static inline int test_feature_bit(int nr, uint32_t *addr) 33.21 +{ 33.22 + return !!(addr[nr>>5] & (1<<(nr&31))); 33.23 +} 33.24 + 33.25 +static int parse_features( 33.26 + const char *feats, 33.27 + uint32_t supported[XENFEAT_NR_SUBMAPS], 33.28 + uint32_t required[XENFEAT_NR_SUBMAPS]) 33.29 +{ 33.30 + const char *end, *p; 33.31 + int i, req; 33.32 + 33.33 + if ( (end = strchr(feats, ',')) == NULL ) 33.34 + end = feats + strlen(feats); 33.35 + 33.36 + while ( feats < end ) 33.37 + { 33.38 + p = strchr(feats, '|'); 33.39 + if ( (p == NULL) || (p > end) ) 33.40 + p = end; 33.41 + 33.42 + req = (*feats == '!'); 33.43 + if ( req ) 33.44 + feats++; 33.45 + 33.46 + for ( i = 0; i < XENFEAT_NR_SUBMAPS*32; i++ ) 33.47 + { 33.48 + if ( feature_names[i] == NULL ) 33.49 + continue; 33.50 + 33.51 + if ( strncmp(feature_names[i], feats, p-feats) == 0 ) 33.52 + { 33.53 + set_feature_bit(i, supported); 33.54 + if ( required && req ) 33.55 + set_feature_bit(i, required); 33.56 + break; 33.57 + } 33.58 + } 33.59 + 33.60 + if ( i == XENFEAT_NR_SUBMAPS*32 ) 33.61 + { 33.62 + ERROR("Unknown feature \"%.*s\".\n", (int)(p-feats), feats); 33.63 + if ( req ) 33.64 + { 33.65 + ERROR("Kernel requires an unknown hypervisor feature.\n"); 33.66 + return -EINVAL; 33.67 + } 33.68 + } 33.69 + 33.70 + feats = p; 33.71 + if ( *feats == '|' ) 33.72 + feats++; 33.73 + } 33.74 + 33.75 + return -EINVAL; 33.76 +} 33.77 + 33.78 static int probeimageformat(char *image, 33.79 unsigned long image_size, 33.80 struct load_funcs *load_funcs) 33.81 @@ -344,7 +415,8 @@ static int setup_guest(int xc_handle, 33.82 unsigned long shared_info_frame, 33.83 unsigned long flags, 33.84 unsigned int store_evtchn, unsigned long *store_mfn, 33.85 - unsigned int console_evtchn, unsigned long *console_mfn) 33.86 + unsigned int console_evtchn, unsigned long *console_mfn, 33.87 + uint32_t required_features[XENFEAT_NR_SUBMAPS]) 33.88 { 33.89 unsigned long *page_array = NULL; 33.90 struct load_funcs load_funcs; 33.91 @@ -483,7 +555,8 @@ static int setup_guest(int xc_handle, 33.92 unsigned long shared_info_frame, 33.93 unsigned long flags, 33.94 unsigned int store_evtchn, unsigned long *store_mfn, 33.95 - unsigned int console_evtchn, unsigned long *console_mfn) 33.96 + unsigned int console_evtchn, unsigned long *console_mfn, 33.97 + uint32_t required_features[XENFEAT_NR_SUBMAPS]) 33.98 { 33.99 unsigned long *page_array = NULL; 33.100 unsigned long count, i, hypercall_pfn; 33.101 @@ -515,8 +588,9 @@ static int setup_guest(int xc_handle, 33.102 unsigned long vpt_start; 33.103 unsigned long vpt_end; 33.104 unsigned long v_end; 33.105 - unsigned shadow_mode_enabled; 33.106 unsigned long guest_store_mfn, guest_console_mfn, guest_shared_info_mfn; 33.107 + unsigned long shadow_mode_enabled; 33.108 + uint32_t supported_features[XENFEAT_NR_SUBMAPS] = { 0, }; 33.109 33.110 rc = probeimageformat(image, image_size, &load_funcs); 33.111 if ( rc != 0 ) 33.112 @@ -534,8 +608,6 @@ static int setup_guest(int xc_handle, 33.113 goto error_out; 33.114 } 33.115 33.116 - shadow_mode_enabled = !!strstr(dsi.xen_guest_string, 33.117 - "SHADOW=translate"); 33.118 /* 33.119 * Why do we need this? The number of page-table frames depends on the 33.120 * size of the bootstrap address space. But the size of the address space 33.121 @@ -637,6 +709,35 @@ static int setup_guest(int xc_handle, 33.122 (load_funcs.loadimage)(image, image_size, xc_handle, dom, page_array, 33.123 &dsi); 33.124 33.125 + /* Parse and validate kernel features. */ 33.126 + p = strstr(dsi.xen_guest_string, "FEATURES="); 33.127 + if ( p != NULL ) 33.128 + { 33.129 + if ( !parse_features(p + strlen("FEATURES="), 33.130 + supported_features, 33.131 + required_features) ) 33.132 + { 33.133 + ERROR("Failed to parse guest kernel features.\n"); 33.134 + goto error_out; 33.135 + } 33.136 + 33.137 + fprintf(stderr, "Supported features = { %08x }.\n", 33.138 + supported_features[0]); 33.139 + fprintf(stderr, "Required features = { %08x }.\n", 33.140 + required_features[0]); 33.141 + } 33.142 + 33.143 + for ( i = 0; i < XENFEAT_NR_SUBMAPS; i++ ) 33.144 + { 33.145 + if ( (supported_features[i]&required_features[i]) != required_features[i] ) 33.146 + { 33.147 + ERROR("Guest kernel does not support a required feature.\n"); 33.148 + goto error_out; 33.149 + } 33.150 + } 33.151 + 33.152 + shadow_mode_enabled = test_feature_bit(XENFEAT_auto_translated_physmap, required_features); 33.153 + 33.154 /* Load the initial ramdisk image. */ 33.155 if ( initrd_len != 0 ) 33.156 { 33.157 @@ -870,6 +971,7 @@ int xc_linux_build(int xc_handle, 33.158 const char *image_name, 33.159 const char *ramdisk_name, 33.160 const char *cmdline, 33.161 + const char *features, 33.162 unsigned long flags, 33.163 unsigned int store_evtchn, 33.164 unsigned long *store_mfn, 33.165 @@ -886,6 +988,16 @@ int xc_linux_build(int xc_handle, 33.166 char *image = NULL; 33.167 unsigned long image_size, initrd_size=0; 33.168 unsigned long vstartinfo_start, vkern_entry, vstack_start; 33.169 + uint32_t features_bitmap[XENFEAT_NR_SUBMAPS] = { 0, }; 33.170 + 33.171 + if ( features != NULL ) 33.172 + { 33.173 + if ( !parse_features(features, features_bitmap, NULL) ) 33.174 + { 33.175 + PERROR("Failed to parse configured features\n"); 33.176 + goto error_out; 33.177 + } 33.178 + } 33.179 33.180 if ( (nr_pages = get_tot_pages(xc_handle, domid)) < 0 ) 33.181 { 33.182 @@ -940,7 +1052,8 @@ int xc_linux_build(int xc_handle, 33.183 &vstack_start, ctxt, cmdline, 33.184 op.u.getdomaininfo.shared_info_frame, 33.185 flags, store_evtchn, store_mfn, 33.186 - console_evtchn, console_mfn) < 0 ) 33.187 + console_evtchn, console_mfn, 33.188 + features_bitmap) < 0 ) 33.189 { 33.190 ERROR("Error constructing guest OS"); 33.191 goto error_out;
34.1 --- a/tools/libxc/xenguest.h Mon Feb 27 17:26:16 2006 +0100 34.2 +++ b/tools/libxc/xenguest.h Mon Feb 27 18:44:38 2006 +0100 34.3 @@ -47,6 +47,7 @@ int xc_linux_build(int xc_handle, 34.4 const char *image_name, 34.5 const char *ramdisk_name, 34.6 const char *cmdline, 34.7 + const char *features, 34.8 unsigned long flags, 34.9 unsigned int store_evtchn, 34.10 unsigned long *store_mfn,
35.1 --- a/tools/python/xen/lowlevel/xc/xc.c Mon Feb 27 17:26:16 2006 +0100 35.2 +++ b/tools/python/xen/lowlevel/xc/xc.c Mon Feb 27 18:44:38 2006 +0100 35.3 @@ -326,27 +326,29 @@ static PyObject *pyxc_linux_build(XcObje 35.4 PyObject *kwds) 35.5 { 35.6 uint32_t dom; 35.7 - char *image, *ramdisk = NULL, *cmdline = ""; 35.8 + char *image, *ramdisk = NULL, *cmdline = "", *features = NULL; 35.9 int flags = 0; 35.10 int store_evtchn, console_evtchn; 35.11 unsigned long store_mfn = 0; 35.12 unsigned long console_mfn = 0; 35.13 35.14 - static char *kwd_list[] = { "dom", "store_evtchn", 35.15 - "console_evtchn", "image", 35.16 + static char *kwd_list[] = { "dom", "store_evtchn", 35.17 + "console_evtchn", "image", 35.18 /* optional */ 35.19 - "ramdisk", "cmdline", "flags", NULL }; 35.20 + "ramdisk", "cmdline", "flags", 35.21 + "features", NULL }; 35.22 35.23 - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssi", kwd_list, 35.24 + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssis", kwd_list, 35.25 &dom, &store_evtchn, 35.26 - &console_evtchn, &image, 35.27 + &console_evtchn, &image, 35.28 /* optional */ 35.29 - &ramdisk, &cmdline, &flags) ) 35.30 + &ramdisk, &cmdline, &flags, 35.31 + &features) ) 35.32 return NULL; 35.33 35.34 if ( xc_linux_build(self->xc_handle, dom, image, 35.35 - ramdisk, cmdline, flags, 35.36 - store_evtchn, &store_mfn, 35.37 + ramdisk, cmdline, features, flags, 35.38 + store_evtchn, &store_mfn, 35.39 console_evtchn, &console_mfn) != 0 ) { 35.40 if (!errno) 35.41 errno = EINVAL;
36.1 --- a/tools/python/xen/xend/image.py Mon Feb 27 17:26:16 2006 +0100 36.2 +++ b/tools/python/xen/xend/image.py Mon Feb 27 18:44:38 2006 +0100 36.3 @@ -68,6 +68,7 @@ class ImageHandler: 36.4 self.kernel = None 36.5 self.ramdisk = None 36.6 self.cmdline = None 36.7 + self.features = None 36.8 36.9 self.configure(imageConfig, deviceConfig) 36.10 36.11 @@ -89,6 +90,7 @@ class ImageHandler: 36.12 if args: 36.13 self.cmdline += " " + args 36.14 self.ramdisk = get_cfg("ramdisk", '') 36.15 + self.features = get_cfg("features", '') 36.16 36.17 self.vm.storeVm(("image/ostype", self.ostype), 36.18 ("image/kernel", self.kernel), 36.19 @@ -175,13 +177,15 @@ class LinuxImageHandler(ImageHandler): 36.20 log.debug("cmdline = %s", self.cmdline) 36.21 log.debug("ramdisk = %s", self.ramdisk) 36.22 log.debug("vcpus = %d", self.vm.getVCpuCount()) 36.23 + log.debug("features = %s", self.features) 36.24 36.25 return xc.linux_build(dom = self.vm.getDomid(), 36.26 image = self.kernel, 36.27 store_evtchn = store_evtchn, 36.28 console_evtchn = console_evtchn, 36.29 cmdline = self.cmdline, 36.30 - ramdisk = self.ramdisk) 36.31 + ramdisk = self.ramdisk, 36.32 + features = self.features) 36.33 36.34 class HVMImageHandler(ImageHandler): 36.35
37.1 --- a/tools/python/xen/xm/create.py Mon Feb 27 17:26:16 2006 +0100 37.2 +++ b/tools/python/xen/xm/create.py Mon Feb 27 18:44:38 2006 +0100 37.3 @@ -137,6 +137,10 @@ gopts.var('ramdisk', val='FILE', 37.4 fn=set_value, default='', 37.5 use="Path to ramdisk.") 37.6 37.7 +gopts.var('features', val='FEATURES', 37.8 + fn=set_value, default='', 37.9 + use="Features to enable in guest kernel") 37.10 + 37.11 gopts.var('builder', val='FUNCTION', 37.12 fn=set_value, default='linux', 37.13 use="Function to use to build the domain.") 37.14 @@ -445,6 +449,8 @@ def configure_image(vals): 37.15 config_image.append(['root', cmdline_root]) 37.16 if vals.extra: 37.17 config_image.append(['args', vals.extra]) 37.18 + if vals.features: 37.19 + config_image.append(['features', vals.features]) 37.20 37.21 if vals.builder == 'hvm': 37.22 configure_hvm(config_image, vals)
38.1 --- a/xen/arch/x86/domain_build.c Mon Feb 27 17:26:16 2006 +0100 38.2 +++ b/xen/arch/x86/domain_build.c Mon Feb 27 18:44:38 2006 +0100 38.3 @@ -802,6 +802,14 @@ int construct_dom0(struct domain *d, 38.4 v->arch.guest_context.user_regs.fs &= ~3; 38.5 v->arch.guest_context.user_regs.gs &= ~3; 38.6 printk("Dom0 runs in ring 0 (supervisor mode)\n"); 38.7 + if ( !test_bit(XENFEAT_supervisor_mode_kernel, 38.8 + dom0_features_supported) ) 38.9 + panic("Dom0 does not support supervisor-mode execution\n"); 38.10 + } 38.11 + else 38.12 + { 38.13 + if ( test_bit(XENFEAT_supervisor_mode_kernel, dom0_features_required) ) 38.14 + panic("Dom0 requires supervisor-mode execution\n"); 38.15 } 38.16 38.17 rc = 0;
39.1 --- a/xen/arch/x86/mm.c Mon Feb 27 17:26:16 2006 +0100 39.2 +++ b/xen/arch/x86/mm.c Mon Feb 27 18:44:38 2006 +0100 39.3 @@ -1570,42 +1570,68 @@ int new_guest_cr3(unsigned long mfn) 39.4 unsigned long old_base_mfn; 39.5 39.6 if ( shadow_mode_refcounts(d) ) 39.7 + { 39.8 okay = get_page_from_pagenr(mfn, d); 39.9 + if ( unlikely(!okay) ) 39.10 + { 39.11 + MEM_LOG("Error while installing new baseptr %lx", mfn); 39.12 + return 0; 39.13 + } 39.14 + } 39.15 else 39.16 - okay = get_page_and_type_from_pagenr(mfn, PGT_root_page_table, d); 39.17 - 39.18 - if ( likely(okay) ) 39.19 { 39.20 - invalidate_shadow_ldt(v); 39.21 - 39.22 - old_base_mfn = pagetable_get_pfn(v->arch.guest_table); 39.23 - v->arch.guest_table = mk_pagetable(mfn << PAGE_SHIFT); 39.24 - update_pagetables(v); /* update shadow_table and monitor_table */ 39.25 - 39.26 - write_ptbase(v); 39.27 - 39.28 + okay = get_page_and_type_from_pagenr(mfn, PGT_root_page_table, d); 39.29 + if ( unlikely(!okay) ) 39.30 + { 39.31 + /* Switch to idle pagetable: this VCPU has no active p.t. now. */ 39.32 + old_base_mfn = pagetable_get_pfn(v->arch.guest_table); 39.33 + v->arch.guest_table = mk_pagetable(0); 39.34 + update_pagetables(v); 39.35 + write_cr3(__pa(idle_pg_table)); 39.36 + if ( old_base_mfn != 0 ) 39.37 + put_page_and_type(mfn_to_page(old_base_mfn)); 39.38 + 39.39 + /* Retry the validation with no active p.t. for this VCPU. */ 39.40 + okay = get_page_and_type_from_pagenr(mfn, PGT_root_page_table, d); 39.41 + if ( !okay ) 39.42 + { 39.43 + /* Failure here is unrecoverable: the VCPU has no pagetable! */ 39.44 + MEM_LOG("Fatal error while installing new baseptr %lx", mfn); 39.45 + domain_crash(d); 39.46 + percpu_info[v->processor].deferred_ops = 0; 39.47 + return 0; 39.48 + } 39.49 + } 39.50 + } 39.51 + 39.52 + invalidate_shadow_ldt(v); 39.53 + 39.54 + old_base_mfn = pagetable_get_pfn(v->arch.guest_table); 39.55 + v->arch.guest_table = mk_pagetable(mfn << PAGE_SHIFT); 39.56 + update_pagetables(v); /* update shadow_table and monitor_table */ 39.57 + 39.58 + write_ptbase(v); 39.59 + 39.60 + if ( likely(old_base_mfn != 0) ) 39.61 + { 39.62 if ( shadow_mode_refcounts(d) ) 39.63 put_page(mfn_to_page(old_base_mfn)); 39.64 else 39.65 put_page_and_type(mfn_to_page(old_base_mfn)); 39.66 - 39.67 - /* CR3 also holds a ref to its shadow... */ 39.68 - if ( shadow_mode_enabled(d) ) 39.69 - { 39.70 - if ( v->arch.monitor_shadow_ref ) 39.71 - put_shadow_ref(v->arch.monitor_shadow_ref); 39.72 - v->arch.monitor_shadow_ref = 39.73 - pagetable_get_pfn(v->arch.monitor_table); 39.74 - ASSERT(!page_get_owner(mfn_to_page(v->arch.monitor_shadow_ref))); 39.75 - get_shadow_ref(v->arch.monitor_shadow_ref); 39.76 - } 39.77 } 39.78 - else 39.79 + 39.80 + /* CR3 also holds a ref to its shadow... */ 39.81 + if ( shadow_mode_enabled(d) ) 39.82 { 39.83 - MEM_LOG("Error while installing new baseptr %lx", mfn); 39.84 + if ( v->arch.monitor_shadow_ref ) 39.85 + put_shadow_ref(v->arch.monitor_shadow_ref); 39.86 + v->arch.monitor_shadow_ref = 39.87 + pagetable_get_pfn(v->arch.monitor_table); 39.88 + ASSERT(!page_get_owner(mfn_to_page(v->arch.monitor_shadow_ref))); 39.89 + get_shadow_ref(v->arch.monitor_shadow_ref); 39.90 } 39.91 39.92 - return okay; 39.93 + return 1; 39.94 } 39.95 39.96 static void process_deferred_ops(unsigned int cpu) 39.97 @@ -1625,7 +1651,7 @@ static void process_deferred_ops(unsigne 39.98 else 39.99 local_flush_tlb(); 39.100 } 39.101 - 39.102 + 39.103 if ( deferred_ops & DOP_RELOAD_LDT ) 39.104 (void)map_ldt_shadow_page(0); 39.105