[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Linux: upgrade patches to 2.6.16.13.
# HG changeset patch # User cl349@xxxxxxxxxxxxxxxxxxxx # Node ID ad5b833122a8d88be39629751e1ee5c1d8629f96 # Parent 44e5abbf333b8d393423d99f89d2191dba022659 Linux: upgrade patches to 2.6.16.13. Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx> --- patches/linux-2.6.16/device_bind.patch | 13 patches/linux-2.6.16/i386-mach-io-check-nmi.patch | 35 patches/linux-2.6.16/net-csum.patch | 58 - patches/linux-2.6.16/pmd-shared.patch | 100 - patches/linux-2.6.16/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch | 27 patches/linux-2.6.16/smp-alts.patch | 540 ---------- patches/linux-2.6.16/x86-increase-interrupt-vector-range.patch | 90 - patches/linux-2.6.16/xenoprof-generic.patch | 345 ------ patches/linux-2.6.16.13/device_bind.patch | 9 patches/linux-2.6.16.13/i386-mach-io-check-nmi.patch | 30 patches/linux-2.6.16.13/net-csum.patch | 43 patches/linux-2.6.16.13/pmd-shared.patch | 57 + patches/linux-2.6.16.13/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch | 26 patches/linux-2.6.16.13/smp-alts.patch | 330 ++++++ patches/linux-2.6.16.13/x86-increase-interrupt-vector-range.patch | 73 + patches/linux-2.6.16.13/xenoprof-generic.patch | 230 ++++ 16 files changed, 798 insertions(+), 1208 deletions(-) diff -r 44e5abbf333b -r ad5b833122a8 patches/linux-2.6.16.13/device_bind.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/linux-2.6.16.13/device_bind.patch Thu May 04 17:44:14 2006 +0100 @@ -0,0 +1,15 @@ +diff -pruN ../pristine-linux-2.6.16.13/drivers/base/bus.c ./drivers/base/bus.c +--- ../pristine-linux-2.6.16.13/drivers/base/bus.c 2006-05-02 22:38:44.000000000 +0100 ++++ ./drivers/base/bus.c 2006-05-04 17:41:30.000000000 +0100 +@@ -188,6 +188,11 @@ static ssize_t driver_bind(struct device + up(&dev->sem); + if (dev->parent) + up(&dev->parent->sem); ++ ++ if (err > 0) /* success */ ++ err = count; ++ else if (err == 0) /* driver didn't accept device */ ++ err = -ENODEV; + } + put_device(dev); + put_bus(bus); diff -r 44e5abbf333b -r ad5b833122a8 patches/linux-2.6.16.13/i386-mach-io-check-nmi.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/linux-2.6.16.13/i386-mach-io-check-nmi.patch Thu May 04 17:44:14 2006 +0100 @@ -0,0 +1,45 @@ +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/traps.c ./arch/i386/kernel/traps.c +--- ../pristine-linux-2.6.16.13/arch/i386/kernel/traps.c 2006-05-02 22:38:44.000000000 +0100 ++++ ./arch/i386/kernel/traps.c 2006-05-04 17:41:34.000000000 +0100 +@@ -567,18 +567,11 @@ static void mem_parity_error(unsigned ch + + static void io_check_error(unsigned char reason, struct pt_regs * regs) + { +- unsigned long i; +- + printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n"); + show_registers(regs); + + /* Re-enable the IOCK line, wait for a few seconds */ +- reason = (reason & 0xf) | 8; +- outb(reason, 0x61); +- i = 2000; +- while (--i) udelay(1000); +- reason &= ~8; +- outb(reason, 0x61); ++ clear_io_check_error(reason); + } + + static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/mach-default/mach_traps.h ./include/asm-i386/mach-default/mach_traps.h +--- ../pristine-linux-2.6.16.13/include/asm-i386/mach-default/mach_traps.h 2006-05-02 22:38:44.000000000 +0100 ++++ ./include/asm-i386/mach-default/mach_traps.h 2006-05-04 17:41:34.000000000 +0100 +@@ -15,6 +15,18 @@ static inline void clear_mem_error(unsig + outb(reason, 0x61); + } + ++static inline void clear_io_check_error(unsigned char reason) ++{ ++ unsigned long i; ++ ++ reason = (reason & 0xf) | 8; ++ outb(reason, 0x61); ++ i = 2000; ++ while (--i) udelay(1000); ++ reason &= ~8; ++ outb(reason, 0x61); ++} ++ + static inline unsigned char get_nmi_reason(void) + { + return inb(0x61); diff -r 44e5abbf333b -r ad5b833122a8 patches/linux-2.6.16.13/net-csum.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/linux-2.6.16.13/net-csum.patch Thu May 04 17:44:14 2006 +0100 @@ -0,0 +1,64 @@ +diff -pruN ../pristine-linux-2.6.16.13/net/ipv4/netfilter/ip_nat_proto_tcp.c ./net/ipv4/netfilter/ip_nat_proto_tcp.c +--- ../pristine-linux-2.6.16.13/net/ipv4/netfilter/ip_nat_proto_tcp.c 2006-05-02 22:38:44.000000000 +0100 ++++ ./net/ipv4/netfilter/ip_nat_proto_tcp.c 2006-05-04 17:41:37.000000000 +0100 +@@ -129,10 +129,14 @@ tcp_manip_pkt(struct sk_buff **pskb, + if (hdrsize < sizeof(*hdr)) + return 1; + +- hdr->check = ip_nat_cheat_check(~oldip, newip, ++ if ((*pskb)->proto_csum_blank) { ++ hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check); ++ } else { ++ hdr->check = ip_nat_cheat_check(~oldip, newip, + ip_nat_cheat_check(oldport ^ 0xFFFF, + newport, + hdr->check)); ++ } + return 1; + } + +diff -pruN ../pristine-linux-2.6.16.13/net/ipv4/netfilter/ip_nat_proto_udp.c ./net/ipv4/netfilter/ip_nat_proto_udp.c +--- ../pristine-linux-2.6.16.13/net/ipv4/netfilter/ip_nat_proto_udp.c 2006-05-02 22:38:44.000000000 +0100 ++++ ./net/ipv4/netfilter/ip_nat_proto_udp.c 2006-05-04 17:41:37.000000000 +0100 +@@ -113,11 +113,16 @@ udp_manip_pkt(struct sk_buff **pskb, + newport = tuple->dst.u.udp.port; + portptr = &hdr->dest; + } +- if (hdr->check) /* 0 is a special case meaning no checksum */ +- hdr->check = ip_nat_cheat_check(~oldip, newip, ++ if (hdr->check) { /* 0 is a special case meaning no checksum */ ++ if ((*pskb)->proto_csum_blank) { ++ hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check); ++ } else { ++ hdr->check = ip_nat_cheat_check(~oldip, newip, + ip_nat_cheat_check(*portptr ^ 0xFFFF, + newport, + hdr->check)); ++ } ++ } + *portptr = newport; + return 1; + } +diff -pruN ../pristine-linux-2.6.16.13/net/ipv4/xfrm4_output.c ./net/ipv4/xfrm4_output.c +--- ../pristine-linux-2.6.16.13/net/ipv4/xfrm4_output.c 2006-05-02 22:38:44.000000000 +0100 ++++ ./net/ipv4/xfrm4_output.c 2006-05-04 17:41:37.000000000 +0100 +@@ -17,6 +17,8 @@ + #include <net/xfrm.h> + #include <net/icmp.h> + ++extern int skb_checksum_setup(struct sk_buff *skb); ++ + /* Add encapsulation header. + * + * In transport mode, the IP header will be moved forward to make space +@@ -103,6 +105,10 @@ static int xfrm4_output_one(struct sk_bu + struct xfrm_state *x = dst->xfrm; + int err; + ++ err = skb_checksum_setup(skb); ++ if (err) ++ goto error_nolock; ++ + if (skb->ip_summed == CHECKSUM_HW) { + err = skb_checksum_help(skb, 0); + if (err) diff -r 44e5abbf333b -r ad5b833122a8 patches/linux-2.6.16.13/pmd-shared.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/linux-2.6.16.13/pmd-shared.patch Thu May 04 17:44:14 2006 +0100 @@ -0,0 +1,111 @@ +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/mm/pageattr.c ./arch/i386/mm/pageattr.c +--- ../pristine-linux-2.6.16.13/arch/i386/mm/pageattr.c 2006-05-02 22:38:44.000000000 +0100 ++++ ./arch/i386/mm/pageattr.c 2006-05-04 17:41:40.000000000 +0100 +@@ -78,7 +78,7 @@ static void set_pmd_pte(pte_t *kpte, uns + unsigned long flags; + + set_pte_atomic(kpte, pte); /* change init_mm */ +- if (PTRS_PER_PMD > 1) ++ if (HAVE_SHARED_KERNEL_PMD) + return; + + spin_lock_irqsave(&pgd_lock, flags); +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/mm/pgtable.c ./arch/i386/mm/pgtable.c +--- ../pristine-linux-2.6.16.13/arch/i386/mm/pgtable.c 2006-05-02 22:38:44.000000000 +0100 ++++ ./arch/i386/mm/pgtable.c 2006-05-04 17:41:40.000000000 +0100 +@@ -215,9 +215,10 @@ void pgd_ctor(void *pgd, kmem_cache_t *c + spin_lock_irqsave(&pgd_lock, flags); + } + +- clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD, +- swapper_pg_dir + USER_PTRS_PER_PGD, +- KERNEL_PGD_PTRS); ++ if (PTRS_PER_PMD == 1 || HAVE_SHARED_KERNEL_PMD) ++ clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD, ++ swapper_pg_dir + USER_PTRS_PER_PGD, ++ KERNEL_PGD_PTRS); + if (PTRS_PER_PMD > 1) + return; + +@@ -249,6 +250,30 @@ pgd_t *pgd_alloc(struct mm_struct *mm) + goto out_oom; + set_pgd(&pgd[i], __pgd(1 + __pa(pmd))); + } ++ ++ if (!HAVE_SHARED_KERNEL_PMD) { ++ unsigned long flags; ++ ++ for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) { ++ pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL); ++ if (!pmd) ++ goto out_oom; ++ set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd))); ++ } ++ ++ spin_lock_irqsave(&pgd_lock, flags); ++ for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) { ++ unsigned long v = (unsigned long)i << PGDIR_SHIFT; ++ pgd_t *kpgd = pgd_offset_k(v); ++ pud_t *kpud = pud_offset(kpgd, v); ++ pmd_t *kpmd = pmd_offset(kpud, v); ++ pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1); ++ memcpy(pmd, kpmd, PAGE_SIZE); ++ } ++ pgd_list_add(pgd); ++ spin_unlock_irqrestore(&pgd_lock, flags); ++ } ++ + return pgd; + + out_oom: +@@ -263,9 +288,23 @@ void pgd_free(pgd_t *pgd) + int i; + + /* in the PAE case user pgd entries are overwritten before usage */ +- if (PTRS_PER_PMD > 1) +- for (i = 0; i < USER_PTRS_PER_PGD; ++i) +- kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1)); ++ if (PTRS_PER_PMD > 1) { ++ for (i = 0; i < USER_PTRS_PER_PGD; ++i) { ++ pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1); ++ kmem_cache_free(pmd_cache, pmd); ++ } ++ if (!HAVE_SHARED_KERNEL_PMD) { ++ unsigned long flags; ++ spin_lock_irqsave(&pgd_lock, flags); ++ pgd_list_del(pgd); ++ spin_unlock_irqrestore(&pgd_lock, flags); ++ for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) { ++ pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1); ++ memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t)); ++ kmem_cache_free(pmd_cache, pmd); ++ } ++ } ++ } + /* in the non-PAE case, free_pgtables() clears user pgd entries */ + kmem_cache_free(pgd_cache, pgd); + } +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/pgtable-2level-defs.h ./include/asm-i386/pgtable-2level-defs.h +--- ../pristine-linux-2.6.16.13/include/asm-i386/pgtable-2level-defs.h 2006-05-02 22:38:44.000000000 +0100 ++++ ./include/asm-i386/pgtable-2level-defs.h 2006-05-04 17:41:40.000000000 +0100 +@@ -1,6 +1,8 @@ + #ifndef _I386_PGTABLE_2LEVEL_DEFS_H + #define _I386_PGTABLE_2LEVEL_DEFS_H + ++#define HAVE_SHARED_KERNEL_PMD 0 ++ + /* + * traditional i386 two-level paging structure: + */ +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/pgtable-3level-defs.h ./include/asm-i386/pgtable-3level-defs.h +--- ../pristine-linux-2.6.16.13/include/asm-i386/pgtable-3level-defs.h 2006-05-02 22:38:44.000000000 +0100 ++++ ./include/asm-i386/pgtable-3level-defs.h 2006-05-04 17:41:40.000000000 +0100 +@@ -1,6 +1,8 @@ + #ifndef _I386_PGTABLE_3LEVEL_DEFS_H + #define _I386_PGTABLE_3LEVEL_DEFS_H + ++#define HAVE_SHARED_KERNEL_PMD 1 ++ + /* + * PGDIR_SHIFT determines what a top-level page table entry can map + */ diff -r 44e5abbf333b -r ad5b833122a8 patches/linux-2.6.16.13/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/linux-2.6.16.13/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch Thu May 04 17:44:14 2006 +0100 @@ -0,0 +1,30 @@ +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/entry.S ./arch/i386/kernel/entry.S +--- ../pristine-linux-2.6.16.13/arch/i386/kernel/entry.S 2006-05-02 22:38:44.000000000 +0100 ++++ ./arch/i386/kernel/entry.S 2006-05-04 17:41:44.000000000 +0100 +@@ -177,7 +177,7 @@ need_resched: + + # sysenter call handler stub + ENTRY(sysenter_entry) +- movl TSS_sysenter_esp0(%esp),%esp ++ movl SYSENTER_stack_esp0(%esp),%esp + sysenter_past_esp: + sti + pushl $(__USER_DS) +@@ -492,7 +492,7 @@ device_not_available_emulate: + * that sets up the real kernel stack. Check here, since we can't + * allow the wrong stack to be used. + * +- * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have ++ * "SYSENTER_stack_esp0+12" is because the NMI/debug handler will have + * already pushed 3 words if it hits on the sysenter instruction: + * eflags, cs and eip. + * +@@ -504,7 +504,7 @@ device_not_available_emulate: + cmpw $__KERNEL_CS,4(%esp); \ + jne ok; \ + label: \ +- movl TSS_sysenter_esp0+offset(%esp),%esp; \ ++ movl SYSENTER_stack_esp0+offset(%esp),%esp; \ + pushfl; \ + pushl $__KERNEL_CS; \ + pushl $sysenter_past_esp diff -r 44e5abbf333b -r ad5b833122a8 patches/linux-2.6.16.13/smp-alts.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/linux-2.6.16.13/smp-alts.patch Thu May 04 17:44:14 2006 +0100 @@ -0,0 +1,591 @@ +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/Kconfig ./arch/i386/Kconfig +--- ../pristine-linux-2.6.16.13/arch/i386/Kconfig 2006-05-02 22:38:44.000000000 +0100 ++++ ./arch/i386/Kconfig 2006-05-04 17:41:45.000000000 +0100 +@@ -202,6 +202,19 @@ config SMP + + If you don't know what to do here, say N. + ++config SMP_ALTERNATIVES ++ bool "SMP alternatives support (EXPERIMENTAL)" ++ depends on SMP && EXPERIMENTAL ++ help ++ Try to reduce the overhead of running an SMP kernel on a uniprocessor ++ host slightly by replacing certain key instruction sequences ++ according to whether we currently have more than one CPU available. ++ This should provide a noticeable boost to performance when ++ running SMP kernels on UP machines, and have negligible impact ++ when running on an true SMP host. ++ ++ If unsure, say N. ++ + config NR_CPUS + int "Maximum number of CPUs (2-255)" + range 2 255 +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/Makefile ./arch/i386/kernel/Makefile +--- ../pristine-linux-2.6.16.13/arch/i386/kernel/Makefile 2006-05-02 22:38:44.000000000 +0100 ++++ ./arch/i386/kernel/Makefile 2006-05-04 17:41:45.000000000 +0100 +@@ -37,6 +37,7 @@ obj-$(CONFIG_EFI) += efi.o efi_stub.o + obj-$(CONFIG_DOUBLEFAULT) += doublefault.o + obj-$(CONFIG_VM86) += vm86.o + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o ++obj-$(CONFIG_SMP_ALTERNATIVES) += smpalts.o + + EXTRA_AFLAGS := -traditional + +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/smpalts.c ./arch/i386/kernel/smpalts.c +--- ../pristine-linux-2.6.16.13/arch/i386/kernel/smpalts.c 1970-01-01 01:00:00.000000000 +0100 ++++ ./arch/i386/kernel/smpalts.c 2006-05-04 17:41:45.000000000 +0100 +@@ -0,0 +1,85 @@ ++#include <linux/kernel.h> ++#include <asm/system.h> ++#include <asm/smp_alt.h> ++#include <asm/processor.h> ++#include <asm/string.h> ++ ++struct smp_replacement_record { ++ unsigned char targ_size; ++ unsigned char smp1_size; ++ unsigned char smp2_size; ++ unsigned char up_size; ++ unsigned char feature; ++ unsigned char data[0]; ++}; ++ ++struct smp_alternative_record { ++ void *targ_start; ++ struct smp_replacement_record *repl; ++}; ++ ++extern struct smp_alternative_record __start_smp_alternatives_table, ++ __stop_smp_alternatives_table; ++extern unsigned long __init_begin, __init_end; ++ ++void prepare_for_smp(void) ++{ ++ struct smp_alternative_record *r; ++ printk(KERN_INFO "Enabling SMP...\n"); ++ for (r = &__start_smp_alternatives_table; ++ r != &__stop_smp_alternatives_table; ++ r++) { ++ BUG_ON(r->repl->targ_size < r->repl->smp1_size); ++ BUG_ON(r->repl->targ_size < r->repl->smp2_size); ++ BUG_ON(r->repl->targ_size < r->repl->up_size); ++ if (system_state == SYSTEM_RUNNING && ++ r->targ_start >= (void *)&__init_begin && ++ r->targ_start < (void *)&__init_end) ++ continue; ++ if (r->repl->feature != (unsigned char)-1 && ++ boot_cpu_has(r->repl->feature)) { ++ memcpy(r->targ_start, ++ r->repl->data + r->repl->smp1_size, ++ r->repl->smp2_size); ++ memset(r->targ_start + r->repl->smp2_size, ++ 0x90, ++ r->repl->targ_size - r->repl->smp2_size); ++ } else { ++ memcpy(r->targ_start, ++ r->repl->data, ++ r->repl->smp1_size); ++ memset(r->targ_start + r->repl->smp1_size, ++ 0x90, ++ r->repl->targ_size - r->repl->smp1_size); ++ } ++ } ++ /* Paranoia */ ++ asm volatile ("jmp 1f\n1:"); ++ mb(); ++} ++ ++void unprepare_for_smp(void) ++{ ++ struct smp_alternative_record *r; ++ printk(KERN_INFO "Disabling SMP...\n"); ++ for (r = &__start_smp_alternatives_table; ++ r != &__stop_smp_alternatives_table; ++ r++) { ++ BUG_ON(r->repl->targ_size < r->repl->smp1_size); ++ BUG_ON(r->repl->targ_size < r->repl->smp2_size); ++ BUG_ON(r->repl->targ_size < r->repl->up_size); ++ if (system_state == SYSTEM_RUNNING && ++ r->targ_start >= (void *)&__init_begin && ++ r->targ_start < (void *)&__init_end) ++ continue; ++ memcpy(r->targ_start, ++ r->repl->data + r->repl->smp1_size + r->repl->smp2_size, ++ r->repl->up_size); ++ memset(r->targ_start + r->repl->up_size, ++ 0x90, ++ r->repl->targ_size - r->repl->up_size); ++ } ++ /* Paranoia */ ++ asm volatile ("jmp 1f\n1:"); ++ mb(); ++} +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/smpboot.c ./arch/i386/kernel/smpboot.c +--- ../pristine-linux-2.6.16.13/arch/i386/kernel/smpboot.c 2006-05-02 22:38:44.000000000 +0100 ++++ ./arch/i386/kernel/smpboot.c 2006-05-04 17:41:45.000000000 +0100 +@@ -1218,6 +1218,11 @@ static void __init smp_boot_cpus(unsigne + if (max_cpus <= cpucount+1) + continue; + ++#ifdef CONFIG_SMP_ALTERNATIVES ++ if (kicked == 1) ++ prepare_for_smp(); ++#endif ++ + if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu)) + printk("CPU #%d not responding - cannot use it.\n", + apicid); +@@ -1396,6 +1401,11 @@ int __devinit __cpu_up(unsigned int cpu) + return -EIO; + } + ++#ifdef CONFIG_SMP_ALTERNATIVES ++ if (num_online_cpus() == 1) ++ prepare_for_smp(); ++#endif ++ + local_irq_enable(); + per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; + /* Unleash the CPU! */ +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/vmlinux.lds.S ./arch/i386/kernel/vmlinux.lds.S +--- ../pristine-linux-2.6.16.13/arch/i386/kernel/vmlinux.lds.S 2006-05-02 22:38:44.000000000 +0100 ++++ ./arch/i386/kernel/vmlinux.lds.S 2006-05-04 17:41:45.000000000 +0100 +@@ -34,6 +34,13 @@ SECTIONS + __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) } + __stop___ex_table = .; + ++ . = ALIGN(16); ++ __start_smp_alternatives_table = .; ++ __smp_alternatives : { *(__smp_alternatives) } ++ __stop_smp_alternatives_table = .; ++ ++ __smp_replacements : { *(__smp_replacements) } ++ + RODATA + + /* writeable */ +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/atomic.h ./include/asm-i386/atomic.h +--- ../pristine-linux-2.6.16.13/include/asm-i386/atomic.h 2006-05-02 22:38:44.000000000 +0100 ++++ ./include/asm-i386/atomic.h 2006-05-04 17:41:45.000000000 +0100 +@@ -4,18 +4,13 @@ + #include <linux/config.h> + #include <linux/compiler.h> + #include <asm/processor.h> ++#include <asm/smp_alt.h> + + /* + * Atomic operations that C can't guarantee us. Useful for + * resource counting etc.. + */ + +-#ifdef CONFIG_SMP +-#define LOCK "lock ; " +-#else +-#define LOCK "" +-#endif +- + /* + * Make sure gcc doesn't try to be clever and move things around + * on us. We need to use _exactly_ the address the user gave us, +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/bitops.h ./include/asm-i386/bitops.h +--- ../pristine-linux-2.6.16.13/include/asm-i386/bitops.h 2006-05-02 22:38:44.000000000 +0100 ++++ ./include/asm-i386/bitops.h 2006-05-04 17:41:45.000000000 +0100 +@@ -7,6 +7,7 @@ + + #include <linux/config.h> + #include <linux/compiler.h> ++#include <asm/smp_alt.h> + + /* + * These have to be done with inline assembly: that way the bit-setting +@@ -16,12 +17,6 @@ + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). + */ + +-#ifdef CONFIG_SMP +-#define LOCK_PREFIX "lock ; " +-#else +-#define LOCK_PREFIX "" +-#endif +- + #define ADDR (*(volatile long *) addr) + + /** +@@ -41,7 +36,7 @@ + */ + static inline void set_bit(int nr, volatile unsigned long * addr) + { +- __asm__ __volatile__( LOCK_PREFIX ++ __asm__ __volatile__( LOCK + "btsl %1,%0" + :"+m" (ADDR) + :"Ir" (nr)); +@@ -76,7 +71,7 @@ static inline void __set_bit(int nr, vol + */ + static inline void clear_bit(int nr, volatile unsigned long * addr) + { +- __asm__ __volatile__( LOCK_PREFIX ++ __asm__ __volatile__( LOCK + "btrl %1,%0" + :"+m" (ADDR) + :"Ir" (nr)); +@@ -121,7 +116,7 @@ static inline void __change_bit(int nr, + */ + static inline void change_bit(int nr, volatile unsigned long * addr) + { +- __asm__ __volatile__( LOCK_PREFIX ++ __asm__ __volatile__( LOCK + "btcl %1,%0" + :"+m" (ADDR) + :"Ir" (nr)); +@@ -140,7 +135,7 @@ static inline int test_and_set_bit(int n + { + int oldbit; + +- __asm__ __volatile__( LOCK_PREFIX ++ __asm__ __volatile__( LOCK + "btsl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"+m" (ADDR) + :"Ir" (nr) : "memory"); +@@ -180,7 +175,7 @@ static inline int test_and_clear_bit(int + { + int oldbit; + +- __asm__ __volatile__( LOCK_PREFIX ++ __asm__ __volatile__( LOCK + "btrl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"+m" (ADDR) + :"Ir" (nr) : "memory"); +@@ -231,7 +226,7 @@ static inline int test_and_change_bit(in + { + int oldbit; + +- __asm__ __volatile__( LOCK_PREFIX ++ __asm__ __volatile__( LOCK + "btcl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"+m" (ADDR) + :"Ir" (nr) : "memory"); +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/futex.h ./include/asm-i386/futex.h +--- ../pristine-linux-2.6.16.13/include/asm-i386/futex.h 2006-05-02 22:38:44.000000000 +0100 ++++ ./include/asm-i386/futex.h 2006-05-04 17:41:45.000000000 +0100 +@@ -28,7 +28,7 @@ + "1: movl %2, %0\n\ + movl %0, %3\n" \ + insn "\n" \ +-"2: " LOCK_PREFIX "cmpxchgl %3, %2\n\ ++"2: " LOCK "cmpxchgl %3, %2\n\ + jnz 1b\n\ + 3: .section .fixup,\"ax\"\n\ + 4: mov %5, %1\n\ +@@ -68,7 +68,7 @@ futex_atomic_op_inuser (int encoded_op, + #endif + switch (op) { + case FUTEX_OP_ADD: +- __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, ++ __futex_atomic_op1(LOCK "xaddl %0, %2", ret, + oldval, uaddr, oparg); + break; + case FUTEX_OP_OR: +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/rwsem.h ./include/asm-i386/rwsem.h +--- ../pristine-linux-2.6.16.13/include/asm-i386/rwsem.h 2006-05-02 22:38:44.000000000 +0100 ++++ ./include/asm-i386/rwsem.h 2006-05-04 17:41:45.000000000 +0100 +@@ -40,6 +40,7 @@ + + #include <linux/list.h> + #include <linux/spinlock.h> ++#include <asm/smp_alt.h> + + struct rwsem_waiter; + +@@ -99,7 +100,7 @@ static inline void __down_read(struct rw + { + __asm__ __volatile__( + "# beginning down_read\n\t" +-LOCK_PREFIX " incl (%%eax)\n\t" /* adds 0x00000001, returns the old value */ ++LOCK " incl (%%eax)\n\t" /* adds 0x00000001, returns the old value */ + " js 2f\n\t" /* jump if we weren't granted the lock */ + "1:\n\t" + LOCK_SECTION_START("") +@@ -130,7 +131,7 @@ static inline int __down_read_trylock(st + " movl %1,%2\n\t" + " addl %3,%2\n\t" + " jle 2f\n\t" +-LOCK_PREFIX " cmpxchgl %2,%0\n\t" ++LOCK " cmpxchgl %2,%0\n\t" + " jnz 1b\n\t" + "2:\n\t" + "# ending __down_read_trylock\n\t" +@@ -150,7 +151,7 @@ static inline void __down_write(struct r + tmp = RWSEM_ACTIVE_WRITE_BIAS; + __asm__ __volatile__( + "# beginning down_write\n\t" +-LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */ ++LOCK " xadd %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */ + " testl %%edx,%%edx\n\t" /* was the count 0 before? */ + " jnz 2f\n\t" /* jump if we weren't granted the lock */ + "1:\n\t" +@@ -188,7 +189,7 @@ static inline void __up_read(struct rw_s + __s32 tmp = -RWSEM_ACTIVE_READ_BIAS; + __asm__ __volatile__( + "# beginning __up_read\n\t" +-LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */ ++LOCK " xadd %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */ + " js 2f\n\t" /* jump if the lock is being waited upon */ + "1:\n\t" + LOCK_SECTION_START("") +@@ -214,7 +215,7 @@ static inline void __up_write(struct rw_ + __asm__ __volatile__( + "# beginning __up_write\n\t" + " movl %2,%%edx\n\t" +-LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */ ++LOCK " xaddl %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */ + " jnz 2f\n\t" /* jump if the lock is being waited upon */ + "1:\n\t" + LOCK_SECTION_START("") +@@ -239,7 +240,7 @@ static inline void __downgrade_write(str + { + __asm__ __volatile__( + "# beginning __downgrade_write\n\t" +-LOCK_PREFIX " addl %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */ ++LOCK " addl %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */ + " js 2f\n\t" /* jump if the lock is being waited upon */ + "1:\n\t" + LOCK_SECTION_START("") +@@ -263,7 +264,7 @@ LOCK_PREFIX " addl %2,(%%eax)\n\t" + static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) + { + __asm__ __volatile__( +-LOCK_PREFIX "addl %1,%0" ++LOCK "addl %1,%0" + : "=m"(sem->count) + : "ir"(delta), "m"(sem->count)); + } +@@ -276,7 +277,7 @@ static inline int rwsem_atomic_update(in + int tmp = delta; + + __asm__ __volatile__( +-LOCK_PREFIX "xadd %0,(%2)" ++LOCK "xadd %0,(%2)" + : "+r"(tmp), "=m"(sem->count) + : "r"(sem), "m"(sem->count) + : "memory"); +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/smp_alt.h ./include/asm-i386/smp_alt.h +--- ../pristine-linux-2.6.16.13/include/asm-i386/smp_alt.h 1970-01-01 01:00:00.000000000 +0100 ++++ ./include/asm-i386/smp_alt.h 2006-05-04 17:41:45.000000000 +0100 +@@ -0,0 +1,32 @@ ++#ifndef __ASM_SMP_ALT_H__ ++#define __ASM_SMP_ALT_H__ ++ ++#include <linux/config.h> ++ ++#ifdef CONFIG_SMP ++#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE) ++#define LOCK \ ++ "6677: nop\n" \ ++ ".section __smp_alternatives,\"a\"\n" \ ++ ".long 6677b\n" \ ++ ".long 6678f\n" \ ++ ".previous\n" \ ++ ".section __smp_replacements,\"a\"\n" \ ++ "6678: .byte 1\n" \ ++ ".byte 1\n" \ ++ ".byte 0\n" \ ++ ".byte 1\n" \ ++ ".byte -1\n" \ ++ "lock\n" \ ++ "nop\n" \ ++ ".previous\n" ++void prepare_for_smp(void); ++void unprepare_for_smp(void); ++#else ++#define LOCK "lock ; " ++#endif ++#else ++#define LOCK "" ++#endif ++ ++#endif /* __ASM_SMP_ALT_H__ */ +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/spinlock.h ./include/asm-i386/spinlock.h +--- ../pristine-linux-2.6.16.13/include/asm-i386/spinlock.h 2006-05-02 22:38:44.000000000 +0100 ++++ ./include/asm-i386/spinlock.h 2006-05-04 17:41:45.000000000 +0100 +@@ -6,6 +6,7 @@ + #include <asm/page.h> + #include <linux/config.h> + #include <linux/compiler.h> ++#include <asm/smp_alt.h> + + /* + * Your basic SMP spinlocks, allowing only a single CPU anywhere +@@ -23,7 +24,8 @@ + + #define __raw_spin_lock_string \ + "\n1:\t" \ +- "lock ; decb %0\n\t" \ ++ LOCK \ ++ "decb %0\n\t" \ + "jns 3f\n" \ + "2:\t" \ + "rep;nop\n\t" \ +@@ -34,7 +36,8 @@ + + #define __raw_spin_lock_string_flags \ + "\n1:\t" \ +- "lock ; decb %0\n\t" \ ++ LOCK \ ++ "decb %0\n\t" \ + "jns 4f\n\t" \ + "2:\t" \ + "testl $0x200, %1\n\t" \ +@@ -65,10 +68,34 @@ static inline void __raw_spin_lock_flags + static inline int __raw_spin_trylock(raw_spinlock_t *lock) + { + char oldval; ++#ifdef CONFIG_SMP_ALTERNATIVES + __asm__ __volatile__( +- "xchgb %b0,%1" ++ "1:movb %1,%b0\n" ++ "movb $0,%1\n" ++ "2:" ++ ".section __smp_alternatives,\"a\"\n" ++ ".long 1b\n" ++ ".long 3f\n" ++ ".previous\n" ++ ".section __smp_replacements,\"a\"\n" ++ "3: .byte 2b - 1b\n" ++ ".byte 5f-4f\n" ++ ".byte 0\n" ++ ".byte 6f-5f\n" ++ ".byte -1\n" ++ "4: xchgb %b0,%1\n" ++ "5: movb %1,%b0\n" ++ "movb $0,%1\n" ++ "6:\n" ++ ".previous\n" + :"=q" (oldval), "=m" (lock->slock) + :"0" (0) : "memory"); ++#else ++ __asm__ __volatile__( ++ "xchgb %b0,%1\n" ++ :"=q" (oldval), "=m" (lock->slock) ++ :"0" (0) : "memory"); ++#endif + return oldval > 0; + } + +@@ -178,12 +205,12 @@ static inline int __raw_write_trylock(ra + + static inline void __raw_read_unlock(raw_rwlock_t *rw) + { +- asm volatile("lock ; incl %0" :"=m" (rw->lock) : : "memory"); ++ asm volatile(LOCK "incl %0" :"=m" (rw->lock) : : "memory"); + } + + static inline void __raw_write_unlock(raw_rwlock_t *rw) + { +- asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ", %0" ++ asm volatile(LOCK "addl $" RW_LOCK_BIAS_STR ", %0" + : "=m" (rw->lock) : : "memory"); + } + +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/system.h ./include/asm-i386/system.h +--- ../pristine-linux-2.6.16.13/include/asm-i386/system.h 2006-05-02 22:38:44.000000000 +0100 ++++ ./include/asm-i386/system.h 2006-05-04 17:41:45.000000000 +0100 +@@ -5,7 +5,7 @@ + #include <linux/kernel.h> + #include <asm/segment.h> + #include <asm/cpufeature.h> +-#include <linux/bitops.h> /* for LOCK_PREFIX */ ++#include <asm/smp_alt.h> + + #ifdef __KERNEL__ + +@@ -271,19 +271,19 @@ static inline unsigned long __cmpxchg(vo + unsigned long prev; + switch (size) { + case 1: +- __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2" ++ __asm__ __volatile__(LOCK "cmpxchgb %b1,%2" + : "=a"(prev) + : "q"(new), "m"(*__xg(ptr)), "0"(old) + : "memory"); + return prev; + case 2: +- __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2" ++ __asm__ __volatile__(LOCK "cmpxchgw %w1,%2" + : "=a"(prev) + : "r"(new), "m"(*__xg(ptr)), "0"(old) + : "memory"); + return prev; + case 4: +- __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2" ++ __asm__ __volatile__(LOCK "cmpxchgl %1,%2" + : "=a"(prev) + : "r"(new), "m"(*__xg(ptr)), "0"(old) + : "memory"); +@@ -336,7 +336,7 @@ static inline unsigned long long __cmpxc + unsigned long long new) + { + unsigned long long prev; +- __asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3" ++ __asm__ __volatile__(LOCK "cmpxchg8b %3" + : "=A"(prev) + : "b"((unsigned long)new), + "c"((unsigned long)(new >> 32)), +@@ -503,11 +503,55 @@ struct alt_instr { + #endif + + #ifdef CONFIG_SMP ++#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE) ++#define smp_alt_mb(instr) \ ++__asm__ __volatile__("6667:\nnop\nnop\nnop\nnop\nnop\nnop\n6668:\n" \ ++ ".section __smp_alternatives,\"a\"\n" \ ++ ".long 6667b\n" \ ++ ".long 6673f\n" \ ++ ".previous\n" \ ++ ".section __smp_replacements,\"a\"\n" \ ++ "6673:.byte 6668b-6667b\n" \ ++ ".byte 6670f-6669f\n" \ ++ ".byte 6671f-6670f\n" \ ++ ".byte 0\n" \ ++ ".byte %c0\n" \ ++ "6669:lock;addl $0,0(%%esp)\n" \ ++ "6670:" instr "\n" \ ++ "6671:\n" \ ++ ".previous\n" \ ++ : \ ++ : "i" (X86_FEATURE_XMM2) \ ++ : "memory") ++#define smp_rmb() smp_alt_mb("lfence") ++#define smp_mb() smp_alt_mb("mfence") ++#define set_mb(var, value) do { \ ++unsigned long __set_mb_temp; \ ++__asm__ __volatile__("6667:movl %1, %0\n6668:\n" \ ++ ".section __smp_alternatives,\"a\"\n" \ ++ ".long 6667b\n" \ ++ ".long 6673f\n" \ ++ ".previous\n" \ ++ ".section __smp_replacements,\"a\"\n" \ ++ "6673: .byte 6668b-6667b\n" \ ++ ".byte 6670f-6669f\n" \ ++ ".byte 0\n" \ ++ ".byte 6671f-6670f\n" \ ++ ".byte -1\n" \ ++ "6669: xchg %1, %0\n" \ ++ "6670:movl %1, %0\n" \ ++ "6671:\n" \ ++ ".previous\n" \ ++ : "=m" (var), "=r" (__set_mb_temp) \ ++ : "1" (value) \ ++ : "memory"); } while (0) ++#else + #define smp_mb() mb() + #define smp_rmb() rmb() ++#define set_mb(var, value) do { (void) xchg(&var, value); } while (0) ++#endif + #define smp_wmb() wmb() + #define smp_read_barrier_depends() read_barrier_depends() +-#define set_mb(var, value) do { (void) xchg(&var, value); } while (0) + #else + #define smp_mb() barrier() + #define smp_rmb() barrier() diff -r 44e5abbf333b -r ad5b833122a8 patches/linux-2.6.16.13/x86-increase-interrupt-vector-range.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/linux-2.6.16.13/x86-increase-interrupt-vector-range.patch Thu May 04 17:44:14 2006 +0100 @@ -0,0 +1,89 @@ +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/entry.S ./arch/i386/kernel/entry.S +--- ../pristine-linux-2.6.16.13/arch/i386/kernel/entry.S 2006-05-02 22:38:44.000000000 +0100 ++++ ./arch/i386/kernel/entry.S 2006-05-04 17:41:49.000000000 +0100 +@@ -406,7 +406,7 @@ vector=0 + ENTRY(irq_entries_start) + .rept NR_IRQS + ALIGN +-1: pushl $vector-256 ++1: pushl $~(vector) + jmp common_interrupt + .data + .long 1b +@@ -423,7 +423,7 @@ common_interrupt: + + #define BUILD_INTERRUPT(name, nr) \ + ENTRY(name) \ +- pushl $nr-256; \ ++ pushl $~(nr); \ + SAVE_ALL \ + movl %esp,%eax; \ + call smp_/**/name; \ +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/irq.c ./arch/i386/kernel/irq.c +--- ../pristine-linux-2.6.16.13/arch/i386/kernel/irq.c 2006-05-02 22:38:44.000000000 +0100 ++++ ./arch/i386/kernel/irq.c 2006-05-04 17:41:49.000000000 +0100 +@@ -53,8 +53,8 @@ static union irq_ctx *softirq_ctx[NR_CPU + */ + fastcall unsigned int do_IRQ(struct pt_regs *regs) + { +- /* high bits used in ret_from_ code */ +- int irq = regs->orig_eax & 0xff; ++ /* high bit used in ret_from_ code */ ++ int irq = ~regs->orig_eax; + #ifdef CONFIG_4KSTACKS + union irq_ctx *curctx, *irqctx; + u32 *isp; +diff -pruN ../pristine-linux-2.6.16.13/arch/x86_64/kernel/entry.S ./arch/x86_64/kernel/entry.S +--- ../pristine-linux-2.6.16.13/arch/x86_64/kernel/entry.S 2006-05-02 22:38:44.000000000 +0100 ++++ ./arch/x86_64/kernel/entry.S 2006-05-04 17:41:49.000000000 +0100 +@@ -601,7 +601,7 @@ retint_kernel: + */ + .macro apicinterrupt num,func + INTR_FRAME +- pushq $\num-256 ++ pushq $~(\num) + CFI_ADJUST_CFA_OFFSET 8 + interrupt \func + jmp ret_from_intr +diff -pruN ../pristine-linux-2.6.16.13/arch/x86_64/kernel/irq.c ./arch/x86_64/kernel/irq.c +--- ../pristine-linux-2.6.16.13/arch/x86_64/kernel/irq.c 2006-05-02 22:38:44.000000000 +0100 ++++ ./arch/x86_64/kernel/irq.c 2006-05-04 17:41:49.000000000 +0100 +@@ -96,8 +96,8 @@ skip: + */ + asmlinkage unsigned int do_IRQ(struct pt_regs *regs) + { +- /* high bits used in ret_from_ code */ +- unsigned irq = regs->orig_rax & 0xff; ++ /* high bit used in ret_from_ code */ ++ unsigned irq = ~regs->orig_rax; + + exit_idle(); + irq_enter(); +diff -pruN ../pristine-linux-2.6.16.13/arch/x86_64/kernel/smp.c ./arch/x86_64/kernel/smp.c +--- ../pristine-linux-2.6.16.13/arch/x86_64/kernel/smp.c 2006-05-02 22:38:44.000000000 +0100 ++++ ./arch/x86_64/kernel/smp.c 2006-05-04 17:41:49.000000000 +0100 +@@ -135,10 +135,10 @@ asmlinkage void smp_invalidate_interrupt + + cpu = smp_processor_id(); + /* +- * orig_rax contains the interrupt vector - 256. ++ * orig_rax contains the negated interrupt vector. + * Use that to determine where the sender put the data. + */ +- sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START; ++ sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START; + f = &per_cpu(flush_state, sender); + + if (!cpu_isset(cpu, f->flush_cpumask)) +diff -pruN ../pristine-linux-2.6.16.13/include/asm-x86_64/hw_irq.h ./include/asm-x86_64/hw_irq.h +--- ../pristine-linux-2.6.16.13/include/asm-x86_64/hw_irq.h 2006-05-02 22:38:44.000000000 +0100 ++++ ./include/asm-x86_64/hw_irq.h 2006-05-04 17:41:49.000000000 +0100 +@@ -127,7 +127,7 @@ asmlinkage void IRQ_NAME(nr); \ + __asm__( \ + "\n.p2align\n" \ + "IRQ" #nr "_interrupt:\n\t" \ +- "push $" #nr "-256 ; " \ ++ "push $~(" #nr ") ; " \ + "jmp common_interrupt"); + + #if defined(CONFIG_X86_IO_APIC) diff -r 44e5abbf333b -r ad5b833122a8 patches/linux-2.6.16.13/xenoprof-generic.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/linux-2.6.16.13/xenoprof-generic.patch Thu May 04 17:44:14 2006 +0100 @@ -0,0 +1,384 @@ +diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c ./drivers/oprofile/buffer_sync.c +--- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c 2006-05-02 22:38:44.000000000 +0100 ++++ ./drivers/oprofile/buffer_sync.c 2006-05-04 17:41:51.000000000 +0100 +@@ -6,6 +6,10 @@ + * + * @author John Levon <levon@xxxxxxxxxxxxxxxxx> + * ++ * Modified by Aravind Menon for Xen ++ * These modifications are: ++ * Copyright (C) 2005 Hewlett-Packard Co. ++ * + * This is the core of the buffer management. Each + * CPU buffer is processed and entered into the + * global event buffer. Such processing is necessary +@@ -275,15 +279,24 @@ static void add_cpu_switch(int i) + last_cookie = INVALID_COOKIE; + } + +-static void add_kernel_ctx_switch(unsigned int in_kernel) ++static void add_cpu_mode_switch(unsigned int cpu_mode) + { + add_event_entry(ESCAPE_CODE); +- if (in_kernel) +- add_event_entry(KERNEL_ENTER_SWITCH_CODE); +- else +- add_event_entry(KERNEL_EXIT_SWITCH_CODE); ++ switch (cpu_mode) { ++ case CPU_MODE_USER: ++ add_event_entry(USER_ENTER_SWITCH_CODE); ++ break; ++ case CPU_MODE_KERNEL: ++ add_event_entry(KERNEL_ENTER_SWITCH_CODE); ++ break; ++ case CPU_MODE_XEN: ++ add_event_entry(XEN_ENTER_SWITCH_CODE); ++ break; ++ default: ++ break; ++ } + } +- ++ + static void + add_user_ctx_switch(struct task_struct const * task, unsigned long cookie) + { +@@ -348,9 +361,9 @@ static int add_us_sample(struct mm_struc + * for later lookup from userspace. + */ + static int +-add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel) ++add_sample(struct mm_struct * mm, struct op_sample * s, int cpu_mode) + { +- if (in_kernel) { ++ if (cpu_mode >= CPU_MODE_KERNEL) { + add_sample_entry(s->eip, s->event); + return 1; + } else if (mm) { +@@ -496,7 +509,7 @@ void sync_buffer(int cpu) + struct mm_struct *mm = NULL; + struct task_struct * new; + unsigned long cookie = 0; +- int in_kernel = 1; ++ int cpu_mode = 1; + unsigned int i; + sync_buffer_state state = sb_buffer_start; + unsigned long available; +@@ -513,12 +526,12 @@ void sync_buffer(int cpu) + struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos]; + + if (is_code(s->eip)) { +- if (s->event <= CPU_IS_KERNEL) { ++ if (s->event <= CPU_MODE_XEN) { + /* kernel/userspace switch */ +- in_kernel = s->event; ++ cpu_mode = s->event; + if (state == sb_buffer_start) + state = sb_sample_start; +- add_kernel_ctx_switch(s->event); ++ add_cpu_mode_switch(s->event); + } else if (s->event == CPU_TRACE_BEGIN) { + state = sb_bt_start; + add_trace_begin(); +@@ -536,7 +549,7 @@ void sync_buffer(int cpu) + } + } else { + if (state >= sb_bt_start && +- !add_sample(mm, s, in_kernel)) { ++ !add_sample(mm, s, cpu_mode)) { + if (state == sb_bt_start) { + state = sb_bt_ignore; + atomic_inc(&oprofile_stats.bt_lost_no_mapping); +diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c ./drivers/oprofile/cpu_buffer.c +--- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c 2006-05-02 22:38:44.000000000 +0100 ++++ ./drivers/oprofile/cpu_buffer.c 2006-05-04 17:41:51.000000000 +0100 +@@ -6,6 +6,10 @@ + * + * @author John Levon <levon@xxxxxxxxxxxxxxxxx> + * ++ * Modified by Aravind Menon for Xen ++ * These modifications are: ++ * Copyright (C) 2005 Hewlett-Packard Co. ++ * + * Each CPU has a local buffer that stores PC value/event + * pairs. We also log context switches when we notice them. + * Eventually each CPU's buffer is processed into the global +@@ -58,7 +62,7 @@ int alloc_cpu_buffers(void) + goto fail; + + b->last_task = NULL; +- b->last_is_kernel = -1; ++ b->last_cpu_mode = -1; + b->tracing = 0; + b->buffer_size = buffer_size; + b->tail_pos = 0; +@@ -114,7 +118,7 @@ void cpu_buffer_reset(struct oprofile_cp + * collected will populate the buffer with proper + * values to initialize the buffer + */ +- cpu_buf->last_is_kernel = -1; ++ cpu_buf->last_cpu_mode = -1; + cpu_buf->last_task = NULL; + } + +@@ -164,13 +168,13 @@ add_code(struct oprofile_cpu_buffer * bu + * because of the head/tail separation of the writer and reader + * of the CPU buffer. + * +- * is_kernel is needed because on some architectures you cannot ++ * cpu_mode is needed because on some architectures you cannot + * tell if you are in kernel or user space simply by looking at +- * pc. We tag this in the buffer by generating kernel enter/exit +- * events whenever is_kernel changes ++ * pc. We tag this in the buffer by generating kernel/user (and xen) ++ * enter events whenever cpu_mode changes + */ + static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc, +- int is_kernel, unsigned long event) ++ int cpu_mode, unsigned long event) + { + struct task_struct * task; + +@@ -181,16 +185,16 @@ static int log_sample(struct oprofile_cp + return 0; + } + +- is_kernel = !!is_kernel; ++ WARN_ON(cpu_mode > CPU_MODE_XEN); + + task = current; + + /* notice a switch from user->kernel or vice versa */ +- if (cpu_buf->last_is_kernel != is_kernel) { +- cpu_buf->last_is_kernel = is_kernel; +- add_code(cpu_buf, is_kernel); ++ if (cpu_buf->last_cpu_mode != cpu_mode) { ++ cpu_buf->last_cpu_mode = cpu_mode; ++ add_code(cpu_buf, cpu_mode); + } +- ++ + /* notice a task switch */ + if (cpu_buf->last_task != task) { + cpu_buf->last_task = task; +diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h ./drivers/oprofile/cpu_buffer.h +--- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h 2006-05-02 22:38:44.000000000 +0100 ++++ ./drivers/oprofile/cpu_buffer.h 2006-05-04 17:41:51.000000000 +0100 +@@ -36,7 +36,7 @@ struct oprofile_cpu_buffer { + volatile unsigned long tail_pos; + unsigned long buffer_size; + struct task_struct * last_task; +- int last_is_kernel; ++ int last_cpu_mode; + int tracing; + struct op_sample * buffer; + unsigned long sample_received; +@@ -51,7 +51,9 @@ extern struct oprofile_cpu_buffer cpu_bu + void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf); + + /* transient events for the CPU buffer -> event buffer */ +-#define CPU_IS_KERNEL 1 +-#define CPU_TRACE_BEGIN 2 ++#define CPU_MODE_USER 0 ++#define CPU_MODE_KERNEL 1 ++#define CPU_MODE_XEN 2 ++#define CPU_TRACE_BEGIN 3 + + #endif /* OPROFILE_CPU_BUFFER_H */ +diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h ./drivers/oprofile/event_buffer.h +--- ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h 2006-05-02 22:38:44.000000000 +0100 ++++ ./drivers/oprofile/event_buffer.h 2006-05-04 17:41:51.000000000 +0100 +@@ -29,11 +29,12 @@ void wake_up_buffer_waiter(void); + #define CPU_SWITCH_CODE 2 + #define COOKIE_SWITCH_CODE 3 + #define KERNEL_ENTER_SWITCH_CODE 4 +-#define KERNEL_EXIT_SWITCH_CODE 5 ++#define USER_ENTER_SWITCH_CODE 5 + #define MODULE_LOADED_CODE 6 + #define CTX_TGID_CODE 7 + #define TRACE_BEGIN_CODE 8 + #define TRACE_END_CODE 9 ++#define XEN_ENTER_SWITCH_CODE 10 + + #define INVALID_COOKIE ~0UL + #define NO_COOKIE 0UL +diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c ./drivers/oprofile/oprof.c +--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c 2006-05-02 22:38:44.000000000 +0100 ++++ ./drivers/oprofile/oprof.c 2006-05-04 17:41:51.000000000 +0100 +@@ -5,6 +5,10 @@ + * @remark Read the file COPYING + * + * @author John Levon <levon@xxxxxxxxxxxxxxxxx> ++ * ++ * Modified by Aravind Menon for Xen ++ * These modifications are: ++ * Copyright (C) 2005 Hewlett-Packard Co. + */ + + #include <linux/kernel.h> +@@ -19,7 +23,7 @@ + #include "cpu_buffer.h" + #include "buffer_sync.h" + #include "oprofile_stats.h" +- ++ + struct oprofile_operations oprofile_ops; + + unsigned long oprofile_started; +@@ -33,6 +37,17 @@ static DECLARE_MUTEX(start_sem); + */ + static int timer = 0; + ++extern unsigned int adomains; ++extern int active_domains[MAX_OPROF_DOMAINS]; ++ ++int oprofile_set_active(void) ++{ ++ if (oprofile_ops.set_active) ++ return oprofile_ops.set_active(active_domains, adomains); ++ ++ return -EINVAL; ++} ++ + int oprofile_setup(void) + { + int err; +diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h ./drivers/oprofile/oprof.h +--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h 2006-05-02 22:38:44.000000000 +0100 ++++ ./drivers/oprofile/oprof.h 2006-05-04 17:41:51.000000000 +0100 +@@ -35,5 +35,7 @@ void oprofile_create_files(struct super_ + void oprofile_timer_init(struct oprofile_operations * ops); + + int oprofile_set_backtrace(unsigned long depth); ++ ++int oprofile_set_active(void); + + #endif /* OPROF_H */ +diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c ./drivers/oprofile/oprofile_files.c +--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c 2006-05-02 22:38:44.000000000 +0100 ++++ ./drivers/oprofile/oprofile_files.c 2006-05-04 17:41:51.000000000 +0100 +@@ -5,15 +5,21 @@ + * @remark Read the file COPYING + * + * @author John Levon <levon@xxxxxxxxxxxxxxxxx> ++ * ++ * Modified by Aravind Menon for Xen ++ * These modifications are: ++ * Copyright (C) 2005 Hewlett-Packard Co. + */ + + #include <linux/fs.h> + #include <linux/oprofile.h> ++#include <asm/uaccess.h> ++#include <linux/ctype.h> + + #include "event_buffer.h" + #include "oprofile_stats.h" + #include "oprof.h" +- ++ + unsigned long fs_buffer_size = 131072; + unsigned long fs_cpu_buffer_size = 8192; + unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */ +@@ -117,11 +123,79 @@ static ssize_t dump_write(struct file * + static struct file_operations dump_fops = { + .write = dump_write, + }; +- ++ ++#define TMPBUFSIZE 512 ++ ++unsigned int adomains = 0; ++long active_domains[MAX_OPROF_DOMAINS]; ++ ++static ssize_t adomain_write(struct file * file, char const __user * buf, ++ size_t count, loff_t * offset) ++{ ++ char tmpbuf[TMPBUFSIZE]; ++ char * startp = tmpbuf; ++ char * endp = tmpbuf; ++ int i; ++ unsigned long val; ++ ++ if (*offset) ++ return -EINVAL; ++ if (!count) ++ return 0; ++ if (count > TMPBUFSIZE - 1) ++ return -EINVAL; ++ ++ memset(tmpbuf, 0x0, TMPBUFSIZE); ++ ++ if (copy_from_user(tmpbuf, buf, count)) ++ return -EFAULT; ++ ++ for (i = 0; i < MAX_OPROF_DOMAINS; i++) ++ active_domains[i] = -1; ++ adomains = 0; ++ ++ while (1) { ++ val = simple_strtol(startp, &endp, 0); ++ if (endp == startp) ++ break; ++ while (ispunct(*endp)) ++ endp++; ++ active_domains[adomains++] = val; ++ if (adomains >= MAX_OPROF_DOMAINS) ++ break; ++ startp = endp; ++ } ++ if (oprofile_set_active()) ++ return -EINVAL; ++ return count; ++} ++ ++static ssize_t adomain_read(struct file * file, char __user * buf, ++ size_t count, loff_t * offset) ++{ ++ char tmpbuf[TMPBUFSIZE]; ++ size_t len = 0; ++ int i; ++ /* This is all screwed up if we run out of space */ ++ for (i = 0; i < adomains; i++) ++ len += snprintf(tmpbuf + len, TMPBUFSIZE - len, ++ "%u ", (unsigned int)active_domains[i]); ++ len += snprintf(tmpbuf + len, TMPBUFSIZE - len, "\n"); ++ return simple_read_from_buffer((void __user *)buf, count, ++ offset, tmpbuf, len); ++} ++ ++ ++static struct file_operations active_domain_ops = { ++ .read = adomain_read, ++ .write = adomain_write, ++}; ++ + void oprofile_create_files(struct super_block * sb, struct dentry * root) + { + oprofilefs_create_file(sb, root, "enable", &enable_fops); + oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666); ++ oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops); + oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops); + oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size); + oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed); +diff -pruN ../pristine-linux-2.6.16.13/include/linux/oprofile.h ./include/linux/oprofile.h +--- ../pristine-linux-2.6.16.13/include/linux/oprofile.h 2006-05-02 22:38:44.000000000 +0100 ++++ ./include/linux/oprofile.h 2006-05-04 17:41:51.000000000 +0100 +@@ -16,6 +16,8 @@ + #include <linux/types.h> + #include <linux/spinlock.h> + #include <asm/atomic.h> ++ ++#include <xen/interface/xenoprof.h> + + struct super_block; + struct dentry; +@@ -27,6 +29,8 @@ struct oprofile_operations { + /* create any necessary configuration files in the oprofile fs. + * Optional. */ + int (*create_files)(struct super_block * sb, struct dentry * root); ++ /* setup active domains with Xen */ ++ int (*set_active)(int *active_domains, unsigned int adomains); + /* Do any necessary interrupt setup. Optional. */ + int (*setup)(void); + /* Do any necessary interrupt shutdown. Optional. */ diff -r 44e5abbf333b -r ad5b833122a8 patches/linux-2.6.16/device_bind.patch --- a/patches/linux-2.6.16/device_bind.patch Thu May 04 17:38:25 2006 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ ---- linux-2.6.16/drivers/base/bus.c 2006-03-16 10:50:20.000000000 -0500 -+++ linux-2.6.16/drivers/base/bus.c 2006-03-16 11:02:08.000000000 -0500 -@@ -188,6 +188,11 @@ static ssize_t driver_bind(struct device - up(&dev->sem); - if (dev->parent) - up(&dev->parent->sem); -+ -+ if (err > 0) /* success */ -+ err = count; -+ else if (err == 0) /* driver didn't accept device */ -+ err = -ENODEV; - } - put_device(dev); - put_bus(bus); diff -r 44e5abbf333b -r ad5b833122a8 patches/linux-2.6.16/i386-mach-io-check-nmi.patch --- a/patches/linux-2.6.16/i386-mach-io-check-nmi.patch Thu May 04 17:38:25 2006 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -diff -pruN ../pristine-linux-2.6.16/arch/i386/kernel/traps.c ./arch/i386/kernel/traps.c ---- ../pristine-linux-2.6.16/arch/i386/kernel/traps.c 2006-03-20 05:53:29.000000000 +0000 -+++ ./arch/i386/kernel/traps.c 2006-03-20 19:38:17.000000000 +0000 -@@ -567,18 +567,11 @@ static void mem_parity_error(unsigned ch - - static void io_check_error(unsigned char reason, struct pt_regs * regs) - { -- unsigned long i; -- - printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n"); - show_registers(regs); - - /* Re-enable the IOCK line, wait for a few seconds */ -- reason = (reason & 0xf) | 8; -- outb(reason, 0x61); -- i = 2000; -- while (--i) udelay(1000); -- reason &= ~8; -- outb(reason, 0x61); -+ clear_io_check_error(reason); - } - - static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/mach-default/mach_traps.h ./include/asm-i386/mach-default/mach_traps.h ---- ../pristine-linux-2.6.16/include/asm-i386/mach-default/mach_traps.h 2006-03-20 05:53:29.000000000 +0000 -+++ ./include/asm-i386/mach-default/mach_traps.h 2006-03-20 19:38:17.000000000 +0000 -@@ -15,6 +15,18 @@ static inline void clear_mem_error(unsig - outb(reason, 0x61); - } - -+static inline void clear_io_check_error(unsigned char reason) -+{ -+ unsigned long i; -+ -+ reason = (reason & 0xf) | 8; -+ outb(reason, 0x61); -+ i = 2000; -+ while (--i) udelay(1000); -+ reason &= ~8; -+ outb(reason, 0x61); -+} -+ - static inline unsigned char get_nmi_reason(void) - { - return inb(0x61); diff -r 44e5abbf333b -r ad5b833122a8 patches/linux-2.6.16/net-csum.patch --- a/patches/linux-2.6.16/net-csum.patch Thu May 04 17:38:25 2006 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -diff -pruN ../pristine-linux-2.6.16/net/ipv4/netfilter/ip_nat_proto_tcp.c ./net/ipv4/netfilter/ip_nat_proto_tcp.c ---- ../pristine-linux-2.6.16/net/ipv4/netfilter/ip_nat_proto_tcp.c 2006-03-20 05:53:29.000000000 +0000 -+++ ./net/ipv4/netfilter/ip_nat_proto_tcp.c 2006-03-20 19:38:19.000000000 +0000 -@@ -129,10 +129,14 @@ tcp_manip_pkt(struct sk_buff **pskb, - if (hdrsize < sizeof(*hdr)) - return 1; - -- hdr->check = ip_nat_cheat_check(~oldip, newip, -+ if ((*pskb)->proto_csum_blank) { -+ hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check); -+ } else { -+ hdr->check = ip_nat_cheat_check(~oldip, newip, - ip_nat_cheat_check(oldport ^ 0xFFFF, - newport, - hdr->check)); -+ } - return 1; - } - -diff -pruN ../pristine-linux-2.6.16/net/ipv4/netfilter/ip_nat_proto_udp.c ./net/ipv4/netfilter/ip_nat_proto_udp.c ---- ../pristine-linux-2.6.16/net/ipv4/netfilter/ip_nat_proto_udp.c 2006-03-20 05:53:29.000000000 +0000 -+++ ./net/ipv4/netfilter/ip_nat_proto_udp.c 2006-03-20 19:38:19.000000000 +0000 -@@ -113,11 +113,16 @@ udp_manip_pkt(struct sk_buff **pskb, - newport = tuple->dst.u.udp.port; - portptr = &hdr->dest; - } -- if (hdr->check) /* 0 is a special case meaning no checksum */ -- hdr->check = ip_nat_cheat_check(~oldip, newip, -+ if (hdr->check) { /* 0 is a special case meaning no checksum */ -+ if ((*pskb)->proto_csum_blank) { -+ hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check); -+ } else { -+ hdr->check = ip_nat_cheat_check(~oldip, newip, - ip_nat_cheat_check(*portptr ^ 0xFFFF, - newport, - hdr->check)); -+ } -+ } - *portptr = newport; - return 1; - } -diff -r 601fa226a761 net/ipv4/xfrm4_output.c ---- a/net/ipv4/xfrm4_output.c Wed Apr 19 18:52:30 2006 -+++ b/net/ipv4/xfrm4_output.c Thu Apr 20 15:49:40 2006 -@@ -16,6 +16,8 @@ - #include <net/ip.h> - #include <net/xfrm.h> - #include <net/icmp.h> -+ -+extern int skb_checksum_setup(struct sk_buff *skb); - - /* Add encapsulation header. - * -@@ -103,6 +105,10 @@ - struct xfrm_state *x = dst->xfrm; - int err; - -+ err = skb_checksum_setup(skb); -+ if (err) -+ goto error_nolock; -+ - if (skb->ip_summed == CHECKSUM_HW) { - err = skb_checksum_help(skb, 0); - if (err) diff -r 44e5abbf333b -r ad5b833122a8 patches/linux-2.6.16/pmd-shared.patch --- a/patches/linux-2.6.16/pmd-shared.patch Thu May 04 17:38:25 2006 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,111 +0,0 @@ -diff -pruN ../pristine-linux-2.6.16/arch/i386/mm/pageattr.c ./arch/i386/mm/pageattr.c ---- ../pristine-linux-2.6.16/arch/i386/mm/pageattr.c 2006-03-20 05:53:29.000000000 +0000 -+++ ./arch/i386/mm/pageattr.c 2006-03-20 19:38:23.000000000 +0000 -@@ -78,7 +78,7 @@ static void set_pmd_pte(pte_t *kpte, uns - unsigned long flags; - - set_pte_atomic(kpte, pte); /* change init_mm */ -- if (PTRS_PER_PMD > 1) -+ if (HAVE_SHARED_KERNEL_PMD) - return; - - spin_lock_irqsave(&pgd_lock, flags); -diff -pruN ../pristine-linux-2.6.16/arch/i386/mm/pgtable.c ./arch/i386/mm/pgtable.c ---- ../pristine-linux-2.6.16/arch/i386/mm/pgtable.c 2006-03-20 05:53:29.000000000 +0000 -+++ ./arch/i386/mm/pgtable.c 2006-03-20 19:38:23.000000000 +0000 -@@ -215,9 +215,10 @@ void pgd_ctor(void *pgd, kmem_cache_t *c - spin_lock_irqsave(&pgd_lock, flags); - } - -- clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD, -- swapper_pg_dir + USER_PTRS_PER_PGD, -- KERNEL_PGD_PTRS); -+ if (PTRS_PER_PMD == 1 || HAVE_SHARED_KERNEL_PMD) -+ clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD, -+ swapper_pg_dir + USER_PTRS_PER_PGD, -+ KERNEL_PGD_PTRS); - if (PTRS_PER_PMD > 1) - return; - -@@ -249,6 +250,30 @@ pgd_t *pgd_alloc(struct mm_struct *mm) - goto out_oom; - set_pgd(&pgd[i], __pgd(1 + __pa(pmd))); - } -+ -+ if (!HAVE_SHARED_KERNEL_PMD) { -+ unsigned long flags; -+ -+ for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) { -+ pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL); -+ if (!pmd) -+ goto out_oom; -+ set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd))); -+ } -+ -+ spin_lock_irqsave(&pgd_lock, flags); -+ for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) { -+ unsigned long v = (unsigned long)i << PGDIR_SHIFT; -+ pgd_t *kpgd = pgd_offset_k(v); -+ pud_t *kpud = pud_offset(kpgd, v); -+ pmd_t *kpmd = pmd_offset(kpud, v); -+ pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1); -+ memcpy(pmd, kpmd, PAGE_SIZE); -+ } -+ pgd_list_add(pgd); -+ spin_unlock_irqrestore(&pgd_lock, flags); -+ } -+ - return pgd; - - out_oom: -@@ -263,9 +288,23 @@ void pgd_free(pgd_t *pgd) - int i; - - /* in the PAE case user pgd entries are overwritten before usage */ -- if (PTRS_PER_PMD > 1) -- for (i = 0; i < USER_PTRS_PER_PGD; ++i) -- kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1)); -+ if (PTRS_PER_PMD > 1) { -+ for (i = 0; i < USER_PTRS_PER_PGD; ++i) { -+ pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1); -+ kmem_cache_free(pmd_cache, pmd); -+ } -+ if (!HAVE_SHARED_KERNEL_PMD) { -+ unsigned long flags; -+ spin_lock_irqsave(&pgd_lock, flags); -+ pgd_list_del(pgd); -+ spin_unlock_irqrestore(&pgd_lock, flags); -+ for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) { -+ pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1); -+ memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t)); -+ kmem_cache_free(pmd_cache, pmd); -+ } -+ } -+ } - /* in the non-PAE case, free_pgtables() clears user pgd entries */ - kmem_cache_free(pgd_cache, pgd); - } -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/pgtable-2level-defs.h ./include/asm-i386/pgtable-2level-defs.h ---- ../pristine-linux-2.6.16/include/asm-i386/pgtable-2level-defs.h 2006-03-20 05:53:29.000000000 +0000 -+++ ./include/asm-i386/pgtable-2level-defs.h 2006-03-20 19:38:23.000000000 +0000 -@@ -1,6 +1,8 @@ - #ifndef _I386_PGTABLE_2LEVEL_DEFS_H - #define _I386_PGTABLE_2LEVEL_DEFS_H - -+#define HAVE_SHARED_KERNEL_PMD 0 -+ - /* - * traditional i386 two-level paging structure: - */ -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/pgtable-3level-defs.h ./include/asm-i386/pgtable-3level-defs.h ---- ../pristine-linux-2.6.16/include/asm-i386/pgtable-3level-defs.h 2006-03-20 05:53:29.000000000 +0000 -+++ ./include/asm-i386/pgtable-3level-defs.h 2006-03-20 19:38:23.000000000 +0000 -@@ -1,6 +1,8 @@ - #ifndef _I386_PGTABLE_3LEVEL_DEFS_H - #define _I386_PGTABLE_3LEVEL_DEFS_H - -+#define HAVE_SHARED_KERNEL_PMD 1 -+ - /* - * PGDIR_SHIFT determines what a top-level page table entry can map - */ diff -r 44e5abbf333b -r ad5b833122a8 patches/linux-2.6.16/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch --- a/patches/linux-2.6.16/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch Thu May 04 17:38:25 2006 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -Index: sysenter/linux-2.6-xen-sparse/arch/i386/kernel/entry.S -=================================================================== ---- linux-2.6.16.orig/arch/i386/kernel/entry.S 2006-04-05 11:12:51.000000000 +0100 -+++ linux-2.6.16/arch/i386/kernel/entry.S 2006-04-05 11:12:52.000000000 +0100 -@@ -177,7 +177,7 @@ - - # sysenter call handler stub - ENTRY(sysenter_entry) -- movl TSS_sysenter_esp0(%esp),%esp -+ movl SYSENTER_stack_esp0(%esp),%esp - sysenter_past_esp: - sti - pushl $(__USER_DS) -@@ -492,7 +492,7 @@ - * that sets up the real kernel stack. Check here, since we can't - * allow the wrong stack to be used. - * -- * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have -+ * "SYSENTER_stack_esp0+12" is because the NMI/debug handler will have - * already pushed 3 words if it hits on the sysenter instruction: - * eflags, cs and eip. - * -@@ -504,7 +504,7 @@ - cmpw $__KERNEL_CS,4(%esp); \ - jne ok; \ - label: \ -- movl TSS_sysenter_esp0+offset(%esp),%esp; \ -+ movl SYSENTER_stack_esp0+offset(%esp),%esp; \ - pushfl; \ - pushl $__KERNEL_CS; \ - pushl $sysenter_past_esp diff -r 44e5abbf333b -r ad5b833122a8 patches/linux-2.6.16/smp-alts.patch --- a/patches/linux-2.6.16/smp-alts.patch Thu May 04 17:38:25 2006 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,591 +0,0 @@ -diff -pruN ../pristine-linux-2.6.16/arch/i386/Kconfig ./arch/i386/Kconfig ---- ../pristine-linux-2.6.16/arch/i386/Kconfig 2006-03-20 05:53:29.000000000 +0000 -+++ ./arch/i386/Kconfig 2006-03-20 19:38:27.000000000 +0000 -@@ -202,6 +202,19 @@ config SMP - - If you don't know what to do here, say N. - -+config SMP_ALTERNATIVES -+ bool "SMP alternatives support (EXPERIMENTAL)" -+ depends on SMP && EXPERIMENTAL -+ help -+ Try to reduce the overhead of running an SMP kernel on a uniprocessor -+ host slightly by replacing certain key instruction sequences -+ according to whether we currently have more than one CPU available. -+ This should provide a noticeable boost to performance when -+ running SMP kernels on UP machines, and have negligible impact -+ when running on an true SMP host. -+ -+ If unsure, say N. -+ - config NR_CPUS - int "Maximum number of CPUs (2-255)" - range 2 255 -diff -pruN ../pristine-linux-2.6.16/arch/i386/kernel/Makefile ./arch/i386/kernel/Makefile ---- ../pristine-linux-2.6.16/arch/i386/kernel/Makefile 2006-03-20 05:53:29.000000000 +0000 -+++ ./arch/i386/kernel/Makefile 2006-03-20 19:38:27.000000000 +0000 -@@ -37,6 +37,7 @@ obj-$(CONFIG_EFI) += efi.o efi_stub.o - obj-$(CONFIG_DOUBLEFAULT) += doublefault.o - obj-$(CONFIG_VM86) += vm86.o - obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -+obj-$(CONFIG_SMP_ALTERNATIVES) += smpalts.o - - EXTRA_AFLAGS := -traditional - -diff -pruN ../pristine-linux-2.6.16/arch/i386/kernel/smpalts.c ./arch/i386/kernel/smpalts.c ---- ../pristine-linux-2.6.16/arch/i386/kernel/smpalts.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./arch/i386/kernel/smpalts.c 2006-03-20 19:38:27.000000000 +0000 -@@ -0,0 +1,85 @@ -+#include <linux/kernel.h> -+#include <asm/system.h> -+#include <asm/smp_alt.h> -+#include <asm/processor.h> -+#include <asm/string.h> -+ -+struct smp_replacement_record { -+ unsigned char targ_size; -+ unsigned char smp1_size; -+ unsigned char smp2_size; -+ unsigned char up_size; -+ unsigned char feature; -+ unsigned char data[0]; -+}; -+ -+struct smp_alternative_record { -+ void *targ_start; -+ struct smp_replacement_record *repl; -+}; -+ -+extern struct smp_alternative_record __start_smp_alternatives_table, -+ __stop_smp_alternatives_table; -+extern unsigned long __init_begin, __init_end; -+ -+void prepare_for_smp(void) -+{ -+ struct smp_alternative_record *r; -+ printk(KERN_INFO "Enabling SMP...\n"); -+ for (r = &__start_smp_alternatives_table; -+ r != &__stop_smp_alternatives_table; -+ r++) { -+ BUG_ON(r->repl->targ_size < r->repl->smp1_size); -+ BUG_ON(r->repl->targ_size < r->repl->smp2_size); -+ BUG_ON(r->repl->targ_size < r->repl->up_size); -+ if (system_state == SYSTEM_RUNNING && -+ r->targ_start >= (void *)&__init_begin && -+ r->targ_start < (void *)&__init_end) -+ continue; -+ if (r->repl->feature != (unsigned char)-1 && -+ boot_cpu_has(r->repl->feature)) { -+ memcpy(r->targ_start, -+ r->repl->data + r->repl->smp1_size, -+ r->repl->smp2_size); -+ memset(r->targ_start + r->repl->smp2_size, -+ 0x90, -+ r->repl->targ_size - r->repl->smp2_size); -+ } else { -+ memcpy(r->targ_start, -+ r->repl->data, -+ r->repl->smp1_size); -+ memset(r->targ_start + r->repl->smp1_size, -+ 0x90, -+ r->repl->targ_size - r->repl->smp1_size); -+ } -+ } -+ /* Paranoia */ -+ asm volatile ("jmp 1f\n1:"); -+ mb(); -+} -+ -+void unprepare_for_smp(void) -+{ -+ struct smp_alternative_record *r; -+ printk(KERN_INFO "Disabling SMP...\n"); -+ for (r = &__start_smp_alternatives_table; -+ r != &__stop_smp_alternatives_table; -+ r++) { -+ BUG_ON(r->repl->targ_size < r->repl->smp1_size); -+ BUG_ON(r->repl->targ_size < r->repl->smp2_size); -+ BUG_ON(r->repl->targ_size < r->repl->up_size); -+ if (system_state == SYSTEM_RUNNING && -+ r->targ_start >= (void *)&__init_begin && -+ r->targ_start < (void *)&__init_end) -+ continue; -+ memcpy(r->targ_start, -+ r->repl->data + r->repl->smp1_size + r->repl->smp2_size, -+ r->repl->up_size); -+ memset(r->targ_start + r->repl->up_size, -+ 0x90, -+ r->repl->targ_size - r->repl->up_size); -+ } -+ /* Paranoia */ -+ asm volatile ("jmp 1f\n1:"); -+ mb(); -+} -diff -pruN ../pristine-linux-2.6.16/arch/i386/kernel/smpboot.c ./arch/i386/kernel/smpboot.c ---- ../pristine-linux-2.6.16/arch/i386/kernel/smpboot.c 2006-03-20 05:53:29.000000000 +0000 -+++ ./arch/i386/kernel/smpboot.c 2006-03-20 19:38:27.000000000 +0000 -@@ -1218,6 +1218,11 @@ static void __init smp_boot_cpus(unsigne - if (max_cpus <= cpucount+1) - continue; - -+#ifdef CONFIG_SMP_ALTERNATIVES -+ if (kicked == 1) -+ prepare_for_smp(); -+#endif -+ - if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu)) - printk("CPU #%d not responding - cannot use it.\n", - apicid); -@@ -1396,6 +1401,11 @@ int __devinit __cpu_up(unsigned int cpu) - return -EIO; - } - -+#ifdef CONFIG_SMP_ALTERNATIVES -+ if (num_online_cpus() == 1) -+ prepare_for_smp(); -+#endif -+ - local_irq_enable(); - per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; - /* Unleash the CPU! */ -diff -pruN ../pristine-linux-2.6.16/arch/i386/kernel/vmlinux.lds.S ./arch/i386/kernel/vmlinux.lds.S ---- ../pristine-linux-2.6.16/arch/i386/kernel/vmlinux.lds.S 2006-03-20 05:53:29.000000000 +0000 -+++ ./arch/i386/kernel/vmlinux.lds.S 2006-03-20 19:38:27.000000000 +0000 -@@ -34,6 +34,13 @@ SECTIONS - __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) } - __stop___ex_table = .; - -+ . = ALIGN(16); -+ __start_smp_alternatives_table = .; -+ __smp_alternatives : { *(__smp_alternatives) } -+ __stop_smp_alternatives_table = .; -+ -+ __smp_replacements : { *(__smp_replacements) } -+ - RODATA - - /* writeable */ -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/atomic.h ./include/asm-i386/atomic.h ---- ../pristine-linux-2.6.16/include/asm-i386/atomic.h 2006-03-20 05:53:29.000000000 +0000 -+++ ./include/asm-i386/atomic.h 2006-03-20 19:38:27.000000000 +0000 -@@ -4,18 +4,13 @@ - #include <linux/config.h> - #include <linux/compiler.h> - #include <asm/processor.h> -+#include <asm/smp_alt.h> - - /* - * Atomic operations that C can't guarantee us. Useful for - * resource counting etc.. - */ - --#ifdef CONFIG_SMP --#define LOCK "lock ; " --#else --#define LOCK "" --#endif -- - /* - * Make sure gcc doesn't try to be clever and move things around - * on us. We need to use _exactly_ the address the user gave us, -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/bitops.h ./include/asm-i386/bitops.h ---- ../pristine-linux-2.6.16/include/asm-i386/bitops.h 2006-03-20 05:53:29.000000000 +0000 -+++ ./include/asm-i386/bitops.h 2006-03-20 19:38:27.000000000 +0000 -@@ -7,6 +7,7 @@ - - #include <linux/config.h> - #include <linux/compiler.h> -+#include <asm/smp_alt.h> - - /* - * These have to be done with inline assembly: that way the bit-setting -@@ -16,12 +17,6 @@ - * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). - */ - --#ifdef CONFIG_SMP --#define LOCK_PREFIX "lock ; " --#else --#define LOCK_PREFIX "" --#endif -- - #define ADDR (*(volatile long *) addr) - - /** -@@ -41,7 +36,7 @@ - */ - static inline void set_bit(int nr, volatile unsigned long * addr) - { -- __asm__ __volatile__( LOCK_PREFIX -+ __asm__ __volatile__( LOCK - "btsl %1,%0" - :"+m" (ADDR) - :"Ir" (nr)); -@@ -76,7 +71,7 @@ static inline void __set_bit(int nr, vol - */ - static inline void clear_bit(int nr, volatile unsigned long * addr) - { -- __asm__ __volatile__( LOCK_PREFIX -+ __asm__ __volatile__( LOCK - "btrl %1,%0" - :"+m" (ADDR) - :"Ir" (nr)); -@@ -121,7 +116,7 @@ static inline void __change_bit(int nr, - */ - static inline void change_bit(int nr, volatile unsigned long * addr) - { -- __asm__ __volatile__( LOCK_PREFIX -+ __asm__ __volatile__( LOCK - "btcl %1,%0" - :"+m" (ADDR) - :"Ir" (nr)); -@@ -140,7 +135,7 @@ static inline int test_and_set_bit(int n - { - int oldbit; - -- __asm__ __volatile__( LOCK_PREFIX -+ __asm__ __volatile__( LOCK - "btsl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"+m" (ADDR) - :"Ir" (nr) : "memory"); -@@ -180,7 +175,7 @@ static inline int test_and_clear_bit(int - { - int oldbit; - -- __asm__ __volatile__( LOCK_PREFIX -+ __asm__ __volatile__( LOCK - "btrl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"+m" (ADDR) - :"Ir" (nr) : "memory"); -@@ -231,7 +226,7 @@ static inline int test_and_change_bit(in - { - int oldbit; - -- __asm__ __volatile__( LOCK_PREFIX -+ __asm__ __volatile__( LOCK - "btcl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"+m" (ADDR) - :"Ir" (nr) : "memory"); -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/futex.h ./include/asm-i386/futex.h ---- ../pristine-linux-2.6.16/include/asm-i386/futex.h 2006-03-20 05:53:29.000000000 +0000 -+++ ./include/asm-i386/futex.h 2006-03-20 19:38:27.000000000 +0000 -@@ -28,7 +28,7 @@ - "1: movl %2, %0\n\ - movl %0, %3\n" \ - insn "\n" \ --"2: " LOCK_PREFIX "cmpxchgl %3, %2\n\ -+"2: " LOCK "cmpxchgl %3, %2\n\ - jnz 1b\n\ - 3: .section .fixup,\"ax\"\n\ - 4: mov %5, %1\n\ -@@ -68,7 +68,7 @@ futex_atomic_op_inuser (int encoded_op, - #endif - switch (op) { - case FUTEX_OP_ADD: -- __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, -+ __futex_atomic_op1(LOCK "xaddl %0, %2", ret, - oldval, uaddr, oparg); - break; - case FUTEX_OP_OR: -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/rwsem.h ./include/asm-i386/rwsem.h ---- ../pristine-linux-2.6.16/include/asm-i386/rwsem.h 2006-03-20 05:53:29.000000000 +0000 -+++ ./include/asm-i386/rwsem.h 2006-03-20 19:38:27.000000000 +0000 -@@ -40,6 +40,7 @@ - - #include <linux/list.h> - #include <linux/spinlock.h> -+#include <asm/smp_alt.h> - - struct rwsem_waiter; - -@@ -99,7 +100,7 @@ static inline void __down_read(struct rw - { - __asm__ __volatile__( - "# beginning down_read\n\t" --LOCK_PREFIX " incl (%%eax)\n\t" /* adds 0x00000001, returns the old value */ -+LOCK " incl (%%eax)\n\t" /* adds 0x00000001, returns the old value */ - " js 2f\n\t" /* jump if we weren't granted the lock */ - "1:\n\t" - LOCK_SECTION_START("") -@@ -130,7 +131,7 @@ static inline int __down_read_trylock(st - " movl %1,%2\n\t" - " addl %3,%2\n\t" - " jle 2f\n\t" --LOCK_PREFIX " cmpxchgl %2,%0\n\t" -+LOCK " cmpxchgl %2,%0\n\t" - " jnz 1b\n\t" - "2:\n\t" - "# ending __down_read_trylock\n\t" -@@ -150,7 +151,7 @@ static inline void __down_write(struct r - tmp = RWSEM_ACTIVE_WRITE_BIAS; - __asm__ __volatile__( - "# beginning down_write\n\t" --LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */ -+LOCK " xadd %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */ - " testl %%edx,%%edx\n\t" /* was the count 0 before? */ - " jnz 2f\n\t" /* jump if we weren't granted the lock */ - "1:\n\t" -@@ -188,7 +189,7 @@ static inline void __up_read(struct rw_s - __s32 tmp = -RWSEM_ACTIVE_READ_BIAS; - __asm__ __volatile__( - "# beginning __up_read\n\t" --LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */ -+LOCK " xadd %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */ - " js 2f\n\t" /* jump if the lock is being waited upon */ - "1:\n\t" - LOCK_SECTION_START("") -@@ -214,7 +215,7 @@ static inline void __up_write(struct rw_ - __asm__ __volatile__( - "# beginning __up_write\n\t" - " movl %2,%%edx\n\t" --LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */ -+LOCK " xaddl %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */ - " jnz 2f\n\t" /* jump if the lock is being waited upon */ - "1:\n\t" - LOCK_SECTION_START("") -@@ -239,7 +240,7 @@ static inline void __downgrade_write(str - { - __asm__ __volatile__( - "# beginning __downgrade_write\n\t" --LOCK_PREFIX " addl %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */ -+LOCK " addl %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */ - " js 2f\n\t" /* jump if the lock is being waited upon */ - "1:\n\t" - LOCK_SECTION_START("") -@@ -263,7 +264,7 @@ LOCK_PREFIX " addl %2,(%%eax)\n\t" - static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) - { - __asm__ __volatile__( --LOCK_PREFIX "addl %1,%0" -+LOCK "addl %1,%0" - : "=m"(sem->count) - : "ir"(delta), "m"(sem->count)); - } -@@ -276,7 +277,7 @@ static inline int rwsem_atomic_update(in - int tmp = delta; - - __asm__ __volatile__( --LOCK_PREFIX "xadd %0,(%2)" -+LOCK "xadd %0,(%2)" - : "+r"(tmp), "=m"(sem->count) - : "r"(sem), "m"(sem->count) - : "memory"); -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/smp_alt.h ./include/asm-i386/smp_alt.h ---- ../pristine-linux-2.6.16/include/asm-i386/smp_alt.h 1970-01-01 01:00:00.000000000 +0100 -+++ ./include/asm-i386/smp_alt.h 2006-03-20 19:38:27.000000000 +0000 -@@ -0,0 +1,32 @@ -+#ifndef __ASM_SMP_ALT_H__ -+#define __ASM_SMP_ALT_H__ -+ -+#include <linux/config.h> -+ -+#ifdef CONFIG_SMP -+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE) -+#define LOCK \ -+ "6677: nop\n" \ -+ ".section __smp_alternatives,\"a\"\n" \ -+ ".long 6677b\n" \ -+ ".long 6678f\n" \ -+ ".previous\n" \ -+ ".section __smp_replacements,\"a\"\n" \ -+ "6678: .byte 1\n" \ -+ ".byte 1\n" \ -+ ".byte 0\n" \ -+ ".byte 1\n" \ -+ ".byte -1\n" \ -+ "lock\n" \ -+ "nop\n" \ -+ ".previous\n" -+void prepare_for_smp(void); -+void unprepare_for_smp(void); -+#else -+#define LOCK "lock ; " -+#endif -+#else -+#define LOCK "" -+#endif -+ -+#endif /* __ASM_SMP_ALT_H__ */ -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/spinlock.h ./include/asm-i386/spinlock.h ---- ../pristine-linux-2.6.16/include/asm-i386/spinlock.h 2006-03-20 05:53:29.000000000 +0000 -+++ ./include/asm-i386/spinlock.h 2006-03-20 19:38:27.000000000 +0000 -@@ -6,6 +6,7 @@ - #include <asm/page.h> - #include <linux/config.h> - #include <linux/compiler.h> -+#include <asm/smp_alt.h> - - /* - * Your basic SMP spinlocks, allowing only a single CPU anywhere -@@ -23,7 +24,8 @@ - - #define __raw_spin_lock_string \ - "\n1:\t" \ -- "lock ; decb %0\n\t" \ -+ LOCK \ -+ "decb %0\n\t" \ - "jns 3f\n" \ - "2:\t" \ - "rep;nop\n\t" \ -@@ -34,7 +36,8 @@ - - #define __raw_spin_lock_string_flags \ - "\n1:\t" \ -- "lock ; decb %0\n\t" \ -+ LOCK \ -+ "decb %0\n\t" \ - "jns 4f\n\t" \ - "2:\t" \ - "testl $0x200, %1\n\t" \ -@@ -65,10 +68,34 @@ static inline void __raw_spin_lock_flags - static inline int __raw_spin_trylock(raw_spinlock_t *lock) - { - char oldval; -+#ifdef CONFIG_SMP_ALTERNATIVES - __asm__ __volatile__( -- "xchgb %b0,%1" -+ "1:movb %1,%b0\n" -+ "movb $0,%1\n" -+ "2:" -+ ".section __smp_alternatives,\"a\"\n" -+ ".long 1b\n" -+ ".long 3f\n" -+ ".previous\n" -+ ".section __smp_replacements,\"a\"\n" -+ "3: .byte 2b - 1b\n" -+ ".byte 5f-4f\n" -+ ".byte 0\n" -+ ".byte 6f-5f\n" -+ ".byte -1\n" -+ "4: xchgb %b0,%1\n" -+ "5: movb %1,%b0\n" -+ "movb $0,%1\n" -+ "6:\n" -+ ".previous\n" - :"=q" (oldval), "=m" (lock->slock) - :"0" (0) : "memory"); -+#else -+ __asm__ __volatile__( -+ "xchgb %b0,%1\n" -+ :"=q" (oldval), "=m" (lock->slock) -+ :"0" (0) : "memory"); -+#endif - return oldval > 0; - } - -@@ -178,12 +205,12 @@ static inline int __raw_write_trylock(ra - - static inline void __raw_read_unlock(raw_rwlock_t *rw) - { -- asm volatile("lock ; incl %0" :"=m" (rw->lock) : : "memory"); -+ asm volatile(LOCK "incl %0" :"=m" (rw->lock) : : "memory"); - } - - static inline void __raw_write_unlock(raw_rwlock_t *rw) - { -- asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ", %0" -+ asm volatile(LOCK "addl $" RW_LOCK_BIAS_STR ", %0" - : "=m" (rw->lock) : : "memory"); - } - -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/system.h ./include/asm-i386/system.h ---- ../pristine-linux-2.6.16/include/asm-i386/system.h 2006-03-20 05:53:29.000000000 +0000 -+++ ./include/asm-i386/system.h 2006-03-20 19:38:27.000000000 +0000 -@@ -5,7 +5,7 @@ - #include <linux/kernel.h> - #include <asm/segment.h> - #include <asm/cpufeature.h> --#include <linux/bitops.h> /* for LOCK_PREFIX */ -+#include <asm/smp_alt.h> - - #ifdef __KERNEL__ - -@@ -271,19 +271,19 @@ static inline unsigned long __cmpxchg(vo - unsigned long prev; - switch (size) { - case 1: -- __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2" -+ __asm__ __volatile__(LOCK "cmpxchgb %b1,%2" - : "=a"(prev) - : "q"(new), "m"(*__xg(ptr)), "0"(old) - : "memory"); - return prev; - case 2: -- __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2" -+ __asm__ __volatile__(LOCK "cmpxchgw %w1,%2" - : "=a"(prev) - : "r"(new), "m"(*__xg(ptr)), "0"(old) - : "memory"); - return prev; - case 4: -- __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2" -+ __asm__ __volatile__(LOCK "cmpxchgl %1,%2" - : "=a"(prev) - : "r"(new), "m"(*__xg(ptr)), "0"(old) - : "memory"); -@@ -336,7 +336,7 @@ static inline unsigned long long __cmpxc - unsigned long long new) - { - unsigned long long prev; -- __asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3" -+ __asm__ __volatile__(LOCK "cmpxchg8b %3" - : "=A"(prev) - : "b"((unsigned long)new), - "c"((unsigned long)(new >> 32)), -@@ -503,11 +503,55 @@ struct alt_instr { - #endif - - #ifdef CONFIG_SMP -+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE) -+#define smp_alt_mb(instr) \ -+__asm__ __volatile__("6667:\nnop\nnop\nnop\nnop\nnop\nnop\n6668:\n" \ -+ ".section __smp_alternatives,\"a\"\n" \ -+ ".long 6667b\n" \ -+ ".long 6673f\n" \ -+ ".previous\n" \ -+ ".section __smp_replacements,\"a\"\n" \ -+ "6673:.byte 6668b-6667b\n" \ -+ ".byte 6670f-6669f\n" \ -+ ".byte 6671f-6670f\n" \ -+ ".byte 0\n" \ -+ ".byte %c0\n" \ -+ "6669:lock;addl $0,0(%%esp)\n" \ -+ "6670:" instr "\n" \ -+ "6671:\n" \ -+ ".previous\n" \ -+ : \ -+ : "i" (X86_FEATURE_XMM2) \ -+ : "memory") -+#define smp_rmb() smp_alt_mb("lfence") -+#define smp_mb() smp_alt_mb("mfence") -+#define set_mb(var, value) do { \ -+unsigned long __set_mb_temp; \ -+__asm__ __volatile__("6667:movl %1, %0\n6668:\n" \ -+ ".section __smp_alternatives,\"a\"\n" \ -+ ".long 6667b\n" \ -+ ".long 6673f\n" \ -+ ".previous\n" \ -+ ".section __smp_replacements,\"a\"\n" \ -+ "6673: .byte 6668b-6667b\n" \ -+ ".byte 6670f-6669f\n" \ -+ ".byte 0\n" \ -+ ".byte 6671f-6670f\n" \ -+ ".byte -1\n" \ -+ "6669: xchg %1, %0\n" \ -+ "6670:movl %1, %0\n" \ -+ "6671:\n" \ -+ ".previous\n" \ -+ : "=m" (var), "=r" (__set_mb_temp) \ -+ : "1" (value) \ -+ : "memory"); } while (0) -+#else - #define smp_mb() mb() - #define smp_rmb() rmb() -+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0) -+#endif - #define smp_wmb() wmb() - #define smp_read_barrier_depends() read_barrier_depends() --#define set_mb(var, value) do { (void) xchg(&var, value); } while (0) - #else - #define smp_mb() barrier() - #define smp_rmb() barrier() diff -r 44e5abbf333b -r ad5b833122a8 patches/linux-2.6.16/x86-increase-interrupt-vector-range.patch --- a/patches/linux-2.6.16/x86-increase-interrupt-vector-range.patch Thu May 04 17:38:25 2006 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -Subject: Increase x86 interrupt vector range - -Remove the limit of 256 interrupt vectors by changing the value -stored in orig_{e,r}ax to be the negated interrupt vector. -The orig_{e,r}ax needs to be < 0 to allow the signal code to -distinguish between return from interrupt and return from syscall. -With this change applied, NR_IRQS can be > 256. - -Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx> ---- - arch/i386/kernel/entry.S | 4 ++-- - arch/i386/kernel/irq.c | 4 ++-- - arch/x86_64/kernel/entry.S | 2 +- - arch/x86_64/kernel/irq.c | 4 ++-- - arch/x86_64/kernel/smp.c | 4 ++-- - include/asm-x86_64/hw_irq.h | 2 +- - 6 files changed, 10 insertions(+), 10 deletions(-) - -diff -r 7d239c83edea arch/i386/kernel/entry.S ---- a/arch/i386/kernel/entry.S Mon Mar 20 06:00:20 2006 +0000 -+++ b/arch/i386/kernel/entry.S Fri Mar 31 17:01:35 2006 +0100 -@@ -406,7 +406,7 @@ ENTRY(irq_entries_start) - ENTRY(irq_entries_start) - .rept NR_IRQS - ALIGN --1: pushl $vector-256 -+1: pushl $~(vector) - jmp common_interrupt - .data - .long 1b -@@ -423,7 +423,7 @@ common_interrupt: - - #define BUILD_INTERRUPT(name, nr) \ - ENTRY(name) \ -- pushl $nr-256; \ -+ pushl $~(nr); \ - SAVE_ALL \ - movl %esp,%eax; \ - call smp_/**/name; \ -diff -r 7d239c83edea arch/i386/kernel/irq.c ---- a/arch/i386/kernel/irq.c Mon Mar 20 06:00:20 2006 +0000 -+++ b/arch/i386/kernel/irq.c Fri Mar 31 17:01:35 2006 +0100 -@@ -53,8 +53,8 @@ static union irq_ctx *softirq_ctx[NR_CPU - */ - fastcall unsigned int do_IRQ(struct pt_regs *regs) - { -- /* high bits used in ret_from_ code */ -- int irq = regs->orig_eax & 0xff; -+ /* high bit used in ret_from_ code */ -+ int irq = ~regs->orig_eax; - #ifdef CONFIG_4KSTACKS - union irq_ctx *curctx, *irqctx; - u32 *isp; -diff -r 7d239c83edea arch/x86_64/kernel/entry.S ---- a/arch/x86_64/kernel/entry.S Mon Mar 20 06:00:20 2006 +0000 -+++ b/arch/x86_64/kernel/entry.S Fri Mar 31 17:01:35 2006 +0100 -@@ -609,7 +609,7 @@ retint_kernel: - */ - .macro apicinterrupt num,func - INTR_FRAME -- pushq $\num-256 -+ pushq $~(\num) - CFI_ADJUST_CFA_OFFSET 8 - interrupt \func - jmp ret_from_intr -diff -r 7d239c83edea arch/x86_64/kernel/irq.c ---- a/arch/x86_64/kernel/irq.c Mon Mar 20 06:00:20 2006 +0000 -+++ b/arch/x86_64/kernel/irq.c Fri Mar 31 17:01:35 2006 +0100 -@@ -96,8 +96,8 @@ skip: - */ - asmlinkage unsigned int do_IRQ(struct pt_regs *regs) - { -- /* high bits used in ret_from_ code */ -- unsigned irq = regs->orig_rax & 0xff; -+ /* high bit used in ret_from_ code */ -+ unsigned irq = ~regs->orig_rax; - - exit_idle(); - irq_enter(); -diff -r 7d239c83edea arch/x86_64/kernel/smp.c ---- a/arch/x86_64/kernel/smp.c Mon Mar 20 06:00:20 2006 +0000 -+++ b/arch/x86_64/kernel/smp.c Fri Mar 31 17:01:35 2006 +0100 -@@ -135,10 +135,10 @@ asmlinkage void smp_invalidate_interrupt - - cpu = smp_processor_id(); - /* -- * orig_rax contains the interrupt vector - 256. -+ * orig_rax contains the negated interrupt vector. - * Use that to determine where the sender put the data. - */ -- sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START; -+ sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START; - f = &per_cpu(flush_state, sender); - - if (!cpu_isset(cpu, f->flush_cpumask)) -diff -r 7d239c83edea include/asm-x86_64/hw_irq.h ---- a/include/asm-x86_64/hw_irq.h Mon Mar 20 06:00:20 2006 +0000 -+++ b/include/asm-x86_64/hw_irq.h Fri Mar 31 17:01:35 2006 +0100 -@@ -127,7 +127,7 @@ __asm__( \ - __asm__( \ - "\n.p2align\n" \ - "IRQ" #nr "_interrupt:\n\t" \ -- "push $" #nr "-256 ; " \ -+ "push $~(" #nr ") ; " \ - "jmp common_interrupt"); - - #if defined(CONFIG_X86_IO_APIC) diff -r 44e5abbf333b -r ad5b833122a8 patches/linux-2.6.16/xenoprof-generic.patch --- a/patches/linux-2.6.16/xenoprof-generic.patch Thu May 04 17:38:25 2006 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,384 +0,0 @@ -diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/buffer_sync.c ./drivers/oprofile/buffer_sync.c ---- ../pristine-linux-2.6.16/drivers/oprofile/buffer_sync.c 2006-03-20 05:53:29.000000000 +0000 -+++ ./drivers/oprofile/buffer_sync.c 2006-04-03 15:53:05.000000000 +0100 -@@ -6,6 +6,10 @@ - * - * @author John Levon <levon@xxxxxxxxxxxxxxxxx> - * -+ * Modified by Aravind Menon for Xen -+ * These modifications are: -+ * Copyright (C) 2005 Hewlett-Packard Co. -+ * - * This is the core of the buffer management. Each - * CPU buffer is processed and entered into the - * global event buffer. Such processing is necessary -@@ -275,15 +279,24 @@ static void add_cpu_switch(int i) - last_cookie = INVALID_COOKIE; - } - --static void add_kernel_ctx_switch(unsigned int in_kernel) -+static void add_cpu_mode_switch(unsigned int cpu_mode) - { - add_event_entry(ESCAPE_CODE); -- if (in_kernel) -- add_event_entry(KERNEL_ENTER_SWITCH_CODE); -- else -- add_event_entry(KERNEL_EXIT_SWITCH_CODE); -+ switch (cpu_mode) { -+ case CPU_MODE_USER: -+ add_event_entry(USER_ENTER_SWITCH_CODE); -+ break; -+ case CPU_MODE_KERNEL: -+ add_event_entry(KERNEL_ENTER_SWITCH_CODE); -+ break; -+ case CPU_MODE_XEN: -+ add_event_entry(XEN_ENTER_SWITCH_CODE); -+ break; -+ default: -+ break; -+ } - } -- -+ - static void - add_user_ctx_switch(struct task_struct const * task, unsigned long cookie) - { -@@ -348,9 +361,9 @@ static int add_us_sample(struct mm_struc - * for later lookup from userspace. - */ - static int --add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel) -+add_sample(struct mm_struct * mm, struct op_sample * s, int cpu_mode) - { -- if (in_kernel) { -+ if (cpu_mode >= CPU_MODE_KERNEL) { - add_sample_entry(s->eip, s->event); - return 1; - } else if (mm) { -@@ -496,7 +509,7 @@ void sync_buffer(int cpu) - struct mm_struct *mm = NULL; - struct task_struct * new; - unsigned long cookie = 0; -- int in_kernel = 1; -+ int cpu_mode = 1; - unsigned int i; - sync_buffer_state state = sb_buffer_start; - unsigned long available; -@@ -513,12 +526,12 @@ void sync_buffer(int cpu) - struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos]; - - if (is_code(s->eip)) { -- if (s->event <= CPU_IS_KERNEL) { -+ if (s->event <= CPU_MODE_XEN) { - /* kernel/userspace switch */ -- in_kernel = s->event; -+ cpu_mode = s->event; - if (state == sb_buffer_start) - state = sb_sample_start; -- add_kernel_ctx_switch(s->event); -+ add_cpu_mode_switch(s->event); - } else if (s->event == CPU_TRACE_BEGIN) { - state = sb_bt_start; - add_trace_begin(); -@@ -536,7 +549,7 @@ void sync_buffer(int cpu) - } - } else { - if (state >= sb_bt_start && -- !add_sample(mm, s, in_kernel)) { -+ !add_sample(mm, s, cpu_mode)) { - if (state == sb_bt_start) { - state = sb_bt_ignore; - atomic_inc(&oprofile_stats.bt_lost_no_mapping); -diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/cpu_buffer.c ./drivers/oprofile/cpu_buffer.c ---- ../pristine-linux-2.6.16/drivers/oprofile/cpu_buffer.c 2006-03-20 05:53:29.000000000 +0000 -+++ ./drivers/oprofile/cpu_buffer.c 2006-04-03 15:53:05.000000000 +0100 -@@ -6,6 +6,10 @@ - * - * @author John Levon <levon@xxxxxxxxxxxxxxxxx> - * -+ * Modified by Aravind Menon for Xen -+ * These modifications are: -+ * Copyright (C) 2005 Hewlett-Packard Co. -+ * - * Each CPU has a local buffer that stores PC value/event - * pairs. We also log context switches when we notice them. - * Eventually each CPU's buffer is processed into the global -@@ -58,7 +62,7 @@ int alloc_cpu_buffers(void) - goto fail; - - b->last_task = NULL; -- b->last_is_kernel = -1; -+ b->last_cpu_mode = -1; - b->tracing = 0; - b->buffer_size = buffer_size; - b->tail_pos = 0; -@@ -114,7 +118,7 @@ void cpu_buffer_reset(struct oprofile_cp - * collected will populate the buffer with proper - * values to initialize the buffer - */ -- cpu_buf->last_is_kernel = -1; -+ cpu_buf->last_cpu_mode = -1; - cpu_buf->last_task = NULL; - } - -@@ -164,13 +168,13 @@ add_code(struct oprofile_cpu_buffer * bu - * because of the head/tail separation of the writer and reader - * of the CPU buffer. - * -- * is_kernel is needed because on some architectures you cannot -+ * cpu_mode is needed because on some architectures you cannot - * tell if you are in kernel or user space simply by looking at -- * pc. We tag this in the buffer by generating kernel enter/exit -- * events whenever is_kernel changes -+ * pc. We tag this in the buffer by generating kernel/user (and xen) -+ * enter events whenever cpu_mode changes - */ - static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc, -- int is_kernel, unsigned long event) -+ int cpu_mode, unsigned long event) - { - struct task_struct * task; - -@@ -181,16 +185,16 @@ static int log_sample(struct oprofile_cp - return 0; - } - -- is_kernel = !!is_kernel; -+ WARN_ON(cpu_mode > CPU_MODE_XEN); - - task = current; - - /* notice a switch from user->kernel or vice versa */ -- if (cpu_buf->last_is_kernel != is_kernel) { -- cpu_buf->last_is_kernel = is_kernel; -- add_code(cpu_buf, is_kernel); -+ if (cpu_buf->last_cpu_mode != cpu_mode) { -+ cpu_buf->last_cpu_mode = cpu_mode; -+ add_code(cpu_buf, cpu_mode); - } -- -+ - /* notice a task switch */ - if (cpu_buf->last_task != task) { - cpu_buf->last_task = task; -diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/cpu_buffer.h ./drivers/oprofile/cpu_buffer.h ---- ../pristine-linux-2.6.16/drivers/oprofile/cpu_buffer.h 2006-03-20 05:53:29.000000000 +0000 -+++ ./drivers/oprofile/cpu_buffer.h 2006-04-03 15:53:05.000000000 +0100 -@@ -36,7 +36,7 @@ struct oprofile_cpu_buffer { - volatile unsigned long tail_pos; - unsigned long buffer_size; - struct task_struct * last_task; -- int last_is_kernel; -+ int last_cpu_mode; - int tracing; - struct op_sample * buffer; - unsigned long sample_received; -@@ -51,7 +51,9 @@ extern struct oprofile_cpu_buffer cpu_bu - void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf); - - /* transient events for the CPU buffer -> event buffer */ --#define CPU_IS_KERNEL 1 --#define CPU_TRACE_BEGIN 2 -+#define CPU_MODE_USER 0 -+#define CPU_MODE_KERNEL 1 -+#define CPU_MODE_XEN 2 -+#define CPU_TRACE_BEGIN 3 - - #endif /* OPROFILE_CPU_BUFFER_H */ -diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/event_buffer.h ./drivers/oprofile/event_buffer.h ---- ../pristine-linux-2.6.16/drivers/oprofile/event_buffer.h 2006-03-20 05:53:29.000000000 +0000 -+++ ./drivers/oprofile/event_buffer.h 2006-04-03 15:53:05.000000000 +0100 -@@ -29,11 +29,12 @@ void wake_up_buffer_waiter(void); - #define CPU_SWITCH_CODE 2 - #define COOKIE_SWITCH_CODE 3 - #define KERNEL_ENTER_SWITCH_CODE 4 --#define KERNEL_EXIT_SWITCH_CODE 5 -+#define USER_ENTER_SWITCH_CODE 5 - #define MODULE_LOADED_CODE 6 - #define CTX_TGID_CODE 7 - #define TRACE_BEGIN_CODE 8 - #define TRACE_END_CODE 9 -+#define XEN_ENTER_SWITCH_CODE 10 - - #define INVALID_COOKIE ~0UL - #define NO_COOKIE 0UL -diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/oprof.c ./drivers/oprofile/oprof.c ---- ../pristine-linux-2.6.16/drivers/oprofile/oprof.c 2006-03-20 05:53:29.000000000 +0000 -+++ ./drivers/oprofile/oprof.c 2006-04-03 15:53:05.000000000 +0100 -@@ -5,6 +5,10 @@ - * @remark Read the file COPYING - * - * @author John Levon <levon@xxxxxxxxxxxxxxxxx> -+ * -+ * Modified by Aravind Menon for Xen -+ * These modifications are: -+ * Copyright (C) 2005 Hewlett-Packard Co. - */ - - #include <linux/kernel.h> -@@ -19,7 +23,7 @@ - #include "cpu_buffer.h" - #include "buffer_sync.h" - #include "oprofile_stats.h" -- -+ - struct oprofile_operations oprofile_ops; - - unsigned long oprofile_started; -@@ -33,6 +37,17 @@ static DECLARE_MUTEX(start_sem); - */ - static int timer = 0; - -+extern unsigned int adomains; -+extern int active_domains[MAX_OPROF_DOMAINS]; -+ -+int oprofile_set_active(void) -+{ -+ if (oprofile_ops.set_active) -+ return oprofile_ops.set_active(active_domains, adomains); -+ -+ return -EINVAL; -+} -+ - int oprofile_setup(void) - { - int err; -diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/oprof.h ./drivers/oprofile/oprof.h ---- ../pristine-linux-2.6.16/drivers/oprofile/oprof.h 2006-03-20 05:53:29.000000000 +0000 -+++ ./drivers/oprofile/oprof.h 2006-04-03 15:53:05.000000000 +0100 -@@ -35,5 +35,7 @@ void oprofile_create_files(struct super_ - void oprofile_timer_init(struct oprofile_operations * ops); - - int oprofile_set_backtrace(unsigned long depth); -+ -+int oprofile_set_active(void); - - #endif /* OPROF_H */ -diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/oprofile_files.c ./drivers/oprofile/oprofile_files.c ---- ../pristine-linux-2.6.16/drivers/oprofile/oprofile_files.c 2006-03-20 05:53:29.000000000 +0000 -+++ ./drivers/oprofile/oprofile_files.c 2006-04-03 15:53:05.000000000 +0100 -@@ -5,15 +5,21 @@ - * @remark Read the file COPYING - * - * @author John Levon <levon@xxxxxxxxxxxxxxxxx> -+ * -+ * Modified by Aravind Menon for Xen -+ * These modifications are: -+ * Copyright (C) 2005 Hewlett-Packard Co. - */ - - #include <linux/fs.h> - #include <linux/oprofile.h> -+#include <asm/uaccess.h> -+#include <linux/ctype.h> - - #include "event_buffer.h" - #include "oprofile_stats.h" - #include "oprof.h" -- -+ - unsigned long fs_buffer_size = 131072; - unsigned long fs_cpu_buffer_size = 8192; - unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */ -@@ -117,11 +123,79 @@ static ssize_t dump_write(struct file * - static struct file_operations dump_fops = { - .write = dump_write, - }; -- -+ -+#define TMPBUFSIZE 512 -+ -+unsigned int adomains = 0; -+long active_domains[MAX_OPROF_DOMAINS]; -+ -+static ssize_t adomain_write(struct file * file, char const __user * buf, -+ size_t count, loff_t * offset) -+{ -+ char tmpbuf[TMPBUFSIZE]; -+ char * startp = tmpbuf; -+ char * endp = tmpbuf; -+ int i; -+ unsigned long val; -+ -+ if (*offset) -+ return -EINVAL; -+ if (!count) -+ return 0; -+ if (count > TMPBUFSIZE - 1) -+ return -EINVAL; -+ -+ memset(tmpbuf, 0x0, TMPBUFSIZE); -+ -+ if (copy_from_user(tmpbuf, buf, count)) -+ return -EFAULT; -+ -+ for (i = 0; i < MAX_OPROF_DOMAINS; i++) -+ active_domains[i] = -1; -+ adomains = 0; -+ -+ while (1) { -+ val = simple_strtol(startp, &endp, 0); -+ if (endp == startp) -+ break; -+ while (ispunct(*endp)) -+ endp++; -+ active_domains[adomains++] = val; -+ if (adomains >= MAX_OPROF_DOMAINS) -+ break; -+ startp = endp; -+ } -+ if (oprofile_set_active()) -+ return -EINVAL; -+ return count; -+} -+ -+static ssize_t adomain_read(struct file * file, char __user * buf, -+ size_t count, loff_t * offset) -+{ -+ char tmpbuf[TMPBUFSIZE]; -+ size_t len = 0; -+ int i; -+ /* This is all screwed up if we run out of space */ -+ for (i = 0; i < adomains; i++) -+ len += snprintf(tmpbuf + len, TMPBUFSIZE - len, -+ "%u ", (unsigned int)active_domains[i]); -+ len += snprintf(tmpbuf + len, TMPBUFSIZE - len, "\n"); -+ return simple_read_from_buffer((void __user *)buf, count, -+ offset, tmpbuf, len); -+} -+ -+ -+static struct file_operations active_domain_ops = { -+ .read = adomain_read, -+ .write = adomain_write, -+}; -+ - void oprofile_create_files(struct super_block * sb, struct dentry * root) - { - oprofilefs_create_file(sb, root, "enable", &enable_fops); - oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666); -+ oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops); - oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops); - oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size); - oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed); -diff -pruN ../pristine-linux-2.6.16/include/linux/oprofile.h ./include/linux/oprofile.h ---- ../pristine-linux-2.6.16/include/linux/oprofile.h 2006-03-20 05:53:29.000000000 +0000 -+++ ./include/linux/oprofile.h 2006-04-03 15:53:05.000000000 +0100 -@@ -16,6 +16,8 @@ - #include <linux/types.h> - #include <linux/spinlock.h> - #include <asm/atomic.h> -+ -+#include <xen/interface/xenoprof.h> - - struct super_block; - struct dentry; -@@ -27,6 +29,8 @@ struct oprofile_operations { - /* create any necessary configuration files in the oprofile fs. - * Optional. */ - int (*create_files)(struct super_block * sb, struct dentry * root); -+ /* setup active domains with Xen */ -+ int (*set_active)(int *active_domains, unsigned int adomains); - /* Do any necessary interrupt setup. Optional. */ - int (*setup)(void); - /* Do any necessary interrupt shutdown. Optional. */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |