aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorTony Luck <tony.luck@intel.com>2005-06-15 17:06:48 -0400
committerTony Luck <tony.luck@intel.com>2005-06-15 17:06:48 -0400
commitf2cbb4f01936a3e4225692e03b084b78c56d386d (patch)
treef89f3d8baa250589a38a4dd2df56f84cddae3c76 /arch
parent325a479c4c110db278ef3361460a48c4093252cc (diff)
parent1016888fb69662936b32ab767c7419a3be9a69d3 (diff)
Auto merge with /home/aegl/GIT/linus
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/Kconfig4
-rw-r--r--arch/alpha/kernel/osf_sys.c7
-rw-r--r--arch/arm/Kconfig28
-rw-r--r--arch/arm/boot/compressed/head-xscale.S7
-rw-r--r--arch/arm/configs/badge4_defconfig29
-rw-r--r--arch/arm/configs/h3600_defconfig24
-rw-r--r--arch/arm/configs/hackkit_defconfig22
-rw-r--r--arch/arm/kernel/entry-armv.S30
-rw-r--r--arch/arm/kernel/head.S3
-rw-r--r--arch/arm/kernel/process.c25
-rw-r--r--arch/arm/kernel/sys_arm.c2
-rw-r--r--arch/arm/kernel/traps.c63
-rw-r--r--arch/arm/kernel/vmlinux.lds.S3
-rw-r--r--arch/arm/lib/io-writesw-armv4.S6
-rw-r--r--arch/arm/mach-clps711x/Kconfig3
-rw-r--r--arch/arm/mach-footbridge/Kconfig12
-rw-r--r--arch/arm/mach-imx/Kconfig1
-rw-r--r--arch/arm/mach-ixp4xx/common-pci.c10
-rw-r--r--arch/arm/mach-pxa/mainstone.c9
-rw-r--r--arch/arm/mach-pxa/pm.c32
-rw-r--r--arch/arm/mach-pxa/pxa25x.c33
-rw-r--r--arch/arm/mach-pxa/pxa27x.c36
-rw-r--r--arch/arm/mach-s3c2410/clock.c2
-rw-r--r--arch/arm/mach-s3c2410/dma.c4
-rw-r--r--arch/arm/mach-s3c2410/s3c2440.c6
-rw-r--r--arch/arm/mach-sa1100/Kconfig2
-rw-r--r--arch/arm/mm/Kconfig38
-rw-r--r--arch/arm/mm/Makefile2
-rw-r--r--arch/arm/mm/copypage-v4mc.S80
-rw-r--r--arch/arm/mm/copypage-v4mc.c111
-rw-r--r--arch/arm/mm/copypage-v6.c28
-rw-r--r--arch/arm/mm/copypage-xscale.S113
-rw-r--r--arch/arm/mm/copypage-xscale.c131
-rw-r--r--arch/arm/mm/flush.c37
-rw-r--r--arch/arm/mm/minicache.c73
-rw-r--r--arch/arm/mm/mm-armv.c27
-rw-r--r--arch/arm26/Kconfig4
-rw-r--r--arch/h8300/kernel/process.c2
-rw-r--r--arch/i386/Kconfig26
-rw-r--r--arch/i386/Makefile6
-rw-r--r--arch/i386/boot/bootsect.S2
-rw-r--r--arch/i386/boot/video.S18
-rw-r--r--arch/i386/kernel/Makefile2
-rw-r--r--arch/i386/kernel/acpi/boot.c2
-rw-r--r--arch/i386/kernel/apm.c2
-rw-r--r--arch/i386/kernel/cpu/amd.c12
-rw-r--r--arch/i386/kernel/cpu/common.c4
-rw-r--r--arch/i386/kernel/cpu/cpufreq/Kconfig14
-rw-r--r--arch/i386/kernel/cpu/cpufreq/Makefile1
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longhaul.c58
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k7.c11
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k8.c113
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k8.h15
-rw-r--r--arch/i386/kernel/cpu/cpufreq/sc520_freq.c186
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c6
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-lib.c6
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-smi.c3
-rw-r--r--arch/i386/kernel/cpu/intel_cacheinfo.c2
-rw-r--r--arch/i386/kernel/cpu/mtrr/cyrix.c4
-rw-r--r--arch/i386/kernel/i386_ksyms.c4
-rw-r--r--arch/i386/kernel/kprobes.c7
-rw-r--r--arch/i386/kernel/process.c13
-rw-r--r--arch/i386/kernel/ptrace.c19
-rw-r--r--arch/i386/kernel/setup.c2
-rw-r--r--arch/i386/kernel/smpboot.c5
-rw-r--r--arch/i386/kernel/timers/common.c6
-rw-r--r--arch/i386/kernel/timers/timer_tsc.c20
-rw-r--r--arch/i386/mach-voyager/voyager_smp.c17
-rw-r--r--arch/i386/mm/ioremap.c10
-rw-r--r--arch/i386/pci/fixup.c2
-rw-r--r--arch/i386/pci/irq.c5
-rw-r--r--arch/ia64/Kconfig23
-rw-r--r--arch/ia64/configs/tiger_defconfig96
-rw-r--r--arch/ia64/hp/common/sba_iommu.c34
-rw-r--r--arch/ia64/ia32/ia32_ioctl.c1
-rw-r--r--arch/ia64/ia32/sys_ia32.c2
-rw-r--r--arch/ia64/kernel/acpi.c23
-rw-r--r--arch/ia64/kernel/entry.S6
-rw-r--r--arch/ia64/kernel/fsys.S4
-rw-r--r--arch/ia64/kernel/mca.c8
-rw-r--r--arch/ia64/kernel/mca_drv.c4
-rw-r--r--arch/ia64/kernel/mca_drv_asm.S18
-rw-r--r--arch/ia64/kernel/minstate.h3
-rw-r--r--arch/ia64/kernel/module.c10
-rw-r--r--arch/ia64/kernel/perfmon.c218
-rw-r--r--arch/ia64/kernel/process.c55
-rw-r--r--arch/ia64/kernel/ptrace.c47
-rw-r--r--arch/ia64/kernel/setup.c3
-rw-r--r--arch/ia64/kernel/signal.c3
-rw-r--r--arch/ia64/kernel/smpboot.c2
-rw-r--r--arch/ia64/kernel/sys_ia64.c7
-rw-r--r--arch/ia64/kernel/traps.c29
-rw-r--r--arch/ia64/lib/flush.S6
-rw-r--r--arch/ia64/lib/memcpy_mck.S2
-rw-r--r--arch/ia64/lib/memset.S2
-rw-r--r--arch/ia64/mm/init.c19
-rw-r--r--arch/ia64/sn/kernel/Makefile7
-rw-r--r--arch/ia64/sn/kernel/io_init.c10
-rw-r--r--arch/ia64/sn/kernel/mca.c34
-rw-r--r--arch/ia64/sn/kernel/setup.c46
-rw-r--r--arch/ia64/sn/kernel/tiocx.c60
-rw-r--r--arch/ia64/sn/kernel/xp_main.c289
-rw-r--r--arch/ia64/sn/kernel/xp_nofault.S31
-rw-r--r--arch/ia64/sn/kernel/xpc.h991
-rw-r--r--arch/ia64/sn/kernel/xpc_channel.c2297
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c1064
-rw-r--r--arch/ia64/sn/kernel/xpc_partition.c984
-rw-r--r--arch/ia64/sn/kernel/xpnet.c715
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_dma.c2
-rw-r--r--arch/ia64/sn/pci/tioca_provider.c2
-rw-r--r--arch/m68k/configs/amiga_defconfig15
-rw-r--r--arch/m68k/configs/apollo_defconfig7
-rw-r--r--arch/m68k/configs/atari_defconfig7
-rw-r--r--arch/m68k/configs/bvme6000_defconfig7
-rw-r--r--arch/m68k/configs/hp300_defconfig7
-rw-r--r--arch/m68k/configs/mac_defconfig7
-rw-r--r--arch/m68k/configs/mvme147_defconfig7
-rw-r--r--arch/m68k/configs/mvme16x_defconfig7
-rw-r--r--arch/m68k/configs/q40_defconfig15
-rw-r--r--arch/m68k/configs/sun3_defconfig8
-rw-r--r--arch/m68k/configs/sun3x_defconfig7
-rw-r--r--arch/m68k/defconfig7
-rw-r--r--arch/m68knommu/Kconfig5
-rw-r--r--arch/m68knommu/kernel/process.c17
-rw-r--r--arch/mips/Kconfig4
-rw-r--r--arch/mips/kernel/ptrace.c38
-rw-r--r--arch/mips/vr41xx/common/pmu.c55
-rw-r--r--arch/parisc/Kconfig4
-rw-r--r--arch/ppc/Kconfig14
-rw-r--r--arch/ppc/boot/images/Makefile3
-rw-r--r--arch/ppc/configs/mpc8555_cds_defconfig117
-rw-r--r--arch/ppc/kernel/cputable.c11
-rw-r--r--arch/ppc/kernel/head_44x.S15
-rw-r--r--arch/ppc/kernel/head_fsl_booke.S15
-rw-r--r--arch/ppc/kernel/misc.S6
-rw-r--r--arch/ppc/kernel/setup.c41
-rw-r--r--arch/ppc/kernel/traps.c7
-rw-r--r--arch/ppc/kernel/vmlinux.lds.S2
-rw-r--r--arch/ppc/lib/string.S7
-rw-r--r--arch/ppc/mm/init.c1
-rw-r--r--arch/ppc/platforms/83xx/mpc834x_sys.c1
-rw-r--r--arch/ppc/platforms/83xx/mpc834x_sys.h7
-rw-r--r--arch/ppc/platforms/85xx/mpc8540_ads.c3
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_cds_common.c143
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_cds_common.h3
-rw-r--r--arch/ppc/platforms/85xx/sbc8560.c3
-rw-r--r--arch/ppc/platforms/pmac_cpufreq.c43
-rw-r--r--arch/ppc/platforms/pq2ads.h41
-rw-r--r--arch/ppc/syslib/Makefile4
-rw-r--r--arch/ppc/syslib/ipic.c2
-rw-r--r--arch/ppc/syslib/m8260_pci.c193
-rw-r--r--arch/ppc/syslib/m8260_pci.h76
-rw-r--r--arch/ppc/syslib/m8260_pci_erratum9.c10
-rw-r--r--arch/ppc/syslib/m8260_setup.c11
-rw-r--r--arch/ppc/syslib/m82xx_pci.c383
-rw-r--r--arch/ppc/syslib/m82xx_pci.h92
-rw-r--r--arch/ppc/syslib/mpc83xx_devices.c1
-rw-r--r--arch/ppc/syslib/mpc85xx_devices.c1
-rw-r--r--arch/ppc/syslib/open_pic.c6
-rw-r--r--arch/ppc/syslib/ppc83xx_setup.c28
-rw-r--r--arch/ppc/syslib/ppc85xx_setup.c16
-rw-r--r--arch/ppc/syslib/prom_init.c10
-rw-r--r--arch/ppc64/Kconfig8
-rw-r--r--arch/ppc64/Kconfig.debug3
-rw-r--r--arch/ppc64/boot/main.c1
-rw-r--r--arch/ppc64/boot/prom.c28
-rw-r--r--arch/ppc64/boot/start.c654
-rw-r--r--arch/ppc64/configs/g5_defconfig76
-rw-r--r--arch/ppc64/configs/iSeries_defconfig62
-rw-r--r--arch/ppc64/configs/maple_defconfig70
-rw-r--r--arch/ppc64/configs/pSeries_defconfig102
-rw-r--r--arch/ppc64/defconfig104
-rw-r--r--arch/ppc64/kernel/entry.S9
-rw-r--r--arch/ppc64/kernel/head.S10
-rw-r--r--arch/ppc64/kernel/iSeries_setup.c22
-rw-r--r--arch/ppc64/kernel/idle.c8
-rw-r--r--arch/ppc64/kernel/kprobes.c18
-rw-r--r--arch/ppc64/kernel/mf.c85
-rw-r--r--arch/ppc64/kernel/misc.S4
-rw-r--r--arch/ppc64/kernel/pSeries_reconfig.c8
-rw-r--r--arch/ppc64/kernel/pSeries_smp.c7
-rw-r--r--arch/ppc64/kernel/pci.c2
-rw-r--r--arch/ppc64/kernel/pmac_smp.c28
-rw-r--r--arch/ppc64/kernel/process.c3
-rw-r--r--arch/ppc64/kernel/prom.c2
-rw-r--r--arch/ppc64/kernel/prom_init.c154
-rw-r--r--arch/ppc64/kernel/ptrace.c15
-rw-r--r--arch/ppc64/kernel/rtc.c39
-rw-r--r--arch/ppc64/kernel/setup.c56
-rw-r--r--arch/ppc64/kernel/signal.c6
-rw-r--r--arch/ppc64/kernel/smp.c3
-rw-r--r--arch/ppc64/kernel/sys_ppc32.c70
-rw-r--r--arch/ppc64/kernel/syscalls.c33
-rw-r--r--arch/ppc64/kernel/sysfs.c8
-rw-r--r--arch/ppc64/kernel/time.c3
-rw-r--r--arch/ppc64/kernel/xics.c16
-rw-r--r--arch/ppc64/mm/hash_native.c3
-rw-r--r--arch/ppc64/mm/hash_utils.c11
-rw-r--r--arch/ppc64/mm/imalloc.c5
-rw-r--r--arch/ppc64/mm/init.c3
-rw-r--r--arch/ppc64/mm/stab.c5
-rw-r--r--arch/s390/appldata/appldata_base.c72
-rw-r--r--arch/s390/appldata/appldata_mem.c2
-rw-r--r--arch/s390/appldata/appldata_net_sum.c2
-rw-r--r--arch/s390/appldata/appldata_os.c4
-rw-r--r--arch/s390/kernel/ptrace.c76
-rw-r--r--arch/s390/mm/fault.c2
-rw-r--r--arch/sh/Kconfig4
-rw-r--r--arch/sparc/kernel/process.c5
-rw-r--r--arch/sparc/prom/memory.c28
-rw-r--r--arch/sparc/prom/sun4prom.c2
-rw-r--r--arch/sparc64/kernel/irq.c6
-rw-r--r--arch/sparc64/kernel/pci_iommu.c221
-rw-r--r--arch/sparc64/kernel/pci_psycho.c2
-rw-r--r--arch/sparc64/kernel/pci_sabre.c2
-rw-r--r--arch/sparc64/kernel/pci_schizo.c2
-rw-r--r--arch/sparc64/kernel/process.c4
-rw-r--r--arch/sparc64/kernel/sbus.c41
-rw-r--r--arch/sparc64/kernel/setup.c11
-rw-r--r--arch/sparc64/kernel/smp.c3
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c2
-rw-r--r--arch/sparc64/kernel/traps.c19
-rw-r--r--arch/sparc64/mm/init.c2
-rw-r--r--arch/um/Kconfig.debug4
-rw-r--r--arch/um/Kconfig_char6
-rw-r--r--arch/um/Kconfig_x86_644
-rw-r--r--arch/um/Makefile80
-rw-r--r--arch/um/Makefile-i3864
-rw-r--r--arch/um/Makefile-x86_644
-rw-r--r--arch/um/drivers/Makefile6
-rw-r--r--arch/um/drivers/chan_kern.c22
-rw-r--r--arch/um/drivers/chan_user.c26
-rw-r--r--arch/um/drivers/line.c41
-rw-r--r--arch/um/drivers/mcast_kern.c4
-rw-r--r--arch/um/drivers/mcast_user.c47
-rw-r--r--arch/um/drivers/mmapper_kern.c24
-rw-r--r--arch/um/drivers/net_user.c2
-rw-r--r--arch/um/drivers/random.c16
-rw-r--r--arch/um/drivers/slip.h23
-rw-r--r--arch/um/drivers/slip_common.c54
-rw-r--r--arch/um/drivers/slip_common.h (renamed from arch/um/drivers/slip_proto.h)47
-rw-r--r--arch/um/drivers/slip_kern.c12
-rw-r--r--arch/um/drivers/slip_user.c152
-rw-r--r--arch/um/drivers/slirp.h26
-rw-r--r--arch/um/drivers/slirp_kern.c5
-rw-r--r--arch/um/drivers/slirp_user.c104
-rw-r--r--arch/um/drivers/ssl.c1
-rw-r--r--arch/um/drivers/stderr_console.c6
-rw-r--r--arch/um/drivers/stdio_console.c1
-rw-r--r--arch/um/drivers/ubd_kern.c303
-rw-r--r--arch/um/drivers/xterm_kern.c1
-rw-r--r--arch/um/include/2_5compat.h24
-rw-r--r--arch/um/include/common-offsets.h14
-rw-r--r--arch/um/include/kern_util.h7
-rw-r--r--arch/um/include/mconsole.h2
-rw-r--r--arch/um/include/net_user.h2
-rw-r--r--arch/um/include/os.h3
-rw-r--r--arch/um/include/skas_ptrace.h15
-rw-r--r--arch/um/include/sysdep-i386/checksum.h39
-rw-r--r--arch/um/include/sysdep-i386/faultinfo.h29
-rw-r--r--arch/um/include/sysdep-i386/ptrace.h26
-rw-r--r--arch/um/include/sysdep-i386/sigcontext.h19
-rw-r--r--arch/um/include/sysdep-i386/signal.h2
-rw-r--r--arch/um/include/sysdep-i386/skas_ptrace.h22
-rw-r--r--arch/um/include/sysdep-ia64/skas_ptrace.h22
-rw-r--r--arch/um/include/sysdep-ppc/skas_ptrace.h22
-rw-r--r--arch/um/include/sysdep-x86_64/checksum.h26
-rw-r--r--arch/um/include/sysdep-x86_64/faultinfo.h29
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace.h78
-rw-r--r--arch/um/include/sysdep-x86_64/sigcontext.h15
-rw-r--r--arch/um/include/sysdep-x86_64/signal.h2
-rw-r--r--arch/um/include/sysdep-x86_64/skas_ptrace.h22
-rw-r--r--arch/um/include/sysrq.h3
-rw-r--r--arch/um/include/user_util.h4
-rw-r--r--arch/um/kernel/Makefile14
-rw-r--r--arch/um/kernel/checksum.c36
-rw-r--r--arch/um/kernel/exec_kern.c1
-rw-r--r--arch/um/kernel/initrd.c (renamed from arch/um/kernel/initrd_kern.c)21
-rw-r--r--arch/um/kernel/initrd_user.c46
-rw-r--r--arch/um/kernel/irq.c1
-rw-r--r--arch/um/kernel/irq_user.c10
-rw-r--r--arch/um/kernel/ksyms.c4
-rw-r--r--arch/um/kernel/main.c42
-rw-r--r--arch/um/kernel/mem.c40
-rw-r--r--arch/um/kernel/process.c51
-rw-r--r--arch/um/kernel/process_kern.c56
-rw-r--r--arch/um/kernel/ptrace.c128
-rw-r--r--arch/um/kernel/sigio_user.c1
-rw-r--r--arch/um/kernel/skas/include/mode_kern-skas.h1
-rw-r--r--arch/um/kernel/skas/include/skas.h3
-rw-r--r--arch/um/kernel/skas/include/uaccess-skas.h4
-rw-r--r--arch/um/kernel/skas/process.c68
-rw-r--r--arch/um/kernel/skas/process_kern.c11
-rw-r--r--arch/um/kernel/skas/trap_user.c24
-rw-r--r--arch/um/kernel/skas/uaccess.c7
-rw-r--r--arch/um/kernel/skas/util/Makefile1
-rw-r--r--arch/um/kernel/skas/util/mk_ptregs-i386.c46
-rw-r--r--arch/um/kernel/skas/util/mk_ptregs-x86_64.c60
-rw-r--r--arch/um/kernel/syscall_kern.c1
-rw-r--r--arch/um/kernel/sysrq.c21
-rw-r--r--arch/um/kernel/time_kern.c18
-rw-r--r--arch/um/kernel/trap_kern.c64
-rw-r--r--arch/um/kernel/trap_user.c13
-rw-r--r--arch/um/kernel/tt/Makefile1
-rw-r--r--arch/um/kernel/tt/include/mode_kern-tt.h1
-rw-r--r--arch/um/kernel/tt/include/uaccess-tt.h4
-rw-r--r--arch/um/kernel/tt/ksyms.c1
-rw-r--r--arch/um/kernel/tt/mem.c8
-rw-r--r--arch/um/kernel/tt/process_kern.c26
-rw-r--r--arch/um/kernel/tt/syscall_user.c4
-rw-r--r--arch/um/kernel/tt/tracer.c8
-rw-r--r--arch/um/kernel/tt/trap_user.c6
-rw-r--r--arch/um/kernel/um_arch.c14
-rw-r--r--arch/um/kernel/uml.lds.S2
-rw-r--r--arch/um/kernel/vmlinux.lds.S6
-rw-r--r--arch/um/os-Linux/elf_aux.c6
-rw-r--r--arch/um/os-Linux/file.c2
-rw-r--r--arch/um/os-Linux/process.c5
-rw-r--r--arch/um/os-Linux/signal.c4
-rw-r--r--arch/um/os-Linux/util/Makefile2
-rw-r--r--arch/um/os-Linux/util/mk_user_constants.c10
-rw-r--r--arch/um/scripts/Makefile.rules25
-rw-r--r--arch/um/sys-i386/Makefile13
-rw-r--r--arch/um/sys-i386/checksum.S6
-rw-r--r--arch/um/sys-i386/delay.c26
-rw-r--r--arch/um/sys-i386/kernel-offsets.c25
-rw-r--r--arch/um/sys-i386/ksyms.c8
-rw-r--r--arch/um/sys-i386/ldt.c5
-rw-r--r--arch/um/sys-i386/ptrace.c40
-rw-r--r--arch/um/sys-i386/signal.c17
-rw-r--r--arch/um/sys-i386/sysrq.c80
-rw-r--r--arch/um/sys-i386/user-offsets.c69
-rw-r--r--arch/um/sys-i386/util/Makefile7
-rw-r--r--arch/um/sys-i386/util/mk_sc.c75
-rw-r--r--arch/um/sys-i386/util/mk_thread.c22
-rw-r--r--arch/um/sys-i386/util/mk_thread_kern.c22
-rw-r--r--arch/um/sys-i386/util/mk_thread_user.c30
-rw-r--r--arch/um/sys-ppc/ptrace.c40
-rw-r--r--arch/um/sys-ppc/sysrq.c14
-rw-r--r--arch/um/sys-x86_64/Makefile22
-rw-r--r--arch/um/sys-x86_64/delay.c39
-rw-r--r--arch/um/sys-x86_64/kernel-offsets.c24
-rw-r--r--arch/um/sys-x86_64/ksyms.c19
-rw-r--r--arch/um/sys-x86_64/ptrace.c53
-rw-r--r--arch/um/sys-x86_64/signal.c12
-rw-r--r--arch/um/sys-x86_64/syscalls.c21
-rw-r--r--arch/um/sys-x86_64/sysrq.c11
-rw-r--r--arch/um/sys-x86_64/um_module.c19
-rw-r--r--arch/um/sys-x86_64/user-offsets.c86
-rw-r--r--arch/um/sys-x86_64/util/Makefile6
-rw-r--r--arch/um/sys-x86_64/util/mk_sc.c79
-rw-r--r--arch/um/sys-x86_64/util/mk_thread.c20
-rw-r--r--arch/um/sys-x86_64/util/mk_thread_kern.c21
-rw-r--r--arch/um/sys-x86_64/util/mk_thread_user.c30
-rw-r--r--arch/um/util/Makefile7
-rw-r--r--arch/um/util/mk_constants.c32
-rw-r--r--arch/um/util/mk_constants_kern.c28
-rw-r--r--arch/um/util/mk_constants_user.c28
-rw-r--r--arch/um/util/mk_task.c (renamed from arch/um/util/mk_task_user.c)18
-rw-r--r--arch/um/util/mk_task_kern.c17
-rw-r--r--arch/x86_64/Kconfig22
-rw-r--r--arch/x86_64/boot/bootsect.S4
-rw-r--r--arch/x86_64/defconfig58
-rw-r--r--arch/x86_64/kernel/Makefile1
-rw-r--r--arch/x86_64/kernel/aperture.c41
-rw-r--r--arch/x86_64/kernel/apic.c5
-rw-r--r--arch/x86_64/kernel/entry.S11
-rw-r--r--arch/x86_64/kernel/io_apic.c82
-rw-r--r--arch/x86_64/kernel/kprobes.c7
-rw-r--r--arch/x86_64/kernel/module.c4
-rw-r--r--arch/x86_64/kernel/mpparse.c23
-rw-r--r--arch/x86_64/kernel/nmi.c248
-rw-r--r--arch/x86_64/kernel/pmtimer.c101
-rw-r--r--arch/x86_64/kernel/ptrace.c38
-rw-r--r--arch/x86_64/kernel/setup.c30
-rw-r--r--arch/x86_64/kernel/signal.c5
-rw-r--r--arch/x86_64/kernel/smpboot.c263
-rw-r--r--arch/x86_64/kernel/time.c64
-rw-r--r--arch/x86_64/kernel/traps.c2
-rw-r--r--arch/x86_64/kernel/vsyscall.c5
-rw-r--r--arch/x86_64/kernel/x8664_ksyms.c16
-rw-r--r--arch/x86_64/mm/fault.c11
-rw-r--r--arch/x86_64/mm/ioremap.c29
383 files changed, 12503 insertions, 4643 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 0c79b9d95f74..f7c96635d3b4 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -280,6 +280,10 @@ config ISA
280 (MCA) or VESA. ISA is an older system, now being displaced by PCI; 280 (MCA) or VESA. ISA is an older system, now being displaced by PCI;
281 newer boards don't support it. If you have ISA, say Y, otherwise N. 281 newer boards don't support it. If you have ISA, say Y, otherwise N.
282 282
283config ISA_DMA_API
284 bool
285 default y
286
283config PCI 287config PCI
284 bool 288 bool
285 depends on !ALPHA_JENSEN 289 depends on !ALPHA_JENSEN
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 64e450dddb49..167fd89f8707 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -1150,16 +1150,13 @@ osf_usleep_thread(struct timeval32 __user *sleep, struct timeval32 __user *remai
1150 if (get_tv32(&tmp, sleep)) 1150 if (get_tv32(&tmp, sleep))
1151 goto fault; 1151 goto fault;
1152 1152
1153 ticks = tmp.tv_usec; 1153 ticks = timeval_to_jiffies(&tmp);
1154 ticks = (ticks + (1000000 / HZ) - 1) / (1000000 / HZ);
1155 ticks += tmp.tv_sec * HZ;
1156 1154
1157 current->state = TASK_INTERRUPTIBLE; 1155 current->state = TASK_INTERRUPTIBLE;
1158 ticks = schedule_timeout(ticks); 1156 ticks = schedule_timeout(ticks);
1159 1157
1160 if (remain) { 1158 if (remain) {
1161 tmp.tv_sec = ticks / HZ; 1159 jiffies_to_timeval(ticks, &tmp);
1162 tmp.tv_usec = ticks % HZ;
1163 if (put_tv32(remain, &tmp)) 1160 if (put_tv32(remain, &tmp))
1164 goto fault; 1161 goto fault;
1165 } 1162 }
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4055115ae0e2..475950c8a831 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -85,6 +85,7 @@ choice
85config ARCH_CLPS7500 85config ARCH_CLPS7500
86 bool "Cirrus-CL-PS7500FE" 86 bool "Cirrus-CL-PS7500FE"
87 select TIMER_ACORN 87 select TIMER_ACORN
88 select ISA
88 89
89config ARCH_CLPS711X 90config ARCH_CLPS711X
90 bool "CLPS711x/EP721x-based" 91 bool "CLPS711x/EP721x-based"
@@ -96,6 +97,7 @@ config ARCH_CO285
96 97
97config ARCH_EBSA110 98config ARCH_EBSA110
98 bool "EBSA-110" 99 bool "EBSA-110"
100 select ISA
99 help 101 help
100 This is an evaluation board for the StrongARM processor available 102 This is an evaluation board for the StrongARM processor available
101 from Digital. It has limited hardware on-board, including an onboard 103 from Digital. It has limited hardware on-board, including an onboard
@@ -120,13 +122,16 @@ config ARCH_INTEGRATOR
120 122
121config ARCH_IOP3XX 123config ARCH_IOP3XX
122 bool "IOP3xx-based" 124 bool "IOP3xx-based"
125 select PCI
123 126
124config ARCH_IXP4XX 127config ARCH_IXP4XX
125 bool "IXP4xx-based" 128 bool "IXP4xx-based"
126 select DMABOUNCE 129 select DMABOUNCE
130 select PCI
127 131
128config ARCH_IXP2000 132config ARCH_IXP2000
129 bool "IXP2400/2800-based" 133 bool "IXP2400/2800-based"
134 select PCI
130 135
131config ARCH_L7200 136config ARCH_L7200
132 bool "LinkUp-L7200" 137 bool "LinkUp-L7200"
@@ -155,6 +160,8 @@ config ARCH_RPC
155 160
156config ARCH_SA1100 161config ARCH_SA1100
157 bool "SA1100-based" 162 bool "SA1100-based"
163 select ISA
164 select DISCONTIGMEM
158 165
159config ARCH_S3C2410 166config ARCH_S3C2410
160 bool "Samsung S3C2410" 167 bool "Samsung S3C2410"
@@ -165,6 +172,9 @@ config ARCH_S3C2410
165 172
166config ARCH_SHARK 173config ARCH_SHARK
167 bool "Shark" 174 bool "Shark"
175 select ISA
176 select ISA_DMA
177 select PCI
168 178
169config ARCH_LH7A40X 179config ARCH_LH7A40X
170 bool "Sharp LH7A40X" 180 bool "Sharp LH7A40X"
@@ -252,8 +262,6 @@ config ARM_AMBA
252 262
253config ISA 263config ISA
254 bool 264 bool
255 depends on FOOTBRIDGE_HOST || ARCH_SHARK || ARCH_CLPS7500 || ARCH_EBSA110 || ARCH_CDB89712 || ARCH_EDB7211 || ARCH_SA1100 || ARCH_MX1ADS
256 default y
257 help 265 help
258 Find out whether you have ISA slots on your motherboard. ISA is the 266 Find out whether you have ISA slots on your motherboard. ISA is the
259 name of a bus system, i.e. the way the CPU talks to the other stuff 267 name of a bus system, i.e. the way the CPU talks to the other stuff
@@ -263,12 +271,13 @@ config ISA
263 271
264config ISA_DMA 272config ISA_DMA
265 bool 273 bool
266 depends on FOOTBRIDGE_HOST || ARCH_SHARK 274
275config ISA_DMA_API
276 bool
267 default y 277 default y
268 278
269config PCI 279config PCI
270 bool "PCI support" if ARCH_INTEGRATOR_AP 280 bool "PCI support" if ARCH_INTEGRATOR_AP
271 default y if ARCH_SHARK || FOOTBRIDGE_HOST || ARCH_IOP3XX || ARCH_IXP4XX || ARCH_IXP2000
272 help 281 help
273 Find out whether you have a PCI motherboard. PCI is the name of a 282 Find out whether you have a PCI motherboard. PCI is the name of a
274 bus system, i.e. the way the CPU talks to the other stuff inside 283 bus system, i.e. the way the CPU talks to the other stuff inside
@@ -296,7 +305,7 @@ menu "Kernel Features"
296 305
297config SMP 306config SMP
298 bool "Symmetric Multi-Processing (EXPERIMENTAL)" 307 bool "Symmetric Multi-Processing (EXPERIMENTAL)"
299 depends on EXPERIMENTAL && n 308 depends on EXPERIMENTAL #&& n
300 help 309 help
301 This enables support for systems with more than one CPU. If you have 310 This enables support for systems with more than one CPU. If you have
302 a system with only one CPU, like most personal computers, say N. If 311 a system with only one CPU, like most personal computers, say N. If
@@ -336,8 +345,7 @@ config PREEMPT
336 345
337config DISCONTIGMEM 346config DISCONTIGMEM
338 bool 347 bool
339 depends on ARCH_EDB7211 || ARCH_SA1100 || (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) 348 default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
340 default y
341 help 349 help
342 Say Y to support efficient handling of discontiguous physical memory, 350 Say Y to support efficient handling of discontiguous physical memory,
343 for architectures which are either NUMA (Non-Uniform Memory Access) 351 for architectures which are either NUMA (Non-Uniform Memory Access)
@@ -489,7 +497,7 @@ source "drivers/cpufreq/Kconfig"
489 497
490config CPU_FREQ_SA1100 498config CPU_FREQ_SA1100
491 bool 499 bool
492 depends on CPU_FREQ && (SA1100_LART || SA1100_PLEB) 500 depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_H3800 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4 || SA1100_HACKKIT)
493 default y 501 default y
494 502
495config CPU_FREQ_SA1110 503config CPU_FREQ_SA1110
@@ -681,7 +689,9 @@ source "drivers/block/Kconfig"
681 689
682source "drivers/acorn/block/Kconfig" 690source "drivers/acorn/block/Kconfig"
683 691
684if ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE 692if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \
693 || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
694 || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE
685source "drivers/ide/Kconfig" 695source "drivers/ide/Kconfig"
686endif 696endif
687 697
diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S
index 665bd2c20743..d3fe2533907e 100644
--- a/arch/arm/boot/compressed/head-xscale.S
+++ b/arch/arm/boot/compressed/head-xscale.S
@@ -47,3 +47,10 @@ __XScale_start:
47 orr r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00) 47 orr r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00)
48#endif 48#endif
49 49
50#ifdef CONFIG_ARCH_IXP2000
51 mov r1, #-1
52 mov r0, #0xd6000000
53 str r1, [r0, #0x14]
54 str r1, [r0, #0x18]
55#endif
56
diff --git a/arch/arm/configs/badge4_defconfig b/arch/arm/configs/badge4_defconfig
index 2b4059d2f8e4..5d92af975d87 100644
--- a/arch/arm/configs/badge4_defconfig
+++ b/arch/arm/configs/badge4_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc1-bk2 3# Linux kernel version: 2.6.12-rc6-git3
4# Sat Mar 26 21:32:26 2005 4# Thu Jun 9 19:00:50 2005
5# 5#
6CONFIG_ARM=y 6CONFIG_ARM=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -16,6 +16,7 @@ CONFIG_GENERIC_IOMAP=y
16CONFIG_EXPERIMENTAL=y 16CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y 17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y 18CONFIG_BROKEN_ON_SMP=y
19CONFIG_INIT_ENV_ARG_LIMIT=32
19 20
20# 21#
21# General setup 22# General setup
@@ -34,6 +35,8 @@ CONFIG_EMBEDDED=y
34CONFIG_KALLSYMS=y 35CONFIG_KALLSYMS=y
35# CONFIG_KALLSYMS_ALL is not set 36# CONFIG_KALLSYMS_ALL is not set
36# CONFIG_KALLSYMS_EXTRA_PASS is not set 37# CONFIG_KALLSYMS_EXTRA_PASS is not set
38CONFIG_PRINTK=y
39CONFIG_BUG=y
37CONFIG_BASE_FULL=y 40CONFIG_BASE_FULL=y
38CONFIG_FUTEX=y 41CONFIG_FUTEX=y
39CONFIG_EPOLL=y 42CONFIG_EPOLL=y
@@ -109,7 +112,6 @@ CONFIG_CPU_ABRT_EV4=y
109CONFIG_CPU_CACHE_V4WB=y 112CONFIG_CPU_CACHE_V4WB=y
110CONFIG_CPU_CACHE_VIVT=y 113CONFIG_CPU_CACHE_VIVT=y
111CONFIG_CPU_TLB_V4WB=y 114CONFIG_CPU_TLB_V4WB=y
112CONFIG_CPU_MINICACHE=y
113 115
114# 116#
115# Processor Features 117# Processor Features
@@ -122,6 +124,7 @@ CONFIG_FORCE_MAX_ZONEORDER=9
122# Bus support 124# Bus support
123# 125#
124CONFIG_ISA=y 126CONFIG_ISA=y
127CONFIG_ISA_DMA_API=y
125 128
126# 129#
127# PCCARD (PCMCIA/CardBus) support 130# PCCARD (PCMCIA/CardBus) support
@@ -131,6 +134,7 @@ CONFIG_ISA=y
131# 134#
132# Kernel Features 135# Kernel Features
133# 136#
137# CONFIG_SMP is not set
134# CONFIG_PREEMPT is not set 138# CONFIG_PREEMPT is not set
135CONFIG_DISCONTIGMEM=y 139CONFIG_DISCONTIGMEM=y
136# CONFIG_LEDS is not set 140# CONFIG_LEDS is not set
@@ -152,12 +156,14 @@ CONFIG_CPU_FREQ_TABLE=y
152# CONFIG_CPU_FREQ_DEBUG is not set 156# CONFIG_CPU_FREQ_DEBUG is not set
153CONFIG_CPU_FREQ_STAT=y 157CONFIG_CPU_FREQ_STAT=y
154# CONFIG_CPU_FREQ_STAT_DETAILS is not set 158# CONFIG_CPU_FREQ_STAT_DETAILS is not set
155CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y 159# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
156# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set 160CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
157CONFIG_CPU_FREQ_GOV_PERFORMANCE=y 161CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
158# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set 162# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
159# CONFIG_CPU_FREQ_GOV_USERSPACE is not set 163CONFIG_CPU_FREQ_GOV_USERSPACE=y
160# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set 164# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
165# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
166CONFIG_CPU_FREQ_SA1100=y
161 167
162# 168#
163# Floating point emulation 169# Floating point emulation
@@ -294,7 +300,6 @@ CONFIG_PARPORT_NOT_PC=y
294# 300#
295# Block devices 301# Block devices
296# 302#
297# CONFIG_BLK_DEV_FD is not set
298# CONFIG_BLK_DEV_XD is not set 303# CONFIG_BLK_DEV_XD is not set
299# CONFIG_PARIDE is not set 304# CONFIG_PARIDE is not set
300# CONFIG_BLK_DEV_COW_COMMON is not set 305# CONFIG_BLK_DEV_COW_COMMON is not set
@@ -428,7 +433,6 @@ CONFIG_NET=y
428# 433#
429CONFIG_PACKET=y 434CONFIG_PACKET=y
430# CONFIG_PACKET_MMAP is not set 435# CONFIG_PACKET_MMAP is not set
431# CONFIG_NETLINK_DEV is not set
432CONFIG_UNIX=y 436CONFIG_UNIX=y
433# CONFIG_NET_KEY is not set 437# CONFIG_NET_KEY is not set
434CONFIG_INET=y 438CONFIG_INET=y
@@ -526,6 +530,7 @@ CONFIG_IRDA_ULTRA=y
526# CONFIG_SMC_IRCC_FIR is not set 530# CONFIG_SMC_IRCC_FIR is not set
527# CONFIG_ALI_FIR is not set 531# CONFIG_ALI_FIR is not set
528CONFIG_SA1100_FIR=y 532CONFIG_SA1100_FIR=y
533# CONFIG_VIA_FIR is not set
529CONFIG_BT=m 534CONFIG_BT=m
530CONFIG_BT_L2CAP=m 535CONFIG_BT_L2CAP=m
531# CONFIG_BT_SCO is not set 536# CONFIG_BT_SCO is not set
@@ -618,7 +623,6 @@ CONFIG_NET_WIRELESS=y
618# 623#
619# CONFIG_SERIO is not set 624# CONFIG_SERIO is not set
620# CONFIG_GAMEPORT is not set 625# CONFIG_GAMEPORT is not set
621CONFIG_SOUND_GAMEPORT=y
622 626
623# 627#
624# Character devices 628# Character devices
@@ -687,7 +691,6 @@ CONFIG_RTC=m
687# 691#
688# TPM devices 692# TPM devices
689# 693#
690# CONFIG_TCG_TPM is not set
691 694
692# 695#
693# I2C support 696# I2C support
@@ -736,6 +739,7 @@ CONFIG_I2C_ELEKTOR=m
736# CONFIG_SENSORS_LM85 is not set 739# CONFIG_SENSORS_LM85 is not set
737# CONFIG_SENSORS_LM87 is not set 740# CONFIG_SENSORS_LM87 is not set
738# CONFIG_SENSORS_LM90 is not set 741# CONFIG_SENSORS_LM90 is not set
742# CONFIG_SENSORS_LM92 is not set
739# CONFIG_SENSORS_MAX1619 is not set 743# CONFIG_SENSORS_MAX1619 is not set
740# CONFIG_SENSORS_PC87360 is not set 744# CONFIG_SENSORS_PC87360 is not set
741# CONFIG_SENSORS_SMSC47B397 is not set 745# CONFIG_SENSORS_SMSC47B397 is not set
@@ -747,6 +751,7 @@ CONFIG_I2C_ELEKTOR=m
747# 751#
748# Other I2C Chip support 752# Other I2C Chip support
749# 753#
754# CONFIG_SENSORS_DS1337 is not set
750# CONFIG_SENSORS_EEPROM is not set 755# CONFIG_SENSORS_EEPROM is not set
751# CONFIG_SENSORS_PCF8574 is not set 756# CONFIG_SENSORS_PCF8574 is not set
752# CONFIG_SENSORS_PCF8591 is not set 757# CONFIG_SENSORS_PCF8591 is not set
@@ -871,7 +876,6 @@ CONFIG_USB_PRINTER=m
871# 876#
872CONFIG_USB_STORAGE=y 877CONFIG_USB_STORAGE=y
873CONFIG_USB_STORAGE_DEBUG=y 878CONFIG_USB_STORAGE_DEBUG=y
874# CONFIG_USB_STORAGE_RW_DETECT is not set
875# CONFIG_USB_STORAGE_DATAFAB is not set 879# CONFIG_USB_STORAGE_DATAFAB is not set
876# CONFIG_USB_STORAGE_FREECOM is not set 880# CONFIG_USB_STORAGE_FREECOM is not set
877# CONFIG_USB_STORAGE_ISD200 is not set 881# CONFIG_USB_STORAGE_ISD200 is not set
@@ -954,9 +958,11 @@ CONFIG_USB_USS720=m
954# 958#
955CONFIG_USB_SERIAL=m 959CONFIG_USB_SERIAL=m
956CONFIG_USB_SERIAL_GENERIC=y 960CONFIG_USB_SERIAL_GENERIC=y
961# CONFIG_USB_SERIAL_AIRPRIME is not set
957CONFIG_USB_SERIAL_BELKIN=m 962CONFIG_USB_SERIAL_BELKIN=m
958CONFIG_USB_SERIAL_WHITEHEAT=m 963CONFIG_USB_SERIAL_WHITEHEAT=m
959CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m 964CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
965# CONFIG_USB_SERIAL_CP2101 is not set
960# CONFIG_USB_SERIAL_CYPRESS_M8 is not set 966# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
961CONFIG_USB_SERIAL_EMPEG=m 967CONFIG_USB_SERIAL_EMPEG=m
962CONFIG_USB_SERIAL_FTDI_SIO=m 968CONFIG_USB_SERIAL_FTDI_SIO=m
@@ -985,6 +991,7 @@ CONFIG_USB_SERIAL_KEYSPAN=m
985# CONFIG_USB_SERIAL_KOBIL_SCT is not set 991# CONFIG_USB_SERIAL_KOBIL_SCT is not set
986CONFIG_USB_SERIAL_MCT_U232=m 992CONFIG_USB_SERIAL_MCT_U232=m
987CONFIG_USB_SERIAL_PL2303=m 993CONFIG_USB_SERIAL_PL2303=m
994# CONFIG_USB_SERIAL_HP4X is not set
988# CONFIG_USB_SERIAL_SAFE is not set 995# CONFIG_USB_SERIAL_SAFE is not set
989# CONFIG_USB_SERIAL_TI is not set 996# CONFIG_USB_SERIAL_TI is not set
990CONFIG_USB_SERIAL_CYBERJACK=m 997CONFIG_USB_SERIAL_CYBERJACK=m
diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig
index b4e297dd54b2..b9de07de80fe 100644
--- a/arch/arm/configs/h3600_defconfig
+++ b/arch/arm/configs/h3600_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc1-bk2 3# Linux kernel version: 2.6.12-rc4
4# Mon Mar 28 00:02:26 2005 4# Thu Jun 9 01:59:03 2005
5# 5#
6CONFIG_ARM=y 6CONFIG_ARM=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -16,6 +16,7 @@ CONFIG_GENERIC_IOMAP=y
16CONFIG_EXPERIMENTAL=y 16CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y 17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y 18CONFIG_BROKEN_ON_SMP=y
19CONFIG_INIT_ENV_ARG_LIMIT=32
19 20
20# 21#
21# General setup 22# General setup
@@ -33,6 +34,8 @@ CONFIG_KOBJECT_UEVENT=y
33# CONFIG_EMBEDDED is not set 34# CONFIG_EMBEDDED is not set
34CONFIG_KALLSYMS=y 35CONFIG_KALLSYMS=y
35# CONFIG_KALLSYMS_EXTRA_PASS is not set 36# CONFIG_KALLSYMS_EXTRA_PASS is not set
37CONFIG_PRINTK=y
38CONFIG_BUG=y
36CONFIG_BASE_FULL=y 39CONFIG_BASE_FULL=y
37CONFIG_FUTEX=y 40CONFIG_FUTEX=y
38CONFIG_EPOLL=y 41CONFIG_EPOLL=y
@@ -120,6 +123,7 @@ CONFIG_CPU_MINICACHE=y
120# Bus support 123# Bus support
121# 124#
122CONFIG_ISA=y 125CONFIG_ISA=y
126CONFIG_ISA_DMA_API=y
123 127
124# 128#
125# PCCARD (PCMCIA/CardBus) support 129# PCCARD (PCMCIA/CardBus) support
@@ -138,6 +142,7 @@ CONFIG_PCMCIA_SA1100=y
138# 142#
139# Kernel Features 143# Kernel Features
140# 144#
145# CONFIG_SMP is not set
141# CONFIG_PREEMPT is not set 146# CONFIG_PREEMPT is not set
142CONFIG_DISCONTIGMEM=y 147CONFIG_DISCONTIGMEM=y
143# CONFIG_LEDS is not set 148# CONFIG_LEDS is not set
@@ -159,12 +164,13 @@ CONFIG_CPU_FREQ_TABLE=y
159# CONFIG_CPU_FREQ_DEBUG is not set 164# CONFIG_CPU_FREQ_DEBUG is not set
160CONFIG_CPU_FREQ_STAT=y 165CONFIG_CPU_FREQ_STAT=y
161# CONFIG_CPU_FREQ_STAT_DETAILS is not set 166# CONFIG_CPU_FREQ_STAT_DETAILS is not set
162CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y 167# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
163# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set 168CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
164CONFIG_CPU_FREQ_GOV_PERFORMANCE=y 169# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
165# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set 170# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
166# CONFIG_CPU_FREQ_GOV_USERSPACE is not set 171CONFIG_CPU_FREQ_GOV_USERSPACE=y
167# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set 172# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
173CONFIG_CPU_FREQ_SA1100=y
168 174
169# 175#
170# Floating point emulation 176# Floating point emulation
@@ -298,7 +304,6 @@ CONFIG_MTD_SA1100=y
298# 304#
299# Block devices 305# Block devices
300# 306#
301# CONFIG_BLK_DEV_FD is not set
302# CONFIG_BLK_DEV_XD is not set 307# CONFIG_BLK_DEV_XD is not set
303# CONFIG_BLK_DEV_COW_COMMON is not set 308# CONFIG_BLK_DEV_COW_COMMON is not set
304CONFIG_BLK_DEV_LOOP=m 309CONFIG_BLK_DEV_LOOP=m
@@ -379,7 +384,6 @@ CONFIG_NET=y
379# Networking options 384# Networking options
380# 385#
381# CONFIG_PACKET is not set 386# CONFIG_PACKET is not set
382# CONFIG_NETLINK_DEV is not set
383CONFIG_UNIX=y 387CONFIG_UNIX=y
384# CONFIG_NET_KEY is not set 388# CONFIG_NET_KEY is not set
385CONFIG_INET=y 389CONFIG_INET=y
@@ -476,6 +480,7 @@ CONFIG_IRCOMM=m
476# CONFIG_SMC_IRCC_FIR is not set 480# CONFIG_SMC_IRCC_FIR is not set
477# CONFIG_ALI_FIR is not set 481# CONFIG_ALI_FIR is not set
478CONFIG_SA1100_FIR=m 482CONFIG_SA1100_FIR=m
483# CONFIG_VIA_FIR is not set
479# CONFIG_BT is not set 484# CONFIG_BT is not set
480CONFIG_NETDEVICES=y 485CONFIG_NETDEVICES=y
481# CONFIG_DUMMY is not set 486# CONFIG_DUMMY is not set
@@ -647,7 +652,6 @@ CONFIG_LEGACY_PTY_COUNT=256
647# 652#
648# TPM devices 653# TPM devices
649# 654#
650# CONFIG_TCG_TPM is not set
651 655
652# 656#
653# I2C support 657# I2C support
@@ -676,9 +680,11 @@ CONFIG_FB_CFB_FILLRECT=y
676CONFIG_FB_CFB_COPYAREA=y 680CONFIG_FB_CFB_COPYAREA=y
677CONFIG_FB_CFB_IMAGEBLIT=y 681CONFIG_FB_CFB_IMAGEBLIT=y
678CONFIG_FB_SOFT_CURSOR=y 682CONFIG_FB_SOFT_CURSOR=y
683# CONFIG_FB_MACMODES is not set
679# CONFIG_FB_MODE_HELPERS is not set 684# CONFIG_FB_MODE_HELPERS is not set
680# CONFIG_FB_TILEBLITTING is not set 685# CONFIG_FB_TILEBLITTING is not set
681CONFIG_FB_SA1100=y 686CONFIG_FB_SA1100=y
687# CONFIG_FB_S1D13XXX is not set
682# CONFIG_FB_VIRTUAL is not set 688# CONFIG_FB_VIRTUAL is not set
683 689
684# 690#
diff --git a/arch/arm/configs/hackkit_defconfig b/arch/arm/configs/hackkit_defconfig
index 6987c8c5ddb4..fb41a36a5a68 100644
--- a/arch/arm/configs/hackkit_defconfig
+++ b/arch/arm/configs/hackkit_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc1-bk2 3# Linux kernel version: 2.6.12-rc6-git3
4# Mon Mar 28 00:22:34 2005 4# Thu Jun 9 20:58:58 2005
5# 5#
6CONFIG_ARM=y 6CONFIG_ARM=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -16,6 +16,7 @@ CONFIG_GENERIC_IOMAP=y
16CONFIG_EXPERIMENTAL=y 16CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y 17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y 18CONFIG_BROKEN_ON_SMP=y
19CONFIG_INIT_ENV_ARG_LIMIT=32
19 20
20# 21#
21# General setup 22# General setup
@@ -34,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
34CONFIG_KALLSYMS=y 35CONFIG_KALLSYMS=y
35# CONFIG_KALLSYMS_ALL is not set 36# CONFIG_KALLSYMS_ALL is not set
36# CONFIG_KALLSYMS_EXTRA_PASS is not set 37# CONFIG_KALLSYMS_EXTRA_PASS is not set
38CONFIG_PRINTK=y
39CONFIG_BUG=y
37CONFIG_BASE_FULL=y 40CONFIG_BASE_FULL=y
38CONFIG_FUTEX=y 41CONFIG_FUTEX=y
39CONFIG_EPOLL=y 42CONFIG_EPOLL=y
@@ -109,7 +112,6 @@ CONFIG_CPU_ABRT_EV4=y
109CONFIG_CPU_CACHE_V4WB=y 112CONFIG_CPU_CACHE_V4WB=y
110CONFIG_CPU_CACHE_VIVT=y 113CONFIG_CPU_CACHE_VIVT=y
111CONFIG_CPU_TLB_V4WB=y 114CONFIG_CPU_TLB_V4WB=y
112CONFIG_CPU_MINICACHE=y
113 115
114# 116#
115# Processor Features 117# Processor Features
@@ -119,6 +121,7 @@ CONFIG_CPU_MINICACHE=y
119# Bus support 121# Bus support
120# 122#
121CONFIG_ISA=y 123CONFIG_ISA=y
124CONFIG_ISA_DMA_API=y
122 125
123# 126#
124# PCCARD (PCMCIA/CardBus) support 127# PCCARD (PCMCIA/CardBus) support
@@ -128,6 +131,7 @@ CONFIG_ISA=y
128# 131#
129# Kernel Features 132# Kernel Features
130# 133#
134# CONFIG_SMP is not set
131# CONFIG_PREEMPT is not set 135# CONFIG_PREEMPT is not set
132CONFIG_DISCONTIGMEM=y 136CONFIG_DISCONTIGMEM=y
133CONFIG_LEDS=y 137CONFIG_LEDS=y
@@ -151,12 +155,14 @@ CONFIG_CPU_FREQ_TABLE=y
151# CONFIG_CPU_FREQ_DEBUG is not set 155# CONFIG_CPU_FREQ_DEBUG is not set
152CONFIG_CPU_FREQ_STAT=y 156CONFIG_CPU_FREQ_STAT=y
153# CONFIG_CPU_FREQ_STAT_DETAILS is not set 157# CONFIG_CPU_FREQ_STAT_DETAILS is not set
154CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y 158# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
155# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set 159CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
156CONFIG_CPU_FREQ_GOV_PERFORMANCE=y 160CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
157# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set 161# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
158# CONFIG_CPU_FREQ_GOV_USERSPACE is not set 162CONFIG_CPU_FREQ_GOV_USERSPACE=y
159# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set 163# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
164# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
165CONFIG_CPU_FREQ_SA1100=y
160 166
161# 167#
162# Floating point emulation 168# Floating point emulation
@@ -280,7 +286,6 @@ CONFIG_MTD_CFI_UTIL=y
280# 286#
281# Block devices 287# Block devices
282# 288#
283# CONFIG_BLK_DEV_FD is not set
284# CONFIG_BLK_DEV_XD is not set 289# CONFIG_BLK_DEV_XD is not set
285# CONFIG_BLK_DEV_COW_COMMON is not set 290# CONFIG_BLK_DEV_COW_COMMON is not set
286# CONFIG_BLK_DEV_LOOP is not set 291# CONFIG_BLK_DEV_LOOP is not set
@@ -338,7 +343,6 @@ CONFIG_NET=y
338# 343#
339CONFIG_PACKET=y 344CONFIG_PACKET=y
340# CONFIG_PACKET_MMAP is not set 345# CONFIG_PACKET_MMAP is not set
341# CONFIG_NETLINK_DEV is not set
342CONFIG_UNIX=y 346CONFIG_UNIX=y
343# CONFIG_NET_KEY is not set 347# CONFIG_NET_KEY is not set
344CONFIG_INET=y 348CONFIG_INET=y
@@ -484,7 +488,6 @@ CONFIG_SERIO=y
484CONFIG_SERIO_SERPORT=y 488CONFIG_SERIO_SERPORT=y
485# CONFIG_SERIO_RAW is not set 489# CONFIG_SERIO_RAW is not set
486# CONFIG_GAMEPORT is not set 490# CONFIG_GAMEPORT is not set
487CONFIG_SOUND_GAMEPORT=y
488 491
489# 492#
490# Character devices 493# Character devices
@@ -533,7 +536,6 @@ CONFIG_LEGACY_PTY_COUNT=256
533# 536#
534# TPM devices 537# TPM devices
535# 538#
536# CONFIG_TCG_TPM is not set
537 539
538# 540#
539# I2C support 541# I2C support
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 080df907f242..e14278d59882 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -17,8 +17,8 @@
17 17
18#include <asm/glue.h> 18#include <asm/glue.h>
19#include <asm/vfpmacros.h> 19#include <asm/vfpmacros.h>
20#include <asm/hardware.h> @ should be moved into entry-macro.S 20#include <asm/hardware.h> /* should be moved into entry-macro.S */
21#include <asm/arch/irqs.h> @ should be moved into entry-macro.S 21#include <asm/arch/irqs.h> /* should be moved into entry-macro.S */
22#include <asm/arch/entry-macro.S> 22#include <asm/arch/entry-macro.S>
23 23
24#include "entry-header.S" 24#include "entry-header.S"
@@ -269,7 +269,7 @@ __pabt_svc:
269 add r5, sp, #S_PC 269 add r5, sp, #S_PC
270 ldmia r7, {r2 - r4} @ Get USR pc, cpsr 270 ldmia r7, {r2 - r4} @ Get USR pc, cpsr
271 271
272#if __LINUX_ARM_ARCH__ < 6 272#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
273 @ make sure our user space atomic helper is aborted 273 @ make sure our user space atomic helper is aborted
274 cmp r2, #VIRT_OFFSET 274 cmp r2, #VIRT_OFFSET
275 bichs r3, r3, #PSR_Z_BIT 275 bichs r3, r3, #PSR_Z_BIT
@@ -505,9 +505,9 @@ ENTRY(__switch_to)
505 mra r4, r5, acc0 505 mra r4, r5, acc0
506 stmia ip, {r4, r5} 506 stmia ip, {r4, r5}
507#endif 507#endif
508#ifdef CONFIG_HAS_TLS_REG 508#if defined(CONFIG_HAS_TLS_REG)
509 mcr p15, 0, r3, c13, c0, 3 @ set TLS register 509 mcr p15, 0, r3, c13, c0, 3 @ set TLS register
510#else 510#elif !defined(CONFIG_TLS_REG_EMUL)
511 mov r4, #0xffff0fff 511 mov r4, #0xffff0fff
512 str r3, [r4, #-15] @ TLS val at 0xffff0ff0 512 str r3, [r4, #-15] @ TLS val at 0xffff0ff0
513#endif 513#endif
@@ -616,11 +616,17 @@ __kuser_helper_start:
616 616
617__kuser_cmpxchg: @ 0xffff0fc0 617__kuser_cmpxchg: @ 0xffff0fc0
618 618
619#if __LINUX_ARM_ARCH__ < 6 619#if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
620 620
621#ifdef CONFIG_SMP /* sanity check */ 621 /*
622#error "CONFIG_SMP on a machine supporting pre-ARMv6 processors?" 622 * Poor you. No fast solution possible...
623#endif 623 * The kernel itself must perform the operation.
624 * A special ghost syscall is used for that (see traps.c).
625 */
626 swi #0x9ffff0
627 mov pc, lr
628
629#elif __LINUX_ARM_ARCH__ < 6
624 630
625 /* 631 /*
626 * Theory of operation: 632 * Theory of operation:
@@ -690,11 +696,7 @@ __kuser_cmpxchg: @ 0xffff0fc0
690 696
691__kuser_get_tls: @ 0xffff0fe0 697__kuser_get_tls: @ 0xffff0fe0
692 698
693#ifndef CONFIG_HAS_TLS_REG 699#if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL)
694
695#ifdef CONFIG_SMP /* sanity check */
696#error "CONFIG_SMP without CONFIG_HAS_TLS_REG is wrong"
697#endif
698 700
699 ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0 701 ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0
700 mov pc, lr 702 mov pc, lr
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 171b3e811c71..4733877296d4 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -19,6 +19,7 @@
19#include <asm/procinfo.h> 19#include <asm/procinfo.h>
20#include <asm/ptrace.h> 20#include <asm/ptrace.h>
21#include <asm/constants.h> 21#include <asm/constants.h>
22#include <asm/thread_info.h>
22#include <asm/system.h> 23#include <asm/system.h>
23 24
24#define PROCINFO_MMUFLAGS 8 25#define PROCINFO_MMUFLAGS 8
@@ -131,7 +132,7 @@ __switch_data:
131 .long processor_id @ r4 132 .long processor_id @ r4
132 .long __machine_arch_type @ r5 133 .long __machine_arch_type @ r5
133 .long cr_alignment @ r6 134 .long cr_alignment @ r6
134 .long init_thread_union+8192 @ sp 135 .long init_thread_union + THREAD_START_SP @ sp
135 136
136/* 137/*
137 * The following fragment of code is executed with the MMU on, and uses 138 * The following fragment of code is executed with the MMU on, and uses
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 26eacd3e5def..8f146a4b4752 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -256,8 +256,6 @@ static unsigned long *thread_info_head;
256static unsigned int nr_thread_info; 256static unsigned int nr_thread_info;
257 257
258#define EXTRA_TASK_STRUCT 4 258#define EXTRA_TASK_STRUCT 4
259#define ll_alloc_task_struct() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
260#define ll_free_task_struct(p) free_pages((unsigned long)(p),1)
261 259
262struct thread_info *alloc_thread_info(struct task_struct *task) 260struct thread_info *alloc_thread_info(struct task_struct *task)
263{ 261{
@@ -274,17 +272,16 @@ struct thread_info *alloc_thread_info(struct task_struct *task)
274 } 272 }
275 273
276 if (!thread) 274 if (!thread)
277 thread = ll_alloc_task_struct(); 275 thread = (struct thread_info *)
276 __get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER);
278 277
279#ifdef CONFIG_MAGIC_SYSRQ 278#ifdef CONFIG_DEBUG_STACK_USAGE
280 /* 279 /*
281 * The stack must be cleared if you want SYSRQ-T to 280 * The stack must be cleared if you want SYSRQ-T to
282 * give sensible stack usage information 281 * give sensible stack usage information
283 */ 282 */
284 if (thread) { 283 if (thread)
285 char *p = (char *)thread; 284 memzero(thread, THREAD_SIZE);
286 memzero(p+KERNEL_STACK_SIZE, KERNEL_STACK_SIZE);
287 }
288#endif 285#endif
289 return thread; 286 return thread;
290} 287}
@@ -297,7 +294,7 @@ void free_thread_info(struct thread_info *thread)
297 thread_info_head = p; 294 thread_info_head = p;
298 nr_thread_info += 1; 295 nr_thread_info += 1;
299 } else 296 } else
300 ll_free_task_struct(thread); 297 free_pages((unsigned long)thread, THREAD_SIZE_ORDER);
301} 298}
302 299
303/* 300/*
@@ -350,7 +347,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start,
350 struct thread_info *thread = p->thread_info; 347 struct thread_info *thread = p->thread_info;
351 struct pt_regs *childregs; 348 struct pt_regs *childregs;
352 349
353 childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_SIZE - 8)) - 1; 350 childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_START_SP)) - 1;
354 *childregs = *regs; 351 *childregs = *regs;
355 childregs->ARM_r0 = 0; 352 childregs->ARM_r0 = 0;
356 childregs->ARM_sp = stack_start; 353 childregs->ARM_sp = stack_start;
@@ -447,15 +444,17 @@ EXPORT_SYMBOL(kernel_thread);
447unsigned long get_wchan(struct task_struct *p) 444unsigned long get_wchan(struct task_struct *p)
448{ 445{
449 unsigned long fp, lr; 446 unsigned long fp, lr;
450 unsigned long stack_page; 447 unsigned long stack_start, stack_end;
451 int count = 0; 448 int count = 0;
452 if (!p || p == current || p->state == TASK_RUNNING) 449 if (!p || p == current || p->state == TASK_RUNNING)
453 return 0; 450 return 0;
454 451
455 stack_page = 4096 + (unsigned long)p->thread_info; 452 stack_start = (unsigned long)(p->thread_info + 1);
453 stack_end = ((unsigned long)p->thread_info) + THREAD_SIZE;
454
456 fp = thread_saved_fp(p); 455 fp = thread_saved_fp(p);
457 do { 456 do {
458 if (fp < stack_page || fp > 4092+stack_page) 457 if (fp < stack_start || fp > stack_end)
459 return 0; 458 return 0;
460 lr = pc_pointer (((unsigned long *)fp)[-1]); 459 lr = pc_pointer (((unsigned long *)fp)[-1]);
461 if (!in_sched_functions(lr)) 460 if (!in_sched_functions(lr))
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index ef32577da304..f897ce2ccf0d 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -302,7 +302,7 @@ long execve(const char *filename, char **argv, char **envp)
302 "b ret_to_user" 302 "b ret_to_user"
303 : 303 :
304 : "r" (current_thread_info()), 304 : "r" (current_thread_info()),
305 "Ir" (THREAD_SIZE - 8 - sizeof(regs)), 305 "Ir" (THREAD_START_SP - sizeof(regs)),
306 "r" (&regs), 306 "r" (&regs),
307 "Ir" (sizeof(regs)) 307 "Ir" (sizeof(regs))
308 : "r0", "r1", "r2", "r3", "ip", "memory"); 308 : "r0", "r1", "r2", "r3", "ip", "memory");
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 3a001fe5540b..45d2a032d890 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -218,7 +218,8 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
218 tsk->comm, tsk->pid, tsk->thread_info + 1); 218 tsk->comm, tsk->pid, tsk->thread_info + 1);
219 219
220 if (!user_mode(regs) || in_interrupt()) { 220 if (!user_mode(regs) || in_interrupt()) {
221 dump_mem("Stack: ", regs->ARM_sp, 8192+(unsigned long)tsk->thread_info); 221 dump_mem("Stack: ", regs->ARM_sp,
222 THREAD_SIZE + (unsigned long)tsk->thread_info);
222 dump_backtrace(regs, tsk); 223 dump_backtrace(regs, tsk);
223 dump_instr(regs); 224 dump_instr(regs);
224 } 225 }
@@ -450,9 +451,9 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
450 451
451 case NR(set_tls): 452 case NR(set_tls):
452 thread->tp_value = regs->ARM_r0; 453 thread->tp_value = regs->ARM_r0;
453#ifdef CONFIG_HAS_TLS_REG 454#if defined(CONFIG_HAS_TLS_REG)
454 asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) ); 455 asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) );
455#else 456#elif !defined(CONFIG_TLS_REG_EMUL)
456 /* 457 /*
457 * User space must never try to access this directly. 458 * User space must never try to access this directly.
458 * Expect your app to break eventually if you do so. 459 * Expect your app to break eventually if you do so.
@@ -463,6 +464,55 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
463#endif 464#endif
464 return 0; 465 return 0;
465 466
467#ifdef CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG
468 /*
469 * Atomically store r1 in *r2 if *r2 is equal to r0 for user space.
470 * Return zero in r0 if *MEM was changed or non-zero if no exchange
471 * happened. Also set the user C flag accordingly.
472 * If access permissions have to be fixed up then non-zero is
473 * returned and the operation has to be re-attempted.
474 *
475 * *NOTE*: This is a ghost syscall private to the kernel. Only the
476 * __kuser_cmpxchg code in entry-armv.S should be aware of its
477 * existence. Don't ever use this from user code.
478 */
479 case 0xfff0:
480 {
481 extern void do_DataAbort(unsigned long addr, unsigned int fsr,
482 struct pt_regs *regs);
483 unsigned long val;
484 unsigned long addr = regs->ARM_r2;
485 struct mm_struct *mm = current->mm;
486 pgd_t *pgd; pmd_t *pmd; pte_t *pte;
487
488 regs->ARM_cpsr &= ~PSR_C_BIT;
489 spin_lock(&mm->page_table_lock);
490 pgd = pgd_offset(mm, addr);
491 if (!pgd_present(*pgd))
492 goto bad_access;
493 pmd = pmd_offset(pgd, addr);
494 if (!pmd_present(*pmd))
495 goto bad_access;
496 pte = pte_offset_map(pmd, addr);
497 if (!pte_present(*pte) || !pte_write(*pte))
498 goto bad_access;
499 val = *(unsigned long *)addr;
500 val -= regs->ARM_r0;
501 if (val == 0) {
502 *(unsigned long *)addr = regs->ARM_r1;
503 regs->ARM_cpsr |= PSR_C_BIT;
504 }
505 spin_unlock(&mm->page_table_lock);
506 return val;
507
508 bad_access:
509 spin_unlock(&mm->page_table_lock);
510 /* simulate a read access fault */
511 do_DataAbort(addr, 15 + (1 << 11), regs);
512 return -1;
513 }
514#endif
515
466 default: 516 default:
467 /* Calls 9f00xx..9f07ff are defined to return -ENOSYS 517 /* Calls 9f00xx..9f07ff are defined to return -ENOSYS
468 if not implemented, rather than raising SIGILL. This 518 if not implemented, rather than raising SIGILL. This
@@ -497,11 +547,14 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
497 return 0; 547 return 0;
498} 548}
499 549
500#if defined(CONFIG_CPU_32v6) && !defined(CONFIG_HAS_TLS_REG) 550#ifdef CONFIG_TLS_REG_EMUL
501 551
502/* 552/*
503 * We might be running on an ARMv6+ processor which should have the TLS 553 * We might be running on an ARMv6+ processor which should have the TLS
504 * register, but for some reason we can't use it and have to emulate it. 554 * register but for some reason we can't use it, or maybe an SMP system
555 * using a pre-ARMv6 processor (there are apparently a few prototypes like
556 * that in existence) and therefore access to that register must be
557 * emulated.
505 */ 558 */
506 559
507static int get_tp_trap(struct pt_regs *regs, unsigned int instr) 560static int get_tp_trap(struct pt_regs *regs, unsigned int instr)
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index a39c6a42d68a..ad2d66c93a5c 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -5,6 +5,7 @@
5 5
6#include <asm-generic/vmlinux.lds.h> 6#include <asm-generic/vmlinux.lds.h>
7#include <linux/config.h> 7#include <linux/config.h>
8#include <asm/thread_info.h>
8 9
9OUTPUT_ARCH(arm) 10OUTPUT_ARCH(arm)
10ENTRY(stext) 11ENTRY(stext)
@@ -103,7 +104,7 @@ SECTIONS
103 __data_loc = ALIGN(4); /* location in binary */ 104 __data_loc = ALIGN(4); /* location in binary */
104 . = DATAADDR; 105 . = DATAADDR;
105#else 106#else
106 . = ALIGN(8192); 107 . = ALIGN(THREAD_SIZE);
107 __data_loc = .; 108 __data_loc = .;
108#endif 109#endif
109 110
diff --git a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S
index 6d1d7c27806e..5e240e452af6 100644
--- a/arch/arm/lib/io-writesw-armv4.S
+++ b/arch/arm/lib/io-writesw-armv4.S
@@ -87,9 +87,9 @@ ENTRY(__raw_writesw)
87 subs r2, r2, #2 87 subs r2, r2, #2
88 orr ip, ip, r3, push_hbyte1 88 orr ip, ip, r3, push_hbyte1
89 strh ip, [r0] 89 strh ip, [r0]
90 bpl 2b 90 bpl 1b
91 91
923: tst r2, #1 92 tst r2, #1
932: movne ip, r3, lsr #8 933: movne ip, r3, lsr #8
94 strneh ip, [r0] 94 strneh ip, [r0]
95 mov pc, lr 95 mov pc, lr
diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig
index f6e676322ca9..45c930ccd064 100644
--- a/arch/arm/mach-clps711x/Kconfig
+++ b/arch/arm/mach-clps711x/Kconfig
@@ -10,6 +10,7 @@ config ARCH_AUTCPU12
10 10
11config ARCH_CDB89712 11config ARCH_CDB89712
12 bool "CDB89712" 12 bool "CDB89712"
13 select ISA
13 help 14 help
14 This is an evaluation board from Cirrus for the CS89712 processor. 15 This is an evaluation board from Cirrus for the CS89712 processor.
15 The board includes 2 serial ports, Ethernet, IRDA, and expansion 16 The board includes 2 serial ports, Ethernet, IRDA, and expansion
@@ -26,6 +27,8 @@ config ARCH_CLEP7312
26 27
27config ARCH_EDB7211 28config ARCH_EDB7211
28 bool "EDB7211" 29 bool "EDB7211"
30 select ISA
31 select DISCONTIGMEM
29 help 32 help
30 Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211 33 Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211
31 evaluation board. 34 evaluation board.
diff --git a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig
index 1090c680b6dd..324d9edeec38 100644
--- a/arch/arm/mach-footbridge/Kconfig
+++ b/arch/arm/mach-footbridge/Kconfig
@@ -5,6 +5,9 @@ menu "Footbridge Implementations"
5config ARCH_CATS 5config ARCH_CATS
6 bool "CATS" 6 bool "CATS"
7 select FOOTBRIDGE_HOST 7 select FOOTBRIDGE_HOST
8 select ISA
9 select ISA_DMA
10 select PCI
8 help 11 help
9 Say Y here if you intend to run this kernel on the CATS. 12 Say Y here if you intend to run this kernel on the CATS.
10 13
@@ -13,6 +16,9 @@ config ARCH_CATS
13config ARCH_PERSONAL_SERVER 16config ARCH_PERSONAL_SERVER
14 bool "Compaq Personal Server" 17 bool "Compaq Personal Server"
15 select FOOTBRIDGE_HOST 18 select FOOTBRIDGE_HOST
19 select ISA
20 select ISA_DMA
21 select PCI
16 ---help--- 22 ---help---
17 Say Y here if you intend to run this kernel on the Compaq 23 Say Y here if you intend to run this kernel on the Compaq
18 Personal Server. 24 Personal Server.
@@ -42,6 +48,9 @@ config ARCH_EBSA285_HOST
42 bool "EBSA285 (host mode)" 48 bool "EBSA285 (host mode)"
43 select ARCH_EBSA285 49 select ARCH_EBSA285
44 select FOOTBRIDGE_HOST 50 select FOOTBRIDGE_HOST
51 select ISA
52 select ISA_DMA
53 select PCI
45 help 54 help
46 Say Y here if you intend to run this kernel on the EBSA285 card 55 Say Y here if you intend to run this kernel on the EBSA285 card
47 in host ("central function") mode. 56 in host ("central function") mode.
@@ -51,6 +60,9 @@ config ARCH_EBSA285_HOST
51config ARCH_NETWINDER 60config ARCH_NETWINDER
52 bool "NetWinder" 61 bool "NetWinder"
53 select FOOTBRIDGE_HOST 62 select FOOTBRIDGE_HOST
63 select ISA
64 select ISA_DMA
65 select PCI
54 help 66 help
55 Say Y here if you intend to run this kernel on the Rebel.COM 67 Say Y here if you intend to run this kernel on the Rebel.COM
56 NetWinder. Information about this machine can be found at: 68 NetWinder. Information about this machine can be found at:
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index ec85813ee5dc..cddd194ac6eb 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -4,6 +4,7 @@ menu "IMX Implementations"
4config ARCH_MX1ADS 4config ARCH_MX1ADS
5 bool "mx1ads" 5 bool "mx1ads"
6 depends on ARCH_IMX 6 depends on ARCH_IMX
7 select ISA
7 help 8 help
8 Say Y here if you are using the Motorola MX1ADS board 9 Say Y here if you are using the Motorola MX1ADS board
9 10
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index 94bcdb933e41..aa92e3708838 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -502,15 +502,6 @@ pci_set_dma_mask(struct pci_dev *dev, u64 mask)
502} 502}
503 503
504int 504int
505pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask)
506{
507 if (mask >= SZ_64M - 1 )
508 return 0;
509
510 return -EIO;
511}
512
513int
514pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) 505pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
515{ 506{
516 if (mask >= SZ_64M - 1 ) 507 if (mask >= SZ_64M - 1 )
@@ -520,7 +511,6 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
520} 511}
521 512
522EXPORT_SYMBOL(pci_set_dma_mask); 513EXPORT_SYMBOL(pci_set_dma_mask);
523EXPORT_SYMBOL(pci_dac_set_dma_mask);
524EXPORT_SYMBOL(pci_set_consistent_dma_mask); 514EXPORT_SYMBOL(pci_set_consistent_dma_mask);
525EXPORT_SYMBOL(ixp4xx_pci_read); 515EXPORT_SYMBOL(ixp4xx_pci_read);
526EXPORT_SYMBOL(ixp4xx_pci_write); 516EXPORT_SYMBOL(ixp4xx_pci_write);
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 3f952237ae3d..6823ae28ae6a 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -304,6 +304,15 @@ static void __init mainstone_map_io(void)
304 PWER = 0xC0000002; 304 PWER = 0xC0000002;
305 PRER = 0x00000002; 305 PRER = 0x00000002;
306 PFER = 0x00000002; 306 PFER = 0x00000002;
307 /* for use I SRAM as framebuffer. */
308 PSLR |= 0xF04;
309 PCFR = 0x66;
310 /* For Keypad wakeup. */
311 KPC &=~KPC_ASACT;
312 KPC |=KPC_AS;
313 PKWR = 0x000FD000;
314 /* Need read PKWR back after set it. */
315 PKWR;
307} 316}
308 317
309MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") 318MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index 82a4bf34c251..9799fe80df23 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -29,9 +29,6 @@
29 */ 29 */
30#undef DEBUG 30#undef DEBUG
31 31
32extern void pxa_cpu_suspend(void);
33extern void pxa_cpu_resume(void);
34
35#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x 32#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
36#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] 33#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
37 34
@@ -63,6 +60,12 @@ enum { SLEEP_SAVE_START = 0,
63 SLEEP_SAVE_ICMR, 60 SLEEP_SAVE_ICMR,
64 SLEEP_SAVE_CKEN, 61 SLEEP_SAVE_CKEN,
65 62
63#ifdef CONFIG_PXA27x
64 SLEEP_SAVE_MDREFR,
65 SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER,
66 SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR,
67#endif
68
66 SLEEP_SAVE_CKSUM, 69 SLEEP_SAVE_CKSUM,
67 70
68 SLEEP_SAVE_SIZE 71 SLEEP_SAVE_SIZE
@@ -75,9 +78,7 @@ static int pxa_pm_enter(suspend_state_t state)
75 unsigned long checksum = 0; 78 unsigned long checksum = 0;
76 struct timespec delta, rtc; 79 struct timespec delta, rtc;
77 int i; 80 int i;
78 81 extern void pxa_cpu_pm_enter(suspend_state_t state);
79 if (state != PM_SUSPEND_MEM)
80 return -EINVAL;
81 82
82#ifdef CONFIG_IWMMXT 83#ifdef CONFIG_IWMMXT
83 /* force any iWMMXt context to ram **/ 84 /* force any iWMMXt context to ram **/
@@ -100,16 +101,17 @@ static int pxa_pm_enter(suspend_state_t state)
100 SAVE(GAFR2_L); SAVE(GAFR2_U); 101 SAVE(GAFR2_L); SAVE(GAFR2_U);
101 102
102#ifdef CONFIG_PXA27x 103#ifdef CONFIG_PXA27x
104 SAVE(MDREFR);
103 SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3); 105 SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3);
104 SAVE(GAFR3_L); SAVE(GAFR3_U); 106 SAVE(GAFR3_L); SAVE(GAFR3_U);
107 SAVE(PWER); SAVE(PCFR); SAVE(PRER);
108 SAVE(PFER); SAVE(PKWR);
105#endif 109#endif
106 110
107 SAVE(ICMR); 111 SAVE(ICMR);
108 ICMR = 0; 112 ICMR = 0;
109 113
110 SAVE(CKEN); 114 SAVE(CKEN);
111 CKEN = 0;
112
113 SAVE(PSTR); 115 SAVE(PSTR);
114 116
115 /* Note: wake up source are set up in each machine specific files */ 117 /* Note: wake up source are set up in each machine specific files */
@@ -123,16 +125,13 @@ static int pxa_pm_enter(suspend_state_t state)
123 /* Clear sleep reset status */ 125 /* Clear sleep reset status */
124 RCSR = RCSR_SMR; 126 RCSR = RCSR_SMR;
125 127
126 /* set resume return address */
127 PSPR = virt_to_phys(pxa_cpu_resume);
128
129 /* before sleeping, calculate and save a checksum */ 128 /* before sleeping, calculate and save a checksum */
130 for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++) 129 for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
131 checksum += sleep_save[i]; 130 checksum += sleep_save[i];
132 sleep_save[SLEEP_SAVE_CKSUM] = checksum; 131 sleep_save[SLEEP_SAVE_CKSUM] = checksum;
133 132
134 /* *** go zzz *** */ 133 /* *** go zzz *** */
135 pxa_cpu_suspend(); 134 pxa_cpu_pm_enter(state);
136 135
137 /* after sleeping, validate the checksum */ 136 /* after sleeping, validate the checksum */
138 checksum = 0; 137 checksum = 0;
@@ -145,7 +144,7 @@ static int pxa_pm_enter(suspend_state_t state)
145 LUB_HEXLED = 0xbadbadc5; 144 LUB_HEXLED = 0xbadbadc5;
146#endif 145#endif
147 while (1) 146 while (1)
148 pxa_cpu_suspend(); 147 pxa_cpu_pm_enter(state);
149 } 148 }
150 149
151 /* ensure not to come back here if it wasn't intended */ 150 /* ensure not to come back here if it wasn't intended */
@@ -162,8 +161,11 @@ static int pxa_pm_enter(suspend_state_t state)
162 RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); 161 RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2);
163 162
164#ifdef CONFIG_PXA27x 163#ifdef CONFIG_PXA27x
164 RESTORE(MDREFR);
165 RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3); 165 RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3);
166 RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3); 166 RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3);
167 RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER);
168 RESTORE(PFER); RESTORE(PKWR);
167#endif 169#endif
168 170
169 PSSR = PSSR_RDH | PSSR_PH; 171 PSSR = PSSR_RDH | PSSR_PH;
@@ -197,7 +199,9 @@ unsigned long sleep_phys_sp(void *sp)
197 */ 199 */
198static int pxa_pm_prepare(suspend_state_t state) 200static int pxa_pm_prepare(suspend_state_t state)
199{ 201{
200 return 0; 202 extern int pxa_cpu_pm_prepare(suspend_state_t state);
203
204 return pxa_cpu_pm_prepare(state);
201} 205}
202 206
203/* 207/*
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index e887b7175ef3..7869c3b4e62f 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -16,6 +16,7 @@
16 * initialization stuff for PXA machines which can be overridden later if 16 * initialization stuff for PXA machines which can be overridden later if
17 * need be. 17 * need be.
18 */ 18 */
19#include <linux/config.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/kernel.h> 21#include <linux/kernel.h>
21#include <linux/init.h> 22#include <linux/init.h>
@@ -102,3 +103,35 @@ unsigned int get_lcdclk_frequency_10khz(void)
102} 103}
103 104
104EXPORT_SYMBOL(get_lcdclk_frequency_10khz); 105EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
106
107#ifdef CONFIG_PM
108
109int pxa_cpu_pm_prepare(suspend_state_t state)
110{
111 switch (state) {
112 case PM_SUSPEND_MEM:
113 break;
114 default:
115 return -EINVAL;
116 }
117
118 return 0;
119}
120
121void pxa_cpu_pm_enter(suspend_state_t state)
122{
123 extern void pxa_cpu_suspend(unsigned int);
124 extern void pxa_cpu_resume(void);
125
126 CKEN = 0;
127
128 switch (state) {
129 case PM_SUSPEND_MEM:
130 /* set resume return address */
131 PSPR = virt_to_phys(pxa_cpu_resume);
132 pxa_cpu_suspend(3);
133 break;
134 }
135}
136
137#endif
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 7e863afefb53..893964fb9659 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -120,6 +120,42 @@ EXPORT_SYMBOL(get_clk_frequency_khz);
120EXPORT_SYMBOL(get_memclk_frequency_10khz); 120EXPORT_SYMBOL(get_memclk_frequency_10khz);
121EXPORT_SYMBOL(get_lcdclk_frequency_10khz); 121EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
122 122
123#ifdef CONFIG_PM
124
125int pxa_cpu_pm_prepare(suspend_state_t state)
126{
127 switch (state) {
128 case PM_SUSPEND_MEM:
129 return 0;
130 default:
131 return -EINVAL;
132 }
133}
134
135void pxa_cpu_pm_enter(suspend_state_t state)
136{
137 extern void pxa_cpu_standby(void);
138 extern void pxa_cpu_suspend(unsigned int);
139 extern void pxa_cpu_resume(void);
140
141 CKEN = CKEN22_MEMC | CKEN9_OSTIMER;
142
143 /* ensure voltage-change sequencer not initiated, which hangs */
144 PCFR &= ~PCFR_FVC;
145
146 /* Clear edge-detect status register. */
147 PEDR = 0xDF12FE1B;
148
149 switch (state) {
150 case PM_SUSPEND_MEM:
151 /* set resume return address */
152 PSPR = virt_to_phys(pxa_cpu_resume);
153 pxa_cpu_suspend(3);
154 break;
155 }
156}
157
158#endif
123 159
124/* 160/*
125 * device registration specific to PXA27x. 161 * device registration specific to PXA27x.
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index e23f534d4e1d..8d986b8401c2 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -478,7 +478,7 @@ static int s3c2440_clk_add(struct sys_device *sysdev)
478{ 478{
479 unsigned long upllcon = __raw_readl(S3C2410_UPLLCON); 479 unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
480 480
481 s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal.rate) * 2; 481 s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal.rate);
482 482
483 printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n", 483 printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n",
484 print_mhz(s3c2440_clk_upll.rate)); 484 print_mhz(s3c2440_clk_upll.rate));
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
index bc229fab86d4..c7c28890d406 100644
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -785,6 +785,10 @@ int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *client)
785 chan->client = NULL; 785 chan->client = NULL;
786 chan->in_use = 0; 786 chan->in_use = 0;
787 787
788 if (chan->irq_claimed)
789 free_irq(chan->irq, (void *)chan);
790 chan->irq_claimed = 0;
791
788 local_irq_restore(flags); 792 local_irq_restore(flags);
789 793
790 return 0; 794 return 0;
diff --git a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2410/s3c2440.c
index 9a8cc5ae2255..d4c8281b55f6 100644
--- a/arch/arm/mach-s3c2410/s3c2440.c
+++ b/arch/arm/mach-s3c2410/s3c2440.c
@@ -192,9 +192,11 @@ void __init s3c2440_map_io(struct map_desc *mach_desc, int size)
192 192
193 iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc)); 193 iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc));
194 iotable_init(mach_desc, size); 194 iotable_init(mach_desc, size);
195
195 /* rename any peripherals used differing from the s3c2410 */ 196 /* rename any peripherals used differing from the s3c2410 */
196 197
197 s3c_device_i2c.name = "s3c2440-i2c"; 198 s3c_device_i2c.name = "s3c2440-i2c";
199 s3c_device_nand.name = "s3c2440-nand";
198 200
199 /* change irq for watchdog */ 201 /* change irq for watchdog */
200 202
@@ -225,7 +227,7 @@ void __init s3c2440_init_clocks(int xtal)
225 break; 227 break;
226 228
227 case S3C2440_CLKDIVN_HDIVN_2: 229 case S3C2440_CLKDIVN_HDIVN_2:
228 hdiv = 1; 230 hdiv = 2;
229 break; 231 break;
230 232
231 case S3C2440_CLKDIVN_HDIVN_4_8: 233 case S3C2440_CLKDIVN_HDIVN_4_8:
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index 50cde576dadf..6923316b3d0d 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -150,7 +150,7 @@ config SA1100_SSP
150 150
151config H3600_SLEEVE 151config H3600_SLEEVE
152 tristate "Compaq iPAQ Handheld sleeve support" 152 tristate "Compaq iPAQ Handheld sleeve support"
153 depends on SA1100_H3600 153 depends on SA1100_H3100 || SA1100_H3600
154 help 154 help
155 Choose this option to enable support for extension packs (sleeves) 155 Choose this option to enable support for extension packs (sleeves)
156 for the Compaq iPAQ H3XXX series of handheld computers. This option 156 for the Compaq iPAQ H3XXX series of handheld computers. This option
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 27892e34b060..3fefb43c67f7 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -228,7 +228,6 @@ config CPU_SA1100
228 select CPU_CACHE_V4WB 228 select CPU_CACHE_V4WB
229 select CPU_CACHE_VIVT 229 select CPU_CACHE_VIVT
230 select CPU_TLB_V4WB 230 select CPU_TLB_V4WB
231 select CPU_MINICACHE
232 231
233# XScale 232# XScale
234config CPU_XSCALE 233config CPU_XSCALE
@@ -239,7 +238,6 @@ config CPU_XSCALE
239 select CPU_ABRT_EV5T 238 select CPU_ABRT_EV5T
240 select CPU_CACHE_VIVT 239 select CPU_CACHE_VIVT
241 select CPU_TLB_V4WBI 240 select CPU_TLB_V4WBI
242 select CPU_MINICACHE
243 241
244# ARMv6 242# ARMv6
245config CPU_V6 243config CPU_V6
@@ -345,11 +343,6 @@ config CPU_TLB_V4WBI
345config CPU_TLB_V6 343config CPU_TLB_V6
346 bool 344 bool
347 345
348config CPU_MINICACHE
349 bool
350 help
351 Processor has a minicache.
352
353comment "Processor Features" 346comment "Processor Features"
354 347
355config ARM_THUMB 348config ARM_THUMB
@@ -410,17 +403,30 @@ config CPU_BPREDICT_DISABLE
410 help 403 help
411 Say Y here to disable branch prediction. If unsure, say N. 404 Say Y here to disable branch prediction. If unsure, say N.
412 405
406config TLS_REG_EMUL
407 bool
408 default y if SMP && (CPU_32v5 || CPU_32v4 || CPU_32v3)
409 help
410 An SMP system using a pre-ARMv6 processor (there are apparently
411 a few prototypes like that in existence) and therefore access to
412 that required register must be emulated.
413
413config HAS_TLS_REG 414config HAS_TLS_REG
414 bool 415 bool
415 depends on CPU_32v6 && !CPU_32v5 && !CPU_32v4 && !CPU_32v3 416 depends on !TLS_REG_EMUL
416 default y 417 default y if SMP || CPU_32v7
417 help 418 help
418 This selects support for the CP15 thread register. 419 This selects support for the CP15 thread register.
419 It is defined to be available on ARMv6 or later. However 420 It is defined to be available on some ARMv6 processors (including
420 if the kernel is configured to support multiple CPUs including 421 all SMP capable ARMv6's) or later processors. User space may
421 a pre-ARMv6 processors, or if a given ARMv6 processor doesn't 422 assume directly accessing that register and always obtain the
422 implement the thread register for some reason, then access to 423 expected value only on ARMv7 and above.
423 this register from user space must be trapped and emulated. 424
424 If user space is relying on the __kuser_get_tls code then 425config NEEDS_SYSCALL_FOR_CMPXCHG
425 there should not be any impact. 426 bool
427 default y if SMP && (CPU_32v5 || CPU_32v4 || CPU_32v3)
428 help
429 SMP on a pre-ARMv6 processor? Well OK then.
430 Forget about fast user space cmpxchg support.
431 It is just not possible.
426 432
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index ccf316c11e02..59f47d4c2dfe 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -31,8 +31,6 @@ obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o mmu.o
31obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o 31obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o
32obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o 32obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o
33 33
34obj-$(CONFIG_CPU_MINICACHE) += minicache.o
35
36obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o 34obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o
37obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o 35obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o
38obj-$(CONFIG_CPU_TLB_V4WB) += tlb-v4wb.o 36obj-$(CONFIG_CPU_TLB_V4WB) += tlb-v4wb.o
diff --git a/arch/arm/mm/copypage-v4mc.S b/arch/arm/mm/copypage-v4mc.S
deleted file mode 100644
index 305af3dab3d8..000000000000
--- a/arch/arm/mm/copypage-v4mc.S
+++ /dev/null
@@ -1,80 +0,0 @@
1/*
2 * linux/arch/arm/lib/copy_page-armv4mc.S
3 *
4 * Copyright (C) 1995-2001 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ASM optimised string functions
11 */
12#include <linux/linkage.h>
13#include <linux/init.h>
14#include <asm/constants.h>
15
16 .text
17 .align 5
18/*
19 * ARMv4 mini-dcache optimised copy_user_page
20 *
21 * We flush the destination cache lines just before we write the data into the
22 * corresponding address. Since the Dcache is read-allocate, this removes the
23 * Dcache aliasing issue. The writes will be forwarded to the write buffer,
24 * and merged as appropriate.
25 *
26 * Note: We rely on all ARMv4 processors implementing the "invalidate D line"
27 * instruction. If your processor does not supply this, you have to write your
28 * own copy_user_page that does the right thing.
29 */
30ENTRY(v4_mc_copy_user_page)
31 stmfd sp!, {r4, lr} @ 2
32 mov r4, r0
33 mov r0, r1
34 bl map_page_minicache
35 mov r1, #PAGE_SZ/64 @ 1
36 ldmia r0!, {r2, r3, ip, lr} @ 4
371: mcr p15, 0, r4, c7, c6, 1 @ 1 invalidate D line
38 stmia r4!, {r2, r3, ip, lr} @ 4
39 ldmia r0!, {r2, r3, ip, lr} @ 4+1
40 stmia r4!, {r2, r3, ip, lr} @ 4
41 ldmia r0!, {r2, r3, ip, lr} @ 4
42 mcr p15, 0, r4, c7, c6, 1 @ 1 invalidate D line
43 stmia r4!, {r2, r3, ip, lr} @ 4
44 ldmia r0!, {r2, r3, ip, lr} @ 4
45 subs r1, r1, #1 @ 1
46 stmia r4!, {r2, r3, ip, lr} @ 4
47 ldmneia r0!, {r2, r3, ip, lr} @ 4
48 bne 1b @ 1
49 ldmfd sp!, {r4, pc} @ 3
50
51 .align 5
52/*
53 * ARMv4 optimised clear_user_page
54 *
55 * Same story as above.
56 */
57ENTRY(v4_mc_clear_user_page)
58 str lr, [sp, #-4]!
59 mov r1, #PAGE_SZ/64 @ 1
60 mov r2, #0 @ 1
61 mov r3, #0 @ 1
62 mov ip, #0 @ 1
63 mov lr, #0 @ 1
641: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line
65 stmia r0!, {r2, r3, ip, lr} @ 4
66 stmia r0!, {r2, r3, ip, lr} @ 4
67 mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line
68 stmia r0!, {r2, r3, ip, lr} @ 4
69 stmia r0!, {r2, r3, ip, lr} @ 4
70 subs r1, r1, #1 @ 1
71 bne 1b @ 1
72 ldr pc, [sp], #4
73
74 __INITDATA
75
76 .type v4_mc_user_fns, #object
77ENTRY(v4_mc_user_fns)
78 .long v4_mc_clear_user_page
79 .long v4_mc_copy_user_page
80 .size v4_mc_user_fns, . - v4_mc_user_fns
diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c
new file mode 100644
index 000000000000..fc69dccdace1
--- /dev/null
+++ b/arch/arm/mm/copypage-v4mc.c
@@ -0,0 +1,111 @@
1/*
2 * linux/arch/arm/lib/copypage-armv4mc.S
3 *
4 * Copyright (C) 1995-2005 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This handles the mini data cache, as found on SA11x0 and XScale
11 * processors. When we copy a user page page, we map it in such a way
12 * that accesses to this page will not touch the main data cache, but
13 * will be cached in the mini data cache. This prevents us thrashing
14 * the main data cache on page faults.
15 */
16#include <linux/init.h>
17#include <linux/mm.h>
18
19#include <asm/page.h>
20#include <asm/pgtable.h>
21#include <asm/tlbflush.h>
22
23/*
24 * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
25 * specific hacks for copying pages efficiently.
26 */
27#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
28 L_PTE_CACHEABLE)
29
30#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)
31
32static DEFINE_SPINLOCK(minicache_lock);
33
34/*
35 * ARMv4 mini-dcache optimised copy_user_page
36 *
37 * We flush the destination cache lines just before we write the data into the
38 * corresponding address. Since the Dcache is read-allocate, this removes the
39 * Dcache aliasing issue. The writes will be forwarded to the write buffer,
40 * and merged as appropriate.
41 *
42 * Note: We rely on all ARMv4 processors implementing the "invalidate D line"
43 * instruction. If your processor does not supply this, you have to write your
44 * own copy_user_page that does the right thing.
45 */
46static void __attribute__((naked))
47mc_copy_user_page(void *from, void *to)
48{
49 asm volatile(
50 "stmfd sp!, {r4, lr} @ 2\n\
51 mov r4, %2 @ 1\n\
52 ldmia %0!, {r2, r3, ip, lr} @ 4\n\
531: mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\
54 stmia %1!, {r2, r3, ip, lr} @ 4\n\
55 ldmia %0!, {r2, r3, ip, lr} @ 4+1\n\
56 stmia %1!, {r2, r3, ip, lr} @ 4\n\
57 ldmia %0!, {r2, r3, ip, lr} @ 4\n\
58 mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\
59 stmia %1!, {r2, r3, ip, lr} @ 4\n\
60 ldmia %0!, {r2, r3, ip, lr} @ 4\n\
61 subs r4, r4, #1 @ 1\n\
62 stmia %1!, {r2, r3, ip, lr} @ 4\n\
63 ldmneia %0!, {r2, r3, ip, lr} @ 4\n\
64 bne 1b @ 1\n\
65 ldmfd sp!, {r4, pc} @ 3"
66 :
67 : "r" (from), "r" (to), "I" (PAGE_SIZE / 64));
68}
69
70void v4_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
71{
72 spin_lock(&minicache_lock);
73
74 set_pte(TOP_PTE(0xffff8000), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot));
75 flush_tlb_kernel_page(0xffff8000);
76
77 mc_copy_user_page((void *)0xffff8000, kto);
78
79 spin_unlock(&minicache_lock);
80}
81
82/*
83 * ARMv4 optimised clear_user_page
84 */
85void __attribute__((naked))
86v4_mc_clear_user_page(void *kaddr, unsigned long vaddr)
87{
88 asm volatile(
89 "str lr, [sp, #-4]!\n\
90 mov r1, %0 @ 1\n\
91 mov r2, #0 @ 1\n\
92 mov r3, #0 @ 1\n\
93 mov ip, #0 @ 1\n\
94 mov lr, #0 @ 1\n\
951: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\
96 stmia r0!, {r2, r3, ip, lr} @ 4\n\
97 stmia r0!, {r2, r3, ip, lr} @ 4\n\
98 mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\
99 stmia r0!, {r2, r3, ip, lr} @ 4\n\
100 stmia r0!, {r2, r3, ip, lr} @ 4\n\
101 subs r1, r1, #1 @ 1\n\
102 bne 1b @ 1\n\
103 ldr pc, [sp], #4"
104 :
105 : "I" (PAGE_SIZE / 64));
106}
107
108struct cpu_user_fns v4_mc_user_fns __initdata = {
109 .cpu_clear_user_page = v4_mc_clear_user_page,
110 .cpu_copy_user_page = v4_mc_copy_user_page,
111};
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
index 694ac8208858..a8c00236bd3d 100644
--- a/arch/arm/mm/copypage-v6.c
+++ b/arch/arm/mm/copypage-v6.c
@@ -26,8 +26,8 @@
26#define to_address (0xffffc000) 26#define to_address (0xffffc000)
27#define to_pgprot PAGE_KERNEL 27#define to_pgprot PAGE_KERNEL
28 28
29static pte_t *from_pte; 29#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)
30static pte_t *to_pte; 30
31static DEFINE_SPINLOCK(v6_lock); 31static DEFINE_SPINLOCK(v6_lock);
32 32
33#define DCACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT) 33#define DCACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
@@ -74,8 +74,8 @@ void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vadd
74 */ 74 */
75 spin_lock(&v6_lock); 75 spin_lock(&v6_lock);
76 76
77 set_pte(from_pte + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot)); 77 set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot));
78 set_pte(to_pte + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot)); 78 set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot));
79 79
80 from = from_address + (offset << PAGE_SHIFT); 80 from = from_address + (offset << PAGE_SHIFT);
81 to = to_address + (offset << PAGE_SHIFT); 81 to = to_address + (offset << PAGE_SHIFT);
@@ -114,7 +114,7 @@ void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
114 */ 114 */
115 spin_lock(&v6_lock); 115 spin_lock(&v6_lock);
116 116
117 set_pte(to_pte + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot)); 117 set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot));
118 flush_tlb_kernel_page(to); 118 flush_tlb_kernel_page(to);
119 clear_page((void *)to); 119 clear_page((void *)to);
120 120
@@ -129,21 +129,6 @@ struct cpu_user_fns v6_user_fns __initdata = {
129static int __init v6_userpage_init(void) 129static int __init v6_userpage_init(void)
130{ 130{
131 if (cache_is_vipt_aliasing()) { 131 if (cache_is_vipt_aliasing()) {
132 pgd_t *pgd;
133 pmd_t *pmd;
134
135 pgd = pgd_offset_k(from_address);
136 pmd = pmd_alloc(&init_mm, pgd, from_address);
137 if (!pmd)
138 BUG();
139 from_pte = pte_alloc_kernel(&init_mm, pmd, from_address);
140 if (!from_pte)
141 BUG();
142
143 to_pte = pte_alloc_kernel(&init_mm, pmd, to_address);
144 if (!to_pte)
145 BUG();
146
147 cpu_user.cpu_clear_user_page = v6_clear_user_page_aliasing; 132 cpu_user.cpu_clear_user_page = v6_clear_user_page_aliasing;
148 cpu_user.cpu_copy_user_page = v6_copy_user_page_aliasing; 133 cpu_user.cpu_copy_user_page = v6_copy_user_page_aliasing;
149 } 134 }
@@ -151,5 +136,4 @@ static int __init v6_userpage_init(void)
151 return 0; 136 return 0;
152} 137}
153 138
154__initcall(v6_userpage_init); 139core_initcall(v6_userpage_init);
155
diff --git a/arch/arm/mm/copypage-xscale.S b/arch/arm/mm/copypage-xscale.S
deleted file mode 100644
index bb277316ef52..000000000000
--- a/arch/arm/mm/copypage-xscale.S
+++ /dev/null
@@ -1,113 +0,0 @@
1/*
2 * linux/arch/arm/lib/copypage-xscale.S
3 *
4 * Copyright (C) 2001 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <linux/init.h>
12#include <asm/constants.h>
13
14/*
15 * General note:
16 * We don't really want write-allocate cache behaviour for these functions
17 * since that will just eat through 8K of the cache.
18 */
19
20 .text
21 .align 5
22/*
23 * XScale optimised copy_user_page
24 * r0 = destination
25 * r1 = source
26 * r2 = virtual user address of ultimate destination page
27 *
28 * The source page may have some clean entries in the cache already, but we
29 * can safely ignore them - break_cow() will flush them out of the cache
30 * if we eventually end up using our copied page.
31 *
32 * What we could do is use the mini-cache to buffer reads from the source
33 * page. We rely on the mini-cache being smaller than one page, so we'll
34 * cycle through the complete cache anyway.
35 */
36ENTRY(xscale_mc_copy_user_page)
37 stmfd sp!, {r4, r5, lr}
38 mov r5, r0
39 mov r0, r1
40 bl map_page_minicache
41 mov r1, r5
42 mov lr, #PAGE_SZ/64-1
43
44 /*
45 * Strangely enough, best performance is achieved
46 * when prefetching destination as well. (NP)
47 */
48 pld [r0, #0]
49 pld [r0, #32]
50 pld [r1, #0]
51 pld [r1, #32]
52
531: pld [r0, #64]
54 pld [r0, #96]
55 pld [r1, #64]
56 pld [r1, #96]
57
582: ldrd r2, [r0], #8
59 ldrd r4, [r0], #8
60 mov ip, r1
61 strd r2, [r1], #8
62 ldrd r2, [r0], #8
63 strd r4, [r1], #8
64 ldrd r4, [r0], #8
65 strd r2, [r1], #8
66 strd r4, [r1], #8
67 mcr p15, 0, ip, c7, c10, 1 @ clean D line
68 ldrd r2, [r0], #8
69 mcr p15, 0, ip, c7, c6, 1 @ invalidate D line
70 ldrd r4, [r0], #8
71 mov ip, r1
72 strd r2, [r1], #8
73 ldrd r2, [r0], #8
74 strd r4, [r1], #8
75 ldrd r4, [r0], #8
76 strd r2, [r1], #8
77 strd r4, [r1], #8
78 mcr p15, 0, ip, c7, c10, 1 @ clean D line
79 subs lr, lr, #1
80 mcr p15, 0, ip, c7, c6, 1 @ invalidate D line
81 bgt 1b
82 beq 2b
83
84 ldmfd sp!, {r4, r5, pc}
85
86 .align 5
87/*
88 * XScale optimised clear_user_page
89 * r0 = destination
90 * r1 = virtual user address of ultimate destination page
91 */
92ENTRY(xscale_mc_clear_user_page)
93 mov r1, #PAGE_SZ/32
94 mov r2, #0
95 mov r3, #0
961: mov ip, r0
97 strd r2, [r0], #8
98 strd r2, [r0], #8
99 strd r2, [r0], #8
100 strd r2, [r0], #8
101 mcr p15, 0, ip, c7, c10, 1 @ clean D line
102 subs r1, r1, #1
103 mcr p15, 0, ip, c7, c6, 1 @ invalidate D line
104 bne 1b
105 mov pc, lr
106
107 __INITDATA
108
109 .type xscale_mc_user_fns, #object
110ENTRY(xscale_mc_user_fns)
111 .long xscale_mc_clear_user_page
112 .long xscale_mc_copy_user_page
113 .size xscale_mc_user_fns, . - xscale_mc_user_fns
diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c
new file mode 100644
index 000000000000..42a6ee255ce0
--- /dev/null
+++ b/arch/arm/mm/copypage-xscale.c
@@ -0,0 +1,131 @@
1/*
2 * linux/arch/arm/lib/copypage-xscale.S
3 *
4 * Copyright (C) 1995-2005 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This handles the mini data cache, as found on SA11x0 and XScale
11 * processors. When we copy a user page page, we map it in such a way
12 * that accesses to this page will not touch the main data cache, but
13 * will be cached in the mini data cache. This prevents us thrashing
14 * the main data cache on page faults.
15 */
16#include <linux/init.h>
17#include <linux/mm.h>
18
19#include <asm/page.h>
20#include <asm/pgtable.h>
21#include <asm/tlbflush.h>
22
23/*
24 * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
25 * specific hacks for copying pages efficiently.
26 */
27#define COPYPAGE_MINICACHE 0xffff8000
28
29#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
30 L_PTE_CACHEABLE)
31
32#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)
33
34static DEFINE_SPINLOCK(minicache_lock);
35
36/*
37 * XScale mini-dcache optimised copy_user_page
38 *
39 * We flush the destination cache lines just before we write the data into the
40 * corresponding address. Since the Dcache is read-allocate, this removes the
41 * Dcache aliasing issue. The writes will be forwarded to the write buffer,
42 * and merged as appropriate.
43 */
44static void __attribute__((naked))
45mc_copy_user_page(void *from, void *to)
46{
47 /*
48 * Strangely enough, best performance is achieved
49 * when prefetching destination as well. (NP)
50 */
51 asm volatile(
52 "stmfd sp!, {r4, r5, lr} \n\
53 mov lr, %2 \n\
54 pld [r0, #0] \n\
55 pld [r0, #32] \n\
56 pld [r1, #0] \n\
57 pld [r1, #32] \n\
581: pld [r0, #64] \n\
59 pld [r0, #96] \n\
60 pld [r1, #64] \n\
61 pld [r1, #96] \n\
622: ldrd r2, [r0], #8 \n\
63 ldrd r4, [r0], #8 \n\
64 mov ip, r1 \n\
65 strd r2, [r1], #8 \n\
66 ldrd r2, [r0], #8 \n\
67 strd r4, [r1], #8 \n\
68 ldrd r4, [r0], #8 \n\
69 strd r2, [r1], #8 \n\
70 strd r4, [r1], #8 \n\
71 mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
72 ldrd r2, [r0], #8 \n\
73 mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
74 ldrd r4, [r0], #8 \n\
75 mov ip, r1 \n\
76 strd r2, [r1], #8 \n\
77 ldrd r2, [r0], #8 \n\
78 strd r4, [r1], #8 \n\
79 ldrd r4, [r0], #8 \n\
80 strd r2, [r1], #8 \n\
81 strd r4, [r1], #8 \n\
82 mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
83 subs lr, lr, #1 \n\
84 mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
85 bgt 1b \n\
86 beq 2b \n\
87 ldmfd sp!, {r4, r5, pc} "
88 :
89 : "r" (from), "r" (to), "I" (PAGE_SIZE / 64 - 1));
90}
91
92void xscale_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
93{
94 spin_lock(&minicache_lock);
95
96 set_pte(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot));
97 flush_tlb_kernel_page(COPYPAGE_MINICACHE);
98
99 mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto);
100
101 spin_unlock(&minicache_lock);
102}
103
104/*
105 * XScale optimised clear_user_page
106 */
107void __attribute__((naked))
108xscale_mc_clear_user_page(void *kaddr, unsigned long vaddr)
109{
110 asm volatile(
111 "mov r1, %0 \n\
112 mov r2, #0 \n\
113 mov r3, #0 \n\
1141: mov ip, r0 \n\
115 strd r2, [r0], #8 \n\
116 strd r2, [r0], #8 \n\
117 strd r2, [r0], #8 \n\
118 strd r2, [r0], #8 \n\
119 mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
120 subs r1, r1, #1 \n\
121 mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
122 bne 1b \n\
123 mov pc, lr"
124 :
125 : "I" (PAGE_SIZE / 32));
126}
127
128struct cpu_user_fns xscale_mc_user_fns __initdata = {
129 .cpu_clear_user_page = xscale_mc_clear_user_page,
130 .cpu_copy_user_page = xscale_mc_copy_user_page,
131};
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index c6de48d89503..4085ed983e46 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -13,6 +13,29 @@
13 13
14#include <asm/cacheflush.h> 14#include <asm/cacheflush.h>
15#include <asm/system.h> 15#include <asm/system.h>
16#include <asm/tlbflush.h>
17
18#ifdef CONFIG_CPU_CACHE_VIPT
19#define ALIAS_FLUSH_START 0xffff4000
20
21#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)
22
23static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
24{
25 unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
26
27 set_pte(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL));
28 flush_tlb_kernel_page(to);
29
30 asm( "mcrr p15, 0, %1, %0, c14\n"
31 " mcrr p15, 0, %1, %0, c5\n"
32 :
33 : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES)
34 : "cc");
35}
36#else
37#define flush_pfn_alias(pfn,vaddr) do { } while (0)
38#endif
16 39
17static void __flush_dcache_page(struct address_space *mapping, struct page *page) 40static void __flush_dcache_page(struct address_space *mapping, struct page *page)
18{ 41{
@@ -37,6 +60,18 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page
37 return; 60 return;
38 61
39 /* 62 /*
63 * This is a page cache page. If we have a VIPT cache, we
64 * only need to do one flush - which would be at the relevant
65 * userspace colour, which is congruent with page->index.
66 */
67 if (cache_is_vipt()) {
68 if (cache_is_vipt_aliasing())
69 flush_pfn_alias(page_to_pfn(page),
70 page->index << PAGE_CACHE_SHIFT);
71 return;
72 }
73
74 /*
40 * There are possible user space mappings of this page: 75 * There are possible user space mappings of this page:
41 * - VIVT cache: we need to also write back and invalidate all user 76 * - VIVT cache: we need to also write back and invalidate all user
42 * data in the current VM view associated with this page. 77 * data in the current VM view associated with this page.
@@ -57,8 +92,6 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page
57 continue; 92 continue;
58 offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT; 93 offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
59 flush_cache_page(mpnt, mpnt->vm_start + offset, page_to_pfn(page)); 94 flush_cache_page(mpnt, mpnt->vm_start + offset, page_to_pfn(page));
60 if (cache_is_vipt())
61 break;
62 } 95 }
63 flush_dcache_mmap_unlock(mapping); 96 flush_dcache_mmap_unlock(mapping);
64} 97}
diff --git a/arch/arm/mm/minicache.c b/arch/arm/mm/minicache.c
deleted file mode 100644
index dedf2ab01b2a..000000000000
--- a/arch/arm/mm/minicache.c
+++ /dev/null
@@ -1,73 +0,0 @@
1/*
2 * linux/arch/arm/mm/minicache.c
3 *
4 * Copyright (C) 2001 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This handles the mini data cache, as found on SA11x0 and XScale
11 * processors. When we copy a user page page, we map it in such a way
12 * that accesses to this page will not touch the main data cache, but
13 * will be cached in the mini data cache. This prevents us thrashing
14 * the main data cache on page faults.
15 */
16#include <linux/init.h>
17#include <linux/mm.h>
18
19#include <asm/page.h>
20#include <asm/pgtable.h>
21#include <asm/tlbflush.h>
22
23/*
24 * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
25 * specific hacks for copying pages efficiently.
26 */
27#define minicache_address (0xffff8000)
28#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
29 L_PTE_CACHEABLE)
30
31static pte_t *minicache_pte;
32
33/*
34 * Note that this is intended to be called only from the copy_user_page
35 * asm code; anything else will require special locking to prevent the
36 * mini-cache space being re-used. (Note: probably preempt unsafe).
37 *
38 * We rely on the fact that the minicache is 2K, and we'll be pushing
39 * 4K of data through it, so we don't actually have to specifically
40 * flush the minicache when we change the mapping.
41 *
42 * Note also: assert(PAGE_OFFSET <= virt < high_memory).
43 * Unsafe: preempt, kmap.
44 */
45unsigned long map_page_minicache(unsigned long virt)
46{
47 set_pte(minicache_pte, pfn_pte(__pa(virt) >> PAGE_SHIFT, minicache_pgprot));
48 flush_tlb_kernel_page(minicache_address);
49
50 return minicache_address;
51}
52
53static int __init minicache_init(void)
54{
55 pgd_t *pgd;
56 pmd_t *pmd;
57
58 spin_lock(&init_mm.page_table_lock);
59
60 pgd = pgd_offset_k(minicache_address);
61 pmd = pmd_alloc(&init_mm, pgd, minicache_address);
62 if (!pmd)
63 BUG();
64 minicache_pte = pte_alloc_kernel(&init_mm, pmd, minicache_address);
65 if (!minicache_pte)
66 BUG();
67
68 spin_unlock(&init_mm.page_table_lock);
69
70 return 0;
71}
72
73core_initcall(minicache_init);
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index 585dfb8e20b9..2c2b93d77d43 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -37,6 +37,8 @@ pgprot_t pgprot_kernel;
37 37
38EXPORT_SYMBOL(pgprot_kernel); 38EXPORT_SYMBOL(pgprot_kernel);
39 39
40pmd_t *top_pmd;
41
40struct cachepolicy { 42struct cachepolicy {
41 const char policy[16]; 43 const char policy[16];
42 unsigned int cr_mask; 44 unsigned int cr_mask;
@@ -142,6 +144,16 @@ __setup("noalign", noalign_setup);
142 144
143#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD) 145#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD)
144 146
147static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt)
148{
149 return pmd_offset(pgd, virt);
150}
151
152static inline pmd_t *pmd_off_k(unsigned long virt)
153{
154 return pmd_off(pgd_offset_k(virt), virt);
155}
156
145/* 157/*
146 * need to get a 16k page for level 1 158 * need to get a 16k page for level 1
147 */ 159 */
@@ -220,7 +232,7 @@ void free_pgd_slow(pgd_t *pgd)
220 return; 232 return;
221 233
222 /* pgd is always present and good */ 234 /* pgd is always present and good */
223 pmd = (pmd_t *)pgd; 235 pmd = pmd_off(pgd, 0);
224 if (pmd_none(*pmd)) 236 if (pmd_none(*pmd))
225 goto free; 237 goto free;
226 if (pmd_bad(*pmd)) { 238 if (pmd_bad(*pmd)) {
@@ -246,9 +258,8 @@ free:
246static inline void 258static inline void
247alloc_init_section(unsigned long virt, unsigned long phys, int prot) 259alloc_init_section(unsigned long virt, unsigned long phys, int prot)
248{ 260{
249 pmd_t *pmdp; 261 pmd_t *pmdp = pmd_off_k(virt);
250 262
251 pmdp = pmd_offset(pgd_offset_k(virt), virt);
252 if (virt & (1 << 20)) 263 if (virt & (1 << 20))
253 pmdp++; 264 pmdp++;
254 265
@@ -283,11 +294,9 @@ alloc_init_supersection(unsigned long virt, unsigned long phys, int prot)
283static inline void 294static inline void
284alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot) 295alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot)
285{ 296{
286 pmd_t *pmdp; 297 pmd_t *pmdp = pmd_off_k(virt);
287 pte_t *ptep; 298 pte_t *ptep;
288 299
289 pmdp = pmd_offset(pgd_offset_k(virt), virt);
290
291 if (pmd_none(*pmdp)) { 300 if (pmd_none(*pmdp)) {
292 unsigned long pmdval; 301 unsigned long pmdval;
293 ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * 302 ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE *
@@ -310,7 +319,7 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg
310 */ 319 */
311static inline void clear_mapping(unsigned long virt) 320static inline void clear_mapping(unsigned long virt)
312{ 321{
313 pmd_clear(pmd_offset(pgd_offset_k(virt), virt)); 322 pmd_clear(pmd_off_k(virt));
314} 323}
315 324
316struct mem_types { 325struct mem_types {
@@ -578,7 +587,7 @@ void setup_mm_for_reboot(char mode)
578 PMD_TYPE_SECT; 587 PMD_TYPE_SECT;
579 if (cpu_arch <= CPU_ARCH_ARMv5) 588 if (cpu_arch <= CPU_ARCH_ARMv5)
580 pmdval |= PMD_BIT4; 589 pmdval |= PMD_BIT4;
581 pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT); 590 pmd = pmd_off(pgd, i << PGDIR_SHIFT);
582 pmd[0] = __pmd(pmdval); 591 pmd[0] = __pmd(pmdval);
583 pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))); 592 pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));
584 flush_pmd_entry(pmd); 593 flush_pmd_entry(pmd);
@@ -675,6 +684,8 @@ void __init memtable_init(struct meminfo *mi)
675 684
676 flush_cache_all(); 685 flush_cache_all();
677 flush_tlb_all(); 686 flush_tlb_all();
687
688 top_pmd = pmd_off_k(0xffff0000);
678} 689}
679 690
680/* 691/*
diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig
index 3955de5af4c0..6caed90661fc 100644
--- a/arch/arm26/Kconfig
+++ b/arch/arm26/Kconfig
@@ -89,6 +89,10 @@ config PAGESIZE_16
89 machine with 4MB of memory. 89 machine with 4MB of memory.
90endmenu 90endmenu
91 91
92config ISA_DMA_API
93 bool
94 default y
95
92menu "General setup" 96menu "General setup"
93 97
94# Compressed boot loader in ROM. Yes, we really want to ask about 98# Compressed boot loader in ROM. Yes, we really want to ask about
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index 134aec1c6d19..b5f83e9f04db 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -54,7 +54,7 @@ asmlinkage void ret_from_fork(void);
54void default_idle(void) 54void default_idle(void)
55{ 55{
56 while(1) { 56 while(1) {
57 if (need_resched()) { 57 if (!need_resched()) {
58 local_irq_enable(); 58 local_irq_enable();
59 __asm__("sleep"); 59 __asm__("sleep");
60 local_irq_disable(); 60 local_irq_disable();
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 99b4f294a52d..dfd904f6883b 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -183,7 +183,7 @@ config M386
183 - "Winchip-C6" for original IDT Winchip. 183 - "Winchip-C6" for original IDT Winchip.
184 - "Winchip-2" for IDT Winchip 2. 184 - "Winchip-2" for IDT Winchip 2.
185 - "Winchip-2A" for IDT Winchips with 3dNow! capabilities. 185 - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
186 - "MediaGX/Geode" for Cyrix MediaGX aka Geode. 186 - "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
187 - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3. 187 - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
188 - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above). 188 - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
189 189
@@ -311,12 +311,10 @@ config MWINCHIP3D
311 stores for this CPU, which can increase performance of some 311 stores for this CPU, which can increase performance of some
312 operations. 312 operations.
313 313
314config MGEODE 314config MGEODEGX1
315 bool "MediaGX/Geode" 315 bool "GeodeGX1"
316 help 316 help
317 Select this for a Cyrix MediaGX aka Geode chip. Linux and GCC 317 Select this for a Geode GX1 (Cyrix MediaGX) chip.
318 treat this chip as a 586TSC with some extended instructions
319 and alignment reqirements.
320 318
321config MCYRIXIII 319config MCYRIXIII
322 bool "CyrixIII/VIA-C3" 320 bool "CyrixIII/VIA-C3"
@@ -368,7 +366,7 @@ config X86_L1_CACHE_SHIFT
368 int 366 int
369 default "7" if MPENTIUM4 || X86_GENERIC 367 default "7" if MPENTIUM4 || X86_GENERIC
370 default "4" if X86_ELAN || M486 || M386 368 default "4" if X86_ELAN || M486 || M386
371 default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE 369 default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1
372 default "6" if MK7 || MK8 || MPENTIUMM 370 default "6" if MK7 || MK8 || MPENTIUMM
373 371
374config RWSEM_GENERIC_SPINLOCK 372config RWSEM_GENERIC_SPINLOCK
@@ -387,7 +385,7 @@ config GENERIC_CALIBRATE_DELAY
387 385
388config X86_PPRO_FENCE 386config X86_PPRO_FENCE
389 bool 387 bool
390 depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODE 388 depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1
391 default y 389 default y
392 390
393config X86_F00F_BUG 391config X86_F00F_BUG
@@ -417,7 +415,7 @@ config X86_POPAD_OK
417 415
418config X86_ALIGNMENT_16 416config X86_ALIGNMENT_16
419 bool 417 bool
420 depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODE 418 depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
421 default y 419 default y
422 420
423config X86_GOOD_APIC 421config X86_GOOD_APIC
@@ -442,7 +440,7 @@ config X86_USE_3DNOW
442 440
443config X86_OOSTORE 441config X86_OOSTORE
444 bool 442 bool
445 depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MGEODE) && MTRR 443 depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR
446 default y 444 default y
447 445
448config HPET_TIMER 446config HPET_TIMER
@@ -578,7 +576,7 @@ config X86_VISWS_APIC
578 576
579config X86_TSC 577config X86_TSC
580 bool 578 bool
581 depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODE) && !X86_NUMAQ 579 depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ
582 default y 580 default y
583 581
584config X86_MCE 582config X86_MCE
@@ -1165,7 +1163,7 @@ config PCI_DIRECT
1165 1163
1166config PCI_MMCONFIG 1164config PCI_MMCONFIG
1167 bool 1165 bool
1168 depends on PCI && (PCI_GOMMCONFIG || (PCI_GOANY && ACPI)) 1166 depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY)
1169 select ACPI_BOOT 1167 select ACPI_BOOT
1170 default y 1168 default y
1171 1169
@@ -1173,6 +1171,10 @@ source "drivers/pci/pcie/Kconfig"
1173 1171
1174source "drivers/pci/Kconfig" 1172source "drivers/pci/Kconfig"
1175 1173
1174config ISA_DMA_API
1175 bool
1176 default y
1177
1176config ISA 1178config ISA
1177 bool "ISA support" 1179 bool "ISA support"
1178 depends on !(X86_VOYAGER || X86_VISWS) 1180 depends on !(X86_VOYAGER || X86_VISWS)
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 04783ceb050c..1c36ca332a96 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -14,7 +14,7 @@
14# 19990713 Artur Skawina <skawina@geocities.com> 14# 19990713 Artur Skawina <skawina@geocities.com>
15# Added '-march' and '-mpreferred-stack-boundary' support 15# Added '-march' and '-mpreferred-stack-boundary' support
16# 16#
17# Kianusch Sayah Karadji <kianusch@sk-tech.net> 17# 20050320 Kianusch Sayah Karadji <kianusch@sk-tech.net>
18# Added support for GEODE CPU 18# Added support for GEODE CPU
19 19
20LDFLAGS := -m elf_i386 20LDFLAGS := -m elf_i386
@@ -54,8 +54,8 @@ cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686)
54# AMD Elan support 54# AMD Elan support
55cflags-$(CONFIG_X86_ELAN) += -march=i486 55cflags-$(CONFIG_X86_ELAN) += -march=i486
56 56
57# MediaGX aka Geode support 57# Geode GX1 support
58cflags-$(CONFIG_MGEODE) += $(call cc-option,-march=pentium-mmx,-march=i586) 58cflags-$(CONFIG_MGEODEGX1) += $(call cc-option,-march=pentium-mmx,-march=i486)
59 59
60# -mregparm=3 works ok on gcc-3.0 and later 60# -mregparm=3 works ok on gcc-3.0 and later
61# 61#
diff --git a/arch/i386/boot/bootsect.S b/arch/i386/boot/bootsect.S
index ba9fe14db6a9..011b7a4993d4 100644
--- a/arch/i386/boot/bootsect.S
+++ b/arch/i386/boot/bootsect.S
@@ -83,7 +83,7 @@ bugger_off_msg:
83 .ascii "\n" 83 .ascii "\n"
84 .ascii "Remove disk and press any key to reboot . . .\r\n" 84 .ascii "Remove disk and press any key to reboot . . .\r\n"
85 .byte 0 85 .byte 0
86 86
87 87
88 # Kernel attributes; used by setup 88 # Kernel attributes; used by setup
89 89
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S
index 925d3f5a3824..0587477c99f2 100644
--- a/arch/i386/boot/video.S
+++ b/arch/i386/boot/video.S
@@ -1924,36 +1924,36 @@ skip10: movb %ah, %al
1924 ret 1924 ret
1925 1925
1926store_edid: 1926store_edid:
1927 pushw %es # just save all registers 1927 pushw %es # just save all registers
1928 pushw %ax 1928 pushw %ax
1929 pushw %bx 1929 pushw %bx
1930 pushw %cx 1930 pushw %cx
1931 pushw %dx 1931 pushw %dx
1932 pushw %di 1932 pushw %di
1933 1933
1934 pushw %fs 1934 pushw %fs
1935 popw %es 1935 popw %es
1936 1936
1937 movl $0x13131313, %eax # memset block with 0x13 1937 movl $0x13131313, %eax # memset block with 0x13
1938 movw $32, %cx 1938 movw $32, %cx
1939 movw $0x140, %di 1939 movw $0x140, %di
1940 cld 1940 cld
1941 rep 1941 rep
1942 stosl 1942 stosl
1943 1943
1944 movw $0x4f15, %ax # do VBE/DDC 1944 movw $0x4f15, %ax # do VBE/DDC
1945 movw $0x01, %bx 1945 movw $0x01, %bx
1946 movw $0x00, %cx 1946 movw $0x00, %cx
1947 movw $0x01, %dx 1947 movw $0x01, %dx
1948 movw $0x140, %di 1948 movw $0x140, %di
1949 int $0x10 1949 int $0x10
1950 1950
1951 popw %di # restore all registers 1951 popw %di # restore all registers
1952 popw %dx 1952 popw %dx
1953 popw %cx 1953 popw %cx
1954 popw %bx 1954 popw %bx
1955 popw %ax 1955 popw %ax
1956 popw %es 1956 popw %es
1957 ret 1957 ret
1958 1958
1959# VIDEO_SELECT-only variables 1959# VIDEO_SELECT-only variables
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index 0fbcfe00dd8d..51ecd512603d 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -43,7 +43,7 @@ obj-$(CONFIG_SCx200) += scx200.o
43# Note: kbuild does not track this dependency due to usage of .incbin 43# Note: kbuild does not track this dependency due to usage of .incbin
44$(obj)/vsyscall.o: $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so 44$(obj)/vsyscall.o: $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so
45targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so) 45targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so)
46targets += vsyscall.lds 46targets += vsyscall-note.o vsyscall.lds
47 47
48# The DSO images are built using a special linker script. 48# The DSO images are built using a special linker script.
49quiet_cmd_syscall = SYSCALL $@ 49quiet_cmd_syscall = SYSCALL $@
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index 53eb5cfd5b63..848bb97af7ca 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -650,7 +650,7 @@ acpi_find_rsdp (void)
650 */ 650 */
651 rsdp_phys = acpi_scan_rsdp (0, 0x400); 651 rsdp_phys = acpi_scan_rsdp (0, 0x400);
652 if (!rsdp_phys) 652 if (!rsdp_phys)
653 rsdp_phys = acpi_scan_rsdp (0xE0000, 0xFFFFF); 653 rsdp_phys = acpi_scan_rsdp (0xE0000, 0x20000);
654 654
655 return rsdp_phys; 655 return rsdp_phys;
656} 656}
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 45641a872550..0ff65abcd56c 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -1222,6 +1222,7 @@ static int suspend(int vetoable)
1222 1222
1223 save_processor_state(); 1223 save_processor_state();
1224 err = set_system_power_state(APM_STATE_SUSPEND); 1224 err = set_system_power_state(APM_STATE_SUSPEND);
1225 ignore_normal_resume = 1;
1225 restore_processor_state(); 1226 restore_processor_state();
1226 1227
1227 local_irq_disable(); 1228 local_irq_disable();
@@ -1229,7 +1230,6 @@ static int suspend(int vetoable)
1229 spin_lock(&i8253_lock); 1230 spin_lock(&i8253_lock);
1230 reinit_timer(); 1231 reinit_timer();
1231 set_time(); 1232 set_time();
1232 ignore_normal_resume = 1;
1233 1233
1234 spin_unlock(&i8253_lock); 1234 spin_unlock(&i8253_lock);
1235 write_sequnlock(&xtime_lock); 1235 write_sequnlock(&xtime_lock);
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index 16dbc4151be4..73aeaf5a9d4e 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -24,9 +24,6 @@ __asm__(".align 4\nvide: ret");
24 24
25static void __init init_amd(struct cpuinfo_x86 *c) 25static void __init init_amd(struct cpuinfo_x86 *c)
26{ 26{
27#ifdef CONFIG_X86_SMP
28 int cpu = c == &boot_cpu_data ? 0 : c - cpu_data;
29#endif
30 u32 l, h; 27 u32 l, h;
31 int mbytes = num_physpages >> (20-PAGE_SHIFT); 28 int mbytes = num_physpages >> (20-PAGE_SHIFT);
32 int r; 29 int r;
@@ -198,14 +195,19 @@ static void __init init_amd(struct cpuinfo_x86 *c)
198 c->x86_num_cores = 1; 195 c->x86_num_cores = 1;
199 } 196 }
200 197
201#ifdef CONFIG_X86_SMP 198#ifdef CONFIG_X86_HT
202 /* 199 /*
203 * On a AMD dual core setup the lower bits of the APIC id 200 * On a AMD dual core setup the lower bits of the APIC id
204 * distingush the cores. Assumes number of cores is a power 201 * distingush the cores. Assumes number of cores is a power
205 * of two. 202 * of two.
206 */ 203 */
207 if (c->x86_num_cores > 1) { 204 if (c->x86_num_cores > 1) {
208 cpu_core_id[cpu] = cpu >> hweight32(c->x86_num_cores - 1); 205 int cpu = smp_processor_id();
206 unsigned bits = 0;
207 while ((1 << bits) < c->x86_num_cores)
208 bits++;
209 cpu_core_id[cpu] = phys_proc_id[cpu] & ((1<<bits)-1);
210 phys_proc_id[cpu] >>= bits;
209 printk(KERN_INFO "CPU %d(%d) -> Core %d\n", 211 printk(KERN_INFO "CPU %d(%d) -> Core %d\n",
210 cpu, c->x86_num_cores, cpu_core_id[cpu]); 212 cpu, c->x86_num_cores, cpu_core_id[cpu]);
211 } 213 }
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 6be0310e3cd3..d199e525680a 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -243,6 +243,10 @@ static void __init early_cpu_detect(void)
243 } 243 }
244 244
245 early_intel_workaround(c); 245 early_intel_workaround(c);
246
247#ifdef CONFIG_X86_HT
248 phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff;
249#endif
246} 250}
247 251
248void __init generic_identify(struct cpuinfo_x86 * c) 252void __init generic_identify(struct cpuinfo_x86 * c)
diff --git a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig
index f25ffd74235c..0f1eb507233b 100644
--- a/arch/i386/kernel/cpu/cpufreq/Kconfig
+++ b/arch/i386/kernel/cpu/cpufreq/Kconfig
@@ -23,7 +23,7 @@ config X86_ACPI_CPUFREQ
23 If in doubt, say N. 23 If in doubt, say N.
24 24
25config ELAN_CPUFREQ 25config ELAN_CPUFREQ
26 tristate "AMD Elan" 26 tristate "AMD Elan SC400 and SC410"
27 select CPU_FREQ_TABLE 27 select CPU_FREQ_TABLE
28 depends on X86_ELAN 28 depends on X86_ELAN
29 ---help--- 29 ---help---
@@ -38,6 +38,18 @@ config ELAN_CPUFREQ
38 38
39 If in doubt, say N. 39 If in doubt, say N.
40 40
41config SC520_CPUFREQ
42 tristate "AMD Elan SC520"
43 select CPU_FREQ_TABLE
44 depends on X86_ELAN
45 ---help---
46 This adds the CPUFreq driver for AMD Elan SC520 processor.
47
48 For details, take a look at <file:Documentation/cpu-freq/>.
49
50 If in doubt, say N.
51
52
41config X86_POWERNOW_K6 53config X86_POWERNOW_K6
42 tristate "AMD Mobile K6-2/K6-3 PowerNow!" 54 tristate "AMD Mobile K6-2/K6-3 PowerNow!"
43 select CPU_FREQ_TABLE 55 select CPU_FREQ_TABLE
diff --git a/arch/i386/kernel/cpu/cpufreq/Makefile b/arch/i386/kernel/cpu/cpufreq/Makefile
index a922e97aeedd..2e894f1c8910 100644
--- a/arch/i386/kernel/cpu/cpufreq/Makefile
+++ b/arch/i386/kernel/cpu/cpufreq/Makefile
@@ -3,6 +3,7 @@ obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o
3obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o 3obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
4obj-$(CONFIG_X86_LONGHAUL) += longhaul.o 4obj-$(CONFIG_X86_LONGHAUL) += longhaul.o
5obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o 5obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o
6obj-$(CONFIG_SC520_CPUFREQ) += sc520_freq.o
6obj-$(CONFIG_X86_LONGRUN) += longrun.o 7obj-$(CONFIG_X86_LONGRUN) += longrun.o
7obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o 8obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o
8obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o 9obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
index ab0f9f5aac11..04e3563da4fe 100644
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c
@@ -29,6 +29,7 @@
29#include <linux/cpufreq.h> 29#include <linux/cpufreq.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/string.h> 31#include <linux/string.h>
32#include <linux/pci.h>
32 33
33#include <asm/msr.h> 34#include <asm/msr.h>
34#include <asm/timex.h> 35#include <asm/timex.h>
@@ -119,7 +120,13 @@ static int longhaul_get_cpu_mult(void)
119static void do_powersaver(union msr_longhaul *longhaul, 120static void do_powersaver(union msr_longhaul *longhaul,
120 unsigned int clock_ratio_index) 121 unsigned int clock_ratio_index)
121{ 122{
123 struct pci_dev *dev;
124 unsigned long flags;
125 unsigned int tmp_mask;
122 int version; 126 int version;
127 int i;
128 u16 pci_cmd;
129 u16 cmd_state[64];
123 130
124 switch (cpu_model) { 131 switch (cpu_model) {
125 case CPU_EZRA_T: 132 case CPU_EZRA_T:
@@ -137,17 +144,58 @@ static void do_powersaver(union msr_longhaul *longhaul,
137 longhaul->bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4; 144 longhaul->bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
138 longhaul->bits.EnableSoftBusRatio = 1; 145 longhaul->bits.EnableSoftBusRatio = 1;
139 longhaul->bits.RevisionKey = 0; 146 longhaul->bits.RevisionKey = 0;
140 local_irq_disable(); 147
141 wrmsrl(MSR_VIA_LONGHAUL, longhaul->val); 148 preempt_disable();
149 local_irq_save(flags);
150
151 /*
152 * get current pci bus master state for all devices
153 * and clear bus master bit
154 */
155 dev = NULL;
156 i = 0;
157 do {
158 dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
159 if (dev != NULL) {
160 pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
161 cmd_state[i++] = pci_cmd;
162 pci_cmd &= ~PCI_COMMAND_MASTER;
163 pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
164 }
165 } while (dev != NULL);
166
167 tmp_mask=inb(0x21); /* works on C3. save mask. */
168 outb(0xFE,0x21); /* TMR0 only */
169 outb(0xFF,0x80); /* delay */
170
142 local_irq_enable(); 171 local_irq_enable();
172
173 __hlt();
174 wrmsrl(MSR_VIA_LONGHAUL, longhaul->val);
143 __hlt(); 175 __hlt();
144 176
177 local_irq_disable();
178
179 outb(tmp_mask,0x21); /* restore mask */
180
181 /* restore pci bus master state for all devices */
182 dev = NULL;
183 i = 0;
184 do {
185 dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
186 if (dev != NULL) {
187 pci_cmd = cmd_state[i++];
188 pci_write_config_byte(dev, PCI_COMMAND, pci_cmd);
189 }
190 } while (dev != NULL);
191 local_irq_restore(flags);
192 preempt_enable();
193
194 /* disable bus ratio bit */
145 rdmsrl(MSR_VIA_LONGHAUL, longhaul->val); 195 rdmsrl(MSR_VIA_LONGHAUL, longhaul->val);
146 longhaul->bits.EnableSoftBusRatio = 0; 196 longhaul->bits.EnableSoftBusRatio = 0;
147 longhaul->bits.RevisionKey = version; 197 longhaul->bits.RevisionKey = version;
148 local_irq_disable();
149 wrmsrl(MSR_VIA_LONGHAUL, longhaul->val); 198 wrmsrl(MSR_VIA_LONGHAUL, longhaul->val);
150 local_irq_enable();
151} 199}
152 200
153/** 201/**
@@ -578,7 +626,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
578 longhaul_setup_voltagescaling(); 626 longhaul_setup_voltagescaling();
579 627
580 policy->governor = CPUFREQ_DEFAULT_GOVERNOR; 628 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
581 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; 629 policy->cpuinfo.transition_latency = 200000; /* nsec */
582 policy->cur = calc_speed(longhaul_get_cpu_mult()); 630 policy->cur = calc_speed(longhaul_get_cpu_mult());
583 631
584 ret = cpufreq_frequency_table_cpuinfo(policy, longhaul_table); 632 ret = cpufreq_frequency_table_cpuinfo(policy, longhaul_table);
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
index 913f652623d9..5c530064eb74 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
@@ -23,6 +23,7 @@
23#include <linux/dmi.h> 23#include <linux/dmi.h>
24 24
25#include <asm/msr.h> 25#include <asm/msr.h>
26#include <asm/timer.h>
26#include <asm/timex.h> 27#include <asm/timex.h>
27#include <asm/io.h> 28#include <asm/io.h>
28#include <asm/system.h> 29#include <asm/system.h>
@@ -586,13 +587,17 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
586 587
587 rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); 588 rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
588 589
589 /* A K7 with powernow technology is set to max frequency by BIOS */ 590 /* recalibrate cpu_khz */
590 fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.MFID]; 591 result = recalibrate_cpu_khz();
592 if (result)
593 return result;
594
595 fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID];
591 if (!fsb) { 596 if (!fsb) {
592 printk(KERN_WARNING PFX "can not determine bus frequency\n"); 597 printk(KERN_WARNING PFX "can not determine bus frequency\n");
593 return -EINVAL; 598 return -EINVAL;
594 } 599 }
595 dprintk("FSB: %3d.%03d MHz\n", fsb/1000, fsb%1000); 600 dprintk("FSB: %3dMHz\n", fsb/1000);
596 601
597 if (dmi_check_system(powernow_dmi_table) || acpi_force) { 602 if (dmi_check_system(powernow_dmi_table) || acpi_force) {
598 printk (KERN_INFO PFX "PSB/PST known to be broken. Trying ACPI instead\n"); 603 printk (KERN_INFO PFX "PSB/PST known to be broken. Trying ACPI instead\n");
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
index a65ff7e32e5d..10cc096c0ade 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
@@ -4,7 +4,7 @@
4 * GNU general public license version 2. See "COPYING" or 4 * GNU general public license version 2. See "COPYING" or
5 * http://www.gnu.org/licenses/gpl.html 5 * http://www.gnu.org/licenses/gpl.html
6 * 6 *
7 * Support : paul.devriendt@amd.com 7 * Support : mark.langsdorf@amd.com
8 * 8 *
9 * Based on the powernow-k7.c module written by Dave Jones. 9 * Based on the powernow-k7.c module written by Dave Jones.
10 * (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs 10 * (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs
@@ -15,12 +15,13 @@
15 * 15 *
16 * Valuable input gratefully received from Dave Jones, Pavel Machek, 16 * Valuable input gratefully received from Dave Jones, Pavel Machek,
17 * Dominik Brodowski, and others. 17 * Dominik Brodowski, and others.
18 * Originally developed by Paul Devriendt.
18 * Processor information obtained from Chapter 9 (Power and Thermal Management) 19 * Processor information obtained from Chapter 9 (Power and Thermal Management)
19 * of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD 20 * of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
20 * Opteron Processors" available for download from www.amd.com 21 * Opteron Processors" available for download from www.amd.com
21 * 22 *
22 * Tables for specific CPUs can be infrerred from 23 * Tables for specific CPUs can be infrerred from
23 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf 24 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf
24 */ 25 */
25 26
26#include <linux/kernel.h> 27#include <linux/kernel.h>
@@ -30,6 +31,7 @@
30#include <linux/cpufreq.h> 31#include <linux/cpufreq.h>
31#include <linux/slab.h> 32#include <linux/slab.h>
32#include <linux/string.h> 33#include <linux/string.h>
34#include <linux/cpumask.h>
33 35
34#include <asm/msr.h> 36#include <asm/msr.h>
35#include <asm/io.h> 37#include <asm/io.h>
@@ -42,7 +44,7 @@
42 44
43#define PFX "powernow-k8: " 45#define PFX "powernow-k8: "
44#define BFX PFX "BIOS error: " 46#define BFX PFX "BIOS error: "
45#define VERSION "version 1.00.09e" 47#define VERSION "version 1.40.2"
46#include "powernow-k8.h" 48#include "powernow-k8.h"
47 49
48/* serialize freq changes */ 50/* serialize freq changes */
@@ -50,6 +52,10 @@ static DECLARE_MUTEX(fidvid_sem);
50 52
51static struct powernow_k8_data *powernow_data[NR_CPUS]; 53static struct powernow_k8_data *powernow_data[NR_CPUS];
52 54
55#ifndef CONFIG_SMP
56static cpumask_t cpu_core_map[1];
57#endif
58
53/* Return a frequency in MHz, given an input fid */ 59/* Return a frequency in MHz, given an input fid */
54static u32 find_freq_from_fid(u32 fid) 60static u32 find_freq_from_fid(u32 fid)
55{ 61{
@@ -274,11 +280,18 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid
274{ 280{
275 u32 rvosteps = data->rvo; 281 u32 rvosteps = data->rvo;
276 u32 savefid = data->currfid; 282 u32 savefid = data->currfid;
283 u32 maxvid, lo;
277 284
278 dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x\n", 285 dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x\n",
279 smp_processor_id(), 286 smp_processor_id(),
280 data->currfid, data->currvid, reqvid, data->rvo); 287 data->currfid, data->currvid, reqvid, data->rvo);
281 288
289 rdmsr(MSR_FIDVID_STATUS, lo, maxvid);
290 maxvid = 0x1f & (maxvid >> 16);
291 dprintk("ph1 maxvid=0x%x\n", maxvid);
292 if (reqvid < maxvid) /* lower numbers are higher voltages */
293 reqvid = maxvid;
294
282 while (data->currvid > reqvid) { 295 while (data->currvid > reqvid) {
283 dprintk("ph1: curr 0x%x, req vid 0x%x\n", 296 dprintk("ph1: curr 0x%x, req vid 0x%x\n",
284 data->currvid, reqvid); 297 data->currvid, reqvid);
@@ -286,8 +299,8 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid
286 return 1; 299 return 1;
287 } 300 }
288 301
289 while ((rvosteps > 0) && ((data->rvo + data->currvid) > reqvid)) { 302 while ((rvosteps > 0) && ((data->rvo + data->currvid) > reqvid)) {
290 if (data->currvid == 0) { 303 if (data->currvid == maxvid) {
291 rvosteps = 0; 304 rvosteps = 0;
292 } else { 305 } else {
293 dprintk("ph1: changing vid for rvo, req 0x%x\n", 306 dprintk("ph1: changing vid for rvo, req 0x%x\n",
@@ -671,7 +684,7 @@ static int find_psb_table(struct powernow_k8_data *data)
671 * BIOS and Kernel Developer's Guide, which is available on 684 * BIOS and Kernel Developer's Guide, which is available on
672 * www.amd.com 685 * www.amd.com
673 */ 686 */
674 printk(KERN_ERR PFX "BIOS error - no PSB\n"); 687 printk(KERN_INFO PFX "BIOS error - no PSB or ACPI _PSS objects\n");
675 return -ENODEV; 688 return -ENODEV;
676} 689}
677 690
@@ -695,7 +708,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
695 struct cpufreq_frequency_table *powernow_table; 708 struct cpufreq_frequency_table *powernow_table;
696 709
697 if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { 710 if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) {
698 dprintk("register performance failed\n"); 711 dprintk("register performance failed: bad ACPI data\n");
699 return -EIO; 712 return -EIO;
700 } 713 }
701 714
@@ -746,22 +759,23 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
746 continue; 759 continue;
747 } 760 }
748 761
749 if (fid < HI_FID_TABLE_BOTTOM) { 762 /* verify only 1 entry from the lo frequency table */
750 if (cntlofreq) { 763 if (fid < HI_FID_TABLE_BOTTOM) {
751 /* if both entries are the same, ignore this 764 if (cntlofreq) {
752 * one... 765 /* if both entries are the same, ignore this
753 */ 766 * one...
754 if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) || 767 */
755 (powernow_table[i].index != powernow_table[cntlofreq].index)) { 768 if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) ||
756 printk(KERN_ERR PFX "Too many lo freq table entries\n"); 769 (powernow_table[i].index != powernow_table[cntlofreq].index)) {
757 goto err_out_mem; 770 printk(KERN_ERR PFX "Too many lo freq table entries\n");
758 } 771 goto err_out_mem;
759 772 }
760 dprintk("double low frequency table entry, ignoring it.\n"); 773
761 powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; 774 dprintk("double low frequency table entry, ignoring it.\n");
762 continue; 775 powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
763 } else 776 continue;
764 cntlofreq = i; 777 } else
778 cntlofreq = i;
765 } 779 }
766 780
767 if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) { 781 if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) {
@@ -816,7 +830,7 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde
816{ 830{
817 u32 fid; 831 u32 fid;
818 u32 vid; 832 u32 vid;
819 int res; 833 int res, i;
820 struct cpufreq_freqs freqs; 834 struct cpufreq_freqs freqs;
821 835
822 dprintk("cpu %d transition to index %u\n", smp_processor_id(), index); 836 dprintk("cpu %d transition to index %u\n", smp_processor_id(), index);
@@ -841,7 +855,8 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde
841 } 855 }
842 856
843 if ((fid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) { 857 if ((fid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) {
844 printk("ignoring illegal change in lo freq table-%x to 0x%x\n", 858 printk(KERN_ERR PFX
859 "ignoring illegal change in lo freq table-%x to 0x%x\n",
845 data->currfid, fid); 860 data->currfid, fid);
846 return 1; 861 return 1;
847 } 862 }
@@ -850,18 +865,20 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde
850 smp_processor_id(), fid, vid); 865 smp_processor_id(), fid, vid);
851 866
852 freqs.cpu = data->cpu; 867 freqs.cpu = data->cpu;
853
854 freqs.old = find_khz_freq_from_fid(data->currfid); 868 freqs.old = find_khz_freq_from_fid(data->currfid);
855 freqs.new = find_khz_freq_from_fid(fid); 869 freqs.new = find_khz_freq_from_fid(fid);
856 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); 870 for_each_cpu_mask(i, cpu_core_map[data->cpu]) {
871 freqs.cpu = i;
872 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
873 }
857 874
858 down(&fidvid_sem);
859 res = transition_fid_vid(data, fid, vid); 875 res = transition_fid_vid(data, fid, vid);
860 up(&fidvid_sem);
861 876
862 freqs.new = find_khz_freq_from_fid(data->currfid); 877 freqs.new = find_khz_freq_from_fid(data->currfid);
863 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); 878 for_each_cpu_mask(i, cpu_core_map[data->cpu]) {
864 879 freqs.cpu = i;
880 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
881 }
865 return res; 882 return res;
866} 883}
867 884
@@ -874,6 +891,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
874 u32 checkvid = data->currvid; 891 u32 checkvid = data->currvid;
875 unsigned int newstate; 892 unsigned int newstate;
876 int ret = -EIO; 893 int ret = -EIO;
894 int i;
877 895
878 /* only run on specific CPU from here on */ 896 /* only run on specific CPU from here on */
879 oldmask = current->cpus_allowed; 897 oldmask = current->cpus_allowed;
@@ -902,22 +920,41 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
902 data->currfid, data->currvid); 920 data->currfid, data->currvid);
903 921
904 if ((checkvid != data->currvid) || (checkfid != data->currfid)) { 922 if ((checkvid != data->currvid) || (checkfid != data->currfid)) {
905 printk(KERN_ERR PFX 923 printk(KERN_INFO PFX
906 "error - out of sync, fid 0x%x 0x%x, vid 0x%x 0x%x\n", 924 "error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n",
907 checkfid, data->currfid, checkvid, data->currvid); 925 checkfid, data->currfid, checkvid, data->currvid);
908 } 926 }
909 927
910 if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate)) 928 if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate))
911 goto err_out; 929 goto err_out;
912 930
931 down(&fidvid_sem);
932
933 for_each_cpu_mask(i, cpu_core_map[pol->cpu]) {
934 /* make sure the sibling is initialized */
935 if (!powernow_data[i]) {
936 ret = 0;
937 up(&fidvid_sem);
938 goto err_out;
939 }
940 }
941
913 powernow_k8_acpi_pst_values(data, newstate); 942 powernow_k8_acpi_pst_values(data, newstate);
914 943
915 if (transition_frequency(data, newstate)) { 944 if (transition_frequency(data, newstate)) {
916 printk(KERN_ERR PFX "transition frequency failed\n"); 945 printk(KERN_ERR PFX "transition frequency failed\n");
917 ret = 1; 946 ret = 1;
947 up(&fidvid_sem);
918 goto err_out; 948 goto err_out;
919 } 949 }
920 950
951 /* Update all the fid/vids of our siblings */
952 for_each_cpu_mask(i, cpu_core_map[pol->cpu]) {
953 powernow_data[i]->currvid = data->currvid;
954 powernow_data[i]->currfid = data->currfid;
955 }
956 up(&fidvid_sem);
957
921 pol->cur = find_khz_freq_from_fid(data->currfid); 958 pol->cur = find_khz_freq_from_fid(data->currfid);
922 ret = 0; 959 ret = 0;
923 960
@@ -962,7 +999,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
962 */ 999 */
963 1000
964 if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) { 1001 if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) {
965 printk(KERN_INFO PFX "MP systems not supported by PSB BIOS structure\n"); 1002 printk(KERN_ERR PFX "MP systems not supported by PSB BIOS structure\n");
966 kfree(data); 1003 kfree(data);
967 return -ENODEV; 1004 return -ENODEV;
968 } 1005 }
@@ -1003,6 +1040,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
1003 schedule(); 1040 schedule();
1004 1041
1005 pol->governor = CPUFREQ_DEFAULT_GOVERNOR; 1042 pol->governor = CPUFREQ_DEFAULT_GOVERNOR;
1043 pol->cpus = cpu_core_map[pol->cpu];
1006 1044
1007 /* Take a crude guess here. 1045 /* Take a crude guess here.
1008 * That guess was in microseconds, so multiply with 1000 */ 1046 * That guess was in microseconds, so multiply with 1000 */
@@ -1069,7 +1107,7 @@ static unsigned int powernowk8_get (unsigned int cpu)
1069 return 0; 1107 return 0;
1070 } 1108 }
1071 preempt_disable(); 1109 preempt_disable();
1072 1110
1073 if (query_current_values_with_pending_wait(data)) 1111 if (query_current_values_with_pending_wait(data))
1074 goto out; 1112 goto out;
1075 1113
@@ -1127,9 +1165,10 @@ static void __exit powernowk8_exit(void)
1127 cpufreq_unregister_driver(&cpufreq_amd64_driver); 1165 cpufreq_unregister_driver(&cpufreq_amd64_driver);
1128} 1166}
1129 1167
1130MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com>"); 1168MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com.");
1131MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver."); 1169MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver.");
1132MODULE_LICENSE("GPL"); 1170MODULE_LICENSE("GPL");
1133 1171
1134late_initcall(powernowk8_init); 1172late_initcall(powernowk8_init);
1135module_exit(powernowk8_exit); 1173module_exit(powernowk8_exit);
1174
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
index 63ebc8470f52..9ed5bf221cb7 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
@@ -174,3 +174,18 @@ static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvi
174static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid); 174static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid);
175 175
176static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index); 176static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index);
177
178#ifndef for_each_cpu_mask
179#define for_each_cpu_mask(i,mask) for (i=0;i<1;i++)
180#endif
181
182#ifdef CONFIG_SMP
183static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[])
184{
185}
186#else
187static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[])
188{
189 cpu_set(0, cpu_sharedcore_mask[0]);
190}
191#endif
diff --git a/arch/i386/kernel/cpu/cpufreq/sc520_freq.c b/arch/i386/kernel/cpu/cpufreq/sc520_freq.c
new file mode 100644
index 000000000000..ef457d50f4ac
--- /dev/null
+++ b/arch/i386/kernel/cpu/cpufreq/sc520_freq.c
@@ -0,0 +1,186 @@
1/*
2 * sc520_freq.c: cpufreq driver for the AMD Elan sc520
3 *
4 * Copyright (C) 2005 Sean Young <sean@mess.org>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 * Based on elanfreq.c
12 *
13 * 2005-03-30: - initial revision
14 */
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/init.h>
19
20#include <linux/delay.h>
21#include <linux/cpufreq.h>
22
23#include <asm/msr.h>
24#include <asm/timex.h>
25#include <asm/io.h>
26
27#define MMCR_BASE 0xfffef000 /* The default base address */
28#define OFFS_CPUCTL 0x2 /* CPU Control Register */
29
30static __u8 __iomem *cpuctl;
31
32#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "sc520_freq", msg)
33
34static struct cpufreq_frequency_table sc520_freq_table[] = {
35 {0x01, 100000},
36 {0x02, 133000},
37 {0, CPUFREQ_TABLE_END},
38};
39
40static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu)
41{
42 u8 clockspeed_reg = *cpuctl;
43
44 switch (clockspeed_reg & 0x03) {
45 default:
46 printk(KERN_ERR "sc520_freq: error: cpuctl register has unexpected value %02x\n", clockspeed_reg);
47 case 0x01:
48 return 100000;
49 case 0x02:
50 return 133000;
51 }
52}
53
54static void sc520_freq_set_cpu_state (unsigned int state)
55{
56
57 struct cpufreq_freqs freqs;
58 u8 clockspeed_reg;
59
60 freqs.old = sc520_freq_get_cpu_frequency(0);
61 freqs.new = sc520_freq_table[state].frequency;
62 freqs.cpu = 0; /* AMD Elan is UP */
63
64 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
65
66 dprintk("attempting to set frequency to %i kHz\n",
67 sc520_freq_table[state].frequency);
68
69 local_irq_disable();
70
71 clockspeed_reg = *cpuctl & ~0x03;
72 *cpuctl = clockspeed_reg | sc520_freq_table[state].index;
73
74 local_irq_enable();
75
76 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
77};
78
79static int sc520_freq_verify (struct cpufreq_policy *policy)
80{
81 return cpufreq_frequency_table_verify(policy, &sc520_freq_table[0]);
82}
83
84static int sc520_freq_target (struct cpufreq_policy *policy,
85 unsigned int target_freq,
86 unsigned int relation)
87{
88 unsigned int newstate = 0;
89
90 if (cpufreq_frequency_table_target(policy, sc520_freq_table, target_freq, relation, &newstate))
91 return -EINVAL;
92
93 sc520_freq_set_cpu_state(newstate);
94
95 return 0;
96}
97
98
99/*
100 * Module init and exit code
101 */
102
103static int sc520_freq_cpu_init(struct cpufreq_policy *policy)
104{
105 struct cpuinfo_x86 *c = cpu_data;
106 int result;
107
108 /* capability check */
109 if (c->x86_vendor != X86_VENDOR_AMD ||
110 c->x86 != 4 || c->x86_model != 9)
111 return -ENODEV;
112
113 /* cpuinfo and default policy values */
114 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
115 policy->cpuinfo.transition_latency = 1000000; /* 1ms */
116 policy->cur = sc520_freq_get_cpu_frequency(0);
117
118 result = cpufreq_frequency_table_cpuinfo(policy, sc520_freq_table);
119 if (result)
120 return (result);
121
122 cpufreq_frequency_table_get_attr(sc520_freq_table, policy->cpu);
123
124 return 0;
125}
126
127
128static int sc520_freq_cpu_exit(struct cpufreq_policy *policy)
129{
130 cpufreq_frequency_table_put_attr(policy->cpu);
131 return 0;
132}
133
134
135static struct freq_attr* sc520_freq_attr[] = {
136 &cpufreq_freq_attr_scaling_available_freqs,
137 NULL,
138};
139
140
141static struct cpufreq_driver sc520_freq_driver = {
142 .get = sc520_freq_get_cpu_frequency,
143 .verify = sc520_freq_verify,
144 .target = sc520_freq_target,
145 .init = sc520_freq_cpu_init,
146 .exit = sc520_freq_cpu_exit,
147 .name = "sc520_freq",
148 .owner = THIS_MODULE,
149 .attr = sc520_freq_attr,
150};
151
152
153static int __init sc520_freq_init(void)
154{
155 struct cpuinfo_x86 *c = cpu_data;
156
157 /* Test if we have the right hardware */
158 if(c->x86_vendor != X86_VENDOR_AMD ||
159 c->x86 != 4 || c->x86_model != 9) {
160 dprintk("no Elan SC520 processor found!\n");
161 return -ENODEV;
162 }
163 cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1);
164 if(!cpuctl) {
165 printk(KERN_ERR "sc520_freq: error: failed to remap memory\n");
166 return -ENOMEM;
167 }
168
169 return cpufreq_register_driver(&sc520_freq_driver);
170}
171
172
173static void __exit sc520_freq_exit(void)
174{
175 cpufreq_unregister_driver(&sc520_freq_driver);
176 iounmap(cpuctl);
177}
178
179
180MODULE_LICENSE("GPL");
181MODULE_AUTHOR("Sean Young <sean@mess.org>");
182MODULE_DESCRIPTION("cpufreq driver for AMD's Elan sc520 CPU");
183
184module_init(sc520_freq_init);
185module_exit(sc520_freq_exit);
186
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
index 07d5612dc00f..7dcbf70fc16f 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -54,6 +54,8 @@ enum {
54 CPU_DOTHAN_A1, 54 CPU_DOTHAN_A1,
55 CPU_DOTHAN_A2, 55 CPU_DOTHAN_A2,
56 CPU_DOTHAN_B0, 56 CPU_DOTHAN_B0,
57 CPU_MP4HT_D0,
58 CPU_MP4HT_E0,
57}; 59};
58 60
59static const struct cpu_id cpu_ids[] = { 61static const struct cpu_id cpu_ids[] = {
@@ -61,6 +63,8 @@ static const struct cpu_id cpu_ids[] = {
61 [CPU_DOTHAN_A1] = { 6, 13, 1 }, 63 [CPU_DOTHAN_A1] = { 6, 13, 1 },
62 [CPU_DOTHAN_A2] = { 6, 13, 2 }, 64 [CPU_DOTHAN_A2] = { 6, 13, 2 },
63 [CPU_DOTHAN_B0] = { 6, 13, 6 }, 65 [CPU_DOTHAN_B0] = { 6, 13, 6 },
66 [CPU_MP4HT_D0] = {15, 3, 4 },
67 [CPU_MP4HT_E0] = {15, 4, 1 },
64}; 68};
65#define N_IDS (sizeof(cpu_ids)/sizeof(cpu_ids[0])) 69#define N_IDS (sizeof(cpu_ids)/sizeof(cpu_ids[0]))
66 70
@@ -226,6 +230,8 @@ static struct cpu_model models[] =
226 { &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL }, 230 { &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL },
227 { &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL }, 231 { &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL },
228 { &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL }, 232 { &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL },
233 { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
234 { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
229 235
230 { NULL, } 236 { NULL, }
231}; 237};
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
index 8ba430a9c3a2..d368b3f5fce8 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
@@ -336,7 +336,7 @@ unsigned int speedstep_get_freqs(unsigned int processor,
336 if (!prev_speed) 336 if (!prev_speed)
337 return -EIO; 337 return -EIO;
338 338
339 dprintk("previous seped is %u\n", prev_speed); 339 dprintk("previous speed is %u\n", prev_speed);
340 340
341 local_irq_save(flags); 341 local_irq_save(flags);
342 342
@@ -348,7 +348,7 @@ unsigned int speedstep_get_freqs(unsigned int processor,
348 goto out; 348 goto out;
349 } 349 }
350 350
351 dprintk("low seped is %u\n", *low_speed); 351 dprintk("low speed is %u\n", *low_speed);
352 352
353 /* switch to high state */ 353 /* switch to high state */
354 set_state(SPEEDSTEP_HIGH); 354 set_state(SPEEDSTEP_HIGH);
@@ -358,7 +358,7 @@ unsigned int speedstep_get_freqs(unsigned int processor,
358 goto out; 358 goto out;
359 } 359 }
360 360
361 dprintk("high seped is %u\n", *high_speed); 361 dprintk("high speed is %u\n", *high_speed);
362 362
363 if (*low_speed == *high_speed) { 363 if (*low_speed == *high_speed) {
364 ret = -ENODEV; 364 ret = -ENODEV;
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
index 79440b3f087e..b25fb6b635ae 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
@@ -357,6 +357,9 @@ static int __init speedstep_init(void)
357 case SPEEDSTEP_PROCESSOR_PIII_C: 357 case SPEEDSTEP_PROCESSOR_PIII_C:
358 case SPEEDSTEP_PROCESSOR_PIII_C_EARLY: 358 case SPEEDSTEP_PROCESSOR_PIII_C_EARLY:
359 break; 359 break;
360 case SPEEDSTEP_PROCESSOR_P4M:
361 printk(KERN_INFO "speedstep-smi: you're trying to use this cpufreq driver on a Pentium 4-based CPU. Most likely it will not work.\n");
362 break;
360 default: 363 default:
361 speedstep_processor = 0; 364 speedstep_processor = 0;
362 } 365 }
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c
index aeb5b4ef8c8b..a710dc4eb20e 100644
--- a/arch/i386/kernel/cpu/intel_cacheinfo.c
+++ b/arch/i386/kernel/cpu/intel_cacheinfo.c
@@ -118,7 +118,7 @@ struct _cpuid4_info {
118}; 118};
119 119
120#define MAX_CACHE_LEAVES 4 120#define MAX_CACHE_LEAVES 4
121static unsigned short __devinitdata num_cache_leaves; 121static unsigned short num_cache_leaves;
122 122
123static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) 123static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
124{ 124{
diff --git a/arch/i386/kernel/cpu/mtrr/cyrix.c b/arch/i386/kernel/cpu/mtrr/cyrix.c
index 933b0dd62f48..9027a987006b 100644
--- a/arch/i386/kernel/cpu/mtrr/cyrix.c
+++ b/arch/i386/kernel/cpu/mtrr/cyrix.c
@@ -218,12 +218,12 @@ typedef struct {
218 mtrr_type type; 218 mtrr_type type;
219} arr_state_t; 219} arr_state_t;
220 220
221static arr_state_t arr_state[8] __initdata = { 221static arr_state_t arr_state[8] __devinitdata = {
222 {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, 222 {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL},
223 {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL} 223 {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}
224}; 224};
225 225
226static unsigned char ccr_state[7] __initdata = { 0, 0, 0, 0, 0, 0, 0 }; 226static unsigned char ccr_state[7] __devinitdata = { 0, 0, 0, 0, 0, 0, 0 };
227 227
228static void cyrix_set_all(void) 228static void cyrix_set_all(void)
229{ 229{
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
index 14ec354bec92..903190a4b3ff 100644
--- a/arch/i386/kernel/i386_ksyms.c
+++ b/arch/i386/kernel/i386_ksyms.c
@@ -169,10 +169,6 @@ EXPORT_SYMBOL(rtc_lock);
169EXPORT_SYMBOL_GPL(set_nmi_callback); 169EXPORT_SYMBOL_GPL(set_nmi_callback);
170EXPORT_SYMBOL_GPL(unset_nmi_callback); 170EXPORT_SYMBOL_GPL(unset_nmi_callback);
171 171
172#undef memcmp
173extern int memcmp(const void *,const void *,__kernel_size_t);
174EXPORT_SYMBOL(memcmp);
175
176EXPORT_SYMBOL(register_die_notifier); 172EXPORT_SYMBOL(register_die_notifier);
177#ifdef CONFIG_HAVE_DEC_LOCK 173#ifdef CONFIG_HAVE_DEC_LOCK
178EXPORT_SYMBOL(_atomic_dec_and_lock); 174EXPORT_SYMBOL(_atomic_dec_and_lock);
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index 671681659243..59ff9b455069 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -217,6 +217,13 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs)
217 *tos &= ~(TF_MASK | IF_MASK); 217 *tos &= ~(TF_MASK | IF_MASK);
218 *tos |= kprobe_old_eflags; 218 *tos |= kprobe_old_eflags;
219 break; 219 break;
220 case 0xc3: /* ret/lret */
221 case 0xcb:
222 case 0xc2:
223 case 0xca:
224 regs->eflags &= ~TF_MASK;
225 /* eip is already adjusted, no more changes required*/
226 return;
220 case 0xe8: /* call relative - Fix return addr */ 227 case 0xe8: /* call relative - Fix return addr */
221 *tos = orig_eip + (*tos - copy_eip); 228 *tos = orig_eip + (*tos - copy_eip);
222 break; 229 break;
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 85bd56d44314..96e3ea6b17c7 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -400,11 +400,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
400 int err; 400 int err;
401 401
402 childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; 402 childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
403 *childregs = *regs;
404 childregs->eax = 0;
405 childregs->esp = esp;
406
407 p->thread.esp = (unsigned long) childregs;
408 /* 403 /*
409 * The below -8 is to reserve 8 bytes on top of the ring0 stack. 404 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
410 * This is necessary to guarantee that the entire "struct pt_regs" 405 * This is necessary to guarantee that the entire "struct pt_regs"
@@ -415,7 +410,13 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
415 * "struct pt_regs" is possible, but they may contain the 410 * "struct pt_regs" is possible, but they may contain the
416 * completely wrong values. 411 * completely wrong values.
417 */ 412 */
418 p->thread.esp0 = (unsigned long) (childregs+1) - 8; 413 childregs = (struct pt_regs *) ((unsigned long) childregs - 8);
414 *childregs = *regs;
415 childregs->eax = 0;
416 childregs->esp = esp;
417
418 p->thread.esp = (unsigned long) childregs;
419 p->thread.esp0 = (unsigned long) (childregs+1);
419 420
420 p->thread.eip = (unsigned long) ret_from_fork; 421 p->thread.eip = (unsigned long) ret_from_fork;
421 422
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index e8c965ce86eb..e34f651fa13c 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -683,24 +683,18 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit)
683 /* do the secure computing check first */ 683 /* do the secure computing check first */
684 secure_computing(regs->orig_eax); 684 secure_computing(regs->orig_eax);
685 685
686 if (unlikely(current->audit_context)) { 686 if (unlikely(current->audit_context) && entryexit)
687 if (!entryexit) 687 audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax);
688 audit_syscall_entry(current, regs->orig_eax,
689 regs->ebx, regs->ecx,
690 regs->edx, regs->esi);
691 else
692 audit_syscall_exit(current, regs->eax);
693 }
694 688
695 if (!(current->ptrace & PT_PTRACED)) 689 if (!(current->ptrace & PT_PTRACED))
696 return; 690 goto out;
697 691
698 /* Fake a debug trap */ 692 /* Fake a debug trap */
699 if (test_thread_flag(TIF_SINGLESTEP)) 693 if (test_thread_flag(TIF_SINGLESTEP))
700 send_sigtrap(current, regs, 0); 694 send_sigtrap(current, regs, 0);
701 695
702 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 696 if (!test_thread_flag(TIF_SYSCALL_TRACE))
703 return; 697 goto out;
704 698
705 /* the 0x80 provides a way for the tracing parent to distinguish 699 /* the 0x80 provides a way for the tracing parent to distinguish
706 between a syscall stop and SIGTRAP delivery */ 700 between a syscall stop and SIGTRAP delivery */
@@ -715,4 +709,9 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit)
715 send_sig(current->exit_code, current, 1); 709 send_sig(current->exit_code, current, 1);
716 current->exit_code = 0; 710 current->exit_code = 0;
717 } 711 }
712 out:
713 if (unlikely(current->audit_context) && !entryexit)
714 audit_syscall_entry(current, AUDIT_ARCH_I386, regs->orig_eax,
715 regs->ebx, regs->ecx, regs->edx, regs->esi);
716
718} 717}
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 945ec73163c8..2bfbddebdbf8 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -1502,11 +1502,13 @@ void __init setup_arch(char **cmdline_p)
1502 if (efi_enabled) 1502 if (efi_enabled)
1503 efi_map_memmap(); 1503 efi_map_memmap();
1504 1504
1505#ifdef CONFIG_ACPI_BOOT
1505 /* 1506 /*
1506 * Parse the ACPI tables for possible boot-time SMP configuration. 1507 * Parse the ACPI tables for possible boot-time SMP configuration.
1507 */ 1508 */
1508 acpi_boot_table_init(); 1509 acpi_boot_table_init();
1509 acpi_boot_init(); 1510 acpi_boot_init();
1511#endif
1510 1512
1511#ifdef CONFIG_X86_LOCAL_APIC 1513#ifdef CONFIG_X86_LOCAL_APIC
1512 if (smp_found_config) 1514 if (smp_found_config)
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index cbea7ac582e5..bc1bb6919e6a 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -888,6 +888,7 @@ void *xquad_portio;
888 888
889cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; 889cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
890cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; 890cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
891EXPORT_SYMBOL(cpu_core_map);
891 892
892static void __init smp_boot_cpus(unsigned int max_cpus) 893static void __init smp_boot_cpus(unsigned int max_cpus)
893{ 894{
@@ -1073,8 +1074,10 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1073 cpu_set(cpu, cpu_sibling_map[cpu]); 1074 cpu_set(cpu, cpu_sibling_map[cpu]);
1074 } 1075 }
1075 1076
1076 if (siblings != smp_num_siblings) 1077 if (siblings != smp_num_siblings) {
1077 printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings); 1078 printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings);
1079 smp_num_siblings = siblings;
1080 }
1078 1081
1079 if (c->x86_num_cores > 1) { 1082 if (c->x86_num_cores > 1) {
1080 for (i = 0; i < NR_CPUS; i++) { 1083 for (i = 0; i < NR_CPUS; i++) {
diff --git a/arch/i386/kernel/timers/common.c b/arch/i386/kernel/timers/common.c
index f7f90005e22e..8e201219f525 100644
--- a/arch/i386/kernel/timers/common.c
+++ b/arch/i386/kernel/timers/common.c
@@ -6,6 +6,7 @@
6#include <linux/timex.h> 6#include <linux/timex.h>
7#include <linux/errno.h> 7#include <linux/errno.h>
8#include <linux/jiffies.h> 8#include <linux/jiffies.h>
9#include <linux/module.h>
9 10
10#include <asm/io.h> 11#include <asm/io.h>
11#include <asm/timer.h> 12#include <asm/timer.h>
@@ -24,7 +25,7 @@
24 25
25#define CALIBRATE_TIME (5 * 1000020/HZ) 26#define CALIBRATE_TIME (5 * 1000020/HZ)
26 27
27unsigned long __init calibrate_tsc(void) 28unsigned long calibrate_tsc(void)
28{ 29{
29 mach_prepare_counter(); 30 mach_prepare_counter();
30 31
@@ -139,7 +140,7 @@ bad_calibration:
139#endif 140#endif
140 141
141/* calculate cpu_khz */ 142/* calculate cpu_khz */
142void __init init_cpu_khz(void) 143void init_cpu_khz(void)
143{ 144{
144 if (cpu_has_tsc) { 145 if (cpu_has_tsc) {
145 unsigned long tsc_quotient = calibrate_tsc(); 146 unsigned long tsc_quotient = calibrate_tsc();
@@ -158,3 +159,4 @@ void __init init_cpu_khz(void)
158 } 159 }
159 } 160 }
160} 161}
162
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
index 7926d967be00..180444d87824 100644
--- a/arch/i386/kernel/timers/timer_tsc.c
+++ b/arch/i386/kernel/timers/timer_tsc.c
@@ -320,6 +320,26 @@ core_initcall(cpufreq_tsc);
320static inline void cpufreq_delayed_get(void) { return; } 320static inline void cpufreq_delayed_get(void) { return; }
321#endif 321#endif
322 322
323int recalibrate_cpu_khz(void)
324{
325#ifndef CONFIG_SMP
326 unsigned long cpu_khz_old = cpu_khz;
327
328 if (cpu_has_tsc) {
329 init_cpu_khz();
330 cpu_data[0].loops_per_jiffy =
331 cpufreq_scale(cpu_data[0].loops_per_jiffy,
332 cpu_khz_old,
333 cpu_khz);
334 return 0;
335 } else
336 return -ENODEV;
337#else
338 return -ENODEV;
339#endif
340}
341EXPORT_SYMBOL(recalibrate_cpu_khz);
342
323static void mark_offset_tsc(void) 343static void mark_offset_tsc(void)
324{ 344{
325 unsigned long lost,delay; 345 unsigned long lost,delay;
diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c
index 903d739ca74a..a6e0ddd65bd0 100644
--- a/arch/i386/mach-voyager/voyager_smp.c
+++ b/arch/i386/mach-voyager/voyager_smp.c
@@ -97,7 +97,6 @@ static void ack_vic_irq(unsigned int irq);
97static void vic_enable_cpi(void); 97static void vic_enable_cpi(void);
98static void do_boot_cpu(__u8 cpuid); 98static void do_boot_cpu(__u8 cpuid);
99static void do_quad_bootstrap(void); 99static void do_quad_bootstrap(void);
100static inline void wrapper_smp_local_timer_interrupt(struct pt_regs *);
101 100
102int hard_smp_processor_id(void); 101int hard_smp_processor_id(void);
103 102
@@ -126,6 +125,14 @@ send_QIC_CPI(__u32 cpuset, __u8 cpi)
126} 125}
127 126
128static inline void 127static inline void
128wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
129{
130 irq_enter();
131 smp_local_timer_interrupt(regs);
132 irq_exit();
133}
134
135static inline void
129send_one_CPI(__u8 cpu, __u8 cpi) 136send_one_CPI(__u8 cpu, __u8 cpi)
130{ 137{
131 if(voyager_quad_processors & (1<<cpu)) 138 if(voyager_quad_processors & (1<<cpu))
@@ -1249,14 +1256,6 @@ smp_vic_timer_interrupt(struct pt_regs *regs)
1249 smp_local_timer_interrupt(regs); 1256 smp_local_timer_interrupt(regs);
1250} 1257}
1251 1258
1252static inline void
1253wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
1254{
1255 irq_enter();
1256 smp_local_timer_interrupt(regs);
1257 irq_exit();
1258}
1259
1260/* local (per CPU) timer interrupt. It does both profiling and 1259/* local (per CPU) timer interrupt. It does both profiling and
1261 * process statistics/rescheduling. 1260 * process statistics/rescheduling.
1262 * 1261 *
diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
index db06f7399913..ab542792b27b 100644
--- a/arch/i386/mm/ioremap.c
+++ b/arch/i386/mm/ioremap.c
@@ -238,19 +238,21 @@ void iounmap(volatile void __iomem *addr)
238 addr < phys_to_virt(ISA_END_ADDRESS)) 238 addr < phys_to_virt(ISA_END_ADDRESS))
239 return; 239 return;
240 240
241 p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr)); 241 write_lock(&vmlist_lock);
242 p = __remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
242 if (!p) { 243 if (!p) {
243 printk("__iounmap: bad address %p\n", addr); 244 printk("iounmap: bad address %p\n", addr);
244 return; 245 goto out_unlock;
245 } 246 }
246 247
247 if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) { 248 if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) {
248 /* p->size includes the guard page, but cpa doesn't like that */
249 change_page_attr(virt_to_page(__va(p->phys_addr)), 249 change_page_attr(virt_to_page(__va(p->phys_addr)),
250 p->size >> PAGE_SHIFT, 250 p->size >> PAGE_SHIFT,
251 PAGE_KERNEL); 251 PAGE_KERNEL);
252 global_flush_tlb(); 252 global_flush_tlb();
253 } 253 }
254out_unlock:
255 write_unlock(&vmlist_lock);
254 kfree(p); 256 kfree(p);
255} 257}
256 258
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
index be52c5ac4e05..8e8e895e1b5a 100644
--- a/arch/i386/pci/fixup.c
+++ b/arch/i386/pci/fixup.c
@@ -253,7 +253,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci
253#define MAX_PCIEROOT 6 253#define MAX_PCIEROOT 6
254static int quirk_aspm_offset[MAX_PCIEROOT << 3]; 254static int quirk_aspm_offset[MAX_PCIEROOT << 3];
255 255
256#define GET_INDEX(a, b) (((a - PCI_DEVICE_ID_INTEL_MCH_PA) << 3) + b) 256#define GET_INDEX(a, b) ((((a) - PCI_DEVICE_ID_INTEL_MCH_PA) << 3) + ((b) & 7))
257 257
258static int quirk_pcie_aspm_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) 258static int quirk_pcie_aspm_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
259{ 259{
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
index d6598da4b67b..da21b1d07c15 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -1029,7 +1029,6 @@ void pcibios_penalize_isa_irq(int irq)
1029static int pirq_enable_irq(struct pci_dev *dev) 1029static int pirq_enable_irq(struct pci_dev *dev)
1030{ 1030{
1031 u8 pin; 1031 u8 pin;
1032 extern int via_interrupt_line_quirk;
1033 struct pci_dev *temp_dev; 1032 struct pci_dev *temp_dev;
1034 1033
1035 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); 1034 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
@@ -1084,10 +1083,6 @@ static int pirq_enable_irq(struct pci_dev *dev)
1084 printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n", 1083 printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
1085 'A' + pin, pci_name(dev), msg); 1084 'A' + pin, pci_name(dev), msg);
1086 } 1085 }
1087 /* VIA bridges use interrupt line for apic/pci steering across
1088 the V-Link */
1089 else if (via_interrupt_line_quirk)
1090 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq & 15);
1091 return 0; 1086 return 0;
1092} 1087}
1093 1088
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 468dbe8a6b9c..3ad2c4af099c 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -46,6 +46,10 @@ config GENERIC_IOMAP
46 bool 46 bool
47 default y 47 default y
48 48
49config SCHED_NO_NO_OMIT_FRAME_POINTER
50 bool
51 default y
52
49choice 53choice
50 prompt "System type" 54 prompt "System type"
51 default IA64_GENERIC 55 default IA64_GENERIC
@@ -217,6 +221,16 @@ config IA64_SGI_SN_SIM
217 If you are compiling a kernel that will run under SGI's IA-64 221 If you are compiling a kernel that will run under SGI's IA-64
218 simulator (Medusa) then say Y, otherwise say N. 222 simulator (Medusa) then say Y, otherwise say N.
219 223
224config IA64_SGI_SN_XP
225 tristate "Support communication between SGI SSIs"
226 depends on MSPEC
227 help
228 An SGI machine can be divided into multiple Single System
229 Images which act independently of each other and have
230 hardware based memory protection from the others. Enabling
231 this feature will allow for direct communication between SSIs
232 based on a network adapter and DMA messaging.
233
220config FORCE_MAX_ZONEORDER 234config FORCE_MAX_ZONEORDER
221 int 235 int
222 default "18" 236 default "18"
@@ -261,6 +275,15 @@ config HOTPLUG_CPU
261 can be controlled through /sys/devices/system/cpu/cpu#. 275 can be controlled through /sys/devices/system/cpu/cpu#.
262 Say N if you want to disable CPU hotplug. 276 Say N if you want to disable CPU hotplug.
263 277
278config SCHED_SMT
279 bool "SMT scheduler support"
280 depends on SMP
281 default off
282 help
283 Improves the CPU scheduler's decision making when dealing with
284 Intel IA64 chips with MultiThreading at a cost of slightly increased
285 overhead in some places. If unsure say N here.
286
264config PREEMPT 287config PREEMPT
265 bool "Preemptible Kernel" 288 bool "Preemptible Kernel"
266 help 289 help
diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig
index 99830e8fc9ba..9086b789f6ac 100644
--- a/arch/ia64/configs/tiger_defconfig
+++ b/arch/ia64/configs/tiger_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-rc2 3# Linux kernel version: 2.6.12-rc3
4# Sat Jan 22 11:17:02 2005 4# Tue May 3 15:55:04 2005
5# 5#
6 6
7# 7#
@@ -10,6 +10,7 @@
10CONFIG_EXPERIMENTAL=y 10CONFIG_EXPERIMENTAL=y
11CONFIG_CLEAN_COMPILE=y 11CONFIG_CLEAN_COMPILE=y
12CONFIG_LOCK_KERNEL=y 12CONFIG_LOCK_KERNEL=y
13CONFIG_INIT_ENV_ARG_LIMIT=32
13 14
14# 15#
15# General setup 16# General setup
@@ -21,24 +22,27 @@ CONFIG_POSIX_MQUEUE=y
21# CONFIG_BSD_PROCESS_ACCT is not set 22# CONFIG_BSD_PROCESS_ACCT is not set
22CONFIG_SYSCTL=y 23CONFIG_SYSCTL=y
23# CONFIG_AUDIT is not set 24# CONFIG_AUDIT is not set
24CONFIG_LOG_BUF_SHIFT=20
25CONFIG_HOTPLUG=y 25CONFIG_HOTPLUG=y
26CONFIG_KOBJECT_UEVENT=y 26CONFIG_KOBJECT_UEVENT=y
27CONFIG_IKCONFIG=y 27CONFIG_IKCONFIG=y
28CONFIG_IKCONFIG_PROC=y 28CONFIG_IKCONFIG_PROC=y
29# CONFIG_CPUSETS is not set
29# CONFIG_EMBEDDED is not set 30# CONFIG_EMBEDDED is not set
30CONFIG_KALLSYMS=y 31CONFIG_KALLSYMS=y
31CONFIG_KALLSYMS_ALL=y 32CONFIG_KALLSYMS_ALL=y
32# CONFIG_KALLSYMS_EXTRA_PASS is not set 33# CONFIG_KALLSYMS_EXTRA_PASS is not set
34CONFIG_PRINTK=y
35CONFIG_BUG=y
36CONFIG_BASE_FULL=y
33CONFIG_FUTEX=y 37CONFIG_FUTEX=y
34CONFIG_EPOLL=y 38CONFIG_EPOLL=y
35# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
36CONFIG_SHMEM=y 39CONFIG_SHMEM=y
37CONFIG_CC_ALIGN_FUNCTIONS=0 40CONFIG_CC_ALIGN_FUNCTIONS=0
38CONFIG_CC_ALIGN_LABELS=0 41CONFIG_CC_ALIGN_LABELS=0
39CONFIG_CC_ALIGN_LOOPS=0 42CONFIG_CC_ALIGN_LOOPS=0
40CONFIG_CC_ALIGN_JUMPS=0 43CONFIG_CC_ALIGN_JUMPS=0
41# CONFIG_TINY_SHMEM is not set 44# CONFIG_TINY_SHMEM is not set
45CONFIG_BASE_SMALL=0
42 46
43# 47#
44# Loadable module support 48# Loadable module support
@@ -85,6 +89,7 @@ CONFIG_FORCE_MAX_ZONEORDER=18
85CONFIG_SMP=y 89CONFIG_SMP=y
86CONFIG_NR_CPUS=4 90CONFIG_NR_CPUS=4
87CONFIG_HOTPLUG_CPU=y 91CONFIG_HOTPLUG_CPU=y
92# CONFIG_SCHED_SMT is not set
88# CONFIG_PREEMPT is not set 93# CONFIG_PREEMPT is not set
89CONFIG_HAVE_DEC_LOCK=y 94CONFIG_HAVE_DEC_LOCK=y
90CONFIG_IA32_SUPPORT=y 95CONFIG_IA32_SUPPORT=y
@@ -135,6 +140,7 @@ CONFIG_PCI_DOMAINS=y
135# CONFIG_PCI_MSI is not set 140# CONFIG_PCI_MSI is not set
136CONFIG_PCI_LEGACY_PROC=y 141CONFIG_PCI_LEGACY_PROC=y
137CONFIG_PCI_NAMES=y 142CONFIG_PCI_NAMES=y
143# CONFIG_PCI_DEBUG is not set
138 144
139# 145#
140# PCI Hotplug Support 146# PCI Hotplug Support
@@ -152,10 +158,6 @@ CONFIG_HOTPLUG_PCI_ACPI=m
152# CONFIG_PCCARD is not set 158# CONFIG_PCCARD is not set
153 159
154# 160#
155# PC-card bridges
156#
157
158#
159# Device Drivers 161# Device Drivers
160# 162#
161 163
@@ -195,9 +197,10 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
195CONFIG_BLK_DEV_NBD=m 197CONFIG_BLK_DEV_NBD=m
196# CONFIG_BLK_DEV_SX8 is not set 198# CONFIG_BLK_DEV_SX8 is not set
197# CONFIG_BLK_DEV_UB is not set 199# CONFIG_BLK_DEV_UB is not set
198CONFIG_BLK_DEV_RAM=m 200CONFIG_BLK_DEV_RAM=y
199CONFIG_BLK_DEV_RAM_COUNT=16 201CONFIG_BLK_DEV_RAM_COUNT=16
200CONFIG_BLK_DEV_RAM_SIZE=4096 202CONFIG_BLK_DEV_RAM_SIZE=4096
203CONFIG_BLK_DEV_INITRD=y
201CONFIG_INITRAMFS_SOURCE="" 204CONFIG_INITRAMFS_SOURCE=""
202# CONFIG_CDROM_PKTCDVD is not set 205# CONFIG_CDROM_PKTCDVD is not set
203 206
@@ -313,7 +316,6 @@ CONFIG_SCSI_FC_ATTRS=y
313# CONFIG_SCSI_BUSLOGIC is not set 316# CONFIG_SCSI_BUSLOGIC is not set
314# CONFIG_SCSI_DMX3191D is not set 317# CONFIG_SCSI_DMX3191D is not set
315# CONFIG_SCSI_EATA is not set 318# CONFIG_SCSI_EATA is not set
316# CONFIG_SCSI_EATA_PIO is not set
317# CONFIG_SCSI_FUTURE_DOMAIN is not set 319# CONFIG_SCSI_FUTURE_DOMAIN is not set
318# CONFIG_SCSI_GDTH is not set 320# CONFIG_SCSI_GDTH is not set
319# CONFIG_SCSI_IPS is not set 321# CONFIG_SCSI_IPS is not set
@@ -325,7 +327,6 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
325CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 327CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
326# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set 328# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
327# CONFIG_SCSI_IPR is not set 329# CONFIG_SCSI_IPR is not set
328# CONFIG_SCSI_QLOGIC_ISP is not set
329CONFIG_SCSI_QLOGIC_FC=y 330CONFIG_SCSI_QLOGIC_FC=y
330# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set 331# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
331CONFIG_SCSI_QLOGIC_1280=y 332CONFIG_SCSI_QLOGIC_1280=y
@@ -336,6 +337,7 @@ CONFIG_SCSI_QLA22XX=m
336CONFIG_SCSI_QLA2300=m 337CONFIG_SCSI_QLA2300=m
337CONFIG_SCSI_QLA2322=m 338CONFIG_SCSI_QLA2322=m
338# CONFIG_SCSI_QLA6312 is not set 339# CONFIG_SCSI_QLA6312 is not set
340# CONFIG_SCSI_LPFC is not set
339# CONFIG_SCSI_DC395x is not set 341# CONFIG_SCSI_DC395x is not set
340# CONFIG_SCSI_DC390T is not set 342# CONFIG_SCSI_DC390T is not set
341# CONFIG_SCSI_DEBUG is not set 343# CONFIG_SCSI_DEBUG is not set
@@ -358,6 +360,7 @@ CONFIG_DM_CRYPT=m
358CONFIG_DM_SNAPSHOT=m 360CONFIG_DM_SNAPSHOT=m
359CONFIG_DM_MIRROR=m 361CONFIG_DM_MIRROR=m
360CONFIG_DM_ZERO=m 362CONFIG_DM_ZERO=m
363# CONFIG_DM_MULTIPATH is not set
361 364
362# 365#
363# Fusion MPT device support 366# Fusion MPT device support
@@ -386,7 +389,6 @@ CONFIG_NET=y
386# 389#
387CONFIG_PACKET=y 390CONFIG_PACKET=y
388# CONFIG_PACKET_MMAP is not set 391# CONFIG_PACKET_MMAP is not set
389CONFIG_NETLINK_DEV=y
390CONFIG_UNIX=y 392CONFIG_UNIX=y
391# CONFIG_NET_KEY is not set 393# CONFIG_NET_KEY is not set
392CONFIG_INET=y 394CONFIG_INET=y
@@ -446,7 +448,6 @@ CONFIG_DUMMY=m
446# CONFIG_BONDING is not set 448# CONFIG_BONDING is not set
447# CONFIG_EQUALIZER is not set 449# CONFIG_EQUALIZER is not set
448# CONFIG_TUN is not set 450# CONFIG_TUN is not set
449# CONFIG_ETHERTAP is not set
450 451
451# 452#
452# ARCnet devices 453# ARCnet devices
@@ -484,7 +485,6 @@ CONFIG_NET_PCI=y
484# CONFIG_DGRS is not set 485# CONFIG_DGRS is not set
485CONFIG_EEPRO100=m 486CONFIG_EEPRO100=m
486CONFIG_E100=m 487CONFIG_E100=m
487# CONFIG_E100_NAPI is not set
488# CONFIG_FEALNX is not set 488# CONFIG_FEALNX is not set
489# CONFIG_NATSEMI is not set 489# CONFIG_NATSEMI is not set
490# CONFIG_NE2K_PCI is not set 490# CONFIG_NE2K_PCI is not set
@@ -566,25 +566,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
566# CONFIG_INPUT_EVBUG is not set 566# CONFIG_INPUT_EVBUG is not set
567 567
568# 568#
569# Input I/O drivers
570#
571CONFIG_GAMEPORT=m
572CONFIG_SOUND_GAMEPORT=m
573# CONFIG_GAMEPORT_NS558 is not set
574# CONFIG_GAMEPORT_L4 is not set
575# CONFIG_GAMEPORT_EMU10K1 is not set
576# CONFIG_GAMEPORT_VORTEX is not set
577# CONFIG_GAMEPORT_FM801 is not set
578# CONFIG_GAMEPORT_CS461X is not set
579CONFIG_SERIO=y
580CONFIG_SERIO_I8042=y
581# CONFIG_SERIO_SERPORT is not set
582# CONFIG_SERIO_CT82C710 is not set
583# CONFIG_SERIO_PCIPS2 is not set
584CONFIG_SERIO_LIBPS2=y
585# CONFIG_SERIO_RAW is not set
586
587#
588# Input Device Drivers 569# Input Device Drivers
589# 570#
590CONFIG_INPUT_KEYBOARD=y 571CONFIG_INPUT_KEYBOARD=y
@@ -602,6 +583,24 @@ CONFIG_MOUSE_PS2=y
602# CONFIG_INPUT_MISC is not set 583# CONFIG_INPUT_MISC is not set
603 584
604# 585#
586# Hardware I/O ports
587#
588CONFIG_SERIO=y
589CONFIG_SERIO_I8042=y
590# CONFIG_SERIO_SERPORT is not set
591# CONFIG_SERIO_PCIPS2 is not set
592CONFIG_SERIO_LIBPS2=y
593# CONFIG_SERIO_RAW is not set
594CONFIG_GAMEPORT=m
595# CONFIG_GAMEPORT_NS558 is not set
596# CONFIG_GAMEPORT_L4 is not set
597# CONFIG_GAMEPORT_EMU10K1 is not set
598# CONFIG_GAMEPORT_VORTEX is not set
599# CONFIG_GAMEPORT_FM801 is not set
600# CONFIG_GAMEPORT_CS461X is not set
601CONFIG_SOUND_GAMEPORT=m
602
603#
605# Character devices 604# Character devices
606# 605#
607CONFIG_VT=y 606CONFIG_VT=y
@@ -615,6 +614,8 @@ CONFIG_SERIAL_NONSTANDARD=y
615# CONFIG_SYNCLINK is not set 614# CONFIG_SYNCLINK is not set
616# CONFIG_SYNCLINKMP is not set 615# CONFIG_SYNCLINKMP is not set
617# CONFIG_N_HDLC is not set 616# CONFIG_N_HDLC is not set
617# CONFIG_SPECIALIX is not set
618# CONFIG_SX is not set
618# CONFIG_STALDRV is not set 619# CONFIG_STALDRV is not set
619 620
620# 621#
@@ -635,6 +636,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
635# 636#
636CONFIG_SERIAL_CORE=y 637CONFIG_SERIAL_CORE=y
637CONFIG_SERIAL_CORE_CONSOLE=y 638CONFIG_SERIAL_CORE_CONSOLE=y
639# CONFIG_SERIAL_JSM is not set
638CONFIG_UNIX98_PTYS=y 640CONFIG_UNIX98_PTYS=y
639CONFIG_LEGACY_PTYS=y 641CONFIG_LEGACY_PTYS=y
640CONFIG_LEGACY_PTY_COUNT=256 642CONFIG_LEGACY_PTY_COUNT=256
@@ -670,6 +672,12 @@ CONFIG_HPET=y
670# CONFIG_HPET_RTC_IRQ is not set 672# CONFIG_HPET_RTC_IRQ is not set
671CONFIG_HPET_MMAP=y 673CONFIG_HPET_MMAP=y
672CONFIG_MAX_RAW_DEVS=256 674CONFIG_MAX_RAW_DEVS=256
675# CONFIG_HANGCHECK_TIMER is not set
676
677#
678# TPM devices
679#
680# CONFIG_TCG_TPM is not set
673 681
674# 682#
675# I2C support 683# I2C support
@@ -705,7 +713,6 @@ CONFIG_MAX_RAW_DEVS=256
705# 713#
706CONFIG_VGA_CONSOLE=y 714CONFIG_VGA_CONSOLE=y
707CONFIG_DUMMY_CONSOLE=y 715CONFIG_DUMMY_CONSOLE=y
708# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
709 716
710# 717#
711# Sound 718# Sound
@@ -715,6 +722,8 @@ CONFIG_DUMMY_CONSOLE=y
715# 722#
716# USB support 723# USB support
717# 724#
725CONFIG_USB_ARCH_HAS_HCD=y
726CONFIG_USB_ARCH_HAS_OHCI=y
718CONFIG_USB=y 727CONFIG_USB=y
719# CONFIG_USB_DEBUG is not set 728# CONFIG_USB_DEBUG is not set
720 729
@@ -726,8 +735,6 @@ CONFIG_USB_DEVICEFS=y
726# CONFIG_USB_DYNAMIC_MINORS is not set 735# CONFIG_USB_DYNAMIC_MINORS is not set
727# CONFIG_USB_SUSPEND is not set 736# CONFIG_USB_SUSPEND is not set
728# CONFIG_USB_OTG is not set 737# CONFIG_USB_OTG is not set
729CONFIG_USB_ARCH_HAS_HCD=y
730CONFIG_USB_ARCH_HAS_OHCI=y
731 738
732# 739#
733# USB Host Controller Drivers 740# USB Host Controller Drivers
@@ -736,6 +743,8 @@ CONFIG_USB_EHCI_HCD=m
736# CONFIG_USB_EHCI_SPLIT_ISO is not set 743# CONFIG_USB_EHCI_SPLIT_ISO is not set
737# CONFIG_USB_EHCI_ROOT_HUB_TT is not set 744# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
738CONFIG_USB_OHCI_HCD=m 745CONFIG_USB_OHCI_HCD=m
746# CONFIG_USB_OHCI_BIG_ENDIAN is not set
747CONFIG_USB_OHCI_LITTLE_ENDIAN=y
739CONFIG_USB_UHCI_HCD=y 748CONFIG_USB_UHCI_HCD=y
740# CONFIG_USB_SL811_HCD is not set 749# CONFIG_USB_SL811_HCD is not set
741 750
@@ -751,12 +760,11 @@ CONFIG_USB_UHCI_HCD=y
751# 760#
752CONFIG_USB_STORAGE=m 761CONFIG_USB_STORAGE=m
753# CONFIG_USB_STORAGE_DEBUG is not set 762# CONFIG_USB_STORAGE_DEBUG is not set
754# CONFIG_USB_STORAGE_RW_DETECT is not set
755# CONFIG_USB_STORAGE_DATAFAB is not set 763# CONFIG_USB_STORAGE_DATAFAB is not set
756# CONFIG_USB_STORAGE_FREECOM is not set 764# CONFIG_USB_STORAGE_FREECOM is not set
757# CONFIG_USB_STORAGE_ISD200 is not set 765# CONFIG_USB_STORAGE_ISD200 is not set
758# CONFIG_USB_STORAGE_DPCM is not set 766# CONFIG_USB_STORAGE_DPCM is not set
759# CONFIG_USB_STORAGE_HP8200e is not set 767# CONFIG_USB_STORAGE_USBAT is not set
760# CONFIG_USB_STORAGE_SDDR09 is not set 768# CONFIG_USB_STORAGE_SDDR09 is not set
761# CONFIG_USB_STORAGE_SDDR55 is not set 769# CONFIG_USB_STORAGE_SDDR55 is not set
762# CONFIG_USB_STORAGE_JUMPSHOT is not set 770# CONFIG_USB_STORAGE_JUMPSHOT is not set
@@ -800,6 +808,7 @@ CONFIG_USB_HIDINPUT=y
800# CONFIG_USB_PEGASUS is not set 808# CONFIG_USB_PEGASUS is not set
801# CONFIG_USB_RTL8150 is not set 809# CONFIG_USB_RTL8150 is not set
802# CONFIG_USB_USBNET is not set 810# CONFIG_USB_USBNET is not set
811# CONFIG_USB_MON is not set
803 812
804# 813#
805# USB port drivers 814# USB port drivers
@@ -824,6 +833,7 @@ CONFIG_USB_HIDINPUT=y
824# CONFIG_USB_PHIDGETKIT is not set 833# CONFIG_USB_PHIDGETKIT is not set
825# CONFIG_USB_PHIDGETSERVO is not set 834# CONFIG_USB_PHIDGETSERVO is not set
826# CONFIG_USB_IDMOUSE is not set 835# CONFIG_USB_IDMOUSE is not set
836# CONFIG_USB_SISUSBVGA is not set
827# CONFIG_USB_TEST is not set 837# CONFIG_USB_TEST is not set
828 838
829# 839#
@@ -867,7 +877,12 @@ CONFIG_REISERFS_FS_POSIX_ACL=y
867CONFIG_REISERFS_FS_SECURITY=y 877CONFIG_REISERFS_FS_SECURITY=y
868# CONFIG_JFS_FS is not set 878# CONFIG_JFS_FS is not set
869CONFIG_FS_POSIX_ACL=y 879CONFIG_FS_POSIX_ACL=y
880
881#
882# XFS support
883#
870CONFIG_XFS_FS=y 884CONFIG_XFS_FS=y
885CONFIG_XFS_EXPORT=y
871# CONFIG_XFS_RT is not set 886# CONFIG_XFS_RT is not set
872# CONFIG_XFS_QUOTA is not set 887# CONFIG_XFS_QUOTA is not set
873# CONFIG_XFS_SECURITY is not set 888# CONFIG_XFS_SECURITY is not set
@@ -945,7 +960,7 @@ CONFIG_NFSD_V4=y
945CONFIG_NFSD_TCP=y 960CONFIG_NFSD_TCP=y
946CONFIG_LOCKD=m 961CONFIG_LOCKD=m
947CONFIG_LOCKD_V4=y 962CONFIG_LOCKD_V4=y
948CONFIG_EXPORTFS=m 963CONFIG_EXPORTFS=y
949CONFIG_SUNRPC=m 964CONFIG_SUNRPC=m
950CONFIG_SUNRPC_GSS=m 965CONFIG_SUNRPC_GSS=m
951CONFIG_RPCSEC_GSS_KRB5=m 966CONFIG_RPCSEC_GSS_KRB5=m
@@ -1042,8 +1057,10 @@ CONFIG_GENERIC_IRQ_PROBE=y
1042# 1057#
1043# Kernel hacking 1058# Kernel hacking
1044# 1059#
1060# CONFIG_PRINTK_TIME is not set
1045CONFIG_DEBUG_KERNEL=y 1061CONFIG_DEBUG_KERNEL=y
1046CONFIG_MAGIC_SYSRQ=y 1062CONFIG_MAGIC_SYSRQ=y
1063CONFIG_LOG_BUF_SHIFT=20
1047# CONFIG_SCHEDSTATS is not set 1064# CONFIG_SCHEDSTATS is not set
1048# CONFIG_DEBUG_SLAB is not set 1065# CONFIG_DEBUG_SLAB is not set
1049# CONFIG_DEBUG_SPINLOCK is not set 1066# CONFIG_DEBUG_SPINLOCK is not set
@@ -1077,6 +1094,7 @@ CONFIG_CRYPTO_MD5=m
1077# CONFIG_CRYPTO_SHA256 is not set 1094# CONFIG_CRYPTO_SHA256 is not set
1078# CONFIG_CRYPTO_SHA512 is not set 1095# CONFIG_CRYPTO_SHA512 is not set
1079# CONFIG_CRYPTO_WP512 is not set 1096# CONFIG_CRYPTO_WP512 is not set
1097# CONFIG_CRYPTO_TGR192 is not set
1080CONFIG_CRYPTO_DES=m 1098CONFIG_CRYPTO_DES=m
1081# CONFIG_CRYPTO_BLOWFISH is not set 1099# CONFIG_CRYPTO_BLOWFISH is not set
1082# CONFIG_CRYPTO_TWOFISH is not set 1100# CONFIG_CRYPTO_TWOFISH is not set
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index 6a8fcba7a853..b8db6e3e5e81 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -1944,43 +1944,17 @@ sba_connect_bus(struct pci_bus *bus)
1944static void __init 1944static void __init
1945sba_map_ioc_to_node(struct ioc *ioc, acpi_handle handle) 1945sba_map_ioc_to_node(struct ioc *ioc, acpi_handle handle)
1946{ 1946{
1947 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
1948 union acpi_object *obj;
1949 acpi_handle phandle;
1950 unsigned int node; 1947 unsigned int node;
1948 int pxm;
1951 1949
1952 ioc->node = MAX_NUMNODES; 1950 ioc->node = MAX_NUMNODES;
1953 1951
1954 /* 1952 pxm = acpi_get_pxm(handle);
1955 * Check for a _PXM on this node first. We don't typically see
1956 * one here, so we'll end up getting it from the parent.
1957 */
1958 if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PXM", NULL, &buffer))) {
1959 if (ACPI_FAILURE(acpi_get_parent(handle, &phandle)))
1960 return;
1961
1962 /* Reset the acpi buffer */
1963 buffer.length = ACPI_ALLOCATE_BUFFER;
1964 buffer.pointer = NULL;
1965
1966 if (ACPI_FAILURE(acpi_evaluate_object(phandle, "_PXM", NULL,
1967 &buffer)))
1968 return;
1969 }
1970 1953
1971 if (!buffer.length || !buffer.pointer) 1954 if (pxm < 0)
1972 return; 1955 return;
1973 1956
1974 obj = buffer.pointer; 1957 node = pxm_to_nid_map[pxm];
1975
1976 if (obj->type != ACPI_TYPE_INTEGER ||
1977 obj->integer.value >= MAX_PXM_DOMAINS) {
1978 acpi_os_free(buffer.pointer);
1979 return;
1980 }
1981
1982 node = pxm_to_nid_map[obj->integer.value];
1983 acpi_os_free(buffer.pointer);
1984 1958
1985 if (node >= MAX_NUMNODES || !node_online(node)) 1959 if (node >= MAX_NUMNODES || !node_online(node))
1986 return; 1960 return;
diff --git a/arch/ia64/ia32/ia32_ioctl.c b/arch/ia64/ia32/ia32_ioctl.c
index 9845dabe2613..164b211f4174 100644
--- a/arch/ia64/ia32/ia32_ioctl.c
+++ b/arch/ia64/ia32/ia32_ioctl.c
@@ -13,7 +13,6 @@
13 13
14#define INCLUDES 14#define INCLUDES
15#include "compat_ioctl.c" 15#include "compat_ioctl.c"
16#include <asm/ioctl32.h>
17 16
18#define IOCTL_NR(a) ((a) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) 17#define IOCTL_NR(a) ((a) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))
19 18
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index 247a21c64aea..c1e20d65dd6c 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -2427,7 +2427,7 @@ sys32_epoll_wait(int epfd, struct epoll_event32 __user * events, int maxevents,
2427{ 2427{
2428 struct epoll_event *events64 = NULL; 2428 struct epoll_event *events64 = NULL;
2429 mm_segment_t old_fs = get_fs(); 2429 mm_segment_t old_fs = get_fs();
2430 int error, numevents, size; 2430 int numevents, size;
2431 int evt_idx; 2431 int evt_idx;
2432 int do_free_pages = 0; 2432 int do_free_pages = 0;
2433 2433
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index a8e99c56a768..72dfd9e7de0f 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -779,7 +779,7 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
779 union acpi_object *obj; 779 union acpi_object *obj;
780 struct acpi_table_iosapic *iosapic; 780 struct acpi_table_iosapic *iosapic;
781 unsigned int gsi_base; 781 unsigned int gsi_base;
782 int node; 782 int pxm, node;
783 783
784 /* Only care about objects w/ a method that returns the MADT */ 784 /* Only care about objects w/ a method that returns the MADT */
785 if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) 785 if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
@@ -805,29 +805,16 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
805 gsi_base = iosapic->global_irq_base; 805 gsi_base = iosapic->global_irq_base;
806 806
807 acpi_os_free(buffer.pointer); 807 acpi_os_free(buffer.pointer);
808 buffer.length = ACPI_ALLOCATE_BUFFER;
809 buffer.pointer = NULL;
810 808
811 /* 809 /*
812 * OK, it's an IOSAPIC MADT entry, look for a _PXM method to tell 810 * OK, it's an IOSAPIC MADT entry, look for a _PXM value to tell
813 * us which node to associate this with. 811 * us which node to associate this with.
814 */ 812 */
815 if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PXM", NULL, &buffer))) 813 pxm = acpi_get_pxm(handle);
816 return AE_OK; 814 if (pxm < 0)
817
818 if (!buffer.length || !buffer.pointer)
819 return AE_OK;
820
821 obj = buffer.pointer;
822
823 if (obj->type != ACPI_TYPE_INTEGER ||
824 obj->integer.value >= MAX_PXM_DOMAINS) {
825 acpi_os_free(buffer.pointer);
826 return AE_OK; 815 return AE_OK;
827 }
828 816
829 node = pxm_to_nid_map[obj->integer.value]; 817 node = pxm_to_nid_map[pxm];
830 acpi_os_free(buffer.pointer);
831 818
832 if (node >= MAX_NUMNODES || !node_online(node) || 819 if (node >= MAX_NUMNODES || !node_online(node) ||
833 cpus_empty(node_to_cpumask(node))) 820 cpus_empty(node_to_cpumask(node)))
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 9353adc18956..8ebfcc0c813a 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -777,7 +777,7 @@ GLOBAL_ENTRY(ia64_ret_from_ia32_execve)
777 st8.spill [r2]=r8 // store return value in slot for r8 and set unat bit 777 st8.spill [r2]=r8 // store return value in slot for r8 and set unat bit
778 .mem.offset 8,0 778 .mem.offset 8,0
779 st8.spill [r3]=r0 // clear error indication in slot for r10 and set unat bit 779 st8.spill [r3]=r0 // clear error indication in slot for r10 and set unat bit
780END(ia64_ret_from_ia32_execve_syscall) 780END(ia64_ret_from_ia32_execve)
781 // fall through 781 // fall through
782#endif /* CONFIG_IA32_SUPPORT */ 782#endif /* CONFIG_IA32_SUPPORT */
783GLOBAL_ENTRY(ia64_leave_kernel) 783GLOBAL_ENTRY(ia64_leave_kernel)
@@ -1176,7 +1176,7 @@ ENTRY(notify_resume_user)
1176 ;; 1176 ;;
1177(pNonSys) mov out2=0 // out2==0 => not a syscall 1177(pNonSys) mov out2=0 // out2==0 => not a syscall
1178 .fframe 16 1178 .fframe 16
1179 .spillpsp ar.unat, 16 // (note that offset is relative to psp+0x10!) 1179 .spillsp ar.unat, 16
1180 st8 [sp]=r9,-16 // allocate space for ar.unat and save it 1180 st8 [sp]=r9,-16 // allocate space for ar.unat and save it
1181 st8 [out1]=loc1,-8 // save ar.pfs, out1=&sigscratch 1181 st8 [out1]=loc1,-8 // save ar.pfs, out1=&sigscratch
1182 .body 1182 .body
@@ -1202,7 +1202,7 @@ GLOBAL_ENTRY(sys_rt_sigsuspend)
1202 adds out2=8,sp // out2=&sigscratch->ar_pfs 1202 adds out2=8,sp // out2=&sigscratch->ar_pfs
1203 ;; 1203 ;;
1204 .fframe 16 1204 .fframe 16
1205 .spillpsp ar.unat, 16 // (note that offset is relative to psp+0x10!) 1205 .spillsp ar.unat, 16
1206 st8 [sp]=r9,-16 // allocate space for ar.unat and save it 1206 st8 [sp]=r9,-16 // allocate space for ar.unat and save it
1207 st8 [out2]=loc1,-8 // save ar.pfs, out2=&sigscratch 1207 st8 [out2]=loc1,-8 // save ar.pfs, out2=&sigscratch
1208 .body 1208 .body
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S
index f566ff43a389..7d7684a369d3 100644
--- a/arch/ia64/kernel/fsys.S
+++ b/arch/ia64/kernel/fsys.S
@@ -460,9 +460,9 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set
460 ;; 460 ;;
461 461
462 st8 [r2]=r14 // update current->blocked with new mask 462 st8 [r2]=r14 // update current->blocked with new mask
463 cmpxchg4.acq r14=[r9],r18,ar.ccv // current->thread_info->flags <- r18 463 cmpxchg4.acq r8=[r9],r18,ar.ccv // current->thread_info->flags <- r18
464 ;; 464 ;;
465 cmp.ne p6,p0=r17,r14 // update failed? 465 cmp.ne p6,p0=r17,r8 // update failed?
466(p6) br.cond.spnt.few 1b // yes -> retry 466(p6) br.cond.spnt.few 1b // yes -> retry
467 467
468#ifdef CONFIG_SMP 468#ifdef CONFIG_SMP
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 4d6c7b8f667b..736e328b5e61 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -1103,8 +1103,6 @@ ia64_mca_cpe_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs)
1103 return IRQ_HANDLED; 1103 return IRQ_HANDLED;
1104} 1104}
1105 1105
1106#endif /* CONFIG_ACPI */
1107
1108/* 1106/*
1109 * ia64_mca_cpe_poll 1107 * ia64_mca_cpe_poll
1110 * 1108 *
@@ -1122,6 +1120,8 @@ ia64_mca_cpe_poll (unsigned long dummy)
1122 platform_send_ipi(first_cpu(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0); 1120 platform_send_ipi(first_cpu(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
1123} 1121}
1124 1122
1123#endif /* CONFIG_ACPI */
1124
1125/* 1125/*
1126 * C portion of the OS INIT handler 1126 * C portion of the OS INIT handler
1127 * 1127 *
@@ -1390,8 +1390,7 @@ ia64_mca_init(void)
1390 register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction); 1390 register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction);
1391 1391
1392#ifdef CONFIG_ACPI 1392#ifdef CONFIG_ACPI
1393 /* Setup the CPEI/P vector and handler */ 1393 /* Setup the CPEI/P handler */
1394 cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI);
1395 register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction); 1394 register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction);
1396#endif 1395#endif
1397 1396
@@ -1436,6 +1435,7 @@ ia64_mca_late_init(void)
1436 1435
1437#ifdef CONFIG_ACPI 1436#ifdef CONFIG_ACPI
1438 /* Setup the CPEI/P vector and handler */ 1437 /* Setup the CPEI/P vector and handler */
1438 cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI);
1439 init_timer(&cpe_poll_timer); 1439 init_timer(&cpe_poll_timer);
1440 cpe_poll_timer.function = ia64_mca_cpe_poll; 1440 cpe_poll_timer.function = ia64_mca_cpe_poll;
1441 1441
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c
index ab478172c349..abc0113a821d 100644
--- a/arch/ia64/kernel/mca_drv.c
+++ b/arch/ia64/kernel/mca_drv.c
@@ -132,8 +132,7 @@ mca_handler_bh(unsigned long paddr)
132 spin_unlock(&mca_bh_lock); 132 spin_unlock(&mca_bh_lock);
133 133
134 /* This process is about to be killed itself */ 134 /* This process is about to be killed itself */
135 force_sig(SIGKILL, current); 135 do_exit(SIGKILL);
136 schedule();
137} 136}
138 137
139/** 138/**
@@ -439,6 +438,7 @@ recover_from_read_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_chec
439 psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr; 438 psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr;
440 psr2->cpl = 0; 439 psr2->cpl = 0;
441 psr2->ri = 0; 440 psr2->ri = 0;
441 psr2->i = 0;
442 442
443 return 1; 443 return 1;
444 } 444 }
diff --git a/arch/ia64/kernel/mca_drv_asm.S b/arch/ia64/kernel/mca_drv_asm.S
index bcfa05acc561..2d7e0217638d 100644
--- a/arch/ia64/kernel/mca_drv_asm.S
+++ b/arch/ia64/kernel/mca_drv_asm.S
@@ -10,6 +10,7 @@
10 10
11#include <asm/asmmacro.h> 11#include <asm/asmmacro.h>
12#include <asm/processor.h> 12#include <asm/processor.h>
13#include <asm/ptrace.h>
13 14
14GLOBAL_ENTRY(mca_handler_bhhook) 15GLOBAL_ENTRY(mca_handler_bhhook)
15 invala // clear RSE ? 16 invala // clear RSE ?
@@ -20,12 +21,21 @@ GLOBAL_ENTRY(mca_handler_bhhook)
20 ;; 21 ;;
21 alloc r16=ar.pfs,0,2,1,0 // make a new frame 22 alloc r16=ar.pfs,0,2,1,0 // make a new frame
22 ;; 23 ;;
24 mov ar.rsc=0
25 ;;
23 mov r13=IA64_KR(CURRENT) // current task pointer 26 mov r13=IA64_KR(CURRENT) // current task pointer
24 ;; 27 ;;
25 adds r12=IA64_TASK_THREAD_KSP_OFFSET,r13 28 mov r2=r13
29 ;;
30 addl r22=IA64_RBS_OFFSET,r2
31 ;;
32 mov ar.bspstore=r22
26 ;; 33 ;;
27 ld8 r12=[r12] // stack pointer 34 addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2
28 ;; 35 ;;
36 adds r2=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
37 ;;
38 st1 [r2]=r0 // clear current->thread.on_ustack flag
29 mov loc0=r16 39 mov loc0=r16
30 movl loc1=mca_handler_bh // recovery C function 40 movl loc1=mca_handler_bh // recovery C function
31 ;; 41 ;;
@@ -34,7 +44,9 @@ GLOBAL_ENTRY(mca_handler_bhhook)
34 ;; 44 ;;
35 mov loc1=rp 45 mov loc1=rp
36 ;; 46 ;;
37 br.call.sptk.many rp=b6 // not return ... 47 ssm psr.i
48 ;;
49 br.call.sptk.many rp=b6 // does not return ...
38 ;; 50 ;;
39 mov ar.pfs=loc0 51 mov ar.pfs=loc0
40 mov rp=loc1 52 mov rp=loc1
diff --git a/arch/ia64/kernel/minstate.h b/arch/ia64/kernel/minstate.h
index 1dbc7b2497c9..f6d8a010d99b 100644
--- a/arch/ia64/kernel/minstate.h
+++ b/arch/ia64/kernel/minstate.h
@@ -41,7 +41,7 @@
41(pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;; \ 41(pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;; \
42(pKStk) ld8 r3 = [r3];; \ 42(pKStk) ld8 r3 = [r3];; \
43(pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;; \ 43(pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;; \
44(pKStk) addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3; \ 44(pKStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3; \
45(pUStk) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \ 45(pUStk) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \
46(pUStk) addl r22=IA64_RBS_OFFSET,r1; /* compute base of register backing store */ \ 46(pUStk) addl r22=IA64_RBS_OFFSET,r1; /* compute base of register backing store */ \
47 ;; \ 47 ;; \
@@ -50,7 +50,6 @@
50(pUStk) mov r23=ar.bspstore; /* save ar.bspstore */ \ 50(pUStk) mov r23=ar.bspstore; /* save ar.bspstore */ \
51(pUStk) dep r22=-1,r22,61,3; /* compute kernel virtual addr of RBS */ \ 51(pUStk) dep r22=-1,r22,61,3; /* compute kernel virtual addr of RBS */ \
52 ;; \ 52 ;; \
53(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \
54(pUStk) mov ar.bspstore=r22; /* switch to kernel RBS */ \ 53(pUStk) mov ar.bspstore=r22; /* switch to kernel RBS */ \
55 ;; \ 54 ;; \
56(pUStk) mov r18=ar.bsp; \ 55(pUStk) mov r18=ar.bsp; \
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
index febc091c2f02..f1aca7cffd12 100644
--- a/arch/ia64/kernel/module.c
+++ b/arch/ia64/kernel/module.c
@@ -825,14 +825,16 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind
825 * XXX Should have an arch-hook for running this after final section 825 * XXX Should have an arch-hook for running this after final section
826 * addresses have been selected... 826 * addresses have been selected...
827 */ 827 */
828 /* See if gp can cover the entire core module: */ 828 uint64_t gp;
829 uint64_t gp = (uint64_t) mod->module_core + MAX_LTOFF / 2; 829 if (mod->core_size > MAX_LTOFF)
830 if (mod->core_size >= MAX_LTOFF)
831 /* 830 /*
832 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated 831 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
833 * at the end of the module. 832 * at the end of the module.
834 */ 833 */
835 gp = (uint64_t) mod->module_core + mod->core_size - MAX_LTOFF / 2; 834 gp = mod->core_size - MAX_LTOFF / 2;
835 else
836 gp = mod->core_size / 2;
837 gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
836 mod->arch.gp = gp; 838 mod->arch.gp = gp;
837 DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp); 839 DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
838 } 840 }
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 376fcbc3f8da..6407bff6bfd7 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -11,7 +11,7 @@
11 * Version Perfmon-2.x is a rewrite of perfmon-1.x 11 * Version Perfmon-2.x is a rewrite of perfmon-1.x
12 * by Stephane Eranian, Hewlett Packard Co. 12 * by Stephane Eranian, Hewlett Packard Co.
13 * 13 *
14 * Copyright (C) 1999-2003, 2005 Hewlett Packard Co 14 * Copyright (C) 1999-2005 Hewlett Packard Co
15 * Stephane Eranian <eranian@hpl.hp.com> 15 * Stephane Eranian <eranian@hpl.hp.com>
16 * David Mosberger-Tang <davidm@hpl.hp.com> 16 * David Mosberger-Tang <davidm@hpl.hp.com>
17 * 17 *
@@ -497,6 +497,9 @@ typedef struct {
497static pfm_stats_t pfm_stats[NR_CPUS]; 497static pfm_stats_t pfm_stats[NR_CPUS];
498static pfm_session_t pfm_sessions; /* global sessions information */ 498static pfm_session_t pfm_sessions; /* global sessions information */
499 499
500static spinlock_t pfm_alt_install_check = SPIN_LOCK_UNLOCKED;
501static pfm_intr_handler_desc_t *pfm_alt_intr_handler;
502
500static struct proc_dir_entry *perfmon_dir; 503static struct proc_dir_entry *perfmon_dir;
501static pfm_uuid_t pfm_null_uuid = {0,}; 504static pfm_uuid_t pfm_null_uuid = {0,};
502 505
@@ -606,6 +609,7 @@ DEFINE_PER_CPU(unsigned long, pfm_syst_info);
606DEFINE_PER_CPU(struct task_struct *, pmu_owner); 609DEFINE_PER_CPU(struct task_struct *, pmu_owner);
607DEFINE_PER_CPU(pfm_context_t *, pmu_ctx); 610DEFINE_PER_CPU(pfm_context_t *, pmu_ctx);
608DEFINE_PER_CPU(unsigned long, pmu_activation_number); 611DEFINE_PER_CPU(unsigned long, pmu_activation_number);
612EXPORT_PER_CPU_SYMBOL_GPL(pfm_syst_info);
609 613
610 614
611/* forward declaration */ 615/* forward declaration */
@@ -1265,6 +1269,8 @@ out:
1265} 1269}
1266EXPORT_SYMBOL(pfm_unregister_buffer_fmt); 1270EXPORT_SYMBOL(pfm_unregister_buffer_fmt);
1267 1271
1272extern void update_pal_halt_status(int);
1273
1268static int 1274static int
1269pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu) 1275pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
1270{ 1276{
@@ -1311,6 +1317,11 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
1311 is_syswide, 1317 is_syswide,
1312 cpu)); 1318 cpu));
1313 1319
1320 /*
1321 * disable default_idle() to go to PAL_HALT
1322 */
1323 update_pal_halt_status(0);
1324
1314 UNLOCK_PFS(flags); 1325 UNLOCK_PFS(flags);
1315 1326
1316 return 0; 1327 return 0;
@@ -1318,7 +1329,7 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
1318error_conflict: 1329error_conflict:
1319 DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n", 1330 DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n",
1320 pfm_sessions.pfs_sys_session[cpu]->pid, 1331 pfm_sessions.pfs_sys_session[cpu]->pid,
1321 smp_processor_id())); 1332 cpu));
1322abort: 1333abort:
1323 UNLOCK_PFS(flags); 1334 UNLOCK_PFS(flags);
1324 1335
@@ -1366,6 +1377,12 @@ pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu)
1366 is_syswide, 1377 is_syswide,
1367 cpu)); 1378 cpu));
1368 1379
1380 /*
1381 * if possible, enable default_idle() to go into PAL_HALT
1382 */
1383 if (pfm_sessions.pfs_task_sessions == 0 && pfm_sessions.pfs_sys_sessions == 0)
1384 update_pal_halt_status(1);
1385
1369 UNLOCK_PFS(flags); 1386 UNLOCK_PFS(flags);
1370 1387
1371 return 0; 1388 return 0;
@@ -4202,7 +4219,7 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
4202 DPRINT(("cannot load to [%d], invalid ctx_state=%d\n", 4219 DPRINT(("cannot load to [%d], invalid ctx_state=%d\n",
4203 req->load_pid, 4220 req->load_pid,
4204 ctx->ctx_state)); 4221 ctx->ctx_state));
4205 return -EINVAL; 4222 return -EBUSY;
4206 } 4223 }
4207 4224
4208 DPRINT(("load_pid [%d] using_dbreg=%d\n", req->load_pid, ctx->ctx_fl_using_dbreg)); 4225 DPRINT(("load_pid [%d] using_dbreg=%d\n", req->load_pid, ctx->ctx_fl_using_dbreg));
@@ -4704,16 +4721,26 @@ recheck:
4704 if (task == current || ctx->ctx_fl_system) return 0; 4721 if (task == current || ctx->ctx_fl_system) return 0;
4705 4722
4706 /* 4723 /*
4707 * if context is UNLOADED we are safe to go 4724 * we are monitoring another thread
4708 */ 4725 */
4709 if (state == PFM_CTX_UNLOADED) return 0; 4726 switch(state) {
4710 4727 case PFM_CTX_UNLOADED:
4711 /* 4728 /*
4712 * no command can operate on a zombie context 4729 * if context is UNLOADED we are safe to go
4713 */ 4730 */
4714 if (state == PFM_CTX_ZOMBIE) { 4731 return 0;
4715 DPRINT(("cmd %d state zombie cannot operate on context\n", cmd)); 4732 case PFM_CTX_ZOMBIE:
4716 return -EINVAL; 4733 /*
4734 * no command can operate on a zombie context
4735 */
4736 DPRINT(("cmd %d state zombie cannot operate on context\n", cmd));
4737 return -EINVAL;
4738 case PFM_CTX_MASKED:
4739 /*
4740 * PMU state has been saved to software even though
4741 * the thread may still be running.
4742 */
4743 if (cmd != PFM_UNLOAD_CONTEXT) return 0;
4717 } 4744 }
4718 4745
4719 /* 4746 /*
@@ -5532,26 +5559,32 @@ pfm_interrupt_handler(int irq, void *arg, struct pt_regs *regs)
5532 int ret; 5559 int ret;
5533 5560
5534 this_cpu = get_cpu(); 5561 this_cpu = get_cpu();
5535 min = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min; 5562 if (likely(!pfm_alt_intr_handler)) {
5536 max = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max; 5563 min = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min;
5564 max = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max;
5537 5565
5538 start_cycles = ia64_get_itc(); 5566 start_cycles = ia64_get_itc();
5539 5567
5540 ret = pfm_do_interrupt_handler(irq, arg, regs); 5568 ret = pfm_do_interrupt_handler(irq, arg, regs);
5541 5569
5542 total_cycles = ia64_get_itc(); 5570 total_cycles = ia64_get_itc();
5543 5571
5544 /* 5572 /*
5545 * don't measure spurious interrupts 5573 * don't measure spurious interrupts
5546 */ 5574 */
5547 if (likely(ret == 0)) { 5575 if (likely(ret == 0)) {
5548 total_cycles -= start_cycles; 5576 total_cycles -= start_cycles;
5549 5577
5550 if (total_cycles < min) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min = total_cycles; 5578 if (total_cycles < min) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min = total_cycles;
5551 if (total_cycles > max) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max = total_cycles; 5579 if (total_cycles > max) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max = total_cycles;
5552 5580
5553 pfm_stats[this_cpu].pfm_ovfl_intr_cycles += total_cycles; 5581 pfm_stats[this_cpu].pfm_ovfl_intr_cycles += total_cycles;
5582 }
5554 } 5583 }
5584 else {
5585 (*pfm_alt_intr_handler->handler)(irq, arg, regs);
5586 }
5587
5555 put_cpu_no_resched(); 5588 put_cpu_no_resched();
5556 return IRQ_HANDLED; 5589 return IRQ_HANDLED;
5557} 5590}
@@ -6402,6 +6435,141 @@ static struct irqaction perfmon_irqaction = {
6402 .name = "perfmon" 6435 .name = "perfmon"
6403}; 6436};
6404 6437
6438static void
6439pfm_alt_save_pmu_state(void *data)
6440{
6441 struct pt_regs *regs;
6442
6443 regs = ia64_task_regs(current);
6444
6445 DPRINT(("called\n"));
6446
6447 /*
6448 * should not be necessary but
6449 * let's take not risk
6450 */
6451 pfm_clear_psr_up();
6452 pfm_clear_psr_pp();
6453 ia64_psr(regs)->pp = 0;
6454
6455 /*
6456 * This call is required
6457 * May cause a spurious interrupt on some processors
6458 */
6459 pfm_freeze_pmu();
6460
6461 ia64_srlz_d();
6462}
6463
6464void
6465pfm_alt_restore_pmu_state(void *data)
6466{
6467 struct pt_regs *regs;
6468
6469 regs = ia64_task_regs(current);
6470
6471 DPRINT(("called\n"));
6472
6473 /*
6474 * put PMU back in state expected
6475 * by perfmon
6476 */
6477 pfm_clear_psr_up();
6478 pfm_clear_psr_pp();
6479 ia64_psr(regs)->pp = 0;
6480
6481 /*
6482 * perfmon runs with PMU unfrozen at all times
6483 */
6484 pfm_unfreeze_pmu();
6485
6486 ia64_srlz_d();
6487}
6488
6489int
6490pfm_install_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl)
6491{
6492 int ret, i;
6493 int reserve_cpu;
6494
6495 /* some sanity checks */
6496 if (hdl == NULL || hdl->handler == NULL) return -EINVAL;
6497
6498 /* do the easy test first */
6499 if (pfm_alt_intr_handler) return -EBUSY;
6500
6501 /* one at a time in the install or remove, just fail the others */
6502 if (!spin_trylock(&pfm_alt_install_check)) {
6503 return -EBUSY;
6504 }
6505
6506 /* reserve our session */
6507 for_each_online_cpu(reserve_cpu) {
6508 ret = pfm_reserve_session(NULL, 1, reserve_cpu);
6509 if (ret) goto cleanup_reserve;
6510 }
6511
6512 /* save the current system wide pmu states */
6513 ret = on_each_cpu(pfm_alt_save_pmu_state, NULL, 0, 1);
6514 if (ret) {
6515 DPRINT(("on_each_cpu() failed: %d\n", ret));
6516 goto cleanup_reserve;
6517 }
6518
6519 /* officially change to the alternate interrupt handler */
6520 pfm_alt_intr_handler = hdl;
6521
6522 spin_unlock(&pfm_alt_install_check);
6523
6524 return 0;
6525
6526cleanup_reserve:
6527 for_each_online_cpu(i) {
6528 /* don't unreserve more than we reserved */
6529 if (i >= reserve_cpu) break;
6530
6531 pfm_unreserve_session(NULL, 1, i);
6532 }
6533
6534 spin_unlock(&pfm_alt_install_check);
6535
6536 return ret;
6537}
6538EXPORT_SYMBOL_GPL(pfm_install_alt_pmu_interrupt);
6539
6540int
6541pfm_remove_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl)
6542{
6543 int i;
6544 int ret;
6545
6546 if (hdl == NULL) return -EINVAL;
6547
6548 /* cannot remove someone else's handler! */
6549 if (pfm_alt_intr_handler != hdl) return -EINVAL;
6550
6551 /* one at a time in the install or remove, just fail the others */
6552 if (!spin_trylock(&pfm_alt_install_check)) {
6553 return -EBUSY;
6554 }
6555
6556 pfm_alt_intr_handler = NULL;
6557
6558 ret = on_each_cpu(pfm_alt_restore_pmu_state, NULL, 0, 1);
6559 if (ret) {
6560 DPRINT(("on_each_cpu() failed: %d\n", ret));
6561 }
6562
6563 for_each_online_cpu(i) {
6564 pfm_unreserve_session(NULL, 1, i);
6565 }
6566
6567 spin_unlock(&pfm_alt_install_check);
6568
6569 return 0;
6570}
6571EXPORT_SYMBOL_GPL(pfm_remove_alt_pmu_interrupt);
6572
6405/* 6573/*
6406 * perfmon initialization routine, called from the initcall() table 6574 * perfmon initialization routine, called from the initcall() table
6407 */ 6575 */
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 7c43aea5f7f7..ebb71f3d6d19 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -50,7 +50,7 @@
50#include "sigframe.h" 50#include "sigframe.h"
51 51
52void (*ia64_mark_idle)(int); 52void (*ia64_mark_idle)(int);
53static cpumask_t cpu_idle_map; 53static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
54 54
55unsigned long boot_option_idle_override = 0; 55unsigned long boot_option_idle_override = 0;
56EXPORT_SYMBOL(boot_option_idle_override); 56EXPORT_SYMBOL(boot_option_idle_override);
@@ -173,7 +173,9 @@ do_notify_resume_user (sigset_t *oldset, struct sigscratch *scr, long in_syscall
173 ia64_do_signal(oldset, scr, in_syscall); 173 ia64_do_signal(oldset, scr, in_syscall);
174} 174}
175 175
176static int pal_halt = 1; 176static int pal_halt = 1;
177static int can_do_pal_halt = 1;
178
177static int __init nohalt_setup(char * str) 179static int __init nohalt_setup(char * str)
178{ 180{
179 pal_halt = 0; 181 pal_halt = 0;
@@ -181,16 +183,20 @@ static int __init nohalt_setup(char * str)
181} 183}
182__setup("nohalt", nohalt_setup); 184__setup("nohalt", nohalt_setup);
183 185
186void
187update_pal_halt_status(int status)
188{
189 can_do_pal_halt = pal_halt && status;
190}
191
184/* 192/*
185 * We use this if we don't have any better idle routine.. 193 * We use this if we don't have any better idle routine..
186 */ 194 */
187void 195void
188default_idle (void) 196default_idle (void)
189{ 197{
190 unsigned long pmu_active = ia64_getreg(_IA64_REG_PSR) & (IA64_PSR_PP | IA64_PSR_UP);
191
192 while (!need_resched()) 198 while (!need_resched())
193 if (pal_halt && !pmu_active) 199 if (can_do_pal_halt)
194 safe_halt(); 200 safe_halt();
195 else 201 else
196 cpu_relax(); 202 cpu_relax();
@@ -223,20 +229,31 @@ static inline void play_dead(void)
223} 229}
224#endif /* CONFIG_HOTPLUG_CPU */ 230#endif /* CONFIG_HOTPLUG_CPU */
225 231
226
227void cpu_idle_wait(void) 232void cpu_idle_wait(void)
228{ 233{
229 int cpu; 234 unsigned int cpu, this_cpu = get_cpu();
230 cpumask_t map; 235 cpumask_t map;
231 236
232 for_each_online_cpu(cpu) 237 set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
233 cpu_set(cpu, cpu_idle_map); 238 put_cpu();
234 239
235 wmb(); 240 cpus_clear(map);
236 do { 241 for_each_online_cpu(cpu) {
237 ssleep(1); 242 per_cpu(cpu_idle_state, cpu) = 1;
238 cpus_and(map, cpu_idle_map, cpu_online_map); 243 cpu_set(cpu, map);
239 } while (!cpus_empty(map)); 244 }
245
246 __get_cpu_var(cpu_idle_state) = 0;
247
248 wmb();
249 do {
250 ssleep(1);
251 for_each_online_cpu(cpu) {
252 if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
253 cpu_clear(cpu, map);
254 }
255 cpus_and(map, map, cpu_online_map);
256 } while (!cpus_empty(map));
240} 257}
241EXPORT_SYMBOL_GPL(cpu_idle_wait); 258EXPORT_SYMBOL_GPL(cpu_idle_wait);
242 259
@@ -244,7 +261,6 @@ void __attribute__((noreturn))
244cpu_idle (void) 261cpu_idle (void)
245{ 262{
246 void (*mark_idle)(int) = ia64_mark_idle; 263 void (*mark_idle)(int) = ia64_mark_idle;
247 int cpu = smp_processor_id();
248 264
249 /* endless idle loop with no priority at all */ 265 /* endless idle loop with no priority at all */
250 while (1) { 266 while (1) {
@@ -255,12 +271,13 @@ cpu_idle (void)
255 while (!need_resched()) { 271 while (!need_resched()) {
256 void (*idle)(void); 272 void (*idle)(void);
257 273
274 if (__get_cpu_var(cpu_idle_state))
275 __get_cpu_var(cpu_idle_state) = 0;
276
277 rmb();
258 if (mark_idle) 278 if (mark_idle)
259 (*mark_idle)(1); 279 (*mark_idle)(1);
260 280
261 if (cpu_isset(cpu, cpu_idle_map))
262 cpu_clear(cpu, cpu_idle_map);
263 rmb();
264 idle = pm_idle; 281 idle = pm_idle;
265 if (!idle) 282 if (!idle)
266 idle = default_idle; 283 idle = default_idle;
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 9e730c7bf0cd..4c1d2f5442b3 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -635,11 +635,17 @@ ia64_flush_fph (struct task_struct *task)
635{ 635{
636 struct ia64_psr *psr = ia64_psr(ia64_task_regs(task)); 636 struct ia64_psr *psr = ia64_psr(ia64_task_regs(task));
637 637
638 /*
639 * Prevent migrating this task while
640 * we're fiddling with the FPU state
641 */
642 preempt_disable();
638 if (ia64_is_local_fpu_owner(task) && psr->mfh) { 643 if (ia64_is_local_fpu_owner(task) && psr->mfh) {
639 psr->mfh = 0; 644 psr->mfh = 0;
640 task->thread.flags |= IA64_THREAD_FPH_VALID; 645 task->thread.flags |= IA64_THREAD_FPH_VALID;
641 ia64_save_fpu(&task->thread.fph[0]); 646 ia64_save_fpu(&task->thread.fph[0]);
642 } 647 }
648 preempt_enable();
643} 649}
644 650
645/* 651/*
@@ -692,16 +698,30 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs *pt,
692 unsigned long cfm) 698 unsigned long cfm)
693{ 699{
694 struct unw_frame_info info, prev_info; 700 struct unw_frame_info info, prev_info;
695 unsigned long ip, pr; 701 unsigned long ip, sp, pr;
696 702
697 unw_init_from_blocked_task(&info, child); 703 unw_init_from_blocked_task(&info, child);
698 while (1) { 704 while (1) {
699 prev_info = info; 705 prev_info = info;
700 if (unw_unwind(&info) < 0) 706 if (unw_unwind(&info) < 0)
701 return; 707 return;
702 if (unw_get_rp(&info, &ip) < 0) 708
709 unw_get_sp(&info, &sp);
710 if ((long)((unsigned long)child + IA64_STK_OFFSET - sp)
711 < IA64_PT_REGS_SIZE) {
712 dprintk("ptrace.%s: ran off the top of the kernel "
713 "stack\n", __FUNCTION__);
714 return;
715 }
716 if (unw_get_pr (&prev_info, &pr) < 0) {
717 unw_get_rp(&prev_info, &ip);
718 dprintk("ptrace.%s: failed to read "
719 "predicate register (ip=0x%lx)\n",
720 __FUNCTION__, ip);
703 return; 721 return;
704 if (ip < FIXADDR_USER_END) 722 }
723 if (unw_is_intr_frame(&info)
724 && (pr & (1UL << PRED_USER_STACK)))
705 break; 725 break;
706 } 726 }
707 727
@@ -1616,20 +1636,25 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,
1616 long arg4, long arg5, long arg6, long arg7, 1636 long arg4, long arg5, long arg6, long arg7,
1617 struct pt_regs regs) 1637 struct pt_regs regs)
1618{ 1638{
1619 long syscall; 1639 if (test_thread_flag(TIF_SYSCALL_TRACE)
1640 && (current->ptrace & PT_PTRACED))
1641 syscall_trace();
1620 1642
1621 if (unlikely(current->audit_context)) { 1643 if (unlikely(current->audit_context)) {
1622 if (IS_IA32_PROCESS(&regs)) 1644 long syscall;
1645 int arch;
1646
1647 if (IS_IA32_PROCESS(&regs)) {
1623 syscall = regs.r1; 1648 syscall = regs.r1;
1624 else 1649 arch = AUDIT_ARCH_I386;
1650 } else {
1625 syscall = regs.r15; 1651 syscall = regs.r15;
1652 arch = AUDIT_ARCH_IA64;
1653 }
1626 1654
1627 audit_syscall_entry(current, syscall, arg0, arg1, arg2, arg3); 1655 audit_syscall_entry(current, arch, syscall, arg0, arg1, arg2, arg3);
1628 } 1656 }
1629 1657
1630 if (test_thread_flag(TIF_SYSCALL_TRACE)
1631 && (current->ptrace & PT_PTRACED))
1632 syscall_trace();
1633} 1658}
1634 1659
1635/* "asmlinkage" so the input arguments are preserved... */ 1660/* "asmlinkage" so the input arguments are preserved... */
@@ -1640,7 +1665,7 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
1640 struct pt_regs regs) 1665 struct pt_regs regs)
1641{ 1666{
1642 if (unlikely(current->audit_context)) 1667 if (unlikely(current->audit_context))
1643 audit_syscall_exit(current, regs.r8); 1668 audit_syscall_exit(current, AUDITSC_RESULT(regs.r10), regs.r8);
1644 1669
1645 if (test_thread_flag(TIF_SYSCALL_TRACE) 1670 if (test_thread_flag(TIF_SYSCALL_TRACE)
1646 && (current->ptrace & PT_PTRACED)) 1671 && (current->ptrace & PT_PTRACED))
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index b7e6b4cb374b..d14692e0920a 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -720,7 +720,8 @@ cpu_init (void)
720 ia64_set_kr(IA64_KR_PT_BASE, __pa(ia64_imva(empty_zero_page))); 720 ia64_set_kr(IA64_KR_PT_BASE, __pa(ia64_imva(empty_zero_page)));
721 721
722 /* 722 /*
723 * Initialize default control register to defer all speculative faults. The 723 * Initialize default control register to defer speculative faults except
724 * for those arising from TLB misses, which are not deferred. The
724 * kernel MUST NOT depend on a particular setting of these bits (in other words, 725 * kernel MUST NOT depend on a particular setting of these bits (in other words,
725 * the kernel must have recovery code for all speculative accesses). Turn on 726 * the kernel must have recovery code for all speculative accesses). Turn on
726 * dcr.lc as per recommendation by the architecture team. Most IA-32 apps 727 * dcr.lc as per recommendation by the architecture team. Most IA-32 apps
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 6891d86937d9..499b7e5317cf 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -224,7 +224,8 @@ ia64_rt_sigreturn (struct sigscratch *scr)
224 * could be corrupted. 224 * could be corrupted.
225 */ 225 */
226 retval = (long) &ia64_leave_kernel; 226 retval = (long) &ia64_leave_kernel;
227 if (test_thread_flag(TIF_SYSCALL_TRACE)) 227 if (test_thread_flag(TIF_SYSCALL_TRACE)
228 || test_thread_flag(TIF_SYSCALL_AUDIT))
228 /* 229 /*
229 * strace expects to be notified after sigreturn returns even though the 230 * strace expects to be notified after sigreturn returns even though the
230 * context to which we return may not be in the middle of a syscall. 231 * context to which we return may not be in the middle of a syscall.
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 0d5ee57c9865..3865f088ffa2 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -624,7 +624,7 @@ static struct {
624 __u16 thread_id; 624 __u16 thread_id;
625 __u16 proc_fixed_addr; 625 __u16 proc_fixed_addr;
626 __u8 valid; 626 __u8 valid;
627}mt_info[NR_CPUS] __devinit; 627} mt_info[NR_CPUS] __devinitdata;
628 628
629#ifdef CONFIG_HOTPLUG_CPU 629#ifdef CONFIG_HOTPLUG_CPU
630static inline void 630static inline void
diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
index a8cf6d8a509c..770fab37928e 100644
--- a/arch/ia64/kernel/sys_ia64.c
+++ b/arch/ia64/kernel/sys_ia64.c
@@ -182,13 +182,6 @@ do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, un
182 } 182 }
183 } 183 }
184 184
185 /*
186 * A zero mmap always succeeds in Linux, independent of whether or not the
187 * remaining arguments are valid.
188 */
189 if (len == 0)
190 goto out;
191
192 /* Careful about overflows.. */ 185 /* Careful about overflows.. */
193 len = PAGE_ALIGN(len); 186 len = PAGE_ALIGN(len);
194 if (!len || len > TASK_SIZE) { 187 if (!len || len > TASK_SIZE) {
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index e82ad78081b3..1861173bd4f6 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -111,6 +111,24 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
111 siginfo_t siginfo; 111 siginfo_t siginfo;
112 int sig, code; 112 int sig, code;
113 113
114 /* break.b always sets cr.iim to 0, which causes problems for
115 * debuggers. Get the real break number from the original instruction,
116 * but only for kernel code. User space break.b is left alone, to
117 * preserve the existing behaviour. All break codings have the same
118 * format, so there is no need to check the slot type.
119 */
120 if (break_num == 0 && !user_mode(regs)) {
121 struct ia64_psr *ipsr = ia64_psr(regs);
122 unsigned long *bundle = (unsigned long *)regs->cr_iip;
123 unsigned long slot;
124 switch (ipsr->ri) {
125 case 0: slot = (bundle[0] >> 5); break;
126 case 1: slot = (bundle[0] >> 46) | (bundle[1] << 18); break;
127 default: slot = (bundle[1] >> 23); break;
128 }
129 break_num = ((slot >> 36 & 1) << 20) | (slot >> 6 & 0xfffff);
130 }
131
114 /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */ 132 /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */
115 siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri); 133 siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
116 siginfo.si_imm = break_num; 134 siginfo.si_imm = break_num;
@@ -202,13 +220,21 @@ disabled_fph_fault (struct pt_regs *regs)
202 220
203 /* first, grant user-level access to fph partition: */ 221 /* first, grant user-level access to fph partition: */
204 psr->dfh = 0; 222 psr->dfh = 0;
223
224 /*
225 * Make sure that no other task gets in on this processor
226 * while we're claiming the FPU
227 */
228 preempt_disable();
205#ifndef CONFIG_SMP 229#ifndef CONFIG_SMP
206 { 230 {
207 struct task_struct *fpu_owner 231 struct task_struct *fpu_owner
208 = (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER); 232 = (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER);
209 233
210 if (ia64_is_local_fpu_owner(current)) 234 if (ia64_is_local_fpu_owner(current)) {
235 preempt_enable_no_resched();
211 return; 236 return;
237 }
212 238
213 if (fpu_owner) 239 if (fpu_owner)
214 ia64_flush_fph(fpu_owner); 240 ia64_flush_fph(fpu_owner);
@@ -226,6 +252,7 @@ disabled_fph_fault (struct pt_regs *regs)
226 */ 252 */
227 psr->mfh = 1; 253 psr->mfh = 1;
228 } 254 }
255 preempt_enable_no_resched();
229} 256}
230 257
231static inline int 258static inline int
diff --git a/arch/ia64/lib/flush.S b/arch/ia64/lib/flush.S
index 29c802b19669..a1af9146cfdb 100644
--- a/arch/ia64/lib/flush.S
+++ b/arch/ia64/lib/flush.S
@@ -1,8 +1,8 @@
1/* 1/*
2 * Cache flushing routines. 2 * Cache flushing routines.
3 * 3 *
4 * Copyright (C) 1999-2001 Hewlett-Packard Co 4 * Copyright (C) 1999-2001, 2005 Hewlett-Packard Co
5 * Copyright (C) 1999-2001 David Mosberger-Tang <davidm@hpl.hp.com> 5 * David Mosberger-Tang <davidm@hpl.hp.com>
6 */ 6 */
7#include <asm/asmmacro.h> 7#include <asm/asmmacro.h>
8#include <asm/page.h> 8#include <asm/page.h>
@@ -26,7 +26,7 @@ GLOBAL_ENTRY(flush_icache_range)
26 26
27 mov ar.lc=r8 27 mov ar.lc=r8
28 ;; 28 ;;
29.Loop: fc in0 // issuable on M0 only 29.Loop: fc.i in0 // issuable on M2 only
30 add in0=32,in0 30 add in0=32,in0
31 br.cloop.sptk.few .Loop 31 br.cloop.sptk.few .Loop
32 ;; 32 ;;
diff --git a/arch/ia64/lib/memcpy_mck.S b/arch/ia64/lib/memcpy_mck.S
index 3c2cd2f04db9..6f308e62c137 100644
--- a/arch/ia64/lib/memcpy_mck.S
+++ b/arch/ia64/lib/memcpy_mck.S
@@ -75,6 +75,7 @@ GLOBAL_ENTRY(memcpy)
75 mov f6=f0 75 mov f6=f0
76 br.cond.sptk .common_code 76 br.cond.sptk .common_code
77 ;; 77 ;;
78END(memcpy)
78GLOBAL_ENTRY(__copy_user) 79GLOBAL_ENTRY(__copy_user)
79 .prologue 80 .prologue
80// check dest alignment 81// check dest alignment
@@ -524,7 +525,6 @@ EK(.ex_handler, (p17) st8 [dst1]=r39,8); \
524#undef B 525#undef B
525#undef C 526#undef C
526#undef D 527#undef D
527END(memcpy)
528 528
529/* 529/*
530 * Due to lack of local tag support in gcc 2.x assembler, it is not clear which 530 * Due to lack of local tag support in gcc 2.x assembler, it is not clear which
diff --git a/arch/ia64/lib/memset.S b/arch/ia64/lib/memset.S
index bd8cf907fe22..f26c16aefb1c 100644
--- a/arch/ia64/lib/memset.S
+++ b/arch/ia64/lib/memset.S
@@ -57,10 +57,10 @@ GLOBAL_ENTRY(memset)
57{ .mmi 57{ .mmi
58 .prologue 58 .prologue
59 alloc tmp = ar.pfs, 3, 0, 0, 0 59 alloc tmp = ar.pfs, 3, 0, 0, 0
60 .body
61 lfetch.nt1 [dest] // 60 lfetch.nt1 [dest] //
62 .save ar.lc, save_lc 61 .save ar.lc, save_lc
63 mov.i save_lc = ar.lc 62 mov.i save_lc = ar.lc
63 .body
64} { .mmi 64} { .mmi
65 mov ret0 = dest // return value 65 mov ret0 = dest // return value
66 cmp.ne p_nz, p_zr = value, r0 // use stf.spill if value is zero 66 cmp.ne p_nz, p_zr = value, r0 // use stf.spill if value is zero
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 547785e3cba2..4eb2f52b87a1 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -305,8 +305,9 @@ setup_gate (void)
305 struct page *page; 305 struct page *page;
306 306
307 /* 307 /*
308 * Map the gate page twice: once read-only to export the ELF headers etc. and once 308 * Map the gate page twice: once read-only to export the ELF
309 * execute-only page to enable privilege-promotion via "epc": 309 * headers etc. and once execute-only page to enable
310 * privilege-promotion via "epc":
310 */ 311 */
311 page = virt_to_page(ia64_imva(__start_gate_section)); 312 page = virt_to_page(ia64_imva(__start_gate_section));
312 put_kernel_page(page, GATE_ADDR, PAGE_READONLY); 313 put_kernel_page(page, GATE_ADDR, PAGE_READONLY);
@@ -315,6 +316,20 @@ setup_gate (void)
315 put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE); 316 put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE);
316#else 317#else
317 put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE); 318 put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE);
319 /* Fill in the holes (if any) with read-only zero pages: */
320 {
321 unsigned long addr;
322
323 for (addr = GATE_ADDR + PAGE_SIZE;
324 addr < GATE_ADDR + PERCPU_PAGE_SIZE;
325 addr += PAGE_SIZE)
326 {
327 put_kernel_page(ZERO_PAGE(0), addr,
328 PAGE_READONLY);
329 put_kernel_page(ZERO_PAGE(0), addr + PERCPU_PAGE_SIZE,
330 PAGE_READONLY);
331 }
332 }
318#endif 333#endif
319 ia64_patch_gate(); 334 ia64_patch_gate();
320} 335}
diff --git a/arch/ia64/sn/kernel/Makefile b/arch/ia64/sn/kernel/Makefile
index 4f381fb25049..4351c4ff9845 100644
--- a/arch/ia64/sn/kernel/Makefile
+++ b/arch/ia64/sn/kernel/Makefile
@@ -4,10 +4,15 @@
4# License. See the file "COPYING" in the main directory of this archive 4# License. See the file "COPYING" in the main directory of this archive
5# for more details. 5# for more details.
6# 6#
7# Copyright (C) 1999,2001-2003 Silicon Graphics, Inc. All Rights Reserved. 7# Copyright (C) 1999,2001-2005 Silicon Graphics, Inc. All Rights Reserved.
8# 8#
9 9
10obj-y += setup.o bte.o bte_error.o irq.o mca.o idle.o \ 10obj-y += setup.o bte.o bte_error.o irq.o mca.o idle.o \
11 huberror.o io_init.o iomv.o klconflib.o sn2/ 11 huberror.o io_init.o iomv.o klconflib.o sn2/
12obj-$(CONFIG_IA64_GENERIC) += machvec.o 12obj-$(CONFIG_IA64_GENERIC) += machvec.o
13obj-$(CONFIG_SGI_TIOCX) += tiocx.o 13obj-$(CONFIG_SGI_TIOCX) += tiocx.o
14obj-$(CONFIG_IA64_SGI_SN_XP) += xp.o
15xp-y := xp_main.o xp_nofault.o
16obj-$(CONFIG_IA64_SGI_SN_XP) += xpc.o
17xpc-y := xpc_main.o xpc_channel.o xpc_partition.o
18obj-$(CONFIG_IA64_SGI_SN_XP) += xpnet.o
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 18160a06a8c9..9e07f5463f21 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -174,6 +174,12 @@ static void sn_fixup_ionodes(void)
174 if (status) 174 if (status)
175 continue; 175 continue;
176 176
177 /* Attach the error interrupt handlers */
178 if (nasid & 1)
179 ice_error_init(hubdev);
180 else
181 hub_error_init(hubdev);
182
177 for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) 183 for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++)
178 hubdev->hdi_xwidget_info[widget].xwi_hubinfo = hubdev; 184 hubdev->hdi_xwidget_info[widget].xwi_hubinfo = hubdev;
179 185
@@ -211,10 +217,6 @@ static void sn_fixup_ionodes(void)
211 sn_flush_device_list; 217 sn_flush_device_list;
212 } 218 }
213 219
214 if (!(i & 1))
215 hub_error_init(hubdev);
216 else
217 ice_error_init(hubdev);
218 } 220 }
219 221
220} 222}
diff --git a/arch/ia64/sn/kernel/mca.c b/arch/ia64/sn/kernel/mca.c
index 857774bb2c9a..6546db6abdba 100644
--- a/arch/ia64/sn/kernel/mca.c
+++ b/arch/ia64/sn/kernel/mca.c
@@ -37,6 +37,11 @@ static u64 *sn_oemdata_size, sn_oemdata_bufsize;
37 * This function is the callback routine that SAL calls to log error 37 * This function is the callback routine that SAL calls to log error
38 * info for platform errors. buf is appended to sn_oemdata, resizing as 38 * info for platform errors. buf is appended to sn_oemdata, resizing as
39 * required. 39 * required.
40 * Note: this is a SAL to OS callback, running under the same rules as the SAL
41 * code. SAL calls are run with preempt disabled so this routine must not
42 * sleep. vmalloc can sleep so print_hook cannot resize the output buffer
43 * itself, instead it must set the required size and return to let the caller
44 * resize the buffer then redrive the SAL call.
40 */ 45 */
41static int print_hook(const char *fmt, ...) 46static int print_hook(const char *fmt, ...)
42{ 47{
@@ -47,18 +52,8 @@ static int print_hook(const char *fmt, ...)
47 vsnprintf(buf, sizeof(buf), fmt, args); 52 vsnprintf(buf, sizeof(buf), fmt, args);
48 va_end(args); 53 va_end(args);
49 len = strlen(buf); 54 len = strlen(buf);
50 while (*sn_oemdata_size + len + 1 > sn_oemdata_bufsize) { 55 if (*sn_oemdata_size + len <= sn_oemdata_bufsize)
51 u8 *newbuf = vmalloc(sn_oemdata_bufsize += 1000); 56 memcpy(*sn_oemdata + *sn_oemdata_size, buf, len);
52 if (!newbuf) {
53 printk(KERN_ERR "%s: unable to extend sn_oemdata\n",
54 __FUNCTION__);
55 return 0;
56 }
57 memcpy(newbuf, *sn_oemdata, *sn_oemdata_size);
58 vfree(*sn_oemdata);
59 *sn_oemdata = newbuf;
60 }
61 memcpy(*sn_oemdata + *sn_oemdata_size, buf, len + 1);
62 *sn_oemdata_size += len; 57 *sn_oemdata_size += len;
63 return 0; 58 return 0;
64} 59}
@@ -98,7 +93,20 @@ sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata,
98 sn_oemdata = oemdata; 93 sn_oemdata = oemdata;
99 sn_oemdata_size = oemdata_size; 94 sn_oemdata_size = oemdata_size;
100 sn_oemdata_bufsize = 0; 95 sn_oemdata_bufsize = 0;
101 ia64_sn_plat_specific_err_print(print_hook, (char *)sect_header); 96 *sn_oemdata_size = PAGE_SIZE; /* first guess at how much data will be generated */
97 while (*sn_oemdata_size > sn_oemdata_bufsize) {
98 u8 *newbuf = vmalloc(*sn_oemdata_size);
99 if (!newbuf) {
100 printk(KERN_ERR "%s: unable to extend sn_oemdata\n",
101 __FUNCTION__);
102 return 1;
103 }
104 vfree(*sn_oemdata);
105 *sn_oemdata = newbuf;
106 sn_oemdata_bufsize = *sn_oemdata_size;
107 *sn_oemdata_size = 0;
108 ia64_sn_plat_specific_err_print(print_hook, (char *)sect_header);
109 }
102 up(&sn_oemdata_mutex); 110 up(&sn_oemdata_mutex);
103 return 0; 111 return 0;
104} 112}
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index d35f2a6f9c94..44bfc7f318cb 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -3,7 +3,7 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 1999,2001-2004 Silicon Graphics, Inc. All rights reserved. 6 * Copyright (C) 1999,2001-2005 Silicon Graphics, Inc. All rights reserved.
7 */ 7 */
8 8
9#include <linux/config.h> 9#include <linux/config.h>
@@ -73,6 +73,12 @@ EXPORT_SYMBOL(sn_rtc_cycles_per_second);
73DEFINE_PER_CPU(struct sn_hub_info_s, __sn_hub_info); 73DEFINE_PER_CPU(struct sn_hub_info_s, __sn_hub_info);
74EXPORT_PER_CPU_SYMBOL(__sn_hub_info); 74EXPORT_PER_CPU_SYMBOL(__sn_hub_info);
75 75
76DEFINE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_NUMNODES]);
77EXPORT_PER_CPU_SYMBOL(__sn_cnodeid_to_nasid);
78
79DEFINE_PER_CPU(struct nodepda_s *, __sn_nodepda);
80EXPORT_PER_CPU_SYMBOL(__sn_nodepda);
81
76partid_t sn_partid = -1; 82partid_t sn_partid = -1;
77EXPORT_SYMBOL(sn_partid); 83EXPORT_SYMBOL(sn_partid);
78char sn_system_serial_number_string[128]; 84char sn_system_serial_number_string[128];
@@ -216,7 +222,7 @@ void __init early_sn_setup(void)
216 222
217extern int platform_intr_list[]; 223extern int platform_intr_list[];
218extern nasid_t master_nasid; 224extern nasid_t master_nasid;
219static int shub_1_1_found __initdata; 225static int __initdata shub_1_1_found = 0;
220 226
221/* 227/*
222 * sn_check_for_wars 228 * sn_check_for_wars
@@ -245,7 +251,7 @@ static void __init sn_check_for_wars(void)
245 } else { 251 } else {
246 for_each_online_node(cnode) { 252 for_each_online_node(cnode) {
247 if (is_shub_1_1(cnodeid_to_nasid(cnode))) 253 if (is_shub_1_1(cnodeid_to_nasid(cnode)))
248 sn_hub_info->shub_1_1_found = 1; 254 shub_1_1_found = 1;
249 } 255 }
250 } 256 }
251} 257}
@@ -265,6 +271,8 @@ void __init sn_setup(char **cmdline_p)
265 int major = sn_sal_rev_major(), minor = sn_sal_rev_minor(); 271 int major = sn_sal_rev_major(), minor = sn_sal_rev_minor();
266 extern void sn_cpu_init(void); 272 extern void sn_cpu_init(void);
267 273
274 ia64_sn_plat_set_error_handling_features();
275
268 /* 276 /*
269 * If the generic code has enabled vga console support - lets 277 * If the generic code has enabled vga console support - lets
270 * get rid of it again. This is a kludge for the fact that ACPI 278 * get rid of it again. This is a kludge for the fact that ACPI
@@ -373,11 +381,11 @@ static void __init sn_init_pdas(char **cmdline_p)
373{ 381{
374 cnodeid_t cnode; 382 cnodeid_t cnode;
375 383
376 memset(pda->cnodeid_to_nasid_table, -1, 384 memset(sn_cnodeid_to_nasid, -1,
377 sizeof(pda->cnodeid_to_nasid_table)); 385 sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid)));
378 for_each_online_node(cnode) 386 for_each_online_node(cnode)
379 pda->cnodeid_to_nasid_table[cnode] = 387 sn_cnodeid_to_nasid[cnode] =
380 pxm_to_nasid(nid_to_pxm_map[cnode]); 388 pxm_to_nasid(nid_to_pxm_map[cnode]);
381 389
382 numionodes = num_online_nodes(); 390 numionodes = num_online_nodes();
383 scan_for_ionodes(); 391 scan_for_ionodes();
@@ -477,7 +485,8 @@ void __init sn_cpu_init(void)
477 485
478 cnode = nasid_to_cnodeid(nasid); 486 cnode = nasid_to_cnodeid(nasid);
479 487
480 pda->p_nodepda = nodepdaindr[cnode]; 488 sn_nodepda = nodepdaindr[cnode];
489
481 pda->led_address = 490 pda->led_address =
482 (typeof(pda->led_address)) (LED0 + (slice << LED_CPU_SHIFT)); 491 (typeof(pda->led_address)) (LED0 + (slice << LED_CPU_SHIFT));
483 pda->led_state = LED_ALWAYS_SET; 492 pda->led_state = LED_ALWAYS_SET;
@@ -486,15 +495,18 @@ void __init sn_cpu_init(void)
486 pda->idle_flag = 0; 495 pda->idle_flag = 0;
487 496
488 if (cpuid != 0) { 497 if (cpuid != 0) {
489 memcpy(pda->cnodeid_to_nasid_table, 498 /* copy cpu 0's sn_cnodeid_to_nasid table to this cpu's */
490 pdacpu(0)->cnodeid_to_nasid_table, 499 memcpy(sn_cnodeid_to_nasid,
491 sizeof(pda->cnodeid_to_nasid_table)); 500 (&per_cpu(__sn_cnodeid_to_nasid, 0)),
501 sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid)));
492 } 502 }
493 503
494 /* 504 /*
495 * Check for WARs. 505 * Check for WARs.
496 * Only needs to be done once, on BSP. 506 * Only needs to be done once, on BSP.
497 * Has to be done after loop above, because it uses pda.cnodeid_to_nasid_table[i]. 507 * Has to be done after loop above, because it uses this cpu's
508 * sn_cnodeid_to_nasid table which was just initialized if this
509 * isn't cpu 0.
498 * Has to be done before assignment below. 510 * Has to be done before assignment below.
499 */ 511 */
500 if (!wars_have_been_checked) { 512 if (!wars_have_been_checked) {
@@ -580,8 +592,7 @@ static void __init scan_for_ionodes(void)
580 brd = find_lboard_any(brd, KLTYPE_SNIA); 592 brd = find_lboard_any(brd, KLTYPE_SNIA);
581 593
582 while (brd) { 594 while (brd) {
583 pda->cnodeid_to_nasid_table[numionodes] = 595 sn_cnodeid_to_nasid[numionodes] = brd->brd_nasid;
584 brd->brd_nasid;
585 physical_node_map[brd->brd_nasid] = numionodes; 596 physical_node_map[brd->brd_nasid] = numionodes;
586 root_lboard[numionodes] = brd; 597 root_lboard[numionodes] = brd;
587 numionodes++; 598 numionodes++;
@@ -602,8 +613,7 @@ static void __init scan_for_ionodes(void)
602 root_lboard[nasid_to_cnodeid(nasid)], 613 root_lboard[nasid_to_cnodeid(nasid)],
603 KLTYPE_TIO); 614 KLTYPE_TIO);
604 while (brd) { 615 while (brd) {
605 pda->cnodeid_to_nasid_table[numionodes] = 616 sn_cnodeid_to_nasid[numionodes] = brd->brd_nasid;
606 brd->brd_nasid;
607 physical_node_map[brd->brd_nasid] = numionodes; 617 physical_node_map[brd->brd_nasid] = numionodes;
608 root_lboard[numionodes] = brd; 618 root_lboard[numionodes] = brd;
609 numionodes++; 619 numionodes++;
@@ -614,7 +624,6 @@ static void __init scan_for_ionodes(void)
614 brd = find_lboard_any(brd, KLTYPE_TIO); 624 brd = find_lboard_any(brd, KLTYPE_TIO);
615 } 625 }
616 } 626 }
617
618} 627}
619 628
620int 629int
@@ -623,7 +632,8 @@ nasid_slice_to_cpuid(int nasid, int slice)
623 long cpu; 632 long cpu;
624 633
625 for (cpu=0; cpu < NR_CPUS; cpu++) 634 for (cpu=0; cpu < NR_CPUS; cpu++)
626 if (nodepda->phys_cpuid[cpu].nasid == nasid && nodepda->phys_cpuid[cpu].slice == slice) 635 if (cpuid_to_nasid(cpu) == nasid &&
636 cpuid_to_slice(cpu) == slice)
627 return cpu; 637 return cpu;
628 638
629 return -1; 639 return -1;
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c
index 66190d7e492d..ab9b5f35c2a7 100644
--- a/arch/ia64/sn/kernel/tiocx.c
+++ b/arch/ia64/sn/kernel/tiocx.c
@@ -21,6 +21,8 @@
21#include <asm/sn/types.h> 21#include <asm/sn/types.h>
22#include <asm/sn/shubio.h> 22#include <asm/sn/shubio.h>
23#include <asm/sn/tiocx.h> 23#include <asm/sn/tiocx.h>
24#include <asm/sn/l1.h>
25#include <asm/sn/module.h>
24#include "tio.h" 26#include "tio.h"
25#include "xtalk/xwidgetdev.h" 27#include "xtalk/xwidgetdev.h"
26#include "xtalk/hubdev.h" 28#include "xtalk/hubdev.h"
@@ -308,14 +310,12 @@ void tiocx_irq_free(struct sn_irq_info *sn_irq_info)
308 } 310 }
309} 311}
310 312
311uint64_t 313uint64_t tiocx_dma_addr(uint64_t addr)
312tiocx_dma_addr(uint64_t addr)
313{ 314{
314 return PHYS_TO_TIODMA(addr); 315 return PHYS_TO_TIODMA(addr);
315} 316}
316 317
317uint64_t 318uint64_t tiocx_swin_base(int nasid)
318tiocx_swin_base(int nasid)
319{ 319{
320 return TIO_SWIN_BASE(nasid, TIOCX_CORELET); 320 return TIO_SWIN_BASE(nasid, TIOCX_CORELET);
321} 321}
@@ -330,19 +330,6 @@ EXPORT_SYMBOL(tiocx_bus_type);
330EXPORT_SYMBOL(tiocx_dma_addr); 330EXPORT_SYMBOL(tiocx_dma_addr);
331EXPORT_SYMBOL(tiocx_swin_base); 331EXPORT_SYMBOL(tiocx_swin_base);
332 332
333static uint64_t tiocx_get_hubdev_info(u64 handle, u64 address)
334{
335
336 struct ia64_sal_retval ret_stuff;
337 ret_stuff.status = 0;
338 ret_stuff.v0 = 0;
339
340 ia64_sal_oemcall_nolock(&ret_stuff,
341 SN_SAL_IOIF_GET_HUBDEV_INFO,
342 handle, address, 0, 0, 0, 0, 0);
343 return ret_stuff.v0;
344}
345
346static void tio_conveyor_set(nasid_t nasid, int enable_flag) 333static void tio_conveyor_set(nasid_t nasid, int enable_flag)
347{ 334{
348 uint64_t ice_frz; 335 uint64_t ice_frz;
@@ -379,7 +366,29 @@ static void tio_corelet_reset(nasid_t nasid, int corelet)
379 udelay(2000); 366 udelay(2000);
380} 367}
381 368
382static int fpga_attached(nasid_t nasid) 369static int tiocx_btchar_get(int nasid)
370{
371 moduleid_t module_id;
372 geoid_t geoid;
373 int cnodeid;
374
375 cnodeid = nasid_to_cnodeid(nasid);
376 geoid = cnodeid_get_geoid(cnodeid);
377 module_id = geo_module(geoid);
378 return MODULE_GET_BTCHAR(module_id);
379}
380
381static int is_fpga_brick(int nasid)
382{
383 switch (tiocx_btchar_get(nasid)) {
384 case L1_BRICKTYPE_SA:
385 case L1_BRICKTYPE_ATHENA:
386 return 1;
387 }
388 return 0;
389}
390
391static int bitstream_loaded(nasid_t nasid)
383{ 392{
384 uint64_t cx_credits; 393 uint64_t cx_credits;
385 394
@@ -396,7 +405,7 @@ static int tiocx_reload(struct cx_dev *cx_dev)
396 int mfg_num = CX_DEV_NONE; 405 int mfg_num = CX_DEV_NONE;
397 nasid_t nasid = cx_dev->cx_id.nasid; 406 nasid_t nasid = cx_dev->cx_id.nasid;
398 407
399 if (fpga_attached(nasid)) { 408 if (bitstream_loaded(nasid)) {
400 uint64_t cx_id; 409 uint64_t cx_id;
401 410
402 cx_id = 411 cx_id =
@@ -427,9 +436,10 @@ static ssize_t show_cxdev_control(struct device *dev, char *buf)
427{ 436{
428 struct cx_dev *cx_dev = to_cx_dev(dev); 437 struct cx_dev *cx_dev = to_cx_dev(dev);
429 438
430 return sprintf(buf, "0x%x 0x%x 0x%x\n", 439 return sprintf(buf, "0x%x 0x%x 0x%x %d\n",
431 cx_dev->cx_id.nasid, 440 cx_dev->cx_id.nasid,
432 cx_dev->cx_id.part_num, cx_dev->cx_id.mfg_num); 441 cx_dev->cx_id.part_num, cx_dev->cx_id.mfg_num,
442 tiocx_btchar_get(cx_dev->cx_id.nasid));
433} 443}
434 444
435static ssize_t store_cxdev_control(struct device *dev, const char *buf, 445static ssize_t store_cxdev_control(struct device *dev, const char *buf,
@@ -475,20 +485,14 @@ static int __init tiocx_init(void)
475 if ((nasid = cnodeid_to_nasid(cnodeid)) < 0) 485 if ((nasid = cnodeid_to_nasid(cnodeid)) < 0)
476 break; /* No more nasids .. bail out of loop */ 486 break; /* No more nasids .. bail out of loop */
477 487
478 if (nasid & 0x1) { /* TIO's are always odd */ 488 if ((nasid & 0x1) && is_fpga_brick(nasid)) {
479 struct hubdev_info *hubdev; 489 struct hubdev_info *hubdev;
480 uint64_t status;
481 struct xwidget_info *widgetp; 490 struct xwidget_info *widgetp;
482 491
483 DBG("Found TIO at nasid 0x%x\n", nasid); 492 DBG("Found TIO at nasid 0x%x\n", nasid);
484 493
485 hubdev = 494 hubdev =
486 (struct hubdev_info *)(NODEPDA(cnodeid)->pdinfo); 495 (struct hubdev_info *)(NODEPDA(cnodeid)->pdinfo);
487 status =
488 tiocx_get_hubdev_info(nasid,
489 (uint64_t) __pa(hubdev));
490 if (status)
491 continue;
492 496
493 widgetp = &hubdev->hdi_xwidget_info[TIOCX_CORELET]; 497 widgetp = &hubdev->hdi_xwidget_info[TIOCX_CORELET];
494 498
diff --git a/arch/ia64/sn/kernel/xp_main.c b/arch/ia64/sn/kernel/xp_main.c
new file mode 100644
index 000000000000..3be52a34c80f
--- /dev/null
+++ b/arch/ia64/sn/kernel/xp_main.c
@@ -0,0 +1,289 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved.
7 */
8
9
10/*
11 * Cross Partition (XP) base.
12 *
13 * XP provides a base from which its users can interact
14 * with XPC, yet not be dependent on XPC.
15 *
16 */
17
18
19#include <linux/kernel.h>
20#include <linux/interrupt.h>
21#include <linux/module.h>
22#include <asm/sn/intr.h>
23#include <asm/sn/sn_sal.h>
24#include <asm/sn/xp.h>
25
26
27/*
28 * Target of nofault PIO read.
29 */
30u64 xp_nofault_PIOR_target;
31
32
33/*
34 * xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level
35 * users of XPC.
36 */
37struct xpc_registration xpc_registrations[XPC_NCHANNELS];
38
39
40/*
41 * Initialize the XPC interface to indicate that XPC isn't loaded.
42 */
43static enum xpc_retval xpc_notloaded(void) { return xpcNotLoaded; }
44
45struct xpc_interface xpc_interface = {
46 (void (*)(int)) xpc_notloaded,
47 (void (*)(int)) xpc_notloaded,
48 (enum xpc_retval (*)(partid_t, int, u32, void **)) xpc_notloaded,
49 (enum xpc_retval (*)(partid_t, int, void *)) xpc_notloaded,
50 (enum xpc_retval (*)(partid_t, int, void *, xpc_notify_func, void *))
51 xpc_notloaded,
52 (void (*)(partid_t, int, void *)) xpc_notloaded,
53 (enum xpc_retval (*)(partid_t, void *)) xpc_notloaded
54};
55
56
57/*
58 * XPC calls this when it (the XPC module) has been loaded.
59 */
60void
61xpc_set_interface(void (*connect)(int),
62 void (*disconnect)(int),
63 enum xpc_retval (*allocate)(partid_t, int, u32, void **),
64 enum xpc_retval (*send)(partid_t, int, void *),
65 enum xpc_retval (*send_notify)(partid_t, int, void *,
66 xpc_notify_func, void *),
67 void (*received)(partid_t, int, void *),
68 enum xpc_retval (*partid_to_nasids)(partid_t, void *))
69{
70 xpc_interface.connect = connect;
71 xpc_interface.disconnect = disconnect;
72 xpc_interface.allocate = allocate;
73 xpc_interface.send = send;
74 xpc_interface.send_notify = send_notify;
75 xpc_interface.received = received;
76 xpc_interface.partid_to_nasids = partid_to_nasids;
77}
78
79
80/*
81 * XPC calls this when it (the XPC module) is being unloaded.
82 */
83void
84xpc_clear_interface(void)
85{
86 xpc_interface.connect = (void (*)(int)) xpc_notloaded;
87 xpc_interface.disconnect = (void (*)(int)) xpc_notloaded;
88 xpc_interface.allocate = (enum xpc_retval (*)(partid_t, int, u32,
89 void **)) xpc_notloaded;
90 xpc_interface.send = (enum xpc_retval (*)(partid_t, int, void *))
91 xpc_notloaded;
92 xpc_interface.send_notify = (enum xpc_retval (*)(partid_t, int, void *,
93 xpc_notify_func, void *)) xpc_notloaded;
94 xpc_interface.received = (void (*)(partid_t, int, void *))
95 xpc_notloaded;
96 xpc_interface.partid_to_nasids = (enum xpc_retval (*)(partid_t, void *))
97 xpc_notloaded;
98}
99
100
101/*
102 * Register for automatic establishment of a channel connection whenever
103 * a partition comes up.
104 *
105 * Arguments:
106 *
107 * ch_number - channel # to register for connection.
108 * func - function to call for asynchronous notification of channel
109 * state changes (i.e., connection, disconnection, error) and
110 * the arrival of incoming messages.
111 * key - pointer to optional user-defined value that gets passed back
112 * to the user on any callouts made to func.
113 * payload_size - size in bytes of the XPC message's payload area which
114 * contains a user-defined message. The user should make
115 * this large enough to hold their largest message.
116 * nentries - max #of XPC message entries a message queue can contain.
117 * The actual number, which is determined when a connection
118 * is established and may be less then requested, will be
119 * passed to the user via the xpcConnected callout.
120 * assigned_limit - max number of kthreads allowed to be processing
121 * messages (per connection) at any given instant.
122 * idle_limit - max number of kthreads allowed to be idle at any given
123 * instant.
124 */
125enum xpc_retval
126xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
127 u16 nentries, u32 assigned_limit, u32 idle_limit)
128{
129 struct xpc_registration *registration;
130
131
132 DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS);
133 DBUG_ON(payload_size == 0 || nentries == 0);
134 DBUG_ON(func == NULL);
135 DBUG_ON(assigned_limit == 0 || idle_limit > assigned_limit);
136
137 registration = &xpc_registrations[ch_number];
138
139 if (down_interruptible(&registration->sema) != 0) {
140 return xpcInterrupted;
141 }
142
143 /* if XPC_CHANNEL_REGISTERED(ch_number) */
144 if (registration->func != NULL) {
145 up(&registration->sema);
146 return xpcAlreadyRegistered;
147 }
148
149 /* register the channel for connection */
150 registration->msg_size = XPC_MSG_SIZE(payload_size);
151 registration->nentries = nentries;
152 registration->assigned_limit = assigned_limit;
153 registration->idle_limit = idle_limit;
154 registration->key = key;
155 registration->func = func;
156
157 up(&registration->sema);
158
159 xpc_interface.connect(ch_number);
160
161 return xpcSuccess;
162}
163
164
165/*
166 * Remove the registration for automatic connection of the specified channel
167 * when a partition comes up.
168 *
169 * Before returning this xpc_disconnect() will wait for all connections on the
170 * specified channel have been closed/torndown. So the caller can be assured
171 * that they will not be receiving any more callouts from XPC to their
172 * function registered via xpc_connect().
173 *
174 * Arguments:
175 *
176 * ch_number - channel # to unregister.
177 */
178void
179xpc_disconnect(int ch_number)
180{
181 struct xpc_registration *registration;
182
183
184 DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS);
185
186 registration = &xpc_registrations[ch_number];
187
188 /*
189 * We've decided not to make this a down_interruptible(), since we
190 * figured XPC's users will just turn around and call xpc_disconnect()
191 * again anyways, so we might as well wait, if need be.
192 */
193 down(&registration->sema);
194
195 /* if !XPC_CHANNEL_REGISTERED(ch_number) */
196 if (registration->func == NULL) {
197 up(&registration->sema);
198 return;
199 }
200
201 /* remove the connection registration for the specified channel */
202 registration->func = NULL;
203 registration->key = NULL;
204 registration->nentries = 0;
205 registration->msg_size = 0;
206 registration->assigned_limit = 0;
207 registration->idle_limit = 0;
208
209 xpc_interface.disconnect(ch_number);
210
211 up(&registration->sema);
212
213 return;
214}
215
216
217int __init
218xp_init(void)
219{
220 int ret, ch_number;
221 u64 func_addr = *(u64 *) xp_nofault_PIOR;
222 u64 err_func_addr = *(u64 *) xp_error_PIOR;
223
224
225 if (!ia64_platform_is("sn2")) {
226 return -ENODEV;
227 }
228
229 /*
230 * Register a nofault code region which performs a cross-partition
231 * PIO read. If the PIO read times out, the MCA handler will consume
232 * the error and return to a kernel-provided instruction to indicate
233 * an error. This PIO read exists because it is guaranteed to timeout
234 * if the destination is down (AMO operations do not timeout on at
235 * least some CPUs on Shubs <= v1.2, which unfortunately we have to
236 * work around).
237 */
238 if ((ret = sn_register_nofault_code(func_addr, err_func_addr,
239 err_func_addr, 1, 1)) != 0) {
240 printk(KERN_ERR "XP: can't register nofault code, error=%d\n",
241 ret);
242 }
243 /*
244 * Setup the nofault PIO read target. (There is no special reason why
245 * SH_IPI_ACCESS was selected.)
246 */
247 if (is_shub2()) {
248 xp_nofault_PIOR_target = SH2_IPI_ACCESS0;
249 } else {
250 xp_nofault_PIOR_target = SH1_IPI_ACCESS;
251 }
252
253 /* initialize the connection registration semaphores */
254 for (ch_number = 0; ch_number < XPC_NCHANNELS; ch_number++) {
255 sema_init(&xpc_registrations[ch_number].sema, 1); /* mutex */
256 }
257
258 return 0;
259}
260module_init(xp_init);
261
262
263void __exit
264xp_exit(void)
265{
266 u64 func_addr = *(u64 *) xp_nofault_PIOR;
267 u64 err_func_addr = *(u64 *) xp_error_PIOR;
268
269
270 /* unregister the PIO read nofault code region */
271 (void) sn_register_nofault_code(func_addr, err_func_addr,
272 err_func_addr, 1, 0);
273}
274module_exit(xp_exit);
275
276
277MODULE_AUTHOR("Silicon Graphics, Inc.");
278MODULE_DESCRIPTION("Cross Partition (XP) base");
279MODULE_LICENSE("GPL");
280
281EXPORT_SYMBOL(xp_nofault_PIOR);
282EXPORT_SYMBOL(xp_nofault_PIOR_target);
283EXPORT_SYMBOL(xpc_registrations);
284EXPORT_SYMBOL(xpc_interface);
285EXPORT_SYMBOL(xpc_clear_interface);
286EXPORT_SYMBOL(xpc_set_interface);
287EXPORT_SYMBOL(xpc_connect);
288EXPORT_SYMBOL(xpc_disconnect);
289
diff --git a/arch/ia64/sn/kernel/xp_nofault.S b/arch/ia64/sn/kernel/xp_nofault.S
new file mode 100644
index 000000000000..b772543053c9
--- /dev/null
+++ b/arch/ia64/sn/kernel/xp_nofault.S
@@ -0,0 +1,31 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved.
7 */
8
9
10/*
11 * The xp_nofault_PIOR function takes a pointer to a remote PIO register
12 * and attempts to load and consume a value from it. This function
13 * will be registered as a nofault code block. In the event that the
14 * PIO read fails, the MCA handler will force the error to look
15 * corrected and vector to the xp_error_PIOR which will return an error.
16 *
17 * extern int xp_nofault_PIOR(void *remote_register);
18 */
19
20 .global xp_nofault_PIOR
21xp_nofault_PIOR:
22 mov r8=r0 // Stage a success return value
23 ld8.acq r9=[r32];; // PIO Read the specified register
24 adds r9=1,r9 // Add to force a consume
25 br.ret.sptk.many b0;; // Return success
26
27 .global xp_error_PIOR
28xp_error_PIOR:
29 mov r8=1 // Return value of 1
30 br.ret.sptk.many b0;; // Return failure
31
diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h
new file mode 100644
index 000000000000..1a0aed8490d1
--- /dev/null
+++ b/arch/ia64/sn/kernel/xpc.h
@@ -0,0 +1,991 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved.
7 */
8
9
10/*
11 * Cross Partition Communication (XPC) structures and macros.
12 */
13
14#ifndef _IA64_SN_KERNEL_XPC_H
15#define _IA64_SN_KERNEL_XPC_H
16
17
18#include <linux/config.h>
19#include <linux/interrupt.h>
20#include <linux/sysctl.h>
21#include <linux/device.h>
22#include <asm/pgtable.h>
23#include <asm/processor.h>
24#include <asm/sn/bte.h>
25#include <asm/sn/clksupport.h>
26#include <asm/sn/addrs.h>
27#include <asm/sn/mspec.h>
28#include <asm/sn/shub_mmr.h>
29#include <asm/sn/xp.h>
30
31
32/*
33 * XPC Version numbers consist of a major and minor number. XPC can always
34 * talk to versions with same major #, and never talk to versions with a
35 * different major #.
36 */
37#define _XPC_VERSION(_maj, _min) (((_maj) << 4) | ((_min) & 0xf))
38#define XPC_VERSION_MAJOR(_v) ((_v) >> 4)
39#define XPC_VERSION_MINOR(_v) ((_v) & 0xf)
40
41
42/*
43 * The next macros define word or bit representations for given
44 * C-brick nasid in either the SAL provided bit array representing
45 * nasids in the partition/machine or the AMO_t array used for
46 * inter-partition initiation communications.
47 *
48 * For SN2 machines, C-Bricks are alway even numbered NASIDs. As
49 * such, some space will be saved by insisting that nasid information
50 * passed from SAL always be packed for C-Bricks and the
51 * cross-partition interrupts use the same packing scheme.
52 */
53#define XPC_NASID_W_INDEX(_n) (((_n) / 64) / 2)
54#define XPC_NASID_B_INDEX(_n) (((_n) / 2) & (64 - 1))
55#define XPC_NASID_IN_ARRAY(_n, _p) ((_p)[XPC_NASID_W_INDEX(_n)] & \
56 (1UL << XPC_NASID_B_INDEX(_n)))
57#define XPC_NASID_FROM_W_B(_w, _b) (((_w) * 64 + (_b)) * 2)
58
59#define XPC_HB_DEFAULT_INTERVAL 5 /* incr HB every x secs */
60#define XPC_HB_CHECK_DEFAULT_TIMEOUT 20 /* check HB every x secs */
61
62/* define the process name of HB checker and the CPU it is pinned to */
63#define XPC_HB_CHECK_THREAD_NAME "xpc_hb"
64#define XPC_HB_CHECK_CPU 0
65
66/* define the process name of the discovery thread */
67#define XPC_DISCOVERY_THREAD_NAME "xpc_discovery"
68
69
70#define XPC_HB_ALLOWED(_p, _v) ((_v)->heartbeating_to_mask & (1UL << (_p)))
71#define XPC_ALLOW_HB(_p, _v) (_v)->heartbeating_to_mask |= (1UL << (_p))
72#define XPC_DISALLOW_HB(_p, _v) (_v)->heartbeating_to_mask &= (~(1UL << (_p)))
73
74
75/*
76 * Reserved Page provided by SAL.
77 *
78 * SAL provides one page per partition of reserved memory. When SAL
79 * initialization is complete, SAL_signature, SAL_version, partid,
80 * part_nasids, and mach_nasids are set.
81 *
82 * Note: Until vars_pa is set, the partition XPC code has not been initialized.
83 */
84struct xpc_rsvd_page {
85 u64 SAL_signature; /* SAL unique signature */
86 u64 SAL_version; /* SAL specified version */
87 u8 partid; /* partition ID from SAL */
88 u8 version;
89 u8 pad[6]; /* pad to u64 align */
90 u64 vars_pa;
91 u64 part_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned;
92 u64 mach_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned;
93};
94#define XPC_RP_VERSION _XPC_VERSION(1,0) /* version 1.0 of the reserved page */
95
96#define XPC_RSVD_PAGE_ALIGNED_SIZE \
97 (L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page)))
98
99
100/*
101 * Define the structures by which XPC variables can be exported to other
102 * partitions. (There are two: struct xpc_vars and struct xpc_vars_part)
103 */
104
105/*
106 * The following structure describes the partition generic variables
107 * needed by other partitions in order to properly initialize.
108 *
109 * struct xpc_vars version number also applies to struct xpc_vars_part.
110 * Changes to either structure and/or related functionality should be
111 * reflected by incrementing either the major or minor version numbers
112 * of struct xpc_vars.
113 */
114struct xpc_vars {
115 u8 version;
116 u64 heartbeat;
117 u64 heartbeating_to_mask;
118 u64 kdb_status; /* 0 = machine running */
119 int act_nasid;
120 int act_phys_cpuid;
121 u64 vars_part_pa;
122 u64 amos_page_pa; /* paddr of page of AMOs from MSPEC driver */
123 AMO_t *amos_page; /* vaddr of page of AMOs from MSPEC driver */
124 AMO_t *act_amos; /* pointer to the first activation AMO */
125};
126#define XPC_V_VERSION _XPC_VERSION(3,0) /* version 3.0 of the cross vars */
127
128#define XPC_VARS_ALIGNED_SIZE (L1_CACHE_ALIGN(sizeof(struct xpc_vars)))
129
130/*
131 * The following structure describes the per partition specific variables.
132 *
133 * An array of these structures, one per partition, will be defined. As a
134 * partition becomes active XPC will copy the array entry corresponding to
135 * itself from that partition. It is desirable that the size of this
136 * structure evenly divide into a cacheline, such that none of the entries
137 * in this array crosses a cacheline boundary. As it is now, each entry
138 * occupies half a cacheline.
139 */
140struct xpc_vars_part {
141 u64 magic;
142
143 u64 openclose_args_pa; /* physical address of open and close args */
144 u64 GPs_pa; /* physical address of Get/Put values */
145
146 u64 IPI_amo_pa; /* physical address of IPI AMO_t structure */
147 int IPI_nasid; /* nasid of where to send IPIs */
148 int IPI_phys_cpuid; /* physical CPU ID of where to send IPIs */
149
150 u8 nchannels; /* #of defined channels supported */
151
152 u8 reserved[23]; /* pad to a full 64 bytes */
153};
154
155/*
156 * The vars_part MAGIC numbers play a part in the first contact protocol.
157 *
158 * MAGIC1 indicates that the per partition specific variables for a remote
159 * partition have been initialized by this partition.
160 *
161 * MAGIC2 indicates that this partition has pulled the remote partititions
162 * per partition variables that pertain to this partition.
163 */
164#define XPC_VP_MAGIC1 0x0053524156435058L /* 'XPCVARS\0'L (little endian) */
165#define XPC_VP_MAGIC2 0x0073726176435058L /* 'XPCvars\0'L (little endian) */
166
167
168
169/*
170 * Functions registered by add_timer() or called by kernel_thread() only
171 * allow for a single 64-bit argument. The following macros can be used to
172 * pack and unpack two (32-bit, 16-bit or 8-bit) arguments into or out from
173 * the passed argument.
174 */
175#define XPC_PACK_ARGS(_arg1, _arg2) \
176 ((((u64) _arg1) & 0xffffffff) | \
177 ((((u64) _arg2) & 0xffffffff) << 32))
178
179#define XPC_UNPACK_ARG1(_args) (((u64) _args) & 0xffffffff)
180#define XPC_UNPACK_ARG2(_args) ((((u64) _args) >> 32) & 0xffffffff)
181
182
183
184/*
185 * Define a Get/Put value pair (pointers) used with a message queue.
186 */
187struct xpc_gp {
188 s64 get; /* Get value */
189 s64 put; /* Put value */
190};
191
192#define XPC_GP_SIZE \
193 L1_CACHE_ALIGN(sizeof(struct xpc_gp) * XPC_NCHANNELS)
194
195
196
197/*
198 * Define a structure that contains arguments associated with opening and
199 * closing a channel.
200 */
201struct xpc_openclose_args {
202 u16 reason; /* reason why channel is closing */
203 u16 msg_size; /* sizeof each message entry */
204 u16 remote_nentries; /* #of message entries in remote msg queue */
205 u16 local_nentries; /* #of message entries in local msg queue */
206 u64 local_msgqueue_pa; /* physical address of local message queue */
207};
208
209#define XPC_OPENCLOSE_ARGS_SIZE \
210 L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * XPC_NCHANNELS)
211
212
213
214/* struct xpc_msg flags */
215
216#define XPC_M_DONE 0x01 /* msg has been received/consumed */
217#define XPC_M_READY 0x02 /* msg is ready to be sent */
218#define XPC_M_INTERRUPT 0x04 /* send interrupt when msg consumed */
219
220
221#define XPC_MSG_ADDRESS(_payload) \
222 ((struct xpc_msg *)((u8 *)(_payload) - XPC_MSG_PAYLOAD_OFFSET))
223
224
225
226/*
227 * Defines notify entry.
228 *
229 * This is used to notify a message's sender that their message was received
230 * and consumed by the intended recipient.
231 */
232struct xpc_notify {
233 struct semaphore sema; /* notify semaphore */
234 u8 type; /* type of notification */
235
236 /* the following two fields are only used if type == XPC_N_CALL */
237 xpc_notify_func func; /* user's notify function */
238 void *key; /* pointer to user's key */
239};
240
241/* struct xpc_notify type of notification */
242
243#define XPC_N_CALL 0x01 /* notify function provided by user */
244
245
246
247/*
248 * Define the structure that manages all the stuff required by a channel. In
249 * particular, they are used to manage the messages sent across the channel.
250 *
251 * This structure is private to a partition, and is NOT shared across the
252 * partition boundary.
253 *
254 * There is an array of these structures for each remote partition. It is
255 * allocated at the time a partition becomes active. The array contains one
256 * of these structures for each potential channel connection to that partition.
257 *
258 * Each of these structures manages two message queues (circular buffers).
259 * They are allocated at the time a channel connection is made. One of
260 * these message queues (local_msgqueue) holds the locally created messages
261 * that are destined for the remote partition. The other of these message
262 * queues (remote_msgqueue) is a locally cached copy of the remote partition's
263 * own local_msgqueue.
264 *
265 * The following is a description of the Get/Put pointers used to manage these
266 * two message queues. Consider the local_msgqueue to be on one partition
267 * and the remote_msgqueue to be its cached copy on another partition. A
268 * description of what each of the lettered areas contains is included.
269 *
270 *
271 * local_msgqueue remote_msgqueue
272 *
273 * |/////////| |/////////|
274 * w_remote_GP.get --> +---------+ |/////////|
275 * | F | |/////////|
276 * remote_GP.get --> +---------+ +---------+ <-- local_GP->get
277 * | | | |
278 * | | | E |
279 * | | | |
280 * | | +---------+ <-- w_local_GP.get
281 * | B | |/////////|
282 * | | |////D////|
283 * | | |/////////|
284 * | | +---------+ <-- w_remote_GP.put
285 * | | |////C////|
286 * local_GP->put --> +---------+ +---------+ <-- remote_GP.put
287 * | | |/////////|
288 * | A | |/////////|
289 * | | |/////////|
290 * w_local_GP.put --> +---------+ |/////////|
291 * |/////////| |/////////|
292 *
293 *
294 * ( remote_GP.[get|put] are cached copies of the remote
295 * partition's local_GP->[get|put], and thus their values can
296 * lag behind their counterparts on the remote partition. )
297 *
298 *
299 * A - Messages that have been allocated, but have not yet been sent to the
300 * remote partition.
301 *
302 * B - Messages that have been sent, but have not yet been acknowledged by the
303 * remote partition as having been received.
304 *
305 * C - Area that needs to be prepared for the copying of sent messages, by
306 * the clearing of the message flags of any previously received messages.
307 *
308 * D - Area into which sent messages are to be copied from the remote
309 * partition's local_msgqueue and then delivered to their intended
310 * recipients. [ To allow for a multi-message copy, another pointer
311 * (next_msg_to_pull) has been added to keep track of the next message
312 * number needing to be copied (pulled). It chases after w_remote_GP.put.
313 * Any messages lying between w_local_GP.get and next_msg_to_pull have
314 * been copied and are ready to be delivered. ]
315 *
316 * E - Messages that have been copied and delivered, but have not yet been
317 * acknowledged by the recipient as having been received.
318 *
319 * F - Messages that have been acknowledged, but XPC has not yet notified the
320 * sender that the message was received by its intended recipient.
321 * This is also an area that needs to be prepared for the allocating of
322 * new messages, by the clearing of the message flags of the acknowledged
323 * messages.
324 */
325struct xpc_channel {
326 partid_t partid; /* ID of remote partition connected */
327 spinlock_t lock; /* lock for updating this structure */
328 u32 flags; /* general flags */
329
330 enum xpc_retval reason; /* reason why channel is disconnect'g */
331 int reason_line; /* line# disconnect initiated from */
332
333 u16 number; /* channel # */
334
335 u16 msg_size; /* sizeof each msg entry */
336 u16 local_nentries; /* #of msg entries in local msg queue */
337 u16 remote_nentries; /* #of msg entries in remote msg queue*/
338
339 void *local_msgqueue_base; /* base address of kmalloc'd space */
340 struct xpc_msg *local_msgqueue; /* local message queue */
341 void *remote_msgqueue_base; /* base address of kmalloc'd space */
342 struct xpc_msg *remote_msgqueue;/* cached copy of remote partition's */
343 /* local message queue */
344 u64 remote_msgqueue_pa; /* phys addr of remote partition's */
345 /* local message queue */
346
347 atomic_t references; /* #of external references to queues */
348
349 atomic_t n_on_msg_allocate_wq; /* #on msg allocation wait queue */
350 wait_queue_head_t msg_allocate_wq; /* msg allocation wait queue */
351
352 /* queue of msg senders who want to be notified when msg received */
353
354 atomic_t n_to_notify; /* #of msg senders to notify */
355 struct xpc_notify *notify_queue;/* notify queue for messages sent */
356
357 xpc_channel_func func; /* user's channel function */
358 void *key; /* pointer to user's key */
359
360 struct semaphore msg_to_pull_sema; /* next msg to pull serialization */
361 struct semaphore teardown_sema; /* wait for teardown completion */
362
363 struct xpc_openclose_args *local_openclose_args; /* args passed on */
364 /* opening or closing of channel */
365
366 /* various flavors of local and remote Get/Put values */
367
368 struct xpc_gp *local_GP; /* local Get/Put values */
369 struct xpc_gp remote_GP; /* remote Get/Put values */
370 struct xpc_gp w_local_GP; /* working local Get/Put values */
371 struct xpc_gp w_remote_GP; /* working remote Get/Put values */
372 s64 next_msg_to_pull; /* Put value of next msg to pull */
373
374 /* kthread management related fields */
375
376// >>> rethink having kthreads_assigned_limit and kthreads_idle_limit; perhaps
377// >>> allow the assigned limit be unbounded and let the idle limit be dynamic
378// >>> dependent on activity over the last interval of time
379 atomic_t kthreads_assigned; /* #of kthreads assigned to channel */
380 u32 kthreads_assigned_limit; /* limit on #of kthreads assigned */
381 atomic_t kthreads_idle; /* #of kthreads idle waiting for work */
382 u32 kthreads_idle_limit; /* limit on #of kthreads idle */
383 atomic_t kthreads_active; /* #of kthreads actively working */
384 // >>> following field is temporary
385 u32 kthreads_created; /* total #of kthreads created */
386
387 wait_queue_head_t idle_wq; /* idle kthread wait queue */
388
389} ____cacheline_aligned;
390
391
392/* struct xpc_channel flags */
393
394#define XPC_C_WASCONNECTED 0x00000001 /* channel was connected */
395
396#define XPC_C_ROPENREPLY 0x00000002 /* remote open channel reply */
397#define XPC_C_OPENREPLY 0x00000004 /* local open channel reply */
398#define XPC_C_ROPENREQUEST 0x00000008 /* remote open channel request */
399#define XPC_C_OPENREQUEST 0x00000010 /* local open channel request */
400
401#define XPC_C_SETUP 0x00000020 /* channel's msgqueues are alloc'd */
402#define XPC_C_CONNECTCALLOUT 0x00000040 /* channel connected callout made */
403#define XPC_C_CONNECTED 0x00000080 /* local channel is connected */
404#define XPC_C_CONNECTING 0x00000100 /* channel is being connected */
405
406#define XPC_C_RCLOSEREPLY 0x00000200 /* remote close channel reply */
407#define XPC_C_CLOSEREPLY 0x00000400 /* local close channel reply */
408#define XPC_C_RCLOSEREQUEST 0x00000800 /* remote close channel request */
409#define XPC_C_CLOSEREQUEST 0x00001000 /* local close channel request */
410
411#define XPC_C_DISCONNECTED 0x00002000 /* channel is disconnected */
412#define XPC_C_DISCONNECTING 0x00004000 /* channel is being disconnected */
413
414
415
416/*
417 * Manages channels on a partition basis. There is one of these structures
418 * for each partition (a partition will never utilize the structure that
419 * represents itself).
420 */
421struct xpc_partition {
422
423 /* XPC HB infrastructure */
424
425 u64 remote_rp_pa; /* phys addr of partition's rsvd pg */
426 u64 remote_vars_pa; /* phys addr of partition's vars */
427 u64 remote_vars_part_pa; /* phys addr of partition's vars part */
428 u64 last_heartbeat; /* HB at last read */
429 u64 remote_amos_page_pa; /* phys addr of partition's amos page */
430 int remote_act_nasid; /* active part's act/deact nasid */
431 int remote_act_phys_cpuid; /* active part's act/deact phys cpuid */
432 u32 act_IRQ_rcvd; /* IRQs since activation */
433 spinlock_t act_lock; /* protect updating of act_state */
434 u8 act_state; /* from XPC HB viewpoint */
435 enum xpc_retval reason; /* reason partition is deactivating */
436 int reason_line; /* line# deactivation initiated from */
437 int reactivate_nasid; /* nasid in partition to reactivate */
438
439
440 /* XPC infrastructure referencing and teardown control */
441
442 u8 setup_state; /* infrastructure setup state */
443 wait_queue_head_t teardown_wq; /* kthread waiting to teardown infra */
444 atomic_t references; /* #of references to infrastructure */
445
446
447 /*
448 * NONE OF THE PRECEDING FIELDS OF THIS STRUCTURE WILL BE CLEARED WHEN
449 * XPC SETS UP THE NECESSARY INFRASTRUCTURE TO SUPPORT CROSS PARTITION
450 * COMMUNICATION. ALL OF THE FOLLOWING FIELDS WILL BE CLEARED. (THE
451 * 'nchannels' FIELD MUST BE THE FIRST OF THE FIELDS TO BE CLEARED.)
452 */
453
454
455 u8 nchannels; /* #of defined channels supported */
456 atomic_t nchannels_active; /* #of channels that are not DISCONNECTED */
457 struct xpc_channel *channels;/* array of channel structures */
458
459 void *local_GPs_base; /* base address of kmalloc'd space */
460 struct xpc_gp *local_GPs; /* local Get/Put values */
461 void *remote_GPs_base; /* base address of kmalloc'd space */
462 struct xpc_gp *remote_GPs;/* copy of remote partition's local Get/Put */
463 /* values */
464 u64 remote_GPs_pa; /* phys address of remote partition's local */
465 /* Get/Put values */
466
467
468 /* fields used to pass args when opening or closing a channel */
469
470 void *local_openclose_args_base; /* base address of kmalloc'd space */
471 struct xpc_openclose_args *local_openclose_args; /* local's args */
472 void *remote_openclose_args_base; /* base address of kmalloc'd space */
473 struct xpc_openclose_args *remote_openclose_args; /* copy of remote's */
474 /* args */
475 u64 remote_openclose_args_pa; /* phys addr of remote's args */
476
477
478 /* IPI sending, receiving and handling related fields */
479
480 int remote_IPI_nasid; /* nasid of where to send IPIs */
481 int remote_IPI_phys_cpuid; /* phys CPU ID of where to send IPIs */
482 AMO_t *remote_IPI_amo_va; /* address of remote IPI AMO_t structure */
483
484 AMO_t *local_IPI_amo_va; /* address of IPI AMO_t structure */
485 u64 local_IPI_amo; /* IPI amo flags yet to be handled */
486 char IPI_owner[8]; /* IPI owner's name */
487 struct timer_list dropped_IPI_timer; /* dropped IPI timer */
488
489 spinlock_t IPI_lock; /* IPI handler lock */
490
491
492 /* channel manager related fields */
493
494 atomic_t channel_mgr_requests; /* #of requests to activate chan mgr */
495 wait_queue_head_t channel_mgr_wq; /* channel mgr's wait queue */
496
497} ____cacheline_aligned;
498
499
500/* struct xpc_partition act_state values (for XPC HB) */
501
502#define XPC_P_INACTIVE 0x00 /* partition is not active */
503#define XPC_P_ACTIVATION_REQ 0x01 /* created thread to activate */
504#define XPC_P_ACTIVATING 0x02 /* activation thread started */
505#define XPC_P_ACTIVE 0x03 /* xpc_partition_up() was called */
506#define XPC_P_DEACTIVATING 0x04 /* partition deactivation initiated */
507
508
509#define XPC_DEACTIVATE_PARTITION(_p, _reason) \
510 xpc_deactivate_partition(__LINE__, (_p), (_reason))
511
512
513/* struct xpc_partition setup_state values */
514
515#define XPC_P_UNSET 0x00 /* infrastructure was never setup */
516#define XPC_P_SETUP 0x01 /* infrastructure is setup */
517#define XPC_P_WTEARDOWN 0x02 /* waiting to teardown infrastructure */
518#define XPC_P_TORNDOWN 0x03 /* infrastructure is torndown */
519
520
521/*
522 * struct xpc_partition IPI_timer #of seconds to wait before checking for
523 * dropped IPIs. These occur whenever an IPI amo write doesn't complete until
524 * after the IPI was received.
525 */
526#define XPC_P_DROPPED_IPI_WAIT (0.25 * HZ)
527
528
529#define XPC_PARTID(_p) ((partid_t) ((_p) - &xpc_partitions[0]))
530
531
532
533/* found in xp_main.c */
534extern struct xpc_registration xpc_registrations[];
535
536
537/* >>> found in xpc_main.c only */
538extern struct device *xpc_part;
539extern struct device *xpc_chan;
540extern irqreturn_t xpc_notify_IRQ_handler(int, void *, struct pt_regs *);
541extern void xpc_dropped_IPI_check(struct xpc_partition *);
542extern void xpc_activate_kthreads(struct xpc_channel *, int);
543extern void xpc_create_kthreads(struct xpc_channel *, int);
544extern void xpc_disconnect_wait(int);
545
546
547/* found in xpc_main.c and efi-xpc.c */
548extern void xpc_activate_partition(struct xpc_partition *);
549
550
551/* found in xpc_partition.c */
552extern int xpc_exiting;
553extern int xpc_hb_interval;
554extern int xpc_hb_check_interval;
555extern struct xpc_vars *xpc_vars;
556extern struct xpc_rsvd_page *xpc_rsvd_page;
557extern struct xpc_vars_part *xpc_vars_part;
558extern struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1];
559extern char xpc_remote_copy_buffer[];
560extern struct xpc_rsvd_page *xpc_rsvd_page_init(void);
561extern void xpc_allow_IPI_ops(void);
562extern void xpc_restrict_IPI_ops(void);
563extern int xpc_identify_act_IRQ_sender(void);
564extern enum xpc_retval xpc_mark_partition_active(struct xpc_partition *);
565extern void xpc_mark_partition_inactive(struct xpc_partition *);
566extern void xpc_discovery(void);
567extern void xpc_check_remote_hb(void);
568extern void xpc_deactivate_partition(const int, struct xpc_partition *,
569 enum xpc_retval);
570extern enum xpc_retval xpc_initiate_partid_to_nasids(partid_t, void *);
571
572
573/* found in xpc_channel.c */
574extern void xpc_initiate_connect(int);
575extern void xpc_initiate_disconnect(int);
576extern enum xpc_retval xpc_initiate_allocate(partid_t, int, u32, void **);
577extern enum xpc_retval xpc_initiate_send(partid_t, int, void *);
578extern enum xpc_retval xpc_initiate_send_notify(partid_t, int, void *,
579 xpc_notify_func, void *);
580extern void xpc_initiate_received(partid_t, int, void *);
581extern enum xpc_retval xpc_setup_infrastructure(struct xpc_partition *);
582extern enum xpc_retval xpc_pull_remote_vars_part(struct xpc_partition *);
583extern void xpc_process_channel_activity(struct xpc_partition *);
584extern void xpc_connected_callout(struct xpc_channel *);
585extern void xpc_deliver_msg(struct xpc_channel *);
586extern void xpc_disconnect_channel(const int, struct xpc_channel *,
587 enum xpc_retval, unsigned long *);
588extern void xpc_disconnected_callout(struct xpc_channel *);
589extern void xpc_partition_down(struct xpc_partition *, enum xpc_retval);
590extern void xpc_teardown_infrastructure(struct xpc_partition *);
591
592
593
594static inline void
595xpc_wakeup_channel_mgr(struct xpc_partition *part)
596{
597 if (atomic_inc_return(&part->channel_mgr_requests) == 1) {
598 wake_up(&part->channel_mgr_wq);
599 }
600}
601
602
603
604/*
605 * These next two inlines are used to keep us from tearing down a channel's
606 * msg queues while a thread may be referencing them.
607 */
608static inline void
609xpc_msgqueue_ref(struct xpc_channel *ch)
610{
611 atomic_inc(&ch->references);
612}
613
614static inline void
615xpc_msgqueue_deref(struct xpc_channel *ch)
616{
617 s32 refs = atomic_dec_return(&ch->references);
618
619 DBUG_ON(refs < 0);
620 if (refs == 0) {
621 xpc_wakeup_channel_mgr(&xpc_partitions[ch->partid]);
622 }
623}
624
625
626
627#define XPC_DISCONNECT_CHANNEL(_ch, _reason, _irqflgs) \
628 xpc_disconnect_channel(__LINE__, _ch, _reason, _irqflgs)
629
630
631/*
632 * These two inlines are used to keep us from tearing down a partition's
633 * setup infrastructure while a thread may be referencing it.
634 */
635static inline void
636xpc_part_deref(struct xpc_partition *part)
637{
638 s32 refs = atomic_dec_return(&part->references);
639
640
641 DBUG_ON(refs < 0);
642 if (refs == 0 && part->setup_state == XPC_P_WTEARDOWN) {
643 wake_up(&part->teardown_wq);
644 }
645}
646
647static inline int
648xpc_part_ref(struct xpc_partition *part)
649{
650 int setup;
651
652
653 atomic_inc(&part->references);
654 setup = (part->setup_state == XPC_P_SETUP);
655 if (!setup) {
656 xpc_part_deref(part);
657 }
658 return setup;
659}
660
661
662
663/*
664 * The following macro is to be used for the setting of the reason and
665 * reason_line fields in both the struct xpc_channel and struct xpc_partition
666 * structures.
667 */
668#define XPC_SET_REASON(_p, _reason, _line) \
669 { \
670 (_p)->reason = _reason; \
671 (_p)->reason_line = _line; \
672 }
673
674
675
676/*
677 * The following set of macros and inlines are used for the sending and
678 * receiving of IPIs (also known as IRQs). There are two flavors of IPIs,
679 * one that is associated with partition activity (SGI_XPC_ACTIVATE) and
680 * the other that is associated with channel activity (SGI_XPC_NOTIFY).
681 */
682
683static inline u64
684xpc_IPI_receive(AMO_t *amo)
685{
686 return FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_CLEAR);
687}
688
689
690static inline enum xpc_retval
691xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector)
692{
693 int ret = 0;
694 unsigned long irq_flags;
695
696
697 local_irq_save(irq_flags);
698
699 FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR, flag);
700 sn_send_IPI_phys(nasid, phys_cpuid, vector, 0);
701
702 /*
703 * We must always use the nofault function regardless of whether we
704 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
705 * didn't, we'd never know that the other partition is down and would
706 * keep sending IPIs and AMOs to it until the heartbeat times out.
707 */
708 ret = xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo->variable),
709 xp_nofault_PIOR_target));
710
711 local_irq_restore(irq_flags);
712
713 return ((ret == 0) ? xpcSuccess : xpcPioReadError);
714}
715
716
717/*
718 * IPIs associated with SGI_XPC_ACTIVATE IRQ.
719 */
720
721/*
722 * Flag the appropriate AMO variable and send an IPI to the specified node.
723 */
724static inline void
725xpc_activate_IRQ_send(u64 amos_page, int from_nasid, int to_nasid,
726 int to_phys_cpuid)
727{
728 int w_index = XPC_NASID_W_INDEX(from_nasid);
729 int b_index = XPC_NASID_B_INDEX(from_nasid);
730 AMO_t *amos = (AMO_t *) __va(amos_page +
731 (XP_MAX_PARTITIONS * sizeof(AMO_t)));
732
733
734 (void) xpc_IPI_send(&amos[w_index], (1UL << b_index), to_nasid,
735 to_phys_cpuid, SGI_XPC_ACTIVATE);
736}
737
738static inline void
739xpc_IPI_send_activate(struct xpc_vars *vars)
740{
741 xpc_activate_IRQ_send(vars->amos_page_pa, cnodeid_to_nasid(0),
742 vars->act_nasid, vars->act_phys_cpuid);
743}
744
745static inline void
746xpc_IPI_send_activated(struct xpc_partition *part)
747{
748 xpc_activate_IRQ_send(part->remote_amos_page_pa, cnodeid_to_nasid(0),
749 part->remote_act_nasid, part->remote_act_phys_cpuid);
750}
751
752static inline void
753xpc_IPI_send_reactivate(struct xpc_partition *part)
754{
755 xpc_activate_IRQ_send(xpc_vars->amos_page_pa, part->reactivate_nasid,
756 xpc_vars->act_nasid, xpc_vars->act_phys_cpuid);
757}
758
759
760/*
761 * IPIs associated with SGI_XPC_NOTIFY IRQ.
762 */
763
764/*
765 * Send an IPI to the remote partition that is associated with the
766 * specified channel.
767 */
768#define XPC_NOTIFY_IRQ_SEND(_ch, _ipi_f, _irq_f) \
769 xpc_notify_IRQ_send(_ch, _ipi_f, #_ipi_f, _irq_f)
770
771static inline void
772xpc_notify_IRQ_send(struct xpc_channel *ch, u8 ipi_flag, char *ipi_flag_string,
773 unsigned long *irq_flags)
774{
775 struct xpc_partition *part = &xpc_partitions[ch->partid];
776 enum xpc_retval ret;
777
778
779 if (likely(part->act_state != XPC_P_DEACTIVATING)) {
780 ret = xpc_IPI_send(part->remote_IPI_amo_va,
781 (u64) ipi_flag << (ch->number * 8),
782 part->remote_IPI_nasid,
783 part->remote_IPI_phys_cpuid,
784 SGI_XPC_NOTIFY);
785 dev_dbg(xpc_chan, "%s sent to partid=%d, channel=%d, ret=%d\n",
786 ipi_flag_string, ch->partid, ch->number, ret);
787 if (unlikely(ret != xpcSuccess)) {
788 if (irq_flags != NULL) {
789 spin_unlock_irqrestore(&ch->lock, *irq_flags);
790 }
791 XPC_DEACTIVATE_PARTITION(part, ret);
792 if (irq_flags != NULL) {
793 spin_lock_irqsave(&ch->lock, *irq_flags);
794 }
795 }
796 }
797}
798
799
800/*
801 * Make it look like the remote partition, which is associated with the
802 * specified channel, sent us an IPI. This faked IPI will be handled
803 * by xpc_dropped_IPI_check().
804 */
805#define XPC_NOTIFY_IRQ_SEND_LOCAL(_ch, _ipi_f) \
806 xpc_notify_IRQ_send_local(_ch, _ipi_f, #_ipi_f)
807
808static inline void
809xpc_notify_IRQ_send_local(struct xpc_channel *ch, u8 ipi_flag,
810 char *ipi_flag_string)
811{
812 struct xpc_partition *part = &xpc_partitions[ch->partid];
813
814
815 FETCHOP_STORE_OP(TO_AMO((u64) &part->local_IPI_amo_va->variable),
816 FETCHOP_OR, ((u64) ipi_flag << (ch->number * 8)));
817 dev_dbg(xpc_chan, "%s sent local from partid=%d, channel=%d\n",
818 ipi_flag_string, ch->partid, ch->number);
819}
820
821
822/*
823 * The sending and receiving of IPIs includes the setting of an AMO variable
824 * to indicate the reason the IPI was sent. The 64-bit variable is divided
825 * up into eight bytes, ordered from right to left. Byte zero pertains to
826 * channel 0, byte one to channel 1, and so on. Each byte is described by
827 * the following IPI flags.
828 */
829
830#define XPC_IPI_CLOSEREQUEST 0x01
831#define XPC_IPI_CLOSEREPLY 0x02
832#define XPC_IPI_OPENREQUEST 0x04
833#define XPC_IPI_OPENREPLY 0x08
834#define XPC_IPI_MSGREQUEST 0x10
835
836
837/* given an AMO variable and a channel#, get its associated IPI flags */
838#define XPC_GET_IPI_FLAGS(_amo, _c) ((u8) (((_amo) >> ((_c) * 8)) & 0xff))
839
840#define XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(_amo) ((_amo) & 0x0f0f0f0f0f0f0f0f)
841#define XPC_ANY_MSG_IPI_FLAGS_SET(_amo) ((_amo) & 0x1010101010101010)
842
843
844static inline void
845xpc_IPI_send_closerequest(struct xpc_channel *ch, unsigned long *irq_flags)
846{
847 struct xpc_openclose_args *args = ch->local_openclose_args;
848
849
850 args->reason = ch->reason;
851
852 XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_CLOSEREQUEST, irq_flags);
853}
854
855static inline void
856xpc_IPI_send_closereply(struct xpc_channel *ch, unsigned long *irq_flags)
857{
858 XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_CLOSEREPLY, irq_flags);
859}
860
861static inline void
862xpc_IPI_send_openrequest(struct xpc_channel *ch, unsigned long *irq_flags)
863{
864 struct xpc_openclose_args *args = ch->local_openclose_args;
865
866
867 args->msg_size = ch->msg_size;
868 args->local_nentries = ch->local_nentries;
869
870 XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_OPENREQUEST, irq_flags);
871}
872
873static inline void
874xpc_IPI_send_openreply(struct xpc_channel *ch, unsigned long *irq_flags)
875{
876 struct xpc_openclose_args *args = ch->local_openclose_args;
877
878
879 args->remote_nentries = ch->remote_nentries;
880 args->local_nentries = ch->local_nentries;
881 args->local_msgqueue_pa = __pa(ch->local_msgqueue);
882
883 XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_OPENREPLY, irq_flags);
884}
885
886static inline void
887xpc_IPI_send_msgrequest(struct xpc_channel *ch)
888{
889 XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_MSGREQUEST, NULL);
890}
891
892static inline void
893xpc_IPI_send_local_msgrequest(struct xpc_channel *ch)
894{
895 XPC_NOTIFY_IRQ_SEND_LOCAL(ch, XPC_IPI_MSGREQUEST);
896}
897
898
899/*
900 * Memory for XPC's AMO variables is allocated by the MSPEC driver. These
901 * pages are located in the lowest granule. The lowest granule uses 4k pages
902 * for cached references and an alternate TLB handler to never provide a
903 * cacheable mapping for the entire region. This will prevent speculative
904 * reading of cached copies of our lines from being issued which will cause
905 * a PI FSB Protocol error to be generated by the SHUB. For XPC, we need 64
906 * (XP_MAX_PARTITIONS) AMO variables for message notification (xpc_main.c)
907 * and an additional 16 AMO variables for partition activation (xpc_hb.c).
908 */
909static inline AMO_t *
910xpc_IPI_init(partid_t partid)
911{
912 AMO_t *part_amo = xpc_vars->amos_page + partid;
913
914
915 xpc_IPI_receive(part_amo);
916 return part_amo;
917}
918
919
920
921static inline enum xpc_retval
922xpc_map_bte_errors(bte_result_t error)
923{
924 switch (error) {
925 case BTE_SUCCESS: return xpcSuccess;
926 case BTEFAIL_DIR: return xpcBteDirectoryError;
927 case BTEFAIL_POISON: return xpcBtePoisonError;
928 case BTEFAIL_WERR: return xpcBteWriteError;
929 case BTEFAIL_ACCESS: return xpcBteAccessError;
930 case BTEFAIL_PWERR: return xpcBtePWriteError;
931 case BTEFAIL_PRERR: return xpcBtePReadError;
932 case BTEFAIL_TOUT: return xpcBteTimeOutError;
933 case BTEFAIL_XTERR: return xpcBteXtalkError;
934 case BTEFAIL_NOTAVAIL: return xpcBteNotAvailable;
935 default: return xpcBteUnmappedError;
936 }
937}
938
939
940
941static inline void *
942xpc_kmalloc_cacheline_aligned(size_t size, int flags, void **base)
943{
944 /* see if kmalloc will give us cachline aligned memory by default */
945 *base = kmalloc(size, flags);
946 if (*base == NULL) {
947 return NULL;
948 }
949 if ((u64) *base == L1_CACHE_ALIGN((u64) *base)) {
950 return *base;
951 }
952 kfree(*base);
953
954 /* nope, we'll have to do it ourselves */
955 *base = kmalloc(size + L1_CACHE_BYTES, flags);
956 if (*base == NULL) {
957 return NULL;
958 }
959 return (void *) L1_CACHE_ALIGN((u64) *base);
960}
961
962
963/*
964 * Check to see if there is any channel activity to/from the specified
965 * partition.
966 */
967static inline void
968xpc_check_for_channel_activity(struct xpc_partition *part)
969{
970 u64 IPI_amo;
971 unsigned long irq_flags;
972
973
974 IPI_amo = xpc_IPI_receive(part->local_IPI_amo_va);
975 if (IPI_amo == 0) {
976 return;
977 }
978
979 spin_lock_irqsave(&part->IPI_lock, irq_flags);
980 part->local_IPI_amo |= IPI_amo;
981 spin_unlock_irqrestore(&part->IPI_lock, irq_flags);
982
983 dev_dbg(xpc_chan, "received IPI from partid=%d, IPI_amo=0x%lx\n",
984 XPC_PARTID(part), IPI_amo);
985
986 xpc_wakeup_channel_mgr(part);
987}
988
989
990#endif /* _IA64_SN_KERNEL_XPC_H */
991
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c
new file mode 100644
index 000000000000..0bf6fbcc46d2
--- /dev/null
+++ b/arch/ia64/sn/kernel/xpc_channel.c
@@ -0,0 +1,2297 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved.
7 */
8
9
10/*
11 * Cross Partition Communication (XPC) channel support.
12 *
13 * This is the part of XPC that manages the channels and
14 * sends/receives messages across them to/from other partitions.
15 *
16 */
17
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/sched.h>
22#include <linux/cache.h>
23#include <linux/interrupt.h>
24#include <linux/slab.h>
25#include <asm/sn/bte.h>
26#include <asm/sn/sn_sal.h>
27#include "xpc.h"
28
29
30/*
31 * Set up the initial values for the XPartition Communication channels.
32 */
33static void
34xpc_initialize_channels(struct xpc_partition *part, partid_t partid)
35{
36 int ch_number;
37 struct xpc_channel *ch;
38
39
40 for (ch_number = 0; ch_number < part->nchannels; ch_number++) {
41 ch = &part->channels[ch_number];
42
43 ch->partid = partid;
44 ch->number = ch_number;
45 ch->flags = XPC_C_DISCONNECTED;
46
47 ch->local_GP = &part->local_GPs[ch_number];
48 ch->local_openclose_args =
49 &part->local_openclose_args[ch_number];
50
51 atomic_set(&ch->kthreads_assigned, 0);
52 atomic_set(&ch->kthreads_idle, 0);
53 atomic_set(&ch->kthreads_active, 0);
54
55 atomic_set(&ch->references, 0);
56 atomic_set(&ch->n_to_notify, 0);
57
58 spin_lock_init(&ch->lock);
59 sema_init(&ch->msg_to_pull_sema, 1); /* mutex */
60
61 atomic_set(&ch->n_on_msg_allocate_wq, 0);
62 init_waitqueue_head(&ch->msg_allocate_wq);
63 init_waitqueue_head(&ch->idle_wq);
64 }
65}
66
67
68/*
69 * Setup the infrastructure necessary to support XPartition Communication
70 * between the specified remote partition and the local one.
71 */
72enum xpc_retval
73xpc_setup_infrastructure(struct xpc_partition *part)
74{
75 int ret;
76 struct timer_list *timer;
77 partid_t partid = XPC_PARTID(part);
78
79
80 /*
81 * Zero out MOST of the entry for this partition. Only the fields
82 * starting with `nchannels' will be zeroed. The preceding fields must
83 * remain `viable' across partition ups and downs, since they may be
84 * referenced during this memset() operation.
85 */
86 memset(&part->nchannels, 0, sizeof(struct xpc_partition) -
87 offsetof(struct xpc_partition, nchannels));
88
89 /*
90 * Allocate all of the channel structures as a contiguous chunk of
91 * memory.
92 */
93 part->channels = kmalloc(sizeof(struct xpc_channel) * XPC_NCHANNELS,
94 GFP_KERNEL);
95 if (part->channels == NULL) {
96 dev_err(xpc_chan, "can't get memory for channels\n");
97 return xpcNoMemory;
98 }
99 memset(part->channels, 0, sizeof(struct xpc_channel) * XPC_NCHANNELS);
100
101 part->nchannels = XPC_NCHANNELS;
102
103
104 /* allocate all the required GET/PUT values */
105
106 part->local_GPs = xpc_kmalloc_cacheline_aligned(XPC_GP_SIZE,
107 GFP_KERNEL, &part->local_GPs_base);
108 if (part->local_GPs == NULL) {
109 kfree(part->channels);
110 part->channels = NULL;
111 dev_err(xpc_chan, "can't get memory for local get/put "
112 "values\n");
113 return xpcNoMemory;
114 }
115 memset(part->local_GPs, 0, XPC_GP_SIZE);
116
117 part->remote_GPs = xpc_kmalloc_cacheline_aligned(XPC_GP_SIZE,
118 GFP_KERNEL, &part->remote_GPs_base);
119 if (part->remote_GPs == NULL) {
120 kfree(part->channels);
121 part->channels = NULL;
122 kfree(part->local_GPs_base);
123 part->local_GPs = NULL;
124 dev_err(xpc_chan, "can't get memory for remote get/put "
125 "values\n");
126 return xpcNoMemory;
127 }
128 memset(part->remote_GPs, 0, XPC_GP_SIZE);
129
130
131 /* allocate all the required open and close args */
132
133 part->local_openclose_args = xpc_kmalloc_cacheline_aligned(
134 XPC_OPENCLOSE_ARGS_SIZE, GFP_KERNEL,
135 &part->local_openclose_args_base);
136 if (part->local_openclose_args == NULL) {
137 kfree(part->channels);
138 part->channels = NULL;
139 kfree(part->local_GPs_base);
140 part->local_GPs = NULL;
141 kfree(part->remote_GPs_base);
142 part->remote_GPs = NULL;
143 dev_err(xpc_chan, "can't get memory for local connect args\n");
144 return xpcNoMemory;
145 }
146 memset(part->local_openclose_args, 0, XPC_OPENCLOSE_ARGS_SIZE);
147
148 part->remote_openclose_args = xpc_kmalloc_cacheline_aligned(
149 XPC_OPENCLOSE_ARGS_SIZE, GFP_KERNEL,
150 &part->remote_openclose_args_base);
151 if (part->remote_openclose_args == NULL) {
152 kfree(part->channels);
153 part->channels = NULL;
154 kfree(part->local_GPs_base);
155 part->local_GPs = NULL;
156 kfree(part->remote_GPs_base);
157 part->remote_GPs = NULL;
158 kfree(part->local_openclose_args_base);
159 part->local_openclose_args = NULL;
160 dev_err(xpc_chan, "can't get memory for remote connect args\n");
161 return xpcNoMemory;
162 }
163 memset(part->remote_openclose_args, 0, XPC_OPENCLOSE_ARGS_SIZE);
164
165
166 xpc_initialize_channels(part, partid);
167
168 atomic_set(&part->nchannels_active, 0);
169
170
171 /* local_IPI_amo were set to 0 by an earlier memset() */
172
173 /* Initialize this partitions AMO_t structure */
174 part->local_IPI_amo_va = xpc_IPI_init(partid);
175
176 spin_lock_init(&part->IPI_lock);
177
178 atomic_set(&part->channel_mgr_requests, 1);
179 init_waitqueue_head(&part->channel_mgr_wq);
180
181 sprintf(part->IPI_owner, "xpc%02d", partid);
182 ret = request_irq(SGI_XPC_NOTIFY, xpc_notify_IRQ_handler, SA_SHIRQ,
183 part->IPI_owner, (void *) (u64) partid);
184 if (ret != 0) {
185 kfree(part->channels);
186 part->channels = NULL;
187 kfree(part->local_GPs_base);
188 part->local_GPs = NULL;
189 kfree(part->remote_GPs_base);
190 part->remote_GPs = NULL;
191 kfree(part->local_openclose_args_base);
192 part->local_openclose_args = NULL;
193 kfree(part->remote_openclose_args_base);
194 part->remote_openclose_args = NULL;
195 dev_err(xpc_chan, "can't register NOTIFY IRQ handler, "
196 "errno=%d\n", -ret);
197 return xpcLackOfResources;
198 }
199
200 /* Setup a timer to check for dropped IPIs */
201 timer = &part->dropped_IPI_timer;
202 init_timer(timer);
203 timer->function = (void (*)(unsigned long)) xpc_dropped_IPI_check;
204 timer->data = (unsigned long) part;
205 timer->expires = jiffies + XPC_P_DROPPED_IPI_WAIT;
206 add_timer(timer);
207
208 /*
209 * With the setting of the partition setup_state to XPC_P_SETUP, we're
210 * declaring that this partition is ready to go.
211 */
212 (volatile u8) part->setup_state = XPC_P_SETUP;
213
214
215 /*
216 * Setup the per partition specific variables required by the
217 * remote partition to establish channel connections with us.
218 *
219 * The setting of the magic # indicates that these per partition
220 * specific variables are ready to be used.
221 */
222 xpc_vars_part[partid].GPs_pa = __pa(part->local_GPs);
223 xpc_vars_part[partid].openclose_args_pa =
224 __pa(part->local_openclose_args);
225 xpc_vars_part[partid].IPI_amo_pa = __pa(part->local_IPI_amo_va);
226 xpc_vars_part[partid].IPI_nasid = cpuid_to_nasid(smp_processor_id());
227 xpc_vars_part[partid].IPI_phys_cpuid =
228 cpu_physical_id(smp_processor_id());
229 xpc_vars_part[partid].nchannels = part->nchannels;
230 (volatile u64) xpc_vars_part[partid].magic = XPC_VP_MAGIC1;
231
232 return xpcSuccess;
233}
234
235
236/*
237 * Create a wrapper that hides the underlying mechanism for pulling a cacheline
238 * (or multiple cachelines) from a remote partition.
239 *
240 * src must be a cacheline aligned physical address on the remote partition.
241 * dst must be a cacheline aligned virtual address on this partition.
242 * cnt must be an cacheline sized
243 */
244static enum xpc_retval
245xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst,
246 const void *src, size_t cnt)
247{
248 bte_result_t bte_ret;
249
250
251 DBUG_ON((u64) src != L1_CACHE_ALIGN((u64) src));
252 DBUG_ON((u64) dst != L1_CACHE_ALIGN((u64) dst));
253 DBUG_ON(cnt != L1_CACHE_ALIGN(cnt));
254
255 if (part->act_state == XPC_P_DEACTIVATING) {
256 return part->reason;
257 }
258
259 bte_ret = xp_bte_copy((u64) src, (u64) ia64_tpa((u64) dst),
260 (u64) cnt, (BTE_NORMAL | BTE_WACQUIRE), NULL);
261 if (bte_ret == BTE_SUCCESS) {
262 return xpcSuccess;
263 }
264
265 dev_dbg(xpc_chan, "xp_bte_copy() from partition %d failed, ret=%d\n",
266 XPC_PARTID(part), bte_ret);
267
268 return xpc_map_bte_errors(bte_ret);
269}
270
271
272/*
273 * Pull the remote per partititon specific variables from the specified
274 * partition.
275 */
276enum xpc_retval
277xpc_pull_remote_vars_part(struct xpc_partition *part)
278{
279 u8 buffer[L1_CACHE_BYTES * 2];
280 struct xpc_vars_part *pulled_entry_cacheline =
281 (struct xpc_vars_part *) L1_CACHE_ALIGN((u64) buffer);
282 struct xpc_vars_part *pulled_entry;
283 u64 remote_entry_cacheline_pa, remote_entry_pa;
284 partid_t partid = XPC_PARTID(part);
285 enum xpc_retval ret;
286
287
288 /* pull the cacheline that contains the variables we're interested in */
289
290 DBUG_ON(part->remote_vars_part_pa !=
291 L1_CACHE_ALIGN(part->remote_vars_part_pa));
292 DBUG_ON(sizeof(struct xpc_vars_part) != L1_CACHE_BYTES / 2);
293
294 remote_entry_pa = part->remote_vars_part_pa +
295 sn_partition_id * sizeof(struct xpc_vars_part);
296
297 remote_entry_cacheline_pa = (remote_entry_pa & ~(L1_CACHE_BYTES - 1));
298
299 pulled_entry = (struct xpc_vars_part *) ((u64) pulled_entry_cacheline +
300 (remote_entry_pa & (L1_CACHE_BYTES - 1)));
301
302 ret = xpc_pull_remote_cachelines(part, pulled_entry_cacheline,
303 (void *) remote_entry_cacheline_pa,
304 L1_CACHE_BYTES);
305 if (ret != xpcSuccess) {
306 dev_dbg(xpc_chan, "failed to pull XPC vars_part from "
307 "partition %d, ret=%d\n", partid, ret);
308 return ret;
309 }
310
311
312 /* see if they've been set up yet */
313
314 if (pulled_entry->magic != XPC_VP_MAGIC1 &&
315 pulled_entry->magic != XPC_VP_MAGIC2) {
316
317 if (pulled_entry->magic != 0) {
318 dev_dbg(xpc_chan, "partition %d's XPC vars_part for "
319 "partition %d has bad magic value (=0x%lx)\n",
320 partid, sn_partition_id, pulled_entry->magic);
321 return xpcBadMagic;
322 }
323
324 /* they've not been initialized yet */
325 return xpcRetry;
326 }
327
328 if (xpc_vars_part[partid].magic == XPC_VP_MAGIC1) {
329
330 /* validate the variables */
331
332 if (pulled_entry->GPs_pa == 0 ||
333 pulled_entry->openclose_args_pa == 0 ||
334 pulled_entry->IPI_amo_pa == 0) {
335
336 dev_err(xpc_chan, "partition %d's XPC vars_part for "
337 "partition %d are not valid\n", partid,
338 sn_partition_id);
339 return xpcInvalidAddress;
340 }
341
342 /* the variables we imported look to be valid */
343
344 part->remote_GPs_pa = pulled_entry->GPs_pa;
345 part->remote_openclose_args_pa =
346 pulled_entry->openclose_args_pa;
347 part->remote_IPI_amo_va =
348 (AMO_t *) __va(pulled_entry->IPI_amo_pa);
349 part->remote_IPI_nasid = pulled_entry->IPI_nasid;
350 part->remote_IPI_phys_cpuid = pulled_entry->IPI_phys_cpuid;
351
352 if (part->nchannels > pulled_entry->nchannels) {
353 part->nchannels = pulled_entry->nchannels;
354 }
355
356 /* let the other side know that we've pulled their variables */
357
358 (volatile u64) xpc_vars_part[partid].magic = XPC_VP_MAGIC2;
359 }
360
361 if (pulled_entry->magic == XPC_VP_MAGIC1) {
362 return xpcRetry;
363 }
364
365 return xpcSuccess;
366}
367
368
369/*
370 * Get the IPI flags and pull the openclose args and/or remote GPs as needed.
371 */
372static u64
373xpc_get_IPI_flags(struct xpc_partition *part)
374{
375 unsigned long irq_flags;
376 u64 IPI_amo;
377 enum xpc_retval ret;
378
379
380 /*
381 * See if there are any IPI flags to be handled.
382 */
383
384 spin_lock_irqsave(&part->IPI_lock, irq_flags);
385 if ((IPI_amo = part->local_IPI_amo) != 0) {
386 part->local_IPI_amo = 0;
387 }
388 spin_unlock_irqrestore(&part->IPI_lock, irq_flags);
389
390
391 if (XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(IPI_amo)) {
392 ret = xpc_pull_remote_cachelines(part,
393 part->remote_openclose_args,
394 (void *) part->remote_openclose_args_pa,
395 XPC_OPENCLOSE_ARGS_SIZE);
396 if (ret != xpcSuccess) {
397 XPC_DEACTIVATE_PARTITION(part, ret);
398
399 dev_dbg(xpc_chan, "failed to pull openclose args from "
400 "partition %d, ret=%d\n", XPC_PARTID(part),
401 ret);
402
403 /* don't bother processing IPIs anymore */
404 IPI_amo = 0;
405 }
406 }
407
408 if (XPC_ANY_MSG_IPI_FLAGS_SET(IPI_amo)) {
409 ret = xpc_pull_remote_cachelines(part, part->remote_GPs,
410 (void *) part->remote_GPs_pa,
411 XPC_GP_SIZE);
412 if (ret != xpcSuccess) {
413 XPC_DEACTIVATE_PARTITION(part, ret);
414
415 dev_dbg(xpc_chan, "failed to pull GPs from partition "
416 "%d, ret=%d\n", XPC_PARTID(part), ret);
417
418 /* don't bother processing IPIs anymore */
419 IPI_amo = 0;
420 }
421 }
422
423 return IPI_amo;
424}
425
426
427/*
428 * Allocate the local message queue and the notify queue.
429 */
430static enum xpc_retval
431xpc_allocate_local_msgqueue(struct xpc_channel *ch)
432{
433 unsigned long irq_flags;
434 int nentries;
435 size_t nbytes;
436
437
438 // >>> may want to check for ch->flags & XPC_C_DISCONNECTING between
439 // >>> iterations of the for-loop, bail if set?
440
441 // >>> should we impose a minumum #of entries? like 4 or 8?
442 for (nentries = ch->local_nentries; nentries > 0; nentries--) {
443
444 nbytes = nentries * ch->msg_size;
445 ch->local_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes,
446 (GFP_KERNEL | GFP_DMA),
447 &ch->local_msgqueue_base);
448 if (ch->local_msgqueue == NULL) {
449 continue;
450 }
451 memset(ch->local_msgqueue, 0, nbytes);
452
453 nbytes = nentries * sizeof(struct xpc_notify);
454 ch->notify_queue = kmalloc(nbytes, (GFP_KERNEL | GFP_DMA));
455 if (ch->notify_queue == NULL) {
456 kfree(ch->local_msgqueue_base);
457 ch->local_msgqueue = NULL;
458 continue;
459 }
460 memset(ch->notify_queue, 0, nbytes);
461
462 spin_lock_irqsave(&ch->lock, irq_flags);
463 if (nentries < ch->local_nentries) {
464 dev_dbg(xpc_chan, "nentries=%d local_nentries=%d, "
465 "partid=%d, channel=%d\n", nentries,
466 ch->local_nentries, ch->partid, ch->number);
467
468 ch->local_nentries = nentries;
469 }
470 spin_unlock_irqrestore(&ch->lock, irq_flags);
471 return xpcSuccess;
472 }
473
474 dev_dbg(xpc_chan, "can't get memory for local message queue and notify "
475 "queue, partid=%d, channel=%d\n", ch->partid, ch->number);
476 return xpcNoMemory;
477}
478
479
480/*
481 * Allocate the cached remote message queue.
482 */
483static enum xpc_retval
484xpc_allocate_remote_msgqueue(struct xpc_channel *ch)
485{
486 unsigned long irq_flags;
487 int nentries;
488 size_t nbytes;
489
490
491 DBUG_ON(ch->remote_nentries <= 0);
492
493 // >>> may want to check for ch->flags & XPC_C_DISCONNECTING between
494 // >>> iterations of the for-loop, bail if set?
495
496 // >>> should we impose a minumum #of entries? like 4 or 8?
497 for (nentries = ch->remote_nentries; nentries > 0; nentries--) {
498
499 nbytes = nentries * ch->msg_size;
500 ch->remote_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes,
501 (GFP_KERNEL | GFP_DMA),
502 &ch->remote_msgqueue_base);
503 if (ch->remote_msgqueue == NULL) {
504 continue;
505 }
506 memset(ch->remote_msgqueue, 0, nbytes);
507
508 spin_lock_irqsave(&ch->lock, irq_flags);
509 if (nentries < ch->remote_nentries) {
510 dev_dbg(xpc_chan, "nentries=%d remote_nentries=%d, "
511 "partid=%d, channel=%d\n", nentries,
512 ch->remote_nentries, ch->partid, ch->number);
513
514 ch->remote_nentries = nentries;
515 }
516 spin_unlock_irqrestore(&ch->lock, irq_flags);
517 return xpcSuccess;
518 }
519
520 dev_dbg(xpc_chan, "can't get memory for cached remote message queue, "
521 "partid=%d, channel=%d\n", ch->partid, ch->number);
522 return xpcNoMemory;
523}
524
525
526/*
527 * Allocate message queues and other stuff associated with a channel.
528 *
529 * Note: Assumes all of the channel sizes are filled in.
530 */
531static enum xpc_retval
532xpc_allocate_msgqueues(struct xpc_channel *ch)
533{
534 unsigned long irq_flags;
535 int i;
536 enum xpc_retval ret;
537
538
539 DBUG_ON(ch->flags & XPC_C_SETUP);
540
541 if ((ret = xpc_allocate_local_msgqueue(ch)) != xpcSuccess) {
542 return ret;
543 }
544
545 if ((ret = xpc_allocate_remote_msgqueue(ch)) != xpcSuccess) {
546 kfree(ch->local_msgqueue_base);
547 ch->local_msgqueue = NULL;
548 kfree(ch->notify_queue);
549 ch->notify_queue = NULL;
550 return ret;
551 }
552
553 for (i = 0; i < ch->local_nentries; i++) {
554 /* use a semaphore as an event wait queue */
555 sema_init(&ch->notify_queue[i].sema, 0);
556 }
557
558 sema_init(&ch->teardown_sema, 0); /* event wait */
559
560 spin_lock_irqsave(&ch->lock, irq_flags);
561 ch->flags |= XPC_C_SETUP;
562 spin_unlock_irqrestore(&ch->lock, irq_flags);
563
564 return xpcSuccess;
565}
566
567
568/*
569 * Process a connect message from a remote partition.
570 *
571 * Note: xpc_process_connect() is expecting to be called with the
572 * spin_lock_irqsave held and will leave it locked upon return.
573 */
574static void
575xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
576{
577 enum xpc_retval ret;
578
579
580 DBUG_ON(!spin_is_locked(&ch->lock));
581
582 if (!(ch->flags & XPC_C_OPENREQUEST) ||
583 !(ch->flags & XPC_C_ROPENREQUEST)) {
584 /* nothing more to do for now */
585 return;
586 }
587 DBUG_ON(!(ch->flags & XPC_C_CONNECTING));
588
589 if (!(ch->flags & XPC_C_SETUP)) {
590 spin_unlock_irqrestore(&ch->lock, *irq_flags);
591 ret = xpc_allocate_msgqueues(ch);
592 spin_lock_irqsave(&ch->lock, *irq_flags);
593
594 if (ret != xpcSuccess) {
595 XPC_DISCONNECT_CHANNEL(ch, ret, irq_flags);
596 }
597 if (ch->flags & (XPC_C_CONNECTED | XPC_C_DISCONNECTING)) {
598 return;
599 }
600
601 DBUG_ON(!(ch->flags & XPC_C_SETUP));
602 DBUG_ON(ch->local_msgqueue == NULL);
603 DBUG_ON(ch->remote_msgqueue == NULL);
604 }
605
606 if (!(ch->flags & XPC_C_OPENREPLY)) {
607 ch->flags |= XPC_C_OPENREPLY;
608 xpc_IPI_send_openreply(ch, irq_flags);
609 }
610
611 if (!(ch->flags & XPC_C_ROPENREPLY)) {
612 return;
613 }
614
615 DBUG_ON(ch->remote_msgqueue_pa == 0);
616
617 ch->flags = (XPC_C_CONNECTED | XPC_C_SETUP); /* clear all else */
618
619 dev_info(xpc_chan, "channel %d to partition %d connected\n",
620 ch->number, ch->partid);
621
622 spin_unlock_irqrestore(&ch->lock, *irq_flags);
623 xpc_create_kthreads(ch, 1);
624 spin_lock_irqsave(&ch->lock, *irq_flags);
625}
626
627
628/*
629 * Free up message queues and other stuff that were allocated for the specified
630 * channel.
631 *
632 * Note: ch->reason and ch->reason_line are left set for debugging purposes,
633 * they're cleared when XPC_C_DISCONNECTED is cleared.
634 */
635static void
636xpc_free_msgqueues(struct xpc_channel *ch)
637{
638 DBUG_ON(!spin_is_locked(&ch->lock));
639 DBUG_ON(atomic_read(&ch->n_to_notify) != 0);
640
641 ch->remote_msgqueue_pa = 0;
642 ch->func = NULL;
643 ch->key = NULL;
644 ch->msg_size = 0;
645 ch->local_nentries = 0;
646 ch->remote_nentries = 0;
647 ch->kthreads_assigned_limit = 0;
648 ch->kthreads_idle_limit = 0;
649
650 ch->local_GP->get = 0;
651 ch->local_GP->put = 0;
652 ch->remote_GP.get = 0;
653 ch->remote_GP.put = 0;
654 ch->w_local_GP.get = 0;
655 ch->w_local_GP.put = 0;
656 ch->w_remote_GP.get = 0;
657 ch->w_remote_GP.put = 0;
658 ch->next_msg_to_pull = 0;
659
660 if (ch->flags & XPC_C_SETUP) {
661 ch->flags &= ~XPC_C_SETUP;
662
663 dev_dbg(xpc_chan, "ch->flags=0x%x, partid=%d, channel=%d\n",
664 ch->flags, ch->partid, ch->number);
665
666 kfree(ch->local_msgqueue_base);
667 ch->local_msgqueue = NULL;
668 kfree(ch->remote_msgqueue_base);
669 ch->remote_msgqueue = NULL;
670 kfree(ch->notify_queue);
671 ch->notify_queue = NULL;
672
673 /* in case someone is waiting for the teardown to complete */
674 up(&ch->teardown_sema);
675 }
676}
677
678
679/*
680 * spin_lock_irqsave() is expected to be held on entry.
681 */
682static void
683xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
684{
685 struct xpc_partition *part = &xpc_partitions[ch->partid];
686 u32 ch_flags = ch->flags;
687
688
689 DBUG_ON(!spin_is_locked(&ch->lock));
690
691 if (!(ch->flags & XPC_C_DISCONNECTING)) {
692 return;
693 }
694
695 DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST));
696
697 /* make sure all activity has settled down first */
698
699 if (atomic_read(&ch->references) > 0) {
700 return;
701 }
702 DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0);
703
704 /* it's now safe to free the channel's message queues */
705
706 xpc_free_msgqueues(ch);
707 DBUG_ON(ch->flags & XPC_C_SETUP);
708
709 if (part->act_state != XPC_P_DEACTIVATING) {
710
711 /* as long as the other side is up do the full protocol */
712
713 if (!(ch->flags & XPC_C_RCLOSEREQUEST)) {
714 return;
715 }
716
717 if (!(ch->flags & XPC_C_CLOSEREPLY)) {
718 ch->flags |= XPC_C_CLOSEREPLY;
719 xpc_IPI_send_closereply(ch, irq_flags);
720 }
721
722 if (!(ch->flags & XPC_C_RCLOSEREPLY)) {
723 return;
724 }
725 }
726
727 /* both sides are disconnected now */
728
729 ch->flags = XPC_C_DISCONNECTED; /* clear all flags, but this one */
730
731 atomic_dec(&part->nchannels_active);
732
733 if (ch_flags & XPC_C_WASCONNECTED) {
734 dev_info(xpc_chan, "channel %d to partition %d disconnected, "
735 "reason=%d\n", ch->number, ch->partid, ch->reason);
736 }
737}
738
739
740/*
741 * Process a change in the channel's remote connection state.
742 */
743static void
744xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number,
745 u8 IPI_flags)
746{
747 unsigned long irq_flags;
748 struct xpc_openclose_args *args =
749 &part->remote_openclose_args[ch_number];
750 struct xpc_channel *ch = &part->channels[ch_number];
751 enum xpc_retval reason;
752
753
754
755 spin_lock_irqsave(&ch->lock, irq_flags);
756
757
758 if (IPI_flags & XPC_IPI_CLOSEREQUEST) {
759
760 dev_dbg(xpc_chan, "XPC_IPI_CLOSEREQUEST (reason=%d) received "
761 "from partid=%d, channel=%d\n", args->reason,
762 ch->partid, ch->number);
763
764 /*
765 * If RCLOSEREQUEST is set, we're probably waiting for
766 * RCLOSEREPLY. We should find it and a ROPENREQUEST packed
767 * with this RCLOSEQREUQEST in the IPI_flags.
768 */
769
770 if (ch->flags & XPC_C_RCLOSEREQUEST) {
771 DBUG_ON(!(ch->flags & XPC_C_DISCONNECTING));
772 DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST));
773 DBUG_ON(!(ch->flags & XPC_C_CLOSEREPLY));
774 DBUG_ON(ch->flags & XPC_C_RCLOSEREPLY);
775
776 DBUG_ON(!(IPI_flags & XPC_IPI_CLOSEREPLY));
777 IPI_flags &= ~XPC_IPI_CLOSEREPLY;
778 ch->flags |= XPC_C_RCLOSEREPLY;
779
780 /* both sides have finished disconnecting */
781 xpc_process_disconnect(ch, &irq_flags);
782 }
783
784 if (ch->flags & XPC_C_DISCONNECTED) {
785 // >>> explain this section
786
787 if (!(IPI_flags & XPC_IPI_OPENREQUEST)) {
788 DBUG_ON(part->act_state !=
789 XPC_P_DEACTIVATING);
790 spin_unlock_irqrestore(&ch->lock, irq_flags);
791 return;
792 }
793
794 XPC_SET_REASON(ch, 0, 0);
795 ch->flags &= ~XPC_C_DISCONNECTED;
796
797 atomic_inc(&part->nchannels_active);
798 ch->flags |= (XPC_C_CONNECTING | XPC_C_ROPENREQUEST);
799 }
800
801 IPI_flags &= ~(XPC_IPI_OPENREQUEST | XPC_IPI_OPENREPLY);
802
803 /*
804 * The meaningful CLOSEREQUEST connection state fields are:
805 * reason = reason connection is to be closed
806 */
807
808 ch->flags |= XPC_C_RCLOSEREQUEST;
809
810 if (!(ch->flags & XPC_C_DISCONNECTING)) {
811 reason = args->reason;
812 if (reason <= xpcSuccess || reason > xpcUnknownReason) {
813 reason = xpcUnknownReason;
814 } else if (reason == xpcUnregistering) {
815 reason = xpcOtherUnregistering;
816 }
817
818 XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags);
819 } else {
820 xpc_process_disconnect(ch, &irq_flags);
821 }
822 }
823
824
825 if (IPI_flags & XPC_IPI_CLOSEREPLY) {
826
827 dev_dbg(xpc_chan, "XPC_IPI_CLOSEREPLY received from partid=%d,"
828 " channel=%d\n", ch->partid, ch->number);
829
830 if (ch->flags & XPC_C_DISCONNECTED) {
831 DBUG_ON(part->act_state != XPC_P_DEACTIVATING);
832 spin_unlock_irqrestore(&ch->lock, irq_flags);
833 return;
834 }
835
836 DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST));
837 DBUG_ON(!(ch->flags & XPC_C_RCLOSEREQUEST));
838
839 ch->flags |= XPC_C_RCLOSEREPLY;
840
841 if (ch->flags & XPC_C_CLOSEREPLY) {
842 /* both sides have finished disconnecting */
843 xpc_process_disconnect(ch, &irq_flags);
844 }
845 }
846
847
848 if (IPI_flags & XPC_IPI_OPENREQUEST) {
849
850 dev_dbg(xpc_chan, "XPC_IPI_OPENREQUEST (msg_size=%d, "
851 "local_nentries=%d) received from partid=%d, "
852 "channel=%d\n", args->msg_size, args->local_nentries,
853 ch->partid, ch->number);
854
855 if ((ch->flags & XPC_C_DISCONNECTING) ||
856 part->act_state == XPC_P_DEACTIVATING) {
857 spin_unlock_irqrestore(&ch->lock, irq_flags);
858 return;
859 }
860 DBUG_ON(!(ch->flags & (XPC_C_DISCONNECTED |
861 XPC_C_OPENREQUEST)));
862 DBUG_ON(ch->flags & (XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY |
863 XPC_C_OPENREPLY | XPC_C_CONNECTED));
864
865 /*
866 * The meaningful OPENREQUEST connection state fields are:
867 * msg_size = size of channel's messages in bytes
868 * local_nentries = remote partition's local_nentries
869 */
870 DBUG_ON(args->msg_size == 0);
871 DBUG_ON(args->local_nentries == 0);
872
873 ch->flags |= (XPC_C_ROPENREQUEST | XPC_C_CONNECTING);
874 ch->remote_nentries = args->local_nentries;
875
876
877 if (ch->flags & XPC_C_OPENREQUEST) {
878 if (args->msg_size != ch->msg_size) {
879 XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes,
880 &irq_flags);
881 spin_unlock_irqrestore(&ch->lock, irq_flags);
882 return;
883 }
884 } else {
885 ch->msg_size = args->msg_size;
886
887 XPC_SET_REASON(ch, 0, 0);
888 ch->flags &= ~XPC_C_DISCONNECTED;
889
890 atomic_inc(&part->nchannels_active);
891 }
892
893 xpc_process_connect(ch, &irq_flags);
894 }
895
896
897 if (IPI_flags & XPC_IPI_OPENREPLY) {
898
899 dev_dbg(xpc_chan, "XPC_IPI_OPENREPLY (local_msgqueue_pa=0x%lx, "
900 "local_nentries=%d, remote_nentries=%d) received from "
901 "partid=%d, channel=%d\n", args->local_msgqueue_pa,
902 args->local_nentries, args->remote_nentries,
903 ch->partid, ch->number);
904
905 if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) {
906 spin_unlock_irqrestore(&ch->lock, irq_flags);
907 return;
908 }
909 DBUG_ON(!(ch->flags & XPC_C_OPENREQUEST));
910 DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST));
911 DBUG_ON(ch->flags & XPC_C_CONNECTED);
912
913 /*
914 * The meaningful OPENREPLY connection state fields are:
915 * local_msgqueue_pa = physical address of remote
916 * partition's local_msgqueue
917 * local_nentries = remote partition's local_nentries
918 * remote_nentries = remote partition's remote_nentries
919 */
920 DBUG_ON(args->local_msgqueue_pa == 0);
921 DBUG_ON(args->local_nentries == 0);
922 DBUG_ON(args->remote_nentries == 0);
923
924 ch->flags |= XPC_C_ROPENREPLY;
925 ch->remote_msgqueue_pa = args->local_msgqueue_pa;
926
927 if (args->local_nentries < ch->remote_nentries) {
928 dev_dbg(xpc_chan, "XPC_IPI_OPENREPLY: new "
929 "remote_nentries=%d, old remote_nentries=%d, "
930 "partid=%d, channel=%d\n",
931 args->local_nentries, ch->remote_nentries,
932 ch->partid, ch->number);
933
934 ch->remote_nentries = args->local_nentries;
935 }
936 if (args->remote_nentries < ch->local_nentries) {
937 dev_dbg(xpc_chan, "XPC_IPI_OPENREPLY: new "
938 "local_nentries=%d, old local_nentries=%d, "
939 "partid=%d, channel=%d\n",
940 args->remote_nentries, ch->local_nentries,
941 ch->partid, ch->number);
942
943 ch->local_nentries = args->remote_nentries;
944 }
945
946 xpc_process_connect(ch, &irq_flags);
947 }
948
949 spin_unlock_irqrestore(&ch->lock, irq_flags);
950}
951
952
953/*
954 * Attempt to establish a channel connection to a remote partition.
955 */
956static enum xpc_retval
957xpc_connect_channel(struct xpc_channel *ch)
958{
959 unsigned long irq_flags;
960 struct xpc_registration *registration = &xpc_registrations[ch->number];
961
962
963 if (down_interruptible(&registration->sema) != 0) {
964 return xpcInterrupted;
965 }
966
967 if (!XPC_CHANNEL_REGISTERED(ch->number)) {
968 up(&registration->sema);
969 return xpcUnregistered;
970 }
971
972 spin_lock_irqsave(&ch->lock, irq_flags);
973
974 DBUG_ON(ch->flags & XPC_C_CONNECTED);
975 DBUG_ON(ch->flags & XPC_C_OPENREQUEST);
976
977 if (ch->flags & XPC_C_DISCONNECTING) {
978 spin_unlock_irqrestore(&ch->lock, irq_flags);
979 up(&registration->sema);
980 return ch->reason;
981 }
982
983
984 /* add info from the channel connect registration to the channel */
985
986 ch->kthreads_assigned_limit = registration->assigned_limit;
987 ch->kthreads_idle_limit = registration->idle_limit;
988 DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0);
989 DBUG_ON(atomic_read(&ch->kthreads_idle) != 0);
990 DBUG_ON(atomic_read(&ch->kthreads_active) != 0);
991
992 ch->func = registration->func;
993 DBUG_ON(registration->func == NULL);
994 ch->key = registration->key;
995
996 ch->local_nentries = registration->nentries;
997
998 if (ch->flags & XPC_C_ROPENREQUEST) {
999 if (registration->msg_size != ch->msg_size) {
1000 /* the local and remote sides aren't the same */
1001
1002 /*
1003 * Because XPC_DISCONNECT_CHANNEL() can block we're
1004 * forced to up the registration sema before we unlock
1005 * the channel lock. But that's okay here because we're
1006 * done with the part that required the registration
1007 * sema. XPC_DISCONNECT_CHANNEL() requires that the
1008 * channel lock be locked and will unlock and relock
1009 * the channel lock as needed.
1010 */
1011 up(&registration->sema);
1012 XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes,
1013 &irq_flags);
1014 spin_unlock_irqrestore(&ch->lock, irq_flags);
1015 return xpcUnequalMsgSizes;
1016 }
1017 } else {
1018 ch->msg_size = registration->msg_size;
1019
1020 XPC_SET_REASON(ch, 0, 0);
1021 ch->flags &= ~XPC_C_DISCONNECTED;
1022
1023 atomic_inc(&xpc_partitions[ch->partid].nchannels_active);
1024 }
1025
1026 up(&registration->sema);
1027
1028
1029 /* initiate the connection */
1030
1031 ch->flags |= (XPC_C_OPENREQUEST | XPC_C_CONNECTING);
1032 xpc_IPI_send_openrequest(ch, &irq_flags);
1033
1034 xpc_process_connect(ch, &irq_flags);
1035
1036 spin_unlock_irqrestore(&ch->lock, irq_flags);
1037
1038 return xpcSuccess;
1039}
1040
1041
1042/*
1043 * Notify those who wanted to be notified upon delivery of their message.
1044 */
1045static void
1046xpc_notify_senders(struct xpc_channel *ch, enum xpc_retval reason, s64 put)
1047{
1048 struct xpc_notify *notify;
1049 u8 notify_type;
1050 s64 get = ch->w_remote_GP.get - 1;
1051
1052
1053 while (++get < put && atomic_read(&ch->n_to_notify) > 0) {
1054
1055 notify = &ch->notify_queue[get % ch->local_nentries];
1056
1057 /*
1058 * See if the notify entry indicates it was associated with
1059 * a message who's sender wants to be notified. It is possible
1060 * that it is, but someone else is doing or has done the
1061 * notification.
1062 */
1063 notify_type = notify->type;
1064 if (notify_type == 0 ||
1065 cmpxchg(&notify->type, notify_type, 0) !=
1066 notify_type) {
1067 continue;
1068 }
1069
1070 DBUG_ON(notify_type != XPC_N_CALL);
1071
1072 atomic_dec(&ch->n_to_notify);
1073
1074 if (notify->func != NULL) {
1075 dev_dbg(xpc_chan, "notify->func() called, notify=0x%p, "
1076 "msg_number=%ld, partid=%d, channel=%d\n",
1077 (void *) notify, get, ch->partid, ch->number);
1078
1079 notify->func(reason, ch->partid, ch->number,
1080 notify->key);
1081
1082 dev_dbg(xpc_chan, "notify->func() returned, "
1083 "notify=0x%p, msg_number=%ld, partid=%d, "
1084 "channel=%d\n", (void *) notify, get,
1085 ch->partid, ch->number);
1086 }
1087 }
1088}
1089
1090
1091/*
1092 * Clear some of the msg flags in the local message queue.
1093 */
1094static inline void
1095xpc_clear_local_msgqueue_flags(struct xpc_channel *ch)
1096{
1097 struct xpc_msg *msg;
1098 s64 get;
1099
1100
1101 get = ch->w_remote_GP.get;
1102 do {
1103 msg = (struct xpc_msg *) ((u64) ch->local_msgqueue +
1104 (get % ch->local_nentries) * ch->msg_size);
1105 msg->flags = 0;
1106 } while (++get < (volatile s64) ch->remote_GP.get);
1107}
1108
1109
1110/*
1111 * Clear some of the msg flags in the remote message queue.
1112 */
1113static inline void
1114xpc_clear_remote_msgqueue_flags(struct xpc_channel *ch)
1115{
1116 struct xpc_msg *msg;
1117 s64 put;
1118
1119
1120 put = ch->w_remote_GP.put;
1121 do {
1122 msg = (struct xpc_msg *) ((u64) ch->remote_msgqueue +
1123 (put % ch->remote_nentries) * ch->msg_size);
1124 msg->flags = 0;
1125 } while (++put < (volatile s64) ch->remote_GP.put);
1126}
1127
1128
1129static void
1130xpc_process_msg_IPI(struct xpc_partition *part, int ch_number)
1131{
1132 struct xpc_channel *ch = &part->channels[ch_number];
1133 int nmsgs_sent;
1134
1135
1136 ch->remote_GP = part->remote_GPs[ch_number];
1137
1138
1139 /* See what, if anything, has changed for each connected channel */
1140
1141 xpc_msgqueue_ref(ch);
1142
1143 if (ch->w_remote_GP.get == ch->remote_GP.get &&
1144 ch->w_remote_GP.put == ch->remote_GP.put) {
1145 /* nothing changed since GPs were last pulled */
1146 xpc_msgqueue_deref(ch);
1147 return;
1148 }
1149
1150 if (!(ch->flags & XPC_C_CONNECTED)){
1151 xpc_msgqueue_deref(ch);
1152 return;
1153 }
1154
1155
1156 /*
1157 * First check to see if messages recently sent by us have been
1158 * received by the other side. (The remote GET value will have
1159 * changed since we last looked at it.)
1160 */
1161
1162 if (ch->w_remote_GP.get != ch->remote_GP.get) {
1163
1164 /*
1165 * We need to notify any senders that want to be notified
1166 * that their sent messages have been received by their
1167 * intended recipients. We need to do this before updating
1168 * w_remote_GP.get so that we don't allocate the same message
1169 * queue entries prematurely (see xpc_allocate_msg()).
1170 */
1171 if (atomic_read(&ch->n_to_notify) > 0) {
1172 /*
1173 * Notify senders that messages sent have been
1174 * received and delivered by the other side.
1175 */
1176 xpc_notify_senders(ch, xpcMsgDelivered,
1177 ch->remote_GP.get);
1178 }
1179
1180 /*
1181 * Clear msg->flags in previously sent messages, so that
1182 * they're ready for xpc_allocate_msg().
1183 */
1184 xpc_clear_local_msgqueue_flags(ch);
1185
1186 (volatile s64) ch->w_remote_GP.get = ch->remote_GP.get;
1187
1188 dev_dbg(xpc_chan, "w_remote_GP.get changed to %ld, partid=%d, "
1189 "channel=%d\n", ch->w_remote_GP.get, ch->partid,
1190 ch->number);
1191
1192 /*
1193 * If anyone was waiting for message queue entries to become
1194 * available, wake them up.
1195 */
1196 if (atomic_read(&ch->n_on_msg_allocate_wq) > 0) {
1197 wake_up(&ch->msg_allocate_wq);
1198 }
1199 }
1200
1201
1202 /*
1203 * Now check for newly sent messages by the other side. (The remote
1204 * PUT value will have changed since we last looked at it.)
1205 */
1206
1207 if (ch->w_remote_GP.put != ch->remote_GP.put) {
1208 /*
1209 * Clear msg->flags in previously received messages, so that
1210 * they're ready for xpc_get_deliverable_msg().
1211 */
1212 xpc_clear_remote_msgqueue_flags(ch);
1213
1214 (volatile s64) ch->w_remote_GP.put = ch->remote_GP.put;
1215
1216 dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, "
1217 "channel=%d\n", ch->w_remote_GP.put, ch->partid,
1218 ch->number);
1219
1220 nmsgs_sent = ch->w_remote_GP.put - ch->w_local_GP.get;
1221 if (nmsgs_sent > 0) {
1222 dev_dbg(xpc_chan, "msgs waiting to be copied and "
1223 "delivered=%d, partid=%d, channel=%d\n",
1224 nmsgs_sent, ch->partid, ch->number);
1225
1226 if (ch->flags & XPC_C_CONNECTCALLOUT) {
1227 xpc_activate_kthreads(ch, nmsgs_sent);
1228 }
1229 }
1230 }
1231
1232 xpc_msgqueue_deref(ch);
1233}
1234
1235
1236void
1237xpc_process_channel_activity(struct xpc_partition *part)
1238{
1239 unsigned long irq_flags;
1240 u64 IPI_amo, IPI_flags;
1241 struct xpc_channel *ch;
1242 int ch_number;
1243
1244
1245 IPI_amo = xpc_get_IPI_flags(part);
1246
1247 /*
1248 * Initiate channel connections for registered channels.
1249 *
1250 * For each connected channel that has pending messages activate idle
1251 * kthreads and/or create new kthreads as needed.
1252 */
1253
1254 for (ch_number = 0; ch_number < part->nchannels; ch_number++) {
1255 ch = &part->channels[ch_number];
1256
1257
1258 /*
1259 * Process any open or close related IPI flags, and then deal
1260 * with connecting or disconnecting the channel as required.
1261 */
1262
1263 IPI_flags = XPC_GET_IPI_FLAGS(IPI_amo, ch_number);
1264
1265 if (XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(IPI_flags)) {
1266 xpc_process_openclose_IPI(part, ch_number, IPI_flags);
1267 }
1268
1269
1270 if (ch->flags & XPC_C_DISCONNECTING) {
1271 spin_lock_irqsave(&ch->lock, irq_flags);
1272 xpc_process_disconnect(ch, &irq_flags);
1273 spin_unlock_irqrestore(&ch->lock, irq_flags);
1274 continue;
1275 }
1276
1277 if (part->act_state == XPC_P_DEACTIVATING) {
1278 continue;
1279 }
1280
1281 if (!(ch->flags & XPC_C_CONNECTED)) {
1282 if (!(ch->flags & XPC_C_OPENREQUEST)) {
1283 DBUG_ON(ch->flags & XPC_C_SETUP);
1284 (void) xpc_connect_channel(ch);
1285 } else {
1286 spin_lock_irqsave(&ch->lock, irq_flags);
1287 xpc_process_connect(ch, &irq_flags);
1288 spin_unlock_irqrestore(&ch->lock, irq_flags);
1289 }
1290 continue;
1291 }
1292
1293
1294 /*
1295 * Process any message related IPI flags, this may involve the
1296 * activation of kthreads to deliver any pending messages sent
1297 * from the other partition.
1298 */
1299
1300 if (XPC_ANY_MSG_IPI_FLAGS_SET(IPI_flags)) {
1301 xpc_process_msg_IPI(part, ch_number);
1302 }
1303 }
1304}
1305
1306
1307/*
1308 * XPC's heartbeat code calls this function to inform XPC that a partition has
1309 * gone down. XPC responds by tearing down the XPartition Communication
1310 * infrastructure used for the just downed partition.
1311 *
1312 * XPC's heartbeat code will never call this function and xpc_partition_up()
1313 * at the same time. Nor will it ever make multiple calls to either function
1314 * at the same time.
1315 */
1316void
1317xpc_partition_down(struct xpc_partition *part, enum xpc_retval reason)
1318{
1319 unsigned long irq_flags;
1320 int ch_number;
1321 struct xpc_channel *ch;
1322
1323
1324 dev_dbg(xpc_chan, "deactivating partition %d, reason=%d\n",
1325 XPC_PARTID(part), reason);
1326
1327 if (!xpc_part_ref(part)) {
1328 /* infrastructure for this partition isn't currently set up */
1329 return;
1330 }
1331
1332
1333 /* disconnect all channels associated with the downed partition */
1334
1335 for (ch_number = 0; ch_number < part->nchannels; ch_number++) {
1336 ch = &part->channels[ch_number];
1337
1338
1339 xpc_msgqueue_ref(ch);
1340 spin_lock_irqsave(&ch->lock, irq_flags);
1341
1342 XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags);
1343
1344 spin_unlock_irqrestore(&ch->lock, irq_flags);
1345 xpc_msgqueue_deref(ch);
1346 }
1347
1348 xpc_wakeup_channel_mgr(part);
1349
1350 xpc_part_deref(part);
1351}
1352
1353
1354/*
1355 * Teardown the infrastructure necessary to support XPartition Communication
1356 * between the specified remote partition and the local one.
1357 */
1358void
1359xpc_teardown_infrastructure(struct xpc_partition *part)
1360{
1361 partid_t partid = XPC_PARTID(part);
1362
1363
1364 /*
1365 * We start off by making this partition inaccessible to local
1366 * processes by marking it as no longer setup. Then we make it
1367 * inaccessible to remote processes by clearing the XPC per partition
1368 * specific variable's magic # (which indicates that these variables
1369 * are no longer valid) and by ignoring all XPC notify IPIs sent to
1370 * this partition.
1371 */
1372
1373 DBUG_ON(atomic_read(&part->nchannels_active) != 0);
1374 DBUG_ON(part->setup_state != XPC_P_SETUP);
1375 part->setup_state = XPC_P_WTEARDOWN;
1376
1377 xpc_vars_part[partid].magic = 0;
1378
1379
1380 free_irq(SGI_XPC_NOTIFY, (void *) (u64) partid);
1381
1382
1383 /*
1384 * Before proceding with the teardown we have to wait until all
1385 * existing references cease.
1386 */
1387 wait_event(part->teardown_wq, (atomic_read(&part->references) == 0));
1388
1389
1390 /* now we can begin tearing down the infrastructure */
1391
1392 part->setup_state = XPC_P_TORNDOWN;
1393
1394 /* in case we've still got outstanding timers registered... */
1395 del_timer_sync(&part->dropped_IPI_timer);
1396
1397 kfree(part->remote_openclose_args_base);
1398 part->remote_openclose_args = NULL;
1399 kfree(part->local_openclose_args_base);
1400 part->local_openclose_args = NULL;
1401 kfree(part->remote_GPs_base);
1402 part->remote_GPs = NULL;
1403 kfree(part->local_GPs_base);
1404 part->local_GPs = NULL;
1405 kfree(part->channels);
1406 part->channels = NULL;
1407 part->local_IPI_amo_va = NULL;
1408}
1409
1410
1411/*
1412 * Called by XP at the time of channel connection registration to cause
1413 * XPC to establish connections to all currently active partitions.
1414 */
1415void
1416xpc_initiate_connect(int ch_number)
1417{
1418 partid_t partid;
1419 struct xpc_partition *part;
1420 struct xpc_channel *ch;
1421
1422
1423 DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS);
1424
1425 for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
1426 part = &xpc_partitions[partid];
1427
1428 if (xpc_part_ref(part)) {
1429 ch = &part->channels[ch_number];
1430
1431 if (!(ch->flags & XPC_C_DISCONNECTING)) {
1432 DBUG_ON(ch->flags & XPC_C_OPENREQUEST);
1433 DBUG_ON(ch->flags & XPC_C_CONNECTED);
1434 DBUG_ON(ch->flags & XPC_C_SETUP);
1435
1436 /*
1437 * Initiate the establishment of a connection
1438 * on the newly registered channel to the
1439 * remote partition.
1440 */
1441 xpc_wakeup_channel_mgr(part);
1442 }
1443
1444 xpc_part_deref(part);
1445 }
1446 }
1447}
1448
1449
1450void
1451xpc_connected_callout(struct xpc_channel *ch)
1452{
1453 unsigned long irq_flags;
1454
1455
1456 /* let the registerer know that a connection has been established */
1457
1458 if (ch->func != NULL) {
1459 dev_dbg(xpc_chan, "ch->func() called, reason=xpcConnected, "
1460 "partid=%d, channel=%d\n", ch->partid, ch->number);
1461
1462 ch->func(xpcConnected, ch->partid, ch->number,
1463 (void *) (u64) ch->local_nentries, ch->key);
1464
1465 dev_dbg(xpc_chan, "ch->func() returned, reason=xpcConnected, "
1466 "partid=%d, channel=%d\n", ch->partid, ch->number);
1467 }
1468
1469 spin_lock_irqsave(&ch->lock, irq_flags);
1470 ch->flags |= XPC_C_CONNECTCALLOUT;
1471 spin_unlock_irqrestore(&ch->lock, irq_flags);
1472}
1473
1474
1475/*
1476 * Called by XP at the time of channel connection unregistration to cause
1477 * XPC to teardown all current connections for the specified channel.
1478 *
1479 * Before returning xpc_initiate_disconnect() will wait until all connections
1480 * on the specified channel have been closed/torndown. So the caller can be
1481 * assured that they will not be receiving any more callouts from XPC to the
1482 * function they registered via xpc_connect().
1483 *
1484 * Arguments:
1485 *
1486 * ch_number - channel # to unregister.
1487 */
1488void
1489xpc_initiate_disconnect(int ch_number)
1490{
1491 unsigned long irq_flags;
1492 partid_t partid;
1493 struct xpc_partition *part;
1494 struct xpc_channel *ch;
1495
1496
1497 DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS);
1498
1499 /* initiate the channel disconnect for every active partition */
1500 for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
1501 part = &xpc_partitions[partid];
1502
1503 if (xpc_part_ref(part)) {
1504 ch = &part->channels[ch_number];
1505 xpc_msgqueue_ref(ch);
1506
1507 spin_lock_irqsave(&ch->lock, irq_flags);
1508
1509 XPC_DISCONNECT_CHANNEL(ch, xpcUnregistering,
1510 &irq_flags);
1511
1512 spin_unlock_irqrestore(&ch->lock, irq_flags);
1513
1514 xpc_msgqueue_deref(ch);
1515 xpc_part_deref(part);
1516 }
1517 }
1518
1519 xpc_disconnect_wait(ch_number);
1520}
1521
1522
1523/*
1524 * To disconnect a channel, and reflect it back to all who may be waiting.
1525 *
1526 * >>> An OPEN is not allowed until XPC_C_DISCONNECTING is cleared by
1527 * >>> xpc_free_msgqueues().
1528 *
1529 * THE CHANNEL IS TO BE LOCKED BY THE CALLER AND WILL REMAIN LOCKED UPON RETURN.
1530 */
1531void
1532xpc_disconnect_channel(const int line, struct xpc_channel *ch,
1533 enum xpc_retval reason, unsigned long *irq_flags)
1534{
1535 u32 flags;
1536
1537
1538 DBUG_ON(!spin_is_locked(&ch->lock));
1539
1540 if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) {
1541 return;
1542 }
1543 DBUG_ON(!(ch->flags & (XPC_C_CONNECTING | XPC_C_CONNECTED)));
1544
1545 dev_dbg(xpc_chan, "reason=%d, line=%d, partid=%d, channel=%d\n",
1546 reason, line, ch->partid, ch->number);
1547
1548 XPC_SET_REASON(ch, reason, line);
1549
1550 flags = ch->flags;
1551 /* some of these may not have been set */
1552 ch->flags &= ~(XPC_C_OPENREQUEST | XPC_C_OPENREPLY |
1553 XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY |
1554 XPC_C_CONNECTING | XPC_C_CONNECTED);
1555
1556 ch->flags |= (XPC_C_CLOSEREQUEST | XPC_C_DISCONNECTING);
1557 xpc_IPI_send_closerequest(ch, irq_flags);
1558
1559 if (flags & XPC_C_CONNECTED) {
1560 ch->flags |= XPC_C_WASCONNECTED;
1561 }
1562
1563 if (atomic_read(&ch->kthreads_idle) > 0) {
1564 /* wake all idle kthreads so they can exit */
1565 wake_up_all(&ch->idle_wq);
1566 }
1567
1568 spin_unlock_irqrestore(&ch->lock, *irq_flags);
1569
1570
1571 /* wake those waiting to allocate an entry from the local msg queue */
1572
1573 if (atomic_read(&ch->n_on_msg_allocate_wq) > 0) {
1574 wake_up(&ch->msg_allocate_wq);
1575 }
1576
1577 /* wake those waiting for notify completion */
1578
1579 if (atomic_read(&ch->n_to_notify) > 0) {
1580 xpc_notify_senders(ch, reason, ch->w_local_GP.put);
1581 }
1582
1583 spin_lock_irqsave(&ch->lock, *irq_flags);
1584}
1585
1586
1587void
1588xpc_disconnected_callout(struct xpc_channel *ch)
1589{
1590 /*
1591 * Let the channel's registerer know that the channel is now
1592 * disconnected. We don't want to do this if the registerer was never
1593 * informed of a connection being made, unless the disconnect was for
1594 * abnormal reasons.
1595 */
1596
1597 if (ch->func != NULL) {
1598 dev_dbg(xpc_chan, "ch->func() called, reason=%d, partid=%d, "
1599 "channel=%d\n", ch->reason, ch->partid, ch->number);
1600
1601 ch->func(ch->reason, ch->partid, ch->number, NULL, ch->key);
1602
1603 dev_dbg(xpc_chan, "ch->func() returned, reason=%d, partid=%d, "
1604 "channel=%d\n", ch->reason, ch->partid, ch->number);
1605 }
1606}
1607
1608
1609/*
1610 * Wait for a message entry to become available for the specified channel,
1611 * but don't wait any longer than 1 jiffy.
1612 */
1613static enum xpc_retval
1614xpc_allocate_msg_wait(struct xpc_channel *ch)
1615{
1616 enum xpc_retval ret;
1617
1618
1619 if (ch->flags & XPC_C_DISCONNECTING) {
1620 DBUG_ON(ch->reason == xpcInterrupted); // >>> Is this true?
1621 return ch->reason;
1622 }
1623
1624 atomic_inc(&ch->n_on_msg_allocate_wq);
1625 ret = interruptible_sleep_on_timeout(&ch->msg_allocate_wq, 1);
1626 atomic_dec(&ch->n_on_msg_allocate_wq);
1627
1628 if (ch->flags & XPC_C_DISCONNECTING) {
1629 ret = ch->reason;
1630 DBUG_ON(ch->reason == xpcInterrupted); // >>> Is this true?
1631 } else if (ret == 0) {
1632 ret = xpcTimeout;
1633 } else {
1634 ret = xpcInterrupted;
1635 }
1636
1637 return ret;
1638}
1639
1640
1641/*
1642 * Allocate an entry for a message from the message queue associated with the
1643 * specified channel.
1644 */
1645static enum xpc_retval
1646xpc_allocate_msg(struct xpc_channel *ch, u32 flags,
1647 struct xpc_msg **address_of_msg)
1648{
1649 struct xpc_msg *msg;
1650 enum xpc_retval ret;
1651 s64 put;
1652
1653
1654 /* this reference will be dropped in xpc_send_msg() */
1655 xpc_msgqueue_ref(ch);
1656
1657 if (ch->flags & XPC_C_DISCONNECTING) {
1658 xpc_msgqueue_deref(ch);
1659 return ch->reason;
1660 }
1661 if (!(ch->flags & XPC_C_CONNECTED)) {
1662 xpc_msgqueue_deref(ch);
1663 return xpcNotConnected;
1664 }
1665
1666
1667 /*
1668 * Get the next available message entry from the local message queue.
1669 * If none are available, we'll make sure that we grab the latest
1670 * GP values.
1671 */
1672 ret = xpcTimeout;
1673
1674 while (1) {
1675
1676 put = (volatile s64) ch->w_local_GP.put;
1677 if (put - (volatile s64) ch->w_remote_GP.get <
1678 ch->local_nentries) {
1679
1680 /* There are available message entries. We need to try
1681 * to secure one for ourselves. We'll do this by trying
1682 * to increment w_local_GP.put as long as someone else
1683 * doesn't beat us to it. If they do, we'll have to
1684 * try again.
1685 */
1686 if (cmpxchg(&ch->w_local_GP.put, put, put + 1) ==
1687 put) {
1688 /* we got the entry referenced by put */
1689 break;
1690 }
1691 continue; /* try again */
1692 }
1693
1694
1695 /*
1696 * There aren't any available msg entries at this time.
1697 *
1698 * In waiting for a message entry to become available,
1699 * we set a timeout in case the other side is not
1700 * sending completion IPIs. This lets us fake an IPI
1701 * that will cause the IPI handler to fetch the latest
1702 * GP values as if an IPI was sent by the other side.
1703 */
1704 if (ret == xpcTimeout) {
1705 xpc_IPI_send_local_msgrequest(ch);
1706 }
1707
1708 if (flags & XPC_NOWAIT) {
1709 xpc_msgqueue_deref(ch);
1710 return xpcNoWait;
1711 }
1712
1713 ret = xpc_allocate_msg_wait(ch);
1714 if (ret != xpcInterrupted && ret != xpcTimeout) {
1715 xpc_msgqueue_deref(ch);
1716 return ret;
1717 }
1718 }
1719
1720
1721 /* get the message's address and initialize it */
1722 msg = (struct xpc_msg *) ((u64) ch->local_msgqueue +
1723 (put % ch->local_nentries) * ch->msg_size);
1724
1725
1726 DBUG_ON(msg->flags != 0);
1727 msg->number = put;
1728
1729 dev_dbg(xpc_chan, "w_local_GP.put changed to %ld; msg=0x%p, "
1730 "msg_number=%ld, partid=%d, channel=%d\n", put + 1,
1731 (void *) msg, msg->number, ch->partid, ch->number);
1732
1733 *address_of_msg = msg;
1734
1735 return xpcSuccess;
1736}
1737
1738
1739/*
1740 * Allocate an entry for a message from the message queue associated with the
1741 * specified channel. NOTE that this routine can sleep waiting for a message
1742 * entry to become available. To not sleep, pass in the XPC_NOWAIT flag.
1743 *
1744 * Arguments:
1745 *
1746 * partid - ID of partition to which the channel is connected.
1747 * ch_number - channel #.
1748 * flags - see xpc.h for valid flags.
1749 * payload - address of the allocated payload area pointer (filled in on
1750 * return) in which the user-defined message is constructed.
1751 */
1752enum xpc_retval
1753xpc_initiate_allocate(partid_t partid, int ch_number, u32 flags, void **payload)
1754{
1755 struct xpc_partition *part = &xpc_partitions[partid];
1756 enum xpc_retval ret = xpcUnknownReason;
1757 struct xpc_msg *msg;
1758
1759
1760 DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
1761 DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
1762
1763 *payload = NULL;
1764
1765 if (xpc_part_ref(part)) {
1766 ret = xpc_allocate_msg(&part->channels[ch_number], flags, &msg);
1767 xpc_part_deref(part);
1768
1769 if (msg != NULL) {
1770 *payload = &msg->payload;
1771 }
1772 }
1773
1774 return ret;
1775}
1776
1777
1778/*
1779 * Now we actually send the messages that are ready to be sent by advancing
1780 * the local message queue's Put value and then send an IPI to the recipient
1781 * partition.
1782 */
1783static void
1784xpc_send_msgs(struct xpc_channel *ch, s64 initial_put)
1785{
1786 struct xpc_msg *msg;
1787 s64 put = initial_put + 1;
1788 int send_IPI = 0;
1789
1790
1791 while (1) {
1792
1793 while (1) {
1794 if (put == (volatile s64) ch->w_local_GP.put) {
1795 break;
1796 }
1797
1798 msg = (struct xpc_msg *) ((u64) ch->local_msgqueue +
1799 (put % ch->local_nentries) * ch->msg_size);
1800
1801 if (!(msg->flags & XPC_M_READY)) {
1802 break;
1803 }
1804
1805 put++;
1806 }
1807
1808 if (put == initial_put) {
1809 /* nothing's changed */
1810 break;
1811 }
1812
1813 if (cmpxchg_rel(&ch->local_GP->put, initial_put, put) !=
1814 initial_put) {
1815 /* someone else beat us to it */
1816 DBUG_ON((volatile s64) ch->local_GP->put < initial_put);
1817 break;
1818 }
1819
1820 /* we just set the new value of local_GP->put */
1821
1822 dev_dbg(xpc_chan, "local_GP->put changed to %ld, partid=%d, "
1823 "channel=%d\n", put, ch->partid, ch->number);
1824
1825 send_IPI = 1;
1826
1827 /*
1828 * We need to ensure that the message referenced by
1829 * local_GP->put is not XPC_M_READY or that local_GP->put
1830 * equals w_local_GP.put, so we'll go have a look.
1831 */
1832 initial_put = put;
1833 }
1834
1835 if (send_IPI) {
1836 xpc_IPI_send_msgrequest(ch);
1837 }
1838}
1839
1840
1841/*
1842 * Common code that does the actual sending of the message by advancing the
1843 * local message queue's Put value and sends an IPI to the partition the
1844 * message is being sent to.
1845 */
1846static enum xpc_retval
1847xpc_send_msg(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type,
1848 xpc_notify_func func, void *key)
1849{
1850 enum xpc_retval ret = xpcSuccess;
1851 struct xpc_notify *notify = NULL; // >>> to keep the compiler happy!!
1852 s64 put, msg_number = msg->number;
1853
1854
1855 DBUG_ON(notify_type == XPC_N_CALL && func == NULL);
1856 DBUG_ON((((u64) msg - (u64) ch->local_msgqueue) / ch->msg_size) !=
1857 msg_number % ch->local_nentries);
1858 DBUG_ON(msg->flags & XPC_M_READY);
1859
1860 if (ch->flags & XPC_C_DISCONNECTING) {
1861 /* drop the reference grabbed in xpc_allocate_msg() */
1862 xpc_msgqueue_deref(ch);
1863 return ch->reason;
1864 }
1865
1866 if (notify_type != 0) {
1867 /*
1868 * Tell the remote side to send an ACK interrupt when the
1869 * message has been delivered.
1870 */
1871 msg->flags |= XPC_M_INTERRUPT;
1872
1873 atomic_inc(&ch->n_to_notify);
1874
1875 notify = &ch->notify_queue[msg_number % ch->local_nentries];
1876 notify->func = func;
1877 notify->key = key;
1878 (volatile u8) notify->type = notify_type;
1879
1880 // >>> is a mb() needed here?
1881
1882 if (ch->flags & XPC_C_DISCONNECTING) {
1883 /*
1884 * An error occurred between our last error check and
1885 * this one. We will try to clear the type field from
1886 * the notify entry. If we succeed then
1887 * xpc_disconnect_channel() didn't already process
1888 * the notify entry.
1889 */
1890 if (cmpxchg(&notify->type, notify_type, 0) ==
1891 notify_type) {
1892 atomic_dec(&ch->n_to_notify);
1893 ret = ch->reason;
1894 }
1895
1896 /* drop the reference grabbed in xpc_allocate_msg() */
1897 xpc_msgqueue_deref(ch);
1898 return ret;
1899 }
1900 }
1901
1902 msg->flags |= XPC_M_READY;
1903
1904 /*
1905 * The preceding store of msg->flags must occur before the following
1906 * load of ch->local_GP->put.
1907 */
1908 mb();
1909
1910 /* see if the message is next in line to be sent, if so send it */
1911
1912 put = ch->local_GP->put;
1913 if (put == msg_number) {
1914 xpc_send_msgs(ch, put);
1915 }
1916
1917 /* drop the reference grabbed in xpc_allocate_msg() */
1918 xpc_msgqueue_deref(ch);
1919 return ret;
1920}
1921
1922
1923/*
1924 * Send a message previously allocated using xpc_initiate_allocate() on the
1925 * specified channel connected to the specified partition.
1926 *
1927 * This routine will not wait for the message to be received, nor will
1928 * notification be given when it does happen. Once this routine has returned
1929 * the message entry allocated via xpc_initiate_allocate() is no longer
1930 * accessable to the caller.
1931 *
1932 * This routine, although called by users, does not call xpc_part_ref() to
1933 * ensure that the partition infrastructure is in place. It relies on the
1934 * fact that we called xpc_msgqueue_ref() in xpc_allocate_msg().
1935 *
1936 * Arguments:
1937 *
1938 * partid - ID of partition to which the channel is connected.
1939 * ch_number - channel # to send message on.
1940 * payload - pointer to the payload area allocated via
1941 * xpc_initiate_allocate().
1942 */
1943enum xpc_retval
1944xpc_initiate_send(partid_t partid, int ch_number, void *payload)
1945{
1946 struct xpc_partition *part = &xpc_partitions[partid];
1947 struct xpc_msg *msg = XPC_MSG_ADDRESS(payload);
1948 enum xpc_retval ret;
1949
1950
1951 dev_dbg(xpc_chan, "msg=0x%p, partid=%d, channel=%d\n", (void *) msg,
1952 partid, ch_number);
1953
1954 DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
1955 DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
1956 DBUG_ON(msg == NULL);
1957
1958 ret = xpc_send_msg(&part->channels[ch_number], msg, 0, NULL, NULL);
1959
1960 return ret;
1961}
1962
1963
1964/*
1965 * Send a message previously allocated using xpc_initiate_allocate on the
1966 * specified channel connected to the specified partition.
1967 *
1968 * This routine will not wait for the message to be sent. Once this routine
1969 * has returned the message entry allocated via xpc_initiate_allocate() is no
1970 * longer accessable to the caller.
1971 *
1972 * Once the remote end of the channel has received the message, the function
1973 * passed as an argument to xpc_initiate_send_notify() will be called. This
1974 * allows the sender to free up or re-use any buffers referenced by the
1975 * message, but does NOT mean the message has been processed at the remote
1976 * end by a receiver.
1977 *
1978 * If this routine returns an error, the caller's function will NOT be called.
1979 *
1980 * This routine, although called by users, does not call xpc_part_ref() to
1981 * ensure that the partition infrastructure is in place. It relies on the
1982 * fact that we called xpc_msgqueue_ref() in xpc_allocate_msg().
1983 *
1984 * Arguments:
1985 *
1986 * partid - ID of partition to which the channel is connected.
1987 * ch_number - channel # to send message on.
1988 * payload - pointer to the payload area allocated via
1989 * xpc_initiate_allocate().
1990 * func - function to call with asynchronous notification of message
1991 * receipt. THIS FUNCTION MUST BE NON-BLOCKING.
1992 * key - user-defined key to be passed to the function when it's called.
1993 */
1994enum xpc_retval
1995xpc_initiate_send_notify(partid_t partid, int ch_number, void *payload,
1996 xpc_notify_func func, void *key)
1997{
1998 struct xpc_partition *part = &xpc_partitions[partid];
1999 struct xpc_msg *msg = XPC_MSG_ADDRESS(payload);
2000 enum xpc_retval ret;
2001
2002
2003 dev_dbg(xpc_chan, "msg=0x%p, partid=%d, channel=%d\n", (void *) msg,
2004 partid, ch_number);
2005
2006 DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
2007 DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
2008 DBUG_ON(msg == NULL);
2009 DBUG_ON(func == NULL);
2010
2011 ret = xpc_send_msg(&part->channels[ch_number], msg, XPC_N_CALL,
2012 func, key);
2013 return ret;
2014}
2015
2016
2017static struct xpc_msg *
2018xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
2019{
2020 struct xpc_partition *part = &xpc_partitions[ch->partid];
2021 struct xpc_msg *remote_msg, *msg;
2022 u32 msg_index, nmsgs;
2023 u64 msg_offset;
2024 enum xpc_retval ret;
2025
2026
2027 if (down_interruptible(&ch->msg_to_pull_sema) != 0) {
2028 /* we were interrupted by a signal */
2029 return NULL;
2030 }
2031
2032 while (get >= ch->next_msg_to_pull) {
2033
2034 /* pull as many messages as are ready and able to be pulled */
2035
2036 msg_index = ch->next_msg_to_pull % ch->remote_nentries;
2037
2038 DBUG_ON(ch->next_msg_to_pull >=
2039 (volatile s64) ch->w_remote_GP.put);
2040 nmsgs = (volatile s64) ch->w_remote_GP.put -
2041 ch->next_msg_to_pull;
2042 if (msg_index + nmsgs > ch->remote_nentries) {
2043 /* ignore the ones that wrap the msg queue for now */
2044 nmsgs = ch->remote_nentries - msg_index;
2045 }
2046
2047 msg_offset = msg_index * ch->msg_size;
2048 msg = (struct xpc_msg *) ((u64) ch->remote_msgqueue +
2049 msg_offset);
2050 remote_msg = (struct xpc_msg *) (ch->remote_msgqueue_pa +
2051 msg_offset);
2052
2053 if ((ret = xpc_pull_remote_cachelines(part, msg, remote_msg,
2054 nmsgs * ch->msg_size)) != xpcSuccess) {
2055
2056 dev_dbg(xpc_chan, "failed to pull %d msgs starting with"
2057 " msg %ld from partition %d, channel=%d, "
2058 "ret=%d\n", nmsgs, ch->next_msg_to_pull,
2059 ch->partid, ch->number, ret);
2060
2061 XPC_DEACTIVATE_PARTITION(part, ret);
2062
2063 up(&ch->msg_to_pull_sema);
2064 return NULL;
2065 }
2066
2067 mb(); /* >>> this may not be needed, we're not sure */
2068
2069 ch->next_msg_to_pull += nmsgs;
2070 }
2071
2072 up(&ch->msg_to_pull_sema);
2073
2074 /* return the message we were looking for */
2075 msg_offset = (get % ch->remote_nentries) * ch->msg_size;
2076 msg = (struct xpc_msg *) ((u64) ch->remote_msgqueue + msg_offset);
2077
2078 return msg;
2079}
2080
2081
2082/*
2083 * Get a message to be delivered.
2084 */
2085static struct xpc_msg *
2086xpc_get_deliverable_msg(struct xpc_channel *ch)
2087{
2088 struct xpc_msg *msg = NULL;
2089 s64 get;
2090
2091
2092 do {
2093 if ((volatile u32) ch->flags & XPC_C_DISCONNECTING) {
2094 break;
2095 }
2096
2097 get = (volatile s64) ch->w_local_GP.get;
2098 if (get == (volatile s64) ch->w_remote_GP.put) {
2099 break;
2100 }
2101
2102 /* There are messages waiting to be pulled and delivered.
2103 * We need to try to secure one for ourselves. We'll do this
2104 * by trying to increment w_local_GP.get and hope that no one
2105 * else beats us to it. If they do, we'll we'll simply have
2106 * to try again for the next one.
2107 */
2108
2109 if (cmpxchg(&ch->w_local_GP.get, get, get + 1) == get) {
2110 /* we got the entry referenced by get */
2111
2112 dev_dbg(xpc_chan, "w_local_GP.get changed to %ld, "
2113 "partid=%d, channel=%d\n", get + 1,
2114 ch->partid, ch->number);
2115
2116 /* pull the message from the remote partition */
2117
2118 msg = xpc_pull_remote_msg(ch, get);
2119
2120 DBUG_ON(msg != NULL && msg->number != get);
2121 DBUG_ON(msg != NULL && (msg->flags & XPC_M_DONE));
2122 DBUG_ON(msg != NULL && !(msg->flags & XPC_M_READY));
2123
2124 break;
2125 }
2126
2127 } while (1);
2128
2129 return msg;
2130}
2131
2132
2133/*
2134 * Deliver a message to its intended recipient.
2135 */
2136void
2137xpc_deliver_msg(struct xpc_channel *ch)
2138{
2139 struct xpc_msg *msg;
2140
2141
2142 if ((msg = xpc_get_deliverable_msg(ch)) != NULL) {
2143
2144 /*
2145 * This ref is taken to protect the payload itself from being
2146 * freed before the user is finished with it, which the user
2147 * indicates by calling xpc_initiate_received().
2148 */
2149 xpc_msgqueue_ref(ch);
2150
2151 atomic_inc(&ch->kthreads_active);
2152
2153 if (ch->func != NULL) {
2154 dev_dbg(xpc_chan, "ch->func() called, msg=0x%p, "
2155 "msg_number=%ld, partid=%d, channel=%d\n",
2156 (void *) msg, msg->number, ch->partid,
2157 ch->number);
2158
2159 /* deliver the message to its intended recipient */
2160 ch->func(xpcMsgReceived, ch->partid, ch->number,
2161 &msg->payload, ch->key);
2162
2163 dev_dbg(xpc_chan, "ch->func() returned, msg=0x%p, "
2164 "msg_number=%ld, partid=%d, channel=%d\n",
2165 (void *) msg, msg->number, ch->partid,
2166 ch->number);
2167 }
2168
2169 atomic_dec(&ch->kthreads_active);
2170 }
2171}
2172
2173
2174/*
2175 * Now we actually acknowledge the messages that have been delivered and ack'd
2176 * by advancing the cached remote message queue's Get value and if requested
2177 * send an IPI to the message sender's partition.
2178 */
2179static void
2180xpc_acknowledge_msgs(struct xpc_channel *ch, s64 initial_get, u8 msg_flags)
2181{
2182 struct xpc_msg *msg;
2183 s64 get = initial_get + 1;
2184 int send_IPI = 0;
2185
2186
2187 while (1) {
2188
2189 while (1) {
2190 if (get == (volatile s64) ch->w_local_GP.get) {
2191 break;
2192 }
2193
2194 msg = (struct xpc_msg *) ((u64) ch->remote_msgqueue +
2195 (get % ch->remote_nentries) * ch->msg_size);
2196
2197 if (!(msg->flags & XPC_M_DONE)) {
2198 break;
2199 }
2200
2201 msg_flags |= msg->flags;
2202 get++;
2203 }
2204
2205 if (get == initial_get) {
2206 /* nothing's changed */
2207 break;
2208 }
2209
2210 if (cmpxchg_rel(&ch->local_GP->get, initial_get, get) !=
2211 initial_get) {
2212 /* someone else beat us to it */
2213 DBUG_ON((volatile s64) ch->local_GP->get <=
2214 initial_get);
2215 break;
2216 }
2217
2218 /* we just set the new value of local_GP->get */
2219
2220 dev_dbg(xpc_chan, "local_GP->get changed to %ld, partid=%d, "
2221 "channel=%d\n", get, ch->partid, ch->number);
2222
2223 send_IPI = (msg_flags & XPC_M_INTERRUPT);
2224
2225 /*
2226 * We need to ensure that the message referenced by
2227 * local_GP->get is not XPC_M_DONE or that local_GP->get
2228 * equals w_local_GP.get, so we'll go have a look.
2229 */
2230 initial_get = get;
2231 }
2232
2233 if (send_IPI) {
2234 xpc_IPI_send_msgrequest(ch);
2235 }
2236}
2237
2238
2239/*
2240 * Acknowledge receipt of a delivered message.
2241 *
2242 * If a message has XPC_M_INTERRUPT set, send an interrupt to the partition
2243 * that sent the message.
2244 *
2245 * This function, although called by users, does not call xpc_part_ref() to
2246 * ensure that the partition infrastructure is in place. It relies on the
2247 * fact that we called xpc_msgqueue_ref() in xpc_deliver_msg().
2248 *
2249 * Arguments:
2250 *
2251 * partid - ID of partition to which the channel is connected.
2252 * ch_number - channel # message received on.
2253 * payload - pointer to the payload area allocated via
2254 * xpc_initiate_allocate().
2255 */
2256void
2257xpc_initiate_received(partid_t partid, int ch_number, void *payload)
2258{
2259 struct xpc_partition *part = &xpc_partitions[partid];
2260 struct xpc_channel *ch;
2261 struct xpc_msg *msg = XPC_MSG_ADDRESS(payload);
2262 s64 get, msg_number = msg->number;
2263
2264
2265 DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
2266 DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
2267
2268 ch = &part->channels[ch_number];
2269
2270 dev_dbg(xpc_chan, "msg=0x%p, msg_number=%ld, partid=%d, channel=%d\n",
2271 (void *) msg, msg_number, ch->partid, ch->number);
2272
2273 DBUG_ON((((u64) msg - (u64) ch->remote_msgqueue) / ch->msg_size) !=
2274 msg_number % ch->remote_nentries);
2275 DBUG_ON(msg->flags & XPC_M_DONE);
2276
2277 msg->flags |= XPC_M_DONE;
2278
2279 /*
2280 * The preceding store of msg->flags must occur before the following
2281 * load of ch->local_GP->get.
2282 */
2283 mb();
2284
2285 /*
2286 * See if this message is next in line to be acknowledged as having
2287 * been delivered.
2288 */
2289 get = ch->local_GP->get;
2290 if (get == msg_number) {
2291 xpc_acknowledge_msgs(ch, get, msg->flags);
2292 }
2293
2294 /* the call to xpc_msgqueue_ref() was done by xpc_deliver_msg() */
2295 xpc_msgqueue_deref(ch);
2296}
2297
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
new file mode 100644
index 000000000000..177ddb748ebe
--- /dev/null
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -0,0 +1,1064 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved.
7 */
8
9
10/*
11 * Cross Partition Communication (XPC) support - standard version.
12 *
13 * XPC provides a message passing capability that crosses partition
14 * boundaries. This module is made up of two parts:
15 *
16 * partition This part detects the presence/absence of other
17 * partitions. It provides a heartbeat and monitors
18 * the heartbeats of other partitions.
19 *
20 * channel This part manages the channels and sends/receives
21 * messages across them to/from other partitions.
22 *
23 * There are a couple of additional functions residing in XP, which
24 * provide an interface to XPC for its users.
25 *
26 *
27 * Caveats:
28 *
29 * . We currently have no way to determine which nasid an IPI came
30 * from. Thus, xpc_IPI_send() does a remote AMO write followed by
31 * an IPI. The AMO indicates where data is to be pulled from, so
32 * after the IPI arrives, the remote partition checks the AMO word.
33 * The IPI can actually arrive before the AMO however, so other code
34 * must periodically check for this case. Also, remote AMO operations
35 * do not reliably time out. Thus we do a remote PIO read solely to
36 * know whether the remote partition is down and whether we should
37 * stop sending IPIs to it. This remote PIO read operation is set up
38 * in a special nofault region so SAL knows to ignore (and cleanup)
39 * any errors due to the remote AMO write, PIO read, and/or PIO
40 * write operations.
41 *
42 * If/when new hardware solves this IPI problem, we should abandon
43 * the current approach.
44 *
45 */
46
47
48#include <linux/kernel.h>
49#include <linux/module.h>
50#include <linux/init.h>
51#include <linux/sched.h>
52#include <linux/syscalls.h>
53#include <linux/cache.h>
54#include <linux/interrupt.h>
55#include <linux/slab.h>
56#include <asm/sn/intr.h>
57#include <asm/sn/sn_sal.h>
58#include <asm/uaccess.h>
59#include "xpc.h"
60
61
62/* define two XPC debug device structures to be used with dev_dbg() et al */
63
64struct device_driver xpc_dbg_name = {
65 .name = "xpc"
66};
67
68struct device xpc_part_dbg_subname = {
69 .bus_id = {0}, /* set to "part" at xpc_init() time */
70 .driver = &xpc_dbg_name
71};
72
73struct device xpc_chan_dbg_subname = {
74 .bus_id = {0}, /* set to "chan" at xpc_init() time */
75 .driver = &xpc_dbg_name
76};
77
78struct device *xpc_part = &xpc_part_dbg_subname;
79struct device *xpc_chan = &xpc_chan_dbg_subname;
80
81
82/* systune related variables for /proc/sys directories */
83
84static int xpc_hb_min = 1;
85static int xpc_hb_max = 10;
86
87static int xpc_hb_check_min = 10;
88static int xpc_hb_check_max = 120;
89
90static ctl_table xpc_sys_xpc_hb_dir[] = {
91 {
92 1,
93 "hb_interval",
94 &xpc_hb_interval,
95 sizeof(int),
96 0644,
97 NULL,
98 &proc_dointvec_minmax,
99 &sysctl_intvec,
100 NULL,
101 &xpc_hb_min, &xpc_hb_max
102 },
103 {
104 2,
105 "hb_check_interval",
106 &xpc_hb_check_interval,
107 sizeof(int),
108 0644,
109 NULL,
110 &proc_dointvec_minmax,
111 &sysctl_intvec,
112 NULL,
113 &xpc_hb_check_min, &xpc_hb_check_max
114 },
115 {0}
116};
117static ctl_table xpc_sys_xpc_dir[] = {
118 {
119 1,
120 "hb",
121 NULL,
122 0,
123 0555,
124 xpc_sys_xpc_hb_dir
125 },
126 {0}
127};
128static ctl_table xpc_sys_dir[] = {
129 {
130 1,
131 "xpc",
132 NULL,
133 0,
134 0555,
135 xpc_sys_xpc_dir
136 },
137 {0}
138};
139static struct ctl_table_header *xpc_sysctl;
140
141
142/* #of IRQs received */
143static atomic_t xpc_act_IRQ_rcvd;
144
145/* IRQ handler notifies this wait queue on receipt of an IRQ */
146static DECLARE_WAIT_QUEUE_HEAD(xpc_act_IRQ_wq);
147
148static unsigned long xpc_hb_check_timeout;
149
150/* xpc_hb_checker thread exited notification */
151static DECLARE_MUTEX_LOCKED(xpc_hb_checker_exited);
152
153/* xpc_discovery thread exited notification */
154static DECLARE_MUTEX_LOCKED(xpc_discovery_exited);
155
156
157static struct timer_list xpc_hb_timer;
158
159
160static void xpc_kthread_waitmsgs(struct xpc_partition *, struct xpc_channel *);
161
162
163/*
164 * Notify the heartbeat check thread that an IRQ has been received.
165 */
166static irqreturn_t
167xpc_act_IRQ_handler(int irq, void *dev_id, struct pt_regs *regs)
168{
169 atomic_inc(&xpc_act_IRQ_rcvd);
170 wake_up_interruptible(&xpc_act_IRQ_wq);
171 return IRQ_HANDLED;
172}
173
174
175/*
176 * Timer to produce the heartbeat. The timer structures function is
177 * already set when this is initially called. A tunable is used to
178 * specify when the next timeout should occur.
179 */
180static void
181xpc_hb_beater(unsigned long dummy)
182{
183 xpc_vars->heartbeat++;
184
185 if (jiffies >= xpc_hb_check_timeout) {
186 wake_up_interruptible(&xpc_act_IRQ_wq);
187 }
188
189 xpc_hb_timer.expires = jiffies + (xpc_hb_interval * HZ);
190 add_timer(&xpc_hb_timer);
191}
192
193
194/*
195 * This thread is responsible for nearly all of the partition
196 * activation/deactivation.
197 */
198static int
199xpc_hb_checker(void *ignore)
200{
201 int last_IRQ_count = 0;
202 int new_IRQ_count;
203 int force_IRQ=0;
204
205
206 /* this thread was marked active by xpc_hb_init() */
207
208 daemonize(XPC_HB_CHECK_THREAD_NAME);
209
210 set_cpus_allowed(current, cpumask_of_cpu(XPC_HB_CHECK_CPU));
211
212 xpc_hb_check_timeout = jiffies + (xpc_hb_check_interval * HZ);
213
214 while (!(volatile int) xpc_exiting) {
215
216 /* wait for IRQ or timeout */
217 (void) wait_event_interruptible(xpc_act_IRQ_wq,
218 (last_IRQ_count < atomic_read(&xpc_act_IRQ_rcvd) ||
219 jiffies >= xpc_hb_check_timeout ||
220 (volatile int) xpc_exiting));
221
222 dev_dbg(xpc_part, "woke up with %d ticks rem; %d IRQs have "
223 "been received\n",
224 (int) (xpc_hb_check_timeout - jiffies),
225 atomic_read(&xpc_act_IRQ_rcvd) - last_IRQ_count);
226
227
228 /* checking of remote heartbeats is skewed by IRQ handling */
229 if (jiffies >= xpc_hb_check_timeout) {
230 dev_dbg(xpc_part, "checking remote heartbeats\n");
231 xpc_check_remote_hb();
232
233 /*
234 * We need to periodically recheck to ensure no
235 * IPI/AMO pairs have been missed. That check
236 * must always reset xpc_hb_check_timeout.
237 */
238 force_IRQ = 1;
239 }
240
241
242 new_IRQ_count = atomic_read(&xpc_act_IRQ_rcvd);
243 if (last_IRQ_count < new_IRQ_count || force_IRQ != 0) {
244 force_IRQ = 0;
245
246 dev_dbg(xpc_part, "found an IRQ to process; will be "
247 "resetting xpc_hb_check_timeout\n");
248
249 last_IRQ_count += xpc_identify_act_IRQ_sender();
250 if (last_IRQ_count < new_IRQ_count) {
251 /* retry once to help avoid missing AMO */
252 (void) xpc_identify_act_IRQ_sender();
253 }
254 last_IRQ_count = new_IRQ_count;
255
256 xpc_hb_check_timeout = jiffies +
257 (xpc_hb_check_interval * HZ);
258 }
259 }
260
261 dev_dbg(xpc_part, "heartbeat checker is exiting\n");
262
263
264 /* mark this thread as inactive */
265 up(&xpc_hb_checker_exited);
266 return 0;
267}
268
269
270/*
271 * This thread will attempt to discover other partitions to activate
272 * based on info provided by SAL. This new thread is short lived and
273 * will exit once discovery is complete.
274 */
275static int
276xpc_initiate_discovery(void *ignore)
277{
278 daemonize(XPC_DISCOVERY_THREAD_NAME);
279
280 xpc_discovery();
281
282 dev_dbg(xpc_part, "discovery thread is exiting\n");
283
284 /* mark this thread as inactive */
285 up(&xpc_discovery_exited);
286 return 0;
287}
288
289
290/*
291 * Establish first contact with the remote partititon. This involves pulling
292 * the XPC per partition variables from the remote partition and waiting for
293 * the remote partition to pull ours.
294 */
295static enum xpc_retval
296xpc_make_first_contact(struct xpc_partition *part)
297{
298 enum xpc_retval ret;
299
300
301 while ((ret = xpc_pull_remote_vars_part(part)) != xpcSuccess) {
302 if (ret != xpcRetry) {
303 XPC_DEACTIVATE_PARTITION(part, ret);
304 return ret;
305 }
306
307 dev_dbg(xpc_chan, "waiting to make first contact with "
308 "partition %d\n", XPC_PARTID(part));
309
310 /* wait a 1/4 of a second or so */
311 set_current_state(TASK_INTERRUPTIBLE);
312 (void) schedule_timeout(0.25 * HZ);
313
314 if (part->act_state == XPC_P_DEACTIVATING) {
315 return part->reason;
316 }
317 }
318
319 return xpc_mark_partition_active(part);
320}
321
322
323/*
324 * The first kthread assigned to a newly activated partition is the one
325 * created by XPC HB with which it calls xpc_partition_up(). XPC hangs on to
326 * that kthread until the partition is brought down, at which time that kthread
327 * returns back to XPC HB. (The return of that kthread will signify to XPC HB
328 * that XPC has dismantled all communication infrastructure for the associated
329 * partition.) This kthread becomes the channel manager for that partition.
330 *
331 * Each active partition has a channel manager, who, besides connecting and
332 * disconnecting channels, will ensure that each of the partition's connected
333 * channels has the required number of assigned kthreads to get the work done.
334 */
335static void
336xpc_channel_mgr(struct xpc_partition *part)
337{
338 while (part->act_state != XPC_P_DEACTIVATING ||
339 atomic_read(&part->nchannels_active) > 0) {
340
341 xpc_process_channel_activity(part);
342
343
344 /*
345 * Wait until we've been requested to activate kthreads or
346 * all of the channel's message queues have been torn down or
347 * a signal is pending.
348 *
349 * The channel_mgr_requests is set to 1 after being awakened,
350 * This is done to prevent the channel mgr from making one pass
351 * through the loop for each request, since he will
352 * be servicing all the requests in one pass. The reason it's
353 * set to 1 instead of 0 is so that other kthreads will know
354 * that the channel mgr is running and won't bother trying to
355 * wake him up.
356 */
357 atomic_dec(&part->channel_mgr_requests);
358 (void) wait_event_interruptible(part->channel_mgr_wq,
359 (atomic_read(&part->channel_mgr_requests) > 0 ||
360 (volatile u64) part->local_IPI_amo != 0 ||
361 ((volatile u8) part->act_state ==
362 XPC_P_DEACTIVATING &&
363 atomic_read(&part->nchannels_active) == 0)));
364 atomic_set(&part->channel_mgr_requests, 1);
365
366 // >>> Does it need to wakeup periodically as well? In case we
367 // >>> miscalculated the #of kthreads to wakeup or create?
368 }
369}
370
371
372/*
373 * When XPC HB determines that a partition has come up, it will create a new
374 * kthread and that kthread will call this function to attempt to set up the
375 * basic infrastructure used for Cross Partition Communication with the newly
376 * upped partition.
377 *
378 * The kthread that was created by XPC HB and which setup the XPC
379 * infrastructure will remain assigned to the partition until the partition
380 * goes down. At which time the kthread will teardown the XPC infrastructure
381 * and then exit.
382 *
383 * XPC HB will put the remote partition's XPC per partition specific variables
384 * physical address into xpc_partitions[partid].remote_vars_part_pa prior to
385 * calling xpc_partition_up().
386 */
387static void
388xpc_partition_up(struct xpc_partition *part)
389{
390 DBUG_ON(part->channels != NULL);
391
392 dev_dbg(xpc_chan, "activating partition %d\n", XPC_PARTID(part));
393
394 if (xpc_setup_infrastructure(part) != xpcSuccess) {
395 return;
396 }
397
398 /*
399 * The kthread that XPC HB called us with will become the
400 * channel manager for this partition. It will not return
401 * back to XPC HB until the partition's XPC infrastructure
402 * has been dismantled.
403 */
404
405 (void) xpc_part_ref(part); /* this will always succeed */
406
407 if (xpc_make_first_contact(part) == xpcSuccess) {
408 xpc_channel_mgr(part);
409 }
410
411 xpc_part_deref(part);
412
413 xpc_teardown_infrastructure(part);
414}
415
416
417static int
418xpc_activating(void *__partid)
419{
420 partid_t partid = (u64) __partid;
421 struct xpc_partition *part = &xpc_partitions[partid];
422 unsigned long irq_flags;
423 struct sched_param param = { sched_priority: MAX_USER_RT_PRIO - 1 };
424 int ret;
425
426
427 DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
428
429 spin_lock_irqsave(&part->act_lock, irq_flags);
430
431 if (part->act_state == XPC_P_DEACTIVATING) {
432 part->act_state = XPC_P_INACTIVE;
433 spin_unlock_irqrestore(&part->act_lock, irq_flags);
434 part->remote_rp_pa = 0;
435 return 0;
436 }
437
438 /* indicate the thread is activating */
439 DBUG_ON(part->act_state != XPC_P_ACTIVATION_REQ);
440 part->act_state = XPC_P_ACTIVATING;
441
442 XPC_SET_REASON(part, 0, 0);
443 spin_unlock_irqrestore(&part->act_lock, irq_flags);
444
445 dev_dbg(xpc_part, "bringing partition %d up\n", partid);
446
447 daemonize("xpc%02d", partid);
448
449 /*
450 * This thread needs to run at a realtime priority to prevent a
451 * significant performance degradation.
452 */
453 ret = sched_setscheduler(current, SCHED_FIFO, &param);
454 if (ret != 0) {
455 dev_warn(xpc_part, "unable to set pid %d to a realtime "
456 "priority, ret=%d\n", current->pid, ret);
457 }
458
459 /* allow this thread and its children to run on any CPU */
460 set_cpus_allowed(current, CPU_MASK_ALL);
461
462 /*
463 * Register the remote partition's AMOs with SAL so it can handle
464 * and cleanup errors within that address range should the remote
465 * partition go down. We don't unregister this range because it is
466 * difficult to tell when outstanding writes to the remote partition
467 * are finished and thus when it is safe to unregister. This should
468 * not result in wasted space in the SAL xp_addr_region table because
469 * we should get the same page for remote_amos_page_pa after module
470 * reloads and system reboots.
471 */
472 if (sn_register_xp_addr_region(part->remote_amos_page_pa,
473 PAGE_SIZE, 1) < 0) {
474 dev_warn(xpc_part, "xpc_partition_up(%d) failed to register "
475 "xp_addr region\n", partid);
476
477 spin_lock_irqsave(&part->act_lock, irq_flags);
478 part->act_state = XPC_P_INACTIVE;
479 XPC_SET_REASON(part, xpcPhysAddrRegFailed, __LINE__);
480 spin_unlock_irqrestore(&part->act_lock, irq_flags);
481 part->remote_rp_pa = 0;
482 return 0;
483 }
484
485 XPC_ALLOW_HB(partid, xpc_vars);
486 xpc_IPI_send_activated(part);
487
488
489 /*
490 * xpc_partition_up() holds this thread and marks this partition as
491 * XPC_P_ACTIVE by calling xpc_hb_mark_active().
492 */
493 (void) xpc_partition_up(part);
494
495 xpc_mark_partition_inactive(part);
496
497 if (part->reason == xpcReactivating) {
498 /* interrupting ourselves results in activating partition */
499 xpc_IPI_send_reactivate(part);
500 }
501
502 return 0;
503}
504
505
506void
507xpc_activate_partition(struct xpc_partition *part)
508{
509 partid_t partid = XPC_PARTID(part);
510 unsigned long irq_flags;
511 pid_t pid;
512
513
514 spin_lock_irqsave(&part->act_lock, irq_flags);
515
516 pid = kernel_thread(xpc_activating, (void *) ((u64) partid), 0);
517
518 DBUG_ON(part->act_state != XPC_P_INACTIVE);
519
520 if (pid > 0) {
521 part->act_state = XPC_P_ACTIVATION_REQ;
522 XPC_SET_REASON(part, xpcCloneKThread, __LINE__);
523 } else {
524 XPC_SET_REASON(part, xpcCloneKThreadFailed, __LINE__);
525 }
526
527 spin_unlock_irqrestore(&part->act_lock, irq_flags);
528}
529
530
531/*
532 * Handle the receipt of a SGI_XPC_NOTIFY IRQ by seeing whether the specified
533 * partition actually sent it. Since SGI_XPC_NOTIFY IRQs may be shared by more
534 * than one partition, we use an AMO_t structure per partition to indicate
535 * whether a partition has sent an IPI or not. >>> If it has, then wake up the
536 * associated kthread to handle it.
537 *
538 * All SGI_XPC_NOTIFY IRQs received by XPC are the result of IPIs sent by XPC
539 * running on other partitions.
540 *
541 * Noteworthy Arguments:
542 *
543 * irq - Interrupt ReQuest number. NOT USED.
544 *
545 * dev_id - partid of IPI's potential sender.
546 *
547 * regs - processor's context before the processor entered
548 * interrupt code. NOT USED.
549 */
550irqreturn_t
551xpc_notify_IRQ_handler(int irq, void *dev_id, struct pt_regs *regs)
552{
553 partid_t partid = (partid_t) (u64) dev_id;
554 struct xpc_partition *part = &xpc_partitions[partid];
555
556
557 DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
558
559 if (xpc_part_ref(part)) {
560 xpc_check_for_channel_activity(part);
561
562 xpc_part_deref(part);
563 }
564 return IRQ_HANDLED;
565}
566
567
568/*
569 * Check to see if xpc_notify_IRQ_handler() dropped any IPIs on the floor
570 * because the write to their associated IPI amo completed after the IRQ/IPI
571 * was received.
572 */
573void
574xpc_dropped_IPI_check(struct xpc_partition *part)
575{
576 if (xpc_part_ref(part)) {
577 xpc_check_for_channel_activity(part);
578
579 part->dropped_IPI_timer.expires = jiffies +
580 XPC_P_DROPPED_IPI_WAIT;
581 add_timer(&part->dropped_IPI_timer);
582 xpc_part_deref(part);
583 }
584}
585
586
587void
588xpc_activate_kthreads(struct xpc_channel *ch, int needed)
589{
590 int idle = atomic_read(&ch->kthreads_idle);
591 int assigned = atomic_read(&ch->kthreads_assigned);
592 int wakeup;
593
594
595 DBUG_ON(needed <= 0);
596
597 if (idle > 0) {
598 wakeup = (needed > idle) ? idle : needed;
599 needed -= wakeup;
600
601 dev_dbg(xpc_chan, "wakeup %d idle kthreads, partid=%d, "
602 "channel=%d\n", wakeup, ch->partid, ch->number);
603
604 /* only wakeup the requested number of kthreads */
605 wake_up_nr(&ch->idle_wq, wakeup);
606 }
607
608 if (needed <= 0) {
609 return;
610 }
611
612 if (needed + assigned > ch->kthreads_assigned_limit) {
613 needed = ch->kthreads_assigned_limit - assigned;
614 // >>>should never be less than 0
615 if (needed <= 0) {
616 return;
617 }
618 }
619
620 dev_dbg(xpc_chan, "create %d new kthreads, partid=%d, channel=%d\n",
621 needed, ch->partid, ch->number);
622
623 xpc_create_kthreads(ch, needed);
624}
625
626
627/*
628 * This function is where XPC's kthreads wait for messages to deliver.
629 */
630static void
631xpc_kthread_waitmsgs(struct xpc_partition *part, struct xpc_channel *ch)
632{
633 do {
634 /* deliver messages to their intended recipients */
635
636 while ((volatile s64) ch->w_local_GP.get <
637 (volatile s64) ch->w_remote_GP.put &&
638 !((volatile u32) ch->flags &
639 XPC_C_DISCONNECTING)) {
640 xpc_deliver_msg(ch);
641 }
642
643 if (atomic_inc_return(&ch->kthreads_idle) >
644 ch->kthreads_idle_limit) {
645 /* too many idle kthreads on this channel */
646 atomic_dec(&ch->kthreads_idle);
647 break;
648 }
649
650 dev_dbg(xpc_chan, "idle kthread calling "
651 "wait_event_interruptible_exclusive()\n");
652
653 (void) wait_event_interruptible_exclusive(ch->idle_wq,
654 ((volatile s64) ch->w_local_GP.get <
655 (volatile s64) ch->w_remote_GP.put ||
656 ((volatile u32) ch->flags &
657 XPC_C_DISCONNECTING)));
658
659 atomic_dec(&ch->kthreads_idle);
660
661 } while (!((volatile u32) ch->flags & XPC_C_DISCONNECTING));
662}
663
664
665static int
666xpc_daemonize_kthread(void *args)
667{
668 partid_t partid = XPC_UNPACK_ARG1(args);
669 u16 ch_number = XPC_UNPACK_ARG2(args);
670 struct xpc_partition *part = &xpc_partitions[partid];
671 struct xpc_channel *ch;
672 int n_needed;
673
674
675 daemonize("xpc%02dc%d", partid, ch_number);
676
677 dev_dbg(xpc_chan, "kthread starting, partid=%d, channel=%d\n",
678 partid, ch_number);
679
680 ch = &part->channels[ch_number];
681
682 if (!(ch->flags & XPC_C_DISCONNECTING)) {
683 DBUG_ON(!(ch->flags & XPC_C_CONNECTED));
684
685 /* let registerer know that connection has been established */
686
687 if (atomic_read(&ch->kthreads_assigned) == 1) {
688 xpc_connected_callout(ch);
689
690 /*
691 * It is possible that while the callout was being
692 * made that the remote partition sent some messages.
693 * If that is the case, we may need to activate
694 * additional kthreads to help deliver them. We only
695 * need one less than total #of messages to deliver.
696 */
697 n_needed = ch->w_remote_GP.put - ch->w_local_GP.get - 1;
698 if (n_needed > 0 &&
699 !(ch->flags & XPC_C_DISCONNECTING)) {
700 xpc_activate_kthreads(ch, n_needed);
701 }
702 }
703
704 xpc_kthread_waitmsgs(part, ch);
705 }
706
707 if (atomic_dec_return(&ch->kthreads_assigned) == 0 &&
708 ((ch->flags & XPC_C_CONNECTCALLOUT) ||
709 (ch->reason != xpcUnregistering &&
710 ch->reason != xpcOtherUnregistering))) {
711 xpc_disconnected_callout(ch);
712 }
713
714
715 xpc_msgqueue_deref(ch);
716
717 dev_dbg(xpc_chan, "kthread exiting, partid=%d, channel=%d\n",
718 partid, ch_number);
719
720 xpc_part_deref(part);
721 return 0;
722}
723
724
725/*
726 * For each partition that XPC has established communications with, there is
727 * a minimum of one kernel thread assigned to perform any operation that
728 * may potentially sleep or block (basically the callouts to the asynchronous
729 * functions registered via xpc_connect()).
730 *
731 * Additional kthreads are created and destroyed by XPC as the workload
732 * demands.
733 *
734 * A kthread is assigned to one of the active channels that exists for a given
735 * partition.
736 */
737void
738xpc_create_kthreads(struct xpc_channel *ch, int needed)
739{
740 unsigned long irq_flags;
741 pid_t pid;
742 u64 args = XPC_PACK_ARGS(ch->partid, ch->number);
743
744
745 while (needed-- > 0) {
746 pid = kernel_thread(xpc_daemonize_kthread, (void *) args, 0);
747 if (pid < 0) {
748 /* the fork failed */
749
750 if (atomic_read(&ch->kthreads_assigned) <
751 ch->kthreads_idle_limit) {
752 /*
753 * Flag this as an error only if we have an
754 * insufficient #of kthreads for the channel
755 * to function.
756 *
757 * No xpc_msgqueue_ref() is needed here since
758 * the channel mgr is doing this.
759 */
760 spin_lock_irqsave(&ch->lock, irq_flags);
761 XPC_DISCONNECT_CHANNEL(ch, xpcLackOfResources,
762 &irq_flags);
763 spin_unlock_irqrestore(&ch->lock, irq_flags);
764 }
765 break;
766 }
767
768 /*
769 * The following is done on behalf of the newly created
770 * kthread. That kthread is responsible for doing the
771 * counterpart to the following before it exits.
772 */
773 (void) xpc_part_ref(&xpc_partitions[ch->partid]);
774 xpc_msgqueue_ref(ch);
775 atomic_inc(&ch->kthreads_assigned);
776 ch->kthreads_created++; // >>> temporary debug only!!!
777 }
778}
779
780
781void
782xpc_disconnect_wait(int ch_number)
783{
784 partid_t partid;
785 struct xpc_partition *part;
786 struct xpc_channel *ch;
787
788
789 /* now wait for all callouts to the caller's function to cease */
790 for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
791 part = &xpc_partitions[partid];
792
793 if (xpc_part_ref(part)) {
794 ch = &part->channels[ch_number];
795
796// >>> how do we keep from falling into the window between our check and going
797// >>> down and coming back up where sema is re-inited?
798 if (ch->flags & XPC_C_SETUP) {
799 (void) down(&ch->teardown_sema);
800 }
801
802 xpc_part_deref(part);
803 }
804 }
805}
806
807
808static void
809xpc_do_exit(void)
810{
811 partid_t partid;
812 int active_part_count;
813 struct xpc_partition *part;
814
815
816 /* now it's time to eliminate our heartbeat */
817 del_timer_sync(&xpc_hb_timer);
818 xpc_vars->heartbeating_to_mask = 0;
819
820 /* indicate to others that our reserved page is uninitialized */
821 xpc_rsvd_page->vars_pa = 0;
822
823 /*
824 * Ignore all incoming interrupts. Without interupts the heartbeat
825 * checker won't activate any new partitions that may come up.
826 */
827 free_irq(SGI_XPC_ACTIVATE, NULL);
828
829 /*
830 * Cause the heartbeat checker and the discovery threads to exit.
831 * We don't want them attempting to activate new partitions as we
832 * try to deactivate the existing ones.
833 */
834 xpc_exiting = 1;
835 wake_up_interruptible(&xpc_act_IRQ_wq);
836
837 /* wait for the heartbeat checker thread to mark itself inactive */
838 down(&xpc_hb_checker_exited);
839
840 /* wait for the discovery thread to mark itself inactive */
841 down(&xpc_discovery_exited);
842
843
844 set_current_state(TASK_INTERRUPTIBLE);
845 schedule_timeout(0.3 * HZ);
846 set_current_state(TASK_RUNNING);
847
848
849 /* wait for all partitions to become inactive */
850
851 do {
852 active_part_count = 0;
853
854 for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
855 part = &xpc_partitions[partid];
856 if (part->act_state != XPC_P_INACTIVE) {
857 active_part_count++;
858
859 XPC_DEACTIVATE_PARTITION(part, xpcUnloading);
860 }
861 }
862
863 if (active_part_count) {
864 set_current_state(TASK_INTERRUPTIBLE);
865 schedule_timeout(0.3 * HZ);
866 set_current_state(TASK_RUNNING);
867 }
868
869 } while (active_part_count > 0);
870
871
872 /* close down protections for IPI operations */
873 xpc_restrict_IPI_ops();
874
875
876 /* clear the interface to XPC's functions */
877 xpc_clear_interface();
878
879 if (xpc_sysctl) {
880 unregister_sysctl_table(xpc_sysctl);
881 }
882}
883
884
885int __init
886xpc_init(void)
887{
888 int ret;
889 partid_t partid;
890 struct xpc_partition *part;
891 pid_t pid;
892
893
894 /*
895 * xpc_remote_copy_buffer is used as a temporary buffer for bte_copy'ng
896 * both a partition's reserved page and its XPC variables. Its size was
897 * based on the size of a reserved page. So we need to ensure that the
898 * XPC variables will fit as well.
899 */
900 if (XPC_VARS_ALIGNED_SIZE > XPC_RSVD_PAGE_ALIGNED_SIZE) {
901 dev_err(xpc_part, "xpc_remote_copy_buffer is not big enough\n");
902 return -EPERM;
903 }
904 DBUG_ON((u64) xpc_remote_copy_buffer !=
905 L1_CACHE_ALIGN((u64) xpc_remote_copy_buffer));
906
907 snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part");
908 snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan");
909
910 xpc_sysctl = register_sysctl_table(xpc_sys_dir, 1);
911
912 /*
913 * The first few fields of each entry of xpc_partitions[] need to
914 * be initialized now so that calls to xpc_connect() and
915 * xpc_disconnect() can be made prior to the activation of any remote
916 * partition. NOTE THAT NONE OF THE OTHER FIELDS BELONGING TO THESE
917 * ENTRIES ARE MEANINGFUL UNTIL AFTER AN ENTRY'S CORRESPONDING
918 * PARTITION HAS BEEN ACTIVATED.
919 */
920 for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
921 part = &xpc_partitions[partid];
922
923 DBUG_ON((u64) part != L1_CACHE_ALIGN((u64) part));
924
925 part->act_IRQ_rcvd = 0;
926 spin_lock_init(&part->act_lock);
927 part->act_state = XPC_P_INACTIVE;
928 XPC_SET_REASON(part, 0, 0);
929 part->setup_state = XPC_P_UNSET;
930 init_waitqueue_head(&part->teardown_wq);
931 atomic_set(&part->references, 0);
932 }
933
934 /*
935 * Open up protections for IPI operations (and AMO operations on
936 * Shub 1.1 systems).
937 */
938 xpc_allow_IPI_ops();
939
940 /*
941 * Interrupts being processed will increment this atomic variable and
942 * awaken the heartbeat thread which will process the interrupts.
943 */
944 atomic_set(&xpc_act_IRQ_rcvd, 0);
945
946 /*
947 * This is safe to do before the xpc_hb_checker thread has started
948 * because the handler releases a wait queue. If an interrupt is
949 * received before the thread is waiting, it will not go to sleep,
950 * but rather immediately process the interrupt.
951 */
952 ret = request_irq(SGI_XPC_ACTIVATE, xpc_act_IRQ_handler, 0,
953 "xpc hb", NULL);
954 if (ret != 0) {
955 dev_err(xpc_part, "can't register ACTIVATE IRQ handler, "
956 "errno=%d\n", -ret);
957
958 xpc_restrict_IPI_ops();
959
960 if (xpc_sysctl) {
961 unregister_sysctl_table(xpc_sysctl);
962 }
963 return -EBUSY;
964 }
965
966 /*
967 * Fill the partition reserved page with the information needed by
968 * other partitions to discover we are alive and establish initial
969 * communications.
970 */
971 xpc_rsvd_page = xpc_rsvd_page_init();
972 if (xpc_rsvd_page == NULL) {
973 dev_err(xpc_part, "could not setup our reserved page\n");
974
975 free_irq(SGI_XPC_ACTIVATE, NULL);
976 xpc_restrict_IPI_ops();
977
978 if (xpc_sysctl) {
979 unregister_sysctl_table(xpc_sysctl);
980 }
981 return -EBUSY;
982 }
983
984
985 /*
986 * Set the beating to other partitions into motion. This is
987 * the last requirement for other partitions' discovery to
988 * initiate communications with us.
989 */
990 init_timer(&xpc_hb_timer);
991 xpc_hb_timer.function = xpc_hb_beater;
992 xpc_hb_beater(0);
993
994
995 /*
996 * The real work-horse behind xpc. This processes incoming
997 * interrupts and monitors remote heartbeats.
998 */
999 pid = kernel_thread(xpc_hb_checker, NULL, 0);
1000 if (pid < 0) {
1001 dev_err(xpc_part, "failed while forking hb check thread\n");
1002
1003 /* indicate to others that our reserved page is uninitialized */
1004 xpc_rsvd_page->vars_pa = 0;
1005
1006 del_timer_sync(&xpc_hb_timer);
1007 free_irq(SGI_XPC_ACTIVATE, NULL);
1008 xpc_restrict_IPI_ops();
1009
1010 if (xpc_sysctl) {
1011 unregister_sysctl_table(xpc_sysctl);
1012 }
1013 return -EBUSY;
1014 }
1015
1016
1017 /*
1018 * Startup a thread that will attempt to discover other partitions to
1019 * activate based on info provided by SAL. This new thread is short
1020 * lived and will exit once discovery is complete.
1021 */
1022 pid = kernel_thread(xpc_initiate_discovery, NULL, 0);
1023 if (pid < 0) {
1024 dev_err(xpc_part, "failed while forking discovery thread\n");
1025
1026 /* mark this new thread as a non-starter */
1027 up(&xpc_discovery_exited);
1028
1029 xpc_do_exit();
1030 return -EBUSY;
1031 }
1032
1033
1034 /* set the interface to point at XPC's functions */
1035 xpc_set_interface(xpc_initiate_connect, xpc_initiate_disconnect,
1036 xpc_initiate_allocate, xpc_initiate_send,
1037 xpc_initiate_send_notify, xpc_initiate_received,
1038 xpc_initiate_partid_to_nasids);
1039
1040 return 0;
1041}
1042module_init(xpc_init);
1043
1044
1045void __exit
1046xpc_exit(void)
1047{
1048 xpc_do_exit();
1049}
1050module_exit(xpc_exit);
1051
1052
1053MODULE_AUTHOR("Silicon Graphics, Inc.");
1054MODULE_DESCRIPTION("Cross Partition Communication (XPC) support");
1055MODULE_LICENSE("GPL");
1056
1057module_param(xpc_hb_interval, int, 0);
1058MODULE_PARM_DESC(xpc_hb_interval, "Number of seconds between "
1059 "heartbeat increments.");
1060
1061module_param(xpc_hb_check_interval, int, 0);
1062MODULE_PARM_DESC(xpc_hb_check_interval, "Number of seconds between "
1063 "heartbeat checks.");
1064
diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c
new file mode 100644
index 000000000000..2c3c4a8af553
--- /dev/null
+++ b/arch/ia64/sn/kernel/xpc_partition.c
@@ -0,0 +1,984 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved.
7 */
8
9
10/*
11 * Cross Partition Communication (XPC) partition support.
12 *
13 * This is the part of XPC that detects the presence/absence of
14 * other partitions. It provides a heartbeat and monitors the
15 * heartbeats of other partitions.
16 *
17 */
18
19
20#include <linux/kernel.h>
21#include <linux/sysctl.h>
22#include <linux/cache.h>
23#include <linux/mmzone.h>
24#include <linux/nodemask.h>
25#include <asm/sn/bte.h>
26#include <asm/sn/intr.h>
27#include <asm/sn/sn_sal.h>
28#include <asm/sn/nodepda.h>
29#include <asm/sn/addrs.h>
30#include "xpc.h"
31
32
33/* XPC is exiting flag */
34int xpc_exiting;
35
36
37/* SH_IPI_ACCESS shub register value on startup */
38static u64 xpc_sh1_IPI_access;
39static u64 xpc_sh2_IPI_access0;
40static u64 xpc_sh2_IPI_access1;
41static u64 xpc_sh2_IPI_access2;
42static u64 xpc_sh2_IPI_access3;
43
44
45/* original protection values for each node */
46u64 xpc_prot_vec[MAX_COMPACT_NODES];
47
48
49/* this partition's reserved page */
50struct xpc_rsvd_page *xpc_rsvd_page;
51
52/* this partition's XPC variables (within the reserved page) */
53struct xpc_vars *xpc_vars;
54struct xpc_vars_part *xpc_vars_part;
55
56
57/*
58 * For performance reasons, each entry of xpc_partitions[] is cacheline
59 * aligned. And xpc_partitions[] is padded with an additional entry at the
60 * end so that the last legitimate entry doesn't share its cacheline with
61 * another variable.
62 */
63struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1];
64
65
66/*
67 * Generic buffer used to store a local copy of the remote partitions
68 * reserved page or XPC variables.
69 *
70 * xpc_discovery runs only once and is a seperate thread that is
71 * very likely going to be processing in parallel with receiving
72 * interrupts.
73 */
74char ____cacheline_aligned
75 xpc_remote_copy_buffer[XPC_RSVD_PAGE_ALIGNED_SIZE];
76
77
78/* systune related variables */
79int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL;
80int xpc_hb_check_interval = XPC_HB_CHECK_DEFAULT_TIMEOUT;
81
82
83/*
84 * Given a nasid, get the physical address of the partition's reserved page
85 * for that nasid. This function returns 0 on any error.
86 */
87static u64
88xpc_get_rsvd_page_pa(int nasid, u64 buf, u64 buf_size)
89{
90 bte_result_t bte_res;
91 s64 status;
92 u64 cookie = 0;
93 u64 rp_pa = nasid; /* seed with nasid */
94 u64 len = 0;
95
96
97 while (1) {
98
99 status = sn_partition_reserved_page_pa(buf, &cookie, &rp_pa,
100 &len);
101
102 dev_dbg(xpc_part, "SAL returned with status=%li, cookie="
103 "0x%016lx, address=0x%016lx, len=0x%016lx\n",
104 status, cookie, rp_pa, len);
105
106 if (status != SALRET_MORE_PASSES) {
107 break;
108 }
109
110 if (len > buf_size) {
111 dev_err(xpc_part, "len (=0x%016lx) > buf_size\n", len);
112 status = SALRET_ERROR;
113 break;
114 }
115
116 bte_res = xp_bte_copy(rp_pa, ia64_tpa(buf), buf_size,
117 (BTE_NOTIFY | BTE_WACQUIRE), NULL);
118 if (bte_res != BTE_SUCCESS) {
119 dev_dbg(xpc_part, "xp_bte_copy failed %i\n", bte_res);
120 status = SALRET_ERROR;
121 break;
122 }
123 }
124
125 if (status != SALRET_OK) {
126 rp_pa = 0;
127 }
128 dev_dbg(xpc_part, "reserved page at phys address 0x%016lx\n", rp_pa);
129 return rp_pa;
130}
131
132
133/*
134 * Fill the partition reserved page with the information needed by
135 * other partitions to discover we are alive and establish initial
136 * communications.
137 */
138struct xpc_rsvd_page *
139xpc_rsvd_page_init(void)
140{
141 struct xpc_rsvd_page *rp;
142 AMO_t *amos_page;
143 u64 rp_pa, next_cl, nasid_array = 0;
144 int i, ret;
145
146
147 /* get the local reserved page's address */
148
149 rp_pa = xpc_get_rsvd_page_pa(cnodeid_to_nasid(0),
150 (u64) xpc_remote_copy_buffer,
151 XPC_RSVD_PAGE_ALIGNED_SIZE);
152 if (rp_pa == 0) {
153 dev_err(xpc_part, "SAL failed to locate the reserved page\n");
154 return NULL;
155 }
156 rp = (struct xpc_rsvd_page *) __va(rp_pa);
157
158 if (rp->partid != sn_partition_id) {
159 dev_err(xpc_part, "the reserved page's partid of %d should be "
160 "%d\n", rp->partid, sn_partition_id);
161 return NULL;
162 }
163
164 rp->version = XPC_RP_VERSION;
165
166 /*
167 * Place the XPC variables on the cache line following the
168 * reserved page structure.
169 */
170 next_cl = (u64) rp + XPC_RSVD_PAGE_ALIGNED_SIZE;
171 xpc_vars = (struct xpc_vars *) next_cl;
172
173 /*
174 * Before clearing xpc_vars, see if a page of AMOs had been previously
175 * allocated. If not we'll need to allocate one and set permissions
176 * so that cross-partition AMOs are allowed.
177 *
178 * The allocated AMO page needs MCA reporting to remain disabled after
179 * XPC has unloaded. To make this work, we keep a copy of the pointer
180 * to this page (i.e., amos_page) in the struct xpc_vars structure,
181 * which is pointed to by the reserved page, and re-use that saved copy
182 * on subsequent loads of XPC. This AMO page is never freed, and its
183 * memory protections are never restricted.
184 */
185 if ((amos_page = xpc_vars->amos_page) == NULL) {
186 amos_page = (AMO_t *) mspec_kalloc_page(0);
187 if (amos_page == NULL) {
188 dev_err(xpc_part, "can't allocate page of AMOs\n");
189 return NULL;
190 }
191
192 /*
193 * Open up AMO-R/W to cpu. This is done for Shub 1.1 systems
194 * when xpc_allow_IPI_ops() is called via xpc_hb_init().
195 */
196 if (!enable_shub_wars_1_1()) {
197 ret = sn_change_memprotect(ia64_tpa((u64) amos_page),
198 PAGE_SIZE, SN_MEMPROT_ACCESS_CLASS_1,
199 &nasid_array);
200 if (ret != 0) {
201 dev_err(xpc_part, "can't change memory "
202 "protections\n");
203 mspec_kfree_page((unsigned long) amos_page);
204 return NULL;
205 }
206 }
207 } else if (!IS_AMO_ADDRESS((u64) amos_page)) {
208 /*
209 * EFI's XPBOOT can also set amos_page in the reserved page,
210 * but it happens to leave it as an uncached physical address
211 * and we need it to be an uncached virtual, so we'll have to
212 * convert it.
213 */
214 if (!IS_AMO_PHYS_ADDRESS((u64) amos_page)) {
215 dev_err(xpc_part, "previously used amos_page address "
216 "is bad = 0x%p\n", (void *) amos_page);
217 return NULL;
218 }
219 amos_page = (AMO_t *) TO_AMO((u64) amos_page);
220 }
221
222 memset(xpc_vars, 0, sizeof(struct xpc_vars));
223
224 /*
225 * Place the XPC per partition specific variables on the cache line
226 * following the XPC variables structure.
227 */
228 next_cl += XPC_VARS_ALIGNED_SIZE;
229 memset((u64 *) next_cl, 0, sizeof(struct xpc_vars_part) *
230 XP_MAX_PARTITIONS);
231 xpc_vars_part = (struct xpc_vars_part *) next_cl;
232 xpc_vars->vars_part_pa = __pa(next_cl);
233
234 xpc_vars->version = XPC_V_VERSION;
235 xpc_vars->act_nasid = cpuid_to_nasid(0);
236 xpc_vars->act_phys_cpuid = cpu_physical_id(0);
237 xpc_vars->amos_page = amos_page; /* save for next load of XPC */
238
239
240 /*
241 * Initialize the activation related AMO variables.
242 */
243 xpc_vars->act_amos = xpc_IPI_init(XP_MAX_PARTITIONS);
244 for (i = 1; i < XP_NASID_MASK_WORDS; i++) {
245 xpc_IPI_init(i + XP_MAX_PARTITIONS);
246 }
247 /* export AMO page's physical address to other partitions */
248 xpc_vars->amos_page_pa = ia64_tpa((u64) xpc_vars->amos_page);
249
250 /*
251 * This signifies to the remote partition that our reserved
252 * page is initialized.
253 */
254 (volatile u64) rp->vars_pa = __pa(xpc_vars);
255
256 return rp;
257}
258
259
260/*
261 * Change protections to allow IPI operations (and AMO operations on
262 * Shub 1.1 systems).
263 */
264void
265xpc_allow_IPI_ops(void)
266{
267 int node;
268 int nasid;
269
270
271 // >>> Change SH_IPI_ACCESS code to use SAL call once it is available.
272
273 if (is_shub2()) {
274 xpc_sh2_IPI_access0 =
275 (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS0));
276 xpc_sh2_IPI_access1 =
277 (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS1));
278 xpc_sh2_IPI_access2 =
279 (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS2));
280 xpc_sh2_IPI_access3 =
281 (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS3));
282
283 for_each_online_node(node) {
284 nasid = cnodeid_to_nasid(node);
285 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS0),
286 -1UL);
287 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS1),
288 -1UL);
289 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS2),
290 -1UL);
291 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS3),
292 -1UL);
293 }
294
295 } else {
296 xpc_sh1_IPI_access =
297 (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH1_IPI_ACCESS));
298
299 for_each_online_node(node) {
300 nasid = cnodeid_to_nasid(node);
301 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH1_IPI_ACCESS),
302 -1UL);
303
304 /*
305 * Since the BIST collides with memory operations on
306 * SHUB 1.1 sn_change_memprotect() cannot be used.
307 */
308 if (enable_shub_wars_1_1()) {
309 /* open up everything */
310 xpc_prot_vec[node] = (u64) HUB_L((u64 *)
311 GLOBAL_MMR_ADDR(nasid,
312 SH1_MD_DQLP_MMR_DIR_PRIVEC0));
313 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid,
314 SH1_MD_DQLP_MMR_DIR_PRIVEC0),
315 -1UL);
316 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid,
317 SH1_MD_DQRP_MMR_DIR_PRIVEC0),
318 -1UL);
319 }
320 }
321 }
322}
323
324
325/*
326 * Restrict protections to disallow IPI operations (and AMO operations on
327 * Shub 1.1 systems).
328 */
329void
330xpc_restrict_IPI_ops(void)
331{
332 int node;
333 int nasid;
334
335
336 // >>> Change SH_IPI_ACCESS code to use SAL call once it is available.
337
338 if (is_shub2()) {
339
340 for_each_online_node(node) {
341 nasid = cnodeid_to_nasid(node);
342 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS0),
343 xpc_sh2_IPI_access0);
344 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS1),
345 xpc_sh2_IPI_access1);
346 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS2),
347 xpc_sh2_IPI_access2);
348 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS3),
349 xpc_sh2_IPI_access3);
350 }
351
352 } else {
353
354 for_each_online_node(node) {
355 nasid = cnodeid_to_nasid(node);
356 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH1_IPI_ACCESS),
357 xpc_sh1_IPI_access);
358
359 if (enable_shub_wars_1_1()) {
360 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid,
361 SH1_MD_DQLP_MMR_DIR_PRIVEC0),
362 xpc_prot_vec[node]);
363 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid,
364 SH1_MD_DQRP_MMR_DIR_PRIVEC0),
365 xpc_prot_vec[node]);
366 }
367 }
368 }
369}
370
371
372/*
373 * At periodic intervals, scan through all active partitions and ensure
374 * their heartbeat is still active. If not, the partition is deactivated.
375 */
376void
377xpc_check_remote_hb(void)
378{
379 struct xpc_vars *remote_vars;
380 struct xpc_partition *part;
381 partid_t partid;
382 bte_result_t bres;
383
384
385 remote_vars = (struct xpc_vars *) xpc_remote_copy_buffer;
386
387 for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
388 if (partid == sn_partition_id) {
389 continue;
390 }
391
392 part = &xpc_partitions[partid];
393
394 if (part->act_state == XPC_P_INACTIVE ||
395 part->act_state == XPC_P_DEACTIVATING) {
396 continue;
397 }
398
399 /* pull the remote_hb cache line */
400 bres = xp_bte_copy(part->remote_vars_pa,
401 ia64_tpa((u64) remote_vars),
402 XPC_VARS_ALIGNED_SIZE,
403 (BTE_NOTIFY | BTE_WACQUIRE), NULL);
404 if (bres != BTE_SUCCESS) {
405 XPC_DEACTIVATE_PARTITION(part,
406 xpc_map_bte_errors(bres));
407 continue;
408 }
409
410 dev_dbg(xpc_part, "partid = %d, heartbeat = %ld, last_heartbeat"
411 " = %ld, kdb_status = %ld, HB_mask = 0x%lx\n", partid,
412 remote_vars->heartbeat, part->last_heartbeat,
413 remote_vars->kdb_status,
414 remote_vars->heartbeating_to_mask);
415
416 if (((remote_vars->heartbeat == part->last_heartbeat) &&
417 (remote_vars->kdb_status == 0)) ||
418 !XPC_HB_ALLOWED(sn_partition_id, remote_vars)) {
419
420 XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat);
421 continue;
422 }
423
424 part->last_heartbeat = remote_vars->heartbeat;
425 }
426}
427
428
429/*
430 * Get a copy of the remote partition's rsvd page.
431 *
432 * remote_rp points to a buffer that is cacheline aligned for BTE copies and
433 * assumed to be of size XPC_RSVD_PAGE_ALIGNED_SIZE.
434 */
435static enum xpc_retval
436xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
437 struct xpc_rsvd_page *remote_rp, u64 *remote_rsvd_page_pa)
438{
439 int bres, i;
440
441
442 /* get the reserved page's physical address */
443
444 *remote_rsvd_page_pa = xpc_get_rsvd_page_pa(nasid, (u64) remote_rp,
445 XPC_RSVD_PAGE_ALIGNED_SIZE);
446 if (*remote_rsvd_page_pa == 0) {
447 return xpcNoRsvdPageAddr;
448 }
449
450
451 /* pull over the reserved page structure */
452
453 bres = xp_bte_copy(*remote_rsvd_page_pa, ia64_tpa((u64) remote_rp),
454 XPC_RSVD_PAGE_ALIGNED_SIZE,
455 (BTE_NOTIFY | BTE_WACQUIRE), NULL);
456 if (bres != BTE_SUCCESS) {
457 return xpc_map_bte_errors(bres);
458 }
459
460
461 if (discovered_nasids != NULL) {
462 for (i = 0; i < XP_NASID_MASK_WORDS; i++) {
463 discovered_nasids[i] |= remote_rp->part_nasids[i];
464 }
465 }
466
467
468 /* check that the partid is for another partition */
469
470 if (remote_rp->partid < 1 ||
471 remote_rp->partid > (XP_MAX_PARTITIONS - 1)) {
472 return xpcInvalidPartid;
473 }
474
475 if (remote_rp->partid == sn_partition_id) {
476 return xpcLocalPartid;
477 }
478
479
480 if (XPC_VERSION_MAJOR(remote_rp->version) !=
481 XPC_VERSION_MAJOR(XPC_RP_VERSION)) {
482 return xpcBadVersion;
483 }
484
485 return xpcSuccess;
486}
487
488
489/*
490 * Get a copy of the remote partition's XPC variables.
491 *
492 * remote_vars points to a buffer that is cacheline aligned for BTE copies and
493 * assumed to be of size XPC_VARS_ALIGNED_SIZE.
494 */
495static enum xpc_retval
496xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars)
497{
498 int bres;
499
500
501 if (remote_vars_pa == 0) {
502 return xpcVarsNotSet;
503 }
504
505
506 /* pull over the cross partition variables */
507
508 bres = xp_bte_copy(remote_vars_pa, ia64_tpa((u64) remote_vars),
509 XPC_VARS_ALIGNED_SIZE,
510 (BTE_NOTIFY | BTE_WACQUIRE), NULL);
511 if (bres != BTE_SUCCESS) {
512 return xpc_map_bte_errors(bres);
513 }
514
515 if (XPC_VERSION_MAJOR(remote_vars->version) !=
516 XPC_VERSION_MAJOR(XPC_V_VERSION)) {
517 return xpcBadVersion;
518 }
519
520 return xpcSuccess;
521}
522
523
524/*
525 * Prior code has determine the nasid which generated an IPI. Inspect
526 * that nasid to determine if its partition needs to be activated or
527 * deactivated.
528 *
529 * A partition is consider "awaiting activation" if our partition
530 * flags indicate it is not active and it has a heartbeat. A
531 * partition is considered "awaiting deactivation" if our partition
532 * flags indicate it is active but it has no heartbeat or it is not
533 * sending its heartbeat to us.
534 *
535 * To determine the heartbeat, the remote nasid must have a properly
536 * initialized reserved page.
537 */
538static void
539xpc_identify_act_IRQ_req(int nasid)
540{
541 struct xpc_rsvd_page *remote_rp;
542 struct xpc_vars *remote_vars;
543 u64 remote_rsvd_page_pa;
544 u64 remote_vars_pa;
545 partid_t partid;
546 struct xpc_partition *part;
547 enum xpc_retval ret;
548
549
550 /* pull over the reserved page structure */
551
552 remote_rp = (struct xpc_rsvd_page *) xpc_remote_copy_buffer;
553
554 ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rsvd_page_pa);
555 if (ret != xpcSuccess) {
556 dev_warn(xpc_part, "unable to get reserved page from nasid %d, "
557 "which sent interrupt, reason=%d\n", nasid, ret);
558 return;
559 }
560
561 remote_vars_pa = remote_rp->vars_pa;
562 partid = remote_rp->partid;
563 part = &xpc_partitions[partid];
564
565
566 /* pull over the cross partition variables */
567
568 remote_vars = (struct xpc_vars *) xpc_remote_copy_buffer;
569
570 ret = xpc_get_remote_vars(remote_vars_pa, remote_vars);
571 if (ret != xpcSuccess) {
572
573 dev_warn(xpc_part, "unable to get XPC variables from nasid %d, "
574 "which sent interrupt, reason=%d\n", nasid, ret);
575
576 XPC_DEACTIVATE_PARTITION(part, ret);
577 return;
578 }
579
580
581 part->act_IRQ_rcvd++;
582
583 dev_dbg(xpc_part, "partid for nasid %d is %d; IRQs = %d; HB = "
584 "%ld:0x%lx\n", (int) nasid, (int) partid, part->act_IRQ_rcvd,
585 remote_vars->heartbeat, remote_vars->heartbeating_to_mask);
586
587
588 if (part->act_state == XPC_P_INACTIVE) {
589
590 part->remote_rp_pa = remote_rsvd_page_pa;
591 dev_dbg(xpc_part, " remote_rp_pa = 0x%016lx\n",
592 part->remote_rp_pa);
593
594 part->remote_vars_pa = remote_vars_pa;
595 dev_dbg(xpc_part, " remote_vars_pa = 0x%016lx\n",
596 part->remote_vars_pa);
597
598 part->last_heartbeat = remote_vars->heartbeat;
599 dev_dbg(xpc_part, " last_heartbeat = 0x%016lx\n",
600 part->last_heartbeat);
601
602 part->remote_vars_part_pa = remote_vars->vars_part_pa;
603 dev_dbg(xpc_part, " remote_vars_part_pa = 0x%016lx\n",
604 part->remote_vars_part_pa);
605
606 part->remote_act_nasid = remote_vars->act_nasid;
607 dev_dbg(xpc_part, " remote_act_nasid = 0x%x\n",
608 part->remote_act_nasid);
609
610 part->remote_act_phys_cpuid = remote_vars->act_phys_cpuid;
611 dev_dbg(xpc_part, " remote_act_phys_cpuid = 0x%x\n",
612 part->remote_act_phys_cpuid);
613
614 part->remote_amos_page_pa = remote_vars->amos_page_pa;
615 dev_dbg(xpc_part, " remote_amos_page_pa = 0x%lx\n",
616 part->remote_amos_page_pa);
617
618 xpc_activate_partition(part);
619
620 } else if (part->remote_amos_page_pa != remote_vars->amos_page_pa ||
621 !XPC_HB_ALLOWED(sn_partition_id, remote_vars)) {
622
623 part->reactivate_nasid = nasid;
624 XPC_DEACTIVATE_PARTITION(part, xpcReactivating);
625 }
626}
627
628
629/*
630 * Loop through the activation AMO variables and process any bits
631 * which are set. Each bit indicates a nasid sending a partition
632 * activation or deactivation request.
633 *
634 * Return #of IRQs detected.
635 */
636int
637xpc_identify_act_IRQ_sender(void)
638{
639 int word, bit;
640 u64 nasid_mask;
641 u64 nasid; /* remote nasid */
642 int n_IRQs_detected = 0;
643 AMO_t *act_amos;
644 struct xpc_rsvd_page *rp = (struct xpc_rsvd_page *) xpc_rsvd_page;
645
646
647 act_amos = xpc_vars->act_amos;
648
649
650 /* scan through act AMO variable looking for non-zero entries */
651 for (word = 0; word < XP_NASID_MASK_WORDS; word++) {
652
653 nasid_mask = xpc_IPI_receive(&act_amos[word]);
654 if (nasid_mask == 0) {
655 /* no IRQs from nasids in this variable */
656 continue;
657 }
658
659 dev_dbg(xpc_part, "AMO[%d] gave back 0x%lx\n", word,
660 nasid_mask);
661
662
663 /*
664 * If this nasid has been added to the machine since
665 * our partition was reset, this will retain the
666 * remote nasid in our reserved pages machine mask.
667 * This is used in the event of module reload.
668 */
669 rp->mach_nasids[word] |= nasid_mask;
670
671
672 /* locate the nasid(s) which sent interrupts */
673
674 for (bit = 0; bit < (8 * sizeof(u64)); bit++) {
675 if (nasid_mask & (1UL << bit)) {
676 n_IRQs_detected++;
677 nasid = XPC_NASID_FROM_W_B(word, bit);
678 dev_dbg(xpc_part, "interrupt from nasid %ld\n",
679 nasid);
680 xpc_identify_act_IRQ_req(nasid);
681 }
682 }
683 }
684 return n_IRQs_detected;
685}
686
687
688/*
689 * Mark specified partition as active.
690 */
691enum xpc_retval
692xpc_mark_partition_active(struct xpc_partition *part)
693{
694 unsigned long irq_flags;
695 enum xpc_retval ret;
696
697
698 dev_dbg(xpc_part, "setting partition %d to ACTIVE\n", XPC_PARTID(part));
699
700 spin_lock_irqsave(&part->act_lock, irq_flags);
701 if (part->act_state == XPC_P_ACTIVATING) {
702 part->act_state = XPC_P_ACTIVE;
703 ret = xpcSuccess;
704 } else {
705 DBUG_ON(part->reason == xpcSuccess);
706 ret = part->reason;
707 }
708 spin_unlock_irqrestore(&part->act_lock, irq_flags);
709
710 return ret;
711}
712
713
714/*
715 * Notify XPC that the partition is down.
716 */
717void
718xpc_deactivate_partition(const int line, struct xpc_partition *part,
719 enum xpc_retval reason)
720{
721 unsigned long irq_flags;
722 partid_t partid = XPC_PARTID(part);
723
724
725 spin_lock_irqsave(&part->act_lock, irq_flags);
726
727 if (part->act_state == XPC_P_INACTIVE) {
728 XPC_SET_REASON(part, reason, line);
729 spin_unlock_irqrestore(&part->act_lock, irq_flags);
730 if (reason == xpcReactivating) {
731 /* we interrupt ourselves to reactivate partition */
732 xpc_IPI_send_reactivate(part);
733 }
734 return;
735 }
736 if (part->act_state == XPC_P_DEACTIVATING) {
737 if ((part->reason == xpcUnloading && reason != xpcUnloading) ||
738 reason == xpcReactivating) {
739 XPC_SET_REASON(part, reason, line);
740 }
741 spin_unlock_irqrestore(&part->act_lock, irq_flags);
742 return;
743 }
744
745 part->act_state = XPC_P_DEACTIVATING;
746 XPC_SET_REASON(part, reason, line);
747
748 spin_unlock_irqrestore(&part->act_lock, irq_flags);
749
750 XPC_DISALLOW_HB(partid, xpc_vars);
751
752 dev_dbg(xpc_part, "bringing partition %d down, reason = %d\n", partid,
753 reason);
754
755 xpc_partition_down(part, reason);
756}
757
758
759/*
760 * Mark specified partition as active.
761 */
762void
763xpc_mark_partition_inactive(struct xpc_partition *part)
764{
765 unsigned long irq_flags;
766
767
768 dev_dbg(xpc_part, "setting partition %d to INACTIVE\n",
769 XPC_PARTID(part));
770
771 spin_lock_irqsave(&part->act_lock, irq_flags);
772 part->act_state = XPC_P_INACTIVE;
773 spin_unlock_irqrestore(&part->act_lock, irq_flags);
774 part->remote_rp_pa = 0;
775}
776
777
778/*
779 * SAL has provided a partition and machine mask. The partition mask
780 * contains a bit for each even nasid in our partition. The machine
781 * mask contains a bit for each even nasid in the entire machine.
782 *
783 * Using those two bit arrays, we can determine which nasids are
784 * known in the machine. Each should also have a reserved page
785 * initialized if they are available for partitioning.
786 */
787void
788xpc_discovery(void)
789{
790 void *remote_rp_base;
791 struct xpc_rsvd_page *remote_rp;
792 struct xpc_vars *remote_vars;
793 u64 remote_rsvd_page_pa;
794 u64 remote_vars_pa;
795 int region;
796 int max_regions;
797 int nasid;
798 struct xpc_rsvd_page *rp;
799 partid_t partid;
800 struct xpc_partition *part;
801 u64 *discovered_nasids;
802 enum xpc_retval ret;
803
804
805 remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RSVD_PAGE_ALIGNED_SIZE,
806 GFP_KERNEL, &remote_rp_base);
807 if (remote_rp == NULL) {
808 return;
809 }
810 remote_vars = (struct xpc_vars *) remote_rp;
811
812
813 discovered_nasids = kmalloc(sizeof(u64) * XP_NASID_MASK_WORDS,
814 GFP_KERNEL);
815 if (discovered_nasids == NULL) {
816 kfree(remote_rp_base);
817 return;
818 }
819 memset(discovered_nasids, 0, sizeof(u64) * XP_NASID_MASK_WORDS);
820
821 rp = (struct xpc_rsvd_page *) xpc_rsvd_page;
822
823 /*
824 * The term 'region' in this context refers to the minimum number of
825 * nodes that can comprise an access protection grouping. The access
826 * protection is in regards to memory, IOI and IPI.
827 */
828//>>> move the next two #defines into either include/asm-ia64/sn/arch.h or
829//>>> include/asm-ia64/sn/addrs.h
830#define SH1_MAX_REGIONS 64
831#define SH2_MAX_REGIONS 256
832 max_regions = is_shub2() ? SH2_MAX_REGIONS : SH1_MAX_REGIONS;
833
834 for (region = 0; region < max_regions; region++) {
835
836 if ((volatile int) xpc_exiting) {
837 break;
838 }
839
840 dev_dbg(xpc_part, "searching region %d\n", region);
841
842 for (nasid = (region * sn_region_size * 2);
843 nasid < ((region + 1) * sn_region_size * 2);
844 nasid += 2) {
845
846 if ((volatile int) xpc_exiting) {
847 break;
848 }
849
850 dev_dbg(xpc_part, "checking nasid %d\n", nasid);
851
852
853 if (XPC_NASID_IN_ARRAY(nasid, rp->part_nasids)) {
854 dev_dbg(xpc_part, "PROM indicates Nasid %d is "
855 "part of the local partition; skipping "
856 "region\n", nasid);
857 break;
858 }
859
860 if (!(XPC_NASID_IN_ARRAY(nasid, rp->mach_nasids))) {
861 dev_dbg(xpc_part, "PROM indicates Nasid %d was "
862 "not on Numa-Link network at reset\n",
863 nasid);
864 continue;
865 }
866
867 if (XPC_NASID_IN_ARRAY(nasid, discovered_nasids)) {
868 dev_dbg(xpc_part, "Nasid %d is part of a "
869 "partition which was previously "
870 "discovered\n", nasid);
871 continue;
872 }
873
874
875 /* pull over the reserved page structure */
876
877 ret = xpc_get_remote_rp(nasid, discovered_nasids,
878 remote_rp, &remote_rsvd_page_pa);
879 if (ret != xpcSuccess) {
880 dev_dbg(xpc_part, "unable to get reserved page "
881 "from nasid %d, reason=%d\n", nasid,
882 ret);
883
884 if (ret == xpcLocalPartid) {
885 break;
886 }
887 continue;
888 }
889
890 remote_vars_pa = remote_rp->vars_pa;
891
892 partid = remote_rp->partid;
893 part = &xpc_partitions[partid];
894
895
896 /* pull over the cross partition variables */
897
898 ret = xpc_get_remote_vars(remote_vars_pa, remote_vars);
899 if (ret != xpcSuccess) {
900 dev_dbg(xpc_part, "unable to get XPC variables "
901 "from nasid %d, reason=%d\n", nasid,
902 ret);
903
904 XPC_DEACTIVATE_PARTITION(part, ret);
905 continue;
906 }
907
908 if (part->act_state != XPC_P_INACTIVE) {
909 dev_dbg(xpc_part, "partition %d on nasid %d is "
910 "already activating\n", partid, nasid);
911 break;
912 }
913
914 /*
915 * Register the remote partition's AMOs with SAL so it
916 * can handle and cleanup errors within that address
917 * range should the remote partition go down. We don't
918 * unregister this range because it is difficult to
919 * tell when outstanding writes to the remote partition
920 * are finished and thus when it is thus safe to
921 * unregister. This should not result in wasted space
922 * in the SAL xp_addr_region table because we should
923 * get the same page for remote_act_amos_pa after
924 * module reloads and system reboots.
925 */
926 if (sn_register_xp_addr_region(
927 remote_vars->amos_page_pa,
928 PAGE_SIZE, 1) < 0) {
929 dev_dbg(xpc_part, "partition %d failed to "
930 "register xp_addr region 0x%016lx\n",
931 partid, remote_vars->amos_page_pa);
932
933 XPC_SET_REASON(part, xpcPhysAddrRegFailed,
934 __LINE__);
935 break;
936 }
937
938 /*
939 * The remote nasid is valid and available.
940 * Send an interrupt to that nasid to notify
941 * it that we are ready to begin activation.
942 */
943 dev_dbg(xpc_part, "sending an interrupt to AMO 0x%lx, "
944 "nasid %d, phys_cpuid 0x%x\n",
945 remote_vars->amos_page_pa,
946 remote_vars->act_nasid,
947 remote_vars->act_phys_cpuid);
948
949 xpc_IPI_send_activate(remote_vars);
950 }
951 }
952
953 kfree(discovered_nasids);
954 kfree(remote_rp_base);
955}
956
957
958/*
959 * Given a partid, get the nasids owned by that partition from the
960 * remote partition's reserved page.
961 */
962enum xpc_retval
963xpc_initiate_partid_to_nasids(partid_t partid, void *nasid_mask)
964{
965 struct xpc_partition *part;
966 u64 part_nasid_pa;
967 int bte_res;
968
969
970 part = &xpc_partitions[partid];
971 if (part->remote_rp_pa == 0) {
972 return xpcPartitionDown;
973 }
974
975 part_nasid_pa = part->remote_rp_pa +
976 (u64) &((struct xpc_rsvd_page *) 0)->part_nasids;
977
978 bte_res = xp_bte_copy(part_nasid_pa, ia64_tpa((u64) nasid_mask),
979 L1_CACHE_ALIGN(XP_NASID_MASK_BYTES),
980 (BTE_NOTIFY | BTE_WACQUIRE), NULL);
981
982 return xpc_map_bte_errors(bte_res);
983}
984
diff --git a/arch/ia64/sn/kernel/xpnet.c b/arch/ia64/sn/kernel/xpnet.c
new file mode 100644
index 000000000000..78c13d676fa6
--- /dev/null
+++ b/arch/ia64/sn/kernel/xpnet.c
@@ -0,0 +1,715 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1999,2001-2005 Silicon Graphics, Inc. All rights reserved.
7 */
8
9
10/*
11 * Cross Partition Network Interface (XPNET) support
12 *
13 * XPNET provides a virtual network layered on top of the Cross
14 * Partition communication layer.
15 *
16 * XPNET provides direct point-to-point and broadcast-like support
17 * for an ethernet-like device. The ethernet broadcast medium is
18 * replaced with a point-to-point message structure which passes
19 * pointers to a DMA-capable block that a remote partition should
20 * retrieve and pass to the upper level networking layer.
21 *
22 */
23
24
25#include <linux/config.h>
26#include <linux/module.h>
27#include <linux/kernel.h>
28#include <linux/pci.h>
29#include <linux/init.h>
30#include <linux/ioport.h>
31#include <linux/netdevice.h>
32#include <linux/etherdevice.h>
33#include <linux/delay.h>
34#include <linux/ethtool.h>
35#include <linux/mii.h>
36#include <linux/smp.h>
37#include <linux/string.h>
38#include <asm/sn/bte.h>
39#include <asm/sn/io.h>
40#include <asm/sn/sn_sal.h>
41#include <asm/types.h>
42#include <asm/atomic.h>
43#include <asm/sn/xp.h>
44
45
46/*
47 * The message payload transferred by XPC.
48 *
49 * buf_pa is the physical address where the DMA should pull from.
50 *
51 * NOTE: for performance reasons, buf_pa should _ALWAYS_ begin on a
52 * cacheline boundary. To accomplish this, we record the number of
53 * bytes from the beginning of the first cacheline to the first useful
54 * byte of the skb (leadin_ignore) and the number of bytes from the
55 * last useful byte of the skb to the end of the last cacheline
56 * (tailout_ignore).
57 *
58 * size is the number of bytes to transfer which includes the skb->len
59 * (useful bytes of the senders skb) plus the leadin and tailout
60 */
61struct xpnet_message {
62 u16 version; /* Version for this message */
63 u16 embedded_bytes; /* #of bytes embedded in XPC message */
64 u32 magic; /* Special number indicating this is xpnet */
65 u64 buf_pa; /* phys address of buffer to retrieve */
66 u32 size; /* #of bytes in buffer */
67 u8 leadin_ignore; /* #of bytes to ignore at the beginning */
68 u8 tailout_ignore; /* #of bytes to ignore at the end */
69 unsigned char data; /* body of small packets */
70};
71
72/*
73 * Determine the size of our message, the cacheline aligned size,
74 * and then the number of message will request from XPC.
75 *
76 * XPC expects each message to exist in an individual cacheline.
77 */
78#define XPNET_MSG_SIZE (L1_CACHE_BYTES - XPC_MSG_PAYLOAD_OFFSET)
79#define XPNET_MSG_DATA_MAX \
80 (XPNET_MSG_SIZE - (u64)(&((struct xpnet_message *)0)->data))
81#define XPNET_MSG_ALIGNED_SIZE (L1_CACHE_ALIGN(XPNET_MSG_SIZE))
82#define XPNET_MSG_NENTRIES (PAGE_SIZE / XPNET_MSG_ALIGNED_SIZE)
83
84
85#define XPNET_MAX_KTHREADS (XPNET_MSG_NENTRIES + 1)
86#define XPNET_MAX_IDLE_KTHREADS (XPNET_MSG_NENTRIES + 1)
87
88/*
89 * Version number of XPNET implementation. XPNET can always talk to versions
90 * with same major #, and never talk to versions with a different version.
91 */
92#define _XPNET_VERSION(_major, _minor) (((_major) << 4) | (_minor))
93#define XPNET_VERSION_MAJOR(_v) ((_v) >> 4)
94#define XPNET_VERSION_MINOR(_v) ((_v) & 0xf)
95
96#define XPNET_VERSION _XPNET_VERSION(1,0) /* version 1.0 */
97#define XPNET_VERSION_EMBED _XPNET_VERSION(1,1) /* version 1.1 */
98#define XPNET_MAGIC 0x88786984 /* "XNET" */
99
100#define XPNET_VALID_MSG(_m) \
101 ((XPNET_VERSION_MAJOR(_m->version) == XPNET_VERSION_MAJOR(XPNET_VERSION)) \
102 && (msg->magic == XPNET_MAGIC))
103
104#define XPNET_DEVICE_NAME "xp0"
105
106
107/*
108 * When messages are queued with xpc_send_notify, a kmalloc'd buffer
109 * of the following type is passed as a notification cookie. When the
110 * notification function is called, we use the cookie to decide
111 * whether all outstanding message sends have completed. The skb can
112 * then be released.
113 */
114struct xpnet_pending_msg {
115 struct list_head free_list;
116 struct sk_buff *skb;
117 atomic_t use_count;
118};
119
120/* driver specific structure pointed to by the device structure */
121struct xpnet_dev_private {
122 struct net_device_stats stats;
123};
124
125struct net_device *xpnet_device;
126
127/*
128 * When we are notified of other partitions activating, we add them to
129 * our bitmask of partitions to which we broadcast.
130 */
131static u64 xpnet_broadcast_partitions;
132/* protect above */
133static spinlock_t xpnet_broadcast_lock = SPIN_LOCK_UNLOCKED;
134
135/*
136 * Since the Block Transfer Engine (BTE) is being used for the transfer
137 * and it relies upon cache-line size transfers, we need to reserve at
138 * least one cache-line for head and tail alignment. The BTE is
139 * limited to 8MB transfers.
140 *
141 * Testing has shown that changing MTU to greater than 64KB has no effect
142 * on TCP as the two sides negotiate a Max Segment Size that is limited
143 * to 64K. Other protocols May use packets greater than this, but for
144 * now, the default is 64KB.
145 */
146#define XPNET_MAX_MTU (0x800000UL - L1_CACHE_BYTES)
147/* 32KB has been determined to be the ideal */
148#define XPNET_DEF_MTU (0x8000UL)
149
150
151/*
152 * The partition id is encapsulated in the MAC address. The following
153 * define locates the octet the partid is in.
154 */
155#define XPNET_PARTID_OCTET 1
156#define XPNET_LICENSE_OCTET 2
157
158
159/*
160 * Define the XPNET debug device structure that is to be used with dev_dbg(),
161 * dev_err(), dev_warn(), and dev_info().
162 */
163struct device_driver xpnet_dbg_name = {
164 .name = "xpnet"
165};
166
167struct device xpnet_dbg_subname = {
168 .bus_id = {0}, /* set to "" */
169 .driver = &xpnet_dbg_name
170};
171
172struct device *xpnet = &xpnet_dbg_subname;
173
174/*
175 * Packet was recevied by XPC and forwarded to us.
176 */
177static void
178xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg)
179{
180 struct sk_buff *skb;
181 bte_result_t bret;
182 struct xpnet_dev_private *priv =
183 (struct xpnet_dev_private *) xpnet_device->priv;
184
185
186 if (!XPNET_VALID_MSG(msg)) {
187 /*
188 * Packet with a different XPC version. Ignore.
189 */
190 xpc_received(partid, channel, (void *) msg);
191
192 priv->stats.rx_errors++;
193
194 return;
195 }
196 dev_dbg(xpnet, "received 0x%lx, %d, %d, %d\n", msg->buf_pa, msg->size,
197 msg->leadin_ignore, msg->tailout_ignore);
198
199
200 /* reserve an extra cache line */
201 skb = dev_alloc_skb(msg->size + L1_CACHE_BYTES);
202 if (!skb) {
203 dev_err(xpnet, "failed on dev_alloc_skb(%d)\n",
204 msg->size + L1_CACHE_BYTES);
205
206 xpc_received(partid, channel, (void *) msg);
207
208 priv->stats.rx_errors++;
209
210 return;
211 }
212
213 /*
214 * The allocated skb has some reserved space.
215 * In order to use bte_copy, we need to get the
216 * skb->data pointer moved forward.
217 */
218 skb_reserve(skb, (L1_CACHE_BYTES - ((u64)skb->data &
219 (L1_CACHE_BYTES - 1)) +
220 msg->leadin_ignore));
221
222 /*
223 * Update the tail pointer to indicate data actually
224 * transferred.
225 */
226 skb_put(skb, (msg->size - msg->leadin_ignore - msg->tailout_ignore));
227
228 /*
229 * Move the data over from the the other side.
230 */
231 if ((XPNET_VERSION_MINOR(msg->version) == 1) &&
232 (msg->embedded_bytes != 0)) {
233 dev_dbg(xpnet, "copying embedded message. memcpy(0x%p, 0x%p, "
234 "%lu)\n", skb->data, &msg->data,
235 (size_t) msg->embedded_bytes);
236
237 memcpy(skb->data, &msg->data, (size_t) msg->embedded_bytes);
238 } else {
239 dev_dbg(xpnet, "transferring buffer to the skb->data area;\n\t"
240 "bte_copy(0x%p, 0x%p, %hu)\n", (void *)msg->buf_pa,
241 (void *)__pa((u64)skb->data & ~(L1_CACHE_BYTES - 1)),
242 msg->size);
243
244 bret = bte_copy(msg->buf_pa,
245 __pa((u64)skb->data & ~(L1_CACHE_BYTES - 1)),
246 msg->size, (BTE_NOTIFY | BTE_WACQUIRE), NULL);
247
248 if (bret != BTE_SUCCESS) {
249 // >>> Need better way of cleaning skb. Currently skb
250 // >>> appears in_use and we can't just call
251 // >>> dev_kfree_skb.
252 dev_err(xpnet, "bte_copy(0x%p, 0x%p, 0x%hx) returned "
253 "error=0x%x\n", (void *)msg->buf_pa,
254 (void *)__pa((u64)skb->data &
255 ~(L1_CACHE_BYTES - 1)),
256 msg->size, bret);
257
258 xpc_received(partid, channel, (void *) msg);
259
260 priv->stats.rx_errors++;
261
262 return;
263 }
264 }
265
266 dev_dbg(xpnet, "<skb->head=0x%p skb->data=0x%p skb->tail=0x%p "
267 "skb->end=0x%p skb->len=%d\n", (void *) skb->head,
268 (void *) skb->data, (void *) skb->tail, (void *) skb->end,
269 skb->len);
270
271 skb->dev = xpnet_device;
272 skb->protocol = eth_type_trans(skb, xpnet_device);
273 skb->ip_summed = CHECKSUM_UNNECESSARY;
274
275 dev_dbg(xpnet, "passing skb to network layer; \n\tskb->head=0x%p "
276 "skb->data=0x%p skb->tail=0x%p skb->end=0x%p skb->len=%d\n",
277 (void *) skb->head, (void *) skb->data, (void *) skb->tail,
278 (void *) skb->end, skb->len);
279
280
281 xpnet_device->last_rx = jiffies;
282 priv->stats.rx_packets++;
283 priv->stats.rx_bytes += skb->len + ETH_HLEN;
284
285 netif_rx_ni(skb);
286 xpc_received(partid, channel, (void *) msg);
287}
288
289
290/*
291 * This is the handler which XPC calls during any sort of change in
292 * state or message reception on a connection.
293 */
294static void
295xpnet_connection_activity(enum xpc_retval reason, partid_t partid, int channel,
296 void *data, void *key)
297{
298 long bp;
299
300
301 DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
302 DBUG_ON(channel != XPC_NET_CHANNEL);
303
304 switch(reason) {
305 case xpcMsgReceived: /* message received */
306 DBUG_ON(data == NULL);
307
308 xpnet_receive(partid, channel, (struct xpnet_message *) data);
309 break;
310
311 case xpcConnected: /* connection completed to a partition */
312 spin_lock_bh(&xpnet_broadcast_lock);
313 xpnet_broadcast_partitions |= 1UL << (partid -1 );
314 bp = xpnet_broadcast_partitions;
315 spin_unlock_bh(&xpnet_broadcast_lock);
316
317 netif_carrier_on(xpnet_device);
318
319 dev_dbg(xpnet, "%s connection created to partition %d; "
320 "xpnet_broadcast_partitions=0x%lx\n",
321 xpnet_device->name, partid, bp);
322 break;
323
324 default:
325 spin_lock_bh(&xpnet_broadcast_lock);
326 xpnet_broadcast_partitions &= ~(1UL << (partid -1 ));
327 bp = xpnet_broadcast_partitions;
328 spin_unlock_bh(&xpnet_broadcast_lock);
329
330 if (bp == 0) {
331 netif_carrier_off(xpnet_device);
332 }
333
334 dev_dbg(xpnet, "%s disconnected from partition %d; "
335 "xpnet_broadcast_partitions=0x%lx\n",
336 xpnet_device->name, partid, bp);
337 break;
338
339 }
340}
341
342
343static int
344xpnet_dev_open(struct net_device *dev)
345{
346 enum xpc_retval ret;
347
348
349 dev_dbg(xpnet, "calling xpc_connect(%d, 0x%p, NULL, %ld, %ld, %d, "
350 "%d)\n", XPC_NET_CHANNEL, xpnet_connection_activity,
351 XPNET_MSG_SIZE, XPNET_MSG_NENTRIES, XPNET_MAX_KTHREADS,
352 XPNET_MAX_IDLE_KTHREADS);
353
354 ret = xpc_connect(XPC_NET_CHANNEL, xpnet_connection_activity, NULL,
355 XPNET_MSG_SIZE, XPNET_MSG_NENTRIES,
356 XPNET_MAX_KTHREADS, XPNET_MAX_IDLE_KTHREADS);
357 if (ret != xpcSuccess) {
358 dev_err(xpnet, "ifconfig up of %s failed on XPC connect, "
359 "ret=%d\n", dev->name, ret);
360
361 return -ENOMEM;
362 }
363
364 dev_dbg(xpnet, "ifconfig up of %s; XPC connected\n", dev->name);
365
366 return 0;
367}
368
369
370static int
371xpnet_dev_stop(struct net_device *dev)
372{
373 xpc_disconnect(XPC_NET_CHANNEL);
374
375 dev_dbg(xpnet, "ifconfig down of %s; XPC disconnected\n", dev->name);
376
377 return 0;
378}
379
380
381static int
382xpnet_dev_change_mtu(struct net_device *dev, int new_mtu)
383{
384 /* 68 comes from min TCP+IP+MAC header */
385 if ((new_mtu < 68) || (new_mtu > XPNET_MAX_MTU)) {
386 dev_err(xpnet, "ifconfig %s mtu %d failed; value must be "
387 "between 68 and %ld\n", dev->name, new_mtu,
388 XPNET_MAX_MTU);
389 return -EINVAL;
390 }
391
392 dev->mtu = new_mtu;
393 dev_dbg(xpnet, "ifconfig %s mtu set to %d\n", dev->name, new_mtu);
394 return 0;
395}
396
397
398/*
399 * Required for the net_device structure.
400 */
401static int
402xpnet_dev_set_config(struct net_device *dev, struct ifmap *new_map)
403{
404 return 0;
405}
406
407
408/*
409 * Return statistics to the caller.
410 */
411static struct net_device_stats *
412xpnet_dev_get_stats(struct net_device *dev)
413{
414 struct xpnet_dev_private *priv;
415
416
417 priv = (struct xpnet_dev_private *) dev->priv;
418
419 return &priv->stats;
420}
421
422
423/*
424 * Notification that the other end has received the message and
425 * DMA'd the skb information. At this point, they are done with
426 * our side. When all recipients are done processing, we
427 * release the skb and then release our pending message structure.
428 */
429static void
430xpnet_send_completed(enum xpc_retval reason, partid_t partid, int channel,
431 void *__qm)
432{
433 struct xpnet_pending_msg *queued_msg =
434 (struct xpnet_pending_msg *) __qm;
435
436
437 DBUG_ON(queued_msg == NULL);
438
439 dev_dbg(xpnet, "message to %d notified with reason %d\n",
440 partid, reason);
441
442 if (atomic_dec_return(&queued_msg->use_count) == 0) {
443 dev_dbg(xpnet, "all acks for skb->head=-x%p\n",
444 (void *) queued_msg->skb->head);
445
446 dev_kfree_skb_any(queued_msg->skb);
447 kfree(queued_msg);
448 }
449}
450
451
452/*
453 * Network layer has formatted a packet (skb) and is ready to place it
454 * "on the wire". Prepare and send an xpnet_message to all partitions
455 * which have connected with us and are targets of this packet.
456 *
457 * MAC-NOTE: For the XPNET driver, the MAC address contains the
458 * destination partition_id. If the destination partition id word
459 * is 0xff, this packet is to broadcast to all partitions.
460 */
461static int
462xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
463{
464 struct xpnet_pending_msg *queued_msg;
465 enum xpc_retval ret;
466 struct xpnet_message *msg;
467 u64 start_addr, end_addr;
468 long dp;
469 u8 second_mac_octet;
470 partid_t dest_partid;
471 struct xpnet_dev_private *priv;
472 u16 embedded_bytes;
473
474
475 priv = (struct xpnet_dev_private *) dev->priv;
476
477
478 dev_dbg(xpnet, ">skb->head=0x%p skb->data=0x%p skb->tail=0x%p "
479 "skb->end=0x%p skb->len=%d\n", (void *) skb->head,
480 (void *) skb->data, (void *) skb->tail, (void *) skb->end,
481 skb->len);
482
483
484 /*
485 * The xpnet_pending_msg tracks how many outstanding
486 * xpc_send_notifies are relying on this skb. When none
487 * remain, release the skb.
488 */
489 queued_msg = kmalloc(sizeof(struct xpnet_pending_msg), GFP_ATOMIC);
490 if (queued_msg == NULL) {
491 dev_warn(xpnet, "failed to kmalloc %ld bytes; dropping "
492 "packet\n", sizeof(struct xpnet_pending_msg));
493
494 priv->stats.tx_errors++;
495
496 return -ENOMEM;
497 }
498
499
500 /* get the beginning of the first cacheline and end of last */
501 start_addr = ((u64) skb->data & ~(L1_CACHE_BYTES - 1));
502 end_addr = L1_CACHE_ALIGN((u64) skb->tail);
503
504 /* calculate how many bytes to embed in the XPC message */
505 embedded_bytes = 0;
506 if (unlikely(skb->len <= XPNET_MSG_DATA_MAX)) {
507 /* skb->data does fit so embed */
508 embedded_bytes = skb->len;
509 }
510
511
512 /*
513 * Since the send occurs asynchronously, we set the count to one
514 * and begin sending. Any sends that happen to complete before
515 * we are done sending will not free the skb. We will be left
516 * with that task during exit. This also handles the case of
517 * a packet destined for a partition which is no longer up.
518 */
519 atomic_set(&queued_msg->use_count, 1);
520 queued_msg->skb = skb;
521
522
523 second_mac_octet = skb->data[XPNET_PARTID_OCTET];
524 if (second_mac_octet == 0xff) {
525 /* we are being asked to broadcast to all partitions */
526 dp = xpnet_broadcast_partitions;
527 } else if (second_mac_octet != 0) {
528 dp = xpnet_broadcast_partitions &
529 (1UL << (second_mac_octet - 1));
530 } else {
531 /* 0 is an invalid partid. Ignore */
532 dp = 0;
533 }
534 dev_dbg(xpnet, "destination Partitions mask (dp) = 0x%lx\n", dp);
535
536 /*
537 * If we wanted to allow promiscous mode to work like an
538 * unswitched network, this would be a good point to OR in a
539 * mask of partitions which should be receiving all packets.
540 */
541
542 /*
543 * Main send loop.
544 */
545 for (dest_partid = 1; dp && dest_partid < XP_MAX_PARTITIONS;
546 dest_partid++) {
547
548
549 if (!(dp & (1UL << (dest_partid - 1)))) {
550 /* not destined for this partition */
551 continue;
552 }
553
554 /* remove this partition from the destinations mask */
555 dp &= ~(1UL << (dest_partid - 1));
556
557
558 /* found a partition to send to */
559
560 ret = xpc_allocate(dest_partid, XPC_NET_CHANNEL,
561 XPC_NOWAIT, (void **)&msg);
562 if (unlikely(ret != xpcSuccess)) {
563 continue;
564 }
565
566 msg->embedded_bytes = embedded_bytes;
567 if (unlikely(embedded_bytes != 0)) {
568 msg->version = XPNET_VERSION_EMBED;
569 dev_dbg(xpnet, "calling memcpy(0x%p, 0x%p, 0x%lx)\n",
570 &msg->data, skb->data, (size_t) embedded_bytes);
571 memcpy(&msg->data, skb->data, (size_t) embedded_bytes);
572 } else {
573 msg->version = XPNET_VERSION;
574 }
575 msg->magic = XPNET_MAGIC;
576 msg->size = end_addr - start_addr;
577 msg->leadin_ignore = (u64) skb->data - start_addr;
578 msg->tailout_ignore = end_addr - (u64) skb->tail;
579 msg->buf_pa = __pa(start_addr);
580
581 dev_dbg(xpnet, "sending XPC message to %d:%d\nmsg->buf_pa="
582 "0x%lx, msg->size=%u, msg->leadin_ignore=%u, "
583 "msg->tailout_ignore=%u\n", dest_partid,
584 XPC_NET_CHANNEL, msg->buf_pa, msg->size,
585 msg->leadin_ignore, msg->tailout_ignore);
586
587
588 atomic_inc(&queued_msg->use_count);
589
590 ret = xpc_send_notify(dest_partid, XPC_NET_CHANNEL, msg,
591 xpnet_send_completed, queued_msg);
592 if (unlikely(ret != xpcSuccess)) {
593 atomic_dec(&queued_msg->use_count);
594 continue;
595 }
596
597 }
598
599 if (atomic_dec_return(&queued_msg->use_count) == 0) {
600 dev_dbg(xpnet, "no partitions to receive packet destined for "
601 "%d\n", dest_partid);
602
603
604 dev_kfree_skb(skb);
605 kfree(queued_msg);
606 }
607
608 priv->stats.tx_packets++;
609 priv->stats.tx_bytes += skb->len;
610
611 return 0;
612}
613
614
615/*
616 * Deal with transmit timeouts coming from the network layer.
617 */
618static void
619xpnet_dev_tx_timeout (struct net_device *dev)
620{
621 struct xpnet_dev_private *priv;
622
623
624 priv = (struct xpnet_dev_private *) dev->priv;
625
626 priv->stats.tx_errors++;
627 return;
628}
629
630
631static int __init
632xpnet_init(void)
633{
634 int i;
635 u32 license_num;
636 int result = -ENOMEM;
637
638
639 dev_info(xpnet, "registering network device %s\n", XPNET_DEVICE_NAME);
640
641 /*
642 * use ether_setup() to init the majority of our device
643 * structure and then override the necessary pieces.
644 */
645 xpnet_device = alloc_netdev(sizeof(struct xpnet_dev_private),
646 XPNET_DEVICE_NAME, ether_setup);
647 if (xpnet_device == NULL) {
648 return -ENOMEM;
649 }
650
651 netif_carrier_off(xpnet_device);
652
653 xpnet_device->mtu = XPNET_DEF_MTU;
654 xpnet_device->change_mtu = xpnet_dev_change_mtu;
655 xpnet_device->open = xpnet_dev_open;
656 xpnet_device->get_stats = xpnet_dev_get_stats;
657 xpnet_device->stop = xpnet_dev_stop;
658 xpnet_device->hard_start_xmit = xpnet_dev_hard_start_xmit;
659 xpnet_device->tx_timeout = xpnet_dev_tx_timeout;
660 xpnet_device->set_config = xpnet_dev_set_config;
661
662 /*
663 * Multicast assumes the LSB of the first octet is set for multicast
664 * MAC addresses. We chose the first octet of the MAC to be unlikely
665 * to collide with any vendor's officially issued MAC.
666 */
667 xpnet_device->dev_addr[0] = 0xfe;
668 xpnet_device->dev_addr[XPNET_PARTID_OCTET] = sn_partition_id;
669 license_num = sn_partition_serial_number_val();
670 for (i = 3; i >= 0; i--) {
671 xpnet_device->dev_addr[XPNET_LICENSE_OCTET + i] =
672 license_num & 0xff;
673 license_num = license_num >> 8;
674 }
675
676 /*
677 * ether_setup() sets this to a multicast device. We are
678 * really not supporting multicast at this time.
679 */
680 xpnet_device->flags &= ~IFF_MULTICAST;
681
682 /*
683 * No need to checksum as it is a DMA transfer. The BTE will
684 * report an error if the data is not retrievable and the
685 * packet will be dropped.
686 */
687 xpnet_device->features = NETIF_F_NO_CSUM;
688
689 result = register_netdev(xpnet_device);
690 if (result != 0) {
691 free_netdev(xpnet_device);
692 }
693
694 return result;
695}
696module_init(xpnet_init);
697
698
699static void __exit
700xpnet_exit(void)
701{
702 dev_info(xpnet, "unregistering network device %s\n",
703 xpnet_device[0].name);
704
705 unregister_netdev(xpnet_device);
706
707 free_netdev(xpnet_device);
708}
709module_exit(xpnet_exit);
710
711
712MODULE_AUTHOR("Silicon Graphics, Inc.");
713MODULE_DESCRIPTION("Cross Partition Network adapter (XPNET)");
714MODULE_LICENSE("GPL");
715
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
index c90685985d81..64af2b2c1787 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
@@ -301,7 +301,7 @@ void sn_dma_flush(uint64_t addr)
301 spin_lock_irqsave(&((struct sn_flush_device_list *)p)-> 301 spin_lock_irqsave(&((struct sn_flush_device_list *)p)->
302 sfdl_flush_lock, flags); 302 sfdl_flush_lock, flags);
303 303
304 p->sfdl_flush_value = 0; 304 *p->sfdl_flush_addr = 0;
305 305
306 /* force an interrupt. */ 306 /* force an interrupt. */
307 *(volatile uint32_t *)(p->sfdl_force_int_addr) = 1; 307 *(volatile uint32_t *)(p->sfdl_force_int_addr) = 1;
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c
index 54a0dd447e76..8dae9eb45456 100644
--- a/arch/ia64/sn/pci/tioca_provider.c
+++ b/arch/ia64/sn/pci/tioca_provider.c
@@ -431,7 +431,7 @@ tioca_dma_mapped(struct pci_dev *pdev, uint64_t paddr, size_t req_size)
431 ca_dmamap->cad_dma_addr = bus_addr; 431 ca_dmamap->cad_dma_addr = bus_addr;
432 ca_dmamap->cad_gart_size = entries; 432 ca_dmamap->cad_gart_size = entries;
433 ca_dmamap->cad_gart_entry = entry; 433 ca_dmamap->cad_gart_entry = entry;
434 list_add(&ca_dmamap->cad_list, &tioca_kern->ca_list); 434 list_add(&ca_dmamap->cad_list, &tioca_kern->ca_dmamaps);
435 435
436 if (xio_addr % ps) { 436 if (xio_addr % ps) {
437 tioca_kern->ca_pcigart[entry] = tioca_paddr_to_gart(xio_addr); 437 tioca_kern->ca_pcigart[entry] = tioca_paddr_to_gart(xio_addr);
diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig
index 7dbf997ff205..5649fbae430e 100644
--- a/arch/m68k/configs/amiga_defconfig
+++ b/arch/m68k/configs/amiga_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc2-m68k 3# Linux kernel version: 2.6.12-rc6-m68k
4# Tue Apr 5 14:05:59 2005 4# Tue Jun 7 20:34:23 2005
5# 5#
6CONFIG_M68K=y 6CONFIG_M68K=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
35CONFIG_KALLSYMS=y 35CONFIG_KALLSYMS=y
36# CONFIG_KALLSYMS_ALL is not set 36# CONFIG_KALLSYMS_ALL is not set
37# CONFIG_KALLSYMS_EXTRA_PASS is not set 37# CONFIG_KALLSYMS_EXTRA_PASS is not set
38CONFIG_PRINTK=y
39CONFIG_BUG=y
38CONFIG_BASE_FULL=y 40CONFIG_BASE_FULL=y
39CONFIG_FUTEX=y 41CONFIG_FUTEX=y
40CONFIG_EPOLL=y 42CONFIG_EPOLL=y
@@ -135,7 +137,6 @@ CONFIG_PARPORT_1284=y
135# 137#
136CONFIG_AMIGA_FLOPPY=y 138CONFIG_AMIGA_FLOPPY=y
137CONFIG_AMIGA_Z2RAM=y 139CONFIG_AMIGA_Z2RAM=y
138# CONFIG_BLK_DEV_XD is not set
139# CONFIG_PARIDE is not set 140# CONFIG_PARIDE is not set
140# CONFIG_BLK_DEV_COW_COMMON is not set 141# CONFIG_BLK_DEV_COW_COMMON is not set
141CONFIG_BLK_DEV_LOOP=y 142CONFIG_BLK_DEV_LOOP=y
@@ -223,17 +224,12 @@ CONFIG_SCSI_CONSTANTS=y
223# 224#
224# SCSI low-level drivers 225# SCSI low-level drivers
225# 226#
226# CONFIG_SCSI_7000FASST is not set
227# CONFIG_SCSI_AHA152X is not set 227# CONFIG_SCSI_AHA152X is not set
228# CONFIG_SCSI_AHA1542 is not set
229# CONFIG_SCSI_AIC7XXX_OLD is not set 228# CONFIG_SCSI_AIC7XXX_OLD is not set
230# CONFIG_SCSI_IN2000 is not set 229# CONFIG_SCSI_IN2000 is not set
231# CONFIG_SCSI_SATA is not set 230# CONFIG_SCSI_SATA is not set
232# CONFIG_SCSI_BUSLOGIC is not set
233# CONFIG_SCSI_DTC3280 is not set 231# CONFIG_SCSI_DTC3280 is not set
234# CONFIG_SCSI_EATA is not set
235# CONFIG_SCSI_FUTURE_DOMAIN is not set 232# CONFIG_SCSI_FUTURE_DOMAIN is not set
236# CONFIG_SCSI_GDTH is not set
237# CONFIG_SCSI_GENERIC_NCR5380 is not set 233# CONFIG_SCSI_GENERIC_NCR5380 is not set
238# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set 234# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
239# CONFIG_SCSI_PPA is not set 235# CONFIG_SCSI_PPA is not set
@@ -244,7 +240,6 @@ CONFIG_SCSI_CONSTANTS=y
244# CONFIG_SCSI_QLOGIC_FAS is not set 240# CONFIG_SCSI_QLOGIC_FAS is not set
245# CONFIG_SCSI_SYM53C416 is not set 241# CONFIG_SCSI_SYM53C416 is not set
246# CONFIG_SCSI_T128 is not set 242# CONFIG_SCSI_T128 is not set
247# CONFIG_SCSI_U14_34F is not set
248# CONFIG_SCSI_DEBUG is not set 243# CONFIG_SCSI_DEBUG is not set
249CONFIG_A3000_SCSI=y 244CONFIG_A3000_SCSI=y
250CONFIG_A2091_SCSI=y 245CONFIG_A2091_SCSI=y
@@ -492,7 +487,6 @@ CONFIG_HYDRA=m
492CONFIG_ZORRO8390=m 487CONFIG_ZORRO8390=m
493CONFIG_APNE=m 488CONFIG_APNE=m
494# CONFIG_NET_VENDOR_3COM is not set 489# CONFIG_NET_VENDOR_3COM is not set
495# CONFIG_LANCE is not set
496# CONFIG_NET_VENDOR_SMC is not set 490# CONFIG_NET_VENDOR_SMC is not set
497# CONFIG_NET_VENDOR_RACAL is not set 491# CONFIG_NET_VENDOR_RACAL is not set
498# CONFIG_AT1700 is not set 492# CONFIG_AT1700 is not set
@@ -620,7 +614,6 @@ CONFIG_SERIO_SERPORT=m
620# CONFIG_SERIO_PARKBD is not set 614# CONFIG_SERIO_PARKBD is not set
621# CONFIG_SERIO_RAW is not set 615# CONFIG_SERIO_RAW is not set
622# CONFIG_GAMEPORT is not set 616# CONFIG_GAMEPORT is not set
623CONFIG_SOUND_GAMEPORT=y
624 617
625# 618#
626# Character devices 619# Character devices
diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig
index 505a2968e604..63024b0b7ac3 100644
--- a/arch/m68k/configs/apollo_defconfig
+++ b/arch/m68k/configs/apollo_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc2-m68k 3# Linux kernel version: 2.6.12-rc6-m68k
4# Tue Apr 5 14:06:00 2005 4# Tue Jun 7 20:34:27 2005
5# 5#
6CONFIG_M68K=y 6CONFIG_M68K=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
35CONFIG_KALLSYMS=y 35CONFIG_KALLSYMS=y
36# CONFIG_KALLSYMS_ALL is not set 36# CONFIG_KALLSYMS_ALL is not set
37# CONFIG_KALLSYMS_EXTRA_PASS is not set 37# CONFIG_KALLSYMS_EXTRA_PASS is not set
38CONFIG_PRINTK=y
39CONFIG_BUG=y
38CONFIG_BASE_FULL=y 40CONFIG_BASE_FULL=y
39CONFIG_FUTEX=y 41CONFIG_FUTEX=y
40CONFIG_EPOLL=y 42CONFIG_EPOLL=y
@@ -497,7 +499,6 @@ CONFIG_SERIO_SERPORT=m
497CONFIG_SERIO_LIBPS2=m 499CONFIG_SERIO_LIBPS2=m
498# CONFIG_SERIO_RAW is not set 500# CONFIG_SERIO_RAW is not set
499# CONFIG_GAMEPORT is not set 501# CONFIG_GAMEPORT is not set
500CONFIG_SOUND_GAMEPORT=y
501 502
502# 503#
503# Character devices 504# Character devices
diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig
index 617aa73c3250..6433da2d2ce2 100644
--- a/arch/m68k/configs/atari_defconfig
+++ b/arch/m68k/configs/atari_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc2-m68k 3# Linux kernel version: 2.6.12-rc6-m68k
4# Tue Apr 5 14:06:18 2005 4# Tue Jun 7 20:34:32 2005
5# 5#
6CONFIG_M68K=y 6CONFIG_M68K=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
35CONFIG_KALLSYMS=y 35CONFIG_KALLSYMS=y
36# CONFIG_KALLSYMS_ALL is not set 36# CONFIG_KALLSYMS_ALL is not set
37# CONFIG_KALLSYMS_EXTRA_PASS is not set 37# CONFIG_KALLSYMS_EXTRA_PASS is not set
38CONFIG_PRINTK=y
39CONFIG_BUG=y
38CONFIG_BASE_FULL=y 40CONFIG_BASE_FULL=y
39CONFIG_FUTEX=y 41CONFIG_FUTEX=y
40CONFIG_EPOLL=y 42CONFIG_EPOLL=y
@@ -531,7 +533,6 @@ CONFIG_SERIO_SERPORT=y
531CONFIG_SERIO_LIBPS2=y 533CONFIG_SERIO_LIBPS2=y
532# CONFIG_SERIO_RAW is not set 534# CONFIG_SERIO_RAW is not set
533# CONFIG_GAMEPORT is not set 535# CONFIG_GAMEPORT is not set
534CONFIG_SOUND_GAMEPORT=y
535 536
536# 537#
537# Character devices 538# Character devices
diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig
index b501db51d9ec..da2a23a21463 100644
--- a/arch/m68k/configs/bvme6000_defconfig
+++ b/arch/m68k/configs/bvme6000_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc2-m68k 3# Linux kernel version: 2.6.12-rc6-m68k
4# Tue Apr 5 14:06:19 2005 4# Tue Jun 7 20:34:37 2005
5# 5#
6CONFIG_M68K=y 6CONFIG_M68K=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
35CONFIG_KALLSYMS=y 35CONFIG_KALLSYMS=y
36# CONFIG_KALLSYMS_ALL is not set 36# CONFIG_KALLSYMS_ALL is not set
37# CONFIG_KALLSYMS_EXTRA_PASS is not set 37# CONFIG_KALLSYMS_EXTRA_PASS is not set
38CONFIG_PRINTK=y
39CONFIG_BUG=y
38CONFIG_BASE_FULL=y 40CONFIG_BASE_FULL=y
39CONFIG_FUTEX=y 41CONFIG_FUTEX=y
40CONFIG_EPOLL=y 42CONFIG_EPOLL=y
@@ -496,7 +498,6 @@ CONFIG_SERIO_SERPORT=m
496CONFIG_SERIO_LIBPS2=m 498CONFIG_SERIO_LIBPS2=m
497# CONFIG_SERIO_RAW is not set 499# CONFIG_SERIO_RAW is not set
498# CONFIG_GAMEPORT is not set 500# CONFIG_GAMEPORT is not set
499CONFIG_SOUND_GAMEPORT=y
500 501
501# 502#
502# Character devices 503# Character devices
diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig
index 2bf6cef4f2b2..51251883adf8 100644
--- a/arch/m68k/configs/hp300_defconfig
+++ b/arch/m68k/configs/hp300_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc2-m68k 3# Linux kernel version: 2.6.12-rc6-m68k
4# Tue Apr 5 14:06:21 2005 4# Tue Jun 7 20:34:41 2005
5# 5#
6CONFIG_M68K=y 6CONFIG_M68K=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
35CONFIG_KALLSYMS=y 35CONFIG_KALLSYMS=y
36# CONFIG_KALLSYMS_ALL is not set 36# CONFIG_KALLSYMS_ALL is not set
37# CONFIG_KALLSYMS_EXTRA_PASS is not set 37# CONFIG_KALLSYMS_EXTRA_PASS is not set
38CONFIG_PRINTK=y
39CONFIG_BUG=y
38CONFIG_BASE_FULL=y 40CONFIG_BASE_FULL=y
39CONFIG_FUTEX=y 41CONFIG_FUTEX=y
40CONFIG_EPOLL=y 42CONFIG_EPOLL=y
@@ -498,7 +500,6 @@ CONFIG_SERIO_SERPORT=m
498CONFIG_SERIO_LIBPS2=m 500CONFIG_SERIO_LIBPS2=m
499# CONFIG_SERIO_RAW is not set 501# CONFIG_SERIO_RAW is not set
500# CONFIG_GAMEPORT is not set 502# CONFIG_GAMEPORT is not set
501CONFIG_SOUND_GAMEPORT=y
502 503
503# 504#
504# Character devices 505# Character devices
diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig
index 7074f856820c..15b80abfe94a 100644
--- a/arch/m68k/configs/mac_defconfig
+++ b/arch/m68k/configs/mac_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc2-m68k 3# Linux kernel version: 2.6.12-rc6-m68k
4# Tue Apr 5 14:06:24 2005 4# Tue Jun 7 20:34:45 2005
5# 5#
6CONFIG_M68K=y 6CONFIG_M68K=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
35CONFIG_KALLSYMS=y 35CONFIG_KALLSYMS=y
36# CONFIG_KALLSYMS_ALL is not set 36# CONFIG_KALLSYMS_ALL is not set
37# CONFIG_KALLSYMS_EXTRA_PASS is not set 37# CONFIG_KALLSYMS_EXTRA_PASS is not set
38CONFIG_PRINTK=y
39CONFIG_BUG=y
38CONFIG_BASE_FULL=y 40CONFIG_BASE_FULL=y
39CONFIG_FUTEX=y 41CONFIG_FUTEX=y
40CONFIG_EPOLL=y 42CONFIG_EPOLL=y
@@ -540,7 +542,6 @@ CONFIG_SERIO_SERPORT=m
540CONFIG_SERIO_LIBPS2=m 542CONFIG_SERIO_LIBPS2=m
541# CONFIG_SERIO_RAW is not set 543# CONFIG_SERIO_RAW is not set
542# CONFIG_GAMEPORT is not set 544# CONFIG_GAMEPORT is not set
543CONFIG_SOUND_GAMEPORT=y
544 545
545# 546#
546# Character devices 547# Character devices
diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig
index 61f09bc4846a..f0d5534f6830 100644
--- a/arch/m68k/configs/mvme147_defconfig
+++ b/arch/m68k/configs/mvme147_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc2-m68k 3# Linux kernel version: 2.6.12-rc6-m68k
4# Tue Apr 5 14:06:28 2005 4# Tue Jun 7 20:34:50 2005
5# 5#
6CONFIG_M68K=y 6CONFIG_M68K=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
35CONFIG_KALLSYMS=y 35CONFIG_KALLSYMS=y
36# CONFIG_KALLSYMS_ALL is not set 36# CONFIG_KALLSYMS_ALL is not set
37# CONFIG_KALLSYMS_EXTRA_PASS is not set 37# CONFIG_KALLSYMS_EXTRA_PASS is not set
38CONFIG_PRINTK=y
39CONFIG_BUG=y
38CONFIG_BASE_FULL=y 40CONFIG_BASE_FULL=y
39CONFIG_FUTEX=y 41CONFIG_FUTEX=y
40CONFIG_EPOLL=y 42CONFIG_EPOLL=y
@@ -498,7 +500,6 @@ CONFIG_SERIO_SERPORT=m
498CONFIG_SERIO_LIBPS2=m 500CONFIG_SERIO_LIBPS2=m
499# CONFIG_SERIO_RAW is not set 501# CONFIG_SERIO_RAW is not set
500# CONFIG_GAMEPORT is not set 502# CONFIG_GAMEPORT is not set
501CONFIG_SOUND_GAMEPORT=y
502 503
503# 504#
504# Character devices 505# Character devices
diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig
index 69c01004ec41..1d5c46ff3c81 100644
--- a/arch/m68k/configs/mvme16x_defconfig
+++ b/arch/m68k/configs/mvme16x_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc2-m68k 3# Linux kernel version: 2.6.12-rc6-m68k
4# Tue Apr 5 14:06:31 2005 4# Tue Jun 7 20:34:53 2005
5# 5#
6CONFIG_M68K=y 6CONFIG_M68K=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
35CONFIG_KALLSYMS=y 35CONFIG_KALLSYMS=y
36# CONFIG_KALLSYMS_ALL is not set 36# CONFIG_KALLSYMS_ALL is not set
37# CONFIG_KALLSYMS_EXTRA_PASS is not set 37# CONFIG_KALLSYMS_EXTRA_PASS is not set
38CONFIG_PRINTK=y
39CONFIG_BUG=y
38CONFIG_BASE_FULL=y 40CONFIG_BASE_FULL=y
39CONFIG_FUTEX=y 41CONFIG_FUTEX=y
40CONFIG_EPOLL=y 42CONFIG_EPOLL=y
@@ -497,7 +499,6 @@ CONFIG_SERIO_SERPORT=m
497CONFIG_SERIO_LIBPS2=m 499CONFIG_SERIO_LIBPS2=m
498# CONFIG_SERIO_RAW is not set 500# CONFIG_SERIO_RAW is not set
499# CONFIG_GAMEPORT is not set 501# CONFIG_GAMEPORT is not set
500CONFIG_SOUND_GAMEPORT=y
501 502
502# 503#
503# Character devices 504# Character devices
diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig
index 550ec26006c1..856238634d42 100644
--- a/arch/m68k/configs/q40_defconfig
+++ b/arch/m68k/configs/q40_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc2-m68k 3# Linux kernel version: 2.6.12-rc6-m68k
4# Tue Apr 5 14:06:34 2005 4# Tue Jun 7 20:34:58 2005
5# 5#
6CONFIG_M68K=y 6CONFIG_M68K=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
35CONFIG_KALLSYMS=y 35CONFIG_KALLSYMS=y
36# CONFIG_KALLSYMS_ALL is not set 36# CONFIG_KALLSYMS_ALL is not set
37# CONFIG_KALLSYMS_EXTRA_PASS is not set 37# CONFIG_KALLSYMS_EXTRA_PASS is not set
38CONFIG_PRINTK=y
39CONFIG_BUG=y
38CONFIG_BASE_FULL=y 40CONFIG_BASE_FULL=y
39CONFIG_FUTEX=y 41CONFIG_FUTEX=y
40CONFIG_EPOLL=y 42CONFIG_EPOLL=y
@@ -125,7 +127,6 @@ CONFIG_FW_LOADER=m
125# Block devices 127# Block devices
126# 128#
127# CONFIG_BLK_DEV_FD is not set 129# CONFIG_BLK_DEV_FD is not set
128# CONFIG_BLK_DEV_XD is not set
129# CONFIG_BLK_DEV_COW_COMMON is not set 130# CONFIG_BLK_DEV_COW_COMMON is not set
130CONFIG_BLK_DEV_LOOP=y 131CONFIG_BLK_DEV_LOOP=y
131CONFIG_BLK_DEV_CRYPTOLOOP=m 132CONFIG_BLK_DEV_CRYPTOLOOP=m
@@ -210,17 +211,12 @@ CONFIG_SCSI_CONSTANTS=y
210# 211#
211# SCSI low-level drivers 212# SCSI low-level drivers
212# 213#
213# CONFIG_SCSI_7000FASST is not set
214# CONFIG_SCSI_AHA152X is not set 214# CONFIG_SCSI_AHA152X is not set
215# CONFIG_SCSI_AHA1542 is not set
216# CONFIG_SCSI_AIC7XXX_OLD is not set 215# CONFIG_SCSI_AIC7XXX_OLD is not set
217# CONFIG_SCSI_IN2000 is not set 216# CONFIG_SCSI_IN2000 is not set
218# CONFIG_SCSI_SATA is not set 217# CONFIG_SCSI_SATA is not set
219# CONFIG_SCSI_BUSLOGIC is not set
220# CONFIG_SCSI_DTC3280 is not set 218# CONFIG_SCSI_DTC3280 is not set
221# CONFIG_SCSI_EATA is not set
222# CONFIG_SCSI_FUTURE_DOMAIN is not set 219# CONFIG_SCSI_FUTURE_DOMAIN is not set
223# CONFIG_SCSI_GDTH is not set
224# CONFIG_SCSI_GENERIC_NCR5380 is not set 220# CONFIG_SCSI_GENERIC_NCR5380 is not set
225# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set 221# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
226# CONFIG_SCSI_NCR53C406A is not set 222# CONFIG_SCSI_NCR53C406A is not set
@@ -229,7 +225,6 @@ CONFIG_SCSI_CONSTANTS=y
229# CONFIG_SCSI_QLOGIC_FAS is not set 225# CONFIG_SCSI_QLOGIC_FAS is not set
230# CONFIG_SCSI_SYM53C416 is not set 226# CONFIG_SCSI_SYM53C416 is not set
231# CONFIG_SCSI_T128 is not set 227# CONFIG_SCSI_T128 is not set
232# CONFIG_SCSI_U14_34F is not set
233# CONFIG_SCSI_DEBUG is not set 228# CONFIG_SCSI_DEBUG is not set
234 229
235# 230#
@@ -466,7 +461,6 @@ CONFIG_EQUALIZER=m
466CONFIG_NET_ETHERNET=y 461CONFIG_NET_ETHERNET=y
467CONFIG_MII=m 462CONFIG_MII=m
468# CONFIG_NET_VENDOR_3COM is not set 463# CONFIG_NET_VENDOR_3COM is not set
469# CONFIG_LANCE is not set
470# CONFIG_NET_VENDOR_SMC is not set 464# CONFIG_NET_VENDOR_SMC is not set
471# CONFIG_NET_VENDOR_RACAL is not set 465# CONFIG_NET_VENDOR_RACAL is not set
472# CONFIG_AT1700 is not set 466# CONFIG_AT1700 is not set
@@ -570,7 +564,6 @@ CONFIG_SERIO_Q40KBD=m
570CONFIG_SERIO_LIBPS2=m 564CONFIG_SERIO_LIBPS2=m
571# CONFIG_SERIO_RAW is not set 565# CONFIG_SERIO_RAW is not set
572# CONFIG_GAMEPORT is not set 566# CONFIG_GAMEPORT is not set
573CONFIG_SOUND_GAMEPORT=y
574 567
575# 568#
576# Character devices 569# Character devices
diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig
index 5b5a619645aa..af903b5c5708 100644
--- a/arch/m68k/configs/sun3_defconfig
+++ b/arch/m68k/configs/sun3_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc2-m68k 3# Linux kernel version: 2.6.12-rc6-m68k
4# Tue Apr 5 14:06:37 2005 4# Tue Jun 7 20:35:02 2005
5# 5#
6CONFIG_M68K=y 6CONFIG_M68K=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
35CONFIG_KALLSYMS=y 35CONFIG_KALLSYMS=y
36# CONFIG_KALLSYMS_ALL is not set 36# CONFIG_KALLSYMS_ALL is not set
37# CONFIG_KALLSYMS_EXTRA_PASS is not set 37# CONFIG_KALLSYMS_EXTRA_PASS is not set
38CONFIG_PRINTK=y
39CONFIG_BUG=y
38CONFIG_BASE_FULL=y 40CONFIG_BASE_FULL=y
39CONFIG_FUTEX=y 41CONFIG_FUTEX=y
40CONFIG_EPOLL=y 42CONFIG_EPOLL=y
@@ -171,7 +173,6 @@ CONFIG_SCSI_CONSTANTS=y
171# 173#
172# CONFIG_SCSI_SATA is not set 174# CONFIG_SCSI_SATA is not set
173# CONFIG_SCSI_DEBUG is not set 175# CONFIG_SCSI_DEBUG is not set
174CONFIG_SUN3_SCSI=y
175 176
176# 177#
177# Multi-device support (RAID and LVM) 178# Multi-device support (RAID and LVM)
@@ -487,7 +488,6 @@ CONFIG_SERIO_SERPORT=m
487CONFIG_SERIO_LIBPS2=m 488CONFIG_SERIO_LIBPS2=m
488# CONFIG_SERIO_RAW is not set 489# CONFIG_SERIO_RAW is not set
489# CONFIG_GAMEPORT is not set 490# CONFIG_GAMEPORT is not set
490CONFIG_SOUND_GAMEPORT=y
491 491
492# 492#
493# Character devices 493# Character devices
diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig
index 704e42344cba..997143b7928a 100644
--- a/arch/m68k/configs/sun3x_defconfig
+++ b/arch/m68k/configs/sun3x_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc2-m68k 3# Linux kernel version: 2.6.12-rc6-m68k
4# Tue Apr 5 14:06:40 2005 4# Tue Jun 7 20:35:06 2005
5# 5#
6CONFIG_M68K=y 6CONFIG_M68K=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
35CONFIG_KALLSYMS=y 35CONFIG_KALLSYMS=y
36# CONFIG_KALLSYMS_ALL is not set 36# CONFIG_KALLSYMS_ALL is not set
37# CONFIG_KALLSYMS_EXTRA_PASS is not set 37# CONFIG_KALLSYMS_EXTRA_PASS is not set
38CONFIG_PRINTK=y
39CONFIG_BUG=y
38CONFIG_BASE_FULL=y 40CONFIG_BASE_FULL=y
39CONFIG_FUTEX=y 41CONFIG_FUTEX=y
40CONFIG_EPOLL=y 42CONFIG_EPOLL=y
@@ -497,7 +499,6 @@ CONFIG_SERIO_SERPORT=m
497CONFIG_SERIO_LIBPS2=m 499CONFIG_SERIO_LIBPS2=m
498# CONFIG_SERIO_RAW is not set 500# CONFIG_SERIO_RAW is not set
499# CONFIG_GAMEPORT is not set 501# CONFIG_GAMEPORT is not set
500CONFIG_SOUND_GAMEPORT=y
501 502
502# 503#
503# Character devices 504# Character devices
diff --git a/arch/m68k/defconfig b/arch/m68k/defconfig
index 5b2296ecba82..7d935e48a9a8 100644
--- a/arch/m68k/defconfig
+++ b/arch/m68k/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc2-m68k 3# Linux kernel version: 2.6.12-rc6-m68k
4# Tue Apr 5 14:05:31 2005 4# Tue Jun 7 20:34:17 2005
5# 5#
6CONFIG_M68K=y 6CONFIG_M68K=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -33,6 +33,8 @@ CONFIG_KOBJECT_UEVENT=y
33# CONFIG_EMBEDDED is not set 33# CONFIG_EMBEDDED is not set
34CONFIG_KALLSYMS=y 34CONFIG_KALLSYMS=y
35# CONFIG_KALLSYMS_EXTRA_PASS is not set 35# CONFIG_KALLSYMS_EXTRA_PASS is not set
36CONFIG_PRINTK=y
37CONFIG_BUG=y
36CONFIG_BASE_FULL=y 38CONFIG_BASE_FULL=y
37CONFIG_FUTEX=y 39CONFIG_FUTEX=y
38CONFIG_EPOLL=y 40CONFIG_EPOLL=y
@@ -355,7 +357,6 @@ CONFIG_SERIO_SERPORT=y
355CONFIG_SERIO_LIBPS2=y 357CONFIG_SERIO_LIBPS2=y
356# CONFIG_SERIO_RAW is not set 358# CONFIG_SERIO_RAW is not set
357# CONFIG_GAMEPORT is not set 359# CONFIG_GAMEPORT is not set
358CONFIG_SOUND_GAMEPORT=y
359 360
360# 361#
361# Character devices 362# Character devices
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index fc4615b6d3a9..e729bd280623 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -534,6 +534,11 @@ endchoice
534 534
535endmenu 535endmenu
536 536
537config ISA_DMA_API
538 bool
539 depends on !M5272
540 default y
541
537menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)" 542menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
538 543
539config PCI 544config PCI
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c
index 2b6c9d32b7a6..c4a33f265dc0 100644
--- a/arch/m68knommu/kernel/process.c
+++ b/arch/m68knommu/kernel/process.c
@@ -45,11 +45,13 @@ asmlinkage void ret_from_fork(void);
45 */ 45 */
46void default_idle(void) 46void default_idle(void)
47{ 47{
48 while(1) { 48 local_irq_disable();
49 if (need_resched()) 49 while (!need_resched()) {
50 __asm__("stop #0x2000" : : : "cc"); 50 /* This stop will re-enable interrupts */
51 schedule(); 51 __asm__("stop #0x2000" : : : "cc");
52 local_irq_disable();
52 } 53 }
54 local_irq_enable();
53} 55}
54 56
55void (*idle)(void) = default_idle; 57void (*idle)(void) = default_idle;
@@ -63,7 +65,12 @@ void (*idle)(void) = default_idle;
63void cpu_idle(void) 65void cpu_idle(void)
64{ 66{
65 /* endless idle loop with no priority at all */ 67 /* endless idle loop with no priority at all */
66 idle(); 68 while (1) {
69 idle();
70 preempt_enable_no_resched();
71 schedule();
72 preempt_disable();
73 }
67} 74}
68 75
69void machine_restart(char * __unused) 76void machine_restart(char * __unused)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 5e666aad8815..ab9944693f1f 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1656,3 +1656,7 @@ config GENERIC_HARDIRQS
1656config GENERIC_IRQ_PROBE 1656config GENERIC_IRQ_PROBE
1657 bool 1657 bool
1658 default y 1658 default y
1659
1660config ISA_DMA_API
1661 bool
1662 default y
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index a2f899c2f4d4..92e70ca3bff9 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -301,25 +301,38 @@ out:
301 return ret; 301 return ret;
302} 302}
303 303
304static inline int audit_arch(void)
305{
306#ifdef CONFIG_CPU_LITTLE_ENDIAN
307#ifdef CONFIG_MIPS64
308 if (!(current->thread.mflags & MF_32BIT_REGS))
309 return AUDIT_ARCH_MIPSEL64;
310#endif /* MIPS64 */
311 return AUDIT_ARCH_MIPSEL;
312
313#else /* big endian... */
314#ifdef CONFIG_MIPS64
315 if (!(current->thread.mflags & MF_32BIT_REGS))
316 return AUDIT_ARCH_MIPS64;
317#endif /* MIPS64 */
318 return AUDIT_ARCH_MIPS;
319
320#endif /* endian */
321}
322
304/* 323/*
305 * Notification of system call entry/exit 324 * Notification of system call entry/exit
306 * - triggered by current->work.syscall_trace 325 * - triggered by current->work.syscall_trace
307 */ 326 */
308asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) 327asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
309{ 328{
310 if (unlikely(current->audit_context)) { 329 if (unlikely(current->audit_context) && entryexit)
311 if (!entryexit) 330 audit_syscall_exit(current, AUDITSC_RESULT(regs->regs[2]), regs->regs[2]);
312 audit_syscall_entry(current, regs->regs[2],
313 regs->regs[4], regs->regs[5],
314 regs->regs[6], regs->regs[7]);
315 else
316 audit_syscall_exit(current, regs->regs[2]);
317 }
318 331
319 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 332 if (!test_thread_flag(TIF_SYSCALL_TRACE))
320 return; 333 goto out;
321 if (!(current->ptrace & PT_PTRACED)) 334 if (!(current->ptrace & PT_PTRACED))
322 return; 335 goto out;
323 336
324 /* The 0x80 provides a way for the tracing parent to distinguish 337 /* The 0x80 provides a way for the tracing parent to distinguish
325 between a syscall stop and SIGTRAP delivery */ 338 between a syscall stop and SIGTRAP delivery */
@@ -335,4 +348,9 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
335 send_sig(current->exit_code, current, 1); 348 send_sig(current->exit_code, current, 1);
336 current->exit_code = 0; 349 current->exit_code = 0;
337 } 350 }
351 out:
352 if (unlikely(current->audit_context) && !entryexit)
353 audit_syscall_entry(current, audit_arch(), regs->regs[2],
354 regs->regs[4], regs->regs[5],
355 regs->regs[6], regs->regs[7]);
338} 356}
diff --git a/arch/mips/vr41xx/common/pmu.c b/arch/mips/vr41xx/common/pmu.c
index c5f1043de938..53166f3598b2 100644
--- a/arch/mips/vr41xx/common/pmu.c
+++ b/arch/mips/vr41xx/common/pmu.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * pmu.c, Power Management Unit routines for NEC VR4100 series. 2 * pmu.c, Power Management Unit routines for NEC VR4100 series.
3 * 3 *
4 * Copyright (C) 2003-2004 Yoichi Yuasa <yuasa@hh.iij4u.or.jp> 4 * Copyright (C) 2003-2005 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -17,7 +17,9 @@
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20#include <linux/errno.h>
20#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/ioport.h>
21#include <linux/kernel.h> 23#include <linux/kernel.h>
22#include <linux/smp.h> 24#include <linux/smp.h>
23#include <linux/types.h> 25#include <linux/types.h>
@@ -27,20 +29,31 @@
27#include <asm/reboot.h> 29#include <asm/reboot.h>
28#include <asm/system.h> 30#include <asm/system.h>
29 31
30#define PMUCNT2REG KSEG1ADDR(0x0f0000c6) 32#define PMU_TYPE1_BASE 0x0b0000a0UL
33#define PMU_TYPE1_SIZE 0x0eUL
34
35#define PMU_TYPE2_BASE 0x0f0000c0UL
36#define PMU_TYPE2_SIZE 0x10UL
37
38#define PMUCNT2REG 0x06
31 #define SOFTRST 0x0010 39 #define SOFTRST 0x0010
32 40
41static void __iomem *pmu_base;
42
43#define pmu_read(offset) readw(pmu_base + (offset))
44#define pmu_write(offset, value) writew((value), pmu_base + (offset))
45
33static inline void software_reset(void) 46static inline void software_reset(void)
34{ 47{
35 uint16_t val; 48 uint16_t pmucnt2;
36 49
37 switch (current_cpu_data.cputype) { 50 switch (current_cpu_data.cputype) {
38 case CPU_VR4122: 51 case CPU_VR4122:
39 case CPU_VR4131: 52 case CPU_VR4131:
40 case CPU_VR4133: 53 case CPU_VR4133:
41 val = readw(PMUCNT2REG); 54 pmucnt2 = pmu_read(PMUCNT2REG);
42 val |= SOFTRST; 55 pmucnt2 |= SOFTRST;
43 writew(val, PMUCNT2REG); 56 pmu_write(PMUCNT2REG, pmucnt2);
44 break; 57 break;
45 default: 58 default:
46 break; 59 break;
@@ -71,6 +84,34 @@ static void vr41xx_power_off(void)
71 84
72static int __init vr41xx_pmu_init(void) 85static int __init vr41xx_pmu_init(void)
73{ 86{
87 unsigned long start, size;
88
89 switch (current_cpu_data.cputype) {
90 case CPU_VR4111:
91 case CPU_VR4121:
92 start = PMU_TYPE1_BASE;
93 size = PMU_TYPE1_SIZE;
94 break;
95 case CPU_VR4122:
96 case CPU_VR4131:
97 case CPU_VR4133:
98 start = PMU_TYPE2_BASE;
99 size = PMU_TYPE2_SIZE;
100 break;
101 default:
102 printk("Unexpected CPU of NEC VR4100 series\n");
103 return -ENODEV;
104 }
105
106 if (request_mem_region(start, size, "PMU") == NULL)
107 return -EBUSY;
108
109 pmu_base = ioremap(start, size);
110 if (pmu_base == NULL) {
111 release_mem_region(start, size);
112 return -EBUSY;
113 }
114
74 _machine_restart = vr41xx_restart; 115 _machine_restart = vr41xx_restart;
75 _machine_halt = vr41xx_halt; 116 _machine_halt = vr41xx_halt;
76 _machine_power_off = vr41xx_power_off; 117 _machine_power_off = vr41xx_power_off;
@@ -78,4 +119,4 @@ static int __init vr41xx_pmu_init(void)
78 return 0; 119 return 0;
79} 120}
80 121
81early_initcall(vr41xx_pmu_init); 122core_initcall(vr41xx_pmu_init);
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 5b5cd00d98ca..e7e7c56fc212 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -45,6 +45,10 @@ config GENERIC_IRQ_PROBE
45config PM 45config PM
46 bool 46 bool
47 47
48config ISA_DMA_API
49 bool
50 default y
51
48source "init/Kconfig" 52source "init/Kconfig"
49 53
50 54
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index c3d941345e3d..6e6377a69d5b 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -43,6 +43,10 @@ config GENERIC_NVRAM
43 bool 43 bool
44 default y 44 default y
45 45
46config SCHED_NO_NO_OMIT_FRAME_POINTER
47 bool
48 default y
49
46source "init/Kconfig" 50source "init/Kconfig"
47 51
48menu "Processor" 52menu "Processor"
@@ -73,9 +77,11 @@ config 44x
73 bool "44x" 77 bool "44x"
74 78
75config POWER3 79config POWER3
80 select PPC_FPU
76 bool "POWER3" 81 bool "POWER3"
77 82
78config POWER4 83config POWER4
84 select PPC_FPU
79 bool "POWER4 and 970 (G5)" 85 bool "POWER4 and 970 (G5)"
80 86
81config 8xx 87config 8xx
@@ -1079,6 +1085,10 @@ source kernel/power/Kconfig
1079 1085
1080endmenu 1086endmenu
1081 1087
1088config ISA_DMA_API
1089 bool
1090 default y
1091
1082menu "Bus options" 1092menu "Bus options"
1083 1093
1084config ISA 1094config ISA
@@ -1133,12 +1143,12 @@ config PCI_QSPAN
1133 1143
1134config PCI_8260 1144config PCI_8260
1135 bool 1145 bool
1136 depends on PCI && 8260 && !8272 1146 depends on PCI && 8260
1137 default y 1147 default y
1138 1148
1139config 8260_PCI9 1149config 8260_PCI9
1140 bool " Enable workaround for MPC826x erratum PCI 9" 1150 bool " Enable workaround for MPC826x erratum PCI 9"
1141 depends on PCI_8260 1151 depends on PCI_8260 && !ADS8272
1142 default y 1152 default y
1143 1153
1144choice 1154choice
diff --git a/arch/ppc/boot/images/Makefile b/arch/ppc/boot/images/Makefile
index f850fb0fb511..c9ac5f5fa9e4 100644
--- a/arch/ppc/boot/images/Makefile
+++ b/arch/ppc/boot/images/Makefile
@@ -22,7 +22,8 @@ targets += uImage
22$(obj)/uImage: $(obj)/vmlinux.gz 22$(obj)/uImage: $(obj)/vmlinux.gz
23 $(Q)rm -f $@ 23 $(Q)rm -f $@
24 $(call if_changed,uimage) 24 $(call if_changed,uimage)
25 @echo ' Image: $@' $(if $(wildcard $@),'is ready','not made') 25 @echo -n ' Image: $@ '
26 @if [ -f $@ ]; then echo 'is ready' ; else echo 'not made'; fi
26 27
27# Files generated that shall be removed upon make clean 28# Files generated that shall be removed upon make clean
28clean-files := sImage vmapus vmlinux* miboot* zImage* uImage 29clean-files := sImage vmapus vmlinux* miboot* zImage* uImage
diff --git a/arch/ppc/configs/mpc8555_cds_defconfig b/arch/ppc/configs/mpc8555_cds_defconfig
index 728bd9e1a8fa..15abebf46b96 100644
--- a/arch/ppc/configs/mpc8555_cds_defconfig
+++ b/arch/ppc/configs/mpc8555_cds_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-rc1 3# Linux kernel version: 2.6.12-rc4
4# Thu Jan 20 01:25:35 2005 4# Tue May 17 11:56:01 2005
5# 5#
6CONFIG_MMU=y 6CONFIG_MMU=y
7CONFIG_GENERIC_HARDIRQS=y 7CONFIG_GENERIC_HARDIRQS=y
@@ -11,6 +11,7 @@ CONFIG_HAVE_DEC_LOCK=y
11CONFIG_PPC=y 11CONFIG_PPC=y
12CONFIG_PPC32=y 12CONFIG_PPC32=y
13CONFIG_GENERIC_NVRAM=y 13CONFIG_GENERIC_NVRAM=y
14CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
14 15
15# 16#
16# Code maturity level options 17# Code maturity level options
@@ -18,6 +19,7 @@ CONFIG_GENERIC_NVRAM=y
18CONFIG_EXPERIMENTAL=y 19CONFIG_EXPERIMENTAL=y
19CONFIG_CLEAN_COMPILE=y 20CONFIG_CLEAN_COMPILE=y
20CONFIG_BROKEN_ON_SMP=y 21CONFIG_BROKEN_ON_SMP=y
22CONFIG_INIT_ENV_ARG_LIMIT=32
21 23
22# 24#
23# General setup 25# General setup
@@ -29,12 +31,14 @@ CONFIG_SYSVIPC=y
29# CONFIG_BSD_PROCESS_ACCT is not set 31# CONFIG_BSD_PROCESS_ACCT is not set
30CONFIG_SYSCTL=y 32CONFIG_SYSCTL=y
31# CONFIG_AUDIT is not set 33# CONFIG_AUDIT is not set
32CONFIG_LOG_BUF_SHIFT=14
33# CONFIG_HOTPLUG is not set 34# CONFIG_HOTPLUG is not set
34CONFIG_KOBJECT_UEVENT=y 35CONFIG_KOBJECT_UEVENT=y
35# CONFIG_IKCONFIG is not set 36# CONFIG_IKCONFIG is not set
36CONFIG_EMBEDDED=y 37CONFIG_EMBEDDED=y
37# CONFIG_KALLSYMS is not set 38# CONFIG_KALLSYMS is not set
39CONFIG_PRINTK=y
40CONFIG_BUG=y
41CONFIG_BASE_FULL=y
38CONFIG_FUTEX=y 42CONFIG_FUTEX=y
39# CONFIG_EPOLL is not set 43# CONFIG_EPOLL is not set
40# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set 44# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -44,6 +48,7 @@ CONFIG_CC_ALIGN_LABELS=0
44CONFIG_CC_ALIGN_LOOPS=0 48CONFIG_CC_ALIGN_LOOPS=0
45CONFIG_CC_ALIGN_JUMPS=0 49CONFIG_CC_ALIGN_JUMPS=0
46# CONFIG_TINY_SHMEM is not set 50# CONFIG_TINY_SHMEM is not set
51CONFIG_BASE_SMALL=0
47 52
48# 53#
49# Loadable module support 54# Loadable module support
@@ -62,10 +67,12 @@ CONFIG_CC_ALIGN_JUMPS=0
62CONFIG_E500=y 67CONFIG_E500=y
63CONFIG_BOOKE=y 68CONFIG_BOOKE=y
64CONFIG_FSL_BOOKE=y 69CONFIG_FSL_BOOKE=y
70# CONFIG_PHYS_64BIT is not set
65CONFIG_SPE=y 71CONFIG_SPE=y
66CONFIG_MATH_EMULATION=y 72CONFIG_MATH_EMULATION=y
67# CONFIG_CPU_FREQ is not set 73# CONFIG_CPU_FREQ is not set
68CONFIG_PPC_GEN550=y 74CONFIG_PPC_GEN550=y
75# CONFIG_PM is not set
69CONFIG_85xx=y 76CONFIG_85xx=y
70CONFIG_PPC_INDIRECT_PCI_BE=y 77CONFIG_PPC_INDIRECT_PCI_BE=y
71 78
@@ -76,6 +83,7 @@ CONFIG_PPC_INDIRECT_PCI_BE=y
76CONFIG_MPC8555_CDS=y 83CONFIG_MPC8555_CDS=y
77# CONFIG_MPC8560_ADS is not set 84# CONFIG_MPC8560_ADS is not set
78# CONFIG_SBC8560 is not set 85# CONFIG_SBC8560 is not set
86# CONFIG_STX_GP3 is not set
79CONFIG_MPC8555=y 87CONFIG_MPC8555=y
80CONFIG_85xx_PCI2=y 88CONFIG_85xx_PCI2=y
81 89
@@ -90,6 +98,7 @@ CONFIG_CPM2=y
90CONFIG_BINFMT_ELF=y 98CONFIG_BINFMT_ELF=y
91# CONFIG_BINFMT_MISC is not set 99# CONFIG_BINFMT_MISC is not set
92# CONFIG_CMDLINE_BOOL is not set 100# CONFIG_CMDLINE_BOOL is not set
101CONFIG_ISA_DMA_API=y
93 102
94# 103#
95# Bus options 104# Bus options
@@ -105,10 +114,6 @@ CONFIG_PCI_NAMES=y
105# CONFIG_PCCARD is not set 114# CONFIG_PCCARD is not set
106 115
107# 116#
108# PC-card bridges
109#
110
111#
112# Advanced setup 117# Advanced setup
113# 118#
114# CONFIG_ADVANCED_OPTIONS is not set 119# CONFIG_ADVANCED_OPTIONS is not set
@@ -180,7 +185,59 @@ CONFIG_IOSCHED_CFQ=y
180# 185#
181# ATA/ATAPI/MFM/RLL support 186# ATA/ATAPI/MFM/RLL support
182# 187#
183# CONFIG_IDE is not set 188CONFIG_IDE=y
189CONFIG_BLK_DEV_IDE=y
190
191#
192# Please see Documentation/ide.txt for help/info on IDE drives
193#
194# CONFIG_BLK_DEV_IDE_SATA is not set
195CONFIG_BLK_DEV_IDEDISK=y
196# CONFIG_IDEDISK_MULTI_MODE is not set
197# CONFIG_BLK_DEV_IDECD is not set
198# CONFIG_BLK_DEV_IDETAPE is not set
199# CONFIG_BLK_DEV_IDEFLOPPY is not set
200# CONFIG_IDE_TASK_IOCTL is not set
201
202#
203# IDE chipset support/bugfixes
204#
205CONFIG_IDE_GENERIC=y
206CONFIG_BLK_DEV_IDEPCI=y
207CONFIG_IDEPCI_SHARE_IRQ=y
208# CONFIG_BLK_DEV_OFFBOARD is not set
209CONFIG_BLK_DEV_GENERIC=y
210# CONFIG_BLK_DEV_OPTI621 is not set
211# CONFIG_BLK_DEV_SL82C105 is not set
212CONFIG_BLK_DEV_IDEDMA_PCI=y
213# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
214CONFIG_IDEDMA_PCI_AUTO=y
215# CONFIG_IDEDMA_ONLYDISK is not set
216# CONFIG_BLK_DEV_AEC62XX is not set
217# CONFIG_BLK_DEV_ALI15X3 is not set
218# CONFIG_BLK_DEV_AMD74XX is not set
219# CONFIG_BLK_DEV_CMD64X is not set
220# CONFIG_BLK_DEV_TRIFLEX is not set
221# CONFIG_BLK_DEV_CY82C693 is not set
222# CONFIG_BLK_DEV_CS5520 is not set
223# CONFIG_BLK_DEV_CS5530 is not set
224# CONFIG_BLK_DEV_HPT34X is not set
225# CONFIG_BLK_DEV_HPT366 is not set
226# CONFIG_BLK_DEV_SC1200 is not set
227# CONFIG_BLK_DEV_PIIX is not set
228# CONFIG_BLK_DEV_NS87415 is not set
229# CONFIG_BLK_DEV_PDC202XX_OLD is not set
230# CONFIG_BLK_DEV_PDC202XX_NEW is not set
231# CONFIG_BLK_DEV_SVWKS is not set
232# CONFIG_BLK_DEV_SIIMAGE is not set
233# CONFIG_BLK_DEV_SLC90E66 is not set
234# CONFIG_BLK_DEV_TRM290 is not set
235CONFIG_BLK_DEV_VIA82CXXX=y
236# CONFIG_IDE_ARM is not set
237CONFIG_BLK_DEV_IDEDMA=y
238# CONFIG_IDEDMA_IVB is not set
239CONFIG_IDEDMA_AUTO=y
240# CONFIG_BLK_DEV_HD is not set
184 241
185# 242#
186# SCSI device support 243# SCSI device support
@@ -220,7 +277,6 @@ CONFIG_NET=y
220# 277#
221CONFIG_PACKET=y 278CONFIG_PACKET=y
222# CONFIG_PACKET_MMAP is not set 279# CONFIG_PACKET_MMAP is not set
223# CONFIG_NETLINK_DEV is not set
224CONFIG_UNIX=y 280CONFIG_UNIX=y
225# CONFIG_NET_KEY is not set 281# CONFIG_NET_KEY is not set
226CONFIG_INET=y 282CONFIG_INET=y
@@ -370,14 +426,6 @@ CONFIG_INPUT=y
370# CONFIG_INPUT_EVBUG is not set 426# CONFIG_INPUT_EVBUG is not set
371 427
372# 428#
373# Input I/O drivers
374#
375# CONFIG_GAMEPORT is not set
376CONFIG_SOUND_GAMEPORT=y
377# CONFIG_SERIO is not set
378# CONFIG_SERIO_I8042 is not set
379
380#
381# Input Device Drivers 429# Input Device Drivers
382# 430#
383# CONFIG_INPUT_KEYBOARD is not set 431# CONFIG_INPUT_KEYBOARD is not set
@@ -387,6 +435,13 @@ CONFIG_SOUND_GAMEPORT=y
387# CONFIG_INPUT_MISC is not set 435# CONFIG_INPUT_MISC is not set
388 436
389# 437#
438# Hardware I/O ports
439#
440# CONFIG_SERIO is not set
441# CONFIG_GAMEPORT is not set
442CONFIG_SOUND_GAMEPORT=y
443
444#
390# Character devices 445# Character devices
391# 446#
392# CONFIG_VT is not set 447# CONFIG_VT is not set
@@ -406,6 +461,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
406CONFIG_SERIAL_CORE=y 461CONFIG_SERIAL_CORE=y
407CONFIG_SERIAL_CORE_CONSOLE=y 462CONFIG_SERIAL_CORE_CONSOLE=y
408# CONFIG_SERIAL_CPM is not set 463# CONFIG_SERIAL_CPM is not set
464# CONFIG_SERIAL_JSM is not set
409CONFIG_UNIX98_PTYS=y 465CONFIG_UNIX98_PTYS=y
410CONFIG_LEGACY_PTYS=y 466CONFIG_LEGACY_PTYS=y
411CONFIG_LEGACY_PTY_COUNT=256 467CONFIG_LEGACY_PTY_COUNT=256
@@ -434,6 +490,11 @@ CONFIG_GEN_RTC=y
434# CONFIG_RAW_DRIVER is not set 490# CONFIG_RAW_DRIVER is not set
435 491
436# 492#
493# TPM devices
494#
495# CONFIG_TCG_TPM is not set
496
497#
437# I2C support 498# I2C support
438# 499#
439CONFIG_I2C=y 500CONFIG_I2C=y
@@ -456,11 +517,11 @@ CONFIG_I2C_CHARDEV=y
456# CONFIG_I2C_AMD8111 is not set 517# CONFIG_I2C_AMD8111 is not set
457# CONFIG_I2C_I801 is not set 518# CONFIG_I2C_I801 is not set
458# CONFIG_I2C_I810 is not set 519# CONFIG_I2C_I810 is not set
520# CONFIG_I2C_PIIX4 is not set
459# CONFIG_I2C_ISA is not set 521# CONFIG_I2C_ISA is not set
460CONFIG_I2C_MPC=y 522CONFIG_I2C_MPC=y
461# CONFIG_I2C_NFORCE2 is not set 523# CONFIG_I2C_NFORCE2 is not set
462# CONFIG_I2C_PARPORT_LIGHT is not set 524# CONFIG_I2C_PARPORT_LIGHT is not set
463# CONFIG_I2C_PIIX4 is not set
464# CONFIG_I2C_PROSAVAGE is not set 525# CONFIG_I2C_PROSAVAGE is not set
465# CONFIG_I2C_SAVAGE4 is not set 526# CONFIG_I2C_SAVAGE4 is not set
466# CONFIG_SCx200_ACB is not set 527# CONFIG_SCx200_ACB is not set
@@ -483,7 +544,9 @@ CONFIG_I2C_MPC=y
483# CONFIG_SENSORS_ASB100 is not set 544# CONFIG_SENSORS_ASB100 is not set
484# CONFIG_SENSORS_DS1621 is not set 545# CONFIG_SENSORS_DS1621 is not set
485# CONFIG_SENSORS_FSCHER is not set 546# CONFIG_SENSORS_FSCHER is not set
547# CONFIG_SENSORS_FSCPOS is not set
486# CONFIG_SENSORS_GL518SM is not set 548# CONFIG_SENSORS_GL518SM is not set
549# CONFIG_SENSORS_GL520SM is not set
487# CONFIG_SENSORS_IT87 is not set 550# CONFIG_SENSORS_IT87 is not set
488# CONFIG_SENSORS_LM63 is not set 551# CONFIG_SENSORS_LM63 is not set
489# CONFIG_SENSORS_LM75 is not set 552# CONFIG_SENSORS_LM75 is not set
@@ -494,9 +557,11 @@ CONFIG_I2C_MPC=y
494# CONFIG_SENSORS_LM85 is not set 557# CONFIG_SENSORS_LM85 is not set
495# CONFIG_SENSORS_LM87 is not set 558# CONFIG_SENSORS_LM87 is not set
496# CONFIG_SENSORS_LM90 is not set 559# CONFIG_SENSORS_LM90 is not set
560# CONFIG_SENSORS_LM92 is not set
497# CONFIG_SENSORS_MAX1619 is not set 561# CONFIG_SENSORS_MAX1619 is not set
498# CONFIG_SENSORS_PC87360 is not set 562# CONFIG_SENSORS_PC87360 is not set
499# CONFIG_SENSORS_SMSC47B397 is not set 563# CONFIG_SENSORS_SMSC47B397 is not set
564# CONFIG_SENSORS_SIS5595 is not set
500# CONFIG_SENSORS_SMSC47M1 is not set 565# CONFIG_SENSORS_SMSC47M1 is not set
501# CONFIG_SENSORS_VIA686A is not set 566# CONFIG_SENSORS_VIA686A is not set
502# CONFIG_SENSORS_W83781D is not set 567# CONFIG_SENSORS_W83781D is not set
@@ -506,10 +571,12 @@ CONFIG_I2C_MPC=y
506# 571#
507# Other I2C Chip support 572# Other I2C Chip support
508# 573#
574# CONFIG_SENSORS_DS1337 is not set
509# CONFIG_SENSORS_EEPROM is not set 575# CONFIG_SENSORS_EEPROM is not set
510# CONFIG_SENSORS_PCF8574 is not set 576# CONFIG_SENSORS_PCF8574 is not set
511# CONFIG_SENSORS_PCF8591 is not set 577# CONFIG_SENSORS_PCF8591 is not set
512# CONFIG_SENSORS_RTC8564 is not set 578# CONFIG_SENSORS_RTC8564 is not set
579# CONFIG_SENSORS_M41T00 is not set
513# CONFIG_I2C_DEBUG_CORE is not set 580# CONFIG_I2C_DEBUG_CORE is not set
514# CONFIG_I2C_DEBUG_ALGO is not set 581# CONFIG_I2C_DEBUG_ALGO is not set
515# CONFIG_I2C_DEBUG_BUS is not set 582# CONFIG_I2C_DEBUG_BUS is not set
@@ -538,7 +605,6 @@ CONFIG_I2C_MPC=y
538# Graphics support 605# Graphics support
539# 606#
540# CONFIG_FB is not set 607# CONFIG_FB is not set
541# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
542 608
543# 609#
544# Sound 610# Sound
@@ -548,13 +614,9 @@ CONFIG_I2C_MPC=y
548# 614#
549# USB support 615# USB support
550# 616#
551# CONFIG_USB is not set
552CONFIG_USB_ARCH_HAS_HCD=y 617CONFIG_USB_ARCH_HAS_HCD=y
553CONFIG_USB_ARCH_HAS_OHCI=y 618CONFIG_USB_ARCH_HAS_OHCI=y
554 619# CONFIG_USB is not set
555#
556# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
557#
558 620
559# 621#
560# USB Gadget Support 622# USB Gadget Support
@@ -585,6 +647,10 @@ CONFIG_JBD=y
585CONFIG_FS_MBCACHE=y 647CONFIG_FS_MBCACHE=y
586# CONFIG_REISERFS_FS is not set 648# CONFIG_REISERFS_FS is not set
587# CONFIG_JFS_FS is not set 649# CONFIG_JFS_FS is not set
650
651#
652# XFS support
653#
588# CONFIG_XFS_FS is not set 654# CONFIG_XFS_FS is not set
589# CONFIG_MINIX_FS is not set 655# CONFIG_MINIX_FS is not set
590# CONFIG_ROMFS_FS is not set 656# CONFIG_ROMFS_FS is not set
@@ -646,7 +712,6 @@ CONFIG_NFS_FS=y
646# CONFIG_NFSD is not set 712# CONFIG_NFSD is not set
647CONFIG_ROOT_NFS=y 713CONFIG_ROOT_NFS=y
648CONFIG_LOCKD=y 714CONFIG_LOCKD=y
649# CONFIG_EXPORTFS is not set
650CONFIG_SUNRPC=y 715CONFIG_SUNRPC=y
651# CONFIG_RPCSEC_GSS_KRB5 is not set 716# CONFIG_RPCSEC_GSS_KRB5 is not set
652# CONFIG_RPCSEC_GSS_SPKM3 is not set 717# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -698,7 +763,9 @@ CONFIG_CRC32=y
698# 763#
699# Kernel hacking 764# Kernel hacking
700# 765#
766# CONFIG_PRINTK_TIME is not set
701# CONFIG_DEBUG_KERNEL is not set 767# CONFIG_DEBUG_KERNEL is not set
768CONFIG_LOG_BUF_SHIFT=14
702# CONFIG_KGDB_CONSOLE is not set 769# CONFIG_KGDB_CONSOLE is not set
703# CONFIG_SERIAL_TEXT_DEBUG is not set 770# CONFIG_SERIAL_TEXT_DEBUG is not set
704 771
diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c
index 8aa5e8c69009..d44b7dc5390a 100644
--- a/arch/ppc/kernel/cputable.c
+++ b/arch/ppc/kernel/cputable.c
@@ -838,6 +838,17 @@ struct cpu_spec cpu_specs[] = {
838 .icache_bsize = 32, 838 .icache_bsize = 32,
839 .dcache_bsize = 32, 839 .dcache_bsize = 32,
840 }, 840 },
841 { /* 405EP */
842 .pvr_mask = 0xffff0000,
843 .pvr_value = 0x51210000,
844 .cpu_name = "405EP",
845 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
846 CPU_FTR_USE_TB,
847 .cpu_user_features = PPC_FEATURE_32 |
848 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
849 .icache_bsize = 32,
850 .dcache_bsize = 32,
851 },
841 852
842#endif /* CONFIG_40x */ 853#endif /* CONFIG_40x */
843#ifdef CONFIG_44x 854#ifdef CONFIG_44x
diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S
index 9b6a8e513657..6c7ae6052464 100644
--- a/arch/ppc/kernel/head_44x.S
+++ b/arch/ppc/kernel/head_44x.S
@@ -330,8 +330,9 @@ interrupt_base:
330 /* If we are faulting a kernel address, we have to use the 330 /* If we are faulting a kernel address, we have to use the
331 * kernel page tables. 331 * kernel page tables.
332 */ 332 */
333 andis. r11, r10, 0x8000 333 lis r11, TASK_SIZE@h
334 beq 3f 334 cmplw r10, r11
335 blt+ 3f
335 lis r11, swapper_pg_dir@h 336 lis r11, swapper_pg_dir@h
336 ori r11, r11, swapper_pg_dir@l 337 ori r11, r11, swapper_pg_dir@l
337 338
@@ -464,8 +465,9 @@ interrupt_base:
464 /* If we are faulting a kernel address, we have to use the 465 /* If we are faulting a kernel address, we have to use the
465 * kernel page tables. 466 * kernel page tables.
466 */ 467 */
467 andis. r11, r10, 0x8000 468 lis r11, TASK_SIZE@h
468 beq 3f 469 cmplw r10, r11
470 blt+ 3f
469 lis r11, swapper_pg_dir@h 471 lis r11, swapper_pg_dir@h
470 ori r11, r11, swapper_pg_dir@l 472 ori r11, r11, swapper_pg_dir@l
471 473
@@ -533,8 +535,9 @@ interrupt_base:
533 /* If we are faulting a kernel address, we have to use the 535 /* If we are faulting a kernel address, we have to use the
534 * kernel page tables. 536 * kernel page tables.
535 */ 537 */
536 andis. r11, r10, 0x8000 538 lis r11, TASK_SIZE@h
537 beq 3f 539 cmplw r10, r11
540 blt+ 3f
538 lis r11, swapper_pg_dir@h 541 lis r11, swapper_pg_dir@h
539 ori r11, r11, swapper_pg_dir@l 542 ori r11, r11, swapper_pg_dir@l
540 543
diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S
index f22ddce36135..ce36e88ba627 100644
--- a/arch/ppc/kernel/head_fsl_booke.S
+++ b/arch/ppc/kernel/head_fsl_booke.S
@@ -232,7 +232,8 @@ skpinv: addi r6,r6,1 /* Increment */
232 tlbwe 232 tlbwe
233 233
234/* 7. Jump to KERNELBASE mapping */ 234/* 7. Jump to KERNELBASE mapping */
235 li r7,0 235 lis r7,MSR_KERNEL@h
236 ori r7,r7,MSR_KERNEL@l
236 bl 1f /* Find our address */ 237 bl 1f /* Find our address */
2371: mflr r9 2381: mflr r9
238 rlwimi r6,r9,0,20,31 239 rlwimi r6,r9,0,20,31
@@ -293,6 +294,18 @@ skpinv: addi r6,r6,1 /* Increment */
293 mtspr SPRN_HID0, r2 294 mtspr SPRN_HID0, r2
294#endif 295#endif
295 296
297#if !defined(CONFIG_BDI_SWITCH)
298 /*
299 * The Abatron BDI JTAG debugger does not tolerate others
300 * mucking with the debug registers.
301 */
302 lis r2,DBCR0_IDM@h
303 mtspr SPRN_DBCR0,r2
304 /* clear any residual debug events */
305 li r2,-1
306 mtspr SPRN_DBSR,r2
307#endif
308
296 /* 309 /*
297 * This is where the main kernel code starts. 310 * This is where the main kernel code starts.
298 */ 311 */
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index e4f1615ec13f..7329ef177a18 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -619,7 +619,7 @@ _GLOBAL(flush_instruction_cache)
619_GLOBAL(flush_icache_range) 619_GLOBAL(flush_icache_range)
620BEGIN_FTR_SECTION 620BEGIN_FTR_SECTION
621 blr /* for 601, do nothing */ 621 blr /* for 601, do nothing */
622END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) 622END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
623 li r5,L1_CACHE_LINE_SIZE-1 623 li r5,L1_CACHE_LINE_SIZE-1
624 andc r3,r3,r5 624 andc r3,r3,r5
625 subf r4,r3,r4 625 subf r4,r3,r4
@@ -736,7 +736,7 @@ _GLOBAL(flush_dcache_all)
736_GLOBAL(__flush_dcache_icache) 736_GLOBAL(__flush_dcache_icache)
737BEGIN_FTR_SECTION 737BEGIN_FTR_SECTION
738 blr /* for 601, do nothing */ 738 blr /* for 601, do nothing */
739END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) 739END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
740 rlwinm r3,r3,0,0,19 /* Get page base address */ 740 rlwinm r3,r3,0,0,19 /* Get page base address */
741 li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */ 741 li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */
742 mtctr r4 742 mtctr r4
@@ -764,7 +764,7 @@ END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE)
764_GLOBAL(__flush_dcache_icache_phys) 764_GLOBAL(__flush_dcache_icache_phys)
765BEGIN_FTR_SECTION 765BEGIN_FTR_SECTION
766 blr /* for 601, do nothing */ 766 blr /* for 601, do nothing */
767END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) 767END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
768 mfmsr r10 768 mfmsr r10
769 rlwinm r0,r10,0,28,26 /* clear DR */ 769 rlwinm r0,r10,0,28,26 /* clear DR */
770 mtmsr r0 770 mtmsr r0
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index e97ce635b99e..5c20266e3b1f 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -221,27 +221,26 @@ int show_cpuinfo(struct seq_file *m, void *v)
221 return err; 221 return err;
222 } 222 }
223 223
224 switch (PVR_VER(pvr)) { 224 /* If we are a Freescale core do a simple check so
225 case 0x0020: /* 403 family */ 225 * we dont have to keep adding cases in the future */
226 maj = PVR_MAJ(pvr) + 1; 226 if ((PVR_VER(pvr) & 0x8000) == 0x8000) {
227 min = PVR_MIN(pvr);
228 break;
229 case 0x1008: /* 740P/750P ?? */
230 maj = ((pvr >> 8) & 0xFF) - 1;
231 min = pvr & 0xFF;
232 break;
233 case 0x8083: /* e300 */
234 maj = PVR_MAJ(pvr);
235 min = PVR_MIN(pvr);
236 break;
237 case 0x8020: /* e500 */
238 maj = PVR_MAJ(pvr); 227 maj = PVR_MAJ(pvr);
239 min = PVR_MIN(pvr); 228 min = PVR_MIN(pvr);
240 break; 229 } else {
241 default: 230 switch (PVR_VER(pvr)) {
242 maj = (pvr >> 8) & 0xFF; 231 case 0x0020: /* 403 family */
243 min = pvr & 0xFF; 232 maj = PVR_MAJ(pvr) + 1;
244 break; 233 min = PVR_MIN(pvr);
234 break;
235 case 0x1008: /* 740P/750P ?? */
236 maj = ((pvr >> 8) & 0xFF) - 1;
237 min = pvr & 0xFF;
238 break;
239 default:
240 maj = (pvr >> 8) & 0xFF;
241 min = pvr & 0xFF;
242 break;
243 }
245 } 244 }
246 245
247 seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n", 246 seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n",
@@ -500,7 +499,7 @@ static int __init set_preferred_console(void)
500{ 499{
501 struct device_node *prom_stdout; 500 struct device_node *prom_stdout;
502 char *name; 501 char *name;
503 int offset; 502 int offset = 0;
504 503
505 if (of_stdout_device == NULL) 504 if (of_stdout_device == NULL)
506 return -ENODEV; 505 return -ENODEV;
@@ -754,6 +753,8 @@ void __init setup_arch(char **cmdline_p)
754 strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); 753 strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
755 *cmdline_p = cmd_line; 754 *cmdline_p = cmd_line;
756 755
756 parse_early_param();
757
757 /* set up the bootmem stuff with available memory */ 758 /* set up the bootmem stuff with available memory */
758 do_init_bootmem(); 759 do_init_bootmem();
759 if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); 760 if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index f8e7e324a173..c65731e8bc65 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -408,12 +408,7 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword)
408 408
409 /* Early out if we are an invalid form of lswx */ 409 /* Early out if we are an invalid form of lswx */
410 if ((instword & INST_STRING_MASK) == INST_LSWX) 410 if ((instword & INST_STRING_MASK) == INST_LSWX)
411 if ((rA >= rT) || (NB_RB >= rT) || (rT == rA) || (rT == NB_RB)) 411 if ((rT == rA) || (rT == NB_RB))
412 return -EINVAL;
413
414 /* Early out if we are an invalid form of lswi */
415 if ((instword & INST_STRING_MASK) == INST_LSWI)
416 if ((rA >= rT) || (rT == rA))
417 return -EINVAL; 412 return -EINVAL;
418 413
419 EA = (rA == 0) ? 0 : regs->gpr[rA]; 414 EA = (rA == 0) ? 0 : regs->gpr[rA];
diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S
index 0c0e714b84de..9353584fb710 100644
--- a/arch/ppc/kernel/vmlinux.lds.S
+++ b/arch/ppc/kernel/vmlinux.lds.S
@@ -145,6 +145,7 @@ SECTIONS
145 __init_end = .; 145 __init_end = .;
146 146
147 . = ALIGN(4096); 147 . = ALIGN(4096);
148 _sextratext = .;
148 __pmac_begin = .; 149 __pmac_begin = .;
149 .pmac.text : { *(.pmac.text) } 150 .pmac.text : { *(.pmac.text) }
150 .pmac.data : { *(.pmac.data) } 151 .pmac.data : { *(.pmac.data) }
@@ -171,6 +172,7 @@ SECTIONS
171 .openfirmware.data : { *(.openfirmware.data) } 172 .openfirmware.data : { *(.openfirmware.data) }
172 . = ALIGN(4096); 173 . = ALIGN(4096);
173 __openfirmware_end = .; 174 __openfirmware_end = .;
175 _eextratext = .;
174 176
175 __bss_start = .; 177 __bss_start = .;
176 .bss : 178 .bss :
diff --git a/arch/ppc/lib/string.S b/arch/ppc/lib/string.S
index 8d08a2eb225e..36c9b97fd92a 100644
--- a/arch/ppc/lib/string.S
+++ b/arch/ppc/lib/string.S
@@ -446,6 +446,7 @@ _GLOBAL(__copy_tofrom_user)
446#ifdef CONFIG_8xx 446#ifdef CONFIG_8xx
447 /* Don't use prefetch on 8xx */ 447 /* Don't use prefetch on 8xx */
448 mtctr r0 448 mtctr r0
449 li r0,0
44953: COPY_16_BYTES_WITHEX(0) 45053: COPY_16_BYTES_WITHEX(0)
450 bdnz 53b 451 bdnz 53b
451 452
@@ -564,7 +565,9 @@ _GLOBAL(__copy_tofrom_user)
564/* or write fault in cacheline loop */ 565/* or write fault in cacheline loop */
565105: li r9,1 566105: li r9,1
56692: li r3,LG_CACHELINE_BYTES 56792: li r3,LG_CACHELINE_BYTES
567 b 99f 568 mfctr r8
569 add r0,r0,r8
570 b 106f
568/* read fault in final word loop */ 571/* read fault in final word loop */
569108: li r9,0 572108: li r9,0
570 b 93f 573 b 93f
@@ -585,7 +588,7 @@ _GLOBAL(__copy_tofrom_user)
585 * r5 + (ctr << r3), and r9 is 0 for read or 1 for write. 588 * r5 + (ctr << r3), and r9 is 0 for read or 1 for write.
586 */ 589 */
58799: mfctr r0 59099: mfctr r0
588 slw r3,r0,r3 591106: slw r3,r0,r3
589 add. r3,r3,r5 592 add. r3,r3,r5
590 beq 120f /* shouldn't happen */ 593 beq 120f /* shouldn't happen */
591 cmpwi 0,r9,0 594 cmpwi 0,r9,0
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index be02a7fec2b7..363c157e3617 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -179,6 +179,7 @@ void free_initmem(void)
179 if (!have_of) 179 if (!have_of)
180 FREESEC(openfirmware); 180 FREESEC(openfirmware);
181 printk("\n"); 181 printk("\n");
182 ppc_md.progress = NULL;
182#undef FREESEC 183#undef FREESEC
183} 184}
184 185
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c
index b3b0f51979d2..e6348b5a1ddc 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.c
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
@@ -127,7 +127,6 @@ mpc834x_sys_map_io(void)
127{ 127{
128 /* we steal the lowest ioremap addr for virt space */ 128 /* we steal the lowest ioremap addr for virt space */
129 io_block_mapping(VIRT_IMMRBAR, immrbar, 1024*1024, _PAGE_IO); 129 io_block_mapping(VIRT_IMMRBAR, immrbar, 1024*1024, _PAGE_IO);
130 io_block_mapping(BCSR_VIRT_ADDR, BCSR_PHYS_ADDR, BCSR_SIZE, _PAGE_IO);
131} 130}
132 131
133int 132int
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.h b/arch/ppc/platforms/83xx/mpc834x_sys.h
index f4d055ae19c1..a2f6e49d7151 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.h
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.h
@@ -26,9 +26,14 @@
26#define VIRT_IMMRBAR ((uint)0xfe000000) 26#define VIRT_IMMRBAR ((uint)0xfe000000)
27 27
28#define BCSR_PHYS_ADDR ((uint)0xf8000000) 28#define BCSR_PHYS_ADDR ((uint)0xf8000000)
29#define BCSR_VIRT_ADDR ((uint)0xfe100000)
30#define BCSR_SIZE ((uint)(32 * 1024)) 29#define BCSR_SIZE ((uint)(32 * 1024))
31 30
31#define BCSR_MISC_REG2_OFF 0x07
32#define BCSR_MISC_REG2_PORESET 0x01
33
34#define BCSR_MISC_REG3_OFF 0x08
35#define BCSR_MISC_REG3_CNFLOCK 0x80
36
32#ifdef CONFIG_PCI 37#ifdef CONFIG_PCI
33/* PCI interrupt controller */ 38/* PCI interrupt controller */
34#define PIRQA MPC83xx_IRQ_IRQ4 39#define PIRQA MPC83xx_IRQ_IRQ4
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c
index 4d857d6d633d..583838ab02d8 100644
--- a/arch/ppc/platforms/85xx/mpc8540_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8540_ads.c
@@ -210,6 +210,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
210#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) 210#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
211 ppc_md.progress = gen550_progress; 211 ppc_md.progress = gen550_progress;
212#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ 212#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
213#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB)
214 ppc_md.early_serial_map = mpc85xx_early_serial_map;
215#endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */
213 216
214 if (ppc_md.progress) 217 if (ppc_md.progress)
215 ppc_md.progress("mpc8540ads_init(): exit", 0); 218 ppc_md.progress("mpc8540ads_init(): exit", 0);
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
index 6c020d67ad70..e7cfa498568c 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
@@ -44,6 +44,7 @@
44#include <asm/machdep.h> 44#include <asm/machdep.h>
45#include <asm/prom.h> 45#include <asm/prom.h>
46#include <asm/open_pic.h> 46#include <asm/open_pic.h>
47#include <asm/i8259.h>
47#include <asm/bootinfo.h> 48#include <asm/bootinfo.h>
48#include <asm/pci-bridge.h> 49#include <asm/pci-bridge.h>
49#include <asm/mpc85xx.h> 50#include <asm/mpc85xx.h>
@@ -181,6 +182,7 @@ void __init
181mpc85xx_cds_init_IRQ(void) 182mpc85xx_cds_init_IRQ(void)
182{ 183{
183 bd_t *binfo = (bd_t *) __res; 184 bd_t *binfo = (bd_t *) __res;
185 int i;
184 186
185 /* Determine the Physical Address of the OpenPIC regs */ 187 /* Determine the Physical Address of the OpenPIC regs */
186 phys_addr_t OpenPIC_PAddr = binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET; 188 phys_addr_t OpenPIC_PAddr = binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET;
@@ -198,6 +200,15 @@ mpc85xx_cds_init_IRQ(void)
198 */ 200 */
199 openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET); 201 openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET);
200 202
203#ifdef CONFIG_PCI
204 openpic_hookup_cascade(PIRQ0A, "82c59 cascade", i8259_irq);
205
206 for (i = 0; i < NUM_8259_INTERRUPTS; i++)
207 irq_desc[i].handler = &i8259_pic;
208
209 i8259_init(0);
210#endif
211
201#ifdef CONFIG_CPM2 212#ifdef CONFIG_CPM2
202 /* Setup CPM2 PIC */ 213 /* Setup CPM2 PIC */
203 cpm2_init_IRQ(); 214 cpm2_init_IRQ();
@@ -231,7 +242,7 @@ mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
231 * interrupt on slot */ 242 * interrupt on slot */
232 { 243 {
233 { 0, 1, 2, 3 }, /* 16 - PMC */ 244 { 0, 1, 2, 3 }, /* 16 - PMC */
234 { 3, 0, 0, 0 }, /* 17 P2P (Tsi320) */ 245 { 0, 1, 2, 3 }, /* 17 P2P (Tsi320) */
235 { 0, 1, 2, 3 }, /* 18 - Slot 1 */ 246 { 0, 1, 2, 3 }, /* 18 - Slot 1 */
236 { 1, 2, 3, 0 }, /* 19 - Slot 2 */ 247 { 1, 2, 3, 0 }, /* 19 - Slot 2 */
237 { 2, 3, 0, 1 }, /* 20 - Slot 3 */ 248 { 2, 3, 0, 1 }, /* 20 - Slot 3 */
@@ -280,13 +291,135 @@ mpc85xx_exclude_device(u_char bus, u_char devfn)
280 return PCIBIOS_DEVICE_NOT_FOUND; 291 return PCIBIOS_DEVICE_NOT_FOUND;
281#endif 292#endif
282 /* We explicitly do not go past the Tundra 320 Bridge */ 293 /* We explicitly do not go past the Tundra 320 Bridge */
283 if (bus == 1) 294 if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
284 return PCIBIOS_DEVICE_NOT_FOUND; 295 return PCIBIOS_DEVICE_NOT_FOUND;
285 if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) 296 if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
286 return PCIBIOS_DEVICE_NOT_FOUND; 297 return PCIBIOS_DEVICE_NOT_FOUND;
287 else 298 else
288 return PCIBIOS_SUCCESSFUL; 299 return PCIBIOS_SUCCESSFUL;
289} 300}
301
302void __init
303mpc85xx_cds_enable_via(struct pci_controller *hose)
304{
305 u32 pci_class;
306 u16 vid, did;
307
308 early_read_config_dword(hose, 0, 0x88, PCI_CLASS_REVISION, &pci_class);
309 if ((pci_class >> 16) != PCI_CLASS_BRIDGE_PCI)
310 return;
311
312 /* Configure P2P so that we can reach bus 1 */
313 early_write_config_byte(hose, 0, 0x88, PCI_PRIMARY_BUS, 0);
314 early_write_config_byte(hose, 0, 0x88, PCI_SECONDARY_BUS, 1);
315 early_write_config_byte(hose, 0, 0x88, PCI_SUBORDINATE_BUS, 0xff);
316
317 early_read_config_word(hose, 1, 0x10, PCI_VENDOR_ID, &vid);
318 early_read_config_word(hose, 1, 0x10, PCI_DEVICE_ID, &did);
319
320 if ((vid != PCI_VENDOR_ID_VIA) ||
321 (did != PCI_DEVICE_ID_VIA_82C686))
322 return;
323
324 /* Enable USB and IDE functions */
325 early_write_config_byte(hose, 1, 0x10, 0x48, 0x08);
326}
327
328void __init
329mpc85xx_cds_fixup_via(struct pci_controller *hose)
330{
331 u32 pci_class;
332 u16 vid, did;
333
334 early_read_config_dword(hose, 0, 0x88, PCI_CLASS_REVISION, &pci_class);
335 if ((pci_class >> 16) != PCI_CLASS_BRIDGE_PCI)
336 return;
337
338 /*
339 * Force the backplane P2P bridge to have a window
340 * open from 0x00000000-0x00001fff in PCI I/O space.
341 * This allows legacy I/O (i8259, etc) on the VIA
342 * southbridge to be accessed.
343 */
344 early_write_config_byte(hose, 0, 0x88, PCI_IO_BASE, 0x00);
345 early_write_config_word(hose, 0, 0x88, PCI_IO_BASE_UPPER16, 0x0000);
346 early_write_config_byte(hose, 0, 0x88, PCI_IO_LIMIT, 0x10);
347 early_write_config_word(hose, 0, 0x88, PCI_IO_LIMIT_UPPER16, 0x0000);
348
349 early_read_config_word(hose, 1, 0x10, PCI_VENDOR_ID, &vid);
350 early_read_config_word(hose, 1, 0x10, PCI_DEVICE_ID, &did);
351 if ((vid != PCI_VENDOR_ID_VIA) ||
352 (did != PCI_DEVICE_ID_VIA_82C686))
353 return;
354
355 /*
356 * Since the P2P window was forced to cover the fixed
357 * legacy I/O addresses, it is necessary to manually
358 * place the base addresses for the IDE and USB functions
359 * within this window.
360 */
361 /* Function 1, IDE */
362 early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_0, 0x1ff8);
363 early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_1, 0x1ff4);
364 early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_2, 0x1fe8);
365 early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_3, 0x1fe4);
366 early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_4, 0x1fd0);
367
368 /* Function 2, USB ports 0-1 */
369 early_write_config_dword(hose, 1, 0x12, PCI_BASE_ADDRESS_4, 0x1fa0);
370
371 /* Function 3, USB ports 2-3 */
372 early_write_config_dword(hose, 1, 0x13, PCI_BASE_ADDRESS_4, 0x1f80);
373
374 /* Function 5, Power Management */
375 early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_0, 0x1e00);
376 early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_1, 0x1dfc);
377 early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_2, 0x1df8);
378
379 /* Function 6, AC97 Interface */
380 early_write_config_dword(hose, 1, 0x16, PCI_BASE_ADDRESS_0, 0x1c00);
381}
382
383void __init
384mpc85xx_cds_pcibios_fixup(void)
385{
386 struct pci_dev *dev = NULL;
387 u_char c;
388
389 if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
390 PCI_DEVICE_ID_VIA_82C586_1, NULL))) {
391 /*
392 * U-Boot does not set the enable bits
393 * for the IDE device. Force them on here.
394 */
395 pci_read_config_byte(dev, 0x40, &c);
396 c |= 0x03; /* IDE: Chip Enable Bits */
397 pci_write_config_byte(dev, 0x40, c);
398
399 /*
400 * Since only primary interface works, force the
401 * IDE function to standard primary IDE interrupt
402 * w/ 8259 offset
403 */
404 dev->irq = 14;
405 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
406 }
407
408 /*
409 * Force legacy USB interrupt routing
410 */
411 if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
412 PCI_DEVICE_ID_VIA_82C586_2, NULL))) {
413 dev->irq = 10;
414 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10);
415 }
416
417 if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
418 PCI_DEVICE_ID_VIA_82C586_2, dev))) {
419 dev->irq = 11;
420 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
421 }
422}
290#endif /* CONFIG_PCI */ 423#endif /* CONFIG_PCI */
291 424
292TODC_ALLOC(); 425TODC_ALLOC();
@@ -328,6 +461,9 @@ mpc85xx_cds_setup_arch(void)
328 loops_per_jiffy = freq / HZ; 461 loops_per_jiffy = freq / HZ;
329 462
330#ifdef CONFIG_PCI 463#ifdef CONFIG_PCI
464 /* VIA IDE configuration */
465 ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup;
466
331 /* setup PCI host bridges */ 467 /* setup PCI host bridges */
332 mpc85xx_setup_hose(); 468 mpc85xx_setup_hose();
333#endif 469#endif
@@ -459,6 +595,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
459#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) 595#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
460 ppc_md.progress = gen550_progress; 596 ppc_md.progress = gen550_progress;
461#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ 597#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
598#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB)
599 ppc_md.early_serial_map = mpc85xx_early_serial_map;
600#endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */
462 601
463 if (ppc_md.progress) 602 if (ppc_md.progress)
464 ppc_md.progress("mpc85xx_cds_init(): exit", 0); 603 ppc_md.progress("mpc85xx_cds_init(): exit", 0);
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.h b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
index 7627d77504bd..12b292c6ae32 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
@@ -77,4 +77,7 @@
77 77
78#define MPC85XX_PCI2_IO_SIZE 0x01000000 78#define MPC85XX_PCI2_IO_SIZE 0x01000000
79 79
80#define NR_8259_INTS 16
81#define CPM_IRQ_OFFSET NR_8259_INTS
82
80#endif /* __MACH_MPC85XX_CDS_H__ */ 83#endif /* __MACH_MPC85XX_CDS_H__ */
diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c
index 9ab05e590c3e..7b9e1543e175 100644
--- a/arch/ppc/platforms/85xx/sbc8560.c
+++ b/arch/ppc/platforms/85xx/sbc8560.c
@@ -221,6 +221,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
221#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) 221#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
222 ppc_md.progress = gen550_progress; 222 ppc_md.progress = gen550_progress;
223#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ 223#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
224#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB)
225 ppc_md.early_serial_map = sbc8560_early_serial_map;
226#endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */
224 227
225 if (ppc_md.progress) 228 if (ppc_md.progress)
226 ppc_md.progress("sbc8560_init(): exit", 0); 229 ppc_md.progress("sbc8560_init(): exit", 0);
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c
index f7fb2786cd50..5fdd4f607a40 100644
--- a/arch/ppc/platforms/pmac_cpufreq.c
+++ b/arch/ppc/platforms/pmac_cpufreq.c
@@ -83,16 +83,13 @@ static u32 frequency_gpio;
83static u32 slew_done_gpio; 83static u32 slew_done_gpio;
84static int no_schedule; 84static int no_schedule;
85static int has_cpu_l2lve; 85static int has_cpu_l2lve;
86 86static int is_pmu_based;
87
88#define PMAC_CPU_LOW_SPEED 1
89#define PMAC_CPU_HIGH_SPEED 0
90 87
91/* There are only two frequency states for each processor. Values 88/* There are only two frequency states for each processor. Values
92 * are in kHz for the time being. 89 * are in kHz for the time being.
93 */ 90 */
94#define CPUFREQ_HIGH PMAC_CPU_HIGH_SPEED 91#define CPUFREQ_HIGH 0
95#define CPUFREQ_LOW PMAC_CPU_LOW_SPEED 92#define CPUFREQ_LOW 1
96 93
97static struct cpufreq_frequency_table pmac_cpu_freqs[] = { 94static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
98 {CPUFREQ_HIGH, 0}, 95 {CPUFREQ_HIGH, 0},
@@ -100,6 +97,11 @@ static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
100 {0, CPUFREQ_TABLE_END}, 97 {0, CPUFREQ_TABLE_END},
101}; 98};
102 99
100static struct freq_attr* pmac_cpu_freqs_attr[] = {
101 &cpufreq_freq_attr_scaling_available_freqs,
102 NULL,
103};
104
103static inline void local_delay(unsigned long ms) 105static inline void local_delay(unsigned long ms)
104{ 106{
105 if (no_schedule) 107 if (no_schedule)
@@ -269,6 +271,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
269#ifdef DEBUG_FREQ 271#ifdef DEBUG_FREQ
270 printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); 272 printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
271#endif 273#endif
274 pmu_suspend();
275
272 /* Disable all interrupt sources on openpic */ 276 /* Disable all interrupt sources on openpic */
273 pic_prio = openpic_get_priority(); 277 pic_prio = openpic_get_priority();
274 openpic_set_priority(0xf); 278 openpic_set_priority(0xf);
@@ -343,6 +347,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
343 debug_calc_bogomips(); 347 debug_calc_bogomips();
344#endif 348#endif
345 349
350 pmu_resume();
351
346 preempt_enable(); 352 preempt_enable();
347 353
348 return 0; 354 return 0;
@@ -355,7 +361,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
355 static unsigned long prev_l3cr; 361 static unsigned long prev_l3cr;
356 362
357 freqs.old = cur_freq; 363 freqs.old = cur_freq;
358 freqs.new = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq; 364 freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
359 freqs.cpu = smp_processor_id(); 365 freqs.cpu = smp_processor_id();
360 366
361 if (freqs.old == freqs.new) 367 if (freqs.old == freqs.new)
@@ -363,7 +369,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
363 369
364 if (notify) 370 if (notify)
365 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); 371 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
366 if (speed_mode == PMAC_CPU_LOW_SPEED && 372 if (speed_mode == CPUFREQ_LOW &&
367 cpu_has_feature(CPU_FTR_L3CR)) { 373 cpu_has_feature(CPU_FTR_L3CR)) {
368 l3cr = _get_L3CR(); 374 l3cr = _get_L3CR();
369 if (l3cr & L3CR_L3E) { 375 if (l3cr & L3CR_L3E) {
@@ -371,8 +377,8 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
371 _set_L3CR(0); 377 _set_L3CR(0);
372 } 378 }
373 } 379 }
374 set_speed_proc(speed_mode == PMAC_CPU_LOW_SPEED); 380 set_speed_proc(speed_mode == CPUFREQ_LOW);
375 if (speed_mode == PMAC_CPU_HIGH_SPEED && 381 if (speed_mode == CPUFREQ_HIGH &&
376 cpu_has_feature(CPU_FTR_L3CR)) { 382 cpu_has_feature(CPU_FTR_L3CR)) {
377 l3cr = _get_L3CR(); 383 l3cr = _get_L3CR();
378 if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr) 384 if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr)
@@ -380,7 +386,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
380 } 386 }
381 if (notify) 387 if (notify)
382 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); 388 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
383 cur_freq = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq; 389 cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
384 390
385 return 0; 391 return 0;
386} 392}
@@ -423,7 +429,8 @@ static int __pmac pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
423 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; 429 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
424 policy->cur = cur_freq; 430 policy->cur = cur_freq;
425 431
426 return cpufreq_frequency_table_cpuinfo(policy, &pmac_cpu_freqs[0]); 432 cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu);
433 return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs);
427} 434}
428 435
429static u32 __pmac read_gpio(struct device_node *np) 436static u32 __pmac read_gpio(struct device_node *np)
@@ -456,8 +463,8 @@ static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, u32 state)
456 */ 463 */
457 no_schedule = 1; 464 no_schedule = 1;
458 sleep_freq = cur_freq; 465 sleep_freq = cur_freq;
459 if (cur_freq == low_freq) 466 if (cur_freq == low_freq && !is_pmu_based)
460 do_set_cpu_speed(PMAC_CPU_HIGH_SPEED, 0); 467 do_set_cpu_speed(CPUFREQ_HIGH, 0);
461 return 0; 468 return 0;
462} 469}
463 470
@@ -473,8 +480,8 @@ static int __pmac pmac_cpufreq_resume(struct cpufreq_policy *policy)
473 * is that we force a switch to whatever it was, which is 480 * is that we force a switch to whatever it was, which is
474 * probably high speed due to our suspend() routine 481 * probably high speed due to our suspend() routine
475 */ 482 */
476 do_set_cpu_speed(sleep_freq == low_freq ? PMAC_CPU_LOW_SPEED 483 do_set_cpu_speed(sleep_freq == low_freq ?
477 : PMAC_CPU_HIGH_SPEED, 0); 484 CPUFREQ_LOW : CPUFREQ_HIGH, 0);
478 485
479 no_schedule = 0; 486 no_schedule = 0;
480 return 0; 487 return 0;
@@ -488,6 +495,7 @@ static struct cpufreq_driver pmac_cpufreq_driver = {
488 .suspend = pmac_cpufreq_suspend, 495 .suspend = pmac_cpufreq_suspend,
489 .resume = pmac_cpufreq_resume, 496 .resume = pmac_cpufreq_resume,
490 .flags = CPUFREQ_PM_NO_WARN, 497 .flags = CPUFREQ_PM_NO_WARN,
498 .attr = pmac_cpu_freqs_attr,
491 .name = "powermac", 499 .name = "powermac",
492 .owner = THIS_MODULE, 500 .owner = THIS_MODULE,
493}; 501};
@@ -580,6 +588,7 @@ static int __pmac pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
580 return 1; 588 return 1;
581 hi_freq = (*value) / 1000; 589 hi_freq = (*value) / 1000;
582 set_speed_proc = pmu_set_cpu_speed; 590 set_speed_proc = pmu_set_cpu_speed;
591 is_pmu_based = 1;
583 592
584 return 0; 593 return 0;
585} 594}
@@ -684,6 +693,7 @@ static int __init pmac_cpufreq_setup(void)
684 hi_freq = cur_freq; 693 hi_freq = cur_freq;
685 low_freq = 400000; 694 low_freq = 400000;
686 set_speed_proc = pmu_set_cpu_speed; 695 set_speed_proc = pmu_set_cpu_speed;
696 is_pmu_based = 1;
687 } 697 }
688 /* Else check for TiPb 400 & 500 */ 698 /* Else check for TiPb 400 & 500 */
689 else if (machine_is_compatible("PowerBook3,2")) { 699 else if (machine_is_compatible("PowerBook3,2")) {
@@ -695,6 +705,7 @@ static int __init pmac_cpufreq_setup(void)
695 hi_freq = cur_freq; 705 hi_freq = cur_freq;
696 low_freq = 300000; 706 low_freq = 300000;
697 set_speed_proc = pmu_set_cpu_speed; 707 set_speed_proc = pmu_set_cpu_speed;
708 is_pmu_based = 1;
698 } 709 }
699 /* Else check for 750FX */ 710 /* Else check for 750FX */
700 else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000) 711 else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000)
diff --git a/arch/ppc/platforms/pq2ads.h b/arch/ppc/platforms/pq2ads.h
index cf5e5dd06d63..067d9a5aebc1 100644
--- a/arch/ppc/platforms/pq2ads.h
+++ b/arch/ppc/platforms/pq2ads.h
@@ -49,10 +49,10 @@
49/* PCI interrupt controller */ 49/* PCI interrupt controller */
50#define PCI_INT_STAT_REG 0xF8200000 50#define PCI_INT_STAT_REG 0xF8200000
51#define PCI_INT_MASK_REG 0xF8200004 51#define PCI_INT_MASK_REG 0xF8200004
52#define PIRQA (NR_SIU_INTS + 0) 52#define PIRQA (NR_CPM_INTS + 0)
53#define PIRQB (NR_SIU_INTS + 1) 53#define PIRQB (NR_CPM_INTS + 1)
54#define PIRQC (NR_SIU_INTS + 2) 54#define PIRQC (NR_CPM_INTS + 2)
55#define PIRQD (NR_SIU_INTS + 3) 55#define PIRQD (NR_CPM_INTS + 3)
56 56
57/* 57/*
58 * PCI memory map definitions for MPC8266ADS-PCI. 58 * PCI memory map definitions for MPC8266ADS-PCI.
@@ -68,28 +68,23 @@
68 * 0x00000000-0x1FFFFFFF 0x00000000-0x1FFFFFFF MPC8266 local memory 68 * 0x00000000-0x1FFFFFFF 0x00000000-0x1FFFFFFF MPC8266 local memory
69 */ 69 */
70 70
71/* window for a PCI master to access MPC8266 memory */ 71/* All the other PCI memory map definitions reside at syslib/m82xx_pci.h
72#define PCI_SLV_MEM_LOCAL 0x00000000 /* Local base */ 72 Here we should redefine what is unique for this board */
73#define PCI_SLV_MEM_BUS 0x00000000 /* PCI base */ 73#define M82xx_PCI_SLAVE_MEM_LOCAL 0x00000000 /* Local base */
74#define M82xx_PCI_SLAVE_MEM_BUS 0x00000000 /* PCI base */
75#define M82xx_PCI_SLAVE_MEM_SIZE 0x10000000 /* 256 Mb */
74 76
75/* window for the processor to access PCI memory with prefetching */ 77#define M82xx_PCI_SLAVE_SEC_WND_SIZE ~(0x40000000 - 1U) /* 2 x 512Mb */
76#define PCI_MSTR_MEM_LOCAL 0x80000000 /* Local base */ 78#define M82xx_PCI_SLAVE_SEC_WND_BASE 0x80000000 /* PCI Memory base */
77#define PCI_MSTR_MEM_BUS 0x80000000 /* PCI base */
78#define PCI_MSTR_MEM_SIZE 0x20000000 /* 512MB */
79 79
80/* window for the processor to access PCI memory without prefetching */ 80#if defined(CONFIG_ADS8272)
81#define PCI_MSTR_MEMIO_LOCAL 0xA0000000 /* Local base */ 81#define PCI_INT_TO_SIU SIU_INT_IRQ2
82#define PCI_MSTR_MEMIO_BUS 0xA0000000 /* PCI base */ 82#elif defined(CONFIG_PQ2FADS)
83#define PCI_MSTR_MEMIO_SIZE 0x20000000 /* 512MB */ 83#define PCI_INT_TO_SIU SIU_INT_IRQ6
84#else
85#warning PCI Bridge will be without interrupts support
86#endif
84 87
85/* window for the processor to access PCI I/O */
86#define PCI_MSTR_IO_LOCAL 0xF4000000 /* Local base */
87#define PCI_MSTR_IO_BUS 0x00000000 /* PCI base */
88#define PCI_MSTR_IO_SIZE 0x04000000 /* 64MB */
89
90#define _IO_BASE PCI_MSTR_IO_LOCAL
91#define _ISA_MEM_BASE PCI_MSTR_MEMIO_LOCAL
92#define PCI_DRAM_OFFSET PCI_SLV_MEM_BUS
93#endif /* CONFIG_PCI */ 88#endif /* CONFIG_PCI */
94 89
95#endif /* __MACH_ADS8260_DEFS */ 90#endif /* __MACH_ADS8260_DEFS */
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
index dd418ea3426c..96acf85800d4 100644
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -81,7 +81,7 @@ obj-$(CONFIG_SBC82xx) += todc_time.o
81obj-$(CONFIG_SPRUCE) += cpc700_pic.o indirect_pci.o pci_auto.o \ 81obj-$(CONFIG_SPRUCE) += cpc700_pic.o indirect_pci.o pci_auto.o \
82 todc_time.o 82 todc_time.o
83obj-$(CONFIG_8260) += m8260_setup.o 83obj-$(CONFIG_8260) += m8260_setup.o
84obj-$(CONFIG_PCI_8260) += m8260_pci.o indirect_pci.o 84obj-$(CONFIG_PCI_8260) += m82xx_pci.o indirect_pci.o pci_auto.o
85obj-$(CONFIG_8260_PCI9) += m8260_pci_erratum9.o 85obj-$(CONFIG_8260_PCI9) += m8260_pci_erratum9.o
86obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o 86obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o
87ifeq ($(CONFIG_PPC_GEN550),y) 87ifeq ($(CONFIG_PPC_GEN550),y)
@@ -97,7 +97,7 @@ obj-$(CONFIG_MPC10X_OPENPIC) += open_pic.o
97obj-$(CONFIG_40x) += dcr.o 97obj-$(CONFIG_40x) += dcr.o
98obj-$(CONFIG_BOOKE) += dcr.o 98obj-$(CONFIG_BOOKE) += dcr.o
99obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \ 99obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \
100 ppc_sys.o mpc85xx_sys.o \ 100 ppc_sys.o i8259.o mpc85xx_sys.o \
101 mpc85xx_devices.o 101 mpc85xx_devices.o
102ifeq ($(CONFIG_85xx),y) 102ifeq ($(CONFIG_85xx),y)
103obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o 103obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o
diff --git a/arch/ppc/syslib/ipic.c b/arch/ppc/syslib/ipic.c
index acb2cde3171f..580ed658e872 100644
--- a/arch/ppc/syslib/ipic.c
+++ b/arch/ppc/syslib/ipic.c
@@ -479,7 +479,7 @@ void __init ipic_init(phys_addr_t phys_addr,
479 temp = 0; 479 temp = 0;
480 for (i = 0 ; i < senses_count ; i++) { 480 for (i = 0 ; i < senses_count ; i++) {
481 if ((senses[i] & IRQ_SENSE_MASK) == IRQ_SENSE_EDGE) { 481 if ((senses[i] & IRQ_SENSE_MASK) == IRQ_SENSE_EDGE) {
482 temp |= 1 << (16 - i); 482 temp |= 1 << (15 - i);
483 if (i != 0) 483 if (i != 0)
484 irq_desc[i + irq_offset + MPC83xx_IRQ_EXT1 - 1].status = 0; 484 irq_desc[i + irq_offset + MPC83xx_IRQ_EXT1 - 1].status = 0;
485 else 485 else
diff --git a/arch/ppc/syslib/m8260_pci.c b/arch/ppc/syslib/m8260_pci.c
deleted file mode 100644
index 057cc3f8ff37..000000000000
--- a/arch/ppc/syslib/m8260_pci.c
+++ /dev/null
@@ -1,193 +0,0 @@
1/*
2 * (C) Copyright 2003
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * (C) Copyright 2004 Red Hat, Inc.
6 *
7 * See file CREDITS for list of people who contributed to this
8 * project.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23 * MA 02111-1307 USA
24 */
25
26#include <linux/kernel.h>
27#include <linux/init.h>
28#include <linux/pci.h>
29#include <linux/slab.h>
30#include <linux/delay.h>
31
32#include <asm/byteorder.h>
33#include <asm/io.h>
34#include <asm/irq.h>
35#include <asm/uaccess.h>
36#include <asm/machdep.h>
37#include <asm/pci-bridge.h>
38#include <asm/immap_cpm2.h>
39#include <asm/mpc8260.h>
40
41#include "m8260_pci.h"
42
43
44/* PCI bus configuration registers.
45 */
46
47static void __init m8260_setup_pci(struct pci_controller *hose)
48{
49 volatile cpm2_map_t *immap = cpm2_immr;
50 unsigned long pocmr;
51 u16 tempShort;
52
53#ifndef CONFIG_ATC /* already done in U-Boot */
54 /*
55 * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]),
56 * and local bus for PCI (SIUMCR [LBPC]).
57 */
58 immap->im_siu_conf.siu_82xx.sc_siumcr = 0x00640000;
59#endif
60
61 /* Make PCI lowest priority */
62 /* Each 4 bits is a device bus request and the MS 4bits
63 is highest priority */
64 /* Bus 4bit value
65 --- ----------
66 CPM high 0b0000
67 CPM middle 0b0001
68 CPM low 0b0010
69 PCI reguest 0b0011
70 Reserved 0b0100
71 Reserved 0b0101
72 Internal Core 0b0110
73 External Master 1 0b0111
74 External Master 2 0b1000
75 External Master 3 0b1001
76 The rest are reserved */
77 immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893;
78
79 /* Park bus on core while modifying PCI Bus accesses */
80 immap->im_siu_conf.siu_82xx.sc_ppc_acr = 0x6;
81
82 /*
83 * Set up master window that allows the CPU to access PCI space. This
84 * window is set up using the first SIU PCIBR registers.
85 */
86 immap->im_memctl.memc_pcimsk0 = MPC826x_PCI_MASK;
87 immap->im_memctl.memc_pcibr0 = MPC826x_PCI_BASE | PCIBR_ENABLE;
88
89 /* Disable machine check on no response or target abort */
90 immap->im_pci.pci_emr = cpu_to_le32(0x1fe7);
91 /* Release PCI RST (by default the PCI RST signal is held low) */
92 immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN);
93
94 /* give it some time */
95 mdelay(1);
96
97 /*
98 * Set up master window that allows the CPU to access PCI Memory (prefetch)
99 * space. This window is set up using the first set of Outbound ATU registers.
100 */
101 immap->im_pci.pci_potar0 = cpu_to_le32(MPC826x_PCI_LOWER_MEM >> 12);
102 immap->im_pci.pci_pobar0 = cpu_to_le32((MPC826x_PCI_LOWER_MEM - MPC826x_PCI_MEM_OFFSET) >> 12);
103 pocmr = ((MPC826x_PCI_UPPER_MEM - MPC826x_PCI_LOWER_MEM) >> 12) ^ 0xfffff;
104 immap->im_pci.pci_pocmr0 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PREFETCH_EN);
105
106 /*
107 * Set up master window that allows the CPU to access PCI Memory (non-prefetch)
108 * space. This window is set up using the second set of Outbound ATU registers.
109 */
110 immap->im_pci.pci_potar1 = cpu_to_le32(MPC826x_PCI_LOWER_MMIO >> 12);
111 immap->im_pci.pci_pobar1 = cpu_to_le32((MPC826x_PCI_LOWER_MMIO - MPC826x_PCI_MMIO_OFFSET) >> 12);
112 pocmr = ((MPC826x_PCI_UPPER_MMIO - MPC826x_PCI_LOWER_MMIO) >> 12) ^ 0xfffff;
113 immap->im_pci.pci_pocmr1 = cpu_to_le32(pocmr | POCMR_ENABLE);
114
115 /*
116 * Set up master window that allows the CPU to access PCI IO space. This window
117 * is set up using the third set of Outbound ATU registers.
118 */
119 immap->im_pci.pci_potar2 = cpu_to_le32(MPC826x_PCI_IO_BASE >> 12);
120 immap->im_pci.pci_pobar2 = cpu_to_le32(MPC826x_PCI_LOWER_IO >> 12);
121 pocmr = ((MPC826x_PCI_UPPER_IO - MPC826x_PCI_LOWER_IO) >> 12) ^ 0xfffff;
122 immap->im_pci.pci_pocmr2 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PCI_IO);
123
124 /*
125 * Set up slave window that allows PCI masters to access MPC826x local memory.
126 * This window is set up using the first set of Inbound ATU registers
127 */
128
129 immap->im_pci.pci_pitar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_LOCAL >> 12);
130 immap->im_pci.pci_pibar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_BUS >> 12);
131 pocmr = ((MPC826x_PCI_SLAVE_MEM_SIZE-1) >> 12) ^ 0xfffff;
132 immap->im_pci.pci_picmr0 = cpu_to_le32(pocmr | PICMR_ENABLE | PICMR_PREFETCH_EN);
133
134 /* See above for description - puts PCI request as highest priority */
135 immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x03124567;
136
137 /* Park the bus on the PCI */
138 immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI;
139
140 /* Host mode - specify the bridge as a host-PCI bridge */
141 early_write_config_word(hose, 0, 0, PCI_CLASS_DEVICE, PCI_CLASS_BRIDGE_HOST);
142
143 /* Enable the host bridge to be a master on the PCI bus, and to act as a PCI memory target */
144 early_read_config_word(hose, 0, 0, PCI_COMMAND, &tempShort);
145 early_write_config_word(hose, 0, 0, PCI_COMMAND,
146 tempShort | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
147}
148
149void __init m8260_find_bridges(void)
150{
151 extern int pci_assign_all_busses;
152 struct pci_controller * hose;
153
154 pci_assign_all_busses = 1;
155
156 hose = pcibios_alloc_controller();
157
158 if (!hose)
159 return;
160
161 ppc_md.pci_swizzle = common_swizzle;
162
163 hose->first_busno = 0;
164 hose->bus_offset = 0;
165 hose->last_busno = 0xff;
166
167 setup_m8260_indirect_pci(hose,
168 (unsigned long)&cpm2_immr->im_pci.pci_cfg_addr,
169 (unsigned long)&cpm2_immr->im_pci.pci_cfg_data);
170
171 m8260_setup_pci(hose);
172 hose->pci_mem_offset = MPC826x_PCI_MEM_OFFSET;
173
174 hose->io_base_virt = ioremap(MPC826x_PCI_IO_BASE,
175 MPC826x_PCI_IO_SIZE);
176 isa_io_base = (unsigned long) hose->io_base_virt;
177
178 /* setup resources */
179 pci_init_resource(&hose->mem_resources[0],
180 MPC826x_PCI_LOWER_MEM,
181 MPC826x_PCI_UPPER_MEM,
182 IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory");
183
184 pci_init_resource(&hose->mem_resources[1],
185 MPC826x_PCI_LOWER_MMIO,
186 MPC826x_PCI_UPPER_MMIO,
187 IORESOURCE_MEM, "PCI memory");
188
189 pci_init_resource(&hose->io_resource,
190 MPC826x_PCI_LOWER_IO,
191 MPC826x_PCI_UPPER_IO,
192 IORESOURCE_IO, "PCI I/O");
193}
diff --git a/arch/ppc/syslib/m8260_pci.h b/arch/ppc/syslib/m8260_pci.h
deleted file mode 100644
index d1352120acd7..000000000000
--- a/arch/ppc/syslib/m8260_pci.h
+++ /dev/null
@@ -1,76 +0,0 @@
1
2#ifndef _PPC_KERNEL_M8260_PCI_H
3#define _PPC_KERNEL_M8260_PCI_H
4
5#include <asm/m8260_pci.h>
6
7/*
8 * Local->PCI map (from CPU) controlled by
9 * MPC826x master window
10 *
11 * 0x80000000 - 0xBFFFFFFF Total CPU2PCI space PCIBR0
12 *
13 * 0x80000000 - 0x9FFFFFFF PCI Mem with prefetch (Outbound ATU #1)
14 * 0xA0000000 - 0xAFFFFFFF PCI Mem w/o prefetch (Outbound ATU #2)
15 * 0xB0000000 - 0xB0FFFFFF 32-bit PCI IO (Outbound ATU #3)
16 *
17 * PCI->Local map (from PCI)
18 * MPC826x slave window controlled by
19 *
20 * 0x00000000 - 0x07FFFFFF MPC826x local memory (Inbound ATU #1)
21 */
22
23/*
24 * Slave window that allows PCI masters to access MPC826x local memory.
25 * This window is set up using the first set of Inbound ATU registers
26 */
27
28#ifndef MPC826x_PCI_SLAVE_MEM_LOCAL
29#define MPC826x_PCI_SLAVE_MEM_LOCAL (((struct bd_info *)__res)->bi_memstart)
30#define MPC826x_PCI_SLAVE_MEM_BUS (((struct bd_info *)__res)->bi_memstart)
31#define MPC826x_PCI_SLAVE_MEM_SIZE (((struct bd_info *)__res)->bi_memsize)
32#endif
33
34/*
35 * This is the window that allows the CPU to access PCI address space.
36 * It will be setup with the SIU PCIBR0 register. All three PCI master
37 * windows, which allow the CPU to access PCI prefetch, non prefetch,
38 * and IO space (see below), must all fit within this window.
39 */
40#ifndef MPC826x_PCI_BASE
41#define MPC826x_PCI_BASE 0x80000000
42#define MPC826x_PCI_MASK 0xc0000000
43#endif
44
45#ifndef MPC826x_PCI_LOWER_MEM
46#define MPC826x_PCI_LOWER_MEM 0x80000000
47#define MPC826x_PCI_UPPER_MEM 0x9fffffff
48#define MPC826x_PCI_MEM_OFFSET 0x00000000
49#endif
50
51#ifndef MPC826x_PCI_LOWER_MMIO
52#define MPC826x_PCI_LOWER_MMIO 0xa0000000
53#define MPC826x_PCI_UPPER_MMIO 0xafffffff
54#define MPC826x_PCI_MMIO_OFFSET 0x00000000
55#endif
56
57#ifndef MPC826x_PCI_LOWER_IO
58#define MPC826x_PCI_LOWER_IO 0x00000000
59#define MPC826x_PCI_UPPER_IO 0x00ffffff
60#define MPC826x_PCI_IO_BASE 0xb0000000
61#define MPC826x_PCI_IO_SIZE 0x01000000
62#endif
63
64#ifndef _IO_BASE
65#define _IO_BASE isa_io_base
66#endif
67
68#ifdef CONFIG_8260_PCI9
69struct pci_controller;
70extern void setup_m8260_indirect_pci(struct pci_controller* hose,
71 u32 cfg_addr, u32 cfg_data);
72#else
73#define setup_m8260_indirect_pci setup_indirect_pci
74#endif
75
76#endif /* _PPC_KERNEL_M8260_PCI_H */
diff --git a/arch/ppc/syslib/m8260_pci_erratum9.c b/arch/ppc/syslib/m8260_pci_erratum9.c
index 9c0582d639e0..1dc7e4e1d491 100644
--- a/arch/ppc/syslib/m8260_pci_erratum9.c
+++ b/arch/ppc/syslib/m8260_pci_erratum9.c
@@ -31,7 +31,7 @@
31#include <asm/immap_cpm2.h> 31#include <asm/immap_cpm2.h>
32#include <asm/cpm2.h> 32#include <asm/cpm2.h>
33 33
34#include "m8260_pci.h" 34#include "m82xx_pci.h"
35 35
36#ifdef CONFIG_8260_PCI9 36#ifdef CONFIG_8260_PCI9
37/*#include <asm/mpc8260_pci9.h>*/ /* included in asm/io.h */ 37/*#include <asm/mpc8260_pci9.h>*/ /* included in asm/io.h */
@@ -248,11 +248,11 @@ EXPORT_SYMBOL(idma_pci9_read_le);
248 248
249static inline int is_pci_mem(unsigned long addr) 249static inline int is_pci_mem(unsigned long addr)
250{ 250{
251 if (addr >= MPC826x_PCI_LOWER_MMIO && 251 if (addr >= M82xx_PCI_LOWER_MMIO &&
252 addr <= MPC826x_PCI_UPPER_MMIO) 252 addr <= M82xx_PCI_UPPER_MMIO)
253 return 1; 253 return 1;
254 if (addr >= MPC826x_PCI_LOWER_MEM && 254 if (addr >= M82xx_PCI_LOWER_MEM &&
255 addr <= MPC826x_PCI_UPPER_MEM) 255 addr <= M82xx_PCI_UPPER_MEM)
256 return 1; 256 return 1;
257 return 0; 257 return 0;
258} 258}
diff --git a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c
index 23ea3f694de2..fda75d79050c 100644
--- a/arch/ppc/syslib/m8260_setup.c
+++ b/arch/ppc/syslib/m8260_setup.c
@@ -34,7 +34,8 @@
34unsigned char __res[sizeof(bd_t)]; 34unsigned char __res[sizeof(bd_t)];
35 35
36extern void cpm2_reset(void); 36extern void cpm2_reset(void);
37extern void m8260_find_bridges(void); 37extern void pq2_find_bridges(void);
38extern void pq2pci_init_irq(void);
38extern void idma_pci9_init(void); 39extern void idma_pci9_init(void);
39 40
40/* Place-holder for board-specific init */ 41/* Place-holder for board-specific init */
@@ -56,7 +57,7 @@ m8260_setup_arch(void)
56 idma_pci9_init(); 57 idma_pci9_init();
57#endif 58#endif
58#ifdef CONFIG_PCI_8260 59#ifdef CONFIG_PCI_8260
59 m8260_find_bridges(); 60 pq2_find_bridges();
60#endif 61#endif
61#ifdef CONFIG_BLK_DEV_INITRD 62#ifdef CONFIG_BLK_DEV_INITRD
62 if (initrd_start) 63 if (initrd_start)
@@ -173,6 +174,12 @@ m8260_init_IRQ(void)
173 * in case the boot rom changed something on us. 174 * in case the boot rom changed something on us.
174 */ 175 */
175 cpm2_immr->im_intctl.ic_siprr = 0x05309770; 176 cpm2_immr->im_intctl.ic_siprr = 0x05309770;
177
178#if defined(CONFIG_PCI) && (defined(CONFIG_ADS8272) || defined(CONFIG_PQ2FADS))
179 /* Initialize stuff for the 82xx CPLD IC and install demux */
180 pq2pci_init_irq();
181#endif
182
176} 183}
177 184
178/* 185/*
diff --git a/arch/ppc/syslib/m82xx_pci.c b/arch/ppc/syslib/m82xx_pci.c
new file mode 100644
index 000000000000..5e7a7edcea74
--- /dev/null
+++ b/arch/ppc/syslib/m82xx_pci.c
@@ -0,0 +1,383 @@
1/*
2 *
3 * (C) Copyright 2003
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 *
6 * (C) Copyright 2004 Red Hat, Inc.
7 *
8 * 2005 (c) MontaVista Software, Inc.
9 * Vitaly Bordug <vbordug@ru.mvista.com>
10 *
11 * See file CREDITS for list of people who contributed to this
12 * project.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27 * MA 02111-1307 USA
28 */
29
30#include <linux/kernel.h>
31#include <linux/init.h>
32#include <linux/pci.h>
33#include <linux/slab.h>
34#include <linux/delay.h>
35#include <linux/irq.h>
36#include <linux/interrupt.h>
37
38#include <asm/byteorder.h>
39#include <asm/io.h>
40#include <asm/irq.h>
41#include <asm/uaccess.h>
42#include <asm/machdep.h>
43#include <asm/pci-bridge.h>
44#include <asm/immap_cpm2.h>
45#include <asm/mpc8260.h>
46#include <asm/cpm2.h>
47
48#include "m82xx_pci.h"
49
50/*
51 * Interrupt routing
52 */
53
54static inline int
55pq2pci_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
56{
57 static char pci_irq_table[][4] =
58 /*
59 * PCI IDSEL/INTPIN->INTLINE
60 * A B C D
61 */
62 {
63 { PIRQA, PIRQB, PIRQC, PIRQD }, /* IDSEL 22 - PCI slot 0 */
64 { PIRQD, PIRQA, PIRQB, PIRQC }, /* IDSEL 23 - PCI slot 1 */
65 { PIRQC, PIRQD, PIRQA, PIRQB }, /* IDSEL 24 - PCI slot 2 */
66 };
67
68 const long min_idsel = 22, max_idsel = 24, irqs_per_slot = 4;
69 return PCI_IRQ_TABLE_LOOKUP;
70}
71
72static void
73pq2pci_mask_irq(unsigned int irq)
74{
75 int bit = irq - NR_CPM_INTS;
76
77 *(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit));
78 return;
79}
80
81static void
82pq2pci_unmask_irq(unsigned int irq)
83{
84 int bit = irq - NR_CPM_INTS;
85
86 *(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit));
87 return;
88}
89
90static void
91pq2pci_mask_and_ack(unsigned int irq)
92{
93 int bit = irq - NR_CPM_INTS;
94
95 *(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit));
96 return;
97}
98
99static void
100pq2pci_end_irq(unsigned int irq)
101{
102 int bit = irq - NR_CPM_INTS;
103
104 *(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit));
105 return;
106}
107
108struct hw_interrupt_type pq2pci_ic = {
109 "PQ2 PCI",
110 NULL,
111 NULL,
112 pq2pci_unmask_irq,
113 pq2pci_mask_irq,
114 pq2pci_mask_and_ack,
115 pq2pci_end_irq,
116 0
117};
118
119static irqreturn_t
120pq2pci_irq_demux(int irq, void *dev_id, struct pt_regs *regs)
121{
122 unsigned long stat, mask, pend;
123 int bit;
124
125 for(;;) {
126 stat = *(volatile unsigned long *) PCI_INT_STAT_REG;
127 mask = *(volatile unsigned long *) PCI_INT_MASK_REG;
128 pend = stat & ~mask & 0xf0000000;
129 if (!pend)
130 break;
131 for (bit = 0; pend != 0; ++bit, pend <<= 1) {
132 if (pend & 0x80000000)
133 __do_IRQ(NR_CPM_INTS + bit, regs);
134 }
135 }
136
137 return IRQ_HANDLED;
138}
139
140static struct irqaction pq2pci_irqaction = {
141 .handler = pq2pci_irq_demux,
142 .flags = SA_INTERRUPT,
143 .mask = CPU_MASK_NONE,
144 .name = "PQ2 PCI cascade",
145};
146
147
148void
149pq2pci_init_irq(void)
150{
151 int irq;
152 volatile cpm2_map_t *immap = cpm2_immr;
153#if defined CONFIG_ADS8272
154 /* configure chip select for PCI interrupt controller */
155 immap->im_memctl.memc_br3 = PCI_INT_STAT_REG | 0x00001801;
156 immap->im_memctl.memc_or3 = 0xffff8010;
157#elif defined CONFIG_PQ2FADS
158 immap->im_memctl.memc_br8 = PCI_INT_STAT_REG | 0x00001801;
159 immap->im_memctl.memc_or8 = 0xffff8010;
160#endif
161 for (irq = NR_CPM_INTS; irq < NR_CPM_INTS + 4; irq++)
162 irq_desc[irq].handler = &pq2pci_ic;
163
164 /* make PCI IRQ level sensitive */
165 immap->im_intctl.ic_siexr &=
166 ~(1 << (14 - (PCI_INT_TO_SIU - SIU_INT_IRQ1)));
167
168 /* mask all PCI interrupts */
169 *(volatile unsigned long *) PCI_INT_MASK_REG |= 0xfff00000;
170
171 /* install the demultiplexer for the PCI cascade interrupt */
172 setup_irq(PCI_INT_TO_SIU, &pq2pci_irqaction);
173 return;
174}
175
176static int
177pq2pci_exclude_device(u_char bus, u_char devfn)
178{
179 return PCIBIOS_SUCCESSFUL;
180}
181
182/* PCI bus configuration registers.
183 */
184static void
185pq2ads_setup_pci(struct pci_controller *hose)
186{
187 __u32 val;
188 volatile cpm2_map_t *immap = cpm2_immr;
189 bd_t* binfo = (bd_t*) __res;
190 u32 sccr = immap->im_clkrst.car_sccr;
191 uint pci_div,freq,time;
192 /* PCI int lowest prio */
193 /* Each 4 bits is a device bus request and the MS 4bits
194 is highest priority */
195 /* Bus 4bit value
196 --- ----------
197 CPM high 0b0000
198 CPM middle 0b0001
199 CPM low 0b0010
200 PCI reguest 0b0011
201 Reserved 0b0100
202 Reserved 0b0101
203 Internal Core 0b0110
204 External Master 1 0b0111
205 External Master 2 0b1000
206 External Master 3 0b1001
207 The rest are reserved
208 */
209 immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893;
210 /* park bus on core */
211 immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_CORE;
212 /*
213 * Set up master windows that allow the CPU to access PCI space. These
214 * windows are set up using the two SIU PCIBR registers.
215 */
216
217 immap->im_memctl.memc_pcimsk0 = M82xx_PCI_PRIM_WND_SIZE;
218 immap->im_memctl.memc_pcibr0 = M82xx_PCI_PRIM_WND_BASE | PCIBR_ENABLE;
219
220#ifdef M82xx_PCI_SEC_WND_SIZE
221 immap->im_memctl.memc_pcimsk1 = M82xx_PCI_SEC_WND_SIZE;
222 immap->im_memctl.memc_pcibr1 = M82xx_PCI_SEC_WND_BASE | PCIBR_ENABLE;
223#endif
224
225#if defined CONFIG_ADS8272
226 immap->im_siu_conf.siu_82xx.sc_siumcr =
227 (immap->im_siu_conf.siu_82xx.sc_siumcr &
228 ~(SIUMCR_BBD | SIUMCR_ESE | SIUMCR_PBSE |
229 SIUMCR_CDIS | SIUMCR_DPPC11 | SIUMCR_L2CPC11 |
230 SIUMCR_LBPC11 | SIUMCR_APPC11 |
231 SIUMCR_CS10PC11 | SIUMCR_BCTLC11 | SIUMCR_MMR11)) |
232 SIUMCR_DPPC11 | SIUMCR_L2CPC01 | SIUMCR_LBPC00 |
233 SIUMCR_APPC10 | SIUMCR_CS10PC00 |
234 SIUMCR_BCTLC00 | SIUMCR_MMR11 ;
235
236#elif defined CONFIG_PQ2FADS
237 /*
238 * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]),
239 * and local bus for PCI (SIUMCR [LBPC]).
240 */
241 immap->im_siu_conf.siu_82xx.sc_siumcr = (immap->im_siu_conf.sc_siumcr &
242 ~(SIUMCR_L2PC11 | SIUMCR_LBPC11 | SIUMCR_CS10PC11 | SIUMCR_APPC11) |
243 SIUMCR_BBD | SIUMCR_LBPC01 | SIUMCR_DPPC11 | SIUMCR_APPC10;
244#endif
245 /* Enable PCI */
246 immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN);
247
248 pci_div = ( (sccr & SCCR_PCI_MODCK) ? 2 : 1) *
249 ( ( (sccr & SCCR_PCIDF_MSK) >> SCCR_PCIDF_SHIFT) + 1);
250 freq = (uint)((2*binfo->bi_cpmfreq)/(pci_div));
251 time = (int)666666/freq;
252 /* due to PCI Local Bus spec, some devices needs to wait such a long
253 time after RST deassertion. More specifically, 0.508s for 66MHz & twice more for 33 */
254 printk("%s: The PCI bus is %d Mhz.\nWaiting %s after deasserting RST...\n",__FILE__,freq,
255 (time==1) ? "0.5 seconds":"1 second" );
256
257 {
258 int i;
259 for(i=0;i<(500*time);i++)
260 udelay(1000);
261 }
262
263 /* setup ATU registers */
264 immap->im_pci.pci_pocmr0 = cpu_to_le32(POCMR_ENABLE | POCMR_PCI_IO |
265 ((~(M82xx_PCI_IO_SIZE - 1U)) >> POTA_ADDR_SHIFT));
266 immap->im_pci.pci_potar0 = cpu_to_le32(M82xx_PCI_LOWER_IO >> POTA_ADDR_SHIFT);
267 immap->im_pci.pci_pobar0 = cpu_to_le32(M82xx_PCI_IO_BASE >> POTA_ADDR_SHIFT);
268
269 /* Set-up non-prefetchable window */
270 immap->im_pci.pci_pocmr1 = cpu_to_le32(POCMR_ENABLE | ((~(M82xx_PCI_MMIO_SIZE-1U)) >> POTA_ADDR_SHIFT));
271 immap->im_pci.pci_potar1 = cpu_to_le32(M82xx_PCI_LOWER_MMIO >> POTA_ADDR_SHIFT);
272 immap->im_pci.pci_pobar1 = cpu_to_le32((M82xx_PCI_LOWER_MMIO - M82xx_PCI_MMIO_OFFSET) >> POTA_ADDR_SHIFT);
273
274 /* Set-up prefetchable window */
275 immap->im_pci.pci_pocmr2 = cpu_to_le32(POCMR_ENABLE |POCMR_PREFETCH_EN |
276 (~(M82xx_PCI_MEM_SIZE-1U) >> POTA_ADDR_SHIFT));
277 immap->im_pci.pci_potar2 = cpu_to_le32(M82xx_PCI_LOWER_MEM >> POTA_ADDR_SHIFT);
278 immap->im_pci.pci_pobar2 = cpu_to_le32((M82xx_PCI_LOWER_MEM - M82xx_PCI_MEM_OFFSET) >> POTA_ADDR_SHIFT);
279
280 /* Inbound transactions from PCI memory space */
281 immap->im_pci.pci_picmr0 = cpu_to_le32(PICMR_ENABLE | PICMR_PREFETCH_EN |
282 ((~(M82xx_PCI_SLAVE_MEM_SIZE-1U)) >> PITA_ADDR_SHIFT));
283 immap->im_pci.pci_pibar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_BUS >> PITA_ADDR_SHIFT);
284 immap->im_pci.pci_pitar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_LOCAL>> PITA_ADDR_SHIFT);
285
286#if defined CONFIG_ADS8272
287 /* PCI int highest prio */
288 immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x01236745;
289#elif defined CONFIG_PQ2FADS
290 immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x03124567;
291#endif
292 /* park bus on PCI */
293 immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI;
294
295 /* Enable bus mastering and inbound memory transactions */
296 early_read_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, &val);
297 val &= 0xffff0000;
298 val |= PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER;
299 early_write_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, val);
300
301}
302
303void __init pq2_find_bridges(void)
304{
305 extern int pci_assign_all_busses;
306 struct pci_controller * hose;
307 int host_bridge;
308
309 pci_assign_all_busses = 1;
310
311 hose = pcibios_alloc_controller();
312
313 if (!hose)
314 return;
315
316 ppc_md.pci_swizzle = common_swizzle;
317
318 hose->first_busno = 0;
319 hose->bus_offset = 0;
320 hose->last_busno = 0xff;
321
322#ifdef CONFIG_ADS8272
323 hose->set_cfg_type = 1;
324#endif
325
326 setup_m8260_indirect_pci(hose,
327 (unsigned long)&cpm2_immr->im_pci.pci_cfg_addr,
328 (unsigned long)&cpm2_immr->im_pci.pci_cfg_data);
329
330 /* Make sure it is a supported bridge */
331 early_read_config_dword(hose,
332 0,
333 PCI_DEVFN(0,0),
334 PCI_VENDOR_ID,
335 &host_bridge);
336 switch (host_bridge) {
337 case PCI_DEVICE_ID_MPC8265:
338 break;
339 case PCI_DEVICE_ID_MPC8272:
340 break;
341 default:
342 printk("Attempting to use unrecognized host bridge ID"
343 " 0x%08x.\n", host_bridge);
344 break;
345 }
346
347 pq2ads_setup_pci(hose);
348
349 hose->io_space.start = M82xx_PCI_LOWER_IO;
350 hose->io_space.end = M82xx_PCI_UPPER_IO;
351 hose->mem_space.start = M82xx_PCI_LOWER_MEM;
352 hose->mem_space.end = M82xx_PCI_UPPER_MMIO;
353 hose->pci_mem_offset = M82xx_PCI_MEM_OFFSET;
354
355 isa_io_base =
356 (unsigned long) ioremap(M82xx_PCI_IO_BASE,
357 M82xx_PCI_IO_SIZE);
358 hose->io_base_virt = (void *) isa_io_base;
359
360 /* setup resources */
361 pci_init_resource(&hose->mem_resources[0],
362 M82xx_PCI_LOWER_MEM,
363 M82xx_PCI_UPPER_MEM,
364 IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory");
365
366 pci_init_resource(&hose->mem_resources[1],
367 M82xx_PCI_LOWER_MMIO,
368 M82xx_PCI_UPPER_MMIO,
369 IORESOURCE_MEM, "PCI memory");
370
371 pci_init_resource(&hose->io_resource,
372 M82xx_PCI_LOWER_IO,
373 M82xx_PCI_UPPER_IO,
374 IORESOURCE_IO | 1, "PCI I/O");
375
376 ppc_md.pci_exclude_device = pq2pci_exclude_device;
377 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
378
379 ppc_md.pci_map_irq = pq2pci_map_irq;
380 ppc_md.pcibios_fixup = NULL;
381 ppc_md.pcibios_fixup_bus = NULL;
382
383}
diff --git a/arch/ppc/syslib/m82xx_pci.h b/arch/ppc/syslib/m82xx_pci.h
new file mode 100644
index 000000000000..924f73f8e595
--- /dev/null
+++ b/arch/ppc/syslib/m82xx_pci.h
@@ -0,0 +1,92 @@
1
2#ifndef _PPC_KERNEL_M82XX_PCI_H
3#define _PPC_KERNEL_M82XX_PCI_H
4
5#include <asm/m8260_pci.h>
6/*
7 * Local->PCI map (from CPU) controlled by
8 * MPC826x master window
9 *
10 * 0xF6000000 - 0xF7FFFFFF IO space
11 * 0x80000000 - 0xBFFFFFFF CPU2PCI memory space PCIBR0
12 *
13 * 0x80000000 - 0x9FFFFFFF PCI Mem with prefetch (Outbound ATU #1)
14 * 0xA0000000 - 0xBFFFFFFF PCI Mem w/o prefetch (Outbound ATU #2)
15 * 0xF6000000 - 0xF7FFFFFF 32-bit PCI IO (Outbound ATU #3)
16 *
17 * PCI->Local map (from PCI)
18 * MPC826x slave window controlled by
19 *
20 * 0x00000000 - 0x07FFFFFF MPC826x local memory (Inbound ATU #1)
21 */
22
23/*
24 * Slave window that allows PCI masters to access MPC826x local memory.
25 * This window is set up using the first set of Inbound ATU registers
26 */
27
28#ifndef M82xx_PCI_SLAVE_MEM_LOCAL
29#define M82xx_PCI_SLAVE_MEM_LOCAL (((struct bd_info *)__res)->bi_memstart)
30#define M82xx_PCI_SLAVE_MEM_BUS (((struct bd_info *)__res)->bi_memstart)
31#define M82xx_PCI_SLAVE_MEM_SIZE (((struct bd_info *)__res)->bi_memsize)
32#endif
33
34/*
35 * This is the window that allows the CPU to access PCI address space.
36 * It will be setup with the SIU PCIBR0 register. All three PCI master
37 * windows, which allow the CPU to access PCI prefetch, non prefetch,
38 * and IO space (see below), must all fit within this window.
39 */
40
41#ifndef M82xx_PCI_LOWER_MEM
42#define M82xx_PCI_LOWER_MEM 0x80000000
43#define M82xx_PCI_UPPER_MEM 0x9fffffff
44#define M82xx_PCI_MEM_OFFSET 0x00000000
45#define M82xx_PCI_MEM_SIZE 0x20000000
46#endif
47
48#ifndef M82xx_PCI_LOWER_MMIO
49#define M82xx_PCI_LOWER_MMIO 0xa0000000
50#define M82xx_PCI_UPPER_MMIO 0xafffffff
51#define M82xx_PCI_MMIO_OFFSET 0x00000000
52#define M82xx_PCI_MMIO_SIZE 0x20000000
53#endif
54
55#ifndef M82xx_PCI_LOWER_IO
56#define M82xx_PCI_LOWER_IO 0x00000000
57#define M82xx_PCI_UPPER_IO 0x01ffffff
58#define M82xx_PCI_IO_BASE 0xf6000000
59#define M82xx_PCI_IO_SIZE 0x02000000
60#endif
61
62#ifndef M82xx_PCI_PRIM_WND_SIZE
63#define M82xx_PCI_PRIM_WND_SIZE ~(M82xx_PCI_IO_SIZE - 1U)
64#define M82xx_PCI_PRIM_WND_BASE (M82xx_PCI_IO_BASE)
65#endif
66
67#ifndef M82xx_PCI_SEC_WND_SIZE
68#define M82xx_PCI_SEC_WND_SIZE ~(M82xx_PCI_MEM_SIZE + M82xx_PCI_MMIO_SIZE - 1U)
69#define M82xx_PCI_SEC_WND_BASE (M82xx_PCI_LOWER_MEM)
70#endif
71
72#ifndef POTA_ADDR_SHIFT
73#define POTA_ADDR_SHIFT 12
74#endif
75
76#ifndef PITA_ADDR_SHIFT
77#define PITA_ADDR_SHIFT 12
78#endif
79
80#ifndef _IO_BASE
81#define _IO_BASE isa_io_base
82#endif
83
84#ifdef CONFIG_8260_PCI9
85struct pci_controller;
86extern void setup_m8260_indirect_pci(struct pci_controller* hose,
87 u32 cfg_addr, u32 cfg_data);
88#else
89#define setup_m8260_indirect_pci setup_indirect_pci
90#endif
91
92#endif /* _PPC_KERNEL_M8260_PCI_H */
diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/mpc83xx_devices.c
index 5c1a919eaabf..75c8e9834ae7 100644
--- a/arch/ppc/syslib/mpc83xx_devices.c
+++ b/arch/ppc/syslib/mpc83xx_devices.c
@@ -61,6 +61,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
61 .iotype = UPIO_MEM, 61 .iotype = UPIO_MEM,
62 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, 62 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
63 }, 63 },
64 { },
64}; 65};
65 66
66struct platform_device ppc_sys_platform_devices[] = { 67struct platform_device ppc_sys_platform_devices[] = {
diff --git a/arch/ppc/syslib/mpc85xx_devices.c b/arch/ppc/syslib/mpc85xx_devices.c
index a231795ee26f..1e658ef57e75 100644
--- a/arch/ppc/syslib/mpc85xx_devices.c
+++ b/arch/ppc/syslib/mpc85xx_devices.c
@@ -61,6 +61,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
61 .iotype = UPIO_MEM, 61 .iotype = UPIO_MEM,
62 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ, 62 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ,
63 }, 63 },
64 { },
64}; 65};
65 66
66struct platform_device ppc_sys_platform_devices[] = { 67struct platform_device ppc_sys_platform_devices[] = {
diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c
index 7619e16fccae..000ba47c67cb 100644
--- a/arch/ppc/syslib/open_pic.c
+++ b/arch/ppc/syslib/open_pic.c
@@ -275,7 +275,7 @@ static void __init openpic_enable_sie(void)
275} 275}
276#endif 276#endif
277 277
278#if defined(CONFIG_EPIC_SERIAL_MODE) || defined(CONFIG_PM) 278#if defined(CONFIG_EPIC_SERIAL_MODE)
279static void openpic_reset(void) 279static void openpic_reset(void)
280{ 280{
281 openpic_setfield(&OpenPIC->Global.Global_Configuration0, 281 openpic_setfield(&OpenPIC->Global.Global_Configuration0,
@@ -557,12 +557,10 @@ static void __init openpic_initipi(u_int ipi, u_int pri, u_int vec)
557 */ 557 */
558void openpic_cause_IPI(u_int ipi, cpumask_t cpumask) 558void openpic_cause_IPI(u_int ipi, cpumask_t cpumask)
559{ 559{
560 cpumask_t phys;
561 DECL_THIS_CPU; 560 DECL_THIS_CPU;
562 561
563 CHECK_THIS_CPU; 562 CHECK_THIS_CPU;
564 check_arg_ipi(ipi); 563 check_arg_ipi(ipi);
565 phys = physmask(cpumask);
566 openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), 564 openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi),
567 cpus_addr(physmask(cpumask))[0]); 565 cpus_addr(physmask(cpumask))[0]);
568} 566}
@@ -995,8 +993,6 @@ int openpic_resume(struct sys_device *sysdev)
995 return 0; 993 return 0;
996 } 994 }
997 995
998 openpic_reset();
999
1000 /* OpenPIC sometimes seem to need some time to be fully back up... */ 996 /* OpenPIC sometimes seem to need some time to be fully back up... */
1001 do { 997 do {
1002 openpic_set_spurious(OPENPIC_VEC_SPURIOUS); 998 openpic_set_spurious(OPENPIC_VEC_SPURIOUS);
diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c
index c28f9d679484..843cf8873e60 100644
--- a/arch/ppc/syslib/ppc83xx_setup.c
+++ b/arch/ppc/syslib/ppc83xx_setup.c
@@ -29,6 +29,7 @@
29#include <asm/mmu.h> 29#include <asm/mmu.h>
30#include <asm/ppc_sys.h> 30#include <asm/ppc_sys.h>
31#include <asm/kgdb.h> 31#include <asm/kgdb.h>
32#include <asm/delay.h>
32 33
33#include <syslib/ppc83xx_setup.h> 34#include <syslib/ppc83xx_setup.h>
34 35
@@ -117,7 +118,34 @@ mpc83xx_early_serial_map(void)
117void 118void
118mpc83xx_restart(char *cmd) 119mpc83xx_restart(char *cmd)
119{ 120{
121 volatile unsigned char __iomem *reg;
122 unsigned char tmp;
123
124 reg = ioremap(BCSR_PHYS_ADDR, BCSR_SIZE);
125
120 local_irq_disable(); 126 local_irq_disable();
127
128 /*
129 * Unlock the BCSR bits so a PRST will update the contents.
130 * Otherwise the reset asserts but doesn't clear.
131 */
132 tmp = in_8(reg + BCSR_MISC_REG3_OFF);
133 tmp |= BCSR_MISC_REG3_CNFLOCK; /* low true, high false */
134 out_8(reg + BCSR_MISC_REG3_OFF, tmp);
135
136 /*
137 * Trigger a reset via a low->high transition of the
138 * PORESET bit.
139 */
140 tmp = in_8(reg + BCSR_MISC_REG2_OFF);
141 tmp &= ~BCSR_MISC_REG2_PORESET;
142 out_8(reg + BCSR_MISC_REG2_OFF, tmp);
143
144 udelay(1);
145
146 tmp |= BCSR_MISC_REG2_PORESET;
147 out_8(reg + BCSR_MISC_REG2_OFF, tmp);
148
121 for(;;); 149 for(;;);
122} 150}
123 151
diff --git a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c
index 152c3ef1312a..f3277f469e78 100644
--- a/arch/ppc/syslib/ppc85xx_setup.c
+++ b/arch/ppc/syslib/ppc85xx_setup.c
@@ -132,6 +132,12 @@ mpc85xx_halt(void)
132} 132}
133 133
134#ifdef CONFIG_PCI 134#ifdef CONFIG_PCI
135
136#if defined(CONFIG_MPC8555_CDS)
137extern void mpc85xx_cds_enable_via(struct pci_controller *hose);
138extern void mpc85xx_cds_fixup_via(struct pci_controller *hose);
139#endif
140
135static void __init 141static void __init
136mpc85xx_setup_pci1(struct pci_controller *hose) 142mpc85xx_setup_pci1(struct pci_controller *hose)
137{ 143{
@@ -302,8 +308,18 @@ mpc85xx_setup_hose(void)
302 308
303 ppc_md.pci_exclude_device = mpc85xx_exclude_device; 309 ppc_md.pci_exclude_device = mpc85xx_exclude_device;
304 310
311#if defined(CONFIG_MPC8555_CDS)
312 /* Pre pciauto_bus_scan VIA init */
313 mpc85xx_cds_enable_via(hose_a);
314#endif
315
305 hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno); 316 hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno);
306 317
318#if defined(CONFIG_MPC8555_CDS)
319 /* Post pciauto_bus_scan VIA fixup */
320 mpc85xx_cds_fixup_via(hose_a);
321#endif
322
307#ifdef CONFIG_85xx_PCI2 323#ifdef CONFIG_85xx_PCI2
308 hose_b = pcibios_alloc_controller(); 324 hose_b = pcibios_alloc_controller();
309 325
diff --git a/arch/ppc/syslib/prom_init.c b/arch/ppc/syslib/prom_init.c
index 2cee87137f2e..7f15136830f4 100644
--- a/arch/ppc/syslib/prom_init.c
+++ b/arch/ppc/syslib/prom_init.c
@@ -626,8 +626,18 @@ inspect_node(phandle node, struct device_node *dad,
626 l = call_prom("package-to-path", 3, 1, node, 626 l = call_prom("package-to-path", 3, 1, node,
627 mem_start, mem_end - mem_start); 627 mem_start, mem_end - mem_start);
628 if (l >= 0) { 628 if (l >= 0) {
629 char *p, *ep;
630
629 np->full_name = PTRUNRELOC((char *) mem_start); 631 np->full_name = PTRUNRELOC((char *) mem_start);
630 *(char *)(mem_start + l) = 0; 632 *(char *)(mem_start + l) = 0;
633 /* Fixup an Apple bug where they have bogus \0 chars in the
634 * middle of the path in some properties
635 */
636 for (p = (char *)mem_start, ep = p + l; p < ep; p++)
637 if ((*p) == '\0') {
638 memmove(p, p+1, ep - p);
639 ep--;
640 }
631 mem_start = ALIGNUL(mem_start + l + 1); 641 mem_start = ALIGNUL(mem_start + l + 1);
632 } 642 }
633 643
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
index ef1f05e437c4..5cb343883e4d 100644
--- a/arch/ppc64/Kconfig
+++ b/arch/ppc64/Kconfig
@@ -40,6 +40,10 @@ config COMPAT
40 bool 40 bool
41 default y 41 default y
42 42
43config SCHED_NO_NO_OMIT_FRAME_POINTER
44 bool
45 default y
46
43# We optimistically allocate largepages from the VM, so make the limit 47# We optimistically allocate largepages from the VM, so make the limit
44# large enough (16MB). This badly named config option is actually 48# large enough (16MB). This badly named config option is actually
45# max order + 1 49# max order + 1
@@ -258,6 +262,7 @@ config PPC_RTAS
258config RTAS_PROC 262config RTAS_PROC
259 bool "Proc interface to RTAS" 263 bool "Proc interface to RTAS"
260 depends on PPC_RTAS 264 depends on PPC_RTAS
265 default y
261 266
262config RTAS_FLASH 267config RTAS_FLASH
263 tristate "Firmware flash interface" 268 tristate "Firmware flash interface"
@@ -293,6 +298,9 @@ config SECCOMP
293 298
294endmenu 299endmenu
295 300
301config ISA_DMA_API
302 bool
303 default y
296 304
297menu "General setup" 305menu "General setup"
298 306
diff --git a/arch/ppc64/Kconfig.debug b/arch/ppc64/Kconfig.debug
index e341a129da80..46b1ce58da3b 100644
--- a/arch/ppc64/Kconfig.debug
+++ b/arch/ppc64/Kconfig.debug
@@ -5,6 +5,9 @@ source "lib/Kconfig.debug"
5config DEBUG_STACKOVERFLOW 5config DEBUG_STACKOVERFLOW
6 bool "Check for stack overflows" 6 bool "Check for stack overflows"
7 depends on DEBUG_KERNEL 7 depends on DEBUG_KERNEL
8 help
9 This option will cause messages to be printed if free stack space
10 drops below a certain limit.
8 11
9config KPROBES 12config KPROBES
10 bool "Kprobes" 13 bool "Kprobes"
diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c
index b0fa86ad8b1b..da12ea2ca464 100644
--- a/arch/ppc64/boot/main.c
+++ b/arch/ppc64/boot/main.c
@@ -14,7 +14,6 @@
14#include <linux/string.h> 14#include <linux/string.h>
15#include <asm/processor.h> 15#include <asm/processor.h>
16#include <asm/page.h> 16#include <asm/page.h>
17#include <asm/bootinfo.h>
18 17
19extern void *finddevice(const char *); 18extern void *finddevice(const char *);
20extern int getprop(void *, const char *, void *, int); 19extern int getprop(void *, const char *, void *, int);
diff --git a/arch/ppc64/boot/prom.c b/arch/ppc64/boot/prom.c
index 7b607d1862cb..d5218b15824e 100644
--- a/arch/ppc64/boot/prom.c
+++ b/arch/ppc64/boot/prom.c
@@ -11,6 +11,23 @@
11#include <linux/string.h> 11#include <linux/string.h>
12#include <linux/ctype.h> 12#include <linux/ctype.h>
13 13
14extern __u32 __div64_32(unsigned long long *dividend, __u32 divisor);
15
16/* The unnecessary pointer compare is there
17 * to check for type safety (n must be 64bit)
18 */
19# define do_div(n,base) ({ \
20 __u32 __base = (base); \
21 __u32 __rem; \
22 (void)(((typeof((n)) *)0) == ((unsigned long long *)0)); \
23 if (((n) >> 32) == 0) { \
24 __rem = (__u32)(n) % __base; \
25 (n) = (__u32)(n) / __base; \
26 } else \
27 __rem = __div64_32(&(n), __base); \
28 __rem; \
29 })
30
14int (*prom)(void *); 31int (*prom)(void *);
15 32
16void *chosen_handle; 33void *chosen_handle;
@@ -352,7 +369,7 @@ static int skip_atoi(const char **s)
352#define SPECIAL 32 /* 0x */ 369#define SPECIAL 32 /* 0x */
353#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ 370#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
354 371
355static char * number(char * str, long num, int base, int size, int precision, int type) 372static char * number(char * str, unsigned long long num, int base, int size, int precision, int type)
356{ 373{
357 char c,sign,tmp[66]; 374 char c,sign,tmp[66];
358 const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; 375 const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
@@ -367,9 +384,9 @@ static char * number(char * str, long num, int base, int size, int precision, in
367 c = (type & ZEROPAD) ? '0' : ' '; 384 c = (type & ZEROPAD) ? '0' : ' ';
368 sign = 0; 385 sign = 0;
369 if (type & SIGN) { 386 if (type & SIGN) {
370 if (num < 0) { 387 if ((signed long long)num < 0) {
371 sign = '-'; 388 sign = '-';
372 num = -num; 389 num = - (signed long long)num;
373 size--; 390 size--;
374 } else if (type & PLUS) { 391 } else if (type & PLUS) {
375 sign = '+'; 392 sign = '+';
@@ -389,8 +406,7 @@ static char * number(char * str, long num, int base, int size, int precision, in
389 if (num == 0) 406 if (num == 0)
390 tmp[i++]='0'; 407 tmp[i++]='0';
391 else while (num != 0) { 408 else while (num != 0) {
392 tmp[i++] = digits[num % base]; 409 tmp[i++] = digits[do_div(num, base)];
393 num /= base;
394 } 410 }
395 if (i > precision) 411 if (i > precision)
396 precision = i; 412 precision = i;
@@ -426,7 +442,7 @@ int sprintf(char * buf, const char *fmt, ...);
426int vsprintf(char *buf, const char *fmt, va_list args) 442int vsprintf(char *buf, const char *fmt, va_list args)
427{ 443{
428 int len; 444 int len;
429 unsigned long num; 445 unsigned long long num;
430 int i, base; 446 int i, base;
431 char * str; 447 char * str;
432 const char *s; 448 const char *s;
diff --git a/arch/ppc64/boot/start.c b/arch/ppc64/boot/start.c
deleted file mode 100644
index ea247e79b55e..000000000000
--- a/arch/ppc64/boot/start.c
+++ /dev/null
@@ -1,654 +0,0 @@
1/*
2 * Copyright (C) Paul Mackerras 1997.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9#include <stdarg.h>
10#include <linux/types.h>
11#include <linux/string.h>
12#include <linux/ctype.h>
13
14#include <asm/div64.h>
15
16int (*prom)(void *);
17
18void *chosen_handle;
19void *stdin;
20void *stdout;
21void *stderr;
22
23void exit(void);
24void *finddevice(const char *name);
25int getprop(void *phandle, const char *name, void *buf, int buflen);
26void chrpboot(int a1, int a2, void *prom); /* in main.c */
27
28void printk(char *fmt, ...);
29
30void
31start(int a1, int a2, void *promptr)
32{
33 prom = (int (*)(void *)) promptr;
34 chosen_handle = finddevice("/chosen");
35 if (chosen_handle == (void *) -1)
36 exit();
37 if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
38 exit();
39 stderr = stdout;
40 if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
41 exit();
42
43 chrpboot(a1, a2, promptr);
44 for (;;)
45 exit();
46}
47
48int
49write(void *handle, void *ptr, int nb)
50{
51 struct prom_args {
52 char *service;
53 int nargs;
54 int nret;
55 void *ihandle;
56 void *addr;
57 int len;
58 int actual;
59 } args;
60
61 args.service = "write";
62 args.nargs = 3;
63 args.nret = 1;
64 args.ihandle = handle;
65 args.addr = ptr;
66 args.len = nb;
67 args.actual = -1;
68 (*prom)(&args);
69 return args.actual;
70}
71
72int
73read(void *handle, void *ptr, int nb)
74{
75 struct prom_args {
76 char *service;
77 int nargs;
78 int nret;
79 void *ihandle;
80 void *addr;
81 int len;
82 int actual;
83 } args;
84
85 args.service = "read";
86 args.nargs = 3;
87 args.nret = 1;
88 args.ihandle = handle;
89 args.addr = ptr;
90 args.len = nb;
91 args.actual = -1;
92 (*prom)(&args);
93 return args.actual;
94}
95
96void
97exit()
98{
99 struct prom_args {
100 char *service;
101 } args;
102
103 for (;;) {
104 args.service = "exit";
105 (*prom)(&args);
106 }
107}
108
109void
110pause(void)
111{
112 struct prom_args {
113 char *service;
114 } args;
115
116 args.service = "enter";
117 (*prom)(&args);
118}
119
120void *
121finddevice(const char *name)
122{
123 struct prom_args {
124 char *service;
125 int nargs;
126 int nret;
127 const char *devspec;
128 void *phandle;
129 } args;
130
131 args.service = "finddevice";
132 args.nargs = 1;
133 args.nret = 1;
134 args.devspec = name;
135 args.phandle = (void *) -1;
136 (*prom)(&args);
137 return args.phandle;
138}
139
140void *
141claim(unsigned long virt, unsigned long size, unsigned long align)
142{
143 struct prom_args {
144 char *service;
145 int nargs;
146 int nret;
147 unsigned int virt;
148 unsigned int size;
149 unsigned int align;
150 void *ret;
151 } args;
152
153 args.service = "claim";
154 args.nargs = 3;
155 args.nret = 1;
156 args.virt = virt;
157 args.size = size;
158 args.align = align;
159 (*prom)(&args);
160 return args.ret;
161}
162
163int
164getprop(void *phandle, const char *name, void *buf, int buflen)
165{
166 struct prom_args {
167 char *service;
168 int nargs;
169 int nret;
170 void *phandle;
171 const char *name;
172 void *buf;
173 int buflen;
174 int size;
175 } args;
176
177 args.service = "getprop";
178 args.nargs = 4;
179 args.nret = 1;
180 args.phandle = phandle;
181 args.name = name;
182 args.buf = buf;
183 args.buflen = buflen;
184 args.size = -1;
185 (*prom)(&args);
186 return args.size;
187}
188
189int
190putc(int c, void *f)
191{
192 char ch = c;
193
194 if (c == '\n')
195 putc('\r', f);
196 return write(f, &ch, 1) == 1? c: -1;
197}
198
199int
200putchar(int c)
201{
202 return putc(c, stdout);
203}
204
205int
206fputs(char *str, void *f)
207{
208 int n = strlen(str);
209
210 return write(f, str, n) == n? 0: -1;
211}
212
213int
214readchar(void)
215{
216 char ch;
217
218 for (;;) {
219 switch (read(stdin, &ch, 1)) {
220 case 1:
221 return ch;
222 case -1:
223 printk("read(stdin) returned -1\r\n");
224 return -1;
225 }
226 }
227}
228
229static char line[256];
230static char *lineptr;
231static int lineleft;
232
233int
234getchar(void)
235{
236 int c;
237
238 if (lineleft == 0) {
239 lineptr = line;
240 for (;;) {
241 c = readchar();
242 if (c == -1 || c == 4)
243 break;
244 if (c == '\r' || c == '\n') {
245 *lineptr++ = '\n';
246 putchar('\n');
247 break;
248 }
249 switch (c) {
250 case 0177:
251 case '\b':
252 if (lineptr > line) {
253 putchar('\b');
254 putchar(' ');
255 putchar('\b');
256 --lineptr;
257 }
258 break;
259 case 'U' & 0x1F:
260 while (lineptr > line) {
261 putchar('\b');
262 putchar(' ');
263 putchar('\b');
264 --lineptr;
265 }
266 break;
267 default:
268 if (lineptr >= &line[sizeof(line) - 1])
269 putchar('\a');
270 else {
271 putchar(c);
272 *lineptr++ = c;
273 }
274 }
275 }
276 lineleft = lineptr - line;
277 lineptr = line;
278 }
279 if (lineleft == 0)
280 return -1;
281 --lineleft;
282 return *lineptr++;
283}
284
285
286
287/* String functions lifted from lib/vsprintf.c and lib/ctype.c */
288unsigned char _ctype[] = {
289_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
290_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
291_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
292_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
293_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
294_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
295_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
296_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
297_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
298_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
299_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
300_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
301_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
302_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
303_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
304_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
3050,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
3060,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
307_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */
308_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
309_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */
310_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */
311_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */
312_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
313
314size_t strnlen(const char * s, size_t count)
315{
316 const char *sc;
317
318 for (sc = s; count-- && *sc != '\0'; ++sc)
319 /* nothing */;
320 return sc - s;
321}
322
323unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
324{
325 unsigned long result = 0,value;
326
327 if (!base) {
328 base = 10;
329 if (*cp == '0') {
330 base = 8;
331 cp++;
332 if ((*cp == 'x') && isxdigit(cp[1])) {
333 cp++;
334 base = 16;
335 }
336 }
337 }
338 while (isxdigit(*cp) &&
339 (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
340 result = result*base + value;
341 cp++;
342 }
343 if (endp)
344 *endp = (char *)cp;
345 return result;
346}
347
348long simple_strtol(const char *cp,char **endp,unsigned int base)
349{
350 if(*cp=='-')
351 return -simple_strtoul(cp+1,endp,base);
352 return simple_strtoul(cp,endp,base);
353}
354
355static int skip_atoi(const char **s)
356{
357 int i=0;
358
359 while (isdigit(**s))
360 i = i*10 + *((*s)++) - '0';
361 return i;
362}
363
364#define ZEROPAD 1 /* pad with zero */
365#define SIGN 2 /* unsigned/signed long */
366#define PLUS 4 /* show plus */
367#define SPACE 8 /* space if plus */
368#define LEFT 16 /* left justified */
369#define SPECIAL 32 /* 0x */
370#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
371
372static char * number(char * str, long long num, int base, int size, int precision, int type)
373{
374 char c,sign,tmp[66];
375 const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
376 int i;
377
378 if (type & LARGE)
379 digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
380 if (type & LEFT)
381 type &= ~ZEROPAD;
382 if (base < 2 || base > 36)
383 return 0;
384 c = (type & ZEROPAD) ? '0' : ' ';
385 sign = 0;
386 if (type & SIGN) {
387 if (num < 0) {
388 sign = '-';
389 num = -num;
390 size--;
391 } else if (type & PLUS) {
392 sign = '+';
393 size--;
394 } else if (type & SPACE) {
395 sign = ' ';
396 size--;
397 }
398 }
399 if (type & SPECIAL) {
400 if (base == 16)
401 size -= 2;
402 else if (base == 8)
403 size--;
404 }
405 i = 0;
406 if (num == 0)
407 tmp[i++]='0';
408 else while (num != 0)
409 tmp[i++] = digits[do_div(num,base)];
410 if (i > precision)
411 precision = i;
412 size -= precision;
413 if (!(type&(ZEROPAD+LEFT)))
414 while(size-->0)
415 *str++ = ' ';
416 if (sign)
417 *str++ = sign;
418 if (type & SPECIAL) {
419 if (base==8)
420 *str++ = '0';
421 else if (base==16) {
422 *str++ = '0';
423 *str++ = digits[33];
424 }
425 }
426 if (!(type & LEFT))
427 while (size-- > 0)
428 *str++ = c;
429 while (i < precision--)
430 *str++ = '0';
431 while (i-- > 0)
432 *str++ = tmp[i];
433 while (size-- > 0)
434 *str++ = ' ';
435 return str;
436}
437
438/* Forward decl. needed for IP address printing stuff... */
439int sprintf(char * buf, const char *fmt, ...);
440
441int vsprintf(char *buf, const char *fmt, va_list args)
442{
443 int len;
444 unsigned long long num;
445 int i, base;
446 char * str;
447 const char *s;
448
449 int flags; /* flags to number() */
450
451 int field_width; /* width of output field */
452 int precision; /* min. # of digits for integers; max
453 number of chars for from string */
454 int qualifier; /* 'h', 'l', or 'L' for integer fields */
455 /* 'z' support added 23/7/1999 S.H. */
456 /* 'z' changed to 'Z' --davidm 1/25/99 */
457
458
459 for (str=buf ; *fmt ; ++fmt) {
460 if (*fmt != '%') {
461 *str++ = *fmt;
462 continue;
463 }
464
465 /* process flags */
466 flags = 0;
467 repeat:
468 ++fmt; /* this also skips first '%' */
469 switch (*fmt) {
470 case '-': flags |= LEFT; goto repeat;
471 case '+': flags |= PLUS; goto repeat;
472 case ' ': flags |= SPACE; goto repeat;
473 case '#': flags |= SPECIAL; goto repeat;
474 case '0': flags |= ZEROPAD; goto repeat;
475 }
476
477 /* get field width */
478 field_width = -1;
479 if (isdigit(*fmt))
480 field_width = skip_atoi(&fmt);
481 else if (*fmt == '*') {
482 ++fmt;
483 /* it's the next argument */
484 field_width = va_arg(args, int);
485 if (field_width < 0) {
486 field_width = -field_width;
487 flags |= LEFT;
488 }
489 }
490
491 /* get the precision */
492 precision = -1;
493 if (*fmt == '.') {
494 ++fmt;
495 if (isdigit(*fmt))
496 precision = skip_atoi(&fmt);
497 else if (*fmt == '*') {
498 ++fmt;
499 /* it's the next argument */
500 precision = va_arg(args, int);
501 }
502 if (precision < 0)
503 precision = 0;
504 }
505
506 /* get the conversion qualifier */
507 qualifier = -1;
508 if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
509 qualifier = *fmt;
510 ++fmt;
511 }
512
513 /* default base */
514 base = 10;
515
516 switch (*fmt) {
517 case 'c':
518 if (!(flags & LEFT))
519 while (--field_width > 0)
520 *str++ = ' ';
521 *str++ = (unsigned char) va_arg(args, int);
522 while (--field_width > 0)
523 *str++ = ' ';
524 continue;
525
526 case 's':
527 s = va_arg(args, char *);
528 if (!s)
529 s = "<NULL>";
530
531 len = strnlen(s, precision);
532
533 if (!(flags & LEFT))
534 while (len < field_width--)
535 *str++ = ' ';
536 for (i = 0; i < len; ++i)
537 *str++ = *s++;
538 while (len < field_width--)
539 *str++ = ' ';
540 continue;
541
542 case 'p':
543 if (field_width == -1) {
544 field_width = 2*sizeof(void *);
545 flags |= ZEROPAD;
546 }
547 str = number(str,
548 (unsigned long) va_arg(args, void *), 16,
549 field_width, precision, flags);
550 continue;
551
552
553 case 'n':
554 if (qualifier == 'l') {
555 long * ip = va_arg(args, long *);
556 *ip = (str - buf);
557 } else if (qualifier == 'Z') {
558 size_t * ip = va_arg(args, size_t *);
559 *ip = (str - buf);
560 } else {
561 int * ip = va_arg(args, int *);
562 *ip = (str - buf);
563 }
564 continue;
565
566 case '%':
567 *str++ = '%';
568 continue;
569
570 /* integer number formats - set up the flags and "break" */
571 case 'o':
572 base = 8;
573 break;
574
575 case 'X':
576 flags |= LARGE;
577 case 'x':
578 base = 16;
579 break;
580
581 case 'd':
582 case 'i':
583 flags |= SIGN;
584 case 'u':
585 break;
586
587 default:
588 *str++ = '%';
589 if (*fmt)
590 *str++ = *fmt;
591 else
592 --fmt;
593 continue;
594 }
595 if (qualifier == 'L')
596 num = va_arg(args, long long);
597 else if (qualifier == 'l') {
598 num = va_arg(args, unsigned long);
599 if (flags & SIGN)
600 num = (signed long) num;
601 } else if (qualifier == 'Z') {
602 num = va_arg(args, size_t);
603 } else if (qualifier == 'h') {
604 num = (unsigned short) va_arg(args, int);
605 if (flags & SIGN)
606 num = (signed short) num;
607 } else {
608 num = va_arg(args, unsigned int);
609 if (flags & SIGN)
610 num = (signed int) num;
611 }
612 str = number(str, num, base, field_width, precision, flags);
613 }
614 *str = '\0';
615 return str-buf;
616}
617
618int sprintf(char * buf, const char *fmt, ...)
619{
620 va_list args;
621 int i;
622
623 va_start(args, fmt);
624 i=vsprintf(buf,fmt,args);
625 va_end(args);
626 return i;
627}
628
629static char sprint_buf[1024];
630
631void
632printk(char *fmt, ...)
633{
634 va_list args;
635 int n;
636
637 va_start(args, fmt);
638 n = vsprintf(sprint_buf, fmt, args);
639 va_end(args);
640 write(stdout, sprint_buf, n);
641}
642
643int
644printf(char *fmt, ...)
645{
646 va_list args;
647 int n;
648
649 va_start(args, fmt);
650 n = vsprintf(sprint_buf, fmt, args);
651 va_end(args);
652 write(stdout, sprint_buf, n);
653 return n;
654}
diff --git a/arch/ppc64/configs/g5_defconfig b/arch/ppc64/configs/g5_defconfig
index 0f90df0b3f9c..1eb33398648e 100644
--- a/arch/ppc64/configs/g5_defconfig
+++ b/arch/ppc64/configs/g5_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11 3# Linux kernel version: 2.6.12-rc6
4# Thu Mar 10 16:47:04 2005 4# Tue Jun 14 16:59:20 2005
5# 5#
6CONFIG_64BIT=y 6CONFIG_64BIT=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y
11CONFIG_HAVE_DEC_LOCK=y 11CONFIG_HAVE_DEC_LOCK=y
12CONFIG_EARLY_PRINTK=y 12CONFIG_EARLY_PRINTK=y
13CONFIG_COMPAT=y 13CONFIG_COMPAT=y
14CONFIG_FRAME_POINTER=y 14CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
15CONFIG_FORCE_MAX_ZONEORDER=13 15CONFIG_FORCE_MAX_ZONEORDER=13
16 16
17# 17#
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13
20CONFIG_EXPERIMENTAL=y 20CONFIG_EXPERIMENTAL=y
21CONFIG_CLEAN_COMPILE=y 21CONFIG_CLEAN_COMPILE=y
22CONFIG_LOCK_KERNEL=y 22CONFIG_LOCK_KERNEL=y
23CONFIG_INIT_ENV_ARG_LIMIT=32
23 24
24# 25#
25# General setup 26# General setup
@@ -31,19 +32,20 @@ CONFIG_POSIX_MQUEUE=y
31# CONFIG_BSD_PROCESS_ACCT is not set 32# CONFIG_BSD_PROCESS_ACCT is not set
32CONFIG_SYSCTL=y 33CONFIG_SYSCTL=y
33# CONFIG_AUDIT is not set 34# CONFIG_AUDIT is not set
34CONFIG_LOG_BUF_SHIFT=17
35CONFIG_HOTPLUG=y 35CONFIG_HOTPLUG=y
36CONFIG_KOBJECT_UEVENT=y 36CONFIG_KOBJECT_UEVENT=y
37CONFIG_IKCONFIG=y 37CONFIG_IKCONFIG=y
38CONFIG_IKCONFIG_PROC=y 38CONFIG_IKCONFIG_PROC=y
39# CONFIG_CPUSETS is not set
39# CONFIG_EMBEDDED is not set 40# CONFIG_EMBEDDED is not set
40CONFIG_KALLSYMS=y 41CONFIG_KALLSYMS=y
41# CONFIG_KALLSYMS_ALL is not set 42# CONFIG_KALLSYMS_ALL is not set
42# CONFIG_KALLSYMS_EXTRA_PASS is not set 43# CONFIG_KALLSYMS_EXTRA_PASS is not set
44CONFIG_PRINTK=y
45CONFIG_BUG=y
43CONFIG_BASE_FULL=y 46CONFIG_BASE_FULL=y
44CONFIG_FUTEX=y 47CONFIG_FUTEX=y
45CONFIG_EPOLL=y 48CONFIG_EPOLL=y
46# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
47CONFIG_SHMEM=y 49CONFIG_SHMEM=y
48CONFIG_CC_ALIGN_FUNCTIONS=0 50CONFIG_CC_ALIGN_FUNCTIONS=0
49CONFIG_CC_ALIGN_LABELS=0 51CONFIG_CC_ALIGN_LABELS=0
@@ -87,6 +89,8 @@ CONFIG_NR_CPUS=2
87# CONFIG_SCHED_SMT is not set 89# CONFIG_SCHED_SMT is not set
88# CONFIG_PREEMPT is not set 90# CONFIG_PREEMPT is not set
89CONFIG_GENERIC_HARDIRQS=y 91CONFIG_GENERIC_HARDIRQS=y
92CONFIG_SECCOMP=y
93CONFIG_ISA_DMA_API=y
90 94
91# 95#
92# General setup 96# General setup
@@ -97,6 +101,7 @@ CONFIG_BINFMT_ELF=y
97# CONFIG_BINFMT_MISC is not set 101# CONFIG_BINFMT_MISC is not set
98CONFIG_PCI_LEGACY_PROC=y 102CONFIG_PCI_LEGACY_PROC=y
99CONFIG_PCI_NAMES=y 103CONFIG_PCI_NAMES=y
104# CONFIG_PCI_DEBUG is not set
100# CONFIG_HOTPLUG_CPU is not set 105# CONFIG_HOTPLUG_CPU is not set
101 106
102# 107#
@@ -105,10 +110,6 @@ CONFIG_PCI_NAMES=y
105# CONFIG_PCCARD is not set 110# CONFIG_PCCARD is not set
106 111
107# 112#
108# PC-card bridges
109#
110
111#
112# PCI Hotplug Support 113# PCI Hotplug Support
113# 114#
114# CONFIG_HOTPLUG_PCI is not set 115# CONFIG_HOTPLUG_PCI is not set
@@ -293,7 +294,6 @@ CONFIG_SCSI_SATA_SVW=y
293# CONFIG_SCSI_BUSLOGIC is not set 294# CONFIG_SCSI_BUSLOGIC is not set
294# CONFIG_SCSI_DMX3191D is not set 295# CONFIG_SCSI_DMX3191D is not set
295# CONFIG_SCSI_EATA is not set 296# CONFIG_SCSI_EATA is not set
296# CONFIG_SCSI_EATA_PIO is not set
297# CONFIG_SCSI_FUTURE_DOMAIN is not set 297# CONFIG_SCSI_FUTURE_DOMAIN is not set
298# CONFIG_SCSI_GDTH is not set 298# CONFIG_SCSI_GDTH is not set
299# CONFIG_SCSI_IPS is not set 299# CONFIG_SCSI_IPS is not set
@@ -301,7 +301,6 @@ CONFIG_SCSI_SATA_SVW=y
301# CONFIG_SCSI_INIA100 is not set 301# CONFIG_SCSI_INIA100 is not set
302# CONFIG_SCSI_SYM53C8XX_2 is not set 302# CONFIG_SCSI_SYM53C8XX_2 is not set
303# CONFIG_SCSI_IPR is not set 303# CONFIG_SCSI_IPR is not set
304# CONFIG_SCSI_QLOGIC_ISP is not set
305# CONFIG_SCSI_QLOGIC_FC is not set 304# CONFIG_SCSI_QLOGIC_FC is not set
306# CONFIG_SCSI_QLOGIC_1280 is not set 305# CONFIG_SCSI_QLOGIC_1280 is not set
307CONFIG_SCSI_QLA2XXX=y 306CONFIG_SCSI_QLA2XXX=y
@@ -310,6 +309,7 @@ CONFIG_SCSI_QLA2XXX=y
310# CONFIG_SCSI_QLA2300 is not set 309# CONFIG_SCSI_QLA2300 is not set
311# CONFIG_SCSI_QLA2322 is not set 310# CONFIG_SCSI_QLA2322 is not set
312# CONFIG_SCSI_QLA6312 is not set 311# CONFIG_SCSI_QLA6312 is not set
312# CONFIG_SCSI_LPFC is not set
313# CONFIG_SCSI_DC395x is not set 313# CONFIG_SCSI_DC395x is not set
314# CONFIG_SCSI_DC390T is not set 314# CONFIG_SCSI_DC390T is not set
315# CONFIG_SCSI_DEBUG is not set 315# CONFIG_SCSI_DEBUG is not set
@@ -332,6 +332,7 @@ CONFIG_DM_CRYPT=m
332CONFIG_DM_SNAPSHOT=m 332CONFIG_DM_SNAPSHOT=m
333CONFIG_DM_MIRROR=m 333CONFIG_DM_MIRROR=m
334CONFIG_DM_ZERO=m 334CONFIG_DM_ZERO=m
335# CONFIG_DM_MULTIPATH is not set
335 336
336# 337#
337# Fusion MPT device support 338# Fusion MPT device support
@@ -394,7 +395,6 @@ CONFIG_NET=y
394# 395#
395CONFIG_PACKET=y 396CONFIG_PACKET=y
396# CONFIG_PACKET_MMAP is not set 397# CONFIG_PACKET_MMAP is not set
397# CONFIG_NETLINK_DEV is not set
398CONFIG_UNIX=y 398CONFIG_UNIX=y
399CONFIG_NET_KEY=m 399CONFIG_NET_KEY=m
400CONFIG_INET=y 400CONFIG_INET=y
@@ -564,6 +564,8 @@ CONFIG_E1000=y
564# CONFIG_R8169 is not set 564# CONFIG_R8169 is not set
565# CONFIG_SK98LIN is not set 565# CONFIG_SK98LIN is not set
566CONFIG_TIGON3=m 566CONFIG_TIGON3=m
567# CONFIG_BNX2 is not set
568# CONFIG_MV643XX_ETH is not set
567 569
568# 570#
569# Ethernet (10000 Mbit) 571# Ethernet (10000 Mbit)
@@ -631,18 +633,6 @@ CONFIG_INPUT_EVDEV=y
631# CONFIG_INPUT_EVBUG is not set 633# CONFIG_INPUT_EVBUG is not set
632 634
633# 635#
634# Input I/O drivers
635#
636# CONFIG_GAMEPORT is not set
637CONFIG_SOUND_GAMEPORT=y
638CONFIG_SERIO=y
639# CONFIG_SERIO_I8042 is not set
640# CONFIG_SERIO_SERPORT is not set
641# CONFIG_SERIO_CT82C710 is not set
642# CONFIG_SERIO_PCIPS2 is not set
643# CONFIG_SERIO_RAW is not set
644
645#
646# Input Device Drivers 636# Input Device Drivers
647# 637#
648CONFIG_INPUT_KEYBOARD=y 638CONFIG_INPUT_KEYBOARD=y
@@ -660,6 +650,16 @@ CONFIG_INPUT_MOUSE=y
660# CONFIG_INPUT_MISC is not set 650# CONFIG_INPUT_MISC is not set
661 651
662# 652#
653# Hardware I/O ports
654#
655CONFIG_SERIO=y
656# CONFIG_SERIO_I8042 is not set
657# CONFIG_SERIO_SERPORT is not set
658# CONFIG_SERIO_PCIPS2 is not set
659# CONFIG_SERIO_RAW is not set
660# CONFIG_GAMEPORT is not set
661
662#
663# Character devices 663# Character devices
664# 664#
665CONFIG_VT=y 665CONFIG_VT=y
@@ -676,6 +676,7 @@ CONFIG_HW_CONSOLE=y
676# Non-8250 serial port support 676# Non-8250 serial port support
677# 677#
678# CONFIG_SERIAL_PMACZILOG is not set 678# CONFIG_SERIAL_PMACZILOG is not set
679# CONFIG_SERIAL_JSM is not set
679CONFIG_UNIX98_PTYS=y 680CONFIG_UNIX98_PTYS=y
680CONFIG_LEGACY_PTYS=y 681CONFIG_LEGACY_PTYS=y
681CONFIG_LEGACY_PTY_COUNT=256 682CONFIG_LEGACY_PTY_COUNT=256
@@ -698,9 +699,12 @@ CONFIG_LEGACY_PTY_COUNT=256
698# 699#
699# Ftape, the floppy tape device driver 700# Ftape, the floppy tape device driver
700# 701#
702CONFIG_AGP=m
703CONFIG_AGP_UNINORTH=m
701# CONFIG_DRM is not set 704# CONFIG_DRM is not set
702CONFIG_RAW_DRIVER=y 705CONFIG_RAW_DRIVER=y
703CONFIG_MAX_RAW_DEVS=256 706CONFIG_MAX_RAW_DEVS=256
707# CONFIG_HANGCHECK_TIMER is not set
704 708
705# 709#
706# TPM devices 710# TPM devices
@@ -730,12 +734,11 @@ CONFIG_I2C_ALGOBIT=y
730# CONFIG_I2C_AMD8111 is not set 734# CONFIG_I2C_AMD8111 is not set
731# CONFIG_I2C_I801 is not set 735# CONFIG_I2C_I801 is not set
732# CONFIG_I2C_I810 is not set 736# CONFIG_I2C_I810 is not set
737# CONFIG_I2C_PIIX4 is not set
733# CONFIG_I2C_ISA is not set 738# CONFIG_I2C_ISA is not set
734CONFIG_I2C_KEYWEST=y 739CONFIG_I2C_KEYWEST=y
735# CONFIG_I2C_MPC is not set
736# CONFIG_I2C_NFORCE2 is not set 740# CONFIG_I2C_NFORCE2 is not set
737# CONFIG_I2C_PARPORT_LIGHT is not set 741# CONFIG_I2C_PARPORT_LIGHT is not set
738# CONFIG_I2C_PIIX4 is not set
739# CONFIG_I2C_PROSAVAGE is not set 742# CONFIG_I2C_PROSAVAGE is not set
740# CONFIG_I2C_SAVAGE4 is not set 743# CONFIG_I2C_SAVAGE4 is not set
741# CONFIG_SCx200_ACB is not set 744# CONFIG_SCx200_ACB is not set
@@ -772,6 +775,7 @@ CONFIG_I2C_KEYWEST=y
772# CONFIG_SENSORS_LM85 is not set 775# CONFIG_SENSORS_LM85 is not set
773# CONFIG_SENSORS_LM87 is not set 776# CONFIG_SENSORS_LM87 is not set
774# CONFIG_SENSORS_LM90 is not set 777# CONFIG_SENSORS_LM90 is not set
778# CONFIG_SENSORS_LM92 is not set
775# CONFIG_SENSORS_MAX1619 is not set 779# CONFIG_SENSORS_MAX1619 is not set
776# CONFIG_SENSORS_PC87360 is not set 780# CONFIG_SENSORS_PC87360 is not set
777# CONFIG_SENSORS_SMSC47B397 is not set 781# CONFIG_SENSORS_SMSC47B397 is not set
@@ -785,6 +789,7 @@ CONFIG_I2C_KEYWEST=y
785# 789#
786# Other I2C Chip support 790# Other I2C Chip support
787# 791#
792# CONFIG_SENSORS_DS1337 is not set
788# CONFIG_SENSORS_EEPROM is not set 793# CONFIG_SENSORS_EEPROM is not set
789# CONFIG_SENSORS_PCF8574 is not set 794# CONFIG_SENSORS_PCF8574 is not set
790# CONFIG_SENSORS_PCF8591 is not set 795# CONFIG_SENSORS_PCF8591 is not set
@@ -817,6 +822,11 @@ CONFIG_I2C_KEYWEST=y
817# Graphics support 822# Graphics support
818# 823#
819CONFIG_FB=y 824CONFIG_FB=y
825CONFIG_FB_CFB_FILLRECT=y
826CONFIG_FB_CFB_COPYAREA=y
827CONFIG_FB_CFB_IMAGEBLIT=y
828CONFIG_FB_SOFT_CURSOR=y
829CONFIG_FB_MACMODES=y
820CONFIG_FB_MODE_HELPERS=y 830CONFIG_FB_MODE_HELPERS=y
821CONFIG_FB_TILEBLITTING=y 831CONFIG_FB_TILEBLITTING=y
822# CONFIG_FB_CIRRUS is not set 832# CONFIG_FB_CIRRUS is not set
@@ -830,6 +840,7 @@ CONFIG_FB_OF=y
830# CONFIG_FB_ASILIANT is not set 840# CONFIG_FB_ASILIANT is not set
831# CONFIG_FB_IMSTT is not set 841# CONFIG_FB_IMSTT is not set
832# CONFIG_FB_VGA16 is not set 842# CONFIG_FB_VGA16 is not set
843# CONFIG_FB_NVIDIA is not set
833CONFIG_FB_RIVA=y 844CONFIG_FB_RIVA=y
834# CONFIG_FB_RIVA_I2C is not set 845# CONFIG_FB_RIVA_I2C is not set
835# CONFIG_FB_RIVA_DEBUG is not set 846# CONFIG_FB_RIVA_DEBUG is not set
@@ -847,6 +858,7 @@ CONFIG_FB_RADEON_I2C=y
847# CONFIG_FB_3DFX is not set 858# CONFIG_FB_3DFX is not set
848# CONFIG_FB_VOODOO1 is not set 859# CONFIG_FB_VOODOO1 is not set
849# CONFIG_FB_TRIDENT is not set 860# CONFIG_FB_TRIDENT is not set
861# CONFIG_FB_S1D13XXX is not set
850# CONFIG_FB_VIRTUAL is not set 862# CONFIG_FB_VIRTUAL is not set
851 863
852# 864#
@@ -880,6 +892,8 @@ CONFIG_LCD_DEVICE=y
880# 892#
881# USB support 893# USB support
882# 894#
895CONFIG_USB_ARCH_HAS_HCD=y
896CONFIG_USB_ARCH_HAS_OHCI=y
883CONFIG_USB=y 897CONFIG_USB=y
884# CONFIG_USB_DEBUG is not set 898# CONFIG_USB_DEBUG is not set
885 899
@@ -890,8 +904,6 @@ CONFIG_USB_DEVICEFS=y
890# CONFIG_USB_BANDWIDTH is not set 904# CONFIG_USB_BANDWIDTH is not set
891# CONFIG_USB_DYNAMIC_MINORS is not set 905# CONFIG_USB_DYNAMIC_MINORS is not set
892# CONFIG_USB_OTG is not set 906# CONFIG_USB_OTG is not set
893CONFIG_USB_ARCH_HAS_HCD=y
894CONFIG_USB_ARCH_HAS_OHCI=y
895 907
896# 908#
897# USB Host Controller Drivers 909# USB Host Controller Drivers
@@ -917,7 +929,6 @@ CONFIG_USB_PRINTER=y
917# 929#
918CONFIG_USB_STORAGE=y 930CONFIG_USB_STORAGE=y
919# CONFIG_USB_STORAGE_DEBUG is not set 931# CONFIG_USB_STORAGE_DEBUG is not set
920CONFIG_USB_STORAGE_RW_DETECT=y
921CONFIG_USB_STORAGE_DATAFAB=y 932CONFIG_USB_STORAGE_DATAFAB=y
922CONFIG_USB_STORAGE_FREECOM=y 933CONFIG_USB_STORAGE_FREECOM=y
923CONFIG_USB_STORAGE_ISD200=y 934CONFIG_USB_STORAGE_ISD200=y
@@ -1004,8 +1015,10 @@ CONFIG_USB_MON=y
1004# 1015#
1005CONFIG_USB_SERIAL=m 1016CONFIG_USB_SERIAL=m
1006CONFIG_USB_SERIAL_GENERIC=y 1017CONFIG_USB_SERIAL_GENERIC=y
1018# CONFIG_USB_SERIAL_AIRPRIME is not set
1007CONFIG_USB_SERIAL_BELKIN=m 1019CONFIG_USB_SERIAL_BELKIN=m
1008CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m 1020CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
1021# CONFIG_USB_SERIAL_CP2101 is not set
1009CONFIG_USB_SERIAL_CYPRESS_M8=m 1022CONFIG_USB_SERIAL_CYPRESS_M8=m
1010CONFIG_USB_SERIAL_EMPEG=m 1023CONFIG_USB_SERIAL_EMPEG=m
1011CONFIG_USB_SERIAL_FTDI_SIO=m 1024CONFIG_USB_SERIAL_FTDI_SIO=m
@@ -1034,6 +1047,7 @@ CONFIG_USB_SERIAL_KLSI=m
1034CONFIG_USB_SERIAL_KOBIL_SCT=m 1047CONFIG_USB_SERIAL_KOBIL_SCT=m
1035CONFIG_USB_SERIAL_MCT_U232=m 1048CONFIG_USB_SERIAL_MCT_U232=m
1036CONFIG_USB_SERIAL_PL2303=m 1049CONFIG_USB_SERIAL_PL2303=m
1050# CONFIG_USB_SERIAL_HP4X is not set
1037CONFIG_USB_SERIAL_SAFE=m 1051CONFIG_USB_SERIAL_SAFE=m
1038CONFIG_USB_SERIAL_SAFE_PADDED=y 1052CONFIG_USB_SERIAL_SAFE_PADDED=y
1039CONFIG_USB_SERIAL_TI=m 1053CONFIG_USB_SERIAL_TI=m
@@ -1270,11 +1284,13 @@ CONFIG_OPROFILE=y
1270# 1284#
1271# Kernel hacking 1285# Kernel hacking
1272# 1286#
1287# CONFIG_PRINTK_TIME is not set
1273CONFIG_DEBUG_KERNEL=y 1288CONFIG_DEBUG_KERNEL=y
1274CONFIG_MAGIC_SYSRQ=y 1289CONFIG_MAGIC_SYSRQ=y
1275# CONFIG_PRINTK_TIME is not set 1290CONFIG_LOG_BUF_SHIFT=17
1276# CONFIG_SCHEDSTATS is not set 1291# CONFIG_SCHEDSTATS is not set
1277# CONFIG_DEBUG_SLAB is not set 1292# CONFIG_DEBUG_SLAB is not set
1293# CONFIG_DEBUG_SPINLOCK is not set
1278# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 1294# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1279# CONFIG_DEBUG_KOBJECT is not set 1295# CONFIG_DEBUG_KOBJECT is not set
1280# CONFIG_DEBUG_INFO is not set 1296# CONFIG_DEBUG_INFO is not set
diff --git a/arch/ppc64/configs/iSeries_defconfig b/arch/ppc64/configs/iSeries_defconfig
index a39e9d2e25da..f6a2b99afd63 100644
--- a/arch/ppc64/configs/iSeries_defconfig
+++ b/arch/ppc64/configs/iSeries_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-rc3-bk6 3# Linux kernel version: 2.6.12-rc6
4# Wed Feb 9 23:34:52 2005 4# Tue Jun 14 17:01:28 2005
5# 5#
6CONFIG_64BIT=y 6CONFIG_64BIT=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y
11CONFIG_HAVE_DEC_LOCK=y 11CONFIG_HAVE_DEC_LOCK=y
12CONFIG_EARLY_PRINTK=y 12CONFIG_EARLY_PRINTK=y
13CONFIG_COMPAT=y 13CONFIG_COMPAT=y
14CONFIG_FRAME_POINTER=y 14CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
15CONFIG_FORCE_MAX_ZONEORDER=13 15CONFIG_FORCE_MAX_ZONEORDER=13
16 16
17# 17#
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13
20CONFIG_EXPERIMENTAL=y 20CONFIG_EXPERIMENTAL=y
21CONFIG_CLEAN_COMPILE=y 21CONFIG_CLEAN_COMPILE=y
22CONFIG_LOCK_KERNEL=y 22CONFIG_LOCK_KERNEL=y
23CONFIG_INIT_ENV_ARG_LIMIT=32
23 24
24# 25#
25# General setup 26# General setup
@@ -30,24 +31,29 @@ CONFIG_SYSVIPC=y
30CONFIG_POSIX_MQUEUE=y 31CONFIG_POSIX_MQUEUE=y
31# CONFIG_BSD_PROCESS_ACCT is not set 32# CONFIG_BSD_PROCESS_ACCT is not set
32CONFIG_SYSCTL=y 33CONFIG_SYSCTL=y
33CONFIG_LOG_BUF_SHIFT=17 34CONFIG_AUDIT=y
35CONFIG_AUDITSYSCALL=y
34CONFIG_HOTPLUG=y 36CONFIG_HOTPLUG=y
35CONFIG_KOBJECT_UEVENT=y 37CONFIG_KOBJECT_UEVENT=y
36CONFIG_IKCONFIG=y 38CONFIG_IKCONFIG=y
37CONFIG_IKCONFIG_PROC=y 39CONFIG_IKCONFIG_PROC=y
40# CONFIG_CPUSETS is not set
38# CONFIG_EMBEDDED is not set 41# CONFIG_EMBEDDED is not set
39CONFIG_KALLSYMS=y 42CONFIG_KALLSYMS=y
40# CONFIG_KALLSYMS_ALL is not set 43# CONFIG_KALLSYMS_ALL is not set
41# CONFIG_KALLSYMS_EXTRA_PASS is not set 44# CONFIG_KALLSYMS_EXTRA_PASS is not set
45CONFIG_PRINTK=y
46CONFIG_BUG=y
47CONFIG_BASE_FULL=y
42CONFIG_FUTEX=y 48CONFIG_FUTEX=y
43CONFIG_EPOLL=y 49CONFIG_EPOLL=y
44# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
45CONFIG_SHMEM=y 50CONFIG_SHMEM=y
46CONFIG_CC_ALIGN_FUNCTIONS=0 51CONFIG_CC_ALIGN_FUNCTIONS=0
47CONFIG_CC_ALIGN_LABELS=0 52CONFIG_CC_ALIGN_LABELS=0
48CONFIG_CC_ALIGN_LOOPS=0 53CONFIG_CC_ALIGN_LOOPS=0
49CONFIG_CC_ALIGN_JUMPS=0 54CONFIG_CC_ALIGN_JUMPS=0
50# CONFIG_TINY_SHMEM is not set 55# CONFIG_TINY_SHMEM is not set
56CONFIG_BASE_SMALL=0
51 57
52# 58#
53# Loadable module support 59# Loadable module support
@@ -79,6 +85,8 @@ CONFIG_NR_CPUS=32
79CONFIG_GENERIC_HARDIRQS=y 85CONFIG_GENERIC_HARDIRQS=y
80CONFIG_MSCHUNKS=y 86CONFIG_MSCHUNKS=y
81CONFIG_LPARCFG=y 87CONFIG_LPARCFG=y
88CONFIG_SECCOMP=y
89CONFIG_ISA_DMA_API=y
82 90
83# 91#
84# General setup 92# General setup
@@ -89,6 +97,7 @@ CONFIG_BINFMT_ELF=y
89# CONFIG_BINFMT_MISC is not set 97# CONFIG_BINFMT_MISC is not set
90CONFIG_PCI_LEGACY_PROC=y 98CONFIG_PCI_LEGACY_PROC=y
91CONFIG_PCI_NAMES=y 99CONFIG_PCI_NAMES=y
100# CONFIG_PCI_DEBUG is not set
92 101
93# 102#
94# PCCARD (PCMCIA/CardBus) support 103# PCCARD (PCMCIA/CardBus) support
@@ -96,10 +105,6 @@ CONFIG_PCI_NAMES=y
96# CONFIG_PCCARD is not set 105# CONFIG_PCCARD is not set
97 106
98# 107#
99# PC-card bridges
100#
101
102#
103# PCI Hotplug Support 108# PCI Hotplug Support
104# 109#
105# CONFIG_HOTPLUG_PCI is not set 110# CONFIG_HOTPLUG_PCI is not set
@@ -210,7 +215,6 @@ CONFIG_SCSI_FC_ATTRS=y
210# CONFIG_SCSI_BUSLOGIC is not set 215# CONFIG_SCSI_BUSLOGIC is not set
211# CONFIG_SCSI_DMX3191D is not set 216# CONFIG_SCSI_DMX3191D is not set
212# CONFIG_SCSI_EATA is not set 217# CONFIG_SCSI_EATA is not set
213# CONFIG_SCSI_EATA_PIO is not set
214# CONFIG_SCSI_FUTURE_DOMAIN is not set 218# CONFIG_SCSI_FUTURE_DOMAIN is not set
215# CONFIG_SCSI_GDTH is not set 219# CONFIG_SCSI_GDTH is not set
216# CONFIG_SCSI_IPS is not set 220# CONFIG_SCSI_IPS is not set
@@ -219,7 +223,6 @@ CONFIG_SCSI_IBMVSCSI=m
219# CONFIG_SCSI_INIA100 is not set 223# CONFIG_SCSI_INIA100 is not set
220# CONFIG_SCSI_SYM53C8XX_2 is not set 224# CONFIG_SCSI_SYM53C8XX_2 is not set
221# CONFIG_SCSI_IPR is not set 225# CONFIG_SCSI_IPR is not set
222# CONFIG_SCSI_QLOGIC_ISP is not set
223# CONFIG_SCSI_QLOGIC_FC is not set 226# CONFIG_SCSI_QLOGIC_FC is not set
224# CONFIG_SCSI_QLOGIC_1280 is not set 227# CONFIG_SCSI_QLOGIC_1280 is not set
225CONFIG_SCSI_QLA2XXX=y 228CONFIG_SCSI_QLA2XXX=y
@@ -228,6 +231,7 @@ CONFIG_SCSI_QLA2XXX=y
228# CONFIG_SCSI_QLA2300 is not set 231# CONFIG_SCSI_QLA2300 is not set
229# CONFIG_SCSI_QLA2322 is not set 232# CONFIG_SCSI_QLA2322 is not set
230# CONFIG_SCSI_QLA6312 is not set 233# CONFIG_SCSI_QLA6312 is not set
234# CONFIG_SCSI_LPFC is not set
231# CONFIG_SCSI_DC395x is not set 235# CONFIG_SCSI_DC395x is not set
232# CONFIG_SCSI_DC390T is not set 236# CONFIG_SCSI_DC390T is not set
233# CONFIG_SCSI_DEBUG is not set 237# CONFIG_SCSI_DEBUG is not set
@@ -250,6 +254,7 @@ CONFIG_DM_CRYPT=m
250CONFIG_DM_SNAPSHOT=m 254CONFIG_DM_SNAPSHOT=m
251CONFIG_DM_MIRROR=m 255CONFIG_DM_MIRROR=m
252CONFIG_DM_ZERO=m 256CONFIG_DM_ZERO=m
257# CONFIG_DM_MULTIPATH is not set
253 258
254# 259#
255# Fusion MPT device support 260# Fusion MPT device support
@@ -280,7 +285,6 @@ CONFIG_NET=y
280# 285#
281CONFIG_PACKET=y 286CONFIG_PACKET=y
282# CONFIG_PACKET_MMAP is not set 287# CONFIG_PACKET_MMAP is not set
283# CONFIG_NETLINK_DEV is not set
284CONFIG_UNIX=y 288CONFIG_UNIX=y
285CONFIG_NET_KEY=m 289CONFIG_NET_KEY=m
286CONFIG_INET=y 290CONFIG_INET=y
@@ -445,7 +449,6 @@ CONFIG_PCNET32=y
445# CONFIG_DGRS is not set 449# CONFIG_DGRS is not set
446# CONFIG_EEPRO100 is not set 450# CONFIG_EEPRO100 is not set
447CONFIG_E100=y 451CONFIG_E100=y
448# CONFIG_E100_NAPI is not set
449# CONFIG_FEALNX is not set 452# CONFIG_FEALNX is not set
450# CONFIG_NATSEMI is not set 453# CONFIG_NATSEMI is not set
451# CONFIG_NE2K_PCI is not set 454# CONFIG_NE2K_PCI is not set
@@ -471,6 +474,7 @@ CONFIG_E1000=m
471# CONFIG_SK98LIN is not set 474# CONFIG_SK98LIN is not set
472# CONFIG_VIA_VELOCITY is not set 475# CONFIG_VIA_VELOCITY is not set
473# CONFIG_TIGON3 is not set 476# CONFIG_TIGON3 is not set
477# CONFIG_BNX2 is not set
474 478
475# 479#
476# Ethernet (10000 Mbit) 480# Ethernet (10000 Mbit)
@@ -539,14 +543,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
539# CONFIG_INPUT_EVBUG is not set 543# CONFIG_INPUT_EVBUG is not set
540 544
541# 545#
542# Input I/O drivers
543#
544# CONFIG_GAMEPORT is not set
545CONFIG_SOUND_GAMEPORT=y
546# CONFIG_SERIO is not set
547# CONFIG_SERIO_I8042 is not set
548
549#
550# Input Device Drivers 546# Input Device Drivers
551# 547#
552# CONFIG_INPUT_KEYBOARD is not set 548# CONFIG_INPUT_KEYBOARD is not set
@@ -556,6 +552,12 @@ CONFIG_SOUND_GAMEPORT=y
556# CONFIG_INPUT_MISC is not set 552# CONFIG_INPUT_MISC is not set
557 553
558# 554#
555# Hardware I/O ports
556#
557# CONFIG_SERIO is not set
558# CONFIG_GAMEPORT is not set
559
560#
559# Character devices 561# Character devices
560# 562#
561# CONFIG_SERIAL_NONSTANDARD is not set 563# CONFIG_SERIAL_NONSTANDARD is not set
@@ -570,6 +572,7 @@ CONFIG_SOUND_GAMEPORT=y
570# 572#
571CONFIG_SERIAL_CORE=m 573CONFIG_SERIAL_CORE=m
572CONFIG_SERIAL_ICOM=m 574CONFIG_SERIAL_ICOM=m
575# CONFIG_SERIAL_JSM is not set
573CONFIG_UNIX98_PTYS=y 576CONFIG_UNIX98_PTYS=y
574CONFIG_LEGACY_PTYS=y 577CONFIG_LEGACY_PTYS=y
575CONFIG_LEGACY_PTY_COUNT=256 578CONFIG_LEGACY_PTY_COUNT=256
@@ -592,9 +595,16 @@ CONFIG_LEGACY_PTY_COUNT=256
592# 595#
593# Ftape, the floppy tape device driver 596# Ftape, the floppy tape device driver
594# 597#
598# CONFIG_AGP is not set
595# CONFIG_DRM is not set 599# CONFIG_DRM is not set
596CONFIG_RAW_DRIVER=y 600CONFIG_RAW_DRIVER=y
597CONFIG_MAX_RAW_DEVS=256 601CONFIG_MAX_RAW_DEVS=256
602# CONFIG_HANGCHECK_TIMER is not set
603
604#
605# TPM devices
606#
607# CONFIG_TCG_TPM is not set
598 608
599# 609#
600# I2C support 610# I2C support
@@ -633,13 +643,9 @@ CONFIG_MAX_RAW_DEVS=256
633# 643#
634# USB support 644# USB support
635# 645#
636# CONFIG_USB is not set
637CONFIG_USB_ARCH_HAS_HCD=y 646CONFIG_USB_ARCH_HAS_HCD=y
638CONFIG_USB_ARCH_HAS_OHCI=y 647CONFIG_USB_ARCH_HAS_OHCI=y
639 648# CONFIG_USB is not set
640#
641# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
642#
643 649
644# 650#
645# USB Gadget Support 651# USB Gadget Support
@@ -848,10 +854,13 @@ CONFIG_OPROFILE=y
848# 854#
849# Kernel hacking 855# Kernel hacking
850# 856#
857# CONFIG_PRINTK_TIME is not set
851CONFIG_DEBUG_KERNEL=y 858CONFIG_DEBUG_KERNEL=y
852CONFIG_MAGIC_SYSRQ=y 859CONFIG_MAGIC_SYSRQ=y
860CONFIG_LOG_BUF_SHIFT=17
853# CONFIG_SCHEDSTATS is not set 861# CONFIG_SCHEDSTATS is not set
854# CONFIG_DEBUG_SLAB is not set 862# CONFIG_DEBUG_SLAB is not set
863# CONFIG_DEBUG_SPINLOCK is not set
855# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 864# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
856# CONFIG_DEBUG_KOBJECT is not set 865# CONFIG_DEBUG_KOBJECT is not set
857# CONFIG_DEBUG_INFO is not set 866# CONFIG_DEBUG_INFO is not set
@@ -881,6 +890,7 @@ CONFIG_CRYPTO_SHA1=m
881CONFIG_CRYPTO_SHA256=m 890CONFIG_CRYPTO_SHA256=m
882CONFIG_CRYPTO_SHA512=m 891CONFIG_CRYPTO_SHA512=m
883CONFIG_CRYPTO_WP512=m 892CONFIG_CRYPTO_WP512=m
893CONFIG_CRYPTO_TGR192=m
884CONFIG_CRYPTO_DES=y 894CONFIG_CRYPTO_DES=y
885CONFIG_CRYPTO_BLOWFISH=m 895CONFIG_CRYPTO_BLOWFISH=m
886CONFIG_CRYPTO_TWOFISH=m 896CONFIG_CRYPTO_TWOFISH=m
diff --git a/arch/ppc64/configs/maple_defconfig b/arch/ppc64/configs/maple_defconfig
index cf527501915c..8051b0f47b6f 100644
--- a/arch/ppc64/configs/maple_defconfig
+++ b/arch/ppc64/configs/maple_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-rc3-bk6 3# Linux kernel version: 2.6.12-rc6
4# Wed Feb 9 23:34:53 2005 4# Tue Jun 14 17:12:48 2005
5# 5#
6CONFIG_64BIT=y 6CONFIG_64BIT=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y
11CONFIG_HAVE_DEC_LOCK=y 11CONFIG_HAVE_DEC_LOCK=y
12CONFIG_EARLY_PRINTK=y 12CONFIG_EARLY_PRINTK=y
13CONFIG_COMPAT=y 13CONFIG_COMPAT=y
14CONFIG_FRAME_POINTER=y 14CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
15CONFIG_FORCE_MAX_ZONEORDER=13 15CONFIG_FORCE_MAX_ZONEORDER=13
16 16
17# 17#
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13
20CONFIG_EXPERIMENTAL=y 20CONFIG_EXPERIMENTAL=y
21CONFIG_CLEAN_COMPILE=y 21CONFIG_CLEAN_COMPILE=y
22CONFIG_LOCK_KERNEL=y 22CONFIG_LOCK_KERNEL=y
23CONFIG_INIT_ENV_ARG_LIMIT=32
23 24
24# 25#
25# General setup 26# General setup
@@ -30,24 +31,28 @@ CONFIG_SYSVIPC=y
30CONFIG_POSIX_MQUEUE=y 31CONFIG_POSIX_MQUEUE=y
31# CONFIG_BSD_PROCESS_ACCT is not set 32# CONFIG_BSD_PROCESS_ACCT is not set
32CONFIG_SYSCTL=y 33CONFIG_SYSCTL=y
33CONFIG_LOG_BUF_SHIFT=17 34# CONFIG_AUDIT is not set
34# CONFIG_HOTPLUG is not set 35# CONFIG_HOTPLUG is not set
35CONFIG_KOBJECT_UEVENT=y 36CONFIG_KOBJECT_UEVENT=y
36CONFIG_IKCONFIG=y 37CONFIG_IKCONFIG=y
37CONFIG_IKCONFIG_PROC=y 38CONFIG_IKCONFIG_PROC=y
39# CONFIG_CPUSETS is not set
38# CONFIG_EMBEDDED is not set 40# CONFIG_EMBEDDED is not set
39CONFIG_KALLSYMS=y 41CONFIG_KALLSYMS=y
40CONFIG_KALLSYMS_ALL=y 42CONFIG_KALLSYMS_ALL=y
41# CONFIG_KALLSYMS_EXTRA_PASS is not set 43# CONFIG_KALLSYMS_EXTRA_PASS is not set
44CONFIG_PRINTK=y
45CONFIG_BUG=y
46CONFIG_BASE_FULL=y
42CONFIG_FUTEX=y 47CONFIG_FUTEX=y
43CONFIG_EPOLL=y 48CONFIG_EPOLL=y
44# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
45CONFIG_SHMEM=y 49CONFIG_SHMEM=y
46CONFIG_CC_ALIGN_FUNCTIONS=0 50CONFIG_CC_ALIGN_FUNCTIONS=0
47CONFIG_CC_ALIGN_LABELS=0 51CONFIG_CC_ALIGN_LABELS=0
48CONFIG_CC_ALIGN_LOOPS=0 52CONFIG_CC_ALIGN_LOOPS=0
49CONFIG_CC_ALIGN_JUMPS=0 53CONFIG_CC_ALIGN_JUMPS=0
50# CONFIG_TINY_SHMEM is not set 54# CONFIG_TINY_SHMEM is not set
55CONFIG_BASE_SMALL=0
51 56
52# 57#
53# Loadable module support 58# Loadable module support
@@ -84,6 +89,8 @@ CONFIG_NR_CPUS=2
84# CONFIG_SCHED_SMT is not set 89# CONFIG_SCHED_SMT is not set
85# CONFIG_PREEMPT is not set 90# CONFIG_PREEMPT is not set
86CONFIG_GENERIC_HARDIRQS=y 91CONFIG_GENERIC_HARDIRQS=y
92CONFIG_SECCOMP=y
93CONFIG_ISA_DMA_API=y
87 94
88# 95#
89# General setup 96# General setup
@@ -94,6 +101,7 @@ CONFIG_BINFMT_ELF=y
94# CONFIG_BINFMT_MISC is not set 101# CONFIG_BINFMT_MISC is not set
95CONFIG_PCI_LEGACY_PROC=y 102CONFIG_PCI_LEGACY_PROC=y
96CONFIG_PCI_NAMES=y 103CONFIG_PCI_NAMES=y
104# CONFIG_PCI_DEBUG is not set
97 105
98# 106#
99# PCCARD (PCMCIA/CardBus) support 107# PCCARD (PCMCIA/CardBus) support
@@ -101,10 +109,6 @@ CONFIG_PCI_NAMES=y
101# CONFIG_PCCARD is not set 109# CONFIG_PCCARD is not set
102 110
103# 111#
104# PC-card bridges
105#
106
107#
108# PCI Hotplug Support 112# PCI Hotplug Support
109# 113#
110# CONFIG_HOTPLUG_PCI is not set 114# CONFIG_HOTPLUG_PCI is not set
@@ -261,7 +265,6 @@ CONFIG_NET=y
261# 265#
262CONFIG_PACKET=y 266CONFIG_PACKET=y
263CONFIG_PACKET_MMAP=y 267CONFIG_PACKET_MMAP=y
264# CONFIG_NETLINK_DEV is not set
265CONFIG_UNIX=y 268CONFIG_UNIX=y
266# CONFIG_NET_KEY is not set 269# CONFIG_NET_KEY is not set
267CONFIG_INET=y 270CONFIG_INET=y
@@ -376,6 +379,8 @@ CONFIG_E1000=y
376# CONFIG_SK98LIN is not set 379# CONFIG_SK98LIN is not set
377# CONFIG_VIA_VELOCITY is not set 380# CONFIG_VIA_VELOCITY is not set
378# CONFIG_TIGON3 is not set 381# CONFIG_TIGON3 is not set
382# CONFIG_BNX2 is not set
383# CONFIG_MV643XX_ETH is not set
379 384
380# 385#
381# Ethernet (10000 Mbit) 386# Ethernet (10000 Mbit)
@@ -432,14 +437,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1200
432# CONFIG_INPUT_EVBUG is not set 437# CONFIG_INPUT_EVBUG is not set
433 438
434# 439#
435# Input I/O drivers
436#
437# CONFIG_GAMEPORT is not set
438CONFIG_SOUND_GAMEPORT=y
439# CONFIG_SERIO is not set
440# CONFIG_SERIO_I8042 is not set
441
442#
443# Input Device Drivers 440# Input Device Drivers
444# 441#
445# CONFIG_INPUT_KEYBOARD is not set 442# CONFIG_INPUT_KEYBOARD is not set
@@ -449,6 +446,12 @@ CONFIG_SOUND_GAMEPORT=y
449# CONFIG_INPUT_MISC is not set 446# CONFIG_INPUT_MISC is not set
450 447
451# 448#
449# Hardware I/O ports
450#
451# CONFIG_SERIO is not set
452# CONFIG_GAMEPORT is not set
453
454#
452# Character devices 455# Character devices
453# 456#
454CONFIG_VT=y 457CONFIG_VT=y
@@ -469,7 +472,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
469# 472#
470CONFIG_SERIAL_CORE=y 473CONFIG_SERIAL_CORE=y
471CONFIG_SERIAL_CORE_CONSOLE=y 474CONFIG_SERIAL_CORE_CONSOLE=y
472# CONFIG_SERIAL_PMACZILOG is not set 475# CONFIG_SERIAL_JSM is not set
473CONFIG_UNIX98_PTYS=y 476CONFIG_UNIX98_PTYS=y
474CONFIG_LEGACY_PTYS=y 477CONFIG_LEGACY_PTYS=y
475CONFIG_LEGACY_PTY_COUNT=256 478CONFIG_LEGACY_PTY_COUNT=256
@@ -492,8 +495,15 @@ CONFIG_LEGACY_PTY_COUNT=256
492# 495#
493# Ftape, the floppy tape device driver 496# Ftape, the floppy tape device driver
494# 497#
498# CONFIG_AGP is not set
495# CONFIG_DRM is not set 499# CONFIG_DRM is not set
496# CONFIG_RAW_DRIVER is not set 500# CONFIG_RAW_DRIVER is not set
501# CONFIG_HANGCHECK_TIMER is not set
502
503#
504# TPM devices
505#
506# CONFIG_TCG_TPM is not set
497 507
498# 508#
499# I2C support 509# I2C support
@@ -518,8 +528,8 @@ CONFIG_I2C_ALGOBIT=y
518CONFIG_I2C_AMD8111=y 528CONFIG_I2C_AMD8111=y
519# CONFIG_I2C_I801 is not set 529# CONFIG_I2C_I801 is not set
520# CONFIG_I2C_I810 is not set 530# CONFIG_I2C_I810 is not set
531# CONFIG_I2C_PIIX4 is not set
521# CONFIG_I2C_ISA is not set 532# CONFIG_I2C_ISA is not set
522# CONFIG_I2C_MPC is not set
523# CONFIG_I2C_NFORCE2 is not set 533# CONFIG_I2C_NFORCE2 is not set
524# CONFIG_I2C_PARPORT_LIGHT is not set 534# CONFIG_I2C_PARPORT_LIGHT is not set
525# CONFIG_I2C_PROSAVAGE is not set 535# CONFIG_I2C_PROSAVAGE is not set
@@ -545,7 +555,9 @@ CONFIG_I2C_AMD8111=y
545# CONFIG_SENSORS_ASB100 is not set 555# CONFIG_SENSORS_ASB100 is not set
546# CONFIG_SENSORS_DS1621 is not set 556# CONFIG_SENSORS_DS1621 is not set
547# CONFIG_SENSORS_FSCHER is not set 557# CONFIG_SENSORS_FSCHER is not set
558# CONFIG_SENSORS_FSCPOS is not set
548# CONFIG_SENSORS_GL518SM is not set 559# CONFIG_SENSORS_GL518SM is not set
560# CONFIG_SENSORS_GL520SM is not set
549# CONFIG_SENSORS_IT87 is not set 561# CONFIG_SENSORS_IT87 is not set
550# CONFIG_SENSORS_LM63 is not set 562# CONFIG_SENSORS_LM63 is not set
551# CONFIG_SENSORS_LM75 is not set 563# CONFIG_SENSORS_LM75 is not set
@@ -556,9 +568,11 @@ CONFIG_I2C_AMD8111=y
556# CONFIG_SENSORS_LM85 is not set 568# CONFIG_SENSORS_LM85 is not set
557# CONFIG_SENSORS_LM87 is not set 569# CONFIG_SENSORS_LM87 is not set
558# CONFIG_SENSORS_LM90 is not set 570# CONFIG_SENSORS_LM90 is not set
571# CONFIG_SENSORS_LM92 is not set
559# CONFIG_SENSORS_MAX1619 is not set 572# CONFIG_SENSORS_MAX1619 is not set
560# CONFIG_SENSORS_PC87360 is not set 573# CONFIG_SENSORS_PC87360 is not set
561# CONFIG_SENSORS_SMSC47B397 is not set 574# CONFIG_SENSORS_SMSC47B397 is not set
575# CONFIG_SENSORS_SIS5595 is not set
562# CONFIG_SENSORS_SMSC47M1 is not set 576# CONFIG_SENSORS_SMSC47M1 is not set
563# CONFIG_SENSORS_VIA686A is not set 577# CONFIG_SENSORS_VIA686A is not set
564# CONFIG_SENSORS_W83781D is not set 578# CONFIG_SENSORS_W83781D is not set
@@ -568,6 +582,7 @@ CONFIG_I2C_AMD8111=y
568# 582#
569# Other I2C Chip support 583# Other I2C Chip support
570# 584#
585# CONFIG_SENSORS_DS1337 is not set
571# CONFIG_SENSORS_EEPROM is not set 586# CONFIG_SENSORS_EEPROM is not set
572# CONFIG_SENSORS_PCF8574 is not set 587# CONFIG_SENSORS_PCF8574 is not set
573# CONFIG_SENSORS_PCF8591 is not set 588# CONFIG_SENSORS_PCF8591 is not set
@@ -615,6 +630,8 @@ CONFIG_DUMMY_CONSOLE=y
615# 630#
616# USB support 631# USB support
617# 632#
633CONFIG_USB_ARCH_HAS_HCD=y
634CONFIG_USB_ARCH_HAS_OHCI=y
618CONFIG_USB=y 635CONFIG_USB=y
619# CONFIG_USB_DEBUG is not set 636# CONFIG_USB_DEBUG is not set
620 637
@@ -625,8 +642,6 @@ CONFIG_USB_DEVICEFS=y
625# CONFIG_USB_BANDWIDTH is not set 642# CONFIG_USB_BANDWIDTH is not set
626# CONFIG_USB_DYNAMIC_MINORS is not set 643# CONFIG_USB_DYNAMIC_MINORS is not set
627# CONFIG_USB_OTG is not set 644# CONFIG_USB_OTG is not set
628CONFIG_USB_ARCH_HAS_HCD=y
629CONFIG_USB_ARCH_HAS_OHCI=y
630 645
631# 646#
632# USB Host Controller Drivers 647# USB Host Controller Drivers
@@ -635,6 +650,8 @@ CONFIG_USB_EHCI_HCD=y
635CONFIG_USB_EHCI_SPLIT_ISO=y 650CONFIG_USB_EHCI_SPLIT_ISO=y
636CONFIG_USB_EHCI_ROOT_HUB_TT=y 651CONFIG_USB_EHCI_ROOT_HUB_TT=y
637CONFIG_USB_OHCI_HCD=y 652CONFIG_USB_OHCI_HCD=y
653# CONFIG_USB_OHCI_BIG_ENDIAN is not set
654CONFIG_USB_OHCI_LITTLE_ENDIAN=y
638CONFIG_USB_UHCI_HCD=y 655CONFIG_USB_UHCI_HCD=y
639# CONFIG_USB_SL811_HCD is not set 656# CONFIG_USB_SL811_HCD is not set
640 657
@@ -688,6 +705,7 @@ CONFIG_USB_HIDINPUT=y
688CONFIG_USB_PEGASUS=y 705CONFIG_USB_PEGASUS=y
689# CONFIG_USB_RTL8150 is not set 706# CONFIG_USB_RTL8150 is not set
690# CONFIG_USB_USBNET is not set 707# CONFIG_USB_USBNET is not set
708CONFIG_USB_MON=y
691 709
692# 710#
693# USB port drivers 711# USB port drivers
@@ -699,8 +717,10 @@ CONFIG_USB_PEGASUS=y
699CONFIG_USB_SERIAL=y 717CONFIG_USB_SERIAL=y
700# CONFIG_USB_SERIAL_CONSOLE is not set 718# CONFIG_USB_SERIAL_CONSOLE is not set
701CONFIG_USB_SERIAL_GENERIC=y 719CONFIG_USB_SERIAL_GENERIC=y
720# CONFIG_USB_SERIAL_AIRPRIME is not set
702# CONFIG_USB_SERIAL_BELKIN is not set 721# CONFIG_USB_SERIAL_BELKIN is not set
703# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set 722# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
723# CONFIG_USB_SERIAL_CP2101 is not set
704CONFIG_USB_SERIAL_CYPRESS_M8=m 724CONFIG_USB_SERIAL_CYPRESS_M8=m
705# CONFIG_USB_SERIAL_EMPEG is not set 725# CONFIG_USB_SERIAL_EMPEG is not set
706# CONFIG_USB_SERIAL_FTDI_SIO is not set 726# CONFIG_USB_SERIAL_FTDI_SIO is not set
@@ -729,6 +749,7 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
729# CONFIG_USB_SERIAL_KOBIL_SCT is not set 749# CONFIG_USB_SERIAL_KOBIL_SCT is not set
730# CONFIG_USB_SERIAL_MCT_U232 is not set 750# CONFIG_USB_SERIAL_MCT_U232 is not set
731# CONFIG_USB_SERIAL_PL2303 is not set 751# CONFIG_USB_SERIAL_PL2303 is not set
752# CONFIG_USB_SERIAL_HP4X is not set
732# CONFIG_USB_SERIAL_SAFE is not set 753# CONFIG_USB_SERIAL_SAFE is not set
733CONFIG_USB_SERIAL_TI=m 754CONFIG_USB_SERIAL_TI=m
734# CONFIG_USB_SERIAL_CYBERJACK is not set 755# CONFIG_USB_SERIAL_CYBERJACK is not set
@@ -750,6 +771,7 @@ CONFIG_USB_EZUSB=y
750# CONFIG_USB_PHIDGETKIT is not set 771# CONFIG_USB_PHIDGETKIT is not set
751# CONFIG_USB_PHIDGETSERVO is not set 772# CONFIG_USB_PHIDGETSERVO is not set
752# CONFIG_USB_IDMOUSE is not set 773# CONFIG_USB_IDMOUSE is not set
774# CONFIG_USB_SISUSBVGA is not set
753# CONFIG_USB_TEST is not set 775# CONFIG_USB_TEST is not set
754 776
755# 777#
@@ -936,10 +958,13 @@ CONFIG_NLS_UTF8=y
936# 958#
937# Kernel hacking 959# Kernel hacking
938# 960#
961# CONFIG_PRINTK_TIME is not set
939CONFIG_DEBUG_KERNEL=y 962CONFIG_DEBUG_KERNEL=y
940CONFIG_MAGIC_SYSRQ=y 963CONFIG_MAGIC_SYSRQ=y
964CONFIG_LOG_BUF_SHIFT=17
941# CONFIG_SCHEDSTATS is not set 965# CONFIG_SCHEDSTATS is not set
942CONFIG_DEBUG_SLAB=y 966CONFIG_DEBUG_SLAB=y
967# CONFIG_DEBUG_SPINLOCK is not set
943CONFIG_DEBUG_SPINLOCK_SLEEP=y 968CONFIG_DEBUG_SPINLOCK_SLEEP=y
944# CONFIG_DEBUG_KOBJECT is not set 969# CONFIG_DEBUG_KOBJECT is not set
945# CONFIG_DEBUG_INFO is not set 970# CONFIG_DEBUG_INFO is not set
@@ -971,6 +996,7 @@ CONFIG_CRYPTO_MD5=y
971# CONFIG_CRYPTO_SHA256 is not set 996# CONFIG_CRYPTO_SHA256 is not set
972# CONFIG_CRYPTO_SHA512 is not set 997# CONFIG_CRYPTO_SHA512 is not set
973# CONFIG_CRYPTO_WP512 is not set 998# CONFIG_CRYPTO_WP512 is not set
999# CONFIG_CRYPTO_TGR192 is not set
974CONFIG_CRYPTO_DES=y 1000CONFIG_CRYPTO_DES=y
975# CONFIG_CRYPTO_BLOWFISH is not set 1001# CONFIG_CRYPTO_BLOWFISH is not set
976# CONFIG_CRYPTO_TWOFISH is not set 1002# CONFIG_CRYPTO_TWOFISH is not set
diff --git a/arch/ppc64/configs/pSeries_defconfig b/arch/ppc64/configs/pSeries_defconfig
index 4fecf237d5c9..3eb5ef25d3a3 100644
--- a/arch/ppc64/configs/pSeries_defconfig
+++ b/arch/ppc64/configs/pSeries_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-rc3-bk6 3# Linux kernel version: 2.6.12-rc6
4# Wed Feb 9 23:34:54 2005 4# Tue Jun 14 17:13:47 2005
5# 5#
6CONFIG_64BIT=y 6CONFIG_64BIT=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y
11CONFIG_HAVE_DEC_LOCK=y 11CONFIG_HAVE_DEC_LOCK=y
12CONFIG_EARLY_PRINTK=y 12CONFIG_EARLY_PRINTK=y
13CONFIG_COMPAT=y 13CONFIG_COMPAT=y
14CONFIG_FRAME_POINTER=y 14CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
15CONFIG_FORCE_MAX_ZONEORDER=13 15CONFIG_FORCE_MAX_ZONEORDER=13
16 16
17# 17#
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13
20CONFIG_EXPERIMENTAL=y 20CONFIG_EXPERIMENTAL=y
21CONFIG_CLEAN_COMPILE=y 21CONFIG_CLEAN_COMPILE=y
22CONFIG_LOCK_KERNEL=y 22CONFIG_LOCK_KERNEL=y
23CONFIG_INIT_ENV_ARG_LIMIT=32
23 24
24# 25#
25# General setup 26# General setup
@@ -30,24 +31,29 @@ CONFIG_SYSVIPC=y
30CONFIG_POSIX_MQUEUE=y 31CONFIG_POSIX_MQUEUE=y
31# CONFIG_BSD_PROCESS_ACCT is not set 32# CONFIG_BSD_PROCESS_ACCT is not set
32CONFIG_SYSCTL=y 33CONFIG_SYSCTL=y
33CONFIG_LOG_BUF_SHIFT=17 34CONFIG_AUDIT=y
35CONFIG_AUDITSYSCALL=y
34CONFIG_HOTPLUG=y 36CONFIG_HOTPLUG=y
35CONFIG_KOBJECT_UEVENT=y 37CONFIG_KOBJECT_UEVENT=y
36CONFIG_IKCONFIG=y 38CONFIG_IKCONFIG=y
37CONFIG_IKCONFIG_PROC=y 39CONFIG_IKCONFIG_PROC=y
40CONFIG_CPUSETS=y
38# CONFIG_EMBEDDED is not set 41# CONFIG_EMBEDDED is not set
39CONFIG_KALLSYMS=y 42CONFIG_KALLSYMS=y
40CONFIG_KALLSYMS_ALL=y 43CONFIG_KALLSYMS_ALL=y
41# CONFIG_KALLSYMS_EXTRA_PASS is not set 44# CONFIG_KALLSYMS_EXTRA_PASS is not set
45CONFIG_PRINTK=y
46CONFIG_BUG=y
47CONFIG_BASE_FULL=y
42CONFIG_FUTEX=y 48CONFIG_FUTEX=y
43CONFIG_EPOLL=y 49CONFIG_EPOLL=y
44# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
45CONFIG_SHMEM=y 50CONFIG_SHMEM=y
46CONFIG_CC_ALIGN_FUNCTIONS=0 51CONFIG_CC_ALIGN_FUNCTIONS=0
47CONFIG_CC_ALIGN_LABELS=0 52CONFIG_CC_ALIGN_LABELS=0
48CONFIG_CC_ALIGN_LOOPS=0 53CONFIG_CC_ALIGN_LOOPS=0
49CONFIG_CC_ALIGN_JUMPS=0 54CONFIG_CC_ALIGN_JUMPS=0
50# CONFIG_TINY_SHMEM is not set 55# CONFIG_TINY_SHMEM is not set
56CONFIG_BASE_SMALL=0
51 57
52# 58#
53# Loadable module support 59# Loadable module support
@@ -89,9 +95,12 @@ CONFIG_SCHED_SMT=y
89CONFIG_EEH=y 95CONFIG_EEH=y
90CONFIG_GENERIC_HARDIRQS=y 96CONFIG_GENERIC_HARDIRQS=y
91CONFIG_PPC_RTAS=y 97CONFIG_PPC_RTAS=y
98CONFIG_RTAS_PROC=y
92CONFIG_RTAS_FLASH=m 99CONFIG_RTAS_FLASH=m
93CONFIG_SCANLOG=m 100CONFIG_SCANLOG=m
94CONFIG_LPARCFG=y 101CONFIG_LPARCFG=y
102CONFIG_SECCOMP=y
103CONFIG_ISA_DMA_API=y
95 104
96# 105#
97# General setup 106# General setup
@@ -102,6 +111,7 @@ CONFIG_BINFMT_ELF=y
102# CONFIG_BINFMT_MISC is not set 111# CONFIG_BINFMT_MISC is not set
103CONFIG_PCI_LEGACY_PROC=y 112CONFIG_PCI_LEGACY_PROC=y
104CONFIG_PCI_NAMES=y 113CONFIG_PCI_NAMES=y
114# CONFIG_PCI_DEBUG is not set
105CONFIG_HOTPLUG_CPU=y 115CONFIG_HOTPLUG_CPU=y
106 116
107# 117#
@@ -110,10 +120,6 @@ CONFIG_HOTPLUG_CPU=y
110# CONFIG_PCCARD is not set 120# CONFIG_PCCARD is not set
111 121
112# 122#
113# PC-card bridges
114#
115
116#
117# PCI Hotplug Support 123# PCI Hotplug Support
118# 124#
119CONFIG_HOTPLUG_PCI=m 125CONFIG_HOTPLUG_PCI=m
@@ -147,11 +153,10 @@ CONFIG_FW_LOADER=y
147# 153#
148CONFIG_PARPORT=m 154CONFIG_PARPORT=m
149CONFIG_PARPORT_PC=m 155CONFIG_PARPORT_PC=m
150CONFIG_PARPORT_PC_CML1=m
151# CONFIG_PARPORT_SERIAL is not set 156# CONFIG_PARPORT_SERIAL is not set
152# CONFIG_PARPORT_PC_FIFO is not set 157# CONFIG_PARPORT_PC_FIFO is not set
153# CONFIG_PARPORT_PC_SUPERIO is not set 158# CONFIG_PARPORT_PC_SUPERIO is not set
154# CONFIG_PARPORT_OTHER is not set 159# CONFIG_PARPORT_GSC is not set
155# CONFIG_PARPORT_1284 is not set 160# CONFIG_PARPORT_1284 is not set
156 161
157# 162#
@@ -293,7 +298,6 @@ CONFIG_SCSI_ISCSI_ATTRS=m
293# CONFIG_SCSI_BUSLOGIC is not set 298# CONFIG_SCSI_BUSLOGIC is not set
294# CONFIG_SCSI_DMX3191D is not set 299# CONFIG_SCSI_DMX3191D is not set
295# CONFIG_SCSI_EATA is not set 300# CONFIG_SCSI_EATA is not set
296# CONFIG_SCSI_EATA_PIO is not set
297# CONFIG_SCSI_FUTURE_DOMAIN is not set 301# CONFIG_SCSI_FUTURE_DOMAIN is not set
298# CONFIG_SCSI_GDTH is not set 302# CONFIG_SCSI_GDTH is not set
299# CONFIG_SCSI_IPS is not set 303# CONFIG_SCSI_IPS is not set
@@ -310,7 +314,6 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
310CONFIG_SCSI_IPR=y 314CONFIG_SCSI_IPR=y
311CONFIG_SCSI_IPR_TRACE=y 315CONFIG_SCSI_IPR_TRACE=y
312CONFIG_SCSI_IPR_DUMP=y 316CONFIG_SCSI_IPR_DUMP=y
313# CONFIG_SCSI_QLOGIC_ISP is not set
314# CONFIG_SCSI_QLOGIC_FC is not set 317# CONFIG_SCSI_QLOGIC_FC is not set
315# CONFIG_SCSI_QLOGIC_1280 is not set 318# CONFIG_SCSI_QLOGIC_1280 is not set
316CONFIG_SCSI_QLA2XXX=y 319CONFIG_SCSI_QLA2XXX=y
@@ -319,6 +322,7 @@ CONFIG_SCSI_QLA22XX=m
319CONFIG_SCSI_QLA2300=m 322CONFIG_SCSI_QLA2300=m
320CONFIG_SCSI_QLA2322=m 323CONFIG_SCSI_QLA2322=m
321CONFIG_SCSI_QLA6312=m 324CONFIG_SCSI_QLA6312=m
325CONFIG_SCSI_LPFC=m
322# CONFIG_SCSI_DC395x is not set 326# CONFIG_SCSI_DC395x is not set
323# CONFIG_SCSI_DC390T is not set 327# CONFIG_SCSI_DC390T is not set
324# CONFIG_SCSI_DEBUG is not set 328# CONFIG_SCSI_DEBUG is not set
@@ -341,6 +345,8 @@ CONFIG_DM_CRYPT=m
341CONFIG_DM_SNAPSHOT=m 345CONFIG_DM_SNAPSHOT=m
342CONFIG_DM_MIRROR=m 346CONFIG_DM_MIRROR=m
343CONFIG_DM_ZERO=m 347CONFIG_DM_ZERO=m
348CONFIG_DM_MULTIPATH=m
349CONFIG_DM_MULTIPATH_EMC=m
344 350
345# 351#
346# Fusion MPT device support 352# Fusion MPT device support
@@ -371,7 +377,6 @@ CONFIG_NET=y
371# 377#
372CONFIG_PACKET=y 378CONFIG_PACKET=y
373# CONFIG_PACKET_MMAP is not set 379# CONFIG_PACKET_MMAP is not set
374# CONFIG_NETLINK_DEV is not set
375CONFIG_UNIX=y 380CONFIG_UNIX=y
376CONFIG_NET_KEY=m 381CONFIG_NET_KEY=m
377CONFIG_INET=y 382CONFIG_INET=y
@@ -539,7 +544,6 @@ CONFIG_PCNET32=y
539# CONFIG_DGRS is not set 544# CONFIG_DGRS is not set
540# CONFIG_EEPRO100 is not set 545# CONFIG_EEPRO100 is not set
541CONFIG_E100=y 546CONFIG_E100=y
542# CONFIG_E100_NAPI is not set
543# CONFIG_FEALNX is not set 547# CONFIG_FEALNX is not set
544# CONFIG_NATSEMI is not set 548# CONFIG_NATSEMI is not set
545# CONFIG_NE2K_PCI is not set 549# CONFIG_NE2K_PCI is not set
@@ -565,6 +569,8 @@ CONFIG_E1000=y
565# CONFIG_SK98LIN is not set 569# CONFIG_SK98LIN is not set
566# CONFIG_VIA_VELOCITY is not set 570# CONFIG_VIA_VELOCITY is not set
567CONFIG_TIGON3=y 571CONFIG_TIGON3=y
572# CONFIG_BNX2 is not set
573# CONFIG_MV643XX_ETH is not set
568 574
569# 575#
570# Ethernet (10000 Mbit) 576# Ethernet (10000 Mbit)
@@ -636,20 +642,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
636# CONFIG_INPUT_EVBUG is not set 642# CONFIG_INPUT_EVBUG is not set
637 643
638# 644#
639# Input I/O drivers
640#
641# CONFIG_GAMEPORT is not set
642CONFIG_SOUND_GAMEPORT=y
643CONFIG_SERIO=y
644CONFIG_SERIO_I8042=y
645# CONFIG_SERIO_SERPORT is not set
646# CONFIG_SERIO_CT82C710 is not set
647# CONFIG_SERIO_PARKBD is not set
648# CONFIG_SERIO_PCIPS2 is not set
649CONFIG_SERIO_LIBPS2=y
650# CONFIG_SERIO_RAW is not set
651
652#
653# Input Device Drivers 645# Input Device Drivers
654# 646#
655CONFIG_INPUT_KEYBOARD=y 647CONFIG_INPUT_KEYBOARD=y
@@ -669,6 +661,18 @@ CONFIG_INPUT_PCSPKR=m
669# CONFIG_INPUT_UINPUT is not set 661# CONFIG_INPUT_UINPUT is not set
670 662
671# 663#
664# Hardware I/O ports
665#
666CONFIG_SERIO=y
667CONFIG_SERIO_I8042=y
668# CONFIG_SERIO_SERPORT is not set
669# CONFIG_SERIO_PARKBD is not set
670# CONFIG_SERIO_PCIPS2 is not set
671CONFIG_SERIO_LIBPS2=y
672# CONFIG_SERIO_RAW is not set
673# CONFIG_GAMEPORT is not set
674
675#
672# Character devices 676# Character devices
673# 677#
674CONFIG_VT=y 678CONFIG_VT=y
@@ -689,8 +693,8 @@ CONFIG_SERIAL_8250_NR_UARTS=4
689# 693#
690CONFIG_SERIAL_CORE=y 694CONFIG_SERIAL_CORE=y
691CONFIG_SERIAL_CORE_CONSOLE=y 695CONFIG_SERIAL_CORE_CONSOLE=y
692# CONFIG_SERIAL_PMACZILOG is not set
693CONFIG_SERIAL_ICOM=m 696CONFIG_SERIAL_ICOM=m
697# CONFIG_SERIAL_JSM is not set
694CONFIG_UNIX98_PTYS=y 698CONFIG_UNIX98_PTYS=y
695CONFIG_LEGACY_PTYS=y 699CONFIG_LEGACY_PTYS=y
696CONFIG_LEGACY_PTY_COUNT=256 700CONFIG_LEGACY_PTY_COUNT=256
@@ -718,9 +722,16 @@ CONFIG_HVCS=m
718# 722#
719# Ftape, the floppy tape device driver 723# Ftape, the floppy tape device driver
720# 724#
725# CONFIG_AGP is not set
721# CONFIG_DRM is not set 726# CONFIG_DRM is not set
722CONFIG_RAW_DRIVER=y 727CONFIG_RAW_DRIVER=y
723CONFIG_MAX_RAW_DEVS=1024 728CONFIG_MAX_RAW_DEVS=1024
729# CONFIG_HANGCHECK_TIMER is not set
730
731#
732# TPM devices
733#
734# CONFIG_TCG_TPM is not set
724 735
725# 736#
726# I2C support 737# I2C support
@@ -745,8 +756,8 @@ CONFIG_I2C_ALGOBIT=y
745# CONFIG_I2C_AMD8111 is not set 756# CONFIG_I2C_AMD8111 is not set
746# CONFIG_I2C_I801 is not set 757# CONFIG_I2C_I801 is not set
747# CONFIG_I2C_I810 is not set 758# CONFIG_I2C_I810 is not set
759# CONFIG_I2C_PIIX4 is not set
748# CONFIG_I2C_ISA is not set 760# CONFIG_I2C_ISA is not set
749# CONFIG_I2C_MPC is not set
750# CONFIG_I2C_NFORCE2 is not set 761# CONFIG_I2C_NFORCE2 is not set
751# CONFIG_I2C_PARPORT is not set 762# CONFIG_I2C_PARPORT is not set
752# CONFIG_I2C_PARPORT_LIGHT is not set 763# CONFIG_I2C_PARPORT_LIGHT is not set
@@ -773,7 +784,9 @@ CONFIG_I2C_ALGOBIT=y
773# CONFIG_SENSORS_ASB100 is not set 784# CONFIG_SENSORS_ASB100 is not set
774# CONFIG_SENSORS_DS1621 is not set 785# CONFIG_SENSORS_DS1621 is not set
775# CONFIG_SENSORS_FSCHER is not set 786# CONFIG_SENSORS_FSCHER is not set
787# CONFIG_SENSORS_FSCPOS is not set
776# CONFIG_SENSORS_GL518SM is not set 788# CONFIG_SENSORS_GL518SM is not set
789# CONFIG_SENSORS_GL520SM is not set
777# CONFIG_SENSORS_IT87 is not set 790# CONFIG_SENSORS_IT87 is not set
778# CONFIG_SENSORS_LM63 is not set 791# CONFIG_SENSORS_LM63 is not set
779# CONFIG_SENSORS_LM75 is not set 792# CONFIG_SENSORS_LM75 is not set
@@ -784,9 +797,11 @@ CONFIG_I2C_ALGOBIT=y
784# CONFIG_SENSORS_LM85 is not set 797# CONFIG_SENSORS_LM85 is not set
785# CONFIG_SENSORS_LM87 is not set 798# CONFIG_SENSORS_LM87 is not set
786# CONFIG_SENSORS_LM90 is not set 799# CONFIG_SENSORS_LM90 is not set
800# CONFIG_SENSORS_LM92 is not set
787# CONFIG_SENSORS_MAX1619 is not set 801# CONFIG_SENSORS_MAX1619 is not set
788# CONFIG_SENSORS_PC87360 is not set 802# CONFIG_SENSORS_PC87360 is not set
789# CONFIG_SENSORS_SMSC47B397 is not set 803# CONFIG_SENSORS_SMSC47B397 is not set
804# CONFIG_SENSORS_SIS5595 is not set
790# CONFIG_SENSORS_SMSC47M1 is not set 805# CONFIG_SENSORS_SMSC47M1 is not set
791# CONFIG_SENSORS_VIA686A is not set 806# CONFIG_SENSORS_VIA686A is not set
792# CONFIG_SENSORS_W83781D is not set 807# CONFIG_SENSORS_W83781D is not set
@@ -796,6 +811,7 @@ CONFIG_I2C_ALGOBIT=y
796# 811#
797# Other I2C Chip support 812# Other I2C Chip support
798# 813#
814# CONFIG_SENSORS_DS1337 is not set
799# CONFIG_SENSORS_EEPROM is not set 815# CONFIG_SENSORS_EEPROM is not set
800# CONFIG_SENSORS_PCF8574 is not set 816# CONFIG_SENSORS_PCF8574 is not set
801# CONFIG_SENSORS_PCF8591 is not set 817# CONFIG_SENSORS_PCF8591 is not set
@@ -828,8 +844,13 @@ CONFIG_I2C_ALGOBIT=y
828# Graphics support 844# Graphics support
829# 845#
830CONFIG_FB=y 846CONFIG_FB=y
847CONFIG_FB_CFB_FILLRECT=y
848CONFIG_FB_CFB_COPYAREA=y
849CONFIG_FB_CFB_IMAGEBLIT=y
850CONFIG_FB_SOFT_CURSOR=y
851CONFIG_FB_MACMODES=y
831CONFIG_FB_MODE_HELPERS=y 852CONFIG_FB_MODE_HELPERS=y
832# CONFIG_FB_TILEBLITTING is not set 853CONFIG_FB_TILEBLITTING=y
833# CONFIG_FB_CIRRUS is not set 854# CONFIG_FB_CIRRUS is not set
834# CONFIG_FB_PM2 is not set 855# CONFIG_FB_PM2 is not set
835# CONFIG_FB_CYBER2000 is not set 856# CONFIG_FB_CYBER2000 is not set
@@ -838,6 +859,7 @@ CONFIG_FB_OF=y
838# CONFIG_FB_ASILIANT is not set 859# CONFIG_FB_ASILIANT is not set
839# CONFIG_FB_IMSTT is not set 860# CONFIG_FB_IMSTT is not set
840# CONFIG_FB_VGA16 is not set 861# CONFIG_FB_VGA16 is not set
862# CONFIG_FB_NVIDIA is not set
841# CONFIG_FB_RIVA is not set 863# CONFIG_FB_RIVA is not set
842CONFIG_FB_MATROX=y 864CONFIG_FB_MATROX=y
843CONFIG_FB_MATROX_MILLENIUM=y 865CONFIG_FB_MATROX_MILLENIUM=y
@@ -858,6 +880,7 @@ CONFIG_FB_RADEON_I2C=y
858# CONFIG_FB_3DFX is not set 880# CONFIG_FB_3DFX is not set
859# CONFIG_FB_VOODOO1 is not set 881# CONFIG_FB_VOODOO1 is not set
860# CONFIG_FB_TRIDENT is not set 882# CONFIG_FB_TRIDENT is not set
883# CONFIG_FB_S1D13XXX is not set
861# CONFIG_FB_VIRTUAL is not set 884# CONFIG_FB_VIRTUAL is not set
862 885
863# 886#
@@ -891,6 +914,8 @@ CONFIG_LCD_DEVICE=y
891# 914#
892# USB support 915# USB support
893# 916#
917CONFIG_USB_ARCH_HAS_HCD=y
918CONFIG_USB_ARCH_HAS_OHCI=y
894CONFIG_USB=y 919CONFIG_USB=y
895# CONFIG_USB_DEBUG is not set 920# CONFIG_USB_DEBUG is not set
896 921
@@ -901,8 +926,6 @@ CONFIG_USB_DEVICEFS=y
901# CONFIG_USB_BANDWIDTH is not set 926# CONFIG_USB_BANDWIDTH is not set
902# CONFIG_USB_DYNAMIC_MINORS is not set 927# CONFIG_USB_DYNAMIC_MINORS is not set
903# CONFIG_USB_OTG is not set 928# CONFIG_USB_OTG is not set
904CONFIG_USB_ARCH_HAS_HCD=y
905CONFIG_USB_ARCH_HAS_OHCI=y
906 929
907# 930#
908# USB Host Controller Drivers 931# USB Host Controller Drivers
@@ -911,6 +934,8 @@ CONFIG_USB_EHCI_HCD=y
911# CONFIG_USB_EHCI_SPLIT_ISO is not set 934# CONFIG_USB_EHCI_SPLIT_ISO is not set
912# CONFIG_USB_EHCI_ROOT_HUB_TT is not set 935# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
913CONFIG_USB_OHCI_HCD=y 936CONFIG_USB_OHCI_HCD=y
937# CONFIG_USB_OHCI_BIG_ENDIAN is not set
938CONFIG_USB_OHCI_LITTLE_ENDIAN=y
914# CONFIG_USB_UHCI_HCD is not set 939# CONFIG_USB_UHCI_HCD is not set
915# CONFIG_USB_SL811_HCD is not set 940# CONFIG_USB_SL811_HCD is not set
916 941
@@ -926,12 +951,11 @@ CONFIG_USB_OHCI_HCD=y
926# 951#
927CONFIG_USB_STORAGE=y 952CONFIG_USB_STORAGE=y
928# CONFIG_USB_STORAGE_DEBUG is not set 953# CONFIG_USB_STORAGE_DEBUG is not set
929# CONFIG_USB_STORAGE_RW_DETECT is not set
930# CONFIG_USB_STORAGE_DATAFAB is not set 954# CONFIG_USB_STORAGE_DATAFAB is not set
931# CONFIG_USB_STORAGE_FREECOM is not set 955# CONFIG_USB_STORAGE_FREECOM is not set
932# CONFIG_USB_STORAGE_ISD200 is not set 956# CONFIG_USB_STORAGE_ISD200 is not set
933# CONFIG_USB_STORAGE_DPCM is not set 957# CONFIG_USB_STORAGE_DPCM is not set
934# CONFIG_USB_STORAGE_HP8200e is not set 958# CONFIG_USB_STORAGE_USBAT is not set
935# CONFIG_USB_STORAGE_SDDR09 is not set 959# CONFIG_USB_STORAGE_SDDR09 is not set
936# CONFIG_USB_STORAGE_SDDR55 is not set 960# CONFIG_USB_STORAGE_SDDR55 is not set
937# CONFIG_USB_STORAGE_JUMPSHOT is not set 961# CONFIG_USB_STORAGE_JUMPSHOT is not set
@@ -975,6 +999,7 @@ CONFIG_USB_HIDDEV=y
975# CONFIG_USB_PEGASUS is not set 999# CONFIG_USB_PEGASUS is not set
976# CONFIG_USB_RTL8150 is not set 1000# CONFIG_USB_RTL8150 is not set
977# CONFIG_USB_USBNET is not set 1001# CONFIG_USB_USBNET is not set
1002CONFIG_USB_MON=y
978 1003
979# 1004#
980# USB port drivers 1005# USB port drivers
@@ -1000,6 +1025,7 @@ CONFIG_USB_HIDDEV=y
1000# CONFIG_USB_PHIDGETKIT is not set 1025# CONFIG_USB_PHIDGETKIT is not set
1001# CONFIG_USB_PHIDGETSERVO is not set 1026# CONFIG_USB_PHIDGETSERVO is not set
1002# CONFIG_USB_IDMOUSE is not set 1027# CONFIG_USB_IDMOUSE is not set
1028# CONFIG_USB_SISUSBVGA is not set
1003# CONFIG_USB_TEST is not set 1029# CONFIG_USB_TEST is not set
1004 1030
1005# 1031#
@@ -1208,10 +1234,13 @@ CONFIG_OPROFILE=y
1208# 1234#
1209# Kernel hacking 1235# Kernel hacking
1210# 1236#
1237# CONFIG_PRINTK_TIME is not set
1211CONFIG_DEBUG_KERNEL=y 1238CONFIG_DEBUG_KERNEL=y
1212CONFIG_MAGIC_SYSRQ=y 1239CONFIG_MAGIC_SYSRQ=y
1240CONFIG_LOG_BUF_SHIFT=17
1213# CONFIG_SCHEDSTATS is not set 1241# CONFIG_SCHEDSTATS is not set
1214# CONFIG_DEBUG_SLAB is not set 1242# CONFIG_DEBUG_SLAB is not set
1243# CONFIG_DEBUG_SPINLOCK is not set
1215# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 1244# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1216# CONFIG_DEBUG_KOBJECT is not set 1245# CONFIG_DEBUG_KOBJECT is not set
1217# CONFIG_DEBUG_INFO is not set 1246# CONFIG_DEBUG_INFO is not set
@@ -1243,6 +1272,7 @@ CONFIG_CRYPTO_SHA1=m
1243CONFIG_CRYPTO_SHA256=m 1272CONFIG_CRYPTO_SHA256=m
1244CONFIG_CRYPTO_SHA512=m 1273CONFIG_CRYPTO_SHA512=m
1245CONFIG_CRYPTO_WP512=m 1274CONFIG_CRYPTO_WP512=m
1275CONFIG_CRYPTO_TGR192=m
1246CONFIG_CRYPTO_DES=y 1276CONFIG_CRYPTO_DES=y
1247CONFIG_CRYPTO_BLOWFISH=m 1277CONFIG_CRYPTO_BLOWFISH=m
1248CONFIG_CRYPTO_TWOFISH=m 1278CONFIG_CRYPTO_TWOFISH=m
diff --git a/arch/ppc64/defconfig b/arch/ppc64/defconfig
index 537b1cc82eab..2f31bf3046f9 100644
--- a/arch/ppc64/defconfig
+++ b/arch/ppc64/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-rc3-bk6 3# Linux kernel version: 2.6.12-rc5-git9
4# Wed Feb 9 23:34:51 2005 4# Sun Jun 5 09:26:47 2005
5# 5#
6CONFIG_64BIT=y 6CONFIG_64BIT=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y
11CONFIG_HAVE_DEC_LOCK=y 11CONFIG_HAVE_DEC_LOCK=y
12CONFIG_EARLY_PRINTK=y 12CONFIG_EARLY_PRINTK=y
13CONFIG_COMPAT=y 13CONFIG_COMPAT=y
14CONFIG_FRAME_POINTER=y 14CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
15CONFIG_FORCE_MAX_ZONEORDER=13 15CONFIG_FORCE_MAX_ZONEORDER=13
16 16
17# 17#
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13
20CONFIG_EXPERIMENTAL=y 20CONFIG_EXPERIMENTAL=y
21CONFIG_CLEAN_COMPILE=y 21CONFIG_CLEAN_COMPILE=y
22CONFIG_LOCK_KERNEL=y 22CONFIG_LOCK_KERNEL=y
23CONFIG_INIT_ENV_ARG_LIMIT=32
23 24
24# 25#
25# General setup 26# General setup
@@ -30,24 +31,28 @@ CONFIG_SYSVIPC=y
30CONFIG_POSIX_MQUEUE=y 31CONFIG_POSIX_MQUEUE=y
31# CONFIG_BSD_PROCESS_ACCT is not set 32# CONFIG_BSD_PROCESS_ACCT is not set
32CONFIG_SYSCTL=y 33CONFIG_SYSCTL=y
33CONFIG_LOG_BUF_SHIFT=17 34# CONFIG_AUDIT is not set
34CONFIG_HOTPLUG=y 35CONFIG_HOTPLUG=y
35CONFIG_KOBJECT_UEVENT=y 36CONFIG_KOBJECT_UEVENT=y
36CONFIG_IKCONFIG=y 37CONFIG_IKCONFIG=y
37CONFIG_IKCONFIG_PROC=y 38CONFIG_IKCONFIG_PROC=y
39CONFIG_CPUSETS=y
38# CONFIG_EMBEDDED is not set 40# CONFIG_EMBEDDED is not set
39CONFIG_KALLSYMS=y 41CONFIG_KALLSYMS=y
40# CONFIG_KALLSYMS_ALL is not set 42# CONFIG_KALLSYMS_ALL is not set
41# CONFIG_KALLSYMS_EXTRA_PASS is not set 43# CONFIG_KALLSYMS_EXTRA_PASS is not set
44CONFIG_PRINTK=y
45CONFIG_BUG=y
46CONFIG_BASE_FULL=y
42CONFIG_FUTEX=y 47CONFIG_FUTEX=y
43CONFIG_EPOLL=y 48CONFIG_EPOLL=y
44# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
45CONFIG_SHMEM=y 49CONFIG_SHMEM=y
46CONFIG_CC_ALIGN_FUNCTIONS=0 50CONFIG_CC_ALIGN_FUNCTIONS=0
47CONFIG_CC_ALIGN_LABELS=0 51CONFIG_CC_ALIGN_LABELS=0
48CONFIG_CC_ALIGN_LOOPS=0 52CONFIG_CC_ALIGN_LOOPS=0
49CONFIG_CC_ALIGN_JUMPS=0 53CONFIG_CC_ALIGN_JUMPS=0
50# CONFIG_TINY_SHMEM is not set 54# CONFIG_TINY_SHMEM is not set
55CONFIG_BASE_SMALL=0
51 56
52# 57#
53# Loadable module support 58# Loadable module support
@@ -91,9 +96,12 @@ CONFIG_DISCONTIGMEM=y
91CONFIG_EEH=y 96CONFIG_EEH=y
92CONFIG_GENERIC_HARDIRQS=y 97CONFIG_GENERIC_HARDIRQS=y
93CONFIG_PPC_RTAS=y 98CONFIG_PPC_RTAS=y
99CONFIG_RTAS_PROC=y
94CONFIG_RTAS_FLASH=m 100CONFIG_RTAS_FLASH=m
95CONFIG_SCANLOG=m 101CONFIG_SCANLOG=m
96CONFIG_LPARCFG=y 102CONFIG_LPARCFG=y
103CONFIG_SECCOMP=y
104CONFIG_ISA_DMA_API=y
97 105
98# 106#
99# General setup 107# General setup
@@ -104,6 +112,7 @@ CONFIG_BINFMT_ELF=y
104CONFIG_BINFMT_MISC=m 112CONFIG_BINFMT_MISC=m
105# CONFIG_PCI_LEGACY_PROC is not set 113# CONFIG_PCI_LEGACY_PROC is not set
106# CONFIG_PCI_NAMES is not set 114# CONFIG_PCI_NAMES is not set
115# CONFIG_PCI_DEBUG is not set
107CONFIG_HOTPLUG_CPU=y 116CONFIG_HOTPLUG_CPU=y
108 117
109# 118#
@@ -112,10 +121,6 @@ CONFIG_HOTPLUG_CPU=y
112# CONFIG_PCCARD is not set 121# CONFIG_PCCARD is not set
113 122
114# 123#
115# PC-card bridges
116#
117
118#
119# PCI Hotplug Support 124# PCI Hotplug Support
120# 125#
121CONFIG_HOTPLUG_PCI=m 126CONFIG_HOTPLUG_PCI=m
@@ -149,11 +154,10 @@ CONFIG_FW_LOADER=y
149# 154#
150CONFIG_PARPORT=m 155CONFIG_PARPORT=m
151CONFIG_PARPORT_PC=m 156CONFIG_PARPORT_PC=m
152CONFIG_PARPORT_PC_CML1=m
153# CONFIG_PARPORT_SERIAL is not set 157# CONFIG_PARPORT_SERIAL is not set
154# CONFIG_PARPORT_PC_FIFO is not set 158# CONFIG_PARPORT_PC_FIFO is not set
155# CONFIG_PARPORT_PC_SUPERIO is not set 159# CONFIG_PARPORT_PC_SUPERIO is not set
156# CONFIG_PARPORT_OTHER is not set 160# CONFIG_PARPORT_GSC is not set
157# CONFIG_PARPORT_1284 is not set 161# CONFIG_PARPORT_1284 is not set
158 162
159# 163#
@@ -301,6 +305,7 @@ CONFIG_SCSI_SATA_SVW=y
301# CONFIG_SCSI_ATA_PIIX is not set 305# CONFIG_SCSI_ATA_PIIX is not set
302# CONFIG_SCSI_SATA_NV is not set 306# CONFIG_SCSI_SATA_NV is not set
303# CONFIG_SCSI_SATA_PROMISE is not set 307# CONFIG_SCSI_SATA_PROMISE is not set
308# CONFIG_SCSI_SATA_QSTOR is not set
304# CONFIG_SCSI_SATA_SX4 is not set 309# CONFIG_SCSI_SATA_SX4 is not set
305# CONFIG_SCSI_SATA_SIL is not set 310# CONFIG_SCSI_SATA_SIL is not set
306# CONFIG_SCSI_SATA_SIS is not set 311# CONFIG_SCSI_SATA_SIS is not set
@@ -310,7 +315,6 @@ CONFIG_SCSI_SATA_SVW=y
310# CONFIG_SCSI_BUSLOGIC is not set 315# CONFIG_SCSI_BUSLOGIC is not set
311# CONFIG_SCSI_DMX3191D is not set 316# CONFIG_SCSI_DMX3191D is not set
312# CONFIG_SCSI_EATA is not set 317# CONFIG_SCSI_EATA is not set
313# CONFIG_SCSI_EATA_PIO is not set
314# CONFIG_SCSI_FUTURE_DOMAIN is not set 318# CONFIG_SCSI_FUTURE_DOMAIN is not set
315# CONFIG_SCSI_GDTH is not set 319# CONFIG_SCSI_GDTH is not set
316# CONFIG_SCSI_IPS is not set 320# CONFIG_SCSI_IPS is not set
@@ -327,7 +331,6 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
327CONFIG_SCSI_IPR=y 331CONFIG_SCSI_IPR=y
328CONFIG_SCSI_IPR_TRACE=y 332CONFIG_SCSI_IPR_TRACE=y
329CONFIG_SCSI_IPR_DUMP=y 333CONFIG_SCSI_IPR_DUMP=y
330# CONFIG_SCSI_QLOGIC_ISP is not set
331# CONFIG_SCSI_QLOGIC_FC is not set 334# CONFIG_SCSI_QLOGIC_FC is not set
332# CONFIG_SCSI_QLOGIC_1280 is not set 335# CONFIG_SCSI_QLOGIC_1280 is not set
333CONFIG_SCSI_QLA2XXX=y 336CONFIG_SCSI_QLA2XXX=y
@@ -336,6 +339,7 @@ CONFIG_SCSI_QLA22XX=m
336CONFIG_SCSI_QLA2300=m 339CONFIG_SCSI_QLA2300=m
337CONFIG_SCSI_QLA2322=m 340CONFIG_SCSI_QLA2322=m
338CONFIG_SCSI_QLA6312=m 341CONFIG_SCSI_QLA6312=m
342CONFIG_SCSI_LPFC=m
339# CONFIG_SCSI_DC395x is not set 343# CONFIG_SCSI_DC395x is not set
340# CONFIG_SCSI_DC390T is not set 344# CONFIG_SCSI_DC390T is not set
341CONFIG_SCSI_DEBUG=m 345CONFIG_SCSI_DEBUG=m
@@ -358,6 +362,8 @@ CONFIG_DM_CRYPT=m
358CONFIG_DM_SNAPSHOT=m 362CONFIG_DM_SNAPSHOT=m
359CONFIG_DM_MIRROR=m 363CONFIG_DM_MIRROR=m
360CONFIG_DM_ZERO=m 364CONFIG_DM_ZERO=m
365CONFIG_DM_MULTIPATH=m
366CONFIG_DM_MULTIPATH_EMC=m
361 367
362# 368#
363# Fusion MPT device support 369# Fusion MPT device support
@@ -405,6 +411,7 @@ CONFIG_IEEE1394_AMDTP=m
405# 411#
406CONFIG_ADB=y 412CONFIG_ADB=y
407CONFIG_ADB_PMU=y 413CONFIG_ADB_PMU=y
414CONFIG_PMAC_SMU=y
408# CONFIG_PMAC_PBOOK is not set 415# CONFIG_PMAC_PBOOK is not set
409# CONFIG_PMAC_BACKLIGHT is not set 416# CONFIG_PMAC_BACKLIGHT is not set
410# CONFIG_INPUT_ADBHID is not set 417# CONFIG_INPUT_ADBHID is not set
@@ -420,7 +427,6 @@ CONFIG_NET=y
420# 427#
421CONFIG_PACKET=y 428CONFIG_PACKET=y
422# CONFIG_PACKET_MMAP is not set 429# CONFIG_PACKET_MMAP is not set
423# CONFIG_NETLINK_DEV is not set
424CONFIG_UNIX=y 430CONFIG_UNIX=y
425CONFIG_NET_KEY=m 431CONFIG_NET_KEY=m
426CONFIG_INET=y 432CONFIG_INET=y
@@ -588,7 +594,6 @@ CONFIG_PCNET32=y
588# CONFIG_DGRS is not set 594# CONFIG_DGRS is not set
589# CONFIG_EEPRO100 is not set 595# CONFIG_EEPRO100 is not set
590CONFIG_E100=y 596CONFIG_E100=y
591# CONFIG_E100_NAPI is not set
592# CONFIG_FEALNX is not set 597# CONFIG_FEALNX is not set
593# CONFIG_NATSEMI is not set 598# CONFIG_NATSEMI is not set
594# CONFIG_NE2K_PCI is not set 599# CONFIG_NE2K_PCI is not set
@@ -614,6 +619,8 @@ CONFIG_E1000=y
614# CONFIG_SK98LIN is not set 619# CONFIG_SK98LIN is not set
615# CONFIG_VIA_VELOCITY is not set 620# CONFIG_VIA_VELOCITY is not set
616CONFIG_TIGON3=y 621CONFIG_TIGON3=y
622# CONFIG_BNX2 is not set
623# CONFIG_MV643XX_ETH is not set
617 624
618# 625#
619# Ethernet (10000 Mbit) 626# Ethernet (10000 Mbit)
@@ -683,20 +690,6 @@ CONFIG_INPUT_EVDEV=m
683# CONFIG_INPUT_EVBUG is not set 690# CONFIG_INPUT_EVBUG is not set
684 691
685# 692#
686# Input I/O drivers
687#
688# CONFIG_GAMEPORT is not set
689CONFIG_SOUND_GAMEPORT=y
690CONFIG_SERIO=y
691CONFIG_SERIO_I8042=y
692# CONFIG_SERIO_SERPORT is not set
693# CONFIG_SERIO_CT82C710 is not set
694# CONFIG_SERIO_PARKBD is not set
695# CONFIG_SERIO_PCIPS2 is not set
696CONFIG_SERIO_LIBPS2=y
697# CONFIG_SERIO_RAW is not set
698
699#
700# Input Device Drivers 693# Input Device Drivers
701# 694#
702CONFIG_INPUT_KEYBOARD=y 695CONFIG_INPUT_KEYBOARD=y
@@ -716,6 +709,18 @@ CONFIG_INPUT_PCSPKR=m
716# CONFIG_INPUT_UINPUT is not set 709# CONFIG_INPUT_UINPUT is not set
717 710
718# 711#
712# Hardware I/O ports
713#
714CONFIG_SERIO=y
715CONFIG_SERIO_I8042=y
716# CONFIG_SERIO_SERPORT is not set
717# CONFIG_SERIO_PARKBD is not set
718# CONFIG_SERIO_PCIPS2 is not set
719CONFIG_SERIO_LIBPS2=y
720# CONFIG_SERIO_RAW is not set
721# CONFIG_GAMEPORT is not set
722
723#
719# Character devices 724# Character devices
720# 725#
721CONFIG_VT=y 726CONFIG_VT=y
@@ -738,6 +743,7 @@ CONFIG_SERIAL_CORE=y
738CONFIG_SERIAL_CORE_CONSOLE=y 743CONFIG_SERIAL_CORE_CONSOLE=y
739# CONFIG_SERIAL_PMACZILOG is not set 744# CONFIG_SERIAL_PMACZILOG is not set
740CONFIG_SERIAL_ICOM=m 745CONFIG_SERIAL_ICOM=m
746CONFIG_SERIAL_JSM=m
741CONFIG_UNIX98_PTYS=y 747CONFIG_UNIX98_PTYS=y
742CONFIG_LEGACY_PTYS=y 748CONFIG_LEGACY_PTYS=y
743CONFIG_LEGACY_PTY_COUNT=256 749CONFIG_LEGACY_PTY_COUNT=256
@@ -766,9 +772,16 @@ CONFIG_HVCS=m
766# 772#
767# Ftape, the floppy tape device driver 773# Ftape, the floppy tape device driver
768# 774#
775# CONFIG_AGP is not set
769# CONFIG_DRM is not set 776# CONFIG_DRM is not set
770CONFIG_RAW_DRIVER=y 777CONFIG_RAW_DRIVER=y
771CONFIG_MAX_RAW_DEVS=256 778CONFIG_MAX_RAW_DEVS=256
779# CONFIG_HANGCHECK_TIMER is not set
780
781#
782# TPM devices
783#
784# CONFIG_TCG_TPM is not set
772 785
773# 786#
774# I2C support 787# I2C support
@@ -793,9 +806,9 @@ CONFIG_I2C_ALGOBIT=y
793CONFIG_I2C_AMD8111=y 806CONFIG_I2C_AMD8111=y
794# CONFIG_I2C_I801 is not set 807# CONFIG_I2C_I801 is not set
795# CONFIG_I2C_I810 is not set 808# CONFIG_I2C_I810 is not set
809# CONFIG_I2C_PIIX4 is not set
796# CONFIG_I2C_ISA is not set 810# CONFIG_I2C_ISA is not set
797CONFIG_I2C_KEYWEST=y 811CONFIG_I2C_KEYWEST=y
798# CONFIG_I2C_MPC is not set
799# CONFIG_I2C_NFORCE2 is not set 812# CONFIG_I2C_NFORCE2 is not set
800# CONFIG_I2C_PARPORT is not set 813# CONFIG_I2C_PARPORT is not set
801# CONFIG_I2C_PARPORT_LIGHT is not set 814# CONFIG_I2C_PARPORT_LIGHT is not set
@@ -822,7 +835,9 @@ CONFIG_I2C_KEYWEST=y
822# CONFIG_SENSORS_ASB100 is not set 835# CONFIG_SENSORS_ASB100 is not set
823# CONFIG_SENSORS_DS1621 is not set 836# CONFIG_SENSORS_DS1621 is not set
824# CONFIG_SENSORS_FSCHER is not set 837# CONFIG_SENSORS_FSCHER is not set
838# CONFIG_SENSORS_FSCPOS is not set
825# CONFIG_SENSORS_GL518SM is not set 839# CONFIG_SENSORS_GL518SM is not set
840# CONFIG_SENSORS_GL520SM is not set
826# CONFIG_SENSORS_IT87 is not set 841# CONFIG_SENSORS_IT87 is not set
827# CONFIG_SENSORS_LM63 is not set 842# CONFIG_SENSORS_LM63 is not set
828# CONFIG_SENSORS_LM75 is not set 843# CONFIG_SENSORS_LM75 is not set
@@ -833,9 +848,11 @@ CONFIG_I2C_KEYWEST=y
833# CONFIG_SENSORS_LM85 is not set 848# CONFIG_SENSORS_LM85 is not set
834# CONFIG_SENSORS_LM87 is not set 849# CONFIG_SENSORS_LM87 is not set
835# CONFIG_SENSORS_LM90 is not set 850# CONFIG_SENSORS_LM90 is not set
851# CONFIG_SENSORS_LM92 is not set
836# CONFIG_SENSORS_MAX1619 is not set 852# CONFIG_SENSORS_MAX1619 is not set
837# CONFIG_SENSORS_PC87360 is not set 853# CONFIG_SENSORS_PC87360 is not set
838# CONFIG_SENSORS_SMSC47B397 is not set 854# CONFIG_SENSORS_SMSC47B397 is not set
855# CONFIG_SENSORS_SIS5595 is not set
839# CONFIG_SENSORS_SMSC47M1 is not set 856# CONFIG_SENSORS_SMSC47M1 is not set
840# CONFIG_SENSORS_VIA686A is not set 857# CONFIG_SENSORS_VIA686A is not set
841# CONFIG_SENSORS_W83781D is not set 858# CONFIG_SENSORS_W83781D is not set
@@ -845,6 +862,7 @@ CONFIG_I2C_KEYWEST=y
845# 862#
846# Other I2C Chip support 863# Other I2C Chip support
847# 864#
865# CONFIG_SENSORS_DS1337 is not set
848# CONFIG_SENSORS_EEPROM is not set 866# CONFIG_SENSORS_EEPROM is not set
849# CONFIG_SENSORS_PCF8574 is not set 867# CONFIG_SENSORS_PCF8574 is not set
850# CONFIG_SENSORS_PCF8591 is not set 868# CONFIG_SENSORS_PCF8591 is not set
@@ -877,6 +895,11 @@ CONFIG_I2C_KEYWEST=y
877# Graphics support 895# Graphics support
878# 896#
879CONFIG_FB=y 897CONFIG_FB=y
898CONFIG_FB_CFB_FILLRECT=y
899CONFIG_FB_CFB_COPYAREA=y
900CONFIG_FB_CFB_IMAGEBLIT=y
901CONFIG_FB_SOFT_CURSOR=y
902CONFIG_FB_MACMODES=y
880CONFIG_FB_MODE_HELPERS=y 903CONFIG_FB_MODE_HELPERS=y
881CONFIG_FB_TILEBLITTING=y 904CONFIG_FB_TILEBLITTING=y
882# CONFIG_FB_CIRRUS is not set 905# CONFIG_FB_CIRRUS is not set
@@ -890,9 +913,8 @@ CONFIG_FB_OF=y
890# CONFIG_FB_ASILIANT is not set 913# CONFIG_FB_ASILIANT is not set
891# CONFIG_FB_IMSTT is not set 914# CONFIG_FB_IMSTT is not set
892# CONFIG_FB_VGA16 is not set 915# CONFIG_FB_VGA16 is not set
893CONFIG_FB_RIVA=y 916# CONFIG_FB_NVIDIA is not set
894CONFIG_FB_RIVA_I2C=y 917# CONFIG_FB_RIVA is not set
895# CONFIG_FB_RIVA_DEBUG is not set
896CONFIG_FB_MATROX=y 918CONFIG_FB_MATROX=y
897CONFIG_FB_MATROX_MILLENIUM=y 919CONFIG_FB_MATROX_MILLENIUM=y
898CONFIG_FB_MATROX_MYSTIQUE=y 920CONFIG_FB_MATROX_MYSTIQUE=y
@@ -913,6 +935,7 @@ CONFIG_FB_RADEON_I2C=y
913# CONFIG_FB_3DFX is not set 935# CONFIG_FB_3DFX is not set
914# CONFIG_FB_VOODOO1 is not set 936# CONFIG_FB_VOODOO1 is not set
915# CONFIG_FB_TRIDENT is not set 937# CONFIG_FB_TRIDENT is not set
938# CONFIG_FB_S1D13XXX is not set
916# CONFIG_FB_VIRTUAL is not set 939# CONFIG_FB_VIRTUAL is not set
917 940
918# 941#
@@ -946,6 +969,8 @@ CONFIG_LCD_DEVICE=y
946# 969#
947# USB support 970# USB support
948# 971#
972CONFIG_USB_ARCH_HAS_HCD=y
973CONFIG_USB_ARCH_HAS_OHCI=y
949CONFIG_USB=y 974CONFIG_USB=y
950# CONFIG_USB_DEBUG is not set 975# CONFIG_USB_DEBUG is not set
951 976
@@ -956,8 +981,6 @@ CONFIG_USB_DEVICEFS=y
956# CONFIG_USB_BANDWIDTH is not set 981# CONFIG_USB_BANDWIDTH is not set
957# CONFIG_USB_DYNAMIC_MINORS is not set 982# CONFIG_USB_DYNAMIC_MINORS is not set
958# CONFIG_USB_OTG is not set 983# CONFIG_USB_OTG is not set
959CONFIG_USB_ARCH_HAS_HCD=y
960CONFIG_USB_ARCH_HAS_OHCI=y
961 984
962# 985#
963# USB Host Controller Drivers 986# USB Host Controller Drivers
@@ -966,6 +989,8 @@ CONFIG_USB_EHCI_HCD=y
966# CONFIG_USB_EHCI_SPLIT_ISO is not set 989# CONFIG_USB_EHCI_SPLIT_ISO is not set
967# CONFIG_USB_EHCI_ROOT_HUB_TT is not set 990# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
968CONFIG_USB_OHCI_HCD=y 991CONFIG_USB_OHCI_HCD=y
992# CONFIG_USB_OHCI_BIG_ENDIAN is not set
993CONFIG_USB_OHCI_LITTLE_ENDIAN=y
969# CONFIG_USB_UHCI_HCD is not set 994# CONFIG_USB_UHCI_HCD is not set
970# CONFIG_USB_SL811_HCD is not set 995# CONFIG_USB_SL811_HCD is not set
971 996
@@ -981,12 +1006,11 @@ CONFIG_USB_OHCI_HCD=y
981# 1006#
982CONFIG_USB_STORAGE=m 1007CONFIG_USB_STORAGE=m
983# CONFIG_USB_STORAGE_DEBUG is not set 1008# CONFIG_USB_STORAGE_DEBUG is not set
984CONFIG_USB_STORAGE_RW_DETECT=y
985# CONFIG_USB_STORAGE_DATAFAB is not set 1009# CONFIG_USB_STORAGE_DATAFAB is not set
986# CONFIG_USB_STORAGE_FREECOM is not set 1010# CONFIG_USB_STORAGE_FREECOM is not set
987# CONFIG_USB_STORAGE_ISD200 is not set 1011# CONFIG_USB_STORAGE_ISD200 is not set
988# CONFIG_USB_STORAGE_DPCM is not set 1012# CONFIG_USB_STORAGE_DPCM is not set
989# CONFIG_USB_STORAGE_HP8200e is not set 1013# CONFIG_USB_STORAGE_USBAT is not set
990# CONFIG_USB_STORAGE_SDDR09 is not set 1014# CONFIG_USB_STORAGE_SDDR09 is not set
991# CONFIG_USB_STORAGE_SDDR55 is not set 1015# CONFIG_USB_STORAGE_SDDR55 is not set
992# CONFIG_USB_STORAGE_JUMPSHOT is not set 1016# CONFIG_USB_STORAGE_JUMPSHOT is not set
@@ -1030,6 +1054,7 @@ CONFIG_USB_HIDDEV=y
1030CONFIG_USB_PEGASUS=y 1054CONFIG_USB_PEGASUS=y
1031# CONFIG_USB_RTL8150 is not set 1055# CONFIG_USB_RTL8150 is not set
1032# CONFIG_USB_USBNET is not set 1056# CONFIG_USB_USBNET is not set
1057# CONFIG_USB_MON is not set
1033 1058
1034# 1059#
1035# USB port drivers 1060# USB port drivers
@@ -1055,6 +1080,7 @@ CONFIG_USB_PEGASUS=y
1055# CONFIG_USB_PHIDGETKIT is not set 1080# CONFIG_USB_PHIDGETKIT is not set
1056# CONFIG_USB_PHIDGETSERVO is not set 1081# CONFIG_USB_PHIDGETSERVO is not set
1057# CONFIG_USB_IDMOUSE is not set 1082# CONFIG_USB_IDMOUSE is not set
1083# CONFIG_USB_SISUSBVGA is not set
1058# CONFIG_USB_TEST is not set 1084# CONFIG_USB_TEST is not set
1059 1085
1060# 1086#
@@ -1276,10 +1302,13 @@ CONFIG_OPROFILE=y
1276# 1302#
1277# Kernel hacking 1303# Kernel hacking
1278# 1304#
1305# CONFIG_PRINTK_TIME is not set
1279CONFIG_DEBUG_KERNEL=y 1306CONFIG_DEBUG_KERNEL=y
1280CONFIG_MAGIC_SYSRQ=y 1307CONFIG_MAGIC_SYSRQ=y
1308CONFIG_LOG_BUF_SHIFT=17
1281# CONFIG_SCHEDSTATS is not set 1309# CONFIG_SCHEDSTATS is not set
1282# CONFIG_DEBUG_SLAB is not set 1310# CONFIG_DEBUG_SLAB is not set
1311# CONFIG_DEBUG_SPINLOCK is not set
1283# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 1312# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1284# CONFIG_DEBUG_KOBJECT is not set 1313# CONFIG_DEBUG_KOBJECT is not set
1285# CONFIG_DEBUG_INFO is not set 1314# CONFIG_DEBUG_INFO is not set
@@ -1311,6 +1340,7 @@ CONFIG_CRYPTO_SHA1=m
1311CONFIG_CRYPTO_SHA256=m 1340CONFIG_CRYPTO_SHA256=m
1312CONFIG_CRYPTO_SHA512=m 1341CONFIG_CRYPTO_SHA512=m
1313CONFIG_CRYPTO_WP512=m 1342CONFIG_CRYPTO_WP512=m
1343CONFIG_CRYPTO_TGR192=m
1314CONFIG_CRYPTO_DES=y 1344CONFIG_CRYPTO_DES=y
1315CONFIG_CRYPTO_BLOWFISH=m 1345CONFIG_CRYPTO_BLOWFISH=m
1316CONFIG_CRYPTO_TWOFISH=m 1346CONFIG_CRYPTO_TWOFISH=m
diff --git a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S
index d3604056e1a9..b61572eb2a71 100644
--- a/arch/ppc64/kernel/entry.S
+++ b/arch/ppc64/kernel/entry.S
@@ -436,15 +436,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
436 REST_8GPRS(14, r1) 436 REST_8GPRS(14, r1)
437 REST_10GPRS(22, r1) 437 REST_10GPRS(22, r1)
438 438
439#ifdef CONFIG_PPC_ISERIES
440 clrrdi r7,r1,THREAD_SHIFT /* get current_thread_info() */
441 ld r7,TI_FLAGS(r7) /* Get run light flag */
442 mfspr r9,CTRLF
443 srdi r7,r7,TIF_RUN_LIGHT
444 insrdi r9,r7,1,63 /* Insert run light into CTRL */
445 mtspr CTRLT,r9
446#endif
447
448 /* convert old thread to its task_struct for return value */ 439 /* convert old thread to its task_struct for return value */
449 addi r3,r3,-THREAD 440 addi r3,r3,-THREAD
450 ld r7,_NIP(r1) /* Return to _switch caller in new task */ 441 ld r7,_NIP(r1) /* Return to _switch caller in new task */
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
index 92a744c31ab1..346dbf606b5d 100644
--- a/arch/ppc64/kernel/head.S
+++ b/arch/ppc64/kernel/head.S
@@ -626,10 +626,10 @@ system_reset_iSeries:
626 lhz r24,PACAPACAINDEX(r13) /* Get processor # */ 626 lhz r24,PACAPACAINDEX(r13) /* Get processor # */
627 cmpwi 0,r24,0 /* Are we processor 0? */ 627 cmpwi 0,r24,0 /* Are we processor 0? */
628 beq .__start_initialization_iSeries /* Start up the first processor */ 628 beq .__start_initialization_iSeries /* Start up the first processor */
629 mfspr r4,CTRLF 629 mfspr r4,SPRN_CTRLF
630 li r5,RUNLATCH /* Turn off the run light */ 630 li r5,CTRL_RUNLATCH /* Turn off the run light */
631 andc r4,r4,r5 631 andc r4,r4,r5
632 mtspr CTRLT,r4 632 mtspr SPRN_CTRLT,r4
633 633
6341: 6341:
635 HMT_LOW 635 HMT_LOW
@@ -2082,9 +2082,9 @@ _GLOBAL(hmt_start_secondary)
2082 mfspr r4, HID0 2082 mfspr r4, HID0
2083 ori r4, r4, 0x1 2083 ori r4, r4, 0x1
2084 mtspr HID0, r4 2084 mtspr HID0, r4
2085 mfspr r4, CTRLF 2085 mfspr r4, SPRN_CTRLF
2086 oris r4, r4, 0x40 2086 oris r4, r4, 0x40
2087 mtspr CTRLT, r4 2087 mtspr SPRN_CTRLT, r4
2088 blr 2088 blr
2089#endif 2089#endif
2090 2090
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
index da20120f2261..6d06eb550a3f 100644
--- a/arch/ppc64/kernel/iSeries_setup.c
+++ b/arch/ppc64/kernel/iSeries_setup.c
@@ -852,6 +852,28 @@ static int __init iSeries_src_init(void)
852 852
853late_initcall(iSeries_src_init); 853late_initcall(iSeries_src_init);
854 854
855static int set_spread_lpevents(char *str)
856{
857 unsigned long i;
858 unsigned long val = simple_strtoul(str, NULL, 0);
859
860 /*
861 * The parameter is the number of processors to share in processing
862 * lp events.
863 */
864 if (( val > 0) && (val <= NR_CPUS)) {
865 for (i = 1; i < val; ++i)
866 paca[i].lpqueue_ptr = paca[0].lpqueue_ptr;
867
868 printk("lpevent processing spread over %ld processors\n", val);
869 } else {
870 printk("invalid spread_lpevents %ld\n", val);
871 }
872
873 return 1;
874}
875__setup("spread_lpevents=", set_spread_lpevents);
876
855void __init iSeries_early_setup(void) 877void __init iSeries_early_setup(void)
856{ 878{
857 iSeries_fixup_klimit(); 879 iSeries_fixup_klimit();
diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c
index 6abc621d3ba0..f24ce2b87200 100644
--- a/arch/ppc64/kernel/idle.c
+++ b/arch/ppc64/kernel/idle.c
@@ -75,13 +75,9 @@ static int iSeries_idle(void)
75{ 75{
76 struct paca_struct *lpaca; 76 struct paca_struct *lpaca;
77 long oldval; 77 long oldval;
78 unsigned long CTRL;
79 78
80 /* ensure iSeries run light will be out when idle */ 79 /* ensure iSeries run light will be out when idle */
81 clear_thread_flag(TIF_RUN_LIGHT); 80 ppc64_runlatch_off();
82 CTRL = mfspr(CTRLF);
83 CTRL &= ~RUNLATCH;
84 mtspr(CTRLT, CTRL);
85 81
86 lpaca = get_paca(); 82 lpaca = get_paca();
87 83
@@ -111,7 +107,9 @@ static int iSeries_idle(void)
111 } 107 }
112 } 108 }
113 109
110 ppc64_runlatch_on();
114 schedule(); 111 schedule();
112 ppc64_runlatch_off();
115 } 113 }
116 114
117 return 0; 115 return 0;
diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c
index 103daaf73573..e950a2058a19 100644
--- a/arch/ppc64/kernel/kprobes.c
+++ b/arch/ppc64/kernel/kprobes.c
@@ -45,12 +45,17 @@ static struct pt_regs jprobe_saved_regs;
45 45
46int arch_prepare_kprobe(struct kprobe *p) 46int arch_prepare_kprobe(struct kprobe *p)
47{ 47{
48 int ret = 0;
48 kprobe_opcode_t insn = *p->addr; 49 kprobe_opcode_t insn = *p->addr;
49 50
50 if (IS_MTMSRD(insn) || IS_RFID(insn)) 51 if ((unsigned long)p->addr & 0x03) {
51 /* cannot put bp on RFID/MTMSRD */ 52 printk("Attempt to register kprobe at an unaligned address\n");
52 return 1; 53 ret = -EINVAL;
53 return 0; 54 } else if (IS_MTMSRD(insn) || IS_RFID(insn)) {
55 printk("Cannot register a kprobe on rfid or mtmsrd\n");
56 ret = -EINVAL;
57 }
58 return ret;
54} 59}
55 60
56void arch_copy_kprobe(struct kprobe *p) 61void arch_copy_kprobe(struct kprobe *p)
@@ -172,8 +177,6 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs)
172 ret = emulate_step(regs, p->ainsn.insn[0]); 177 ret = emulate_step(regs, p->ainsn.insn[0]);
173 if (ret == 0) 178 if (ret == 0)
174 regs->nip = (unsigned long)p->addr + 4; 179 regs->nip = (unsigned long)p->addr + 4;
175
176 regs->msr &= ~MSR_SE;
177} 180}
178 181
179static inline int post_kprobe_handler(struct pt_regs *regs) 182static inline int post_kprobe_handler(struct pt_regs *regs)
@@ -210,6 +213,7 @@ static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
210 213
211 if (kprobe_status & KPROBE_HIT_SS) { 214 if (kprobe_status & KPROBE_HIT_SS) {
212 resume_execution(current_kprobe, regs); 215 resume_execution(current_kprobe, regs);
216 regs->msr &= ~MSR_SE;
213 regs->msr |= kprobe_saved_msr; 217 regs->msr |= kprobe_saved_msr;
214 218
215 unlock_kprobes(); 219 unlock_kprobes();
@@ -233,8 +237,6 @@ int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
233 */ 237 */
234 preempt_disable(); 238 preempt_disable();
235 switch (val) { 239 switch (val) {
236 case DIE_IABR_MATCH:
237 case DIE_DABR_MATCH:
238 case DIE_BPT: 240 case DIE_BPT:
239 if (kprobe_handler(args->regs)) 241 if (kprobe_handler(args->regs))
240 ret = NOTIFY_STOP; 242 ret = NOTIFY_STOP;
diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c
index 1bd52ece497c..5aca7e8005a8 100644
--- a/arch/ppc64/kernel/mf.c
+++ b/arch/ppc64/kernel/mf.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * mf.c 2 * mf.c
3 * Copyright (C) 2001 Troy D. Armstrong IBM Corporation 3 * Copyright (C) 2001 Troy D. Armstrong IBM Corporation
4 * Copyright (C) 2004 Stephen Rothwell IBM Corporation 4 * Copyright (C) 2004-2005 Stephen Rothwell IBM Corporation
5 * 5 *
6 * This modules exists as an interface between a Linux secondary partition 6 * This modules exists as an interface between a Linux secondary partition
7 * running on an iSeries and the primary partition's Virtual Service 7 * running on an iSeries and the primary partition's Virtual Service
@@ -36,10 +36,12 @@
36 36
37#include <asm/time.h> 37#include <asm/time.h>
38#include <asm/uaccess.h> 38#include <asm/uaccess.h>
39#include <asm/paca.h>
39#include <asm/iSeries/vio.h> 40#include <asm/iSeries/vio.h>
40#include <asm/iSeries/mf.h> 41#include <asm/iSeries/mf.h>
41#include <asm/iSeries/HvLpConfig.h> 42#include <asm/iSeries/HvLpConfig.h>
42#include <asm/iSeries/ItSpCommArea.h> 43#include <asm/iSeries/ItSpCommArea.h>
44#include <asm/iSeries/ItLpQueue.h>
43 45
44/* 46/*
45 * This is the structure layout for the Machine Facilites LPAR event 47 * This is the structure layout for the Machine Facilites LPAR event
@@ -696,36 +698,23 @@ static void get_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
696 complete(&rtc->com); 698 complete(&rtc->com);
697} 699}
698 700
699int mf_get_rtc(struct rtc_time *tm) 701static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm)
700{ 702{
701 struct ce_msg_comp_data ce_complete;
702 struct rtc_time_data rtc_data;
703 int rc;
704
705 memset(&ce_complete, 0, sizeof(ce_complete));
706 memset(&rtc_data, 0, sizeof(rtc_data));
707 init_completion(&rtc_data.com);
708 ce_complete.handler = &get_rtc_time_complete;
709 ce_complete.token = &rtc_data;
710 rc = signal_ce_msg_simple(0x40, &ce_complete);
711 if (rc)
712 return rc;
713 wait_for_completion(&rtc_data.com);
714 tm->tm_wday = 0; 703 tm->tm_wday = 0;
715 tm->tm_yday = 0; 704 tm->tm_yday = 0;
716 tm->tm_isdst = 0; 705 tm->tm_isdst = 0;
717 if (rtc_data.rc) { 706 if (rc) {
718 tm->tm_sec = 0; 707 tm->tm_sec = 0;
719 tm->tm_min = 0; 708 tm->tm_min = 0;
720 tm->tm_hour = 0; 709 tm->tm_hour = 0;
721 tm->tm_mday = 15; 710 tm->tm_mday = 15;
722 tm->tm_mon = 5; 711 tm->tm_mon = 5;
723 tm->tm_year = 52; 712 tm->tm_year = 52;
724 return rtc_data.rc; 713 return rc;
725 } 714 }
726 715
727 if ((rtc_data.ce_msg.ce_msg[2] == 0xa9) || 716 if ((ce_msg[2] == 0xa9) ||
728 (rtc_data.ce_msg.ce_msg[2] == 0xaf)) { 717 (ce_msg[2] == 0xaf)) {
729 /* TOD clock is not set */ 718 /* TOD clock is not set */
730 tm->tm_sec = 1; 719 tm->tm_sec = 1;
731 tm->tm_min = 1; 720 tm->tm_min = 1;
@@ -736,7 +725,6 @@ int mf_get_rtc(struct rtc_time *tm)
736 mf_set_rtc(tm); 725 mf_set_rtc(tm);
737 } 726 }
738 { 727 {
739 u8 *ce_msg = rtc_data.ce_msg.ce_msg;
740 u8 year = ce_msg[5]; 728 u8 year = ce_msg[5];
741 u8 sec = ce_msg[6]; 729 u8 sec = ce_msg[6];
742 u8 min = ce_msg[7]; 730 u8 min = ce_msg[7];
@@ -765,6 +753,63 @@ int mf_get_rtc(struct rtc_time *tm)
765 return 0; 753 return 0;
766} 754}
767 755
756int mf_get_rtc(struct rtc_time *tm)
757{
758 struct ce_msg_comp_data ce_complete;
759 struct rtc_time_data rtc_data;
760 int rc;
761
762 memset(&ce_complete, 0, sizeof(ce_complete));
763 memset(&rtc_data, 0, sizeof(rtc_data));
764 init_completion(&rtc_data.com);
765 ce_complete.handler = &get_rtc_time_complete;
766 ce_complete.token = &rtc_data;
767 rc = signal_ce_msg_simple(0x40, &ce_complete);
768 if (rc)
769 return rc;
770 wait_for_completion(&rtc_data.com);
771 return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
772}
773
774struct boot_rtc_time_data {
775 int busy;
776 struct ce_msg_data ce_msg;
777 int rc;
778};
779
780static void get_boot_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
781{
782 struct boot_rtc_time_data *rtc = token;
783
784 memcpy(&rtc->ce_msg, ce_msg, sizeof(rtc->ce_msg));
785 rtc->rc = 0;
786 rtc->busy = 0;
787}
788
789int mf_get_boot_rtc(struct rtc_time *tm)
790{
791 struct ce_msg_comp_data ce_complete;
792 struct boot_rtc_time_data rtc_data;
793 int rc;
794
795 memset(&ce_complete, 0, sizeof(ce_complete));
796 memset(&rtc_data, 0, sizeof(rtc_data));
797 rtc_data.busy = 1;
798 ce_complete.handler = &get_boot_rtc_time_complete;
799 ce_complete.token = &rtc_data;
800 rc = signal_ce_msg_simple(0x40, &ce_complete);
801 if (rc)
802 return rc;
803 /* We need to poll here as we are not yet taking interrupts */
804 while (rtc_data.busy) {
805 extern unsigned long lpevent_count;
806 struct ItLpQueue *lpq = get_paca()->lpqueue_ptr;
807 if (lpq && ItLpQueue_isLpIntPending(lpq))
808 lpevent_count += ItLpQueue_process(lpq, NULL);
809 }
810 return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
811}
812
768int mf_set_rtc(struct rtc_time *tm) 813int mf_set_rtc(struct rtc_time *tm)
769{ 814{
770 char ce_time[12]; 815 char ce_time[12];
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
index 90b41f48d21c..e3c73b3425dc 100644
--- a/arch/ppc64/kernel/misc.S
+++ b/arch/ppc64/kernel/misc.S
@@ -32,7 +32,7 @@
32 .text 32 .text
33 33
34/* 34/*
35 * Returns (address we're running at) - (address we were linked at) 35 * Returns (address we were linked at) - (address we are running at)
36 * for use before the text and data are mapped to KERNELBASE. 36 * for use before the text and data are mapped to KERNELBASE.
37 */ 37 */
38 38
@@ -792,7 +792,7 @@ _GLOBAL(sys_call_table32)
792 .llong .compat_sys_newstat 792 .llong .compat_sys_newstat
793 .llong .compat_sys_newlstat 793 .llong .compat_sys_newlstat
794 .llong .compat_sys_newfstat 794 .llong .compat_sys_newfstat
795 .llong .sys_uname 795 .llong .sys32_uname
796 .llong .sys_ni_syscall /* 110 old iopl syscall */ 796 .llong .sys_ni_syscall /* 110 old iopl syscall */
797 .llong .sys_vhangup 797 .llong .sys_vhangup
798 .llong .sys_ni_syscall /* old idle syscall */ 798 .llong .sys_ni_syscall /* old idle syscall */
diff --git a/arch/ppc64/kernel/pSeries_reconfig.c b/arch/ppc64/kernel/pSeries_reconfig.c
index cb5443f2e49b..dc2a69d412a2 100644
--- a/arch/ppc64/kernel/pSeries_reconfig.c
+++ b/arch/ppc64/kernel/pSeries_reconfig.c
@@ -47,14 +47,6 @@ static void remove_node_proc_entries(struct device_node *np)
47 remove_proc_entry(pp->name, np->pde); 47 remove_proc_entry(pp->name, np->pde);
48 pp = pp->next; 48 pp = pp->next;
49 } 49 }
50
51 /* Assuming that symlinks have the same parent directory as
52 * np->pde.
53 */
54 if (np->name_link)
55 remove_proc_entry(np->name_link->name, parent->pde);
56 if (np->addr_link)
57 remove_proc_entry(np->addr_link->name, parent->pde);
58 if (np->pde) 50 if (np->pde)
59 remove_proc_entry(np->pde->name, parent->pde); 51 remove_proc_entry(np->pde->name, parent->pde);
60} 52}
diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c
index c60d8cb2b84d..fbad349ec58c 100644
--- a/arch/ppc64/kernel/pSeries_smp.c
+++ b/arch/ppc64/kernel/pSeries_smp.c
@@ -326,13 +326,6 @@ static void __devinit smp_xics_setup_cpu(int cpu)
326 326
327 cpu_clear(cpu, of_spin_map); 327 cpu_clear(cpu, of_spin_map);
328 328
329 /*
330 * Put the calling processor into the GIQ. This is really only
331 * necessary from a secondary thread as the OF start-cpu interface
332 * performs this function for us on primary threads.
333 */
334 rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
335 (1UL << interrupt_server_size) - 1 - default_distrib_server, 1);
336} 329}
337 330
338static DEFINE_SPINLOCK(timebase_lock); 331static DEFINE_SPINLOCK(timebase_lock);
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
index be3cc387c1ec..d786d4b6af0b 100644
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/ppc64/kernel/pci.c
@@ -438,7 +438,7 @@ pgprot_t pci_phys_mem_access_prot(struct file *file,
438 int i; 438 int i;
439 439
440 if (page_is_ram(offset >> PAGE_SHIFT)) 440 if (page_is_ram(offset >> PAGE_SHIFT))
441 return prot; 441 return __pgprot(prot);
442 442
443 prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; 443 prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
444 444
diff --git a/arch/ppc64/kernel/pmac_smp.c b/arch/ppc64/kernel/pmac_smp.c
index c27588ede2fe..a23de37227bf 100644
--- a/arch/ppc64/kernel/pmac_smp.c
+++ b/arch/ppc64/kernel/pmac_smp.c
@@ -68,6 +68,7 @@ extern struct smp_ops_t *smp_ops;
68 68
69static void (*pmac_tb_freeze)(int freeze); 69static void (*pmac_tb_freeze)(int freeze);
70static struct device_node *pmac_tb_clock_chip_host; 70static struct device_node *pmac_tb_clock_chip_host;
71static u8 pmac_tb_pulsar_addr;
71static DEFINE_SPINLOCK(timebase_lock); 72static DEFINE_SPINLOCK(timebase_lock);
72static unsigned long timebase; 73static unsigned long timebase;
73 74
@@ -106,12 +107,9 @@ static void smp_core99_pulsar_tb_freeze(int freeze)
106 u8 data; 107 u8 data;
107 int rc; 108 int rc;
108 109
109 /* Strangely, the device-tree says address is 0xd2, but darwin
110 * accesses 0xd0 ...
111 */
112 pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined); 110 pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
113 rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, 111 rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
114 0xd4 | pmac_low_i2c_read, 112 pmac_tb_pulsar_addr | pmac_low_i2c_read,
115 0x2e, &data, 1); 113 0x2e, &data, 1);
116 if (rc != 0) 114 if (rc != 0)
117 goto bail; 115 goto bail;
@@ -120,7 +118,7 @@ static void smp_core99_pulsar_tb_freeze(int freeze)
120 118
121 pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub); 119 pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
122 rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, 120 rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
123 0xd4 | pmac_low_i2c_write, 121 pmac_tb_pulsar_addr | pmac_low_i2c_write,
124 0x2e, &data, 1); 122 0x2e, &data, 1);
125 bail: 123 bail:
126 if (rc != 0) { 124 if (rc != 0) {
@@ -185,6 +183,12 @@ static int __init smp_core99_probe(void)
185 if (ncpus <= 1) 183 if (ncpus <= 1)
186 return 1; 184 return 1;
187 185
186 /* HW sync only on these platforms */
187 if (!machine_is_compatible("PowerMac7,2") &&
188 !machine_is_compatible("PowerMac7,3") &&
189 !machine_is_compatible("RackMac3,1"))
190 goto nohwsync;
191
188 /* Look for the clock chip */ 192 /* Look for the clock chip */
189 for (cc = NULL; (cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL;) { 193 for (cc = NULL; (cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL;) {
190 struct device_node *p = of_get_parent(cc); 194 struct device_node *p = of_get_parent(cc);
@@ -198,11 +202,18 @@ static int __init smp_core99_probe(void)
198 goto next; 202 goto next;
199 switch (*reg) { 203 switch (*reg) {
200 case 0xd2: 204 case 0xd2:
201 pmac_tb_freeze = smp_core99_cypress_tb_freeze; 205 if (device_is_compatible(cc, "pulsar-legacy-slewing")) {
202 printk(KERN_INFO "Timebase clock is Cypress chip\n"); 206 pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
207 pmac_tb_pulsar_addr = 0xd2;
208 printk(KERN_INFO "Timebase clock is Pulsar chip\n");
209 } else if (device_is_compatible(cc, "cy28508")) {
210 pmac_tb_freeze = smp_core99_cypress_tb_freeze;
211 printk(KERN_INFO "Timebase clock is Cypress chip\n");
212 }
203 break; 213 break;
204 case 0xd4: 214 case 0xd4:
205 pmac_tb_freeze = smp_core99_pulsar_tb_freeze; 215 pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
216 pmac_tb_pulsar_addr = 0xd4;
206 printk(KERN_INFO "Timebase clock is Pulsar chip\n"); 217 printk(KERN_INFO "Timebase clock is Pulsar chip\n");
207 break; 218 break;
208 } 219 }
@@ -210,12 +221,15 @@ static int __init smp_core99_probe(void)
210 pmac_tb_clock_chip_host = p; 221 pmac_tb_clock_chip_host = p;
211 smp_ops->give_timebase = smp_core99_give_timebase; 222 smp_ops->give_timebase = smp_core99_give_timebase;
212 smp_ops->take_timebase = smp_core99_take_timebase; 223 smp_ops->take_timebase = smp_core99_take_timebase;
224 of_node_put(cc);
225 of_node_put(p);
213 break; 226 break;
214 } 227 }
215 next: 228 next:
216 of_node_put(p); 229 of_node_put(p);
217 } 230 }
218 231
232 nohwsync:
219 mpic_request_ipis(); 233 mpic_request_ipis();
220 234
221 return ncpus; 235 return ncpus;
diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c
index 8b0686122738..cdfecbeb331f 100644
--- a/arch/ppc64/kernel/process.c
+++ b/arch/ppc64/kernel/process.c
@@ -378,9 +378,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
378 childregs->gpr[1] = sp + sizeof(struct pt_regs); 378 childregs->gpr[1] = sp + sizeof(struct pt_regs);
379 p->thread.regs = NULL; /* no user register state */ 379 p->thread.regs = NULL; /* no user register state */
380 clear_ti_thread_flag(p->thread_info, TIF_32BIT); 380 clear_ti_thread_flag(p->thread_info, TIF_32BIT);
381#ifdef CONFIG_PPC_ISERIES
382 set_ti_thread_flag(p->thread_info, TIF_RUN_LIGHT);
383#endif
384 } else { 381 } else {
385 childregs->gpr[1] = usp; 382 childregs->gpr[1] = usp;
386 p->thread.regs = childregs; 383 p->thread.regs = childregs;
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
index fe2946c58314..eb6538b58008 100644
--- a/arch/ppc64/kernel/prom.c
+++ b/arch/ppc64/kernel/prom.c
@@ -834,7 +834,7 @@ void __init unflatten_device_tree(void)
834{ 834{
835 unsigned long start, mem, size; 835 unsigned long start, mem, size;
836 struct device_node **allnextp = &allnodes; 836 struct device_node **allnextp = &allnodes;
837 char *p; 837 char *p = NULL;
838 int l = 0; 838 int l = 0;
839 839
840 DBG(" -> unflatten_device_tree()\n"); 840 DBG(" -> unflatten_device_tree()\n");
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
index 35ec42de962e..b7683abfbe6a 100644
--- a/arch/ppc64/kernel/prom_init.c
+++ b/arch/ppc64/kernel/prom_init.c
@@ -211,13 +211,23 @@ struct {
211 */ 211 */
212#define ADDR(x) (u32) ((unsigned long)(x) - offset) 212#define ADDR(x) (u32) ((unsigned long)(x) - offset)
213 213
214/*
215 * Error results ... some OF calls will return "-1" on error, some
216 * will return 0, some will return either. To simplify, here are
217 * macros to use with any ihandle or phandle return value to check if
218 * it is valid
219 */
220
221#define PROM_ERROR (-1u)
222#define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR)
223#define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR)
224
225
214/* This is the one and *ONLY* place where we actually call open 226/* This is the one and *ONLY* place where we actually call open
215 * firmware from, since we need to make sure we're running in 32b 227 * firmware from, since we need to make sure we're running in 32b
216 * mode when we do. We switch back to 64b mode upon return. 228 * mode when we do. We switch back to 64b mode upon return.
217 */ 229 */
218 230
219#define PROM_ERROR (-1)
220
221static int __init call_prom(const char *service, int nargs, int nret, ...) 231static int __init call_prom(const char *service, int nargs, int nret, ...)
222{ 232{
223 int i; 233 int i;
@@ -587,14 +597,13 @@ static void __init prom_send_capabilities(void)
587{ 597{
588 unsigned long offset = reloc_offset(); 598 unsigned long offset = reloc_offset();
589 ihandle elfloader; 599 ihandle elfloader;
590 int ret;
591 600
592 elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader")); 601 elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
593 if (elfloader == 0) { 602 if (elfloader == 0) {
594 prom_printf("couldn't open /packages/elf-loader\n"); 603 prom_printf("couldn't open /packages/elf-loader\n");
595 return; 604 return;
596 } 605 }
597 ret = call_prom("call-method", 3, 1, ADDR("process-elf-header"), 606 call_prom("call-method", 3, 1, ADDR("process-elf-header"),
598 elfloader, ADDR(&fake_elf)); 607 elfloader, ADDR(&fake_elf));
599 call_prom("close", 1, 0, elfloader); 608 call_prom("close", 1, 0, elfloader);
600} 609}
@@ -646,7 +655,7 @@ static unsigned long __init alloc_up(unsigned long size, unsigned long align)
646 base = _ALIGN_UP(base + 0x100000, align)) { 655 base = _ALIGN_UP(base + 0x100000, align)) {
647 prom_debug(" trying: 0x%x\n\r", base); 656 prom_debug(" trying: 0x%x\n\r", base);
648 addr = (unsigned long)prom_claim(base, size, 0); 657 addr = (unsigned long)prom_claim(base, size, 0);
649 if ((int)addr != PROM_ERROR) 658 if (addr != PROM_ERROR)
650 break; 659 break;
651 addr = 0; 660 addr = 0;
652 if (align == 0) 661 if (align == 0)
@@ -708,7 +717,7 @@ static unsigned long __init alloc_down(unsigned long size, unsigned long align,
708 for(; base > RELOC(alloc_bottom); base = _ALIGN_DOWN(base - 0x100000, align)) { 717 for(; base > RELOC(alloc_bottom); base = _ALIGN_DOWN(base - 0x100000, align)) {
709 prom_debug(" trying: 0x%x\n\r", base); 718 prom_debug(" trying: 0x%x\n\r", base);
710 addr = (unsigned long)prom_claim(base, size, 0); 719 addr = (unsigned long)prom_claim(base, size, 0);
711 if ((int)addr != PROM_ERROR) 720 if (addr != PROM_ERROR)
712 break; 721 break;
713 addr = 0; 722 addr = 0;
714 } 723 }
@@ -902,18 +911,19 @@ static void __init prom_instantiate_rtas(void)
902{ 911{
903 unsigned long offset = reloc_offset(); 912 unsigned long offset = reloc_offset();
904 struct prom_t *_prom = PTRRELOC(&prom); 913 struct prom_t *_prom = PTRRELOC(&prom);
905 phandle prom_rtas, rtas_node; 914 phandle rtas_node;
915 ihandle rtas_inst;
906 u32 base, entry = 0; 916 u32 base, entry = 0;
907 u32 size = 0; 917 u32 size = 0;
908 918
909 prom_debug("prom_instantiate_rtas: start...\n"); 919 prom_debug("prom_instantiate_rtas: start...\n");
910 920
911 prom_rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); 921 rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
912 prom_debug("prom_rtas: %x\n", prom_rtas); 922 prom_debug("rtas_node: %x\n", rtas_node);
913 if (prom_rtas == (phandle) -1) 923 if (!PHANDLE_VALID(rtas_node))
914 return; 924 return;
915 925
916 prom_getprop(prom_rtas, "rtas-size", &size, sizeof(size)); 926 prom_getprop(rtas_node, "rtas-size", &size, sizeof(size));
917 if (size == 0) 927 if (size == 0)
918 return; 928 return;
919 929
@@ -922,14 +932,18 @@ static void __init prom_instantiate_rtas(void)
922 prom_printf("RTAS allocation failed !\n"); 932 prom_printf("RTAS allocation failed !\n");
923 return; 933 return;
924 } 934 }
925 prom_printf("instantiating rtas at 0x%x", base);
926 935
927 rtas_node = call_prom("open", 1, 1, ADDR("/rtas")); 936 rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
928 prom_printf("..."); 937 if (!IHANDLE_VALID(rtas_inst)) {
938 prom_printf("opening rtas package failed");
939 return;
940 }
941
942 prom_printf("instantiating rtas at 0x%x ...", base);
929 943
930 if (call_prom("call-method", 3, 2, 944 if (call_prom("call-method", 3, 2,
931 ADDR("instantiate-rtas"), 945 ADDR("instantiate-rtas"),
932 rtas_node, base) != PROM_ERROR) { 946 rtas_inst, base) != PROM_ERROR) {
933 entry = (long)_prom->args.rets[1]; 947 entry = (long)_prom->args.rets[1];
934 } 948 }
935 if (entry == 0) { 949 if (entry == 0) {
@@ -940,8 +954,8 @@ static void __init prom_instantiate_rtas(void)
940 954
941 reserve_mem(base, size); 955 reserve_mem(base, size);
942 956
943 prom_setprop(prom_rtas, "linux,rtas-base", &base, sizeof(base)); 957 prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base));
944 prom_setprop(prom_rtas, "linux,rtas-entry", &entry, sizeof(entry)); 958 prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry));
945 959
946 prom_debug("rtas base = 0x%x\n", base); 960 prom_debug("rtas base = 0x%x\n", base);
947 prom_debug("rtas entry = 0x%x\n", entry); 961 prom_debug("rtas entry = 0x%x\n", entry);
@@ -1062,7 +1076,7 @@ static void __init prom_initialize_tce_table(void)
1062 1076
1063 prom_printf("opening PHB %s", path); 1077 prom_printf("opening PHB %s", path);
1064 phb_node = call_prom("open", 1, 1, path); 1078 phb_node = call_prom("open", 1, 1, path);
1065 if ( (long)phb_node <= 0) 1079 if (phb_node == 0)
1066 prom_printf("... failed\n"); 1080 prom_printf("... failed\n");
1067 else 1081 else
1068 prom_printf("... done\n"); 1082 prom_printf("... done\n");
@@ -1279,12 +1293,12 @@ static void __init prom_init_client_services(unsigned long pp)
1279 1293
1280 /* get a handle for the stdout device */ 1294 /* get a handle for the stdout device */
1281 _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen")); 1295 _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
1282 if ((long)_prom->chosen <= 0) 1296 if (!PHANDLE_VALID(_prom->chosen))
1283 prom_panic("cannot find chosen"); /* msg won't be printed :( */ 1297 prom_panic("cannot find chosen"); /* msg won't be printed :( */
1284 1298
1285 /* get device tree root */ 1299 /* get device tree root */
1286 _prom->root = call_prom("finddevice", 1, 1, ADDR("/")); 1300 _prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
1287 if ((long)_prom->root <= 0) 1301 if (!PHANDLE_VALID(_prom->root))
1288 prom_panic("cannot find device tree root"); /* msg won't be printed :( */ 1302 prom_panic("cannot find device tree root"); /* msg won't be printed :( */
1289} 1303}
1290 1304
@@ -1356,9 +1370,8 @@ static int __init prom_find_machine_type(void)
1356 } 1370 }
1357 /* Default to pSeries. We need to know if we are running LPAR */ 1371 /* Default to pSeries. We need to know if we are running LPAR */
1358 rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); 1372 rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1359 if (rtas != (phandle) -1) { 1373 if (PHANDLE_VALID(rtas)) {
1360 unsigned long x; 1374 int x = prom_getproplen(rtas, "ibm,hypertas-functions");
1361 x = prom_getproplen(rtas, "ibm,hypertas-functions");
1362 if (x != PROM_ERROR) { 1375 if (x != PROM_ERROR) {
1363 prom_printf("Hypertas detected, assuming LPAR !\n"); 1376 prom_printf("Hypertas detected, assuming LPAR !\n");
1364 return PLATFORM_PSERIES_LPAR; 1377 return PLATFORM_PSERIES_LPAR;
@@ -1426,12 +1439,13 @@ static void __init prom_check_displays(void)
1426 * leave some room at the end of the path for appending extra 1439 * leave some room at the end of the path for appending extra
1427 * arguments 1440 * arguments
1428 */ 1441 */
1429 if (call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-10) < 0) 1442 if (call_prom("package-to-path", 3, 1, node, path,
1443 PROM_SCRATCH_SIZE-10) == PROM_ERROR)
1430 continue; 1444 continue;
1431 prom_printf("found display : %s, opening ... ", path); 1445 prom_printf("found display : %s, opening ... ", path);
1432 1446
1433 ih = call_prom("open", 1, 1, path); 1447 ih = call_prom("open", 1, 1, path);
1434 if (ih == (ihandle)0 || ih == (ihandle)-1) { 1448 if (ih == 0) {
1435 prom_printf("failed\n"); 1449 prom_printf("failed\n");
1436 continue; 1450 continue;
1437 } 1451 }
@@ -1514,6 +1528,12 @@ static unsigned long __init dt_find_string(char *str)
1514 return 0; 1528 return 0;
1515} 1529}
1516 1530
1531/*
1532 * The Open Firmware 1275 specification states properties must be 31 bytes or
1533 * less, however not all firmwares obey this. Make it 64 bytes to be safe.
1534 */
1535#define MAX_PROPERTY_NAME 64
1536
1517static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, 1537static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start,
1518 unsigned long *mem_end) 1538 unsigned long *mem_end)
1519{ 1539{
@@ -1527,10 +1547,12 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start,
1527 /* get and store all property names */ 1547 /* get and store all property names */
1528 prev_name = RELOC(""); 1548 prev_name = RELOC("");
1529 for (;;) { 1549 for (;;) {
1530 1550 int rc;
1531 /* 32 is max len of name including nul. */ 1551
1532 namep = make_room(mem_start, mem_end, 32, 1); 1552 /* 64 is max len of name including nul. */
1533 if (call_prom("nextprop", 3, 1, node, prev_name, namep) <= 0) { 1553 namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
1554 rc = call_prom("nextprop", 3, 1, node, prev_name, namep);
1555 if (rc != 1) {
1534 /* No more nodes: unwind alloc */ 1556 /* No more nodes: unwind alloc */
1535 *mem_start = (unsigned long)namep; 1557 *mem_start = (unsigned long)namep;
1536 break; 1558 break;
@@ -1555,18 +1577,12 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start,
1555 } 1577 }
1556} 1578}
1557 1579
1558/*
1559 * The Open Firmware 1275 specification states properties must be 31 bytes or
1560 * less, however not all firmwares obey this. Make it 64 bytes to be safe.
1561 */
1562#define MAX_PROPERTY_NAME 64
1563
1564static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, 1580static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1565 unsigned long *mem_end) 1581 unsigned long *mem_end)
1566{ 1582{
1567 int l, align; 1583 int l, align;
1568 phandle child; 1584 phandle child;
1569 char *namep, *prev_name, *sstart; 1585 char *namep, *prev_name, *sstart, *p, *ep;
1570 unsigned long soff; 1586 unsigned long soff;
1571 unsigned char *valp; 1587 unsigned char *valp;
1572 unsigned long offset = reloc_offset(); 1588 unsigned long offset = reloc_offset();
@@ -1588,6 +1604,14 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1588 call_prom("package-to-path", 3, 1, node, namep, l); 1604 call_prom("package-to-path", 3, 1, node, namep, l);
1589 } 1605 }
1590 namep[l] = '\0'; 1606 namep[l] = '\0';
1607 /* Fixup an Apple bug where they have bogus \0 chars in the
1608 * middle of the path in some properties
1609 */
1610 for (p = namep, ep = namep + l; p < ep; p++)
1611 if (*p == '\0') {
1612 memmove(p, p+1, ep - p);
1613 ep--; l--;
1614 }
1591 *mem_start = _ALIGN(((unsigned long) namep) + strlen(namep) + 1, 4); 1615 *mem_start = _ALIGN(((unsigned long) namep) + strlen(namep) + 1, 4);
1592 } 1616 }
1593 1617
@@ -1599,7 +1623,10 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1599 prev_name = RELOC(""); 1623 prev_name = RELOC("");
1600 sstart = (char *)RELOC(dt_string_start); 1624 sstart = (char *)RELOC(dt_string_start);
1601 for (;;) { 1625 for (;;) {
1602 if (call_prom("nextprop", 3, 1, node, prev_name, pname) <= 0) 1626 int rc;
1627
1628 rc = call_prom("nextprop", 3, 1, node, prev_name, pname);
1629 if (rc != 1)
1603 break; 1630 break;
1604 1631
1605 /* find string offset */ 1632 /* find string offset */
@@ -1615,7 +1642,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1615 l = call_prom("getproplen", 2, 1, node, pname); 1642 l = call_prom("getproplen", 2, 1, node, pname);
1616 1643
1617 /* sanity checks */ 1644 /* sanity checks */
1618 if (l < 0) 1645 if (l == PROM_ERROR)
1619 continue; 1646 continue;
1620 if (l > MAX_PROPERTY_LENGTH) { 1647 if (l > MAX_PROPERTY_LENGTH) {
1621 prom_printf("WARNING: ignoring large property "); 1648 prom_printf("WARNING: ignoring large property ");
@@ -1750,7 +1777,45 @@ static void __init flatten_device_tree(void)
1750 prom_printf("Device tree struct 0x%x -> 0x%x\n", 1777 prom_printf("Device tree struct 0x%x -> 0x%x\n",
1751 RELOC(dt_struct_start), RELOC(dt_struct_end)); 1778 RELOC(dt_struct_start), RELOC(dt_struct_end));
1752 1779
1753 } 1780}
1781
1782
1783static void __init fixup_device_tree(void)
1784{
1785 unsigned long offset = reloc_offset();
1786 phandle u3, i2c, mpic;
1787 u32 u3_rev;
1788 u32 interrupts[2];
1789 u32 parent;
1790
1791 /* Some G5s have a missing interrupt definition, fix it up here */
1792 u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
1793 if (!PHANDLE_VALID(u3))
1794 return;
1795 i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
1796 if (!PHANDLE_VALID(i2c))
1797 return;
1798 mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
1799 if (!PHANDLE_VALID(mpic))
1800 return;
1801
1802 /* check if proper rev of u3 */
1803 if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
1804 == PROM_ERROR)
1805 return;
1806 if (u3_rev != 0x35)
1807 return;
1808 /* does it need fixup ? */
1809 if (prom_getproplen(i2c, "interrupts") > 0)
1810 return;
1811 /* interrupt on this revision of u3 is number 0 and level */
1812 interrupts[0] = 0;
1813 interrupts[1] = 1;
1814 prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts));
1815 parent = (u32)mpic;
1816 prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent));
1817}
1818
1754 1819
1755static void __init prom_find_boot_cpu(void) 1820static void __init prom_find_boot_cpu(void)
1756{ 1821{
@@ -1844,6 +1909,12 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
1844 &getprop_rval, sizeof(getprop_rval)); 1909 &getprop_rval, sizeof(getprop_rval));
1845 1910
1846 /* 1911 /*
1912 * On pSeries, inform the firmware about our capabilities
1913 */
1914 if (RELOC(of_platform) & PLATFORM_PSERIES)
1915 prom_send_capabilities();
1916
1917 /*
1847 * On pSeries, copy the CPU hold code 1918 * On pSeries, copy the CPU hold code
1848 */ 1919 */
1849 if (RELOC(of_platform) & PLATFORM_PSERIES) 1920 if (RELOC(of_platform) & PLATFORM_PSERIES)
@@ -1920,6 +1991,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
1920 } 1991 }
1921 1992
1922 /* 1993 /*
1994 * Fixup any known bugs in the device-tree
1995 */
1996 fixup_device_tree();
1997
1998 /*
1923 * Now finally create the flattened device-tree 1999 * Now finally create the flattened device-tree
1924 */ 2000 */
1925 prom_printf("copying OF device tree ...\n"); 2001 prom_printf("copying OF device tree ...\n");
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
index 5a846324ca8c..9f8c6087ae56 100644
--- a/arch/ppc64/kernel/ptrace.c
+++ b/arch/ppc64/kernel/ptrace.c
@@ -305,14 +305,17 @@ static void do_syscall_trace(void)
305 305
306void do_syscall_trace_enter(struct pt_regs *regs) 306void do_syscall_trace_enter(struct pt_regs *regs)
307{ 307{
308 if (test_thread_flag(TIF_SYSCALL_TRACE)
309 && (current->ptrace & PT_PTRACED))
310 do_syscall_trace();
311
308 if (unlikely(current->audit_context)) 312 if (unlikely(current->audit_context))
309 audit_syscall_entry(current, regs->gpr[0], 313 audit_syscall_entry(current,
314 test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64,
315 regs->gpr[0],
310 regs->gpr[3], regs->gpr[4], 316 regs->gpr[3], regs->gpr[4],
311 regs->gpr[5], regs->gpr[6]); 317 regs->gpr[5], regs->gpr[6]);
312 318
313 if (test_thread_flag(TIF_SYSCALL_TRACE)
314 && (current->ptrace & PT_PTRACED))
315 do_syscall_trace();
316} 319}
317 320
318void do_syscall_trace_leave(struct pt_regs *regs) 321void do_syscall_trace_leave(struct pt_regs *regs)
@@ -320,7 +323,9 @@ void do_syscall_trace_leave(struct pt_regs *regs)
320 secure_computing(regs->gpr[0]); 323 secure_computing(regs->gpr[0]);
321 324
322 if (unlikely(current->audit_context)) 325 if (unlikely(current->audit_context))
323 audit_syscall_exit(current, regs->result); 326 audit_syscall_exit(current,
327 (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
328 regs->result);
324 329
325 if ((test_thread_flag(TIF_SYSCALL_TRACE) 330 if ((test_thread_flag(TIF_SYSCALL_TRACE)
326 || test_thread_flag(TIF_SINGLESTEP)) 331 || test_thread_flag(TIF_SINGLESTEP))
diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c
index 3e70b91375fc..67989055a9fe 100644
--- a/arch/ppc64/kernel/rtc.c
+++ b/arch/ppc64/kernel/rtc.c
@@ -292,47 +292,10 @@ int iSeries_set_rtc_time(struct rtc_time *tm)
292 292
293void iSeries_get_boot_time(struct rtc_time *tm) 293void iSeries_get_boot_time(struct rtc_time *tm)
294{ 294{
295 unsigned long time;
296 static unsigned long lastsec = 1;
297
298 u32 dataWord1 = *((u32 *)(&xSpCommArea.xBcdTimeAtIplStart));
299 u32 dataWord2 = *(((u32 *)&(xSpCommArea.xBcdTimeAtIplStart)) + 1);
300 int year = 1970;
301 int year1 = ( dataWord1 >> 24 ) & 0x000000FF;
302 int year2 = ( dataWord1 >> 16 ) & 0x000000FF;
303 int sec = ( dataWord1 >> 8 ) & 0x000000FF;
304 int min = dataWord1 & 0x000000FF;
305 int hour = ( dataWord2 >> 24 ) & 0x000000FF;
306 int day = ( dataWord2 >> 8 ) & 0x000000FF;
307 int mon = dataWord2 & 0x000000FF;
308
309 if ( piranha_simulator ) 295 if ( piranha_simulator )
310 return; 296 return;
311 297
312 BCD_TO_BIN(sec); 298 mf_get_boot_rtc(tm);
313 BCD_TO_BIN(min);
314 BCD_TO_BIN(hour);
315 BCD_TO_BIN(day);
316 BCD_TO_BIN(mon);
317 BCD_TO_BIN(year1);
318 BCD_TO_BIN(year2);
319 year = year1 * 100 + year2;
320
321 time = mktime(year, mon, day, hour, min, sec);
322 time += ( jiffies / HZ );
323
324 /* Now THIS is a nasty hack!
325 * It ensures that the first two calls get different answers.
326 * That way the loop in init_time (time.c) will not think
327 * the clock is stuck.
328 */
329 if ( lastsec ) {
330 time -= lastsec;
331 --lastsec;
332 }
333
334 to_tm(time, tm);
335 tm->tm_year -= 1900;
336 tm->tm_mon -= 1; 299 tm->tm_mon -= 1;
337} 300}
338#endif 301#endif
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
index 21c57f539c29..dce198d39328 100644
--- a/arch/ppc64/kernel/setup.c
+++ b/arch/ppc64/kernel/setup.c
@@ -103,11 +103,6 @@ extern void unflatten_device_tree(void);
103 103
104extern void smp_release_cpus(void); 104extern void smp_release_cpus(void);
105 105
106unsigned long decr_overclock = 1;
107unsigned long decr_overclock_proc0 = 1;
108unsigned long decr_overclock_set = 0;
109unsigned long decr_overclock_proc0_set = 0;
110
111int have_of = 1; 106int have_of = 1;
112int boot_cpuid = 0; 107int boot_cpuid = 0;
113int boot_cpuid_phys = 0; 108int boot_cpuid_phys = 0;
@@ -1120,64 +1115,15 @@ void ppc64_dump_msg(unsigned int src, const char *msg)
1120 printk("[dump]%04x %s\n", src, msg); 1115 printk("[dump]%04x %s\n", src, msg);
1121} 1116}
1122 1117
1123int set_spread_lpevents( char * str )
1124{
1125 /* The parameter is the number of processors to share in processing lp events */
1126 unsigned long i;
1127 unsigned long val = simple_strtoul( str, NULL, 0 );
1128 if ( ( val > 0 ) && ( val <= NR_CPUS ) ) {
1129 for ( i=1; i<val; ++i )
1130 paca[i].lpqueue_ptr = paca[0].lpqueue_ptr;
1131 printk("lpevent processing spread over %ld processors\n", val);
1132 }
1133 else
1134 printk("invalid spreaqd_lpevents %ld\n", val);
1135 return 1;
1136}
1137
1138/* This should only be called on processor 0 during calibrate decr */ 1118/* This should only be called on processor 0 during calibrate decr */
1139void setup_default_decr(void) 1119void setup_default_decr(void)
1140{ 1120{
1141 struct paca_struct *lpaca = get_paca(); 1121 struct paca_struct *lpaca = get_paca();
1142 1122
1143 if ( decr_overclock_set && !decr_overclock_proc0_set ) 1123 lpaca->default_decr = tb_ticks_per_jiffy;
1144 decr_overclock_proc0 = decr_overclock;
1145
1146 lpaca->default_decr = tb_ticks_per_jiffy / decr_overclock_proc0;
1147 lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy; 1124 lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy;
1148} 1125}
1149 1126
1150int set_decr_overclock_proc0( char * str )
1151{
1152 unsigned long val = simple_strtoul( str, NULL, 0 );
1153 if ( ( val >= 1 ) && ( val <= 48 ) ) {
1154 decr_overclock_proc0_set = 1;
1155 decr_overclock_proc0 = val;
1156 printk("proc 0 decrementer overclock factor of %ld\n", val);
1157 }
1158 else
1159 printk("invalid proc 0 decrementer overclock factor of %ld\n", val);
1160 return 1;
1161}
1162
1163int set_decr_overclock( char * str )
1164{
1165 unsigned long val = simple_strtoul( str, NULL, 0 );
1166 if ( ( val >= 1 ) && ( val <= 48 ) ) {
1167 decr_overclock_set = 1;
1168 decr_overclock = val;
1169 printk("decrementer overclock factor of %ld\n", val);
1170 }
1171 else
1172 printk("invalid decrementer overclock factor of %ld\n", val);
1173 return 1;
1174
1175}
1176
1177__setup("spread_lpevents=", set_spread_lpevents );
1178__setup("decr_overclock_proc0=", set_decr_overclock_proc0 );
1179__setup("decr_overclock=", set_decr_overclock );
1180
1181#ifndef CONFIG_PPC_ISERIES 1127#ifndef CONFIG_PPC_ISERIES
1182/* 1128/*
1183 * This function can be used by platforms to "find" legacy serial ports. 1129 * This function can be used by platforms to "find" legacy serial ports.
diff --git a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c
index a95a2b49a1d5..bf782276984c 100644
--- a/arch/ppc64/kernel/signal.c
+++ b/arch/ppc64/kernel/signal.c
@@ -42,11 +42,7 @@
42 42
43#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 43#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
44 44
45#ifndef MIN 45#define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
46#define MIN(a,b) (((a) < (b)) ? (a) : (b))
47#endif
48
49#define GP_REGS_SIZE MIN(sizeof(elf_gregset_t), sizeof(struct pt_regs))
50#define FP_REGS_SIZE sizeof(elf_fpregset_t) 46#define FP_REGS_SIZE sizeof(elf_fpregset_t)
51 47
52#define TRAMP_TRACEBACK 3 48#define TRAMP_TRACEBACK 3
diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
index 3b906cd94037..9ef5d36d6b25 100644
--- a/arch/ppc64/kernel/smp.c
+++ b/arch/ppc64/kernel/smp.c
@@ -334,7 +334,6 @@ void smp_call_function_interrupt(void)
334 } 334 }
335} 335}
336 336
337extern unsigned long decr_overclock;
338extern struct gettimeofday_struct do_gtod; 337extern struct gettimeofday_struct do_gtod;
339 338
340struct thread_info *current_set[NR_CPUS]; 339struct thread_info *current_set[NR_CPUS];
@@ -491,7 +490,7 @@ int __devinit __cpu_up(unsigned int cpu)
491 if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)) 490 if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))
492 return -EINVAL; 491 return -EINVAL;
493 492
494 paca[cpu].default_decr = tb_ticks_per_jiffy / decr_overclock; 493 paca[cpu].default_decr = tb_ticks_per_jiffy;
495 494
496 if (!cpu_has_feature(CPU_FTR_SLB)) { 495 if (!cpu_has_feature(CPU_FTR_SLB)) {
497 void *tmp; 496 void *tmp;
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
index 7cf7a9600025..9c8e317c598d 100644
--- a/arch/ppc64/kernel/sys_ppc32.c
+++ b/arch/ppc64/kernel/sys_ppc32.c
@@ -791,31 +791,6 @@ asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn)
791} 791}
792 792
793 793
794asmlinkage int ppc64_newuname(struct new_utsname __user * name)
795{
796 int errno = sys_newuname(name);
797
798 if (current->personality == PER_LINUX32 && !errno) {
799 if(copy_to_user(name->machine, "ppc\0\0", 8)) {
800 errno = -EFAULT;
801 }
802 }
803 return errno;
804}
805
806asmlinkage int ppc64_personality(unsigned long personality)
807{
808 int ret;
809 if (current->personality == PER_LINUX32 && personality == PER_LINUX)
810 personality = PER_LINUX32;
811 ret = sys_personality(personality);
812 if (ret == PER_LINUX32)
813 ret = PER_LINUX;
814 return ret;
815}
816
817
818
819/* Note: it is necessary to treat mode as an unsigned int, 794/* Note: it is necessary to treat mode as an unsigned int,
820 * with the corresponding cast to a signed int to insure that the 795 * with the corresponding cast to a signed int to insure that the
821 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 796 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
@@ -1158,26 +1133,47 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
1158} 1133}
1159#endif 1134#endif
1160 1135
1136asmlinkage int sys32_uname(struct old_utsname __user * name)
1137{
1138 int err = 0;
1139
1140 down_read(&uts_sem);
1141 if (copy_to_user(name, &system_utsname, sizeof(*name)))
1142 err = -EFAULT;
1143 up_read(&uts_sem);
1144 if (!err && personality(current->personality) == PER_LINUX32) {
1145 /* change "ppc64" to "ppc" */
1146 if (__put_user(0, name->machine + 3)
1147 || __put_user(0, name->machine + 4))
1148 err = -EFAULT;
1149 }
1150 return err;
1151}
1152
1161asmlinkage int sys32_olduname(struct oldold_utsname __user * name) 1153asmlinkage int sys32_olduname(struct oldold_utsname __user * name)
1162{ 1154{
1163 int error; 1155 int error;
1164 1156
1165 if (!name)
1166 return -EFAULT;
1167 if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) 1157 if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
1168 return -EFAULT; 1158 return -EFAULT;
1169 1159
1170 down_read(&uts_sem); 1160 down_read(&uts_sem);
1171 error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); 1161 error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
1172 error -= __put_user(0,name->sysname+__OLD_UTS_LEN); 1162 error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
1173 error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); 1163 error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
1174 error -= __put_user(0,name->nodename+__OLD_UTS_LEN); 1164 error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
1175 error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); 1165 error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
1176 error -= __put_user(0,name->release+__OLD_UTS_LEN); 1166 error |= __put_user(0,name->release+__OLD_UTS_LEN);
1177 error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); 1167 error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
1178 error -= __put_user(0,name->version+__OLD_UTS_LEN); 1168 error |= __put_user(0,name->version+__OLD_UTS_LEN);
1179 error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); 1169 error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
1180 error = __put_user(0,name->machine+__OLD_UTS_LEN); 1170 error |= __put_user(0,name->machine+__OLD_UTS_LEN);
1171 if (personality(current->personality) == PER_LINUX32) {
1172 /* change "ppc64" to "ppc" */
1173 error |= __put_user(0, name->machine + 3);
1174 error |= __put_user(0, name->machine + 4);
1175 }
1176
1181 up_read(&uts_sem); 1177 up_read(&uts_sem);
1182 1178
1183 error = error ? -EFAULT : 0; 1179 error = error ? -EFAULT : 0;
diff --git a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c
index f2865ff8d2f9..a8cbb202b8cd 100644
--- a/arch/ppc64/kernel/syscalls.c
+++ b/arch/ppc64/kernel/syscalls.c
@@ -199,24 +199,33 @@ out:
199 return ret; 199 return ret;
200} 200}
201 201
202static int __init set_fakeppc(char *str) 202long ppc64_personality(unsigned long personality)
203{ 203{
204 if (*str) 204 long ret;
205 return 0; 205
206 init_task.personality = PER_LINUX32; 206 if (personality(current->personality) == PER_LINUX32
207 return 1; 207 && personality == PER_LINUX)
208 personality = PER_LINUX32;
209 ret = sys_personality(personality);
210 if (ret == PER_LINUX32)
211 ret = PER_LINUX;
212 return ret;
208} 213}
209__setup("fakeppc", set_fakeppc);
210 214
211asmlinkage int sys_uname(struct old_utsname __user * name) 215long ppc64_newuname(struct new_utsname __user * name)
212{ 216{
213 int err = -EFAULT; 217 int err = 0;
214 218
215 down_read(&uts_sem); 219 down_read(&uts_sem);
216 if (name && !copy_to_user(name, &system_utsname, sizeof (*name))) 220 if (copy_to_user(name, &system_utsname, sizeof(*name)))
217 err = 0; 221 err = -EFAULT;
218 up_read(&uts_sem); 222 up_read(&uts_sem);
219 223 if (!err && personality(current->personality) == PER_LINUX32) {
224 /* change ppc64 to ppc */
225 if (__put_user(0, name->machine + 3)
226 || __put_user(0, name->machine + 4))
227 err = -EFAULT;
228 }
220 return err; 229 return err;
221} 230}
222 231
diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c
index 0925694c3ce5..c8fa6569b2fd 100644
--- a/arch/ppc64/kernel/sysfs.c
+++ b/arch/ppc64/kernel/sysfs.c
@@ -113,7 +113,6 @@ void ppc64_enable_pmcs(void)
113#ifdef CONFIG_PPC_PSERIES 113#ifdef CONFIG_PPC_PSERIES
114 unsigned long set, reset; 114 unsigned long set, reset;
115 int ret; 115 int ret;
116 unsigned int ctrl;
117#endif /* CONFIG_PPC_PSERIES */ 116#endif /* CONFIG_PPC_PSERIES */
118 117
119 /* Only need to enable them once */ 118 /* Only need to enable them once */
@@ -167,11 +166,8 @@ void ppc64_enable_pmcs(void)
167 * On SMT machines we have to set the run latch in the ctrl register 166 * On SMT machines we have to set the run latch in the ctrl register
168 * in order to make PMC6 spin. 167 * in order to make PMC6 spin.
169 */ 168 */
170 if (cpu_has_feature(CPU_FTR_SMT)) { 169 if (cpu_has_feature(CPU_FTR_SMT))
171 ctrl = mfspr(CTRLF); 170 ppc64_runlatch_on();
172 ctrl |= RUNLATCH;
173 mtspr(CTRLT, ctrl);
174 }
175#endif /* CONFIG_PPC_PSERIES */ 171#endif /* CONFIG_PPC_PSERIES */
176} 172}
177 173
diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c
index 772a465b49f9..33364a7d2cd2 100644
--- a/arch/ppc64/kernel/time.c
+++ b/arch/ppc64/kernel/time.c
@@ -325,9 +325,7 @@ int timer_interrupt(struct pt_regs * regs)
325 325
326 irq_enter(); 326 irq_enter();
327 327
328#ifndef CONFIG_PPC_ISERIES
329 profile_tick(CPU_PROFILING, regs); 328 profile_tick(CPU_PROFILING, regs);
330#endif
331 329
332 lpaca->lppaca.int_dword.fields.decr_int = 0; 330 lpaca->lppaca.int_dword.fields.decr_int = 0;
333 331
@@ -515,6 +513,7 @@ void __init time_init(void)
515 do_gtod.varp = &do_gtod.vars[0]; 513 do_gtod.varp = &do_gtod.vars[0];
516 do_gtod.var_idx = 0; 514 do_gtod.var_idx = 0;
517 do_gtod.varp->tb_orig_stamp = tb_last_stamp; 515 do_gtod.varp->tb_orig_stamp = tb_last_stamp;
516 get_paca()->next_jiffy_update_tb = tb_last_stamp + tb_ticks_per_jiffy;
518 do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC; 517 do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
519 do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; 518 do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
520 do_gtod.varp->tb_to_xs = tb_to_xs; 519 do_gtod.varp->tb_to_xs = tb_to_xs;
diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c
index eedd1d3c2a10..879f39b90a33 100644
--- a/arch/ppc64/kernel/xics.c
+++ b/arch/ppc64/kernel/xics.c
@@ -432,6 +432,7 @@ void xics_cause_IPI(int cpu)
432{ 432{
433 ops->qirr_info(cpu, IPI_PRIORITY); 433 ops->qirr_info(cpu, IPI_PRIORITY);
434} 434}
435#endif /* CONFIG_SMP */
435 436
436void xics_setup_cpu(void) 437void xics_setup_cpu(void)
437{ 438{
@@ -439,9 +440,17 @@ void xics_setup_cpu(void)
439 440
440 ops->cppr_info(cpu, 0xff); 441 ops->cppr_info(cpu, 0xff);
441 iosync(); 442 iosync();
442}
443 443
444#endif /* CONFIG_SMP */ 444 /*
445 * Put the calling processor into the GIQ. This is really only
446 * necessary from a secondary thread as the OF start-cpu interface
447 * performs this function for us on primary threads.
448 *
449 * XXX: undo of teardown on kexec needs this too, as may hotplug
450 */
451 rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
452 (1UL << interrupt_server_size) - 1 - default_distrib_server, 1);
453}
445 454
446void xics_init_IRQ(void) 455void xics_init_IRQ(void)
447{ 456{
@@ -563,8 +572,7 @@ nextnode:
563 for (; i < NR_IRQS; ++i) 572 for (; i < NR_IRQS; ++i)
564 get_irq_desc(i)->handler = &xics_pic; 573 get_irq_desc(i)->handler = &xics_pic;
565 574
566 ops->cppr_info(boot_cpuid, 0xff); 575 xics_setup_cpu();
567 iosync();
568 576
569 ppc64_boot_msg(0x21, "XICS Done"); 577 ppc64_boot_msg(0x21, "XICS Done");
570} 578}
diff --git a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c
index 144657e0c3d5..52b6b9305341 100644
--- a/arch/ppc64/mm/hash_native.c
+++ b/arch/ppc64/mm/hash_native.c
@@ -320,8 +320,7 @@ static void native_flush_hash_range(unsigned long context,
320 320
321 j = 0; 321 j = 0;
322 for (i = 0; i < number; i++) { 322 for (i = 0; i < number; i++) {
323 if ((batch->addr[i] >= USER_START) && 323 if (batch->addr[i] < KERNELBASE)
324 (batch->addr[i] <= USER_END))
325 vsid = get_vsid(context, batch->addr[i]); 324 vsid = get_vsid(context, batch->addr[i]);
326 else 325 else
327 vsid = get_kernel_vsid(batch->addr[i]); 326 vsid = get_kernel_vsid(batch->addr[i]);
diff --git a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c
index e48be12f518c..0a0f97008d02 100644
--- a/arch/ppc64/mm/hash_utils.c
+++ b/arch/ppc64/mm/hash_utils.c
@@ -298,24 +298,23 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
298 int local = 0; 298 int local = 0;
299 cpumask_t tmp; 299 cpumask_t tmp;
300 300
301 if ((ea & ~REGION_MASK) > EADDR_MASK)
302 return 1;
303
301 switch (REGION_ID(ea)) { 304 switch (REGION_ID(ea)) {
302 case USER_REGION_ID: 305 case USER_REGION_ID:
303 user_region = 1; 306 user_region = 1;
304 mm = current->mm; 307 mm = current->mm;
305 if ((ea > USER_END) || (! mm)) 308 if (! mm)
306 return 1; 309 return 1;
307 310
308 vsid = get_vsid(mm->context.id, ea); 311 vsid = get_vsid(mm->context.id, ea);
309 break; 312 break;
310 case IO_REGION_ID: 313 case IO_REGION_ID:
311 if (ea > IMALLOC_END)
312 return 1;
313 mm = &ioremap_mm; 314 mm = &ioremap_mm;
314 vsid = get_kernel_vsid(ea); 315 vsid = get_kernel_vsid(ea);
315 break; 316 break;
316 case VMALLOC_REGION_ID: 317 case VMALLOC_REGION_ID:
317 if (ea > VMALLOC_END)
318 return 1;
319 mm = &init_mm; 318 mm = &init_mm;
320 vsid = get_kernel_vsid(ea); 319 vsid = get_kernel_vsid(ea);
321 break; 320 break;
@@ -362,7 +361,7 @@ void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte,
362 unsigned long vsid, vpn, va, hash, secondary, slot; 361 unsigned long vsid, vpn, va, hash, secondary, slot;
363 unsigned long huge = pte_huge(pte); 362 unsigned long huge = pte_huge(pte);
364 363
365 if ((ea >= USER_START) && (ea <= USER_END)) 364 if (ea < KERNELBASE)
366 vsid = get_vsid(context, ea); 365 vsid = get_vsid(context, ea);
367 else 366 else
368 vsid = get_kernel_vsid(ea); 367 vsid = get_kernel_vsid(ea);
diff --git a/arch/ppc64/mm/imalloc.c b/arch/ppc64/mm/imalloc.c
index 9d92b0d9cde5..cb8727f3267a 100644
--- a/arch/ppc64/mm/imalloc.c
+++ b/arch/ppc64/mm/imalloc.c
@@ -14,6 +14,7 @@
14#include <asm/pgalloc.h> 14#include <asm/pgalloc.h>
15#include <asm/pgtable.h> 15#include <asm/pgtable.h>
16#include <asm/semaphore.h> 16#include <asm/semaphore.h>
17#include <asm/imalloc.h>
17 18
18static DECLARE_MUTEX(imlist_sem); 19static DECLARE_MUTEX(imlist_sem);
19struct vm_struct * imlist = NULL; 20struct vm_struct * imlist = NULL;
@@ -23,11 +24,11 @@ static int get_free_im_addr(unsigned long size, unsigned long *im_addr)
23 unsigned long addr; 24 unsigned long addr;
24 struct vm_struct **p, *tmp; 25 struct vm_struct **p, *tmp;
25 26
26 addr = IMALLOC_START; 27 addr = ioremap_bot;
27 for (p = &imlist; (tmp = *p) ; p = &tmp->next) { 28 for (p = &imlist; (tmp = *p) ; p = &tmp->next) {
28 if (size + addr < (unsigned long) tmp->addr) 29 if (size + addr < (unsigned long) tmp->addr)
29 break; 30 break;
30 if ((unsigned long)tmp->addr >= IMALLOC_START) 31 if ((unsigned long)tmp->addr >= ioremap_bot)
31 addr = tmp->size + (unsigned long) tmp->addr; 32 addr = tmp->size + (unsigned long) tmp->addr;
32 if (addr > IMALLOC_END-size) 33 if (addr > IMALLOC_END-size)
33 return 1; 34 return 1;
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
index cf33d7ec2e29..4b42aff74d73 100644
--- a/arch/ppc64/mm/init.c
+++ b/arch/ppc64/mm/init.c
@@ -64,6 +64,7 @@
64#include <asm/iommu.h> 64#include <asm/iommu.h>
65#include <asm/abs_addr.h> 65#include <asm/abs_addr.h>
66#include <asm/vdso.h> 66#include <asm/vdso.h>
67#include <asm/imalloc.h>
67 68
68int mem_init_done; 69int mem_init_done;
69unsigned long ioremap_bot = IMALLOC_BASE; 70unsigned long ioremap_bot = IMALLOC_BASE;
@@ -668,7 +669,7 @@ void __init paging_init(void)
668 zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; 669 zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
669 zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT; 670 zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT;
670 671
671 free_area_init_node(0, &contig_page_data, zones_size, 672 free_area_init_node(0, NODE_DATA(0), zones_size,
672 __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); 673 __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size);
673} 674}
674#endif /* CONFIG_DISCONTIGMEM */ 675#endif /* CONFIG_DISCONTIGMEM */
diff --git a/arch/ppc64/mm/stab.c b/arch/ppc64/mm/stab.c
index 31491131d5e4..df4bbe14153c 100644
--- a/arch/ppc64/mm/stab.c
+++ b/arch/ppc64/mm/stab.c
@@ -19,6 +19,11 @@
19#include <asm/paca.h> 19#include <asm/paca.h>
20#include <asm/cputable.h> 20#include <asm/cputable.h>
21 21
22struct stab_entry {
23 unsigned long esid_data;
24 unsigned long vsid_data;
25};
26
22/* Both the segment table and SLB code uses the following cache */ 27/* Both the segment table and SLB code uses the following cache */
23#define NR_STAB_CACHE_ENTRIES 8 28#define NR_STAB_CACHE_ENTRIES 8
24DEFINE_PER_CPU(long, stab_cache_ptr); 29DEFINE_PER_CPU(long, stab_cache_ptr);
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
index 01ae1964c938..c067435bae45 100644
--- a/arch/s390/appldata/appldata_base.c
+++ b/arch/s390/appldata/appldata_base.c
@@ -28,6 +28,7 @@
28//#include <linux/kernel_stat.h> 28//#include <linux/kernel_stat.h>
29#include <linux/notifier.h> 29#include <linux/notifier.h>
30#include <linux/cpu.h> 30#include <linux/cpu.h>
31#include <linux/workqueue.h>
31 32
32#include "appldata.h" 33#include "appldata.h"
33 34
@@ -133,9 +134,12 @@ static int appldata_interval = APPLDATA_CPU_INTERVAL;
133static int appldata_timer_active; 134static int appldata_timer_active;
134 135
135/* 136/*
136 * Tasklet 137 * Work queue
137 */ 138 */
138static struct tasklet_struct appldata_tasklet_struct; 139static struct workqueue_struct *appldata_wq;
140static void appldata_work_fn(void *data);
141static DECLARE_WORK(appldata_work, appldata_work_fn, NULL);
142
139 143
140/* 144/*
141 * Ops list 145 * Ops list
@@ -144,11 +148,11 @@ static DEFINE_SPINLOCK(appldata_ops_lock);
144static LIST_HEAD(appldata_ops_list); 148static LIST_HEAD(appldata_ops_list);
145 149
146 150
147/************************* timer, tasklet, DIAG ******************************/ 151/*************************** timer, work, DIAG *******************************/
148/* 152/*
149 * appldata_timer_function() 153 * appldata_timer_function()
150 * 154 *
151 * schedule tasklet and reschedule timer 155 * schedule work and reschedule timer
152 */ 156 */
153static void appldata_timer_function(unsigned long data, struct pt_regs *regs) 157static void appldata_timer_function(unsigned long data, struct pt_regs *regs)
154{ 158{
@@ -157,22 +161,22 @@ static void appldata_timer_function(unsigned long data, struct pt_regs *regs)
157 atomic_read(&appldata_expire_count)); 161 atomic_read(&appldata_expire_count));
158 if (atomic_dec_and_test(&appldata_expire_count)) { 162 if (atomic_dec_and_test(&appldata_expire_count)) {
159 atomic_set(&appldata_expire_count, num_online_cpus()); 163 atomic_set(&appldata_expire_count, num_online_cpus());
160 tasklet_schedule((struct tasklet_struct *) data); 164 queue_work(appldata_wq, (struct work_struct *) data);
161 } 165 }
162} 166}
163 167
164/* 168/*
165 * appldata_tasklet_function() 169 * appldata_work_fn()
166 * 170 *
167 * call data gathering function for each (active) module 171 * call data gathering function for each (active) module
168 */ 172 */
169static void appldata_tasklet_function(unsigned long data) 173static void appldata_work_fn(void *data)
170{ 174{
171 struct list_head *lh; 175 struct list_head *lh;
172 struct appldata_ops *ops; 176 struct appldata_ops *ops;
173 int i; 177 int i;
174 178
175 P_DEBUG(" -= Tasklet =-\n"); 179 P_DEBUG(" -= Work Queue =-\n");
176 i = 0; 180 i = 0;
177 spin_lock(&appldata_ops_lock); 181 spin_lock(&appldata_ops_lock);
178 list_for_each(lh, &appldata_ops_list) { 182 list_for_each(lh, &appldata_ops_list) {
@@ -231,7 +235,7 @@ static int appldata_diag(char record_nr, u16 function, unsigned long buffer,
231 : "=d" (ry) : "d" (&(appldata_parameter_list)) : "cc"); 235 : "=d" (ry) : "d" (&(appldata_parameter_list)) : "cc");
232 return (int) ry; 236 return (int) ry;
233} 237}
234/********************** timer, tasklet, DIAG <END> ***************************/ 238/************************ timer, work, DIAG <END> ****************************/
235 239
236 240
237/****************************** /proc stuff **********************************/ 241/****************************** /proc stuff **********************************/
@@ -411,7 +415,7 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp,
411 struct list_head *lh; 415 struct list_head *lh;
412 416
413 found = 0; 417 found = 0;
414 spin_lock_bh(&appldata_ops_lock); 418 spin_lock(&appldata_ops_lock);
415 list_for_each(lh, &appldata_ops_list) { 419 list_for_each(lh, &appldata_ops_list) {
416 tmp_ops = list_entry(lh, struct appldata_ops, list); 420 tmp_ops = list_entry(lh, struct appldata_ops, list);
417 if (&tmp_ops->ctl_table[2] == ctl) { 421 if (&tmp_ops->ctl_table[2] == ctl) {
@@ -419,15 +423,15 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp,
419 } 423 }
420 } 424 }
421 if (!found) { 425 if (!found) {
422 spin_unlock_bh(&appldata_ops_lock); 426 spin_unlock(&appldata_ops_lock);
423 return -ENODEV; 427 return -ENODEV;
424 } 428 }
425 ops = ctl->data; 429 ops = ctl->data;
426 if (!try_module_get(ops->owner)) { // protect this function 430 if (!try_module_get(ops->owner)) { // protect this function
427 spin_unlock_bh(&appldata_ops_lock); 431 spin_unlock(&appldata_ops_lock);
428 return -ENODEV; 432 return -ENODEV;
429 } 433 }
430 spin_unlock_bh(&appldata_ops_lock); 434 spin_unlock(&appldata_ops_lock);
431 435
432 if (!*lenp || *ppos) { 436 if (!*lenp || *ppos) {
433 *lenp = 0; 437 *lenp = 0;
@@ -451,10 +455,11 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp,
451 return -EFAULT; 455 return -EFAULT;
452 } 456 }
453 457
454 spin_lock_bh(&appldata_ops_lock); 458 spin_lock(&appldata_ops_lock);
455 if ((buf[0] == '1') && (ops->active == 0)) { 459 if ((buf[0] == '1') && (ops->active == 0)) {
456 if (!try_module_get(ops->owner)) { // protect tasklet 460 // protect work queue callback
457 spin_unlock_bh(&appldata_ops_lock); 461 if (!try_module_get(ops->owner)) {
462 spin_unlock(&appldata_ops_lock);
458 module_put(ops->owner); 463 module_put(ops->owner);
459 return -ENODEV; 464 return -ENODEV;
460 } 465 }
@@ -485,7 +490,7 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp,
485 } 490 }
486 module_put(ops->owner); 491 module_put(ops->owner);
487 } 492 }
488 spin_unlock_bh(&appldata_ops_lock); 493 spin_unlock(&appldata_ops_lock);
489out: 494out:
490 *lenp = len; 495 *lenp = len;
491 *ppos += len; 496 *ppos += len;
@@ -529,7 +534,7 @@ int appldata_register_ops(struct appldata_ops *ops)
529 } 534 }
530 memset(ops->ctl_table, 0, 4*sizeof(struct ctl_table)); 535 memset(ops->ctl_table, 0, 4*sizeof(struct ctl_table));
531 536
532 spin_lock_bh(&appldata_ops_lock); 537 spin_lock(&appldata_ops_lock);
533 list_for_each(lh, &appldata_ops_list) { 538 list_for_each(lh, &appldata_ops_list) {
534 tmp_ops = list_entry(lh, struct appldata_ops, list); 539 tmp_ops = list_entry(lh, struct appldata_ops, list);
535 P_DEBUG("register_ops loop: %i) name = %s, ctl = %i\n", 540 P_DEBUG("register_ops loop: %i) name = %s, ctl = %i\n",
@@ -541,18 +546,18 @@ int appldata_register_ops(struct appldata_ops *ops)
541 APPLDATA_PROC_NAME_LENGTH) == 0) { 546 APPLDATA_PROC_NAME_LENGTH) == 0) {
542 P_ERROR("Name \"%s\" already registered!\n", ops->name); 547 P_ERROR("Name \"%s\" already registered!\n", ops->name);
543 kfree(ops->ctl_table); 548 kfree(ops->ctl_table);
544 spin_unlock_bh(&appldata_ops_lock); 549 spin_unlock(&appldata_ops_lock);
545 return -EBUSY; 550 return -EBUSY;
546 } 551 }
547 if (tmp_ops->ctl_nr == ops->ctl_nr) { 552 if (tmp_ops->ctl_nr == ops->ctl_nr) {
548 P_ERROR("ctl_nr %i already registered!\n", ops->ctl_nr); 553 P_ERROR("ctl_nr %i already registered!\n", ops->ctl_nr);
549 kfree(ops->ctl_table); 554 kfree(ops->ctl_table);
550 spin_unlock_bh(&appldata_ops_lock); 555 spin_unlock(&appldata_ops_lock);
551 return -EBUSY; 556 return -EBUSY;
552 } 557 }
553 } 558 }
554 list_add(&ops->list, &appldata_ops_list); 559 list_add(&ops->list, &appldata_ops_list);
555 spin_unlock_bh(&appldata_ops_lock); 560 spin_unlock(&appldata_ops_lock);
556 561
557 ops->ctl_table[0].ctl_name = CTL_APPLDATA; 562 ops->ctl_table[0].ctl_name = CTL_APPLDATA;
558 ops->ctl_table[0].procname = appldata_proc_name; 563 ops->ctl_table[0].procname = appldata_proc_name;
@@ -583,12 +588,12 @@ int appldata_register_ops(struct appldata_ops *ops)
583 */ 588 */
584void appldata_unregister_ops(struct appldata_ops *ops) 589void appldata_unregister_ops(struct appldata_ops *ops)
585{ 590{
586 spin_lock_bh(&appldata_ops_lock); 591 spin_lock(&appldata_ops_lock);
587 unregister_sysctl_table(ops->sysctl_header); 592 unregister_sysctl_table(ops->sysctl_header);
588 list_del(&ops->list); 593 list_del(&ops->list);
589 kfree(ops->ctl_table); 594 kfree(ops->ctl_table);
590 ops->ctl_table = NULL; 595 ops->ctl_table = NULL;
591 spin_unlock_bh(&appldata_ops_lock); 596 spin_unlock(&appldata_ops_lock);
592 P_INFO("%s-ops unregistered!\n", ops->name); 597 P_INFO("%s-ops unregistered!\n", ops->name);
593} 598}
594/********************** module-ops management <END> **************************/ 599/********************** module-ops management <END> **************************/
@@ -602,7 +607,7 @@ appldata_online_cpu(int cpu)
602 init_virt_timer(&per_cpu(appldata_timer, cpu)); 607 init_virt_timer(&per_cpu(appldata_timer, cpu));
603 per_cpu(appldata_timer, cpu).function = appldata_timer_function; 608 per_cpu(appldata_timer, cpu).function = appldata_timer_function;
604 per_cpu(appldata_timer, cpu).data = (unsigned long) 609 per_cpu(appldata_timer, cpu).data = (unsigned long)
605 &appldata_tasklet_struct; 610 &appldata_work;
606 atomic_inc(&appldata_expire_count); 611 atomic_inc(&appldata_expire_count);
607 spin_lock(&appldata_timer_lock); 612 spin_lock(&appldata_timer_lock);
608 __appldata_vtimer_setup(APPLDATA_MOD_TIMER); 613 __appldata_vtimer_setup(APPLDATA_MOD_TIMER);
@@ -615,7 +620,7 @@ appldata_offline_cpu(int cpu)
615 del_virt_timer(&per_cpu(appldata_timer, cpu)); 620 del_virt_timer(&per_cpu(appldata_timer, cpu));
616 if (atomic_dec_and_test(&appldata_expire_count)) { 621 if (atomic_dec_and_test(&appldata_expire_count)) {
617 atomic_set(&appldata_expire_count, num_online_cpus()); 622 atomic_set(&appldata_expire_count, num_online_cpus());
618 tasklet_schedule(&appldata_tasklet_struct); 623 queue_work(appldata_wq, &appldata_work);
619 } 624 }
620 spin_lock(&appldata_timer_lock); 625 spin_lock(&appldata_timer_lock);
621 __appldata_vtimer_setup(APPLDATA_MOD_TIMER); 626 __appldata_vtimer_setup(APPLDATA_MOD_TIMER);
@@ -648,7 +653,7 @@ static struct notifier_block __devinitdata appldata_nb = {
648/* 653/*
649 * appldata_init() 654 * appldata_init()
650 * 655 *
651 * init timer and tasklet, register /proc entries 656 * init timer, register /proc entries
652 */ 657 */
653static int __init appldata_init(void) 658static int __init appldata_init(void)
654{ 659{
@@ -657,6 +662,12 @@ static int __init appldata_init(void)
657 P_DEBUG("sizeof(parameter_list) = %lu\n", 662 P_DEBUG("sizeof(parameter_list) = %lu\n",
658 sizeof(struct appldata_parameter_list)); 663 sizeof(struct appldata_parameter_list));
659 664
665 appldata_wq = create_singlethread_workqueue("appldata");
666 if (!appldata_wq) {
667 P_ERROR("Could not create work queue\n");
668 return -ENOMEM;
669 }
670
660 for_each_online_cpu(i) 671 for_each_online_cpu(i)
661 appldata_online_cpu(i); 672 appldata_online_cpu(i);
662 673
@@ -670,7 +681,6 @@ static int __init appldata_init(void)
670 appldata_table[1].de->owner = THIS_MODULE; 681 appldata_table[1].de->owner = THIS_MODULE;
671#endif 682#endif
672 683
673 tasklet_init(&appldata_tasklet_struct, appldata_tasklet_function, 0);
674 P_DEBUG("Base interface initialized.\n"); 684 P_DEBUG("Base interface initialized.\n");
675 return 0; 685 return 0;
676} 686}
@@ -678,7 +688,7 @@ static int __init appldata_init(void)
678/* 688/*
679 * appldata_exit() 689 * appldata_exit()
680 * 690 *
681 * stop timer and tasklet, unregister /proc entries 691 * stop timer, unregister /proc entries
682 */ 692 */
683static void __exit appldata_exit(void) 693static void __exit appldata_exit(void)
684{ 694{
@@ -690,7 +700,7 @@ static void __exit appldata_exit(void)
690 /* 700 /*
691 * ops list should be empty, but just in case something went wrong... 701 * ops list should be empty, but just in case something went wrong...
692 */ 702 */
693 spin_lock_bh(&appldata_ops_lock); 703 spin_lock(&appldata_ops_lock);
694 list_for_each(lh, &appldata_ops_list) { 704 list_for_each(lh, &appldata_ops_list) {
695 ops = list_entry(lh, struct appldata_ops, list); 705 ops = list_entry(lh, struct appldata_ops, list);
696 rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, 706 rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC,
@@ -700,7 +710,7 @@ static void __exit appldata_exit(void)
700 "return code: %d\n", ops->name, rc); 710 "return code: %d\n", ops->name, rc);
701 } 711 }
702 } 712 }
703 spin_unlock_bh(&appldata_ops_lock); 713 spin_unlock(&appldata_ops_lock);
704 714
705 for_each_online_cpu(i) 715 for_each_online_cpu(i)
706 appldata_offline_cpu(i); 716 appldata_offline_cpu(i);
@@ -709,7 +719,7 @@ static void __exit appldata_exit(void)
709 719
710 unregister_sysctl_table(appldata_sysctl_header); 720 unregister_sysctl_table(appldata_sysctl_header);
711 721
712 tasklet_kill(&appldata_tasklet_struct); 722 destroy_workqueue(appldata_wq);
713 P_DEBUG("... module unloaded!\n"); 723 P_DEBUG("... module unloaded!\n");
714} 724}
715/**************************** init / exit <END> ******************************/ 725/**************************** init / exit <END> ******************************/
diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c
index 462ee9a84e76..f0e2fbed3d4c 100644
--- a/arch/s390/appldata/appldata_mem.c
+++ b/arch/s390/appldata/appldata_mem.c
@@ -68,7 +68,7 @@ struct appldata_mem_data {
68 u64 pgmajfault; /* page faults (major only) */ 68 u64 pgmajfault; /* page faults (major only) */
69// <-- New in 2.6 69// <-- New in 2.6
70 70
71} appldata_mem_data; 71} __attribute__((packed)) appldata_mem_data;
72 72
73 73
74static inline void appldata_debug_print(struct appldata_mem_data *mem_data) 74static inline void appldata_debug_print(struct appldata_mem_data *mem_data)
diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c
index dd61638d3027..2a4c7432db4a 100644
--- a/arch/s390/appldata/appldata_net_sum.c
+++ b/arch/s390/appldata/appldata_net_sum.c
@@ -57,7 +57,7 @@ struct appldata_net_sum_data {
57 u64 rx_dropped; /* no space in linux buffers */ 57 u64 rx_dropped; /* no space in linux buffers */
58 u64 tx_dropped; /* no space available in linux */ 58 u64 tx_dropped; /* no space available in linux */
59 u64 collisions; /* collisions while transmitting */ 59 u64 collisions; /* collisions while transmitting */
60} appldata_net_sum_data; 60} __attribute__((packed)) appldata_net_sum_data;
61 61
62 62
63static inline void appldata_print_debug(struct appldata_net_sum_data *net_data) 63static inline void appldata_print_debug(struct appldata_net_sum_data *net_data)
diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c
index b83f07484551..e0a476bf4fd6 100644
--- a/arch/s390/appldata/appldata_os.c
+++ b/arch/s390/appldata/appldata_os.c
@@ -49,7 +49,7 @@ struct appldata_os_per_cpu {
49 u32 per_cpu_softirq; /* ... spent in softirqs */ 49 u32 per_cpu_softirq; /* ... spent in softirqs */
50 u32 per_cpu_iowait; /* ... spent while waiting for I/O */ 50 u32 per_cpu_iowait; /* ... spent while waiting for I/O */
51// <-- New in 2.6 51// <-- New in 2.6
52}; 52} __attribute__((packed));
53 53
54struct appldata_os_data { 54struct appldata_os_data {
55 u64 timestamp; 55 u64 timestamp;
@@ -75,7 +75,7 @@ struct appldata_os_data {
75 75
76 /* per cpu data */ 76 /* per cpu data */
77 struct appldata_os_per_cpu os_cpu[0]; 77 struct appldata_os_per_cpu os_cpu[0];
78}; 78} __attribute__((packed));
79 79
80static struct appldata_os_data *appldata_os_data; 80static struct appldata_os_data *appldata_os_data;
81 81
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 9f0d73e3f5f7..06afa3103ace 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -40,6 +40,7 @@
40#include <asm/pgalloc.h> 40#include <asm/pgalloc.h>
41#include <asm/system.h> 41#include <asm/system.h>
42#include <asm/uaccess.h> 42#include <asm/uaccess.h>
43#include <asm/unistd.h>
43 44
44#ifdef CONFIG_S390_SUPPORT 45#ifdef CONFIG_S390_SUPPORT
45#include "compat_ptrace.h" 46#include "compat_ptrace.h"
@@ -130,13 +131,19 @@ static int
130peek_user(struct task_struct *child, addr_t addr, addr_t data) 131peek_user(struct task_struct *child, addr_t addr, addr_t data)
131{ 132{
132 struct user *dummy = NULL; 133 struct user *dummy = NULL;
133 addr_t offset, tmp; 134 addr_t offset, tmp, mask;
134 135
135 /* 136 /*
136 * Stupid gdb peeks/pokes the access registers in 64 bit with 137 * Stupid gdb peeks/pokes the access registers in 64 bit with
137 * an alignment of 4. Programmers from hell... 138 * an alignment of 4. Programmers from hell...
138 */ 139 */
139 if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK) 140 mask = __ADDR_MASK;
141#ifdef CONFIG_ARCH_S390X
142 if (addr >= (addr_t) &dummy->regs.acrs &&
143 addr < (addr_t) &dummy->regs.orig_gpr2)
144 mask = 3;
145#endif
146 if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
140 return -EIO; 147 return -EIO;
141 148
142 if (addr < (addr_t) &dummy->regs.acrs) { 149 if (addr < (addr_t) &dummy->regs.acrs) {
@@ -153,6 +160,16 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data)
153 * access registers are stored in the thread structure 160 * access registers are stored in the thread structure
154 */ 161 */
155 offset = addr - (addr_t) &dummy->regs.acrs; 162 offset = addr - (addr_t) &dummy->regs.acrs;
163#ifdef CONFIG_ARCH_S390X
164 /*
165 * Very special case: old & broken 64 bit gdb reading
166 * from acrs[15]. Result is a 64 bit value. Read the
167 * 32 bit acrs[15] value and shift it by 32. Sick...
168 */
169 if (addr == (addr_t) &dummy->regs.acrs[15])
170 tmp = ((unsigned long) child->thread.acrs[15]) << 32;
171 else
172#endif
156 tmp = *(addr_t *)((addr_t) &child->thread.acrs + offset); 173 tmp = *(addr_t *)((addr_t) &child->thread.acrs + offset);
157 174
158 } else if (addr == (addr_t) &dummy->regs.orig_gpr2) { 175 } else if (addr == (addr_t) &dummy->regs.orig_gpr2) {
@@ -167,6 +184,9 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data)
167 */ 184 */
168 offset = addr - (addr_t) &dummy->regs.fp_regs; 185 offset = addr - (addr_t) &dummy->regs.fp_regs;
169 tmp = *(addr_t *)((addr_t) &child->thread.fp_regs + offset); 186 tmp = *(addr_t *)((addr_t) &child->thread.fp_regs + offset);
187 if (addr == (addr_t) &dummy->regs.fp_regs.fpc)
188 tmp &= (unsigned long) FPC_VALID_MASK
189 << (BITS_PER_LONG - 32);
170 190
171 } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) { 191 } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
172 /* 192 /*
@@ -191,13 +211,19 @@ static int
191poke_user(struct task_struct *child, addr_t addr, addr_t data) 211poke_user(struct task_struct *child, addr_t addr, addr_t data)
192{ 212{
193 struct user *dummy = NULL; 213 struct user *dummy = NULL;
194 addr_t offset; 214 addr_t offset, mask;
195 215
196 /* 216 /*
197 * Stupid gdb peeks/pokes the access registers in 64 bit with 217 * Stupid gdb peeks/pokes the access registers in 64 bit with
198 * an alignment of 4. Programmers from hell indeed... 218 * an alignment of 4. Programmers from hell indeed...
199 */ 219 */
200 if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK) 220 mask = __ADDR_MASK;
221#ifdef CONFIG_ARCH_S390X
222 if (addr >= (addr_t) &dummy->regs.acrs &&
223 addr < (addr_t) &dummy->regs.orig_gpr2)
224 mask = 3;
225#endif
226 if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
201 return -EIO; 227 return -EIO;
202 228
203 if (addr < (addr_t) &dummy->regs.acrs) { 229 if (addr < (addr_t) &dummy->regs.acrs) {
@@ -224,6 +250,17 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
224 * access registers are stored in the thread structure 250 * access registers are stored in the thread structure
225 */ 251 */
226 offset = addr - (addr_t) &dummy->regs.acrs; 252 offset = addr - (addr_t) &dummy->regs.acrs;
253#ifdef CONFIG_ARCH_S390X
254 /*
255 * Very special case: old & broken 64 bit gdb writing
256 * to acrs[15] with a 64 bit value. Ignore the lower
257 * half of the value and write the upper 32 bit to
258 * acrs[15]. Sick...
259 */
260 if (addr == (addr_t) &dummy->regs.acrs[15])
261 child->thread.acrs[15] = (unsigned int) (data >> 32);
262 else
263#endif
227 *(addr_t *)((addr_t) &child->thread.acrs + offset) = data; 264 *(addr_t *)((addr_t) &child->thread.acrs + offset) = data;
228 265
229 } else if (addr == (addr_t) &dummy->regs.orig_gpr2) { 266 } else if (addr == (addr_t) &dummy->regs.orig_gpr2) {
@@ -237,7 +274,8 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
237 * floating point regs. are stored in the thread structure 274 * floating point regs. are stored in the thread structure
238 */ 275 */
239 if (addr == (addr_t) &dummy->regs.fp_regs.fpc && 276 if (addr == (addr_t) &dummy->regs.fp_regs.fpc &&
240 (data & ~FPC_VALID_MASK) != 0) 277 (data & ~((unsigned long) FPC_VALID_MASK
278 << (BITS_PER_LONG - 32))) != 0)
241 return -EINVAL; 279 return -EINVAL;
242 offset = addr - (addr_t) &dummy->regs.fp_regs; 280 offset = addr - (addr_t) &dummy->regs.fp_regs;
243 *(addr_t *)((addr_t) &child->thread.fp_regs + offset) = data; 281 *(addr_t *)((addr_t) &child->thread.fp_regs + offset) = data;
@@ -712,22 +750,24 @@ out:
712asmlinkage void 750asmlinkage void
713syscall_trace(struct pt_regs *regs, int entryexit) 751syscall_trace(struct pt_regs *regs, int entryexit)
714{ 752{
715 if (unlikely(current->audit_context)) { 753 if (unlikely(current->audit_context) && entryexit)
716 if (!entryexit) 754 audit_syscall_exit(current, AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]);
717 audit_syscall_entry(current, regs->gprs[2], 755
718 regs->orig_gpr2, regs->gprs[3],
719 regs->gprs[4], regs->gprs[5]);
720 else
721 audit_syscall_exit(current, regs->gprs[2]);
722 }
723 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 756 if (!test_thread_flag(TIF_SYSCALL_TRACE))
724 return; 757 goto out;
725 if (!(current->ptrace & PT_PTRACED)) 758 if (!(current->ptrace & PT_PTRACED))
726 return; 759 goto out;
727 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) 760 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
728 ? 0x80 : 0)); 761 ? 0x80 : 0));
729 762
730 /* 763 /*
764 * If the debuffer has set an invalid system call number,
765 * we prepare to skip the system call restart handling.
766 */
767 if (!entryexit && regs->gprs[2] >= NR_syscalls)
768 regs->trap = -1;
769
770 /*
731 * this isn't the same as continuing with a signal, but it will do 771 * this isn't the same as continuing with a signal, but it will do
732 * for normal use. strace only continues with a signal if the 772 * for normal use. strace only continues with a signal if the
733 * stopping signal is not SIGTRAP. -brl 773 * stopping signal is not SIGTRAP. -brl
@@ -736,4 +776,10 @@ syscall_trace(struct pt_regs *regs, int entryexit)
736 send_sig(current->exit_code, current, 1); 776 send_sig(current->exit_code, current, 1);
737 current->exit_code = 0; 777 current->exit_code = 0;
738 } 778 }
779 out:
780 if (unlikely(current->audit_context) && !entryexit)
781 audit_syscall_entry(current,
782 test_thread_flag(TIF_31BIT)?AUDIT_ARCH_S390:AUDIT_ARCH_S390X,
783 regs->gprs[2], regs->orig_gpr2, regs->gprs[3],
784 regs->gprs[4], regs->gprs[5]);
739} 785}
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 80306bc8c799..75fde949d125 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -207,7 +207,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection)
207 * we are not in an interrupt and that there is a 207 * we are not in an interrupt and that there is a
208 * user context. 208 * user context.
209 */ 209 */
210 if (user_address == 0 || in_interrupt() || !mm) 210 if (user_address == 0 || in_atomic() || !mm)
211 goto no_context; 211 goto no_context;
212 212
213 /* 213 /*
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 722ea1d63c94..3468d5127223 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -693,6 +693,10 @@ config RTC_9701JE
693 693
694endmenu 694endmenu
695 695
696config ISA_DMA_API
697 bool
698 depends on MPC1211
699 default y
696 700
697menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)" 701menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
698 702
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index 066e253f9c12..2c216ffeea90 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -83,9 +83,6 @@ void default_idle(void)
83 */ 83 */
84void cpu_idle(void) 84void cpu_idle(void)
85{ 85{
86 if (current->pid != 0)
87 goto out;
88
89 /* endless idle loop with no priority at all */ 86 /* endless idle loop with no priority at all */
90 for (;;) { 87 for (;;) {
91 if (ARCH_SUN4C_SUN4) { 88 if (ARCH_SUN4C_SUN4) {
@@ -126,8 +123,6 @@ void cpu_idle(void)
126 schedule(); 123 schedule();
127 check_pgt_cache(); 124 check_pgt_cache();
128 } 125 }
129out:
130 return;
131} 126}
132 127
133#else 128#else
diff --git a/arch/sparc/prom/memory.c b/arch/sparc/prom/memory.c
index 46aa51afec14..c20e5309f8aa 100644
--- a/arch/sparc/prom/memory.c
+++ b/arch/sparc/prom/memory.c
@@ -47,9 +47,9 @@ prom_sortmemlist(struct linux_mlist_v0 *thislist)
47 char *tmpaddr; 47 char *tmpaddr;
48 char *lowest; 48 char *lowest;
49 49
50 for(i=0; thislist[i].theres_more != 0; i++) { 50 for(i=0; thislist[i].theres_more; i++) {
51 lowest = thislist[i].start_adr; 51 lowest = thislist[i].start_adr;
52 for(mitr = i+1; thislist[mitr-1].theres_more != 0; mitr++) 52 for(mitr = i+1; thislist[mitr-1].theres_more; mitr++)
53 if(thislist[mitr].start_adr < lowest) { 53 if(thislist[mitr].start_adr < lowest) {
54 lowest = thislist[mitr].start_adr; 54 lowest = thislist[mitr].start_adr;
55 swapi = mitr; 55 swapi = mitr;
@@ -85,7 +85,7 @@ void __init prom_meminit(void)
85 prom_phys_total[iter].num_bytes = mptr->num_bytes; 85 prom_phys_total[iter].num_bytes = mptr->num_bytes;
86 prom_phys_total[iter].theres_more = &prom_phys_total[iter+1]; 86 prom_phys_total[iter].theres_more = &prom_phys_total[iter+1];
87 } 87 }
88 prom_phys_total[iter-1].theres_more = 0x0; 88 prom_phys_total[iter-1].theres_more = NULL;
89 /* Second, the total prom taken descriptors. */ 89 /* Second, the total prom taken descriptors. */
90 for(mptr = (*(romvec->pv_v0mem.v0_prommap)), iter=0; 90 for(mptr = (*(romvec->pv_v0mem.v0_prommap)), iter=0;
91 mptr; mptr=mptr->theres_more, iter++) { 91 mptr; mptr=mptr->theres_more, iter++) {
@@ -93,7 +93,7 @@ void __init prom_meminit(void)
93 prom_prom_taken[iter].num_bytes = mptr->num_bytes; 93 prom_prom_taken[iter].num_bytes = mptr->num_bytes;
94 prom_prom_taken[iter].theres_more = &prom_prom_taken[iter+1]; 94 prom_prom_taken[iter].theres_more = &prom_prom_taken[iter+1];
95 } 95 }
96 prom_prom_taken[iter-1].theres_more = 0x0; 96 prom_prom_taken[iter-1].theres_more = NULL;
97 /* Last, the available physical descriptors. */ 97 /* Last, the available physical descriptors. */
98 for(mptr = (*(romvec->pv_v0mem.v0_available)), iter=0; 98 for(mptr = (*(romvec->pv_v0mem.v0_available)), iter=0;
99 mptr; mptr=mptr->theres_more, iter++) { 99 mptr; mptr=mptr->theres_more, iter++) {
@@ -101,7 +101,7 @@ void __init prom_meminit(void)
101 prom_phys_avail[iter].num_bytes = mptr->num_bytes; 101 prom_phys_avail[iter].num_bytes = mptr->num_bytes;
102 prom_phys_avail[iter].theres_more = &prom_phys_avail[iter+1]; 102 prom_phys_avail[iter].theres_more = &prom_phys_avail[iter+1];
103 } 103 }
104 prom_phys_avail[iter-1].theres_more = 0x0; 104 prom_phys_avail[iter-1].theres_more = NULL;
105 /* Sort all the lists. */ 105 /* Sort all the lists. */
106 prom_sortmemlist(prom_phys_total); 106 prom_sortmemlist(prom_phys_total);
107 prom_sortmemlist(prom_prom_taken); 107 prom_sortmemlist(prom_prom_taken);
@@ -124,7 +124,7 @@ void __init prom_meminit(void)
124 prom_phys_avail[iter].theres_more = 124 prom_phys_avail[iter].theres_more =
125 &prom_phys_avail[iter+1]; 125 &prom_phys_avail[iter+1];
126 } 126 }
127 prom_phys_avail[iter-1].theres_more = 0x0; 127 prom_phys_avail[iter-1].theres_more = NULL;
128 128
129 num_regs = prom_getproperty(node, "reg", 129 num_regs = prom_getproperty(node, "reg",
130 (char *) prom_reg_memlist, 130 (char *) prom_reg_memlist,
@@ -138,7 +138,7 @@ void __init prom_meminit(void)
138 prom_phys_total[iter].theres_more = 138 prom_phys_total[iter].theres_more =
139 &prom_phys_total[iter+1]; 139 &prom_phys_total[iter+1];
140 } 140 }
141 prom_phys_total[iter-1].theres_more = 0x0; 141 prom_phys_total[iter-1].theres_more = NULL;
142 142
143 node = prom_getchild(prom_root_node); 143 node = prom_getchild(prom_root_node);
144 node = prom_searchsiblings(node, "virtual-memory"); 144 node = prom_searchsiblings(node, "virtual-memory");
@@ -158,7 +158,7 @@ void __init prom_meminit(void)
158 prom_prom_taken[iter].theres_more = 158 prom_prom_taken[iter].theres_more =
159 &prom_prom_taken[iter+1]; 159 &prom_prom_taken[iter+1];
160 } 160 }
161 prom_prom_taken[iter-1].theres_more = 0x0; 161 prom_prom_taken[iter-1].theres_more = NULL;
162 162
163 prom_sortmemlist(prom_prom_taken); 163 prom_sortmemlist(prom_prom_taken);
164 164
@@ -182,15 +182,15 @@ void __init prom_meminit(void)
182 case PROM_SUN4: 182 case PROM_SUN4:
183#ifdef CONFIG_SUN4 183#ifdef CONFIG_SUN4
184 /* how simple :) */ 184 /* how simple :) */
185 prom_phys_total[0].start_adr = 0x0; 185 prom_phys_total[0].start_adr = NULL;
186 prom_phys_total[0].num_bytes = *(sun4_romvec->memorysize); 186 prom_phys_total[0].num_bytes = *(sun4_romvec->memorysize);
187 prom_phys_total[0].theres_more = 0x0; 187 prom_phys_total[0].theres_more = NULL;
188 prom_prom_taken[0].start_adr = 0x0; 188 prom_prom_taken[0].start_adr = NULL;
189 prom_prom_taken[0].num_bytes = 0x0; 189 prom_prom_taken[0].num_bytes = 0x0;
190 prom_prom_taken[0].theres_more = 0x0; 190 prom_prom_taken[0].theres_more = NULL;
191 prom_phys_avail[0].start_adr = 0x0; 191 prom_phys_avail[0].start_adr = NULL;
192 prom_phys_avail[0].num_bytes = *(sun4_romvec->memoryavail); 192 prom_phys_avail[0].num_bytes = *(sun4_romvec->memoryavail);
193 prom_phys_avail[0].theres_more = 0x0; 193 prom_phys_avail[0].theres_more = NULL;
194#endif 194#endif
195 break; 195 break;
196 196
diff --git a/arch/sparc/prom/sun4prom.c b/arch/sparc/prom/sun4prom.c
index 69ca735f0d4e..00390a2652aa 100644
--- a/arch/sparc/prom/sun4prom.c
+++ b/arch/sparc/prom/sun4prom.c
@@ -151,7 +151,7 @@ struct linux_romvec * __init sun4_prom_init(void)
151 * have more time, we can teach the penguin to say "By your 151 * have more time, we can teach the penguin to say "By your
152 * command" or "Activating turbo boost, Michael". :-) 152 * command" or "Activating turbo boost, Michael". :-)
153 */ 153 */
154 sun4_romvec->setLEDs(0x0); 154 sun4_romvec->setLEDs(NULL);
155 155
156 printk("PROMLIB: Old Sun4 boot PROM monitor %s, romvec version %d\n", 156 printk("PROMLIB: Old Sun4 boot PROM monitor %s, romvec version %d\n",
157 sun4_romvec->monid, 157 sun4_romvec->monid,
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index a38cb5036df0..4dcb8af94090 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -756,7 +756,7 @@ void handler_irq(int irq, struct pt_regs *regs)
756 clear_softint(clr_mask); 756 clear_softint(clr_mask);
757 } 757 }
758#else 758#else
759 int should_forward = 1; 759 int should_forward = 0;
760 760
761 clear_softint(1 << irq); 761 clear_softint(1 << irq);
762#endif 762#endif
@@ -1007,10 +1007,10 @@ static int retarget_one_irq(struct irqaction *p, int goal_cpu)
1007 } 1007 }
1008 upa_writel(tid | IMAP_VALID, imap); 1008 upa_writel(tid | IMAP_VALID, imap);
1009 1009
1010 while (!cpu_online(goal_cpu)) { 1010 do {
1011 if (++goal_cpu >= NR_CPUS) 1011 if (++goal_cpu >= NR_CPUS)
1012 goal_cpu = 0; 1012 goal_cpu = 0;
1013 } 1013 } while (!cpu_online(goal_cpu));
1014 1014
1015 return goal_cpu; 1015 return goal_cpu;
1016} 1016}
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c
index 292983413ae2..2803bc7c2c79 100644
--- a/arch/sparc64/kernel/pci_iommu.c
+++ b/arch/sparc64/kernel/pci_iommu.c
@@ -8,6 +8,7 @@
8#include <linux/kernel.h> 8#include <linux/kernel.h>
9#include <linux/sched.h> 9#include <linux/sched.h>
10#include <linux/mm.h> 10#include <linux/mm.h>
11#include <linux/delay.h>
11 12
12#include <asm/pbm.h> 13#include <asm/pbm.h>
13 14
@@ -195,6 +196,34 @@ static iopte_t *alloc_consistent_cluster(struct pci_iommu *iommu, unsigned long
195 return NULL; 196 return NULL;
196} 197}
197 198
199static int iommu_alloc_ctx(struct pci_iommu *iommu)
200{
201 int lowest = iommu->ctx_lowest_free;
202 int sz = IOMMU_NUM_CTXS - lowest;
203 int n = find_next_zero_bit(iommu->ctx_bitmap, sz, lowest);
204
205 if (unlikely(n == sz)) {
206 n = find_next_zero_bit(iommu->ctx_bitmap, lowest, 1);
207 if (unlikely(n == lowest)) {
208 printk(KERN_WARNING "IOMMU: Ran out of contexts.\n");
209 n = 0;
210 }
211 }
212 if (n)
213 __set_bit(n, iommu->ctx_bitmap);
214
215 return n;
216}
217
218static inline void iommu_free_ctx(struct pci_iommu *iommu, int ctx)
219{
220 if (likely(ctx)) {
221 __clear_bit(ctx, iommu->ctx_bitmap);
222 if (ctx < iommu->ctx_lowest_free)
223 iommu->ctx_lowest_free = ctx;
224 }
225}
226
198/* Allocate and map kernel buffer of size SIZE using consistent mode 227/* Allocate and map kernel buffer of size SIZE using consistent mode
199 * DMA for PCI device PDEV. Return non-NULL cpu-side address if 228 * DMA for PCI device PDEV. Return non-NULL cpu-side address if
200 * successful and set *DMA_ADDRP to the PCI side dma address. 229 * successful and set *DMA_ADDRP to the PCI side dma address.
@@ -235,7 +264,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_ad
235 npages = size >> IO_PAGE_SHIFT; 264 npages = size >> IO_PAGE_SHIFT;
236 ctx = 0; 265 ctx = 0;
237 if (iommu->iommu_ctxflush) 266 if (iommu->iommu_ctxflush)
238 ctx = iommu->iommu_cur_ctx++; 267 ctx = iommu_alloc_ctx(iommu);
239 first_page = __pa(first_page); 268 first_page = __pa(first_page);
240 while (npages--) { 269 while (npages--) {
241 iopte_val(*iopte) = (IOPTE_CONSISTENT(ctx) | 270 iopte_val(*iopte) = (IOPTE_CONSISTENT(ctx) |
@@ -316,6 +345,8 @@ void pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_
316 } 345 }
317 } 346 }
318 347
348 iommu_free_ctx(iommu, ctx);
349
319 spin_unlock_irqrestore(&iommu->lock, flags); 350 spin_unlock_irqrestore(&iommu->lock, flags);
320 351
321 order = get_order(size); 352 order = get_order(size);
@@ -359,7 +390,7 @@ dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direct
359 base_paddr = __pa(oaddr & IO_PAGE_MASK); 390 base_paddr = __pa(oaddr & IO_PAGE_MASK);
360 ctx = 0; 391 ctx = 0;
361 if (iommu->iommu_ctxflush) 392 if (iommu->iommu_ctxflush)
362 ctx = iommu->iommu_cur_ctx++; 393 ctx = iommu_alloc_ctx(iommu);
363 if (strbuf->strbuf_enabled) 394 if (strbuf->strbuf_enabled)
364 iopte_protection = IOPTE_STREAMING(ctx); 395 iopte_protection = IOPTE_STREAMING(ctx);
365 else 396 else
@@ -379,6 +410,70 @@ bad:
379 return PCI_DMA_ERROR_CODE; 410 return PCI_DMA_ERROR_CODE;
380} 411}
381 412
413static void pci_strbuf_flush(struct pci_strbuf *strbuf, struct pci_iommu *iommu, u32 vaddr, unsigned long ctx, unsigned long npages, int direction)
414{
415 int limit;
416
417 if (strbuf->strbuf_ctxflush &&
418 iommu->iommu_ctxflush) {
419 unsigned long matchreg, flushreg;
420 u64 val;
421
422 flushreg = strbuf->strbuf_ctxflush;
423 matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
424
425 pci_iommu_write(flushreg, ctx);
426 val = pci_iommu_read(matchreg);
427 val &= 0xffff;
428 if (!val)
429 goto do_flush_sync;
430
431 while (val) {
432 if (val & 0x1)
433 pci_iommu_write(flushreg, ctx);
434 val >>= 1;
435 }
436 val = pci_iommu_read(matchreg);
437 if (unlikely(val)) {
438 printk(KERN_WARNING "pci_strbuf_flush: ctx flush "
439 "timeout matchreg[%lx] ctx[%lx]\n",
440 val, ctx);
441 goto do_page_flush;
442 }
443 } else {
444 unsigned long i;
445
446 do_page_flush:
447 for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
448 pci_iommu_write(strbuf->strbuf_pflush, vaddr);
449 }
450
451do_flush_sync:
452 /* If the device could not have possibly put dirty data into
453 * the streaming cache, no flush-flag synchronization needs
454 * to be performed.
455 */
456 if (direction == PCI_DMA_TODEVICE)
457 return;
458
459 PCI_STC_FLUSHFLAG_INIT(strbuf);
460 pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
461 (void) pci_iommu_read(iommu->write_complete_reg);
462
463 limit = 100000;
464 while (!PCI_STC_FLUSHFLAG_SET(strbuf)) {
465 limit--;
466 if (!limit)
467 break;
468 udelay(1);
469 membar("#LoadLoad");
470 }
471 if (!limit)
472 printk(KERN_WARNING "pci_strbuf_flush: flushflag timeout "
473 "vaddr[%08x] ctx[%lx] npages[%ld]\n",
474 vaddr, ctx, npages);
475}
476
382/* Unmap a single streaming mode DMA translation. */ 477/* Unmap a single streaming mode DMA translation. */
383void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) 478void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction)
384{ 479{
@@ -386,7 +481,7 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
386 struct pci_iommu *iommu; 481 struct pci_iommu *iommu;
387 struct pci_strbuf *strbuf; 482 struct pci_strbuf *strbuf;
388 iopte_t *base; 483 iopte_t *base;
389 unsigned long flags, npages, i, ctx; 484 unsigned long flags, npages, ctx;
390 485
391 if (direction == PCI_DMA_NONE) 486 if (direction == PCI_DMA_NONE)
392 BUG(); 487 BUG();
@@ -414,29 +509,8 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
414 ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL; 509 ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL;
415 510
416 /* Step 1: Kick data out of streaming buffers if necessary. */ 511 /* Step 1: Kick data out of streaming buffers if necessary. */
417 if (strbuf->strbuf_enabled) { 512 if (strbuf->strbuf_enabled)
418 u32 vaddr = bus_addr; 513 pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction);
419
420 PCI_STC_FLUSHFLAG_INIT(strbuf);
421 if (strbuf->strbuf_ctxflush &&
422 iommu->iommu_ctxflush) {
423 unsigned long matchreg, flushreg;
424
425 flushreg = strbuf->strbuf_ctxflush;
426 matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
427 do {
428 pci_iommu_write(flushreg, ctx);
429 } while(((long)pci_iommu_read(matchreg)) < 0L);
430 } else {
431 for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
432 pci_iommu_write(strbuf->strbuf_pflush, vaddr);
433 }
434
435 pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
436 (void) pci_iommu_read(iommu->write_complete_reg);
437 while (!PCI_STC_FLUSHFLAG_SET(strbuf))
438 membar("#LoadLoad");
439 }
440 514
441 /* Step 2: Clear out first TSB entry. */ 515 /* Step 2: Clear out first TSB entry. */
442 iopte_make_dummy(iommu, base); 516 iopte_make_dummy(iommu, base);
@@ -444,6 +518,8 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
444 free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base, 518 free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base,
445 npages, ctx); 519 npages, ctx);
446 520
521 iommu_free_ctx(iommu, ctx);
522
447 spin_unlock_irqrestore(&iommu->lock, flags); 523 spin_unlock_irqrestore(&iommu->lock, flags);
448} 524}
449 525
@@ -583,7 +659,7 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int
583 /* Step 4: Choose a context if necessary. */ 659 /* Step 4: Choose a context if necessary. */
584 ctx = 0; 660 ctx = 0;
585 if (iommu->iommu_ctxflush) 661 if (iommu->iommu_ctxflush)
586 ctx = iommu->iommu_cur_ctx++; 662 ctx = iommu_alloc_ctx(iommu);
587 663
588 /* Step 5: Create the mappings. */ 664 /* Step 5: Create the mappings. */
589 if (strbuf->strbuf_enabled) 665 if (strbuf->strbuf_enabled)
@@ -647,29 +723,8 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems,
647 ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL; 723 ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL;
648 724
649 /* Step 1: Kick data out of streaming buffers if necessary. */ 725 /* Step 1: Kick data out of streaming buffers if necessary. */
650 if (strbuf->strbuf_enabled) { 726 if (strbuf->strbuf_enabled)
651 u32 vaddr = (u32) bus_addr; 727 pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction);
652
653 PCI_STC_FLUSHFLAG_INIT(strbuf);
654 if (strbuf->strbuf_ctxflush &&
655 iommu->iommu_ctxflush) {
656 unsigned long matchreg, flushreg;
657
658 flushreg = strbuf->strbuf_ctxflush;
659 matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
660 do {
661 pci_iommu_write(flushreg, ctx);
662 } while(((long)pci_iommu_read(matchreg)) < 0L);
663 } else {
664 for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
665 pci_iommu_write(strbuf->strbuf_pflush, vaddr);
666 }
667
668 pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
669 (void) pci_iommu_read(iommu->write_complete_reg);
670 while (!PCI_STC_FLUSHFLAG_SET(strbuf))
671 membar("#LoadLoad");
672 }
673 728
674 /* Step 2: Clear out first TSB entry. */ 729 /* Step 2: Clear out first TSB entry. */
675 iopte_make_dummy(iommu, base); 730 iopte_make_dummy(iommu, base);
@@ -677,6 +732,8 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems,
677 free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base, 732 free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base,
678 npages, ctx); 733 npages, ctx);
679 734
735 iommu_free_ctx(iommu, ctx);
736
680 spin_unlock_irqrestore(&iommu->lock, flags); 737 spin_unlock_irqrestore(&iommu->lock, flags);
681} 738}
682 739
@@ -715,28 +772,7 @@ void pci_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size
715 } 772 }
716 773
717 /* Step 2: Kick data out of streaming buffers. */ 774 /* Step 2: Kick data out of streaming buffers. */
718 PCI_STC_FLUSHFLAG_INIT(strbuf); 775 pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction);
719 if (iommu->iommu_ctxflush &&
720 strbuf->strbuf_ctxflush) {
721 unsigned long matchreg, flushreg;
722
723 flushreg = strbuf->strbuf_ctxflush;
724 matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
725 do {
726 pci_iommu_write(flushreg, ctx);
727 } while(((long)pci_iommu_read(matchreg)) < 0L);
728 } else {
729 unsigned long i;
730
731 for (i = 0; i < npages; i++, bus_addr += IO_PAGE_SIZE)
732 pci_iommu_write(strbuf->strbuf_pflush, bus_addr);
733 }
734
735 /* Step 3: Perform flush synchronization sequence. */
736 pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
737 (void) pci_iommu_read(iommu->write_complete_reg);
738 while (!PCI_STC_FLUSHFLAG_SET(strbuf))
739 membar("#LoadLoad");
740 776
741 spin_unlock_irqrestore(&iommu->lock, flags); 777 spin_unlock_irqrestore(&iommu->lock, flags);
742} 778}
@@ -749,7 +785,8 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i
749 struct pcidev_cookie *pcp; 785 struct pcidev_cookie *pcp;
750 struct pci_iommu *iommu; 786 struct pci_iommu *iommu;
751 struct pci_strbuf *strbuf; 787 struct pci_strbuf *strbuf;
752 unsigned long flags, ctx; 788 unsigned long flags, ctx, npages, i;
789 u32 bus_addr;
753 790
754 pcp = pdev->sysdata; 791 pcp = pdev->sysdata;
755 iommu = pcp->pbm->iommu; 792 iommu = pcp->pbm->iommu;
@@ -772,36 +809,14 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i
772 } 809 }
773 810
774 /* Step 2: Kick data out of streaming buffers. */ 811 /* Step 2: Kick data out of streaming buffers. */
775 PCI_STC_FLUSHFLAG_INIT(strbuf); 812 bus_addr = sglist[0].dma_address & IO_PAGE_MASK;
776 if (iommu->iommu_ctxflush && 813 for(i = 1; i < nelems; i++)
777 strbuf->strbuf_ctxflush) { 814 if (!sglist[i].dma_length)
778 unsigned long matchreg, flushreg; 815 break;
779 816 i--;
780 flushreg = strbuf->strbuf_ctxflush; 817 npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length)
781 matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx); 818 - bus_addr) >> IO_PAGE_SHIFT;
782 do { 819 pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction);
783 pci_iommu_write(flushreg, ctx);
784 } while (((long)pci_iommu_read(matchreg)) < 0L);
785 } else {
786 unsigned long i, npages;
787 u32 bus_addr;
788
789 bus_addr = sglist[0].dma_address & IO_PAGE_MASK;
790
791 for(i = 1; i < nelems; i++)
792 if (!sglist[i].dma_length)
793 break;
794 i--;
795 npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - bus_addr) >> IO_PAGE_SHIFT;
796 for (i = 0; i < npages; i++, bus_addr += IO_PAGE_SIZE)
797 pci_iommu_write(strbuf->strbuf_pflush, bus_addr);
798 }
799
800 /* Step 3: Perform flush synchronization sequence. */
801 pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
802 (void) pci_iommu_read(iommu->write_complete_reg);
803 while (!PCI_STC_FLUSHFLAG_SET(strbuf))
804 membar("#LoadLoad");
805 820
806 spin_unlock_irqrestore(&iommu->lock, flags); 821 spin_unlock_irqrestore(&iommu->lock, flags);
807} 822}
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 3567fa879e1f..534320ef0db2 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -1212,7 +1212,7 @@ static void __init psycho_iommu_init(struct pci_controller_info *p)
1212 1212
1213 /* Setup initial software IOMMU state. */ 1213 /* Setup initial software IOMMU state. */
1214 spin_lock_init(&iommu->lock); 1214 spin_lock_init(&iommu->lock);
1215 iommu->iommu_cur_ctx = 0; 1215 iommu->ctx_lowest_free = 1;
1216 1216
1217 /* Register addresses. */ 1217 /* Register addresses. */
1218 iommu->iommu_control = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL; 1218 iommu->iommu_control = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL;
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index 5525d1ec4af8..53d333b4a4e8 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -1265,7 +1265,7 @@ static void __init sabre_iommu_init(struct pci_controller_info *p,
1265 1265
1266 /* Setup initial software IOMMU state. */ 1266 /* Setup initial software IOMMU state. */
1267 spin_lock_init(&iommu->lock); 1267 spin_lock_init(&iommu->lock);
1268 iommu->iommu_cur_ctx = 0; 1268 iommu->ctx_lowest_free = 1;
1269 1269
1270 /* Register addresses. */ 1270 /* Register addresses. */
1271 iommu->iommu_control = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL; 1271 iommu->iommu_control = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL;
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c
index e93fcadc3722..5753175b94e6 100644
--- a/arch/sparc64/kernel/pci_schizo.c
+++ b/arch/sparc64/kernel/pci_schizo.c
@@ -1753,7 +1753,7 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
1753 1753
1754 /* Setup initial software IOMMU state. */ 1754 /* Setup initial software IOMMU state. */
1755 spin_lock_init(&iommu->lock); 1755 spin_lock_init(&iommu->lock);
1756 iommu->iommu_cur_ctx = 0; 1756 iommu->ctx_lowest_free = 1;
1757 1757
1758 /* Register addresses, SCHIZO has iommu ctx flushing. */ 1758 /* Register addresses, SCHIZO has iommu ctx flushing. */
1759 iommu->iommu_control = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL; 1759 iommu->iommu_control = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL;
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 26d3ec41da1c..a0cd2b2494d6 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -62,9 +62,6 @@ void default_idle(void)
62 */ 62 */
63void cpu_idle(void) 63void cpu_idle(void)
64{ 64{
65 if (current->pid != 0)
66 return;
67
68 /* endless idle loop with no priority at all */ 65 /* endless idle loop with no priority at all */
69 for (;;) { 66 for (;;) {
70 /* If current->work.need_resched is zero we should really 67 /* If current->work.need_resched is zero we should really
@@ -80,7 +77,6 @@ void cpu_idle(void)
80 schedule(); 77 schedule();
81 check_pgt_cache(); 78 check_pgt_cache();
82 } 79 }
83 return;
84} 80}
85 81
86#else 82#else
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
index 14d9c3a21b9a..89f5e019f24c 100644
--- a/arch/sparc64/kernel/sbus.c
+++ b/arch/sparc64/kernel/sbus.c
@@ -117,19 +117,42 @@ static void iommu_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages
117 117
118#define STRBUF_TAG_VALID 0x02UL 118#define STRBUF_TAG_VALID 0x02UL
119 119
120static void strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages) 120static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages, int direction)
121{ 121{
122 iommu->strbuf_flushflag = 0UL; 122 unsigned long n;
123 while (npages--) 123 int limit;
124 upa_writeq(base + (npages << IO_PAGE_SHIFT), 124
125 n = npages;
126 while (n--)
127 upa_writeq(base + (n << IO_PAGE_SHIFT),
125 iommu->strbuf_regs + STRBUF_PFLUSH); 128 iommu->strbuf_regs + STRBUF_PFLUSH);
126 129
130 /* If the device could not have possibly put dirty data into
131 * the streaming cache, no flush-flag synchronization needs
132 * to be performed.
133 */
134 if (direction == SBUS_DMA_TODEVICE)
135 return;
136
137 iommu->strbuf_flushflag = 0UL;
138
127 /* Whoopee cushion! */ 139 /* Whoopee cushion! */
128 upa_writeq(__pa(&iommu->strbuf_flushflag), 140 upa_writeq(__pa(&iommu->strbuf_flushflag),
129 iommu->strbuf_regs + STRBUF_FSYNC); 141 iommu->strbuf_regs + STRBUF_FSYNC);
130 upa_readq(iommu->sbus_control_reg); 142 upa_readq(iommu->sbus_control_reg);
131 while (iommu->strbuf_flushflag == 0UL) 143
144 limit = 100000;
145 while (iommu->strbuf_flushflag == 0UL) {
146 limit--;
147 if (!limit)
148 break;
149 udelay(1);
132 membar("#LoadLoad"); 150 membar("#LoadLoad");
151 }
152 if (!limit)
153 printk(KERN_WARNING "sbus_strbuf_flush: flushflag timeout "
154 "vaddr[%08x] npages[%ld]\n",
155 base, npages);
133} 156}
134 157
135static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages) 158static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages)
@@ -406,7 +429,7 @@ void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size,
406 429
407 spin_lock_irqsave(&iommu->lock, flags); 430 spin_lock_irqsave(&iommu->lock, flags);
408 free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT); 431 free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT);
409 strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT); 432 sbus_strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT, direction);
410 spin_unlock_irqrestore(&iommu->lock, flags); 433 spin_unlock_irqrestore(&iommu->lock, flags);
411} 434}
412 435
@@ -569,7 +592,7 @@ void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int
569 iommu = sdev->bus->iommu; 592 iommu = sdev->bus->iommu;
570 spin_lock_irqsave(&iommu->lock, flags); 593 spin_lock_irqsave(&iommu->lock, flags);
571 free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT); 594 free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT);
572 strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT); 595 sbus_strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT, direction);
573 spin_unlock_irqrestore(&iommu->lock, flags); 596 spin_unlock_irqrestore(&iommu->lock, flags);
574} 597}
575 598
@@ -581,7 +604,7 @@ void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t base, size_t
581 size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK)); 604 size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK));
582 605
583 spin_lock_irqsave(&iommu->lock, flags); 606 spin_lock_irqsave(&iommu->lock, flags);
584 strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT); 607 sbus_strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT, direction);
585 spin_unlock_irqrestore(&iommu->lock, flags); 608 spin_unlock_irqrestore(&iommu->lock, flags);
586} 609}
587 610
@@ -605,7 +628,7 @@ void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int
605 size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base; 628 size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base;
606 629
607 spin_lock_irqsave(&iommu->lock, flags); 630 spin_lock_irqsave(&iommu->lock, flags);
608 strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT); 631 sbus_strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT, direction);
609 spin_unlock_irqrestore(&iommu->lock, flags); 632 spin_unlock_irqrestore(&iommu->lock, flags);
610} 633}
611 634
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 12c3d84b7460..b7e6a91952b2 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -383,6 +383,17 @@ static void __init process_switch(char c)
383 /* Use PROM debug console. */ 383 /* Use PROM debug console. */
384 register_console(&prom_debug_console); 384 register_console(&prom_debug_console);
385 break; 385 break;
386 case 'P':
387 /* Force UltraSPARC-III P-Cache on. */
388 if (tlb_type != cheetah) {
389 printk("BOOT: Ignoring P-Cache force option.\n");
390 break;
391 }
392 cheetah_pcache_forced_on = 1;
393 add_taint(TAINT_MACHINE_CHECK);
394 cheetah_enable_pcache();
395 break;
396
386 default: 397 default:
387 printk("Unknown boot switch (-%c)\n", c); 398 printk("Unknown boot switch (-%c)\n", c);
388 break; 399 break;
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 6dff06a44e76..e5b9c7a27789 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -123,6 +123,9 @@ void __init smp_callin(void)
123 123
124 smp_setup_percpu_timer(); 124 smp_setup_percpu_timer();
125 125
126 if (cheetah_pcache_forced_on)
127 cheetah_enable_pcache();
128
126 local_irq_enable(); 129 local_irq_enable();
127 130
128 calibrate_delay(); 131 calibrate_delay();
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index cad5a1122800..e78cc53594fa 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -278,7 +278,7 @@ EXPORT_SYMBOL(verify_compat_iovec);
278 278
279EXPORT_SYMBOL(dump_thread); 279EXPORT_SYMBOL(dump_thread);
280EXPORT_SYMBOL(dump_fpu); 280EXPORT_SYMBOL(dump_fpu);
281EXPORT_SYMBOL(__pte_alloc_one_kernel); 281EXPORT_SYMBOL(pte_alloc_one_kernel);
282#ifndef CONFIG_SMP 282#ifndef CONFIG_SMP
283EXPORT_SYMBOL(pgt_quicklists); 283EXPORT_SYMBOL(pgt_quicklists);
284#endif 284#endif
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 56b203a2af69..a9f4596d7c2b 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -421,6 +421,25 @@ asmlinkage void cee_log(unsigned long ce_status,
421 } 421 }
422} 422}
423 423
424int cheetah_pcache_forced_on;
425
426void cheetah_enable_pcache(void)
427{
428 unsigned long dcr;
429
430 printk("CHEETAH: Enabling P-Cache on cpu %d.\n",
431 smp_processor_id());
432
433 __asm__ __volatile__("ldxa [%%g0] %1, %0"
434 : "=r" (dcr)
435 : "i" (ASI_DCU_CONTROL_REG));
436 dcr |= (DCU_PE | DCU_HPE | DCU_SPE | DCU_SL);
437 __asm__ __volatile__("stxa %0, [%%g0] %1\n\t"
438 "membar #Sync"
439 : /* no outputs */
440 : "r" (dcr), "i" (ASI_DCU_CONTROL_REG));
441}
442
424/* Cheetah error trap handling. */ 443/* Cheetah error trap handling. */
425static unsigned long ecache_flush_physbase; 444static unsigned long ecache_flush_physbase;
426static unsigned long ecache_flush_linesize; 445static unsigned long ecache_flush_linesize;
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index db6fa77b4dab..9c5222075da9 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -1114,7 +1114,7 @@ struct pgtable_cache_struct pgt_quicklists;
1114#else 1114#else
1115#define DC_ALIAS_SHIFT 0 1115#define DC_ALIAS_SHIFT 0
1116#endif 1116#endif
1117pte_t *__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) 1117pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
1118{ 1118{
1119 struct page *page; 1119 struct page *page;
1120 unsigned long color; 1120 unsigned long color;
diff --git a/arch/um/Kconfig.debug b/arch/um/Kconfig.debug
index b89989de364d..bd41e4286d0d 100644
--- a/arch/um/Kconfig.debug
+++ b/arch/um/Kconfig.debug
@@ -2,10 +2,6 @@ menu "Kernel hacking"
2 2
3source "lib/Kconfig.debug" 3source "lib/Kconfig.debug"
4 4
5config FRAME_POINTER
6 bool
7 default y if DEBUG_INFO
8
9config PT_PROXY 5config PT_PROXY
10 bool "Enable ptrace proxy" 6 bool "Enable ptrace proxy"
11 depends on XTERM_CHAN && DEBUG_INFO && MODE_TT 7 depends on XTERM_CHAN && DEBUG_INFO && MODE_TT
diff --git a/arch/um/Kconfig_char b/arch/um/Kconfig_char
index 3e50fdb67626..62d87b71179b 100644
--- a/arch/um/Kconfig_char
+++ b/arch/um/Kconfig_char
@@ -204,5 +204,11 @@ config UML_RANDOM
204 http://sourceforge.net/projects/gkernel/). rngd periodically reads 204 http://sourceforge.net/projects/gkernel/). rngd periodically reads
205 /dev/hwrng and injects the entropy into /dev/random. 205 /dev/hwrng and injects the entropy into /dev/random.
206 206
207config MMAPPER
208 tristate "iomem emulation driver"
209 help
210 This driver allows a host file to be used as emulated IO memory inside
211 UML.
212
207endmenu 213endmenu
208 214
diff --git a/arch/um/Kconfig_x86_64 b/arch/um/Kconfig_x86_64
index fd8d7e8982b1..f162f50f0b17 100644
--- a/arch/um/Kconfig_x86_64
+++ b/arch/um/Kconfig_x86_64
@@ -6,6 +6,10 @@ config 64BIT
6 bool 6 bool
7 default y 7 default y
8 8
9config TOP_ADDR
10 hex
11 default 0x80000000
12
9config 3_LEVEL_PGTABLES 13config 3_LEVEL_PGTABLES
10 bool 14 bool
11 default y 15 default y
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 97bca6b5ca95..f2a0c40a9204 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -17,7 +17,7 @@ core-y += $(ARCH_DIR)/kernel/ \
17 17
18# Have to precede the include because the included Makefiles reference them. 18# Have to precede the include because the included Makefiles reference them.
19SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \ 19SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \
20 arch-signal.h module.h vm-flags.h 20 module.h vm-flags.h elf.h
21SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header)) 21SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
22 22
23# XXX: The "os" symlink is only used by arch/um/include/os.h, which includes 23# XXX: The "os" symlink is only used by arch/um/include/os.h, which includes
@@ -44,6 +44,11 @@ ifneq ($(MAKEFILES-INCL),)
44endif 44endif
45 45
46ARCH_INCLUDE := -I$(ARCH_DIR)/include 46ARCH_INCLUDE := -I$(ARCH_DIR)/include
47ifneq ($(KBUILD_SRC),)
48ARCH_INCLUDE += -I$(ARCH_DIR)/include2
49ARCH_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include
50MRPROPER_DIRS += $(ARCH_DIR)/include2
51endif
47SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH) 52SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH)
48 53
49include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) 54include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
@@ -94,17 +99,18 @@ define archhelp
94 echo ' find in the kernel root.' 99 echo ' find in the kernel root.'
95endef 100endef
96 101
102ifneq ($(KBUILD_SRC),)
103$(shell mkdir -p $(ARCH_DIR) && ln -fsn $(srctree)/$(ARCH_DIR)/Kconfig_$(SUBARCH) $(ARCH_DIR)/Kconfig_arch)
104CLEAN_FILES += $(ARCH_DIR)/Kconfig_arch
105else
97$(shell cd $(ARCH_DIR) && ln -sf Kconfig_$(SUBARCH) Kconfig_arch) 106$(shell cd $(ARCH_DIR) && ln -sf Kconfig_$(SUBARCH) Kconfig_arch)
107endif
98 108
99prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) \ 109prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS)
100 $(ARCH_DIR)/kernel/vmlinux.lds.S
101 110
102LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static 111LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static
103LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib 112LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib
104 113
105LD_SCRIPT-$(CONFIG_LD_SCRIPT_STATIC) := uml.lds.S
106LD_SCRIPT-$(CONFIG_LD_SCRIPT_DYN) := dyn.lds.S
107
108CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT 114CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT
109CONFIG_KERNEL_STACK_ORDER ?= 2 115CONFIG_KERNEL_STACK_ORDER ?= 2
110STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] ) 116STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
@@ -126,7 +132,7 @@ define cmd_vmlinux__
126 $(CC) $(CFLAGS_vmlinux) -o $@ \ 132 $(CC) $(CFLAGS_vmlinux) -o $@ \
127 -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \ 133 -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \
128 -Wl,--start-group $(vmlinux-main) -Wl,--end-group \ 134 -Wl,--start-group $(vmlinux-main) -Wl,--end-group \
129 -L/usr/lib -lutil \ 135 -lutil \
130 $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) \ 136 $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) \
131 FORCE ,$^) ; rm -f linux 137 FORCE ,$^) ; rm -f linux
132endef 138endef
@@ -145,31 +151,42 @@ archclean:
145 @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ 151 @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
146 -o -name '*.gcov' \) -type f -print | xargs rm -f 152 -o -name '*.gcov' \) -type f -print | xargs rm -f
147 153
148#We need to re-preprocess this when the symlink dest changes.
149#So we touch it when needed.
150$(ARCH_DIR)/kernel/vmlinux.lds.S: FORCE
151 $(Q)if [ "$(shell readlink $@)" != "$(LD_SCRIPT-y)" ]; then \
152 echo ' SYMLINK $@'; \
153 ln -sf $(LD_SCRIPT-y) $@; \
154 touch $@; \
155 fi;
156
157$(SYMLINK_HEADERS): 154$(SYMLINK_HEADERS):
158 @echo ' SYMLINK $@' 155 @echo ' SYMLINK $@'
156ifneq ($(KBUILD_SRC),)
157 ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@
158else
159 $(Q)cd $(TOPDIR)/$(dir $@) ; \ 159 $(Q)cd $(TOPDIR)/$(dir $@) ; \
160 ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@) 160 ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@)
161endif
161 162
162include/asm-um/arch: 163include/asm-um/arch:
163 @echo ' SYMLINK $@' 164 @echo ' SYMLINK $@'
165ifneq ($(KBUILD_SRC),)
166 $(Q)mkdir -p include/asm-um
167 $(Q)ln -fsn $(srctree)/include/asm-$(SUBARCH) include/asm-um/arch
168else
164 $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch 169 $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch
170endif
165 171
166$(ARCH_DIR)/include/sysdep: 172$(ARCH_DIR)/include/sysdep:
167 @echo ' SYMLINK $@' 173 @echo ' SYMLINK $@'
174ifneq ($(KBUILD_SRC),)
175 $(Q)mkdir -p $(ARCH_DIR)/include
176 $(Q)mkdir -p $(ARCH_DIR)/include2
177 $(Q)ln -fsn sysdep-$(SUBARCH) $(ARCH_DIR)/include/sysdep
178 $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/include/sysdep-$(SUBARCH) $(ARCH_DIR)/include2/sysdep
179else
168 $(Q)cd $(ARCH_DIR)/include && ln -sf sysdep-$(SUBARCH) sysdep 180 $(Q)cd $(ARCH_DIR)/include && ln -sf sysdep-$(SUBARCH) sysdep
181endif
169 182
170$(ARCH_DIR)/os: 183$(ARCH_DIR)/os:
171 @echo ' SYMLINK $@' 184 @echo ' SYMLINK $@'
185ifneq ($(KBUILD_SRC),)
186 $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/os-$(OS) $(ARCH_DIR)/os
187else
172 $(Q)cd $(ARCH_DIR) && ln -sf os-$(OS) os 188 $(Q)cd $(ARCH_DIR) && ln -sf os-$(OS) os
189endif
173 190
174# Generated files 191# Generated files
175define filechk_umlconfig 192define filechk_umlconfig
@@ -179,10 +196,31 @@ endef
179$(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h 196$(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h
180 $(call filechk,umlconfig) 197 $(call filechk,umlconfig)
181 198
199$(ARCH_DIR)/user-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.c
200 $(CC) $(USER_CFLAGS) -S -o $@ $<
201
202$(ARCH_DIR)/user-offsets.h: $(ARCH_DIR)/user-offsets.s
203 $(call filechk,gen-asm-offsets)
204
205CLEAN_FILES += $(ARCH_DIR)/user-offsets.s $(ARCH_DIR)/user-offsets.h
206
207$(ARCH_DIR)/kernel-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/kernel-offsets.c \
208 $(ARCH_SYMLINKS) \
209 $(SYS_DIR)/sc.h \
210 include/asm include/linux/version.h \
211 include/config/MARKER \
212 $(ARCH_DIR)/include/user_constants.h
213 $(CC) $(CFLAGS) $(NOSTDINC_FLAGS) $(CPPFLAGS) -S -o $@ $<
214
215$(ARCH_DIR)/kernel-offsets.h: $(ARCH_DIR)/kernel-offsets.s
216 $(call filechk,gen-asm-offsets)
217
218CLEAN_FILES += $(ARCH_DIR)/kernel-offsets.s $(ARCH_DIR)/kernel-offsets.h
219
182$(ARCH_DIR)/include/task.h: $(ARCH_DIR)/util/mk_task 220$(ARCH_DIR)/include/task.h: $(ARCH_DIR)/util/mk_task
183 $(call filechk,gen_header) 221 $(call filechk,gen_header)
184 222
185$(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/os/util/mk_user_constants 223$(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/os-$(OS)/util/mk_user_constants
186 $(call filechk,gen_header) 224 $(call filechk,gen_header)
187 225
188$(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/util/mk_constants 226$(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/util/mk_constants
@@ -191,20 +229,20 @@ $(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/util/mk_constants
191$(ARCH_DIR)/include/skas_ptregs.h: $(ARCH_DIR)/kernel/skas/util/mk_ptregs 229$(ARCH_DIR)/include/skas_ptregs.h: $(ARCH_DIR)/kernel/skas/util/mk_ptregs
192 $(call filechk,gen_header) 230 $(call filechk,gen_header)
193 231
194$(ARCH_DIR)/os/util/mk_user_constants: $(ARCH_DIR)/os/util FORCE ; 232$(ARCH_DIR)/os-$(OS)/util/mk_user_constants: $(ARCH_DIR)/os-$(OS)/util FORCE ;
195 233
196$(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants: $(ARCH_DIR)/include/user_constants.h $(ARCH_DIR)/util \ 234$(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants: $(ARCH_DIR)/include/user_constants.h $(ARCH_DIR)/util \
197 FORCE ; 235 FORCE ;
198 236
199$(ARCH_DIR)/kernel/skas/util/mk_ptregs: $(ARCH_DIR)/kernel/skas/util FORCE ; 237$(ARCH_DIR)/kernel/skas/util/mk_ptregs: $(ARCH_DIR)/kernel/skas/util FORCE ;
200 238
201$(ARCH_DIR)/util: scripts_basic $(SYS_DIR)/sc.h FORCE 239$(ARCH_DIR)/util: scripts_basic $(SYS_DIR)/sc.h $(ARCH_DIR)/kernel-offsets.h FORCE
202 $(Q)$(MAKE) $(build)=$@ 240 $(Q)$(MAKE) $(build)=$@
203 241
204$(ARCH_DIR)/kernel/skas/util: scripts_basic FORCE 242$(ARCH_DIR)/kernel/skas/util: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
205 $(Q)$(MAKE) $(build)=$@ 243 $(Q)$(MAKE) $(build)=$@
206 244
207$(ARCH_DIR)/os/util: scripts_basic FORCE 245$(ARCH_DIR)/os-$(OS)/util: scripts_basic FORCE
208 $(Q)$(MAKE) $(build)=$@ 246 $(Q)$(MAKE) $(build)=$@
209 247
210export SUBARCH USER_CFLAGS OS 248export SUBARCH USER_CFLAGS OS
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index f9e3c0f06541..29e182d5a83a 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -32,10 +32,10 @@ $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
32$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread 32$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
33 $(call filechk,gen_header) 33 $(call filechk,gen_header)
34 34
35$(SYS_UTIL_DIR)/mk_sc: scripts_basic FORCE 35$(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
36 $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ 36 $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
37 37
38$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE 38$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_DIR)/kernel-offsets.h FORCE
39 $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ 39 $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
40 40
41$(SYS_UTIL_DIR): scripts_basic include/asm FORCE 41$(SYS_UTIL_DIR): scripts_basic include/asm FORCE
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index a77971133e91..32144562c279 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -23,10 +23,10 @@ $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
23$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread 23$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
24 $(call filechk,gen_header) 24 $(call filechk,gen_header)
25 25
26$(SYS_UTIL_DIR)/mk_sc: scripts_basic FORCE 26$(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
27 $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ 27 $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
28 28
29$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE 29$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(GEN_HEADERS) $(ARCH_DIR)/kernel-offsets.h FORCE
30 $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ 30 $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
31 31
32CLEAN_FILES += $(SYS_HEADERS) 32CLEAN_FILES += $(SYS_HEADERS)
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index 323f72c64cd2..b2de9916c32c 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -22,8 +22,8 @@ obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o
22obj-$(CONFIG_SSL) += ssl.o 22obj-$(CONFIG_SSL) += ssl.o
23obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o 23obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o
24 24
25obj-$(CONFIG_UML_NET_SLIP) += slip.o 25obj-$(CONFIG_UML_NET_SLIP) += slip.o slip_common.o
26obj-$(CONFIG_UML_NET_SLIRP) += slirp.o 26obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o
27obj-$(CONFIG_UML_NET_DAEMON) += daemon.o 27obj-$(CONFIG_UML_NET_DAEMON) += daemon.o
28obj-$(CONFIG_UML_NET_MCAST) += mcast.o 28obj-$(CONFIG_UML_NET_MCAST) += mcast.o
29#obj-$(CONFIG_UML_NET_PCAP) += pcap.o $(PCAP) 29#obj-$(CONFIG_UML_NET_PCAP) += pcap.o $(PCAP)
@@ -41,6 +41,6 @@ obj-$(CONFIG_UML_WATCHDOG) += harddog.o
41obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o 41obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
42obj-$(CONFIG_UML_RANDOM) += random.o 42obj-$(CONFIG_UML_RANDOM) += random.o
43 43
44USER_OBJS := fd.o null.o pty.o tty.o xterm.o 44USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o
45 45
46include arch/um/scripts/Makefile.rules 46include arch/um/scripts/Makefile.rules
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 0150038af795..14a12d6b3df6 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -20,9 +20,17 @@
20#include "os.h" 20#include "os.h"
21 21
22#ifdef CONFIG_NOCONFIG_CHAN 22#ifdef CONFIG_NOCONFIG_CHAN
23
24/* The printk's here are wrong because we are complaining that there is no
25 * output device, but printk is printing to that output device. The user will
26 * never see the error. printf would be better, except it can't run on a
27 * kernel stack because it will overflow it.
28 * Use printk for now since that will avoid crashing.
29 */
30
23static void *not_configged_init(char *str, int device, struct chan_opts *opts) 31static void *not_configged_init(char *str, int device, struct chan_opts *opts)
24{ 32{
25 printf(KERN_ERR "Using a channel type which is configured out of " 33 printk(KERN_ERR "Using a channel type which is configured out of "
26 "UML\n"); 34 "UML\n");
27 return(NULL); 35 return(NULL);
28} 36}
@@ -30,27 +38,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts)
30static int not_configged_open(int input, int output, int primary, void *data, 38static int not_configged_open(int input, int output, int primary, void *data,
31 char **dev_out) 39 char **dev_out)
32{ 40{
33 printf(KERN_ERR "Using a channel type which is configured out of " 41 printk(KERN_ERR "Using a channel type which is configured out of "
34 "UML\n"); 42 "UML\n");
35 return(-ENODEV); 43 return(-ENODEV);
36} 44}
37 45
38static void not_configged_close(int fd, void *data) 46static void not_configged_close(int fd, void *data)
39{ 47{
40 printf(KERN_ERR "Using a channel type which is configured out of " 48 printk(KERN_ERR "Using a channel type which is configured out of "
41 "UML\n"); 49 "UML\n");
42} 50}
43 51
44static int not_configged_read(int fd, char *c_out, void *data) 52static int not_configged_read(int fd, char *c_out, void *data)
45{ 53{
46 printf(KERN_ERR "Using a channel type which is configured out of " 54 printk(KERN_ERR "Using a channel type which is configured out of "
47 "UML\n"); 55 "UML\n");
48 return(-EIO); 56 return(-EIO);
49} 57}
50 58
51static int not_configged_write(int fd, const char *buf, int len, void *data) 59static int not_configged_write(int fd, const char *buf, int len, void *data)
52{ 60{
53 printf(KERN_ERR "Using a channel type which is configured out of " 61 printk(KERN_ERR "Using a channel type which is configured out of "
54 "UML\n"); 62 "UML\n");
55 return(-EIO); 63 return(-EIO);
56} 64}
@@ -58,7 +66,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data)
58static int not_configged_console_write(int fd, const char *buf, int len, 66static int not_configged_console_write(int fd, const char *buf, int len,
59 void *data) 67 void *data)
60{ 68{
61 printf(KERN_ERR "Using a channel type which is configured out of " 69 printk(KERN_ERR "Using a channel type which is configured out of "
62 "UML\n"); 70 "UML\n");
63 return(-EIO); 71 return(-EIO);
64} 72}
@@ -66,7 +74,7 @@ static int not_configged_console_write(int fd, const char *buf, int len,
66static int not_configged_window_size(int fd, void *data, unsigned short *rows, 74static int not_configged_window_size(int fd, void *data, unsigned short *rows,
67 unsigned short *cols) 75 unsigned short *cols)
68{ 76{
69 printf(KERN_ERR "Using a channel type which is configured out of " 77 printk(KERN_ERR "Using a channel type which is configured out of "
70 "UML\n"); 78 "UML\n");
71 return(-ENODEV); 79 return(-ENODEV);
72} 80}
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 583b8e137c33..5d3768156c92 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -143,22 +143,22 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out)
143{ 143{
144 struct winch_data data; 144 struct winch_data data;
145 unsigned long stack; 145 unsigned long stack;
146 int fds[2], pid, n, err; 146 int fds[2], n, err;
147 char c; 147 char c;
148 148
149 err = os_pipe(fds, 1, 1); 149 err = os_pipe(fds, 1, 1);
150 if(err < 0){ 150 if(err < 0){
151 printk("winch_tramp : os_pipe failed, err = %d\n", -err); 151 printk("winch_tramp : os_pipe failed, err = %d\n", -err);
152 return(err); 152 goto out;
153 } 153 }
154 154
155 data = ((struct winch_data) { .pty_fd = fd, 155 data = ((struct winch_data) { .pty_fd = fd,
156 .pipe_fd = fds[1], 156 .pipe_fd = fds[1],
157 .close_me = fds[0] } ); 157 .close_me = fds[0] } );
158 pid = run_helper_thread(winch_thread, &data, 0, &stack, 0); 158 err = run_helper_thread(winch_thread, &data, 0, &stack, 0);
159 if(pid < 0){ 159 if(err < 0){
160 printk("fork of winch_thread failed - errno = %d\n", errno); 160 printk("fork of winch_thread failed - errno = %d\n", errno);
161 return(pid); 161 goto out_close;
162 } 162 }
163 163
164 os_close_file(fds[1]); 164 os_close_file(fds[1]);
@@ -168,14 +168,22 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out)
168 printk("winch_tramp : failed to read synchronization byte\n"); 168 printk("winch_tramp : failed to read synchronization byte\n");
169 printk("read failed, err = %d\n", -n); 169 printk("read failed, err = %d\n", -n);
170 printk("fd %d will not support SIGWINCH\n", fd); 170 printk("fd %d will not support SIGWINCH\n", fd);
171 *fd_out = -1; 171 err = -EINVAL;
172 goto out_close1;
172 } 173 }
173 return(pid); 174 return err ;
175
176 out_close:
177 os_close_file(fds[1]);
178 out_close1:
179 os_close_file(fds[0]);
180 out:
181 return err;
174} 182}
175 183
176void register_winch(int fd, struct tty_struct *tty) 184void register_winch(int fd, struct tty_struct *tty)
177{ 185{
178 int pid, thread, thread_fd; 186 int pid, thread, thread_fd = -1;
179 int count; 187 int count;
180 char c = 1; 188 char c = 1;
181 189
@@ -186,7 +194,7 @@ void register_winch(int fd, struct tty_struct *tty)
186 if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, 194 if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd,
187 tty) && (pid == -1)){ 195 tty) && (pid == -1)){
188 thread = winch_tramp(fd, tty, &thread_fd); 196 thread = winch_tramp(fd, tty, &thread_fd);
189 if(fd != -1){ 197 if(thread > 0){
190 register_winch_irq(thread_fd, fd, thread, tty); 198 register_winch_irq(thread_fd, fd, thread, tty);
191 199
192 count = os_write_file(thread_fd, &c, sizeof(c)); 200 count = os_write_file(thread_fd, &c, sizeof(c));
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index d0f97127adf6..025d3be8aca4 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -462,12 +462,15 @@ out:
462 return err; 462 return err;
463} 463}
464 464
465static void unregister_winch(struct tty_struct *tty);
466
465void line_close(struct tty_struct *tty, struct file * filp) 467void line_close(struct tty_struct *tty, struct file * filp)
466{ 468{
467 struct line *line = tty->driver_data; 469 struct line *line = tty->driver_data;
468 470
469 /* XXX: I assume this should be called in process context, not with interrupt 471 /* XXX: I assume this should be called in process context, not with
470 * disabled!*/ 472 * interrupts disabled!
473 */
471 spin_lock_irq(&line->lock); 474 spin_lock_irq(&line->lock);
472 475
473 /* We ignore the error anyway! */ 476 /* We ignore the error anyway! */
@@ -478,6 +481,12 @@ void line_close(struct tty_struct *tty, struct file * filp)
478 line_disable(tty, -1); 481 line_disable(tty, -1);
479 tty->driver_data = NULL; 482 tty->driver_data = NULL;
480 } 483 }
484
485 if((line->count == 0) && line->sigio){
486 unregister_winch(tty);
487 line->sigio = 0;
488 }
489
481 spin_unlock_irq(&line->lock); 490 spin_unlock_irq(&line->lock);
482} 491}
483 492
@@ -729,6 +738,34 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty)
729 up(&winch_handler_sem); 738 up(&winch_handler_sem);
730} 739}
731 740
741static void unregister_winch(struct tty_struct *tty)
742{
743 struct list_head *ele;
744 struct winch *winch, *found = NULL;
745
746 down(&winch_handler_sem);
747 list_for_each(ele, &winch_handlers){
748 winch = list_entry(ele, struct winch, list);
749 if(winch->tty == tty){
750 found = winch;
751 break;
752 }
753 }
754
755 if(found == NULL)
756 goto out;
757
758 if(winch->pid != -1)
759 os_kill_process(winch->pid, 1);
760
761 free_irq_by_irq_and_dev(WINCH_IRQ, winch);
762 free_irq(WINCH_IRQ, winch);
763 list_del(&winch->list);
764 kfree(winch);
765 out:
766 up(&winch_handler_sem);
767}
768
732static void winch_cleanup(void) 769static void winch_cleanup(void)
733{ 770{
734 struct list_head *ele; 771 struct list_head *ele;
diff --git a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c
index faf714e87b5b..217438cdef33 100644
--- a/arch/um/drivers/mcast_kern.c
+++ b/arch/um/drivers/mcast_kern.c
@@ -73,7 +73,6 @@ int mcast_setup(char *str, char **mac_out, void *data)
73 struct mcast_init *init = data; 73 struct mcast_init *init = data;
74 char *port_str = NULL, *ttl_str = NULL, *remain; 74 char *port_str = NULL, *ttl_str = NULL, *remain;
75 char *last; 75 char *last;
76 int n;
77 76
78 *init = ((struct mcast_init) 77 *init = ((struct mcast_init)
79 { .addr = "239.192.168.1", 78 { .addr = "239.192.168.1",
@@ -89,13 +88,12 @@ int mcast_setup(char *str, char **mac_out, void *data)
89 } 88 }
90 89
91 if(port_str != NULL){ 90 if(port_str != NULL){
92 n = simple_strtoul(port_str, &last, 10); 91 init->port = simple_strtoul(port_str, &last, 10);
93 if((*last != '\0') || (last == port_str)){ 92 if((*last != '\0') || (last == port_str)){
94 printk(KERN_ERR "mcast_setup - Bad port : '%s'\n", 93 printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
95 port_str); 94 port_str);
96 return(0); 95 return(0);
97 } 96 }
98 init->port = htons(n);
99 } 97 }
100 98
101 if(ttl_str != NULL){ 99 if(ttl_str != NULL){
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
index 0fe1d9fa9139..7a0d115b29d0 100644
--- a/arch/um/drivers/mcast_user.c
+++ b/arch/um/drivers/mcast_user.c
@@ -38,7 +38,7 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port)
38 } 38 }
39 sin->sin_family = AF_INET; 39 sin->sin_family = AF_INET;
40 sin->sin_addr.s_addr = in_aton(addr); 40 sin->sin_addr.s_addr = in_aton(addr);
41 sin->sin_port = port; 41 sin->sin_port = htons(port);
42 return(sin); 42 return(sin);
43} 43}
44 44
@@ -55,28 +55,25 @@ static int mcast_open(void *data)
55 struct mcast_data *pri = data; 55 struct mcast_data *pri = data;
56 struct sockaddr_in *sin = pri->mcast_addr; 56 struct sockaddr_in *sin = pri->mcast_addr;
57 struct ip_mreq mreq; 57 struct ip_mreq mreq;
58 int fd, yes = 1; 58 int fd = -EINVAL, yes = 1, err = -EINVAL;;
59 59
60 60
61 if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) { 61 if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0))
62 fd = -EINVAL;
63 goto out; 62 goto out;
64 }
65 63
66 fd = socket(AF_INET, SOCK_DGRAM, 0); 64 fd = socket(AF_INET, SOCK_DGRAM, 0);
65
67 if (fd < 0){ 66 if (fd < 0){
68 printk("mcast_open : data socket failed, errno = %d\n", 67 printk("mcast_open : data socket failed, errno = %d\n",
69 errno); 68 errno);
70 fd = -ENOMEM; 69 fd = -errno;
71 goto out; 70 goto out;
72 } 71 }
73 72
74 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) { 73 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
75 printk("mcast_open: SO_REUSEADDR failed, errno = %d\n", 74 printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
76 errno); 75 errno);
77 os_close_file(fd); 76 goto out_close;
78 fd = -EINVAL;
79 goto out;
80 } 77 }
81 78
82 /* set ttl according to config */ 79 /* set ttl according to config */
@@ -84,26 +81,20 @@ static int mcast_open(void *data)
84 sizeof(pri->ttl)) < 0) { 81 sizeof(pri->ttl)) < 0) {
85 printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n", 82 printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
86 errno); 83 errno);
87 os_close_file(fd); 84 goto out_close;
88 fd = -EINVAL;
89 goto out;
90 } 85 }
91 86
92 /* set LOOP, so data does get fed back to local sockets */ 87 /* set LOOP, so data does get fed back to local sockets */
93 if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) { 88 if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
94 printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n", 89 printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
95 errno); 90 errno);
96 os_close_file(fd); 91 goto out_close;
97 fd = -EINVAL;
98 goto out;
99 } 92 }
100 93
101 /* bind socket to mcast address */ 94 /* bind socket to mcast address */
102 if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) { 95 if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
103 printk("mcast_open : data bind failed, errno = %d\n", errno); 96 printk("mcast_open : data bind failed, errno = %d\n", errno);
104 os_close_file(fd); 97 goto out_close;
105 fd = -EINVAL;
106 goto out;
107 } 98 }
108 99
109 /* subscribe to the multicast group */ 100 /* subscribe to the multicast group */
@@ -117,12 +108,15 @@ static int mcast_open(void *data)
117 "interface on the host.\n"); 108 "interface on the host.\n");
118 printk("eth0 should be configured in order to use the " 109 printk("eth0 should be configured in order to use the "
119 "multicast transport.\n"); 110 "multicast transport.\n");
120 os_close_file(fd); 111 goto out_close;
121 fd = -EINVAL;
122 } 112 }
123 113
124 out: 114 out:
125 return(fd); 115 return fd;
116
117 out_close:
118 os_close_file(fd);
119 return err;
126} 120}
127 121
128static void mcast_close(int fd, void *data) 122static void mcast_close(int fd, void *data)
@@ -164,14 +158,3 @@ struct net_user_info mcast_user_info = {
164 .delete_address = NULL, 158 .delete_address = NULL,
165 .max_packet = MAX_PACKET - ETH_HEADER_OTHER 159 .max_packet = MAX_PACKET - ETH_HEADER_OTHER
166}; 160};
167
168/*
169 * Overrides for Emacs so that we follow Linus's tabbing style.
170 * Emacs will notice this stuff at the end of the file and automatically
171 * adjust the settings for this buffer only. This must remain at the end
172 * of the file.
173 * ---------------------------------------------------------------------------
174 * Local variables:
175 * c-file-style: "linux"
176 * End:
177 */
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index a63231dffe05..a37a5ac13c22 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -18,6 +18,7 @@
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/smp_lock.h> 20#include <linux/smp_lock.h>
21#include <linux/miscdevice.h>
21#include <asm/uaccess.h> 22#include <asm/uaccess.h>
22#include <asm/irq.h> 23#include <asm/irq.h>
23#include <asm/pgtable.h> 24#include <asm/pgtable.h>
@@ -117,24 +118,39 @@ static struct file_operations mmapper_fops = {
117 .release = mmapper_release, 118 .release = mmapper_release,
118}; 119};
119 120
121static struct miscdevice mmapper_dev = {
122 .minor = MISC_DYNAMIC_MINOR,
123 .name = "mmapper",
124 .fops = &mmapper_fops
125};
126
120static int __init mmapper_init(void) 127static int __init mmapper_init(void)
121{ 128{
129 int err;
130
122 printk(KERN_INFO "Mapper v0.1\n"); 131 printk(KERN_INFO "Mapper v0.1\n");
123 132
124 v_buf = (char *) find_iomem("mmapper", &mmapper_size); 133 v_buf = (char *) find_iomem("mmapper", &mmapper_size);
125 if(mmapper_size == 0){ 134 if(mmapper_size == 0){
126 printk(KERN_ERR "mmapper_init - find_iomem failed\n"); 135 printk(KERN_ERR "mmapper_init - find_iomem failed\n");
127 return(0); 136 goto out;
128 } 137 }
129 138
130 p_buf = __pa(v_buf); 139 err = misc_register(&mmapper_dev);
140 if(err){
141 printk(KERN_ERR "mmapper - misc_register failed, err = %d\n",
142 err);
143 goto out;
144 }
131 145
132 devfs_mk_cdev(MKDEV(30, 0), S_IFCHR|S_IRUGO|S_IWUGO, "mmapper"); 146 p_buf = __pa(v_buf);
133 return(0); 147out:
148 return 0;
134} 149}
135 150
136static void mmapper_exit(void) 151static void mmapper_exit(void)
137{ 152{
153 misc_deregister(&mmapper_dev);
138} 154}
139 155
140module_init(mmapper_init); 156module_init(mmapper_init);
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 47229fe4a813..3730d4f12713 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -32,7 +32,7 @@ int tap_open_common(void *dev, char *gate_addr)
32 return(0); 32 return(0);
33} 33}
34 34
35void tap_check_ips(char *gate_addr, char *eth_addr) 35void tap_check_ips(char *gate_addr, unsigned char *eth_addr)
36{ 36{
37 int tap_addr[4]; 37 int tap_addr[4];
38 38
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index d43e9fab05a7..f9e22198e011 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -1,5 +1,10 @@
1/* Much of this ripped from hw_random.c */ 1/* Copyright (C) 2005 Jeff Dike <jdike@addtoit.com> */
2 2/* Much of this ripped from drivers/char/hw_random.c, see there for other
3 * copyright.
4 *
5 * This software may be used and distributed according to the terms
6 * of the GNU General Public License, incorporated herein by reference.
7 */
3#include <linux/module.h> 8#include <linux/module.h>
4#include <linux/fs.h> 9#include <linux/fs.h>
5#include <linux/miscdevice.h> 10#include <linux/miscdevice.h>
@@ -12,8 +17,6 @@
12 */ 17 */
13#define RNG_VERSION "1.0.0" 18#define RNG_VERSION "1.0.0"
14#define RNG_MODULE_NAME "random" 19#define RNG_MODULE_NAME "random"
15#define RNG_DRIVER_NAME RNG_MODULE_NAME " virtual driver " RNG_VERSION
16#define PFX RNG_MODULE_NAME ": "
17 20
18#define RNG_MISCDEV_MINOR 183 /* official */ 21#define RNG_MISCDEV_MINOR 183 /* official */
19 22
@@ -98,7 +101,7 @@ static int __init rng_init (void)
98 101
99 err = misc_register (&rng_miscdev); 102 err = misc_register (&rng_miscdev);
100 if (err) { 103 if (err) {
101 printk (KERN_ERR PFX "misc device register failed\n"); 104 printk (KERN_ERR RNG_MODULE_NAME ": misc device register failed\n");
102 goto err_out_cleanup_hw; 105 goto err_out_cleanup_hw;
103 } 106 }
104 107
@@ -120,3 +123,6 @@ static void __exit rng_cleanup (void)
120 123
121module_init (rng_init); 124module_init (rng_init);
122module_exit (rng_cleanup); 125module_exit (rng_cleanup);
126
127MODULE_DESCRIPTION("UML Host Random Number Generator (RNG) driver");
128MODULE_LICENSE("GPL");
diff --git a/arch/um/drivers/slip.h b/arch/um/drivers/slip.h
index 495f2f1b1420..bb0dab41c2e4 100644
--- a/arch/um/drivers/slip.h
+++ b/arch/um/drivers/slip.h
@@ -1,10 +1,7 @@
1#ifndef __UM_SLIP_H 1#ifndef __UM_SLIP_H
2#define __UM_SLIP_H 2#define __UM_SLIP_H
3 3
4#define BUF_SIZE 1500 4#include "slip_common.h"
5 /* two bytes each for a (pathological) max packet of escaped chars + *
6 * terminating END char + initial END char */
7#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
8 5
9struct slip_data { 6struct slip_data {
10 void *dev; 7 void *dev;
@@ -12,28 +9,12 @@ struct slip_data {
12 char *addr; 9 char *addr;
13 char *gate_addr; 10 char *gate_addr;
14 int slave; 11 int slave;
15 char ibuf[ENC_BUF_SIZE]; 12 struct slip_proto slip;
16 char obuf[ENC_BUF_SIZE];
17 int more; /* more data: do not read fd until ibuf has been drained */
18 int pos;
19 int esc;
20}; 13};
21 14
22extern struct net_user_info slip_user_info; 15extern struct net_user_info slip_user_info;
23 16
24extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
25extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri); 17extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri);
26extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri); 18extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri);
27 19
28#endif 20#endif
29
30/*
31 * Overrides for Emacs so that we follow Linus's tabbing style.
32 * Emacs will notice this stuff at the end of the file and automatically
33 * adjust the settings for this buffer only. This must remain at the end
34 * of the file.
35 * ---------------------------------------------------------------------------
36 * Local variables:
37 * c-file-style: "linux"
38 * End:
39 */
diff --git a/arch/um/drivers/slip_common.c b/arch/um/drivers/slip_common.c
new file mode 100644
index 000000000000..e89cfc68fc3e
--- /dev/null
+++ b/arch/um/drivers/slip_common.c
@@ -0,0 +1,54 @@
1#include <string.h>
2#include "slip_common.h"
3#include "net_user.h"
4
5int slip_proto_read(int fd, void *buf, int len, struct slip_proto *slip)
6{
7 int i, n, size, start;
8
9 if(slip->more > 0){
10 i = 0;
11 while(i < slip->more){
12 size = slip_unesc(slip->ibuf[i++], slip->ibuf,
13 &slip->pos, &slip->esc);
14 if(size){
15 memcpy(buf, slip->ibuf, size);
16 memmove(slip->ibuf, &slip->ibuf[i],
17 slip->more - i);
18 slip->more = slip->more - i;
19 return size;
20 }
21 }
22 slip->more = 0;
23 }
24
25 n = net_read(fd, &slip->ibuf[slip->pos],
26 sizeof(slip->ibuf) - slip->pos);
27 if(n <= 0)
28 return n;
29
30 start = slip->pos;
31 for(i = 0; i < n; i++){
32 size = slip_unesc(slip->ibuf[start + i], slip->ibuf,&slip->pos,
33 &slip->esc);
34 if(size){
35 memcpy(buf, slip->ibuf, size);
36 memmove(slip->ibuf, &slip->ibuf[start+i+1],
37 n - (i + 1));
38 slip->more = n - (i + 1);
39 return size;
40 }
41 }
42 return 0;
43}
44
45int slip_proto_write(int fd, void *buf, int len, struct slip_proto *slip)
46{
47 int actual, n;
48
49 actual = slip_esc(buf, slip->obuf, len);
50 n = net_write(fd, slip->obuf, actual);
51 if(n < 0)
52 return n;
53 else return len;
54}
diff --git a/arch/um/drivers/slip_proto.h b/arch/um/drivers/slip_common.h
index 7206361ace45..2ae76d8f1be1 100644
--- a/arch/um/drivers/slip_proto.h
+++ b/arch/um/drivers/slip_common.h
@@ -1,10 +1,10 @@
1/* 1#ifndef __UM_SLIP_COMMON_H
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2#define __UM_SLIP_COMMON_H
3 * Licensed under the GPL
4 */
5 3
6#ifndef __UM_SLIP_PROTO_H__ 4#define BUF_SIZE 1500
7#define __UM_SLIP_PROTO_H__ 5 /* two bytes each for a (pathological) max packet of escaped chars + *
6 * terminating END char + initial END char */
7#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
8 8
9/* SLIP protocol characters. */ 9/* SLIP protocol characters. */
10#define SLIP_END 0300 /* indicates end of frame */ 10#define SLIP_END 0300 /* indicates end of frame */
@@ -12,7 +12,8 @@
12#define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */ 12#define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */
13#define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */ 13#define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */
14 14
15static inline int slip_unesc(unsigned char c,char *buf,int *pos, int *esc) 15static inline int slip_unesc(unsigned char c, unsigned char *buf, int *pos,
16 int *esc)
16{ 17{
17 int ret; 18 int ret;
18 19
@@ -79,15 +80,25 @@ static inline int slip_esc(unsigned char *s, unsigned char *d, int len)
79 return (ptr - d); 80 return (ptr - d);
80} 81}
81 82
82#endif 83struct slip_proto {
84 unsigned char ibuf[ENC_BUF_SIZE];
85 unsigned char obuf[ENC_BUF_SIZE];
86 int more; /* more data: do not read fd until ibuf has been drained */
87 int pos;
88 int esc;
89};
90
91#define SLIP_PROTO_INIT { \
92 .ibuf = { '\0' }, \
93 .obuf = { '\0' }, \
94 .more = 0, \
95 .pos = 0, \
96 .esc = 0 \
97}
83 98
84/* 99extern int slip_proto_read(int fd, void *buf, int len,
85 * Overrides for Emacs so that we follow Linus's tabbing style. 100 struct slip_proto *slip);
86 * Emacs will notice this stuff at the end of the file and automatically 101extern int slip_proto_write(int fd, void *buf, int len,
87 * adjust the settings for this buffer only. This must remain at the end 102 struct slip_proto *slip);
88 * of the file. 103
89 * --------------------------------------------------------------------------- 104#endif
90 * Local variables:
91 * c-file-style: "linux"
92 * End:
93 */
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
index 0886eedba213..9a6f5c85f902 100644
--- a/arch/um/drivers/slip_kern.c
+++ b/arch/um/drivers/slip_kern.c
@@ -26,16 +26,16 @@ void slip_init(struct net_device *dev, void *data)
26 .addr = NULL, 26 .addr = NULL,
27 .gate_addr = init->gate_addr, 27 .gate_addr = init->gate_addr,
28 .slave = -1, 28 .slave = -1,
29 .ibuf = { '\0' }, 29 .slip = SLIP_PROTO_INIT,
30 .obuf = { '\0' },
31 .pos = 0,
32 .esc = 0,
33 .dev = dev }); 30 .dev = dev });
34 31
35 dev->init = NULL; 32 dev->init = NULL;
33 dev->header_cache_update = NULL;
34 dev->hard_header_cache = NULL;
35 dev->hard_header = NULL;
36 dev->hard_header_len = 0; 36 dev->hard_header_len = 0;
37 dev->addr_len = 4; 37 dev->addr_len = 0;
38 dev->type = ARPHRD_ETHER; 38 dev->type = ARPHRD_SLIP;
39 dev->tx_queue_len = 256; 39 dev->tx_queue_len = 256;
40 dev->flags = IFF_NOARP; 40 dev->flags = IFF_NOARP;
41 printk("SLIP backend - SLIP IP = %s\n", spri->gate_addr); 41 printk("SLIP backend - SLIP IP = %s\n", spri->gate_addr);
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index d94846b1b4cf..71af444e591f 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -13,7 +13,7 @@
13#include "user.h" 13#include "user.h"
14#include "net_user.h" 14#include "net_user.h"
15#include "slip.h" 15#include "slip.h"
16#include "slip_proto.h" 16#include "slip_common.h"
17#include "helper.h" 17#include "helper.h"
18#include "os.h" 18#include "os.h"
19 19
@@ -77,41 +77,51 @@ static int slip_tramp(char **argv, int fd)
77 err = os_pipe(fds, 1, 0); 77 err = os_pipe(fds, 1, 0);
78 if(err < 0){ 78 if(err < 0){
79 printk("slip_tramp : pipe failed, err = %d\n", -err); 79 printk("slip_tramp : pipe failed, err = %d\n", -err);
80 return(err); 80 goto out;
81 } 81 }
82 82
83 err = 0; 83 err = 0;
84 pe_data.stdin = fd; 84 pe_data.stdin = fd;
85 pe_data.stdout = fds[1]; 85 pe_data.stdout = fds[1];
86 pe_data.close_me = fds[0]; 86 pe_data.close_me = fds[0];
87 pid = run_helper(slip_pre_exec, &pe_data, argv, NULL); 87 err = run_helper(slip_pre_exec, &pe_data, argv, NULL);
88 if(err < 0)
89 goto out_close;
90 pid = err;
91
92 output_len = page_size();
93 output = um_kmalloc(output_len);
94 if(output == NULL){
95 printk("slip_tramp : failed to allocate output buffer\n");
96 os_kill_process(pid, 1);
97 err = -ENOMEM;
98 goto out_free;
99 }
88 100
89 if(pid < 0) err = pid; 101 os_close_file(fds[1]);
90 else { 102 read_output(fds[0], output, output_len);
91 output_len = page_size(); 103 printk("%s", output);
92 output = um_kmalloc(output_len); 104
93 if(output == NULL) 105 CATCH_EINTR(err = waitpid(pid, &status, 0));
94 printk("slip_tramp : failed to allocate output " 106 if(err < 0)
95 "buffer\n"); 107 err = errno;
96 108 else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
97 os_close_file(fds[1]); 109 printk("'%s' didn't exit with status 0\n", argv[0]);
98 read_output(fds[0], output, output_len); 110 err = -EINVAL;
99 if(output != NULL){
100 printk("%s", output);
101 kfree(output);
102 }
103 CATCH_EINTR(err = waitpid(pid, &status, 0));
104 if(err < 0)
105 err = errno;
106 else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
107 printk("'%s' didn't exit with status 0\n", argv[0]);
108 err = -EINVAL;
109 }
110 } 111 }
112 else err = 0;
111 113
112 os_close_file(fds[0]); 114 os_close_file(fds[0]);
113 115
114 return(err); 116out_free:
117 kfree(output);
118 return err;
119
120out_close:
121 os_close_file(fds[0]);
122 os_close_file(fds[1]);
123out:
124 return err;
115} 125}
116 126
117static int slip_open(void *data) 127static int slip_open(void *data)
@@ -123,21 +133,26 @@ static int slip_open(void *data)
123 NULL }; 133 NULL };
124 int sfd, mfd, err; 134 int sfd, mfd, err;
125 135
126 mfd = get_pty(); 136 err = get_pty();
127 if(mfd < 0){ 137 if(err < 0){
128 printk("umn : Failed to open pty, err = %d\n", -mfd); 138 printk("slip-open : Failed to open pty, err = %d\n", -err);
129 return(mfd); 139 goto out;
130 } 140 }
131 sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0); 141 mfd = err;
132 if(sfd < 0){ 142
133 printk("Couldn't open tty for slip line, err = %d\n", -sfd); 143 err = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
134 os_close_file(mfd); 144 if(err < 0){
135 return(sfd); 145 printk("Couldn't open tty for slip line, err = %d\n", -err);
146 goto out_close;
136 } 147 }
137 if(set_up_tty(sfd)) return(-1); 148 sfd = err;
149
150 if(set_up_tty(sfd))
151 goto out_close2;
152
138 pri->slave = sfd; 153 pri->slave = sfd;
139 pri->pos = 0; 154 pri->slip.pos = 0;
140 pri->esc = 0; 155 pri->slip.esc = 0;
141 if(pri->gate_addr != NULL){ 156 if(pri->gate_addr != NULL){
142 sprintf(version_buf, "%d", UML_NET_VERSION); 157 sprintf(version_buf, "%d", UML_NET_VERSION);
143 strcpy(gate_buf, pri->gate_addr); 158 strcpy(gate_buf, pri->gate_addr);
@@ -146,12 +161,12 @@ static int slip_open(void *data)
146 161
147 if(err < 0){ 162 if(err < 0){
148 printk("slip_tramp failed - err = %d\n", -err); 163 printk("slip_tramp failed - err = %d\n", -err);
149 return(err); 164 goto out_close2;
150 } 165 }
151 err = os_get_ifname(pri->slave, pri->name); 166 err = os_get_ifname(pri->slave, pri->name);
152 if(err < 0){ 167 if(err < 0){
153 printk("get_ifname failed, err = %d\n", -err); 168 printk("get_ifname failed, err = %d\n", -err);
154 return(err); 169 goto out_close2;
155 } 170 }
156 iter_addresses(pri->dev, open_addr, pri->name); 171 iter_addresses(pri->dev, open_addr, pri->name);
157 } 172 }
@@ -160,10 +175,16 @@ static int slip_open(void *data)
160 if(err < 0){ 175 if(err < 0){
161 printk("Failed to set slip discipline encapsulation - " 176 printk("Failed to set slip discipline encapsulation - "
162 "err = %d\n", -err); 177 "err = %d\n", -err);
163 return(err); 178 goto out_close2;
164 } 179 }
165 } 180 }
166 return(mfd); 181 return(mfd);
182out_close2:
183 os_close_file(sfd);
184out_close:
185 os_close_file(mfd);
186out:
187 return err;
167} 188}
168 189
169static void slip_close(int fd, void *data) 190static void slip_close(int fd, void *data)
@@ -190,48 +211,12 @@ static void slip_close(int fd, void *data)
190 211
191int slip_user_read(int fd, void *buf, int len, struct slip_data *pri) 212int slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
192{ 213{
193 int i, n, size, start; 214 return slip_proto_read(fd, buf, len, &pri->slip);
194
195 if(pri->more>0) {
196 i = 0;
197 while(i < pri->more) {
198 size = slip_unesc(pri->ibuf[i++],
199 pri->ibuf, &pri->pos, &pri->esc);
200 if(size){
201 memcpy(buf, pri->ibuf, size);
202 memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
203 pri->more=pri->more-i;
204 return(size);
205 }
206 }
207 pri->more=0;
208 }
209
210 n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
211 if(n <= 0) return(n);
212
213 start = pri->pos;
214 for(i = 0; i < n; i++){
215 size = slip_unesc(pri->ibuf[start + i],
216 pri->ibuf, &pri->pos, &pri->esc);
217 if(size){
218 memcpy(buf, pri->ibuf, size);
219 memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
220 pri->more=n-(i+1);
221 return(size);
222 }
223 }
224 return(0);
225} 215}
226 216
227int slip_user_write(int fd, void *buf, int len, struct slip_data *pri) 217int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
228{ 218{
229 int actual, n; 219 return slip_proto_write(fd, buf, len, &pri->slip);
230
231 actual = slip_esc(buf, pri->obuf, len);
232 n = net_write(fd, pri->obuf, actual);
233 if(n < 0) return(n);
234 else return(len);
235} 220}
236 221
237static int slip_set_mtu(int mtu, void *data) 222static int slip_set_mtu(int mtu, void *data)
@@ -267,14 +252,3 @@ struct net_user_info slip_user_info = {
267 .delete_address = slip_del_addr, 252 .delete_address = slip_del_addr,
268 .max_packet = BUF_SIZE 253 .max_packet = BUF_SIZE
269}; 254};
270
271/*
272 * Overrides for Emacs so that we follow Linus's tabbing style.
273 * Emacs will notice this stuff at the end of the file and automatically
274 * adjust the settings for this buffer only. This must remain at the end
275 * of the file.
276 * ---------------------------------------------------------------------------
277 * Local variables:
278 * c-file-style: "linux"
279 * End:
280 */
diff --git a/arch/um/drivers/slirp.h b/arch/um/drivers/slirp.h
index 04e407d1e44a..6cf88ab580c9 100644
--- a/arch/um/drivers/slirp.h
+++ b/arch/um/drivers/slirp.h
@@ -1,10 +1,7 @@
1#ifndef __UM_SLIRP_H 1#ifndef __UM_SLIRP_H
2#define __UM_SLIRP_H 2#define __UM_SLIRP_H
3 3
4#define BUF_SIZE 1500 4#include "slip_common.h"
5 /* two bytes each for a (pathological) max packet of escaped chars + *
6 * terminating END char + initial END char */
7#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
8 5
9#define SLIRP_MAX_ARGS 100 6#define SLIRP_MAX_ARGS 100
10/* 7/*
@@ -24,28 +21,13 @@ struct slirp_data {
24 struct arg_list_dummy_wrapper argw; 21 struct arg_list_dummy_wrapper argw;
25 int pid; 22 int pid;
26 int slave; 23 int slave;
27 char ibuf[ENC_BUF_SIZE]; 24 struct slip_proto slip;
28 char obuf[ENC_BUF_SIZE];
29 int more; /* more data: do not read fd until ibuf has been drained */
30 int pos;
31 int esc;
32}; 25};
33 26
34extern struct net_user_info slirp_user_info; 27extern struct net_user_info slirp_user_info;
35 28
36extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
37extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri); 29extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri);
38extern int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri); 30extern int slirp_user_write(int fd, void *buf, int len,
31 struct slirp_data *pri);
39 32
40#endif 33#endif
41
42/*
43 * Overrides for Emacs so that we follow Linus's tabbing style.
44 * Emacs will notice this stuff at the end of the file and automatically
45 * adjust the settings for this buffer only. This must remain at the end
46 * of the file.
47 * ---------------------------------------------------------------------------
48 * Local variables:
49 * c-file-style: "linux"
50 * End:
51 */
diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c
index c9d6b52a831d..9864d27afdbe 100644
--- a/arch/um/drivers/slirp_kern.c
+++ b/arch/um/drivers/slirp_kern.c
@@ -25,10 +25,7 @@ void slirp_init(struct net_device *dev, void *data)
25 { .argw = init->argw, 25 { .argw = init->argw,
26 .pid = -1, 26 .pid = -1,
27 .slave = -1, 27 .slave = -1,
28 .ibuf = { '\0' }, 28 .slip = SLIP_PROTO_INIT,
29 .obuf = { '\0' },
30 .pos = 0,
31 .esc = 0,
32 .dev = dev }); 29 .dev = dev });
33 30
34 dev->init = NULL; 31 dev->init = NULL;
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index c322515c71cc..8d91f663d82c 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -12,7 +12,7 @@
12#include "user.h" 12#include "user.h"
13#include "net_user.h" 13#include "net_user.h"
14#include "slirp.h" 14#include "slirp.h"
15#include "slip_proto.h" 15#include "slip_common.h"
16#include "helper.h" 16#include "helper.h"
17#include "os.h" 17#include "os.h"
18 18
@@ -48,47 +48,32 @@ static int slirp_tramp(char **argv, int fd)
48 return(pid); 48 return(pid);
49} 49}
50 50
51/* XXX This is just a trivial wrapper around os_pipe */
52static int slirp_datachan(int *mfd, int *sfd)
53{
54 int fds[2], err;
55
56 err = os_pipe(fds, 1, 1);
57 if(err < 0){
58 printk("slirp_datachan: Failed to open pipe, err = %d\n", -err);
59 return(err);
60 }
61
62 *mfd = fds[0];
63 *sfd = fds[1];
64 return(0);
65}
66
67static int slirp_open(void *data) 51static int slirp_open(void *data)
68{ 52{
69 struct slirp_data *pri = data; 53 struct slirp_data *pri = data;
70 int sfd, mfd, pid, err; 54 int fds[2], pid, err;
71 55
72 err = slirp_datachan(&mfd, &sfd); 56 err = os_pipe(fds, 1, 1);
73 if(err) 57 if(err)
74 return(err); 58 return(err);
75 59
76 pid = slirp_tramp(pri->argw.argv, sfd); 60 err = slirp_tramp(pri->argw.argv, fds[1]);
77 61 if(err < 0){
78 if(pid < 0){ 62 printk("slirp_tramp failed - errno = %d\n", -err);
79 printk("slirp_tramp failed - errno = %d\n", -pid); 63 goto out;
80 os_close_file(sfd);
81 os_close_file(mfd);
82 return(pid);
83 } 64 }
84 65 pid = err;
85 pri->slave = sfd; 66
86 pri->pos = 0; 67 pri->slave = fds[1];
87 pri->esc = 0; 68 pri->slip.pos = 0;
88 69 pri->slip.esc = 0;
89 pri->pid = pid; 70 pri->pid = err;
90 71
91 return(mfd); 72 return(fds[0]);
73out:
74 os_close_file(fds[0]);
75 os_close_file(fds[1]);
76 return err;
92} 77}
93 78
94static void slirp_close(int fd, void *data) 79static void slirp_close(int fd, void *data)
@@ -129,48 +114,12 @@ static void slirp_close(int fd, void *data)
129 114
130int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri) 115int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri)
131{ 116{
132 int i, n, size, start; 117 return slip_proto_read(fd, buf, len, &pri->slip);
133
134 if(pri->more>0) {
135 i = 0;
136 while(i < pri->more) {
137 size = slip_unesc(pri->ibuf[i++],
138 pri->ibuf,&pri->pos,&pri->esc);
139 if(size){
140 memcpy(buf, pri->ibuf, size);
141 memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
142 pri->more=pri->more-i;
143 return(size);
144 }
145 }
146 pri->more=0;
147 }
148
149 n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
150 if(n <= 0) return(n);
151
152 start = pri->pos;
153 for(i = 0; i < n; i++){
154 size = slip_unesc(pri->ibuf[start + i],
155 pri->ibuf,&pri->pos,&pri->esc);
156 if(size){
157 memcpy(buf, pri->ibuf, size);
158 memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
159 pri->more=n-(i+1);
160 return(size);
161 }
162 }
163 return(0);
164} 118}
165 119
166int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri) 120int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri)
167{ 121{
168 int actual, n; 122 return slip_proto_write(fd, buf, len, &pri->slip);
169
170 actual = slip_esc(buf, pri->obuf, len);
171 n = net_write(fd, pri->obuf, actual);
172 if(n < 0) return(n);
173 else return(len);
174} 123}
175 124
176static int slirp_set_mtu(int mtu, void *data) 125static int slirp_set_mtu(int mtu, void *data)
@@ -188,14 +137,3 @@ struct net_user_info slirp_user_info = {
188 .delete_address = NULL, 137 .delete_address = NULL,
189 .max_packet = BUF_SIZE 138 .max_packet = BUF_SIZE
190}; 139};
191
192/*
193 * Overrides for Emacs so that we follow Linus's tabbing style.
194 * Emacs will notice this stuff at the end of the file and automatically
195 * adjust the settings for this buffer only. This must remain at the end
196 * of the file.
197 * ---------------------------------------------------------------------------
198 * Local variables:
199 * c-file-style: "linux"
200 * End:
201 */
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index a2bac429f3d4..b32a77010fbe 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -22,7 +22,6 @@
22#include "init.h" 22#include "init.h"
23#include "irq_user.h" 23#include "irq_user.h"
24#include "mconsole_kern.h" 24#include "mconsole_kern.h"
25#include "2_5compat.h"
26 25
27static int ssl_version = 1; 26static int ssl_version = 1;
28 27
diff --git a/arch/um/drivers/stderr_console.c b/arch/um/drivers/stderr_console.c
index 98565b53d170..429ae8e6c7e5 100644
--- a/arch/um/drivers/stderr_console.c
+++ b/arch/um/drivers/stderr_console.c
@@ -22,9 +22,9 @@ static void stderr_console_write(struct console *console, const char *string,
22} 22}
23 23
24static struct console stderr_console = { 24static struct console stderr_console = {
25 .name "stderr", 25 .name = "stderr",
26 .write stderr_console_write, 26 .write = stderr_console_write,
27 .flags CON_PRINTBUFFER, 27 .flags = CON_PRINTBUFFER,
28}; 28};
29 29
30static int __init stderr_console_init(void) 30static int __init stderr_console_init(void)
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 361d0be342b3..afbe1e71ed83 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -28,7 +28,6 @@
28#include "irq_user.h" 28#include "irq_user.h"
29#include "mconsole_kern.h" 29#include "mconsole_kern.h"
30#include "init.h" 30#include "init.h"
31#include "2_5compat.h"
32 31
33#define MAX_TTYS (16) 32#define MAX_TTYS (16)
34 33
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 9a56ff94308d..2a7f6892c55c 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -49,13 +49,12 @@
49#include "irq_user.h" 49#include "irq_user.h"
50#include "irq_kern.h" 50#include "irq_kern.h"
51#include "ubd_user.h" 51#include "ubd_user.h"
52#include "2_5compat.h"
53#include "os.h" 52#include "os.h"
54#include "mem.h" 53#include "mem.h"
55#include "mem_kern.h" 54#include "mem_kern.h"
56#include "cow.h" 55#include "cow.h"
57 56
58enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP }; 57enum ubd_req { UBD_READ, UBD_WRITE };
59 58
60struct io_thread_req { 59struct io_thread_req {
61 enum ubd_req op; 60 enum ubd_req op;
@@ -68,8 +67,6 @@ struct io_thread_req {
68 unsigned long sector_mask; 67 unsigned long sector_mask;
69 unsigned long long cow_offset; 68 unsigned long long cow_offset;
70 unsigned long bitmap_words[2]; 69 unsigned long bitmap_words[2];
71 int map_fd;
72 unsigned long long map_offset;
73 int error; 70 int error;
74}; 71};
75 72
@@ -122,10 +119,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
122 119
123#define MAX_DEV (8) 120#define MAX_DEV (8)
124 121
125/* Changed in early boot */
126static int ubd_do_mmap = 0;
127#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE
128
129static struct block_device_operations ubd_blops = { 122static struct block_device_operations ubd_blops = {
130 .owner = THIS_MODULE, 123 .owner = THIS_MODULE,
131 .open = ubd_open, 124 .open = ubd_open,
@@ -175,12 +168,6 @@ struct ubd {
175 int no_cow; 168 int no_cow;
176 struct cow cow; 169 struct cow cow;
177 struct platform_device pdev; 170 struct platform_device pdev;
178
179 int map_writes;
180 int map_reads;
181 int nomap_writes;
182 int nomap_reads;
183 int write_maps;
184}; 171};
185 172
186#define DEFAULT_COW { \ 173#define DEFAULT_COW { \
@@ -200,11 +187,6 @@ struct ubd {
200 .openflags = OPEN_FLAGS, \ 187 .openflags = OPEN_FLAGS, \
201 .no_cow = 0, \ 188 .no_cow = 0, \
202 .cow = DEFAULT_COW, \ 189 .cow = DEFAULT_COW, \
203 .map_writes = 0, \
204 .map_reads = 0, \
205 .nomap_writes = 0, \
206 .nomap_reads = 0, \
207 .write_maps = 0, \
208} 190}
209 191
210struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD }; 192struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
@@ -314,13 +296,6 @@ static int ubd_setup_common(char *str, int *index_out)
314 int major; 296 int major;
315 297
316 str++; 298 str++;
317 if(!strcmp(str, "mmap")){
318 CHOOSE_MODE(printk("mmap not supported by the ubd "
319 "driver in tt mode\n"),
320 ubd_do_mmap = 1);
321 return(0);
322 }
323
324 if(!strcmp(str, "sync")){ 299 if(!strcmp(str, "sync")){
325 global_openflags = of_sync(global_openflags); 300 global_openflags = of_sync(global_openflags);
326 return(0); 301 return(0);
@@ -464,9 +439,9 @@ static int udb_setup(char *str)
464__setup("udb", udb_setup); 439__setup("udb", udb_setup);
465__uml_help(udb_setup, 440__uml_help(udb_setup,
466"udb\n" 441"udb\n"
467" This option is here solely to catch ubd -> udb typos, which can be\n\n" 442" This option is here solely to catch ubd -> udb typos, which can be\n"
468" to impossible to catch visually unless you specifically look for\n\n" 443" to impossible to catch visually unless you specifically look for\n"
469" them. The only result of any option starting with 'udb' is an error\n\n" 444" them. The only result of any option starting with 'udb' is an error\n"
470" in the boot output.\n\n" 445" in the boot output.\n\n"
471); 446);
472 447
@@ -524,7 +499,7 @@ static void ubd_handler(void)
524{ 499{
525 struct io_thread_req req; 500 struct io_thread_req req;
526 struct request *rq = elv_next_request(ubd_queue); 501 struct request *rq = elv_next_request(ubd_queue);
527 int n, err; 502 int n;
528 503
529 do_ubd = NULL; 504 do_ubd = NULL;
530 intr_count++; 505 intr_count++;
@@ -538,19 +513,6 @@ static void ubd_handler(void)
538 return; 513 return;
539 } 514 }
540 515
541 if((req.op != UBD_MMAP) &&
542 ((req.offset != ((__u64) (rq->sector)) << 9) ||
543 (req.length != (rq->current_nr_sectors) << 9)))
544 panic("I/O op mismatch");
545
546 if(req.map_fd != -1){
547 err = physmem_subst_mapping(req.buffer, req.map_fd,
548 req.map_offset, 1);
549 if(err)
550 printk("ubd_handler - physmem_subst_mapping failed, "
551 "err = %d\n", -err);
552 }
553
554 ubd_finish(rq, req.error); 516 ubd_finish(rq, req.error);
555 reactivate_fd(thread_fd, UBD_IRQ); 517 reactivate_fd(thread_fd, UBD_IRQ);
556 do_ubd_request(ubd_queue); 518 do_ubd_request(ubd_queue);
@@ -583,14 +545,10 @@ static int ubd_file_size(struct ubd *dev, __u64 *size_out)
583 545
584static void ubd_close(struct ubd *dev) 546static void ubd_close(struct ubd *dev)
585{ 547{
586 if(ubd_do_mmap)
587 physmem_forget_descriptor(dev->fd);
588 os_close_file(dev->fd); 548 os_close_file(dev->fd);
589 if(dev->cow.file == NULL) 549 if(dev->cow.file == NULL)
590 return; 550 return;
591 551
592 if(ubd_do_mmap)
593 physmem_forget_descriptor(dev->cow.fd);
594 os_close_file(dev->cow.fd); 552 os_close_file(dev->cow.fd);
595 vfree(dev->cow.bitmap); 553 vfree(dev->cow.bitmap);
596 dev->cow.bitmap = NULL; 554 dev->cow.bitmap = NULL;
@@ -1010,94 +968,13 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
1010 req->bitmap_words, bitmap_len); 968 req->bitmap_words, bitmap_len);
1011} 969}
1012 970
1013static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset)
1014{
1015 __u64 sector;
1016 unsigned char *bitmap;
1017 int bit, i;
1018
1019 /* mmap must have been requested on the command line */
1020 if(!ubd_do_mmap)
1021 return(-1);
1022
1023 /* The buffer must be page aligned */
1024 if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0)
1025 return(-1);
1026
1027 /* The request must be a page long */
1028 if((req->current_nr_sectors << 9) != PAGE_SIZE)
1029 return(-1);
1030
1031 if(dev->cow.file == NULL)
1032 return(dev->fd);
1033
1034 sector = offset >> 9;
1035 bitmap = (unsigned char *) dev->cow.bitmap;
1036 bit = ubd_test_bit(sector, bitmap);
1037
1038 for(i = 1; i < req->current_nr_sectors; i++){
1039 if(ubd_test_bit(sector + i, bitmap) != bit)
1040 return(-1);
1041 }
1042
1043 if(bit || (rq_data_dir(req) == WRITE))
1044 offset += dev->cow.data_offset;
1045
1046 /* The data on disk must be page aligned */
1047 if((offset % UBD_MMAP_BLOCK_SIZE) != 0)
1048 return(-1);
1049
1050 return(bit ? dev->fd : dev->cow.fd);
1051}
1052
1053static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset,
1054 struct request *req,
1055 struct io_thread_req *io_req)
1056{
1057 int err;
1058
1059 if(rq_data_dir(req) == WRITE){
1060 /* Writes are almost no-ops since the new data is already in the
1061 * host page cache
1062 */
1063 dev->map_writes++;
1064 if(dev->cow.file != NULL)
1065 cowify_bitmap(io_req->offset, io_req->length,
1066 &io_req->sector_mask, &io_req->cow_offset,
1067 dev->cow.bitmap, dev->cow.bitmap_offset,
1068 io_req->bitmap_words,
1069 dev->cow.bitmap_len);
1070 }
1071 else {
1072 int w;
1073
1074 if((dev->cow.file != NULL) && (fd == dev->cow.fd))
1075 w = 0;
1076 else w = dev->openflags.w;
1077
1078 if((dev->cow.file != NULL) && (fd == dev->fd))
1079 offset += dev->cow.data_offset;
1080
1081 err = physmem_subst_mapping(req->buffer, fd, offset, w);
1082 if(err){
1083 printk("physmem_subst_mapping failed, err = %d\n",
1084 -err);
1085 return(1);
1086 }
1087 dev->map_reads++;
1088 }
1089 io_req->op = UBD_MMAP;
1090 io_req->buffer = req->buffer;
1091 return(0);
1092}
1093
1094/* Called with ubd_io_lock held */ 971/* Called with ubd_io_lock held */
1095static int prepare_request(struct request *req, struct io_thread_req *io_req) 972static int prepare_request(struct request *req, struct io_thread_req *io_req)
1096{ 973{
1097 struct gendisk *disk = req->rq_disk; 974 struct gendisk *disk = req->rq_disk;
1098 struct ubd *dev = disk->private_data; 975 struct ubd *dev = disk->private_data;
1099 __u64 offset; 976 __u64 offset;
1100 int len, fd; 977 int len;
1101 978
1102 if(req->rq_status == RQ_INACTIVE) return(1); 979 if(req->rq_status == RQ_INACTIVE) return(1);
1103 980
@@ -1114,34 +991,12 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
1114 991
1115 io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd; 992 io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
1116 io_req->fds[1] = dev->fd; 993 io_req->fds[1] = dev->fd;
1117 io_req->map_fd = -1;
1118 io_req->cow_offset = -1; 994 io_req->cow_offset = -1;
1119 io_req->offset = offset; 995 io_req->offset = offset;
1120 io_req->length = len; 996 io_req->length = len;
1121 io_req->error = 0; 997 io_req->error = 0;
1122 io_req->sector_mask = 0; 998 io_req->sector_mask = 0;
1123 999
1124 fd = mmap_fd(req, dev, io_req->offset);
1125 if(fd > 0){
1126 /* If mmapping is otherwise OK, but the first access to the
1127 * page is a write, then it's not mapped in yet. So we have
1128 * to write the data to disk first, then we can map the disk
1129 * page in and continue normally from there.
1130 */
1131 if((rq_data_dir(req) == WRITE) && !is_remapped(req->buffer)){
1132 io_req->map_fd = dev->fd;
1133 io_req->map_offset = io_req->offset +
1134 dev->cow.data_offset;
1135 dev->write_maps++;
1136 }
1137 else return(prepare_mmap_request(dev, fd, io_req->offset, req,
1138 io_req));
1139 }
1140
1141 if(rq_data_dir(req) == READ)
1142 dev->nomap_reads++;
1143 else dev->nomap_writes++;
1144
1145 io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE; 1000 io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
1146 io_req->offsets[0] = 0; 1001 io_req->offsets[0] = 0;
1147 io_req->offsets[1] = dev->cow.data_offset; 1002 io_req->offsets[1] = dev->cow.data_offset;
@@ -1229,143 +1084,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
1229 return(-EINVAL); 1084 return(-EINVAL);
1230} 1085}
1231 1086
1232static int ubd_check_remapped(int fd, unsigned long address, int is_write,
1233 __u64 offset)
1234{
1235 __u64 bitmap_offset;
1236 unsigned long new_bitmap[2];
1237 int i, err, n;
1238
1239 /* If it's not a write access, we can't do anything about it */
1240 if(!is_write)
1241 return(0);
1242
1243 /* We have a write */
1244 for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){
1245 struct ubd *dev = &ubd_dev[i];
1246
1247 if((dev->fd != fd) && (dev->cow.fd != fd))
1248 continue;
1249
1250 /* It's a write to a ubd device */
1251
1252 /* This should be impossible now */
1253 if(!dev->openflags.w){
1254 /* It's a write access on a read-only device - probably
1255 * shouldn't happen. If the kernel is trying to change
1256 * something with no intention of writing it back out,
1257 * then this message will clue us in that this needs
1258 * fixing
1259 */
1260 printk("Write access to mapped page from readonly ubd "
1261 "device %d\n", i);
1262 return(0);
1263 }
1264
1265 /* It's a write to a writeable ubd device - it must be COWed
1266 * because, otherwise, the page would have been mapped in
1267 * writeable
1268 */
1269
1270 if(!dev->cow.file)
1271 panic("Write fault on writeable non-COW ubd device %d",
1272 i);
1273
1274 /* It should also be an access to the backing file since the
1275 * COW pages should be mapped in read-write
1276 */
1277
1278 if(fd == dev->fd)
1279 panic("Write fault on a backing page of ubd "
1280 "device %d\n", i);
1281
1282 /* So, we do the write, copying the backing data to the COW
1283 * file...
1284 */
1285
1286 err = os_seek_file(dev->fd, offset + dev->cow.data_offset);
1287 if(err < 0)
1288 panic("Couldn't seek to %lld in COW file of ubd "
1289 "device %d, err = %d",
1290 offset + dev->cow.data_offset, i, -err);
1291
1292 n = os_write_file(dev->fd, (void *) address, PAGE_SIZE);
1293 if(n != PAGE_SIZE)
1294 panic("Couldn't copy data to COW file of ubd "
1295 "device %d, err = %d", i, -n);
1296
1297 /* ... updating the COW bitmap... */
1298
1299 cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset,
1300 dev->cow.bitmap, dev->cow.bitmap_offset,
1301 new_bitmap, dev->cow.bitmap_len);
1302
1303 err = os_seek_file(dev->fd, bitmap_offset);
1304 if(err < 0)
1305 panic("Couldn't seek to %lld in COW file of ubd "
1306 "device %d, err = %d", bitmap_offset, i, -err);
1307
1308 n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap));
1309 if(n != sizeof(new_bitmap))
1310 panic("Couldn't update bitmap of ubd device %d, "
1311 "err = %d", i, -n);
1312
1313 /* Maybe we can map the COW page in, and maybe we can't. If
1314 * it is a pre-V3 COW file, we can't, since the alignment will
1315 * be wrong. If it is a V3 or later COW file which has been
1316 * moved to a system with a larger page size, then maybe we
1317 * can't, depending on the exact location of the page.
1318 */
1319
1320 offset += dev->cow.data_offset;
1321
1322 /* Remove the remapping, putting the original anonymous page
1323 * back. If the COW file can be mapped in, that is done.
1324 * Otherwise, the COW page is read in.
1325 */
1326
1327 if(!physmem_remove_mapping((void *) address))
1328 panic("Address 0x%lx not remapped by ubd device %d",
1329 address, i);
1330 if((offset % UBD_MMAP_BLOCK_SIZE) == 0)
1331 physmem_subst_mapping((void *) address, dev->fd,
1332 offset, 1);
1333 else {
1334 err = os_seek_file(dev->fd, offset);
1335 if(err < 0)
1336 panic("Couldn't seek to %lld in COW file of "
1337 "ubd device %d, err = %d", offset, i,
1338 -err);
1339
1340 n = os_read_file(dev->fd, (void *) address, PAGE_SIZE);
1341 if(n != PAGE_SIZE)
1342 panic("Failed to read page from offset %llx of "
1343 "COW file of ubd device %d, err = %d",
1344 offset, i, -n);
1345 }
1346
1347 return(1);
1348 }
1349
1350 /* It's not a write on a ubd device */
1351 return(0);
1352}
1353
1354static struct remapper ubd_remapper = {
1355 .list = LIST_HEAD_INIT(ubd_remapper.list),
1356 .proc = ubd_check_remapped,
1357};
1358
1359static int ubd_remapper_setup(void)
1360{
1361 if(ubd_do_mmap)
1362 register_remapper(&ubd_remapper);
1363
1364 return(0);
1365}
1366
1367__initcall(ubd_remapper_setup);
1368
1369static int same_backing_files(char *from_cmdline, char *from_cow, char *cow) 1087static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
1370{ 1088{
1371 struct uml_stat buf1, buf2; 1089 struct uml_stat buf1, buf2;
@@ -1568,15 +1286,6 @@ void do_io(struct io_thread_req *req)
1568 int err; 1286 int err;
1569 __u64 off; 1287 __u64 off;
1570 1288
1571 if(req->op == UBD_MMAP){
1572 /* Touch the page to force the host to do any necessary IO to
1573 * get it into memory
1574 */
1575 n = *((volatile int *) req->buffer);
1576 req->error = update_bitmap(req);
1577 return;
1578 }
1579
1580 nsectors = req->length / req->sectorsize; 1289 nsectors = req->length / req->sectorsize;
1581 start = 0; 1290 start = 0;
1582 do { 1291 do {
diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
index 7917b9d1cec8..a4fdf3584ad2 100644
--- a/arch/um/drivers/xterm_kern.c
+++ b/arch/um/drivers/xterm_kern.c
@@ -7,7 +7,6 @@
7#include "linux/slab.h" 7#include "linux/slab.h"
8#include "linux/signal.h" 8#include "linux/signal.h"
9#include "linux/interrupt.h" 9#include "linux/interrupt.h"
10#include "asm/semaphore.h"
11#include "asm/irq.h" 10#include "asm/irq.h"
12#include "irq_user.h" 11#include "irq_user.h"
13#include "irq_kern.h" 12#include "irq_kern.h"
diff --git a/arch/um/include/2_5compat.h b/arch/um/include/2_5compat.h
deleted file mode 100644
index abdb015a4d71..000000000000
--- a/arch/um/include/2_5compat.h
+++ /dev/null
@@ -1,24 +0,0 @@
1/*
2 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __2_5_COMPAT_H__
7#define __2_5_COMPAT_H__
8
9#define INIT_HARDSECT(arr, maj, sizes)
10
11#define SET_PRI(task) do ; while(0)
12
13#endif
14
15/*
16 * Overrides for Emacs so that we follow Linus's tabbing style.
17 * Emacs will notice this stuff at the end of the file and automatically
18 * adjust the settings for this buffer only. This must remain at the end
19 * of the file.
20 * ---------------------------------------------------------------------------
21 * Local variables:
22 * c-file-style: "linux"
23 * End:
24 */
diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h
new file mode 100644
index 000000000000..d705daa2d854
--- /dev/null
+++ b/arch/um/include/common-offsets.h
@@ -0,0 +1,14 @@
1/* for use by sys-$SUBARCH/kernel-offsets.c */
2
3OFFSET(TASK_REGS, task_struct, thread.regs);
4OFFSET(TASK_PID, task_struct, pid);
5DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE);
6DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
7DEFINE_STR(UM_KERN_EMERG, KERN_EMERG);
8DEFINE_STR(UM_KERN_ALERT, KERN_ALERT);
9DEFINE_STR(UM_KERN_CRIT, KERN_CRIT);
10DEFINE_STR(UM_KERN_ERR, KERN_ERR);
11DEFINE_STR(UM_KERN_WARNING, KERN_WARNING);
12DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE);
13DEFINE_STR(UM_KERN_INFO, KERN_INFO);
14DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG);
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index 15389c886b41..e5fec5570199 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -8,6 +8,7 @@
8 8
9#include "linux/threads.h" 9#include "linux/threads.h"
10#include "sysdep/ptrace.h" 10#include "sysdep/ptrace.h"
11#include "sysdep/faultinfo.h"
11 12
12extern int ncpus; 13extern int ncpus;
13extern char *linux_prog; 14extern char *linux_prog;
@@ -31,8 +32,8 @@ extern int current_pid(void);
31extern unsigned long alloc_stack(int order, int atomic); 32extern unsigned long alloc_stack(int order, int atomic);
32extern int do_signal(void); 33extern int do_signal(void);
33extern int is_stack_fault(unsigned long sp); 34extern int is_stack_fault(unsigned long sp);
34extern unsigned long segv(unsigned long address, unsigned long ip, 35extern unsigned long segv(struct faultinfo fi, unsigned long ip,
35 int is_write, int is_user, void *sc); 36 int is_user, void *sc);
36extern int handle_page_fault(unsigned long address, unsigned long ip, 37extern int handle_page_fault(unsigned long address, unsigned long ip,
37 int is_write, int is_user, int *code_out); 38 int is_write, int is_user, int *code_out);
38extern void syscall_ready(void); 39extern void syscall_ready(void);
@@ -82,7 +83,7 @@ extern void timer_irq(union uml_pt_regs *regs);
82extern void unprotect_stack(unsigned long stack); 83extern void unprotect_stack(unsigned long stack);
83extern void do_uml_exitcalls(void); 84extern void do_uml_exitcalls(void);
84extern int attach_debugger(int idle_pid, int pid, int stop); 85extern int attach_debugger(int idle_pid, int pid, int stop);
85extern void bad_segv(unsigned long address, unsigned long ip, int is_write); 86extern void bad_segv(struct faultinfo fi, unsigned long ip);
86extern int config_gdb(char *str); 87extern int config_gdb(char *str);
87extern int remove_gdb(void); 88extern int remove_gdb(void);
88extern char *uml_strdup(char *string); 89extern char *uml_strdup(char *string);
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
index 9fbe3083fdd8..cfa368e045a5 100644
--- a/arch/um/include/mconsole.h
+++ b/arch/um/include/mconsole.h
@@ -56,7 +56,7 @@ struct mc_request
56 int as_interrupt; 56 int as_interrupt;
57 57
58 int originating_fd; 58 int originating_fd;
59 int originlen; 59 unsigned int originlen;
60 unsigned char origin[128]; /* sockaddr_un */ 60 unsigned char origin[128]; /* sockaddr_un */
61 61
62 struct mconsole_request request; 62 struct mconsole_request request;
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h
index 36807b796e9f..89885a77a771 100644
--- a/arch/um/include/net_user.h
+++ b/arch/um/include/net_user.h
@@ -35,7 +35,7 @@ extern void *get_output_buffer(int *len_out);
35extern void free_output_buffer(void *buffer); 35extern void free_output_buffer(void *buffer);
36 36
37extern int tap_open_common(void *dev, char *gate_addr); 37extern int tap_open_common(void *dev, char *gate_addr);
38extern void tap_check_ips(char *gate_addr, char *eth_addr); 38extern void tap_check_ips(char *gate_addr, unsigned char *eth_addr);
39 39
40extern void read_output(int fd, char *output_out, int len); 40extern void read_output(int fd, char *output_out, int len);
41 41
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 07340c8cf203..881d2988d2d8 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -136,7 +136,7 @@ extern int os_seek_file(int fd, __u64 offset);
136extern int os_open_file(char *file, struct openflags flags, int mode); 136extern int os_open_file(char *file, struct openflags flags, int mode);
137extern int os_read_file(int fd, void *buf, int len); 137extern int os_read_file(int fd, void *buf, int len);
138extern int os_write_file(int fd, const void *buf, int count); 138extern int os_write_file(int fd, const void *buf, int count);
139extern int os_file_size(char *file, long long *size_out); 139extern int os_file_size(char *file, unsigned long long *size_out);
140extern int os_file_modtime(char *file, unsigned long *modtime); 140extern int os_file_modtime(char *file, unsigned long *modtime);
141extern int os_pipe(int *fd, int stream, int close_on_exec); 141extern int os_pipe(int *fd, int stream, int close_on_exec);
142extern int os_set_fd_async(int fd, int owner); 142extern int os_set_fd_async(int fd, int owner);
@@ -160,6 +160,7 @@ extern void os_kill_process(int pid, int reap_child);
160extern void os_kill_ptraced_process(int pid, int reap_child); 160extern void os_kill_ptraced_process(int pid, int reap_child);
161extern void os_usr1_process(int pid); 161extern void os_usr1_process(int pid);
162extern int os_getpid(void); 162extern int os_getpid(void);
163extern int os_getpgrp(void);
163 164
164extern int os_map_memory(void *virt, int fd, unsigned long long off, 165extern int os_map_memory(void *virt, int fd, unsigned long long off,
165 unsigned long len, int r, int w, int x); 166 unsigned long len, int r, int w, int x);
diff --git a/arch/um/include/skas_ptrace.h b/arch/um/include/skas_ptrace.h
index cfb5fb4f5b91..cd2327d09c8d 100644
--- a/arch/um/include/skas_ptrace.h
+++ b/arch/um/include/skas_ptrace.h
@@ -6,22 +6,11 @@
6#ifndef __SKAS_PTRACE_H 6#ifndef __SKAS_PTRACE_H
7#define __SKAS_PTRACE_H 7#define __SKAS_PTRACE_H
8 8
9struct ptrace_faultinfo {
10 int is_write;
11 unsigned long addr;
12};
13
14struct ptrace_ldt {
15 int func;
16 void *ptr;
17 unsigned long bytecount;
18};
19
20#define PTRACE_FAULTINFO 52 9#define PTRACE_FAULTINFO 52
21#define PTRACE_SIGPENDING 53
22#define PTRACE_LDT 54
23#define PTRACE_SWITCH_MM 55 10#define PTRACE_SWITCH_MM 55
24 11
12#include "sysdep/skas_ptrace.h"
13
25#endif 14#endif
26 15
27/* 16/*
diff --git a/arch/um/include/sysdep-i386/checksum.h b/arch/um/include/sysdep-i386/checksum.h
index 3a2a45811aa3..764ba4db4788 100644
--- a/arch/um/include/sysdep-i386/checksum.h
+++ b/arch/um/include/sysdep-i386/checksum.h
@@ -24,19 +24,6 @@ unsigned int csum_partial(const unsigned char * buff, int len,
24 unsigned int sum); 24 unsigned int sum);
25 25
26/* 26/*
27 * the same as csum_partial, but copies from src while it
28 * checksums, and handles user-space pointer exceptions correctly, when needed.
29 *
30 * here even more important to align src and dst on a 32-bit (or even
31 * better 64-bit) boundary
32 */
33
34unsigned int csum_partial_copy_to(const unsigned char *src, unsigned char *dst,
35 int len, int sum, int *err_ptr);
36unsigned int csum_partial_copy_from(const unsigned char *src, unsigned char *dst,
37 int len, int sum, int *err_ptr);
38
39/*
40 * Note: when you get a NULL pointer exception here this means someone 27 * Note: when you get a NULL pointer exception here this means someone
41 * passed in an incorrect kernel address to one of these functions. 28 * passed in an incorrect kernel address to one of these functions.
42 * 29 *
@@ -52,11 +39,24 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *
52 return(csum_partial(dst, len, sum)); 39 return(csum_partial(dst, len, sum));
53} 40}
54 41
42/*
43 * the same as csum_partial, but copies from src while it
44 * checksums, and handles user-space pointer exceptions correctly, when needed.
45 *
46 * here even more important to align src and dst on a 32-bit (or even
47 * better 64-bit) boundary
48 */
49
55static __inline__ 50static __inline__
56unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, 51unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
57 int len, int sum, int *err_ptr) 52 int len, int sum, int *err_ptr)
58{ 53{
59 return csum_partial_copy_from(src, dst, len, sum, err_ptr); 54 if(copy_from_user(dst, src, len)){
55 *err_ptr = -EFAULT;
56 return(-1);
57 }
58
59 return csum_partial(dst, len, sum);
60} 60}
61 61
62/* 62/*
@@ -67,7 +67,6 @@ unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char
67 */ 67 */
68 68
69#define csum_partial_copy_fromuser csum_partial_copy_from_user 69#define csum_partial_copy_fromuser csum_partial_copy_from_user
70unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, int len, int sum);
71 70
72/* 71/*
73 * This is a version of ip_compute_csum() optimized for IP headers, 72 * This is a version of ip_compute_csum() optimized for IP headers,
@@ -196,8 +195,14 @@ static __inline__ unsigned int csum_and_copy_to_user(const unsigned char *src,
196 unsigned char *dst, 195 unsigned char *dst,
197 int len, int sum, int *err_ptr) 196 int len, int sum, int *err_ptr)
198{ 197{
199 if (access_ok(VERIFY_WRITE, dst, len)) 198 if (access_ok(VERIFY_WRITE, dst, len)){
200 return(csum_partial_copy_to(src, dst, len, sum, err_ptr)); 199 if(copy_to_user(dst, src, len)){
200 *err_ptr = -EFAULT;
201 return(-1);
202 }
203
204 return csum_partial(src, len, sum);
205 }
201 206
202 if (len) 207 if (len)
203 *err_ptr = -EFAULT; 208 *err_ptr = -EFAULT;
diff --git a/arch/um/include/sysdep-i386/faultinfo.h b/arch/um/include/sysdep-i386/faultinfo.h
new file mode 100644
index 000000000000..db437cc373bc
--- /dev/null
+++ b/arch/um/include/sysdep-i386/faultinfo.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
3 * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
4 * Licensed under the GPL
5 */
6
7#ifndef __FAULTINFO_I386_H
8#define __FAULTINFO_I386_H
9
10/* this structure contains the full arch-specific faultinfo
11 * from the traps.
12 * On i386, ptrace_faultinfo unfortunately doesn't provide
13 * all the info, since trap_no is missing.
14 * All common elements are defined at the same position in
15 * both structures, thus making it easy to copy the
16 * contents without knowledge about the structure elements.
17 */
18struct faultinfo {
19 int error_code; /* in ptrace_faultinfo misleadingly called is_write */
20 unsigned long cr2; /* in ptrace_faultinfo called addr */
21 int trap_no; /* missing in ptrace_faultinfo */
22};
23
24#define FAULT_WRITE(fi) ((fi).error_code & 2)
25#define FAULT_ADDRESS(fi) ((fi).cr2)
26
27#define PTRACE_FULL_FAULTINFO 0
28
29#endif
diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h
index 661d495e2044..c8ee9559f3ab 100644
--- a/arch/um/include/sysdep-i386/ptrace.h
+++ b/arch/um/include/sysdep-i386/ptrace.h
@@ -8,6 +8,8 @@
8 8
9#include "uml-config.h" 9#include "uml-config.h"
10#include "user_constants.h" 10#include "user_constants.h"
11#include "sysdep/faultinfo.h"
12#include "choose-mode.h"
11 13
12#define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) 14#define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long))
13#define MAX_REG_OFFSET (UM_FRAME_SIZE) 15#define MAX_REG_OFFSET (UM_FRAME_SIZE)
@@ -53,24 +55,17 @@ extern int sysemu_supported;
53 55
54#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) 56#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
55 57
56#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type)
57
58#define REGS_FAULT_ADDR(r) ((r)->fault_addr)
59
60#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type)
61
62#endif 58#endif
63#ifndef PTRACE_SYSEMU_SINGLESTEP 59#ifndef PTRACE_SYSEMU_SINGLESTEP
64#define PTRACE_SYSEMU_SINGLESTEP 32 60#define PTRACE_SYSEMU_SINGLESTEP 32
65#endif 61#endif
66 62
67#include "choose-mode.h"
68
69union uml_pt_regs { 63union uml_pt_regs {
70#ifdef UML_CONFIG_MODE_TT 64#ifdef UML_CONFIG_MODE_TT
71 struct tt_regs { 65 struct tt_regs {
72 long syscall; 66 long syscall;
73 void *sc; 67 void *sc;
68 struct faultinfo faultinfo;
74 } tt; 69 } tt;
75#endif 70#endif
76#ifdef UML_CONFIG_MODE_SKAS 71#ifdef UML_CONFIG_MODE_SKAS
@@ -78,9 +73,7 @@ union uml_pt_regs {
78 unsigned long regs[HOST_FRAME_SIZE]; 73 unsigned long regs[HOST_FRAME_SIZE];
79 unsigned long fp[HOST_FP_SIZE]; 74 unsigned long fp[HOST_FP_SIZE];
80 unsigned long xfp[HOST_XFP_SIZE]; 75 unsigned long xfp[HOST_XFP_SIZE];
81 unsigned long fault_addr; 76 struct faultinfo faultinfo;
82 unsigned long fault_type;
83 unsigned long trap_type;
84 long syscall; 77 long syscall;
85 int is_user; 78 int is_user;
86 } skas; 79 } skas;
@@ -217,15 +210,8 @@ struct syscall_args {
217#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r) 210#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r)
218#define UPT_SYSCALL_RET(r) UPT_EAX(r) 211#define UPT_SYSCALL_RET(r) UPT_EAX(r)
219 212
220#define UPT_SEGV_IS_FIXABLE(r) \ 213#define UPT_FAULTINFO(r) \
221 CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \ 214 CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo))
222 REGS_SEGV_IS_FIXABLE(&r->skas))
223
224#define UPT_FAULT_ADDR(r) \
225 __CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas))
226
227#define UPT_FAULT_WRITE(r) \
228 CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
229 215
230#endif 216#endif
231 217
diff --git a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h
index dfee589de360..1fe729265167 100644
--- a/arch/um/include/sysdep-i386/sigcontext.h
+++ b/arch/um/include/sysdep-i386/sigcontext.h
@@ -13,15 +13,12 @@
13#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc)) 13#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc))
14#define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result) 14#define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result)
15 15
16#define SC_FAULT_ADDR(sc) SC_CR2(sc) 16#define GET_FAULTINFO_FROM_SC(fi,sc) \
17#define SC_FAULT_TYPE(sc) SC_ERR(sc) 17 { \
18 18 (fi).cr2 = SC_CR2(sc); \
19#define FAULT_WRITE(err) (err & 2) 19 (fi).error_code = SC_ERR(sc); \
20#define TO_SC_ERR(is_write) ((is_write) ? 2 : 0) 20 (fi).trap_no = SC_TRAPNO(sc); \
21 21 }
22#define SC_FAULT_WRITE(sc) (FAULT_WRITE(SC_ERR(sc)))
23
24#define SC_TRAP_TYPE(sc) SC_TRAPNO(sc)
25 22
26/* ptrace expects that, at the start of a system call, %eax contains 23/* ptrace expects that, at the start of a system call, %eax contains
27 * -ENOSYS, so this makes it so. 24 * -ENOSYS, so this makes it so.
@@ -29,9 +26,7 @@
29#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0) 26#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
30 27
31/* This is Page Fault */ 28/* This is Page Fault */
32#define SEGV_IS_FIXABLE(trap) (trap == 14) 29#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
33
34#define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
35 30
36extern unsigned long *sc_sigmask(void *sc_ptr); 31extern unsigned long *sc_sigmask(void *sc_ptr);
37extern int sc_get_fpregs(unsigned long buf, void *sc_ptr); 32extern int sc_get_fpregs(unsigned long buf, void *sc_ptr);
diff --git a/arch/um/include/sysdep-i386/signal.h b/arch/um/include/sysdep-i386/signal.h
index b1e1f7a77499..07518b162136 100644
--- a/arch/um/include/sysdep-i386/signal.h
+++ b/arch/um/include/sysdep-i386/signal.h
@@ -8,6 +8,8 @@
8 8
9#include <signal.h> 9#include <signal.h>
10 10
11#define ARCH_SIGHDLR_PARAM int sig
12
11#define ARCH_GET_SIGCONTEXT(sc, sig) \ 13#define ARCH_GET_SIGCONTEXT(sc, sig) \
12 do sc = (struct sigcontext *) (&sig + 1); while(0) 14 do sc = (struct sigcontext *) (&sig + 1); while(0)
13 15
diff --git a/arch/um/include/sysdep-i386/skas_ptrace.h b/arch/um/include/sysdep-i386/skas_ptrace.h
new file mode 100644
index 000000000000..e27b8a791773
--- /dev/null
+++ b/arch/um/include/sysdep-i386/skas_ptrace.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SYSDEP_I386_SKAS_PTRACE_H
7#define __SYSDEP_I386_SKAS_PTRACE_H
8
9struct ptrace_faultinfo {
10 int is_write;
11 unsigned long addr;
12};
13
14struct ptrace_ldt {
15 int func;
16 void *ptr;
17 unsigned long bytecount;
18};
19
20#define PTRACE_LDT 54
21
22#endif
diff --git a/arch/um/include/sysdep-ia64/skas_ptrace.h b/arch/um/include/sysdep-ia64/skas_ptrace.h
new file mode 100644
index 000000000000..25a38e715702
--- /dev/null
+++ b/arch/um/include/sysdep-ia64/skas_ptrace.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SYSDEP_IA64_SKAS_PTRACE_H
7#define __SYSDEP_IA64_SKAS_PTRACE_H
8
9struct ptrace_faultinfo {
10 int is_write;
11 unsigned long addr;
12};
13
14struct ptrace_ldt {
15 int func;
16 void *ptr;
17 unsigned long bytecount;
18};
19
20#define PTRACE_LDT 54
21
22#endif
diff --git a/arch/um/include/sysdep-ppc/skas_ptrace.h b/arch/um/include/sysdep-ppc/skas_ptrace.h
new file mode 100644
index 000000000000..d9fbbac10de0
--- /dev/null
+++ b/arch/um/include/sysdep-ppc/skas_ptrace.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SYSDEP_PPC_SKAS_PTRACE_H
7#define __SYSDEP_PPC_SKAS_PTRACE_H
8
9struct ptrace_faultinfo {
10 int is_write;
11 unsigned long addr;
12};
13
14struct ptrace_ldt {
15 int func;
16 void *ptr;
17 unsigned long bytecount;
18};
19
20#define PTRACE_LDT 54
21
22#endif
diff --git a/arch/um/include/sysdep-x86_64/checksum.h b/arch/um/include/sysdep-x86_64/checksum.h
index 572c6c19be33..ea97005af694 100644
--- a/arch/um/include/sysdep-x86_64/checksum.h
+++ b/arch/um/include/sysdep-x86_64/checksum.h
@@ -9,8 +9,6 @@
9#include "linux/in6.h" 9#include "linux/in6.h"
10#include "asm/uaccess.h" 10#include "asm/uaccess.h"
11 11
12extern unsigned int csum_partial_copy_from(const unsigned char *src, unsigned char *dst, int len,
13 int sum, int *err_ptr);
14extern unsigned csum_partial(const unsigned char *buff, unsigned len, 12extern unsigned csum_partial(const unsigned char *buff, unsigned len,
15 unsigned sum); 13 unsigned sum);
16 14
@@ -31,10 +29,15 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *
31} 29}
32 30
33static __inline__ 31static __inline__
34unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, 32unsigned int csum_partial_copy_from_user(const unsigned char *src,
35 int len, int sum, int *err_ptr) 33 unsigned char *dst, int len, int sum,
34 int *err_ptr)
36{ 35{
37 return csum_partial_copy_from(src, dst, len, sum, err_ptr); 36 if(copy_from_user(dst, src, len)){
37 *err_ptr = -EFAULT;
38 return(-1);
39 }
40 return csum_partial(dst, len, sum);
38} 41}
39 42
40/** 43/**
@@ -137,15 +140,6 @@ static inline unsigned add32_with_carry(unsigned a, unsigned b)
137 return a; 140 return a;
138} 141}
139 142
140#endif 143extern unsigned short ip_compute_csum(unsigned char * buff, int len);
141 144
142/* 145#endif
143 * Overrides for Emacs so that we follow Linus's tabbing style.
144 * Emacs will notice this stuff at the end of the file and automatically
145 * adjust the settings for this buffer only. This must remain at the end
146 * of the file.
147 * ---------------------------------------------------------------------------
148 * Local variables:
149 * c-file-style: "linux"
150 * End:
151 */
diff --git a/arch/um/include/sysdep-x86_64/faultinfo.h b/arch/um/include/sysdep-x86_64/faultinfo.h
new file mode 100644
index 000000000000..cb917b0d5660
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/faultinfo.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
3 * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
4 * Licensed under the GPL
5 */
6
7#ifndef __FAULTINFO_X86_64_H
8#define __FAULTINFO_X86_64_H
9
10/* this structure contains the full arch-specific faultinfo
11 * from the traps.
12 * On i386, ptrace_faultinfo unfortunately doesn't provide
13 * all the info, since trap_no is missing.
14 * All common elements are defined at the same position in
15 * both structures, thus making it easy to copy the
16 * contents without knowledge about the structure elements.
17 */
18struct faultinfo {
19 int error_code; /* in ptrace_faultinfo misleadingly called is_write */
20 unsigned long cr2; /* in ptrace_faultinfo called addr */
21 int trap_no; /* missing in ptrace_faultinfo */
22};
23
24#define FAULT_WRITE(fi) ((fi).error_code & 2)
25#define FAULT_ADDRESS(fi) ((fi).cr2)
26
27#define PTRACE_FULL_FAULTINFO 1
28
29#endif
diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h
index 915c82daffbd..be8acd5efd97 100644
--- a/arch/um/include/sysdep-x86_64/ptrace.h
+++ b/arch/um/include/sysdep-x86_64/ptrace.h
@@ -9,6 +9,7 @@
9 9
10#include "uml-config.h" 10#include "uml-config.h"
11#include "user_constants.h" 11#include "user_constants.h"
12#include "sysdep/faultinfo.h"
12 13
13#define MAX_REG_OFFSET (UM_FRAME_SIZE) 14#define MAX_REG_OFFSET (UM_FRAME_SIZE)
14#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long)) 15#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long))
@@ -83,6 +84,7 @@ union uml_pt_regs {
83 long syscall; 84 long syscall;
84 unsigned long orig_rax; 85 unsigned long orig_rax;
85 void *sc; 86 void *sc;
87 struct faultinfo faultinfo;
86 } tt; 88 } tt;
87#endif 89#endif
88#ifdef UML_CONFIG_MODE_SKAS 90#ifdef UML_CONFIG_MODE_SKAS
@@ -90,9 +92,7 @@ union uml_pt_regs {
90 /* XXX */ 92 /* XXX */
91 unsigned long regs[27]; 93 unsigned long regs[27];
92 unsigned long fp[65]; 94 unsigned long fp[65];
93 unsigned long fault_addr; 95 struct faultinfo faultinfo;
94 unsigned long fault_type;
95 unsigned long trap_type;
96 long syscall; 96 long syscall;
97 int is_user; 97 int is_user;
98 } skas; 98 } skas;
@@ -135,6 +135,7 @@ extern int mode_tt;
135 __CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs)) 135 __CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
136#define UPT_SC(r) ((r)->tt.sc) 136#define UPT_SC(r) ((r)->tt.sc)
137#define UPT_SYSCALL_NR(r) __CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall) 137#define UPT_SYSCALL_NR(r) __CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
138#define UPT_SYSCALL_RET(r) UPT_RAX(r)
138 139
139extern int user_context(unsigned long sp); 140extern int user_context(unsigned long sp);
140 141
@@ -196,32 +197,32 @@ struct syscall_args {
196 197
197 198
198#define UPT_SET(regs, reg, val) \ 199#define UPT_SET(regs, reg, val) \
199 ({ unsigned long val; \ 200 ({ unsigned long __upt_val = val; \
200 switch(reg){ \ 201 switch(reg){ \
201 case R8: UPT_R8(regs) = val; break; \ 202 case R8: UPT_R8(regs) = __upt_val; break; \
202 case R9: UPT_R9(regs) = val; break; \ 203 case R9: UPT_R9(regs) = __upt_val; break; \
203 case R10: UPT_R10(regs) = val; break; \ 204 case R10: UPT_R10(regs) = __upt_val; break; \
204 case R11: UPT_R11(regs) = val; break; \ 205 case R11: UPT_R11(regs) = __upt_val; break; \
205 case R12: UPT_R12(regs) = val; break; \ 206 case R12: UPT_R12(regs) = __upt_val; break; \
206 case R13: UPT_R13(regs) = val; break; \ 207 case R13: UPT_R13(regs) = __upt_val; break; \
207 case R14: UPT_R14(regs) = val; break; \ 208 case R14: UPT_R14(regs) = __upt_val; break; \
208 case R15: UPT_R15(regs) = val; break; \ 209 case R15: UPT_R15(regs) = __upt_val; break; \
209 case RIP: UPT_IP(regs) = val; break; \ 210 case RIP: UPT_IP(regs) = __upt_val; break; \
210 case RSP: UPT_SP(regs) = val; break; \ 211 case RSP: UPT_SP(regs) = __upt_val; break; \
211 case RAX: UPT_RAX(regs) = val; break; \ 212 case RAX: UPT_RAX(regs) = __upt_val; break; \
212 case RBX: UPT_RBX(regs) = val; break; \ 213 case RBX: UPT_RBX(regs) = __upt_val; break; \
213 case RCX: UPT_RCX(regs) = val; break; \ 214 case RCX: UPT_RCX(regs) = __upt_val; break; \
214 case RDX: UPT_RDX(regs) = val; break; \ 215 case RDX: UPT_RDX(regs) = __upt_val; break; \
215 case RSI: UPT_RSI(regs) = val; break; \ 216 case RSI: UPT_RSI(regs) = __upt_val; break; \
216 case RDI: UPT_RDI(regs) = val; break; \ 217 case RDI: UPT_RDI(regs) = __upt_val; break; \
217 case RBP: UPT_RBP(regs) = val; break; \ 218 case RBP: UPT_RBP(regs) = __upt_val; break; \
218 case ORIG_RAX: UPT_ORIG_RAX(regs) = val; break; \ 219 case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \
219 case CS: UPT_CS(regs) = val; break; \ 220 case CS: UPT_CS(regs) = __upt_val; break; \
220 case DS: UPT_DS(regs) = val; break; \ 221 case DS: UPT_DS(regs) = __upt_val; break; \
221 case ES: UPT_ES(regs) = val; break; \ 222 case ES: UPT_ES(regs) = __upt_val; break; \
222 case FS: UPT_FS(regs) = val; break; \ 223 case FS: UPT_FS(regs) = __upt_val; break; \
223 case GS: UPT_GS(regs) = val; break; \ 224 case GS: UPT_GS(regs) = __upt_val; break; \
224 case EFLAGS: UPT_EFLAGS(regs) = val; break; \ 225 case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \
225 default : \ 226 default : \
226 panic("Bad register in UPT_SET : %d\n", reg); \ 227 panic("Bad register in UPT_SET : %d\n", reg); \
227 break; \ 228 break; \
@@ -241,24 +242,7 @@ struct syscall_args {
241 CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \ 242 CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
242 REGS_SEGV_IS_FIXABLE(&r->skas)) 243 REGS_SEGV_IS_FIXABLE(&r->skas))
243 244
244#define UPT_FAULT_ADDR(r) \ 245#define UPT_FAULTINFO(r) \
245 __CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas)) 246 CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo))
246
247#define UPT_FAULT_WRITE(r) \
248 CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
249
250#define UPT_TRAP(r) __CHOOSE_MODE(SC_TRAP_TYPE(UPT_SC(r)), REGS_TRAP(&r->skas))
251#define UPT_ERR(r) __CHOOSE_MODE(SC_FAULT_TYPE(UPT_SC(r)), REGS_ERR(&r->skas))
252 247
253#endif 248#endif
254
255/*
256 * Overrides for Emacs so that we follow Linus's tabbing style.
257 * Emacs will notice this stuff at the end of the file and automatically
258 * adjust the settings for this buffer only. This must remain at the end
259 * of the file.
260 * ---------------------------------------------------------------------------
261 * Local variables:
262 * c-file-style: "linux"
263 * End:
264 */
diff --git a/arch/um/include/sysdep-x86_64/sigcontext.h b/arch/um/include/sysdep-x86_64/sigcontext.h
index 1e38a54ff4cf..2a78260d15a0 100644
--- a/arch/um/include/sysdep-x86_64/sigcontext.h
+++ b/arch/um/include/sysdep-x86_64/sigcontext.h
@@ -17,11 +17,12 @@
17#define SC_FAULT_ADDR(sc) SC_CR2(sc) 17#define SC_FAULT_ADDR(sc) SC_CR2(sc)
18#define SC_FAULT_TYPE(sc) SC_ERR(sc) 18#define SC_FAULT_TYPE(sc) SC_ERR(sc)
19 19
20#define FAULT_WRITE(err) ((err) & 2) 20#define GET_FAULTINFO_FROM_SC(fi,sc) \
21 21 { \
22#define SC_FAULT_WRITE(sc) FAULT_WRITE(SC_FAULT_TYPE(sc)) 22 (fi).cr2 = SC_CR2(sc); \
23 23 (fi).error_code = SC_ERR(sc); \
24#define SC_TRAP_TYPE(sc) SC_TRAPNO(sc) 24 (fi).trap_no = SC_TRAPNO(sc); \
25 }
25 26
26/* ptrace expects that, at the start of a system call, %eax contains 27/* ptrace expects that, at the start of a system call, %eax contains
27 * -ENOSYS, so this makes it so. 28 * -ENOSYS, so this makes it so.
@@ -29,8 +30,8 @@
29 30
30#define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0) 31#define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0)
31 32
32#define SEGV_IS_FIXABLE(trap) ((trap) == 14) 33/* This is Page Fault */
33#define SC_SEGV_IS_FIXABLE(sc) SEGV_IS_FIXABLE(SC_TRAP_TYPE(sc)) 34#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
34 35
35extern unsigned long *sc_sigmask(void *sc_ptr); 36extern unsigned long *sc_sigmask(void *sc_ptr);
36 37
diff --git a/arch/um/include/sysdep-x86_64/signal.h b/arch/um/include/sysdep-x86_64/signal.h
index e5e52756fab4..6142897af3d1 100644
--- a/arch/um/include/sysdep-x86_64/signal.h
+++ b/arch/um/include/sysdep-x86_64/signal.h
@@ -6,6 +6,8 @@
6#ifndef __X86_64_SIGNAL_H_ 6#ifndef __X86_64_SIGNAL_H_
7#define __X86_64_SIGNAL_H_ 7#define __X86_64_SIGNAL_H_
8 8
9#define ARCH_SIGHDLR_PARAM int sig
10
9#define ARCH_GET_SIGCONTEXT(sc, sig_addr) \ 11#define ARCH_GET_SIGCONTEXT(sc, sig_addr) \
10 do { \ 12 do { \
11 struct ucontext *__uc; \ 13 struct ucontext *__uc; \
diff --git a/arch/um/include/sysdep-x86_64/skas_ptrace.h b/arch/um/include/sysdep-x86_64/skas_ptrace.h
new file mode 100644
index 000000000000..95db4be786e4
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/skas_ptrace.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SYSDEP_X86_64_SKAS_PTRACE_H
7#define __SYSDEP_X86_64_SKAS_PTRACE_H
8
9struct ptrace_faultinfo {
10 int is_write;
11 unsigned long addr;
12};
13
14struct ptrace_ldt {
15 int func;
16 void *ptr;
17 unsigned long bytecount;
18};
19
20#define PTRACE_LDT 54
21
22#endif
diff --git a/arch/um/include/sysrq.h b/arch/um/include/sysrq.h
index 2ce9423460b3..c8d332b56b98 100644
--- a/arch/um/include/sysrq.h
+++ b/arch/um/include/sysrq.h
@@ -1,6 +1,7 @@
1#ifndef __UM_SYSRQ_H 1#ifndef __UM_SYSRQ_H
2#define __UM_SYSRQ_H 2#define __UM_SYSRQ_H
3 3
4extern void show_trace(unsigned long *stack); 4struct task_struct;
5extern void show_trace(struct task_struct* task, unsigned long *stack);
5 6
6#endif 7#endif
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
index 103cd320386c..7b6a24dfd302 100644
--- a/arch/um/include/user_util.h
+++ b/arch/um/include/user_util.h
@@ -41,9 +41,6 @@ extern unsigned long highmem;
41extern char host_info[]; 41extern char host_info[];
42 42
43extern char saved_command_line[]; 43extern char saved_command_line[];
44extern char command_line[];
45
46extern char *tempdir;
47 44
48extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; 45extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end;
49extern unsigned long _unprotected_end; 46extern unsigned long _unprotected_end;
@@ -67,7 +64,6 @@ extern void *um_kmalloc(int size);
67extern int switcheroo(int fd, int prot, void *from, void *to, int size); 64extern int switcheroo(int fd, int prot, void *from, void *to, int size);
68extern void setup_machinename(char *machine_out); 65extern void setup_machinename(char *machine_out);
69extern void setup_hostinfo(void); 66extern void setup_hostinfo(void);
70extern void add_arg(char *arg);
71extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)); 67extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
72extern void init_new_thread_signals(int altstack); 68extern void init_new_thread_signals(int altstack);
73extern void do_exec(int old_pid, int new_pid); 69extern void do_exec(int old_pid, int new_pid);
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 246f0e7fb4cc..a8918e80df96 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -4,9 +4,9 @@
4# 4#
5 5
6extra-y := vmlinux.lds 6extra-y := vmlinux.lds
7clean-files := vmlinux.lds.S config.tmp 7clean-files :=
8 8
9obj-y = checksum.o config.o exec_kern.o exitcode.o \ 9obj-y = config.o exec_kern.o exitcode.o \
10 helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \ 10 helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \
11 physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \ 11 physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \
12 sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \ 12 sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \
@@ -14,7 +14,7 @@ obj-y = checksum.o config.o exec_kern.o exitcode.o \
14 tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \ 14 tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \
15 user_util.o 15 user_util.o
16 16
17obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o 17obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
18obj-$(CONFIG_GPROF) += gprof_syms.o 18obj-$(CONFIG_GPROF) += gprof_syms.o
19obj-$(CONFIG_GCOV) += gmon_syms.o 19obj-$(CONFIG_GCOV) += gmon_syms.o
20obj-$(CONFIG_TTY_LOG) += tty_log.o 20obj-$(CONFIG_TTY_LOG) += tty_log.o
@@ -23,18 +23,14 @@ obj-$(CONFIG_SYSCALL_DEBUG) += syscall_user.o
23obj-$(CONFIG_MODE_TT) += tt/ 23obj-$(CONFIG_MODE_TT) += tt/
24obj-$(CONFIG_MODE_SKAS) += skas/ 24obj-$(CONFIG_MODE_SKAS) += skas/
25 25
26# This needs be compiled with frame pointers regardless of how the rest of the
27# kernel is built.
28CFLAGS_frame.o := -fno-omit-frame-pointer
29
30user-objs-$(CONFIG_TTY_LOG) += tty_log.o 26user-objs-$(CONFIG_TTY_LOG) += tty_log.o
31 27
32USER_OBJS := $(user-objs-y) config.o helper.o main.o process.o tempfile.o \ 28USER_OBJS := $(user-objs-y) config.o helper.o main.o process.o tempfile.o \
33 time.o tty_log.o umid.o user_util.o frame.o 29 time.o tty_log.o umid.o user_util.o
34 30
35include arch/um/scripts/Makefile.rules 31include arch/um/scripts/Makefile.rules
36 32
37targets += config.c 33targets := config.c config.tmp
38 34
39# Be careful with the below Sed code - sed is pitfall-rich! 35# Be careful with the below Sed code - sed is pitfall-rich!
40# We use sed to lower build requirements, for "embedded" builders for instance. 36# We use sed to lower build requirements, for "embedded" builders for instance.
diff --git a/arch/um/kernel/checksum.c b/arch/um/kernel/checksum.c
deleted file mode 100644
index e69b2be951d1..000000000000
--- a/arch/um/kernel/checksum.c
+++ /dev/null
@@ -1,36 +0,0 @@
1#include "asm/uaccess.h"
2#include "linux/errno.h"
3#include "linux/module.h"
4
5unsigned int arch_csum_partial(const unsigned char *buff, int len, int sum);
6
7unsigned int csum_partial(unsigned char *buff, int len, int sum)
8{
9 return arch_csum_partial(buff, len, sum);
10}
11
12EXPORT_SYMBOL(csum_partial);
13
14unsigned int csum_partial_copy_to(const unsigned char *src,
15 unsigned char __user *dst, int len, int sum,
16 int *err_ptr)
17{
18 if(copy_to_user(dst, src, len)){
19 *err_ptr = -EFAULT;
20 return(-1);
21 }
22
23 return(arch_csum_partial(src, len, sum));
24}
25
26unsigned int csum_partial_copy_from(const unsigned char __user *src,
27 unsigned char *dst, int len, int sum,
28 int *err_ptr)
29{
30 if(copy_from_user(dst, src, len)){
31 *err_ptr = -EFAULT;
32 return(-1);
33 }
34
35 return arch_csum_partial(dst, len, sum);
36}
diff --git a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec_kern.c
index 49ddabe69be7..efd222ffe20e 100644
--- a/arch/um/kernel/exec_kern.c
+++ b/arch/um/kernel/exec_kern.c
@@ -16,7 +16,6 @@
16#include "kern.h" 16#include "kern.h"
17#include "irq_user.h" 17#include "irq_user.h"
18#include "tlb.h" 18#include "tlb.h"
19#include "2_5compat.h"
20#include "os.h" 19#include "os.h"
21#include "time_user.h" 20#include "time_user.h"
22#include "choose-mode.h" 21#include "choose-mode.h"
diff --git a/arch/um/kernel/initrd_kern.c b/arch/um/kernel/initrd.c
index fc568af468b9..82ecf904b09c 100644
--- a/arch/um/kernel/initrd_kern.c
+++ b/arch/um/kernel/initrd.c
@@ -41,12 +41,31 @@ static int __init uml_initrd_setup(char *line, int *add)
41 return 0; 41 return 0;
42} 42}
43 43
44__uml_setup("initrd=", uml_initrd_setup, 44__uml_setup("initrd=", uml_initrd_setup,
45"initrd=<initrd image>\n" 45"initrd=<initrd image>\n"
46" This is used to boot UML from an initrd image. The argument is the\n" 46" This is used to boot UML from an initrd image. The argument is the\n"
47" name of the file containing the image.\n\n" 47" name of the file containing the image.\n\n"
48); 48);
49 49
50int load_initrd(char *filename, void *buf, int size)
51{
52 int fd, n;
53
54 fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
55 if(fd < 0){
56 printk("Opening '%s' failed - err = %d\n", filename, -fd);
57 return(-1);
58 }
59 n = os_read_file(fd, buf, size);
60 if(n != size){
61 printk("Read of %d bytes from '%s' failed, err = %d\n", size,
62 filename, -n);
63 return(-1);
64 }
65
66 os_close_file(fd);
67 return(0);
68}
50/* 69/*
51 * Overrides for Emacs so that we follow Linus's tabbing style. 70 * Overrides for Emacs so that we follow Linus's tabbing style.
52 * Emacs will notice this stuff at the end of the file and automatically 71 * Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/kernel/initrd_user.c b/arch/um/kernel/initrd_user.c
deleted file mode 100644
index cb90681e151c..000000000000
--- a/arch/um/kernel/initrd_user.c
+++ /dev/null
@@ -1,46 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <unistd.h>
7#include <sys/types.h>
8#include <sys/stat.h>
9#include <errno.h>
10
11#include "user_util.h"
12#include "kern_util.h"
13#include "user.h"
14#include "initrd.h"
15#include "os.h"
16
17int load_initrd(char *filename, void *buf, int size)
18{
19 int fd, n;
20
21 fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
22 if(fd < 0){
23 printk("Opening '%s' failed - err = %d\n", filename, -fd);
24 return(-1);
25 }
26 n = os_read_file(fd, buf, size);
27 if(n != size){
28 printk("Read of %d bytes from '%s' failed, err = %d\n", size,
29 filename, -n);
30 return(-1);
31 }
32
33 os_close_file(fd);
34 return(0);
35}
36
37/*
38 * Overrides for Emacs so that we follow Linus's tabbing style.
39 * Emacs will notice this stuff at the end of the file and automatically
40 * adjust the settings for this buffer only. This must remain at the end
41 * of the file.
42 * ---------------------------------------------------------------------------
43 * Local variables:
44 * c-file-style: "linux"
45 * End:
46 */
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index d71e8f00810f..d44fb5282547 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -163,7 +163,6 @@ void __init init_IRQ(void)
163 irq_desc[i].handler = &SIGIO_irq_type; 163 irq_desc[i].handler = &SIGIO_irq_type;
164 enable_irq(i); 164 enable_irq(i);
165 } 165 }
166 init_irq_signals(0);
167} 166}
168 167
169/* 168/*
diff --git a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c
index 6d6f9484b884..b3074cbaa479 100644
--- a/arch/um/kernel/irq_user.c
+++ b/arch/um/kernel/irq_user.c
@@ -236,9 +236,15 @@ static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
236 (*prev)->fd, pollfds[i].fd); 236 (*prev)->fd, pollfds[i].fd);
237 goto out; 237 goto out;
238 } 238 }
239 memcpy(&pollfds[i], &pollfds[i + 1], 239
240 (pollfds_num - i - 1) * sizeof(pollfds[0]));
241 pollfds_num--; 240 pollfds_num--;
241
242 /* This moves the *whole* array after pollfds[i] (though
243 * it doesn't spot as such)! */
244
245 memmove(&pollfds[i], &pollfds[i + 1],
246 (pollfds_num - i) * sizeof(pollfds[0]));
247
242 if(last_irq_ptr == &old_fd->next) 248 if(last_irq_ptr == &old_fd->next)
243 last_irq_ptr = prev; 249 last_irq_ptr = prev;
244 *prev = (*prev)->next; 250 *prev = (*prev)->next;
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index b41d3397d07b..99439fa15ef4 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -10,7 +10,6 @@
10#include "linux/spinlock.h" 10#include "linux/spinlock.h"
11#include "linux/highmem.h" 11#include "linux/highmem.h"
12#include "asm/current.h" 12#include "asm/current.h"
13#include "asm/delay.h"
14#include "asm/processor.h" 13#include "asm/processor.h"
15#include "asm/unistd.h" 14#include "asm/unistd.h"
16#include "asm/pgalloc.h" 15#include "asm/pgalloc.h"
@@ -28,8 +27,6 @@ EXPORT_SYMBOL(uml_physmem);
28EXPORT_SYMBOL(set_signals); 27EXPORT_SYMBOL(set_signals);
29EXPORT_SYMBOL(get_signals); 28EXPORT_SYMBOL(get_signals);
30EXPORT_SYMBOL(kernel_thread); 29EXPORT_SYMBOL(kernel_thread);
31EXPORT_SYMBOL(__const_udelay);
32EXPORT_SYMBOL(__udelay);
33EXPORT_SYMBOL(sys_waitpid); 30EXPORT_SYMBOL(sys_waitpid);
34EXPORT_SYMBOL(task_size); 31EXPORT_SYMBOL(task_size);
35EXPORT_SYMBOL(flush_tlb_range); 32EXPORT_SYMBOL(flush_tlb_range);
@@ -60,6 +57,7 @@ EXPORT_SYMBOL(copy_to_user_tt);
60EXPORT_SYMBOL(strncpy_from_user_skas); 57EXPORT_SYMBOL(strncpy_from_user_skas);
61EXPORT_SYMBOL(copy_to_user_skas); 58EXPORT_SYMBOL(copy_to_user_skas);
62EXPORT_SYMBOL(copy_from_user_skas); 59EXPORT_SYMBOL(copy_from_user_skas);
60EXPORT_SYMBOL(clear_user_skas);
63#endif 61#endif
64EXPORT_SYMBOL(uml_strdup); 62EXPORT_SYMBOL(uml_strdup);
65 63
diff --git a/arch/um/kernel/main.c b/arch/um/kernel/main.c
index a17c49703f9b..e59f58152678 100644
--- a/arch/um/kernel/main.c
+++ b/arch/um/kernel/main.c
@@ -24,8 +24,6 @@
24#include "mode.h" 24#include "mode.h"
25#include "choose-mode.h" 25#include "choose-mode.h"
26#include "uml-config.h" 26#include "uml-config.h"
27#include "irq_user.h"
28#include "time_user.h"
29#include "os.h" 27#include "os.h"
30 28
31/* Set in set_stklim, which is called from main and __wrap_malloc. 29/* Set in set_stklim, which is called from main and __wrap_malloc.
@@ -71,7 +69,7 @@ static __init void do_uml_initcalls(void)
71 69
72static void last_ditch_exit(int sig) 70static void last_ditch_exit(int sig)
73{ 71{
74 CHOOSE_MODE(kmalloc_ok = 0, (void) 0); 72 kmalloc_ok = 0;
75 signal(SIGINT, SIG_DFL); 73 signal(SIGINT, SIG_DFL);
76 signal(SIGTERM, SIG_DFL); 74 signal(SIGTERM, SIG_DFL);
77 signal(SIGHUP, SIG_DFL); 75 signal(SIGHUP, SIG_DFL);
@@ -87,7 +85,7 @@ int main(int argc, char **argv, char **envp)
87{ 85{
88 char **new_argv; 86 char **new_argv;
89 sigset_t mask; 87 sigset_t mask;
90 int ret, i; 88 int ret, i, err;
91 89
92 /* Enable all signals except SIGIO - in some environments, we can 90 /* Enable all signals except SIGIO - in some environments, we can
93 * enter with some signals blocked 91 * enter with some signals blocked
@@ -160,27 +158,29 @@ int main(int argc, char **argv, char **envp)
160 */ 158 */
161 change_sig(SIGPROF, 0); 159 change_sig(SIGPROF, 0);
162 160
163 /* Reboot */ 161 /* This signal stuff used to be in the reboot case. However,
164 if(ret){ 162 * sometimes a SIGVTALRM can come in when we're halting (reproducably
165 int err; 163 * when writing out gcov information, presumably because that takes
164 * some time) and cause a segfault.
165 */
166 166
167 printf("\n"); 167 /* stop timers and set SIG*ALRM to be ignored */
168 disable_timer();
168 169
169 /* stop timers and set SIG*ALRM to be ignored */ 170 /* disable SIGIO for the fds and set SIGIO to be ignored */
170 disable_timer(); 171 err = deactivate_all_fds();
172 if(err)
173 printf("deactivate_all_fds failed, errno = %d\n", -err);
171 174
172 /* disable SIGIO for the fds and set SIGIO to be ignored */ 175 /* Let any pending signals fire now. This ensures
173 err = deactivate_all_fds(); 176 * that they won't be delivered after the exec, when
174 if(err) 177 * they are definitely not expected.
175 printf("deactivate_all_fds failed, errno = %d\n", 178 */
176 -err); 179 unblock_signals();
177
178 /* Let any pending signals fire now. This ensures
179 * that they won't be delivered after the exec, when
180 * they are definitely not expected.
181 */
182 unblock_signals();
183 180
181 /* Reboot */
182 if(ret){
183 printf("\n");
184 execvp(new_argv[0], new_argv); 184 execvp(new_argv[0], new_argv);
185 perror("Failed to exec kernel"); 185 perror("Failed to exec kernel");
186 ret = 1; 186 ret = 1;
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index f156661781cb..c22825f13e40 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -100,12 +100,37 @@ void mem_init(void)
100#endif 100#endif
101} 101}
102 102
103/*
104 * Create a page table and place a pointer to it in a middle page
105 * directory entry.
106 */
107static void __init one_page_table_init(pmd_t *pmd)
108{
109 if (pmd_none(*pmd)) {
110 pte_t *pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
111 set_pmd(pmd, __pmd(_KERNPG_TABLE +
112 (unsigned long) __pa(pte)));
113 if (pte != pte_offset_kernel(pmd, 0))
114 BUG();
115 }
116}
117
118static void __init one_md_table_init(pud_t *pud)
119{
120#ifdef CONFIG_3_LEVEL_PGTABLES
121 pmd_t *pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
122 set_pud(pud, __pud(_KERNPG_TABLE + (unsigned long) __pa(pmd_table)));
123 if (pmd_table != pmd_offset(pud, 0))
124 BUG();
125#endif
126}
127
103static void __init fixrange_init(unsigned long start, unsigned long end, 128static void __init fixrange_init(unsigned long start, unsigned long end,
104 pgd_t *pgd_base) 129 pgd_t *pgd_base)
105{ 130{
106 pgd_t *pgd; 131 pgd_t *pgd;
132 pud_t *pud;
107 pmd_t *pmd; 133 pmd_t *pmd;
108 pte_t *pte;
109 int i, j; 134 int i, j;
110 unsigned long vaddr; 135 unsigned long vaddr;
111 136
@@ -115,15 +140,12 @@ static void __init fixrange_init(unsigned long start, unsigned long end,
115 pgd = pgd_base + i; 140 pgd = pgd_base + i;
116 141
117 for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) { 142 for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) {
118 pmd = (pmd_t *)pgd; 143 pud = pud_offset(pgd, vaddr);
144 if (pud_none(*pud))
145 one_md_table_init(pud);
146 pmd = pmd_offset(pud, vaddr);
119 for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { 147 for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
120 if (pmd_none(*pmd)) { 148 one_page_table_init(pmd);
121 pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
122 set_pmd(pmd, __pmd(_KERNPG_TABLE +
123 (unsigned long) __pa(pte)));
124 if (pte != pte_offset_kernel(pmd, 0))
125 BUG();
126 }
127 vaddr += PMD_SIZE; 149 vaddr += PMD_SIZE;
128 } 150 }
129 j = 0; 151 j = 0;
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index f76a2692adca..1b5ef3e96c71 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -30,7 +30,6 @@
30#include "init.h" 30#include "init.h"
31#include "os.h" 31#include "os.h"
32#include "uml-config.h" 32#include "uml-config.h"
33#include "ptrace_user.h"
34#include "choose-mode.h" 33#include "choose-mode.h"
35#include "mode.h" 34#include "mode.h"
36#ifdef UML_CONFIG_MODE_SKAS 35#ifdef UML_CONFIG_MODE_SKAS
@@ -65,8 +64,6 @@ void init_new_thread_signals(int altstack)
65 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 64 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
66 set_handler(SIGBUS, (__sighandler_t) sig_handler, flags, 65 set_handler(SIGBUS, (__sighandler_t) sig_handler, flags,
67 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 66 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
68 set_handler(SIGWINCH, (__sighandler_t) sig_handler, flags,
69 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
70 set_handler(SIGUSR2, (__sighandler_t) sig_handler, 67 set_handler(SIGUSR2, (__sighandler_t) sig_handler,
71 flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 68 flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
72 signal(SIGHUP, SIG_IGN); 69 signal(SIGHUP, SIG_IGN);
@@ -133,7 +130,7 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack,
133 return(arg.pid); 130 return(arg.pid);
134} 131}
135 132
136static int ptrace_child(void *arg) 133static int ptrace_child(void)
137{ 134{
138 int ret; 135 int ret;
139 int pid = os_getpid(), ppid = getppid(); 136 int pid = os_getpid(), ppid = getppid();
@@ -162,20 +159,16 @@ static int ptrace_child(void *arg)
162 _exit(ret); 159 _exit(ret);
163} 160}
164 161
165static int start_ptraced_child(void **stack_out) 162static int start_ptraced_child(void)
166{ 163{
167 void *stack;
168 unsigned long sp;
169 int pid, n, status; 164 int pid, n, status;
170 165
171 stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, 166 pid = fork();
172 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 167 if(pid == 0)
173 if(stack == MAP_FAILED) 168 ptrace_child();
174 panic("check_ptrace : mmap failed, errno = %d", errno); 169
175 sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
176 pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
177 if(pid < 0) 170 if(pid < 0)
178 panic("check_ptrace : clone failed, errno = %d", errno); 171 panic("check_ptrace : fork failed, errno = %d", errno);
179 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 172 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
180 if(n < 0) 173 if(n < 0)
181 panic("check_ptrace : wait failed, errno = %d", errno); 174 panic("check_ptrace : wait failed, errno = %d", errno);
@@ -183,7 +176,6 @@ static int start_ptraced_child(void **stack_out)
183 panic("check_ptrace : expected SIGSTOP, got status = %d", 176 panic("check_ptrace : expected SIGSTOP, got status = %d",
184 status); 177 status);
185 178
186 *stack_out = stack;
187 return(pid); 179 return(pid);
188} 180}
189 181
@@ -191,12 +183,12 @@ static int start_ptraced_child(void **stack_out)
191 * just avoid using sysemu, not panic, but only if SYSEMU features are broken. 183 * just avoid using sysemu, not panic, but only if SYSEMU features are broken.
192 * So only for SYSEMU features we test mustpanic, while normal host features 184 * So only for SYSEMU features we test mustpanic, while normal host features
193 * must work anyway!*/ 185 * must work anyway!*/
194static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) 186static int stop_ptraced_child(int pid, int exitcode, int mustexit)
195{ 187{
196 int status, n, ret = 0; 188 int status, n, ret = 0;
197 189
198 if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) 190 if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
199 panic("check_ptrace : ptrace failed, errno = %d", errno); 191 panic("stop_ptraced_child : ptrace failed, errno = %d", errno);
200 CATCH_EINTR(n = waitpid(pid, &status, 0)); 192 CATCH_EINTR(n = waitpid(pid, &status, 0));
201 if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { 193 if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
202 int exit_with = WEXITSTATUS(status); 194 int exit_with = WEXITSTATUS(status);
@@ -207,15 +199,13 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic)
207 printk("check_ptrace : child exited with exitcode %d, while " 199 printk("check_ptrace : child exited with exitcode %d, while "
208 "expecting %d; status 0x%x", exit_with, 200 "expecting %d; status 0x%x", exit_with,
209 exitcode, status); 201 exitcode, status);
210 if (mustpanic) 202 if (mustexit)
211 panic("\n"); 203 panic("\n");
212 else 204 else
213 printk("\n"); 205 printk("\n");
214 ret = -1; 206 ret = -1;
215 } 207 }
216 208
217 if(munmap(stack, PAGE_SIZE) < 0)
218 panic("check_ptrace : munmap failed, errno = %d", errno);
219 return ret; 209 return ret;
220} 210}
221 211
@@ -237,12 +227,11 @@ __uml_setup("nosysemu", nosysemu_cmd_param,
237 227
238static void __init check_sysemu(void) 228static void __init check_sysemu(void)
239{ 229{
240 void *stack;
241 int pid, syscall, n, status, count=0; 230 int pid, syscall, n, status, count=0;
242 231
243 printk("Checking syscall emulation patch for ptrace..."); 232 printk("Checking syscall emulation patch for ptrace...");
244 sysemu_supported = 0; 233 sysemu_supported = 0;
245 pid = start_ptraced_child(&stack); 234 pid = start_ptraced_child();
246 235
247 if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) 236 if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0)
248 goto fail; 237 goto fail;
@@ -260,7 +249,7 @@ static void __init check_sysemu(void)
260 panic("check_sysemu : failed to modify system " 249 panic("check_sysemu : failed to modify system "
261 "call return, errno = %d", errno); 250 "call return, errno = %d", errno);
262 251
263 if (stop_ptraced_child(pid, stack, 0, 0) < 0) 252 if (stop_ptraced_child(pid, 0, 0) < 0)
264 goto fail_stopped; 253 goto fail_stopped;
265 254
266 sysemu_supported = 1; 255 sysemu_supported = 1;
@@ -268,7 +257,7 @@ static void __init check_sysemu(void)
268 set_using_sysemu(!force_sysemu_disabled); 257 set_using_sysemu(!force_sysemu_disabled);
269 258
270 printk("Checking advanced syscall emulation patch for ptrace..."); 259 printk("Checking advanced syscall emulation patch for ptrace...");
271 pid = start_ptraced_child(&stack); 260 pid = start_ptraced_child();
272 while(1){ 261 while(1){
273 count++; 262 count++;
274 if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) 263 if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0)
@@ -293,7 +282,7 @@ static void __init check_sysemu(void)
293 break; 282 break;
294 } 283 }
295 } 284 }
296 if (stop_ptraced_child(pid, stack, 0, 0) < 0) 285 if (stop_ptraced_child(pid, 0, 0) < 0)
297 goto fail_stopped; 286 goto fail_stopped;
298 287
299 sysemu_supported = 2; 288 sysemu_supported = 2;
@@ -304,18 +293,17 @@ static void __init check_sysemu(void)
304 return; 293 return;
305 294
306fail: 295fail:
307 stop_ptraced_child(pid, stack, 1, 0); 296 stop_ptraced_child(pid, 1, 0);
308fail_stopped: 297fail_stopped:
309 printk("missing\n"); 298 printk("missing\n");
310} 299}
311 300
312void __init check_ptrace(void) 301void __init check_ptrace(void)
313{ 302{
314 void *stack;
315 int pid, syscall, n, status; 303 int pid, syscall, n, status;
316 304
317 printk("Checking that ptrace can change system call numbers..."); 305 printk("Checking that ptrace can change system call numbers...");
318 pid = start_ptraced_child(&stack); 306 pid = start_ptraced_child();
319 307
320 if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) 308 if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
321 panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno); 309 panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno);
@@ -342,7 +330,7 @@ void __init check_ptrace(void)
342 break; 330 break;
343 } 331 }
344 } 332 }
345 stop_ptraced_child(pid, stack, 0, 1); 333 stop_ptraced_child(pid, 0, 1);
346 printk("OK\n"); 334 printk("OK\n");
347 check_sysemu(); 335 check_sysemu();
348} 336}
@@ -374,11 +362,10 @@ void forward_pending_sigio(int target)
374static inline int check_skas3_ptrace_support(void) 362static inline int check_skas3_ptrace_support(void)
375{ 363{
376 struct ptrace_faultinfo fi; 364 struct ptrace_faultinfo fi;
377 void *stack;
378 int pid, n, ret = 1; 365 int pid, n, ret = 1;
379 366
380 printf("Checking for the skas3 patch in the host..."); 367 printf("Checking for the skas3 patch in the host...");
381 pid = start_ptraced_child(&stack); 368 pid = start_ptraced_child();
382 369
383 n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); 370 n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
384 if (n < 0) { 371 if (n < 0) {
@@ -393,7 +380,7 @@ static inline int check_skas3_ptrace_support(void)
393 } 380 }
394 381
395 init_registers(pid); 382 init_registers(pid);
396 stop_ptraced_child(pid, stack, 1, 1); 383 stop_ptraced_child(pid, 1, 1);
397 384
398 return(ret); 385 return(ret);
399} 386}
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index 7a943696f950..804c6bbdf67c 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -43,7 +43,6 @@
43#include "tlb.h" 43#include "tlb.h"
44#include "frame_kern.h" 44#include "frame_kern.h"
45#include "sigcontext.h" 45#include "sigcontext.h"
46#include "2_5compat.h"
47#include "os.h" 46#include "os.h"
48#include "mode.h" 47#include "mode.h"
49#include "mode_kern.h" 48#include "mode_kern.h"
@@ -55,18 +54,6 @@
55 */ 54 */
56struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } }; 55struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
57 56
58struct task_struct *get_task(int pid, int require)
59{
60 struct task_struct *ret;
61
62 read_lock(&tasklist_lock);
63 ret = find_task_by_pid(pid);
64 read_unlock(&tasklist_lock);
65
66 if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
67 return(ret);
68}
69
70int external_pid(void *t) 57int external_pid(void *t)
71{ 58{
72 struct task_struct *task = t ? t : current; 59 struct task_struct *task = t ? t : current;
@@ -115,16 +102,6 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
115 return(pid); 102 return(pid);
116} 103}
117 104
118void switch_mm(struct mm_struct *prev, struct mm_struct *next,
119 struct task_struct *tsk)
120{
121 int cpu = smp_processor_id();
122
123 if (prev != next)
124 cpu_clear(cpu, prev->cpu_vm_mask);
125 cpu_set(cpu, next->cpu_vm_mask);
126}
127
128void set_current(void *t) 105void set_current(void *t)
129{ 106{
130 struct task_struct *task = t; 107 struct task_struct *task = t;
@@ -152,7 +129,6 @@ void release_thread(struct task_struct *task)
152 129
153void exit_thread(void) 130void exit_thread(void)
154{ 131{
155 CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
156 unprotect_stack((unsigned long) current_thread); 132 unprotect_stack((unsigned long) current_thread);
157} 133}
158 134
@@ -200,7 +176,6 @@ void default_idle(void)
200 176
201 while(1){ 177 while(1){
202 /* endless idle loop with no priority at all */ 178 /* endless idle loop with no priority at all */
203 SET_PRI(current);
204 179
205 /* 180 /*
206 * although we are an idle CPU, we do not want to 181 * although we are an idle CPU, we do not want to
@@ -223,11 +198,6 @@ int page_size(void)
223 return(PAGE_SIZE); 198 return(PAGE_SIZE);
224} 199}
225 200
226unsigned long page_mask(void)
227{
228 return(PAGE_MASK);
229}
230
231void *um_virt_to_phys(struct task_struct *task, unsigned long addr, 201void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
232 pte_t *pte_out) 202 pte_t *pte_out)
233{ 203{
@@ -360,11 +330,6 @@ char *uml_strdup(char *string)
360 return(new); 330 return(new);
361} 331}
362 332
363void *get_init_task(void)
364{
365 return(&init_thread_union.thread_info.task);
366}
367
368int copy_to_user_proc(void __user *to, void *from, int size) 333int copy_to_user_proc(void __user *to, void *from, int size)
369{ 334{
370 return(copy_to_user(to, from, size)); 335 return(copy_to_user(to, from, size));
@@ -476,21 +441,18 @@ int singlestepping(void * t)
476 return 2; 441 return 2;
477} 442}
478 443
444/*
445 * Only x86 and x86_64 have an arch_align_stack().
446 * All other arches have "#define arch_align_stack(x) (x)"
447 * in their asm/system.h
448 * As this is included in UML from asm-um/system-generic.h,
449 * we can use it to behave as the subarch does.
450 */
451#ifndef arch_align_stack
479unsigned long arch_align_stack(unsigned long sp) 452unsigned long arch_align_stack(unsigned long sp)
480{ 453{
481 if (randomize_va_space) 454 if (randomize_va_space)
482 sp -= get_random_int() % 8192; 455 sp -= get_random_int() % 8192;
483 return sp & ~0xf; 456 return sp & ~0xf;
484} 457}
485 458#endif
486
487/*
488 * Overrides for Emacs so that we follow Linus's tabbing style.
489 * Emacs will notice this stuff at the end of the file and automatically
490 * adjust the settings for this buffer only. This must remain at the end
491 * of the file.
492 * ---------------------------------------------------------------------------
493 * Local variables:
494 * c-file-style: "linux"
495 * End:
496 */
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index e50e60ff5d27..71af4d503899 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -19,15 +19,30 @@
19#include "skas_ptrace.h" 19#include "skas_ptrace.h"
20#include "sysdep/ptrace.h" 20#include "sysdep/ptrace.h"
21 21
22static inline void set_singlestepping(struct task_struct *child, int on)
23{
24 if (on)
25 child->ptrace |= PT_DTRACE;
26 else
27 child->ptrace &= ~PT_DTRACE;
28 child->thread.singlestep_syscall = 0;
29
30#ifdef SUBARCH_SET_SINGLESTEPPING
31 SUBARCH_SET_SINGLESTEPPING(child, on);
32#endif
33}
34
22/* 35/*
23 * Called by kernel/ptrace.c when detaching.. 36 * Called by kernel/ptrace.c when detaching..
24 */ 37 */
25void ptrace_disable(struct task_struct *child) 38void ptrace_disable(struct task_struct *child)
26{ 39{
27 child->ptrace &= ~PT_DTRACE; 40 set_singlestepping(child,0);
28 child->thread.singlestep_syscall = 0;
29} 41}
30 42
43extern int peek_user(struct task_struct * child, long addr, long data);
44extern int poke_user(struct task_struct * child, long addr, long data);
45
31long sys_ptrace(long request, long pid, long addr, long data) 46long sys_ptrace(long request, long pid, long addr, long data)
32{ 47{
33 struct task_struct *child; 48 struct task_struct *child;
@@ -67,6 +82,10 @@ long sys_ptrace(long request, long pid, long addr, long data)
67 goto out_tsk; 82 goto out_tsk;
68 } 83 }
69 84
85#ifdef SUBACH_PTRACE_SPECIAL
86 SUBARCH_PTRACE_SPECIAL(child,request,addr,data);
87#endif
88
70 ret = ptrace_check_attach(child, request == PTRACE_KILL); 89 ret = ptrace_check_attach(child, request == PTRACE_KILL);
71 if (ret < 0) 90 if (ret < 0)
72 goto out_tsk; 91 goto out_tsk;
@@ -87,26 +106,9 @@ long sys_ptrace(long request, long pid, long addr, long data)
87 } 106 }
88 107
89 /* read the word at location addr in the USER area. */ 108 /* read the word at location addr in the USER area. */
90 case PTRACE_PEEKUSR: { 109 case PTRACE_PEEKUSR:
91 unsigned long tmp; 110 ret = peek_user(child, addr, data);
92 111 break;
93 ret = -EIO;
94 if ((addr & 3) || addr < 0)
95 break;
96
97 tmp = 0; /* Default return condition */
98 if(addr < MAX_REG_OFFSET){
99 tmp = getreg(child, addr);
100 }
101 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
102 (addr <= offsetof(struct user, u_debugreg[7]))){
103 addr -= offsetof(struct user, u_debugreg[0]);
104 addr = addr >> 2;
105 tmp = child->thread.arch.debugregs[addr];
106 }
107 ret = put_user(tmp, (unsigned long __user *) data);
108 break;
109 }
110 112
111 /* when I and D space are separate, this will have to be fixed. */ 113 /* when I and D space are separate, this will have to be fixed. */
112 case PTRACE_POKETEXT: /* write the word at location addr. */ 114 case PTRACE_POKETEXT: /* write the word at location addr. */
@@ -119,26 +121,8 @@ long sys_ptrace(long request, long pid, long addr, long data)
119 break; 121 break;
120 122
121 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ 123 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
122 ret = -EIO; 124 ret = poke_user(child, addr, data);
123 if ((addr & 3) || addr < 0) 125 break;
124 break;
125
126 if (addr < MAX_REG_OFFSET) {
127 ret = putreg(child, addr, data);
128 break;
129 }
130#if 0 /* XXX x86_64 */
131 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
132 (addr <= offsetof(struct user, u_debugreg[7]))){
133 addr -= offsetof(struct user, u_debugreg[0]);
134 addr = addr >> 2;
135 if((addr == 4) || (addr == 5)) break;
136 child->thread.arch.debugregs[addr] = data;
137 ret = 0;
138 }
139#endif
140
141 break;
142 126
143 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ 127 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
144 case PTRACE_CONT: { /* restart after signal. */ 128 case PTRACE_CONT: { /* restart after signal. */
@@ -146,8 +130,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
146 if (!valid_signal(data)) 130 if (!valid_signal(data))
147 break; 131 break;
148 132
149 child->ptrace &= ~PT_DTRACE; 133 set_singlestepping(child, 0);
150 child->thread.singlestep_syscall = 0;
151 if (request == PTRACE_SYSCALL) { 134 if (request == PTRACE_SYSCALL) {
152 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 135 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
153 } 136 }
@@ -170,8 +153,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
170 if (child->exit_state == EXIT_ZOMBIE) /* already dead */ 153 if (child->exit_state == EXIT_ZOMBIE) /* already dead */
171 break; 154 break;
172 155
173 child->ptrace &= ~PT_DTRACE; 156 set_singlestepping(child, 0);
174 child->thread.singlestep_syscall = 0;
175 child->exit_code = SIGKILL; 157 child->exit_code = SIGKILL;
176 wake_up_process(child); 158 wake_up_process(child);
177 break; 159 break;
@@ -182,8 +164,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
182 if (!valid_signal(data)) 164 if (!valid_signal(data))
183 break; 165 break;
184 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 166 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
185 child->ptrace |= PT_DTRACE; 167 set_singlestepping(child, 1);
186 child->thread.singlestep_syscall = 0;
187 child->exit_code = data; 168 child->exit_code = data;
188 /* give it a chance to run. */ 169 /* give it a chance to run. */
189 wake_up_process(child); 170 wake_up_process(child);
@@ -250,23 +231,19 @@ long sys_ptrace(long request, long pid, long addr, long data)
250 break; 231 break;
251#endif 232#endif
252 case PTRACE_FAULTINFO: { 233 case PTRACE_FAULTINFO: {
253 struct ptrace_faultinfo fault; 234 /* Take the info from thread->arch->faultinfo,
254 235 * but transfer max. sizeof(struct ptrace_faultinfo).
255 fault = ((struct ptrace_faultinfo) 236 * On i386, ptrace_faultinfo is smaller!
256 { .is_write = child->thread.err, 237 */
257 .addr = child->thread.cr2 }); 238 ret = copy_to_user((unsigned long __user *) data,
258 ret = copy_to_user((unsigned long __user *) data, &fault, 239 &child->thread.arch.faultinfo,
259 sizeof(fault)); 240 sizeof(struct ptrace_faultinfo));
260 if(ret) 241 if(ret)
261 break; 242 break;
262 break; 243 break;
263 } 244 }
264 case PTRACE_SIGPENDING:
265 ret = copy_to_user((unsigned long __user *) data,
266 &child->pending.signal,
267 sizeof(child->pending.signal));
268 break;
269 245
246#ifdef PTRACE_LDT
270 case PTRACE_LDT: { 247 case PTRACE_LDT: {
271 struct ptrace_ldt ldt; 248 struct ptrace_ldt ldt;
272 249
@@ -282,6 +259,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
282 ret = -EIO; 259 ret = -EIO;
283 break; 260 break;
284 } 261 }
262#endif
285#ifdef CONFIG_PROC_MM 263#ifdef CONFIG_PROC_MM
286 case PTRACE_SWITCH_MM: { 264 case PTRACE_SWITCH_MM: {
287 struct mm_struct *old = child->mm; 265 struct mm_struct *old = child->mm;
@@ -337,15 +315,16 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit)
337 315
338 if (unlikely(current->audit_context)) { 316 if (unlikely(current->audit_context)) {
339 if (!entryexit) 317 if (!entryexit)
340 audit_syscall_entry(current, 318 audit_syscall_entry(current,
341 UPT_SYSCALL_NR(&regs->regs), 319 HOST_AUDIT_ARCH,
342 UPT_SYSCALL_ARG1(&regs->regs), 320 UPT_SYSCALL_NR(regs),
343 UPT_SYSCALL_ARG2(&regs->regs), 321 UPT_SYSCALL_ARG1(regs),
344 UPT_SYSCALL_ARG3(&regs->regs), 322 UPT_SYSCALL_ARG2(regs),
345 UPT_SYSCALL_ARG4(&regs->regs)); 323 UPT_SYSCALL_ARG3(regs),
346 else 324 UPT_SYSCALL_ARG4(regs));
347 audit_syscall_exit(current, 325 else audit_syscall_exit(current,
348 UPT_SYSCALL_RET(&regs->regs)); 326 AUDITSC_RESULT(UPT_SYSCALL_RET(regs)),
327 UPT_SYSCALL_RET(regs));
349 } 328 }
350 329
351 /* Fake a debug trap */ 330 /* Fake a debug trap */
@@ -375,14 +354,3 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit)
375 current->exit_code = 0; 354 current->exit_code = 0;
376 } 355 }
377} 356}
378
379/*
380 * Overrides for Emacs so that we follow Linus's tabbing style.
381 * Emacs will notice this stuff at the end of the file and automatically
382 * adjust the settings for this buffer only. This must remain at the end
383 * of the file.
384 * ---------------------------------------------------------------------------
385 * Local variables:
386 * c-file-style: "linux"
387 * End:
388 */
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
index 668df13d8c9d..e89218958f38 100644
--- a/arch/um/kernel/sigio_user.c
+++ b/arch/um/kernel/sigio_user.c
@@ -182,6 +182,7 @@ static int write_sigio_thread(void *unused)
182 int i, n, respond_fd; 182 int i, n, respond_fd;
183 char c; 183 char c;
184 184
185 signal(SIGWINCH, SIG_IGN);
185 fds = &current_poll; 186 fds = &current_poll;
186 while(1){ 187 while(1){
187 n = poll(fds->poll, fds->used, -1); 188 n = poll(fds->poll, fds->used, -1);
diff --git a/arch/um/kernel/skas/include/mode_kern-skas.h b/arch/um/kernel/skas/include/mode_kern-skas.h
index 94c564962378..e48490028111 100644
--- a/arch/um/kernel/skas/include/mode_kern-skas.h
+++ b/arch/um/kernel/skas/include/mode_kern-skas.h
@@ -18,7 +18,6 @@ extern int copy_thread_skas(int nr, unsigned long clone_flags,
18 unsigned long sp, unsigned long stack_top, 18 unsigned long sp, unsigned long stack_top,
19 struct task_struct *p, struct pt_regs *regs); 19 struct task_struct *p, struct pt_regs *regs);
20extern void release_thread_skas(struct task_struct *task); 20extern void release_thread_skas(struct task_struct *task);
21extern void exit_thread_skas(void);
22extern void initial_thread_cb_skas(void (*proc)(void *), void *arg); 21extern void initial_thread_cb_skas(void (*proc)(void *), void *arg);
23extern void init_idle_skas(void); 22extern void init_idle_skas(void);
24extern void flush_tlb_kernel_range_skas(unsigned long start, 23extern void flush_tlb_kernel_range_skas(unsigned long start,
diff --git a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h
index f0702c2c7204..96b51dba3471 100644
--- a/arch/um/kernel/skas/include/skas.h
+++ b/arch/um/kernel/skas/include/skas.h
@@ -27,9 +27,10 @@ extern void map(int fd, unsigned long virt, unsigned long len, int r, int w,
27extern int unmap(int fd, void *addr, unsigned long len); 27extern int unmap(int fd, void *addr, unsigned long len);
28extern int protect(int fd, unsigned long addr, unsigned long len, 28extern int protect(int fd, unsigned long addr, unsigned long len,
29 int r, int w, int x); 29 int r, int w, int x);
30extern void user_signal(int sig, union uml_pt_regs *regs); 30extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
31extern int new_mm(int from); 31extern int new_mm(int from);
32extern void start_userspace(int cpu); 32extern void start_userspace(int cpu);
33extern void get_skas_faultinfo(int pid, struct faultinfo * fi);
33extern long execute_syscall_skas(void *r); 34extern long execute_syscall_skas(void *r);
34 35
35#endif 36#endif
diff --git a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/kernel/skas/include/uaccess-skas.h
index c35620385da0..cd6c280482cb 100644
--- a/arch/um/kernel/skas/include/uaccess-skas.h
+++ b/arch/um/kernel/skas/include/uaccess-skas.h
@@ -18,8 +18,8 @@
18 ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ 18 ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
19 ((unsigned long) (addr) + (size) >= (unsigned long)(addr)))) 19 ((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
20 20
21static inline int __deprecated verify_area_skas(int type, const void * addr, 21static inline int verify_area_skas(int type, const void * addr,
22 unsigned long size) 22 unsigned long size)
23{ 23{
24 return(access_ok_skas(type, addr, size) ? 0 : -EFAULT); 24 return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
25} 25}
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index b4ffaaa81241..773cd2b525fc 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -4,6 +4,7 @@
4 */ 4 */
5 5
6#include <stdlib.h> 6#include <stdlib.h>
7#include <string.h>
7#include <unistd.h> 8#include <unistd.h>
8#include <errno.h> 9#include <errno.h>
9#include <signal.h> 10#include <signal.h>
@@ -27,27 +28,37 @@
27#include "chan_user.h" 28#include "chan_user.h"
28#include "signal_user.h" 29#include "signal_user.h"
29#include "registers.h" 30#include "registers.h"
31#include "process.h"
30 32
31int is_skas_winch(int pid, int fd, void *data) 33int is_skas_winch(int pid, int fd, void *data)
32{ 34{
33 if(pid != os_getpid()) 35 if(pid != os_getpgrp())
34 return(0); 36 return(0);
35 37
36 register_winch_irq(-1, fd, -1, data); 38 register_winch_irq(-1, fd, -1, data);
37 return(1); 39 return(1);
38} 40}
39 41
40static void handle_segv(int pid) 42void get_skas_faultinfo(int pid, struct faultinfo * fi)
41{ 43{
42 struct ptrace_faultinfo fault;
43 int err; 44 int err;
44 45
45 err = ptrace(PTRACE_FAULTINFO, pid, 0, &fault); 46 err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
46 if(err) 47 if(err)
47 panic("handle_segv - PTRACE_FAULTINFO failed, errno = %d\n", 48 panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
48 errno); 49 "errno = %d\n", errno);
50
51 /* Special handling for i386, which has different structs */
52 if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo))
53 memset((char *)fi + sizeof(struct ptrace_faultinfo), 0,
54 sizeof(struct faultinfo) -
55 sizeof(struct ptrace_faultinfo));
56}
49 57
50 segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL); 58static void handle_segv(int pid, union uml_pt_regs * regs)
59{
60 get_skas_faultinfo(pid, &regs->skas.faultinfo);
61 segv(regs->skas.faultinfo, 0, 1, NULL);
51} 62}
52 63
53/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/ 64/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/
@@ -163,7 +174,7 @@ void userspace(union uml_pt_regs *regs)
163 if(WIFSTOPPED(status)){ 174 if(WIFSTOPPED(status)){
164 switch(WSTOPSIG(status)){ 175 switch(WSTOPSIG(status)){
165 case SIGSEGV: 176 case SIGSEGV:
166 handle_segv(pid); 177 handle_segv(pid, regs);
167 break; 178 break;
168 case SIGTRAP + 0x80: 179 case SIGTRAP + 0x80:
169 handle_trap(pid, regs, local_using_sysemu); 180 handle_trap(pid, regs, local_using_sysemu);
@@ -177,7 +188,7 @@ void userspace(union uml_pt_regs *regs)
177 case SIGBUS: 188 case SIGBUS:
178 case SIGFPE: 189 case SIGFPE:
179 case SIGWINCH: 190 case SIGWINCH:
180 user_signal(WSTOPSIG(status), regs); 191 user_signal(WSTOPSIG(status), regs, pid);
181 break; 192 break;
182 default: 193 default:
183 printk("userspace - child stopped with signal " 194 printk("userspace - child stopped with signal "
@@ -190,6 +201,11 @@ void userspace(union uml_pt_regs *regs)
190 } 201 }
191 } 202 }
192} 203}
204#define INIT_JMP_NEW_THREAD 0
205#define INIT_JMP_REMOVE_SIGSTACK 1
206#define INIT_JMP_CALLBACK 2
207#define INIT_JMP_HALT 3
208#define INIT_JMP_REBOOT 4
193 209
194void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, 210void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
195 void (*handler)(int)) 211 void (*handler)(int))
@@ -225,7 +241,7 @@ void thread_wait(void *sw, void *fb)
225 *switch_buf = &buf; 241 *switch_buf = &buf;
226 fork_buf = fb; 242 fork_buf = fb;
227 if(sigsetjmp(buf, 1) == 0) 243 if(sigsetjmp(buf, 1) == 0)
228 siglongjmp(*fork_buf, 1); 244 siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK);
229} 245}
230 246
231void switch_threads(void *me, void *next) 247void switch_threads(void *me, void *next)
@@ -249,23 +265,31 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
249 sigjmp_buf **switch_buf = switch_buf_ptr; 265 sigjmp_buf **switch_buf = switch_buf_ptr;
250 int n; 266 int n;
251 267
268 set_handler(SIGWINCH, (__sighandler_t) sig_handler,
269 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
270 SIGVTALRM, -1);
271
252 *fork_buf_ptr = &initial_jmpbuf; 272 *fork_buf_ptr = &initial_jmpbuf;
253 n = sigsetjmp(initial_jmpbuf, 1); 273 n = sigsetjmp(initial_jmpbuf, 1);
254 if(n == 0) 274 switch(n){
255 new_thread_proc((void *) stack, new_thread_handler); 275 case INIT_JMP_NEW_THREAD:
256 else if(n == 1) 276 new_thread_proc((void *) stack, new_thread_handler);
257 remove_sigstack(); 277 break;
258 else if(n == 2){ 278 case INIT_JMP_REMOVE_SIGSTACK:
279 remove_sigstack();
280 break;
281 case INIT_JMP_CALLBACK:
259 (*cb_proc)(cb_arg); 282 (*cb_proc)(cb_arg);
260 siglongjmp(*cb_back, 1); 283 siglongjmp(*cb_back, 1);
261 } 284 break;
262 else if(n == 3){ 285 case INIT_JMP_HALT:
263 kmalloc_ok = 0; 286 kmalloc_ok = 0;
264 return(0); 287 return(0);
265 } 288 case INIT_JMP_REBOOT:
266 else if(n == 4){
267 kmalloc_ok = 0; 289 kmalloc_ok = 0;
268 return(1); 290 return(1);
291 default:
292 panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
269 } 293 }
270 siglongjmp(**switch_buf, 1); 294 siglongjmp(**switch_buf, 1);
271} 295}
@@ -290,7 +314,7 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
290 314
291 block_signals(); 315 block_signals();
292 if(sigsetjmp(here, 1) == 0) 316 if(sigsetjmp(here, 1) == 0)
293 siglongjmp(initial_jmpbuf, 2); 317 siglongjmp(initial_jmpbuf, INIT_JMP_CALLBACK);
294 unblock_signals(); 318 unblock_signals();
295 319
296 cb_proc = NULL; 320 cb_proc = NULL;
@@ -301,13 +325,13 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
301void halt_skas(void) 325void halt_skas(void)
302{ 326{
303 block_signals(); 327 block_signals();
304 siglongjmp(initial_jmpbuf, 3); 328 siglongjmp(initial_jmpbuf, INIT_JMP_HALT);
305} 329}
306 330
307void reboot_skas(void) 331void reboot_skas(void)
308{ 332{
309 block_signals(); 333 block_signals();
310 siglongjmp(initial_jmpbuf, 4); 334 siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT);
311} 335}
312 336
313void switch_mm_skas(int mm_fd) 337void switch_mm_skas(int mm_fd)
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index 5d096ea63b97..fc71ef295782 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -68,8 +68,11 @@ void new_thread_handler(int sig)
68 * 0 if it just exits 68 * 0 if it just exits
69 */ 69 */
70 n = run_kernel_thread(fn, arg, &current->thread.exec_buf); 70 n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
71 if(n == 1) 71 if(n == 1){
72 /* Handle any immediate reschedules or signals */
73 interrupt_end();
72 userspace(&current->thread.regs.regs); 74 userspace(&current->thread.regs.regs);
75 }
73 else do_exit(0); 76 else do_exit(0);
74} 77}
75 78
@@ -83,10 +86,6 @@ void release_thread_skas(struct task_struct *task)
83{ 86{
84} 87}
85 88
86void exit_thread_skas(void)
87{
88}
89
90void fork_handler(int sig) 89void fork_handler(int sig)
91{ 90{
92 change_sig(SIGUSR1, 1); 91 change_sig(SIGUSR1, 1);
@@ -100,6 +99,8 @@ void fork_handler(int sig)
100 schedule_tail(current->thread.prev_sched); 99 schedule_tail(current->thread.prev_sched);
101 current->thread.prev_sched = NULL; 100 current->thread.prev_sched = NULL;
102 101
102 /* Handle any immediate reschedules or signals */
103 interrupt_end();
103 userspace(&current->thread.regs.regs); 104 userspace(&current->thread.regs.regs);
104} 105}
105 106
diff --git a/arch/um/kernel/skas/trap_user.c b/arch/um/kernel/skas/trap_user.c
index 8e9b46d4702e..0dee1d95c806 100644
--- a/arch/um/kernel/skas/trap_user.c
+++ b/arch/um/kernel/skas/trap_user.c
@@ -5,12 +5,15 @@
5 5
6#include <signal.h> 6#include <signal.h>
7#include <errno.h> 7#include <errno.h>
8#include "sysdep/ptrace.h"
9#include "signal_user.h" 8#include "signal_user.h"
10#include "user_util.h" 9#include "user_util.h"
11#include "kern_util.h" 10#include "kern_util.h"
12#include "task.h" 11#include "task.h"
13#include "sigcontext.h" 12#include "sigcontext.h"
13#include "skas.h"
14#include "ptrace_user.h"
15#include "sysdep/ptrace.h"
16#include "sysdep/ptrace_user.h"
14 17
15void sig_handler_common_skas(int sig, void *sc_ptr) 18void sig_handler_common_skas(int sig, void *sc_ptr)
16{ 19{
@@ -31,9 +34,11 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
31 r = &TASK_REGS(get_current())->skas; 34 r = &TASK_REGS(get_current())->skas;
32 save_user = r->is_user; 35 save_user = r->is_user;
33 r->is_user = 0; 36 r->is_user = 0;
34 r->fault_addr = SC_FAULT_ADDR(sc); 37 if ( sig == SIGFPE || sig == SIGSEGV ||
35 r->fault_type = SC_FAULT_TYPE(sc); 38 sig == SIGBUS || sig == SIGILL ||
36 r->trap_type = SC_TRAP_TYPE(sc); 39 sig == SIGTRAP ) {
40 GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
41 }
37 42
38 change_sig(SIGUSR1, 1); 43 change_sig(SIGUSR1, 1);
39 info = &sig_info[sig]; 44 info = &sig_info[sig];
@@ -45,14 +50,17 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
45 r->is_user = save_user; 50 r->is_user = save_user;
46} 51}
47 52
48void user_signal(int sig, union uml_pt_regs *regs) 53extern int ptrace_faultinfo;
54
55void user_signal(int sig, union uml_pt_regs *regs, int pid)
49{ 56{
50 struct signal_info *info; 57 struct signal_info *info;
58 int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
59 (sig == SIGILL) || (sig == SIGTRAP));
51 60
52 regs->skas.is_user = 1; 61 regs->skas.is_user = 1;
53 regs->skas.fault_addr = 0; 62 if (segv)
54 regs->skas.fault_type = 0; 63 get_skas_faultinfo(pid, &regs->skas.faultinfo);
55 regs->skas.trap_type = 0;
56 info = &sig_info[sig]; 64 info = &sig_info[sig];
57 (*info->handler)(sig, regs); 65 (*info->handler)(sig, regs);
58 66
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index f7da9d027672..75195281081e 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -29,9 +29,12 @@ static unsigned long maybe_map(unsigned long virt, int is_write)
29 if(IS_ERR(phys) || (is_write && !pte_write(pte))){ 29 if(IS_ERR(phys) || (is_write && !pte_write(pte))){
30 err = handle_page_fault(virt, 0, is_write, 1, &dummy_code); 30 err = handle_page_fault(virt, 0, is_write, 1, &dummy_code);
31 if(err) 31 if(err)
32 return(0); 32 return(-1UL);
33 phys = um_virt_to_phys(current, virt, NULL); 33 phys = um_virt_to_phys(current, virt, NULL);
34 } 34 }
35 if(IS_ERR(phys))
36 phys = (void *) -1;
37
35 return((unsigned long) phys); 38 return((unsigned long) phys);
36} 39}
37 40
@@ -42,7 +45,7 @@ static int do_op(unsigned long addr, int len, int is_write,
42 int n; 45 int n;
43 46
44 addr = maybe_map(addr, is_write); 47 addr = maybe_map(addr, is_write);
45 if(addr == -1) 48 if(addr == -1UL)
46 return(-1); 49 return(-1);
47 50
48 page = phys_to_page(addr); 51 page = phys_to_page(addr);
diff --git a/arch/um/kernel/skas/util/Makefile b/arch/um/kernel/skas/util/Makefile
index 17f5909d60f7..f7b7eba83340 100644
--- a/arch/um/kernel/skas/util/Makefile
+++ b/arch/um/kernel/skas/util/Makefile
@@ -2,3 +2,4 @@ hostprogs-y := mk_ptregs
2always := $(hostprogs-y) 2always := $(hostprogs-y)
3 3
4mk_ptregs-objs := mk_ptregs-$(SUBARCH).o 4mk_ptregs-objs := mk_ptregs-$(SUBARCH).o
5HOSTCFLAGS_mk_ptregs-$(SUBARCH).o := -I$(objtree)/arch/um
diff --git a/arch/um/kernel/skas/util/mk_ptregs-i386.c b/arch/um/kernel/skas/util/mk_ptregs-i386.c
index 0788dd05bcac..1f96e1eeb8a7 100644
--- a/arch/um/kernel/skas/util/mk_ptregs-i386.c
+++ b/arch/um/kernel/skas/util/mk_ptregs-i386.c
@@ -1,8 +1,7 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <asm/ptrace.h> 2#include <user-offsets.h>
3#include <asm/user.h>
4 3
5#define PRINT_REG(name, val) printf("#define HOST_%s %d\n", (name), (val)) 4#define SHOW(name) printf("#define %s %d\n", #name, name)
6 5
7int main(int argc, char **argv) 6int main(int argc, char **argv)
8{ 7{
@@ -12,28 +11,27 @@ int main(int argc, char **argv)
12 printf("#ifndef __SKAS_PT_REGS_\n"); 11 printf("#ifndef __SKAS_PT_REGS_\n");
13 printf("#define __SKAS_PT_REGS_\n"); 12 printf("#define __SKAS_PT_REGS_\n");
14 printf("\n"); 13 printf("\n");
15 printf("#define HOST_FRAME_SIZE %d\n", FRAME_SIZE); 14 SHOW(HOST_FRAME_SIZE);
16 printf("#define HOST_FP_SIZE %d\n", 15 SHOW(HOST_FP_SIZE);
17 sizeof(struct user_i387_struct) / sizeof(unsigned long)); 16 SHOW(HOST_XFP_SIZE);
18 printf("#define HOST_XFP_SIZE %d\n", 17
19 sizeof(struct user_fxsr_struct) / sizeof(unsigned long)); 18 SHOW(HOST_IP);
19 SHOW(HOST_SP);
20 SHOW(HOST_EFLAGS);
21 SHOW(HOST_EAX);
22 SHOW(HOST_EBX);
23 SHOW(HOST_ECX);
24 SHOW(HOST_EDX);
25 SHOW(HOST_ESI);
26 SHOW(HOST_EDI);
27 SHOW(HOST_EBP);
28 SHOW(HOST_CS);
29 SHOW(HOST_SS);
30 SHOW(HOST_DS);
31 SHOW(HOST_FS);
32 SHOW(HOST_ES);
33 SHOW(HOST_GS);
20 34
21 PRINT_REG("IP", EIP);
22 PRINT_REG("SP", UESP);
23 PRINT_REG("EFLAGS", EFL);
24 PRINT_REG("EAX", EAX);
25 PRINT_REG("EBX", EBX);
26 PRINT_REG("ECX", ECX);
27 PRINT_REG("EDX", EDX);
28 PRINT_REG("ESI", ESI);
29 PRINT_REG("EDI", EDI);
30 PRINT_REG("EBP", EBP);
31 PRINT_REG("CS", CS);
32 PRINT_REG("SS", SS);
33 PRINT_REG("DS", DS);
34 PRINT_REG("FS", FS);
35 PRINT_REG("ES", ES);
36 PRINT_REG("GS", GS);
37 printf("\n"); 35 printf("\n");
38 printf("#endif\n"); 36 printf("#endif\n");
39 return(0); 37 return(0);
diff --git a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c b/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
index 67aee92a70ef..5fccbfe35f78 100644
--- a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
+++ b/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
@@ -5,11 +5,10 @@
5 */ 5 */
6 6
7#include <stdio.h> 7#include <stdio.h>
8#define __FRAME_OFFSETS 8#include <user-offsets.h>
9#include <asm/ptrace.h>
10 9
11#define PRINT_REG(name, val) \ 10#define SHOW(name) \
12 printf("#define HOST_%s (%d / sizeof(unsigned long))\n", (name), (val)) 11 printf("#define %s (%d / sizeof(unsigned long))\n", #name, name)
13 12
14int main(int argc, char **argv) 13int main(int argc, char **argv)
15{ 14{
@@ -18,36 +17,35 @@ int main(int argc, char **argv)
18 printf("\n"); 17 printf("\n");
19 printf("#ifndef __SKAS_PT_REGS_\n"); 18 printf("#ifndef __SKAS_PT_REGS_\n");
20 printf("#define __SKAS_PT_REGS_\n"); 19 printf("#define __SKAS_PT_REGS_\n");
21 printf("#define HOST_FRAME_SIZE (%d / sizeof(unsigned long))\n", 20 SHOW(HOST_FRAME_SIZE);
22 FRAME_SIZE); 21 SHOW(HOST_RBX);
23 PRINT_REG("RBX", RBX); 22 SHOW(HOST_RCX);
24 PRINT_REG("RCX", RCX); 23 SHOW(HOST_RDI);
25 PRINT_REG("RDI", RDI); 24 SHOW(HOST_RSI);
26 PRINT_REG("RSI", RSI); 25 SHOW(HOST_RDX);
27 PRINT_REG("RDX", RDX); 26 SHOW(HOST_RBP);
28 PRINT_REG("RBP", RBP); 27 SHOW(HOST_RAX);
29 PRINT_REG("RAX", RAX); 28 SHOW(HOST_R8);
30 PRINT_REG("R8", R8); 29 SHOW(HOST_R9);
31 PRINT_REG("R9", R9); 30 SHOW(HOST_R10);
32 PRINT_REG("R10", R10); 31 SHOW(HOST_R11);
33 PRINT_REG("R11", R11); 32 SHOW(HOST_R12);
34 PRINT_REG("R12", R12); 33 SHOW(HOST_R13);
35 PRINT_REG("R13", R13); 34 SHOW(HOST_R14);
36 PRINT_REG("R14", R14); 35 SHOW(HOST_R15);
37 PRINT_REG("R15", R15); 36 SHOW(HOST_ORIG_RAX);
38 PRINT_REG("ORIG_RAX", ORIG_RAX); 37 SHOW(HOST_CS);
39 PRINT_REG("CS", CS); 38 SHOW(HOST_SS);
40 PRINT_REG("SS", SS); 39 SHOW(HOST_EFLAGS);
41 PRINT_REG("EFLAGS", EFLAGS);
42#if 0 40#if 0
43 PRINT_REG("FS", FS); 41 SHOW(HOST_FS);
44 PRINT_REG("GS", GS); 42 SHOW(HOST_GS);
45 PRINT_REG("DS", DS); 43 SHOW(HOST_DS);
46 PRINT_REG("ES", ES); 44 SHOW(HOST_ES);
47#endif 45#endif
48 46
49 PRINT_REG("IP", RIP); 47 SHOW(HOST_IP);
50 PRINT_REG("SP", RSP); 48 SHOW(HOST_SP);
51 printf("#define HOST_FP_SIZE 0\n"); 49 printf("#define HOST_FP_SIZE 0\n");
52 printf("#define HOST_XFP_SIZE 0\n"); 50 printf("#define HOST_XFP_SIZE 0\n");
53 printf("\n"); 51 printf("\n");
diff --git a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c
index 42731e04f50f..b7a55251e897 100644
--- a/arch/um/kernel/syscall_kern.c
+++ b/arch/um/kernel/syscall_kern.c
@@ -17,7 +17,6 @@
17#include "linux/utime.h" 17#include "linux/utime.h"
18#include "asm/mman.h" 18#include "asm/mman.h"
19#include "asm/uaccess.h" 19#include "asm/uaccess.h"
20#include "asm/ipc.h"
21#include "kern_util.h" 20#include "kern_util.h"
22#include "user_util.h" 21#include "user_util.h"
23#include "sysdep/syscalls.h" 22#include "sysdep/syscalls.h"
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
index e630438f9e73..f80850091e79 100644
--- a/arch/um/kernel/sysrq.c
+++ b/arch/um/kernel/sysrq.c
@@ -3,6 +3,7 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/config.h"
6#include "linux/sched.h" 7#include "linux/sched.h"
7#include "linux/kernel.h" 8#include "linux/kernel.h"
8#include "linux/module.h" 9#include "linux/module.h"
@@ -12,14 +13,14 @@
12#include "sysrq.h" 13#include "sysrq.h"
13#include "user_util.h" 14#include "user_util.h"
14 15
15void show_trace(unsigned long * stack) 16/* Catch non-i386 SUBARCH's. */
17#if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT)
18void show_trace(struct task_struct *task, unsigned long * stack)
16{ 19{
17 /* XXX: Copy the CONFIG_FRAME_POINTER stack-walking backtrace from
18 * arch/i386/kernel/traps.c, and then move this to sys-i386/sysrq.c.*/
19 unsigned long addr; 20 unsigned long addr;
20 21
21 if (!stack) { 22 if (!stack) {
22 stack = (unsigned long*) &stack; 23 stack = (unsigned long*) &stack;
23 WARN_ON(1); 24 WARN_ON(1);
24 } 25 }
25 26
@@ -35,6 +36,7 @@ void show_trace(unsigned long * stack)
35 } 36 }
36 printk("\n"); 37 printk("\n");
37} 38}
39#endif
38 40
39/* 41/*
40 * stack dumps generator - this is used by arch-independent code. 42 * stack dumps generator - this is used by arch-independent code.
@@ -44,7 +46,7 @@ void dump_stack(void)
44{ 46{
45 unsigned long stack; 47 unsigned long stack;
46 48
47 show_trace(&stack); 49 show_trace(current, &stack);
48} 50}
49EXPORT_SYMBOL(dump_stack); 51EXPORT_SYMBOL(dump_stack);
50 52
@@ -59,7 +61,11 @@ void show_stack(struct task_struct *task, unsigned long *esp)
59 int i; 61 int i;
60 62
61 if (esp == NULL) { 63 if (esp == NULL) {
62 if (task != current) { 64 if (task != current && task != NULL) {
65 /* XXX: Isn't this bogus? I.e. isn't this the
66 * *userspace* stack of this task? If not so, use this
67 * even when task == current (as in i386).
68 */
63 esp = (unsigned long *) KSTK_ESP(task); 69 esp = (unsigned long *) KSTK_ESP(task);
64 /* Which one? No actual difference - just coding style.*/ 70 /* Which one? No actual difference - just coding style.*/
65 //esp = (unsigned long *) PT_REGS_IP(&task->thread.regs); 71 //esp = (unsigned long *) PT_REGS_IP(&task->thread.regs);
@@ -77,5 +83,6 @@ void show_stack(struct task_struct *task, unsigned long *esp)
77 printk("%08lx ", *stack++); 83 printk("%08lx ", *stack++);
78 } 84 }
79 85
80 show_trace(esp); 86 printk("Call Trace: \n");
87 show_trace(current, esp);
81} 88}
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
index 2461cd73ca87..6516fc52afe0 100644
--- a/arch/um/kernel/time_kern.c
+++ b/arch/um/kernel/time_kern.c
@@ -48,8 +48,6 @@ static unsigned long long prev_usecs;
48static long long delta; /* Deviation per interval */ 48static long long delta; /* Deviation per interval */
49#endif 49#endif
50 50
51#define MILLION 1000000
52
53void timer_irq(union uml_pt_regs *regs) 51void timer_irq(union uml_pt_regs *regs)
54{ 52{
55 unsigned long long ticks = 0; 53 unsigned long long ticks = 0;
@@ -136,22 +134,6 @@ long um_stime(int __user *tptr)
136 return 0; 134 return 0;
137} 135}
138 136
139void __udelay(unsigned long usecs)
140{
141 int i, n;
142
143 n = (loops_per_jiffy * HZ * usecs) / MILLION;
144 for(i=0;i<n;i++) ;
145}
146
147void __const_udelay(unsigned long usecs)
148{
149 int i, n;
150
151 n = (loops_per_jiffy * HZ * usecs) / MILLION;
152 for(i=0;i<n;i++) ;
153}
154
155void timer_handler(int sig, union uml_pt_regs *regs) 137void timer_handler(int sig, union uml_pt_regs *regs)
156{ 138{
157 local_irq_disable(); 139 local_irq_disable();
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
index 47e766e6ba10..c20aef120598 100644
--- a/arch/um/kernel/trap_kern.c
+++ b/arch/um/kernel/trap_kern.c
@@ -23,7 +23,6 @@
23#include "kern.h" 23#include "kern.h"
24#include "chan_kern.h" 24#include "chan_kern.h"
25#include "mconsole_kern.h" 25#include "mconsole_kern.h"
26#include "2_5compat.h"
27#include "mem.h" 26#include "mem.h"
28#include "mem_kern.h" 27#include "mem_kern.h"
29 28
@@ -48,7 +47,7 @@ int handle_page_fault(unsigned long address, unsigned long ip,
48 goto good_area; 47 goto good_area;
49 else if(!(vma->vm_flags & VM_GROWSDOWN)) 48 else if(!(vma->vm_flags & VM_GROWSDOWN))
50 goto out; 49 goto out;
51 else if(!ARCH_IS_STACKGROW(address)) 50 else if(is_user && !ARCH_IS_STACKGROW(address))
52 goto out; 51 goto out;
53 else if(expand_stack(vma, address)) 52 else if(expand_stack(vma, address))
54 goto out; 53 goto out;
@@ -57,10 +56,11 @@ int handle_page_fault(unsigned long address, unsigned long ip,
57 *code_out = SEGV_ACCERR; 56 *code_out = SEGV_ACCERR;
58 if(is_write && !(vma->vm_flags & VM_WRITE)) 57 if(is_write && !(vma->vm_flags & VM_WRITE))
59 goto out; 58 goto out;
59
60 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
61 goto out;
62
60 page = address & PAGE_MASK; 63 page = address & PAGE_MASK;
61 pgd = pgd_offset(mm, page);
62 pud = pud_offset(pgd, page);
63 pmd = pmd_offset(pud, page);
64 do { 64 do {
65 survive: 65 survive:
66 switch (handle_mm_fault(mm, vma, address, is_write)){ 66 switch (handle_mm_fault(mm, vma, address, is_write)){
@@ -106,46 +106,24 @@ out_of_memory:
106 goto out; 106 goto out;
107} 107}
108 108
109LIST_HEAD(physmem_remappers); 109/*
110 110 * We give a *copy* of the faultinfo in the regs to segv.
111void register_remapper(struct remapper *info) 111 * This must be done, since nesting SEGVs could overwrite
112{ 112 * the info in the regs. A pointer to the info then would
113 list_add(&info->list, &physmem_remappers); 113 * give us bad data!
114} 114 */
115 115unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
116static int check_remapped_addr(unsigned long address, int is_write)
117{
118 struct remapper *remapper;
119 struct list_head *ele;
120 __u64 offset;
121 int fd;
122
123 fd = phys_mapping(__pa(address), &offset);
124 if(fd == -1)
125 return(0);
126
127 list_for_each(ele, &physmem_remappers){
128 remapper = list_entry(ele, struct remapper, list);
129 if((*remapper->proc)(fd, address, is_write, offset))
130 return(1);
131 }
132
133 return(0);
134}
135
136unsigned long segv(unsigned long address, unsigned long ip, int is_write,
137 int is_user, void *sc)
138{ 116{
139 struct siginfo si; 117 struct siginfo si;
140 void *catcher; 118 void *catcher;
141 int err; 119 int err;
120 int is_write = FAULT_WRITE(fi);
121 unsigned long address = FAULT_ADDRESS(fi);
142 122
143 if(!is_user && (address >= start_vm) && (address < end_vm)){ 123 if(!is_user && (address >= start_vm) && (address < end_vm)){
144 flush_tlb_kernel_vm(); 124 flush_tlb_kernel_vm();
145 return(0); 125 return(0);
146 } 126 }
147 else if(check_remapped_addr(address & PAGE_MASK, is_write))
148 return(0);
149 else if(current->mm == NULL) 127 else if(current->mm == NULL)
150 panic("Segfault with no mm"); 128 panic("Segfault with no mm");
151 err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); 129 err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
@@ -159,7 +137,7 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write,
159 } 137 }
160 else if(current->thread.fault_addr != NULL) 138 else if(current->thread.fault_addr != NULL)
161 panic("fault_addr set but no fault catcher"); 139 panic("fault_addr set but no fault catcher");
162 else if(arch_fixup(ip, sc)) 140 else if(!is_user && arch_fixup(ip, sc))
163 return(0); 141 return(0);
164 142
165 if(!is_user) 143 if(!is_user)
@@ -171,6 +149,7 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write,
171 si.si_errno = 0; 149 si.si_errno = 0;
172 si.si_code = BUS_ADRERR; 150 si.si_code = BUS_ADRERR;
173 si.si_addr = (void *)address; 151 si.si_addr = (void *)address;
152 current->thread.arch.faultinfo = fi;
174 force_sig_info(SIGBUS, &si, current); 153 force_sig_info(SIGBUS, &si, current);
175 } 154 }
176 else if(err == -ENOMEM){ 155 else if(err == -ENOMEM){
@@ -180,22 +159,20 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write,
180 else { 159 else {
181 si.si_signo = SIGSEGV; 160 si.si_signo = SIGSEGV;
182 si.si_addr = (void *) address; 161 si.si_addr = (void *) address;
183 current->thread.cr2 = address; 162 current->thread.arch.faultinfo = fi;
184 current->thread.err = is_write;
185 force_sig_info(SIGSEGV, &si, current); 163 force_sig_info(SIGSEGV, &si, current);
186 } 164 }
187 return(0); 165 return(0);
188} 166}
189 167
190void bad_segv(unsigned long address, unsigned long ip, int is_write) 168void bad_segv(struct faultinfo fi, unsigned long ip)
191{ 169{
192 struct siginfo si; 170 struct siginfo si;
193 171
194 si.si_signo = SIGSEGV; 172 si.si_signo = SIGSEGV;
195 si.si_code = SEGV_ACCERR; 173 si.si_code = SEGV_ACCERR;
196 si.si_addr = (void *) address; 174 si.si_addr = (void *) FAULT_ADDRESS(fi);
197 current->thread.cr2 = address; 175 current->thread.arch.faultinfo = fi;
198 current->thread.err = is_write;
199 force_sig_info(SIGSEGV, &si, current); 176 force_sig_info(SIGSEGV, &si, current);
200} 177}
201 178
@@ -204,6 +181,7 @@ void relay_signal(int sig, union uml_pt_regs *regs)
204 if(arch_handle_signal(sig, regs)) return; 181 if(arch_handle_signal(sig, regs)) return;
205 if(!UPT_IS_USER(regs)) 182 if(!UPT_IS_USER(regs))
206 panic("Kernel mode signal %d", sig); 183 panic("Kernel mode signal %d", sig);
184 current->thread.arch.faultinfo = *UPT_FAULTINFO(regs);
207 force_sig(sig, current); 185 force_sig(sig, current);
208} 186}
209 187
diff --git a/arch/um/kernel/trap_user.c b/arch/um/kernel/trap_user.c
index 50a4042a509f..f825a6eda3f5 100644
--- a/arch/um/kernel/trap_user.c
+++ b/arch/um/kernel/trap_user.c
@@ -54,23 +54,22 @@ struct {
54void segv_handler(int sig, union uml_pt_regs *regs) 54void segv_handler(int sig, union uml_pt_regs *regs)
55{ 55{
56 int index, max; 56 int index, max;
57 struct faultinfo * fi = UPT_FAULTINFO(regs);
57 58
58 if(UPT_IS_USER(regs) && !UPT_SEGV_IS_FIXABLE(regs)){ 59 if(UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)){
59 bad_segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), 60 bad_segv(*fi, UPT_IP(regs));
60 UPT_FAULT_WRITE(regs));
61 return; 61 return;
62 } 62 }
63 max = sizeof(segfault_record)/sizeof(segfault_record[0]); 63 max = sizeof(segfault_record)/sizeof(segfault_record[0]);
64 index = next_trap_index(max); 64 index = next_trap_index(max);
65 65
66 nsegfaults++; 66 nsegfaults++;
67 segfault_record[index].address = UPT_FAULT_ADDR(regs); 67 segfault_record[index].address = FAULT_ADDRESS(*fi);
68 segfault_record[index].pid = os_getpid(); 68 segfault_record[index].pid = os_getpid();
69 segfault_record[index].is_write = UPT_FAULT_WRITE(regs); 69 segfault_record[index].is_write = FAULT_WRITE(*fi);
70 segfault_record[index].sp = UPT_SP(regs); 70 segfault_record[index].sp = UPT_SP(regs);
71 segfault_record[index].is_user = UPT_IS_USER(regs); 71 segfault_record[index].is_user = UPT_IS_USER(regs);
72 segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), UPT_FAULT_WRITE(regs), 72 segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs);
73 UPT_IS_USER(regs), regs);
74} 73}
75 74
76void usr2_handler(int sig, union uml_pt_regs *regs) 75void usr2_handler(int sig, union uml_pt_regs *regs)
diff --git a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile
index 3d5177df3504..c3faea21a996 100644
--- a/arch/um/kernel/tt/Makefile
+++ b/arch/um/kernel/tt/Makefile
@@ -4,6 +4,7 @@
4# 4#
5 5
6extra-y := unmap_fin.o 6extra-y := unmap_fin.o
7targets := unmap.o
7clean-files := unmap_tmp.o 8clean-files := unmap_tmp.o
8 9
9obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \ 10obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
diff --git a/arch/um/kernel/tt/include/mode_kern-tt.h b/arch/um/kernel/tt/include/mode_kern-tt.h
index 28aaab3448fa..e0ca0e0b2516 100644
--- a/arch/um/kernel/tt/include/mode_kern-tt.h
+++ b/arch/um/kernel/tt/include/mode_kern-tt.h
@@ -19,7 +19,6 @@ extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
19 unsigned long stack_top, struct task_struct *p, 19 unsigned long stack_top, struct task_struct *p,
20 struct pt_regs *regs); 20 struct pt_regs *regs);
21extern void release_thread_tt(struct task_struct *task); 21extern void release_thread_tt(struct task_struct *task);
22extern void exit_thread_tt(void);
23extern void initial_thread_cb_tt(void (*proc)(void *), void *arg); 22extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
24extern void init_idle_tt(void); 23extern void init_idle_tt(void);
25extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end); 24extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end);
diff --git a/arch/um/kernel/tt/include/uaccess-tt.h b/arch/um/kernel/tt/include/uaccess-tt.h
index bb69d6b7d022..3fbb5fe26f49 100644
--- a/arch/um/kernel/tt/include/uaccess-tt.h
+++ b/arch/um/kernel/tt/include/uaccess-tt.h
@@ -33,8 +33,8 @@ extern unsigned long uml_physmem;
33 (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \ 33 (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
34 (under_task_size(addr, size) || is_stack(addr, size)))) 34 (under_task_size(addr, size) || is_stack(addr, size))))
35 35
36static inline int __deprecated verify_area_tt(int type, const void * addr, 36static inline int verify_area_tt(int type, const void * addr,
37 unsigned long size) 37 unsigned long size)
38{ 38{
39 return(access_ok_tt(type, addr, size) ? 0 : -EFAULT); 39 return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);
40} 40}
diff --git a/arch/um/kernel/tt/ksyms.c b/arch/um/kernel/tt/ksyms.c
index 92ec85d67c7c..84a9385a8fef 100644
--- a/arch/um/kernel/tt/ksyms.c
+++ b/arch/um/kernel/tt/ksyms.c
@@ -12,6 +12,7 @@ EXPORT_SYMBOL(__do_copy_to_user);
12EXPORT_SYMBOL(__do_strncpy_from_user); 12EXPORT_SYMBOL(__do_strncpy_from_user);
13EXPORT_SYMBOL(__do_strnlen_user); 13EXPORT_SYMBOL(__do_strnlen_user);
14EXPORT_SYMBOL(__do_clear_user); 14EXPORT_SYMBOL(__do_clear_user);
15EXPORT_SYMBOL(clear_user_tt);
15 16
16EXPORT_SYMBOL(tracing_pid); 17EXPORT_SYMBOL(tracing_pid);
17EXPORT_SYMBOL(honeypot); 18EXPORT_SYMBOL(honeypot);
diff --git a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c
index 74346a04a2b2..bcb8796c3cb1 100644
--- a/arch/um/kernel/tt/mem.c
+++ b/arch/um/kernel/tt/mem.c
@@ -21,14 +21,8 @@ void before_mem_tt(unsigned long brk_start)
21 remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(&_end), 1); 21 remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(&_end), 1);
22} 22}
23 23
24#ifdef CONFIG_HOST_2G_2G
25#define TOP 0x80000000
26#else
27#define TOP 0xc0000000
28#endif
29
30#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000) 24#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000)
31#define START (TOP - SIZE) 25#define START (CONFIG_TOP_ADDR - SIZE)
32 26
33unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, 27unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out,
34 unsigned long *task_size_out) 28 unsigned long *task_size_out)
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
index f19f7c18febe..776310fd5b8b 100644
--- a/arch/um/kernel/tt/process_kern.c
+++ b/arch/um/kernel/tt/process_kern.c
@@ -32,10 +32,6 @@ void *switch_to_tt(void *prev, void *next, void *last)
32 unsigned long flags; 32 unsigned long flags;
33 int err, vtalrm, alrm, prof, cpu; 33 int err, vtalrm, alrm, prof, cpu;
34 char c; 34 char c;
35 /* jailing and SMP are incompatible, so this doesn't need to be
36 * made per-cpu
37 */
38 static int reading;
39 35
40 from = prev; 36 from = prev;
41 to = next; 37 to = next;
@@ -59,14 +55,11 @@ void *switch_to_tt(void *prev, void *next, void *last)
59 c = 0; 55 c = 0;
60 set_current(to); 56 set_current(to);
61 57
62 reading = 0;
63 err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); 58 err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
64 if(err != sizeof(c)) 59 if(err != sizeof(c))
65 panic("write of switch_pipe failed, err = %d", -err); 60 panic("write of switch_pipe failed, err = %d", -err);
66 61
67 reading = 1; 62 if(from->thread.mode.tt.switch_pipe[0] == -1)
68 if((from->exit_state == EXIT_ZOMBIE) ||
69 (from->exit_state == EXIT_DEAD))
70 os_kill_process(os_getpid(), 0); 63 os_kill_process(os_getpid(), 0);
71 64
72 err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); 65 err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c));
@@ -81,8 +74,7 @@ void *switch_to_tt(void *prev, void *next, void *last)
81 * in case it has not already killed itself. 74 * in case it has not already killed itself.
82 */ 75 */
83 prev_sched = current->thread.prev_sched; 76 prev_sched = current->thread.prev_sched;
84 if((prev_sched->exit_state == EXIT_ZOMBIE) || 77 if(prev_sched->thread.mode.tt.switch_pipe[0] == -1)
85 (prev_sched->exit_state == EXIT_DEAD))
86 os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1); 78 os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1);
87 79
88 change_sig(SIGVTALRM, vtalrm); 80 change_sig(SIGVTALRM, vtalrm);
@@ -101,14 +93,18 @@ void release_thread_tt(struct task_struct *task)
101{ 93{
102 int pid = task->thread.mode.tt.extern_pid; 94 int pid = task->thread.mode.tt.extern_pid;
103 95
96 /*
97 * We first have to kill the other process, before
98 * closing its switch_pipe. Else it might wake up
99 * and receive "EOF" before we could kill it.
100 */
104 if(os_getpid() != pid) 101 if(os_getpid() != pid)
105 os_kill_process(pid, 0); 102 os_kill_process(pid, 0);
106}
107 103
108void exit_thread_tt(void) 104 os_close_file(task->thread.mode.tt.switch_pipe[0]);
109{ 105 os_close_file(task->thread.mode.tt.switch_pipe[1]);
110 os_close_file(current->thread.mode.tt.switch_pipe[0]); 106 /* use switch_pipe as flag: thread is released */
111 os_close_file(current->thread.mode.tt.switch_pipe[1]); 107 task->thread.mode.tt.switch_pipe[0] = -1;
112} 108}
113 109
114void suspend_new_thread(int fd) 110void suspend_new_thread(int fd)
diff --git a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c
index e4e7e9c2224c..b218316cfdb2 100644
--- a/arch/um/kernel/tt/syscall_user.c
+++ b/arch/um/kernel/tt/syscall_user.c
@@ -63,6 +63,10 @@ void do_syscall(void *task, int pid, int local_using_sysemu)
63 63
64 UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs); 64 UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs);
65 65
66#ifdef UPT_ORIGGPR2
67 UPT_ORIGGPR2(TASK_REGS(task)) = REGS_ORIGGPR2(proc_regs);
68#endif
69
66 if(((unsigned long *) PT_IP(proc_regs) >= &_stext) && 70 if(((unsigned long *) PT_IP(proc_regs) >= &_stext) &&
67 ((unsigned long *) PT_IP(proc_regs) <= &_etext)) 71 ((unsigned long *) PT_IP(proc_regs) <= &_etext))
68 tracer_panic("I'm tracing myself and I can't get out"); 72 tracer_panic("I'm tracing myself and I can't get out");
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
index 7b5d937e5955..d11e7399d7a1 100644
--- a/arch/um/kernel/tt/tracer.c
+++ b/arch/um/kernel/tt/tracer.c
@@ -26,6 +26,7 @@
26#include "kern_util.h" 26#include "kern_util.h"
27#include "chan_user.h" 27#include "chan_user.h"
28#include "ptrace_user.h" 28#include "ptrace_user.h"
29#include "irq_user.h"
29#include "mode.h" 30#include "mode.h"
30#include "tt.h" 31#include "tt.h"
31 32
@@ -33,7 +34,7 @@ static int tracer_winch[2];
33 34
34int is_tracer_winch(int pid, int fd, void *data) 35int is_tracer_winch(int pid, int fd, void *data)
35{ 36{
36 if(pid != tracing_pid) 37 if(pid != os_getpgrp())
37 return(0); 38 return(0);
38 39
39 register_winch_irq(tracer_winch[0], fd, -1, data); 40 register_winch_irq(tracer_winch[0], fd, -1, data);
@@ -89,8 +90,10 @@ void tracer_panic(char *format, ...)
89 90
90static void tracer_segv(int sig, struct sigcontext sc) 91static void tracer_segv(int sig, struct sigcontext sc)
91{ 92{
93 struct faultinfo fi;
94 GET_FAULTINFO_FROM_SC(fi, &sc);
92 printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n", 95 printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n",
93 SC_FAULT_ADDR(&sc), SC_IP(&sc)); 96 FAULT_ADDRESS(fi), SC_IP(&sc));
94 while(1) 97 while(1)
95 pause(); 98 pause();
96} 99}
@@ -117,6 +120,7 @@ static int signal_tramp(void *arg)
117 signal(SIGSEGV, (__sighandler_t) sig_handler); 120 signal(SIGSEGV, (__sighandler_t) sig_handler);
118 set_cmdline("(idle thread)"); 121 set_cmdline("(idle thread)");
119 set_init_pid(os_getpid()); 122 set_init_pid(os_getpid());
123 init_irq_signals(0);
120 proc = arg; 124 proc = arg;
121 return((*proc)(NULL)); 125 return((*proc)(NULL));
122} 126}
diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c
index 92a3820ca543..fc108615beaf 100644
--- a/arch/um/kernel/tt/trap_user.c
+++ b/arch/um/kernel/tt/trap_user.c
@@ -7,6 +7,7 @@
7#include <errno.h> 7#include <errno.h>
8#include <signal.h> 8#include <signal.h>
9#include "sysdep/ptrace.h" 9#include "sysdep/ptrace.h"
10#include "sysdep/sigcontext.h"
10#include "signal_user.h" 11#include "signal_user.h"
11#include "user_util.h" 12#include "user_util.h"
12#include "kern_util.h" 13#include "kern_util.h"
@@ -28,6 +29,11 @@ void sig_handler_common_tt(int sig, void *sc_ptr)
28 change_sig(SIGSEGV, 1); 29 change_sig(SIGSEGV, 1);
29 30
30 r = &TASK_REGS(get_current())->tt; 31 r = &TASK_REGS(get_current())->tt;
32 if ( sig == SIGFPE || sig == SIGSEGV ||
33 sig == SIGBUS || sig == SIGILL ||
34 sig == SIGTRAP ) {
35 GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
36 }
31 save_regs = *r; 37 save_regs = *r;
32 is_user = user_context(SC_SP(sc)); 38 is_user = user_context(SC_SP(sc));
33 r->sc = sc; 39 r->sc = sc;
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 5c49d88eed3d..8736d098f0ee 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -23,9 +23,9 @@
23#include "asm/ptrace.h" 23#include "asm/ptrace.h"
24#include "asm/elf.h" 24#include "asm/elf.h"
25#include "asm/user.h" 25#include "asm/user.h"
26#include "asm/setup.h"
26#include "ubd_user.h" 27#include "ubd_user.h"
27#include "asm/current.h" 28#include "asm/current.h"
28#include "asm/setup.h"
29#include "user_util.h" 29#include "user_util.h"
30#include "kern_util.h" 30#include "kern_util.h"
31#include "kern.h" 31#include "kern.h"
@@ -42,9 +42,9 @@
42#define DEFAULT_COMMAND_LINE "root=98:0" 42#define DEFAULT_COMMAND_LINE "root=98:0"
43 43
44/* Changed in linux_main and setup_arch, which run before SMP is started */ 44/* Changed in linux_main and setup_arch, which run before SMP is started */
45char command_line[COMMAND_LINE_SIZE] = { 0 }; 45static char command_line[COMMAND_LINE_SIZE] = { 0 };
46 46
47void add_arg(char *arg) 47static void add_arg(char *arg)
48{ 48{
49 if (strlen(command_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) { 49 if (strlen(command_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) {
50 printf("add_arg: Too many command line arguments!\n"); 50 printf("add_arg: Too many command line arguments!\n");
@@ -110,12 +110,6 @@ struct seq_operations cpuinfo_op = {
110 .show = show_cpuinfo, 110 .show = show_cpuinfo,
111}; 111};
112 112
113pte_t * __bad_pagetable(void)
114{
115 panic("Someone should implement __bad_pagetable");
116 return(NULL);
117}
118
119/* Set in linux_main */ 113/* Set in linux_main */
120unsigned long host_task_size; 114unsigned long host_task_size;
121unsigned long task_size; 115unsigned long task_size;
@@ -449,7 +443,7 @@ void __init setup_arch(char **cmdline_p)
449{ 443{
450 notifier_chain_register(&panic_notifier_list, &panic_exit_notifier); 444 notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
451 paging_init(); 445 paging_init();
452 strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); 446 strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
453 *cmdline_p = command_line; 447 *cmdline_p = command_line;
454 setup_hostinfo(); 448 setup_hostinfo();
455} 449}
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index 76eadb309189..dd5355500bdc 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -73,6 +73,8 @@ SECTIONS
73 73
74 .got : { *(.got.plt) *(.got) } 74 .got : { *(.got.plt) *(.got) }
75 .dynamic : { *(.dynamic) } 75 .dynamic : { *(.dynamic) }
76 .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
77 .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
76 /* We want the small data sections together, so single-instruction offsets 78 /* We want the small data sections together, so single-instruction offsets
77 can access them all, and initialized data all before uninitialized, so 79 can access them all, and initialized data all before uninitialized, so
78 we can shorten the on-disk segment size. */ 80 we can shorten the on-disk segment size. */
diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S
new file mode 100644
index 000000000000..1660a769674b
--- /dev/null
+++ b/arch/um/kernel/vmlinux.lds.S
@@ -0,0 +1,6 @@
1#include <linux/config.h>
2#ifdef CONFIG_LD_SCRIPT_STATIC
3#include "uml.lds.S"
4#else
5#include "dyn.lds.S"
6#endif
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c
index 9aee0b62ebca..f0d6060e3e57 100644
--- a/arch/um/os-Linux/elf_aux.c
+++ b/arch/um/os-Linux/elf_aux.c
@@ -45,7 +45,11 @@ __init void scan_elf_aux( char **envp)
45 elf_aux_hwcap = auxv->a_un.a_val; 45 elf_aux_hwcap = auxv->a_un.a_val;
46 break; 46 break;
47 case AT_PLATFORM: 47 case AT_PLATFORM:
48 elf_aux_platform = auxv->a_un.a_ptr; 48 /* elf.h removed the pointer elements from
49 * a_un, so we have to use a_val, which is
50 * all that's left.
51 */
52 elf_aux_platform = (char *) auxv->a_un.a_val;
49 break; 53 break;
50 case AT_PAGESZ: 54 case AT_PAGESZ:
51 page_size = auxv->a_un.a_val; 55 page_size = auxv->a_un.a_val;
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index 77d4066d1af8..fd45bb260907 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -363,7 +363,7 @@ int os_write_file(int fd, const void *buf, int len)
363 (int (*)(int, void *, int)) write, copy_to_user_proc)); 363 (int (*)(int, void *, int)) write, copy_to_user_proc));
364} 364}
365 365
366int os_file_size(char *file, long long *size_out) 366int os_file_size(char *file, unsigned long long *size_out)
367{ 367{
368 struct uml_stat buf; 368 struct uml_stat buf;
369 int err; 369 int err;
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index ba9ca1cc790a..1e126bfd31a7 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -123,6 +123,11 @@ int os_getpid(void)
123 return(getpid()); 123 return(getpid());
124} 124}
125 125
126int os_getpgrp(void)
127{
128 return getpgrp();
129}
130
126int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len, 131int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
127 int r, int w, int x) 132 int r, int w, int x)
128{ 133{
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 7eac1baf5975..c7bfd5ee3925 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -8,7 +8,7 @@
8#include "mode.h" 8#include "mode.h"
9#include "sysdep/signal.h" 9#include "sysdep/signal.h"
10 10
11void sig_handler(int sig) 11void sig_handler(ARCH_SIGHDLR_PARAM)
12{ 12{
13 struct sigcontext *sc; 13 struct sigcontext *sc;
14 14
@@ -19,7 +19,7 @@ void sig_handler(int sig)
19 19
20extern int timer_irq_inited; 20extern int timer_irq_inited;
21 21
22void alarm_handler(int sig) 22void alarm_handler(ARCH_SIGHDLR_PARAM)
23{ 23{
24 struct sigcontext *sc; 24 struct sigcontext *sc;
25 25
diff --git a/arch/um/os-Linux/util/Makefile b/arch/um/os-Linux/util/Makefile
index fb00ddf969bd..9778aed0c314 100644
--- a/arch/um/os-Linux/util/Makefile
+++ b/arch/um/os-Linux/util/Makefile
@@ -1,4 +1,4 @@
1hostprogs-y := mk_user_constants 1hostprogs-y := mk_user_constants
2always := $(hostprogs-y) 2always := $(hostprogs-y)
3 3
4mk_user_constants-objs := mk_user_constants.o 4HOSTCFLAGS_mk_user_constants.o := -I$(objtree)/arch/um
diff --git a/arch/um/os-Linux/util/mk_user_constants.c b/arch/um/os-Linux/util/mk_user_constants.c
index 0933518aa8bd..4838f30eecf0 100644
--- a/arch/um/os-Linux/util/mk_user_constants.c
+++ b/arch/um/os-Linux/util/mk_user_constants.c
@@ -1,11 +1,5 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <asm/types.h> 2#include <user-offsets.h>
3/* For some reason, x86_64 nowhere defines u64 and u32, even though they're
4 * used throughout the headers.
5 */
6typedef __u64 u64;
7typedef __u32 u32;
8#include <asm/user.h>
9 3
10int main(int argc, char **argv) 4int main(int argc, char **argv)
11{ 5{
@@ -20,7 +14,7 @@ int main(int argc, char **argv)
20 * x86_64 (216 vs 168 bytes). user_regs_struct is the correct size on 14 * x86_64 (216 vs 168 bytes). user_regs_struct is the correct size on
21 * both x86_64 and i386. 15 * both x86_64 and i386.
22 */ 16 */
23 printf("#define UM_FRAME_SIZE %d\n", (int) sizeof(struct user_regs_struct)); 17 printf("#define UM_FRAME_SIZE %d\n", __UM_FRAME_SIZE);
24 18
25 printf("\n"); 19 printf("\n");
26 printf("#endif\n"); 20 printf("#endif\n");
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index 143f6fea0763..98346c711493 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -2,12 +2,27 @@
2# arch/um: Generic definitions 2# arch/um: Generic definitions
3# =========================================================================== 3# ===========================================================================
4 4
5USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs)) 5USER_SINGLE_OBJS := \
6USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) 6 $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
7 7USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS))
8USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) 8USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
9 9
10$(USER_OBJS): c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(notdir $@)) 10$(USER_OBJS) : c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) \
11 $(CFLAGS_$(notdir $@))
11 12
12quiet_cmd_make_link = SYMLINK $@ 13quiet_cmd_make_link = SYMLINK $@
13cmd_make_link = rm -f $@; ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@ 14cmd_make_link = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@
15
16# this needs to be before the foreach, because targets does not accept
17# complete paths like $(obj)/$(f). To make sure this works, use a := assignment
18# or we will get $(obj)/$(f) in the "targets" value.
19# Also, this forces you to use the := syntax when assigning to targets.
20# Otherwise the line below will cause an infinite loop (if you don't know why,
21# just do it).
22
23targets := $(targets) $(SYMLINKS)
24
25SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$(f))
26
27$(SYMLINKS): FORCE
28 $(call if_changed,make_link)
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 950781e354de..4351e5605506 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -7,24 +7,13 @@ obj-$(CONFIG_MODULES) += module.o
7 7
8USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o 8USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
9 9
10include arch/um/scripts/Makefile.rules
11
12SYMLINKS = bitops.c semaphore.c highmem.c module.c 10SYMLINKS = bitops.c semaphore.c highmem.c module.c
13 11
14# this needs to be before the foreach, because clean-files does not accept 12include arch/um/scripts/Makefile.rules
15# complete paths like $(src)/$f.
16clean-files := $(SYMLINKS)
17
18targets += $(SYMLINKS)
19
20SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$f)
21 13
22bitops.c-dir = lib 14bitops.c-dir = lib
23semaphore.c-dir = kernel 15semaphore.c-dir = kernel
24highmem.c-dir = mm 16highmem.c-dir = mm
25module.c-dir = kernel 17module.c-dir = kernel
26 18
27$(SYMLINKS): FORCE
28 $(call if_changed,make_link)
29
30subdir- := util 19subdir- := util
diff --git a/arch/um/sys-i386/checksum.S b/arch/um/sys-i386/checksum.S
index a11171fb6223..d98b2fff3d08 100644
--- a/arch/um/sys-i386/checksum.S
+++ b/arch/um/sys-i386/checksum.S
@@ -38,7 +38,7 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
38 38
39.text 39.text
40.align 4 40.align 4
41.globl arch_csum_partial 41.globl csum_partial
42 42
43#ifndef CONFIG_X86_USE_PPRO_CHECKSUM 43#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
44 44
@@ -49,7 +49,7 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
49 * Fortunately, it is easy to convert 2-byte alignment to 4-byte 49 * Fortunately, it is easy to convert 2-byte alignment to 4-byte
50 * alignment for the unrolled loop. 50 * alignment for the unrolled loop.
51 */ 51 */
52arch_csum_partial: 52csum_partial:
53 pushl %esi 53 pushl %esi
54 pushl %ebx 54 pushl %ebx
55 movl 20(%esp),%eax # Function arg: unsigned int sum 55 movl 20(%esp),%eax # Function arg: unsigned int sum
@@ -119,7 +119,7 @@ arch_csum_partial:
119 119
120/* Version for PentiumII/PPro */ 120/* Version for PentiumII/PPro */
121 121
122arch_csum_partial: 122csum_partial:
123 pushl %esi 123 pushl %esi
124 pushl %ebx 124 pushl %ebx
125 movl 20(%esp),%eax # Function arg: unsigned int sum 125 movl 20(%esp),%eax # Function arg: unsigned int sum
diff --git a/arch/um/sys-i386/delay.c b/arch/um/sys-i386/delay.c
index 20d37dbbaf08..2c11b9770e8b 100644
--- a/arch/um/sys-i386/delay.c
+++ b/arch/um/sys-i386/delay.c
@@ -1,3 +1,8 @@
1#include <linux/module.h>
2#include <linux/kernel.h>
3#include <linux/delay.h>
4#include <asm/param.h>
5
1void __delay(unsigned long time) 6void __delay(unsigned long time)
2{ 7{
3 /* Stolen from the i386 __loop_delay */ 8 /* Stolen from the i386 __loop_delay */
@@ -12,3 +17,24 @@ void __delay(unsigned long time)
12 :"0" (time)); 17 :"0" (time));
13} 18}
14 19
20void __udelay(unsigned long usecs)
21{
22 int i, n;
23
24 n = (loops_per_jiffy * HZ * usecs) / MILLION;
25 for(i=0;i<n;i++)
26 cpu_relax();
27}
28
29EXPORT_SYMBOL(__udelay);
30
31void __const_udelay(unsigned long usecs)
32{
33 int i, n;
34
35 n = (loops_per_jiffy * HZ * usecs) / MILLION;
36 for(i=0;i<n;i++)
37 cpu_relax();
38}
39
40EXPORT_SYMBOL(__const_udelay);
diff --git a/arch/um/sys-i386/kernel-offsets.c b/arch/um/sys-i386/kernel-offsets.c
new file mode 100644
index 000000000000..9f8ecd1fdd96
--- /dev/null
+++ b/arch/um/sys-i386/kernel-offsets.c
@@ -0,0 +1,25 @@
1#include <linux/config.h>
2#include <linux/stddef.h>
3#include <linux/sched.h>
4#include <linux/time.h>
5#include <asm/page.h>
6
7#define DEFINE(sym, val) \
8 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
9
10#define STR(x) #x
11#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " STR(val) " " #val: : )
12
13#define BLANK() asm volatile("\n->" : : )
14
15#define OFFSET(sym, str, mem) \
16 DEFINE(sym, offsetof(struct str, mem));
17
18void foo(void)
19{
20 OFFSET(TASK_DEBUGREGS, task_struct, thread.arch.debugregs);
21#ifdef CONFIG_MODE_TT
22 OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
23#endif
24#include <common-offsets.h>
25}
diff --git a/arch/um/sys-i386/ksyms.c b/arch/um/sys-i386/ksyms.c
index 74f70a120458..db524ab3f743 100644
--- a/arch/um/sys-i386/ksyms.c
+++ b/arch/um/sys-i386/ksyms.c
@@ -2,6 +2,7 @@
2#include "linux/in6.h" 2#include "linux/in6.h"
3#include "linux/rwsem.h" 3#include "linux/rwsem.h"
4#include "asm/byteorder.h" 4#include "asm/byteorder.h"
5#include "asm/delay.h"
5#include "asm/semaphore.h" 6#include "asm/semaphore.h"
6#include "asm/uaccess.h" 7#include "asm/uaccess.h"
7#include "asm/checksum.h" 8#include "asm/checksum.h"
@@ -13,5 +14,8 @@ EXPORT_SYMBOL(__down_failed_trylock);
13EXPORT_SYMBOL(__up_wakeup); 14EXPORT_SYMBOL(__up_wakeup);
14 15
15/* Networking helper routines. */ 16/* Networking helper routines. */
16EXPORT_SYMBOL(csum_partial_copy_from); 17EXPORT_SYMBOL(csum_partial);
17EXPORT_SYMBOL(csum_partial_copy_to); 18
19/* delay core functions */
20EXPORT_SYMBOL(__const_udelay);
21EXPORT_SYMBOL(__udelay);
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index 31bcb2f997d4..dc755b0b9db8 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -25,7 +25,7 @@ int sys_modify_ldt_tt(int func, void __user *ptr, unsigned long bytecount)
25#endif 25#endif
26 26
27#ifdef CONFIG_MODE_SKAS 27#ifdef CONFIG_MODE_SKAS
28extern int userspace_pid; 28extern int userspace_pid[];
29 29
30#include "skas_ptrace.h" 30#include "skas_ptrace.h"
31 31
@@ -56,7 +56,8 @@ int sys_modify_ldt_skas(int func, void __user *ptr, unsigned long bytecount)
56 ldt = ((struct ptrace_ldt) { .func = func, 56 ldt = ((struct ptrace_ldt) { .func = func,
57 .ptr = buf, 57 .ptr = buf,
58 .bytecount = bytecount }); 58 .bytecount = bytecount });
59 res = ptrace(PTRACE_LDT, userspace_pid, 0, (unsigned long) &ldt); 59#warning Need to look up userspace_pid by cpu
60 res = ptrace(PTRACE_LDT, userspace_pid[0], 0, (unsigned long) &ldt);
60 if(res < 0) 61 if(res < 0)
61 goto out; 62 goto out;
62 63
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index e470d28cdf84..e839ce65ad28 100644
--- a/arch/um/sys-i386/ptrace.c
+++ b/arch/um/sys-i386/ptrace.c
@@ -73,6 +73,25 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
73 return 0; 73 return 0;
74} 74}
75 75
76int poke_user(struct task_struct *child, long addr, long data)
77{
78 if ((addr & 3) || addr < 0)
79 return -EIO;
80
81 if (addr < MAX_REG_OFFSET)
82 return putreg(child, addr, data);
83
84 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
85 (addr <= offsetof(struct user, u_debugreg[7]))){
86 addr -= offsetof(struct user, u_debugreg[0]);
87 addr = addr >> 2;
88 if((addr == 4) || (addr == 5)) return -EIO;
89 child->thread.arch.debugregs[addr] = data;
90 return 0;
91 }
92 return -EIO;
93}
94
76unsigned long getreg(struct task_struct *child, int regno) 95unsigned long getreg(struct task_struct *child, int regno)
77{ 96{
78 unsigned long retval = ~0UL; 97 unsigned long retval = ~0UL;
@@ -93,6 +112,27 @@ unsigned long getreg(struct task_struct *child, int regno)
93 return retval; 112 return retval;
94} 113}
95 114
115int peek_user(struct task_struct *child, long addr, long data)
116{
117/* read the word at location addr in the USER area. */
118 unsigned long tmp;
119
120 if ((addr & 3) || addr < 0)
121 return -EIO;
122
123 tmp = 0; /* Default return condition */
124 if(addr < MAX_REG_OFFSET){
125 tmp = getreg(child, addr);
126 }
127 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
128 (addr <= offsetof(struct user, u_debugreg[7]))){
129 addr -= offsetof(struct user, u_debugreg[0]);
130 addr = addr >> 2;
131 tmp = child->thread.arch.debugregs[addr];
132 }
133 return put_user(tmp, (unsigned long *) data);
134}
135
96struct i387_fxsave_struct { 136struct i387_fxsave_struct {
97 unsigned short cwd; 137 unsigned short cwd;
98 unsigned short swd; 138 unsigned short swd;
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index 76ba87254b25..03913ca5d256 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -47,9 +47,6 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
47 REGS_CS(regs->regs.skas.regs) = sc.cs; 47 REGS_CS(regs->regs.skas.regs) = sc.cs;
48 REGS_EFLAGS(regs->regs.skas.regs) = sc.eflags; 48 REGS_EFLAGS(regs->regs.skas.regs) = sc.eflags;
49 REGS_SS(regs->regs.skas.regs) = sc.ss; 49 REGS_SS(regs->regs.skas.regs) = sc.ss;
50 regs->regs.skas.fault_addr = sc.cr2;
51 regs->regs.skas.fault_type = FAULT_WRITE(sc.err);
52 regs->regs.skas.trap_type = sc.trapno;
53 50
54 err = restore_fp_registers(userspace_pid[0], fpregs); 51 err = restore_fp_registers(userspace_pid[0], fpregs);
55 if(err < 0){ 52 if(err < 0){
@@ -62,11 +59,11 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
62} 59}
63 60
64int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, 61int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
65 struct pt_regs *regs, unsigned long fault_addr, 62 struct pt_regs *regs)
66 int fault_type)
67{ 63{
68 struct sigcontext sc; 64 struct sigcontext sc;
69 unsigned long fpregs[HOST_FP_SIZE]; 65 unsigned long fpregs[HOST_FP_SIZE];
66 struct faultinfo * fi = &current->thread.arch.faultinfo;
70 int err; 67 int err;
71 68
72 sc.gs = REGS_GS(regs->regs.skas.regs); 69 sc.gs = REGS_GS(regs->regs.skas.regs);
@@ -86,9 +83,9 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
86 sc.eflags = REGS_EFLAGS(regs->regs.skas.regs); 83 sc.eflags = REGS_EFLAGS(regs->regs.skas.regs);
87 sc.esp_at_signal = regs->regs.skas.regs[UESP]; 84 sc.esp_at_signal = regs->regs.skas.regs[UESP];
88 sc.ss = regs->regs.skas.regs[SS]; 85 sc.ss = regs->regs.skas.regs[SS];
89 sc.cr2 = fault_addr; 86 sc.cr2 = fi->cr2;
90 sc.err = TO_SC_ERR(fault_type); 87 sc.err = fi->error_code;
91 sc.trapno = regs->regs.skas.trap_type; 88 sc.trapno = fi->trap_no;
92 89
93 err = save_fp_registers(userspace_pid[0], fpregs); 90 err = save_fp_registers(userspace_pid[0], fpregs);
94 if(err < 0){ 91 if(err < 0){
@@ -167,9 +164,7 @@ static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp,
167{ 164{
168 return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), 165 return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
169 sizeof(*fp)), 166 sizeof(*fp)),
170 copy_sc_to_user_skas(to, fp, from, 167 copy_sc_to_user_skas(to, fp, from)));
171 current->thread.cr2,
172 current->thread.err)));
173} 168}
174 169
175static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp, 170static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp,
diff --git a/arch/um/sys-i386/sysrq.c b/arch/um/sys-i386/sysrq.c
index 281fc7b8ca00..e3706d15c4f5 100644
--- a/arch/um/sys-i386/sysrq.c
+++ b/arch/um/sys-i386/sysrq.c
@@ -3,12 +3,15 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/config.h"
6#include "linux/kernel.h" 7#include "linux/kernel.h"
7#include "linux/smp.h" 8#include "linux/smp.h"
8#include "linux/sched.h" 9#include "linux/sched.h"
10#include "linux/kallsyms.h"
9#include "asm/ptrace.h" 11#include "asm/ptrace.h"
10#include "sysrq.h" 12#include "sysrq.h"
11 13
14/* This is declared by <linux/sched.h> */
12void show_regs(struct pt_regs *regs) 15void show_regs(struct pt_regs *regs)
13{ 16{
14 printk("\n"); 17 printk("\n");
@@ -31,5 +34,80 @@ void show_regs(struct pt_regs *regs)
31 0xffff & PT_REGS_DS(regs), 34 0xffff & PT_REGS_DS(regs),
32 0xffff & PT_REGS_ES(regs)); 35 0xffff & PT_REGS_ES(regs));
33 36
34 show_trace((unsigned long *) &regs); 37 show_trace(NULL, (unsigned long *) &regs);
35} 38}
39
40/* Copied from i386. */
41static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
42{
43 return p > (void *)tinfo &&
44 p < (void *)tinfo + THREAD_SIZE - 3;
45}
46
47/* Adapted from i386 (we also print the address we read from). */
48static inline unsigned long print_context_stack(struct thread_info *tinfo,
49 unsigned long *stack, unsigned long ebp)
50{
51 unsigned long addr;
52
53#ifdef CONFIG_FRAME_POINTER
54 while (valid_stack_ptr(tinfo, (void *)ebp)) {
55 addr = *(unsigned long *)(ebp + 4);
56 printk("%08lx: [<%08lx>]", ebp + 4, addr);
57 print_symbol(" %s", addr);
58 printk("\n");
59 ebp = *(unsigned long *)ebp;
60 }
61#else
62 while (valid_stack_ptr(tinfo, stack)) {
63 addr = *stack;
64 if (__kernel_text_address(addr)) {
65 printk("%08lx: [<%08lx>]", (unsigned long) stack, addr);
66 print_symbol(" %s", addr);
67 printk("\n");
68 }
69 stack++;
70 }
71#endif
72 return ebp;
73}
74
75void show_trace(struct task_struct* task, unsigned long * stack)
76{
77 unsigned long ebp;
78 struct thread_info *context;
79
80 /* Turn this into BUG_ON if possible. */
81 if (!stack) {
82 stack = (unsigned long*) &stack;
83 printk("show_trace: got NULL stack, implicit assumption task == current");
84 WARN_ON(1);
85 }
86
87 if (!task)
88 task = current;
89
90 if (task != current) {
91 //ebp = (unsigned long) KSTK_EBP(task);
92 /* Which one? No actual difference - just coding style.*/
93 ebp = (unsigned long) PT_REGS_EBP(&task->thread.regs);
94 } else {
95 asm ("movl %%ebp, %0" : "=r" (ebp) : );
96 }
97
98 context = (struct thread_info *)
99 ((unsigned long)stack & (~(THREAD_SIZE - 1)));
100 print_context_stack(context, stack, ebp);
101
102 /*while (((long) stack & (THREAD_SIZE-1)) != 0) {
103 addr = *stack;
104 if (__kernel_text_address(addr)) {
105 printk("%08lx: [<%08lx>]", (unsigned long) stack, addr);
106 print_symbol(" %s", addr);
107 printk("\n");
108 }
109 stack++;
110 }*/
111 printk("\n");
112}
113
diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c
new file mode 100644
index 000000000000..3ceaabceb3d7
--- /dev/null
+++ b/arch/um/sys-i386/user-offsets.c
@@ -0,0 +1,69 @@
1#include <stdio.h>
2#include <signal.h>
3#include <asm/ptrace.h>
4#include <asm/user.h>
5#include <linux/stddef.h>
6
7#define DEFINE(sym, val) \
8 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
9
10#define OFFSET(sym, str, mem) \
11 DEFINE(sym, offsetof(struct str, mem));
12
13void foo(void)
14{
15 OFFSET(SC_IP, sigcontext, eip);
16 OFFSET(SC_SP, sigcontext, esp);
17 OFFSET(SC_FS, sigcontext, fs);
18 OFFSET(SC_GS, sigcontext, gs);
19 OFFSET(SC_DS, sigcontext, ds);
20 OFFSET(SC_ES, sigcontext, es);
21 OFFSET(SC_SS, sigcontext, ss);
22 OFFSET(SC_CS, sigcontext, cs);
23 OFFSET(SC_EFLAGS, sigcontext, eflags);
24 OFFSET(SC_EAX, sigcontext, eax);
25 OFFSET(SC_EBX, sigcontext, ebx);
26 OFFSET(SC_ECX, sigcontext, ecx);
27 OFFSET(SC_EDX, sigcontext, edx);
28 OFFSET(SC_EDI, sigcontext, edi);
29 OFFSET(SC_ESI, sigcontext, esi);
30 OFFSET(SC_EBP, sigcontext, ebp);
31 OFFSET(SC_TRAPNO, sigcontext, trapno);
32 OFFSET(SC_ERR, sigcontext, err);
33 OFFSET(SC_CR2, sigcontext, cr2);
34 OFFSET(SC_FPSTATE, sigcontext, fpstate);
35 OFFSET(SC_SIGMASK, sigcontext, oldmask);
36 OFFSET(SC_FP_CW, _fpstate, cw);
37 OFFSET(SC_FP_SW, _fpstate, sw);
38 OFFSET(SC_FP_TAG, _fpstate, tag);
39 OFFSET(SC_FP_IPOFF, _fpstate, ipoff);
40 OFFSET(SC_FP_CSSEL, _fpstate, cssel);
41 OFFSET(SC_FP_DATAOFF, _fpstate, dataoff);
42 OFFSET(SC_FP_DATASEL, _fpstate, datasel);
43 OFFSET(SC_FP_ST, _fpstate, _st);
44 OFFSET(SC_FXSR_ENV, _fpstate, _fxsr_env);
45
46 DEFINE(HOST_FRAME_SIZE, FRAME_SIZE);
47 DEFINE(HOST_FP_SIZE,
48 sizeof(struct user_i387_struct) / sizeof(unsigned long));
49 DEFINE(HOST_XFP_SIZE,
50 sizeof(struct user_fxsr_struct) / sizeof(unsigned long));
51
52 DEFINE(HOST_IP, EIP);
53 DEFINE(HOST_SP, UESP);
54 DEFINE(HOST_EFLAGS, EFL);
55 DEFINE(HOST_EAX, EAX);
56 DEFINE(HOST_EBX, EBX);
57 DEFINE(HOST_ECX, ECX);
58 DEFINE(HOST_EDX, EDX);
59 DEFINE(HOST_ESI, ESI);
60 DEFINE(HOST_EDI, EDI);
61 DEFINE(HOST_EBP, EBP);
62 DEFINE(HOST_CS, CS);
63 DEFINE(HOST_SS, SS);
64 DEFINE(HOST_DS, DS);
65 DEFINE(HOST_FS, FS);
66 DEFINE(HOST_ES, ES);
67 DEFINE(HOST_GS, GS);
68 DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct));
69}
diff --git a/arch/um/sys-i386/util/Makefile b/arch/um/sys-i386/util/Makefile
index 34860f9ca7b0..bf61afd0b045 100644
--- a/arch/um/sys-i386/util/Makefile
+++ b/arch/um/sys-i386/util/Makefile
@@ -1,8 +1,5 @@
1
2hostprogs-y := mk_sc mk_thread 1hostprogs-y := mk_sc mk_thread
3always := $(hostprogs-y) 2always := $(hostprogs-y)
4 3
5mk_thread-objs := mk_thread_kern.o mk_thread_user.o 4HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um
6 5HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um
7HOSTCFLAGS_mk_thread_kern.o := $(CFLAGS) $(CPPFLAGS)
8HOSTCFLAGS_mk_thread_user.o := $(USER_CFLAGS)
diff --git a/arch/um/sys-i386/util/mk_sc.c b/arch/um/sys-i386/util/mk_sc.c
index 85cbd30396f7..04c0d73433aa 100644
--- a/arch/um/sys-i386/util/mk_sc.c
+++ b/arch/um/sys-i386/util/mk_sc.c
@@ -1,52 +1,51 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <signal.h> 2#include <user-offsets.h>
3#include <linux/stddef.h>
4 3
5#define SC_OFFSET(name, field) \ 4#define SC_OFFSET(name, field) \
6 printf("#define " name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\ 5 printf("#define " #name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
7 offsetof(struct sigcontext, field)) 6 name)
8 7
9#define SC_FP_OFFSET(name, field) \ 8#define SC_FP_OFFSET(name, field) \
10 printf("#define " name \ 9 printf("#define " #name \
11 "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\ 10 "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
12 offsetof(struct _fpstate, field)) 11 name)
13 12
14#define SC_FP_OFFSET_PTR(name, field, type) \ 13#define SC_FP_OFFSET_PTR(name, field, type) \
15 printf("#define " name \ 14 printf("#define " #name \
16 "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\ 15 "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
17 offsetof(struct _fpstate, field)) 16 name)
18 17
19int main(int argc, char **argv) 18int main(int argc, char **argv)
20{ 19{
21 SC_OFFSET("SC_IP", eip); 20 SC_OFFSET(SC_IP, eip);
22 SC_OFFSET("SC_SP", esp); 21 SC_OFFSET(SC_SP, esp);
23 SC_OFFSET("SC_FS", fs); 22 SC_OFFSET(SC_FS, fs);
24 SC_OFFSET("SC_GS", gs); 23 SC_OFFSET(SC_GS, gs);
25 SC_OFFSET("SC_DS", ds); 24 SC_OFFSET(SC_DS, ds);
26 SC_OFFSET("SC_ES", es); 25 SC_OFFSET(SC_ES, es);
27 SC_OFFSET("SC_SS", ss); 26 SC_OFFSET(SC_SS, ss);
28 SC_OFFSET("SC_CS", cs); 27 SC_OFFSET(SC_CS, cs);
29 SC_OFFSET("SC_EFLAGS", eflags); 28 SC_OFFSET(SC_EFLAGS, eflags);
30 SC_OFFSET("SC_EAX", eax); 29 SC_OFFSET(SC_EAX, eax);
31 SC_OFFSET("SC_EBX", ebx); 30 SC_OFFSET(SC_EBX, ebx);
32 SC_OFFSET("SC_ECX", ecx); 31 SC_OFFSET(SC_ECX, ecx);
33 SC_OFFSET("SC_EDX", edx); 32 SC_OFFSET(SC_EDX, edx);
34 SC_OFFSET("SC_EDI", edi); 33 SC_OFFSET(SC_EDI, edi);
35 SC_OFFSET("SC_ESI", esi); 34 SC_OFFSET(SC_ESI, esi);
36 SC_OFFSET("SC_EBP", ebp); 35 SC_OFFSET(SC_EBP, ebp);
37 SC_OFFSET("SC_TRAPNO", trapno); 36 SC_OFFSET(SC_TRAPNO, trapno);
38 SC_OFFSET("SC_ERR", err); 37 SC_OFFSET(SC_ERR, err);
39 SC_OFFSET("SC_CR2", cr2); 38 SC_OFFSET(SC_CR2, cr2);
40 SC_OFFSET("SC_FPSTATE", fpstate); 39 SC_OFFSET(SC_FPSTATE, fpstate);
41 SC_OFFSET("SC_SIGMASK", oldmask); 40 SC_OFFSET(SC_SIGMASK, oldmask);
42 SC_FP_OFFSET("SC_FP_CW", cw); 41 SC_FP_OFFSET(SC_FP_CW, cw);
43 SC_FP_OFFSET("SC_FP_SW", sw); 42 SC_FP_OFFSET(SC_FP_SW, sw);
44 SC_FP_OFFSET("SC_FP_TAG", tag); 43 SC_FP_OFFSET(SC_FP_TAG, tag);
45 SC_FP_OFFSET("SC_FP_IPOFF", ipoff); 44 SC_FP_OFFSET(SC_FP_IPOFF, ipoff);
46 SC_FP_OFFSET("SC_FP_CSSEL", cssel); 45 SC_FP_OFFSET(SC_FP_CSSEL, cssel);
47 SC_FP_OFFSET("SC_FP_DATAOFF", dataoff); 46 SC_FP_OFFSET(SC_FP_DATAOFF, dataoff);
48 SC_FP_OFFSET("SC_FP_DATASEL", datasel); 47 SC_FP_OFFSET(SC_FP_DATASEL, datasel);
49 SC_FP_OFFSET_PTR("SC_FP_ST", _st, "struct _fpstate"); 48 SC_FP_OFFSET_PTR(SC_FP_ST, _st, "struct _fpstate");
50 SC_FP_OFFSET_PTR("SC_FXSR_ENV", _fxsr_env, "void"); 49 SC_FP_OFFSET_PTR(SC_FXSR_ENV, _fxsr_env, "void");
51 return(0); 50 return(0);
52} 51}
diff --git a/arch/um/sys-i386/util/mk_thread.c b/arch/um/sys-i386/util/mk_thread.c
new file mode 100644
index 000000000000..7470d0dda67e
--- /dev/null
+++ b/arch/um/sys-i386/util/mk_thread.c
@@ -0,0 +1,22 @@
1#include <stdio.h>
2#include <kernel-offsets.h>
3
4int main(int argc, char **argv)
5{
6 printf("/*\n");
7 printf(" * Generated by mk_thread\n");
8 printf(" */\n");
9 printf("\n");
10 printf("#ifndef __UM_THREAD_H\n");
11 printf("#define __UM_THREAD_H\n");
12 printf("\n");
13 printf("#define TASK_DEBUGREGS(task) ((unsigned long *) "
14 "&(((char *) (task))[%d]))\n", TASK_DEBUGREGS);
15#ifdef TASK_EXTERN_PID
16 printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n",
17 TASK_EXTERN_PID);
18#endif
19 printf("\n");
20 printf("#endif\n");
21 return(0);
22}
diff --git a/arch/um/sys-i386/util/mk_thread_kern.c b/arch/um/sys-i386/util/mk_thread_kern.c
deleted file mode 100644
index 948b1ce85230..000000000000
--- a/arch/um/sys-i386/util/mk_thread_kern.c
+++ /dev/null
@@ -1,22 +0,0 @@
1#include "linux/config.h"
2#include "linux/stddef.h"
3#include "linux/sched.h"
4
5extern void print_head(void);
6extern void print_constant_ptr(char *name, int value);
7extern void print_constant(char *name, char *type, int value);
8extern void print_tail(void);
9
10#define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field)
11
12int main(int argc, char **argv)
13{
14 print_head();
15 print_constant_ptr("TASK_DEBUGREGS", THREAD_OFFSET(arch.debugregs));
16#ifdef CONFIG_MODE_TT
17 print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid));
18#endif
19 print_tail();
20 return(0);
21}
22
diff --git a/arch/um/sys-i386/util/mk_thread_user.c b/arch/um/sys-i386/util/mk_thread_user.c
deleted file mode 100644
index 2620cd6aa1f1..000000000000
--- a/arch/um/sys-i386/util/mk_thread_user.c
+++ /dev/null
@@ -1,30 +0,0 @@
1#include <stdio.h>
2
3void print_head(void)
4{
5 printf("/*\n");
6 printf(" * Generated by mk_thread\n");
7 printf(" */\n");
8 printf("\n");
9 printf("#ifndef __UM_THREAD_H\n");
10 printf("#define __UM_THREAD_H\n");
11 printf("\n");
12}
13
14void print_constant_ptr(char *name, int value)
15{
16 printf("#define %s(task) ((unsigned long *) "
17 "&(((char *) (task))[%d]))\n", name, value);
18}
19
20void print_constant(char *name, char *type, int value)
21{
22 printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
23 value);
24}
25
26void print_tail(void)
27{
28 printf("\n");
29 printf("#endif\n");
30}
diff --git a/arch/um/sys-ppc/ptrace.c b/arch/um/sys-ppc/ptrace.c
index a971366d3277..8e71b47f2b8e 100644
--- a/arch/um/sys-ppc/ptrace.c
+++ b/arch/um/sys-ppc/ptrace.c
@@ -8,6 +8,25 @@ int putreg(struct task_struct *child, unsigned long regno,
8 return 0; 8 return 0;
9} 9}
10 10
11int poke_user(struct task_struct *child, long addr, long data)
12{
13 if ((addr & 3) || addr < 0)
14 return -EIO;
15
16 if (addr < MAX_REG_OFFSET)
17 return putreg(child, addr, data);
18
19 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
20 (addr <= offsetof(struct user, u_debugreg[7]))){
21 addr -= offsetof(struct user, u_debugreg[0]);
22 addr = addr >> 2;
23 if((addr == 4) || (addr == 5)) return -EIO;
24 child->thread.arch.debugregs[addr] = data;
25 return 0;
26 }
27 return -EIO;
28}
29
11unsigned long getreg(struct task_struct *child, unsigned long regno) 30unsigned long getreg(struct task_struct *child, unsigned long regno)
12{ 31{
13 unsigned long retval = ~0UL; 32 unsigned long retval = ~0UL;
@@ -16,6 +35,27 @@ unsigned long getreg(struct task_struct *child, unsigned long regno)
16 return retval; 35 return retval;
17} 36}
18 37
38int peek_user(struct task_struct *child, long addr, long data)
39{
40 /* read the word at location addr in the USER area. */
41 unsigned long tmp;
42
43 if ((addr & 3) || addr < 0)
44 return -EIO;
45
46 tmp = 0; /* Default return condition */
47 if(addr < MAX_REG_OFFSET){
48 tmp = getreg(child, addr);
49 }
50 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
51 (addr <= offsetof(struct user, u_debugreg[7]))){
52 addr -= offsetof(struct user, u_debugreg[0]);
53 addr = addr >> 2;
54 tmp = child->thread.arch.debugregs[addr];
55 }
56 return put_user(tmp, (unsigned long *) data);
57}
58
19/* 59/*
20 * Overrides for Emacs so that we follow Linus's tabbing style. 60 * Overrides for Emacs so that we follow Linus's tabbing style.
21 * Emacs will notice this stuff at the end of the file and automatically 61 * Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/sys-ppc/sysrq.c b/arch/um/sys-ppc/sysrq.c
index 82d6e9335bb6..2f816f1a0ff4 100644
--- a/arch/um/sys-ppc/sysrq.c
+++ b/arch/um/sys-ppc/sysrq.c
@@ -27,17 +27,5 @@ void show_regs(struct pt_regs_subarch *regs)
27 0xffff & regs->xds, 0xffff & regs->xes); 27 0xffff & regs->xds, 0xffff & regs->xes);
28#endif 28#endif
29 29
30 show_trace(&regs->gpr[1]); 30 show_trace(current, &regs->gpr[1]);
31} 31}
32
33
34/*
35 * Overrides for Emacs so that we follow Linus's tabbing style.
36 * Emacs will notice this stuff at the end of the file and automatically
37 * adjust the settings for this buffer only. This must remain at the end
38 * of the file.
39 * ---------------------------------------------------------------------------
40 * Local variables:
41 * c-file-style: "linux"
42 * End:
43 */
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index d7ed2f7908df..608466ad6b22 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -4,24 +4,20 @@
4# Licensed under the GPL 4# Licensed under the GPL
5# 5#
6 6
7#XXX: why into lib-y?
7lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \ 8lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \
8 ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \ 9 ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \
9 syscalls.o sysrq.o thunk.o syscall_table.o 10 syscalls.o sysrq.o thunk.o syscall_table.o
10 11
11USER_OBJS := ptrace_user.o sigcontext.o 12obj-y := ksyms.o
13obj-$(CONFIG_MODULES) += module.o um_module.o
12 14
13include arch/um/scripts/Makefile.rules 15USER_OBJS := ptrace_user.o sigcontext.o
14 16
15SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \ 17SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \
16 semaphore.c thunk.S 18 semaphore.c thunk.S module.c
17
18# this needs to be before the foreach, because clean-files does not accept
19# complete paths like $(src)/$f.
20clean-files := $(SYMLINKS)
21 19
22targets += $(SYMLINKS) 20include arch/um/scripts/Makefile.rules
23
24SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$f)
25 21
26bitops.c-dir = lib 22bitops.c-dir = lib
27csum-copy.S-dir = lib 23csum-copy.S-dir = lib
@@ -30,8 +26,6 @@ csum-wrappers.c-dir = lib
30memcpy.S-dir = lib 26memcpy.S-dir = lib
31semaphore.c-dir = kernel 27semaphore.c-dir = kernel
32thunk.S-dir = lib 28thunk.S-dir = lib
29module.c-dir = kernel
33 30
34$(SYMLINKS): FORCE 31subdir- := util
35 $(call if_changed,make_link)
36
37CFLAGS_csum-partial.o := -Dcsum_partial=arch_csum_partial
diff --git a/arch/um/sys-x86_64/delay.c b/arch/um/sys-x86_64/delay.c
index f3b5187942b4..137f4446b439 100644
--- a/arch/um/sys-x86_64/delay.c
+++ b/arch/um/sys-x86_64/delay.c
@@ -5,22 +5,37 @@
5 * Licensed under the GPL 5 * Licensed under the GPL
6 */ 6 */
7 7
8#include "asm/processor.h" 8#include <linux/module.h>
9#include <linux/delay.h>
10#include <asm/processor.h>
11#include <asm/param.h>
9 12
10void __delay(unsigned long loops) 13void __delay(unsigned long loops)
11{ 14{
12 unsigned long i; 15 unsigned long i;
13 16
14 for(i = 0; i < loops; i++) ; 17 for(i = 0; i < loops; i++)
18 cpu_relax();
15} 19}
16 20
17/* 21void __udelay(unsigned long usecs)
18 * Overrides for Emacs so that we follow Linus's tabbing style. 22{
19 * Emacs will notice this stuff at the end of the file and automatically 23 unsigned long i, n;
20 * adjust the settings for this buffer only. This must remain at the end 24
21 * of the file. 25 n = (loops_per_jiffy * HZ * usecs) / MILLION;
22 * --------------------------------------------------------------------------- 26 for(i=0;i<n;i++)
23 * Local variables: 27 cpu_relax();
24 * c-file-style: "linux" 28}
25 * End: 29
26 */ 30EXPORT_SYMBOL(__udelay);
31
32void __const_udelay(unsigned long usecs)
33{
34 unsigned long i, n;
35
36 n = (loops_per_jiffy * HZ * usecs) / MILLION;
37 for(i=0;i<n;i++)
38 cpu_relax();
39}
40
41EXPORT_SYMBOL(__const_udelay);
diff --git a/arch/um/sys-x86_64/kernel-offsets.c b/arch/um/sys-x86_64/kernel-offsets.c
new file mode 100644
index 000000000000..220e875cbe29
--- /dev/null
+++ b/arch/um/sys-x86_64/kernel-offsets.c
@@ -0,0 +1,24 @@
1#include <linux/config.h>
2#include <linux/stddef.h>
3#include <linux/sched.h>
4#include <linux/time.h>
5#include <asm/page.h>
6
7#define DEFINE(sym, val) \
8 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
9
10#define DEFINE_STR1(x) #x
11#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " DEFINE_STR1(val) " " #val: : )
12
13#define BLANK() asm volatile("\n->" : : )
14
15#define OFFSET(sym, str, mem) \
16 DEFINE(sym, offsetof(struct str, mem));
17
18void foo(void)
19{
20#ifdef CONFIG_MODE_TT
21 OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
22#endif
23#include <common-offsets.h>
24}
diff --git a/arch/um/sys-x86_64/ksyms.c b/arch/um/sys-x86_64/ksyms.c
new file mode 100644
index 000000000000..859273808203
--- /dev/null
+++ b/arch/um/sys-x86_64/ksyms.c
@@ -0,0 +1,19 @@
1#include "linux/module.h"
2#include "linux/in6.h"
3#include "linux/rwsem.h"
4#include "asm/byteorder.h"
5#include "asm/semaphore.h"
6#include "asm/uaccess.h"
7#include "asm/checksum.h"
8#include "asm/errno.h"
9
10EXPORT_SYMBOL(__down_failed);
11EXPORT_SYMBOL(__down_failed_interruptible);
12EXPORT_SYMBOL(__down_failed_trylock);
13EXPORT_SYMBOL(__up_wakeup);
14
15/*XXX: we need them because they would be exported by x86_64 */
16EXPORT_SYMBOL(__memcpy);
17
18/* Networking helper routines. */
19EXPORT_SYMBOL(ip_compute_csum);
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c
index 8c146b2a1e00..74eee5c7c6dd 100644
--- a/arch/um/sys-x86_64/ptrace.c
+++ b/arch/um/sys-x86_64/ptrace.c
@@ -5,10 +5,11 @@
5 */ 5 */
6 6
7#define __FRAME_OFFSETS 7#define __FRAME_OFFSETS
8#include "asm/ptrace.h" 8#include <asm/ptrace.h>
9#include "linux/sched.h" 9#include <linux/sched.h>
10#include "linux/errno.h" 10#include <linux/errno.h>
11#include "asm/elf.h" 11#include <asm/uaccess.h>
12#include <asm/elf.h>
12 13
13/* XXX x86_64 */ 14/* XXX x86_64 */
14unsigned long not_ss; 15unsigned long not_ss;
@@ -62,6 +63,27 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
62 return 0; 63 return 0;
63} 64}
64 65
66int poke_user(struct task_struct *child, long addr, long data)
67{
68 if ((addr & 3) || addr < 0)
69 return -EIO;
70
71 if (addr < MAX_REG_OFFSET)
72 return putreg(child, addr, data);
73
74#if 0 /* Need x86_64 debugregs handling */
75 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
76 (addr <= offsetof(struct user, u_debugreg[7]))){
77 addr -= offsetof(struct user, u_debugreg[0]);
78 addr = addr >> 2;
79 if((addr == 4) || (addr == 5)) return -EIO;
80 child->thread.arch.debugregs[addr] = data;
81 return 0;
82 }
83#endif
84 return -EIO;
85}
86
65unsigned long getreg(struct task_struct *child, int regno) 87unsigned long getreg(struct task_struct *child, int regno)
66{ 88{
67 unsigned long retval = ~0UL; 89 unsigned long retval = ~0UL;
@@ -84,6 +106,29 @@ unsigned long getreg(struct task_struct *child, int regno)
84 return retval; 106 return retval;
85} 107}
86 108
109int peek_user(struct task_struct *child, long addr, long data)
110{
111 /* read the word at location addr in the USER area. */
112 unsigned long tmp;
113
114 if ((addr & 3) || addr < 0)
115 return -EIO;
116
117 tmp = 0; /* Default return condition */
118 if(addr < MAX_REG_OFFSET){
119 tmp = getreg(child, addr);
120 }
121#if 0 /* Need x86_64 debugregs handling */
122 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
123 (addr <= offsetof(struct user, u_debugreg[7]))){
124 addr -= offsetof(struct user, u_debugreg[0]);
125 addr = addr >> 2;
126 tmp = child->thread.arch.debugregs[addr];
127 }
128#endif
129 return put_user(tmp, (unsigned long *) data);
130}
131
87void arch_switch(void) 132void arch_switch(void)
88{ 133{
89/* XXX 134/* XXX
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
index 5bc5a0d796e5..73a7926f7370 100644
--- a/arch/um/sys-x86_64/signal.c
+++ b/arch/um/sys-x86_64/signal.c
@@ -57,7 +57,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
57int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, 57int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
58 struct pt_regs *regs, unsigned long mask) 58 struct pt_regs *regs, unsigned long mask)
59{ 59{
60 unsigned long eflags; 60 struct faultinfo * fi = &current->thread.arch.faultinfo;
61 int err = 0; 61 int err = 0;
62 62
63 err |= __put_user(0, &to->gs); 63 err |= __put_user(0, &to->gs);
@@ -84,14 +84,16 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
84 err |= PUTREG(regs, R14, to, r14); 84 err |= PUTREG(regs, R14, to, r14);
85 err |= PUTREG(regs, R15, to, r15); 85 err |= PUTREG(regs, R15, to, r15);
86 err |= PUTREG(regs, CS, to, cs); /* XXX x86_64 doesn't do this */ 86 err |= PUTREG(regs, CS, to, cs); /* XXX x86_64 doesn't do this */
87 err |= __put_user(current->thread.err, &to->err); 87
88 err |= __put_user(current->thread.trap_no, &to->trapno); 88 err |= __put_user(fi->cr2, &to->cr2);
89 err |= __put_user(fi->error_code, &to->err);
90 err |= __put_user(fi->trap_no, &to->trapno);
91
89 err |= PUTREG(regs, RIP, to, rip); 92 err |= PUTREG(regs, RIP, to, rip);
90 err |= PUTREG(regs, EFLAGS, to, eflags); 93 err |= PUTREG(regs, EFLAGS, to, eflags);
91#undef PUTREG 94#undef PUTREG
92 95
93 err |= __put_user(mask, &to->oldmask); 96 err |= __put_user(mask, &to->oldmask);
94 err |= __put_user(current->thread.cr2, &to->cr2);
95 97
96 return(err); 98 return(err);
97} 99}
@@ -166,7 +168,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
166 168
167 frame = (struct rt_sigframe __user *) 169 frame = (struct rt_sigframe __user *)
168 round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8; 170 round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8;
169 frame -= 128; 171 ((unsigned char *) frame) -= 128;
170 172
171 if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) 173 if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
172 goto out; 174 goto out;
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index ab4b0abf8af3..6f44f40204ed 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -7,12 +7,15 @@
7#include "linux/linkage.h" 7#include "linux/linkage.h"
8#include "linux/slab.h" 8#include "linux/slab.h"
9#include "linux/shm.h" 9#include "linux/shm.h"
10#include "linux/utsname.h"
11#include "linux/personality.h"
10#include "asm/uaccess.h" 12#include "asm/uaccess.h"
11#define __FRAME_OFFSETS 13#define __FRAME_OFFSETS
12#include "asm/ptrace.h" 14#include "asm/ptrace.h"
13#include "asm/unistd.h" 15#include "asm/unistd.h"
14#include "asm/prctl.h" /* XXX This should get the constants from libc */ 16#include "asm/prctl.h" /* XXX This should get the constants from libc */
15#include "choose-mode.h" 17#include "choose-mode.h"
18#include "kern.h"
16 19
17asmlinkage long sys_uname64(struct new_utsname __user * name) 20asmlinkage long sys_uname64(struct new_utsname __user * name)
18{ 21{
@@ -42,6 +45,8 @@ long sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
42#ifdef CONFIG_MODE_SKAS 45#ifdef CONFIG_MODE_SKAS
43extern int userspace_pid[]; 46extern int userspace_pid[];
44 47
48#include "skas_ptrace.h"
49
45long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount) 50long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
46{ 51{
47 struct ptrace_ldt ldt; 52 struct ptrace_ldt ldt;
@@ -128,23 +133,27 @@ static long arch_prctl_tt(int code, unsigned long addr)
128 133
129#ifdef CONFIG_MODE_SKAS 134#ifdef CONFIG_MODE_SKAS
130 135
136/* XXX: Must also call arch_prctl in the host, beside saving the segment bases! */
131static long arch_prctl_skas(int code, unsigned long addr) 137static long arch_prctl_skas(int code, unsigned long addr)
132{ 138{
133 long ret = 0; 139 long ret = 0;
134 140
135 switch(code){ 141 switch(code){
136 case ARCH_SET_GS:
137 current->thread.regs.regs.skas.regs[GS_BASE / sizeof(unsigned long)] = addr;
138 break;
139 case ARCH_SET_FS: 142 case ARCH_SET_FS:
140 current->thread.regs.regs.skas.regs[FS_BASE / sizeof(unsigned long)] = addr; 143 current->thread.regs.regs.skas.regs[FS_BASE / sizeof(unsigned long)] = addr;
141 break; 144 break;
145 case ARCH_SET_GS:
146 current->thread.regs.regs.skas.regs[GS_BASE / sizeof(unsigned long)] = addr;
147 break;
142 case ARCH_GET_FS: 148 case ARCH_GET_FS:
143 ret = put_user(current->thread.regs.regs.skas.regs[GS / sizeof(unsigned long)], &addr); 149 ret = put_user(current->thread.regs.regs.skas.
150 regs[FS_BASE / sizeof(unsigned long)],
151 (unsigned long __user *)addr);
144 break; 152 break;
145 case ARCH_GET_GS: 153 case ARCH_GET_GS:
146 ret = put_user(current->thread.regs.regs.skas.regs[FS / sizeof(unsigned \ 154 ret = put_user(current->thread.regs.regs.skas.
147long)], &addr); 155 regs[GS_BASE / sizeof(unsigned long)],
156 (unsigned long __user *)addr);
148 break; 157 break;
149 default: 158 default:
150 ret = -EINVAL; 159 ret = -EINVAL;
diff --git a/arch/um/sys-x86_64/sysrq.c b/arch/um/sys-x86_64/sysrq.c
index ddf74691a610..d0a25af19a5b 100644
--- a/arch/um/sys-x86_64/sysrq.c
+++ b/arch/um/sys-x86_64/sysrq.c
@@ -36,14 +36,5 @@ void __show_regs(struct pt_regs * regs)
36void show_regs(struct pt_regs *regs) 36void show_regs(struct pt_regs *regs)
37{ 37{
38 __show_regs(regs); 38 __show_regs(regs);
39 show_trace((unsigned long *) &regs); 39 show_trace(current, (unsigned long *) &regs);
40} 40}
41
42/* Emacs will notice this stuff at the end of the file and automatically
43 * adjust the settings for this buffer only. This must remain at the end
44 * of the file.
45 * ---------------------------------------------------------------------------
46 * Local variables:
47 * c-file-style: "linux"
48 * End:
49 */
diff --git a/arch/um/sys-x86_64/um_module.c b/arch/um/sys-x86_64/um_module.c
new file mode 100644
index 000000000000..8b8eff1bd977
--- /dev/null
+++ b/arch/um/sys-x86_64/um_module.c
@@ -0,0 +1,19 @@
1#include <linux/vmalloc.h>
2#include <linux/moduleloader.h>
3
4/*Copied from i386 arch/i386/kernel/module.c */
5void *module_alloc(unsigned long size)
6{
7 if (size == 0)
8 return NULL;
9 return vmalloc_exec(size);
10}
11
12/* Free memory returned from module_alloc */
13void module_free(struct module *mod, void *module_region)
14{
15 vfree(module_region);
16 /* FIXME: If module_region == mod->init_region, trim exception
17 table entries. */
18}
19
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c
new file mode 100644
index 000000000000..513d17ceafd4
--- /dev/null
+++ b/arch/um/sys-x86_64/user-offsets.c
@@ -0,0 +1,86 @@
1#include <stdio.h>
2#include <stddef.h>
3#include <signal.h>
4#define __FRAME_OFFSETS
5#include <asm/ptrace.h>
6#include <asm/types.h>
7/* For some reason, x86_64 defines u64 and u32 only in <pci/types.h>, which I
8 * refuse to include here, even though they're used throughout the headers.
9 * These are used in asm/user.h, and that include can't be avoided because of
10 * the sizeof(struct user_regs_struct) below.
11 */
12typedef __u64 u64;
13typedef __u32 u32;
14#include <asm/user.h>
15
16#define DEFINE(sym, val) \
17 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
18
19#define OFFSET(sym, str, mem) \
20 DEFINE(sym, offsetof(struct str, mem));
21
22void foo(void)
23{
24 OFFSET(SC_RBX, sigcontext, rbx);
25 OFFSET(SC_RCX, sigcontext, rcx);
26 OFFSET(SC_RDX, sigcontext, rdx);
27 OFFSET(SC_RSI, sigcontext, rsi);
28 OFFSET(SC_RDI, sigcontext, rdi);
29 OFFSET(SC_RBP, sigcontext, rbp);
30 OFFSET(SC_RAX, sigcontext, rax);
31 OFFSET(SC_R8, sigcontext, r8);
32 OFFSET(SC_R9, sigcontext, r9);
33 OFFSET(SC_R10, sigcontext, r10);
34 OFFSET(SC_R11, sigcontext, r11);
35 OFFSET(SC_R12, sigcontext, r12);
36 OFFSET(SC_R13, sigcontext, r13);
37 OFFSET(SC_R14, sigcontext, r14);
38 OFFSET(SC_R15, sigcontext, r15);
39 OFFSET(SC_IP, sigcontext, rip);
40 OFFSET(SC_SP, sigcontext, rsp);
41 OFFSET(SC_CR2, sigcontext, cr2);
42 OFFSET(SC_ERR, sigcontext, err);
43 OFFSET(SC_TRAPNO, sigcontext, trapno);
44 OFFSET(SC_CS, sigcontext, cs);
45 OFFSET(SC_FS, sigcontext, fs);
46 OFFSET(SC_GS, sigcontext, gs);
47 OFFSET(SC_EFLAGS, sigcontext, eflags);
48 OFFSET(SC_SIGMASK, sigcontext, oldmask);
49#if 0
50 OFFSET(SC_ORIG_RAX, sigcontext, orig_rax);
51 OFFSET(SC_DS, sigcontext, ds);
52 OFFSET(SC_ES, sigcontext, es);
53 OFFSET(SC_SS, sigcontext, ss);
54#endif
55
56 DEFINE(HOST_FRAME_SIZE, FRAME_SIZE);
57 DEFINE(HOST_RBX, RBX);
58 DEFINE(HOST_RCX, RCX);
59 DEFINE(HOST_RDI, RDI);
60 DEFINE(HOST_RSI, RSI);
61 DEFINE(HOST_RDX, RDX);
62 DEFINE(HOST_RBP, RBP);
63 DEFINE(HOST_RAX, RAX);
64 DEFINE(HOST_R8, R8);
65 DEFINE(HOST_R9, R9);
66 DEFINE(HOST_R10, R10);
67 DEFINE(HOST_R11, R11);
68 DEFINE(HOST_R12, R12);
69 DEFINE(HOST_R13, R13);
70 DEFINE(HOST_R14, R14);
71 DEFINE(HOST_R15, R15);
72 DEFINE(HOST_ORIG_RAX, ORIG_RAX);
73 DEFINE(HOST_CS, CS);
74 DEFINE(HOST_SS, SS);
75 DEFINE(HOST_EFLAGS, EFLAGS);
76#if 0
77 DEFINE(HOST_FS, FS);
78 DEFINE(HOST_GS, GS);
79 DEFINE(HOST_DS, DS);
80 DEFINE(HOST_ES, ES);
81#endif
82
83 DEFINE(HOST_IP, RIP);
84 DEFINE(HOST_SP, RSP);
85 DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct));
86}
diff --git a/arch/um/sys-x86_64/util/Makefile b/arch/um/sys-x86_64/util/Makefile
index 002607980864..75b052cfc206 100644
--- a/arch/um/sys-x86_64/util/Makefile
+++ b/arch/um/sys-x86_64/util/Makefile
@@ -4,7 +4,5 @@
4hostprogs-y := mk_sc mk_thread 4hostprogs-y := mk_sc mk_thread
5always := $(hostprogs-y) 5always := $(hostprogs-y)
6 6
7mk_thread-objs := mk_thread_kern.o mk_thread_user.o 7HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um
8 8HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um
9HOSTCFLAGS_mk_thread_kern.o := $(CFLAGS) $(CPPFLAGS)
10HOSTCFLAGS_mk_thread_user.o := $(USER_CFLAGS)
diff --git a/arch/um/sys-x86_64/util/mk_sc.c b/arch/um/sys-x86_64/util/mk_sc.c
index c236e213918d..7619bc377c1f 100644
--- a/arch/um/sys-x86_64/util/mk_sc.c
+++ b/arch/um/sys-x86_64/util/mk_sc.c
@@ -3,56 +3,45 @@
3 */ 3 */
4 4
5#include <stdio.h> 5#include <stdio.h>
6#include <signal.h> 6#include <user-offsets.h>
7#include <linux/stddef.h>
8 7
9#define SC_OFFSET(name, field) \ 8#define SC_OFFSET(name) \
10 printf("#define " name \ 9 printf("#define " #name \
11 "(sc) *((unsigned long *) &(((char *) (sc))[%ld]))\n",\ 10 "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
12 offsetof(struct sigcontext, field)) 11 name)
13
14#define SC_FP_OFFSET(name, field) \
15 printf("#define " name \
16 "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%ld]))\n",\
17 offsetof(struct _fpstate, field))
18
19#define SC_FP_OFFSET_PTR(name, field, type) \
20 printf("#define " name \
21 "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
22 offsetof(struct _fpstate, field))
23 12
24int main(int argc, char **argv) 13int main(int argc, char **argv)
25{ 14{
26 SC_OFFSET("SC_RBX", rbx); 15 SC_OFFSET(SC_RBX);
27 SC_OFFSET("SC_RCX", rcx); 16 SC_OFFSET(SC_RCX);
28 SC_OFFSET("SC_RDX", rdx); 17 SC_OFFSET(SC_RDX);
29 SC_OFFSET("SC_RSI", rsi); 18 SC_OFFSET(SC_RSI);
30 SC_OFFSET("SC_RDI", rdi); 19 SC_OFFSET(SC_RDI);
31 SC_OFFSET("SC_RBP", rbp); 20 SC_OFFSET(SC_RBP);
32 SC_OFFSET("SC_RAX", rax); 21 SC_OFFSET(SC_RAX);
33 SC_OFFSET("SC_R8", r8); 22 SC_OFFSET(SC_R8);
34 SC_OFFSET("SC_R9", r9); 23 SC_OFFSET(SC_R9);
35 SC_OFFSET("SC_R10", r10); 24 SC_OFFSET(SC_R10);
36 SC_OFFSET("SC_R11", r11); 25 SC_OFFSET(SC_R11);
37 SC_OFFSET("SC_R12", r12); 26 SC_OFFSET(SC_R12);
38 SC_OFFSET("SC_R13", r13); 27 SC_OFFSET(SC_R13);
39 SC_OFFSET("SC_R14", r14); 28 SC_OFFSET(SC_R14);
40 SC_OFFSET("SC_R15", r15); 29 SC_OFFSET(SC_R15);
41 SC_OFFSET("SC_IP", rip); 30 SC_OFFSET(SC_IP);
42 SC_OFFSET("SC_SP", rsp); 31 SC_OFFSET(SC_SP);
43 SC_OFFSET("SC_CR2", cr2); 32 SC_OFFSET(SC_CR2);
44 SC_OFFSET("SC_ERR", err); 33 SC_OFFSET(SC_ERR);
45 SC_OFFSET("SC_TRAPNO", trapno); 34 SC_OFFSET(SC_TRAPNO);
46 SC_OFFSET("SC_CS", cs); 35 SC_OFFSET(SC_CS);
47 SC_OFFSET("SC_FS", fs); 36 SC_OFFSET(SC_FS);
48 SC_OFFSET("SC_GS", gs); 37 SC_OFFSET(SC_GS);
49 SC_OFFSET("SC_EFLAGS", eflags); 38 SC_OFFSET(SC_EFLAGS);
50 SC_OFFSET("SC_SIGMASK", oldmask); 39 SC_OFFSET(SC_SIGMASK);
51#if 0 40#if 0
52 SC_OFFSET("SC_ORIG_RAX", orig_rax); 41 SC_OFFSET(SC_ORIG_RAX);
53 SC_OFFSET("SC_DS", ds); 42 SC_OFFSET(SC_DS);
54 SC_OFFSET("SC_ES", es); 43 SC_OFFSET(SC_ES);
55 SC_OFFSET("SC_SS", ss); 44 SC_OFFSET(SC_SS);
56#endif 45#endif
57 return(0); 46 return(0);
58} 47}
diff --git a/arch/um/sys-x86_64/util/mk_thread.c b/arch/um/sys-x86_64/util/mk_thread.c
new file mode 100644
index 000000000000..15517396e9cf
--- /dev/null
+++ b/arch/um/sys-x86_64/util/mk_thread.c
@@ -0,0 +1,20 @@
1#include <stdio.h>
2#include <kernel-offsets.h>
3
4int main(int argc, char **argv)
5{
6 printf("/*\n");
7 printf(" * Generated by mk_thread\n");
8 printf(" */\n");
9 printf("\n");
10 printf("#ifndef __UM_THREAD_H\n");
11 printf("#define __UM_THREAD_H\n");
12 printf("\n");
13#ifdef TASK_EXTERN_PID
14 printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n",
15 TASK_EXTERN_PID);
16#endif
17 printf("\n");
18 printf("#endif\n");
19 return(0);
20}
diff --git a/arch/um/sys-x86_64/util/mk_thread_kern.c b/arch/um/sys-x86_64/util/mk_thread_kern.c
deleted file mode 100644
index a281673f02b2..000000000000
--- a/arch/um/sys-x86_64/util/mk_thread_kern.c
+++ /dev/null
@@ -1,21 +0,0 @@
1#include "linux/config.h"
2#include "linux/stddef.h"
3#include "linux/sched.h"
4
5extern void print_head(void);
6extern void print_constant_ptr(char *name, int value);
7extern void print_constant(char *name, char *type, int value);
8extern void print_tail(void);
9
10#define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field)
11
12int main(int argc, char **argv)
13{
14 print_head();
15#ifdef CONFIG_MODE_TT
16 print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid));
17#endif
18 print_tail();
19 return(0);
20}
21
diff --git a/arch/um/sys-x86_64/util/mk_thread_user.c b/arch/um/sys-x86_64/util/mk_thread_user.c
deleted file mode 100644
index 7989725568b8..000000000000
--- a/arch/um/sys-x86_64/util/mk_thread_user.c
+++ /dev/null
@@ -1,30 +0,0 @@
1#include <stdio.h>
2
3void print_head(void)
4{
5 printf("/*\n");
6 printf(" * Generated by mk_thread\n");
7 printf(" */\n");
8 printf("\n");
9 printf("#ifndef __UM_THREAD_H\n");
10 printf("#define __UM_THREAD_H\n");
11 printf("\n");
12}
13
14void print_constant_ptr(char *name, int value)
15{
16 printf("#define %s(task) ((unsigned long *) "
17 "&(((char *) (task))[%d]))\n", name, value);
18}
19
20void print_constant(char *name, char *type, int value)
21{
22 printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
23 value);
24}
25
26void print_tail(void)
27{
28 printf("\n");
29 printf("#endif\n");
30}
diff --git a/arch/um/util/Makefile b/arch/um/util/Makefile
index e2ab71209f3f..4c7551c28033 100644
--- a/arch/um/util/Makefile
+++ b/arch/um/util/Makefile
@@ -1,8 +1,5 @@
1hostprogs-y := mk_task mk_constants 1hostprogs-y := mk_task mk_constants
2always := $(hostprogs-y) 2always := $(hostprogs-y)
3 3
4mk_task-objs := mk_task_user.o mk_task_kern.o 4HOSTCFLAGS_mk_task.o := -I$(objtree)/arch/um
5mk_constants-objs := mk_constants_user.o mk_constants_kern.o 5HOSTCFLAGS_mk_constants.o := -I$(objtree)/arch/um
6
7HOSTCFLAGS_mk_task_kern.o := $(CFLAGS) $(CPPFLAGS)
8HOSTCFLAGS_mk_constants_kern.o := $(CFLAGS) $(CPPFLAGS)
diff --git a/arch/um/util/mk_constants.c b/arch/um/util/mk_constants.c
new file mode 100644
index 000000000000..ab217becc36a
--- /dev/null
+++ b/arch/um/util/mk_constants.c
@@ -0,0 +1,32 @@
1#include <stdio.h>
2#include <kernel-offsets.h>
3
4#define SHOW_INT(sym) printf("#define %s %d\n", #sym, sym)
5#define SHOW_STR(sym) printf("#define %s %s\n", #sym, sym)
6
7int main(int argc, char **argv)
8{
9 printf("/*\n");
10 printf(" * Generated by mk_constants\n");
11 printf(" */\n");
12 printf("\n");
13 printf("#ifndef __UM_CONSTANTS_H\n");
14 printf("#define __UM_CONSTANTS_H\n");
15 printf("\n");
16
17 SHOW_INT(UM_KERN_PAGE_SIZE);
18
19 SHOW_STR(UM_KERN_EMERG);
20 SHOW_STR(UM_KERN_ALERT);
21 SHOW_STR(UM_KERN_CRIT);
22 SHOW_STR(UM_KERN_ERR);
23 SHOW_STR(UM_KERN_WARNING);
24 SHOW_STR(UM_KERN_NOTICE);
25 SHOW_STR(UM_KERN_INFO);
26 SHOW_STR(UM_KERN_DEBUG);
27
28 SHOW_INT(UM_NSEC_PER_SEC);
29 printf("\n");
30 printf("#endif\n");
31 return(0);
32}
diff --git a/arch/um/util/mk_constants_kern.c b/arch/um/util/mk_constants_kern.c
deleted file mode 100644
index cdcb1232a1ea..000000000000
--- a/arch/um/util/mk_constants_kern.c
+++ /dev/null
@@ -1,28 +0,0 @@
1#include "linux/kernel.h"
2#include "linux/stringify.h"
3#include "linux/time.h"
4#include "asm/page.h"
5
6extern void print_head(void);
7extern void print_constant_str(char *name, char *value);
8extern void print_constant_int(char *name, int value);
9extern void print_tail(void);
10
11int main(int argc, char **argv)
12{
13 print_head();
14 print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
15
16 print_constant_str("UM_KERN_EMERG", KERN_EMERG);
17 print_constant_str("UM_KERN_ALERT", KERN_ALERT);
18 print_constant_str("UM_KERN_CRIT", KERN_CRIT);
19 print_constant_str("UM_KERN_ERR", KERN_ERR);
20 print_constant_str("UM_KERN_WARNING", KERN_WARNING);
21 print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
22 print_constant_str("UM_KERN_INFO", KERN_INFO);
23 print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
24
25 print_constant_int("UM_NSEC_PER_SEC", NSEC_PER_SEC);
26 print_tail();
27 return(0);
28}
diff --git a/arch/um/util/mk_constants_user.c b/arch/um/util/mk_constants_user.c
deleted file mode 100644
index 8f4d7e50be7c..000000000000
--- a/arch/um/util/mk_constants_user.c
+++ /dev/null
@@ -1,28 +0,0 @@
1#include <stdio.h>
2
3void print_head(void)
4{
5 printf("/*\n");
6 printf(" * Generated by mk_constants\n");
7 printf(" */\n");
8 printf("\n");
9 printf("#ifndef __UM_CONSTANTS_H\n");
10 printf("#define __UM_CONSTANTS_H\n");
11 printf("\n");
12}
13
14void print_constant_str(char *name, char *value)
15{
16 printf("#define %s \"%s\"\n", name, value);
17}
18
19void print_constant_int(char *name, int value)
20{
21 printf("#define %s %d\n", name, value);
22}
23
24void print_tail(void)
25{
26 printf("\n");
27 printf("#endif\n");
28}
diff --git a/arch/um/util/mk_task_user.c b/arch/um/util/mk_task.c
index 9db849f3f3ac..36c9606505e2 100644
--- a/arch/um/util/mk_task_user.c
+++ b/arch/um/util/mk_task.c
@@ -1,18 +1,19 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <kernel-offsets.h>
2 3
3void print(char *name, char *type, int offset) 4void print_ptr(char *name, char *type, int offset)
4{ 5{
5 printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type, 6 printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type,
6 offset); 7 offset);
7} 8}
8 9
9void print_ptr(char *name, char *type, int offset) 10void print(char *name, char *type, int offset)
10{ 11{
11 printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type, 12 printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
12 offset); 13 offset);
13} 14}
14 15
15void print_head(void) 16int main(int argc, char **argv)
16{ 17{
17 printf("/*\n"); 18 printf("/*\n");
18 printf(" * Generated by mk_task\n"); 19 printf(" * Generated by mk_task\n");
@@ -21,10 +22,9 @@ void print_head(void)
21 printf("#ifndef __TASK_H\n"); 22 printf("#ifndef __TASK_H\n");
22 printf("#define __TASK_H\n"); 23 printf("#define __TASK_H\n");
23 printf("\n"); 24 printf("\n");
24} 25 print_ptr("TASK_REGS", "union uml_pt_regs", TASK_REGS);
25 26 print("TASK_PID", "int", TASK_PID);
26void print_tail(void)
27{
28 printf("\n"); 27 printf("\n");
29 printf("#endif\n"); 28 printf("#endif\n");
29 return(0);
30} 30}
diff --git a/arch/um/util/mk_task_kern.c b/arch/um/util/mk_task_kern.c
deleted file mode 100644
index c218103315ed..000000000000
--- a/arch/um/util/mk_task_kern.c
+++ /dev/null
@@ -1,17 +0,0 @@
1#include "linux/sched.h"
2#include "linux/stddef.h"
3
4extern void print(char *name, char *type, int offset);
5extern void print_ptr(char *name, char *type, int offset);
6extern void print_head(void);
7extern void print_tail(void);
8
9int main(int argc, char **argv)
10{
11 print_head();
12 print_ptr("TASK_REGS", "union uml_pt_regs",
13 offsetof(struct task_struct, thread.regs));
14 print("TASK_PID", "int", offsetof(struct task_struct, pid));
15 print_tail();
16 return(0);
17}
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 80c38c5d71fe..289f448ac89c 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -303,6 +303,21 @@ config HPET_TIMER
303 as it is off-chip. You can find the HPET spec at 303 as it is off-chip. You can find the HPET spec at
304 <http://www.intel.com/labs/platcomp/hpet/hpetspec.htm>. 304 <http://www.intel.com/labs/platcomp/hpet/hpetspec.htm>.
305 305
306config X86_PM_TIMER
307 bool "PM timer"
308 depends on ACPI
309 default y
310 help
311 Support the ACPI PM timer for time keeping. This is slow,
312 but is useful on some chipsets without HPET on systems with more
313 than one CPU. On a single processor or single socket multi core
314 system it is normally not required.
315 When the PM timer is active 64bit vsyscalls are disabled
316 and should not be enabled (/proc/sys/kernel/vsyscall64 should
317 not be changed).
318 The kernel selects the PM timer only as a last resort, so it is
319 useful to enable just in case.
320
306config HPET_EMULATE_RTC 321config HPET_EMULATE_RTC
307 bool "Provide RTC interrupt" 322 bool "Provide RTC interrupt"
308 depends on HPET_TIMER && RTC=y 323 depends on HPET_TIMER && RTC=y
@@ -379,6 +394,11 @@ config GENERIC_IRQ_PROBE
379 bool 394 bool
380 default y 395 default y
381 396
397# we have no ISA slots, but we do have ISA-style DMA.
398config ISA_DMA_API
399 bool
400 default y
401
382menu "Power management options" 402menu "Power management options"
383 403
384source kernel/power/Kconfig 404source kernel/power/Kconfig
@@ -402,7 +422,7 @@ config PCI_DIRECT
402 422
403config PCI_MMCONFIG 423config PCI_MMCONFIG
404 bool "Support mmconfig PCI config space access" 424 bool "Support mmconfig PCI config space access"
405 depends on PCI 425 depends on PCI && ACPI
406 select ACPI_BOOT 426 select ACPI_BOOT
407 427
408config UNORDERED_IO 428config UNORDERED_IO
diff --git a/arch/x86_64/boot/bootsect.S b/arch/x86_64/boot/bootsect.S
index bb15d406ee95..011b7a4993d4 100644
--- a/arch/x86_64/boot/bootsect.S
+++ b/arch/x86_64/boot/bootsect.S
@@ -63,7 +63,7 @@ msg_loop:
63 jz die 63 jz die
64 movb $0xe, %ah 64 movb $0xe, %ah
65 movw $7, %bx 65 movw $7, %bx
66 int $0x10 66 int $0x10
67 jmp msg_loop 67 jmp msg_loop
68 68
69die: 69die:
@@ -71,7 +71,7 @@ die:
71 xorw %ax, %ax 71 xorw %ax, %ax
72 int $0x16 72 int $0x16
73 int $0x19 73 int $0x19
74 74
75 # int 0x19 should never return. In case it does anyway, 75 # int 0x19 should never return. In case it does anyway,
76 # invoke the BIOS reset code... 76 # invoke the BIOS reset code...
77 ljmp $0xf000,$0xfff0 77 ljmp $0xf000,$0xfff0
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index 9ce51dee30b3..569595b74c7c 100644
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-bk7 3# Linux kernel version: 2.6.12-rc4
4# Sat Mar 12 23:43:44 2005 4# Fri May 13 06:39:11 2005
5# 5#
6CONFIG_X86_64=y 6CONFIG_X86_64=y
7CONFIG_64BIT=y 7CONFIG_64BIT=y
@@ -11,8 +11,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
11CONFIG_GENERIC_CALIBRATE_DELAY=y 11CONFIG_GENERIC_CALIBRATE_DELAY=y
12CONFIG_X86_CMPXCHG=y 12CONFIG_X86_CMPXCHG=y
13CONFIG_EARLY_PRINTK=y 13CONFIG_EARLY_PRINTK=y
14CONFIG_HPET_TIMER=y
15CONFIG_HPET_EMULATE_RTC=y
16CONFIG_GENERIC_ISA_DMA=y 14CONFIG_GENERIC_ISA_DMA=y
17CONFIG_GENERIC_IOMAP=y 15CONFIG_GENERIC_IOMAP=y
18 16
@@ -22,6 +20,7 @@ CONFIG_GENERIC_IOMAP=y
22CONFIG_EXPERIMENTAL=y 20CONFIG_EXPERIMENTAL=y
23CONFIG_CLEAN_COMPILE=y 21CONFIG_CLEAN_COMPILE=y
24CONFIG_LOCK_KERNEL=y 22CONFIG_LOCK_KERNEL=y
23CONFIG_INIT_ENV_ARG_LIMIT=32
25 24
26# 25#
27# General setup 26# General setup
@@ -33,7 +32,6 @@ CONFIG_POSIX_MQUEUE=y
33# CONFIG_BSD_PROCESS_ACCT is not set 32# CONFIG_BSD_PROCESS_ACCT is not set
34CONFIG_SYSCTL=y 33CONFIG_SYSCTL=y
35# CONFIG_AUDIT is not set 34# CONFIG_AUDIT is not set
36CONFIG_LOG_BUF_SHIFT=18
37# CONFIG_HOTPLUG is not set 35# CONFIG_HOTPLUG is not set
38CONFIG_KOBJECT_UEVENT=y 36CONFIG_KOBJECT_UEVENT=y
39CONFIG_IKCONFIG=y 37CONFIG_IKCONFIG=y
@@ -43,10 +41,11 @@ CONFIG_IKCONFIG_PROC=y
43CONFIG_KALLSYMS=y 41CONFIG_KALLSYMS=y
44CONFIG_KALLSYMS_ALL=y 42CONFIG_KALLSYMS_ALL=y
45# CONFIG_KALLSYMS_EXTRA_PASS is not set 43# CONFIG_KALLSYMS_EXTRA_PASS is not set
44CONFIG_PRINTK=y
45CONFIG_BUG=y
46CONFIG_BASE_FULL=y 46CONFIG_BASE_FULL=y
47CONFIG_FUTEX=y 47CONFIG_FUTEX=y
48CONFIG_EPOLL=y 48CONFIG_EPOLL=y
49# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
50CONFIG_SHMEM=y 49CONFIG_SHMEM=y
51CONFIG_CC_ALIGN_FUNCTIONS=0 50CONFIG_CC_ALIGN_FUNCTIONS=0
52CONFIG_CC_ALIGN_LABELS=0 51CONFIG_CC_ALIGN_LABELS=0
@@ -93,6 +92,9 @@ CONFIG_DISCONTIGMEM=y
93CONFIG_NUMA=y 92CONFIG_NUMA=y
94CONFIG_HAVE_DEC_LOCK=y 93CONFIG_HAVE_DEC_LOCK=y
95CONFIG_NR_CPUS=8 94CONFIG_NR_CPUS=8
95CONFIG_HPET_TIMER=y
96CONFIG_X86_PM_TIMER=y
97CONFIG_HPET_EMULATE_RTC=y
96CONFIG_GART_IOMMU=y 98CONFIG_GART_IOMMU=y
97CONFIG_SWIOTLB=y 99CONFIG_SWIOTLB=y
98CONFIG_X86_MCE=y 100CONFIG_X86_MCE=y
@@ -100,6 +102,7 @@ CONFIG_X86_MCE_INTEL=y
100CONFIG_SECCOMP=y 102CONFIG_SECCOMP=y
101CONFIG_GENERIC_HARDIRQS=y 103CONFIG_GENERIC_HARDIRQS=y
102CONFIG_GENERIC_IRQ_PROBE=y 104CONFIG_GENERIC_IRQ_PROBE=y
105CONFIG_ISA_DMA_API=y
103 106
104# 107#
105# Power management options 108# Power management options
@@ -129,7 +132,7 @@ CONFIG_ACPI_NUMA=y
129# CONFIG_ACPI_IBM is not set 132# CONFIG_ACPI_IBM is not set
130CONFIG_ACPI_TOSHIBA=y 133CONFIG_ACPI_TOSHIBA=y
131CONFIG_ACPI_BLACKLIST_YEAR=2001 134CONFIG_ACPI_BLACKLIST_YEAR=2001
132CONFIG_ACPI_DEBUG=y 135# CONFIG_ACPI_DEBUG is not set
133CONFIG_ACPI_BUS=y 136CONFIG_ACPI_BUS=y
134CONFIG_ACPI_EC=y 137CONFIG_ACPI_EC=y
135CONFIG_ACPI_POWER=y 138CONFIG_ACPI_POWER=y
@@ -141,6 +144,7 @@ CONFIG_ACPI_SYSTEM=y
141# CPU Frequency scaling 144# CPU Frequency scaling
142# 145#
143CONFIG_CPU_FREQ=y 146CONFIG_CPU_FREQ=y
147CONFIG_CPU_FREQ_TABLE=y
144# CONFIG_CPU_FREQ_DEBUG is not set 148# CONFIG_CPU_FREQ_DEBUG is not set
145CONFIG_CPU_FREQ_STAT=y 149CONFIG_CPU_FREQ_STAT=y
146# CONFIG_CPU_FREQ_STAT_DETAILS is not set 150# CONFIG_CPU_FREQ_STAT_DETAILS is not set
@@ -150,7 +154,6 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
150# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set 154# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
151CONFIG_CPU_FREQ_GOV_USERSPACE=y 155CONFIG_CPU_FREQ_GOV_USERSPACE=y
152CONFIG_CPU_FREQ_GOV_ONDEMAND=y 156CONFIG_CPU_FREQ_GOV_ONDEMAND=y
153CONFIG_CPU_FREQ_TABLE=y
154 157
155# 158#
156# CPUFreq processor drivers 159# CPUFreq processor drivers
@@ -164,6 +167,7 @@ CONFIG_X86_ACPI_CPUFREQ=y
164# shared options 167# shared options
165# 168#
166CONFIG_X86_ACPI_CPUFREQ_PROC_INTF=y 169CONFIG_X86_ACPI_CPUFREQ_PROC_INTF=y
170# CONFIG_X86_SPEEDSTEP_LIB is not set
167 171
168# 172#
169# Bus options (PCI etc.) 173# Bus options (PCI etc.)
@@ -172,9 +176,11 @@ CONFIG_PCI=y
172CONFIG_PCI_DIRECT=y 176CONFIG_PCI_DIRECT=y
173CONFIG_PCI_MMCONFIG=y 177CONFIG_PCI_MMCONFIG=y
174CONFIG_UNORDERED_IO=y 178CONFIG_UNORDERED_IO=y
179# CONFIG_PCIEPORTBUS is not set
175CONFIG_PCI_MSI=y 180CONFIG_PCI_MSI=y
176# CONFIG_PCI_LEGACY_PROC is not set 181# CONFIG_PCI_LEGACY_PROC is not set
177# CONFIG_PCI_NAMES is not set 182# CONFIG_PCI_NAMES is not set
183# CONFIG_PCI_DEBUG is not set
178 184
179# 185#
180# PCCARD (PCMCIA/CardBus) support 186# PCCARD (PCMCIA/CardBus) support
@@ -182,10 +188,6 @@ CONFIG_PCI_MSI=y
182# CONFIG_PCCARD is not set 188# CONFIG_PCCARD is not set
183 189
184# 190#
185# PC-card bridges
186#
187
188#
189# PCI Hotplug Support 191# PCI Hotplug Support
190# 192#
191# CONFIG_HOTPLUG_PCI is not set 193# CONFIG_HOTPLUG_PCI is not set
@@ -254,7 +256,7 @@ CONFIG_LBD=y
254# IO Schedulers 256# IO Schedulers
255# 257#
256CONFIG_IOSCHED_NOOP=y 258CONFIG_IOSCHED_NOOP=y
257CONFIG_IOSCHED_AS=y 259# CONFIG_IOSCHED_AS is not set
258CONFIG_IOSCHED_DEADLINE=y 260CONFIG_IOSCHED_DEADLINE=y
259CONFIG_IOSCHED_CFQ=y 261CONFIG_IOSCHED_CFQ=y
260# CONFIG_ATA_OVER_ETH is not set 262# CONFIG_ATA_OVER_ETH is not set
@@ -308,7 +310,8 @@ CONFIG_BLK_DEV_AMD74XX=y
308CONFIG_BLK_DEV_PIIX=y 310CONFIG_BLK_DEV_PIIX=y
309# CONFIG_BLK_DEV_NS87415 is not set 311# CONFIG_BLK_DEV_NS87415 is not set
310# CONFIG_BLK_DEV_PDC202XX_OLD is not set 312# CONFIG_BLK_DEV_PDC202XX_OLD is not set
311# CONFIG_BLK_DEV_PDC202XX_NEW is not set 313CONFIG_BLK_DEV_PDC202XX_NEW=y
314# CONFIG_PDC202XX_FORCE is not set
312# CONFIG_BLK_DEV_SVWKS is not set 315# CONFIG_BLK_DEV_SVWKS is not set
313# CONFIG_BLK_DEV_SIIMAGE is not set 316# CONFIG_BLK_DEV_SIIMAGE is not set
314# CONFIG_BLK_DEV_SIS5513 is not set 317# CONFIG_BLK_DEV_SIS5513 is not set
@@ -353,7 +356,7 @@ CONFIG_BLK_DEV_SD=y
353# 356#
354# SCSI low-level drivers 357# SCSI low-level drivers
355# 358#
356CONFIG_BLK_DEV_3W_XXXX_RAID=y 359# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
357# CONFIG_SCSI_3W_9XXX is not set 360# CONFIG_SCSI_3W_9XXX is not set
358# CONFIG_SCSI_ACARD is not set 361# CONFIG_SCSI_ACARD is not set
359# CONFIG_SCSI_AACRAID is not set 362# CONFIG_SCSI_AACRAID is not set
@@ -384,7 +387,6 @@ CONFIG_SCSI_SATA_VIA=y
384# CONFIG_SCSI_BUSLOGIC is not set 387# CONFIG_SCSI_BUSLOGIC is not set
385# CONFIG_SCSI_DMX3191D is not set 388# CONFIG_SCSI_DMX3191D is not set
386# CONFIG_SCSI_EATA is not set 389# CONFIG_SCSI_EATA is not set
387# CONFIG_SCSI_EATA_PIO is not set
388# CONFIG_SCSI_FUTURE_DOMAIN is not set 390# CONFIG_SCSI_FUTURE_DOMAIN is not set
389# CONFIG_SCSI_GDTH is not set 391# CONFIG_SCSI_GDTH is not set
390# CONFIG_SCSI_IPS is not set 392# CONFIG_SCSI_IPS is not set
@@ -392,7 +394,6 @@ CONFIG_SCSI_SATA_VIA=y
392# CONFIG_SCSI_INIA100 is not set 394# CONFIG_SCSI_INIA100 is not set
393# CONFIG_SCSI_SYM53C8XX_2 is not set 395# CONFIG_SCSI_SYM53C8XX_2 is not set
394# CONFIG_SCSI_IPR is not set 396# CONFIG_SCSI_IPR is not set
395# CONFIG_SCSI_QLOGIC_ISP is not set
396# CONFIG_SCSI_QLOGIC_FC is not set 397# CONFIG_SCSI_QLOGIC_FC is not set
397# CONFIG_SCSI_QLOGIC_1280 is not set 398# CONFIG_SCSI_QLOGIC_1280 is not set
398CONFIG_SCSI_QLA2XXX=y 399CONFIG_SCSI_QLA2XXX=y
@@ -401,6 +402,7 @@ CONFIG_SCSI_QLA2XXX=y
401# CONFIG_SCSI_QLA2300 is not set 402# CONFIG_SCSI_QLA2300 is not set
402# CONFIG_SCSI_QLA2322 is not set 403# CONFIG_SCSI_QLA2322 is not set
403# CONFIG_SCSI_QLA6312 is not set 404# CONFIG_SCSI_QLA6312 is not set
405# CONFIG_SCSI_LPFC is not set
404# CONFIG_SCSI_DC395x is not set 406# CONFIG_SCSI_DC395x is not set
405# CONFIG_SCSI_DC390T is not set 407# CONFIG_SCSI_DC390T is not set
406# CONFIG_SCSI_DEBUG is not set 408# CONFIG_SCSI_DEBUG is not set
@@ -437,7 +439,6 @@ CONFIG_NET=y
437# 439#
438CONFIG_PACKET=y 440CONFIG_PACKET=y
439# CONFIG_PACKET_MMAP is not set 441# CONFIG_PACKET_MMAP is not set
440# CONFIG_NETLINK_DEV is not set
441CONFIG_UNIX=y 442CONFIG_UNIX=y
442# CONFIG_NET_KEY is not set 443# CONFIG_NET_KEY is not set
443CONFIG_INET=y 444CONFIG_INET=y
@@ -502,7 +503,7 @@ CONFIG_NETDEVICES=y
502# CONFIG_DUMMY is not set 503# CONFIG_DUMMY is not set
503# CONFIG_BONDING is not set 504# CONFIG_BONDING is not set
504# CONFIG_EQUALIZER is not set 505# CONFIG_EQUALIZER is not set
505# CONFIG_TUN is not set 506CONFIG_TUN=y
506 507
507# 508#
508# ARCnet devices 509# ARCnet devices
@@ -525,8 +526,7 @@ CONFIG_MII=y
525# CONFIG_HP100 is not set 526# CONFIG_HP100 is not set
526CONFIG_NET_PCI=y 527CONFIG_NET_PCI=y
527# CONFIG_PCNET32 is not set 528# CONFIG_PCNET32 is not set
528CONFIG_AMD8111_ETH=y 529# CONFIG_AMD8111_ETH is not set
529# CONFIG_AMD8111E_NAPI is not set
530# CONFIG_ADAPTEC_STARFIRE is not set 530# CONFIG_ADAPTEC_STARFIRE is not set
531# CONFIG_B44 is not set 531# CONFIG_B44 is not set
532CONFIG_FORCEDETH=y 532CONFIG_FORCEDETH=y
@@ -536,7 +536,7 @@ CONFIG_FORCEDETH=y
536# CONFIG_FEALNX is not set 536# CONFIG_FEALNX is not set
537# CONFIG_NATSEMI is not set 537# CONFIG_NATSEMI is not set
538# CONFIG_NE2K_PCI is not set 538# CONFIG_NE2K_PCI is not set
539CONFIG_8139CP=m 539CONFIG_8139CP=y
540CONFIG_8139TOO=y 540CONFIG_8139TOO=y
541# CONFIG_8139TOO_PIO is not set 541# CONFIG_8139TOO_PIO is not set
542# CONFIG_8139TOO_TUNE_TWISTER is not set 542# CONFIG_8139TOO_TUNE_TWISTER is not set
@@ -671,6 +671,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
671# 671#
672CONFIG_SERIAL_CORE=y 672CONFIG_SERIAL_CORE=y
673CONFIG_SERIAL_CORE_CONSOLE=y 673CONFIG_SERIAL_CORE_CONSOLE=y
674# CONFIG_SERIAL_JSM is not set
674CONFIG_UNIX98_PTYS=y 675CONFIG_UNIX98_PTYS=y
675CONFIG_LEGACY_PTYS=y 676CONFIG_LEGACY_PTYS=y
676CONFIG_LEGACY_PTY_COUNT=256 677CONFIG_LEGACY_PTY_COUNT=256
@@ -696,6 +697,7 @@ CONFIG_RTC=y
696# 697#
697CONFIG_AGP=y 698CONFIG_AGP=y
698CONFIG_AGP_AMD64=y 699CONFIG_AGP_AMD64=y
700CONFIG_AGP_INTEL=y
699# CONFIG_DRM is not set 701# CONFIG_DRM is not set
700# CONFIG_MWAVE is not set 702# CONFIG_MWAVE is not set
701CONFIG_RAW_DRIVER=y 703CONFIG_RAW_DRIVER=y
@@ -703,7 +705,7 @@ CONFIG_HPET=y
703# CONFIG_HPET_RTC_IRQ is not set 705# CONFIG_HPET_RTC_IRQ is not set
704CONFIG_HPET_MMAP=y 706CONFIG_HPET_MMAP=y
705CONFIG_MAX_RAW_DEVS=256 707CONFIG_MAX_RAW_DEVS=256
706CONFIG_HANGCHECK_TIMER=y 708# CONFIG_HANGCHECK_TIMER is not set
707 709
708# 710#
709# TPM devices 711# TPM devices
@@ -786,6 +788,8 @@ CONFIG_SOUND_ICH=y
786# 788#
787# USB support 789# USB support
788# 790#
791CONFIG_USB_ARCH_HAS_HCD=y
792CONFIG_USB_ARCH_HAS_OHCI=y
789CONFIG_USB=y 793CONFIG_USB=y
790# CONFIG_USB_DEBUG is not set 794# CONFIG_USB_DEBUG is not set
791 795
@@ -797,8 +801,6 @@ CONFIG_USB_DEVICEFS=y
797# CONFIG_USB_DYNAMIC_MINORS is not set 801# CONFIG_USB_DYNAMIC_MINORS is not set
798# CONFIG_USB_SUSPEND is not set 802# CONFIG_USB_SUSPEND is not set
799# CONFIG_USB_OTG is not set 803# CONFIG_USB_OTG is not set
800CONFIG_USB_ARCH_HAS_HCD=y
801CONFIG_USB_ARCH_HAS_OHCI=y
802 804
803# 805#
804# USB Host Controller Drivers 806# USB Host Controller Drivers
@@ -826,7 +828,6 @@ CONFIG_USB_PRINTER=y
826# 828#
827CONFIG_USB_STORAGE=y 829CONFIG_USB_STORAGE=y
828# CONFIG_USB_STORAGE_DEBUG is not set 830# CONFIG_USB_STORAGE_DEBUG is not set
829# CONFIG_USB_STORAGE_RW_DETECT is not set
830# CONFIG_USB_STORAGE_DATAFAB is not set 831# CONFIG_USB_STORAGE_DATAFAB is not set
831# CONFIG_USB_STORAGE_FREECOM is not set 832# CONFIG_USB_STORAGE_FREECOM is not set
832# CONFIG_USB_STORAGE_ISD200 is not set 833# CONFIG_USB_STORAGE_ISD200 is not set
@@ -965,7 +966,7 @@ CONFIG_AUTOFS_FS=y
965# CD-ROM/DVD Filesystems 966# CD-ROM/DVD Filesystems
966# 967#
967CONFIG_ISO9660_FS=y 968CONFIG_ISO9660_FS=y
968# CONFIG_JOLIET is not set 969CONFIG_JOLIET=y
969# CONFIG_ZISOFS is not set 970# CONFIG_ZISOFS is not set
970# CONFIG_UDF_FS is not set 971# CONFIG_UDF_FS is not set
971 972
@@ -1092,9 +1093,10 @@ CONFIG_OPROFILE=y
1092# 1093#
1093# Kernel hacking 1094# Kernel hacking
1094# 1095#
1096# CONFIG_PRINTK_TIME is not set
1095CONFIG_DEBUG_KERNEL=y 1097CONFIG_DEBUG_KERNEL=y
1096CONFIG_MAGIC_SYSRQ=y 1098CONFIG_MAGIC_SYSRQ=y
1097# CONFIG_PRINTK_TIME is not set 1099CONFIG_LOG_BUF_SHIFT=18
1098# CONFIG_SCHEDSTATS is not set 1100# CONFIG_SCHEDSTATS is not set
1099# CONFIG_DEBUG_SLAB is not set 1101# CONFIG_DEBUG_SLAB is not set
1100# CONFIG_DEBUG_SPINLOCK is not set 1102# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
index 0a3318e08ab6..5ca4a4598fda 100644
--- a/arch/x86_64/kernel/Makefile
+++ b/arch/x86_64/kernel/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o
28obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o 28obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o
29obj-$(CONFIG_SWIOTLB) += swiotlb.o 29obj-$(CONFIG_SWIOTLB) += swiotlb.o
30obj-$(CONFIG_KPROBES) += kprobes.o 30obj-$(CONFIG_KPROBES) += kprobes.o
31obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o
31 32
32obj-$(CONFIG_MODULES) += module.o 33obj-$(CONFIG_MODULES) += module.o
33 34
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c
index a491f72cc966..504e63474993 100644
--- a/arch/x86_64/kernel/aperture.c
+++ b/arch/x86_64/kernel/aperture.c
@@ -33,12 +33,10 @@ int fallback_aper_force __initdata = 0;
33 33
34int fix_aperture __initdata = 1; 34int fix_aperture __initdata = 1;
35 35
36#define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16)) 36/* This code runs before the PCI subsystem is initialized, so just
37 access the northbridge directly. */
37 38
38static struct resource aper_res = { 39#define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16))
39 .name = "Aperture",
40 .flags = IORESOURCE_MEM,
41};
42 40
43static u32 __init allocate_aperture(void) 41static u32 __init allocate_aperture(void)
44{ 42{
@@ -55,24 +53,11 @@ static u32 __init allocate_aperture(void)
55 aper_size = (32 * 1024 * 1024) << fallback_aper_order; 53 aper_size = (32 * 1024 * 1024) << fallback_aper_order;
56 54
57 /* 55 /*
58 * Aperture has to be naturally aligned. This means an 2GB 56 * Aperture has to be naturally aligned. This means an 2GB aperture won't
59 * aperture won't have much chances to find a place in the 57 * have much chances to find a place in the lower 4GB of memory.
60 * lower 4GB of memory. Unfortunately we cannot move it up 58 * Unfortunately we cannot move it up because that would make the
61 * because that would make the IOMMU useless. 59 * IOMMU useless.
62 */ 60 */
63
64 /* First try to find some free unused space */
65 if (!allocate_resource(&iomem_resource, &aper_res,
66 aper_size,
67 0, 0xffffffff,
68 aper_size,
69 NULL, NULL)) {
70 printk(KERN_INFO "Putting aperture at %lx-%lx\n",
71 aper_res.start, aper_res.end);
72 return aper_res.start;
73 }
74
75 /* No free space found. Go on to waste some memory... */
76 p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); 61 p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0);
77 if (!p || __pa(p)+aper_size > 0xffffffff) { 62 if (!p || __pa(p)+aper_size > 0xffffffff) {
78 printk("Cannot allocate aperture memory hole (%p,%uK)\n", 63 printk("Cannot allocate aperture memory hole (%p,%uK)\n",
@@ -81,7 +66,7 @@ static u32 __init allocate_aperture(void)
81 free_bootmem_node(nd0, (unsigned long)p, aper_size); 66 free_bootmem_node(nd0, (unsigned long)p, aper_size);
82 return 0; 67 return 0;
83 } 68 }
84 printk("Mapping aperture over %d KB of precious RAM @ %lx\n", 69 printk("Mapping aperture over %d KB of RAM @ %lx\n",
85 aper_size >> 10, __pa(p)); 70 aper_size >> 10, __pa(p));
86 return (u32)__pa(p); 71 return (u32)__pa(p);
87} 72}
@@ -102,16 +87,10 @@ static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size)
102 printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name); 87 printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name);
103 return 0; 88 return 0;
104 } 89 }
105 /* Don't check the resource here because the aperture is usually
106 in an e820 reserved area, and we allocated these earlier. */
107 return 1; 90 return 1;
108} 91}
109 92
110/* 93/* Find a PCI capability */
111 * Find a PCI capability.
112 * This code runs before the PCI subsystem is initialized, so just
113 * access the northbridge directly.
114 */
115static __u32 __init find_cap(int num, int slot, int func, int cap) 94static __u32 __init find_cap(int num, int slot, int func, int cap)
116{ 95{
117 u8 pos; 96 u8 pos;
@@ -276,6 +255,8 @@ void __init iommu_hole_init(void)
276 fallback_aper_force) { 255 fallback_aper_force) {
277 printk("Your BIOS doesn't leave a aperture memory hole\n"); 256 printk("Your BIOS doesn't leave a aperture memory hole\n");
278 printk("Please enable the IOMMU option in the BIOS setup\n"); 257 printk("Please enable the IOMMU option in the BIOS setup\n");
258 printk("This costs you %d MB of RAM\n",
259 32 << fallback_aper_order);
279 260
280 aper_order = fallback_aper_order; 261 aper_order = fallback_aper_order;
281 aper_alloc = allocate_aperture(); 262 aper_alloc = allocate_aperture();
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index 7e13545748e0..f8e6cc4fecd4 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -33,6 +33,7 @@
33#include <asm/mpspec.h> 33#include <asm/mpspec.h>
34#include <asm/pgalloc.h> 34#include <asm/pgalloc.h>
35#include <asm/mach_apic.h> 35#include <asm/mach_apic.h>
36#include <asm/nmi.h>
36 37
37int apic_verbosity; 38int apic_verbosity;
38 39
@@ -925,7 +926,7 @@ __init int oem_force_hpet_timer(void)
925 unsigned id; 926 unsigned id;
926 DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS); 927 DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS);
927 928
928 bitmap_empty(clustermap, NUM_APIC_CLUSTERS); 929 bitmap_zero(clustermap, NUM_APIC_CLUSTERS);
929 930
930 for (i = 0; i < NR_CPUS; i++) { 931 for (i = 0; i < NR_CPUS; i++) {
931 id = bios_cpu_apicid[i]; 932 id = bios_cpu_apicid[i];
@@ -1056,7 +1057,7 @@ int __init APIC_init_uniprocessor (void)
1056 nr_ioapics = 0; 1057 nr_ioapics = 0;
1057#endif 1058#endif
1058 setup_boot_APIC_clock(); 1059 setup_boot_APIC_clock();
1059 1060 check_nmi_watchdog();
1060 return 0; 1061 return 0;
1061} 1062}
1062 1063
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index 1086b5fcac21..28817490fdc6 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -220,13 +220,18 @@ sysret_careful:
220 jmp sysret_check 220 jmp sysret_check
221 221
222 /* Handle a signal */ 222 /* Handle a signal */
223 /* edx: work flags (arg3) */
224sysret_signal: 223sysret_signal:
225 sti 224 sti
225 testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
226 jz 1f
227
228 /* Really a signal */
229 /* edx: work flags (arg3) */
226 leaq do_notify_resume(%rip),%rax 230 leaq do_notify_resume(%rip),%rax
227 leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1 231 leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1
228 xorl %esi,%esi # oldset -> arg2 232 xorl %esi,%esi # oldset -> arg2
229 call ptregscall_common 233 call ptregscall_common
2341: movl $_TIF_NEED_RESCHED,%edi
230 jmp sysret_check 235 jmp sysret_check
231 236
232 /* Do syscall tracing */ 237 /* Do syscall tracing */
@@ -484,6 +489,8 @@ retint_careful:
484 jmp retint_check 489 jmp retint_check
485 490
486retint_signal: 491retint_signal:
492 testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
493 jz retint_swapgs
487 sti 494 sti
488 SAVE_REST 495 SAVE_REST
489 movq $-1,ORIG_RAX(%rsp) 496 movq $-1,ORIG_RAX(%rsp)
@@ -492,8 +499,8 @@ retint_signal:
492 call do_notify_resume 499 call do_notify_resume
493 RESTORE_REST 500 RESTORE_REST
494 cli 501 cli
502 movl $_TIF_NEED_RESCHED,%edi
495 GET_THREAD_INFO(%rcx) 503 GET_THREAD_INFO(%rcx)
496 movl $_TIF_WORK_MASK,%edi
497 jmp retint_check 504 jmp retint_check
498 505
499#ifdef CONFIG_PREEMPT 506#ifdef CONFIG_PREEMPT
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 60be58617eb9..afd87e64d0a8 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -37,11 +37,14 @@
37#include <asm/desc.h> 37#include <asm/desc.h>
38#include <asm/proto.h> 38#include <asm/proto.h>
39#include <asm/mach_apic.h> 39#include <asm/mach_apic.h>
40#include <asm/acpi.h>
40 41
41#define __apicdebuginit __init 42#define __apicdebuginit __init
42 43
43int sis_apic_bug; /* not actually supported, dummy for compile */ 44int sis_apic_bug; /* not actually supported, dummy for compile */
44 45
46static int no_timer_check;
47
45static DEFINE_SPINLOCK(ioapic_lock); 48static DEFINE_SPINLOCK(ioapic_lock);
46 49
47/* 50/*
@@ -1601,7 +1604,7 @@ static inline void check_timer(void)
1601 * Ok, does IRQ0 through the IOAPIC work? 1604 * Ok, does IRQ0 through the IOAPIC work?
1602 */ 1605 */
1603 unmask_IO_APIC_irq(0); 1606 unmask_IO_APIC_irq(0);
1604 if (timer_irq_works()) { 1607 if (!no_timer_check && timer_irq_works()) {
1605 nmi_watchdog_default(); 1608 nmi_watchdog_default();
1606 if (nmi_watchdog == NMI_IO_APIC) { 1609 if (nmi_watchdog == NMI_IO_APIC) {
1607 disable_8259A_irq(0); 1610 disable_8259A_irq(0);
@@ -1671,6 +1674,13 @@ static inline void check_timer(void)
1671 panic("IO-APIC + timer doesn't work! Try using the 'noapic' kernel parameter\n"); 1674 panic("IO-APIC + timer doesn't work! Try using the 'noapic' kernel parameter\n");
1672} 1675}
1673 1676
1677static int __init notimercheck(char *s)
1678{
1679 no_timer_check = 1;
1680 return 1;
1681}
1682__setup("no_timer_check", notimercheck);
1683
1674/* 1684/*
1675 * 1685 *
1676 * IRQ's that are handled by the PIC in the MPS IOAPIC case. 1686 * IRQ's that are handled by the PIC in the MPS IOAPIC case.
@@ -1804,76 +1814,6 @@ device_initcall(ioapic_init_sysfs);
1804 1814
1805#define IO_APIC_MAX_ID 0xFE 1815#define IO_APIC_MAX_ID 0xFE
1806 1816
1807int __init io_apic_get_unique_id (int ioapic, int apic_id)
1808{
1809 union IO_APIC_reg_00 reg_00;
1810 static physid_mask_t apic_id_map;
1811 unsigned long flags;
1812 int i = 0;
1813
1814 /*
1815 * The P4 platform supports up to 256 APIC IDs on two separate APIC
1816 * buses (one for LAPICs, one for IOAPICs), where predecessors only
1817 * supports up to 16 on one shared APIC bus.
1818 *
1819 * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full
1820 * advantage of new APIC bus architecture.
1821 */
1822
1823 if (physids_empty(apic_id_map))
1824 apic_id_map = phys_cpu_present_map;
1825
1826 spin_lock_irqsave(&ioapic_lock, flags);
1827 reg_00.raw = io_apic_read(ioapic, 0);
1828 spin_unlock_irqrestore(&ioapic_lock, flags);
1829
1830 if (apic_id >= IO_APIC_MAX_ID) {
1831 apic_printk(APIC_QUIET, KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying "
1832 "%d\n", ioapic, apic_id, reg_00.bits.ID);
1833 apic_id = reg_00.bits.ID;
1834 }
1835
1836 /*
1837 * Every APIC in a system must have a unique ID or we get lots of nice
1838 * 'stuck on smp_invalidate_needed IPI wait' messages.
1839 */
1840 if (physid_isset(apic_id, apic_id_map)) {
1841
1842 for (i = 0; i < IO_APIC_MAX_ID; i++) {
1843 if (!physid_isset(i, apic_id_map))
1844 break;
1845 }
1846
1847 if (i == IO_APIC_MAX_ID)
1848 panic("Max apic_id exceeded!\n");
1849
1850 apic_printk(APIC_VERBOSE, KERN_WARNING "IOAPIC[%d]: apic_id %d already used, "
1851 "trying %d\n", ioapic, apic_id, i);
1852
1853 apic_id = i;
1854 }
1855
1856 physid_set(apic_id, apic_id_map);
1857
1858 if (reg_00.bits.ID != apic_id) {
1859 reg_00.bits.ID = apic_id;
1860
1861 spin_lock_irqsave(&ioapic_lock, flags);
1862 io_apic_write(ioapic, 0, reg_00.raw);
1863 reg_00.raw = io_apic_read(ioapic, 0);
1864 spin_unlock_irqrestore(&ioapic_lock, flags);
1865
1866 /* Sanity check */
1867 if (reg_00.bits.ID != apic_id)
1868 panic("IOAPIC[%d]: Unable change apic_id!\n", ioapic);
1869 }
1870
1871 apic_printk(APIC_VERBOSE,KERN_INFO "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id);
1872
1873 return apic_id;
1874}
1875
1876
1877int __init io_apic_get_version (int ioapic) 1817int __init io_apic_get_version (int ioapic)
1878{ 1818{
1879 union IO_APIC_reg_01 reg_01; 1819 union IO_APIC_reg_01 reg_01;
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
index 4f2a852299b6..f77f8a0ff187 100644
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -355,6 +355,13 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs)
355 *tos &= ~(TF_MASK | IF_MASK); 355 *tos &= ~(TF_MASK | IF_MASK);
356 *tos |= kprobe_old_rflags; 356 *tos |= kprobe_old_rflags;
357 break; 357 break;
358 case 0xc3: /* ret/lret */
359 case 0xcb:
360 case 0xc2:
361 case 0xca:
362 regs->eflags &= ~TF_MASK;
363 /* rip is already adjusted, no more changes required*/
364 return;
358 case 0xe8: /* call relative - Fix return addr */ 365 case 0xe8: /* call relative - Fix return addr */
359 *tos = orig_rip + (*tos - copy_rip); 366 *tos = orig_rip + (*tos - copy_rip);
360 break; 367 break;
diff --git a/arch/x86_64/kernel/module.c b/arch/x86_64/kernel/module.c
index c2ffea8845ed..bac195c74bcc 100644
--- a/arch/x86_64/kernel/module.c
+++ b/arch/x86_64/kernel/module.c
@@ -30,9 +30,12 @@
30 30
31#define DEBUGP(fmt...) 31#define DEBUGP(fmt...)
32 32
33#ifndef CONFIG_UML
33void module_free(struct module *mod, void *module_region) 34void module_free(struct module *mod, void *module_region)
34{ 35{
35 vfree(module_region); 36 vfree(module_region);
37 /* FIXME: If module_region == mod->init_region, trim exception
38 table entries. */
36} 39}
37 40
38void *module_alloc(unsigned long size) 41void *module_alloc(unsigned long size)
@@ -51,6 +54,7 @@ void *module_alloc(unsigned long size)
51 54
52 return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC); 55 return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
53} 56}
57#endif
54 58
55/* We don't need anything special. */ 59/* We don't need anything special. */
56int module_frob_arch_sections(Elf_Ehdr *hdr, 60int module_frob_arch_sections(Elf_Ehdr *hdr,
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index 7ec031c6ca10..61a63be6b294 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -30,6 +30,7 @@
30#include <asm/pgalloc.h> 30#include <asm/pgalloc.h>
31#include <asm/io_apic.h> 31#include <asm/io_apic.h>
32#include <asm/proto.h> 32#include <asm/proto.h>
33#include <asm/acpi.h>
33 34
34/* Have we found an MP table */ 35/* Have we found an MP table */
35int smp_found_config; 36int smp_found_config;
@@ -107,6 +108,7 @@ static int __init mpf_checksum(unsigned char *mp, int len)
107static void __init MP_processor_info (struct mpc_config_processor *m) 108static void __init MP_processor_info (struct mpc_config_processor *m)
108{ 109{
109 int ver; 110 int ver;
111 static int found_bsp=0;
110 112
111 if (!(m->mpc_cpuflag & CPU_ENABLED)) 113 if (!(m->mpc_cpuflag & CPU_ENABLED))
112 return; 114 return;
@@ -126,11 +128,6 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
126 " Processor ignored.\n", NR_CPUS); 128 " Processor ignored.\n", NR_CPUS);
127 return; 129 return;
128 } 130 }
129 if (num_processors >= maxcpus) {
130 printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
131 " Processor ignored.\n", maxcpus);
132 return;
133 }
134 131
135 num_processors++; 132 num_processors++;
136 133
@@ -150,7 +147,19 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
150 ver = 0x10; 147 ver = 0x10;
151 } 148 }
152 apic_version[m->mpc_apicid] = ver; 149 apic_version[m->mpc_apicid] = ver;
153 bios_cpu_apicid[num_processors - 1] = m->mpc_apicid; 150 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
151 /*
152 * bios_cpu_apicid is required to have processors listed
153 * in same order as logical cpu numbers. Hence the first
154 * entry is BSP, and so on.
155 */
156 bios_cpu_apicid[0] = m->mpc_apicid;
157 x86_cpu_to_apicid[0] = m->mpc_apicid;
158 found_bsp = 1;
159 } else {
160 bios_cpu_apicid[num_processors - found_bsp] = m->mpc_apicid;
161 x86_cpu_to_apicid[num_processors - found_bsp] = m->mpc_apicid;
162 }
154} 163}
155 164
156static void __init MP_bus_info (struct mpc_config_bus *m) 165static void __init MP_bus_info (struct mpc_config_bus *m)
@@ -759,7 +768,7 @@ void __init mp_register_ioapic (
759 mp_ioapics[idx].mpc_apicaddr = address; 768 mp_ioapics[idx].mpc_apicaddr = address;
760 769
761 set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); 770 set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
762 mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id); 771 mp_ioapics[idx].mpc_apicid = id;
763 mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); 772 mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx);
764 773
765 /* 774 /*
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index 61de0b34a01e..31c0f2e6ac91 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -33,6 +33,7 @@
33#include <asm/msr.h> 33#include <asm/msr.h>
34#include <asm/proto.h> 34#include <asm/proto.h>
35#include <asm/kdebug.h> 35#include <asm/kdebug.h>
36#include <asm/local.h>
36 37
37/* 38/*
38 * lapic_nmi_owner tracks the ownership of the lapic NMI hardware: 39 * lapic_nmi_owner tracks the ownership of the lapic NMI hardware:
@@ -59,7 +60,8 @@ int panic_on_timeout;
59 60
60unsigned int nmi_watchdog = NMI_DEFAULT; 61unsigned int nmi_watchdog = NMI_DEFAULT;
61static unsigned int nmi_hz = HZ; 62static unsigned int nmi_hz = HZ;
62unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ 63static unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */
64static unsigned int nmi_p4_cccr_val;
63 65
64/* Note that these events don't tick when the CPU idles. This means 66/* Note that these events don't tick when the CPU idles. This means
65 the frequency varies with CPU load. */ 67 the frequency varies with CPU load. */
@@ -71,61 +73,87 @@ unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */
71#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 73#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76
72#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 74#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING
73 75
74#define P6_EVNTSEL0_ENABLE (1 << 22) 76#define MSR_P4_MISC_ENABLE 0x1A0
75#define P6_EVNTSEL_INT (1 << 20) 77#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7)
76#define P6_EVNTSEL_OS (1 << 17) 78#define MSR_P4_MISC_ENABLE_PEBS_UNAVAIL (1<<12)
77#define P6_EVNTSEL_USR (1 << 16) 79#define MSR_P4_PERFCTR0 0x300
78#define P6_EVENT_CPU_CLOCKS_NOT_HALTED 0x79 80#define MSR_P4_CCCR0 0x360
79#define P6_NMI_EVENT P6_EVENT_CPU_CLOCKS_NOT_HALTED 81#define P4_ESCR_EVENT_SELECT(N) ((N)<<25)
82#define P4_ESCR_OS (1<<3)
83#define P4_ESCR_USR (1<<2)
84#define P4_CCCR_OVF_PMI0 (1<<26)
85#define P4_CCCR_OVF_PMI1 (1<<27)
86#define P4_CCCR_THRESHOLD(N) ((N)<<20)
87#define P4_CCCR_COMPLEMENT (1<<19)
88#define P4_CCCR_COMPARE (1<<18)
89#define P4_CCCR_REQUIRED (3<<16)
90#define P4_CCCR_ESCR_SELECT(N) ((N)<<13)
91#define P4_CCCR_ENABLE (1<<12)
92/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter
93 CRU_ESCR0 (with any non-null event selector) through a complemented
94 max threshold. [IA32-Vol3, Section 14.9.9] */
95#define MSR_P4_IQ_COUNTER0 0x30C
96#define P4_NMI_CRU_ESCR0 (P4_ESCR_EVENT_SELECT(0x3F)|P4_ESCR_OS|P4_ESCR_USR)
97#define P4_NMI_IQ_CCCR0 \
98 (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \
99 P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE)
100
101static __init inline int nmi_known_cpu(void)
102{
103 switch (boot_cpu_data.x86_vendor) {
104 case X86_VENDOR_AMD:
105 return boot_cpu_data.x86 == 15;
106 case X86_VENDOR_INTEL:
107 return boot_cpu_data.x86 == 15;
108 }
109 return 0;
110}
80 111
81/* Run after command line and cpu_init init, but before all other checks */ 112/* Run after command line and cpu_init init, but before all other checks */
82void __init nmi_watchdog_default(void) 113void __init nmi_watchdog_default(void)
83{ 114{
84 if (nmi_watchdog != NMI_DEFAULT) 115 if (nmi_watchdog != NMI_DEFAULT)
85 return; 116 return;
86 117 if (nmi_known_cpu())
87 /* For some reason the IO APIC watchdog doesn't work on the AMD 118 nmi_watchdog = NMI_LOCAL_APIC;
88 8111 chipset. For now switch to local APIC mode using 119 else
89 perfctr0 there. On Intel CPUs we don't have code to handle
90 the perfctr and the IO-APIC seems to work, so use that. */
91
92 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
93 nmi_watchdog = NMI_LOCAL_APIC;
94 printk(KERN_INFO
95 "Using local APIC NMI watchdog using perfctr0\n");
96 } else {
97 printk(KERN_INFO "Using IO APIC NMI watchdog\n");
98 nmi_watchdog = NMI_IO_APIC; 120 nmi_watchdog = NMI_IO_APIC;
99 }
100} 121}
101 122
102/* Why is there no CPUID flag for this? */ 123#ifdef CONFIG_SMP
103static __init int cpu_has_lapic(void) 124/* The performance counters used by NMI_LOCAL_APIC don't trigger when
125 * the CPU is idle. To make sure the NMI watchdog really ticks on all
126 * CPUs during the test make them busy.
127 */
128static __init void nmi_cpu_busy(void *data)
104{ 129{
105 switch (boot_cpu_data.x86_vendor) { 130 volatile int *endflag = data;
106 case X86_VENDOR_INTEL: 131 local_irq_enable();
107 case X86_VENDOR_AMD: 132 /* Intentionally don't use cpu_relax here. This is
108 return boot_cpu_data.x86 >= 6; 133 to make sure that the performance counter really ticks,
109 /* .... add more cpus here or find a different way to figure this out. */ 134 even if there is a simulator or similar that catches the
110 default: 135 pause instruction. On a real HT machine this is fine because
111 return 0; 136 all other CPUs are busy with "useless" delay loops and don't
112 } 137 care if they get somewhat less cycles. */
138 while (*endflag == 0)
139 barrier();
113} 140}
141#endif
114 142
115static int __init check_nmi_watchdog (void) 143int __init check_nmi_watchdog (void)
116{ 144{
117 int counts[NR_CPUS]; 145 volatile int endflag = 0;
146 int *counts;
118 int cpu; 147 int cpu;
119 148
120 if (nmi_watchdog == NMI_NONE) 149 counts = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL);
121 return 0; 150 if (!counts)
151 return -1;
122 152
123 if (nmi_watchdog == NMI_LOCAL_APIC && !cpu_has_lapic()) { 153 printk(KERN_INFO "testing NMI watchdog ... ");
124 nmi_watchdog = NMI_NONE;
125 return -1;
126 }
127 154
128 printk(KERN_INFO "Testing NMI watchdog ... "); 155 if (nmi_watchdog == NMI_LOCAL_APIC)
156 smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0);
129 157
130 for (cpu = 0; cpu < NR_CPUS; cpu++) 158 for (cpu = 0; cpu < NR_CPUS; cpu++)
131 counts[cpu] = cpu_pda[cpu].__nmi_count; 159 counts[cpu] = cpu_pda[cpu].__nmi_count;
@@ -133,15 +161,22 @@ static int __init check_nmi_watchdog (void)
133 mdelay((10*1000)/nmi_hz); // wait 10 ticks 161 mdelay((10*1000)/nmi_hz); // wait 10 ticks
134 162
135 for (cpu = 0; cpu < NR_CPUS; cpu++) { 163 for (cpu = 0; cpu < NR_CPUS; cpu++) {
164 if (!cpu_online(cpu))
165 continue;
136 if (cpu_pda[cpu].__nmi_count - counts[cpu] <= 5) { 166 if (cpu_pda[cpu].__nmi_count - counts[cpu] <= 5) {
137 printk("CPU#%d: NMI appears to be stuck (%d)!\n", 167 endflag = 1;
168 printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n",
138 cpu, 169 cpu,
170 counts[cpu],
139 cpu_pda[cpu].__nmi_count); 171 cpu_pda[cpu].__nmi_count);
140 nmi_active = 0; 172 nmi_active = 0;
141 lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG; 173 lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG;
174 nmi_perfctr_msr = 0;
175 kfree(counts);
142 return -1; 176 return -1;
143 } 177 }
144 } 178 }
179 endflag = 1;
145 printk("OK.\n"); 180 printk("OK.\n");
146 181
147 /* now that we know it works we can reduce NMI frequency to 182 /* now that we know it works we can reduce NMI frequency to
@@ -149,10 +184,9 @@ static int __init check_nmi_watchdog (void)
149 if (nmi_watchdog == NMI_LOCAL_APIC) 184 if (nmi_watchdog == NMI_LOCAL_APIC)
150 nmi_hz = 1; 185 nmi_hz = 1;
151 186
187 kfree(counts);
152 return 0; 188 return 0;
153} 189}
154/* Have this called later during boot so counters are updating */
155late_initcall(check_nmi_watchdog);
156 190
157int __init setup_nmi_watchdog(char *str) 191int __init setup_nmi_watchdog(char *str)
158{ 192{
@@ -170,7 +204,7 @@ int __init setup_nmi_watchdog(char *str)
170 204
171 if (nmi >= NMI_INVALID) 205 if (nmi >= NMI_INVALID)
172 return 0; 206 return 0;
173 nmi_watchdog = nmi; 207 nmi_watchdog = nmi;
174 return 1; 208 return 1;
175} 209}
176 210
@@ -185,7 +219,10 @@ static void disable_lapic_nmi_watchdog(void)
185 wrmsr(MSR_K7_EVNTSEL0, 0, 0); 219 wrmsr(MSR_K7_EVNTSEL0, 0, 0);
186 break; 220 break;
187 case X86_VENDOR_INTEL: 221 case X86_VENDOR_INTEL:
188 wrmsr(MSR_IA32_EVNTSEL0, 0, 0); 222 if (boot_cpu_data.x86 == 15) {
223 wrmsr(MSR_P4_IQ_CCCR0, 0, 0);
224 wrmsr(MSR_P4_CRU_ESCR0, 0, 0);
225 }
189 break; 226 break;
190 } 227 }
191 nmi_active = -1; 228 nmi_active = -1;
@@ -253,7 +290,7 @@ void enable_timer_nmi_watchdog(void)
253 290
254static int nmi_pm_active; /* nmi_active before suspend */ 291static int nmi_pm_active; /* nmi_active before suspend */
255 292
256static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state) 293static int lapic_nmi_suspend(struct sys_device *dev, u32 state)
257{ 294{
258 nmi_pm_active = nmi_active; 295 nmi_pm_active = nmi_active;
259 disable_lapic_nmi_watchdog(); 296 disable_lapic_nmi_watchdog();
@@ -300,22 +337,27 @@ late_initcall(init_lapic_nmi_sysfs);
300 * Original code written by Keith Owens. 337 * Original code written by Keith Owens.
301 */ 338 */
302 339
340static void clear_msr_range(unsigned int base, unsigned int n)
341{
342 unsigned int i;
343
344 for(i = 0; i < n; ++i)
345 wrmsr(base+i, 0, 0);
346}
347
303static void setup_k7_watchdog(void) 348static void setup_k7_watchdog(void)
304{ 349{
305 int i; 350 int i;
306 unsigned int evntsel; 351 unsigned int evntsel;
307 352
308 /* No check, so can start with slow frequency */
309 nmi_hz = 1;
310
311 /* XXX should check these in EFER */
312
313 nmi_perfctr_msr = MSR_K7_PERFCTR0; 353 nmi_perfctr_msr = MSR_K7_PERFCTR0;
314 354
315 for(i = 0; i < 4; ++i) { 355 for(i = 0; i < 4; ++i) {
316 /* Simulator may not support it */ 356 /* Simulator may not support it */
317 if (checking_wrmsrl(MSR_K7_EVNTSEL0+i, 0UL)) 357 if (checking_wrmsrl(MSR_K7_EVNTSEL0+i, 0UL)) {
358 nmi_perfctr_msr = 0;
318 return; 359 return;
360 }
319 wrmsrl(MSR_K7_PERFCTR0+i, 0UL); 361 wrmsrl(MSR_K7_PERFCTR0+i, 0UL);
320 } 362 }
321 363
@@ -325,12 +367,54 @@ static void setup_k7_watchdog(void)
325 | K7_NMI_EVENT; 367 | K7_NMI_EVENT;
326 368
327 wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); 369 wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
328 wrmsrl(MSR_K7_PERFCTR0, -((u64)cpu_khz*1000) / nmi_hz); 370 wrmsr(MSR_K7_PERFCTR0, -(cpu_khz/nmi_hz*1000), -1);
329 apic_write(APIC_LVTPC, APIC_DM_NMI); 371 apic_write(APIC_LVTPC, APIC_DM_NMI);
330 evntsel |= K7_EVNTSEL_ENABLE; 372 evntsel |= K7_EVNTSEL_ENABLE;
331 wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); 373 wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
332} 374}
333 375
376
377static int setup_p4_watchdog(void)
378{
379 unsigned int misc_enable, dummy;
380
381 rdmsr(MSR_P4_MISC_ENABLE, misc_enable, dummy);
382 if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL))
383 return 0;
384
385 nmi_perfctr_msr = MSR_P4_IQ_COUNTER0;
386 nmi_p4_cccr_val = P4_NMI_IQ_CCCR0;
387#ifdef CONFIG_SMP
388 if (smp_num_siblings == 2)
389 nmi_p4_cccr_val |= P4_CCCR_OVF_PMI1;
390#endif
391
392 if (!(misc_enable & MSR_P4_MISC_ENABLE_PEBS_UNAVAIL))
393 clear_msr_range(0x3F1, 2);
394 /* MSR 0x3F0 seems to have a default value of 0xFC00, but current
395 docs doesn't fully define it, so leave it alone for now. */
396 if (boot_cpu_data.x86_model >= 0x3) {
397 /* MSR_P4_IQ_ESCR0/1 (0x3ba/0x3bb) removed */
398 clear_msr_range(0x3A0, 26);
399 clear_msr_range(0x3BC, 3);
400 } else {
401 clear_msr_range(0x3A0, 31);
402 }
403 clear_msr_range(0x3C0, 6);
404 clear_msr_range(0x3C8, 6);
405 clear_msr_range(0x3E0, 2);
406 clear_msr_range(MSR_P4_CCCR0, 18);
407 clear_msr_range(MSR_P4_PERFCTR0, 18);
408
409 wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0);
410 wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0);
411 Dprintk("setting P4_IQ_COUNTER0 to 0x%08lx\n", -(cpu_khz/nmi_hz*1000));
412 wrmsr(MSR_P4_IQ_COUNTER0, -(cpu_khz/nmi_hz*1000), -1);
413 apic_write(APIC_LVTPC, APIC_DM_NMI);
414 wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0);
415 return 1;
416}
417
334void setup_apic_nmi_watchdog(void) 418void setup_apic_nmi_watchdog(void)
335{ 419{
336 switch (boot_cpu_data.x86_vendor) { 420 switch (boot_cpu_data.x86_vendor) {
@@ -341,6 +425,13 @@ void setup_apic_nmi_watchdog(void)
341 return; 425 return;
342 setup_k7_watchdog(); 426 setup_k7_watchdog();
343 break; 427 break;
428 case X86_VENDOR_INTEL:
429 if (boot_cpu_data.x86 != 15)
430 return;
431 if (!setup_p4_watchdog())
432 return;
433 break;
434
344 default: 435 default:
345 return; 436 return;
346 } 437 }
@@ -355,56 +446,67 @@ void setup_apic_nmi_watchdog(void)
355 * 446 *
356 * as these watchdog NMI IRQs are generated on every CPU, we only 447 * as these watchdog NMI IRQs are generated on every CPU, we only
357 * have to check the current processor. 448 * have to check the current processor.
358 *
359 * since NMIs don't listen to _any_ locks, we have to be extremely
360 * careful not to rely on unsafe variables. The printk might lock
361 * up though, so we have to break up any console locks first ...
362 * [when there will be more tty-related locks, break them up
363 * here too!]
364 */ 449 */
365 450
366static unsigned int 451static DEFINE_PER_CPU(unsigned, last_irq_sum);
367 last_irq_sums [NR_CPUS], 452static DEFINE_PER_CPU(local_t, alert_counter);
368 alert_counter [NR_CPUS]; 453static DEFINE_PER_CPU(int, nmi_touch);
369 454
370void touch_nmi_watchdog (void) 455void touch_nmi_watchdog (void)
371{ 456{
372 int i; 457 int i;
373 458
374 /* 459 /*
375 * Just reset the alert counters, (other CPUs might be 460 * Tell other CPUs to reset their alert counters. We cannot
376 * spinning on locks we hold): 461 * do it ourselves because the alert count increase is not
462 * atomic.
377 */ 463 */
378 for (i = 0; i < NR_CPUS; i++) 464 for (i = 0; i < NR_CPUS; i++)
379 alert_counter[i] = 0; 465 per_cpu(nmi_touch, i) = 1;
380} 466}
381 467
382void nmi_watchdog_tick (struct pt_regs * regs, unsigned reason) 468void nmi_watchdog_tick (struct pt_regs * regs, unsigned reason)
383{ 469{
384 int sum, cpu; 470 int sum;
471 int touched = 0;
385 472
386 cpu = safe_smp_processor_id();
387 sum = read_pda(apic_timer_irqs); 473 sum = read_pda(apic_timer_irqs);
388 if (last_irq_sums[cpu] == sum) { 474 if (__get_cpu_var(nmi_touch)) {
475 __get_cpu_var(nmi_touch) = 0;
476 touched = 1;
477 }
478 if (!touched && __get_cpu_var(last_irq_sum) == sum) {
389 /* 479 /*
390 * Ayiee, looks like this CPU is stuck ... 480 * Ayiee, looks like this CPU is stuck ...
391 * wait a few IRQs (5 seconds) before doing the oops ... 481 * wait a few IRQs (5 seconds) before doing the oops ...
392 */ 482 */
393 alert_counter[cpu]++; 483 local_inc(&__get_cpu_var(alert_counter));
394 if (alert_counter[cpu] == 5*nmi_hz) { 484 if (local_read(&__get_cpu_var(alert_counter)) == 5*nmi_hz) {
395 if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) 485 if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT)
396 == NOTIFY_STOP) { 486 == NOTIFY_STOP) {
397 alert_counter[cpu] = 0; 487 local_set(&__get_cpu_var(alert_counter), 0);
398 return; 488 return;
399 } 489 }
400 die_nmi("NMI Watchdog detected LOCKUP on CPU%d", regs); 490 die_nmi("NMI Watchdog detected LOCKUP on CPU%d", regs);
401 } 491 }
402 } else { 492 } else {
403 last_irq_sums[cpu] = sum; 493 __get_cpu_var(last_irq_sum) = sum;
404 alert_counter[cpu] = 0; 494 local_set(&__get_cpu_var(alert_counter), 0);
405 } 495 }
406 if (nmi_perfctr_msr) 496 if (nmi_perfctr_msr) {
497 if (nmi_perfctr_msr == MSR_P4_IQ_COUNTER0) {
498 /*
499 * P4 quirks:
500 * - An overflown perfctr will assert its interrupt
501 * until the OVF flag in its CCCR is cleared.
502 * - LVTPC is masked on interrupt and must be
503 * unmasked by the LVTPC handler.
504 */
505 wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0);
506 apic_write(APIC_LVTPC, APIC_DM_NMI);
507 }
407 wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1); 508 wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1);
509 }
408} 510}
409 511
410static int dummy_nmi_callback(struct pt_regs * regs, int cpu) 512static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
diff --git a/arch/x86_64/kernel/pmtimer.c b/arch/x86_64/kernel/pmtimer.c
new file mode 100644
index 000000000000..feb5f108dd26
--- /dev/null
+++ b/arch/x86_64/kernel/pmtimer.c
@@ -0,0 +1,101 @@
1/* Ported over from i386 by AK, original copyright was:
2 *
3 * (C) Dominik Brodowski <linux@brodo.de> 2003
4 *
5 * Driver to use the Power Management Timer (PMTMR) available in some
6 * southbridges as primary timing source for the Linux kernel.
7 *
8 * Based on parts of linux/drivers/acpi/hardware/hwtimer.c, timer_pit.c,
9 * timer_hpet.c, and on Arjan van de Ven's implementation for 2.4.
10 *
11 * This file is licensed under the GPL v2.
12 *
13 * Dropped all the hardware bug workarounds for now. Hopefully they
14 * are not needed on 64bit chipsets.
15 */
16
17#include <linux/jiffies.h>
18#include <linux/kernel.h>
19#include <linux/time.h>
20#include <linux/init.h>
21#include <linux/cpumask.h>
22#include <asm/io.h>
23#include <asm/proto.h>
24#include <asm/msr.h>
25#include <asm/vsyscall.h>
26
27/* The I/O port the PMTMR resides at.
28 * The location is detected during setup_arch(),
29 * in arch/i386/kernel/acpi/boot.c */
30u32 pmtmr_ioport;
31
32/* value of the Power timer at last timer interrupt */
33static u32 offset_delay;
34static u32 last_pmtmr_tick;
35
36#define ACPI_PM_MASK 0xFFFFFF /* limit it to 24 bits */
37
38static inline u32 cyc2us(u32 cycles)
39{
40 /* The Power Management Timer ticks at 3.579545 ticks per microsecond.
41 * 1 / PM_TIMER_FREQUENCY == 0.27936511 =~ 286/1024 [error: 0.024%]
42 *
43 * Even with HZ = 100, delta is at maximum 35796 ticks, so it can
44 * easily be multiplied with 286 (=0x11E) without having to fear
45 * u32 overflows.
46 */
47 cycles *= 286;
48 return (cycles >> 10);
49}
50
51int pmtimer_mark_offset(void)
52{
53 static int first_run = 1;
54 unsigned long tsc;
55 u32 lost;
56
57 u32 tick = inl(pmtmr_ioport);
58 u32 delta;
59
60 delta = cyc2us((tick - last_pmtmr_tick) & ACPI_PM_MASK);
61
62 last_pmtmr_tick = tick;
63 monotonic_base += delta * NSEC_PER_USEC;
64
65 delta += offset_delay;
66
67 lost = delta / (USEC_PER_SEC / HZ);
68 offset_delay = delta % (USEC_PER_SEC / HZ);
69
70 rdtscll(tsc);
71 vxtime.last_tsc = tsc - offset_delay * cpu_khz;
72
73 /* don't calculate delay for first run,
74 or if we've got less then a tick */
75 if (first_run || (lost < 1)) {
76 first_run = 0;
77 offset_delay = 0;
78 }
79
80 return lost - 1;
81}
82
83unsigned int do_gettimeoffset_pm(void)
84{
85 u32 now, offset, delta = 0;
86
87 offset = last_pmtmr_tick;
88 now = inl(pmtmr_ioport);
89 delta = (now - offset) & ACPI_PM_MASK;
90
91 return offset_delay + cyc2us(delta);
92}
93
94
95static int __init nopmtimer_setup(char *s)
96{
97 pmtmr_ioport = 0;
98 return 0;
99}
100
101__setup("nopmtimer", nopmtimer_setup);
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
index c64b9c97c745..525f6a128a27 100644
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -257,13 +257,13 @@ static int putreg(struct task_struct *child,
257 value &= 0xffff; 257 value &= 0xffff;
258 return 0; 258 return 0;
259 case offsetof(struct user_regs_struct,fs_base): 259 case offsetof(struct user_regs_struct,fs_base):
260 if (!((value >> 48) == 0 || (value >> 48) == 0xffff)) 260 if (value >= TASK_SIZE)
261 return -EIO; 261 return -EIO;
262 child->thread.fs = value; 262 child->thread.fs = value;
263 return 0; 263 return 0;
264 case offsetof(struct user_regs_struct,gs_base): 264 case offsetof(struct user_regs_struct,gs_base):
265 if (!((value >> 48) == 0 || (value >> 48) == 0xffff)) 265 if (value >= TASK_SIZE)
266 return -EIO; 266 return -EIO;
267 child->thread.gs = value; 267 child->thread.gs = value;
268 return 0; 268 return 0;
269 case offsetof(struct user_regs_struct, eflags): 269 case offsetof(struct user_regs_struct, eflags):
@@ -277,6 +277,11 @@ static int putreg(struct task_struct *child,
277 return -EIO; 277 return -EIO;
278 value &= 0xffff; 278 value &= 0xffff;
279 break; 279 break;
280 case offsetof(struct user_regs_struct, rip):
281 /* Check if the new RIP address is canonical */
282 if (value >= TASK_SIZE)
283 return -EIO;
284 break;
280 } 285 }
281 put_stack_long(child, regno - sizeof(struct pt_regs), value); 286 put_stack_long(child, regno - sizeof(struct pt_regs), value);
282 return 0; 287 return 0;
@@ -375,7 +380,7 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data
375 break; 380 break;
376 381
377 switch (addr) { 382 switch (addr) {
378 case 0 ... sizeof(struct user_regs_struct): 383 case 0 ... sizeof(struct user_regs_struct) - sizeof(long):
379 tmp = getreg(child, addr); 384 tmp = getreg(child, addr);
380 break; 385 break;
381 case offsetof(struct user, u_debugreg[0]): 386 case offsetof(struct user, u_debugreg[0]):
@@ -420,7 +425,7 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data
420 break; 425 break;
421 426
422 switch (addr) { 427 switch (addr) {
423 case 0 ... sizeof(struct user_regs_struct): 428 case 0 ... sizeof(struct user_regs_struct) - sizeof(long):
424 ret = putreg(child, addr, data); 429 ret = putreg(child, addr, data);
425 break; 430 break;
426 /* Disallows to set a breakpoint into the vsyscall */ 431 /* Disallows to set a breakpoint into the vsyscall */
@@ -635,20 +640,29 @@ asmlinkage void syscall_trace_enter(struct pt_regs *regs)
635 /* do the secure computing check first */ 640 /* do the secure computing check first */
636 secure_computing(regs->orig_rax); 641 secure_computing(regs->orig_rax);
637 642
638 if (unlikely(current->audit_context))
639 audit_syscall_entry(current, regs->orig_rax,
640 regs->rdi, regs->rsi,
641 regs->rdx, regs->r10);
642
643 if (test_thread_flag(TIF_SYSCALL_TRACE) 643 if (test_thread_flag(TIF_SYSCALL_TRACE)
644 && (current->ptrace & PT_PTRACED)) 644 && (current->ptrace & PT_PTRACED))
645 syscall_trace(regs); 645 syscall_trace(regs);
646
647 if (unlikely(current->audit_context)) {
648 if (test_thread_flag(TIF_IA32)) {
649 audit_syscall_entry(current, AUDIT_ARCH_I386,
650 regs->orig_rax,
651 regs->rbx, regs->rcx,
652 regs->rdx, regs->rsi);
653 } else {
654 audit_syscall_entry(current, AUDIT_ARCH_X86_64,
655 regs->orig_rax,
656 regs->rdi, regs->rsi,
657 regs->rdx, regs->r10);
658 }
659 }
646} 660}
647 661
648asmlinkage void syscall_trace_leave(struct pt_regs *regs) 662asmlinkage void syscall_trace_leave(struct pt_regs *regs)
649{ 663{
650 if (unlikely(current->audit_context)) 664 if (unlikely(current->audit_context))
651 audit_syscall_exit(current, regs->rax); 665 audit_syscall_exit(current, AUDITSC_RESULT(regs->rax), regs->rax);
652 666
653 if ((test_thread_flag(TIF_SYSCALL_TRACE) 667 if ((test_thread_flag(TIF_SYSCALL_TRACE)
654 || test_thread_flag(TIF_SINGLESTEP)) 668 || test_thread_flag(TIF_SINGLESTEP))
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 2129cf9ba6b2..99f038ede23c 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -719,7 +719,6 @@ static void __init display_cacheinfo(struct cpuinfo_x86 *c)
719 } 719 }
720} 720}
721 721
722#ifdef CONFIG_SMP
723/* 722/*
724 * On a AMD dual core setup the lower bits of the APIC id distingush the cores. 723 * On a AMD dual core setup the lower bits of the APIC id distingush the cores.
725 * Assumes number of cores is a power of two. 724 * Assumes number of cores is a power of two.
@@ -727,17 +726,26 @@ static void __init display_cacheinfo(struct cpuinfo_x86 *c)
727static void __init amd_detect_cmp(struct cpuinfo_x86 *c) 726static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
728{ 727{
729#ifdef CONFIG_SMP 728#ifdef CONFIG_SMP
730 int cpu = c->x86_apicid; 729 int cpu = smp_processor_id();
731 int node = 0; 730 int node = 0;
731 unsigned bits;
732 if (c->x86_num_cores == 1) 732 if (c->x86_num_cores == 1)
733 return; 733 return;
734 cpu_core_id[cpu] = cpu >> hweight32(c->x86_num_cores - 1); 734
735 bits = 0;
736 while ((1 << bits) < c->x86_num_cores)
737 bits++;
738
739 /* Low order bits define the core id (index of core in socket) */
740 cpu_core_id[cpu] = phys_proc_id[cpu] & ((1 << bits)-1);
741 /* Convert the APIC ID into the socket ID */
742 phys_proc_id[cpu] >>= bits;
735 743
736#ifdef CONFIG_NUMA 744#ifdef CONFIG_NUMA
737 /* When an ACPI SRAT table is available use the mappings from SRAT 745 /* When an ACPI SRAT table is available use the mappings from SRAT
738 instead. */ 746 instead. */
739 if (acpi_numa <= 0) { 747 if (acpi_numa <= 0) {
740 node = cpu_core_id[cpu]; 748 node = phys_proc_id[cpu];
741 if (!node_online(node)) 749 if (!node_online(node))
742 node = first_node(node_online_map); 750 node = first_node(node_online_map);
743 cpu_to_node[cpu] = node; 751 cpu_to_node[cpu] = node;
@@ -745,15 +753,11 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
745 node = cpu_to_node[cpu]; 753 node = cpu_to_node[cpu];
746 } 754 }
747#endif 755#endif
756
748 printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n", 757 printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n",
749 cpu, c->x86_num_cores, node, cpu_core_id[cpu]); 758 cpu, c->x86_num_cores, node, cpu_core_id[cpu]);
750#endif 759#endif
751} 760}
752#else
753static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
754{
755}
756#endif
757 761
758static int __init init_amd(struct cpuinfo_x86 *c) 762static int __init init_amd(struct cpuinfo_x86 *c)
759{ 763{
@@ -925,7 +929,6 @@ void __init early_identify_cpu(struct cpuinfo_x86 *c)
925 c->x86_clflush_size = 64; 929 c->x86_clflush_size = 64;
926 c->x86_cache_alignment = c->x86_clflush_size; 930 c->x86_cache_alignment = c->x86_clflush_size;
927 c->x86_num_cores = 1; 931 c->x86_num_cores = 1;
928 c->x86_apicid = c == &boot_cpu_data ? 0 : c - cpu_data;
929 c->extended_cpuid_level = 0; 932 c->extended_cpuid_level = 0;
930 memset(&c->x86_capability, 0, sizeof c->x86_capability); 933 memset(&c->x86_capability, 0, sizeof c->x86_capability);
931 934
@@ -954,11 +957,14 @@ void __init early_identify_cpu(struct cpuinfo_x86 *c)
954 } 957 }
955 if (c->x86_capability[0] & (1<<19)) 958 if (c->x86_capability[0] & (1<<19))
956 c->x86_clflush_size = ((misc >> 8) & 0xff) * 8; 959 c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
957 c->x86_apicid = misc >> 24;
958 } else { 960 } else {
959 /* Have CPUID level 0 only - unheard of */ 961 /* Have CPUID level 0 only - unheard of */
960 c->x86 = 4; 962 c->x86 = 4;
961 } 963 }
964
965#ifdef CONFIG_SMP
966 phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff;
967#endif
962} 968}
963 969
964/* 970/*
@@ -1088,7 +1094,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
1088 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1094 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1089 1095
1090 /* Other (Linux-defined) */ 1096 /* Other (Linux-defined) */
1091 "cxmmx", NULL, "cyrix_arr", "centaur_mcr", "k8c+", 1097 "cxmmx", NULL, "cyrix_arr", "centaur_mcr", NULL,
1092 "constant_tsc", NULL, NULL, 1098 "constant_tsc", NULL, NULL,
1093 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1099 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1094 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1100 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
index d439ced150c6..429c0269dc4e 100644
--- a/arch/x86_64/kernel/signal.c
+++ b/arch/x86_64/kernel/signal.c
@@ -28,6 +28,7 @@
28#include <asm/uaccess.h> 28#include <asm/uaccess.h>
29#include <asm/i387.h> 29#include <asm/i387.h>
30#include <asm/proto.h> 30#include <asm/proto.h>
31#include <asm/ia32_unistd.h>
31 32
32/* #define DEBUG_SIG 1 */ 33/* #define DEBUG_SIG 1 */
33 34
@@ -452,7 +453,9 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
452 regs->rip -= 2; 453 regs->rip -= 2;
453 } 454 }
454 if (regs->rax == (unsigned long)-ERESTART_RESTARTBLOCK) { 455 if (regs->rax == (unsigned long)-ERESTART_RESTARTBLOCK) {
455 regs->rax = __NR_restart_syscall; 456 regs->rax = test_thread_flag(TIF_IA32) ?
457 __NR_ia32_restart_syscall :
458 __NR_restart_syscall;
456 regs->rip -= 2; 459 regs->rip -= 2;
457 } 460 }
458 } 461 }
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 73f7e8b9543a..f1ec0f345941 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -56,6 +56,7 @@
56#include <asm/kdebug.h> 56#include <asm/kdebug.h>
57#include <asm/tlbflush.h> 57#include <asm/tlbflush.h>
58#include <asm/proto.h> 58#include <asm/proto.h>
59#include <asm/nmi.h>
59 60
60/* Change for real CPU hotplug. Note other files need to be fixed 61/* Change for real CPU hotplug. Note other files need to be fixed
61 first too. */ 62 first too. */
@@ -93,6 +94,7 @@ int smp_threads_ready;
93 94
94cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; 95cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
95cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; 96cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
97EXPORT_SYMBOL(cpu_core_map);
96 98
97/* 99/*
98 * Trampoline 80x86 program as an array. 100 * Trampoline 80x86 program as an array.
@@ -125,96 +127,210 @@ static void __cpuinit smp_store_cpu_info(int id)
125 127
126 *c = boot_cpu_data; 128 *c = boot_cpu_data;
127 identify_cpu(c); 129 identify_cpu(c);
130 print_cpu_info(c);
128} 131}
129 132
130/* 133/*
131 * Synchronize TSCs of CPUs 134 * New Funky TSC sync algorithm borrowed from IA64.
135 * Main advantage is that it doesn't reset the TSCs fully and
136 * in general looks more robust and it works better than my earlier
137 * attempts. I believe it was written by David Mosberger. Some minor
138 * adjustments for x86-64 by me -AK
132 * 139 *
133 * This new algorithm is less accurate than the old "zero TSCs" 140 * Original comment reproduced below.
134 * one, but we cannot zero TSCs anymore in the new hotplug CPU 141 *
135 * model. 142 * Synchronize TSC of the current (slave) CPU with the TSC of the
143 * MASTER CPU (normally the time-keeper CPU). We use a closed loop to
144 * eliminate the possibility of unaccounted-for errors (such as
145 * getting a machine check in the middle of a calibration step). The
146 * basic idea is for the slave to ask the master what itc value it has
147 * and to read its own itc before and after the master responds. Each
148 * iteration gives us three timestamps:
149 *
150 * slave master
151 *
152 * t0 ---\
153 * ---\
154 * --->
155 * tm
156 * /---
157 * /---
158 * t1 <---
159 *
160 *
161 * The goal is to adjust the slave's TSC such that tm falls exactly
162 * half-way between t0 and t1. If we achieve this, the clocks are
163 * synchronized provided the interconnect between the slave and the
164 * master is symmetric. Even if the interconnect were asymmetric, we
165 * would still know that the synchronization error is smaller than the
166 * roundtrip latency (t0 - t1).
167 *
168 * When the interconnect is quiet and symmetric, this lets us
169 * synchronize the TSC to within one or two cycles. However, we can
170 * only *guarantee* that the synchronization is accurate to within a
171 * round-trip time, which is typically in the range of several hundred
172 * cycles (e.g., ~500 cycles). In practice, this means that the TSCs
173 * are usually almost perfectly synchronized, but we shouldn't assume
174 * that the accuracy is much better than half a micro second or so.
175 *
176 * [there are other errors like the latency of RDTSC and of the
177 * WRMSR. These can also account to hundreds of cycles. So it's
178 * probably worse. It claims 153 cycles error on a dual Opteron,
179 * but I suspect the numbers are actually somewhat worse -AK]
136 */ 180 */
137 181
138static atomic_t __cpuinitdata tsc_flag; 182#define MASTER 0
183#define SLAVE (SMP_CACHE_BYTES/8)
184
185/* Intentionally don't use cpu_relax() while TSC synchronization
186 because we don't want to go into funky power save modi or cause
187 hypervisors to schedule us away. Going to sleep would likely affect
188 latency and low latency is the primary objective here. -AK */
189#define no_cpu_relax() barrier()
190
139static __cpuinitdata DEFINE_SPINLOCK(tsc_sync_lock); 191static __cpuinitdata DEFINE_SPINLOCK(tsc_sync_lock);
140static unsigned long long __cpuinitdata bp_tsc, ap_tsc; 192static volatile __cpuinitdata unsigned long go[SLAVE + 1];
193static int notscsync __cpuinitdata;
194
195#undef DEBUG_TSC_SYNC
141 196
142#define NR_LOOPS 5 197#define NUM_ROUNDS 64 /* magic value */
198#define NUM_ITERS 5 /* likewise */
143 199
144static void __cpuinit sync_tsc_bp_init(int init) 200/* Callback on boot CPU */
201static __cpuinit void sync_master(void *arg)
145{ 202{
146 if (init) 203 unsigned long flags, i;
147 _raw_spin_lock(&tsc_sync_lock); 204
148 else 205 if (smp_processor_id() != boot_cpu_id)
149 _raw_spin_unlock(&tsc_sync_lock); 206 return;
150 atomic_set(&tsc_flag, 0); 207
208 go[MASTER] = 0;
209
210 local_irq_save(flags);
211 {
212 for (i = 0; i < NUM_ROUNDS*NUM_ITERS; ++i) {
213 while (!go[MASTER])
214 no_cpu_relax();
215 go[MASTER] = 0;
216 rdtscll(go[SLAVE]);
217 }
218 }
219 local_irq_restore(flags);
151} 220}
152 221
153/* 222/*
154 * Synchronize TSC on AP with BP. 223 * Return the number of cycles by which our tsc differs from the tsc
224 * on the master (time-keeper) CPU. A positive number indicates our
225 * tsc is ahead of the master, negative that it is behind.
155 */ 226 */
156static void __cpuinit __sync_tsc_ap(void) 227static inline long
228get_delta(long *rt, long *master)
157{ 229{
158 if (!cpu_has_tsc) 230 unsigned long best_t0 = 0, best_t1 = ~0UL, best_tm = 0;
159 return; 231 unsigned long tcenter, t0, t1, tm;
160 Dprintk("AP %d syncing TSC\n", smp_processor_id()); 232 int i;
161 233
162 while (atomic_read(&tsc_flag) != 0) 234 for (i = 0; i < NUM_ITERS; ++i) {
163 cpu_relax(); 235 rdtscll(t0);
164 atomic_inc(&tsc_flag); 236 go[MASTER] = 1;
165 mb(); 237 while (!(tm = go[SLAVE]))
166 _raw_spin_lock(&tsc_sync_lock); 238 no_cpu_relax();
167 wrmsrl(MSR_IA32_TSC, bp_tsc); 239 go[SLAVE] = 0;
168 _raw_spin_unlock(&tsc_sync_lock); 240 rdtscll(t1);
169 rdtscll(ap_tsc); 241
170 mb(); 242 if (t1 - t0 < best_t1 - best_t0)
171 atomic_inc(&tsc_flag); 243 best_t0 = t0, best_t1 = t1, best_tm = tm;
172 mb(); 244 }
245
246 *rt = best_t1 - best_t0;
247 *master = best_tm - best_t0;
248
249 /* average best_t0 and best_t1 without overflow: */
250 tcenter = (best_t0/2 + best_t1/2);
251 if (best_t0 % 2 + best_t1 % 2 == 2)
252 ++tcenter;
253 return tcenter - best_tm;
173} 254}
174 255
175static void __cpuinit sync_tsc_ap(void) 256static __cpuinit void sync_tsc(void)
176{ 257{
177 int i; 258 int i, done = 0;
178 for (i = 0; i < NR_LOOPS; i++) 259 long delta, adj, adjust_latency = 0;
179 __sync_tsc_ap(); 260 unsigned long flags, rt, master_time_stamp, bound;
261#if DEBUG_TSC_SYNC
262 static struct syncdebug {
263 long rt; /* roundtrip time */
264 long master; /* master's timestamp */
265 long diff; /* difference between midpoint and master's timestamp */
266 long lat; /* estimate of tsc adjustment latency */
267 } t[NUM_ROUNDS] __cpuinitdata;
268#endif
269
270 go[MASTER] = 1;
271
272 smp_call_function(sync_master, NULL, 1, 0);
273
274 while (go[MASTER]) /* wait for master to be ready */
275 no_cpu_relax();
276
277 spin_lock_irqsave(&tsc_sync_lock, flags);
278 {
279 for (i = 0; i < NUM_ROUNDS; ++i) {
280 delta = get_delta(&rt, &master_time_stamp);
281 if (delta == 0) {
282 done = 1; /* let's lock on to this... */
283 bound = rt;
284 }
285
286 if (!done) {
287 unsigned long t;
288 if (i > 0) {
289 adjust_latency += -delta;
290 adj = -delta + adjust_latency/4;
291 } else
292 adj = -delta;
293
294 rdtscll(t);
295 wrmsrl(MSR_IA32_TSC, t + adj);
296 }
297#if DEBUG_TSC_SYNC
298 t[i].rt = rt;
299 t[i].master = master_time_stamp;
300 t[i].diff = delta;
301 t[i].lat = adjust_latency/4;
302#endif
303 }
304 }
305 spin_unlock_irqrestore(&tsc_sync_lock, flags);
306
307#if DEBUG_TSC_SYNC
308 for (i = 0; i < NUM_ROUNDS; ++i)
309 printk("rt=%5ld master=%5ld diff=%5ld adjlat=%5ld\n",
310 t[i].rt, t[i].master, t[i].diff, t[i].lat);
311#endif
312
313 printk(KERN_INFO
314 "CPU %d: synchronized TSC with CPU %u (last diff %ld cycles, "
315 "maxerr %lu cycles)\n",
316 smp_processor_id(), boot_cpu_id, delta, rt);
180} 317}
181 318
182/* 319static void __cpuinit tsc_sync_wait(void)
183 * Synchronize TSC from BP to AP.
184 */
185static void __cpuinit __sync_tsc_bp(int cpu)
186{ 320{
187 if (!cpu_has_tsc) 321 if (notscsync || !cpu_has_tsc)
188 return; 322 return;
189 323 printk(KERN_INFO "CPU %d: Syncing TSC to CPU %u.\n", smp_processor_id(),
190 /* Wait for AP */ 324 boot_cpu_id);
191 while (atomic_read(&tsc_flag) == 0) 325 sync_tsc();
192 cpu_relax();
193 /* Save BPs TSC */
194 sync_core();
195 rdtscll(bp_tsc);
196 /* Don't do the sync core here to avoid too much latency. */
197 mb();
198 /* Start the AP */
199 _raw_spin_unlock(&tsc_sync_lock);
200 /* Wait for AP again */
201 while (atomic_read(&tsc_flag) < 2)
202 cpu_relax();
203 rdtscl(bp_tsc);
204 barrier();
205} 326}
206 327
207static void __cpuinit sync_tsc_bp(int cpu) 328static __init int notscsync_setup(char *s)
208{ 329{
209 int i; 330 notscsync = 1;
210 for (i = 0; i < NR_LOOPS - 1; i++) { 331 return 0;
211 __sync_tsc_bp(cpu);
212 sync_tsc_bp_init(1);
213 }
214 __sync_tsc_bp(cpu);
215 printk(KERN_INFO "Synced TSC of CPU %d difference %Ld\n",
216 cpu, ap_tsc - bp_tsc);
217} 332}
333__setup("notscsync", notscsync_setup);
218 334
219static atomic_t init_deasserted __cpuinitdata; 335static atomic_t init_deasserted __cpuinitdata;
220 336
@@ -315,11 +431,6 @@ void __cpuinit start_secondary(void)
315 cpu_init(); 431 cpu_init();
316 smp_callin(); 432 smp_callin();
317 433
318 /*
319 * Synchronize the TSC with the BP
320 */
321 sync_tsc_ap();
322
323 /* otherwise gcc will move up the smp_processor_id before the cpu_init */ 434 /* otherwise gcc will move up the smp_processor_id before the cpu_init */
324 barrier(); 435 barrier();
325 436
@@ -334,7 +445,6 @@ void __cpuinit start_secondary(void)
334 enable_8259A_irq(0); 445 enable_8259A_irq(0);
335 } 446 }
336 447
337
338 enable_APIC_timer(); 448 enable_APIC_timer();
339 449
340 /* 450 /*
@@ -343,6 +453,11 @@ void __cpuinit start_secondary(void)
343 cpu_set(smp_processor_id(), cpu_online_map); 453 cpu_set(smp_processor_id(), cpu_online_map);
344 mb(); 454 mb();
345 455
456 /* Wait for TSC sync to not schedule things before.
457 We still process interrupts, which could see an inconsistent
458 time in that window unfortunately. */
459 tsc_sync_wait();
460
346 cpu_idle(); 461 cpu_idle();
347} 462}
348 463
@@ -531,7 +646,6 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid)
531 printk("failed fork for CPU %d\n", cpu); 646 printk("failed fork for CPU %d\n", cpu);
532 return PTR_ERR(idle); 647 return PTR_ERR(idle);
533 } 648 }
534 x86_cpu_to_apicid[cpu] = apicid;
535 649
536 cpu_pda[cpu].pcurrent = idle; 650 cpu_pda[cpu].pcurrent = idle;
537 651
@@ -600,8 +714,6 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid)
600 714
601 if (cpu_isset(cpu, cpu_callin_map)) { 715 if (cpu_isset(cpu, cpu_callin_map)) {
602 /* number CPUs logically, starting from 1 (BSP is 0) */ 716 /* number CPUs logically, starting from 1 (BSP is 0) */
603 Dprintk("OK.\n");
604 print_cpu_info(&cpu_data[cpu]);
605 Dprintk("CPU has booted.\n"); 717 Dprintk("CPU has booted.\n");
606 } else { 718 } else {
607 boot_error = 1; 719 boot_error = 1;
@@ -842,7 +954,6 @@ void __cpuinit smp_prepare_cpus(unsigned int max_cpus)
842 GET_APIC_ID(apic_read(APIC_ID)), boot_cpu_id); 954 GET_APIC_ID(apic_read(APIC_ID)), boot_cpu_id);
843 /* Or can we switch back to PIC here? */ 955 /* Or can we switch back to PIC here? */
844 } 956 }
845 x86_cpu_to_apicid[0] = boot_cpu_id;
846 957
847 /* 958 /*
848 * Now start the IO-APICs 959 * Now start the IO-APICs
@@ -889,18 +1000,14 @@ int __cpuinit __cpu_up(unsigned int cpu)
889 printk("__cpu_up: bad cpu %d\n", cpu); 1000 printk("__cpu_up: bad cpu %d\n", cpu);
890 return -EINVAL; 1001 return -EINVAL;
891 } 1002 }
892 sync_tsc_bp_init(1);
893 1003
894 /* Boot it! */ 1004 /* Boot it! */
895 err = do_boot_cpu(cpu, apicid); 1005 err = do_boot_cpu(cpu, apicid);
896 if (err < 0) { 1006 if (err < 0) {
897 sync_tsc_bp_init(0);
898 Dprintk("do_boot_cpu failed %d\n", err); 1007 Dprintk("do_boot_cpu failed %d\n", err);
899 return err; 1008 return err;
900 } 1009 }
901 1010
902 sync_tsc_bp(cpu);
903
904 /* Unleash the CPU! */ 1011 /* Unleash the CPU! */
905 Dprintk("waiting for cpu %d\n", cpu); 1012 Dprintk("waiting for cpu %d\n", cpu);
906 1013
@@ -923,4 +1030,6 @@ void __cpuinit smp_cpus_done(unsigned int max_cpus)
923 1030
924 detect_siblings(); 1031 detect_siblings();
925 time_init_gtod(); 1032 time_init_gtod();
1033
1034 check_nmi_watchdog();
926} 1035}
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 0e3b60e1ac5b..fb8c809b4cd9 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -26,6 +26,10 @@
26#include <linux/sysdev.h> 26#include <linux/sysdev.h>
27#include <linux/bcd.h> 27#include <linux/bcd.h>
28#include <linux/kallsyms.h> 28#include <linux/kallsyms.h>
29#include <linux/acpi.h>
30#ifdef CONFIG_ACPI
31#include <acpi/achware.h> /* for PM timer frequency */
32#endif
29#include <asm/8253pit.h> 33#include <asm/8253pit.h>
30#include <asm/pgtable.h> 34#include <asm/pgtable.h>
31#include <asm/vsyscall.h> 35#include <asm/vsyscall.h>
@@ -396,6 +400,10 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
396 (offset - vxtime.last)*(NSEC_PER_SEC/HZ) / hpet_tick; 400 (offset - vxtime.last)*(NSEC_PER_SEC/HZ) / hpet_tick;
397 401
398 vxtime.last = offset; 402 vxtime.last = offset;
403#ifdef CONFIG_X86_PM_TIMER
404 } else if (vxtime.mode == VXTIME_PMTMR) {
405 lost = pmtimer_mark_offset();
406#endif
399 } else { 407 } else {
400 offset = (((tsc - vxtime.last_tsc) * 408 offset = (((tsc - vxtime.last_tsc) *
401 vxtime.tsc_quot) >> 32) - (USEC_PER_SEC / HZ); 409 vxtime.tsc_quot) >> 32) - (USEC_PER_SEC / HZ);
@@ -898,6 +906,13 @@ void __init time_init(void)
898 hpet_period; 906 hpet_period;
899 cpu_khz = hpet_calibrate_tsc(); 907 cpu_khz = hpet_calibrate_tsc();
900 timename = "HPET"; 908 timename = "HPET";
909#ifdef CONFIG_X86_PM_TIMER
910 } else if (pmtmr_ioport) {
911 vxtime_hz = PM_TIMER_FREQUENCY;
912 timename = "PM";
913 pit_init();
914 cpu_khz = pit_calibrate_tsc();
915#endif
901 } else { 916 } else {
902 pit_init(); 917 pit_init();
903 cpu_khz = pit_calibrate_tsc(); 918 cpu_khz = pit_calibrate_tsc();
@@ -923,35 +938,50 @@ void __init time_init(void)
923} 938}
924 939
925/* 940/*
941 * Make an educated guess if the TSC is trustworthy and synchronized
942 * over all CPUs.
943 */
944static __init int unsynchronized_tsc(void)
945{
946#ifdef CONFIG_SMP
947 if (oem_force_hpet_timer())
948 return 1;
949 /* Intel systems are normally all synchronized. Exceptions
950 are handled in the OEM check above. */
951 if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
952 return 0;
953 /* All in a single socket - should be synchronized */
954 if (cpus_weight(cpu_core_map[0]) == num_online_cpus())
955 return 0;
956#endif
957 /* Assume multi socket systems are not synchronized */
958 return num_online_cpus() > 1;
959}
960
961/*
926 * Decide after all CPUs are booted what mode gettimeofday should use. 962 * Decide after all CPUs are booted what mode gettimeofday should use.
927 */ 963 */
928void __init time_init_gtod(void) 964void __init time_init_gtod(void)
929{ 965{
930 char *timetype; 966 char *timetype;
931 967
932 /* 968 if (unsynchronized_tsc())
933 * AMD systems with more than one CPU don't have fully synchronized
934 * TSCs. Always use HPET gettimeofday for these, although it is slower.
935 * Intel SMP systems usually have synchronized TSCs, so use always
936 * the TSC.
937 *
938 * Exceptions:
939 * IBM Summit2 checked by oem_force_hpet_timer().
940 * AMD dual core may also not need HPET. Check me.
941 *
942 * Can be turned off with "notsc".
943 */
944 if (num_online_cpus() > 1 &&
945 boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
946 notsc = 1;
947 /* Some systems will want to disable TSC and use HPET. */
948 if (oem_force_hpet_timer())
949 notsc = 1; 969 notsc = 1;
950 if (vxtime.hpet_address && notsc) { 970 if (vxtime.hpet_address && notsc) {
951 timetype = "HPET"; 971 timetype = "HPET";
952 vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick; 972 vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick;
953 vxtime.mode = VXTIME_HPET; 973 vxtime.mode = VXTIME_HPET;
954 do_gettimeoffset = do_gettimeoffset_hpet; 974 do_gettimeoffset = do_gettimeoffset_hpet;
975#ifdef CONFIG_X86_PM_TIMER
976 /* Using PM for gettimeofday is quite slow, but we have no other
977 choice because the TSC is too unreliable on some systems. */
978 } else if (pmtmr_ioport && !vxtime.hpet_address && notsc) {
979 timetype = "PM";
980 do_gettimeoffset = do_gettimeoffset_pm;
981 vxtime.mode = VXTIME_PMTMR;
982 sysctl_vsyscall = 0;
983 printk(KERN_INFO "Disabling vsyscall due to use of PM timer\n");
984#endif
955 } else { 985 } else {
956 timetype = vxtime.hpet_address ? "HPET/TSC" : "PIT/TSC"; 986 timetype = vxtime.hpet_address ? "HPET/TSC" : "PIT/TSC";
957 vxtime.mode = VXTIME_TSC; 987 vxtime.mode = VXTIME_TSC;
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 65a37f52c56e..3dfec8fdabcd 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -332,10 +332,12 @@ void handle_BUG(struct pt_regs *regs)
332 printk(KERN_ALERT "Kernel BUG at %.50s:%d\n", f.filename, f.line); 332 printk(KERN_ALERT "Kernel BUG at %.50s:%d\n", f.filename, f.line);
333} 333}
334 334
335#ifdef CONFIG_BUG
335void out_of_line_bug(void) 336void out_of_line_bug(void)
336{ 337{
337 BUG(); 338 BUG();
338} 339}
340#endif
339 341
340static DEFINE_SPINLOCK(die_lock); 342static DEFINE_SPINLOCK(die_lock);
341static int die_owner = -1; 343static int die_owner = -1;
diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c
index b4b8dc59663a..2e5734425949 100644
--- a/arch/x86_64/kernel/vsyscall.c
+++ b/arch/x86_64/kernel/vsyscall.c
@@ -65,7 +65,7 @@ static force_inline void do_vgettimeofday(struct timeval * tv)
65 usec = (__xtime.tv_nsec / 1000) + 65 usec = (__xtime.tv_nsec / 1000) +
66 (__jiffies - __wall_jiffies) * (1000000 / HZ); 66 (__jiffies - __wall_jiffies) * (1000000 / HZ);
67 67
68 if (__vxtime.mode == VXTIME_TSC) { 68 if (__vxtime.mode != VXTIME_HPET) {
69 sync_core(); 69 sync_core();
70 rdtscll(t); 70 rdtscll(t);
71 if (t < __vxtime.last_tsc) 71 if (t < __vxtime.last_tsc)
@@ -217,8 +217,9 @@ static int __init vsyscall_init(void)
217 BUG_ON((unsigned long) &vtime != VSYSCALL_ADDR(__NR_vtime)); 217 BUG_ON((unsigned long) &vtime != VSYSCALL_ADDR(__NR_vtime));
218 BUG_ON((VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE))); 218 BUG_ON((VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE)));
219 map_vsyscall(); 219 map_vsyscall();
220 sysctl_vsyscall = 1; 220#ifdef CONFIG_SYSCTL
221 register_sysctl_table(kernel_root_table2, 0); 221 register_sysctl_table(kernel_root_table2, 0);
222#endif
222 return 0; 223 return 0;
223} 224}
224 225
diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c
index 88626e626886..68ec03070e5a 100644
--- a/arch/x86_64/kernel/x8664_ksyms.c
+++ b/arch/x86_64/kernel/x8664_ksyms.c
@@ -139,35 +139,23 @@ EXPORT_SYMBOL_GPL(unset_nmi_callback);
139#undef memmove 139#undef memmove
140#undef memchr 140#undef memchr
141#undef strlen 141#undef strlen
142#undef strcpy
143#undef strncmp 142#undef strncmp
144#undef strncpy 143#undef strncpy
145#undef strchr 144#undef strchr
146#undef strcmp
147#undef strcpy
148#undef strcat
149#undef memcmp
150 145
151extern void * memset(void *,int,__kernel_size_t); 146extern void * memset(void *,int,__kernel_size_t);
152extern size_t strlen(const char *); 147extern size_t strlen(const char *);
153extern void * memmove(void * dest,const void *src,size_t count); 148extern void * memmove(void * dest,const void *src,size_t count);
154extern char * strcpy(char * dest,const char *src);
155extern int strcmp(const char * cs,const char * ct);
156extern void *memchr(const void *s, int c, size_t n); 149extern void *memchr(const void *s, int c, size_t n);
157extern void * memcpy(void *,const void *,__kernel_size_t); 150extern void * memcpy(void *,const void *,__kernel_size_t);
158extern void * __memcpy(void *,const void *,__kernel_size_t); 151extern void * __memcpy(void *,const void *,__kernel_size_t);
159extern char * strcat(char *, const char *);
160extern int memcmp(const void * cs,const void * ct,size_t count);
161 152
162EXPORT_SYMBOL(memset); 153EXPORT_SYMBOL(memset);
163EXPORT_SYMBOL(strlen); 154EXPORT_SYMBOL(strlen);
164EXPORT_SYMBOL(memmove); 155EXPORT_SYMBOL(memmove);
165EXPORT_SYMBOL(strcpy);
166EXPORT_SYMBOL(strncmp); 156EXPORT_SYMBOL(strncmp);
167EXPORT_SYMBOL(strncpy); 157EXPORT_SYMBOL(strncpy);
168EXPORT_SYMBOL(strchr); 158EXPORT_SYMBOL(strchr);
169EXPORT_SYMBOL(strcmp);
170EXPORT_SYMBOL(strcat);
171EXPORT_SYMBOL(strncat); 159EXPORT_SYMBOL(strncat);
172EXPORT_SYMBOL(memchr); 160EXPORT_SYMBOL(memchr);
173EXPORT_SYMBOL(strrchr); 161EXPORT_SYMBOL(strrchr);
@@ -175,7 +163,6 @@ EXPORT_SYMBOL(strnlen);
175EXPORT_SYMBOL(memscan); 163EXPORT_SYMBOL(memscan);
176EXPORT_SYMBOL(memcpy); 164EXPORT_SYMBOL(memcpy);
177EXPORT_SYMBOL(__memcpy); 165EXPORT_SYMBOL(__memcpy);
178EXPORT_SYMBOL(memcmp);
179 166
180#ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM 167#ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM
181/* prototypes are wrong, these are assembly with custom calling functions */ 168/* prototypes are wrong, these are assembly with custom calling functions */
@@ -206,8 +193,9 @@ EXPORT_SYMBOL(smp_num_siblings);
206extern void do_softirq_thunk(void); 193extern void do_softirq_thunk(void);
207EXPORT_SYMBOL(do_softirq_thunk); 194EXPORT_SYMBOL(do_softirq_thunk);
208 195
209void out_of_line_bug(void); 196#ifdef CONFIG_BUG
210EXPORT_SYMBOL(out_of_line_bug); 197EXPORT_SYMBOL(out_of_line_bug);
198#endif
211 199
212EXPORT_SYMBOL(init_level4_pgt); 200EXPORT_SYMBOL(init_level4_pgt);
213 201
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
index e03309216764..5d6b2114cc9a 100644
--- a/arch/x86_64/mm/fault.c
+++ b/arch/x86_64/mm/fault.c
@@ -234,6 +234,8 @@ static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
234 234
235/* 235/*
236 * Handle a fault on the vmalloc or module mapping area 236 * Handle a fault on the vmalloc or module mapping area
237 *
238 * This assumes no large pages in there.
237 */ 239 */
238static int vmalloc_fault(unsigned long address) 240static int vmalloc_fault(unsigned long address)
239{ 241{
@@ -272,7 +274,10 @@ static int vmalloc_fault(unsigned long address)
272 if (!pte_present(*pte_ref)) 274 if (!pte_present(*pte_ref))
273 return -1; 275 return -1;
274 pte = pte_offset_kernel(pmd, address); 276 pte = pte_offset_kernel(pmd, address);
275 if (!pte_present(*pte) || pte_page(*pte) != pte_page(*pte_ref)) 277 /* Don't use pte_page here, because the mappings can point
278 outside mem_map, and the NUMA hash lookup cannot handle
279 that. */
280 if (!pte_present(*pte) || pte_pfn(*pte) != pte_pfn(*pte_ref))
276 BUG(); 281 BUG();
277 __flush_tlb_all(); 282 __flush_tlb_all();
278 return 0; 283 return 0;
@@ -346,7 +351,9 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
346 * protection error (error_code & 1) == 0. 351 * protection error (error_code & 1) == 0.
347 */ 352 */
348 if (unlikely(address >= TASK_SIZE)) { 353 if (unlikely(address >= TASK_SIZE)) {
349 if (!(error_code & 5)) { 354 if (!(error_code & 5) &&
355 ((address >= VMALLOC_START && address < VMALLOC_END) ||
356 (address >= MODULES_VADDR && address < MODULES_END))) {
350 if (vmalloc_fault(address) < 0) 357 if (vmalloc_fault(address) < 0)
351 goto bad_area_nosemaphore; 358 goto bad_area_nosemaphore;
352 return; 359 return;
diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c
index 74ec8554b195..58aac23760ef 100644
--- a/arch/x86_64/mm/ioremap.c
+++ b/arch/x86_64/mm/ioremap.c
@@ -133,7 +133,7 @@ ioremap_change_attr(unsigned long phys_addr, unsigned long size,
133 unsigned long flags) 133 unsigned long flags)
134{ 134{
135 int err = 0; 135 int err = 0;
136 if (flags && phys_addr + size - 1 < (end_pfn_map << PAGE_SHIFT)) { 136 if (phys_addr + size - 1 < (end_pfn_map << PAGE_SHIFT)) {
137 unsigned long npages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; 137 unsigned long npages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
138 unsigned long vaddr = (unsigned long) __va(phys_addr); 138 unsigned long vaddr = (unsigned long) __va(phys_addr);
139 139
@@ -214,7 +214,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
214 remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr)); 214 remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr));
215 return NULL; 215 return NULL;
216 } 216 }
217 if (ioremap_change_attr(phys_addr, size, flags) < 0) { 217 if (flags && ioremap_change_attr(phys_addr, size, flags) < 0) {
218 area->flags &= 0xffffff; 218 area->flags &= 0xffffff;
219 vunmap(addr); 219 vunmap(addr);
220 return NULL; 220 return NULL;
@@ -251,7 +251,7 @@ void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size)
251 251
252void iounmap(volatile void __iomem *addr) 252void iounmap(volatile void __iomem *addr)
253{ 253{
254 struct vm_struct *p, **pprev; 254 struct vm_struct *p;
255 255
256 if (addr <= high_memory) 256 if (addr <= high_memory)
257 return; 257 return;
@@ -260,24 +260,11 @@ void iounmap(volatile void __iomem *addr)
260 return; 260 return;
261 261
262 write_lock(&vmlist_lock); 262 write_lock(&vmlist_lock);
263 for (p = vmlist, pprev = &vmlist; p != NULL; pprev = &p->next, p = *pprev) 263 p = __remove_vm_area((void *)((unsigned long)addr & PAGE_MASK));
264 if (p->addr == (void *)(PAGE_MASK & (unsigned long)addr)) 264 if (!p)
265 break; 265 printk("iounmap: bad address %p\n", addr);
266 if (!p) { 266 else if (p->flags >> 20)
267 printk("__iounmap: bad address %p\n", addr); 267 ioremap_change_attr(p->phys_addr, p->size, 0);
268 goto out_unlock;
269 }
270 *pprev = p->next;
271 unmap_vm_area(p);
272 if ((p->flags >> 20) &&
273 p->phys_addr + p->size - 1 < virt_to_phys(high_memory)) {
274 /* p->size includes the guard page, but cpa doesn't like that */
275 change_page_attr(virt_to_page(__va(p->phys_addr)),
276 p->size >> PAGE_SHIFT,
277 PAGE_KERNEL);
278 global_flush_tlb();
279 }
280out_unlock:
281 write_unlock(&vmlist_lock); 268 write_unlock(&vmlist_lock);
282 kfree(p); 269 kfree(p);
283} 270}