Warning!

Notice: the grml team is migrating from Mercurial to Git.
Please visit git.grml.org instead!

Split patches into the single flavours
authorMichael Prokop <mika@grml.org>
Sun Apr 15 15:24:16 2007 +0200 (19 months ago)
changeset 3041a2870cd34c
manifest41a2870cd34c
parent 29711c19d33ae5
child 31d678459cafde
Split patches into the single flavours
2.6.20/1000_2.6.20.7.patch
2.6.20/2400_r8169-link-speed.patch
2.6.20/4100_sata-promise-ide.patch
2.6.20/4101_sata-promise-ide-cable-detect.patch
2.6.20/4150_iteraid.patch
2.6.20/4210_cx88-cinergy-1400-support.patch
2.6.20/4300_squashfs-3.2.patch
2.6.20/4310_unionfs-2.6.20-u1.patch
2.6.20/4400_speakup-20070204.patch
2.6.20/5001_grml_logo.patch
2.6.20/5002_commandlinesize.patch
2.6.20/5003_grml-kernelversion.patch
2.6.20/grml-small/1000_2.6.20.7.patch
2.6.20/grml-small/2400_r8169-link-speed.patch
2.6.20/grml-small/4100_sata-promise-ide.patch
2.6.20/grml-small/4101_sata-promise-ide-cable-detect.patch
2.6.20/grml-small/4150_iteraid.patch
2.6.20/grml-small/4210_cx88-cinergy-1400-support.patch
2.6.20/grml-small/4300_squashfs-3.2.patch
2.6.20/grml-small/4310_unionfs-2.6.20-u1.patch
2.6.20/grml-small/5001_grml_logo.patch
2.6.20/grml-small/5002_commandlinesize.patch
2.6.20/grml-small/5003_grml-kernelversion.patch
2.6.20/grml64/1000_2.6.20.7.patch
2.6.20/grml64/2400_r8169-link-speed.patch
2.6.20/grml64/4100_sata-promise-ide.patch
2.6.20/grml64/4101_sata-promise-ide-cable-detect.patch
2.6.20/grml64/4150_iteraid.patch
2.6.20/grml64/4210_cx88-cinergy-1400-support.patch
2.6.20/grml64/4300_squashfs-3.2.patch
2.6.20/grml64/4310_unionfs-2.6.20-u1.patch
2.6.20/grml64/5001_grml_logo.patch
2.6.20/grml64/5002_commandlinesize.patch
2.6.20/grml64/5003_grml-kernelversion.patch
2.6.20/x86/1000_2.6.20.7.patch
2.6.20/x86/2400_r8169-link-speed.patch
2.6.20/x86/4100_sata-promise-ide.patch
2.6.20/x86/4101_sata-promise-ide-cable-detect.patch
2.6.20/x86/4150_iteraid.patch
2.6.20/x86/4210_cx88-cinergy-1400-support.patch
2.6.20/x86/4300_squashfs-3.2.patch
2.6.20/x86/4310_unionfs-2.6.20-u1.patch
2.6.20/x86/4400_speakup-20070204.patch
2.6.20/x86/5001_grml_logo.patch
2.6.20/x86/5002_commandlinesize.patch
2.6.20/x86/5003_grml-kernelversion.patch
config/config-2.6.20-grml-small
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/2.6.20/grml-small/1000_2.6.20.7.patch Sun Apr 15 15:24:16 2007 +0200
@@ -0,0 +1,9846 @@
+diff --git a/Makefile b/Makefile
+index 7e2750f..bc99522 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ VERSION = 2
+ PATCHLEVEL = 6
+ SUBLEVEL = 20
+-EXTRAVERSION =
++EXTRAVERSION = .7
+ NAME = Homicidal Dwarf Hamster
+
+ # *DOCUMENTATION*
+diff --git a/arch/i386/kernel/cpu/mtrr/if.c b/arch/i386/kernel/cpu/mtrr/if.c
+index 5ae1705..590d99e 100644
+--- a/arch/i386/kernel/cpu/mtrr/if.c
++++ b/arch/i386/kernel/cpu/mtrr/if.c
+@@ -158,8 +158,9 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
+ struct mtrr_sentry sentry;
+ struct mtrr_gentry gentry;
+ void __user *arg = (void __user *) __arg;
++ unsigned int compat_cmd = cmd;
+
+- switch (cmd) {
++ switch (compat_cmd) {
+ case MTRRIOC_ADD_ENTRY:
+ case MTRRIOC_SET_ENTRY:
+ case MTRRIOC_DEL_ENTRY:
+@@ -177,14 +178,20 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
+ return -EFAULT;
+ break;
+ #ifdef CONFIG_COMPAT
+- case MTRRIOC32_ADD_ENTRY:
+- case MTRRIOC32_SET_ENTRY:
+- case MTRRIOC32_DEL_ENTRY:
+- case MTRRIOC32_KILL_ENTRY:
+- case MTRRIOC32_ADD_PAGE_ENTRY:
+- case MTRRIOC32_SET_PAGE_ENTRY:
+- case MTRRIOC32_DEL_PAGE_ENTRY:
+- case MTRRIOC32_KILL_PAGE_ENTRY: {
++#define MTRR_COMPAT_OP(op, type)\
++ case MTRRIOC32_##op: \
++ cmd = MTRRIOC_##op; \
++ goto compat_get_##type
++
++ MTRR_COMPAT_OP(ADD_ENTRY, sentry);
++ MTRR_COMPAT_OP(SET_ENTRY, sentry);
++ MTRR_COMPAT_OP(DEL_ENTRY, sentry);
++ MTRR_COMPAT_OP(KILL_ENTRY, sentry);
++ MTRR_COMPAT_OP(ADD_PAGE_ENTRY, sentry);
++ MTRR_COMPAT_OP(SET_PAGE_ENTRY, sentry);
++ MTRR_COMPAT_OP(DEL_PAGE_ENTRY, sentry);
++ MTRR_COMPAT_OP(KILL_PAGE_ENTRY, sentry);
++compat_get_sentry: {
+ struct mtrr_sentry32 __user *s32 = (struct mtrr_sentry32 __user *)__arg;
+ err = get_user(sentry.base, &s32->base);
+ err |= get_user(sentry.size, &s32->size);
+@@ -193,8 +200,9 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
+ return err;
+ break;
+ }
+- case MTRRIOC32_GET_ENTRY:
+- case MTRRIOC32_GET_PAGE_ENTRY: {
++ MTRR_COMPAT_OP(GET_ENTRY, gentry);
++ MTRR_COMPAT_OP(GET_PAGE_ENTRY, gentry);
++compat_get_gentry: {
+ struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg;
+ err = get_user(gentry.regnum, &g32->regnum);
+ err |= get_user(gentry.base, &g32->base);
+@@ -204,6 +212,7 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
+ return err;
+ break;
+ }
++#undef MTRR_COMPAT_OP
+ #endif
+ }
+
+@@ -287,7 +296,7 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
+ if (err)
+ return err;
+
+- switch(cmd) {
++ switch(compat_cmd) {
+ case MTRRIOC_GET_ENTRY:
+ case MTRRIOC_GET_PAGE_ENTRY:
+ if (copy_to_user(arg, &gentry, sizeof gentry))
+diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
+index 65d7620..f654505 100644
+--- a/arch/i386/kernel/signal.c
++++ b/arch/i386/kernel/signal.c
+@@ -21,6 +21,7 @@
+ #include <linux/suspend.h>
+ #include <linux/ptrace.h>
+ #include <linux/elf.h>
++#include <linux/binfmts.h>
+ #include <asm/processor.h>
+ #include <asm/ucontext.h>
+ #include <asm/uaccess.h>
+@@ -349,7 +350,10 @@ static int setup_frame(int sig, struct k_sigaction *ka,
+ goto give_sigsegv;
+ }
+
+- restorer = (void *)VDSO_SYM(&__kernel_sigreturn);
++ if (current->binfmt->hasvdso)
++ restorer = (void *)VDSO_SYM(&__kernel_sigreturn);
++ else
++ restorer = (void *)&frame->retcode;
+ if (ka->sa.sa_flags & SA_RESTORER)
+ restorer = ka->sa.sa_restorer;
+
+diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c
+index 5da7442..666f70d 100644
+--- a/arch/i386/kernel/sysenter.c
++++ b/arch/i386/kernel/sysenter.c
+@@ -77,7 +77,7 @@ int __init sysenter_setup(void)
+ syscall_page = (void *)get_zeroed_page(GFP_ATOMIC);
+
+ #ifdef CONFIG_COMPAT_VDSO
+- __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY);
++ __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY_EXEC);
+ printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO));
+ #endif
+
+diff --git a/arch/i386/lib/usercopy.c b/arch/i386/lib/usercopy.c
+index d22cfc9..086b372 100644
+--- a/arch/i386/lib/usercopy.c
++++ b/arch/i386/lib/usercopy.c
+@@ -10,6 +10,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/module.h>
+ #include <linux/backing-dev.h>
++#include <linux/interrupt.h>
+ #include <asm/uaccess.h>
+ #include <asm/mmx.h>
+
+@@ -719,6 +720,14 @@ unsigned long __copy_to_user_ll(void __user *to, const void *from,
+ #ifndef CONFIG_X86_WP_WORKS_OK
+ if (unlikely(boot_cpu_data.wp_works_ok == 0) &&
+ ((unsigned long )to) < TASK_SIZE) {
++ /*
++ * When we are in an atomic section (see
++ * mm/filemap.c:file_read_actor), return the full
++ * length to take the slow path.
++ */
++ if (in_atomic())
++ return n;
++
+ /*
+ * CPU does not honor the WP bit when writing
+ * from supervisory mode, and due to preemption or SMP,
+diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
+index fcacfe2..c085199 100644
+--- a/arch/ia64/Kconfig
++++ b/arch/ia64/Kconfig
+@@ -11,6 +11,7 @@ menu "Processor type and features"
+
+ config IA64
+ bool
++ select ATA_NONSTANDARD if ATA
+ default y
+ help
+ The Itanium Processor Family is Intel's 64-bit successor to
+diff --git a/arch/ia64/kernel/crash.c b/arch/ia64/kernel/crash.c
+index bc2f64d..2018e62 100644
+--- a/arch/ia64/kernel/crash.c
++++ b/arch/ia64/kernel/crash.c
+@@ -79,6 +79,7 @@ crash_save_this_cpu()
+ final_note(buf);
+ }
+
++#ifdef CONFIG_SMP
+ static int
+ kdump_wait_cpu_freeze(void)
+ {
+@@ -91,6 +92,7 @@ kdump_wait_cpu_freeze(void)
+ }
+ return 1;
+ }
++#endif
+
+ void
+ machine_crash_shutdown(struct pt_regs *pt)
+@@ -132,11 +134,12 @@ kdump_cpu_freeze(struct unw_frame_info *info, void *arg)
+ atomic_inc(&kdump_cpu_freezed);
+ kdump_status[cpuid] = 1;
+ mb();
+- if (cpuid == 0) {
+- for (;;)
+- cpu_relax();
+- } else
++#ifdef CONFIG_HOTPLUG_CPU
++ if (cpuid != 0)
+ ia64_jump_to_sal(&sal_boot_rendez_state[cpuid]);
++#endif
++ for (;;)
++ cpu_relax();
+ }
+
+ static int
+diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
+index 0fc5fb7..02479e1 100644
+--- a/arch/ia64/kernel/iosapic.c
++++ b/arch/ia64/kernel/iosapic.c
+@@ -446,7 +446,7 @@ iosapic_end_level_irq (unsigned int irq)
+ #define iosapic_disable_level_irq mask_irq
+ #define iosapic_ack_level_irq nop
+
+-struct hw_interrupt_type irq_type_iosapic_level = {
++struct irq_chip irq_type_iosapic_level = {
+ .name = "IO-SAPIC-level",
+ .startup = iosapic_startup_level_irq,
+ .shutdown = iosapic_shutdown_level_irq,
+@@ -454,6 +454,8 @@ struct hw_interrupt_type irq_type_iosapic_level = {
+ .disable = iosapic_disable_level_irq,
+ .ack = iosapic_ack_level_irq,
+ .end = iosapic_end_level_irq,
++ .mask = mask_irq,
++ .unmask = unmask_irq,
+ .set_affinity = iosapic_set_affinity
+ };
+
+@@ -493,7 +495,7 @@ iosapic_ack_edge_irq (unsigned int irq)
+ #define iosapic_disable_edge_irq nop
+ #define iosapic_end_edge_irq nop
+
+-struct hw_interrupt_type irq_type_iosapic_edge = {
++struct irq_chip irq_type_iosapic_edge = {
+ .name = "IO-SAPIC-edge",
+ .startup = iosapic_startup_edge_irq,
+ .shutdown = iosapic_disable_edge_irq,
+@@ -501,6 +503,8 @@ struct hw_interrupt_type irq_type_iosapic_edge = {
+ .disable = iosapic_disable_edge_irq,
+ .ack = iosapic_ack_edge_irq,
+ .end = iosapic_end_edge_irq,
++ .mask = mask_irq,
++ .unmask = unmask_irq,
+ .set_affinity = iosapic_set_affinity
+ };
+
+diff --git a/arch/ia64/kernel/machine_kexec.c b/arch/ia64/kernel/machine_kexec.c
+index e2ccc9f..7141795 100644
+--- a/arch/ia64/kernel/machine_kexec.c
++++ b/arch/ia64/kernel/machine_kexec.c
+@@ -70,12 +70,14 @@ void machine_kexec_cleanup(struct kimage *image)
+
+ void machine_shutdown(void)
+ {
++#ifdef CONFIG_HOTPLUG_CPU
+ int cpu;
+
+ for_each_online_cpu(cpu) {
+ if (cpu != smp_processor_id())
+ cpu_down(cpu);
+ }
++#endif
+ kexec_disable_iosapic();
+ }
+
+diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
+index 8c5bee0..8d2a1bf 100644
+--- a/arch/ia64/sn/kernel/irq.c
++++ b/arch/ia64/sn/kernel/irq.c
+@@ -205,7 +205,17 @@ static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask)
+ (void)sn_retarget_vector(sn_irq_info, nasid, slice);
+ }
+
+-struct hw_interrupt_type irq_type_sn = {
++static void
++sn_mask_irq(unsigned int irq)
++{
++}
++
++static void
++sn_unmask_irq(unsigned int irq)
++{
++}
++
++struct irq_chip irq_type_sn = {
+ .name = "SN hub",
+ .startup = sn_startup_irq,
+ .shutdown = sn_shutdown_irq,
+@@ -213,6 +223,8 @@ struct hw_interrupt_type irq_type_sn = {
+ .disable = sn_disable_irq,
+ .ack = sn_ack_irq,
+ .end = sn_end_irq,
++ .mask = sn_mask_irq,
++ .unmask = sn_unmask_irq,
+ .set_affinity = sn_set_affinity_irq
+ };
+
+diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c
+index 44cbe0c..a689e29 100644
+--- a/arch/m32r/kernel/process.c
++++ b/arch/m32r/kernel/process.c
+@@ -174,7 +174,7 @@ void show_regs(struct pt_regs * regs)
+ regs->acc1h, regs->acc1l);
+ #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
+ printk("ACCH[%08lx]:ACCL[%08lx]\n", \
+- regs->acch, regs->accl);
++ regs->acc0h, regs->acc0l);
+ #else
+ #error unknown isa configuration
+ #endif
+diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
+index 092ea86..4b15605 100644
+--- a/arch/m32r/kernel/signal.c
++++ b/arch/m32r/kernel/signal.c
+@@ -109,19 +109,10 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
+ COPY(r10);
+ COPY(r11);
+ COPY(r12);
+-#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
+ COPY(acc0h);
+ COPY(acc0l);
+- COPY(acc1h);
+- COPY(acc1l);
+-#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
+- COPY(acch);
+- COPY(accl);
+- COPY(dummy_acc1h);
+- COPY(dummy_acc1l);
+-#else
+-#error unknown isa configuration
+-#endif
++ COPY(acc1h); /* ISA_DSP_LEVEL2 only */
++ COPY(acc1l); /* ISA_DSP_LEVEL2 only */
+ COPY(psw);
+ COPY(bpc);
+ COPY(bbpsw);
+@@ -196,19 +187,10 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
+ COPY(r10);
+ COPY(r11);
+ COPY(r12);
+-#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
+ COPY(acc0h);
+ COPY(acc0l);
+- COPY(acc1h);
+- COPY(acc1l);
+-#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
+- COPY(acch);
+- COPY(accl);
+- COPY(dummy_acc1h);
+- COPY(dummy_acc1l);
+-#else
+-#error unknown isa configuration
+-#endif
++ COPY(acc1h); /* ISA_DSP_LEVEL2 only */
++ COPY(acc1l); /* ISA_DSP_LEVEL2 only */
+ COPY(psw);
+ COPY(bpc);
+ COPY(bbpsw);
+diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
+index 71b1fe5..97cedcd 100644
+--- a/arch/powerpc/kernel/head_64.S
++++ b/arch/powerpc/kernel/head_64.S
+@@ -613,7 +613,7 @@ system_call_pSeries:
+ /*** pSeries interrupt support ***/
+
+ /* moved from 0xf00 */
+- MASKABLE_EXCEPTION_PSERIES(., performance_monitor)
++ STD_EXCEPTION_PSERIES(., performance_monitor)
+
+ /*
+ * An interrupt came in while soft-disabled; clear EE in SRR1,
+diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
+index c8b65ca..6d9857c 100644
+--- a/arch/ppc/kernel/ppc_ksyms.c
++++ b/arch/ppc/kernel/ppc_ksyms.c
+@@ -270,7 +270,7 @@ EXPORT_SYMBOL(mmu_hash_lock); /* For MOL */
+ extern long *intercept_table;
+ EXPORT_SYMBOL(intercept_table);
+ #endif /* CONFIG_PPC_STD_MMU */
+-#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
++#ifdef CONFIG_PPC_DCR_NATIVE
+ EXPORT_SYMBOL(__mtdcr);
+ EXPORT_SYMBOL(__mfdcr);
+ #endif
+diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c
+index dab6169..798b140 100644
+--- a/arch/sparc/kernel/of_device.c
++++ b/arch/sparc/kernel/of_device.c
+@@ -495,7 +495,7 @@ static void __init build_device_resources(struct of_device *op,
+ u32 *reg = (preg + (index * ((na + ns) * 4)));
+ struct device_node *dp = op->node;
+ struct device_node *pp = p_op->node;
+- struct of_bus *pbus;
++ struct of_bus *pbus, *dbus;
+ u64 size, result = OF_BAD_ADDR;
+ unsigned long flags;
+ int dna, dns;
+@@ -516,6 +516,7 @@ static void __init build_device_resources(struct of_device *op,
+
+ dna = na;
+ dns = ns;
++ dbus = bus;
+
+ while (1) {
+ dp = pp;
+@@ -528,13 +529,13 @@ static void __init build_device_resources(struct of_device *op,
+ pbus = of_match_bus(pp);
+ pbus->count_cells(dp, &pna, &pns);
+
+- if (build_one_resource(dp, bus, pbus, addr,
++ if (build_one_resource(dp, dbus, pbus, addr,
+ dna, dns, pna))
+ break;
+
+ dna = pna;
+ dns = pns;
+- bus = pbus;
++ dbus = pbus;
+ }
+
+ build_res:
+diff --git a/arch/sparc64/kernel/ktlb.S b/arch/sparc64/kernel/ktlb.S
+index e492db8..d4024ac 100644
+--- a/arch/sparc64/kernel/ktlb.S
++++ b/arch/sparc64/kernel/ktlb.S
+@@ -138,9 +138,15 @@ kvmap_dtlb_4v:
+ brgez,pn %g4, kvmap_dtlb_nonlinear
+ nop
+
++#ifdef CONFIG_DEBUG_PAGEALLOC
++ /* Index through the base page size TSB even for linear
++ * mappings when using page allocation debugging.
++ */
++ KERN_TSB_LOOKUP_TL1(%g4, %g6, %g5, %g1, %g2, %g3, kvmap_dtlb_load)
++#else
+ /* Correct TAG_TARGET is already in %g6, check 4mb TSB. */
+ KERN_TSB4M_LOOKUP_TL1(%g6, %g5, %g1, %g2, %g3, kvmap_dtlb_load)
+-
++#endif
+ /* TSB entry address left in %g1, lookup linear PTE.
+ * Must preserve %g1 and %g6 (TAG).
+ */
+diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
+index b0f3e00..1f45985 100644
+--- a/arch/sparc64/kernel/of_device.c
++++ b/arch/sparc64/kernel/of_device.c
+@@ -581,7 +581,7 @@ static void __init build_device_resources(struct of_device *op,
+ u32 *reg = (preg + (index * ((na + ns) * 4)));
+ struct device_node *dp = op->node;
+ struct device_node *pp = p_op->node;
+- struct of_bus *pbus;
++ struct of_bus *pbus, *dbus;
+ u64 size, result = OF_BAD_ADDR;
+ unsigned long flags;
+ int dna, dns;
+@@ -599,6 +599,7 @@ static void __init build_device_resources(struct of_device *op,
+
+ dna = na;
+ dns = ns;
++ dbus = bus;
+
+ while (1) {
+ dp = pp;
+@@ -611,13 +612,13 @@ static void __init build_device_resources(struct of_device *op,
+ pbus = of_match_bus(pp);
+ pbus->count_cells(dp, &pna, &pns);
+
+- if (build_one_resource(dp, bus, pbus, addr,
++ if (build_one_resource(dp, dbus, pbus, addr,
+ dna, dns, pna))
+ break;
+
+ dna = pna;
+ dns = pns;
+- bus = pbus;
++ dbus = pbus;
+ }
+
+ build_res:
+@@ -708,7 +709,7 @@ static unsigned int __init pci_irq_swizzle(struct device_node *dp,
+ unsigned int irq)
+ {
+ struct linux_prom_pci_registers *regs;
+- unsigned int devfn, slot, ret;
++ unsigned int bus, devfn, slot, ret;
+
+ if (irq < 1 || irq > 4)
+ return irq;
+@@ -717,10 +718,46 @@ static unsigned int __init pci_irq_swizzle(struct device_node *dp,
+ if (!regs)
+ return irq;
+
++ bus = (regs->phys_hi >> 16) & 0xff;
+ devfn = (regs->phys_hi >> 8) & 0xff;
+ slot = (devfn >> 3) & 0x1f;
+
+- ret = ((irq - 1 + (slot & 3)) & 3) + 1;
++ if (pp->irq_trans) {
++ /* Derived from Table 8-3, U2P User's Manual. This branch
++ * is handling a PCI controller that lacks a proper set of
++ * interrupt-map and interrupt-map-mask properties. The
++ * Ultra-E450 is one example.
++ *
++ * The bit layout is BSSLL, where:
++ * B: 0 on bus A, 1 on bus B
++ * D: 2-bit slot number, derived from PCI device number as
++ * (dev - 1) for bus A, or (dev - 2) for bus B
++ * L: 2-bit line number
++ *
++ * Actually, more "portable" way to calculate the funky
++ * slot number is to subtract pbm->pci_first_slot from the
++ * device number, and that's exactly what the pre-OF
++ * sparc64 code did, but we're building this stuff generically
++ * using the OBP tree, not in the PCI controller layer.
++ */
++ if (bus & 0x80) {
++ /* PBM-A */
++ bus = 0x00;
++ slot = (slot - 1) << 2;
++ } else {
++ /* PBM-B */
++ bus = 0x10;
++ slot = (slot - 2) << 2;
++ }
++ irq -= 1;
++
++ ret = (bus | slot | irq);
++ } else {
++ /* Going through a PCI-PCI bridge that lacks a set of
++ * interrupt-map and interrupt-map-mask properties.
++ */
++ ret = ((irq - 1 + (slot & 3)) & 3) + 1;
++ }
+
+ return ret;
+ }
+diff --git a/arch/sparc64/kernel/tsb.S b/arch/sparc64/kernel/tsb.S
+index eedf94f..10adb2f 100644
+--- a/arch/sparc64/kernel/tsb.S
++++ b/arch/sparc64/kernel/tsb.S
+@@ -546,6 +546,7 @@ NGtsb_init:
+ subcc %o1, 0x100, %o1
+ bne,pt %xcc, 1b
+ add %o0, 0x100, %o0
++ membar #Sync
+ retl
+ wr %g2, 0x0, %asi
+ .size NGtsb_init, .-NGtsb_init
+diff --git a/arch/sparc64/lib/NGbzero.S b/arch/sparc64/lib/NGbzero.S
+index e86baec..f10e452 100644
+--- a/arch/sparc64/lib/NGbzero.S
++++ b/arch/sparc64/lib/NGbzero.S
+@@ -88,6 +88,7 @@ NGbzero_loop:
+ bne,pt %xcc, NGbzero_loop
+ add %o0, 64, %o0
+
++ membar #Sync
+ wr %o4, 0x0, %asi
+ brz,pn %o1, NGbzero_done
+ NGbzero_medium:
+diff --git a/arch/sparc64/lib/NGmemcpy.S b/arch/sparc64/lib/NGmemcpy.S
+index 8e522b3..66063a9 100644
+--- a/arch/sparc64/lib/NGmemcpy.S
++++ b/arch/sparc64/lib/NGmemcpy.S
+@@ -247,6 +247,8 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
+ /* fall through */
+
+ 60:
++ membar #Sync
++
+ /* %o2 contains any final bytes still needed to be copied
+ * over. If anything is left, we copy it one byte at a time.
+ */
+diff --git a/arch/sparc64/lib/NGpage.S b/arch/sparc64/lib/NGpage.S
+index 7d7c3bb..8ce3a0c 100644
+--- a/arch/sparc64/lib/NGpage.S
++++ b/arch/sparc64/lib/NGpage.S
+@@ -41,6 +41,7 @@ NGcopy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */
+ subcc %g7, 64, %g7
+ bne,pt %xcc, 1b
+ add %o0, 32, %o0
++ membar #Sync
+ retl
+ nop
+
+@@ -63,6 +64,7 @@ NGclear_user_page: /* %o0=dest, %o1=vaddr */
+ subcc %g7, 64, %g7
+ bne,pt %xcc, 1b
+ add %o0, 32, %o0
++ membar #Sync
+ retl
+ nop
+
+diff --git a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c
+index 33fd0b2..00677b5 100644
+--- a/arch/sparc64/mm/hugetlbpage.c
++++ b/arch/sparc64/mm/hugetlbpage.c
+@@ -248,6 +248,7 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+ if (!pte_present(*ptep) && pte_present(entry))
+ mm->context.huge_pte_count++;
+
++ addr &= HPAGE_MASK;
+ for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
+ set_pte_at(mm, addr, ptep, entry);
+ ptep++;
+@@ -266,6 +267,8 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+ if (pte_present(entry))
+ mm->context.huge_pte_count--;
+
++ addr &= HPAGE_MASK;
++
+ for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
+ pte_clear(mm, addr, ptep);
+ addr += PAGE_SIZE;
+diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
+index 054822a..5391cd5 100644
+--- a/arch/sparc64/mm/init.c
++++ b/arch/sparc64/mm/init.c
+@@ -59,8 +59,10 @@ unsigned long kern_linear_pte_xor[2] __read_mostly;
+ */
+ unsigned long kpte_linear_bitmap[KPTE_BITMAP_BYTES / sizeof(unsigned long)];
+
++#ifndef CONFIG_DEBUG_PAGEALLOC
+ /* A special kernel TSB for 4MB and 256MB linear mappings. */
+ struct tsb swapper_4m_tsb[KERNEL_TSB4M_NENTRIES];
++#endif
+
+ #define MAX_BANKS 32
+
+@@ -1301,7 +1303,12 @@ static void __init tsb_phys_patch(void)
+ }
+
+ /* Don't mark as init, we give this to the Hypervisor. */
+-static struct hv_tsb_descr ktsb_descr[2];
++#ifndef CONFIG_DEBUG_PAGEALLOC
++#define NUM_KTSB_DESCR 2
++#else
++#define NUM_KTSB_DESCR 1
++#endif
++static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR];
+ extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES];
+
+ static void __init sun4v_ktsb_init(void)
+@@ -1340,6 +1347,7 @@ static void __init sun4v_ktsb_init(void)
+ ktsb_descr[0].tsb_base = ktsb_pa;
+ ktsb_descr[0].resv = 0;
+
++#ifndef CONFIG_DEBUG_PAGEALLOC
+ /* Second KTSB for 4MB/256MB mappings. */
+ ktsb_pa = (kern_base +
+ ((unsigned long)&swapper_4m_tsb[0] - KERNBASE));
+@@ -1352,6 +1360,7 @@ static void __init sun4v_ktsb_init(void)
+ ktsb_descr[1].ctx_idx = 0;
+ ktsb_descr[1].tsb_base = ktsb_pa;
+ ktsb_descr[1].resv = 0;
++#endif
+ }
+
+ void __cpuinit sun4v_ktsb_register(void)
+@@ -1364,7 +1373,7 @@ void __cpuinit sun4v_ktsb_register(void)
+ pa = kern_base + ((unsigned long)&ktsb_descr[0] - KERNBASE);
+
+ func = HV_FAST_MMU_TSB_CTX0;
+- arg0 = 2;
++ arg0 = NUM_KTSB_DESCR;
+ arg1 = pa;
+ __asm__ __volatile__("ta %6"
+ : "=&r" (func), "=&r" (arg0), "=&r" (arg1)
+@@ -1393,7 +1402,9 @@ void __init paging_init(void)
+
+ /* Invalidate both kernel TSBs. */
+ memset(swapper_tsb, 0x40, sizeof(swapper_tsb));
++#ifndef CONFIG_DEBUG_PAGEALLOC
+ memset(swapper_4m_tsb, 0x40, sizeof(swapper_4m_tsb));
++#endif
+
+ if (tlb_type == hypervisor)
+ sun4v_pgprot_init();
+@@ -1725,8 +1736,13 @@ static void __init sun4u_pgprot_init(void)
+ pg_iobits = (_PAGE_VALID | _PAGE_PRESENT_4U | __DIRTY_BITS_4U |
+ __ACCESS_BITS_4U | _PAGE_E_4U);
+
++#ifdef CONFIG_DEBUG_PAGEALLOC
++ kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZBITS_4U) ^
++ 0xfffff80000000000;
++#else
+ kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4U) ^
+ 0xfffff80000000000;
++#endif
+ kern_linear_pte_xor[0] |= (_PAGE_CP_4U | _PAGE_CV_4U |
+ _PAGE_P_4U | _PAGE_W_4U);
+
+@@ -1769,13 +1785,23 @@ static void __init sun4v_pgprot_init(void)
+ _PAGE_E = _PAGE_E_4V;
+ _PAGE_CACHE = _PAGE_CACHE_4V;
+
++#ifdef CONFIG_DEBUG_PAGEALLOC
++ kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZBITS_4V) ^
++ 0xfffff80000000000;
++#else
+ kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4V) ^
+ 0xfffff80000000000;
++#endif
+ kern_linear_pte_xor[0] |= (_PAGE_CP_4V | _PAGE_CV_4V |
+ _PAGE_P_4V | _PAGE_W_4V);
+
++#ifdef CONFIG_DEBUG_PAGEALLOC
++ kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZBITS_4V) ^
++ 0xfffff80000000000;
++#else
+ kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZ256MB_4V) ^
+ 0xfffff80000000000;
++#endif
+ kern_linear_pte_xor[1] |= (_PAGE_CP_4V | _PAGE_CV_4V |
+ _PAGE_P_4V | _PAGE_W_4V);
+
+diff --git a/arch/um/include/os.h b/arch/um/include/os.h
+index 13a86bd..4e9a13e 100644
+--- a/arch/um/include/os.h
++++ b/arch/um/include/os.h
+@@ -341,4 +341,6 @@ extern void maybe_sigio_broken(int fd, int read);
+ extern void sig_handler_common_skas(int sig, void *sc_ptr);
+ extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
+
++extern int os_arch_prctl(int pid, int code, unsigned long *addr);
++
+ #endif
+diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h
+index 66cb400..62403bd 100644
+--- a/arch/um/include/sysdep-x86_64/ptrace.h
++++ b/arch/um/include/sysdep-x86_64/ptrace.h
+@@ -104,10 +104,6 @@ union uml_pt_regs {
+ #endif
+ #ifdef UML_CONFIG_MODE_SKAS
+ struct skas_regs {
+- /* x86_64 ptrace uses sizeof(user_regs_struct) as its register
+- * file size, while i386 uses FRAME_SIZE. Therefore, we need
+- * to use UM_FRAME_SIZE here instead of HOST_FRAME_SIZE.
+- */
+ unsigned long regs[MAX_REG_NR];
+ unsigned long fp[HOST_FP_SIZE];
+ struct faultinfo faultinfo;
+diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c
+index 5a99dd3..13c6cb5 100644
+--- a/arch/um/os-Linux/elf_aux.c
++++ b/arch/um/os-Linux/elf_aux.c
+@@ -40,6 +40,9 @@ __init void scan_elf_aux( char **envp)
+ switch ( auxv->a_type ) {
+ case AT_SYSINFO:
+ __kernel_vsyscall = auxv->a_un.a_val;
++ /* See if the page is under TASK_SIZE */
++ if (__kernel_vsyscall < (unsigned long) envp)
++ __kernel_vsyscall = 0;
+ break;
+ case AT_SYSINFO_EHDR:
+ vsyscall_ehdr = auxv->a_un.a_val;
+diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
+index 925a652..b2e1fd8 100644
+--- a/arch/um/os-Linux/sigio.c
++++ b/arch/um/os-Linux/sigio.c
+@@ -97,20 +97,22 @@ static int write_sigio_thread(void *unused)
+
+ static int need_poll(struct pollfds *polls, int n)
+ {
+- if(n <= polls->size){
+- polls->used = n;
++ struct pollfd *new;
++
++ if(n <= polls->size)
+ return 0;
+- }
+- kfree(polls->poll);
+- polls->poll = um_kmalloc_atomic(n * sizeof(struct pollfd));
+- if(polls->poll == NULL){
++
++ new = um_kmalloc_atomic(n * sizeof(struct pollfd));
++ if(new == NULL){
+ printk("need_poll : failed to allocate new pollfds\n");
+- polls->size = 0;
+- polls->used = 0;
+ return -ENOMEM;
+ }
++
++ memcpy(new, polls->poll, polls->used * sizeof(struct pollfd));
++ kfree(polls->poll);
++
++ polls->poll = new;
+ polls->size = n;
+- polls->used = n;
+ return 0;
+ }
+
+@@ -171,15 +173,15 @@ int add_sigio_fd(int fd)
+ goto out;
+ }
+
+- n = current_poll.used + 1;
+- err = need_poll(&next_poll, n);
++ n = current_poll.used;
++ err = need_poll(&next_poll, n + 1);
+ if(err)
+ goto out;
+
+- for(i = 0; i < current_poll.used; i++)
+- next_poll.poll[i] = current_poll.poll[i];
+-
+- next_poll.poll[n - 1] = *p;
++ memcpy(next_poll.poll, current_poll.poll,
++ current_poll.used * sizeof(struct pollfd));
++ next_poll.poll[n] = *p;
++ next_poll.used = n + 1;
+ update_thread();
+ out:
+ sigio_unlock();
+@@ -214,6 +216,7 @@ int ignore_sigio_fd(int fd)
+ if(p->fd != fd)
+ next_poll.poll[n++] = *p;
+ }
++ next_poll.used = current_poll.used - 1;
+
+ update_thread();
+ out:
+@@ -331,10 +334,9 @@ void maybe_sigio_broken(int fd, int read)
+
+ sigio_lock();
+ err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1);
+- if(err){
+- printk("maybe_sigio_broken - failed to add pollfd\n");
++ if(err)
+ goto out;
+- }
++
+ all_sigio_fds.poll[all_sigio_fds.used++] =
+ ((struct pollfd) { .fd = fd,
+ .events = read ? POLLIN : POLLOUT,
+diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
+index b3c11cf..9383e87 100644
+--- a/arch/um/os-Linux/skas/mem.c
++++ b/arch/um/os-Linux/skas/mem.c
+@@ -48,7 +48,7 @@ int multi_op_count = 0;
+ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
+ {
+ unsigned long regs[MAX_REG_NR];
+- int n;
++ int n, i;
+ long ret, offset;
+ unsigned long * data;
+ unsigned long * syscall;
+@@ -66,9 +66,13 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
+ (unsigned long) &__syscall_stub_start);
+
+ n = ptrace_setregs(pid, regs);
+- if(n < 0)
++ if(n < 0){
++ printk("Registers - \n");
++ for(i = 0; i < MAX_REG_NR; i++)
++ printk("\t%d\t0x%lx\n", i, regs[i]);
+ panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n",
+- n);
++ -n);
++ }
+
+ wait_stub_done(pid, 0, "do_syscall_stub");
+
+diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
+index 9b34fe6..c4998cf 100644
+--- a/arch/um/os-Linux/skas/process.c
++++ b/arch/um/os-Linux/skas/process.c
+@@ -67,7 +67,7 @@ void wait_stub_done(int pid, int sig, char * fname)
+
+ if((n < 0) || !WIFSTOPPED(status) ||
+ (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){
+- unsigned long regs[HOST_FRAME_SIZE];
++ unsigned long regs[MAX_REG_NR];
+
+ if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
+ printk("Failed to get registers from stub, "
+@@ -76,7 +76,7 @@ void wait_stub_done(int pid, int sig, char * fname)
+ int i;
+
+ printk("Stub registers -\n");
+- for(i = 0; i < HOST_FRAME_SIZE; i++)
++ for(i = 0; i < ARRAY_SIZE(regs); i++)
+ printk("\t%d - %lx\n", i, regs[i]);
+ }
+ panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
+@@ -328,7 +328,7 @@ void userspace(union uml_pt_regs *regs)
+ int copy_context_skas0(unsigned long new_stack, int pid)
+ {
+ int err;
+- unsigned long regs[HOST_FRAME_SIZE];
++ unsigned long regs[MAX_REG_NR];
+ unsigned long fp_regs[HOST_FP_SIZE];
+ unsigned long current_stack = current_stub_stack();
+ struct stub_data *data = (struct stub_data *) current_stack;
+diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
+index 7cd0369..ecd21e0 100644
+--- a/arch/um/os-Linux/sys-i386/registers.c
++++ b/arch/um/os-Linux/sys-i386/registers.c
+@@ -15,7 +15,7 @@
+
+ /* These are set once at boot time and not changed thereafter */
+
+-static unsigned long exec_regs[HOST_FRAME_SIZE];
++static unsigned long exec_regs[MAX_REG_NR];
+ static unsigned long exec_fp_regs[HOST_FP_SIZE];
+ static unsigned long exec_fpx_regs[HOST_XFP_SIZE];
+ static int have_fpx_regs = 1;
+@@ -101,6 +101,7 @@ void init_registers(int pid)
+ {
+ int err;
+
++ memset(exec_regs, 0, sizeof(exec_regs));
+ err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
+ if(err)
+ panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
+@@ -124,7 +125,7 @@ void init_registers(int pid)
+
+ void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
+ {
+- memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
++ memcpy(regs, exec_regs, sizeof(exec_regs));
+ if(fp_regs != NULL)
+ memcpy(fp_regs, exec_fp_regs,
+ HOST_FP_SIZE * sizeof(unsigned long));
+diff --git a/arch/um/os-Linux/sys-x86_64/Makefile b/arch/um/os-Linux/sys-x86_64/Makefile
+index f67842a..7955e06 100644
+--- a/arch/um/os-Linux/sys-x86_64/Makefile
++++ b/arch/um/os-Linux/sys-x86_64/Makefile
+@@ -3,7 +3,7 @@
+ # Licensed under the GPL
+ #
+
+-obj-$(CONFIG_MODE_SKAS) = registers.o signal.o
++obj-$(CONFIG_MODE_SKAS) = registers.o prctl.o signal.o
+
+ USER_OBJS := $(obj-y)
+
+diff --git a/arch/um/os-Linux/sys-x86_64/prctl.c b/arch/um/os-Linux/sys-x86_64/prctl.c
+new file mode 100644
+index 0000000..79c278a
+--- /dev/null
++++ b/arch/um/os-Linux/sys-x86_64/prctl.c
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2007 Jeff Dike (jdike@{addtoit.com,linux.intel.com})
++ * Licensed under the GPL
++ */
++
++#include <sys/ptrace.h>
++#include <linux/ptrace.h>
++
++int os_arch_prctl(int pid, int code, unsigned long *addr)
++{
++ return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) addr, code);
++}
+diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c
+index cb8e8a2..019f6c4 100644
+--- a/arch/um/os-Linux/sys-x86_64/registers.c
++++ b/arch/um/os-Linux/sys-x86_64/registers.c
+@@ -14,7 +14,7 @@
+
+ /* These are set once at boot time and not changed thereafter */
+
+-static unsigned long exec_regs[HOST_FRAME_SIZE];
++static unsigned long exec_regs[MAX_REG_NR];
+ static unsigned long exec_fp_regs[HOST_FP_SIZE];
+
+ void init_thread_registers(union uml_pt_regs *to)
+@@ -72,7 +72,7 @@ void init_registers(int pid)
+
+ void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
+ {
+- memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
++ memcpy(regs, exec_regs, sizeof(exec_regs));
+ if(fp_regs != NULL)
+ memcpy(fp_regs, exec_fp_regs,
+ HOST_FP_SIZE * sizeof(unsigned long));
+diff --git a/arch/um/sys-i386/delay.c b/arch/um/sys-i386/delay.c
+index 2c11b97..d623e07 100644
+--- a/arch/um/sys-i386/delay.c
++++ b/arch/um/sys-i386/delay.c
+@@ -27,14 +27,3 @@ void __udelay(unsigned long usecs)
+ }
+
+ EXPORT_SYMBOL(__udelay);
+-
+-void __const_udelay(unsigned long usecs)
+-{
+- int i, n;
+-
+- n = (loops_per_jiffy * HZ * usecs) / MILLION;
+- for(i=0;i<n;i++)
+- cpu_relax();
+-}
+-
+-EXPORT_SYMBOL(__const_udelay);
+diff --git a/arch/um/sys-x86_64/delay.c b/arch/um/sys-x86_64/delay.c
+index 137f444..dee5be6 100644
+--- a/arch/um/sys-x86_64/delay.c
++++ b/arch/um/sys-x86_64/delay.c
+@@ -28,14 +28,3 @@ void __udelay(unsigned long usecs)
+ }
+
+ EXPORT_SYMBOL(__udelay);
+-
+-void __const_udelay(unsigned long usecs)
+-{
+- unsigned long i, n;
+-
+- n = (loops_per_jiffy * HZ * usecs) / MILLION;
+- for(i=0;i<n;i++)
+- cpu_relax();
+-}
+-
+-EXPORT_SYMBOL(__const_udelay);
+diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
+index 73ce446..6d5605b 100644
+--- a/arch/um/sys-x86_64/syscalls.c
++++ b/arch/um/sys-x86_64/syscalls.c
+@@ -16,6 +16,7 @@
+ #include "asm/prctl.h" /* XXX This should get the constants from libc */
+ #include "choose-mode.h"
+ #include "kern.h"
++#include "os.h"
+
+ asmlinkage long sys_uname64(struct new_utsname __user * name)
+ {
+@@ -58,40 +59,70 @@ static long arch_prctl_tt(int code, unsigned long addr)
+
+ #ifdef CONFIG_MODE_SKAS
+
+-/* XXX: Must also call arch_prctl in the host, beside saving the segment bases! */
+-static long arch_prctl_skas(int code, unsigned long addr)
++static long arch_prctl_skas(int code, unsigned long __user *addr)
+ {
+- long ret = 0;
++ unsigned long *ptr = addr, tmp;
++ long ret;
++ int pid = current->mm->context.skas.id.u.pid;
++
++ /*
++ * With ARCH_SET_FS (and ARCH_SET_GS is treated similarly to
++ * be safe), we need to call arch_prctl on the host because
++ * setting %fs may result in something else happening (like a
++ * GDT being set instead). So, we let the host fiddle the
++ * registers and restore them afterwards.
++ *
++ * So, the saved registers are stored to the process (this
++ * needed because a stub may have been the last thing to run),
++ * arch_prctl is run on the host, then the registers are read
++ * back.
++ */
++ switch(code){
++ case ARCH_SET_FS:
++ case ARCH_SET_GS:
++ restore_registers(pid, &current->thread.regs.regs);
++ break;
++ case ARCH_GET_FS:
++ case ARCH_GET_GS:
++ /*
++ * With these two, we read to a local pointer and
++ * put_user it to the userspace pointer that we were
++ * given. If addr isn't valid (because it hasn't been
++ * faulted in or is just bogus), we want put_user to
++ * fault it in (or return -EFAULT) instead of having
++ * the host return -EFAULT.
++ */
++ ptr = &tmp;
++ }
++
++ ret = os_arch_prctl(pid, code, ptr);
++ if(ret)
++ return ret;
+
+ switch(code){
+ case ARCH_SET_FS:
+- current->thread.regs.regs.skas.regs[FS_BASE / sizeof(unsigned long)] = addr;
++ current->thread.arch.fs = (unsigned long) ptr;
++ save_registers(pid, &current->thread.regs.regs);
+ break;
+ case ARCH_SET_GS:
+- current->thread.regs.regs.skas.regs[GS_BASE / sizeof(unsigned long)] = addr;
++ save_registers(pid, &current->thread.regs.regs);
+ break;
+ case ARCH_GET_FS:
+- ret = put_user(current->thread.regs.regs.skas.
+- regs[FS_BASE / sizeof(unsigned long)],
+- (unsigned long __user *)addr);
+- break;
++ ret = put_user(tmp, addr);
++ break;
+ case ARCH_GET_GS:
+- ret = put_user(current->thread.regs.regs.skas.
+- regs[GS_BASE / sizeof(unsigned long)],
+- (unsigned long __user *)addr);
+- break;
+- default:
+- ret = -EINVAL;
++ ret = put_user(tmp, addr);
+ break;
+ }
+
+- return(ret);
++ return ret;
+ }
+ #endif
+
+ long sys_arch_prctl(int code, unsigned long addr)
+ {
+- return(CHOOSE_MODE_PROC(arch_prctl_tt, arch_prctl_skas, code, addr));
++ return CHOOSE_MODE_PROC(arch_prctl_tt, arch_prctl_skas, code,
++ (unsigned long __user *) addr);
+ }
+
+ long sys_clone(unsigned long clone_flags, unsigned long newsp,
+@@ -105,5 +136,14 @@ long sys_clone(unsigned long clone_flags, unsigned long newsp,
+ ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
+ child_tid);
+ current->thread.forking = 0;
+- return(ret);
++ return ret;
+ }
++
++void arch_switch_to_skas(struct task_struct *from, struct task_struct *to)
++{
++ if((to->thread.arch.fs == 0) || (to->mm == NULL))
++ return;
++
++ arch_prctl_skas(ARCH_SET_FS, (void __user *) to->thread.arch.fs);
++}
++
+diff --git a/arch/um/sys-x86_64/tls.c b/arch/um/sys-x86_64/tls.c
+index ce1bf1b..febbc94 100644
+--- a/arch/um/sys-x86_64/tls.c
++++ b/arch/um/sys-x86_64/tls.c
+@@ -1,14 +1,17 @@
+ #include "linux/sched.h"
+
+-void debug_arch_force_load_TLS(void)
+-{
+-}
+-
+ void clear_flushed_tls(struct task_struct *task)
+ {
+ }
+
+ int arch_copy_tls(struct task_struct *t)
+ {
++ /*
++ * If CLONE_SETTLS is set, we need to save the thread id
++ * (which is argument 5, child_tid, of clone) so it can be set
++ * during context switches.
++ */
++ t->thread.arch.fs = t->thread.regs.regs.skas.regs[R8 / sizeof(long)];
++
+ return 0;
+ }
+diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
+index ff499ef..c7beadf 100644
+--- a/arch/x86_64/ia32/ia32_signal.c
++++ b/arch/x86_64/ia32/ia32_signal.c
+@@ -21,6 +21,7 @@
+ #include <linux/stddef.h>
+ #include <linux/personality.h>
+ #include <linux/compat.h>
++#include <linux/binfmts.h>
+ #include <asm/ucontext.h>
+ #include <asm/uaccess.h>
+ #include <asm/i387.h>
+@@ -449,7 +450,11 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
+
+ /* Return stub is in 32bit vsyscall page */
+ {
+- void __user *restorer = VSYSCALL32_SIGRETURN;
++ void __user *restorer;
++ if (current->binfmt->hasvdso)
++ restorer = VSYSCALL32_SIGRETURN;
++ else
++ restorer = (void *)&frame->retcode;
+ if (ka->sa.sa_flags & SA_RESTORER)
+ restorer = ka->sa.sa_restorer;
+ err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
+diff --git a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c
+index 04566fe..4de3a54 100644
+--- a/arch/x86_64/ia32/ptrace32.c
++++ b/arch/x86_64/ia32/ptrace32.c
+@@ -243,6 +243,7 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
+ case PTRACE_SINGLESTEP:
+ case PTRACE_DETACH:
+ case PTRACE_SYSCALL:
++ case PTRACE_OLDSETOPTIONS:
+ case PTRACE_SETOPTIONS:
+ case PTRACE_SET_THREAD_AREA:
+ case PTRACE_GET_THREAD_AREA:
+diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c
+index 0c06af6..3bc30d2 100644
+--- a/arch/x86_64/kernel/irq.c
++++ b/arch/x86_64/kernel/irq.c
+@@ -18,6 +18,7 @@
+ #include <asm/uaccess.h>
+ #include <asm/io_apic.h>
+ #include <asm/idle.h>
++#include <asm/smp.h>
+
+ atomic_t irq_err_count;
+
+@@ -120,9 +121,14 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
+
+ if (likely(irq < NR_IRQS))
+ generic_handle_irq(irq);
+- else if (printk_ratelimit())
+- printk(KERN_EMERG "%s: %d.%d No irq handler for vector\n",
+- __func__, smp_processor_id(), vector);
++ else {
++ if (!disable_apic)
++ ack_APIC_irq();
++
++ if (printk_ratelimit())
++ printk(KERN_EMERG "%s: %d.%d No irq handler for vector\n",
++ __func__, smp_processor_id(), vector);
++ }
+
+ irq_exit();
+
+diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
+index fb67897..38c293b 100644
+--- a/block/ll_rw_blk.c
++++ b/block/ll_rw_blk.c
+@@ -1264,7 +1264,7 @@ new_hw_segment:
+ bio->bi_hw_segments = nr_hw_segs;
+ bio->bi_flags |= (1 << BIO_SEG_VALID);
+ }
+-
++EXPORT_SYMBOL(blk_recount_segments);
+
+ static int blk_phys_contig_segment(request_queue_t *q, struct bio *bio,
+ struct bio *nxt)
+diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
+index 35172d3..0f76175 100644
+--- a/crypto/scatterwalk.c
++++ b/crypto/scatterwalk.c
+@@ -91,6 +91,8 @@ void scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
+ memcpy_dir(buf, vaddr, len_this_page, out);
+ scatterwalk_unmap(vaddr, out);
+
++ scatterwalk_advance(walk, len_this_page);
++
+ if (nbytes == len_this_page)
+ break;
+
+@@ -99,7 +101,5 @@ void scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
+
+ scatterwalk_pagedone(walk, out, 1);
+ }
+-
+- scatterwalk_advance(walk, nbytes);
+ }
+ EXPORT_SYMBOL_GPL(scatterwalk_copychunks);
+diff --git a/drivers/Makefile b/drivers/Makefile
+index 0dd96d1..f28dcb4 100644
+--- a/drivers/Makefile
++++ b/drivers/Makefile
+@@ -30,7 +30,7 @@ obj-$(CONFIG_PARPORT) += parport/
+ obj-y += base/ block/ misc/ mfd/ net/ media/
+ obj-$(CONFIG_NUBUS) += nubus/
+ obj-$(CONFIG_ATM) += atm/
+-obj-$(CONFIG_PPC_PMAC) += macintosh/
++obj-y += macintosh/
+ obj-$(CONFIG_IDE) += ide/
+ obj-$(CONFIG_FC4) += fc4/
+ obj-$(CONFIG_SCSI) += scsi/
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index 48616c6..21fb66f 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -82,6 +82,7 @@ enum {
+ board_ahci_pi = 1,
+ board_ahci_vt8251 = 2,
+ board_ahci_ign_iferr = 3,
++ board_ahci_sb600 = 4,
+
+ /* global controller registers */
+ HOST_CAP = 0x00, /* host capabilities */
+@@ -173,6 +174,7 @@ enum {
+ AHCI_FLAG_NO_NCQ = (1 << 24),
+ AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore IRQ_IF_ERR */
+ AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */
++ AHCI_FLAG_IGN_SERR_INTERNAL = (1 << 27), /* ignore SERR_INTERNAL */
+ };
+
+ struct ahci_cmd_hdr {
+@@ -225,10 +227,12 @@ static void ahci_thaw(struct ata_port *ap);
+ static void ahci_error_handler(struct ata_port *ap);
+ static void ahci_vt8251_error_handler(struct ata_port *ap);
+ static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
++#ifdef CONFIG_PM
+ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg);
+ static int ahci_port_resume(struct ata_port *ap);
+ static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
+ static int ahci_pci_device_resume(struct pci_dev *pdev);
++#endif
+ static void ahci_remove_one (struct pci_dev *pdev);
+
+ static struct scsi_host_template ahci_sht = {
+@@ -248,8 +252,10 @@ static struct scsi_host_template ahci_sht = {
+ .slave_configure = ata_scsi_slave_config,
+ .slave_destroy = ata_scsi_slave_destroy,
+ .bios_param = ata_std_bios_param,
++#ifdef CONFIG_PM
+ .suspend = ata_scsi_device_suspend,
+ .resume = ata_scsi_device_resume,
++#endif
+ };
+
+ static const struct ata_port_operations ahci_ops = {
+@@ -276,8 +282,10 @@ static const struct ata_port_operations ahci_ops = {
+ .error_handler = ahci_error_handler,
+ .post_internal_cmd = ahci_post_internal_cmd,
+
++#ifdef CONFIG_PM
+ .port_suspend = ahci_port_suspend,
+ .port_resume = ahci_port_resume,
++#endif
+
+ .port_start = ahci_port_start,
+ .port_stop = ahci_port_stop,
+@@ -307,8 +315,10 @@ static const struct ata_port_operations ahci_vt8251_ops = {
+ .error_handler = ahci_vt8251_error_handler,
+ .post_internal_cmd = ahci_post_internal_cmd,
+
++#ifdef CONFIG_PM
+ .port_suspend = ahci_port_suspend,
+ .port_resume = ahci_port_resume,
++#endif
+
+ .port_start = ahci_port_start,
+ .port_stop = ahci_port_stop,
+@@ -357,6 +367,18 @@ static const struct ata_port_info ahci_port_info[] = {
+ .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .port_ops = &ahci_ops,
+ },
++ /* board_ahci_sb600 */
++ {
++ .sht = &ahci_sht,
++ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
++ ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
++ ATA_FLAG_SKIP_D2H_BSY |
++ AHCI_FLAG_IGN_SERR_INTERNAL,
++ .pio_mask = 0x1f, /* pio0-4 */
++ .udma_mask = 0x7f, /* udma0-6 ; FIXME */
++ .port_ops = &ahci_ops,
++ },
++
+ };
+
+ static const struct pci_device_id ahci_pci_tbl[] = {
+@@ -396,7 +418,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
+ { PCI_VDEVICE(JMICRON, 0x2366), board_ahci_ign_iferr }, /* JMB366 */
+
+ /* ATI */
+- { PCI_VDEVICE(ATI, 0x4380), board_ahci }, /* ATI SB600 non-raid */
++ { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 non-raid */
+ { PCI_VDEVICE(ATI, 0x4381), board_ahci }, /* ATI SB600 raid */
+
+ /* VIA */
+@@ -441,8 +463,10 @@ static struct pci_driver ahci_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = ahci_pci_tbl,
+ .probe = ahci_init_one,
++#ifdef CONFIG_PM
+ .suspend = ahci_pci_device_suspend,
+ .resume = ahci_pci_device_resume,
++#endif
+ .remove = ahci_remove_one,
+ };
+
+@@ -587,6 +611,7 @@ static void ahci_power_up(void __iomem *port_mmio, u32 cap)
+ writel(cmd | PORT_CMD_ICC_ACTIVE, port_mmio + PORT_CMD);
+ }
+
++#ifdef CONFIG_PM
+ static void ahci_power_down(void __iomem *port_mmio, u32 cap)
+ {
+ u32 cmd, scontrol;
+@@ -604,6 +629,7 @@ static void ahci_power_down(void __iomem *port_mmio, u32 cap)
+ cmd &= ~PORT_CMD_SPIN_UP;
+ writel(cmd, port_mmio + PORT_CMD);
+ }
++#endif
+
+ static void ahci_init_port(void __iomem *port_mmio, u32 cap,
+ dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma)
+@@ -1064,8 +1090,11 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
+ if (ap->flags & AHCI_FLAG_IGN_IRQ_IF_ERR)
+ irq_stat &= ~PORT_IRQ_IF_ERR;
+
+- if (irq_stat & PORT_IRQ_TF_ERR)
++ if (irq_stat & PORT_IRQ_TF_ERR) {
+ err_mask |= AC_ERR_DEV;
++ if (ap->flags & AHCI_FLAG_IGN_SERR_INTERNAL)
++ serror &= ~SERR_INTERNAL;
++ }
+
+ if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) {
+ err_mask |= AC_ERR_HOST_BUS;
+@@ -1336,6 +1365,7 @@ static void ahci_post_internal_cmd(struct ata_queued_cmd *qc)
+ }
+ }
+
++#ifdef CONFIG_PM
+ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
+ {
+ struct ahci_host_priv *hpriv = ap->host->private_data;
+@@ -1412,6 +1442,7 @@ static int ahci_pci_device_resume(struct pci_dev *pdev)
+
+ return 0;
+ }
++#endif
+
+ static int ahci_port_start(struct ata_port *ap)
+ {
+diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c
+index 24af560..91ccc20 100644
+--- a/drivers/ata/ata_generic.c
++++ b/drivers/ata/ata_generic.c
+@@ -119,8 +119,10 @@ static struct scsi_host_template generic_sht = {
+ .slave_configure = ata_scsi_slave_config,
+ .slave_destroy = ata_scsi_slave_destroy,
+ .bios_param = ata_std_bios_param,
++#ifdef CONFIG_PM
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
++#endif
+ };
+
+ static struct ata_port_operations generic_port_ops = {
+@@ -230,8 +232,10 @@ static struct pci_driver ata_generic_pci_driver = {