aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/Kconfig32
-rw-r--r--arch/alpha/kernel/process.c6
-rw-r--r--arch/alpha/kernel/smp.c1
-rw-r--r--arch/arm/Kconfig.debug6
-rw-r--r--arch/arm/Makefile4
-rw-r--r--arch/arm/boot/compressed/head.S5
-rw-r--r--arch/arm/boot/dts/at91sam9260.dtsi3
-rw-r--r--arch/arm/boot/dts/at91sam9263.dtsi5
-rw-r--r--arch/arm/boot/dts/at91sam9g45.dtsi5
-rw-r--r--arch/arm/boot/dts/at91sam9n12.dtsi4
-rw-r--r--arch/arm/boot/dts/at91sam9x5.dtsi4
-rw-r--r--arch/arm/include/asm/assembler.h8
-rw-r--r--arch/arm/include/asm/memory.h3
-rw-r--r--arch/arm/include/asm/tlb.h4
-rw-r--r--arch/arm/include/asm/uaccess.h58
-rw-r--r--arch/arm/include/asm/unistd.h2
-rw-r--r--arch/arm/kernel/calls.S1
-rw-r--r--arch/arm/kernel/hw_breakpoint.c62
-rw-r--r--arch/arm/kernel/smp_twd.c48
-rw-r--r--arch/arm/kernel/traps.c11
-rw-r--r--arch/arm/lib/delay.c1
-rw-r--r--arch/arm/lib/getuser.S23
-rw-r--r--arch/arm/lib/putuser.S6
-rw-r--r--arch/arm/mach-imx/clk-imx25.c8
-rw-r--r--arch/arm/mach-imx/clk-imx35.c6
-rw-r--r--arch/arm/mach-imx/mach-armadillo5x0.c3
-rw-r--r--arch/arm/mach-mxs/mach-mxs.c2
-rw-r--r--arch/arm/mach-omap2/Kconfig3
-rw-r--r--arch/arm/mach-omap2/Makefile2
-rw-r--r--arch/arm/mach-omap2/clock33xx_data.c14
-rw-r--r--arch/arm/mach-omap2/clockdomain2xxx_3xxx.c50
-rw-r--r--arch/arm/mach-omap2/cm-regbits-34xx.h1
-rw-r--r--arch/arm/mach-omap2/omap-wakeupgen.c2
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c1
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c15
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c12
-rw-r--r--arch/arm/mach-omap2/timer.c7
-rw-r--r--arch/arm/mach-orion5x/common.c7
-rw-r--r--arch/arm/mach-shmobile/board-kzm9g.c4
-rw-r--r--arch/arm/mach-tegra/board-harmony-power.c12
-rw-r--r--arch/arm/mm/context.c7
-rw-r--r--arch/arm/mm/dma-mapping.c4
-rw-r--r--arch/arm/mm/mm.h3
-rw-r--r--arch/arm/mm/mmu.c8
-rw-r--r--arch/arm/plat-mxc/include/mach/mx25.h1
-rw-r--r--arch/arm/plat-omap/sram.c11
-rw-r--r--arch/arm/plat-samsung/clock.c10
-rw-r--r--arch/arm64/Kconfig222
-rw-r--r--arch/arm64/Kconfig.debug27
-rw-r--r--arch/arm64/Makefile71
-rw-r--r--arch/arm64/boot/.gitignore2
-rw-r--r--arch/arm64/boot/Makefile36
-rw-r--r--arch/arm64/boot/install.sh46
-rw-r--r--arch/arm64/configs/defconfig85
-rw-r--r--arch/arm64/include/asm/Kbuild51
-rw-r--r--arch/arm64/include/asm/arm_generic.h100
-rw-r--r--arch/arm64/include/asm/asm-offsets.h1
-rw-r--r--arch/arm64/include/asm/assembler.h109
-rw-r--r--arch/arm64/include/asm/atomic.h305
-rw-r--r--arch/arm64/include/asm/auxvec.h22
-rw-r--r--arch/arm64/include/asm/barrier.h52
-rw-r--r--arch/arm64/include/asm/bitops.h53
-rw-r--r--arch/arm64/include/asm/bitsperlong.h23
-rw-r--r--arch/arm64/include/asm/byteorder.h21
-rw-r--r--arch/arm64/include/asm/cache.h32
-rw-r--r--arch/arm64/include/asm/cacheflush.h148
-rw-r--r--arch/arm64/include/asm/cachetype.h48
-rw-r--r--arch/arm64/include/asm/cmpxchg.h173
-rw-r--r--arch/arm64/include/asm/compat.h242
-rw-r--r--arch/arm64/include/asm/compiler.h30
-rw-r--r--arch/arm64/include/asm/cputable.h30
-rw-r--r--arch/arm64/include/asm/cputype.h49
-rw-r--r--arch/arm64/include/asm/debug-monitors.h88
-rw-r--r--arch/arm64/include/asm/device.h26
-rw-r--r--arch/arm64/include/asm/dma-mapping.h124
-rw-r--r--arch/arm64/include/asm/elf.h179
-rw-r--r--arch/arm64/include/asm/exception.h23
-rw-r--r--arch/arm64/include/asm/exec.h23
-rw-r--r--arch/arm64/include/asm/fb.h34
-rw-r--r--arch/arm64/include/asm/fcntl.h29
-rw-r--r--arch/arm64/include/asm/fpsimd.h64
-rw-r--r--arch/arm64/include/asm/futex.h136
-rw-r--r--arch/arm64/include/asm/hardirq.h52
-rw-r--r--arch/arm64/include/asm/hw_breakpoint.h137
-rw-r--r--arch/arm64/include/asm/hwcap.h53
-rw-r--r--arch/arm64/include/asm/io.h258
-rw-r--r--arch/arm64/include/asm/irq.h8
-rw-r--r--arch/arm64/include/asm/irqflags.h91
-rw-r--r--arch/arm64/include/asm/memblock.h21
-rw-r--r--arch/arm64/include/asm/memory.h144
-rw-r--r--arch/arm64/include/asm/mmu.h30
-rw-r--r--arch/arm64/include/asm/mmu_context.h152
-rw-r--r--arch/arm64/include/asm/module.h23
-rw-r--r--arch/arm64/include/asm/page.h67
-rw-r--r--arch/arm64/include/asm/param.h23
-rw-r--r--arch/arm64/include/asm/perf_event.h22
-rw-r--r--arch/arm64/include/asm/pgalloc.h113
-rw-r--r--arch/arm64/include/asm/pgtable-2level-hwdef.h43
-rw-r--r--arch/arm64/include/asm/pgtable-2level-types.h60
-rw-r--r--arch/arm64/include/asm/pgtable-3level-hwdef.h50
-rw-r--r--arch/arm64/include/asm/pgtable-3level-types.h66
-rw-r--r--arch/arm64/include/asm/pgtable-hwdef.h94
-rw-r--r--arch/arm64/include/asm/pgtable.h328
-rw-r--r--arch/arm64/include/asm/pmu.h82
-rw-r--r--arch/arm64/include/asm/proc-fns.h50
-rw-r--r--arch/arm64/include/asm/processor.h175
-rw-r--r--arch/arm64/include/asm/prom.h1
-rw-r--r--arch/arm64/include/asm/ptrace.h207
-rw-r--r--arch/arm64/include/asm/setup.h26
-rw-r--r--arch/arm64/include/asm/shmparam.h28
-rw-r--r--arch/arm64/include/asm/sigcontext.h69
-rw-r--r--arch/arm64/include/asm/siginfo.h23
-rw-r--r--arch/arm64/include/asm/signal.h24
-rw-r--r--arch/arm64/include/asm/signal32.h53
-rw-r--r--arch/arm64/include/asm/smp.h69
-rw-r--r--arch/arm64/include/asm/sparsemem.h24
-rw-r--r--arch/arm64/include/asm/spinlock.h202
-rw-r--r--arch/arm64/include/asm/spinlock_types.h38
-rw-r--r--arch/arm64/include/asm/stacktrace.h29
-rw-r--r--arch/arm64/include/asm/stat.h62
-rw-r--r--arch/arm64/include/asm/statfs.h23
-rw-r--r--arch/arm64/include/asm/syscall.h101
-rw-r--r--arch/arm64/include/asm/syscalls.h40
-rw-r--r--arch/arm64/include/asm/system_misc.h54
-rw-r--r--arch/arm64/include/asm/thread_info.h127
-rw-r--r--arch/arm64/include/asm/timex.h29
-rw-r--r--arch/arm64/include/asm/tlb.h190
-rw-r--r--arch/arm64/include/asm/tlbflush.h122
-rw-r--r--arch/arm64/include/asm/traps.h30
-rw-r--r--arch/arm64/include/asm/uaccess.h297
-rw-r--r--arch/arm64/include/asm/ucontext.h30
-rw-r--r--arch/arm64/include/asm/unistd.h27
-rw-r--r--arch/arm64/include/asm/unistd32.h758
-rw-r--r--arch/arm64/include/asm/vdso.h41
-rw-r--r--arch/arm64/include/asm/vdso_datapage.h43
-rw-r--r--arch/arm64/kernel/.gitignore1
-rw-r--r--arch/arm64/kernel/Makefile27
-rw-r--r--arch/arm64/kernel/arm64ksyms.c46
-rw-r--r--arch/arm64/kernel/asm-offsets.c108
-rw-r--r--arch/arm64/kernel/cputable.c33
-rw-r--r--arch/arm64/kernel/debug-monitors.c288
-rw-r--r--arch/arm64/kernel/entry-fpsimd.S80
-rw-r--r--arch/arm64/kernel/entry.S695
-rw-r--r--arch/arm64/kernel/fpsimd.c106
-rw-r--r--arch/arm64/kernel/head.S510
-rw-r--r--arch/arm64/kernel/hw_breakpoint.c880
-rw-r--r--arch/arm64/kernel/io.c64
-rw-r--r--arch/arm64/kernel/irq.c84
-rw-r--r--arch/arm64/kernel/kuser32.S77
-rw-r--r--arch/arm64/kernel/module.c456
-rw-r--r--arch/arm64/kernel/perf_event.c1368
-rw-r--r--arch/arm64/kernel/process.c408
-rw-r--r--arch/arm64/kernel/ptrace.c1126
-rw-r--r--arch/arm64/kernel/setup.c347
-rw-r--r--arch/arm64/kernel/signal.c437
-rw-r--r--arch/arm64/kernel/signal32.c876
-rw-r--r--arch/arm64/kernel/smp.c469
-rw-r--r--arch/arm64/kernel/stacktrace.c127
-rw-r--r--arch/arm64/kernel/sys.c138
-rw-r--r--arch/arm64/kernel/sys32.S282
-rw-r--r--arch/arm64/kernel/sys_compat.c164
-rw-r--r--arch/arm64/kernel/time.c65
-rw-r--r--arch/arm64/kernel/traps.c348
-rw-r--r--arch/arm64/kernel/vdso.c261
-rw-r--r--arch/arm64/kernel/vdso/.gitignore2
-rw-r--r--arch/arm64/kernel/vdso/Makefile63
-rwxr-xr-xarch/arm64/kernel/vdso/gen_vdso_offsets.sh15
-rw-r--r--arch/arm64/kernel/vdso/gettimeofday.S242
-rw-r--r--arch/arm64/kernel/vdso/note.S28
-rw-r--r--arch/arm64/kernel/vdso/sigreturn.S37
-rw-r--r--arch/arm64/kernel/vdso/vdso.S33
-rw-r--r--arch/arm64/kernel/vdso/vdso.lds.S100
-rw-r--r--arch/arm64/kernel/vmlinux.lds.S126
-rw-r--r--arch/arm64/lib/Makefile4
-rw-r--r--arch/arm64/lib/bitops.c25
-rw-r--r--arch/arm64/lib/clear_page.S39
-rw-r--r--arch/arm64/lib/clear_user.S58
-rw-r--r--arch/arm64/lib/copy_from_user.S66
-rw-r--r--arch/arm64/lib/copy_in_user.S63
-rw-r--r--arch/arm64/lib/copy_page.S46
-rw-r--r--arch/arm64/lib/copy_to_user.S61
-rw-r--r--arch/arm64/lib/delay.c55
-rw-r--r--arch/arm64/lib/strncpy_from_user.S50
-rw-r--r--arch/arm64/lib/strnlen_user.S47
-rw-r--r--arch/arm64/mm/Makefile4
-rw-r--r--arch/arm64/mm/cache.S168
-rw-r--r--arch/arm64/mm/context.c159
-rw-r--r--arch/arm64/mm/copypage.c34
-rw-r--r--arch/arm64/mm/dma-mapping.c79
-rw-r--r--arch/arm64/mm/extable.c17
-rw-r--r--arch/arm64/mm/fault.c534
-rw-r--r--arch/arm64/mm/flush.c135
-rw-r--r--arch/arm64/mm/init.c437
-rw-r--r--arch/arm64/mm/ioremap.c84
-rw-r--r--arch/arm64/mm/mm.h2
-rw-r--r--arch/arm64/mm/mmap.c144
-rw-r--r--arch/arm64/mm/mmu.c395
-rw-r--r--arch/arm64/mm/pgd.c54
-rw-r--r--arch/arm64/mm/proc-macros.S55
-rw-r--r--arch/arm64/mm/proc.S175
-rw-r--r--arch/arm64/mm/tlb.S71
-rw-r--r--arch/blackfin/Kconfig1
-rw-r--r--arch/blackfin/Makefile1
-rw-r--r--arch/blackfin/include/asm/smp.h2
-rw-r--r--arch/blackfin/mach-common/smp.c223
-rw-r--r--arch/c6x/include/asm/Kbuild1
-rw-r--r--arch/c6x/include/asm/barrier.h27
-rw-r--r--arch/cris/kernel/process.c3
-rw-r--r--arch/frv/kernel/process.c3
-rw-r--r--arch/h8300/kernel/process.c3
-rw-r--r--arch/ia64/Kconfig12
-rw-r--r--arch/ia64/include/asm/switch_to.h8
-rw-r--r--arch/ia64/kernel/process.c3
-rw-r--r--arch/ia64/kernel/time.c66
-rw-r--r--arch/m32r/kernel/process.c3
-rw-r--r--arch/m68k/kernel/process.c3
-rw-r--r--arch/m68k/platform/coldfire/clk.c6
-rw-r--r--arch/mips/kernel/smp-cmp.c2
-rw-r--r--arch/mips/mm/gup.c2
-rw-r--r--arch/mips/mti-malta/malta-int.c9
-rw-r--r--arch/mips/mti-malta/malta-platform.c5
-rw-r--r--arch/mn10300/kernel/process.c3
-rw-r--r--arch/parisc/kernel/process.c3
-rw-r--r--arch/powerpc/boot/.gitignore4
-rw-r--r--arch/powerpc/include/asm/time.h6
-rw-r--r--arch/powerpc/kernel/process.c3
-rw-r--r--arch/powerpc/kernel/time.c55
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype16
-rw-r--r--arch/s390/Kbuild1
-rw-r--r--arch/s390/Kconfig421
-rw-r--r--arch/s390/boot/compressed/Makefile1
-rw-r--r--arch/s390/boot/compressed/misc.c45
-rw-r--r--arch/s390/defconfig14
-rw-r--r--arch/s390/include/asm/appldata.h2
-rw-r--r--arch/s390/include/asm/chsc.h28
-rw-r--r--arch/s390/include/asm/cio.h28
-rw-r--r--arch/s390/include/asm/cmpxchg.h61
-rw-r--r--arch/s390/include/asm/cpu_mf.h4
-rw-r--r--arch/s390/include/asm/cputime.h3
-rw-r--r--arch/s390/include/asm/css_chars.h39
-rw-r--r--arch/s390/include/asm/eadm.h124
-rw-r--r--arch/s390/include/asm/elf.h3
-rw-r--r--arch/s390/include/asm/etr.h8
-rw-r--r--arch/s390/include/asm/hugetlb.h24
-rw-r--r--arch/s390/include/asm/irq.h2
-rw-r--r--arch/s390/include/asm/isc.h1
-rw-r--r--arch/s390/include/asm/lowcore.h6
-rw-r--r--arch/s390/include/asm/mmu_context.h2
-rw-r--r--arch/s390/include/asm/percpu.h50
-rw-r--r--arch/s390/include/asm/processor.h59
-rw-r--r--arch/s390/include/asm/ptrace.h12
-rw-r--r--arch/s390/include/asm/runtime_instr.h98
-rw-r--r--arch/s390/include/asm/scsw.h38
-rw-r--r--arch/s390/include/asm/setup.h5
-rw-r--r--arch/s390/include/asm/smp.h4
-rw-r--r--arch/s390/include/asm/string.h8
-rw-r--r--arch/s390/include/asm/switch_to.h6
-rw-r--r--arch/s390/include/asm/sysinfo.h39
-rw-r--r--arch/s390/include/asm/tlbflush.h2
-rw-r--r--arch/s390/include/asm/topology.h20
-rw-r--r--arch/s390/include/asm/uaccess.h15
-rw-r--r--arch/s390/include/asm/unistd.h4
-rw-r--r--arch/s390/kernel/Makefile12
-rw-r--r--arch/s390/kernel/asm-offsets.c2
-rw-r--r--arch/s390/kernel/cache.c385
-rw-r--r--arch/s390/kernel/compat_wrapper.S13
-rw-r--r--arch/s390/kernel/crash.c14
-rw-r--r--arch/s390/kernel/crash_dump.c3
-rw-r--r--arch/s390/kernel/dis.c58
-rw-r--r--arch/s390/kernel/early.c38
-rw-r--r--arch/s390/kernel/entry64.S17
-rw-r--r--arch/s390/kernel/irq.c56
-rw-r--r--arch/s390/kernel/kprobes.c2
-rw-r--r--arch/s390/kernel/lgr.c29
-rw-r--r--arch/s390/kernel/machine_kexec.c9
-rw-r--r--arch/s390/kernel/process.c8
-rw-r--r--arch/s390/kernel/processor.c7
-rw-r--r--arch/s390/kernel/ptrace.c70
-rw-r--r--arch/s390/kernel/runtime_instr.c150
-rw-r--r--arch/s390/kernel/s390_ksyms.c2
-rw-r--r--arch/s390/kernel/setup.c56
-rw-r--r--arch/s390/kernel/smp.c46
-rw-r--r--arch/s390/kernel/syscalls.S2
-rw-r--r--arch/s390/kernel/sysinfo.c351
-rw-r--r--arch/s390/kernel/time.c4
-rw-r--r--arch/s390/kernel/topology.c27
-rw-r--r--arch/s390/kernel/traps.c41
-rw-r--r--arch/s390/kernel/vdso.c8
-rw-r--r--arch/s390/kernel/vtime.c11
-rw-r--r--arch/s390/kvm/Kconfig2
-rw-r--r--arch/s390/kvm/priv.c4
-rw-r--r--arch/s390/lib/Makefile3
-rw-r--r--arch/s390/lib/mem32.S92
-rw-r--r--arch/s390/lib/mem64.S88
-rw-r--r--arch/s390/lib/string.c56
-rw-r--r--arch/s390/lib/uaccess_pt.c142
-rw-r--r--arch/s390/mm/Makefile2
-rw-r--r--arch/s390/mm/extable.c81
-rw-r--r--arch/s390/mm/fault.c7
-rw-r--r--arch/s390/mm/gup.c37
-rw-r--r--arch/s390/mm/init.c4
-rw-r--r--arch/s390/mm/pgtable.c6
-rw-r--r--arch/s390/mm/vmem.c2
-rw-r--r--arch/s390/net/Makefile4
-rw-r--r--arch/s390/net/bpf_jit.S130
-rw-r--r--arch/s390/net/bpf_jit_comp.c776
-rw-r--r--arch/s390/oprofile/init.c10
-rw-r--r--arch/score/kernel/process.c4
-rw-r--r--arch/sh/kernel/cpu/sh5/entry.S2
-rw-r--r--arch/sh/kernel/entry-common.S2
-rw-r--r--arch/sparc/kernel/module.c13
-rw-r--r--arch/tile/include/asm/topology.h1
-rw-r--r--arch/tile/include/gxio/iorpc_trio.h24
-rw-r--r--arch/um/drivers/mconsole_kern.c1
-rw-r--r--arch/um/include/asm/processor-generic.h9
-rw-r--r--arch/um/include/shared/common-offsets.h10
-rw-r--r--arch/um/include/shared/user.h11
-rw-r--r--arch/um/kernel/exec.c25
-rw-r--r--arch/um/kernel/process.c8
-rw-r--r--arch/um/kernel/signal.c6
-rw-r--r--arch/um/kernel/syscall.c24
-rw-r--r--arch/um/scripts/Makefile.rules2
-rw-r--r--arch/x86/Kconfig95
-rw-r--r--arch/x86/Kconfig.cpu5
-rw-r--r--arch/x86/Makefile2
-rw-r--r--arch/x86/boot/compressed/Makefile3
-rw-r--r--arch/x86/boot/compressed/eboot.c34
-rw-r--r--arch/x86/boot/compressed/eboot.h4
-rw-r--r--arch/x86/boot/header.S4
-rw-r--r--arch/x86/configs/i386_defconfig23
-rw-r--r--arch/x86/configs/x86_64_defconfig23
-rw-r--r--arch/x86/ia32/ia32_signal.c20
-rw-r--r--arch/x86/ia32/sys_ia32.c2
-rw-r--r--arch/x86/include/asm/alternative.h4
-rw-r--r--arch/x86/include/asm/bitops.h14
-rw-r--r--arch/x86/include/asm/calling.h48
-rw-r--r--arch/x86/include/asm/cpufeature.h4
-rw-r--r--arch/x86/include/asm/fpu-internal.h390
-rw-r--r--arch/x86/include/asm/ftrace.h56
-rw-r--r--arch/x86/include/asm/hardirq.h4
-rw-r--r--arch/x86/include/asm/hpet.h2
-rw-r--r--arch/x86/include/asm/i387.h29
-rw-r--r--arch/x86/include/asm/iommu_table.h6
-rw-r--r--arch/x86/include/asm/kprobes.h1
-rw-r--r--arch/x86/include/asm/kvm.h16
-rw-r--r--arch/x86/include/asm/kvm_host.h16
-rw-r--r--arch/x86/include/asm/mce.h13
-rw-r--r--arch/x86/include/asm/microcode.h10
-rw-r--r--arch/x86/include/asm/perf_event.h2
-rw-r--r--arch/x86/include/asm/perf_regs.h33
-rw-r--r--arch/x86/include/asm/pgtable_types.h6
-rw-r--r--arch/x86/include/asm/processor.h3
-rw-r--r--arch/x86/include/asm/rcu.h32
-rw-r--r--arch/x86/include/asm/signal.h4
-rw-r--r--arch/x86/include/asm/svm.h205
-rw-r--r--arch/x86/include/asm/sys_ia32.h2
-rw-r--r--arch/x86/include/asm/thread_info.h10
-rw-r--r--arch/x86/include/asm/uprobes.h3
-rw-r--r--arch/x86/include/asm/vdso.h3
-rw-r--r--arch/x86/include/asm/vmx.h127
-rw-r--r--arch/x86/include/asm/x86_init.h9
-rw-r--r--arch/x86/include/asm/xen/page.h3
-rw-r--r--arch/x86/include/asm/xor_32.h56
-rw-r--r--arch/x86/include/asm/xor_64.h61
-rw-r--r--arch/x86/include/asm/xor_avx.h54
-rw-r--r--arch/x86/include/asm/xsave.h13
-rw-r--r--arch/x86/kernel/Makefile2
-rw-r--r--arch/x86/kernel/acpi/boot.c2
-rw-r--r--arch/x86/kernel/alternative.c111
-rw-r--r--arch/x86/kernel/apic/apic.c2
-rw-r--r--arch/x86/kernel/cpu/amd.c67
-rw-r--r--arch/x86/kernel/cpu/bugs.c7
-rw-r--r--arch/x86/kernel/cpu/common.c19
-rw-r--r--arch/x86/kernel/cpu/intel.c4
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce-inject.c8
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce-internal.h12
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c94
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_intel.c168
-rw-r--r--arch/x86/kernel/cpu/perf_event.h2
-rw-r--r--arch/x86/kernel/cpu/perf_event_amd_ibs.c12
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel.c25
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_ds.c14
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_lbr.c3
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_uncore.c36
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_uncore.h6
-rw-r--r--arch/x86/kernel/cpu/proc.c5
-rw-r--r--arch/x86/kernel/cpuid.c5
-rw-r--r--arch/x86/kernel/devicetree.c51
-rw-r--r--arch/x86/kernel/entry_32.S74
-rw-r--r--arch/x86/kernel/entry_64.S161
-rw-r--r--arch/x86/kernel/ftrace.c73
-rw-r--r--arch/x86/kernel/i387.c292
-rw-r--r--arch/x86/kernel/i8259.c2
-rw-r--r--arch/x86/kernel/irq.c4
-rw-r--r--arch/x86/kernel/kprobes.c67
-rw-r--r--arch/x86/kernel/microcode_amd.c357
-rw-r--r--arch/x86/kernel/microcode_core.c70
-rw-r--r--arch/x86/kernel/microcode_intel.c3
-rw-r--r--arch/x86/kernel/msr.c5
-rw-r--r--arch/x86/kernel/perf_regs.c105
-rw-r--r--arch/x86/kernel/probe_roms.c2
-rw-r--r--arch/x86/kernel/process.c22
-rw-r--r--arch/x86/kernel/process_32.c4
-rw-r--r--arch/x86/kernel/process_64.c4
-rw-r--r--arch/x86/kernel/ptrace.c8
-rw-r--r--arch/x86/kernel/setup.c4
-rw-r--r--arch/x86/kernel/signal.c215
-rw-r--r--arch/x86/kernel/smpboot.c20
-rw-r--r--arch/x86/kernel/step.c53
-rw-r--r--arch/x86/kernel/traps.c174
-rw-r--r--arch/x86/kernel/uprobes.c52
-rw-r--r--arch/x86/kernel/x8664_ksyms_64.c6
-rw-r--r--arch/x86/kernel/x86_init.c4
-rw-r--r--arch/x86/kernel/xsave.c517
-rw-r--r--arch/x86/kvm/i8259.c2
-rw-r--r--arch/x86/kvm/trace.h89
-rw-r--r--arch/x86/kvm/vmx.c35
-rw-r--r--arch/x86/kvm/x86.c16
-rw-r--r--arch/x86/mm/fault.c13
-rw-r--r--arch/x86/mm/init.c2
-rw-r--r--arch/x86/mm/init_32.c11
-rw-r--r--arch/x86/mm/tlb.c4
-rw-r--r--arch/x86/pci/mmconfig-shared.c2
-rw-r--r--arch/x86/platform/efi/Makefile1
-rw-r--r--arch/x86/platform/efi/efi-bgrt.c76
-rw-r--r--arch/x86/platform/efi/efi.c66
-rw-r--r--arch/x86/um/Kconfig1
-rw-r--r--arch/x86/um/shared/sysdep/kernel-offsets.h3
-rw-r--r--arch/x86/um/shared/sysdep/syscalls.h2
-rw-r--r--arch/x86/um/signal.c6
-rw-r--r--arch/x86/um/sys_call_table_32.c2
-rw-r--r--arch/x86/um/syscalls_32.c27
-rw-r--r--arch/x86/um/syscalls_64.c23
-rw-r--r--arch/x86/xen/enlighten.c4
-rw-r--r--arch/x86/xen/mmu.c18
-rw-r--r--arch/x86/xen/p2m.c27
-rw-r--r--arch/x86/xen/setup.c4
-rw-r--r--arch/x86/xen/smp.c6
-rw-r--r--arch/xtensa/kernel/process.c3
439 files changed, 27879 insertions, 3316 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index 72f2fa189cc5..a62965d057f6 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -222,6 +222,19 @@ config HAVE_PERF_EVENTS_NMI
222 subsystem. Also has support for calculating CPU cycle events 222 subsystem. Also has support for calculating CPU cycle events
223 to determine how many clock cycles in a given period. 223 to determine how many clock cycles in a given period.
224 224
225config HAVE_PERF_REGS
226 bool
227 help
228 Support selective register dumps for perf events. This includes
229 bit-mapping of each registers and a unique architecture id.
230
231config HAVE_PERF_USER_STACK_DUMP
232 bool
233 help
234 Support user stack dumps for perf event samples. This needs
235 access to the user stack pointer which is not unified across
236 architectures.
237
225config HAVE_ARCH_JUMP_LABEL 238config HAVE_ARCH_JUMP_LABEL
226 bool 239 bool
227 240
@@ -281,4 +294,23 @@ config SECCOMP_FILTER
281 294
282 See Documentation/prctl/seccomp_filter.txt for details. 295 See Documentation/prctl/seccomp_filter.txt for details.
283 296
297config HAVE_RCU_USER_QS
298 bool
299 help
300 Provide kernel entry/exit hooks necessary for userspace
301 RCU extended quiescent state. Syscalls need to be wrapped inside
302 rcu_user_exit()-rcu_user_enter() through the slow path using
303 TIF_NOHZ flag. Exceptions handlers must be wrapped as well. Irqs
304 are already protected inside rcu_irq_enter/rcu_irq_exit() but
305 preemption or signal handling on irq exit still need to be protected.
306
307config HAVE_VIRT_CPU_ACCOUNTING
308 bool
309
310config HAVE_IRQ_TIME_ACCOUNTING
311 bool
312 help
313 Archs need to ensure they use a high enough resolution clock to
314 support irq time accounting and then call enable_sched_clock_irqtime().
315
284source "kernel/gcov/Kconfig" 316source "kernel/gcov/Kconfig"
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index d6fde98b74b3..83638aa096d5 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -28,6 +28,7 @@
28#include <linux/tty.h> 28#include <linux/tty.h>
29#include <linux/console.h> 29#include <linux/console.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/rcupdate.h>
31 32
32#include <asm/reg.h> 33#include <asm/reg.h>
33#include <asm/uaccess.h> 34#include <asm/uaccess.h>
@@ -54,9 +55,12 @@ cpu_idle(void)
54 /* FIXME -- EV6 and LCA45 know how to power down 55 /* FIXME -- EV6 and LCA45 know how to power down
55 the CPU. */ 56 the CPU. */
56 57
58 rcu_idle_enter();
57 while (!need_resched()) 59 while (!need_resched())
58 cpu_relax(); 60 cpu_relax();
59 schedule(); 61
62 rcu_idle_exit();
63 schedule_preempt_disabled();
60 } 64 }
61} 65}
62 66
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index 35ddc02bfa4a..a41ad90a97a6 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -166,6 +166,7 @@ smp_callin(void)
166 DBGS(("smp_callin: commencing CPU %d current %p active_mm %p\n", 166 DBGS(("smp_callin: commencing CPU %d current %p active_mm %p\n",
167 cpuid, current, current->active_mm)); 167 cpuid, current, current->active_mm));
168 168
169 preempt_disable();
169 /* Do nothing. */ 170 /* Do nothing. */
170 cpu_idle(); 171 cpu_idle();
171} 172}
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index f15f82bf3a50..e968a52e4881 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -356,15 +356,15 @@ choice
356 is nothing connected to read from the DCC. 356 is nothing connected to read from the DCC.
357 357
358 config DEBUG_SEMIHOSTING 358 config DEBUG_SEMIHOSTING
359 bool "Kernel low-level debug output via semihosting I" 359 bool "Kernel low-level debug output via semihosting I/O"
360 help 360 help
361 Semihosting enables code running on an ARM target to use 361 Semihosting enables code running on an ARM target to use
362 the I/O facilities on a host debugger/emulator through a 362 the I/O facilities on a host debugger/emulator through a
363 simple SVC calls. The host debugger or emulator must have 363 simple SVC call. The host debugger or emulator must have
364 semihosting enabled for the special svc call to be trapped 364 semihosting enabled for the special svc call to be trapped
365 otherwise the kernel will crash. 365 otherwise the kernel will crash.
366 366
367 This is known to work with OpenOCD, as wellas 367 This is known to work with OpenOCD, as well as
368 ARM's Fast Models, or any other controlling environment 368 ARM's Fast Models, or any other controlling environment
369 that implements semihosting. 369 that implements semihosting.
370 370
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 30eae87ead6d..a051dfbdd7db 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -284,10 +284,10 @@ zImage Image xipImage bootpImage uImage: vmlinux
284zinstall uinstall install: vmlinux 284zinstall uinstall install: vmlinux
285 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ 285 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
286 286
287%.dtb: 287%.dtb: scripts
288 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ 288 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
289 289
290dtbs: 290dtbs: scripts
291 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ 291 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
292 292
293# We use MRPROPER_FILES and CLEAN_FILES now 293# We use MRPROPER_FILES and CLEAN_FILES now
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index b8c64b80bafc..bc67cbff3944 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -653,16 +653,21 @@ __armv7_mmu_cache_on:
653 mcrne p15, 0, r0, c8, c7, 0 @ flush I,D TLBs 653 mcrne p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
654#endif 654#endif
655 mrc p15, 0, r0, c1, c0, 0 @ read control reg 655 mrc p15, 0, r0, c1, c0, 0 @ read control reg
656 bic r0, r0, #1 << 28 @ clear SCTLR.TRE
656 orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement 657 orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement
657 orr r0, r0, #0x003c @ write buffer 658 orr r0, r0, #0x003c @ write buffer
658#ifdef CONFIG_MMU 659#ifdef CONFIG_MMU
659#ifdef CONFIG_CPU_ENDIAN_BE8 660#ifdef CONFIG_CPU_ENDIAN_BE8
660 orr r0, r0, #1 << 25 @ big-endian page tables 661 orr r0, r0, #1 << 25 @ big-endian page tables
661#endif 662#endif
663 mrcne p15, 0, r6, c2, c0, 2 @ read ttb control reg
662 orrne r0, r0, #1 @ MMU enabled 664 orrne r0, r0, #1 @ MMU enabled
663 movne r1, #0xfffffffd @ domain 0 = client 665 movne r1, #0xfffffffd @ domain 0 = client
666 bic r6, r6, #1 << 31 @ 32-bit translation system
667 bic r6, r6, #3 << 0 @ use only ttbr0
664 mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer 668 mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer
665 mcrne p15, 0, r1, c3, c0, 0 @ load domain access control 669 mcrne p15, 0, r1, c3, c0, 0 @ load domain access control
670 mcrne p15, 0, r6, c2, c0, 2 @ load ttb control
666#endif 671#endif
667 mcr p15, 0, r0, c7, c5, 4 @ ISB 672 mcr p15, 0, r0, c7, c5, 4 @ ISB
668 mcr p15, 0, r0, c1, c0, 0 @ load control register 673 mcr p15, 0, r0, c1, c0, 0 @ load control register
diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi
index 66389c1c6f62..7c95f76398de 100644
--- a/arch/arm/boot/dts/at91sam9260.dtsi
+++ b/arch/arm/boot/dts/at91sam9260.dtsi
@@ -104,6 +104,7 @@
104 #gpio-cells = <2>; 104 #gpio-cells = <2>;
105 gpio-controller; 105 gpio-controller;
106 interrupt-controller; 106 interrupt-controller;
107 #interrupt-cells = <2>;
107 }; 108 };
108 109
109 pioB: gpio@fffff600 { 110 pioB: gpio@fffff600 {
@@ -113,6 +114,7 @@
113 #gpio-cells = <2>; 114 #gpio-cells = <2>;
114 gpio-controller; 115 gpio-controller;
115 interrupt-controller; 116 interrupt-controller;
117 #interrupt-cells = <2>;
116 }; 118 };
117 119
118 pioC: gpio@fffff800 { 120 pioC: gpio@fffff800 {
@@ -122,6 +124,7 @@
122 #gpio-cells = <2>; 124 #gpio-cells = <2>;
123 gpio-controller; 125 gpio-controller;
124 interrupt-controller; 126 interrupt-controller;
127 #interrupt-cells = <2>;
125 }; 128 };
126 129
127 dbgu: serial@fffff200 { 130 dbgu: serial@fffff200 {
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi
index b460d6ce9eb5..195019b7ca0e 100644
--- a/arch/arm/boot/dts/at91sam9263.dtsi
+++ b/arch/arm/boot/dts/at91sam9263.dtsi
@@ -95,6 +95,7 @@
95 #gpio-cells = <2>; 95 #gpio-cells = <2>;
96 gpio-controller; 96 gpio-controller;
97 interrupt-controller; 97 interrupt-controller;
98 #interrupt-cells = <2>;
98 }; 99 };
99 100
100 pioB: gpio@fffff400 { 101 pioB: gpio@fffff400 {
@@ -104,6 +105,7 @@
104 #gpio-cells = <2>; 105 #gpio-cells = <2>;
105 gpio-controller; 106 gpio-controller;
106 interrupt-controller; 107 interrupt-controller;
108 #interrupt-cells = <2>;
107 }; 109 };
108 110
109 pioC: gpio@fffff600 { 111 pioC: gpio@fffff600 {
@@ -113,6 +115,7 @@
113 #gpio-cells = <2>; 115 #gpio-cells = <2>;
114 gpio-controller; 116 gpio-controller;
115 interrupt-controller; 117 interrupt-controller;
118 #interrupt-cells = <2>;
116 }; 119 };
117 120
118 pioD: gpio@fffff800 { 121 pioD: gpio@fffff800 {
@@ -122,6 +125,7 @@
122 #gpio-cells = <2>; 125 #gpio-cells = <2>;
123 gpio-controller; 126 gpio-controller;
124 interrupt-controller; 127 interrupt-controller;
128 #interrupt-cells = <2>;
125 }; 129 };
126 130
127 pioE: gpio@fffffa00 { 131 pioE: gpio@fffffa00 {
@@ -131,6 +135,7 @@
131 #gpio-cells = <2>; 135 #gpio-cells = <2>;
132 gpio-controller; 136 gpio-controller;
133 interrupt-controller; 137 interrupt-controller;
138 #interrupt-cells = <2>;
134 }; 139 };
135 140
136 dbgu: serial@ffffee00 { 141 dbgu: serial@ffffee00 {
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
index bafa8806fc17..63751b1e744b 100644
--- a/arch/arm/boot/dts/at91sam9g45.dtsi
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -113,6 +113,7 @@
113 #gpio-cells = <2>; 113 #gpio-cells = <2>;
114 gpio-controller; 114 gpio-controller;
115 interrupt-controller; 115 interrupt-controller;
116 #interrupt-cells = <2>;
116 }; 117 };
117 118
118 pioB: gpio@fffff400 { 119 pioB: gpio@fffff400 {
@@ -122,6 +123,7 @@
122 #gpio-cells = <2>; 123 #gpio-cells = <2>;
123 gpio-controller; 124 gpio-controller;
124 interrupt-controller; 125 interrupt-controller;
126 #interrupt-cells = <2>;
125 }; 127 };
126 128
127 pioC: gpio@fffff600 { 129 pioC: gpio@fffff600 {
@@ -131,6 +133,7 @@
131 #gpio-cells = <2>; 133 #gpio-cells = <2>;
132 gpio-controller; 134 gpio-controller;
133 interrupt-controller; 135 interrupt-controller;
136 #interrupt-cells = <2>;
134 }; 137 };
135 138
136 pioD: gpio@fffff800 { 139 pioD: gpio@fffff800 {
@@ -140,6 +143,7 @@
140 #gpio-cells = <2>; 143 #gpio-cells = <2>;
141 gpio-controller; 144 gpio-controller;
142 interrupt-controller; 145 interrupt-controller;
146 #interrupt-cells = <2>;
143 }; 147 };
144 148
145 pioE: gpio@fffffa00 { 149 pioE: gpio@fffffa00 {
@@ -149,6 +153,7 @@
149 #gpio-cells = <2>; 153 #gpio-cells = <2>;
150 gpio-controller; 154 gpio-controller;
151 interrupt-controller; 155 interrupt-controller;
156 #interrupt-cells = <2>;
152 }; 157 };
153 158
154 dbgu: serial@ffffee00 { 159 dbgu: serial@ffffee00 {
diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi
index bfac0dfc332c..ef9336ae9614 100644
--- a/arch/arm/boot/dts/at91sam9n12.dtsi
+++ b/arch/arm/boot/dts/at91sam9n12.dtsi
@@ -107,6 +107,7 @@
107 #gpio-cells = <2>; 107 #gpio-cells = <2>;
108 gpio-controller; 108 gpio-controller;
109 interrupt-controller; 109 interrupt-controller;
110 #interrupt-cells = <2>;
110 }; 111 };
111 112
112 pioB: gpio@fffff600 { 113 pioB: gpio@fffff600 {
@@ -116,6 +117,7 @@
116 #gpio-cells = <2>; 117 #gpio-cells = <2>;
117 gpio-controller; 118 gpio-controller;
118 interrupt-controller; 119 interrupt-controller;
120 #interrupt-cells = <2>;
119 }; 121 };
120 122
121 pioC: gpio@fffff800 { 123 pioC: gpio@fffff800 {
@@ -125,6 +127,7 @@
125 #gpio-cells = <2>; 127 #gpio-cells = <2>;
126 gpio-controller; 128 gpio-controller;
127 interrupt-controller; 129 interrupt-controller;
130 #interrupt-cells = <2>;
128 }; 131 };
129 132
130 pioD: gpio@fffffa00 { 133 pioD: gpio@fffffa00 {
@@ -134,6 +137,7 @@
134 #gpio-cells = <2>; 137 #gpio-cells = <2>;
135 gpio-controller; 138 gpio-controller;
136 interrupt-controller; 139 interrupt-controller;
140 #interrupt-cells = <2>;
137 }; 141 };
138 142
139 dbgu: serial@fffff200 { 143 dbgu: serial@fffff200 {
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index 4a18c393b136..8a387a8d61b7 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -115,6 +115,7 @@
115 #gpio-cells = <2>; 115 #gpio-cells = <2>;
116 gpio-controller; 116 gpio-controller;
117 interrupt-controller; 117 interrupt-controller;
118 #interrupt-cells = <2>;
118 }; 119 };
119 120
120 pioB: gpio@fffff600 { 121 pioB: gpio@fffff600 {
@@ -124,6 +125,7 @@
124 #gpio-cells = <2>; 125 #gpio-cells = <2>;
125 gpio-controller; 126 gpio-controller;
126 interrupt-controller; 127 interrupt-controller;
128 #interrupt-cells = <2>;
127 }; 129 };
128 130
129 pioC: gpio@fffff800 { 131 pioC: gpio@fffff800 {
@@ -133,6 +135,7 @@
133 #gpio-cells = <2>; 135 #gpio-cells = <2>;
134 gpio-controller; 136 gpio-controller;
135 interrupt-controller; 137 interrupt-controller;
138 #interrupt-cells = <2>;
136 }; 139 };
137 140
138 pioD: gpio@fffffa00 { 141 pioD: gpio@fffffa00 {
@@ -142,6 +145,7 @@
142 #gpio-cells = <2>; 145 #gpio-cells = <2>;
143 gpio-controller; 146 gpio-controller;
144 interrupt-controller; 147 interrupt-controller;
148 #interrupt-cells = <2>;
145 }; 149 };
146 150
147 dbgu: serial@fffff200 { 151 dbgu: serial@fffff200 {
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 03fb93621d0d..5c8b3bf4d825 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -320,4 +320,12 @@
320 .size \name , . - \name 320 .size \name , . - \name
321 .endm 321 .endm
322 322
323 .macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req
324#ifndef CONFIG_CPU_USE_DOMAINS
325 adds \tmp, \addr, #\size - 1
326 sbcccs \tmp, \tmp, \limit
327 bcs \bad
328#endif
329 .endm
330
323#endif /* __ASM_ASSEMBLER_H__ */ 331#endif /* __ASM_ASSEMBLER_H__ */
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index e965f1b560f1..5f6ddcc56452 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -187,6 +187,7 @@ static inline unsigned long __phys_to_virt(unsigned long x)
187#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET) 187#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
188#endif 188#endif
189#endif 189#endif
190#endif /* __ASSEMBLY__ */
190 191
191#ifndef PHYS_OFFSET 192#ifndef PHYS_OFFSET
192#ifdef PLAT_PHYS_OFFSET 193#ifdef PLAT_PHYS_OFFSET
@@ -196,6 +197,8 @@ static inline unsigned long __phys_to_virt(unsigned long x)
196#endif 197#endif
197#endif 198#endif
198 199
200#ifndef __ASSEMBLY__
201
199/* 202/*
200 * PFNs are used to describe any physical page; this means 203 * PFNs are used to describe any physical page; this means
201 * PFN 0 == physical address 0. 204 * PFN 0 == physical address 0.
diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h
index 314d4664eae7..99a19512ee26 100644
--- a/arch/arm/include/asm/tlb.h
+++ b/arch/arm/include/asm/tlb.h
@@ -199,6 +199,9 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
199{ 199{
200 pgtable_page_dtor(pte); 200 pgtable_page_dtor(pte);
201 201
202#ifdef CONFIG_ARM_LPAE
203 tlb_add_flush(tlb, addr);
204#else
202 /* 205 /*
203 * With the classic ARM MMU, a pte page has two corresponding pmd 206 * With the classic ARM MMU, a pte page has two corresponding pmd
204 * entries, each covering 1MB. 207 * entries, each covering 1MB.
@@ -206,6 +209,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
206 addr &= PMD_MASK; 209 addr &= PMD_MASK;
207 tlb_add_flush(tlb, addr + SZ_1M - PAGE_SIZE); 210 tlb_add_flush(tlb, addr + SZ_1M - PAGE_SIZE);
208 tlb_add_flush(tlb, addr + SZ_1M); 211 tlb_add_flush(tlb, addr + SZ_1M);
212#endif
209 213
210 tlb_remove_page(tlb, pte); 214 tlb_remove_page(tlb, pte);
211} 215}
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 479a6352e0b5..77bd79f2ffdb 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -101,28 +101,39 @@ extern int __get_user_1(void *);
101extern int __get_user_2(void *); 101extern int __get_user_2(void *);
102extern int __get_user_4(void *); 102extern int __get_user_4(void *);
103 103
104#define __get_user_x(__r2,__p,__e,__s,__i...) \ 104#define __GUP_CLOBBER_1 "lr", "cc"
105#ifdef CONFIG_CPU_USE_DOMAINS
106#define __GUP_CLOBBER_2 "ip", "lr", "cc"
107#else
108#define __GUP_CLOBBER_2 "lr", "cc"
109#endif
110#define __GUP_CLOBBER_4 "lr", "cc"
111
112#define __get_user_x(__r2,__p,__e,__l,__s) \
105 __asm__ __volatile__ ( \ 113 __asm__ __volatile__ ( \
106 __asmeq("%0", "r0") __asmeq("%1", "r2") \ 114 __asmeq("%0", "r0") __asmeq("%1", "r2") \
115 __asmeq("%3", "r1") \
107 "bl __get_user_" #__s \ 116 "bl __get_user_" #__s \
108 : "=&r" (__e), "=r" (__r2) \ 117 : "=&r" (__e), "=r" (__r2) \
109 : "0" (__p) \ 118 : "0" (__p), "r" (__l) \
110 : __i, "cc") 119 : __GUP_CLOBBER_##__s)
111 120
112#define get_user(x,p) \ 121#define __get_user_check(x,p) \
113 ({ \ 122 ({ \
123 unsigned long __limit = current_thread_info()->addr_limit - 1; \
114 register const typeof(*(p)) __user *__p asm("r0") = (p);\ 124 register const typeof(*(p)) __user *__p asm("r0") = (p);\
115 register unsigned long __r2 asm("r2"); \ 125 register unsigned long __r2 asm("r2"); \
126 register unsigned long __l asm("r1") = __limit; \
116 register int __e asm("r0"); \ 127 register int __e asm("r0"); \
117 switch (sizeof(*(__p))) { \ 128 switch (sizeof(*(__p))) { \
118 case 1: \ 129 case 1: \
119 __get_user_x(__r2, __p, __e, 1, "lr"); \ 130 __get_user_x(__r2, __p, __e, __l, 1); \
120 break; \ 131 break; \
121 case 2: \ 132 case 2: \
122 __get_user_x(__r2, __p, __e, 2, "r3", "lr"); \ 133 __get_user_x(__r2, __p, __e, __l, 2); \
123 break; \ 134 break; \
124 case 4: \ 135 case 4: \
125 __get_user_x(__r2, __p, __e, 4, "lr"); \ 136 __get_user_x(__r2, __p, __e, __l, 4); \
126 break; \ 137 break; \
127 default: __e = __get_user_bad(); break; \ 138 default: __e = __get_user_bad(); break; \
128 } \ 139 } \
@@ -130,42 +141,57 @@ extern int __get_user_4(void *);
130 __e; \ 141 __e; \
131 }) 142 })
132 143
144#define get_user(x,p) \
145 ({ \
146 might_fault(); \
147 __get_user_check(x,p); \
148 })
149
133extern int __put_user_1(void *, unsigned int); 150extern int __put_user_1(void *, unsigned int);
134extern int __put_user_2(void *, unsigned int); 151extern int __put_user_2(void *, unsigned int);
135extern int __put_user_4(void *, unsigned int); 152extern int __put_user_4(void *, unsigned int);
136extern int __put_user_8(void *, unsigned long long); 153extern int __put_user_8(void *, unsigned long long);
137 154
138#define __put_user_x(__r2,__p,__e,__s) \ 155#define __put_user_x(__r2,__p,__e,__l,__s) \
139 __asm__ __volatile__ ( \ 156 __asm__ __volatile__ ( \
140 __asmeq("%0", "r0") __asmeq("%2", "r2") \ 157 __asmeq("%0", "r0") __asmeq("%2", "r2") \
158 __asmeq("%3", "r1") \
141 "bl __put_user_" #__s \ 159 "bl __put_user_" #__s \
142 : "=&r" (__e) \ 160 : "=&r" (__e) \
143 : "0" (__p), "r" (__r2) \ 161 : "0" (__p), "r" (__r2), "r" (__l) \
144 : "ip", "lr", "cc") 162 : "ip", "lr", "cc")
145 163
146#define put_user(x,p) \ 164#define __put_user_check(x,p) \
147 ({ \ 165 ({ \
166 unsigned long __limit = current_thread_info()->addr_limit - 1; \
148 register const typeof(*(p)) __r2 asm("r2") = (x); \ 167 register const typeof(*(p)) __r2 asm("r2") = (x); \
149 register const typeof(*(p)) __user *__p asm("r0") = (p);\ 168 register const typeof(*(p)) __user *__p asm("r0") = (p);\
169 register unsigned long __l asm("r1") = __limit; \
150 register int __e asm("r0"); \ 170 register int __e asm("r0"); \
151 switch (sizeof(*(__p))) { \ 171 switch (sizeof(*(__p))) { \
152 case 1: \ 172 case 1: \
153 __put_user_x(__r2, __p, __e, 1); \ 173 __put_user_x(__r2, __p, __e, __l, 1); \
154 break; \ 174 break; \
155 case 2: \ 175 case 2: \
156 __put_user_x(__r2, __p, __e, 2); \ 176 __put_user_x(__r2, __p, __e, __l, 2); \
157 break; \ 177 break; \
158 case 4: \ 178 case 4: \
159 __put_user_x(__r2, __p, __e, 4); \ 179 __put_user_x(__r2, __p, __e, __l, 4); \
160 break; \ 180 break; \
161 case 8: \ 181 case 8: \
162 __put_user_x(__r2, __p, __e, 8); \ 182 __put_user_x(__r2, __p, __e, __l, 8); \
163 break; \ 183 break; \
164 default: __e = __put_user_bad(); break; \ 184 default: __e = __put_user_bad(); break; \
165 } \ 185 } \
166 __e; \ 186 __e; \
167 }) 187 })
168 188
189#define put_user(x,p) \
190 ({ \
191 might_fault(); \
192 __put_user_check(x,p); \
193 })
194
169#else /* CONFIG_MMU */ 195#else /* CONFIG_MMU */
170 196
171/* 197/*
@@ -219,6 +245,7 @@ do { \
219 unsigned long __gu_addr = (unsigned long)(ptr); \ 245 unsigned long __gu_addr = (unsigned long)(ptr); \
220 unsigned long __gu_val; \ 246 unsigned long __gu_val; \
221 __chk_user_ptr(ptr); \ 247 __chk_user_ptr(ptr); \
248 might_fault(); \
222 switch (sizeof(*(ptr))) { \ 249 switch (sizeof(*(ptr))) { \
223 case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \ 250 case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \
224 case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \ 251 case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \
@@ -300,6 +327,7 @@ do { \
300 unsigned long __pu_addr = (unsigned long)(ptr); \ 327 unsigned long __pu_addr = (unsigned long)(ptr); \
301 __typeof__(*(ptr)) __pu_val = (x); \ 328 __typeof__(*(ptr)) __pu_val = (x); \
302 __chk_user_ptr(ptr); \ 329 __chk_user_ptr(ptr); \
330 might_fault(); \
303 switch (sizeof(*(ptr))) { \ 331 switch (sizeof(*(ptr))) { \
304 case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \ 332 case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \
305 case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \ 333 case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 0cab47d4a83f..2fde5fd1acce 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -404,6 +404,7 @@
404#define __NR_setns (__NR_SYSCALL_BASE+375) 404#define __NR_setns (__NR_SYSCALL_BASE+375)
405#define __NR_process_vm_readv (__NR_SYSCALL_BASE+376) 405#define __NR_process_vm_readv (__NR_SYSCALL_BASE+376)
406#define __NR_process_vm_writev (__NR_SYSCALL_BASE+377) 406#define __NR_process_vm_writev (__NR_SYSCALL_BASE+377)
407 /* 378 for kcmp */
407 408
408/* 409/*
409 * The following SWIs are ARM private. 410 * The following SWIs are ARM private.
@@ -483,6 +484,7 @@
483 */ 484 */
484#define __IGNORE_fadvise64_64 485#define __IGNORE_fadvise64_64
485#define __IGNORE_migrate_pages 486#define __IGNORE_migrate_pages
487#define __IGNORE_kcmp
486 488
487#endif /* __KERNEL__ */ 489#endif /* __KERNEL__ */
488#endif /* __ASM_ARM_UNISTD_H */ 490#endif /* __ASM_ARM_UNISTD_H */
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 463ff4a0ec8a..e337879595e5 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -387,6 +387,7 @@
387/* 375 */ CALL(sys_setns) 387/* 375 */ CALL(sys_setns)
388 CALL(sys_process_vm_readv) 388 CALL(sys_process_vm_readv)
389 CALL(sys_process_vm_writev) 389 CALL(sys_process_vm_writev)
390 CALL(sys_ni_syscall) /* reserved for sys_kcmp */
390#ifndef syscalls_counted 391#ifndef syscalls_counted
391.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls 392.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
392#define syscalls_counted 393#define syscalls_counted
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index ba386bd94107..281bf3301241 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -159,6 +159,12 @@ static int debug_arch_supported(void)
159 arch >= ARM_DEBUG_ARCH_V7_1; 159 arch >= ARM_DEBUG_ARCH_V7_1;
160} 160}
161 161
162/* Can we determine the watchpoint access type from the fsr? */
163static int debug_exception_updates_fsr(void)
164{
165 return 0;
166}
167
162/* Determine number of WRP registers available. */ 168/* Determine number of WRP registers available. */
163static int get_num_wrp_resources(void) 169static int get_num_wrp_resources(void)
164{ 170{
@@ -604,13 +610,14 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
604 /* Aligned */ 610 /* Aligned */
605 break; 611 break;
606 case 1: 612 case 1:
607 /* Allow single byte watchpoint. */
608 if (info->ctrl.len == ARM_BREAKPOINT_LEN_1)
609 break;
610 case 2: 613 case 2:
611 /* Allow halfword watchpoints and breakpoints. */ 614 /* Allow halfword watchpoints and breakpoints. */
612 if (info->ctrl.len == ARM_BREAKPOINT_LEN_2) 615 if (info->ctrl.len == ARM_BREAKPOINT_LEN_2)
613 break; 616 break;
617 case 3:
618 /* Allow single byte watchpoint. */
619 if (info->ctrl.len == ARM_BREAKPOINT_LEN_1)
620 break;
614 default: 621 default:
615 ret = -EINVAL; 622 ret = -EINVAL;
616 goto out; 623 goto out;
@@ -619,18 +626,35 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
619 info->address &= ~alignment_mask; 626 info->address &= ~alignment_mask;
620 info->ctrl.len <<= offset; 627 info->ctrl.len <<= offset;
621 628
622 /* 629 if (!bp->overflow_handler) {
623 * Currently we rely on an overflow handler to take 630 /*
624 * care of single-stepping the breakpoint when it fires. 631 * Mismatch breakpoints are required for single-stepping
625 * In the case of userspace breakpoints on a core with V7 debug, 632 * breakpoints.
626 * we can use the mismatch feature as a poor-man's hardware 633 */
627 * single-step, but this only works for per-task breakpoints. 634 if (!core_has_mismatch_brps())
628 */ 635 return -EINVAL;
629 if (!bp->overflow_handler && (arch_check_bp_in_kernelspace(bp) || 636
630 !core_has_mismatch_brps() || !bp->hw.bp_target)) { 637 /* We don't allow mismatch breakpoints in kernel space. */
631 pr_warning("overflow handler required but none found\n"); 638 if (arch_check_bp_in_kernelspace(bp))
632 ret = -EINVAL; 639 return -EPERM;
640
641 /*
642 * Per-cpu breakpoints are not supported by our stepping
643 * mechanism.
644 */
645 if (!bp->hw.bp_target)
646 return -EINVAL;
647
648 /*
649 * We only support specific access types if the fsr
650 * reports them.
651 */
652 if (!debug_exception_updates_fsr() &&
653 (info->ctrl.type == ARM_BREAKPOINT_LOAD ||
654 info->ctrl.type == ARM_BREAKPOINT_STORE))
655 return -EINVAL;
633 } 656 }
657
634out: 658out:
635 return ret; 659 return ret;
636} 660}
@@ -706,10 +730,12 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,
706 goto unlock; 730 goto unlock;
707 731
708 /* Check that the access type matches. */ 732 /* Check that the access type matches. */
709 access = (fsr & ARM_FSR_ACCESS_MASK) ? HW_BREAKPOINT_W : 733 if (debug_exception_updates_fsr()) {
710 HW_BREAKPOINT_R; 734 access = (fsr & ARM_FSR_ACCESS_MASK) ?
711 if (!(access & hw_breakpoint_type(wp))) 735 HW_BREAKPOINT_W : HW_BREAKPOINT_R;
712 goto unlock; 736 if (!(access & hw_breakpoint_type(wp)))
737 goto unlock;
738 }
713 739
714 /* We have a winner. */ 740 /* We have a winner. */
715 info->trigger = addr; 741 info->trigger = addr;
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index fef42b21cecb..e1f906989bb8 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -11,7 +11,6 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/clk.h> 13#include <linux/clk.h>
14#include <linux/cpufreq.h>
15#include <linux/delay.h> 14#include <linux/delay.h>
16#include <linux/device.h> 15#include <linux/device.h>
17#include <linux/err.h> 16#include <linux/err.h>
@@ -96,7 +95,52 @@ static void twd_timer_stop(struct clock_event_device *clk)
96 disable_percpu_irq(clk->irq); 95 disable_percpu_irq(clk->irq);
97} 96}
98 97
99#ifdef CONFIG_CPU_FREQ 98#ifdef CONFIG_COMMON_CLK
99
100/*
101 * Updates clockevent frequency when the cpu frequency changes.
102 * Called on the cpu that is changing frequency with interrupts disabled.
103 */
104static void twd_update_frequency(void *new_rate)
105{
106 twd_timer_rate = *((unsigned long *) new_rate);
107
108 clockevents_update_freq(*__this_cpu_ptr(twd_evt), twd_timer_rate);
109}
110
111static int twd_rate_change(struct notifier_block *nb,
112 unsigned long flags, void *data)
113{
114 struct clk_notifier_data *cnd = data;
115
116 /*
117 * The twd clock events must be reprogrammed to account for the new
118 * frequency. The timer is local to a cpu, so cross-call to the
119 * changing cpu.
120 */
121 if (flags == POST_RATE_CHANGE)
122 smp_call_function(twd_update_frequency,
123 (void *)&cnd->new_rate, 1);
124
125 return NOTIFY_OK;
126}
127
128static struct notifier_block twd_clk_nb = {
129 .notifier_call = twd_rate_change,
130};
131
132static int twd_clk_init(void)
133{
134 if (twd_evt && *__this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk))
135 return clk_notifier_register(twd_clk, &twd_clk_nb);
136
137 return 0;
138}
139core_initcall(twd_clk_init);
140
141#elif defined (CONFIG_CPU_FREQ)
142
143#include <linux/cpufreq.h>
100 144
101/* 145/*
102 * Updates clockevent frequency when the cpu frequency changes. 146 * Updates clockevent frequency when the cpu frequency changes.
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index f7945218b8c6..b0179b89a04c 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -420,20 +420,23 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
420#endif 420#endif
421 instr = *(u32 *) pc; 421 instr = *(u32 *) pc;
422 } else if (thumb_mode(regs)) { 422 } else if (thumb_mode(regs)) {
423 get_user(instr, (u16 __user *)pc); 423 if (get_user(instr, (u16 __user *)pc))
424 goto die_sig;
424 if (is_wide_instruction(instr)) { 425 if (is_wide_instruction(instr)) {
425 unsigned int instr2; 426 unsigned int instr2;
426 get_user(instr2, (u16 __user *)pc+1); 427 if (get_user(instr2, (u16 __user *)pc+1))
428 goto die_sig;
427 instr <<= 16; 429 instr <<= 16;
428 instr |= instr2; 430 instr |= instr2;
429 } 431 }
430 } else { 432 } else if (get_user(instr, (u32 __user *)pc)) {
431 get_user(instr, (u32 __user *)pc); 433 goto die_sig;
432 } 434 }
433 435
434 if (call_undef_hook(regs, instr) == 0) 436 if (call_undef_hook(regs, instr) == 0)
435 return; 437 return;
436 438
439die_sig:
437#ifdef CONFIG_DEBUG_USER 440#ifdef CONFIG_DEBUG_USER
438 if (user_debug & UDBG_UNDEFINED) { 441 if (user_debug & UDBG_UNDEFINED) {
439 printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n", 442 printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c
index d6dacc69254e..395d5fbb8fa2 100644
--- a/arch/arm/lib/delay.c
+++ b/arch/arm/lib/delay.c
@@ -59,6 +59,7 @@ void __init init_current_timer_delay(unsigned long freq)
59{ 59{
60 pr_info("Switching to timer-based delay loop\n"); 60 pr_info("Switching to timer-based delay loop\n");
61 lpj_fine = freq / HZ; 61 lpj_fine = freq / HZ;
62 loops_per_jiffy = lpj_fine;
62 arm_delay_ops.delay = __timer_delay; 63 arm_delay_ops.delay = __timer_delay;
63 arm_delay_ops.const_udelay = __timer_const_udelay; 64 arm_delay_ops.const_udelay = __timer_const_udelay;
64 arm_delay_ops.udelay = __timer_udelay; 65 arm_delay_ops.udelay = __timer_udelay;
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
index 11093a7c3e32..9b06bb41fca6 100644
--- a/arch/arm/lib/getuser.S
+++ b/arch/arm/lib/getuser.S
@@ -16,8 +16,9 @@
16 * __get_user_X 16 * __get_user_X
17 * 17 *
18 * Inputs: r0 contains the address 18 * Inputs: r0 contains the address
19 * r1 contains the address limit, which must be preserved
19 * Outputs: r0 is the error code 20 * Outputs: r0 is the error code
20 * r2, r3 contains the zero-extended value 21 * r2 contains the zero-extended value
21 * lr corrupted 22 * lr corrupted
22 * 23 *
23 * No other registers must be altered. (see <asm/uaccess.h> 24 * No other registers must be altered. (see <asm/uaccess.h>
@@ -27,33 +28,39 @@
27 * Note also that it is intended that __get_user_bad is not global. 28 * Note also that it is intended that __get_user_bad is not global.
28 */ 29 */
29#include <linux/linkage.h> 30#include <linux/linkage.h>
31#include <asm/assembler.h>
30#include <asm/errno.h> 32#include <asm/errno.h>
31#include <asm/domain.h> 33#include <asm/domain.h>
32 34
33ENTRY(__get_user_1) 35ENTRY(__get_user_1)
36 check_uaccess r0, 1, r1, r2, __get_user_bad
341: TUSER(ldrb) r2, [r0] 371: TUSER(ldrb) r2, [r0]
35 mov r0, #0 38 mov r0, #0
36 mov pc, lr 39 mov pc, lr
37ENDPROC(__get_user_1) 40ENDPROC(__get_user_1)
38 41
39ENTRY(__get_user_2) 42ENTRY(__get_user_2)
40#ifdef CONFIG_THUMB2_KERNEL 43 check_uaccess r0, 2, r1, r2, __get_user_bad
412: TUSER(ldrb) r2, [r0] 44#ifdef CONFIG_CPU_USE_DOMAINS
423: TUSER(ldrb) r3, [r0, #1] 45rb .req ip
462: ldrbt r2, [r0], #1
473: ldrbt rb, [r0], #0
43#else 48#else
442: TUSER(ldrb) r2, [r0], #1 49rb .req r0
453: TUSER(ldrb) r3, [r0] 502: ldrb r2, [r0]
513: ldrb rb, [r0, #1]
46#endif 52#endif
47#ifndef __ARMEB__ 53#ifndef __ARMEB__
48 orr r2, r2, r3, lsl #8 54 orr r2, r2, rb, lsl #8
49#else 55#else
50 orr r2, r3, r2, lsl #8 56 orr r2, rb, r2, lsl #8
51#endif 57#endif
52 mov r0, #0 58 mov r0, #0
53 mov pc, lr 59 mov pc, lr
54ENDPROC(__get_user_2) 60ENDPROC(__get_user_2)
55 61
56ENTRY(__get_user_4) 62ENTRY(__get_user_4)
63 check_uaccess r0, 4, r1, r2, __get_user_bad
574: TUSER(ldr) r2, [r0] 644: TUSER(ldr) r2, [r0]
58 mov r0, #0 65 mov r0, #0
59 mov pc, lr 66 mov pc, lr
diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S
index 7db25990c589..3d73dcb959b0 100644
--- a/arch/arm/lib/putuser.S
+++ b/arch/arm/lib/putuser.S
@@ -16,6 +16,7 @@
16 * __put_user_X 16 * __put_user_X
17 * 17 *
18 * Inputs: r0 contains the address 18 * Inputs: r0 contains the address
19 * r1 contains the address limit, which must be preserved
19 * r2, r3 contains the value 20 * r2, r3 contains the value
20 * Outputs: r0 is the error code 21 * Outputs: r0 is the error code
21 * lr corrupted 22 * lr corrupted
@@ -27,16 +28,19 @@
27 * Note also that it is intended that __put_user_bad is not global. 28 * Note also that it is intended that __put_user_bad is not global.
28 */ 29 */
29#include <linux/linkage.h> 30#include <linux/linkage.h>
31#include <asm/assembler.h>
30#include <asm/errno.h> 32#include <asm/errno.h>
31#include <asm/domain.h> 33#include <asm/domain.h>
32 34
33ENTRY(__put_user_1) 35ENTRY(__put_user_1)
36 check_uaccess r0, 1, r1, ip, __put_user_bad
341: TUSER(strb) r2, [r0] 371: TUSER(strb) r2, [r0]
35 mov r0, #0 38 mov r0, #0
36 mov pc, lr 39 mov pc, lr
37ENDPROC(__put_user_1) 40ENDPROC(__put_user_1)
38 41
39ENTRY(__put_user_2) 42ENTRY(__put_user_2)
43 check_uaccess r0, 2, r1, ip, __put_user_bad
40 mov ip, r2, lsr #8 44 mov ip, r2, lsr #8
41#ifdef CONFIG_THUMB2_KERNEL 45#ifdef CONFIG_THUMB2_KERNEL
42#ifndef __ARMEB__ 46#ifndef __ARMEB__
@@ -60,12 +64,14 @@ ENTRY(__put_user_2)
60ENDPROC(__put_user_2) 64ENDPROC(__put_user_2)
61 65
62ENTRY(__put_user_4) 66ENTRY(__put_user_4)
67 check_uaccess r0, 4, r1, ip, __put_user_bad
634: TUSER(str) r2, [r0] 684: TUSER(str) r2, [r0]
64 mov r0, #0 69 mov r0, #0
65 mov pc, lr 70 mov pc, lr
66ENDPROC(__put_user_4) 71ENDPROC(__put_user_4)
67 72
68ENTRY(__put_user_8) 73ENTRY(__put_user_8)
74 check_uaccess r0, 8, r1, ip, __put_user_bad
69#ifdef CONFIG_THUMB2_KERNEL 75#ifdef CONFIG_THUMB2_KERNEL
705: TUSER(str) r2, [r0] 765: TUSER(str) r2, [r0]
716: TUSER(str) r3, [r0, #4] 776: TUSER(str) r3, [r0, #4]
diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c
index fdd8cc87c9fe..d20d4795f4ea 100644
--- a/arch/arm/mach-imx/clk-imx25.c
+++ b/arch/arm/mach-imx/clk-imx25.c
@@ -222,10 +222,8 @@ int __init mx25_clocks_init(void)
222 clk_register_clkdev(clk[lcdc_ipg], "ipg", "imx-fb.0"); 222 clk_register_clkdev(clk[lcdc_ipg], "ipg", "imx-fb.0");
223 clk_register_clkdev(clk[lcdc_ahb], "ahb", "imx-fb.0"); 223 clk_register_clkdev(clk[lcdc_ahb], "ahb", "imx-fb.0");
224 clk_register_clkdev(clk[wdt_ipg], NULL, "imx2-wdt.0"); 224 clk_register_clkdev(clk[wdt_ipg], NULL, "imx2-wdt.0");
225 clk_register_clkdev(clk[ssi1_ipg_per], "per", "imx-ssi.0"); 225 clk_register_clkdev(clk[ssi1_ipg], NULL, "imx-ssi.0");
226 clk_register_clkdev(clk[ssi1_ipg], "ipg", "imx-ssi.0"); 226 clk_register_clkdev(clk[ssi2_ipg], NULL, "imx-ssi.1");
227 clk_register_clkdev(clk[ssi2_ipg_per], "per", "imx-ssi.1");
228 clk_register_clkdev(clk[ssi2_ipg], "ipg", "imx-ssi.1");
229 clk_register_clkdev(clk[esdhc1_ipg_per], "per", "sdhci-esdhc-imx25.0"); 227 clk_register_clkdev(clk[esdhc1_ipg_per], "per", "sdhci-esdhc-imx25.0");
230 clk_register_clkdev(clk[esdhc1_ipg], "ipg", "sdhci-esdhc-imx25.0"); 228 clk_register_clkdev(clk[esdhc1_ipg], "ipg", "sdhci-esdhc-imx25.0");
231 clk_register_clkdev(clk[esdhc1_ahb], "ahb", "sdhci-esdhc-imx25.0"); 229 clk_register_clkdev(clk[esdhc1_ahb], "ahb", "sdhci-esdhc-imx25.0");
@@ -243,6 +241,6 @@ int __init mx25_clocks_init(void)
243 clk_register_clkdev(clk[sdma_ahb], "ahb", "imx35-sdma"); 241 clk_register_clkdev(clk[sdma_ahb], "ahb", "imx35-sdma");
244 clk_register_clkdev(clk[iim_ipg], "iim", NULL); 242 clk_register_clkdev(clk[iim_ipg], "iim", NULL);
245 243
246 mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54); 244 mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), MX25_INT_GPT1);
247 return 0; 245 return 0;
248} 246}
diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c
index c6422fb10bae..65fb8bcd86cb 100644
--- a/arch/arm/mach-imx/clk-imx35.c
+++ b/arch/arm/mach-imx/clk-imx35.c
@@ -230,10 +230,8 @@ int __init mx35_clocks_init()
230 clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb"); 230 clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb");
231 clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1"); 231 clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1");
232 clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma"); 232 clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma");
233 clk_register_clkdev(clk[ipg], "ipg", "imx-ssi.0"); 233 clk_register_clkdev(clk[ssi1_gate], NULL, "imx-ssi.0");
234 clk_register_clkdev(clk[ssi1_div_post], "per", "imx-ssi.0"); 234 clk_register_clkdev(clk[ssi2_gate], NULL, "imx-ssi.1");
235 clk_register_clkdev(clk[ipg], "ipg", "imx-ssi.1");
236 clk_register_clkdev(clk[ssi2_div_post], "per", "imx-ssi.1");
237 /* i.mx35 has the i.mx21 type uart */ 235 /* i.mx35 has the i.mx21 type uart */
238 clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0"); 236 clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0");
239 clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0"); 237 clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0");
diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c
index 2c6ab3273f9e..5985ed1b8c98 100644
--- a/arch/arm/mach-imx/mach-armadillo5x0.c
+++ b/arch/arm/mach-imx/mach-armadillo5x0.c
@@ -526,7 +526,8 @@ static void __init armadillo5x0_init(void)
526 imx31_add_mxc_nand(&armadillo5x0_nand_board_info); 526 imx31_add_mxc_nand(&armadillo5x0_nand_board_info);
527 527
528 /* set NAND page size to 2k if not configured via boot mode pins */ 528 /* set NAND page size to 2k if not configured via boot mode pins */
529 __raw_writel(__raw_readl(MXC_CCM_RCSR) | (1 << 30), MXC_CCM_RCSR); 529 __raw_writel(__raw_readl(mx3_ccm_base + MXC_CCM_RCSR) |
530 (1 << 30), mx3_ccm_base + MXC_CCM_RCSR);
530 531
531 /* RTC */ 532 /* RTC */
532 /* Get RTC IRQ and register the chip */ 533 /* Get RTC IRQ and register the chip */
diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
index 8dabfe81d07c..ff886e01a0b0 100644
--- a/arch/arm/mach-mxs/mach-mxs.c
+++ b/arch/arm/mach-mxs/mach-mxs.c
@@ -261,7 +261,7 @@ static void __init apx4devkit_init(void)
261 enable_clk_enet_out(); 261 enable_clk_enet_out();
262 262
263 if (IS_BUILTIN(CONFIG_PHYLIB)) 263 if (IS_BUILTIN(CONFIG_PHYLIB))
264 phy_register_fixup_for_uid(PHY_ID_KS8051, MICREL_PHY_ID_MASK, 264 phy_register_fixup_for_uid(PHY_ID_KSZ8051, MICREL_PHY_ID_MASK,
265 apx4devkit_phy_fixup); 265 apx4devkit_phy_fixup);
266 266
267 mxsfb_pdata.mode_list = apx4devkit_video_modes; 267 mxsfb_pdata.mode_list = apx4devkit_video_modes;
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index fcd4e85c4ddc..346fd26f3aa6 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -232,10 +232,11 @@ config MACH_OMAP3_PANDORA
232 select OMAP_PACKAGE_CBB 232 select OMAP_PACKAGE_CBB
233 select REGULATOR_FIXED_VOLTAGE if REGULATOR 233 select REGULATOR_FIXED_VOLTAGE if REGULATOR
234 234
235config MACH_OMAP3_TOUCHBOOK 235config MACH_TOUCHBOOK
236 bool "OMAP3 Touch Book" 236 bool "OMAP3 Touch Book"
237 depends on ARCH_OMAP3 237 depends on ARCH_OMAP3
238 default y 238 default y
239 select OMAP_PACKAGE_CBB
239 240
240config MACH_OMAP_3430SDP 241config MACH_OMAP_3430SDP
241 bool "OMAP 3430 SDP board" 242 bool "OMAP 3430 SDP board"
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index f6a24b3f9c4f..34c2c7f59f0a 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -255,7 +255,7 @@ obj-$(CONFIG_MACH_OMAP_3630SDP) += board-zoom-display.o
255obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o 255obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o
256obj-$(CONFIG_MACH_CM_T3517) += board-cm-t3517.o 256obj-$(CONFIG_MACH_CM_T3517) += board-cm-t3517.o
257obj-$(CONFIG_MACH_IGEP0020) += board-igep0020.o 257obj-$(CONFIG_MACH_IGEP0020) += board-igep0020.o
258obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK) += board-omap3touchbook.o 258obj-$(CONFIG_MACH_TOUCHBOOK) += board-omap3touchbook.o
259obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o 259obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o
260obj-$(CONFIG_MACH_OMAP4_PANDA) += board-omap4panda.o 260obj-$(CONFIG_MACH_OMAP4_PANDA) += board-omap4panda.o
261 261
diff --git a/arch/arm/mach-omap2/clock33xx_data.c b/arch/arm/mach-omap2/clock33xx_data.c
index 25bbcc7ca4dc..ae27de8899a6 100644
--- a/arch/arm/mach-omap2/clock33xx_data.c
+++ b/arch/arm/mach-omap2/clock33xx_data.c
@@ -1036,13 +1036,13 @@ static struct omap_clk am33xx_clks[] = {
1036 CLK(NULL, "mmu_fck", &mmu_fck, CK_AM33XX), 1036 CLK(NULL, "mmu_fck", &mmu_fck, CK_AM33XX),
1037 CLK(NULL, "smartreflex0_fck", &smartreflex0_fck, CK_AM33XX), 1037 CLK(NULL, "smartreflex0_fck", &smartreflex0_fck, CK_AM33XX),
1038 CLK(NULL, "smartreflex1_fck", &smartreflex1_fck, CK_AM33XX), 1038 CLK(NULL, "smartreflex1_fck", &smartreflex1_fck, CK_AM33XX),
1039 CLK(NULL, "gpt1_fck", &timer1_fck, CK_AM33XX), 1039 CLK(NULL, "timer1_fck", &timer1_fck, CK_AM33XX),
1040 CLK(NULL, "gpt2_fck", &timer2_fck, CK_AM33XX), 1040 CLK(NULL, "timer2_fck", &timer2_fck, CK_AM33XX),
1041 CLK(NULL, "gpt3_fck", &timer3_fck, CK_AM33XX), 1041 CLK(NULL, "timer3_fck", &timer3_fck, CK_AM33XX),
1042 CLK(NULL, "gpt4_fck", &timer4_fck, CK_AM33XX), 1042 CLK(NULL, "timer4_fck", &timer4_fck, CK_AM33XX),
1043 CLK(NULL, "gpt5_fck", &timer5_fck, CK_AM33XX), 1043 CLK(NULL, "timer5_fck", &timer5_fck, CK_AM33XX),
1044 CLK(NULL, "gpt6_fck", &timer6_fck, CK_AM33XX), 1044 CLK(NULL, "timer6_fck", &timer6_fck, CK_AM33XX),
1045 CLK(NULL, "gpt7_fck", &timer7_fck, CK_AM33XX), 1045 CLK(NULL, "timer7_fck", &timer7_fck, CK_AM33XX),
1046 CLK(NULL, "usbotg_fck", &usbotg_fck, CK_AM33XX), 1046 CLK(NULL, "usbotg_fck", &usbotg_fck, CK_AM33XX),
1047 CLK(NULL, "ieee5000_fck", &ieee5000_fck, CK_AM33XX), 1047 CLK(NULL, "ieee5000_fck", &ieee5000_fck, CK_AM33XX),
1048 CLK(NULL, "wdt1_fck", &wdt1_fck, CK_AM33XX), 1048 CLK(NULL, "wdt1_fck", &wdt1_fck, CK_AM33XX),
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index a0d68dbecfa3..f99e65cfb862 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -241,6 +241,52 @@ static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)
241 _clkdm_del_autodeps(clkdm); 241 _clkdm_del_autodeps(clkdm);
242} 242}
243 243
244static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
245{
246 bool hwsup = false;
247
248 if (!clkdm->clktrctrl_mask)
249 return 0;
250
251 hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
252 clkdm->clktrctrl_mask);
253
254 if (hwsup) {
255 /* Disable HW transitions when we are changing deps */
256 _disable_hwsup(clkdm);
257 _clkdm_add_autodeps(clkdm);
258 _enable_hwsup(clkdm);
259 } else {
260 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
261 omap3_clkdm_wakeup(clkdm);
262 }
263
264 return 0;
265}
266
267static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
268{
269 bool hwsup = false;
270
271 if (!clkdm->clktrctrl_mask)
272 return 0;
273
274 hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
275 clkdm->clktrctrl_mask);
276
277 if (hwsup) {
278 /* Disable HW transitions when we are changing deps */
279 _disable_hwsup(clkdm);
280 _clkdm_del_autodeps(clkdm);
281 _enable_hwsup(clkdm);
282 } else {
283 if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
284 omap3_clkdm_sleep(clkdm);
285 }
286
287 return 0;
288}
289
244struct clkdm_ops omap2_clkdm_operations = { 290struct clkdm_ops omap2_clkdm_operations = {
245 .clkdm_add_wkdep = omap2_clkdm_add_wkdep, 291 .clkdm_add_wkdep = omap2_clkdm_add_wkdep,
246 .clkdm_del_wkdep = omap2_clkdm_del_wkdep, 292 .clkdm_del_wkdep = omap2_clkdm_del_wkdep,
@@ -267,6 +313,6 @@ struct clkdm_ops omap3_clkdm_operations = {
267 .clkdm_wakeup = omap3_clkdm_wakeup, 313 .clkdm_wakeup = omap3_clkdm_wakeup,
268 .clkdm_allow_idle = omap3_clkdm_allow_idle, 314 .clkdm_allow_idle = omap3_clkdm_allow_idle,
269 .clkdm_deny_idle = omap3_clkdm_deny_idle, 315 .clkdm_deny_idle = omap3_clkdm_deny_idle,
270 .clkdm_clk_enable = omap2_clkdm_clk_enable, 316 .clkdm_clk_enable = omap3xxx_clkdm_clk_enable,
271 .clkdm_clk_disable = omap2_clkdm_clk_disable, 317 .clkdm_clk_disable = omap3xxx_clkdm_clk_disable,
272}; 318};
diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h
index 766338fe4d34..975f6bda0e0b 100644
--- a/arch/arm/mach-omap2/cm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-34xx.h
@@ -67,6 +67,7 @@
67#define OMAP3430_EN_IVA2_DPLL_MASK (0x7 << 0) 67#define OMAP3430_EN_IVA2_DPLL_MASK (0x7 << 0)
68 68
69/* CM_IDLEST_IVA2 */ 69/* CM_IDLEST_IVA2 */
70#define OMAP3430_ST_IVA2_SHIFT 0
70#define OMAP3430_ST_IVA2_MASK (1 << 0) 71#define OMAP3430_ST_IVA2_MASK (1 << 0)
71 72
72/* CM_IDLEST_PLL_IVA2 */ 73/* CM_IDLEST_PLL_IVA2 */
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
index 05fdebfaa195..330d4c6e746b 100644
--- a/arch/arm/mach-omap2/omap-wakeupgen.c
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -46,7 +46,7 @@
46static void __iomem *wakeupgen_base; 46static void __iomem *wakeupgen_base;
47static void __iomem *sar_base; 47static void __iomem *sar_base;
48static DEFINE_SPINLOCK(wakeupgen_lock); 48static DEFINE_SPINLOCK(wakeupgen_lock);
49static unsigned int irq_target_cpu[NR_IRQS]; 49static unsigned int irq_target_cpu[MAX_IRQS];
50static unsigned int irq_banks = MAX_NR_REG_BANKS; 50static unsigned int irq_banks = MAX_NR_REG_BANKS;
51static unsigned int max_irqs = MAX_IRQS; 51static unsigned int max_irqs = MAX_IRQS;
52static unsigned int omap_secure_apis; 52static unsigned int omap_secure_apis;
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 6ca8e519968d..37afbd173c2c 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1889,6 +1889,7 @@ static int _enable(struct omap_hwmod *oh)
1889 _enable_sysc(oh); 1889 _enable_sysc(oh);
1890 } 1890 }
1891 } else { 1891 } else {
1892 _omap4_disable_module(oh);
1892 _disable_clocks(oh); 1893 _disable_clocks(oh);
1893 pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n", 1894 pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n",
1894 oh->name, r); 1895 oh->name, r);
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index c9e38200216b..ce7e6068768f 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -100,9 +100,9 @@ static struct omap_hwmod omap3xxx_mpu_hwmod = {
100 100
101/* IVA2 (IVA2) */ 101/* IVA2 (IVA2) */
102static struct omap_hwmod_rst_info omap3xxx_iva_resets[] = { 102static struct omap_hwmod_rst_info omap3xxx_iva_resets[] = {
103 { .name = "logic", .rst_shift = 0 }, 103 { .name = "logic", .rst_shift = 0, .st_shift = 8 },
104 { .name = "seq0", .rst_shift = 1 }, 104 { .name = "seq0", .rst_shift = 1, .st_shift = 9 },
105 { .name = "seq1", .rst_shift = 2 }, 105 { .name = "seq1", .rst_shift = 2, .st_shift = 10 },
106}; 106};
107 107
108static struct omap_hwmod omap3xxx_iva_hwmod = { 108static struct omap_hwmod omap3xxx_iva_hwmod = {
@@ -112,6 +112,15 @@ static struct omap_hwmod omap3xxx_iva_hwmod = {
112 .rst_lines = omap3xxx_iva_resets, 112 .rst_lines = omap3xxx_iva_resets,
113 .rst_lines_cnt = ARRAY_SIZE(omap3xxx_iva_resets), 113 .rst_lines_cnt = ARRAY_SIZE(omap3xxx_iva_resets),
114 .main_clk = "iva2_ck", 114 .main_clk = "iva2_ck",
115 .prcm = {
116 .omap2 = {
117 .module_offs = OMAP3430_IVA2_MOD,
118 .prcm_reg_id = 1,
119 .module_bit = OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT,
120 .idlest_reg_id = 1,
121 .idlest_idle_bit = OMAP3430_ST_IVA2_SHIFT,
122 }
123 },
115}; 124};
116 125
117/* timer class */ 126/* timer class */
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 242aee498ceb..afb60917a948 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -4210,7 +4210,7 @@ static struct omap_hwmod_ocp_if omap44xx_dsp__iva = {
4210}; 4210};
4211 4211
4212/* dsp -> sl2if */ 4212/* dsp -> sl2if */
4213static struct omap_hwmod_ocp_if omap44xx_dsp__sl2if = { 4213static struct omap_hwmod_ocp_if __maybe_unused omap44xx_dsp__sl2if = {
4214 .master = &omap44xx_dsp_hwmod, 4214 .master = &omap44xx_dsp_hwmod,
4215 .slave = &omap44xx_sl2if_hwmod, 4215 .slave = &omap44xx_sl2if_hwmod,
4216 .clk = "dpll_iva_m5x2_ck", 4216 .clk = "dpll_iva_m5x2_ck",
@@ -4828,7 +4828,7 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iss = {
4828}; 4828};
4829 4829
4830/* iva -> sl2if */ 4830/* iva -> sl2if */
4831static struct omap_hwmod_ocp_if omap44xx_iva__sl2if = { 4831static struct omap_hwmod_ocp_if __maybe_unused omap44xx_iva__sl2if = {
4832 .master = &omap44xx_iva_hwmod, 4832 .master = &omap44xx_iva_hwmod,
4833 .slave = &omap44xx_sl2if_hwmod, 4833 .slave = &omap44xx_sl2if_hwmod,
4834 .clk = "dpll_iva_m5x2_ck", 4834 .clk = "dpll_iva_m5x2_ck",
@@ -5362,7 +5362,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_wkup__scrm = {
5362}; 5362};
5363 5363
5364/* l3_main_2 -> sl2if */ 5364/* l3_main_2 -> sl2if */
5365static struct omap_hwmod_ocp_if omap44xx_l3_main_2__sl2if = { 5365static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l3_main_2__sl2if = {
5366 .master = &omap44xx_l3_main_2_hwmod, 5366 .master = &omap44xx_l3_main_2_hwmod,
5367 .slave = &omap44xx_sl2if_hwmod, 5367 .slave = &omap44xx_sl2if_hwmod,
5368 .clk = "l3_div_ck", 5368 .clk = "l3_div_ck",
@@ -6032,7 +6032,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
6032 &omap44xx_l4_abe__dmic, 6032 &omap44xx_l4_abe__dmic,
6033 &omap44xx_l4_abe__dmic_dma, 6033 &omap44xx_l4_abe__dmic_dma,
6034 &omap44xx_dsp__iva, 6034 &omap44xx_dsp__iva,
6035 &omap44xx_dsp__sl2if, 6035 /* &omap44xx_dsp__sl2if, */
6036 &omap44xx_l4_cfg__dsp, 6036 &omap44xx_l4_cfg__dsp,
6037 &omap44xx_l3_main_2__dss, 6037 &omap44xx_l3_main_2__dss,
6038 &omap44xx_l4_per__dss, 6038 &omap44xx_l4_per__dss,
@@ -6068,7 +6068,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
6068 &omap44xx_l4_per__i2c4, 6068 &omap44xx_l4_per__i2c4,
6069 &omap44xx_l3_main_2__ipu, 6069 &omap44xx_l3_main_2__ipu,
6070 &omap44xx_l3_main_2__iss, 6070 &omap44xx_l3_main_2__iss,
6071 &omap44xx_iva__sl2if, 6071 /* &omap44xx_iva__sl2if, */
6072 &omap44xx_l3_main_2__iva, 6072 &omap44xx_l3_main_2__iva,
6073 &omap44xx_l4_wkup__kbd, 6073 &omap44xx_l4_wkup__kbd,
6074 &omap44xx_l4_cfg__mailbox, 6074 &omap44xx_l4_cfg__mailbox,
@@ -6099,7 +6099,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
6099 &omap44xx_l4_cfg__cm_core, 6099 &omap44xx_l4_cfg__cm_core,
6100 &omap44xx_l4_wkup__prm, 6100 &omap44xx_l4_wkup__prm,
6101 &omap44xx_l4_wkup__scrm, 6101 &omap44xx_l4_wkup__scrm,
6102 &omap44xx_l3_main_2__sl2if, 6102 /* &omap44xx_l3_main_2__sl2if, */
6103 &omap44xx_l4_abe__slimbus1, 6103 &omap44xx_l4_abe__slimbus1,
6104 &omap44xx_l4_abe__slimbus1_dma, 6104 &omap44xx_l4_abe__slimbus1_dma,
6105 &omap44xx_l4_per__slimbus2, 6105 &omap44xx_l4_per__slimbus2,
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 2ff6d41ec6c6..2ba4f57dda86 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -260,6 +260,7 @@ static u32 notrace dmtimer_read_sched_clock(void)
260 return 0; 260 return 0;
261} 261}
262 262
263#ifdef CONFIG_OMAP_32K_TIMER
263/* Setup free-running counter for clocksource */ 264/* Setup free-running counter for clocksource */
264static int __init omap2_sync32k_clocksource_init(void) 265static int __init omap2_sync32k_clocksource_init(void)
265{ 266{
@@ -299,6 +300,12 @@ static int __init omap2_sync32k_clocksource_init(void)
299 300
300 return ret; 301 return ret;
301} 302}
303#else
304static inline int omap2_sync32k_clocksource_init(void)
305{
306 return -ENODEV;
307}
308#endif
302 309
303static void __init omap2_gptimer_clocksource_init(int gptimer_id, 310static void __init omap2_gptimer_clocksource_init(int gptimer_id,
304 const char *fck_source) 311 const char *fck_source)
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c
index 410291c67666..a6cd14ab1e4e 100644
--- a/arch/arm/mach-orion5x/common.c
+++ b/arch/arm/mach-orion5x/common.c
@@ -204,6 +204,13 @@ void __init orion5x_wdt_init(void)
204void __init orion5x_init_early(void) 204void __init orion5x_init_early(void)
205{ 205{
206 orion_time_set_base(TIMER_VIRT_BASE); 206 orion_time_set_base(TIMER_VIRT_BASE);
207
208 /*
209 * Some Orion5x devices allocate their coherent buffers from atomic
210 * context. Increase size of atomic coherent pool to make sure such
211 * the allocations won't fail.
212 */
213 init_dma_coherent_pool_size(SZ_1M);
207} 214}
208 215
209int orion5x_tclk; 216int orion5x_tclk;
diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c
index 53b7ea92c32c..3b8a0171c3cb 100644
--- a/arch/arm/mach-shmobile/board-kzm9g.c
+++ b/arch/arm/mach-shmobile/board-kzm9g.c
@@ -346,11 +346,11 @@ static struct resource sh_mmcif_resources[] = {
346 .flags = IORESOURCE_MEM, 346 .flags = IORESOURCE_MEM,
347 }, 347 },
348 [1] = { 348 [1] = {
349 .start = gic_spi(141), 349 .start = gic_spi(140),
350 .flags = IORESOURCE_IRQ, 350 .flags = IORESOURCE_IRQ,
351 }, 351 },
352 [2] = { 352 [2] = {
353 .start = gic_spi(140), 353 .start = gic_spi(141),
354 .flags = IORESOURCE_IRQ, 354 .flags = IORESOURCE_IRQ,
355 }, 355 },
356}; 356};
diff --git a/arch/arm/mach-tegra/board-harmony-power.c b/arch/arm/mach-tegra/board-harmony-power.c
index b7344beec102..94486e7e9dfd 100644
--- a/arch/arm/mach-tegra/board-harmony-power.c
+++ b/arch/arm/mach-tegra/board-harmony-power.c
@@ -67,6 +67,13 @@ static struct regulator_init_data ldo0_data = {
67 }, \ 67 }, \
68 } 68 }
69 69
70static struct regulator_init_data sys_data = {
71 .supply_regulator = "vdd_5v0",
72 .constraints = {
73 .name = "vdd_sys",
74 },
75};
76
70HARMONY_REGULATOR_INIT(sm0, "vdd_sm0", "vdd_sys", 725, 1500, 1); 77HARMONY_REGULATOR_INIT(sm0, "vdd_sm0", "vdd_sys", 725, 1500, 1);
71HARMONY_REGULATOR_INIT(sm1, "vdd_sm1", "vdd_sys", 725, 1500, 1); 78HARMONY_REGULATOR_INIT(sm1, "vdd_sm1", "vdd_sys", 725, 1500, 1);
72HARMONY_REGULATOR_INIT(sm2, "vdd_sm2", "vdd_sys", 3000, 4550, 1); 79HARMONY_REGULATOR_INIT(sm2, "vdd_sm2", "vdd_sys", 3000, 4550, 1);
@@ -74,7 +81,7 @@ HARMONY_REGULATOR_INIT(ldo1, "vdd_ldo1", "vdd_sm2", 725, 1500, 1);
74HARMONY_REGULATOR_INIT(ldo2, "vdd_ldo2", "vdd_sm2", 725, 1500, 0); 81HARMONY_REGULATOR_INIT(ldo2, "vdd_ldo2", "vdd_sm2", 725, 1500, 0);
75HARMONY_REGULATOR_INIT(ldo3, "vdd_ldo3", "vdd_sm2", 1250, 3300, 1); 82HARMONY_REGULATOR_INIT(ldo3, "vdd_ldo3", "vdd_sm2", 1250, 3300, 1);
76HARMONY_REGULATOR_INIT(ldo4, "vdd_ldo4", "vdd_sm2", 1700, 2475, 1); 83HARMONY_REGULATOR_INIT(ldo4, "vdd_ldo4", "vdd_sm2", 1700, 2475, 1);
77HARMONY_REGULATOR_INIT(ldo5, "vdd_ldo5", NULL, 1250, 3300, 1); 84HARMONY_REGULATOR_INIT(ldo5, "vdd_ldo5", "vdd_sys", 1250, 3300, 1);
78HARMONY_REGULATOR_INIT(ldo6, "vdd_ldo6", "vdd_sm2", 1250, 3300, 0); 85HARMONY_REGULATOR_INIT(ldo6, "vdd_ldo6", "vdd_sm2", 1250, 3300, 0);
79HARMONY_REGULATOR_INIT(ldo7, "vdd_ldo7", "vdd_sm2", 1250, 3300, 0); 86HARMONY_REGULATOR_INIT(ldo7, "vdd_ldo7", "vdd_sm2", 1250, 3300, 0);
80HARMONY_REGULATOR_INIT(ldo8, "vdd_ldo8", "vdd_sm2", 1250, 3300, 0); 87HARMONY_REGULATOR_INIT(ldo8, "vdd_ldo8", "vdd_sm2", 1250, 3300, 0);
@@ -88,6 +95,7 @@ HARMONY_REGULATOR_INIT(ldo9, "vdd_ldo9", "vdd_sm2", 1250, 3300, 1);
88 } 95 }
89 96
90static struct tps6586x_subdev_info tps_devs[] = { 97static struct tps6586x_subdev_info tps_devs[] = {
98 TPS_REG(SYS, &sys_data),
91 TPS_REG(SM_0, &sm0_data), 99 TPS_REG(SM_0, &sm0_data),
92 TPS_REG(SM_1, &sm1_data), 100 TPS_REG(SM_1, &sm1_data),
93 TPS_REG(SM_2, &sm2_data), 101 TPS_REG(SM_2, &sm2_data),
@@ -120,7 +128,7 @@ static struct i2c_board_info __initdata harmony_regulators[] = {
120 128
121int __init harmony_regulator_init(void) 129int __init harmony_regulator_init(void)
122{ 130{
123 regulator_register_always_on(0, "vdd_sys", 131 regulator_register_always_on(0, "vdd_5v0",
124 NULL, 0, 5000000); 132 NULL, 0, 5000000);
125 133
126 if (machine_is_harmony()) { 134 if (machine_is_harmony()) {
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index 119bc52ab93e..4e07eec1270d 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -63,10 +63,11 @@ static int contextidr_notifier(struct notifier_block *unused, unsigned long cmd,
63 pid = task_pid_nr(thread->task) << ASID_BITS; 63 pid = task_pid_nr(thread->task) << ASID_BITS;
64 asm volatile( 64 asm volatile(
65 " mrc p15, 0, %0, c13, c0, 1\n" 65 " mrc p15, 0, %0, c13, c0, 1\n"
66 " bfi %1, %0, #0, %2\n" 66 " and %0, %0, %2\n"
67 " mcr p15, 0, %1, c13, c0, 1\n" 67 " orr %0, %0, %1\n"
68 " mcr p15, 0, %0, c13, c0, 1\n"
68 : "=r" (contextidr), "+r" (pid) 69 : "=r" (contextidr), "+r" (pid)
69 : "I" (ASID_BITS)); 70 : "I" (~ASID_MASK));
70 isb(); 71 isb();
71 72
72 return NOTIFY_OK; 73 return NOTIFY_OK;
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 051204fc4617..13f555d62491 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -346,6 +346,8 @@ static int __init atomic_pool_init(void)
346 (unsigned)pool->size / 1024); 346 (unsigned)pool->size / 1024);
347 return 0; 347 return 0;
348 } 348 }
349
350 kfree(pages);
349no_pages: 351no_pages:
350 kfree(bitmap); 352 kfree(bitmap);
351no_bitmap: 353no_bitmap:
@@ -489,7 +491,7 @@ static bool __in_atomic_pool(void *start, size_t size)
489 void *pool_start = pool->vaddr; 491 void *pool_start = pool->vaddr;
490 void *pool_end = pool->vaddr + pool->size; 492 void *pool_end = pool->vaddr + pool->size;
491 493
492 if (start < pool_start || start > pool_end) 494 if (start < pool_start || start >= pool_end)
493 return false; 495 return false;
494 496
495 if (end <= pool_end) 497 if (end <= pool_end)
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index 6776160618ef..a8ee92da3544 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -55,6 +55,9 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
55/* permanent static mappings from iotable_init() */ 55/* permanent static mappings from iotable_init() */
56#define VM_ARM_STATIC_MAPPING 0x40000000 56#define VM_ARM_STATIC_MAPPING 0x40000000
57 57
58/* empty mapping */
59#define VM_ARM_EMPTY_MAPPING 0x20000000
60
58/* mapping type (attributes) for permanent static mappings */ 61/* mapping type (attributes) for permanent static mappings */
59#define VM_ARM_MTYPE(mt) ((mt) << 20) 62#define VM_ARM_MTYPE(mt) ((mt) << 20)
60#define VM_ARM_MTYPE_MASK (0x1f << 20) 63#define VM_ARM_MTYPE_MASK (0x1f << 20)
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 4c2d0451e84a..c2fa21d0103e 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -807,7 +807,7 @@ static void __init pmd_empty_section_gap(unsigned long addr)
807 vm = early_alloc_aligned(sizeof(*vm), __alignof__(*vm)); 807 vm = early_alloc_aligned(sizeof(*vm), __alignof__(*vm));
808 vm->addr = (void *)addr; 808 vm->addr = (void *)addr;
809 vm->size = SECTION_SIZE; 809 vm->size = SECTION_SIZE;
810 vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING; 810 vm->flags = VM_IOREMAP | VM_ARM_EMPTY_MAPPING;
811 vm->caller = pmd_empty_section_gap; 811 vm->caller = pmd_empty_section_gap;
812 vm_area_add_early(vm); 812 vm_area_add_early(vm);
813} 813}
@@ -820,7 +820,7 @@ static void __init fill_pmd_gaps(void)
820 820
821 /* we're still single threaded hence no lock needed here */ 821 /* we're still single threaded hence no lock needed here */
822 for (vm = vmlist; vm; vm = vm->next) { 822 for (vm = vmlist; vm; vm = vm->next) {
823 if (!(vm->flags & VM_ARM_STATIC_MAPPING)) 823 if (!(vm->flags & (VM_ARM_STATIC_MAPPING | VM_ARM_EMPTY_MAPPING)))
824 continue; 824 continue;
825 addr = (unsigned long)vm->addr; 825 addr = (unsigned long)vm->addr;
826 if (addr < next) 826 if (addr < next)
@@ -961,8 +961,8 @@ void __init sanity_check_meminfo(void)
961 * Check whether this memory bank would partially overlap 961 * Check whether this memory bank would partially overlap
962 * the vmalloc area. 962 * the vmalloc area.
963 */ 963 */
964 if (__va(bank->start + bank->size) > vmalloc_min || 964 if (__va(bank->start + bank->size - 1) >= vmalloc_min ||
965 __va(bank->start + bank->size) < __va(bank->start)) { 965 __va(bank->start + bank->size - 1) <= __va(bank->start)) {
966 unsigned long newsize = vmalloc_min - __va(bank->start); 966 unsigned long newsize = vmalloc_min - __va(bank->start);
967 printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx " 967 printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx "
968 "to -%.8llx (vmalloc region overlap).\n", 968 "to -%.8llx (vmalloc region overlap).\n",
diff --git a/arch/arm/plat-mxc/include/mach/mx25.h b/arch/arm/plat-mxc/include/mach/mx25.h
index 627d94f1b010..ec466400a200 100644
--- a/arch/arm/plat-mxc/include/mach/mx25.h
+++ b/arch/arm/plat-mxc/include/mach/mx25.h
@@ -98,6 +98,7 @@
98#define MX25_INT_UART1 (NR_IRQS_LEGACY + 45) 98#define MX25_INT_UART1 (NR_IRQS_LEGACY + 45)
99#define MX25_INT_GPIO2 (NR_IRQS_LEGACY + 51) 99#define MX25_INT_GPIO2 (NR_IRQS_LEGACY + 51)
100#define MX25_INT_GPIO1 (NR_IRQS_LEGACY + 52) 100#define MX25_INT_GPIO1 (NR_IRQS_LEGACY + 52)
101#define MX25_INT_GPT1 (NR_IRQS_LEGACY + 54)
101#define MX25_INT_FEC (NR_IRQS_LEGACY + 57) 102#define MX25_INT_FEC (NR_IRQS_LEGACY + 57)
102 103
103#define MX25_DMA_REQ_SSI2_RX1 22 104#define MX25_DMA_REQ_SSI2_RX1 22
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 766181cb5c95..024f3b08db29 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -68,6 +68,7 @@
68 68
69static unsigned long omap_sram_start; 69static unsigned long omap_sram_start;
70static void __iomem *omap_sram_base; 70static void __iomem *omap_sram_base;
71static unsigned long omap_sram_skip;
71static unsigned long omap_sram_size; 72static unsigned long omap_sram_size;
72static void __iomem *omap_sram_ceil; 73static void __iomem *omap_sram_ceil;
73 74
@@ -106,6 +107,7 @@ static int is_sram_locked(void)
106 */ 107 */
107static void __init omap_detect_sram(void) 108static void __init omap_detect_sram(void)
108{ 109{
110 omap_sram_skip = SRAM_BOOTLOADER_SZ;
109 if (cpu_class_is_omap2()) { 111 if (cpu_class_is_omap2()) {
110 if (is_sram_locked()) { 112 if (is_sram_locked()) {
111 if (cpu_is_omap34xx()) { 113 if (cpu_is_omap34xx()) {
@@ -113,6 +115,7 @@ static void __init omap_detect_sram(void)
113 if ((omap_type() == OMAP2_DEVICE_TYPE_EMU) || 115 if ((omap_type() == OMAP2_DEVICE_TYPE_EMU) ||
114 (omap_type() == OMAP2_DEVICE_TYPE_SEC)) { 116 (omap_type() == OMAP2_DEVICE_TYPE_SEC)) {
115 omap_sram_size = 0x7000; /* 28K */ 117 omap_sram_size = 0x7000; /* 28K */
118 omap_sram_skip += SZ_16K;
116 } else { 119 } else {
117 omap_sram_size = 0x8000; /* 32K */ 120 omap_sram_size = 0x8000; /* 32K */
118 } 121 }
@@ -175,8 +178,10 @@ static void __init omap_map_sram(void)
175 return; 178 return;
176 179
177#ifdef CONFIG_OMAP4_ERRATA_I688 180#ifdef CONFIG_OMAP4_ERRATA_I688
181 if (cpu_is_omap44xx()) {
178 omap_sram_start += PAGE_SIZE; 182 omap_sram_start += PAGE_SIZE;
179 omap_sram_size -= SZ_16K; 183 omap_sram_size -= SZ_16K;
184 }
180#endif 185#endif
181 if (cpu_is_omap34xx()) { 186 if (cpu_is_omap34xx()) {
182 /* 187 /*
@@ -203,8 +208,8 @@ static void __init omap_map_sram(void)
203 * Looks like we need to preserve some bootloader code at the 208 * Looks like we need to preserve some bootloader code at the
204 * beginning of SRAM for jumping to flash for reboot to work... 209 * beginning of SRAM for jumping to flash for reboot to work...
205 */ 210 */
206 memset_io(omap_sram_base + SRAM_BOOTLOADER_SZ, 0, 211 memset_io(omap_sram_base + omap_sram_skip, 0,
207 omap_sram_size - SRAM_BOOTLOADER_SZ); 212 omap_sram_size - omap_sram_skip);
208} 213}
209 214
210/* 215/*
@@ -218,7 +223,7 @@ void *omap_sram_push_address(unsigned long size)
218{ 223{
219 unsigned long available, new_ceil = (unsigned long)omap_sram_ceil; 224 unsigned long available, new_ceil = (unsigned long)omap_sram_ceil;
220 225
221 available = omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ); 226 available = omap_sram_ceil - (omap_sram_base + omap_sram_skip);
222 227
223 if (size > available) { 228 if (size > available) {
224 pr_err("Not enough space in SRAM\n"); 229 pr_err("Not enough space in SRAM\n");
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
index 65c5eca475e7..d1116e2dfbea 100644
--- a/arch/arm/plat-samsung/clock.c
+++ b/arch/arm/plat-samsung/clock.c
@@ -144,6 +144,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
144 144
145int clk_set_rate(struct clk *clk, unsigned long rate) 145int clk_set_rate(struct clk *clk, unsigned long rate)
146{ 146{
147 unsigned long flags;
147 int ret; 148 int ret;
148 149
149 if (IS_ERR(clk)) 150 if (IS_ERR(clk))
@@ -159,9 +160,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
159 if (clk->ops == NULL || clk->ops->set_rate == NULL) 160 if (clk->ops == NULL || clk->ops->set_rate == NULL)
160 return -EINVAL; 161 return -EINVAL;
161 162
162 spin_lock(&clocks_lock); 163 spin_lock_irqsave(&clocks_lock, flags);
163 ret = (clk->ops->set_rate)(clk, rate); 164 ret = (clk->ops->set_rate)(clk, rate);
164 spin_unlock(&clocks_lock); 165 spin_unlock_irqrestore(&clocks_lock, flags);
165 166
166 return ret; 167 return ret;
167} 168}
@@ -173,17 +174,18 @@ struct clk *clk_get_parent(struct clk *clk)
173 174
174int clk_set_parent(struct clk *clk, struct clk *parent) 175int clk_set_parent(struct clk *clk, struct clk *parent)
175{ 176{
177 unsigned long flags;
176 int ret = 0; 178 int ret = 0;
177 179
178 if (IS_ERR(clk)) 180 if (IS_ERR(clk))
179 return -EINVAL; 181 return -EINVAL;
180 182
181 spin_lock(&clocks_lock); 183 spin_lock_irqsave(&clocks_lock, flags);
182 184
183 if (clk->ops && clk->ops->set_parent) 185 if (clk->ops && clk->ops->set_parent)
184 ret = (clk->ops->set_parent)(clk, parent); 186 ret = (clk->ops->set_parent)(clk, parent);
185 187
186 spin_unlock(&clocks_lock); 188 spin_unlock_irqrestore(&clocks_lock, flags);
187 189
188 return ret; 190 return ret;
189} 191}
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
new file mode 100644
index 000000000000..767ba5685454
--- /dev/null
+++ b/arch/arm64/Kconfig
@@ -0,0 +1,222 @@
1config ARM64
2 def_bool y
3 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
4 select GENERIC_CLOCKEVENTS
5 select GENERIC_HARDIRQS_NO_DEPRECATED
6 select GENERIC_IOMAP
7 select GENERIC_IRQ_PROBE
8 select GENERIC_IRQ_SHOW
9 select GENERIC_SMP_IDLE_THREAD
10 select GENERIC_TIME_VSYSCALL
11 select HARDIRQS_SW_RESEND
12 select HAVE_ARCH_TRACEHOOK
13 select HAVE_DMA_API_DEBUG
14 select HAVE_DMA_ATTRS
15 select HAVE_GENERIC_DMA_COHERENT
16 select HAVE_GENERIC_HARDIRQS
17 select HAVE_HW_BREAKPOINT if PERF_EVENTS
18 select HAVE_IRQ_WORK
19 select HAVE_MEMBLOCK
20 select HAVE_PERF_EVENTS
21 select HAVE_SPARSE_IRQ
22 select IRQ_DOMAIN
23 select NO_BOOTMEM
24 select OF
25 select OF_EARLY_FLATTREE
26 select PERF_USE_VMALLOC
27 select RTC_LIB
28 select SPARSE_IRQ
29 help
30 ARM 64-bit (AArch64) Linux support.
31
32config 64BIT
33 def_bool y
34
35config ARCH_PHYS_ADDR_T_64BIT
36 def_bool y
37
38config MMU
39 def_bool y
40
41config NO_IOPORT
42 def_bool y
43
44config STACKTRACE_SUPPORT
45 def_bool y
46
47config LOCKDEP_SUPPORT
48 def_bool y
49
50config TRACE_IRQFLAGS_SUPPORT
51 def_bool y
52
53config GENERIC_LOCKBREAK
54 def_bool y
55 depends on SMP && PREEMPT
56
57config RWSEM_GENERIC_SPINLOCK
58 def_bool y
59
60config GENERIC_HWEIGHT
61 def_bool y
62
63config GENERIC_CSUM
64 def_bool y
65
66config GENERIC_CALIBRATE_DELAY
67 def_bool y
68
69config ZONE_DMA32
70 def_bool y
71
72config ARCH_DMA_ADDR_T_64BIT
73 def_bool y
74
75config NEED_DMA_MAP_STATE
76 def_bool y
77
78config NEED_SG_DMA_LENGTH
79 def_bool y
80
81config SWIOTLB
82 def_bool y
83
84config IOMMU_HELPER
85 def_bool SWIOTLB
86
87source "init/Kconfig"
88
89source "kernel/Kconfig.freezer"
90
91menu "System Type"
92
93endmenu
94
95menu "Bus support"
96
97config ARM_AMBA
98 bool
99
100endmenu
101
102menu "Kernel Features"
103
104source "kernel/time/Kconfig"
105
106config ARM64_64K_PAGES
107 bool "Enable 64KB pages support"
108 help
109 This feature enables 64KB pages support (4KB by default)
110 allowing only two levels of page tables and faster TLB
111 look-up. AArch32 emulation is not available when this feature
112 is enabled.
113
114config SMP
115 bool "Symmetric Multi-Processing"
116 select USE_GENERIC_SMP_HELPERS
117 help
118 This enables support for systems with more than one CPU. If
119 you say N here, the kernel will run on single and
120 multiprocessor machines, but will use only one CPU of a
121 multiprocessor machine. If you say Y here, the kernel will run
122 on many, but not all, single processor machines. On a single
123 processor machine, the kernel will run faster if you say N
124 here.
125
126 If you don't know what to do here, say N.
127
128config NR_CPUS
129 int "Maximum number of CPUs (2-32)"
130 range 2 32
131 depends on SMP
132 default "4"
133
134source kernel/Kconfig.preempt
135
136config HZ
137 int
138 default 100
139
140config ARCH_HAS_HOLES_MEMORYMODEL
141 def_bool y if SPARSEMEM
142
143config ARCH_SPARSEMEM_ENABLE
144 def_bool y
145 select SPARSEMEM_VMEMMAP_ENABLE
146
147config ARCH_SPARSEMEM_DEFAULT
148 def_bool ARCH_SPARSEMEM_ENABLE
149
150config ARCH_SELECT_MEMORY_MODEL
151 def_bool ARCH_SPARSEMEM_ENABLE
152
153config HAVE_ARCH_PFN_VALID
154 def_bool ARCH_HAS_HOLES_MEMORYMODEL || !SPARSEMEM
155
156config HW_PERF_EVENTS
157 bool "Enable hardware performance counter support for perf events"
158 depends on PERF_EVENTS
159 default y
160 help
161 Enable hardware performance counter support for perf events. If
162 disabled, perf events will use software events only.
163
164source "mm/Kconfig"
165
166endmenu
167
168menu "Boot options"
169
170config CMDLINE
171 string "Default kernel command string"
172 default ""
173 help
174 Provide a set of default command-line options at build time by
175 entering them here. As a minimum, you should specify the the
176 root device (e.g. root=/dev/nfs).
177
178config CMDLINE_FORCE
179 bool "Always use the default kernel command string"
180 help
181 Always use the default kernel command string, even if the boot
182 loader passes other arguments to the kernel.
183 This is useful if you cannot or don't want to change the
184 command-line options your boot loader passes to the kernel.
185
186endmenu
187
188menu "Userspace binary formats"
189
190source "fs/Kconfig.binfmt"
191
192config COMPAT
193 bool "Kernel support for 32-bit EL0"
194 depends on !ARM64_64K_PAGES
195 select COMPAT_BINFMT_ELF
196 help
197 This option enables support for a 32-bit EL0 running under a 64-bit
198 kernel at EL1. AArch32-specific components such as system calls,
199 the user helper functions, VFP support and the ptrace interface are
200 handled appropriately by the kernel.
201
202 If you want to execute 32-bit userspace applications, say Y.
203
204config SYSVIPC_COMPAT
205 def_bool y
206 depends on COMPAT && SYSVIPC
207
208endmenu
209
210source "net/Kconfig"
211
212source "drivers/Kconfig"
213
214source "fs/Kconfig"
215
216source "arch/arm64/Kconfig.debug"
217
218source "security/Kconfig"
219
220source "crypto/Kconfig"
221
222source "lib/Kconfig"
diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
new file mode 100644
index 000000000000..d7553f2bda66
--- /dev/null
+++ b/arch/arm64/Kconfig.debug
@@ -0,0 +1,27 @@
1menu "Kernel hacking"
2
3source "lib/Kconfig.debug"
4
5config FRAME_POINTER
6 bool
7 default y
8
9config DEBUG_ERRORS
10 bool "Verbose kernel error messages"
11 depends on DEBUG_KERNEL
12 help
13 This option controls verbose debugging information which can be
14 printed when the kernel detects an internal error. This debugging
15 information is useful to kernel hackers when tracking down problems,
16 but mostly meaningless to other people. It's safe to say Y unless
17 you are concerned with the code size or don't want to see these
18 messages.
19
20config DEBUG_STACK_USAGE
21 bool "Enable stack utilization instrumentation"
22 depends on DEBUG_KERNEL
23 help
24 Enables the display of the minimum amount of free stack which each
25 task has ever had available in the sysrq-T output.
26
27endmenu
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
new file mode 100644
index 000000000000..364191f3be43
--- /dev/null
+++ b/arch/arm64/Makefile
@@ -0,0 +1,71 @@
1#
2# arch/arm64/Makefile
3#
4# This file is included by the global makefile so that you can add your own
5# architecture-specific flags and dependencies.
6#
7# This file is subject to the terms and conditions of the GNU General Public
8# License. See the file "COPYING" in the main directory of this archive
9# for more details.
10#
11# Copyright (C) 1995-2001 by Russell King
12
13LDFLAGS_vmlinux :=-p --no-undefined -X
14CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET)
15OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
16GZFLAGS :=-9
17
18LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
19
20KBUILD_DEFCONFIG := defconfig
21
22KBUILD_CFLAGS += -mgeneral-regs-only
23KBUILD_CPPFLAGS += -mlittle-endian
24AS += -EL
25LD += -EL
26
27comma = ,
28
29CHECKFLAGS += -D__aarch64__
30
31# Default value
32head-y := arch/arm64/kernel/head.o
33
34# The byte offset of the kernel image in RAM from the start of RAM.
35TEXT_OFFSET := 0x00080000
36
37export TEXT_OFFSET GZFLAGS
38
39core-y += arch/arm64/kernel/ arch/arm64/mm/
40libs-y := arch/arm64/lib/ $(libs-y)
41libs-y += $(LIBGCC)
42
43# Default target when executing plain make
44KBUILD_IMAGE := Image.gz
45
46all: $(KBUILD_IMAGE)
47
48boot := arch/arm64/boot
49
50Image Image.gz: vmlinux
51 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
52
53zinstall install: vmlinux
54 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
55
56%.dtb:
57 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
58
59# We use MRPROPER_FILES and CLEAN_FILES now
60archclean:
61 $(Q)$(MAKE) $(clean)=$(boot)
62
63define archhelp
64 echo '* Image.gz - Compressed kernel image (arch/$(ARCH)/boot/Image.gz)'
65 echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
66 echo ' install - Install uncompressed kernel'
67 echo ' zinstall - Install compressed kernel'
68 echo ' Install using (your) ~/bin/installkernel or'
69 echo ' (distribution) /sbin/installkernel or'
70 echo ' install to $$(INSTALL_PATH) and run lilo'
71endef
diff --git a/arch/arm64/boot/.gitignore b/arch/arm64/boot/.gitignore
new file mode 100644
index 000000000000..8dab0bb6ae66
--- /dev/null
+++ b/arch/arm64/boot/.gitignore
@@ -0,0 +1,2 @@
1Image
2Image.gz
diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile
new file mode 100644
index 000000000000..eca209b2b0bf
--- /dev/null
+++ b/arch/arm64/boot/Makefile
@@ -0,0 +1,36 @@
1#
2# arch/arm64/boot/Makefile
3#
4# This file is included by the global makefile so that you can add your own
5# architecture-specific flags and dependencies.
6#
7# This file is subject to the terms and conditions of the GNU General Public
8# License. See the file "COPYING" in the main directory of this archive
9# for more details.
10#
11# Copyright (C) 2012, ARM Ltd.
12# Author: Will Deacon <will.deacon@arm.com>
13#
14# Based on the ia64 boot/Makefile.
15#
16
17targets := Image Image.gz
18
19$(obj)/Image: vmlinux FORCE
20 $(call if_changed,objcopy)
21
22$(obj)/Image.gz: $(obj)/Image FORCE
23 $(call if_changed,gzip)
24
25$(obj)/%.dtb: $(src)/dts/%.dts
26 $(call cmd,dtc)
27
28install: $(obj)/Image
29 $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
30 $(obj)/Image System.map "$(INSTALL_PATH)"
31
32zinstall: $(obj)/Image.gz
33 $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
34 $(obj)/Image.gz System.map "$(INSTALL_PATH)"
35
36clean-files += *.dtb
diff --git a/arch/arm64/boot/install.sh b/arch/arm64/boot/install.sh
new file mode 100644
index 000000000000..12ed78aa6f0c
--- /dev/null
+++ b/arch/arm64/boot/install.sh
@@ -0,0 +1,46 @@
1#!/bin/sh
2#
3# arch/arm64/boot/install.sh
4#
5# This file is subject to the terms and conditions of the GNU General Public
6# License. See the file "COPYING" in the main directory of this archive
7# for more details.
8#
9# Copyright (C) 1995 by Linus Torvalds
10#
11# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
12# Adapted from code in arch/i386/boot/install.sh by Russell King
13#
14# "make install" script for the AArch64 Linux port
15#
16# Arguments:
17# $1 - kernel version
18# $2 - kernel image file
19# $3 - kernel map file
20# $4 - default install path (blank if root directory)
21#
22
23# User may have a custom install script
24if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
25if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
26
27if [ "$(basename $2)" = "Image.gz" ]; then
28# Compressed install
29 echo "Installing compressed kernel"
30 base=vmlinuz
31else
32# Normal install
33 echo "Installing normal kernel"
34 base=vmlinux
35fi
36
37if [ -f $4/$base-$1 ]; then
38 mv $4/$base-$1 $4/$base-$1.old
39fi
40cat $2 > $4/$base-$1
41
42# Install system map file
43if [ -f $4/System.map-$1 ]; then
44 mv $4/System.map-$1 $4/System.map-$1.old
45fi
46cp $3 $4/System.map-$1
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
new file mode 100644
index 000000000000..9212c7880da7
--- /dev/null
+++ b/arch/arm64/configs/defconfig
@@ -0,0 +1,85 @@
1CONFIG_EXPERIMENTAL=y
2# CONFIG_LOCALVERSION_AUTO is not set
3# CONFIG_SWAP is not set
4CONFIG_SYSVIPC=y
5CONFIG_POSIX_MQUEUE=y
6CONFIG_BSD_PROCESS_ACCT=y
7CONFIG_BSD_PROCESS_ACCT_V3=y
8CONFIG_NO_HZ=y
9CONFIG_HIGH_RES_TIMERS=y
10CONFIG_IKCONFIG=y
11CONFIG_IKCONFIG_PROC=y
12CONFIG_LOG_BUF_SHIFT=14
13# CONFIG_UTS_NS is not set
14# CONFIG_IPC_NS is not set
15# CONFIG_PID_NS is not set
16# CONFIG_NET_NS is not set
17CONFIG_SCHED_AUTOGROUP=y
18CONFIG_BLK_DEV_INITRD=y
19CONFIG_KALLSYMS_ALL=y
20# CONFIG_COMPAT_BRK is not set
21CONFIG_PROFILING=y
22CONFIG_MODULES=y
23CONFIG_MODULE_UNLOAD=y
24# CONFIG_BLK_DEV_BSG is not set
25# CONFIG_IOSCHED_DEADLINE is not set
26CONFIG_SMP=y
27CONFIG_PREEMPT_VOLUNTARY=y
28CONFIG_CMDLINE="console=ttyAMA0"
29# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
30CONFIG_COMPAT=y
31CONFIG_NET=y
32CONFIG_PACKET=y
33CONFIG_UNIX=y
34CONFIG_INET=y
35CONFIG_IP_PNP=y
36CONFIG_IP_PNP_DHCP=y
37CONFIG_IP_PNP_BOOTP=y
38# CONFIG_INET_LRO is not set
39# CONFIG_IPV6 is not set
40# CONFIG_WIRELESS is not set
41CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
42CONFIG_DEVTMPFS=y
43# CONFIG_BLK_DEV is not set
44CONFIG_SCSI=y
45# CONFIG_SCSI_PROC_FS is not set
46CONFIG_BLK_DEV_SD=y
47# CONFIG_SCSI_LOWLEVEL is not set
48CONFIG_NETDEVICES=y
49CONFIG_MII=y
50# CONFIG_WLAN is not set
51CONFIG_INPUT_EVDEV=y
52# CONFIG_SERIO_I8042 is not set
53# CONFIG_SERIO_SERPORT is not set
54CONFIG_LEGACY_PTY_COUNT=16
55# CONFIG_HW_RANDOM is not set
56# CONFIG_HWMON is not set
57CONFIG_FB=y
58# CONFIG_VGA_CONSOLE is not set
59CONFIG_FRAMEBUFFER_CONSOLE=y
60CONFIG_LOGO=y
61# CONFIG_LOGO_LINUX_MONO is not set
62# CONFIG_LOGO_LINUX_VGA16 is not set
63# CONFIG_USB_SUPPORT is not set
64# CONFIG_IOMMU_SUPPORT is not set
65CONFIG_EXT2_FS=y
66CONFIG_EXT3_FS=y
67# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
68# CONFIG_EXT3_FS_XATTR is not set
69CONFIG_FUSE_FS=y
70CONFIG_CUSE=y
71CONFIG_VFAT_FS=y
72CONFIG_TMPFS=y
73# CONFIG_MISC_FILESYSTEMS is not set
74CONFIG_NFS_FS=y
75CONFIG_ROOT_NFS=y
76CONFIG_NLS_CODEPAGE_437=y
77CONFIG_NLS_ISO8859_1=y
78CONFIG_MAGIC_SYSRQ=y
79CONFIG_DEBUG_FS=y
80CONFIG_DEBUG_KERNEL=y
81# CONFIG_SCHED_DEBUG is not set
82CONFIG_DEBUG_INFO=y
83# CONFIG_FTRACE is not set
84CONFIG_ATOMIC64_SELFTEST=y
85CONFIG_DEBUG_ERRORS=y
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
new file mode 100644
index 000000000000..35924a542d43
--- /dev/null
+++ b/arch/arm64/include/asm/Kbuild
@@ -0,0 +1,51 @@
1include include/asm-generic/Kbuild.asm
2
3header-y += hwcap.h
4
5generic-y += bug.h
6generic-y += bugs.h
7generic-y += checksum.h
8generic-y += cputime.h
9generic-y += current.h
10generic-y += delay.h
11generic-y += div64.h
12generic-y += dma.h
13generic-y += emergency-restart.h
14generic-y += errno.h
15generic-y += ftrace.h
16generic-y += hw_irq.h
17generic-y += ioctl.h
18generic-y += ioctls.h
19generic-y += ipcbuf.h
20generic-y += irq_regs.h
21generic-y += kdebug.h
22generic-y += kmap_types.h
23generic-y += linkage.h
24generic-y += local.h
25generic-y += local64.h
26generic-y += mman.h
27generic-y += msgbuf.h
28generic-y += mutex.h
29generic-y += pci.h
30generic-y += percpu.h
31generic-y += poll.h
32generic-y += posix_types.h
33generic-y += resource.h
34generic-y += scatterlist.h
35generic-y += sections.h
36generic-y += segment.h
37generic-y += sembuf.h
38generic-y += serial.h
39generic-y += shmbuf.h
40generic-y += sizes.h
41generic-y += socket.h
42generic-y += sockios.h
43generic-y += string.h
44generic-y += switch_to.h
45generic-y += swab.h
46generic-y += termbits.h
47generic-y += termios.h
48generic-y += topology.h
49generic-y += types.h
50generic-y += unaligned.h
51generic-y += user.h
diff --git a/arch/arm64/include/asm/arm_generic.h b/arch/arm64/include/asm/arm_generic.h
new file mode 100644
index 000000000000..e4cec9d30f27
--- /dev/null
+++ b/arch/arm64/include/asm/arm_generic.h
@@ -0,0 +1,100 @@
1/*
2 * arch/arm64/include/asm/arm_generic.h
3 *
4 * Copyright (C) 2012 ARM Ltd.
5 * Author: Marc Zyngier <marc.zyngier@arm.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef __ASM_ARM_GENERIC_H
20#define __ASM_ARM_GENERIC_H
21
22#include <linux/clocksource.h>
23
24#define ARCH_TIMER_CTRL_ENABLE (1 << 0)
25#define ARCH_TIMER_CTRL_IMASK (1 << 1)
26#define ARCH_TIMER_CTRL_ISTATUS (1 << 2)
27
28#define ARCH_TIMER_REG_CTRL 0
29#define ARCH_TIMER_REG_FREQ 1
30#define ARCH_TIMER_REG_TVAL 2
31
32static inline void arch_timer_reg_write(int reg, u32 val)
33{
34 switch (reg) {
35 case ARCH_TIMER_REG_CTRL:
36 asm volatile("msr cntp_ctl_el0, %0" : : "r" (val));
37 break;
38 case ARCH_TIMER_REG_TVAL:
39 asm volatile("msr cntp_tval_el0, %0" : : "r" (val));
40 break;
41 default:
42 BUILD_BUG();
43 }
44
45 isb();
46}
47
48static inline u32 arch_timer_reg_read(int reg)
49{
50 u32 val;
51
52 switch (reg) {
53 case ARCH_TIMER_REG_CTRL:
54 asm volatile("mrs %0, cntp_ctl_el0" : "=r" (val));
55 break;
56 case ARCH_TIMER_REG_FREQ:
57 asm volatile("mrs %0, cntfrq_el0" : "=r" (val));
58 break;
59 case ARCH_TIMER_REG_TVAL:
60 asm volatile("mrs %0, cntp_tval_el0" : "=r" (val));
61 break;
62 default:
63 BUILD_BUG();
64 }
65
66 return val;
67}
68
69static inline void __cpuinit arch_counter_enable_user_access(void)
70{
71 u32 cntkctl;
72
73 /* Disable user access to the timers and the virtual counter. */
74 asm volatile("mrs %0, cntkctl_el1" : "=r" (cntkctl));
75 cntkctl &= ~((3 << 8) | (1 << 1));
76
77 /* Enable user access to the physical counter and frequency. */
78 cntkctl |= 1;
79 asm volatile("msr cntkctl_el1, %0" : : "r" (cntkctl));
80}
81
82static inline cycle_t arch_counter_get_cntpct(void)
83{
84 cycle_t cval;
85
86 asm volatile("mrs %0, cntpct_el0" : "=r" (cval));
87
88 return cval;
89}
90
91static inline cycle_t arch_counter_get_cntvct(void)
92{
93 cycle_t cval;
94
95 asm volatile("mrs %0, cntvct_el0" : "=r" (cval));
96
97 return cval;
98}
99
100#endif
diff --git a/arch/arm64/include/asm/asm-offsets.h b/arch/arm64/include/asm/asm-offsets.h
new file mode 100644
index 000000000000..d370ee36a182
--- /dev/null
+++ b/arch/arm64/include/asm/asm-offsets.h
@@ -0,0 +1 @@
#include <generated/asm-offsets.h>
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
new file mode 100644
index 000000000000..da2a13e8f1e6
--- /dev/null
+++ b/arch/arm64/include/asm/assembler.h
@@ -0,0 +1,109 @@
1/*
2 * Based on arch/arm/include/asm/assembler.h
3 *
4 * Copyright (C) 1996-2000 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef __ASSEMBLY__
20#error "Only include this from assembly code"
21#endif
22
23#include <asm/ptrace.h>
24
25/*
26 * Stack pushing/popping (register pairs only). Equivalent to store decrement
27 * before, load increment after.
28 */
29 .macro push, xreg1, xreg2
30 stp \xreg1, \xreg2, [sp, #-16]!
31 .endm
32
33 .macro pop, xreg1, xreg2
34 ldp \xreg1, \xreg2, [sp], #16
35 .endm
36
37/*
38 * Enable and disable interrupts.
39 */
40 .macro disable_irq
41 msr daifset, #2
42 .endm
43
44 .macro enable_irq
45 msr daifclr, #2
46 .endm
47
48/*
49 * Save/disable and restore interrupts.
50 */
51 .macro save_and_disable_irqs, olddaif
52 mrs \olddaif, daif
53 disable_irq
54 .endm
55
56 .macro restore_irqs, olddaif
57 msr daif, \olddaif
58 .endm
59
60/*
61 * Enable and disable debug exceptions.
62 */
63 .macro disable_dbg
64 msr daifset, #8
65 .endm
66
67 .macro enable_dbg
68 msr daifclr, #8
69 .endm
70
71 .macro disable_step, tmp
72 mrs \tmp, mdscr_el1
73 bic \tmp, \tmp, #1
74 msr mdscr_el1, \tmp
75 .endm
76
77 .macro enable_step, tmp
78 mrs \tmp, mdscr_el1
79 orr \tmp, \tmp, #1
80 msr mdscr_el1, \tmp
81 .endm
82
83 .macro enable_dbg_if_not_stepping, tmp
84 mrs \tmp, mdscr_el1
85 tbnz \tmp, #1, 9990f
86 enable_dbg
879990:
88 .endm
89
90/*
91 * SMP data memory barrier
92 */
93 .macro smp_dmb, opt
94#ifdef CONFIG_SMP
95 dmb \opt
96#endif
97 .endm
98
99#define USER(l, x...) \
1009999: x; \
101 .section __ex_table,"a"; \
102 .align 3; \
103 .quad 9999b,l; \
104 .previous
105
106/*
107 * Register aliases.
108 */
109lr .req x30 // link register
diff --git a/arch/arm64/include/asm/atomic.h b/arch/arm64/include/asm/atomic.h
new file mode 100644
index 000000000000..407717ba060e
--- /dev/null
+++ b/arch/arm64/include/asm/atomic.h
@@ -0,0 +1,305 @@
1/*
2 * Based on arch/arm/include/asm/atomic.h
3 *
4 * Copyright (C) 1996 Russell King.
5 * Copyright (C) 2002 Deep Blue Solutions Ltd.
6 * Copyright (C) 2012 ARM Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20#ifndef __ASM_ATOMIC_H
21#define __ASM_ATOMIC_H
22
23#include <linux/compiler.h>
24#include <linux/types.h>
25
26#include <asm/barrier.h>
27#include <asm/cmpxchg.h>
28
29#define ATOMIC_INIT(i) { (i) }
30
31#ifdef __KERNEL__
32
33/*
34 * On ARM, ordinary assignment (str instruction) doesn't clear the local
35 * strex/ldrex monitor on some implementations. The reason we can use it for
36 * atomic_set() is the clrex or dummy strex done on every exception return.
37 */
38#define atomic_read(v) (*(volatile int *)&(v)->counter)
39#define atomic_set(v,i) (((v)->counter) = (i))
40
41/*
42 * AArch64 UP and SMP safe atomic ops. We use load exclusive and
43 * store exclusive to ensure that these are atomic. We may loop
44 * to ensure that the update happens.
45 */
46static inline void atomic_add(int i, atomic_t *v)
47{
48 unsigned long tmp;
49 int result;
50
51 asm volatile("// atomic_add\n"
52"1: ldxr %w0, [%3]\n"
53" add %w0, %w0, %w4\n"
54" stxr %w1, %w0, [%3]\n"
55" cbnz %w1, 1b"
56 : "=&r" (result), "=&r" (tmp), "+o" (v->counter)
57 : "r" (&v->counter), "Ir" (i)
58 : "cc");
59}
60
61static inline int atomic_add_return(int i, atomic_t *v)
62{
63 unsigned long tmp;
64 int result;
65
66 asm volatile("// atomic_add_return\n"
67"1: ldaxr %w0, [%3]\n"
68" add %w0, %w0, %w4\n"
69" stlxr %w1, %w0, [%3]\n"
70" cbnz %w1, 1b"
71 : "=&r" (result), "=&r" (tmp), "+o" (v->counter)
72 : "r" (&v->counter), "Ir" (i)
73 : "cc");
74
75 return result;
76}
77
78static inline void atomic_sub(int i, atomic_t *v)
79{
80 unsigned long tmp;
81 int result;
82
83 asm volatile("// atomic_sub\n"
84"1: ldxr %w0, [%3]\n"
85" sub %w0, %w0, %w4\n"
86" stxr %w1, %w0, [%3]\n"
87" cbnz %w1, 1b"
88 : "=&r" (result), "=&r" (tmp), "+o" (v->counter)
89 : "r" (&v->counter), "Ir" (i)
90 : "cc");
91}
92
93static inline int atomic_sub_return(int i, atomic_t *v)
94{
95 unsigned long tmp;
96 int result;
97
98 asm volatile("// atomic_sub_return\n"
99"1: ldaxr %w0, [%3]\n"
100" sub %w0, %w0, %w4\n"
101" stlxr %w1, %w0, [%3]\n"
102" cbnz %w1, 1b"
103 : "=&r" (result), "=&r" (tmp), "+o" (v->counter)
104 : "r" (&v->counter), "Ir" (i)
105 : "cc");
106
107 return result;
108}
109
110static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
111{
112 unsigned long tmp;
113 int oldval;
114
115 asm volatile("// atomic_cmpxchg\n"
116"1: ldaxr %w1, [%3]\n"
117" cmp %w1, %w4\n"
118" b.ne 2f\n"
119" stlxr %w0, %w5, [%3]\n"
120" cbnz %w0, 1b\n"
121"2:"
122 : "=&r" (tmp), "=&r" (oldval), "+o" (ptr->counter)
123 : "r" (&ptr->counter), "Ir" (old), "r" (new)
124 : "cc");
125
126 return oldval;
127}
128
129static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
130{
131 unsigned long tmp, tmp2;
132
133 asm volatile("// atomic_clear_mask\n"
134"1: ldxr %0, [%3]\n"
135" bic %0, %0, %4\n"
136" stxr %w1, %0, [%3]\n"
137" cbnz %w1, 1b"
138 : "=&r" (tmp), "=&r" (tmp2), "+o" (*addr)
139 : "r" (addr), "Ir" (mask)
140 : "cc");
141}
142
143#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
144
145static inline int __atomic_add_unless(atomic_t *v, int a, int u)
146{
147 int c, old;
148
149 c = atomic_read(v);
150 while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c)
151 c = old;
152 return c;
153}
154
155#define atomic_inc(v) atomic_add(1, v)
156#define atomic_dec(v) atomic_sub(1, v)
157
158#define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0)
159#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0)
160#define atomic_inc_return(v) (atomic_add_return(1, v))
161#define atomic_dec_return(v) (atomic_sub_return(1, v))
162#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
163
164#define atomic_add_negative(i,v) (atomic_add_return(i, v) < 0)
165
166#define smp_mb__before_atomic_dec() smp_mb()
167#define smp_mb__after_atomic_dec() smp_mb()
168#define smp_mb__before_atomic_inc() smp_mb()
169#define smp_mb__after_atomic_inc() smp_mb()
170
171/*
172 * 64-bit atomic operations.
173 */
174#define ATOMIC64_INIT(i) { (i) }
175
176#define atomic64_read(v) (*(volatile long long *)&(v)->counter)
177#define atomic64_set(v,i) (((v)->counter) = (i))
178
179static inline void atomic64_add(u64 i, atomic64_t *v)
180{
181 long result;
182 unsigned long tmp;
183
184 asm volatile("// atomic64_add\n"
185"1: ldxr %0, [%3]\n"
186" add %0, %0, %4\n"
187" stxr %w1, %0, [%3]\n"
188" cbnz %w1, 1b"
189 : "=&r" (result), "=&r" (tmp), "+o" (v->counter)
190 : "r" (&v->counter), "Ir" (i)
191 : "cc");
192}
193
194static inline long atomic64_add_return(long i, atomic64_t *v)
195{
196 long result;
197 unsigned long tmp;
198
199 asm volatile("// atomic64_add_return\n"
200"1: ldaxr %0, [%3]\n"
201" add %0, %0, %4\n"
202" stlxr %w1, %0, [%3]\n"
203" cbnz %w1, 1b"
204 : "=&r" (result), "=&r" (tmp), "+o" (v->counter)
205 : "r" (&v->counter), "Ir" (i)
206 : "cc");
207
208 return result;
209}
210
211static inline void atomic64_sub(u64 i, atomic64_t *v)
212{
213 long result;
214 unsigned long tmp;
215
216 asm volatile("// atomic64_sub\n"
217"1: ldxr %0, [%3]\n"
218" sub %0, %0, %4\n"
219" stxr %w1, %0, [%3]\n"
220" cbnz %w1, 1b"
221 : "=&r" (result), "=&r" (tmp), "+o" (v->counter)
222 : "r" (&v->counter), "Ir" (i)
223 : "cc");
224}
225
226static inline long atomic64_sub_return(long i, atomic64_t *v)
227{
228 long result;
229 unsigned long tmp;
230
231 asm volatile("// atomic64_sub_return\n"
232"1: ldaxr %0, [%3]\n"
233" sub %0, %0, %4\n"
234" stlxr %w1, %0, [%3]\n"
235" cbnz %w1, 1b"
236 : "=&r" (result), "=&r" (tmp), "+o" (v->counter)
237 : "r" (&v->counter), "Ir" (i)
238 : "cc");
239
240 return result;
241}
242
243static inline long atomic64_cmpxchg(atomic64_t *ptr, long old, long new)
244{
245 long oldval;
246 unsigned long res;
247
248 asm volatile("// atomic64_cmpxchg\n"
249"1: ldaxr %1, [%3]\n"
250" cmp %1, %4\n"
251" b.ne 2f\n"
252" stlxr %w0, %5, [%3]\n"
253" cbnz %w0, 1b\n"
254"2:"
255 : "=&r" (res), "=&r" (oldval), "+o" (ptr->counter)
256 : "r" (&ptr->counter), "Ir" (old), "r" (new)
257 : "cc");
258
259 return oldval;
260}
261
262#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
263
264static inline long atomic64_dec_if_positive(atomic64_t *v)
265{
266 long result;
267 unsigned long tmp;
268
269 asm volatile("// atomic64_dec_if_positive\n"
270"1: ldaxr %0, [%3]\n"
271" subs %0, %0, #1\n"
272" b.mi 2f\n"
273" stlxr %w1, %0, [%3]\n"
274" cbnz %w1, 1b\n"
275"2:"
276 : "=&r" (result), "=&r" (tmp), "+o" (v->counter)
277 : "r" (&v->counter)
278 : "cc");
279
280 return result;
281}
282
283static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
284{
285 long c, old;
286
287 c = atomic64_read(v);
288 while (c != u && (old = atomic64_cmpxchg((v), c, c + a)) != c)
289 c = old;
290
291 return c != u;
292}
293
294#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
295#define atomic64_inc(v) atomic64_add(1LL, (v))
296#define atomic64_inc_return(v) atomic64_add_return(1LL, (v))
297#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
298#define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0)
299#define atomic64_dec(v) atomic64_sub(1LL, (v))
300#define atomic64_dec_return(v) atomic64_sub_return(1LL, (v))
301#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0)
302#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1LL, 0LL)
303
304#endif
305#endif
diff --git a/arch/arm64/include/asm/auxvec.h b/arch/arm64/include/asm/auxvec.h
new file mode 100644
index 000000000000..22d6d8885854
--- /dev/null
+++ b/arch/arm64/include/asm/auxvec.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_AUXVEC_H
17#define __ASM_AUXVEC_H
18
19/* vDSO location */
20#define AT_SYSINFO_EHDR 33
21
22#endif
diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h
new file mode 100644
index 000000000000..d4a63338a53c
--- /dev/null
+++ b/arch/arm64/include/asm/barrier.h
@@ -0,0 +1,52 @@
1/*
2 * Based on arch/arm/include/asm/barrier.h
3 *
4 * Copyright (C) 2012 ARM Ltd.
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#ifndef __ASM_BARRIER_H
19#define __ASM_BARRIER_H
20
21#ifndef __ASSEMBLY__
22
23#define sev() asm volatile("sev" : : : "memory")
24#define wfe() asm volatile("wfe" : : : "memory")
25#define wfi() asm volatile("wfi" : : : "memory")
26
27#define isb() asm volatile("isb" : : : "memory")
28#define dsb() asm volatile("dsb sy" : : : "memory")
29
30#define mb() dsb()
31#define rmb() asm volatile("dsb ld" : : : "memory")
32#define wmb() asm volatile("dsb st" : : : "memory")
33
34#ifndef CONFIG_SMP
35#define smp_mb() barrier()
36#define smp_rmb() barrier()
37#define smp_wmb() barrier()
38#else
39#define smp_mb() asm volatile("dmb ish" : : : "memory")
40#define smp_rmb() asm volatile("dmb ishld" : : : "memory")
41#define smp_wmb() asm volatile("dmb ishst" : : : "memory")
42#endif
43
44#define read_barrier_depends() do { } while(0)
45#define smp_read_barrier_depends() do { } while(0)
46
47#define set_mb(var, value) do { var = value; smp_mb(); } while (0)
48#define nop() asm volatile("nop");
49
50#endif /* __ASSEMBLY__ */
51
52#endif /* __ASM_BARRIER_H */
diff --git a/arch/arm64/include/asm/bitops.h b/arch/arm64/include/asm/bitops.h
new file mode 100644
index 000000000000..5e693073b030
--- /dev/null
+++ b/arch/arm64/include/asm/bitops.h
@@ -0,0 +1,53 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_BITOPS_H
17#define __ASM_BITOPS_H
18
19#include <linux/compiler.h>
20
21#include <asm/barrier.h>
22
23/*
24 * clear_bit may not imply a memory barrier
25 */
26#ifndef smp_mb__before_clear_bit
27#define smp_mb__before_clear_bit() smp_mb()
28#define smp_mb__after_clear_bit() smp_mb()
29#endif
30
31#ifndef _LINUX_BITOPS_H
32#error only <linux/bitops.h> can be included directly
33#endif
34
35#include <asm-generic/bitops/builtin-__ffs.h>
36#include <asm-generic/bitops/builtin-ffs.h>
37#include <asm-generic/bitops/builtin-__fls.h>
38#include <asm-generic/bitops/builtin-fls.h>
39
40#include <asm-generic/bitops/ffz.h>
41#include <asm-generic/bitops/fls64.h>
42#include <asm-generic/bitops/find.h>
43
44#include <asm-generic/bitops/sched.h>
45#include <asm-generic/bitops/hweight.h>
46#include <asm-generic/bitops/lock.h>
47
48#include <asm-generic/bitops/atomic.h>
49#include <asm-generic/bitops/non-atomic.h>
50#include <asm-generic/bitops/le.h>
51#include <asm-generic/bitops/ext2-atomic.h>
52
53#endif /* __ASM_BITOPS_H */
diff --git a/arch/arm64/include/asm/bitsperlong.h b/arch/arm64/include/asm/bitsperlong.h
new file mode 100644
index 000000000000..fce9c2924fa3
--- /dev/null
+++ b/arch/arm64/include/asm/bitsperlong.h
@@ -0,0 +1,23 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_BITSPERLONG_H
17#define __ASM_BITSPERLONG_H
18
19#define __BITS_PER_LONG 64
20
21#include <asm-generic/bitsperlong.h>
22
23#endif /* __ASM_BITSPERLONG_H */
diff --git a/arch/arm64/include/asm/byteorder.h b/arch/arm64/include/asm/byteorder.h
new file mode 100644
index 000000000000..2b92046aafc5
--- /dev/null
+++ b/arch/arm64/include/asm/byteorder.h
@@ -0,0 +1,21 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_BYTEORDER_H
17#define __ASM_BYTEORDER_H
18
19#include <linux/byteorder/little_endian.h>
20
21#endif /* __ASM_BYTEORDER_H */
diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h
new file mode 100644
index 000000000000..390308a67f0d
--- /dev/null
+++ b/arch/arm64/include/asm/cache.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_CACHE_H
17#define __ASM_CACHE_H
18
19#define L1_CACHE_SHIFT 6
20#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
21
22/*
23 * Memory returned by kmalloc() may be used for DMA, so we must make
24 * sure that all such allocations are cache aligned. Otherwise,
25 * unrelated code may cause parts of the buffer to be read into the
26 * cache before the transfer is done, causing old data to be seen by
27 * the CPU.
28 */
29#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
30#define ARCH_SLAB_MINALIGN 8
31
32#endif
diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
new file mode 100644
index 000000000000..aa3132ab7f29
--- /dev/null
+++ b/arch/arm64/include/asm/cacheflush.h
@@ -0,0 +1,148 @@
1/*
2 * Based on arch/arm/include/asm/cacheflush.h
3 *
4 * Copyright (C) 1999-2002 Russell King.
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef __ASM_CACHEFLUSH_H
20#define __ASM_CACHEFLUSH_H
21
22#include <linux/mm.h>
23
24/*
25 * This flag is used to indicate that the page pointed to by a pte is clean
26 * and does not require cleaning before returning it to the user.
27 */
28#define PG_dcache_clean PG_arch_1
29
30/*
31 * MM Cache Management
32 * ===================
33 *
34 * The arch/arm64/mm/cache.S implements these methods.
35 *
36 * Start addresses are inclusive and end addresses are exclusive; start
37 * addresses should be rounded down, end addresses up.
38 *
39 * See Documentation/cachetlb.txt for more information. Please note that
40 * the implementation assumes non-aliasing VIPT D-cache and (aliasing)
41 * VIPT or ASID-tagged VIVT I-cache.
42 *
43 * flush_cache_all()
44 *
45 * Unconditionally clean and invalidate the entire cache.
46 *
47 * flush_cache_mm(mm)
48 *
49 * Clean and invalidate all user space cache entries
50 * before a change of page tables.
51 *
52 * flush_icache_range(start, end)
53 *
54 * Ensure coherency between the I-cache and the D-cache in the
55 * region described by start, end.
56 * - start - virtual start address
57 * - end - virtual end address
58 *
59 * __flush_cache_user_range(start, end)
60 *
61 * Ensure coherency between the I-cache and the D-cache in the
62 * region described by start, end.
63 * - start - virtual start address
64 * - end - virtual end address
65 *
66 * __flush_dcache_area(kaddr, size)
67 *
68 * Ensure that the data held in page is written back.
69 * - kaddr - page address
70 * - size - region size
71 */
72extern void flush_cache_all(void);
73extern void flush_cache_mm(struct mm_struct *mm);
74extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
75extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn);
76extern void flush_icache_range(unsigned long start, unsigned long end);
77extern void __flush_dcache_area(void *addr, size_t len);
78extern void __flush_cache_user_range(unsigned long start, unsigned long end);
79
80/*
81 * Copy user data from/to a page which is mapped into a different
82 * processes address space. Really, we want to allow our "user
83 * space" model to handle this.
84 */
85extern void copy_to_user_page(struct vm_area_struct *, struct page *,
86 unsigned long, void *, const void *, unsigned long);
87#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
88 do { \
89 memcpy(dst, src, len); \
90 } while (0)
91
92#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
93
94/*
95 * flush_dcache_page is used when the kernel has written to the page
96 * cache page at virtual address page->virtual.
97 *
98 * If this page isn't mapped (ie, page_mapping == NULL), or it might
99 * have userspace mappings, then we _must_ always clean + invalidate
100 * the dcache entries associated with the kernel mapping.
101 *
102 * Otherwise we can defer the operation, and clean the cache when we are
103 * about to change to user space. This is the same method as used on SPARC64.
104 * See update_mmu_cache for the user space part.
105 */
106#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
107extern void flush_dcache_page(struct page *);
108
109static inline void __flush_icache_all(void)
110{
111 asm("ic ialluis");
112}
113
114#define flush_dcache_mmap_lock(mapping) \
115 spin_lock_irq(&(mapping)->tree_lock)
116#define flush_dcache_mmap_unlock(mapping) \
117 spin_unlock_irq(&(mapping)->tree_lock)
118
119#define flush_icache_user_range(vma,page,addr,len) \
120 flush_dcache_page(page)
121
122/*
123 * We don't appear to need to do anything here. In fact, if we did, we'd
124 * duplicate cache flushing elsewhere performed by flush_dcache_page().
125 */
126#define flush_icache_page(vma,page) do { } while (0)
127
128/*
129 * flush_cache_vmap() is used when creating mappings (eg, via vmap,
130 * vmalloc, ioremap etc) in kernel space for pages. On non-VIPT
131 * caches, since the direct-mappings of these pages may contain cached
132 * data, we need to do a full cache flush to ensure that writebacks
133 * don't corrupt data placed into these pages via the new mappings.
134 */
135static inline void flush_cache_vmap(unsigned long start, unsigned long end)
136{
137 /*
138 * set_pte_at() called from vmap_pte_range() does not
139 * have a DSB after cleaning the cache line.
140 */
141 dsb();
142}
143
144static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
145{
146}
147
148#endif
diff --git a/arch/arm64/include/asm/cachetype.h b/arch/arm64/include/asm/cachetype.h
new file mode 100644
index 000000000000..85f5f511352a
--- /dev/null
+++ b/arch/arm64/include/asm/cachetype.h
@@ -0,0 +1,48 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_CACHETYPE_H
17#define __ASM_CACHETYPE_H
18
19#include <asm/cputype.h>
20
21#define CTR_L1IP_SHIFT 14
22#define CTR_L1IP_MASK 3
23
24#define ICACHE_POLICY_RESERVED 0
25#define ICACHE_POLICY_AIVIVT 1
26#define ICACHE_POLICY_VIPT 2
27#define ICACHE_POLICY_PIPT 3
28
29static inline u32 icache_policy(void)
30{
31 return (read_cpuid_cachetype() >> CTR_L1IP_SHIFT) & CTR_L1IP_MASK;
32}
33
34/*
35 * Whilst the D-side always behaves as PIPT on AArch64, aliasing is
36 * permitted in the I-cache.
37 */
38static inline int icache_is_aliasing(void)
39{
40 return icache_policy() != ICACHE_POLICY_PIPT;
41}
42
43static inline int icache_is_aivivt(void)
44{
45 return icache_policy() == ICACHE_POLICY_AIVIVT;
46}
47
48#endif /* __ASM_CACHETYPE_H */
diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h
new file mode 100644
index 000000000000..e0e65b069d9e
--- /dev/null
+++ b/arch/arm64/include/asm/cmpxchg.h
@@ -0,0 +1,173 @@
1/*
2 * Based on arch/arm/include/asm/cmpxchg.h
3 *
4 * Copyright (C) 2012 ARM Ltd.
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#ifndef __ASM_CMPXCHG_H
19#define __ASM_CMPXCHG_H
20
21#include <linux/bug.h>
22
23#include <asm/barrier.h>
24
25static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
26{
27 unsigned long ret, tmp;
28
29 switch (size) {
30 case 1:
31 asm volatile("// __xchg1\n"
32 "1: ldaxrb %w0, [%3]\n"
33 " stlxrb %w1, %w2, [%3]\n"
34 " cbnz %w1, 1b\n"
35 : "=&r" (ret), "=&r" (tmp)
36 : "r" (x), "r" (ptr)
37 : "memory", "cc");
38 break;
39 case 2:
40 asm volatile("// __xchg2\n"
41 "1: ldaxrh %w0, [%3]\n"
42 " stlxrh %w1, %w2, [%3]\n"
43 " cbnz %w1, 1b\n"
44 : "=&r" (ret), "=&r" (tmp)
45 : "r" (x), "r" (ptr)
46 : "memory", "cc");
47 break;
48 case 4:
49 asm volatile("// __xchg4\n"
50 "1: ldaxr %w0, [%3]\n"
51 " stlxr %w1, %w2, [%3]\n"
52 " cbnz %w1, 1b\n"
53 : "=&r" (ret), "=&r" (tmp)
54 : "r" (x), "r" (ptr)
55 : "memory", "cc");
56 break;
57 case 8:
58 asm volatile("// __xchg8\n"
59 "1: ldaxr %0, [%3]\n"
60 " stlxr %w1, %2, [%3]\n"
61 " cbnz %w1, 1b\n"
62 : "=&r" (ret), "=&r" (tmp)
63 : "r" (x), "r" (ptr)
64 : "memory", "cc");
65 break;
66 default:
67 BUILD_BUG();
68 }
69
70 return ret;
71}
72
73#define xchg(ptr,x) \
74 ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
75
76static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
77 unsigned long new, int size)
78{
79 unsigned long oldval = 0, res;
80
81 switch (size) {
82 case 1:
83 do {
84 asm volatile("// __cmpxchg1\n"
85 " ldxrb %w1, [%2]\n"
86 " mov %w0, #0\n"
87 " cmp %w1, %w3\n"
88 " b.ne 1f\n"
89 " stxrb %w0, %w4, [%2]\n"
90 "1:\n"
91 : "=&r" (res), "=&r" (oldval)
92 : "r" (ptr), "Ir" (old), "r" (new)
93 : "cc");
94 } while (res);
95 break;
96
97 case 2:
98 do {
99 asm volatile("// __cmpxchg2\n"
100 " ldxrh %w1, [%2]\n"
101 " mov %w0, #0\n"
102 " cmp %w1, %w3\n"
103 " b.ne 1f\n"
104 " stxrh %w0, %w4, [%2]\n"
105 "1:\n"
106 : "=&r" (res), "=&r" (oldval)
107 : "r" (ptr), "Ir" (old), "r" (new)
108 : "memory", "cc");
109 } while (res);
110 break;
111
112 case 4:
113 do {
114 asm volatile("// __cmpxchg4\n"
115 " ldxr %w1, [%2]\n"
116 " mov %w0, #0\n"
117 " cmp %w1, %w3\n"
118 " b.ne 1f\n"
119 " stxr %w0, %w4, [%2]\n"
120 "1:\n"
121 : "=&r" (res), "=&r" (oldval)
122 : "r" (ptr), "Ir" (old), "r" (new)
123 : "cc");
124 } while (res);
125 break;
126
127 case 8:
128 do {
129 asm volatile("// __cmpxchg8\n"
130 " ldxr %1, [%2]\n"
131 " mov %w0, #0\n"
132 " cmp %1, %3\n"
133 " b.ne 1f\n"
134 " stxr %w0, %4, [%2]\n"
135 "1:\n"
136 : "=&r" (res), "=&r" (oldval)
137 : "r" (ptr), "Ir" (old), "r" (new)
138 : "cc");
139 } while (res);
140 break;
141
142 default:
143 BUILD_BUG();
144 }
145
146 return oldval;
147}
148
149static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old,
150 unsigned long new, int size)
151{
152 unsigned long ret;
153
154 smp_mb();
155 ret = __cmpxchg(ptr, old, new, size);
156 smp_mb();
157
158 return ret;
159}
160
161#define cmpxchg(ptr,o,n) \
162 ((__typeof__(*(ptr)))__cmpxchg_mb((ptr), \
163 (unsigned long)(o), \
164 (unsigned long)(n), \
165 sizeof(*(ptr))))
166
167#define cmpxchg_local(ptr,o,n) \
168 ((__typeof__(*(ptr)))__cmpxchg((ptr), \
169 (unsigned long)(o), \
170 (unsigned long)(n), \
171 sizeof(*(ptr))))
172
173#endif /* __ASM_CMPXCHG_H */
diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
new file mode 100644
index 000000000000..a670a33ad736
--- /dev/null
+++ b/arch/arm64/include/asm/compat.h
@@ -0,0 +1,242 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_COMPAT_H
17#define __ASM_COMPAT_H
18#ifdef __KERNEL__
19#ifdef CONFIG_COMPAT
20
21/*
22 * Architecture specific compatibility types
23 */
24#include <linux/types.h>
25#include <linux/sched.h>
26
27#define COMPAT_USER_HZ 100
28#define COMPAT_UTS_MACHINE "armv8l\0\0"
29
30typedef u32 compat_size_t;
31typedef s32 compat_ssize_t;
32typedef s32 compat_time_t;
33typedef s32 compat_clock_t;
34typedef s32 compat_pid_t;
35typedef u32 __compat_uid_t;
36typedef u32 __compat_gid_t;
37typedef u32 __compat_uid32_t;
38typedef u32 __compat_gid32_t;
39typedef u32 compat_mode_t;
40typedef u32 compat_ino_t;
41typedef u32 compat_dev_t;
42typedef s32 compat_off_t;
43typedef s64 compat_loff_t;
44typedef s16 compat_nlink_t;
45typedef u16 compat_ipc_pid_t;
46typedef s32 compat_daddr_t;
47typedef u32 compat_caddr_t;
48typedef __kernel_fsid_t compat_fsid_t;
49typedef s32 compat_key_t;
50typedef s32 compat_timer_t;
51
52typedef s32 compat_int_t;
53typedef s32 compat_long_t;
54typedef s64 compat_s64;
55typedef u32 compat_uint_t;
56typedef u32 compat_ulong_t;
57typedef u64 compat_u64;
58
59struct compat_timespec {
60 compat_time_t tv_sec;
61 s32 tv_nsec;
62};
63
64struct compat_timeval {
65 compat_time_t tv_sec;
66 s32 tv_usec;
67};
68
69struct compat_stat {
70 compat_dev_t st_dev;
71 compat_ino_t st_ino;
72 compat_mode_t st_mode;
73 compat_nlink_t st_nlink;
74 __compat_uid32_t st_uid;
75 __compat_gid32_t st_gid;
76 compat_dev_t st_rdev;
77 compat_off_t st_size;
78 compat_off_t st_blksize;
79 compat_off_t st_blocks;
80 compat_time_t st_atime;
81 u32 st_atime_nsec;
82 compat_time_t st_mtime;
83 u32 st_mtime_nsec;
84 compat_time_t st_ctime;
85 u32 st_ctime_nsec;
86 u32 __unused4[2];
87};
88
89struct compat_flock {
90 short l_type;
91 short l_whence;
92 compat_off_t l_start;
93 compat_off_t l_len;
94 compat_pid_t l_pid;
95};
96
97#define F_GETLK64 12 /* using 'struct flock64' */
98#define F_SETLK64 13
99#define F_SETLKW64 14
100
101struct compat_flock64 {
102 short l_type;
103 short l_whence;
104 compat_loff_t l_start;
105 compat_loff_t l_len;
106 compat_pid_t l_pid;
107};
108
109struct compat_statfs {
110 int f_type;
111 int f_bsize;
112 int f_blocks;
113 int f_bfree;
114 int f_bavail;
115 int f_files;
116 int f_ffree;
117 compat_fsid_t f_fsid;
118 int f_namelen; /* SunOS ignores this field. */
119 int f_frsize;
120 int f_flags;
121 int f_spare[4];
122};
123
124#define COMPAT_RLIM_INFINITY 0xffffffff
125
126typedef u32 compat_old_sigset_t;
127
128#define _COMPAT_NSIG 64
129#define _COMPAT_NSIG_BPW 32
130
131typedef u32 compat_sigset_word;
132
133#define COMPAT_OFF_T_MAX 0x7fffffff
134#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
135
136/*
137 * A pointer passed in from user mode. This should not
138 * be used for syscall parameters, just declare them
139 * as pointers because the syscall entry code will have
140 * appropriately converted them already.
141 */
142typedef u32 compat_uptr_t;
143
144static inline void __user *compat_ptr(compat_uptr_t uptr)
145{
146 return (void __user *)(unsigned long)uptr;
147}
148
149static inline compat_uptr_t ptr_to_compat(void __user *uptr)
150{
151 return (u32)(unsigned long)uptr;
152}
153
154static inline void __user *arch_compat_alloc_user_space(long len)
155{
156 struct pt_regs *regs = task_pt_regs(current);
157 return (void __user *)regs->compat_sp - len;
158}
159
160struct compat_ipc64_perm {
161 compat_key_t key;
162 __compat_uid32_t uid;
163 __compat_gid32_t gid;
164 __compat_uid32_t cuid;
165 __compat_gid32_t cgid;
166 unsigned short mode;
167 unsigned short __pad1;
168 unsigned short seq;
169 unsigned short __pad2;
170 compat_ulong_t unused1;
171 compat_ulong_t unused2;
172};
173
174struct compat_semid64_ds {
175 struct compat_ipc64_perm sem_perm;
176 compat_time_t sem_otime;
177 compat_ulong_t __unused1;
178 compat_time_t sem_ctime;
179 compat_ulong_t __unused2;
180 compat_ulong_t sem_nsems;
181 compat_ulong_t __unused3;
182 compat_ulong_t __unused4;
183};
184
185struct compat_msqid64_ds {
186 struct compat_ipc64_perm msg_perm;
187 compat_time_t msg_stime;
188 compat_ulong_t __unused1;
189 compat_time_t msg_rtime;
190 compat_ulong_t __unused2;
191 compat_time_t msg_ctime;
192 compat_ulong_t __unused3;
193 compat_ulong_t msg_cbytes;
194 compat_ulong_t msg_qnum;
195 compat_ulong_t msg_qbytes;
196 compat_pid_t msg_lspid;
197 compat_pid_t msg_lrpid;
198 compat_ulong_t __unused4;
199 compat_ulong_t __unused5;
200};
201
202struct compat_shmid64_ds {
203 struct compat_ipc64_perm shm_perm;
204 compat_size_t shm_segsz;
205 compat_time_t shm_atime;
206 compat_ulong_t __unused1;
207 compat_time_t shm_dtime;
208 compat_ulong_t __unused2;
209 compat_time_t shm_ctime;
210 compat_ulong_t __unused3;
211 compat_pid_t shm_cpid;
212 compat_pid_t shm_lpid;
213 compat_ulong_t shm_nattch;
214 compat_ulong_t __unused4;
215 compat_ulong_t __unused5;
216};
217
218static inline int is_compat_task(void)
219{
220 return test_thread_flag(TIF_32BIT);
221}
222
223static inline int is_compat_thread(struct thread_info *thread)
224{
225 return test_ti_thread_flag(thread, TIF_32BIT);
226}
227
228#else /* !CONFIG_COMPAT */
229
230static inline int is_compat_task(void)
231{
232 return 0;
233}
234
235static inline int is_compat_thread(struct thread_info *thread)
236{
237 return 0;
238}
239
240#endif /* CONFIG_COMPAT */
241#endif /* __KERNEL__ */
242#endif /* __ASM_COMPAT_H */
diff --git a/arch/arm64/include/asm/compiler.h b/arch/arm64/include/asm/compiler.h
new file mode 100644
index 000000000000..ee35fd0f2236
--- /dev/null
+++ b/arch/arm64/include/asm/compiler.h
@@ -0,0 +1,30 @@
1/*
2 * Based on arch/arm/include/asm/compiler.h
3 *
4 * Copyright (C) 2012 ARM Ltd.
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#ifndef __ASM_COMPILER_H
19#define __ASM_COMPILER_H
20
21/*
22 * This is used to ensure the compiler did actually allocate the register we
23 * asked it for some inline assembly sequences. Apparently we can't trust the
24 * compiler from one version to another so a bit of paranoia won't hurt. This
25 * string is meant to be concatenated with the inline asm string and will
26 * cause compilation to stop on mismatch. (for details, see gcc PR 15089)
27 */
28#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
29
30#endif /* __ASM_COMPILER_H */
diff --git a/arch/arm64/include/asm/cputable.h b/arch/arm64/include/asm/cputable.h
new file mode 100644
index 000000000000..e3bd983d3661
--- /dev/null
+++ b/arch/arm64/include/asm/cputable.h
@@ -0,0 +1,30 @@
1/*
2 * arch/arm64/include/asm/cputable.h
3 *
4 * Copyright (C) 2012 ARM Ltd.
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#ifndef __ASM_CPUTABLE_H
19#define __ASM_CPUTABLE_H
20
21struct cpu_info {
22 unsigned int cpu_id_val;
23 unsigned int cpu_id_mask;
24 const char *cpu_name;
25 unsigned long (*cpu_setup)(void);
26};
27
28extern struct cpu_info *lookup_processor_type(unsigned int);
29
30#endif
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
new file mode 100644
index 000000000000..ef54125e6c1e
--- /dev/null
+++ b/arch/arm64/include/asm/cputype.h
@@ -0,0 +1,49 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_CPUTYPE_H
17#define __ASM_CPUTYPE_H
18
19#define ID_MIDR_EL1 "midr_el1"
20#define ID_CTR_EL0 "ctr_el0"
21
22#define ID_AA64PFR0_EL1 "id_aa64pfr0_el1"
23#define ID_AA64DFR0_EL1 "id_aa64dfr0_el1"
24#define ID_AA64AFR0_EL1 "id_aa64afr0_el1"
25#define ID_AA64ISAR0_EL1 "id_aa64isar0_el1"
26#define ID_AA64MMFR0_EL1 "id_aa64mmfr0_el1"
27
28#define read_cpuid(reg) ({ \
29 u64 __val; \
30 asm("mrs %0, " reg : "=r" (__val)); \
31 __val; \
32})
33
34/*
35 * The CPU ID never changes at run time, so we might as well tell the
36 * compiler that it's constant. Use this function to read the CPU ID
37 * rather than directly reading processor_id or read_cpuid() directly.
38 */
39static inline u32 __attribute_const__ read_cpuid_id(void)
40{
41 return read_cpuid(ID_MIDR_EL1);
42}
43
44static inline u32 __attribute_const__ read_cpuid_cachetype(void)
45{
46 return read_cpuid(ID_CTR_EL0);
47}
48
49#endif
diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h
new file mode 100644
index 000000000000..7eaa0b302493
--- /dev/null
+++ b/arch/arm64/include/asm/debug-monitors.h
@@ -0,0 +1,88 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_DEBUG_MONITORS_H
17#define __ASM_DEBUG_MONITORS_H
18
19#ifdef __KERNEL__
20
21#define DBG_ESR_EVT(x) (((x) >> 27) & 0x7)
22
23/* AArch64 */
24#define DBG_ESR_EVT_HWBP 0x0
25#define DBG_ESR_EVT_HWSS 0x1
26#define DBG_ESR_EVT_HWWP 0x2
27#define DBG_ESR_EVT_BRK 0x6
28
29enum debug_el {
30 DBG_ACTIVE_EL0 = 0,
31 DBG_ACTIVE_EL1,
32};
33
34/* AArch32 */
35#define DBG_ESR_EVT_BKPT 0x4
36#define DBG_ESR_EVT_VECC 0x5
37
38#define AARCH32_BREAK_ARM 0x07f001f0
39#define AARCH32_BREAK_THUMB 0xde01
40#define AARCH32_BREAK_THUMB2_LO 0xf7f0
41#define AARCH32_BREAK_THUMB2_HI 0xa000
42
43#ifndef __ASSEMBLY__
44struct task_struct;
45
46#define local_dbg_save(flags) \
47 do { \
48 typecheck(unsigned long, flags); \
49 asm volatile( \
50 "mrs %0, daif // local_dbg_save\n" \
51 "msr daifset, #8" \
52 : "=r" (flags) : : "memory"); \
53 } while (0)
54
55#define local_dbg_restore(flags) \
56 do { \
57 typecheck(unsigned long, flags); \
58 asm volatile( \
59 "msr daif, %0 // local_dbg_restore\n" \
60 : : "r" (flags) : "memory"); \
61 } while (0)
62
63#define DBG_ARCH_ID_RESERVED 0 /* In case of ptrace ABI updates. */
64
65u8 debug_monitors_arch(void);
66
67void enable_debug_monitors(enum debug_el el);
68void disable_debug_monitors(enum debug_el el);
69
70void user_rewind_single_step(struct task_struct *task);
71void user_fastforward_single_step(struct task_struct *task);
72
73void kernel_enable_single_step(struct pt_regs *regs);
74void kernel_disable_single_step(void);
75int kernel_active_single_step(void);
76
77#ifdef CONFIG_HAVE_HW_BREAKPOINT
78int reinstall_suspended_bps(struct pt_regs *regs);
79#else
80static inline int reinstall_suspended_bps(struct pt_regs *regs)
81{
82 return -ENODEV;
83}
84#endif
85
86#endif /* __ASSEMBLY */
87#endif /* __KERNEL__ */
88#endif /* __ASM_DEBUG_MONITORS_H */
diff --git a/arch/arm64/include/asm/device.h b/arch/arm64/include/asm/device.h
new file mode 100644
index 000000000000..0d8453c755a8
--- /dev/null
+++ b/arch/arm64/include/asm/device.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_DEVICE_H
17#define __ASM_DEVICE_H
18
19struct dev_archdata {
20 struct dma_map_ops *dma_ops;
21};
22
23struct pdev_archdata {
24};
25
26#endif
diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
new file mode 100644
index 000000000000..538f4b44db5d
--- /dev/null
+++ b/arch/arm64/include/asm/dma-mapping.h
@@ -0,0 +1,124 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_DMA_MAPPING_H
17#define __ASM_DMA_MAPPING_H
18
19#ifdef __KERNEL__
20
21#include <linux/types.h>
22#include <linux/vmalloc.h>
23
24#include <asm-generic/dma-coherent.h>
25
26#define ARCH_HAS_DMA_GET_REQUIRED_MASK
27
28extern struct dma_map_ops *dma_ops;
29
30static inline struct dma_map_ops *get_dma_ops(struct device *dev)
31{
32 if (unlikely(!dev) || !dev->archdata.dma_ops)
33 return dma_ops;
34 else
35 return dev->archdata.dma_ops;
36}
37
38#include <asm-generic/dma-mapping-common.h>
39
40static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
41{
42 return (dma_addr_t)paddr;
43}
44
45static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr)
46{
47 return (phys_addr_t)dev_addr;
48}
49
50static inline int dma_mapping_error(struct device *dev, dma_addr_t dev_addr)
51{
52 struct dma_map_ops *ops = get_dma_ops(dev);
53 return ops->mapping_error(dev, dev_addr);
54}
55
56static inline int dma_supported(struct device *dev, u64 mask)
57{
58 struct dma_map_ops *ops = get_dma_ops(dev);
59 return ops->dma_supported(dev, mask);
60}
61
62static inline int dma_set_mask(struct device *dev, u64 mask)
63{
64 if (!dev->dma_mask || !dma_supported(dev, mask))
65 return -EIO;
66 *dev->dma_mask = mask;
67
68 return 0;
69}
70
71static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
72{
73 if (!dev->dma_mask)
74 return 0;
75
76 return addr + size - 1 <= *dev->dma_mask;
77}
78
79static inline void dma_mark_clean(void *addr, size_t size)
80{
81}
82
83static inline void *dma_alloc_coherent(struct device *dev, size_t size,
84 dma_addr_t *dma_handle, gfp_t flags)
85{
86 struct dma_map_ops *ops = get_dma_ops(dev);
87 void *vaddr;
88
89 if (dma_alloc_from_coherent(dev, size, dma_handle, &vaddr))
90 return vaddr;
91
92 vaddr = ops->alloc(dev, size, dma_handle, flags, NULL);
93 debug_dma_alloc_coherent(dev, size, *dma_handle, vaddr);
94 return vaddr;
95}
96
97static inline void dma_free_coherent(struct device *dev, size_t size,
98 void *vaddr, dma_addr_t dev_addr)
99{
100 struct dma_map_ops *ops = get_dma_ops(dev);
101
102 if (dma_release_from_coherent(dev, get_order(size), vaddr))
103 return;
104
105 debug_dma_free_coherent(dev, size, vaddr, dev_addr);
106 ops->free(dev, size, vaddr, dev_addr, NULL);
107}
108
109/*
110 * There is no dma_cache_sync() implementation, so just return NULL here.
111 */
112static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
113 dma_addr_t *handle, gfp_t flags)
114{
115 return NULL;
116}
117
118static inline void dma_free_noncoherent(struct device *dev, size_t size,
119 void *cpu_addr, dma_addr_t handle)
120{
121}
122
123#endif /* __KERNEL__ */
124#endif /* __ASM_DMA_MAPPING_H */
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
new file mode 100644
index 000000000000..cf284649dfcb
--- /dev/null
+++ b/arch/arm64/include/asm/elf.h
@@ -0,0 +1,179 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_ELF_H
17#define __ASM_ELF_H
18
19#include <asm/hwcap.h>
20
21/*
22 * ELF register definitions..
23 */
24#include <asm/ptrace.h>
25#include <asm/user.h>
26
27typedef unsigned long elf_greg_t;
28typedef unsigned long elf_freg_t[3];
29
30#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
31typedef elf_greg_t elf_gregset_t[ELF_NGREG];
32
33typedef struct user_fp elf_fpregset_t;
34
35#define EM_AARCH64 183
36
37/*
38 * AArch64 static relocation types.
39 */
40
41/* Miscellaneous. */
42#define R_ARM_NONE 0
43#define R_AARCH64_NONE 256
44
45/* Data. */
46#define R_AARCH64_ABS64 257
47#define R_AARCH64_ABS32 258
48#define R_AARCH64_ABS16 259
49#define R_AARCH64_PREL64 260
50#define R_AARCH64_PREL32 261
51#define R_AARCH64_PREL16 262
52
53/* Instructions. */
54#define R_AARCH64_MOVW_UABS_G0 263
55#define R_AARCH64_MOVW_UABS_G0_NC 264
56#define R_AARCH64_MOVW_UABS_G1 265
57#define R_AARCH64_MOVW_UABS_G1_NC 266
58#define R_AARCH64_MOVW_UABS_G2 267
59#define R_AARCH64_MOVW_UABS_G2_NC 268
60#define R_AARCH64_MOVW_UABS_G3 269
61
62#define R_AARCH64_MOVW_SABS_G0 270
63#define R_AARCH64_MOVW_SABS_G1 271
64#define R_AARCH64_MOVW_SABS_G2 272
65
66#define R_AARCH64_LD_PREL_LO19 273
67#define R_AARCH64_ADR_PREL_LO21 274
68#define R_AARCH64_ADR_PREL_PG_HI21 275
69#define R_AARCH64_ADR_PREL_PG_HI21_NC 276
70#define R_AARCH64_ADD_ABS_LO12_NC 277
71#define R_AARCH64_LDST8_ABS_LO12_NC 278
72
73#define R_AARCH64_TSTBR14 279
74#define R_AARCH64_CONDBR19 280
75#define R_AARCH64_JUMP26 282
76#define R_AARCH64_CALL26 283
77#define R_AARCH64_LDST16_ABS_LO12_NC 284
78#define R_AARCH64_LDST32_ABS_LO12_NC 285
79#define R_AARCH64_LDST64_ABS_LO12_NC 286
80#define R_AARCH64_LDST128_ABS_LO12_NC 299
81
82#define R_AARCH64_MOVW_PREL_G0 287
83#define R_AARCH64_MOVW_PREL_G0_NC 288
84#define R_AARCH64_MOVW_PREL_G1 289
85#define R_AARCH64_MOVW_PREL_G1_NC 290
86#define R_AARCH64_MOVW_PREL_G2 291
87#define R_AARCH64_MOVW_PREL_G2_NC 292
88#define R_AARCH64_MOVW_PREL_G3 293
89
90
91/*
92 * These are used to set parameters in the core dumps.
93 */
94#define ELF_CLASS ELFCLASS64
95#define ELF_DATA ELFDATA2LSB
96#define ELF_ARCH EM_AARCH64
97
98#define ELF_PLATFORM_SIZE 16
99#define ELF_PLATFORM ("aarch64")
100
101/*
102 * This is used to ensure we don't load something for the wrong architecture.
103 */
104#define elf_check_arch(x) ((x)->e_machine == EM_AARCH64)
105
106#define elf_read_implies_exec(ex,stk) (stk != EXSTACK_DISABLE_X)
107
108#define CORE_DUMP_USE_REGSET
109#define ELF_EXEC_PAGESIZE PAGE_SIZE
110
111/*
112 * This is the location that an ET_DYN program is loaded if exec'ed. Typical
113 * use of this is to invoke "./ld.so someprog" to test out a new version of
114 * the loader. We need to make sure that it is out of the way of the program
115 * that it will "exec", and that there is sufficient room for the brk.
116 */
117extern unsigned long randomize_et_dyn(unsigned long base);
118#define ELF_ET_DYN_BASE (randomize_et_dyn(2 * TASK_SIZE_64 / 3))
119
120/*
121 * When the program starts, a1 contains a pointer to a function to be
122 * registered with atexit, as per the SVR4 ABI. A value of 0 means we have no
123 * such handler.
124 */
125#define ELF_PLAT_INIT(_r, load_addr) (_r)->regs[0] = 0
126
127#define SET_PERSONALITY(ex) clear_thread_flag(TIF_32BIT);
128
129#define ARCH_DLINFO \
130do { \
131 NEW_AUX_ENT(AT_SYSINFO_EHDR, \
132 (elf_addr_t)current->mm->context.vdso); \
133} while (0)
134
135#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
136struct linux_binprm;
137extern int arch_setup_additional_pages(struct linux_binprm *bprm,
138 int uses_interp);
139
140/* 1GB of VA */
141#ifdef CONFIG_COMPAT
142#define STACK_RND_MASK (test_thread_flag(TIF_32BIT) ? \
143 0x7ff >> (PAGE_SHIFT - 12) : \
144 0x3ffff >> (PAGE_SHIFT - 12))
145#else
146#define STACK_RND_MASK (0x3ffff >> (PAGE_SHIFT - 12))
147#endif
148
149struct mm_struct;
150extern unsigned long arch_randomize_brk(struct mm_struct *mm);
151#define arch_randomize_brk arch_randomize_brk
152
153#ifdef CONFIG_COMPAT
154#define EM_ARM 40
155#define COMPAT_ELF_PLATFORM ("v8l")
156
157#define COMPAT_ELF_ET_DYN_BASE (randomize_et_dyn(2 * TASK_SIZE_32 / 3))
158
159/* AArch32 registers. */
160#define COMPAT_ELF_NGREG 18
161typedef unsigned int compat_elf_greg_t;
162typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
163
164/* AArch32 EABI. */
165#define EF_ARM_EABI_MASK 0xff000000
166#define compat_elf_check_arch(x) (((x)->e_machine == EM_ARM) && \
167 ((x)->e_flags & EF_ARM_EABI_MASK))
168
169#define compat_start_thread compat_start_thread
170#define COMPAT_SET_PERSONALITY(ex) set_thread_flag(TIF_32BIT);
171#define COMPAT_ARCH_DLINFO
172extern int aarch32_setup_vectors_page(struct linux_binprm *bprm,
173 int uses_interp);
174#define compat_arch_setup_additional_pages \
175 aarch32_setup_vectors_page
176
177#endif /* CONFIG_COMPAT */
178
179#endif
diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
new file mode 100644
index 000000000000..ac63519b7b90
--- /dev/null
+++ b/arch/arm64/include/asm/exception.h
@@ -0,0 +1,23 @@
1/*
2 * Based on arch/arm/include/asm/exception.h
3 *
4 * Copyright (C) 2012 ARM Ltd.
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#ifndef __ASM_EXCEPTION_H
19#define __ASM_EXCEPTION_H
20
21#define __exception __attribute__((section(".exception.text")))
22
23#endif /* __ASM_EXCEPTION_H */
diff --git a/arch/arm64/include/asm/exec.h b/arch/arm64/include/asm/exec.h
new file mode 100644
index 000000000000..db0563c23482
--- /dev/null
+++ b/arch/arm64/include/asm/exec.h
@@ -0,0 +1,23 @@
1/*
2 * Based on arch/arm/include/asm/exec.h
3 *
4 * Copyright (C) 2012 ARM Ltd.
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#ifndef __ASM_EXEC_H
19#define __ASM_EXEC_H
20
21extern unsigned long arch_align_stack(unsigned long sp);
22
23#endif /* __ASM_EXEC_H */
diff --git a/arch/arm64/include/asm/fb.h b/arch/arm64/include/asm/fb.h
new file mode 100644
index 000000000000..adb88a64b2fe
--- /dev/null
+++ b/arch/arm64/include/asm/fb.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_FB_H_
17#define __ASM_FB_H_
18
19#include <linux/fb.h>
20#include <linux/fs.h>
21#include <asm/page.h>
22
23static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
24 unsigned long off)
25{
26 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
27}
28
29static inline int fb_is_primary_device(struct fb_info *info)
30{
31 return 0;
32}
33
34#endif /* __ASM_FB_H_ */
diff --git a/arch/arm64/include/asm/fcntl.h b/arch/arm64/include/asm/fcntl.h
new file mode 100644
index 000000000000..cd2e630c235e
--- /dev/null
+++ b/arch/arm64/include/asm/fcntl.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_FCNTL_H
17#define __ASM_FCNTL_H
18
19/*
20 * Using our own definitions for AArch32 (compat) support.
21 */
22#define O_DIRECTORY 040000 /* must be a directory */
23#define O_NOFOLLOW 0100000 /* don't follow links */
24#define O_DIRECT 0200000 /* direct disk access hint - currently ignored */
25#define O_LARGEFILE 0400000
26
27#include <asm-generic/fcntl.h>
28
29#endif
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
new file mode 100644
index 000000000000..b42fab9f62a9
--- /dev/null
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -0,0 +1,64 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_FP_H
17#define __ASM_FP_H
18
19#include <asm/ptrace.h>
20
21#ifndef __ASSEMBLY__
22
23/*
24 * FP/SIMD storage area has:
25 * - FPSR and FPCR
26 * - 32 128-bit data registers
27 *
28 * Note that user_fp forms a prefix of this structure, which is relied
29 * upon in the ptrace FP/SIMD accessors. struct user_fpsimd_state must
30 * form a prefix of struct fpsimd_state.
31 */
32struct fpsimd_state {
33 union {
34 struct user_fpsimd_state user_fpsimd;
35 struct {
36 __uint128_t vregs[32];
37 u32 fpsr;
38 u32 fpcr;
39 };
40 };
41};
42
43#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
44/* Masks for extracting the FPSR and FPCR from the FPSCR */
45#define VFP_FPSCR_STAT_MASK 0xf800009f
46#define VFP_FPSCR_CTRL_MASK 0x07f79f00
47/*
48 * The VFP state has 32x64-bit registers and a single 32-bit
49 * control/status register.
50 */
51#define VFP_STATE_SIZE ((32 * 8) + 4)
52#endif
53
54struct task_struct;
55
56extern void fpsimd_save_state(struct fpsimd_state *state);
57extern void fpsimd_load_state(struct fpsimd_state *state);
58
59extern void fpsimd_thread_switch(struct task_struct *next);
60extern void fpsimd_flush_thread(void);
61
62#endif
63
64#endif
diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h
new file mode 100644
index 000000000000..3468ae8439fa
--- /dev/null
+++ b/arch/arm64/include/asm/futex.h
@@ -0,0 +1,136 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_FUTEX_H
17#define __ASM_FUTEX_H
18
19#ifdef __KERNEL__
20
21#include <linux/futex.h>
22#include <linux/uaccess.h>
23#include <asm/errno.h>
24
25#define __futex_atomic_op(insn, ret, oldval, uaddr, tmp, oparg) \
26 asm volatile( \
27"1: ldaxr %w1, %2\n" \
28 insn "\n" \
29"2: stlxr %w3, %w0, %2\n" \
30" cbnz %w3, 1b\n" \
31"3:\n" \
32" .pushsection .fixup,\"ax\"\n" \
33"4: mov %w0, %w5\n" \
34" b 3b\n" \
35" .popsection\n" \
36" .pushsection __ex_table,\"a\"\n" \
37" .align 3\n" \
38" .quad 1b, 4b, 2b, 4b\n" \
39" .popsection\n" \
40 : "=&r" (ret), "=&r" (oldval), "+Q" (*uaddr), "=&r" (tmp) \
41 : "r" (oparg), "Ir" (-EFAULT) \
42 : "cc")
43
44static inline int
45futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
46{
47 int op = (encoded_op >> 28) & 7;
48 int cmp = (encoded_op >> 24) & 15;
49 int oparg = (encoded_op << 8) >> 20;
50 int cmparg = (encoded_op << 20) >> 20;
51 int oldval = 0, ret, tmp;
52
53 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
54 oparg = 1 << oparg;
55
56 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
57 return -EFAULT;
58
59 pagefault_disable(); /* implies preempt_disable() */
60
61 switch (op) {
62 case FUTEX_OP_SET:
63 __futex_atomic_op("mov %w0, %w4",
64 ret, oldval, uaddr, tmp, oparg);
65 break;
66 case FUTEX_OP_ADD:
67 __futex_atomic_op("add %w0, %w1, %w4",
68 ret, oldval, uaddr, tmp, oparg);
69 break;
70 case FUTEX_OP_OR:
71 __futex_atomic_op("orr %w0, %w1, %w4",
72 ret, oldval, uaddr, tmp, oparg);
73 break;
74 case FUTEX_OP_ANDN:
75 __futex_atomic_op("and %w0, %w1, %w4",
76 ret, oldval, uaddr, tmp, ~oparg);
77 break;
78 case FUTEX_OP_XOR:
79 __futex_atomic_op("eor %w0, %w1, %w4",
80 ret, oldval, uaddr, tmp, oparg);
81 break;
82 default:
83 ret = -ENOSYS;
84 }
85
86 pagefault_enable(); /* subsumes preempt_enable() */
87
88 if (!ret) {
89 switch (cmp) {
90 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
91 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
92 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
93 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
94 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
95 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
96 default: ret = -ENOSYS;
97 }
98 }
99 return ret;
100}
101
102static inline int
103futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
104 u32 oldval, u32 newval)
105{
106 int ret = 0;
107 u32 val, tmp;
108
109 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
110 return -EFAULT;
111
112 asm volatile("// futex_atomic_cmpxchg_inatomic\n"
113"1: ldaxr %w1, %2\n"
114" sub %w3, %w1, %w4\n"
115" cbnz %w3, 3f\n"
116"2: stlxr %w3, %w5, %2\n"
117" cbnz %w3, 1b\n"
118"3:\n"
119" .pushsection .fixup,\"ax\"\n"
120"4: mov %w0, %w6\n"
121" b 3b\n"
122" .popsection\n"
123" .pushsection __ex_table,\"a\"\n"
124" .align 3\n"
125" .quad 1b, 4b, 2b, 4b\n"
126" .popsection\n"
127 : "+r" (ret), "=&r" (val), "+Q" (*uaddr), "=&r" (tmp)
128 : "r" (oldval), "r" (newval), "Ir" (-EFAULT)
129 : "cc", "memory");
130
131 *uval = val;
132 return ret;
133}
134
135#endif /* __KERNEL__ */
136#endif /* __ASM_FUTEX_H */
diff --git a/arch/arm64/include/asm/hardirq.h b/arch/arm64/include/asm/hardirq.h
new file mode 100644
index 000000000000..507546353d62
--- /dev/null
+++ b/arch/arm64/include/asm/hardirq.h
@@ -0,0 +1,52 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_HARDIRQ_H
17#define __ASM_HARDIRQ_H
18
19#include <linux/cache.h>
20#include <linux/threads.h>
21#include <asm/irq.h>
22
23#define NR_IPI 4
24
25typedef struct {
26 unsigned int __softirq_pending;
27#ifdef CONFIG_SMP
28 unsigned int ipi_irqs[NR_IPI];
29#endif
30} ____cacheline_aligned irq_cpustat_t;
31
32#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
33
34#define __inc_irq_stat(cpu, member) __IRQ_STAT(cpu, member)++
35#define __get_irq_stat(cpu, member) __IRQ_STAT(cpu, member)
36
37#ifdef CONFIG_SMP
38u64 smp_irq_stat_cpu(unsigned int cpu);
39#define arch_irq_stat_cpu smp_irq_stat_cpu
40#endif
41
42#define __ARCH_IRQ_EXIT_IRQS_DISABLED 1
43
44static inline void ack_bad_irq(unsigned int irq)
45{
46 extern unsigned long irq_err_count;
47 irq_err_count++;
48}
49
50extern void handle_IRQ(unsigned int, struct pt_regs *);
51
52#endif /* __ASM_HARDIRQ_H */
diff --git a/arch/arm64/include/asm/hw_breakpoint.h b/arch/arm64/include/asm/hw_breakpoint.h
new file mode 100644
index 000000000000..d064047612b1
--- /dev/null
+++ b/arch/arm64/include/asm/hw_breakpoint.h
@@ -0,0 +1,137 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_HW_BREAKPOINT_H
17#define __ASM_HW_BREAKPOINT_H
18
19#ifdef __KERNEL__
20
21struct arch_hw_breakpoint_ctrl {
22 u32 __reserved : 19,
23 len : 8,
24 type : 2,
25 privilege : 2,
26 enabled : 1;
27};
28
29struct arch_hw_breakpoint {
30 u64 address;
31 u64 trigger;
32 struct arch_hw_breakpoint_ctrl ctrl;
33};
34
35static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl)
36{
37 return (ctrl.len << 5) | (ctrl.type << 3) | (ctrl.privilege << 1) |
38 ctrl.enabled;
39}
40
41static inline void decode_ctrl_reg(u32 reg,
42 struct arch_hw_breakpoint_ctrl *ctrl)
43{
44 ctrl->enabled = reg & 0x1;
45 reg >>= 1;
46 ctrl->privilege = reg & 0x3;
47 reg >>= 2;
48 ctrl->type = reg & 0x3;
49 reg >>= 2;
50 ctrl->len = reg & 0xff;
51}
52
53/* Breakpoint */
54#define ARM_BREAKPOINT_EXECUTE 0
55
56/* Watchpoints */
57#define ARM_BREAKPOINT_LOAD 1
58#define ARM_BREAKPOINT_STORE 2
59#define AARCH64_ESR_ACCESS_MASK (1 << 6)
60
61/* Privilege Levels */
62#define AARCH64_BREAKPOINT_EL1 1
63#define AARCH64_BREAKPOINT_EL0 2
64
65/* Lengths */
66#define ARM_BREAKPOINT_LEN_1 0x1
67#define ARM_BREAKPOINT_LEN_2 0x3
68#define ARM_BREAKPOINT_LEN_4 0xf
69#define ARM_BREAKPOINT_LEN_8 0xff
70
71/* Kernel stepping */
72#define ARM_KERNEL_STEP_NONE 0
73#define ARM_KERNEL_STEP_ACTIVE 1
74#define ARM_KERNEL_STEP_SUSPEND 2
75
76/*
77 * Limits.
78 * Changing these will require modifications to the register accessors.
79 */
80#define ARM_MAX_BRP 16
81#define ARM_MAX_WRP 16
82#define ARM_MAX_HBP_SLOTS (ARM_MAX_BRP + ARM_MAX_WRP)
83
84/* Virtual debug register bases. */
85#define AARCH64_DBG_REG_BVR 0
86#define AARCH64_DBG_REG_BCR (AARCH64_DBG_REG_BVR + ARM_MAX_BRP)
87#define AARCH64_DBG_REG_WVR (AARCH64_DBG_REG_BCR + ARM_MAX_BRP)
88#define AARCH64_DBG_REG_WCR (AARCH64_DBG_REG_WVR + ARM_MAX_WRP)
89
90/* Debug register names. */
91#define AARCH64_DBG_REG_NAME_BVR "bvr"
92#define AARCH64_DBG_REG_NAME_BCR "bcr"
93#define AARCH64_DBG_REG_NAME_WVR "wvr"
94#define AARCH64_DBG_REG_NAME_WCR "wcr"
95
96/* Accessor macros for the debug registers. */
97#define AARCH64_DBG_READ(N, REG, VAL) do {\
98 asm volatile("mrs %0, dbg" REG #N "_el1" : "=r" (VAL));\
99} while (0)
100
101#define AARCH64_DBG_WRITE(N, REG, VAL) do {\
102 asm volatile("msr dbg" REG #N "_el1, %0" :: "r" (VAL));\
103} while (0)
104
105struct task_struct;
106struct notifier_block;
107struct perf_event;
108struct pmu;
109
110extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
111 int *gen_len, int *gen_type);
112extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
113extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
114extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
115 unsigned long val, void *data);
116
117extern int arch_install_hw_breakpoint(struct perf_event *bp);
118extern void arch_uninstall_hw_breakpoint(struct perf_event *bp);
119extern void hw_breakpoint_pmu_read(struct perf_event *bp);
120extern int hw_breakpoint_slots(int type);
121
122#ifdef CONFIG_HAVE_HW_BREAKPOINT
123extern void hw_breakpoint_thread_switch(struct task_struct *next);
124extern void ptrace_hw_copy_thread(struct task_struct *task);
125#else
126static inline void hw_breakpoint_thread_switch(struct task_struct *next)
127{
128}
129static inline void ptrace_hw_copy_thread(struct task_struct *task)
130{
131}
132#endif
133
134extern struct pmu perf_ops_bp;
135
136#endif /* __KERNEL__ */
137#endif /* __ASM_BREAKPOINT_H */
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
new file mode 100644
index 000000000000..f8190ba45a3e
--- /dev/null
+++ b/arch/arm64/include/asm/hwcap.h
@@ -0,0 +1,53 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_HWCAP_H
17#define __ASM_HWCAP_H
18
19/*
20 * HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP
21 */
22#define HWCAP_FP (1 << 0)
23#define HWCAP_ASIMD (1 << 1)
24
25#define COMPAT_HWCAP_HALF (1 << 1)
26#define COMPAT_HWCAP_THUMB (1 << 2)
27#define COMPAT_HWCAP_FAST_MULT (1 << 4)
28#define COMPAT_HWCAP_VFP (1 << 6)
29#define COMPAT_HWCAP_EDSP (1 << 7)
30#define COMPAT_HWCAP_NEON (1 << 12)
31#define COMPAT_HWCAP_VFPv3 (1 << 13)
32#define COMPAT_HWCAP_TLS (1 << 15)
33#define COMPAT_HWCAP_VFPv4 (1 << 16)
34#define COMPAT_HWCAP_IDIVA (1 << 17)
35#define COMPAT_HWCAP_IDIVT (1 << 18)
36#define COMPAT_HWCAP_IDIV (COMPAT_HWCAP_IDIVA|COMPAT_HWCAP_IDIVT)
37
38#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
39/*
40 * This yields a mask that user programs can use to figure out what
41 * instruction set this cpu supports.
42 */
43#define ELF_HWCAP (elf_hwcap)
44#define COMPAT_ELF_HWCAP (COMPAT_HWCAP_HALF|COMPAT_HWCAP_THUMB|\
45 COMPAT_HWCAP_FAST_MULT|COMPAT_HWCAP_EDSP|\
46 COMPAT_HWCAP_TLS|COMPAT_HWCAP_VFP|\
47 COMPAT_HWCAP_VFPv3|COMPAT_HWCAP_VFPv4|\
48 COMPAT_HWCAP_NEON|COMPAT_HWCAP_IDIV)
49
50extern unsigned int elf_hwcap;
51#endif
52
53#endif
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
new file mode 100644
index 000000000000..74a2a7d304a9
--- /dev/null
+++ b/arch/arm64/include/asm/io.h
@@ -0,0 +1,258 @@
1/*
2 * Based on arch/arm/include/asm/io.h
3 *
4 * Copyright (C) 1996-2000 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef __ASM_IO_H
20#define __ASM_IO_H
21
22#ifdef __KERNEL__
23
24#include <linux/types.h>
25
26#include <asm/byteorder.h>
27#include <asm/barrier.h>
28#include <asm/pgtable.h>
29
30/*
31 * Generic IO read/write. These perform native-endian accesses.
32 */
33static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
34{
35 asm volatile("strb %w0, [%1]" : : "r" (val), "r" (addr));
36}
37
38static inline void __raw_writew(u16 val, volatile void __iomem *addr)
39{
40 asm volatile("strh %w0, [%1]" : : "r" (val), "r" (addr));
41}
42
43static inline void __raw_writel(u32 val, volatile void __iomem *addr)
44{
45 asm volatile("str %w0, [%1]" : : "r" (val), "r" (addr));
46}
47
48static inline void __raw_writeq(u64 val, volatile void __iomem *addr)
49{
50 asm volatile("str %0, [%1]" : : "r" (val), "r" (addr));
51}
52
53static inline u8 __raw_readb(const volatile void __iomem *addr)
54{
55 u8 val;
56 asm volatile("ldrb %w0, [%1]" : "=r" (val) : "r" (addr));
57 return val;
58}
59
60static inline u16 __raw_readw(const volatile void __iomem *addr)
61{
62 u16 val;
63 asm volatile("ldrh %w0, [%1]" : "=r" (val) : "r" (addr));
64 return val;
65}
66
67static inline u32 __raw_readl(const volatile void __iomem *addr)
68{
69 u32 val;
70 asm volatile("ldr %w0, [%1]" : "=r" (val) : "r" (addr));
71 return val;
72}
73
74static inline u64 __raw_readq(const volatile void __iomem *addr)
75{
76 u64 val;
77 asm volatile("ldr %0, [%1]" : "=r" (val) : "r" (addr));
78 return val;
79}
80
81/* IO barriers */
82#define __iormb() rmb()
83#define __iowmb() wmb()
84
85#define mmiowb() do { } while (0)
86
87/*
88 * Relaxed I/O memory access primitives. These follow the Device memory
89 * ordering rules but do not guarantee any ordering relative to Normal memory
90 * accesses.
91 */
92#define readb_relaxed(c) ({ u8 __v = __raw_readb(c); __v; })
93#define readw_relaxed(c) ({ u16 __v = le16_to_cpu((__force __le16)__raw_readw(c)); __v; })
94#define readl_relaxed(c) ({ u32 __v = le32_to_cpu((__force __le32)__raw_readl(c)); __v; })
95
96#define writeb_relaxed(v,c) ((void)__raw_writeb((v),(c)))
97#define writew_relaxed(v,c) ((void)__raw_writew((__force u16)cpu_to_le16(v),(c)))
98#define writel_relaxed(v,c) ((void)__raw_writel((__force u32)cpu_to_le32(v),(c)))
99
100/*
101 * I/O memory access primitives. Reads are ordered relative to any
102 * following Normal memory access. Writes are ordered relative to any prior
103 * Normal memory access.
104 */
105#define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; })
106#define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; })
107#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; })
108
109#define writeb(v,c) ({ __iowmb(); writeb_relaxed((v),(c)); })
110#define writew(v,c) ({ __iowmb(); writew_relaxed((v),(c)); })
111#define writel(v,c) ({ __iowmb(); writel_relaxed((v),(c)); })
112
113/*
114 * I/O port access primitives.
115 */
116#define IO_SPACE_LIMIT 0xffff
117#define PCI_IOBASE ((void __iomem *)0xffffffbbfffe0000UL)
118
119static inline u8 inb(unsigned long addr)
120{
121 return readb(addr + PCI_IOBASE);
122}
123
124static inline u16 inw(unsigned long addr)
125{
126 return readw(addr + PCI_IOBASE);
127}
128
129static inline u32 inl(unsigned long addr)
130{
131 return readl(addr + PCI_IOBASE);
132}
133
134static inline void outb(u8 b, unsigned long addr)
135{
136 writeb(b, addr + PCI_IOBASE);
137}
138
139static inline void outw(u16 b, unsigned long addr)
140{
141 writew(b, addr + PCI_IOBASE);
142}
143
144static inline void outl(u32 b, unsigned long addr)
145{
146 writel(b, addr + PCI_IOBASE);
147}
148
149#define inb_p(addr) inb(addr)
150#define inw_p(addr) inw(addr)
151#define inl_p(addr) inl(addr)
152
153#define outb_p(x, addr) outb((x), (addr))
154#define outw_p(x, addr) outw((x), (addr))
155#define outl_p(x, addr) outl((x), (addr))
156
157static inline void insb(unsigned long addr, void *buffer, int count)
158{
159 u8 *buf = buffer;
160 while (count--)
161 *buf++ = __raw_readb(addr + PCI_IOBASE);
162}
163
164static inline void insw(unsigned long addr, void *buffer, int count)
165{
166 u16 *buf = buffer;
167 while (count--)
168 *buf++ = __raw_readw(addr + PCI_IOBASE);
169}
170
171static inline void insl(unsigned long addr, void *buffer, int count)
172{
173 u32 *buf = buffer;
174 while (count--)
175 *buf++ = __raw_readl(addr + PCI_IOBASE);
176}
177
178static inline void outsb(unsigned long addr, const void *buffer, int count)
179{
180 const u8 *buf = buffer;
181 while (count--)
182 __raw_writeb(*buf++, addr + PCI_IOBASE);
183}
184
185static inline void outsw(unsigned long addr, const void *buffer, int count)
186{
187 const u16 *buf = buffer;
188 while (count--)
189 __raw_writew(*buf++, addr + PCI_IOBASE);
190}
191
192static inline void outsl(unsigned long addr, const void *buffer, int count)
193{
194 const u32 *buf = buffer;
195 while (count--)
196 __raw_writel(*buf++, addr + PCI_IOBASE);
197}
198
199#define insb_p(port,to,len) insb(port,to,len)
200#define insw_p(port,to,len) insw(port,to,len)
201#define insl_p(port,to,len) insl(port,to,len)
202
203#define outsb_p(port,from,len) outsb(port,from,len)
204#define outsw_p(port,from,len) outsw(port,from,len)
205#define outsl_p(port,from,len) outsl(port,from,len)
206
207/*
208 * String version of I/O memory access operations.
209 */
210extern void __memcpy_fromio(void *, const volatile void __iomem *, size_t);
211extern void __memcpy_toio(volatile void __iomem *, const void *, size_t);
212extern void __memset_io(volatile void __iomem *, int, size_t);
213
214#define memset_io(c,v,l) __memset_io((c),(v),(l))
215#define memcpy_fromio(a,c,l) __memcpy_fromio((a),(c),(l))
216#define memcpy_toio(c,a,l) __memcpy_toio((c),(a),(l))
217
218/*
219 * I/O memory mapping functions.
220 */
221extern void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot);
222extern void __iounmap(volatile void __iomem *addr);
223
224#define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_DIRTY)
225#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_XN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
226#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC))
227
228#define ioremap(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE)
229#define ioremap_nocache(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE)
230#define ioremap_wc(addr, size) __ioremap((addr), (size), PROT_NORMAL_NC)
231#define iounmap __iounmap
232
233#define ARCH_HAS_IOREMAP_WC
234#include <asm-generic/iomap.h>
235
236/*
237 * More restrictive address range checking than the default implementation
238 * (PHYS_OFFSET and PHYS_MASK taken into account).
239 */
240#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
241extern int valid_phys_addr_range(unsigned long addr, size_t size);
242extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
243
244extern int devmem_is_allowed(unsigned long pfn);
245
246/*
247 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
248 * access
249 */
250#define xlate_dev_mem_ptr(p) __va(p)
251
252/*
253 * Convert a virtual cached pointer to an uncached pointer
254 */
255#define xlate_dev_kmem_ptr(p) p
256
257#endif /* __KERNEL__ */
258#endif /* __ASM_IO_H */
diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h
new file mode 100644
index 000000000000..a4e1cad3202a
--- /dev/null
+++ b/arch/arm64/include/asm/irq.h
@@ -0,0 +1,8 @@
1#ifndef __ASM_IRQ_H
2#define __ASM_IRQ_H
3
4#include <asm-generic/irq.h>
5
6extern void (*handle_arch_irq)(struct pt_regs *);
7
8#endif
diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h
new file mode 100644
index 000000000000..aa11943b8502
--- /dev/null
+++ b/arch/arm64/include/asm/irqflags.h
@@ -0,0 +1,91 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_IRQFLAGS_H
17#define __ASM_IRQFLAGS_H
18
19#ifdef __KERNEL__
20
21#include <asm/ptrace.h>
22
23/*
24 * CPU interrupt mask handling.
25 */
26static inline unsigned long arch_local_irq_save(void)
27{
28 unsigned long flags;
29 asm volatile(
30 "mrs %0, daif // arch_local_irq_save\n"
31 "msr daifset, #2"
32 : "=r" (flags)
33 :
34 : "memory");
35 return flags;
36}
37
38static inline void arch_local_irq_enable(void)
39{
40 asm volatile(
41 "msr daifclr, #2 // arch_local_irq_enable"
42 :
43 :
44 : "memory");
45}
46
47static inline void arch_local_irq_disable(void)
48{
49 asm volatile(
50 "msr daifset, #2 // arch_local_irq_disable"
51 :
52 :
53 : "memory");
54}
55
56#define local_fiq_enable() asm("msr daifclr, #1" : : : "memory")
57#define local_fiq_disable() asm("msr daifset, #1" : : : "memory")
58
59/*
60 * Save the current interrupt enable state.
61 */
62static inline unsigned long arch_local_save_flags(void)
63{
64 unsigned long flags;
65 asm volatile(
66 "mrs %0, daif // arch_local_save_flags"
67 : "=r" (flags)
68 :
69 : "memory");
70 return flags;
71}
72
73/*
74 * restore saved IRQ state
75 */
76static inline void arch_local_irq_restore(unsigned long flags)
77{
78 asm volatile(
79 "msr daif, %0 // arch_local_irq_restore"
80 :
81 : "r" (flags)
82 : "memory");
83}
84
85static inline int arch_irqs_disabled_flags(unsigned long flags)
86{
87 return flags & PSR_I_BIT;
88}
89
90#endif
91#endif
diff --git a/arch/arm64/include/asm/memblock.h b/arch/arm64/include/asm/memblock.h
new file mode 100644
index 000000000000..6afeed2467f1
--- /dev/null
+++ b/arch/arm64/include/asm/memblock.h
@@ -0,0 +1,21 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_MEMBLOCK_H
17#define __ASM_MEMBLOCK_H
18
19extern void arm64_memblock_init(void);
20
21#endif
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
new file mode 100644
index 000000000000..1cac16a001cb
--- /dev/null
+++ b/arch/arm64/include/asm/memory.h
@@ -0,0 +1,144 @@
1/*
2 * Based on arch/arm/include/asm/memory.h
3 *
4 * Copyright (C) 2000-2002 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Note: this file should not be included by non-asm/.h files
20 */
21#ifndef __ASM_MEMORY_H
22#define __ASM_MEMORY_H
23
24#include <linux/compiler.h>
25#include <linux/const.h>
26#include <linux/types.h>
27#include <asm/sizes.h>
28
29/*
30 * Allow for constants defined here to be used from assembly code
31 * by prepending the UL suffix only with actual C code compilation.
32 */
33#define UL(x) _AC(x, UL)
34
35/*
36 * PAGE_OFFSET - the virtual address of the start of the kernel image.
37 * VA_BITS - the maximum number of bits for virtual addresses.
38 * TASK_SIZE - the maximum size of a user space task.
39 * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area.
40 * The module space lives between the addresses given by TASK_SIZE
41 * and PAGE_OFFSET - it must be within 128MB of the kernel text.
42 */
43#define PAGE_OFFSET UL(0xffffffc000000000)
44#define MODULES_END (PAGE_OFFSET)
45#define MODULES_VADDR (MODULES_END - SZ_64M)
46#define VA_BITS (39)
47#define TASK_SIZE_64 (UL(1) << VA_BITS)
48
49#ifdef CONFIG_COMPAT
50#define TASK_SIZE_32 UL(0x100000000)
51#define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \
52 TASK_SIZE_32 : TASK_SIZE_64)
53#else
54#define TASK_SIZE TASK_SIZE_64
55#endif /* CONFIG_COMPAT */
56
57#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 4))
58
59#if TASK_SIZE_64 > MODULES_VADDR
60#error Top of 64-bit user space clashes with start of module space
61#endif
62
63/*
64 * Physical vs virtual RAM address space conversion. These are
65 * private definitions which should NOT be used outside memory.h
66 * files. Use virt_to_phys/phys_to_virt/__pa/__va instead.
67 */
68#define __virt_to_phys(x) (((phys_addr_t)(x) - PAGE_OFFSET + PHYS_OFFSET))
69#define __phys_to_virt(x) ((unsigned long)((x) - PHYS_OFFSET + PAGE_OFFSET))
70
71/*
72 * Convert a physical address to a Page Frame Number and back
73 */
74#define __phys_to_pfn(paddr) ((unsigned long)((paddr) >> PAGE_SHIFT))
75#define __pfn_to_phys(pfn) ((phys_addr_t)(pfn) << PAGE_SHIFT)
76
77/*
78 * Convert a page to/from a physical address
79 */
80#define page_to_phys(page) (__pfn_to_phys(page_to_pfn(page)))
81#define phys_to_page(phys) (pfn_to_page(__phys_to_pfn(phys)))
82
83/*
84 * Memory types available.
85 */
86#define MT_DEVICE_nGnRnE 0
87#define MT_DEVICE_nGnRE 1
88#define MT_DEVICE_GRE 2
89#define MT_NORMAL_NC 3
90#define MT_NORMAL 4
91
92#ifndef __ASSEMBLY__
93
94extern phys_addr_t memstart_addr;
95/* PHYS_OFFSET - the physical address of the start of memory. */
96#define PHYS_OFFSET ({ memstart_addr; })
97
98/*
99 * PFNs are used to describe any physical page; this means
100 * PFN 0 == physical address 0.
101 *
102 * This is the PFN of the first RAM page in the kernel
103 * direct-mapped view. We assume this is the first page
104 * of RAM in the mem_map as well.
105 */
106#define PHYS_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT)
107
108/*
109 * Note: Drivers should NOT use these. They are the wrong
110 * translation for translating DMA addresses. Use the driver
111 * DMA support - see dma-mapping.h.
112 */
113static inline phys_addr_t virt_to_phys(const volatile void *x)
114{
115 return __virt_to_phys((unsigned long)(x));
116}
117
118static inline void *phys_to_virt(phys_addr_t x)
119{
120 return (void *)(__phys_to_virt(x));
121}
122
123/*
124 * Drivers should NOT use these either.
125 */
126#define __pa(x) __virt_to_phys((unsigned long)(x))
127#define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x)))
128#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
129
130/*
131 * virt_to_page(k) convert a _valid_ virtual address to struct page *
132 * virt_addr_valid(k) indicates whether a virtual address is valid
133 */
134#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET
135
136#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
137#define virt_addr_valid(kaddr) (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \
138 ((void *)(kaddr) < (void *)high_memory))
139
140#endif
141
142#include <asm-generic/memory_model.h>
143
144#endif
diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
new file mode 100644
index 000000000000..d4f7fd5b9e33
--- /dev/null
+++ b/arch/arm64/include/asm/mmu.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_MMU_H
17#define __ASM_MMU_H
18
19typedef struct {
20 unsigned int id;
21 raw_spinlock_t id_lock;
22 void *vdso;
23} mm_context_t;
24
25#define ASID(mm) ((mm)->context.id & 0xffff)
26
27extern void paging_init(void);
28extern void setup_mm_for_reboot(void);
29
30#endif
diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
new file mode 100644
index 000000000000..f68465dee026
--- /dev/null
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -0,0 +1,152 @@
1/*
2 * Based on arch/arm/include/asm/mmu_context.h
3 *
4 * Copyright (C) 1996 Russell King.
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef __ASM_MMU_CONTEXT_H
20#define __ASM_MMU_CONTEXT_H
21
22#include <linux/compiler.h>
23#include <linux/sched.h>
24
25#include <asm/cacheflush.h>
26#include <asm/proc-fns.h>
27#include <asm-generic/mm_hooks.h>
28#include <asm/cputype.h>
29#include <asm/pgtable.h>
30
31#define MAX_ASID_BITS 16
32
33extern unsigned int cpu_last_asid;
34
35void __init_new_context(struct task_struct *tsk, struct mm_struct *mm);
36void __new_context(struct mm_struct *mm);
37
38/*
39 * Set TTBR0 to empty_zero_page. No translations will be possible via TTBR0.
40 */
41static inline void cpu_set_reserved_ttbr0(void)
42{
43 unsigned long ttbr = page_to_phys(empty_zero_page);
44
45 asm(
46 " msr ttbr0_el1, %0 // set TTBR0\n"
47 " isb"
48 :
49 : "r" (ttbr));
50}
51
52static inline void switch_new_context(struct mm_struct *mm)
53{
54 unsigned long flags;
55
56 __new_context(mm);
57
58 local_irq_save(flags);
59 cpu_switch_mm(mm->pgd, mm);
60 local_irq_restore(flags);
61}
62
63static inline void check_and_switch_context(struct mm_struct *mm,
64 struct task_struct *tsk)
65{
66 /*
67 * Required during context switch to avoid speculative page table
68 * walking with the wrong TTBR.
69 */
70 cpu_set_reserved_ttbr0();
71
72 if (!((mm->context.id ^ cpu_last_asid) >> MAX_ASID_BITS))
73 /*
74 * The ASID is from the current generation, just switch to the
75 * new pgd. This condition is only true for calls from
76 * context_switch() and interrupts are already disabled.
77 */
78 cpu_switch_mm(mm->pgd, mm);
79 else if (irqs_disabled())
80 /*
81 * Defer the new ASID allocation until after the context
82 * switch critical region since __new_context() cannot be
83 * called with interrupts disabled.
84 */
85 set_ti_thread_flag(task_thread_info(tsk), TIF_SWITCH_MM);
86 else
87 /*
88 * That is a direct call to switch_mm() or activate_mm() with
89 * interrupts enabled and a new context.
90 */
91 switch_new_context(mm);
92}
93
94#define init_new_context(tsk,mm) (__init_new_context(tsk,mm),0)
95#define destroy_context(mm) do { } while(0)
96
97#define finish_arch_post_lock_switch \
98 finish_arch_post_lock_switch
99static inline void finish_arch_post_lock_switch(void)
100{
101 if (test_and_clear_thread_flag(TIF_SWITCH_MM)) {
102 struct mm_struct *mm = current->mm;
103 unsigned long flags;
104
105 __new_context(mm);
106
107 local_irq_save(flags);
108 cpu_switch_mm(mm->pgd, mm);
109 local_irq_restore(flags);
110 }
111}
112
113/*
114 * This is called when "tsk" is about to enter lazy TLB mode.
115 *
116 * mm: describes the currently active mm context
117 * tsk: task which is entering lazy tlb
118 * cpu: cpu number which is entering lazy tlb
119 *
120 * tsk->mm will be NULL
121 */
122static inline void
123enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
124{
125}
126
127/*
128 * This is the actual mm switch as far as the scheduler
129 * is concerned. No registers are touched. We avoid
130 * calling the CPU specific function when the mm hasn't
131 * actually changed.
132 */
133static inline void
134switch_mm(struct mm_struct *prev, struct mm_struct *next,
135 struct task_struct *tsk)
136{
137 unsigned int cpu = smp_processor_id();
138
139#ifdef CONFIG_SMP
140 /* check for possible thread migration */
141 if (!cpumask_empty(mm_cpumask(next)) &&
142 !cpumask_test_cpu(cpu, mm_cpumask(next)))
143 __flush_icache_all();
144#endif
145 if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next)
146 check_and_switch_context(next, tsk);
147}
148
149#define deactivate_mm(tsk,mm) do { } while (0)
150#define activate_mm(prev,next) switch_mm(prev, next, NULL)
151
152#endif
diff --git a/arch/arm64/include/asm/module.h b/arch/arm64/include/asm/module.h
new file mode 100644
index 000000000000..e80e232b730e
--- /dev/null
+++ b/arch/arm64/include/asm/module.h
@@ -0,0 +1,23 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_MODULE_H
17#define __ASM_MODULE_H
18
19#include <asm-generic/module.h>
20
21#define MODULE_ARCH_VERMAGIC "aarch64"
22
23#endif /* __ASM_MODULE_H */
diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
new file mode 100644
index 000000000000..46bf66628b6a
--- /dev/null
+++ b/arch/arm64/include/asm/page.h
@@ -0,0 +1,67 @@
1/*
2 * Based on arch/arm/include/asm/page.h
3 *
4 * Copyright (C) 1995-2003 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef __ASM_PAGE_H
20#define __ASM_PAGE_H
21
22/* PAGE_SHIFT determines the page size */
23#ifdef CONFIG_ARM64_64K_PAGES
24#define PAGE_SHIFT 16
25#else
26#define PAGE_SHIFT 12
27#endif
28#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
29#define PAGE_MASK (~(PAGE_SIZE-1))
30
31/* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */
32#define __HAVE_ARCH_GATE_AREA 1
33
34#ifndef __ASSEMBLY__
35
36#ifdef CONFIG_ARM64_64K_PAGES
37#include <asm/pgtable-2level-types.h>
38#else
39#include <asm/pgtable-3level-types.h>
40#endif
41
42extern void __cpu_clear_user_page(void *p, unsigned long user);
43extern void __cpu_copy_user_page(void *to, const void *from,
44 unsigned long user);
45extern void copy_page(void *to, const void *from);
46extern void clear_page(void *to);
47
48#define clear_user_page(addr,vaddr,pg) __cpu_clear_user_page(addr, vaddr)
49#define copy_user_page(to,from,vaddr,pg) __cpu_copy_user_page(to, from, vaddr)
50
51typedef struct page *pgtable_t;
52
53#ifdef CONFIG_HAVE_ARCH_PFN_VALID
54extern int pfn_valid(unsigned long);
55#endif
56
57#include <asm/memory.h>
58
59#endif /* !__ASSEMBLY__ */
60
61#define VM_DATA_DEFAULT_FLAGS \
62 (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
63 VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
64
65#include <asm-generic/getorder.h>
66
67#endif
diff --git a/arch/arm64/include/asm/param.h b/arch/arm64/include/asm/param.h
new file mode 100644
index 000000000000..8e3a281d448a
--- /dev/null
+++ b/arch/arm64/include/asm/param.h
@@ -0,0 +1,23 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_PARAM_H
17#define __ASM_PARAM_H
18
19#define EXEC_PAGESIZE 65536
20
21#include <asm-generic/param.h>
22
23#endif
diff --git a/arch/arm64/include/asm/perf_event.h b/arch/arm64/include/asm/perf_event.h
new file mode 100644
index 000000000000..a6fffd511c5e
--- /dev/null
+++ b/arch/arm64/include/asm/perf_event.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef __ASM_PERF_EVENT_H
18#define __ASM_PERF_EVENT_H
19
20/* It's quiet around here... */
21
22#endif
diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
new file mode 100644
index 000000000000..f214069ec5d5
--- /dev/null
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -0,0 +1,113 @@
1/*
2 * Based on arch/arm/include/asm/pgalloc.h
3 *
4 * Copyright (C) 2000-2001 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef __ASM_PGALLOC_H
20#define __ASM_PGALLOC_H
21
22#include <asm/pgtable-hwdef.h>
23#include <asm/processor.h>
24#include <asm/cacheflush.h>
25#include <asm/tlbflush.h>
26
27#define check_pgt_cache() do { } while (0)
28
29#ifndef CONFIG_ARM64_64K_PAGES
30
31static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
32{
33 return (pmd_t *)get_zeroed_page(GFP_KERNEL | __GFP_REPEAT);
34}
35
36static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
37{
38 BUG_ON((unsigned long)pmd & (PAGE_SIZE-1));
39 free_page((unsigned long)pmd);
40}
41
42static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
43{
44 set_pud(pud, __pud(__pa(pmd) | PMD_TYPE_TABLE));
45}
46
47#endif /* CONFIG_ARM64_64K_PAGES */
48
49extern pgd_t *pgd_alloc(struct mm_struct *mm);
50extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
51
52#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
53
54static inline pte_t *
55pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
56{
57 return (pte_t *)__get_free_page(PGALLOC_GFP);
58}
59
60static inline pgtable_t
61pte_alloc_one(struct mm_struct *mm, unsigned long addr)
62{
63 struct page *pte;
64
65 pte = alloc_pages(PGALLOC_GFP, 0);
66 if (pte)
67 pgtable_page_ctor(pte);
68
69 return pte;
70}
71
72/*
73 * Free a PTE table.
74 */
75static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
76{
77 if (pte)
78 free_page((unsigned long)pte);
79}
80
81static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
82{
83 pgtable_page_dtor(pte);
84 __free_page(pte);
85}
86
87static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte,
88 pmdval_t prot)
89{
90 set_pmd(pmdp, __pmd(pte | prot));
91}
92
93/*
94 * Populate the pmdp entry with a pointer to the pte. This pmd is part
95 * of the mm address space.
96 */
97static inline void
98pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
99{
100 /*
101 * The pmd must be loaded with the physical address of the PTE table
102 */
103 __pmd_populate(pmdp, __pa(ptep), PMD_TYPE_TABLE);
104}
105
106static inline void
107pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
108{
109 __pmd_populate(pmdp, page_to_phys(ptep), PMD_TYPE_TABLE);
110}
111#define pmd_pgtable(pmd) pmd_page(pmd)
112
113#endif
diff --git a/arch/arm64/include/asm/pgtable-2level-hwdef.h b/arch/arm64/include/asm/pgtable-2level-hwdef.h
new file mode 100644
index 000000000000..0a8ed3f94e93
--- /dev/null
+++ b/arch/arm64/include/asm/pgtable-2level-hwdef.h
@@ -0,0 +1,43 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_PGTABLE_2LEVEL_HWDEF_H
17#define __ASM_PGTABLE_2LEVEL_HWDEF_H
18
19/*
20 * With LPAE and 64KB pages, there are 2 levels of page tables. Each level has
21 * 8192 entries of 8 bytes each, occupying a 64KB page. Levels 0 and 1 are not
22 * used. The 2nd level table (PGD for Linux) can cover a range of 4TB, each
23 * entry representing 512MB. The user and kernel address spaces are limited to
24 * 512GB and therefore we only use 1024 entries in the PGD.
25 */
26#define PTRS_PER_PTE 8192
27#define PTRS_PER_PGD 1024
28
29/*
30 * PGDIR_SHIFT determines the size a top-level page table entry can map.
31 */
32#define PGDIR_SHIFT 29
33#define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT)
34#define PGDIR_MASK (~(PGDIR_SIZE-1))
35
36/*
37 * section address mask and size definitions.
38 */
39#define SECTION_SHIFT 29
40#define SECTION_SIZE (_AC(1, UL) << SECTION_SHIFT)
41#define SECTION_MASK (~(SECTION_SIZE-1))
42
43#endif
diff --git a/arch/arm64/include/asm/pgtable-2level-types.h b/arch/arm64/include/asm/pgtable-2level-types.h
new file mode 100644
index 000000000000..3c3ca7d361e4
--- /dev/null
+++ b/arch/arm64/include/asm/pgtable-2level-types.h
@@ -0,0 +1,60 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_PGTABLE_2LEVEL_TYPES_H
17#define __ASM_PGTABLE_2LEVEL_TYPES_H
18
19typedef u64 pteval_t;
20typedef u64 pgdval_t;
21typedef pgdval_t pmdval_t;
22
23#undef STRICT_MM_TYPECHECKS
24
25#ifdef STRICT_MM_TYPECHECKS
26
27/*
28 * These are used to make use of C type-checking..
29 */
30typedef struct { pteval_t pte; } pte_t;
31typedef struct { pgdval_t pgd; } pgd_t;
32typedef struct { pteval_t pgprot; } pgprot_t;
33
34#define pte_val(x) ((x).pte)
35#define pgd_val(x) ((x).pgd)
36#define pgprot_val(x) ((x).pgprot)
37
38#define __pte(x) ((pte_t) { (x) } )
39#define __pgd(x) ((pgd_t) { (x) } )
40#define __pgprot(x) ((pgprot_t) { (x) } )
41
42#else /* !STRICT_MM_TYPECHECKS */
43
44typedef pteval_t pte_t;
45typedef pgdval_t pgd_t;
46typedef pteval_t pgprot_t;
47
48#define pte_val(x) (x)
49#define pgd_val(x) (x)
50#define pgprot_val(x) (x)
51
52#define __pte(x) (x)
53#define __pgd(x) (x)
54#define __pgprot(x) (x)
55
56#endif /* STRICT_MM_TYPECHECKS */
57
58#include <asm-generic/pgtable-nopmd.h>
59
60#endif /* __ASM_PGTABLE_2LEVEL_TYPES_H */
diff --git a/arch/arm64/include/asm/pgtable-3level-hwdef.h b/arch/arm64/include/asm/pgtable-3level-hwdef.h
new file mode 100644
index 000000000000..3dbf941d7767
--- /dev/null
+++ b/arch/arm64/include/asm/pgtable-3level-hwdef.h
@@ -0,0 +1,50 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_PGTABLE_3LEVEL_HWDEF_H
17#define __ASM_PGTABLE_3LEVEL_HWDEF_H
18
19/*
20 * With LPAE and 4KB pages, there are 3 levels of page tables. Each level has
21 * 512 entries of 8 bytes each, occupying a 4K page. The first level table
22 * covers a range of 512GB, each entry representing 1GB. The user and kernel
23 * address spaces are limited to 512GB each.
24 */
25#define PTRS_PER_PTE 512
26#define PTRS_PER_PMD 512
27#define PTRS_PER_PGD 512
28
29/*
30 * PGDIR_SHIFT determines the size a top-level page table entry can map.
31 */
32#define PGDIR_SHIFT 30
33#define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT)
34#define PGDIR_MASK (~(PGDIR_SIZE-1))
35
36/*
37 * PMD_SHIFT determines the size a middle-level page table entry can map.
38 */
39#define PMD_SHIFT 21
40#define PMD_SIZE (_AC(1, UL) << PMD_SHIFT)
41#define PMD_MASK (~(PMD_SIZE-1))
42
43/*
44 * section address mask and size definitions.
45 */
46#define SECTION_SHIFT 21
47#define SECTION_SIZE (_AC(1, UL) << SECTION_SHIFT)
48#define SECTION_MASK (~(SECTION_SIZE-1))
49
50#endif
diff --git a/arch/arm64/include/asm/pgtable-3level-types.h b/arch/arm64/include/asm/pgtable-3level-types.h
new file mode 100644
index 000000000000..4489615f14a9
--- /dev/null
+++ b/arch/arm64/include/asm/pgtable-3level-types.h
@@ -0,0 +1,66 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_PGTABLE_3LEVEL_TYPES_H
17#define __ASM_PGTABLE_3LEVEL_TYPES_H
18
19typedef u64 pteval_t;
20typedef u64 pmdval_t;
21typedef u64 pgdval_t;
22
23#undef STRICT_MM_TYPECHECKS
24
25#ifdef STRICT_MM_TYPECHECKS
26
27/*
28 * These are used to make use of C type-checking..
29 */
30typedef struct { pteval_t pte; } pte_t;
31typedef struct { pmdval_t pmd; } pmd_t;
32typedef struct { pgdval_t pgd; } pgd_t;
33typedef struct { pteval_t pgprot; } pgprot_t;
34
35#define pte_val(x) ((x).pte)
36#define pmd_val(x) ((x).pmd)
37#define pgd_val(x) ((x).pgd)
38#define pgprot_val(x) ((x).pgprot)
39
40#define __pte(x) ((pte_t) { (x) } )
41#define __pmd(x) ((pmd_t) { (x) } )
42#define __pgd(x) ((pgd_t) { (x) } )
43#define __pgprot(x) ((pgprot_t) { (x) } )
44
45#else /* !STRICT_MM_TYPECHECKS */
46
47typedef pteval_t pte_t;
48typedef pmdval_t pmd_t;
49typedef pgdval_t pgd_t;
50typedef pteval_t pgprot_t;
51
52#define pte_val(x) (x)
53#define pmd_val(x) (x)
54#define pgd_val(x) (x)
55#define pgprot_val(x) (x)
56
57#define __pte(x) (x)
58#define __pmd(x) (x)
59#define __pgd(x) (x)
60#define __pgprot(x) (x)
61
62#endif /* STRICT_MM_TYPECHECKS */
63
64#include <asm-generic/pgtable-nopud.h>
65
66#endif /* __ASM_PGTABLE_3LEVEL_TYPES_H */
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
new file mode 100644
index 000000000000..0f3b4581d925
--- /dev/null
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -0,0 +1,94 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_PGTABLE_HWDEF_H
17#define __ASM_PGTABLE_HWDEF_H
18
19#ifdef CONFIG_ARM64_64K_PAGES
20#include <asm/pgtable-2level-hwdef.h>
21#else
22#include <asm/pgtable-3level-hwdef.h>
23#endif
24
25/*
26 * Hardware page table definitions.
27 *
28 * Level 2 descriptor (PMD).
29 */
30#define PMD_TYPE_MASK (_AT(pmdval_t, 3) << 0)
31#define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0)
32#define PMD_TYPE_TABLE (_AT(pmdval_t, 3) << 0)
33#define PMD_TYPE_SECT (_AT(pmdval_t, 1) << 0)
34
35/*
36 * Section
37 */
38#define PMD_SECT_S (_AT(pmdval_t, 3) << 8)
39#define PMD_SECT_AF (_AT(pmdval_t, 1) << 10)
40#define PMD_SECT_NG (_AT(pmdval_t, 1) << 11)
41#define PMD_SECT_XN (_AT(pmdval_t, 1) << 54)
42
43/*
44 * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
45 */
46#define PMD_ATTRINDX(t) (_AT(pmdval_t, (t)) << 2)
47#define PMD_ATTRINDX_MASK (_AT(pmdval_t, 7) << 2)
48
49/*
50 * Level 3 descriptor (PTE).
51 */
52#define PTE_TYPE_MASK (_AT(pteval_t, 3) << 0)
53#define PTE_TYPE_FAULT (_AT(pteval_t, 0) << 0)
54#define PTE_TYPE_PAGE (_AT(pteval_t, 3) << 0)
55#define PTE_USER (_AT(pteval_t, 1) << 6) /* AP[1] */
56#define PTE_RDONLY (_AT(pteval_t, 1) << 7) /* AP[2] */
57#define PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */
58#define PTE_AF (_AT(pteval_t, 1) << 10) /* Access Flag */
59#define PTE_NG (_AT(pteval_t, 1) << 11) /* nG */
60#define PTE_XN (_AT(pteval_t, 1) << 54) /* XN */
61
62/*
63 * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
64 */
65#define PTE_ATTRINDX(t) (_AT(pteval_t, (t)) << 2)
66#define PTE_ATTRINDX_MASK (_AT(pteval_t, 7) << 2)
67
68/*
69 * 40-bit physical address supported.
70 */
71#define PHYS_MASK_SHIFT (40)
72#define PHYS_MASK ((UL(1) << PHYS_MASK_SHIFT) - 1)
73
74/*
75 * TCR flags.
76 */
77#define TCR_TxSZ(x) (((UL(64) - (x)) << 16) | ((UL(64) - (x)) << 0))
78#define TCR_IRGN_NC ((UL(0) << 8) | (UL(0) << 24))
79#define TCR_IRGN_WBWA ((UL(1) << 8) | (UL(1) << 24))
80#define TCR_IRGN_WT ((UL(2) << 8) | (UL(2) << 24))
81#define TCR_IRGN_WBnWA ((UL(3) << 8) | (UL(3) << 24))
82#define TCR_IRGN_MASK ((UL(3) << 8) | (UL(3) << 24))
83#define TCR_ORGN_NC ((UL(0) << 10) | (UL(0) << 26))
84#define TCR_ORGN_WBWA ((UL(1) << 10) | (UL(1) << 26))
85#define TCR_ORGN_WT ((UL(2) << 10) | (UL(2) << 26))
86#define TCR_ORGN_WBnWA ((UL(3) << 10) | (UL(3) << 26))
87#define TCR_ORGN_MASK ((UL(3) << 10) | (UL(3) << 26))
88#define TCR_SHARED ((UL(3) << 12) | (UL(3) << 28))
89#define TCR_TG0_64K (UL(1) << 14)
90#define TCR_TG1_64K (UL(1) << 30)
91#define TCR_IPS_40BIT (UL(2) << 32)
92#define TCR_ASID16 (UL(1) << 36)
93
94#endif
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
new file mode 100644
index 000000000000..8960239be722
--- /dev/null
+++ b/arch/arm64/include/asm/pgtable.h
@@ -0,0 +1,328 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_PGTABLE_H
17#define __ASM_PGTABLE_H
18
19#include <asm/proc-fns.h>
20
21#include <asm/memory.h>
22#include <asm/pgtable-hwdef.h>
23
24/*
25 * Software defined PTE bits definition.
26 */
27#define PTE_VALID (_AT(pteval_t, 1) << 0) /* pte_present() check */
28#define PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !pte_present() */
29#define PTE_DIRTY (_AT(pteval_t, 1) << 55)
30#define PTE_SPECIAL (_AT(pteval_t, 1) << 56)
31
32/*
33 * VMALLOC and SPARSEMEM_VMEMMAP ranges.
34 */
35#define VMALLOC_START UL(0xffffff8000000000)
36#define VMALLOC_END (PAGE_OFFSET - UL(0x400000000) - SZ_64K)
37
38#define vmemmap ((struct page *)(VMALLOC_END + SZ_64K))
39
40#define FIRST_USER_ADDRESS 0
41
42#ifndef __ASSEMBLY__
43extern void __pte_error(const char *file, int line, unsigned long val);
44extern void __pmd_error(const char *file, int line, unsigned long val);
45extern void __pgd_error(const char *file, int line, unsigned long val);
46
47#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte))
48#ifndef CONFIG_ARM64_64K_PAGES
49#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd_val(pmd))
50#endif
51#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd))
52
53/*
54 * The pgprot_* and protection_map entries will be fixed up at runtime to
55 * include the cachable and bufferable bits based on memory policy, as well as
56 * any architecture dependent bits like global/ASID and SMP shared mapping
57 * bits.
58 */
59#define _PAGE_DEFAULT PTE_TYPE_PAGE | PTE_AF
60
61extern pgprot_t pgprot_default;
62
63#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b))
64
65#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_XN | PTE_RDONLY)
66#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN)
67#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG)
68#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY)
69#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY)
70#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY)
71#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY)
72#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_XN | PTE_DIRTY)
73#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_DIRTY)
74
75#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_XN | PTE_RDONLY)
76#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN)
77#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG)
78#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY)
79#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY)
80#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY)
81#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY)
82
83#endif /* __ASSEMBLY__ */
84
85#define __P000 __PAGE_NONE
86#define __P001 __PAGE_READONLY
87#define __P010 __PAGE_COPY
88#define __P011 __PAGE_COPY
89#define __P100 __PAGE_READONLY_EXEC
90#define __P101 __PAGE_READONLY_EXEC
91#define __P110 __PAGE_COPY_EXEC
92#define __P111 __PAGE_COPY_EXEC
93
94#define __S000 __PAGE_NONE
95#define __S001 __PAGE_READONLY
96#define __S010 __PAGE_SHARED
97#define __S011 __PAGE_SHARED
98#define __S100 __PAGE_READONLY_EXEC
99#define __S101 __PAGE_READONLY_EXEC
100#define __S110 __PAGE_SHARED_EXEC
101#define __S111 __PAGE_SHARED_EXEC
102
103#ifndef __ASSEMBLY__
104/*
105 * ZERO_PAGE is a global shared page that is always zero: used
106 * for zero-mapped memory areas etc..
107 */
108extern struct page *empty_zero_page;
109#define ZERO_PAGE(vaddr) (empty_zero_page)
110
111#define pte_pfn(pte) ((pte_val(pte) & PHYS_MASK) >> PAGE_SHIFT)
112
113#define pfn_pte(pfn,prot) (__pte(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
114
115#define pte_none(pte) (!pte_val(pte))
116#define pte_clear(mm,addr,ptep) set_pte(ptep, __pte(0))
117#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
118#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
119
120#define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr))
121#define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir), (addr))
122#define pte_unmap(pte) do { } while (0)
123#define pte_unmap_nested(pte) do { } while (0)
124
125/*
126 * The following only work if pte_present(). Undefined behaviour otherwise.
127 */
128#define pte_present(pte) (pte_val(pte) & PTE_VALID)
129#define pte_dirty(pte) (pte_val(pte) & PTE_DIRTY)
130#define pte_young(pte) (pte_val(pte) & PTE_AF)
131#define pte_special(pte) (pte_val(pte) & PTE_SPECIAL)
132#define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY))
133#define pte_exec(pte) (!(pte_val(pte) & PTE_XN))
134
135#define pte_present_exec_user(pte) \
136 ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_XN)) == \
137 (PTE_VALID | PTE_USER))
138
139#define PTE_BIT_FUNC(fn,op) \
140static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
141
142PTE_BIT_FUNC(wrprotect, |= PTE_RDONLY);
143PTE_BIT_FUNC(mkwrite, &= ~PTE_RDONLY);
144PTE_BIT_FUNC(mkclean, &= ~PTE_DIRTY);
145PTE_BIT_FUNC(mkdirty, |= PTE_DIRTY);
146PTE_BIT_FUNC(mkold, &= ~PTE_AF);
147PTE_BIT_FUNC(mkyoung, |= PTE_AF);
148PTE_BIT_FUNC(mkspecial, |= PTE_SPECIAL);
149
150static inline void set_pte(pte_t *ptep, pte_t pte)
151{
152 *ptep = pte;
153}
154
155extern void __sync_icache_dcache(pte_t pteval, unsigned long addr);
156
157static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
158 pte_t *ptep, pte_t pte)
159{
160 if (pte_present_exec_user(pte))
161 __sync_icache_dcache(pte, addr);
162 set_pte(ptep, pte);
163}
164
165/*
166 * Huge pte definitions.
167 */
168#define pte_huge(pte) ((pte_val(pte) & PTE_TYPE_MASK) == PTE_TYPE_HUGEPAGE)
169#define pte_mkhuge(pte) (__pte((pte_val(pte) & ~PTE_TYPE_MASK) | PTE_TYPE_HUGEPAGE))
170
171#define __pgprot_modify(prot,mask,bits) \
172 __pgprot((pgprot_val(prot) & ~(mask)) | (bits))
173
174#define __HAVE_ARCH_PTE_SPECIAL
175
176/*
177 * Mark the prot value as uncacheable and unbufferable.
178 */
179#define pgprot_noncached(prot) \
180 __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE))
181#define pgprot_writecombine(prot) \
182 __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_GRE))
183#define pgprot_dmacoherent(prot) \
184 __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
185#define __HAVE_PHYS_MEM_ACCESS_PROT
186struct file;
187extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
188 unsigned long size, pgprot_t vma_prot);
189
190#define pmd_none(pmd) (!pmd_val(pmd))
191#define pmd_present(pmd) (pmd_val(pmd))
192
193#define pmd_bad(pmd) (!(pmd_val(pmd) & 2))
194
195static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
196{
197 *pmdp = pmd;
198 dsb();
199}
200
201static inline void pmd_clear(pmd_t *pmdp)
202{
203 set_pmd(pmdp, __pmd(0));
204}
205
206static inline pte_t *pmd_page_vaddr(pmd_t pmd)
207{
208 return __va(pmd_val(pmd) & PHYS_MASK & (s32)PAGE_MASK);
209}
210
211#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
212
213/*
214 * Conversion functions: convert a page and protection to a page entry,
215 * and a page entry and page directory to the page they refer to.
216 */
217#define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot)
218
219#ifndef CONFIG_ARM64_64K_PAGES
220
221#define pud_none(pud) (!pud_val(pud))
222#define pud_bad(pud) (!(pud_val(pud) & 2))
223#define pud_present(pud) (pud_val(pud))
224
225static inline void set_pud(pud_t *pudp, pud_t pud)
226{
227 *pudp = pud;
228 dsb();
229}
230
231static inline void pud_clear(pud_t *pudp)
232{
233 set_pud(pudp, __pud(0));
234}
235
236static inline pmd_t *pud_page_vaddr(pud_t pud)
237{
238 return __va(pud_val(pud) & PHYS_MASK & (s32)PAGE_MASK);
239}
240
241#endif /* CONFIG_ARM64_64K_PAGES */
242
243/* to find an entry in a page-table-directory */
244#define pgd_index(addr) (((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
245
246#define pgd_offset(mm, addr) ((mm)->pgd+pgd_index(addr))
247
248/* to find an entry in a kernel page-table-directory */
249#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
250
251/* Find an entry in the second-level page table.. */
252#ifndef CONFIG_ARM64_64K_PAGES
253#define pmd_index(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
254static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
255{
256 return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr);
257}
258#endif
259
260/* Find an entry in the third-level page table.. */
261#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
262
263static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
264{
265 const pteval_t mask = PTE_USER | PTE_XN | PTE_RDONLY;
266 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
267 return pte;
268}
269
270extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
271extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
272
273#define SWAPPER_DIR_SIZE (3 * PAGE_SIZE)
274#define IDMAP_DIR_SIZE (2 * PAGE_SIZE)
275
276/*
277 * Encode and decode a swap entry:
278 * bits 0-1: present (must be zero)
279 * bit 2: PTE_FILE
280 * bits 3-8: swap type
281 * bits 9-63: swap offset
282 */
283#define __SWP_TYPE_SHIFT 3
284#define __SWP_TYPE_BITS 6
285#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1)
286#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
287
288#define __swp_type(x) (((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK)
289#define __swp_offset(x) ((x).val >> __SWP_OFFSET_SHIFT)
290#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << __SWP_TYPE_SHIFT) | ((offset) << __SWP_OFFSET_SHIFT) })
291
292#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
293#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val })
294
295/*
296 * Ensure that there are not more swap files than can be encoded in the kernel
297 * the PTEs.
298 */
299#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS)
300
301/*
302 * Encode and decode a file entry:
303 * bits 0-1: present (must be zero)
304 * bit 2: PTE_FILE
305 * bits 3-63: file offset / PAGE_SIZE
306 */
307#define pte_file(pte) (pte_val(pte) & PTE_FILE)
308#define pte_to_pgoff(x) (pte_val(x) >> 3)
309#define pgoff_to_pte(x) __pte(((x) << 3) | PTE_FILE)
310
311#define PTE_FILE_MAX_BITS 61
312
313extern int kern_addr_valid(unsigned long addr);
314
315#include <asm-generic/pgtable.h>
316
317/*
318 * remap a physical page `pfn' of size `size' with page protection `prot'
319 * into virtual address `from'
320 */
321#define io_remap_pfn_range(vma,from,pfn,size,prot) \
322 remap_pfn_range(vma, from, pfn, size, prot)
323
324#define pgtable_cache_init() do { } while (0)
325
326#endif /* !__ASSEMBLY__ */
327
328#endif /* __ASM_PGTABLE_H */
diff --git a/arch/arm64/include/asm/pmu.h b/arch/arm64/include/asm/pmu.h
new file mode 100644
index 000000000000..e6f087806aaf
--- /dev/null
+++ b/arch/arm64/include/asm/pmu.h
@@ -0,0 +1,82 @@
1/*
2 * Based on arch/arm/include/asm/pmu.h
3 *
4 * Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef __ASM_PMU_H
20#define __ASM_PMU_H
21
22#ifdef CONFIG_HW_PERF_EVENTS
23
24/* The events for a given PMU register set. */
25struct pmu_hw_events {
26 /*
27 * The events that are active on the PMU for the given index.
28 */
29 struct perf_event **events;
30
31 /*
32 * A 1 bit for an index indicates that the counter is being used for
33 * an event. A 0 means that the counter can be used.
34 */
35 unsigned long *used_mask;
36
37 /*
38 * Hardware lock to serialize accesses to PMU registers. Needed for the
39 * read/modify/write sequences.
40 */
41 raw_spinlock_t pmu_lock;
42};
43
44struct arm_pmu {
45 struct pmu pmu;
46 cpumask_t active_irqs;
47 const char *name;
48 irqreturn_t (*handle_irq)(int irq_num, void *dev);
49 void (*enable)(struct hw_perf_event *evt, int idx);
50 void (*disable)(struct hw_perf_event *evt, int idx);
51 int (*get_event_idx)(struct pmu_hw_events *hw_events,
52 struct hw_perf_event *hwc);
53 int (*set_event_filter)(struct hw_perf_event *evt,
54 struct perf_event_attr *attr);
55 u32 (*read_counter)(int idx);
56 void (*write_counter)(int idx, u32 val);
57 void (*start)(void);
58 void (*stop)(void);
59 void (*reset)(void *);
60 int (*map_event)(struct perf_event *event);
61 int num_events;
62 atomic_t active_events;
63 struct mutex reserve_mutex;
64 u64 max_period;
65 struct platform_device *plat_device;
66 struct pmu_hw_events *(*get_hw_events)(void);
67};
68
69#define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))
70
71int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type);
72
73u64 armpmu_event_update(struct perf_event *event,
74 struct hw_perf_event *hwc,
75 int idx);
76
77int armpmu_event_set_period(struct perf_event *event,
78 struct hw_perf_event *hwc,
79 int idx);
80
81#endif /* CONFIG_HW_PERF_EVENTS */
82#endif /* __ASM_PMU_H */
diff --git a/arch/arm64/include/asm/proc-fns.h b/arch/arm64/include/asm/proc-fns.h
new file mode 100644
index 000000000000..7cdf466fd0c5
--- /dev/null
+++ b/arch/arm64/include/asm/proc-fns.h
@@ -0,0 +1,50 @@
1/*
2 * Based on arch/arm/include/asm/proc-fns.h
3 *
4 * Copyright (C) 1997-1999 Russell King
5 * Copyright (C) 2000 Deep Blue Solutions Ltd
6 * Copyright (C) 2012 ARM Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20#ifndef __ASM_PROCFNS_H
21#define __ASM_PROCFNS_H
22
23#ifdef __KERNEL__
24#ifndef __ASSEMBLY__
25
26#include <asm/page.h>
27
28struct mm_struct;
29
30extern void cpu_cache_off(void);
31extern void cpu_do_idle(void);
32extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
33extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
34
35#include <asm/memory.h>
36
37#define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm)
38
39#define cpu_get_pgd() \
40({ \
41 unsigned long pg; \
42 asm("mrs %0, ttbr0_el1\n" \
43 : "=r" (pg)); \
44 pg &= ~0xffff000000003ffful; \
45 (pgd_t *)phys_to_virt(pg); \
46})
47
48#endif /* __ASSEMBLY__ */
49#endif /* __KERNEL__ */
50#endif /* __ASM_PROCFNS_H */
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
new file mode 100644
index 000000000000..39a208a392f7
--- /dev/null
+++ b/arch/arm64/include/asm/processor.h
@@ -0,0 +1,175 @@
1/*
2 * Based on arch/arm/include/asm/processor.h
3 *
4 * Copyright (C) 1995-1999 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef __ASM_PROCESSOR_H
20#define __ASM_PROCESSOR_H
21
22/*
23 * Default implementation of macro that returns current
24 * instruction pointer ("program counter").
25 */
26#define current_text_addr() ({ __label__ _l; _l: &&_l;})
27
28#ifdef __KERNEL__
29
30#include <linux/string.h>
31
32#include <asm/fpsimd.h>
33#include <asm/hw_breakpoint.h>
34#include <asm/ptrace.h>
35#include <asm/types.h>
36
37#ifdef __KERNEL__
38#define STACK_TOP_MAX TASK_SIZE_64
39#ifdef CONFIG_COMPAT
40#define AARCH32_VECTORS_BASE 0xffff0000
41#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
42 AARCH32_VECTORS_BASE : STACK_TOP_MAX)
43#else
44#define STACK_TOP STACK_TOP_MAX
45#endif /* CONFIG_COMPAT */
46#endif /* __KERNEL__ */
47
48struct debug_info {
49 /* Have we suspended stepping by a debugger? */
50 int suspended_step;
51 /* Allow breakpoints and watchpoints to be disabled for this thread. */
52 int bps_disabled;
53 int wps_disabled;
54 /* Hardware breakpoints pinned to this task. */
55 struct perf_event *hbp_break[ARM_MAX_BRP];
56 struct perf_event *hbp_watch[ARM_MAX_WRP];
57};
58
59struct cpu_context {
60 unsigned long x19;
61 unsigned long x20;
62 unsigned long x21;
63 unsigned long x22;
64 unsigned long x23;
65 unsigned long x24;
66 unsigned long x25;
67 unsigned long x26;
68 unsigned long x27;
69 unsigned long x28;
70 unsigned long fp;
71 unsigned long sp;
72 unsigned long pc;
73};
74
75struct thread_struct {
76 struct cpu_context cpu_context; /* cpu context */
77 unsigned long tp_value;
78 struct fpsimd_state fpsimd_state;
79 unsigned long fault_address; /* fault info */
80 struct debug_info debug; /* debugging */
81};
82
83#define INIT_THREAD { }
84
85static inline void start_thread_common(struct pt_regs *regs, unsigned long pc)
86{
87 memset(regs, 0, sizeof(*regs));
88 regs->syscallno = ~0UL;
89 regs->pc = pc;
90}
91
92static inline void start_thread(struct pt_regs *regs, unsigned long pc,
93 unsigned long sp)
94{
95 unsigned long *stack = (unsigned long *)sp;
96
97 start_thread_common(regs, pc);
98 regs->pstate = PSR_MODE_EL0t;
99 regs->sp = sp;
100 regs->regs[2] = stack[2]; /* x2 (envp) */
101 regs->regs[1] = stack[1]; /* x1 (argv) */
102 regs->regs[0] = stack[0]; /* x0 (argc) */
103}
104
105#ifdef CONFIG_COMPAT
106static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc,
107 unsigned long sp)
108{
109 unsigned int *stack = (unsigned int *)sp;
110
111 start_thread_common(regs, pc);
112 regs->pstate = COMPAT_PSR_MODE_USR;
113 if (pc & 1)
114 regs->pstate |= COMPAT_PSR_T_BIT;
115 regs->compat_sp = sp;
116 regs->regs[2] = stack[2]; /* x2 (envp) */
117 regs->regs[1] = stack[1]; /* x1 (argv) */
118 regs->regs[0] = stack[0]; /* x0 (argc) */
119}
120#endif
121
122/* Forward declaration, a strange C thing */
123struct task_struct;
124
125/* Free all resources held by a thread. */
126extern void release_thread(struct task_struct *);
127
128/* Prepare to copy thread state - unlazy all lazy status */
129#define prepare_to_copy(tsk) do { } while (0)
130
131unsigned long get_wchan(struct task_struct *p);
132
133#define cpu_relax() barrier()
134
135/* Thread switching */
136extern struct task_struct *cpu_switch_to(struct task_struct *prev,
137 struct task_struct *next);
138
139/*
140 * Create a new kernel thread
141 */
142extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
143
144#define task_pt_regs(p) \
145 ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
146
147#define KSTK_EIP(tsk) task_pt_regs(tsk)->pc
148#define KSTK_ESP(tsk) task_pt_regs(tsk)->sp
149
150/*
151 * Prefetching support
152 */
153#define ARCH_HAS_PREFETCH
154static inline void prefetch(const void *ptr)
155{
156 asm volatile("prfm pldl1keep, %a0\n" : : "p" (ptr));
157}
158
159#define ARCH_HAS_PREFETCHW
160static inline void prefetchw(const void *ptr)
161{
162 asm volatile("prfm pstl1keep, %a0\n" : : "p" (ptr));
163}
164
165#define ARCH_HAS_SPINLOCK_PREFETCH
166static inline void spin_lock_prefetch(const void *x)
167{
168 prefetchw(x);
169}
170
171#define HAVE_ARCH_PICK_MMAP_LAYOUT
172
173#endif
174
175#endif /* __ASM_PROCESSOR_H */
diff --git a/arch/arm64/include/asm/prom.h b/arch/arm64/include/asm/prom.h
new file mode 100644
index 000000000000..68b90e682957
--- /dev/null
+++ b/arch/arm64/include/asm/prom.h
@@ -0,0 +1 @@
/* Empty for now */
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
new file mode 100644
index 000000000000..0fa5d6c9ef76
--- /dev/null
+++ b/arch/arm64/include/asm/ptrace.h
@@ -0,0 +1,207 @@
1/*
2 * Based on arch/arm/include/asm/ptrace.h
3 *
4 * Copyright (C) 1996-2003 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef __ASM_PTRACE_H
20#define __ASM_PTRACE_H
21
22#include <linux/types.h>
23
24#include <asm/hwcap.h>
25
26/* AArch32-specific ptrace requests */
27#define COMPAT_PTRACE_GETREGS 12
28#define COMPAT_PTRACE_SETREGS 13
29#define COMPAT_PTRACE_GET_THREAD_AREA 22
30#define COMPAT_PTRACE_SET_SYSCALL 23
31#define COMPAT_PTRACE_GETVFPREGS 27
32#define COMPAT_PTRACE_SETVFPREGS 28
33#define COMPAT_PTRACE_GETHBPREGS 29
34#define COMPAT_PTRACE_SETHBPREGS 30
35
36/*
37 * PSR bits
38 */
39#define PSR_MODE_EL0t 0x00000000
40#define PSR_MODE_EL1t 0x00000004
41#define PSR_MODE_EL1h 0x00000005
42#define PSR_MODE_EL2t 0x00000008
43#define PSR_MODE_EL2h 0x00000009
44#define PSR_MODE_EL3t 0x0000000c
45#define PSR_MODE_EL3h 0x0000000d
46#define PSR_MODE_MASK 0x0000000f
47
48/* AArch32 CPSR bits */
49#define PSR_MODE32_BIT 0x00000010
50#define COMPAT_PSR_MODE_USR 0x00000010
51#define COMPAT_PSR_T_BIT 0x00000020
52#define COMPAT_PSR_IT_MASK 0x0600fc00 /* If-Then execution state mask */
53
54/* AArch64 SPSR bits */
55#define PSR_F_BIT 0x00000040
56#define PSR_I_BIT 0x00000080
57#define PSR_A_BIT 0x00000100
58#define PSR_D_BIT 0x00000200
59#define PSR_Q_BIT 0x08000000
60#define PSR_V_BIT 0x10000000
61#define PSR_C_BIT 0x20000000
62#define PSR_Z_BIT 0x40000000
63#define PSR_N_BIT 0x80000000
64
65/*
66 * Groups of PSR bits
67 */
68#define PSR_f 0xff000000 /* Flags */
69#define PSR_s 0x00ff0000 /* Status */
70#define PSR_x 0x0000ff00 /* Extension */
71#define PSR_c 0x000000ff /* Control */
72
73/*
74 * These are 'magic' values for PTRACE_PEEKUSR that return info about where a
75 * process is located in memory.
76 */
77#define PT_TEXT_ADDR 0x10000
78#define PT_DATA_ADDR 0x10004
79#define PT_TEXT_END_ADDR 0x10008
80
81#ifndef __ASSEMBLY__
82
83/*
84 * User structures for general purpose, floating point and debug registers.
85 */
86struct user_pt_regs {
87 __u64 regs[31];
88 __u64 sp;
89 __u64 pc;
90 __u64 pstate;
91};
92
93struct user_fpsimd_state {
94 __uint128_t vregs[32];
95 __u32 fpsr;
96 __u32 fpcr;
97};
98
99struct user_hwdebug_state {
100 __u32 dbg_info;
101 struct {
102 __u64 addr;
103 __u32 ctrl;
104 } dbg_regs[16];
105};
106
107#ifdef __KERNEL__
108
109/* sizeof(struct user) for AArch32 */
110#define COMPAT_USER_SZ 296
111/* AArch32 uses x13 as the stack pointer... */
112#define compat_sp regs[13]
113/* ... and x14 as the link register. */
114#define compat_lr regs[14]
115
116/*
117 * This struct defines the way the registers are stored on the stack during an
118 * exception. Note that sizeof(struct pt_regs) has to be a multiple of 16 (for
119 * stack alignment). struct user_pt_regs must form a prefix of struct pt_regs.
120 */
121struct pt_regs {
122 union {
123 struct user_pt_regs user_regs;
124 struct {
125 u64 regs[31];
126 u64 sp;
127 u64 pc;
128 u64 pstate;
129 };
130 };
131 u64 orig_x0;
132 u64 syscallno;
133};
134
135#define arch_has_single_step() (1)
136
137#ifdef CONFIG_COMPAT
138#define compat_thumb_mode(regs) \
139 (((regs)->pstate & COMPAT_PSR_T_BIT))
140#else
141#define compat_thumb_mode(regs) (0)
142#endif
143
144#define user_mode(regs) \
145 (((regs)->pstate & PSR_MODE_MASK) == PSR_MODE_EL0t)
146
147#define compat_user_mode(regs) \
148 (((regs)->pstate & (PSR_MODE32_BIT | PSR_MODE_MASK)) == \
149 (PSR_MODE32_BIT | PSR_MODE_EL0t))
150
151#define processor_mode(regs) \
152 ((regs)->pstate & PSR_MODE_MASK)
153
154#define interrupts_enabled(regs) \
155 (!((regs)->pstate & PSR_I_BIT))
156
157#define fast_interrupts_enabled(regs) \
158 (!((regs)->pstate & PSR_F_BIT))
159
160#define user_stack_pointer(regs) \
161 ((regs)->sp)
162
163/*
164 * Are the current registers suitable for user mode? (used to maintain
165 * security in signal handlers)
166 */
167static inline int valid_user_regs(struct user_pt_regs *regs)
168{
169 if (user_mode(regs) && (regs->pstate & PSR_I_BIT) == 0) {
170 regs->pstate &= ~(PSR_F_BIT | PSR_A_BIT);
171
172 /* The T bit is reserved for AArch64 */
173 if (!(regs->pstate & PSR_MODE32_BIT))
174 regs->pstate &= ~COMPAT_PSR_T_BIT;
175
176 return 1;
177 }
178
179 /*
180 * Force PSR to something logical...
181 */
182 regs->pstate &= PSR_f | PSR_s | (PSR_x & ~PSR_A_BIT) | \
183 COMPAT_PSR_T_BIT | PSR_MODE32_BIT;
184
185 if (!(regs->pstate & PSR_MODE32_BIT)) {
186 regs->pstate &= ~COMPAT_PSR_T_BIT;
187 regs->pstate |= PSR_MODE_EL0t;
188 }
189
190 return 0;
191}
192
193#define instruction_pointer(regs) (regs)->pc
194
195#ifdef CONFIG_SMP
196extern unsigned long profile_pc(struct pt_regs *regs);
197#else
198#define profile_pc(regs) instruction_pointer(regs)
199#endif
200
201extern int aarch32_break_trap(struct pt_regs *regs);
202
203#endif /* __KERNEL__ */
204
205#endif /* __ASSEMBLY__ */
206
207#endif
diff --git a/arch/arm64/include/asm/setup.h b/arch/arm64/include/asm/setup.h
new file mode 100644
index 000000000000..9cf2e46fbbdf
--- /dev/null
+++ b/arch/arm64/include/asm/setup.h
@@ -0,0 +1,26 @@
1/*
2 * Based on arch/arm/include/asm/setup.h
3 *
4 * Copyright (C) 1997-1999 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef __ASM_SETUP_H
20#define __ASM_SETUP_H
21
22#include <linux/types.h>
23
24#define COMMAND_LINE_SIZE 2048
25
26#endif
diff --git a/arch/arm64/include/asm/shmparam.h b/arch/arm64/include/asm/shmparam.h
new file mode 100644
index 000000000000..4df608a8459e
--- /dev/null
+++ b/arch/arm64/include/asm/shmparam.h
@@ -0,0 +1,28 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_SHMPARAM_H
17#define __ASM_SHMPARAM_H
18
19/*
20 * For IPC syscalls from compat tasks, we need to use the legacy 16k
21 * alignment value. Since we don't have aliasing D-caches, the rest of
22 * the time we can safely use PAGE_SIZE.
23 */
24#define COMPAT_SHMLBA 0x4000
25
26#include <asm-generic/shmparam.h>
27
28#endif /* __ASM_SHMPARAM_H */
diff --git a/arch/arm64/include/asm/sigcontext.h b/arch/arm64/include/asm/sigcontext.h
new file mode 100644
index 000000000000..573cec778819
--- /dev/null
+++ b/arch/arm64/include/asm/sigcontext.h
@@ -0,0 +1,69 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_SIGCONTEXT_H
17#define __ASM_SIGCONTEXT_H
18
19#include <linux/types.h>
20
21/*
22 * Signal context structure - contains all info to do with the state
23 * before the signal handler was invoked.
24 */
25struct sigcontext {
26 __u64 fault_address;
27 /* AArch64 registers */
28 __u64 regs[31];
29 __u64 sp;
30 __u64 pc;
31 __u64 pstate;
32 /* 4K reserved for FP/SIMD state and future expansion */
33 __u8 __reserved[4096] __attribute__((__aligned__(16)));
34};
35
36/*
37 * Header to be used at the beginning of structures extending the user
38 * context. Such structures must be placed after the rt_sigframe on the stack
39 * and be 16-byte aligned. The last structure must be a dummy one with the
40 * magic and size set to 0.
41 */
42struct _aarch64_ctx {
43 __u32 magic;
44 __u32 size;
45};
46
47#define FPSIMD_MAGIC 0x46508001
48
49struct fpsimd_context {
50 struct _aarch64_ctx head;
51 __u32 fpsr;
52 __u32 fpcr;
53 __uint128_t vregs[32];
54};
55
56#ifdef __KERNEL__
57/*
58 * Auxiliary context saved in the sigcontext.__reserved array. Not exported to
59 * user space as it will change with the addition of new context. User space
60 * should check the magic/size information.
61 */
62struct aux_context {
63 struct fpsimd_context fpsimd;
64 /* additional context to be added before "end" */
65 struct _aarch64_ctx end;
66};
67#endif
68
69#endif
diff --git a/arch/arm64/include/asm/siginfo.h b/arch/arm64/include/asm/siginfo.h
new file mode 100644
index 000000000000..5a74a0853db0
--- /dev/null
+++ b/arch/arm64/include/asm/siginfo.h
@@ -0,0 +1,23 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_SIGINFO_H
17#define __ASM_SIGINFO_H
18
19#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
20
21#include <asm-generic/siginfo.h>
22
23#endif
diff --git a/arch/arm64/include/asm/signal.h b/arch/arm64/include/asm/signal.h
new file mode 100644
index 000000000000..8d1e7236431b
--- /dev/null
+++ b/arch/arm64/include/asm/signal.h
@@ -0,0 +1,24 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_SIGNAL_H
17#define __ASM_SIGNAL_H
18
19/* Required for AArch32 compatibility. */
20#define SA_RESTORER 0x04000000
21
22#include <asm-generic/signal.h>
23
24#endif
diff --git a/arch/arm64/include/asm/signal32.h b/arch/arm64/include/asm/signal32.h
new file mode 100644
index 000000000000..7c275e3b640f
--- /dev/null
+++ b/arch/arm64/include/asm/signal32.h
@@ -0,0 +1,53 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_SIGNAL32_H
17#define __ASM_SIGNAL32_H
18
19#ifdef __KERNEL__
20#ifdef CONFIG_COMPAT
21#include <linux/compat.h>
22
23#define AARCH32_KERN_SIGRET_CODE_OFFSET 0x500
24
25extern const compat_ulong_t aarch32_sigret_code[6];
26
27int compat_setup_frame(int usig, struct k_sigaction *ka, sigset_t *set,
28 struct pt_regs *regs);
29int compat_setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
30 sigset_t *set, struct pt_regs *regs);
31
32void compat_setup_restart_syscall(struct pt_regs *regs);
33#else
34
35static inline int compat_setup_frame(int usid, struct k_sigaction *ka,
36 sigset_t *set, struct pt_regs *regs)
37{
38 return -ENOSYS;
39}
40
41static inline int compat_setup_rt_frame(int usig, struct k_sigaction *ka,
42 siginfo_t *info, sigset_t *set,
43 struct pt_regs *regs)
44{
45 return -ENOSYS;
46}
47
48static inline void compat_setup_restart_syscall(struct pt_regs *regs)
49{
50}
51#endif /* CONFIG_COMPAT */
52#endif /* __KERNEL__ */
53#endif /* __ASM_SIGNAL32_H */
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
new file mode 100644
index 000000000000..7e34295f78e3
--- /dev/null
+++ b/arch/arm64/include/asm/smp.h
@@ -0,0 +1,69 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_SMP_H
17#define __ASM_SMP_H
18
19#include <linux/threads.h>
20#include <linux/cpumask.h>
21#include <linux/thread_info.h>
22
23#ifndef CONFIG_SMP
24# error "<asm/smp.h> included in non-SMP build"
25#endif
26
27#define raw_smp_processor_id() (current_thread_info()->cpu)
28
29struct seq_file;
30
31/*
32 * generate IPI list text
33 */
34extern void show_ipi_list(struct seq_file *p, int prec);
35
36/*
37 * Called from C code, this handles an IPI.
38 */
39extern void handle_IPI(int ipinr, struct pt_regs *regs);
40
41/*
42 * Setup the set of possible CPUs (via set_cpu_possible)
43 */
44extern void smp_init_cpus(void);
45
46/*
47 * Provide a function to raise an IPI cross call on CPUs in callmap.
48 */
49extern void set_smp_cross_call(void (*)(const struct cpumask *, unsigned int));
50
51/*
52 * Called from the secondary holding pen, this is the secondary CPU entry point.
53 */
54asmlinkage void secondary_start_kernel(void);
55
56/*
57 * Initial data for bringing up a secondary CPU.
58 */
59struct secondary_data {
60 void *stack;
61};
62extern struct secondary_data secondary_data;
63extern void secondary_holding_pen(void);
64extern volatile unsigned long secondary_holding_pen_release;
65
66extern void arch_send_call_function_single_ipi(int cpu);
67extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
68
69#endif /* ifndef __ASM_SMP_H */
diff --git a/arch/arm64/include/asm/sparsemem.h b/arch/arm64/include/asm/sparsemem.h
new file mode 100644
index 000000000000..1be62bcb9d47
--- /dev/null
+++ b/arch/arm64/include/asm/sparsemem.h
@@ -0,0 +1,24 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_SPARSEMEM_H
17#define __ASM_SPARSEMEM_H
18
19#ifdef CONFIG_SPARSEMEM
20#define MAX_PHYSMEM_BITS 40
21#define SECTION_SIZE_BITS 30
22#endif
23
24#endif
diff --git a/arch/arm64/include/asm/spinlock.h b/arch/arm64/include/asm/spinlock.h
new file mode 100644
index 000000000000..41112fe2f8b1
--- /dev/null
+++ b/arch/arm64/include/asm/spinlock.h
@@ -0,0 +1,202 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_SPINLOCK_H
17#define __ASM_SPINLOCK_H
18
19#include <asm/spinlock_types.h>
20#include <asm/processor.h>
21
22/*
23 * Spinlock implementation.
24 *
25 * The old value is read exclusively and the new one, if unlocked, is written
26 * exclusively. In case of failure, the loop is restarted.
27 *
28 * The memory barriers are implicit with the load-acquire and store-release
29 * instructions.
30 *
31 * Unlocked value: 0
32 * Locked value: 1
33 */
34
35#define arch_spin_is_locked(x) ((x)->lock != 0)
36#define arch_spin_unlock_wait(lock) \
37 do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0)
38
39#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
40
41static inline void arch_spin_lock(arch_spinlock_t *lock)
42{
43 unsigned int tmp;
44
45 asm volatile(
46 " sevl\n"
47 "1: wfe\n"
48 "2: ldaxr %w0, [%1]\n"
49 " cbnz %w0, 1b\n"
50 " stxr %w0, %w2, [%1]\n"
51 " cbnz %w0, 2b\n"
52 : "=&r" (tmp)
53 : "r" (&lock->lock), "r" (1)
54 : "memory");
55}
56
57static inline int arch_spin_trylock(arch_spinlock_t *lock)
58{
59 unsigned int tmp;
60
61 asm volatile(
62 " ldaxr %w0, [%1]\n"
63 " cbnz %w0, 1f\n"
64 " stxr %w0, %w2, [%1]\n"
65 "1:\n"
66 : "=&r" (tmp)
67 : "r" (&lock->lock), "r" (1)
68 : "memory");
69
70 return !tmp;
71}
72
73static inline void arch_spin_unlock(arch_spinlock_t *lock)
74{
75 asm volatile(
76 " stlr %w1, [%0]\n"
77 : : "r" (&lock->lock), "r" (0) : "memory");
78}
79
80/*
81 * Write lock implementation.
82 *
83 * Write locks set bit 31. Unlocking, is done by writing 0 since the lock is
84 * exclusively held.
85 *
86 * The memory barriers are implicit with the load-acquire and store-release
87 * instructions.
88 */
89
90static inline void arch_write_lock(arch_rwlock_t *rw)
91{
92 unsigned int tmp;
93
94 asm volatile(
95 " sevl\n"
96 "1: wfe\n"
97 "2: ldaxr %w0, [%1]\n"
98 " cbnz %w0, 1b\n"
99 " stxr %w0, %w2, [%1]\n"
100 " cbnz %w0, 2b\n"
101 : "=&r" (tmp)
102 : "r" (&rw->lock), "r" (0x80000000)
103 : "memory");
104}
105
106static inline int arch_write_trylock(arch_rwlock_t *rw)
107{
108 unsigned int tmp;
109
110 asm volatile(
111 " ldaxr %w0, [%1]\n"
112 " cbnz %w0, 1f\n"
113 " stxr %w0, %w2, [%1]\n"
114 "1:\n"
115 : "=&r" (tmp)
116 : "r" (&rw->lock), "r" (0x80000000)
117 : "memory");
118
119 return !tmp;
120}
121
122static inline void arch_write_unlock(arch_rwlock_t *rw)
123{
124 asm volatile(
125 " stlr %w1, [%0]\n"
126 : : "r" (&rw->lock), "r" (0) : "memory");
127}
128
129/* write_can_lock - would write_trylock() succeed? */
130#define arch_write_can_lock(x) ((x)->lock == 0)
131
132/*
133 * Read lock implementation.
134 *
135 * It exclusively loads the lock value, increments it and stores the new value
136 * back if positive and the CPU still exclusively owns the location. If the
137 * value is negative, the lock is already held.
138 *
139 * During unlocking there may be multiple active read locks but no write lock.
140 *
141 * The memory barriers are implicit with the load-acquire and store-release
142 * instructions.
143 */
144static inline void arch_read_lock(arch_rwlock_t *rw)
145{
146 unsigned int tmp, tmp2;
147
148 asm volatile(
149 " sevl\n"
150 "1: wfe\n"
151 "2: ldaxr %w0, [%2]\n"
152 " add %w0, %w0, #1\n"
153 " tbnz %w0, #31, 1b\n"
154 " stxr %w1, %w0, [%2]\n"
155 " cbnz %w1, 2b\n"
156 : "=&r" (tmp), "=&r" (tmp2)
157 : "r" (&rw->lock)
158 : "memory");
159}
160
161static inline void arch_read_unlock(arch_rwlock_t *rw)
162{
163 unsigned int tmp, tmp2;
164
165 asm volatile(
166 "1: ldxr %w0, [%2]\n"
167 " sub %w0, %w0, #1\n"
168 " stlxr %w1, %w0, [%2]\n"
169 " cbnz %w1, 1b\n"
170 : "=&r" (tmp), "=&r" (tmp2)
171 : "r" (&rw->lock)
172 : "memory");
173}
174
175static inline int arch_read_trylock(arch_rwlock_t *rw)
176{
177 unsigned int tmp, tmp2 = 1;
178
179 asm volatile(
180 " ldaxr %w0, [%2]\n"
181 " add %w0, %w0, #1\n"
182 " tbnz %w0, #31, 1f\n"
183 " stxr %w1, %w0, [%2]\n"
184 "1:\n"
185 : "=&r" (tmp), "+r" (tmp2)
186 : "r" (&rw->lock)
187 : "memory");
188
189 return !tmp2;
190}
191
192/* read_can_lock - would read_trylock() succeed? */
193#define arch_read_can_lock(x) ((x)->lock < 0x80000000)
194
195#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
196#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
197
198#define arch_spin_relax(lock) cpu_relax()
199#define arch_read_relax(lock) cpu_relax()
200#define arch_write_relax(lock) cpu_relax()
201
202#endif /* __ASM_SPINLOCK_H */
diff --git a/arch/arm64/include/asm/spinlock_types.h b/arch/arm64/include/asm/spinlock_types.h
new file mode 100644
index 000000000000..9a494346efed
--- /dev/null
+++ b/arch/arm64/include/asm/spinlock_types.h
@@ -0,0 +1,38 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_SPINLOCK_TYPES_H
17#define __ASM_SPINLOCK_TYPES_H
18
19#if !defined(__LINUX_SPINLOCK_TYPES_H) && !defined(__ASM_SPINLOCK_H)
20# error "please don't include this file directly"
21#endif
22
23/* We only require natural alignment for exclusive accesses. */
24#define __lock_aligned
25
26typedef struct {
27 volatile unsigned int lock;
28} arch_spinlock_t;
29
30#define __ARCH_SPIN_LOCK_UNLOCKED { 0 }
31
32typedef struct {
33 volatile unsigned int lock;
34} arch_rwlock_t;
35
36#define __ARCH_RW_LOCK_UNLOCKED { 0 }
37
38#endif
diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
new file mode 100644
index 000000000000..7318f6d54aa9
--- /dev/null
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_STACKTRACE_H
17#define __ASM_STACKTRACE_H
18
19struct stackframe {
20 unsigned long fp;
21 unsigned long sp;
22 unsigned long pc;
23};
24
25extern int unwind_frame(struct stackframe *frame);
26extern void walk_stackframe(struct stackframe *frame,
27 int (*fn)(struct stackframe *, void *), void *data);
28
29#endif /* __ASM_STACKTRACE_H */
diff --git a/arch/arm64/include/asm/stat.h b/arch/arm64/include/asm/stat.h
new file mode 100644
index 000000000000..d87225cbead8
--- /dev/null
+++ b/arch/arm64/include/asm/stat.h
@@ -0,0 +1,62 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_STAT_H
17#define __ASM_STAT_H
18
19#include <asm-generic/stat.h>
20
21#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
22
23#include <asm/compat.h>
24
25/*
26 * struct stat64 is needed for compat tasks only. Its definition is different
27 * from the generic struct stat64.
28 */
29struct stat64 {
30 compat_u64 st_dev;
31 unsigned char __pad0[4];
32
33#define STAT64_HAS_BROKEN_ST_INO 1
34 compat_ulong_t __st_ino;
35 compat_uint_t st_mode;
36 compat_uint_t st_nlink;
37
38 compat_ulong_t st_uid;
39 compat_ulong_t st_gid;
40
41 compat_u64 st_rdev;
42 unsigned char __pad3[4];
43
44 compat_s64 st_size;
45 compat_ulong_t st_blksize;
46 compat_u64 st_blocks; /* Number of 512-byte blocks allocated. */
47
48 compat_ulong_t st_atime;
49 compat_ulong_t st_atime_nsec;
50
51 compat_ulong_t st_mtime;
52 compat_ulong_t st_mtime_nsec;
53
54 compat_ulong_t st_ctime;
55 compat_ulong_t st_ctime_nsec;
56
57 compat_u64 st_ino;
58};
59
60#endif
61
62#endif
diff --git a/arch/arm64/include/asm/statfs.h b/arch/arm64/include/asm/statfs.h
new file mode 100644
index 000000000000..6f6219050978
--- /dev/null
+++ b/arch/arm64/include/asm/statfs.h
@@ -0,0 +1,23 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_STATFS_H
17#define __ASM_STATFS_H
18
19#define ARCH_PACK_COMPAT_STATFS64 __attribute__((packed,aligned(4)))
20
21#include <asm-generic/statfs.h>
22
23#endif
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
new file mode 100644
index 000000000000..89c047f9a971
--- /dev/null
+++ b/arch/arm64/include/asm/syscall.h
@@ -0,0 +1,101 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_SYSCALL_H
17#define __ASM_SYSCALL_H
18
19#include <linux/err.h>
20
21
22static inline int syscall_get_nr(struct task_struct *task,
23 struct pt_regs *regs)
24{
25 return regs->syscallno;
26}
27
28static inline void syscall_rollback(struct task_struct *task,
29 struct pt_regs *regs)
30{
31 regs->regs[0] = regs->orig_x0;
32}
33
34
35static inline long syscall_get_error(struct task_struct *task,
36 struct pt_regs *regs)
37{
38 unsigned long error = regs->regs[0];
39 return IS_ERR_VALUE(error) ? error : 0;
40}
41
42static inline long syscall_get_return_value(struct task_struct *task,
43 struct pt_regs *regs)
44{
45 return regs->regs[0];
46}
47
48static inline void syscall_set_return_value(struct task_struct *task,
49 struct pt_regs *regs,
50 int error, long val)
51{
52 regs->regs[0] = (long) error ? error : val;
53}
54
55#define SYSCALL_MAX_ARGS 6
56
57static inline void syscall_get_arguments(struct task_struct *task,
58 struct pt_regs *regs,
59 unsigned int i, unsigned int n,
60 unsigned long *args)
61{
62 if (i + n > SYSCALL_MAX_ARGS) {
63 unsigned long *args_bad = args + SYSCALL_MAX_ARGS - i;
64 unsigned int n_bad = n + i - SYSCALL_MAX_ARGS;
65 pr_warning("%s called with max args %d, handling only %d\n",
66 __func__, i + n, SYSCALL_MAX_ARGS);
67 memset(args_bad, 0, n_bad * sizeof(args[0]));
68 }
69
70 if (i == 0) {
71 args[0] = regs->orig_x0;
72 args++;
73 i++;
74 n--;
75 }
76
77 memcpy(args, &regs->regs[i], n * sizeof(args[0]));
78}
79
80static inline void syscall_set_arguments(struct task_struct *task,
81 struct pt_regs *regs,
82 unsigned int i, unsigned int n,
83 const unsigned long *args)
84{
85 if (i + n > SYSCALL_MAX_ARGS) {
86 pr_warning("%s called with max args %d, handling only %d\n",
87 __func__, i + n, SYSCALL_MAX_ARGS);
88 n = SYSCALL_MAX_ARGS - i;
89 }
90
91 if (i == 0) {
92 regs->orig_x0 = args[0];
93 args++;
94 i++;
95 n--;
96 }
97
98 memcpy(&regs->regs[i], args, n * sizeof(args[0]));
99}
100
101#endif /* __ASM_SYSCALL_H */
diff --git a/arch/arm64/include/asm/syscalls.h b/arch/arm64/include/asm/syscalls.h
new file mode 100644
index 000000000000..09ff33572aab
--- /dev/null
+++ b/arch/arm64/include/asm/syscalls.h
@@ -0,0 +1,40 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_SYSCALLS_H
17#define __ASM_SYSCALLS_H
18
19#include <linux/linkage.h>
20#include <linux/compiler.h>
21#include <linux/signal.h>
22
23/*
24 * System call wrappers implemented in kernel/entry.S.
25 */
26asmlinkage long sys_execve_wrapper(const char __user *filename,
27 const char __user *const __user *argv,
28 const char __user *const __user *envp);
29asmlinkage long sys_clone_wrapper(unsigned long clone_flags,
30 unsigned long newsp,
31 void __user *parent_tid,
32 unsigned long tls_val,
33 void __user *child_tid);
34asmlinkage long sys_rt_sigreturn_wrapper(void);
35asmlinkage long sys_sigaltstack_wrapper(const stack_t __user *uss,
36 stack_t __user *uoss);
37
38#include <asm-generic/syscalls.h>
39
40#endif /* __ASM_SYSCALLS_H */
diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h
new file mode 100644
index 000000000000..95e407255347
--- /dev/null
+++ b/arch/arm64/include/asm/system_misc.h
@@ -0,0 +1,54 @@
1/*
2 * Based on arch/arm/include/asm/system_misc.h
3 *
4 * Copyright (C) 2012 ARM Ltd.
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#ifndef __ASM_SYSTEM_MISC_H
19#define __ASM_SYSTEM_MISC_H
20
21#ifndef __ASSEMBLY__
22
23#include <linux/compiler.h>
24#include <linux/linkage.h>
25#include <linux/irqflags.h>
26
27struct pt_regs;
28
29void die(const char *msg, struct pt_regs *regs, int err);
30
31struct siginfo;
32void arm64_notify_die(const char *str, struct pt_regs *regs,
33 struct siginfo *info, int err);
34
35void hook_debug_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
36 struct pt_regs *),
37 int sig, int code, const char *name);
38
39struct mm_struct;
40extern void show_pte(struct mm_struct *mm, unsigned long addr);
41extern void __show_regs(struct pt_regs *);
42
43void soft_restart(unsigned long);
44extern void (*pm_restart)(const char *cmd);
45
46#define UDBG_UNDEFINED (1 << 0)
47#define UDBG_SYSCALL (1 << 1)
48#define UDBG_BADABORT (1 << 2)
49#define UDBG_SEGV (1 << 3)
50#define UDBG_BUS (1 << 4)
51
52#endif /* __ASSEMBLY__ */
53
54#endif /* __ASM_SYSTEM_MISC_H */
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
new file mode 100644
index 000000000000..3659e460071d
--- /dev/null
+++ b/arch/arm64/include/asm/thread_info.h
@@ -0,0 +1,127 @@
1/*
2 * Based on arch/arm/include/asm/thread_info.h
3 *
4 * Copyright (C) 2002 Russell King.
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef __ASM_THREAD_INFO_H
20#define __ASM_THREAD_INFO_H
21
22#ifdef __KERNEL__
23
24#include <linux/compiler.h>
25
26#ifndef CONFIG_ARM64_64K_PAGES
27#define THREAD_SIZE_ORDER 1
28#endif
29
30#define THREAD_SIZE 8192
31#define THREAD_START_SP (THREAD_SIZE - 16)
32
33#ifndef __ASSEMBLY__
34
35struct task_struct;
36struct exec_domain;
37
38#include <asm/types.h>
39
40typedef unsigned long mm_segment_t;
41
42/*
43 * low level task data that entry.S needs immediate access to.
44 * __switch_to() assumes cpu_context follows immediately after cpu_domain.
45 */
46struct thread_info {
47 unsigned long flags; /* low level flags */
48 mm_segment_t addr_limit; /* address limit */
49 struct task_struct *task; /* main task structure */
50 struct exec_domain *exec_domain; /* execution domain */
51 struct restart_block restart_block;
52 int preempt_count; /* 0 => preemptable, <0 => bug */
53 int cpu; /* cpu */
54};
55
56#define INIT_THREAD_INFO(tsk) \
57{ \
58 .task = &tsk, \
59 .exec_domain = &default_exec_domain, \
60 .flags = 0, \
61 .preempt_count = INIT_PREEMPT_COUNT, \
62 .addr_limit = KERNEL_DS, \
63 .restart_block = { \
64 .fn = do_no_restart_syscall, \
65 }, \
66}
67
68#define init_thread_info (init_thread_union.thread_info)
69#define init_stack (init_thread_union.stack)
70
71/*
72 * how to get the thread information struct from C
73 */
74static inline struct thread_info *current_thread_info(void) __attribute_const__;
75
76static inline struct thread_info *current_thread_info(void)
77{
78 register unsigned long sp asm ("sp");
79 return (struct thread_info *)(sp & ~(THREAD_SIZE - 1));
80}
81
82#define thread_saved_pc(tsk) \
83 ((unsigned long)(tsk->thread.cpu_context.pc))
84#define thread_saved_sp(tsk) \
85 ((unsigned long)(tsk->thread.cpu_context.sp))
86#define thread_saved_fp(tsk) \
87 ((unsigned long)(tsk->thread.cpu_context.fp))
88
89#endif
90
91/*
92 * We use bit 30 of the preempt_count to indicate that kernel
93 * preemption is occurring. See <asm/hardirq.h>.
94 */
95#define PREEMPT_ACTIVE 0x40000000
96
97/*
98 * thread information flags:
99 * TIF_SYSCALL_TRACE - syscall trace active
100 * TIF_SIGPENDING - signal pending
101 * TIF_NEED_RESCHED - rescheduling necessary
102 * TIF_NOTIFY_RESUME - callback before returning to user
103 * TIF_USEDFPU - FPU was used by this task this quantum (SMP)
104 * TIF_POLLING_NRFLAG - true if poll_idle() is polling TIF_NEED_RESCHED
105 */
106#define TIF_SIGPENDING 0
107#define TIF_NEED_RESCHED 1
108#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */
109#define TIF_SYSCALL_TRACE 8
110#define TIF_POLLING_NRFLAG 16
111#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
112#define TIF_FREEZE 19
113#define TIF_RESTORE_SIGMASK 20
114#define TIF_SINGLESTEP 21
115#define TIF_32BIT 22 /* 32bit process */
116#define TIF_SWITCH_MM 23 /* deferred switch_mm */
117
118#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
119#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
120#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
121#define _TIF_32BIT (1 << TIF_32BIT)
122
123#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
124 _TIF_NOTIFY_RESUME)
125
126#endif /* __KERNEL__ */
127#endif /* __ASM_THREAD_INFO_H */
diff --git a/arch/arm64/include/asm/timex.h b/arch/arm64/include/asm/timex.h
new file mode 100644
index 000000000000..b24a31a7e2c9
--- /dev/null
+++ b/arch/arm64/include/asm/timex.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_TIMEX_H
17#define __ASM_TIMEX_H
18
19/*
20 * Use the current timer as a cycle counter since this is what we use for
21 * the delay loop.
22 */
23#define get_cycles() ({ cycles_t c; read_current_timer(&c); c; })
24
25#include <asm-generic/timex.h>
26
27#define ARCH_HAS_READ_CURRENT_TIMER
28
29#endif
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
new file mode 100644
index 000000000000..654f0968030b
--- /dev/null
+++ b/arch/arm64/include/asm/tlb.h
@@ -0,0 +1,190 @@
1/*
2 * Based on arch/arm/include/asm/tlb.h
3 *
4 * Copyright (C) 2002 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef __ASM_TLB_H
20#define __ASM_TLB_H
21
22#include <linux/pagemap.h>
23#include <linux/swap.h>
24
25#include <asm/pgalloc.h>
26#include <asm/tlbflush.h>
27
28#define MMU_GATHER_BUNDLE 8
29
30/*
31 * TLB handling. This allows us to remove pages from the page
32 * tables, and efficiently handle the TLB issues.
33 */
34struct mmu_gather {
35 struct mm_struct *mm;
36 unsigned int fullmm;
37 struct vm_area_struct *vma;
38 unsigned long range_start;
39 unsigned long range_end;
40 unsigned int nr;
41 unsigned int max;
42 struct page **pages;
43 struct page *local[MMU_GATHER_BUNDLE];
44};
45
46/*
47 * This is unnecessarily complex. There's three ways the TLB shootdown
48 * code is used:
49 * 1. Unmapping a range of vmas. See zap_page_range(), unmap_region().
50 * tlb->fullmm = 0, and tlb_start_vma/tlb_end_vma will be called.
51 * tlb->vma will be non-NULL.
52 * 2. Unmapping all vmas. See exit_mmap().
53 * tlb->fullmm = 1, and tlb_start_vma/tlb_end_vma will be called.
54 * tlb->vma will be non-NULL. Additionally, page tables will be freed.
55 * 3. Unmapping argument pages. See shift_arg_pages().
56 * tlb->fullmm = 0, but tlb_start_vma/tlb_end_vma will not be called.
57 * tlb->vma will be NULL.
58 */
59static inline void tlb_flush(struct mmu_gather *tlb)
60{
61 if (tlb->fullmm || !tlb->vma)
62 flush_tlb_mm(tlb->mm);
63 else if (tlb->range_end > 0) {
64 flush_tlb_range(tlb->vma, tlb->range_start, tlb->range_end);
65 tlb->range_start = TASK_SIZE;
66 tlb->range_end = 0;
67 }
68}
69
70static inline void tlb_add_flush(struct mmu_gather *tlb, unsigned long addr)
71{
72 if (!tlb->fullmm) {
73 if (addr < tlb->range_start)
74 tlb->range_start = addr;
75 if (addr + PAGE_SIZE > tlb->range_end)
76 tlb->range_end = addr + PAGE_SIZE;
77 }
78}
79
80static inline void __tlb_alloc_page(struct mmu_gather *tlb)
81{
82 unsigned long addr = __get_free_pages(GFP_NOWAIT | __GFP_NOWARN, 0);
83
84 if (addr) {
85 tlb->pages = (void *)addr;
86 tlb->max = PAGE_SIZE / sizeof(struct page *);
87 }
88}
89
90static inline void tlb_flush_mmu(struct mmu_gather *tlb)
91{
92 tlb_flush(tlb);
93 free_pages_and_swap_cache(tlb->pages, tlb->nr);
94 tlb->nr = 0;
95 if (tlb->pages == tlb->local)
96 __tlb_alloc_page(tlb);
97}
98
99static inline void
100tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int fullmm)
101{
102 tlb->mm = mm;
103 tlb->fullmm = fullmm;
104 tlb->vma = NULL;
105 tlb->max = ARRAY_SIZE(tlb->local);
106 tlb->pages = tlb->local;
107 tlb->nr = 0;
108 __tlb_alloc_page(tlb);
109}
110
111static inline void
112tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
113{
114 tlb_flush_mmu(tlb);
115
116 /* keep the page table cache within bounds */
117 check_pgt_cache();
118
119 if (tlb->pages != tlb->local)
120 free_pages((unsigned long)tlb->pages, 0);
121}
122
123/*
124 * Memorize the range for the TLB flush.
125 */
126static inline void
127tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep, unsigned long addr)
128{
129 tlb_add_flush(tlb, addr);
130}
131
132/*
133 * In the case of tlb vma handling, we can optimise these away in the
134 * case where we're doing a full MM flush. When we're doing a munmap,
135 * the vmas are adjusted to only cover the region to be torn down.
136 */
137static inline void
138tlb_start_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
139{
140 if (!tlb->fullmm) {
141 tlb->vma = vma;
142 tlb->range_start = TASK_SIZE;
143 tlb->range_end = 0;
144 }
145}
146
147static inline void
148tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
149{
150 if (!tlb->fullmm)
151 tlb_flush(tlb);
152}
153
154static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
155{
156 tlb->pages[tlb->nr++] = page;
157 VM_BUG_ON(tlb->nr > tlb->max);
158 return tlb->max - tlb->nr;
159}
160
161static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
162{
163 if (!__tlb_remove_page(tlb, page))
164 tlb_flush_mmu(tlb);
165}
166
167static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
168 unsigned long addr)
169{
170 pgtable_page_dtor(pte);
171 tlb_add_flush(tlb, addr);
172 tlb_remove_page(tlb, pte);
173}
174
175#ifndef CONFIG_ARM64_64K_PAGES
176static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
177 unsigned long addr)
178{
179 tlb_add_flush(tlb, addr);
180 tlb_remove_page(tlb, virt_to_page(pmdp));
181}
182#endif
183
184#define pte_free_tlb(tlb, ptep, addr) __pte_free_tlb(tlb, ptep, addr)
185#define pmd_free_tlb(tlb, pmdp, addr) __pmd_free_tlb(tlb, pmdp, addr)
186#define pud_free_tlb(tlb, pudp, addr) pud_free((tlb)->mm, pudp)
187
188#define tlb_migrate_finish(mm) do { } while (0)
189
190#endif
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
new file mode 100644
index 000000000000..122d6320f745
--- /dev/null
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -0,0 +1,122 @@
1/*
2 * Based on arch/arm/include/asm/tlbflush.h
3 *
4 * Copyright (C) 1999-2003 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef __ASM_TLBFLUSH_H
20#define __ASM_TLBFLUSH_H
21
22#ifndef __ASSEMBLY__
23
24#include <linux/sched.h>
25#include <asm/cputype.h>
26
27extern void __cpu_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *);
28extern void __cpu_flush_kern_tlb_range(unsigned long, unsigned long);
29
30extern struct cpu_tlb_fns cpu_tlb;
31
32/*
33 * TLB Management
34 * ==============
35 *
36 * The arch/arm64/mm/tlb.S files implement these methods.
37 *
38 * The TLB specific code is expected to perform whatever tests it needs
39 * to determine if it should invalidate the TLB for each call. Start
40 * addresses are inclusive and end addresses are exclusive; it is safe to
41 * round these addresses down.
42 *
43 * flush_tlb_all()
44 *
45 * Invalidate the entire TLB.
46 *
47 * flush_tlb_mm(mm)
48 *
49 * Invalidate all TLB entries in a particular address space.
50 * - mm - mm_struct describing address space
51 *
52 * flush_tlb_range(mm,start,end)
53 *
54 * Invalidate a range of TLB entries in the specified address
55 * space.
56 * - mm - mm_struct describing address space
57 * - start - start address (may not be aligned)
58 * - end - end address (exclusive, may not be aligned)
59 *
60 * flush_tlb_page(vaddr,vma)
61 *
62 * Invalidate the specified page in the specified address range.
63 * - vaddr - virtual address (may not be aligned)
64 * - vma - vma_struct describing address range
65 *
66 * flush_kern_tlb_page(kaddr)
67 *
68 * Invalidate the TLB entry for the specified page. The address
69 * will be in the kernels virtual memory space. Current uses
70 * only require the D-TLB to be invalidated.
71 * - kaddr - Kernel virtual memory address
72 */
73static inline void flush_tlb_all(void)
74{
75 dsb();
76 asm("tlbi vmalle1is");
77 dsb();
78 isb();
79}
80
81static inline void flush_tlb_mm(struct mm_struct *mm)
82{
83 unsigned long asid = (unsigned long)ASID(mm) << 48;
84
85 dsb();
86 asm("tlbi aside1is, %0" : : "r" (asid));
87 dsb();
88}
89
90static inline void flush_tlb_page(struct vm_area_struct *vma,
91 unsigned long uaddr)
92{
93 unsigned long addr = uaddr >> 12 |
94 ((unsigned long)ASID(vma->vm_mm) << 48);
95
96 dsb();
97 asm("tlbi vae1is, %0" : : "r" (addr));
98 dsb();
99}
100
101/*
102 * Convert calls to our calling convention.
103 */
104#define flush_tlb_range(vma,start,end) __cpu_flush_user_tlb_range(start,end,vma)
105#define flush_tlb_kernel_range(s,e) __cpu_flush_kern_tlb_range(s,e)
106
107/*
108 * On AArch64, the cache coherency is handled via the set_pte_at() function.
109 */
110static inline void update_mmu_cache(struct vm_area_struct *vma,
111 unsigned long addr, pte_t *ptep)
112{
113 /*
114 * set_pte() does not have a DSB, so make sure that the page table
115 * write is visible.
116 */
117 dsb();
118}
119
120#endif
121
122#endif
diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h
new file mode 100644
index 000000000000..10ca8ff93cc2
--- /dev/null
+++ b/arch/arm64/include/asm/traps.h
@@ -0,0 +1,30 @@
1/*
2 * Based on arch/arm/include/asm/traps.h
3 *
4 * Copyright (C) 2012 ARM Ltd.
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#ifndef __ASM_TRAP_H
19#define __ASM_TRAP_H
20
21static inline int in_exception_text(unsigned long ptr)
22{
23 extern char __exception_text_start[];
24 extern char __exception_text_end[];
25
26 return ptr >= (unsigned long)&__exception_text_start &&
27 ptr < (unsigned long)&__exception_text_end;
28}
29
30#endif
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
new file mode 100644
index 000000000000..008f8481da65
--- /dev/null
+++ b/arch/arm64/include/asm/uaccess.h
@@ -0,0 +1,297 @@
1/*
2 * Based on arch/arm/include/asm/uaccess.h
3 *
4 * Copyright (C) 2012 ARM Ltd.
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#ifndef __ASM_UACCESS_H
19#define __ASM_UACCESS_H
20
21/*
22 * User space memory access functions
23 */
24#include <linux/string.h>
25#include <linux/thread_info.h>
26
27#include <asm/ptrace.h>
28#include <asm/errno.h>
29#include <asm/memory.h>
30#include <asm/compiler.h>
31
32#define VERIFY_READ 0
33#define VERIFY_WRITE 1
34
35/*
36 * The exception table consists of pairs of addresses: the first is the
37 * address of an instruction that is allowed to fault, and the second is
38 * the address at which the program should continue. No registers are
39 * modified, so it is entirely up to the continuation code to figure out
40 * what to do.
41 *
42 * All the routines below use bits of fixup code that are out of line
43 * with the main instruction path. This means when everything is well,
44 * we don't even have to jump over them. Further, they do not intrude
45 * on our cache or tlb entries.
46 */
47
48struct exception_table_entry
49{
50 unsigned long insn, fixup;
51};
52
53extern int fixup_exception(struct pt_regs *regs);
54
55#define KERNEL_DS (-1UL)
56#define get_ds() (KERNEL_DS)
57
58#define USER_DS TASK_SIZE_64
59#define get_fs() (current_thread_info()->addr_limit)
60
61static inline void set_fs(mm_segment_t fs)
62{
63 current_thread_info()->addr_limit = fs;
64}
65
66#define segment_eq(a,b) ((a) == (b))
67
68/*
69 * Return 1 if addr < current->addr_limit, 0 otherwise.
70 */
71#define __addr_ok(addr) \
72({ \
73 unsigned long flag; \
74 asm("cmp %1, %0; cset %0, lo" \
75 : "=&r" (flag) \
76 : "r" (addr), "0" (current_thread_info()->addr_limit) \
77 : "cc"); \
78 flag; \
79})
80
81/*
82 * Test whether a block of memory is a valid user space address.
83 * Returns 1 if the range is valid, 0 otherwise.
84 *
85 * This is equivalent to the following test:
86 * (u65)addr + (u65)size < (u65)current->addr_limit
87 *
88 * This needs 65-bit arithmetic.
89 */
90#define __range_ok(addr, size) \
91({ \
92 unsigned long flag, roksum; \
93 __chk_user_ptr(addr); \
94 asm("adds %1, %1, %3; ccmp %1, %4, #2, cc; cset %0, cc" \
95 : "=&r" (flag), "=&r" (roksum) \
96 : "1" (addr), "Ir" (size), \
97 "r" (current_thread_info()->addr_limit) \
98 : "cc"); \
99 flag; \
100})
101
102#define access_ok(type, addr, size) __range_ok(addr, size)
103
104/*
105 * The "__xxx" versions of the user access functions do not verify the address
106 * space - it must have been done previously with a separate "access_ok()"
107 * call.
108 *
109 * The "__xxx_error" versions set the third argument to -EFAULT if an error
110 * occurs, and leave it unchanged on success.
111 */
112#define __get_user_asm(instr, reg, x, addr, err) \
113 asm volatile( \
114 "1: " instr " " reg "1, [%2]\n" \
115 "2:\n" \
116 " .section .fixup, \"ax\"\n" \
117 " .align 2\n" \
118 "3: mov %w0, %3\n" \
119 " mov %1, #0\n" \
120 " b 2b\n" \
121 " .previous\n" \
122 " .section __ex_table,\"a\"\n" \
123 " .align 3\n" \
124 " .quad 1b, 3b\n" \
125 " .previous" \
126 : "+r" (err), "=&r" (x) \
127 : "r" (addr), "i" (-EFAULT))
128
129#define __get_user_err(x, ptr, err) \
130do { \
131 unsigned long __gu_val; \
132 __chk_user_ptr(ptr); \
133 switch (sizeof(*(ptr))) { \
134 case 1: \
135 __get_user_asm("ldrb", "%w", __gu_val, (ptr), (err)); \
136 break; \
137 case 2: \
138 __get_user_asm("ldrh", "%w", __gu_val, (ptr), (err)); \
139 break; \
140 case 4: \
141 __get_user_asm("ldr", "%w", __gu_val, (ptr), (err)); \
142 break; \
143 case 8: \
144 __get_user_asm("ldr", "%", __gu_val, (ptr), (err)); \
145 break; \
146 default: \
147 BUILD_BUG(); \
148 } \
149 (x) = (__typeof__(*(ptr)))__gu_val; \
150} while (0)
151
152#define __get_user(x, ptr) \
153({ \
154 int __gu_err = 0; \
155 __get_user_err((x), (ptr), __gu_err); \
156 __gu_err; \
157})
158
159#define __get_user_error(x, ptr, err) \
160({ \
161 __get_user_err((x), (ptr), (err)); \
162 (void)0; \
163})
164
165#define __get_user_unaligned __get_user
166
167#define get_user(x, ptr) \
168({ \
169 might_sleep(); \
170 access_ok(VERIFY_READ, (ptr), sizeof(*(ptr))) ? \
171 __get_user((x), (ptr)) : \
172 ((x) = 0, -EFAULT); \
173})
174
175#define __put_user_asm(instr, reg, x, addr, err) \
176 asm volatile( \
177 "1: " instr " " reg "1, [%2]\n" \
178 "2:\n" \
179 " .section .fixup,\"ax\"\n" \
180 " .align 2\n" \
181 "3: mov %w0, %3\n" \
182 " b 2b\n" \
183 " .previous\n" \
184 " .section __ex_table,\"a\"\n" \
185 " .align 3\n" \
186 " .quad 1b, 3b\n" \
187 " .previous" \
188 : "+r" (err) \
189 : "r" (x), "r" (addr), "i" (-EFAULT))
190
191#define __put_user_err(x, ptr, err) \
192do { \
193 __typeof__(*(ptr)) __pu_val = (x); \
194 __chk_user_ptr(ptr); \
195 switch (sizeof(*(ptr))) { \
196 case 1: \
197 __put_user_asm("strb", "%w", __pu_val, (ptr), (err)); \
198 break; \
199 case 2: \
200 __put_user_asm("strh", "%w", __pu_val, (ptr), (err)); \
201 break; \
202 case 4: \
203 __put_user_asm("str", "%w", __pu_val, (ptr), (err)); \
204 break; \
205 case 8: \
206 __put_user_asm("str", "%", __pu_val, (ptr), (err)); \
207 break; \
208 default: \
209 BUILD_BUG(); \
210 } \
211} while (0)
212
213#define __put_user(x, ptr) \
214({ \
215 int __pu_err = 0; \
216 __put_user_err((x), (ptr), __pu_err); \
217 __pu_err; \
218})
219
220#define __put_user_error(x, ptr, err) \
221({ \
222 __put_user_err((x), (ptr), (err)); \
223 (void)0; \
224})
225
226#define __put_user_unaligned __put_user
227
228#define put_user(x, ptr) \
229({ \
230 might_sleep(); \
231 access_ok(VERIFY_WRITE, (ptr), sizeof(*(ptr))) ? \
232 __put_user((x), (ptr)) : \
233 -EFAULT; \
234})
235
236extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n);
237extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n);
238extern unsigned long __must_check __copy_in_user(void __user *to, const void __user *from, unsigned long n);
239extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n);
240
241extern unsigned long __must_check __strncpy_from_user(char *to, const char __user *from, unsigned long count);
242extern unsigned long __must_check __strnlen_user(const char __user *s, long n);
243
244static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
245{
246 if (access_ok(VERIFY_READ, from, n))
247 n = __copy_from_user(to, from, n);
248 else /* security hole - plug it */
249 memset(to, 0, n);
250 return n;
251}
252
253static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
254{
255 if (access_ok(VERIFY_WRITE, to, n))
256 n = __copy_to_user(to, from, n);
257 return n;
258}
259
260static inline unsigned long __must_check copy_in_user(void __user *to, const void __user *from, unsigned long n)
261{
262 if (access_ok(VERIFY_READ, from, n) && access_ok(VERIFY_WRITE, to, n))
263 n = __copy_in_user(to, from, n);
264 return n;
265}
266
267#define __copy_to_user_inatomic __copy_to_user
268#define __copy_from_user_inatomic __copy_from_user
269
270static inline unsigned long __must_check clear_user(void __user *to, unsigned long n)
271{
272 if (access_ok(VERIFY_WRITE, to, n))
273 n = __clear_user(to, n);
274 return n;
275}
276
277static inline long __must_check strncpy_from_user(char *dst, const char __user *src, long count)
278{
279 long res = -EFAULT;
280 if (access_ok(VERIFY_READ, src, 1))
281 res = __strncpy_from_user(dst, src, count);
282 return res;
283}
284
285#define strlen_user(s) strnlen_user(s, ~0UL >> 1)
286
287static inline long __must_check strnlen_user(const char __user *s, long n)
288{
289 unsigned long res = 0;
290
291 if (__addr_ok(s))
292 res = __strnlen_user(s, n);
293
294 return res;
295}
296
297#endif /* __ASM_UACCESS_H */
diff --git a/arch/arm64/include/asm/ucontext.h b/arch/arm64/include/asm/ucontext.h
new file mode 100644
index 000000000000..bde960720892
--- /dev/null
+++ b/arch/arm64/include/asm/ucontext.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_UCONTEXT_H
17#define __ASM_UCONTEXT_H
18
19struct ucontext {
20 unsigned long uc_flags;
21 struct ucontext *uc_link;
22 stack_t uc_stack;
23 sigset_t uc_sigmask;
24 /* glibc uses a 1024-bit sigset_t */
25 __u8 __unused[(1024 - sizeof(sigset_t)) / 8];
26 /* last for future expansion */
27 struct sigcontext uc_mcontext;
28};
29
30#endif /* __ASM_UCONTEXT_H */
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
new file mode 100644
index 000000000000..fe18a683274f
--- /dev/null
+++ b/arch/arm64/include/asm/unistd.h
@@ -0,0 +1,27 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#if !defined(__ASM_UNISTD_H) || defined(__SYSCALL)
17#define __ASM_UNISTD_H
18
19#ifndef __SYSCALL_COMPAT
20#include <asm-generic/unistd.h>
21#endif
22
23#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
24#include <asm/unistd32.h>
25#endif
26
27#endif /* __ASM_UNISTD_H */
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
new file mode 100644
index 000000000000..a50405f5ee42
--- /dev/null
+++ b/arch/arm64/include/asm/unistd32.h
@@ -0,0 +1,758 @@
1/*
2 * Based on arch/arm/include/asm/unistd.h
3 *
4 * Copyright (C) 2001-2005 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#if !defined(__ASM_UNISTD32_H) || defined(__SYSCALL)
20#define __ASM_UNISTD32_H
21
22#ifndef __SYSCALL
23#define __SYSCALL(x, y)
24#endif
25
26/*
27 * This file contains the system call numbers.
28 */
29
30#ifdef __SYSCALL_COMPAT
31
32#define __NR_restart_syscall 0
33__SYSCALL(__NR_restart_syscall, sys_restart_syscall)
34#define __NR_exit 1
35__SYSCALL(__NR_exit, sys_exit)
36#define __NR_fork 2
37__SYSCALL(__NR_fork, sys_fork)
38#define __NR_read 3
39__SYSCALL(__NR_read, sys_read)
40#define __NR_write 4
41__SYSCALL(__NR_write, sys_write)
42#define __NR_open 5
43__SYSCALL(__NR_open, sys_open)
44#define __NR_close 6
45__SYSCALL(__NR_close, sys_close)
46__SYSCALL(7, sys_ni_syscall) /* 7 was sys_waitpid */
47#define __NR_creat 8
48__SYSCALL(__NR_creat, sys_creat)
49#define __NR_link 9
50__SYSCALL(__NR_link, sys_link)
51#define __NR_unlink 10
52__SYSCALL(__NR_unlink, sys_unlink)
53#define __NR_execve 11
54__SYSCALL(__NR_execve, sys_execve)
55#define __NR_chdir 12
56__SYSCALL(__NR_chdir, sys_chdir)
57__SYSCALL(13, sys_ni_syscall) /* 13 was sys_time */
58#define __NR_mknod 14
59__SYSCALL(__NR_mknod, sys_mknod)
60#define __NR_chmod 15
61__SYSCALL(__NR_chmod, sys_chmod)
62#define __NR_lchown 16
63__SYSCALL(__NR_lchown, sys_lchown16)
64__SYSCALL(17, sys_ni_syscall) /* 17 was sys_break */
65__SYSCALL(18, sys_ni_syscall) /* 18 was sys_stat */
66#define __NR_lseek 19
67__SYSCALL(__NR_lseek, sys_lseek)
68#define __NR_getpid 20
69__SYSCALL(__NR_getpid, sys_getpid)
70#define __NR_mount 21
71__SYSCALL(__NR_mount, sys_mount)
72__SYSCALL(22, sys_ni_syscall) /* 22 was sys_umount */
73#define __NR_setuid 23
74__SYSCALL(__NR_setuid, sys_setuid16)
75#define __NR_getuid 24
76__SYSCALL(__NR_getuid, sys_getuid16)
77__SYSCALL(25, sys_ni_syscall) /* 25 was sys_stime */
78#define __NR_ptrace 26
79__SYSCALL(__NR_ptrace, sys_ptrace)
80__SYSCALL(27, sys_ni_syscall) /* 27 was sys_alarm */
81__SYSCALL(28, sys_ni_syscall) /* 28 was sys_fstat */
82#define __NR_pause 29
83__SYSCALL(__NR_pause, sys_pause)
84__SYSCALL(30, sys_ni_syscall) /* 30 was sys_utime */
85__SYSCALL(31, sys_ni_syscall) /* 31 was sys_stty */
86__SYSCALL(32, sys_ni_syscall) /* 32 was sys_gtty */
87#define __NR_access 33
88__SYSCALL(__NR_access, sys_access)
89#define __NR_nice 34
90__SYSCALL(__NR_nice, sys_nice)
91__SYSCALL(35, sys_ni_syscall) /* 35 was sys_ftime */
92#define __NR_sync 36
93__SYSCALL(__NR_sync, sys_sync)
94#define __NR_kill 37
95__SYSCALL(__NR_kill, sys_kill)
96#define __NR_rename 38
97__SYSCALL(__NR_rename, sys_rename)
98#define __NR_mkdir 39
99__SYSCALL(__NR_mkdir, sys_mkdir)
100#define __NR_rmdir 40
101__SYSCALL(__NR_rmdir, sys_rmdir)
102#define __NR_dup 41
103__SYSCALL(__NR_dup, sys_dup)
104#define __NR_pipe 42
105__SYSCALL(__NR_pipe, sys_pipe)
106#define __NR_times 43
107__SYSCALL(__NR_times, sys_times)
108__SYSCALL(44, sys_ni_syscall) /* 44 was sys_prof */
109#define __NR_brk 45
110__SYSCALL(__NR_brk, sys_brk)
111#define __NR_setgid 46
112__SYSCALL(__NR_setgid, sys_setgid16)
113#define __NR_getgid 47
114__SYSCALL(__NR_getgid, sys_getgid16)
115__SYSCALL(48, sys_ni_syscall) /* 48 was sys_signal */
116#define __NR_geteuid 49
117__SYSCALL(__NR_geteuid, sys_geteuid16)
118#define __NR_getegid 50
119__SYSCALL(__NR_getegid, sys_getegid16)
120#define __NR_acct 51
121__SYSCALL(__NR_acct, sys_acct)
122#define __NR_umount2 52
123__SYSCALL(__NR_umount2, sys_umount)
124__SYSCALL(53, sys_ni_syscall) /* 53 was sys_lock */
125#define __NR_ioctl 54
126__SYSCALL(__NR_ioctl, sys_ioctl)
127#define __NR_fcntl 55
128__SYSCALL(__NR_fcntl, sys_fcntl)
129__SYSCALL(56, sys_ni_syscall) /* 56 was sys_mpx */
130#define __NR_setpgid 57
131__SYSCALL(__NR_setpgid, sys_setpgid)
132__SYSCALL(58, sys_ni_syscall) /* 58 was sys_ulimit */
133__SYSCALL(59, sys_ni_syscall) /* 59 was sys_olduname */
134#define __NR_umask 60
135__SYSCALL(__NR_umask, sys_umask)
136#define __NR_chroot 61
137__SYSCALL(__NR_chroot, sys_chroot)
138#define __NR_ustat 62
139__SYSCALL(__NR_ustat, sys_ustat)
140#define __NR_dup2 63
141__SYSCALL(__NR_dup2, sys_dup2)
142#define __NR_getppid 64
143__SYSCALL(__NR_getppid, sys_getppid)
144#define __NR_getpgrp 65
145__SYSCALL(__NR_getpgrp, sys_getpgrp)
146#define __NR_setsid 66
147__SYSCALL(__NR_setsid, sys_setsid)
148#define __NR_sigaction 67
149__SYSCALL(__NR_sigaction, sys_sigaction)
150__SYSCALL(68, sys_ni_syscall) /* 68 was sys_sgetmask */
151__SYSCALL(69, sys_ni_syscall) /* 69 was sys_ssetmask */
152#define __NR_setreuid 70
153__SYSCALL(__NR_setreuid, sys_setreuid16)
154#define __NR_setregid 71
155__SYSCALL(__NR_setregid, sys_setregid16)
156#define __NR_sigsuspend 72
157__SYSCALL(__NR_sigsuspend, sys_sigsuspend)
158#define __NR_sigpending 73
159__SYSCALL(__NR_sigpending, sys_sigpending)
160#define __NR_sethostname 74
161__SYSCALL(__NR_sethostname, sys_sethostname)
162#define __NR_setrlimit 75
163__SYSCALL(__NR_setrlimit, sys_setrlimit)
164__SYSCALL(76, sys_ni_syscall) /* 76 was sys_getrlimit */
165#define __NR_getrusage 77
166__SYSCALL(__NR_getrusage, sys_getrusage)
167#define __NR_gettimeofday 78
168__SYSCALL(__NR_gettimeofday, sys_gettimeofday)
169#define __NR_settimeofday 79
170__SYSCALL(__NR_settimeofday, sys_settimeofday)
171#define __NR_getgroups 80
172__SYSCALL(__NR_getgroups, sys_getgroups16)
173#define __NR_setgroups 81
174__SYSCALL(__NR_setgroups, sys_setgroups16)
175__SYSCALL(82, sys_ni_syscall) /* 82 was sys_select */
176#define __NR_symlink 83
177__SYSCALL(__NR_symlink, sys_symlink)
178__SYSCALL(84, sys_ni_syscall) /* 84 was sys_lstat */
179#define __NR_readlink 85
180__SYSCALL(__NR_readlink, sys_readlink)
181#define __NR_uselib 86
182__SYSCALL(__NR_uselib, sys_uselib)
183#define __NR_swapon 87
184__SYSCALL(__NR_swapon, sys_swapon)
185#define __NR_reboot 88
186__SYSCALL(__NR_reboot, sys_reboot)
187__SYSCALL(89, sys_ni_syscall) /* 89 was sys_readdir */
188__SYSCALL(90, sys_ni_syscall) /* 90 was sys_mmap */
189#define __NR_munmap 91
190__SYSCALL(__NR_munmap, sys_munmap)
191#define __NR_truncate 92
192__SYSCALL(__NR_truncate, sys_truncate)
193#define __NR_ftruncate 93
194__SYSCALL(__NR_ftruncate, sys_ftruncate)
195#define __NR_fchmod 94
196__SYSCALL(__NR_fchmod, sys_fchmod)
197#define __NR_fchown 95
198__SYSCALL(__NR_fchown, sys_fchown16)
199#define __NR_getpriority 96
200__SYSCALL(__NR_getpriority, sys_getpriority)
201#define __NR_setpriority 97
202__SYSCALL(__NR_setpriority, sys_setpriority)
203__SYSCALL(98, sys_ni_syscall) /* 98 was sys_profil */
204#define __NR_statfs 99
205__SYSCALL(__NR_statfs, sys_statfs)
206#define __NR_fstatfs 100
207__SYSCALL(__NR_fstatfs, sys_fstatfs)
208__SYSCALL(101, sys_ni_syscall) /* 101 was sys_ioperm */
209__SYSCALL(102, sys_ni_syscall) /* 102 was sys_socketcall */
210#define __NR_syslog 103
211__SYSCALL(__NR_syslog, sys_syslog)
212#define __NR_setitimer 104
213__SYSCALL(__NR_setitimer, sys_setitimer)
214#define __NR_getitimer 105
215__SYSCALL(__NR_getitimer, sys_getitimer)
216#define __NR_stat 106
217__SYSCALL(__NR_stat, sys_newstat)
218#define __NR_lstat 107
219__SYSCALL(__NR_lstat, sys_newlstat)
220#define __NR_fstat 108
221__SYSCALL(__NR_fstat, sys_newfstat)
222__SYSCALL(109, sys_ni_syscall) /* 109 was sys_uname */
223__SYSCALL(110, sys_ni_syscall) /* 110 was sys_iopl */
224#define __NR_vhangup 111
225__SYSCALL(__NR_vhangup, sys_vhangup)
226__SYSCALL(112, sys_ni_syscall) /* 112 was sys_idle */
227__SYSCALL(113, sys_ni_syscall) /* 113 was sys_syscall */
228#define __NR_wait4 114
229__SYSCALL(__NR_wait4, sys_wait4)
230#define __NR_swapoff 115
231__SYSCALL(__NR_swapoff, sys_swapoff)
232#define __NR_sysinfo 116
233__SYSCALL(__NR_sysinfo, sys_sysinfo)
234__SYSCALL(117, sys_ni_syscall) /* 117 was sys_ipc */
235#define __NR_fsync 118
236__SYSCALL(__NR_fsync, sys_fsync)
237#define __NR_sigreturn 119
238__SYSCALL(__NR_sigreturn, sys_sigreturn)
239#define __NR_clone 120
240__SYSCALL(__NR_clone, sys_clone)
241#define __NR_setdomainname 121
242__SYSCALL(__NR_setdomainname, sys_setdomainname)
243#define __NR_uname 122
244__SYSCALL(__NR_uname, sys_newuname)
245__SYSCALL(123, sys_ni_syscall) /* 123 was sys_modify_ldt */
246#define __NR_adjtimex 124
247__SYSCALL(__NR_adjtimex, sys_adjtimex)
248#define __NR_mprotect 125
249__SYSCALL(__NR_mprotect, sys_mprotect)
250#define __NR_sigprocmask 126
251__SYSCALL(__NR_sigprocmask, sys_sigprocmask)
252__SYSCALL(127, sys_ni_syscall) /* 127 was sys_create_module */
253#define __NR_init_module 128
254__SYSCALL(__NR_init_module, sys_init_module)
255#define __NR_delete_module 129
256__SYSCALL(__NR_delete_module, sys_delete_module)
257__SYSCALL(130, sys_ni_syscall) /* 130 was sys_get_kernel_syms */
258#define __NR_quotactl 131
259__SYSCALL(__NR_quotactl, sys_quotactl)
260#define __NR_getpgid 132
261__SYSCALL(__NR_getpgid, sys_getpgid)
262#define __NR_fchdir 133
263__SYSCALL(__NR_fchdir, sys_fchdir)
264#define __NR_bdflush 134
265__SYSCALL(__NR_bdflush, sys_bdflush)
266#define __NR_sysfs 135
267__SYSCALL(__NR_sysfs, sys_sysfs)
268#define __NR_personality 136
269__SYSCALL(__NR_personality, sys_personality)
270__SYSCALL(137, sys_ni_syscall) /* 137 was sys_afs_syscall */
271#define __NR_setfsuid 138
272__SYSCALL(__NR_setfsuid, sys_setfsuid16)
273#define __NR_setfsgid 139
274__SYSCALL(__NR_setfsgid, sys_setfsgid16)
275#define __NR__llseek 140
276__SYSCALL(__NR__llseek, sys_llseek)
277#define __NR_getdents 141
278__SYSCALL(__NR_getdents, sys_getdents)
279#define __NR__newselect 142
280__SYSCALL(__NR__newselect, sys_select)
281#define __NR_flock 143
282__SYSCALL(__NR_flock, sys_flock)
283#define __NR_msync 144
284__SYSCALL(__NR_msync, sys_msync)
285#define __NR_readv 145
286__SYSCALL(__NR_readv, sys_readv)
287#define __NR_writev 146
288__SYSCALL(__NR_writev, sys_writev)
289#define __NR_getsid 147
290__SYSCALL(__NR_getsid, sys_getsid)
291#define __NR_fdatasync 148
292__SYSCALL(__NR_fdatasync, sys_fdatasync)
293#define __NR__sysctl 149
294__SYSCALL(__NR__sysctl, sys_sysctl)
295#define __NR_mlock 150
296__SYSCALL(__NR_mlock, sys_mlock)
297#define __NR_munlock 151
298__SYSCALL(__NR_munlock, sys_munlock)
299#define __NR_mlockall 152
300__SYSCALL(__NR_mlockall, sys_mlockall)
301#define __NR_munlockall 153
302__SYSCALL(__NR_munlockall, sys_munlockall)
303#define __NR_sched_setparam 154
304__SYSCALL(__NR_sched_setparam, sys_sched_setparam)
305#define __NR_sched_getparam 155
306__SYSCALL(__NR_sched_getparam, sys_sched_getparam)
307#define __NR_sched_setscheduler 156
308__SYSCALL(__NR_sched_setscheduler, sys_sched_setscheduler)
309#define __NR_sched_getscheduler 157
310__SYSCALL(__NR_sched_getscheduler, sys_sched_getscheduler)
311#define __NR_sched_yield 158
312__SYSCALL(__NR_sched_yield, sys_sched_yield)
313#define __NR_sched_get_priority_max 159
314__SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max)
315#define __NR_sched_get_priority_min 160
316__SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min)
317#define __NR_sched_rr_get_interval 161
318__SYSCALL(__NR_sched_rr_get_interval, sys_sched_rr_get_interval)
319#define __NR_nanosleep 162
320__SYSCALL(__NR_nanosleep, sys_nanosleep)
321#define __NR_mremap 163
322__SYSCALL(__NR_mremap, sys_mremap)
323#define __NR_setresuid 164
324__SYSCALL(__NR_setresuid, sys_setresuid16)
325#define __NR_getresuid 165
326__SYSCALL(__NR_getresuid, sys_getresuid16)
327__SYSCALL(166, sys_ni_syscall) /* 166 was sys_vm86 */
328__SYSCALL(167, sys_ni_syscall) /* 167 was sys_query_module */
329#define __NR_poll 168
330__SYSCALL(__NR_poll, sys_poll)
331#define __NR_nfsservctl 169
332__SYSCALL(__NR_nfsservctl, sys_ni_syscall)
333#define __NR_setresgid 170
334__SYSCALL(__NR_setresgid, sys_setresgid16)
335#define __NR_getresgid 171
336__SYSCALL(__NR_getresgid, sys_getresgid16)
337#define __NR_prctl 172
338__SYSCALL(__NR_prctl, sys_prctl)
339#define __NR_rt_sigreturn 173
340__SYSCALL(__NR_rt_sigreturn, sys_rt_sigreturn)
341#define __NR_rt_sigaction 174
342__SYSCALL(__NR_rt_sigaction, sys_rt_sigaction)
343#define __NR_rt_sigprocmask 175
344__SYSCALL(__NR_rt_sigprocmask, sys_rt_sigprocmask)
345#define __NR_rt_sigpending 176
346__SYSCALL(__NR_rt_sigpending, sys_rt_sigpending)
347#define __NR_rt_sigtimedwait 177
348__SYSCALL(__NR_rt_sigtimedwait, sys_rt_sigtimedwait)
349#define __NR_rt_sigqueueinfo 178
350__SYSCALL(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo)
351#define __NR_rt_sigsuspend 179
352__SYSCALL(__NR_rt_sigsuspend, sys_rt_sigsuspend)
353#define __NR_pread64 180
354__SYSCALL(__NR_pread64, sys_pread64)
355#define __NR_pwrite64 181
356__SYSCALL(__NR_pwrite64, sys_pwrite64)
357#define __NR_chown 182
358__SYSCALL(__NR_chown, sys_chown16)
359#define __NR_getcwd 183
360__SYSCALL(__NR_getcwd, sys_getcwd)
361#define __NR_capget 184
362__SYSCALL(__NR_capget, sys_capget)
363#define __NR_capset 185
364__SYSCALL(__NR_capset, sys_capset)
365#define __NR_sigaltstack 186
366__SYSCALL(__NR_sigaltstack, sys_sigaltstack)
367#define __NR_sendfile 187
368__SYSCALL(__NR_sendfile, sys_sendfile)
369__SYSCALL(188, sys_ni_syscall) /* 188 reserved */
370__SYSCALL(189, sys_ni_syscall) /* 189 reserved */
371#define __NR_vfork 190
372__SYSCALL(__NR_vfork, sys_vfork)
373#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */
374__SYSCALL(__NR_ugetrlimit, sys_getrlimit)
375#define __NR_mmap2 192
376__SYSCALL(__NR_mmap2, sys_mmap2)
377#define __NR_truncate64 193
378__SYSCALL(__NR_truncate64, sys_truncate64)
379#define __NR_ftruncate64 194
380__SYSCALL(__NR_ftruncate64, sys_ftruncate64)
381#define __NR_stat64 195
382__SYSCALL(__NR_stat64, sys_stat64)
383#define __NR_lstat64 196
384__SYSCALL(__NR_lstat64, sys_lstat64)
385#define __NR_fstat64 197
386__SYSCALL(__NR_fstat64, sys_fstat64)
387#define __NR_lchown32 198
388__SYSCALL(__NR_lchown32, sys_lchown)
389#define __NR_getuid32 199
390__SYSCALL(__NR_getuid32, sys_getuid)
391#define __NR_getgid32 200
392__SYSCALL(__NR_getgid32, sys_getgid)
393#define __NR_geteuid32 201
394__SYSCALL(__NR_geteuid32, sys_geteuid)
395#define __NR_getegid32 202
396__SYSCALL(__NR_getegid32, sys_getegid)
397#define __NR_setreuid32 203
398__SYSCALL(__NR_setreuid32, sys_setreuid)
399#define __NR_setregid32 204
400__SYSCALL(__NR_setregid32, sys_setregid)
401#define __NR_getgroups32 205
402__SYSCALL(__NR_getgroups32, sys_getgroups)
403#define __NR_setgroups32 206
404__SYSCALL(__NR_setgroups32, sys_setgroups)
405#define __NR_fchown32 207
406__SYSCALL(__NR_fchown32, sys_fchown)
407#define __NR_setresuid32 208
408__SYSCALL(__NR_setresuid32, sys_setresuid)
409#define __NR_getresuid32 209
410__SYSCALL(__NR_getresuid32, sys_getresuid)
411#define __NR_setresgid32 210
412__SYSCALL(__NR_setresgid32, sys_setresgid)
413#define __NR_getresgid32 211
414__SYSCALL(__NR_getresgid32, sys_getresgid)
415#define __NR_chown32 212
416__SYSCALL(__NR_chown32, sys_chown)
417#define __NR_setuid32 213
418__SYSCALL(__NR_setuid32, sys_setuid)
419#define __NR_setgid32 214
420__SYSCALL(__NR_setgid32, sys_setgid)
421#define __NR_setfsuid32 215
422__SYSCALL(__NR_setfsuid32, sys_setfsuid)
423#define __NR_setfsgid32 216
424__SYSCALL(__NR_setfsgid32, sys_setfsgid)
425#define __NR_getdents64 217
426__SYSCALL(__NR_getdents64, sys_getdents64)
427#define __NR_pivot_root 218
428__SYSCALL(__NR_pivot_root, sys_pivot_root)
429#define __NR_mincore 219
430__SYSCALL(__NR_mincore, sys_mincore)
431#define __NR_madvise 220
432__SYSCALL(__NR_madvise, sys_madvise)
433#define __NR_fcntl64 221
434__SYSCALL(__NR_fcntl64, sys_fcntl64)
435__SYSCALL(222, sys_ni_syscall) /* 222 for tux */
436__SYSCALL(223, sys_ni_syscall) /* 223 is unused */
437#define __NR_gettid 224
438__SYSCALL(__NR_gettid, sys_gettid)
439#define __NR_readahead 225
440__SYSCALL(__NR_readahead, sys_readahead)
441#define __NR_setxattr 226
442__SYSCALL(__NR_setxattr, sys_setxattr)
443#define __NR_lsetxattr 227
444__SYSCALL(__NR_lsetxattr, sys_lsetxattr)
445#define __NR_fsetxattr 228
446__SYSCALL(__NR_fsetxattr, sys_fsetxattr)
447#define __NR_getxattr 229
448__SYSCALL(__NR_getxattr, sys_getxattr)
449#define __NR_lgetxattr 230
450__SYSCALL(__NR_lgetxattr, sys_lgetxattr)
451#define __NR_fgetxattr 231
452__SYSCALL(__NR_fgetxattr, sys_fgetxattr)
453#define __NR_listxattr 232
454__SYSCALL(__NR_listxattr, sys_listxattr)
455#define __NR_llistxattr 233
456__SYSCALL(__NR_llistxattr, sys_llistxattr)
457#define __NR_flistxattr 234
458__SYSCALL(__NR_flistxattr, sys_flistxattr)
459#define __NR_removexattr 235
460__SYSCALL(__NR_removexattr, sys_removexattr)
461#define __NR_lremovexattr 236
462__SYSCALL(__NR_lremovexattr, sys_lremovexattr)
463#define __NR_fremovexattr 237
464__SYSCALL(__NR_fremovexattr, sys_fremovexattr)
465#define __NR_tkill 238
466__SYSCALL(__NR_tkill, sys_tkill)
467#define __NR_sendfile64 239
468__SYSCALL(__NR_sendfile64, sys_sendfile64)
469#define __NR_futex 240
470__SYSCALL(__NR_futex, sys_futex)
471#define __NR_sched_setaffinity 241
472__SYSCALL(__NR_sched_setaffinity, sys_sched_setaffinity)
473#define __NR_sched_getaffinity 242
474__SYSCALL(__NR_sched_getaffinity, sys_sched_getaffinity)
475#define __NR_io_setup 243
476__SYSCALL(__NR_io_setup, sys_io_setup)
477#define __NR_io_destroy 244
478__SYSCALL(__NR_io_destroy, sys_io_destroy)
479#define __NR_io_getevents 245
480__SYSCALL(__NR_io_getevents, sys_io_getevents)
481#define __NR_io_submit 246
482__SYSCALL(__NR_io_submit, sys_io_submit)
483#define __NR_io_cancel 247
484__SYSCALL(__NR_io_cancel, sys_io_cancel)
485#define __NR_exit_group 248
486__SYSCALL(__NR_exit_group, sys_exit_group)
487#define __NR_lookup_dcookie 249
488__SYSCALL(__NR_lookup_dcookie, sys_lookup_dcookie)
489#define __NR_epoll_create 250
490__SYSCALL(__NR_epoll_create, sys_epoll_create)
491#define __NR_epoll_ctl 251
492__SYSCALL(__NR_epoll_ctl, sys_epoll_ctl)
493#define __NR_epoll_wait 252
494__SYSCALL(__NR_epoll_wait, sys_epoll_wait)
495#define __NR_remap_file_pages 253
496__SYSCALL(__NR_remap_file_pages, sys_remap_file_pages)
497__SYSCALL(254, sys_ni_syscall) /* 254 for set_thread_area */
498__SYSCALL(255, sys_ni_syscall) /* 255 for get_thread_area */
499#define __NR_set_tid_address 256
500__SYSCALL(__NR_set_tid_address, sys_set_tid_address)
501#define __NR_timer_create 257
502__SYSCALL(__NR_timer_create, sys_timer_create)
503#define __NR_timer_settime 258
504__SYSCALL(__NR_timer_settime, sys_timer_settime)
505#define __NR_timer_gettime 259
506__SYSCALL(__NR_timer_gettime, sys_timer_gettime)
507#define __NR_timer_getoverrun 260
508__SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun)
509#define __NR_timer_delete 261
510__SYSCALL(__NR_timer_delete, sys_timer_delete)
511#define __NR_clock_settime 262
512__SYSCALL(__NR_clock_settime, sys_clock_settime)
513#define __NR_clock_gettime 263
514__SYSCALL(__NR_clock_gettime, sys_clock_gettime)
515#define __NR_clock_getres 264
516__SYSCALL(__NR_clock_getres, sys_clock_getres)
517#define __NR_clock_nanosleep 265
518__SYSCALL(__NR_clock_nanosleep, sys_clock_nanosleep)
519#define __NR_statfs64 266
520__SYSCALL(__NR_statfs64, sys_statfs64)
521#define __NR_fstatfs64 267
522__SYSCALL(__NR_fstatfs64, sys_fstatfs64)
523#define __NR_tgkill 268
524__SYSCALL(__NR_tgkill, sys_tgkill)
525#define __NR_utimes 269
526__SYSCALL(__NR_utimes, sys_utimes)
527#define __NR_fadvise64 270
528__SYSCALL(__NR_fadvise64, sys_fadvise64_64)
529#define __NR_pciconfig_iobase 271
530__SYSCALL(__NR_pciconfig_iobase, sys_pciconfig_iobase)
531#define __NR_pciconfig_read 272
532__SYSCALL(__NR_pciconfig_read, sys_pciconfig_read)
533#define __NR_pciconfig_write 273
534__SYSCALL(__NR_pciconfig_write, sys_pciconfig_write)
535#define __NR_mq_open 274
536__SYSCALL(__NR_mq_open, sys_mq_open)
537#define __NR_mq_unlink 275
538__SYSCALL(__NR_mq_unlink, sys_mq_unlink)
539#define __NR_mq_timedsend 276
540__SYSCALL(__NR_mq_timedsend, sys_mq_timedsend)
541#define __NR_mq_timedreceive 277
542__SYSCALL(__NR_mq_timedreceive, sys_mq_timedreceive)
543#define __NR_mq_notify 278
544__SYSCALL(__NR_mq_notify, sys_mq_notify)
545#define __NR_mq_getsetattr 279
546__SYSCALL(__NR_mq_getsetattr, sys_mq_getsetattr)
547#define __NR_waitid 280
548__SYSCALL(__NR_waitid, sys_waitid)
549#define __NR_socket 281
550__SYSCALL(__NR_socket, sys_socket)
551#define __NR_bind 282
552__SYSCALL(__NR_bind, sys_bind)
553#define __NR_connect 283
554__SYSCALL(__NR_connect, sys_connect)
555#define __NR_listen 284
556__SYSCALL(__NR_listen, sys_listen)
557#define __NR_accept 285
558__SYSCALL(__NR_accept, sys_accept)
559#define __NR_getsockname 286
560__SYSCALL(__NR_getsockname, sys_getsockname)
561#define __NR_getpeername 287
562__SYSCALL(__NR_getpeername, sys_getpeername)
563#define __NR_socketpair 288
564__SYSCALL(__NR_socketpair, sys_socketpair)
565#define __NR_send 289
566__SYSCALL(__NR_send, sys_send)
567#define __NR_sendto 290
568__SYSCALL(__NR_sendto, sys_sendto)
569#define __NR_recv 291
570__SYSCALL(__NR_recv, sys_recv)
571#define __NR_recvfrom 292
572__SYSCALL(__NR_recvfrom, sys_recvfrom)
573#define __NR_shutdown 293
574__SYSCALL(__NR_shutdown, sys_shutdown)
575#define __NR_setsockopt 294
576__SYSCALL(__NR_setsockopt, sys_setsockopt)
577#define __NR_getsockopt 295
578__SYSCALL(__NR_getsockopt, sys_getsockopt)
579#define __NR_sendmsg 296
580__SYSCALL(__NR_sendmsg, sys_sendmsg)
581#define __NR_recvmsg 297
582__SYSCALL(__NR_recvmsg, sys_recvmsg)
583#define __NR_semop 298
584__SYSCALL(__NR_semop, sys_semop)
585#define __NR_semget 299
586__SYSCALL(__NR_semget, sys_semget)
587#define __NR_semctl 300
588__SYSCALL(__NR_semctl, sys_semctl)
589#define __NR_msgsnd 301
590__SYSCALL(__NR_msgsnd, sys_msgsnd)
591#define __NR_msgrcv 302
592__SYSCALL(__NR_msgrcv, sys_msgrcv)
593#define __NR_msgget 303
594__SYSCALL(__NR_msgget, sys_msgget)
595#define __NR_msgctl 304
596__SYSCALL(__NR_msgctl, sys_msgctl)
597#define __NR_shmat 305
598__SYSCALL(__NR_shmat, sys_shmat)
599#define __NR_shmdt 306
600__SYSCALL(__NR_shmdt, sys_shmdt)
601#define __NR_shmget 307
602__SYSCALL(__NR_shmget, sys_shmget)
603#define __NR_shmctl 308
604__SYSCALL(__NR_shmctl, sys_shmctl)
605#define __NR_add_key 309
606__SYSCALL(__NR_add_key, sys_add_key)
607#define __NR_request_key 310
608__SYSCALL(__NR_request_key, sys_request_key)
609#define __NR_keyctl 311
610__SYSCALL(__NR_keyctl, sys_keyctl)
611#define __NR_semtimedop 312
612__SYSCALL(__NR_semtimedop, sys_semtimedop)
613#define __NR_vserver 313
614__SYSCALL(__NR_vserver, sys_ni_syscall)
615#define __NR_ioprio_set 314
616__SYSCALL(__NR_ioprio_set, sys_ioprio_set)
617#define __NR_ioprio_get 315
618__SYSCALL(__NR_ioprio_get, sys_ioprio_get)
619#define __NR_inotify_init 316
620__SYSCALL(__NR_inotify_init, sys_inotify_init)
621#define __NR_inotify_add_watch 317
622__SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch)
623#define __NR_inotify_rm_watch 318
624__SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch)
625#define __NR_mbind 319
626__SYSCALL(__NR_mbind, sys_mbind)
627#define __NR_get_mempolicy 320
628__SYSCALL(__NR_get_mempolicy, sys_get_mempolicy)
629#define __NR_set_mempolicy 321
630__SYSCALL(__NR_set_mempolicy, sys_set_mempolicy)
631#define __NR_openat 322
632__SYSCALL(__NR_openat, sys_openat)
633#define __NR_mkdirat 323
634__SYSCALL(__NR_mkdirat, sys_mkdirat)
635#define __NR_mknodat 324
636__SYSCALL(__NR_mknodat, sys_mknodat)
637#define __NR_fchownat 325
638__SYSCALL(__NR_fchownat, sys_fchownat)
639#define __NR_futimesat 326
640__SYSCALL(__NR_futimesat, sys_futimesat)
641#define __NR_fstatat64 327
642__SYSCALL(__NR_fstatat64, sys_fstatat64)
643#define __NR_unlinkat 328
644__SYSCALL(__NR_unlinkat, sys_unlinkat)
645#define __NR_renameat 329
646__SYSCALL(__NR_renameat, sys_renameat)
647#define __NR_linkat 330
648__SYSCALL(__NR_linkat, sys_linkat)
649#define __NR_symlinkat 331
650__SYSCALL(__NR_symlinkat, sys_symlinkat)
651#define __NR_readlinkat 332
652__SYSCALL(__NR_readlinkat, sys_readlinkat)
653#define __NR_fchmodat 333
654__SYSCALL(__NR_fchmodat, sys_fchmodat)
655#define __NR_faccessat 334
656__SYSCALL(__NR_faccessat, sys_faccessat)
657#define __NR_pselect6 335
658__SYSCALL(__NR_pselect6, sys_pselect6)
659#define __NR_ppoll 336
660__SYSCALL(__NR_ppoll, sys_ppoll)
661#define __NR_unshare 337
662__SYSCALL(__NR_unshare, sys_unshare)
663#define __NR_set_robust_list 338
664__SYSCALL(__NR_set_robust_list, sys_set_robust_list)
665#define __NR_get_robust_list 339
666__SYSCALL(__NR_get_robust_list, sys_get_robust_list)
667#define __NR_splice 340
668__SYSCALL(__NR_splice, sys_splice)
669#define __NR_sync_file_range2 341
670__SYSCALL(__NR_sync_file_range2, sys_sync_file_range2)
671#define __NR_tee 342
672__SYSCALL(__NR_tee, sys_tee)
673#define __NR_vmsplice 343
674__SYSCALL(__NR_vmsplice, sys_vmsplice)
675#define __NR_move_pages 344
676__SYSCALL(__NR_move_pages, sys_move_pages)
677#define __NR_getcpu 345
678__SYSCALL(__NR_getcpu, sys_getcpu)
679#define __NR_epoll_pwait 346
680__SYSCALL(__NR_epoll_pwait, sys_epoll_pwait)
681#define __NR_kexec_load 347
682__SYSCALL(__NR_kexec_load, sys_kexec_load)
683#define __NR_utimensat 348
684__SYSCALL(__NR_utimensat, sys_utimensat)
685#define __NR_signalfd 349
686__SYSCALL(__NR_signalfd, sys_signalfd)
687#define __NR_timerfd_create 350
688__SYSCALL(__NR_timerfd_create, sys_timerfd_create)
689#define __NR_eventfd 351
690__SYSCALL(__NR_eventfd, sys_eventfd)
691#define __NR_fallocate 352
692__SYSCALL(__NR_fallocate, sys_fallocate)
693#define __NR_timerfd_settime 353
694__SYSCALL(__NR_timerfd_settime, sys_timerfd_settime)
695#define __NR_timerfd_gettime 354
696__SYSCALL(__NR_timerfd_gettime, sys_timerfd_gettime)
697#define __NR_signalfd4 355
698__SYSCALL(__NR_signalfd4, sys_signalfd4)
699#define __NR_eventfd2 356
700__SYSCALL(__NR_eventfd2, sys_eventfd2)
701#define __NR_epoll_create1 357
702__SYSCALL(__NR_epoll_create1, sys_epoll_create1)
703#define __NR_dup3 358
704__SYSCALL(__NR_dup3, sys_dup3)
705#define __NR_pipe2 359
706__SYSCALL(__NR_pipe2, sys_pipe2)
707#define __NR_inotify_init1 360
708__SYSCALL(__NR_inotify_init1, sys_inotify_init1)
709#define __NR_preadv 361
710__SYSCALL(__NR_preadv, sys_preadv)
711#define __NR_pwritev 362
712__SYSCALL(__NR_pwritev, sys_pwritev)
713#define __NR_rt_tgsigqueueinfo 363
714__SYSCALL(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo)
715#define __NR_perf_event_open 364
716__SYSCALL(__NR_perf_event_open, sys_perf_event_open)
717#define __NR_recvmmsg 365
718__SYSCALL(__NR_recvmmsg, sys_recvmmsg)
719#define __NR_accept4 366
720__SYSCALL(__NR_accept4, sys_accept4)
721#define __NR_fanotify_init 367
722__SYSCALL(__NR_fanotify_init, sys_fanotify_init)
723#define __NR_fanotify_mark 368
724__SYSCALL(__NR_fanotify_mark, sys_fanotify_mark)
725#define __NR_prlimit64 369
726__SYSCALL(__NR_prlimit64, sys_prlimit64)
727#define __NR_name_to_handle_at 370
728__SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at)
729#define __NR_open_by_handle_at 371
730__SYSCALL(__NR_open_by_handle_at, sys_open_by_handle_at)
731#define __NR_clock_adjtime 372
732__SYSCALL(__NR_clock_adjtime, sys_clock_adjtime)
733#define __NR_syncfs 373
734__SYSCALL(__NR_syncfs, sys_syncfs)
735
736/*
737 * The following SVCs are ARM private.
738 */
739#define __ARM_NR_COMPAT_BASE 0x0f0000
740#define __ARM_NR_compat_cacheflush (__ARM_NR_COMPAT_BASE+2)
741#define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE+5)
742
743#endif /* __SYSCALL_COMPAT */
744
745#define __NR_compat_syscalls 374
746
747#define __ARCH_WANT_COMPAT_IPC_PARSE_VERSION
748#define __ARCH_WANT_COMPAT_STAT64
749#define __ARCH_WANT_SYS_GETHOSTNAME
750#define __ARCH_WANT_SYS_PAUSE
751#define __ARCH_WANT_SYS_GETPGRP
752#define __ARCH_WANT_SYS_LLSEEK
753#define __ARCH_WANT_SYS_NICE
754#define __ARCH_WANT_SYS_SIGPENDING
755#define __ARCH_WANT_SYS_SIGPROCMASK
756#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
757
758#endif /* __ASM_UNISTD32_H */
diff --git a/arch/arm64/include/asm/vdso.h b/arch/arm64/include/asm/vdso.h
new file mode 100644
index 000000000000..839ce0031bd5
--- /dev/null
+++ b/arch/arm64/include/asm/vdso.h
@@ -0,0 +1,41 @@
1/*
2 * Copyright (C) 2012 ARM Limited
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_VDSO_H
17#define __ASM_VDSO_H
18
19#ifdef __KERNEL__
20
21/*
22 * Default link address for the vDSO.
23 * Since we randomise the VDSO mapping, there's little point in trying
24 * to prelink this.
25 */
26#define VDSO_LBASE 0x0
27
28#ifndef __ASSEMBLY__
29
30#include <generated/vdso-offsets.h>
31
32#define VDSO_SYMBOL(base, name) \
33({ \
34 (void *)(vdso_offset_##name - VDSO_LBASE + (unsigned long)(base)); \
35})
36
37#endif /* !__ASSEMBLY__ */
38
39#endif /* __KERNEL__ */
40
41#endif /* __ASM_VDSO_H */
diff --git a/arch/arm64/include/asm/vdso_datapage.h b/arch/arm64/include/asm/vdso_datapage.h
new file mode 100644
index 000000000000..de66199673d7
--- /dev/null
+++ b/arch/arm64/include/asm/vdso_datapage.h
@@ -0,0 +1,43 @@
1/*
2 * Copyright (C) 2012 ARM Limited
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_VDSO_DATAPAGE_H
17#define __ASM_VDSO_DATAPAGE_H
18
19#ifdef __KERNEL__
20
21#ifndef __ASSEMBLY__
22
23struct vdso_data {
24 __u64 cs_cycle_last; /* Timebase at clocksource init */
25 __u64 xtime_clock_sec; /* Kernel time */
26 __u64 xtime_clock_nsec;
27 __u64 xtime_coarse_sec; /* Coarse time */
28 __u64 xtime_coarse_nsec;
29 __u64 wtm_clock_sec; /* Wall to monotonic time */
30 __u64 wtm_clock_nsec;
31 __u32 tb_seq_count; /* Timebase sequence counter */
32 __u32 cs_mult; /* Clocksource multiplier */
33 __u32 cs_shift; /* Clocksource shift */
34 __u32 tz_minuteswest; /* Whacky timezone stuff */
35 __u32 tz_dsttime;
36 __u32 use_syscall;
37};
38
39#endif /* !__ASSEMBLY__ */
40
41#endif /* __KERNEL__ */
42
43#endif /* __ASM_VDSO_DATAPAGE_H */
diff --git a/arch/arm64/kernel/.gitignore b/arch/arm64/kernel/.gitignore
new file mode 100644
index 000000000000..c5f676c3c224
--- /dev/null
+++ b/arch/arm64/kernel/.gitignore
@@ -0,0 +1 @@
vmlinux.lds
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
new file mode 100644
index 000000000000..e2caff1b812a
--- /dev/null
+++ b/arch/arm64/kernel/Makefile
@@ -0,0 +1,27 @@
1#
2# Makefile for the linux kernel.
3#
4
5CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET)
6AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
7
8# Object file lists.
9arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \
10 entry-fpsimd.o process.o ptrace.o setup.o signal.o \
11 sys.o stacktrace.o time.o traps.o io.o vdso.o
12
13arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \
14 sys_compat.o
15arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o
16arm64-obj-$(CONFIG_SMP) += smp.o
17arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
18arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
19
20obj-y += $(arm64-obj-y) vdso/
21obj-m += $(arm64-obj-m)
22head-y := head.o
23extra-y := $(head-y) vmlinux.lds
24
25# vDSO - this must be built first to generate the symbol offsets
26$(call objectify,$(arm64-obj-y)): $(obj)/vdso/vdso-offsets.h
27$(obj)/vdso/vdso-offsets.h: $(obj)/vdso
diff --git a/arch/arm64/kernel/arm64ksyms.c b/arch/arm64/kernel/arm64ksyms.c
new file mode 100644
index 000000000000..cef3925eaf60
--- /dev/null
+++ b/arch/arm64/kernel/arm64ksyms.c
@@ -0,0 +1,46 @@
1/*
2 * Based on arch/arm/kernel/armksyms.c
3 *
4 * Copyright (C) 2000 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/export.h>
21#include <linux/sched.h>
22#include <linux/string.h>
23#include <linux/cryptohash.h>
24#include <linux/delay.h>
25#include <linux/in6.h>
26#include <linux/syscalls.h>
27#include <linux/uaccess.h>
28#include <linux/io.h>
29
30#include <asm/checksum.h>
31
32 /* user mem (segment) */
33EXPORT_SYMBOL(__strnlen_user);
34EXPORT_SYMBOL(__strncpy_from_user);
35
36EXPORT_SYMBOL(copy_page);
37
38EXPORT_SYMBOL(__copy_from_user);
39EXPORT_SYMBOL(__copy_to_user);
40EXPORT_SYMBOL(__clear_user);
41
42 /* bitops */
43EXPORT_SYMBOL(__atomic_hash);
44
45 /* physical memory */
46EXPORT_SYMBOL(memstart_addr);
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
new file mode 100644
index 000000000000..a2a4d810bea3
--- /dev/null
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -0,0 +1,108 @@
1/*
2 * Based on arch/arm/kernel/asm-offsets.c
3 *
4 * Copyright (C) 1995-2003 Russell King
5 * 2001-2002 Keith Owens
6 * Copyright (C) 2012 ARM Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <linux/sched.h>
22#include <linux/mm.h>
23#include <linux/dma-mapping.h>
24#include <asm/thread_info.h>
25#include <asm/memory.h>
26#include <asm/cputable.h>
27#include <asm/vdso_datapage.h>
28#include <linux/kbuild.h>
29
30int main(void)
31{
32 DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
33 BLANK();
34 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
35 DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
36 DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
37 DEFINE(TI_TASK, offsetof(struct thread_info, task));
38 DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain));
39 DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
40 BLANK();
41 DEFINE(THREAD_CPU_CONTEXT, offsetof(struct task_struct, thread.cpu_context));
42 BLANK();
43 DEFINE(S_X0, offsetof(struct pt_regs, regs[0]));
44 DEFINE(S_X1, offsetof(struct pt_regs, regs[1]));
45 DEFINE(S_X2, offsetof(struct pt_regs, regs[2]));
46 DEFINE(S_X3, offsetof(struct pt_regs, regs[3]));
47 DEFINE(S_X4, offsetof(struct pt_regs, regs[4]));
48 DEFINE(S_X5, offsetof(struct pt_regs, regs[5]));
49 DEFINE(S_X6, offsetof(struct pt_regs, regs[6]));
50 DEFINE(S_X7, offsetof(struct pt_regs, regs[7]));
51 DEFINE(S_LR, offsetof(struct pt_regs, regs[30]));
52 DEFINE(S_SP, offsetof(struct pt_regs, sp));
53#ifdef CONFIG_COMPAT
54 DEFINE(S_COMPAT_SP, offsetof(struct pt_regs, compat_sp));
55#endif
56 DEFINE(S_PSTATE, offsetof(struct pt_regs, pstate));
57 DEFINE(S_PC, offsetof(struct pt_regs, pc));
58 DEFINE(S_ORIG_X0, offsetof(struct pt_regs, orig_x0));
59 DEFINE(S_SYSCALLNO, offsetof(struct pt_regs, syscallno));
60 DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
61 BLANK();
62 DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id));
63 BLANK();
64 DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm));
65 DEFINE(VMA_VM_FLAGS, offsetof(struct vm_area_struct, vm_flags));
66 BLANK();
67 DEFINE(VM_EXEC, VM_EXEC);
68 BLANK();
69 DEFINE(PAGE_SZ, PAGE_SIZE);
70 BLANK();
71 DEFINE(CPU_INFO_SZ, sizeof(struct cpu_info));
72 DEFINE(CPU_INFO_SETUP, offsetof(struct cpu_info, cpu_setup));
73 BLANK();
74 DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL);
75 DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE);
76 DEFINE(DMA_FROM_DEVICE, DMA_FROM_DEVICE);
77 BLANK();
78 DEFINE(CLOCK_REALTIME, CLOCK_REALTIME);
79 DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
80 DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
81 DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE);
82 DEFINE(CLOCK_MONOTONIC_COARSE,CLOCK_MONOTONIC_COARSE);
83 DEFINE(CLOCK_COARSE_RES, LOW_RES_NSEC);
84 DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
85 BLANK();
86 DEFINE(VDSO_CS_CYCLE_LAST, offsetof(struct vdso_data, cs_cycle_last));
87 DEFINE(VDSO_XTIME_CLK_SEC, offsetof(struct vdso_data, xtime_clock_sec));
88 DEFINE(VDSO_XTIME_CLK_NSEC, offsetof(struct vdso_data, xtime_clock_nsec));
89 DEFINE(VDSO_XTIME_CRS_SEC, offsetof(struct vdso_data, xtime_coarse_sec));
90 DEFINE(VDSO_XTIME_CRS_NSEC, offsetof(struct vdso_data, xtime_coarse_nsec));
91 DEFINE(VDSO_WTM_CLK_SEC, offsetof(struct vdso_data, wtm_clock_sec));
92 DEFINE(VDSO_WTM_CLK_NSEC, offsetof(struct vdso_data, wtm_clock_nsec));
93 DEFINE(VDSO_TB_SEQ_COUNT, offsetof(struct vdso_data, tb_seq_count));
94 DEFINE(VDSO_CS_MULT, offsetof(struct vdso_data, cs_mult));
95 DEFINE(VDSO_CS_SHIFT, offsetof(struct vdso_data, cs_shift));
96 DEFINE(VDSO_TZ_MINWEST, offsetof(struct vdso_data, tz_minuteswest));
97 DEFINE(VDSO_TZ_DSTTIME, offsetof(struct vdso_data, tz_dsttime));
98 DEFINE(VDSO_USE_SYSCALL, offsetof(struct vdso_data, use_syscall));
99 BLANK();
100 DEFINE(TVAL_TV_SEC, offsetof(struct timeval, tv_sec));
101 DEFINE(TVAL_TV_USEC, offsetof(struct timeval, tv_usec));
102 DEFINE(TSPEC_TV_SEC, offsetof(struct timespec, tv_sec));
103 DEFINE(TSPEC_TV_NSEC, offsetof(struct timespec, tv_nsec));
104 BLANK();
105 DEFINE(TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
106 DEFINE(TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
107 return 0;
108}
diff --git a/arch/arm64/kernel/cputable.c b/arch/arm64/kernel/cputable.c
new file mode 100644
index 000000000000..63cfc4a43f4e
--- /dev/null
+++ b/arch/arm64/kernel/cputable.c
@@ -0,0 +1,33 @@
1/*
2 * arch/arm64/kernel/cputable.c
3 *
4 * Copyright (C) 2012 ARM Ltd.
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/init.h>
20
21#include <asm/cputable.h>
22
23extern unsigned long __cpu_setup(void);
24
25struct cpu_info __initdata cpu_table[] = {
26 {
27 .cpu_id_val = 0x000f0000,
28 .cpu_id_mask = 0x000f0000,
29 .cpu_name = "AArch64 Processor",
30 .cpu_setup = __cpu_setup,
31 },
32 { /* Empty */ },
33};
diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
new file mode 100644
index 000000000000..0c3ba9f51376
--- /dev/null
+++ b/arch/arm64/kernel/debug-monitors.c
@@ -0,0 +1,288 @@
1/*
2 * ARMv8 single-step debug support and mdscr context switching.
3 *
4 * Copyright (C) 2012 ARM Limited
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Author: Will Deacon <will.deacon@arm.com>
19 */
20
21#include <linux/cpu.h>
22#include <linux/debugfs.h>
23#include <linux/hardirq.h>
24#include <linux/init.h>
25#include <linux/ptrace.h>
26#include <linux/stat.h>
27
28#include <asm/debug-monitors.h>
29#include <asm/local.h>
30#include <asm/cputype.h>
31#include <asm/system_misc.h>
32
33/* Low-level stepping controls. */
34#define DBG_MDSCR_SS (1 << 0)
35#define DBG_SPSR_SS (1 << 21)
36
37/* MDSCR_EL1 enabling bits */
38#define DBG_MDSCR_KDE (1 << 13)
39#define DBG_MDSCR_MDE (1 << 15)
40#define DBG_MDSCR_MASK ~(DBG_MDSCR_KDE | DBG_MDSCR_MDE)
41
42/* Determine debug architecture. */
43u8 debug_monitors_arch(void)
44{
45 return read_cpuid(ID_AA64DFR0_EL1) & 0xf;
46}
47
48/*
49 * MDSCR access routines.
50 */
51static void mdscr_write(u32 mdscr)
52{
53 unsigned long flags;
54 local_dbg_save(flags);
55 asm volatile("msr mdscr_el1, %0" :: "r" (mdscr));
56 local_dbg_restore(flags);
57}
58
59static u32 mdscr_read(void)
60{
61 u32 mdscr;
62 asm volatile("mrs %0, mdscr_el1" : "=r" (mdscr));
63 return mdscr;
64}
65
66/*
67 * Allow root to disable self-hosted debug from userspace.
68 * This is useful if you want to connect an external JTAG debugger.
69 */
70static u32 debug_enabled = 1;
71
72static int create_debug_debugfs_entry(void)
73{
74 debugfs_create_bool("debug_enabled", 0644, NULL, &debug_enabled);
75 return 0;
76}
77fs_initcall(create_debug_debugfs_entry);
78
79static int __init early_debug_disable(char *buf)
80{
81 debug_enabled = 0;
82 return 0;
83}
84
85early_param("nodebugmon", early_debug_disable);
86
87/*
88 * Keep track of debug users on each core.
89 * The ref counts are per-cpu so we use a local_t type.
90 */
91static DEFINE_PER_CPU(local_t, mde_ref_count);
92static DEFINE_PER_CPU(local_t, kde_ref_count);
93
94void enable_debug_monitors(enum debug_el el)
95{
96 u32 mdscr, enable = 0;
97
98 WARN_ON(preemptible());
99
100 if (local_inc_return(&__get_cpu_var(mde_ref_count)) == 1)
101 enable = DBG_MDSCR_MDE;
102
103 if (el == DBG_ACTIVE_EL1 &&
104 local_inc_return(&__get_cpu_var(kde_ref_count)) == 1)
105 enable |= DBG_MDSCR_KDE;
106
107 if (enable && debug_enabled) {
108 mdscr = mdscr_read();
109 mdscr |= enable;
110 mdscr_write(mdscr);
111 }
112}
113
114void disable_debug_monitors(enum debug_el el)
115{
116 u32 mdscr, disable = 0;
117
118 WARN_ON(preemptible());
119
120 if (local_dec_and_test(&__get_cpu_var(mde_ref_count)))
121 disable = ~DBG_MDSCR_MDE;
122
123 if (el == DBG_ACTIVE_EL1 &&
124 local_dec_and_test(&__get_cpu_var(kde_ref_count)))
125 disable &= ~DBG_MDSCR_KDE;
126
127 if (disable) {
128 mdscr = mdscr_read();
129 mdscr &= disable;
130 mdscr_write(mdscr);
131 }
132}
133
134/*
135 * OS lock clearing.
136 */
137static void clear_os_lock(void *unused)
138{
139 asm volatile("msr mdscr_el1, %0" : : "r" (0));
140 isb();
141 asm volatile("msr oslar_el1, %0" : : "r" (0));
142 isb();
143}
144
145static int __cpuinit os_lock_notify(struct notifier_block *self,
146 unsigned long action, void *data)
147{
148 int cpu = (unsigned long)data;
149 if (action == CPU_ONLINE)
150 smp_call_function_single(cpu, clear_os_lock, NULL, 1);
151 return NOTIFY_OK;
152}
153
154static struct notifier_block __cpuinitdata os_lock_nb = {
155 .notifier_call = os_lock_notify,
156};
157
158static int __cpuinit debug_monitors_init(void)
159{
160 /* Clear the OS lock. */
161 smp_call_function(clear_os_lock, NULL, 1);
162 clear_os_lock(NULL);
163
164 /* Register hotplug handler. */
165 register_cpu_notifier(&os_lock_nb);
166 return 0;
167}
168postcore_initcall(debug_monitors_init);
169
170/*
171 * Single step API and exception handling.
172 */
173static void set_regs_spsr_ss(struct pt_regs *regs)
174{
175 unsigned long spsr;
176
177 spsr = regs->pstate;
178 spsr &= ~DBG_SPSR_SS;
179 spsr |= DBG_SPSR_SS;
180 regs->pstate = spsr;
181}
182
183static void clear_regs_spsr_ss(struct pt_regs *regs)
184{
185 unsigned long spsr;
186
187 spsr = regs->pstate;
188 spsr &= ~DBG_SPSR_SS;
189 regs->pstate = spsr;
190}
191
192static int single_step_handler(unsigned long addr, unsigned int esr,
193 struct pt_regs *regs)
194{
195 siginfo_t info;
196
197 /*
198 * If we are stepping a pending breakpoint, call the hw_breakpoint
199 * handler first.
200 */
201 if (!reinstall_suspended_bps(regs))
202 return 0;
203
204 if (user_mode(regs)) {
205 info.si_signo = SIGTRAP;
206 info.si_errno = 0;
207 info.si_code = TRAP_HWBKPT;
208 info.si_addr = (void __user *)instruction_pointer(regs);
209 force_sig_info(SIGTRAP, &info, current);
210
211 /*
212 * ptrace will disable single step unless explicitly
213 * asked to re-enable it. For other clients, it makes
214 * sense to leave it enabled (i.e. rewind the controls
215 * to the active-not-pending state).
216 */
217 user_rewind_single_step(current);
218 } else {
219 /* TODO: route to KGDB */
220 pr_warning("Unexpected kernel single-step exception at EL1\n");
221 /*
222 * Re-enable stepping since we know that we will be
223 * returning to regs.
224 */
225 set_regs_spsr_ss(regs);
226 }
227
228 return 0;
229}
230
231static int __init single_step_init(void)
232{
233 hook_debug_fault_code(DBG_ESR_EVT_HWSS, single_step_handler, SIGTRAP,
234 TRAP_HWBKPT, "single-step handler");
235 return 0;
236}
237arch_initcall(single_step_init);
238
239/* Re-enable single step for syscall restarting. */
240void user_rewind_single_step(struct task_struct *task)
241{
242 /*
243 * If single step is active for this thread, then set SPSR.SS
244 * to 1 to avoid returning to the active-pending state.
245 */
246 if (test_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP))
247 set_regs_spsr_ss(task_pt_regs(task));
248}
249
250void user_fastforward_single_step(struct task_struct *task)
251{
252 if (test_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP))
253 clear_regs_spsr_ss(task_pt_regs(task));
254}
255
256/* Kernel API */
257void kernel_enable_single_step(struct pt_regs *regs)
258{
259 WARN_ON(!irqs_disabled());
260 set_regs_spsr_ss(regs);
261 mdscr_write(mdscr_read() | DBG_MDSCR_SS);
262 enable_debug_monitors(DBG_ACTIVE_EL1);
263}
264
265void kernel_disable_single_step(void)
266{
267 WARN_ON(!irqs_disabled());
268 mdscr_write(mdscr_read() & ~DBG_MDSCR_SS);
269 disable_debug_monitors(DBG_ACTIVE_EL1);
270}
271
272int kernel_active_single_step(void)
273{
274 WARN_ON(!irqs_disabled());
275 return mdscr_read() & DBG_MDSCR_SS;
276}
277
278/* ptrace API */
279void user_enable_single_step(struct task_struct *task)
280{
281 set_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP);
282 set_regs_spsr_ss(task_pt_regs(task));
283}
284
285void user_disable_single_step(struct task_struct *task)
286{
287 clear_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP);
288}
diff --git a/arch/arm64/kernel/entry-fpsimd.S b/arch/arm64/kernel/entry-fpsimd.S
new file mode 100644
index 000000000000..17988a6e7ea2
--- /dev/null
+++ b/arch/arm64/kernel/entry-fpsimd.S
@@ -0,0 +1,80 @@
1/*
2 * FP/SIMD state saving and restoring
3 *
4 * Copyright (C) 2012 ARM Ltd.
5 * Author: Catalin Marinas <catalin.marinas@arm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/linkage.h>
21
22#include <asm/assembler.h>
23
24/*
25 * Save the FP registers.
26 *
27 * x0 - pointer to struct fpsimd_state
28 */
29ENTRY(fpsimd_save_state)
30 stp q0, q1, [x0, #16 * 0]
31 stp q2, q3, [x0, #16 * 2]
32 stp q4, q5, [x0, #16 * 4]
33 stp q6, q7, [x0, #16 * 6]
34 stp q8, q9, [x0, #16 * 8]
35 stp q10, q11, [x0, #16 * 10]
36 stp q12, q13, [x0, #16 * 12]
37 stp q14, q15, [x0, #16 * 14]
38 stp q16, q17, [x0, #16 * 16]
39 stp q18, q19, [x0, #16 * 18]
40 stp q20, q21, [x0, #16 * 20]
41 stp q22, q23, [x0, #16 * 22]
42 stp q24, q25, [x0, #16 * 24]
43 stp q26, q27, [x0, #16 * 26]
44 stp q28, q29, [x0, #16 * 28]
45 stp q30, q31, [x0, #16 * 30]!
46 mrs x8, fpsr
47 str w8, [x0, #16 * 2]
48 mrs x8, fpcr
49 str w8, [x0, #16 * 2 + 4]
50 ret
51ENDPROC(fpsimd_save_state)
52
53/*
54 * Load the FP registers.
55 *
56 * x0 - pointer to struct fpsimd_state
57 */
58ENTRY(fpsimd_load_state)
59 ldp q0, q1, [x0, #16 * 0]
60 ldp q2, q3, [x0, #16 * 2]
61 ldp q4, q5, [x0, #16 * 4]
62 ldp q6, q7, [x0, #16 * 6]
63 ldp q8, q9, [x0, #16 * 8]
64 ldp q10, q11, [x0, #16 * 10]
65 ldp q12, q13, [x0, #16 * 12]
66 ldp q14, q15, [x0, #16 * 14]
67 ldp q16, q17, [x0, #16 * 16]
68 ldp q18, q19, [x0, #16 * 18]
69 ldp q20, q21, [x0, #16 * 20]
70 ldp q22, q23, [x0, #16 * 22]
71 ldp q24, q25, [x0, #16 * 24]
72 ldp q26, q27, [x0, #16 * 26]
73 ldp q28, q29, [x0, #16 * 28]
74 ldp q30, q31, [x0, #16 * 30]!
75 ldr w8, [x0, #16 * 2]
76 ldr w9, [x0, #16 * 2 + 4]
77 msr fpsr, x8
78 msr fpcr, x9
79 ret
80ENDPROC(fpsimd_load_state)
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
new file mode 100644
index 000000000000..38cf853a3667
--- /dev/null
+++ b/arch/arm64/kernel/entry.S
@@ -0,0 +1,695 @@
1/*
2 * Low-level exception handling code
3 *
4 * Copyright (C) 2012 ARM Ltd.
5 * Authors: Catalin Marinas <catalin.marinas@arm.com>
6 * Will Deacon <will.deacon@arm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <linux/init.h>
22#include <linux/linkage.h>
23
24#include <asm/assembler.h>
25#include <asm/asm-offsets.h>
26#include <asm/errno.h>
27#include <asm/thread_info.h>
28#include <asm/unistd.h>
29
30/*
31 * Bad Abort numbers
32 *-----------------
33 */
34#define BAD_SYNC 0
35#define BAD_IRQ 1
36#define BAD_FIQ 2
37#define BAD_ERROR 3
38
39 .macro kernel_entry, el, regsize = 64
40 sub sp, sp, #S_FRAME_SIZE - S_LR // room for LR, SP, SPSR, ELR
41 .if \regsize == 32
42 mov w0, w0 // zero upper 32 bits of x0
43 .endif
44 push x28, x29
45 push x26, x27
46 push x24, x25
47 push x22, x23
48 push x20, x21
49 push x18, x19
50 push x16, x17
51 push x14, x15
52 push x12, x13
53 push x10, x11
54 push x8, x9
55 push x6, x7
56 push x4, x5
57 push x2, x3
58 push x0, x1
59 .if \el == 0
60 mrs x21, sp_el0
61 .else
62 add x21, sp, #S_FRAME_SIZE
63 .endif
64 mrs x22, elr_el1
65 mrs x23, spsr_el1
66 stp lr, x21, [sp, #S_LR]
67 stp x22, x23, [sp, #S_PC]
68
69 /*
70 * Set syscallno to -1 by default (overridden later if real syscall).
71 */
72 .if \el == 0
73 mvn x21, xzr
74 str x21, [sp, #S_SYSCALLNO]
75 .endif
76
77 /*
78 * Registers that may be useful after this macro is invoked:
79 *
80 * x21 - aborted SP
81 * x22 - aborted PC
82 * x23 - aborted PSTATE
83 */
84 .endm
85
86 .macro kernel_exit, el, ret = 0
87 ldp x21, x22, [sp, #S_PC] // load ELR, SPSR
88 .if \el == 0
89 ldr x23, [sp, #S_SP] // load return stack pointer
90 .endif
91 .if \ret
92 ldr x1, [sp, #S_X1] // preserve x0 (syscall return)
93 add sp, sp, S_X2
94 .else
95 pop x0, x1
96 .endif
97 pop x2, x3 // load the rest of the registers
98 pop x4, x5
99 pop x6, x7
100 pop x8, x9
101 msr elr_el1, x21 // set up the return data
102 msr spsr_el1, x22
103 .if \el == 0
104 msr sp_el0, x23
105 .endif
106 pop x10, x11
107 pop x12, x13
108 pop x14, x15
109 pop x16, x17
110 pop x18, x19
111 pop x20, x21
112 pop x22, x23
113 pop x24, x25
114 pop x26, x27
115 pop x28, x29
116 ldr lr, [sp], #S_FRAME_SIZE - S_LR // load LR and restore SP
117 eret // return to kernel
118 .endm
119
120 .macro get_thread_info, rd
121 mov \rd, sp
122 and \rd, \rd, #~((1 << 13) - 1) // top of 8K stack
123 .endm
124
125/*
126 * These are the registers used in the syscall handler, and allow us to
127 * have in theory up to 7 arguments to a function - x0 to x6.
128 *
129 * x7 is reserved for the system call number in 32-bit mode.
130 */
131sc_nr .req x25 // number of system calls
132scno .req x26 // syscall number
133stbl .req x27 // syscall table pointer
134tsk .req x28 // current thread_info
135
136/*
137 * Interrupt handling.
138 */
139 .macro irq_handler
140 ldr x1, handle_arch_irq
141 mov x0, sp
142 blr x1
143 .endm
144
145 .text
146
147/*
148 * Exception vectors.
149 */
150 .macro ventry label
151 .align 7
152 b \label
153 .endm
154
155 .align 11
156ENTRY(vectors)
157 ventry el1_sync_invalid // Synchronous EL1t
158 ventry el1_irq_invalid // IRQ EL1t
159 ventry el1_fiq_invalid // FIQ EL1t
160 ventry el1_error_invalid // Error EL1t
161
162 ventry el1_sync // Synchronous EL1h
163 ventry el1_irq // IRQ EL1h
164 ventry el1_fiq_invalid // FIQ EL1h
165 ventry el1_error_invalid // Error EL1h
166
167 ventry el0_sync // Synchronous 64-bit EL0
168 ventry el0_irq // IRQ 64-bit EL0
169 ventry el0_fiq_invalid // FIQ 64-bit EL0
170 ventry el0_error_invalid // Error 64-bit EL0
171
172#ifdef CONFIG_COMPAT
173 ventry el0_sync_compat // Synchronous 32-bit EL0
174 ventry el0_irq_compat // IRQ 32-bit EL0
175 ventry el0_fiq_invalid_compat // FIQ 32-bit EL0
176 ventry el0_error_invalid_compat // Error 32-bit EL0
177#else
178 ventry el0_sync_invalid // Synchronous 32-bit EL0
179 ventry el0_irq_invalid // IRQ 32-bit EL0
180 ventry el0_fiq_invalid // FIQ 32-bit EL0
181 ventry el0_error_invalid // Error 32-bit EL0
182#endif
183END(vectors)
184
185/*
186 * Invalid mode handlers
187 */
188 .macro inv_entry, el, reason, regsize = 64
189 kernel_entry el, \regsize
190 mov x0, sp
191 mov x1, #\reason
192 mrs x2, esr_el1
193 b bad_mode
194 .endm
195
196el0_sync_invalid:
197 inv_entry 0, BAD_SYNC
198ENDPROC(el0_sync_invalid)
199
200el0_irq_invalid:
201 inv_entry 0, BAD_IRQ
202ENDPROC(el0_irq_invalid)
203
204el0_fiq_invalid:
205 inv_entry 0, BAD_FIQ
206ENDPROC(el0_fiq_invalid)
207
208el0_error_invalid:
209 inv_entry 0, BAD_ERROR
210ENDPROC(el0_error_invalid)
211
212#ifdef CONFIG_COMPAT
213el0_fiq_invalid_compat:
214 inv_entry 0, BAD_FIQ, 32
215ENDPROC(el0_fiq_invalid_compat)
216
217el0_error_invalid_compat:
218 inv_entry 0, BAD_ERROR, 32
219ENDPROC(el0_error_invalid_compat)
220#endif
221
222el1_sync_invalid:
223 inv_entry 1, BAD_SYNC
224ENDPROC(el1_sync_invalid)
225
226el1_irq_invalid:
227 inv_entry 1, BAD_IRQ
228ENDPROC(el1_irq_invalid)
229
230el1_fiq_invalid:
231 inv_entry 1, BAD_FIQ
232ENDPROC(el1_fiq_invalid)
233
234el1_error_invalid:
235 inv_entry 1, BAD_ERROR
236ENDPROC(el1_error_invalid)
237
238/*
239 * EL1 mode handlers.
240 */
241 .align 6
242el1_sync:
243 kernel_entry 1
244 mrs x1, esr_el1 // read the syndrome register
245 lsr x24, x1, #26 // exception class
246 cmp x24, #0x25 // data abort in EL1
247 b.eq el1_da
248 cmp x24, #0x18 // configurable trap
249 b.eq el1_undef
250 cmp x24, #0x26 // stack alignment exception
251 b.eq el1_sp_pc
252 cmp x24, #0x22 // pc alignment exception
253 b.eq el1_sp_pc
254 cmp x24, #0x00 // unknown exception in EL1
255 b.eq el1_undef
256 cmp x24, #0x30 // debug exception in EL1
257 b.ge el1_dbg
258 b el1_inv
259el1_da:
260 /*
261 * Data abort handling
262 */
263 mrs x0, far_el1
264 enable_dbg_if_not_stepping x2
265 // re-enable interrupts if they were enabled in the aborted context
266 tbnz x23, #7, 1f // PSR_I_BIT
267 enable_irq
2681:
269 mov x2, sp // struct pt_regs
270 bl do_mem_abort
271
272 // disable interrupts before pulling preserved data off the stack
273 disable_irq
274 kernel_exit 1
275el1_sp_pc:
276 /*
277 * Stack or PC alignment exception handling
278 */
279 mrs x0, far_el1
280 mov x1, x25
281 mov x2, sp
282 b do_sp_pc_abort
283el1_undef:
284 /*
285 * Undefined instruction
286 */
287 mov x0, sp
288 b do_undefinstr
289el1_dbg:
290 /*
291 * Debug exception handling
292 */
293 tbz x24, #0, el1_inv // EL1 only
294 mrs x0, far_el1
295 mov x2, sp // struct pt_regs
296 bl do_debug_exception
297
298 kernel_exit 1
299el1_inv:
300 // TODO: add support for undefined instructions in kernel mode
301 mov x0, sp
302 mov x1, #BAD_SYNC
303 mrs x2, esr_el1
304 b bad_mode
305ENDPROC(el1_sync)
306
307 .align 6
308el1_irq:
309 kernel_entry 1
310 enable_dbg_if_not_stepping x0
311#ifdef CONFIG_TRACE_IRQFLAGS
312 bl trace_hardirqs_off
313#endif
314#ifdef CONFIG_PREEMPT
315 get_thread_info tsk
316 ldr x24, [tsk, #TI_PREEMPT] // get preempt count
317 add x0, x24, #1 // increment it
318 str x0, [tsk, #TI_PREEMPT]
319#endif
320 irq_handler
321#ifdef CONFIG_PREEMPT
322 str x24, [tsk, #TI_PREEMPT] // restore preempt count
323 cbnz x24, 1f // preempt count != 0
324 ldr x0, [tsk, #TI_FLAGS] // get flags
325 tbz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling?
326 bl el1_preempt
3271:
328#endif
329#ifdef CONFIG_TRACE_IRQFLAGS
330 bl trace_hardirqs_on
331#endif
332 kernel_exit 1
333ENDPROC(el1_irq)
334
335#ifdef CONFIG_PREEMPT
336el1_preempt:
337 mov x24, lr
3381: enable_dbg
339 bl preempt_schedule_irq // irq en/disable is done inside
340 ldr x0, [tsk, #TI_FLAGS] // get new tasks TI_FLAGS
341 tbnz x0, #TIF_NEED_RESCHED, 1b // needs rescheduling?
342 ret x24
343#endif
344
345/*
346 * EL0 mode handlers.
347 */
348 .align 6
349el0_sync:
350 kernel_entry 0
351 mrs x25, esr_el1 // read the syndrome register
352 lsr x24, x25, #26 // exception class
353 cmp x24, #0x15 // SVC in 64-bit state
354 b.eq el0_svc
355 adr lr, ret_from_exception
356 cmp x24, #0x24 // data abort in EL0
357 b.eq el0_da
358 cmp x24, #0x20 // instruction abort in EL0
359 b.eq el0_ia
360 cmp x24, #0x07 // FP/ASIMD access
361 b.eq el0_fpsimd_acc
362 cmp x24, #0x2c // FP/ASIMD exception
363 b.eq el0_fpsimd_exc
364 cmp x24, #0x18 // configurable trap
365 b.eq el0_undef
366 cmp x24, #0x26 // stack alignment exception
367 b.eq el0_sp_pc
368 cmp x24, #0x22 // pc alignment exception
369 b.eq el0_sp_pc
370 cmp x24, #0x00 // unknown exception in EL0
371 b.eq el0_undef
372 cmp x24, #0x30 // debug exception in EL0
373 b.ge el0_dbg
374 b el0_inv
375
376#ifdef CONFIG_COMPAT
377 .align 6
378el0_sync_compat:
379 kernel_entry 0, 32
380 mrs x25, esr_el1 // read the syndrome register
381 lsr x24, x25, #26 // exception class
382 cmp x24, #0x11 // SVC in 32-bit state
383 b.eq el0_svc_compat
384 adr lr, ret_from_exception
385 cmp x24, #0x24 // data abort in EL0
386 b.eq el0_da
387 cmp x24, #0x20 // instruction abort in EL0
388 b.eq el0_ia
389 cmp x24, #0x07 // FP/ASIMD access
390 b.eq el0_fpsimd_acc
391 cmp x24, #0x28 // FP/ASIMD exception
392 b.eq el0_fpsimd_exc
393 cmp x24, #0x00 // unknown exception in EL0
394 b.eq el0_undef
395 cmp x24, #0x30 // debug exception in EL0
396 b.ge el0_dbg
397 b el0_inv
398el0_svc_compat:
399 /*
400 * AArch32 syscall handling
401 */
402 adr stbl, compat_sys_call_table // load compat syscall table pointer
403 uxtw scno, w7 // syscall number in w7 (r7)
404 mov sc_nr, #__NR_compat_syscalls
405 b el0_svc_naked
406
407 .align 6
408el0_irq_compat:
409 kernel_entry 0, 32
410 b el0_irq_naked
411#endif
412
413el0_da:
414 /*
415 * Data abort handling
416 */
417 mrs x0, far_el1
418 disable_step x1
419 isb
420 enable_dbg
421 // enable interrupts before calling the main handler
422 enable_irq
423 mov x1, x25
424 mov x2, sp
425 b do_mem_abort
426el0_ia:
427 /*
428 * Instruction abort handling
429 */
430 mrs x0, far_el1
431 disable_step x1
432 isb
433 enable_dbg
434 // enable interrupts before calling the main handler
435 enable_irq
436 orr x1, x25, #1 << 24 // use reserved ISS bit for instruction aborts
437 mov x2, sp
438 b do_mem_abort
439el0_fpsimd_acc:
440 /*
441 * Floating Point or Advanced SIMD access
442 */
443 mov x0, x25
444 mov x1, sp
445 b do_fpsimd_acc
446el0_fpsimd_exc:
447 /*
448 * Floating Point or Advanced SIMD exception
449 */
450 mov x0, x25
451 mov x1, sp
452 b do_fpsimd_exc
453el0_sp_pc:
454 /*
455 * Stack or PC alignment exception handling
456 */
457 mrs x0, far_el1
458 disable_step x1
459 isb
460 enable_dbg
461 // enable interrupts before calling the main handler
462 enable_irq
463 mov x1, x25
464 mov x2, sp
465 b do_sp_pc_abort
466el0_undef:
467 /*
468 * Undefined instruction
469 */
470 mov x0, sp
471 b do_undefinstr
472el0_dbg:
473 /*
474 * Debug exception handling
475 */
476 tbnz x24, #0, el0_inv // EL0 only
477 mrs x0, far_el1
478 disable_step x1
479 mov x1, x25
480 mov x2, sp
481 b do_debug_exception
482el0_inv:
483 mov x0, sp
484 mov x1, #BAD_SYNC
485 mrs x2, esr_el1
486 b bad_mode
487ENDPROC(el0_sync)
488
489 .align 6
490el0_irq:
491 kernel_entry 0
492el0_irq_naked:
493 disable_step x1
494 isb
495 enable_dbg
496#ifdef CONFIG_TRACE_IRQFLAGS
497 bl trace_hardirqs_off
498#endif
499 get_thread_info tsk
500#ifdef CONFIG_PREEMPT
501 ldr x24, [tsk, #TI_PREEMPT] // get preempt count
502 add x23, x24, #1 // increment it
503 str x23, [tsk, #TI_PREEMPT]
504#endif
505 irq_handler
506#ifdef CONFIG_PREEMPT
507 ldr x0, [tsk, #TI_PREEMPT]
508 str x24, [tsk, #TI_PREEMPT]
509 cmp x0, x23
510 b.eq 1f
511 mov x1, #0
512 str x1, [x1] // BUG
5131:
514#endif
515#ifdef CONFIG_TRACE_IRQFLAGS
516 bl trace_hardirqs_on
517#endif
518 b ret_to_user
519ENDPROC(el0_irq)
520
521/*
522 * This is the return code to user mode for abort handlers
523 */
524ret_from_exception:
525 get_thread_info tsk
526 b ret_to_user
527ENDPROC(ret_from_exception)
528
529/*
530 * Register switch for AArch64. The callee-saved registers need to be saved
531 * and restored. On entry:
532 * x0 = previous task_struct (must be preserved across the switch)
533 * x1 = next task_struct
534 * Previous and next are guaranteed not to be the same.
535 *
536 */
537ENTRY(cpu_switch_to)
538 add x8, x0, #THREAD_CPU_CONTEXT
539 mov x9, sp
540 stp x19, x20, [x8], #16 // store callee-saved registers
541 stp x21, x22, [x8], #16
542 stp x23, x24, [x8], #16
543 stp x25, x26, [x8], #16
544 stp x27, x28, [x8], #16
545 stp x29, x9, [x8], #16
546 str lr, [x8]
547 add x8, x1, #THREAD_CPU_CONTEXT
548 ldp x19, x20, [x8], #16 // restore callee-saved registers
549 ldp x21, x22, [x8], #16
550 ldp x23, x24, [x8], #16
551 ldp x25, x26, [x8], #16
552 ldp x27, x28, [x8], #16
553 ldp x29, x9, [x8], #16
554 ldr lr, [x8]
555 mov sp, x9
556 ret
557ENDPROC(cpu_switch_to)
558
559/*
560 * This is the fast syscall return path. We do as little as possible here,
561 * and this includes saving x0 back into the kernel stack.
562 */
563ret_fast_syscall:
564 disable_irq // disable interrupts
565 ldr x1, [tsk, #TI_FLAGS]
566 and x2, x1, #_TIF_WORK_MASK
567 cbnz x2, fast_work_pending
568 tbz x1, #TIF_SINGLESTEP, fast_exit
569 disable_dbg
570 enable_step x2
571fast_exit:
572 kernel_exit 0, ret = 1
573
574/*
575 * Ok, we need to do extra processing, enter the slow path.
576 */
577fast_work_pending:
578 str x0, [sp, #S_X0] // returned x0
579work_pending:
580 tbnz x1, #TIF_NEED_RESCHED, work_resched
581 /* TIF_SIGPENDING or TIF_NOTIFY_RESUME case */
582 ldr x2, [sp, #S_PSTATE]
583 mov x0, sp // 'regs'
584 tst x2, #PSR_MODE_MASK // user mode regs?
585 b.ne no_work_pending // returning to kernel
586 bl do_notify_resume
587 b ret_to_user
588work_resched:
589 enable_dbg
590 bl schedule
591
592/*
593 * "slow" syscall return path.
594 */
595ENTRY(ret_to_user)
596 disable_irq // disable interrupts
597 ldr x1, [tsk, #TI_FLAGS]
598 and x2, x1, #_TIF_WORK_MASK
599 cbnz x2, work_pending
600 tbz x1, #TIF_SINGLESTEP, no_work_pending
601 disable_dbg
602 enable_step x2
603no_work_pending:
604 kernel_exit 0, ret = 0
605ENDPROC(ret_to_user)
606
607/*
608 * This is how we return from a fork.
609 */
610ENTRY(ret_from_fork)
611 bl schedule_tail
612 get_thread_info tsk
613 b ret_to_user
614ENDPROC(ret_from_fork)
615
616/*
617 * SVC handler.
618 */
619 .align 6
620el0_svc:
621 adrp stbl, sys_call_table // load syscall table pointer
622 uxtw scno, w8 // syscall number in w8
623 mov sc_nr, #__NR_syscalls
624el0_svc_naked: // compat entry point
625 stp x0, scno, [sp, #S_ORIG_X0] // save the original x0 and syscall number
626 disable_step x16
627 isb
628 enable_dbg
629 enable_irq
630
631 get_thread_info tsk
632 ldr x16, [tsk, #TI_FLAGS] // check for syscall tracing
633 tbnz x16, #TIF_SYSCALL_TRACE, __sys_trace // are we tracing syscalls?
634 adr lr, ret_fast_syscall // return address
635 cmp scno, sc_nr // check upper syscall limit
636 b.hs ni_sys
637 ldr x16, [stbl, scno, lsl #3] // address in the syscall table
638 br x16 // call sys_* routine
639ni_sys:
640 mov x0, sp
641 b do_ni_syscall
642ENDPROC(el0_svc)
643
644 /*
645 * This is the really slow path. We're going to be doing context
646 * switches, and waiting for our parent to respond.
647 */
648__sys_trace:
649 mov x1, sp
650 mov w0, #0 // trace entry
651 bl syscall_trace
652 adr lr, __sys_trace_return // return address
653 uxtw scno, w0 // syscall number (possibly new)
654 mov x1, sp // pointer to regs
655 cmp scno, sc_nr // check upper syscall limit
656 b.hs ni_sys
657 ldp x0, x1, [sp] // restore the syscall args
658 ldp x2, x3, [sp, #S_X2]
659 ldp x4, x5, [sp, #S_X4]
660 ldp x6, x7, [sp, #S_X6]
661 ldr x16, [stbl, scno, lsl #3] // address in the syscall table
662 br x16 // call sys_* routine
663
664__sys_trace_return:
665 str x0, [sp] // save returned x0
666 mov x1, sp
667 mov w0, #1 // trace exit
668 bl syscall_trace
669 b ret_to_user
670
671/*
672 * Special system call wrappers.
673 */
674ENTRY(sys_execve_wrapper)
675 mov x3, sp
676 b sys_execve
677ENDPROC(sys_execve_wrapper)
678
679ENTRY(sys_clone_wrapper)
680 mov x5, sp
681 b sys_clone
682ENDPROC(sys_clone_wrapper)
683
684ENTRY(sys_rt_sigreturn_wrapper)
685 mov x0, sp
686 b sys_rt_sigreturn
687ENDPROC(sys_rt_sigreturn_wrapper)
688
689ENTRY(sys_sigaltstack_wrapper)
690 ldr x2, [sp, #S_SP]
691 b sys_sigaltstack
692ENDPROC(sys_sigaltstack_wrapper)
693
694ENTRY(handle_arch_irq)
695 .quad 0
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
new file mode 100644
index 000000000000..e8b8357aedb4
--- /dev/null
+++ b/arch/arm64/kernel/fpsimd.c
@@ -0,0 +1,106 @@
1/*
2 * FP/SIMD context switching and fault handling
3 *
4 * Copyright (C) 2012 ARM Ltd.
5 * Author: Catalin Marinas <catalin.marinas@arm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/sched.h>
23#include <linux/signal.h>
24
25#include <asm/fpsimd.h>
26#include <asm/cputype.h>
27
28#define FPEXC_IOF (1 << 0)
29#define FPEXC_DZF (1 << 1)
30#define FPEXC_OFF (1 << 2)
31#define FPEXC_UFF (1 << 3)
32#define FPEXC_IXF (1 << 4)
33#define FPEXC_IDF (1 << 7)
34
35/*
36 * Trapped FP/ASIMD access.
37 */
38void do_fpsimd_acc(unsigned int esr, struct pt_regs *regs)
39{
40 /* TODO: implement lazy context saving/restoring */
41 WARN_ON(1);
42}
43
44/*
45 * Raise a SIGFPE for the current process.
46 */
47void do_fpsimd_exc(unsigned int esr, struct pt_regs *regs)
48{
49 siginfo_t info;
50 unsigned int si_code = 0;
51
52 if (esr & FPEXC_IOF)
53 si_code = FPE_FLTINV;
54 else if (esr & FPEXC_DZF)
55 si_code = FPE_FLTDIV;
56 else if (esr & FPEXC_OFF)
57 si_code = FPE_FLTOVF;
58 else if (esr & FPEXC_UFF)
59 si_code = FPE_FLTUND;
60 else if (esr & FPEXC_IXF)
61 si_code = FPE_FLTRES;
62
63 memset(&info, 0, sizeof(info));
64 info.si_signo = SIGFPE;
65 info.si_code = si_code;
66 info.si_addr = (void __user *)instruction_pointer(regs);
67
68 send_sig_info(SIGFPE, &info, current);
69}
70
71void fpsimd_thread_switch(struct task_struct *next)
72{
73 /* check if not kernel threads */
74 if (current->mm)
75 fpsimd_save_state(&current->thread.fpsimd_state);
76 if (next->mm)
77 fpsimd_load_state(&next->thread.fpsimd_state);
78}
79
80void fpsimd_flush_thread(void)
81{
82 memset(&current->thread.fpsimd_state, 0, sizeof(struct fpsimd_state));
83 fpsimd_load_state(&current->thread.fpsimd_state);
84}
85
86/*
87 * FP/SIMD support code initialisation.
88 */
89static int __init fpsimd_init(void)
90{
91 u64 pfr = read_cpuid(ID_AA64PFR0_EL1);
92
93 if (pfr & (0xf << 16)) {
94 pr_notice("Floating-point is not implemented\n");
95 return 0;
96 }
97 elf_hwcap |= HWCAP_FP;
98
99 if (pfr & (0xf << 20))
100 pr_notice("Advanced SIMD is not implemented\n");
101 else
102 elf_hwcap |= HWCAP_ASIMD;
103
104 return 0;
105}
106late_initcall(fpsimd_init);
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
new file mode 100644
index 000000000000..a2f02b63eae9
--- /dev/null
+++ b/arch/arm64/kernel/head.S
@@ -0,0 +1,510 @@
1/*
2 * Low-level CPU initialisation
3 * Based on arch/arm/kernel/head.S
4 *
5 * Copyright (C) 1994-2002 Russell King
6 * Copyright (C) 2003-2012 ARM Ltd.
7 * Authors: Catalin Marinas <catalin.marinas@arm.com>
8 * Will Deacon <will.deacon@arm.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23#include <linux/linkage.h>
24#include <linux/init.h>
25
26#include <asm/assembler.h>
27#include <asm/ptrace.h>
28#include <asm/asm-offsets.h>
29#include <asm/memory.h>
30#include <asm/thread_info.h>
31#include <asm/pgtable-hwdef.h>
32#include <asm/pgtable.h>
33#include <asm/page.h>
34
35/*
36 * swapper_pg_dir is the virtual address of the initial page table. We place
37 * the page tables 3 * PAGE_SIZE below KERNEL_RAM_VADDR. The idmap_pg_dir has
38 * 2 pages and is placed below swapper_pg_dir.
39 */
40#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
41
42#if (KERNEL_RAM_VADDR & 0xfffff) != 0x80000
43#error KERNEL_RAM_VADDR must start at 0xXXX80000
44#endif
45
46#define SWAPPER_DIR_SIZE (3 * PAGE_SIZE)
47#define IDMAP_DIR_SIZE (2 * PAGE_SIZE)
48
49 .globl swapper_pg_dir
50 .equ swapper_pg_dir, KERNEL_RAM_VADDR - SWAPPER_DIR_SIZE
51
52 .globl idmap_pg_dir
53 .equ idmap_pg_dir, swapper_pg_dir - IDMAP_DIR_SIZE
54
55 .macro pgtbl, ttb0, ttb1, phys
56 add \ttb1, \phys, #TEXT_OFFSET - SWAPPER_DIR_SIZE
57 sub \ttb0, \ttb1, #IDMAP_DIR_SIZE
58 .endm
59
60#ifdef CONFIG_ARM64_64K_PAGES
61#define BLOCK_SHIFT PAGE_SHIFT
62#define BLOCK_SIZE PAGE_SIZE
63#else
64#define BLOCK_SHIFT SECTION_SHIFT
65#define BLOCK_SIZE SECTION_SIZE
66#endif
67
68#define KERNEL_START KERNEL_RAM_VADDR
69#define KERNEL_END _end
70
71/*
72 * Initial memory map attributes.
73 */
74#ifndef CONFIG_SMP
75#define PTE_FLAGS PTE_TYPE_PAGE | PTE_AF
76#define PMD_FLAGS PMD_TYPE_SECT | PMD_SECT_AF
77#else
78#define PTE_FLAGS PTE_TYPE_PAGE | PTE_AF | PTE_SHARED
79#define PMD_FLAGS PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S
80#endif
81
82#ifdef CONFIG_ARM64_64K_PAGES
83#define MM_MMUFLAGS PTE_ATTRINDX(MT_NORMAL) | PTE_FLAGS
84#define IO_MMUFLAGS PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_XN | PTE_FLAGS
85#else
86#define MM_MMUFLAGS PMD_ATTRINDX(MT_NORMAL) | PMD_FLAGS
87#define IO_MMUFLAGS PMD_ATTRINDX(MT_DEVICE_nGnRE) | PMD_SECT_XN | PMD_FLAGS
88#endif
89
90/*
91 * Kernel startup entry point.
92 * ---------------------------
93 *
94 * The requirements are:
95 * MMU = off, D-cache = off, I-cache = on or off,
96 * x0 = physical address to the FDT blob.
97 *
98 * This code is mostly position independent so you call this at
99 * __pa(PAGE_OFFSET + TEXT_OFFSET).
100 *
101 * Note that the callee-saved registers are used for storing variables
102 * that are useful before the MMU is enabled. The allocations are described
103 * in the entry routines.
104 */
105 __HEAD
106
107 /*
108 * DO NOT MODIFY. Image header expected by Linux boot-loaders.
109 */
110 b stext // branch to kernel start, magic
111 .long 0 // reserved
112 .quad TEXT_OFFSET // Image load offset from start of RAM
113 .quad 0 // reserved
114 .quad 0 // reserved
115
116ENTRY(stext)
117 mov x21, x0 // x21=FDT
118 bl el2_setup // Drop to EL1
119 mrs x22, midr_el1 // x22=cpuid
120 mov x0, x22
121 bl lookup_processor_type
122 mov x23, x0 // x23=current cpu_table
123 cbz x23, __error_p // invalid processor (x23=0)?
124 bl __calc_phys_offset // x24=PHYS_OFFSET, x28=PHYS_OFFSET-PAGE_OFFSET
125 bl __vet_fdt
126 bl __create_page_tables // x25=TTBR0, x26=TTBR1
127 /*
128 * The following calls CPU specific code in a position independent
129 * manner. See arch/arm64/mm/proc.S for details. x23 = base of
130 * cpu_info structure selected by lookup_processor_type above.
131 * On return, the CPU will be ready for the MMU to be turned on and
132 * the TCR will have been set.
133 */
134 ldr x27, __switch_data // address to jump to after
135 // MMU has been enabled
136 adr lr, __enable_mmu // return (PIC) address
137 ldr x12, [x23, #CPU_INFO_SETUP]
138 add x12, x12, x28 // __virt_to_phys
139 br x12 // initialise processor
140ENDPROC(stext)
141
142/*
143 * If we're fortunate enough to boot at EL2, ensure that the world is
144 * sane before dropping to EL1.
145 */
146ENTRY(el2_setup)
147 mrs x0, CurrentEL
148 cmp x0, #PSR_MODE_EL2t
149 ccmp x0, #PSR_MODE_EL2h, #0x4, ne
150 b.eq 1f
151 ret
152
153 /* Hyp configuration. */
1541: mov x0, #(1 << 31) // 64-bit EL1
155 msr hcr_el2, x0
156
157 /* Generic timers. */
158 mrs x0, cnthctl_el2
159 orr x0, x0, #3 // Enable EL1 physical timers
160 msr cnthctl_el2, x0
161
162 /* Populate ID registers. */
163 mrs x0, midr_el1
164 mrs x1, mpidr_el1
165 msr vpidr_el2, x0
166 msr vmpidr_el2, x1
167
168 /* sctlr_el1 */
169 mov x0, #0x0800 // Set/clear RES{1,0} bits
170 movk x0, #0x30d0, lsl #16
171 msr sctlr_el1, x0
172
173 /* Coprocessor traps. */
174 mov x0, #0x33ff
175 msr cptr_el2, x0 // Disable copro. traps to EL2
176
177#ifdef CONFIG_COMPAT
178 msr hstr_el2, xzr // Disable CP15 traps to EL2
179#endif
180
181 /* spsr */
182 mov x0, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\
183 PSR_MODE_EL1h)
184 msr spsr_el2, x0
185 msr elr_el2, lr
186 eret
187ENDPROC(el2_setup)
188
189 .align 3
1902: .quad .
191 .quad PAGE_OFFSET
192
193#ifdef CONFIG_SMP
194 .pushsection .smp.pen.text, "ax"
195 .align 3
1961: .quad .
197 .quad secondary_holding_pen_release
198
199 /*
200 * This provides a "holding pen" for platforms to hold all secondary
201 * cores are held until we're ready for them to initialise.
202 */
203ENTRY(secondary_holding_pen)
204 bl el2_setup // Drop to EL1
205 mrs x0, mpidr_el1
206 and x0, x0, #15 // CPU number
207 adr x1, 1b
208 ldp x2, x3, [x1]
209 sub x1, x1, x2
210 add x3, x3, x1
211pen: ldr x4, [x3]
212 cmp x4, x0
213 b.eq secondary_startup
214 wfe
215 b pen
216ENDPROC(secondary_holding_pen)
217 .popsection
218
219ENTRY(secondary_startup)
220 /*
221 * Common entry point for secondary CPUs.
222 */
223 mrs x22, midr_el1 // x22=cpuid
224 mov x0, x22
225 bl lookup_processor_type
226 mov x23, x0 // x23=current cpu_table
227 cbz x23, __error_p // invalid processor (x23=0)?
228
229 bl __calc_phys_offset // x24=phys offset
230 pgtbl x25, x26, x24 // x25=TTBR0, x26=TTBR1
231 ldr x12, [x23, #CPU_INFO_SETUP]
232 add x12, x12, x28 // __virt_to_phys
233 blr x12 // initialise processor
234
235 ldr x21, =secondary_data
236 ldr x27, =__secondary_switched // address to jump to after enabling the MMU
237 b __enable_mmu
238ENDPROC(secondary_startup)
239
240ENTRY(__secondary_switched)
241 ldr x0, [x21] // get secondary_data.stack
242 mov sp, x0
243 mov x29, #0
244 b secondary_start_kernel
245ENDPROC(__secondary_switched)
246#endif /* CONFIG_SMP */
247
248/*
249 * Setup common bits before finally enabling the MMU. Essentially this is just
250 * loading the page table pointer and vector base registers.
251 *
252 * On entry to this code, x0 must contain the SCTLR_EL1 value for turning on
253 * the MMU.
254 */
255__enable_mmu:
256 ldr x5, =vectors
257 msr vbar_el1, x5
258 msr ttbr0_el1, x25 // load TTBR0
259 msr ttbr1_el1, x26 // load TTBR1
260 isb
261 b __turn_mmu_on
262ENDPROC(__enable_mmu)
263
264/*
265 * Enable the MMU. This completely changes the structure of the visible memory
266 * space. You will not be able to trace execution through this.
267 *
268 * x0 = system control register
269 * x27 = *virtual* address to jump to upon completion
270 *
271 * other registers depend on the function called upon completion
272 */
273 .align 6
274__turn_mmu_on:
275 msr sctlr_el1, x0
276 isb
277 br x27
278ENDPROC(__turn_mmu_on)
279
280/*
281 * Calculate the start of physical memory.
282 */
283__calc_phys_offset:
284 adr x0, 1f
285 ldp x1, x2, [x0]
286 sub x28, x0, x1 // x28 = PHYS_OFFSET - PAGE_OFFSET
287 add x24, x2, x28 // x24 = PHYS_OFFSET
288 ret
289ENDPROC(__calc_phys_offset)
290
291 .align 3
2921: .quad .
293 .quad PAGE_OFFSET
294
295/*
296 * Macro to populate the PGD for the corresponding block entry in the next
297 * level (tbl) for the given virtual address.
298 *
299 * Preserves: pgd, tbl, virt
300 * Corrupts: tmp1, tmp2
301 */
302 .macro create_pgd_entry, pgd, tbl, virt, tmp1, tmp2
303 lsr \tmp1, \virt, #PGDIR_SHIFT
304 and \tmp1, \tmp1, #PTRS_PER_PGD - 1 // PGD index
305 orr \tmp2, \tbl, #3 // PGD entry table type
306 str \tmp2, [\pgd, \tmp1, lsl #3]
307 .endm
308
309/*
310 * Macro to populate block entries in the page table for the start..end
311 * virtual range (inclusive).
312 *
313 * Preserves: tbl, flags
314 * Corrupts: phys, start, end, pstate
315 */
316 .macro create_block_map, tbl, flags, phys, start, end, idmap=0
317 lsr \phys, \phys, #BLOCK_SHIFT
318 .if \idmap
319 and \start, \phys, #PTRS_PER_PTE - 1 // table index
320 .else
321 lsr \start, \start, #BLOCK_SHIFT
322 and \start, \start, #PTRS_PER_PTE - 1 // table index
323 .endif
324 orr \phys, \flags, \phys, lsl #BLOCK_SHIFT // table entry
325 .ifnc \start,\end
326 lsr \end, \end, #BLOCK_SHIFT
327 and \end, \end, #PTRS_PER_PTE - 1 // table end index
328 .endif
3299999: str \phys, [\tbl, \start, lsl #3] // store the entry
330 .ifnc \start,\end
331 add \start, \start, #1 // next entry
332 add \phys, \phys, #BLOCK_SIZE // next block
333 cmp \start, \end
334 b.ls 9999b
335 .endif
336 .endm
337
338/*
339 * Setup the initial page tables. We only setup the barest amount which is
340 * required to get the kernel running. The following sections are required:
341 * - identity mapping to enable the MMU (low address, TTBR0)
342 * - first few MB of the kernel linear mapping to jump to once the MMU has
343 * been enabled, including the FDT blob (TTBR1)
344 */
345__create_page_tables:
346 pgtbl x25, x26, x24 // idmap_pg_dir and swapper_pg_dir addresses
347
348 /*
349 * Clear the idmap and swapper page tables.
350 */
351 mov x0, x25
352 add x6, x26, #SWAPPER_DIR_SIZE
3531: stp xzr, xzr, [x0], #16
354 stp xzr, xzr, [x0], #16
355 stp xzr, xzr, [x0], #16
356 stp xzr, xzr, [x0], #16
357 cmp x0, x6
358 b.lo 1b
359
360 ldr x7, =MM_MMUFLAGS
361
362 /*
363 * Create the identity mapping.
364 */
365 add x0, x25, #PAGE_SIZE // section table address
366 adr x3, __turn_mmu_on // virtual/physical address
367 create_pgd_entry x25, x0, x3, x5, x6
368 create_block_map x0, x7, x3, x5, x5, idmap=1
369
370 /*
371 * Map the kernel image (starting with PHYS_OFFSET).
372 */
373 add x0, x26, #PAGE_SIZE // section table address
374 mov x5, #PAGE_OFFSET
375 create_pgd_entry x26, x0, x5, x3, x6
376 ldr x6, =KERNEL_END - 1
377 mov x3, x24 // phys offset
378 create_block_map x0, x7, x3, x5, x6
379
380 /*
381 * Map the FDT blob (maximum 2MB; must be within 512MB of
382 * PHYS_OFFSET).
383 */
384 mov x3, x21 // FDT phys address
385 and x3, x3, #~((1 << 21) - 1) // 2MB aligned
386 mov x6, #PAGE_OFFSET
387 sub x5, x3, x24 // subtract PHYS_OFFSET
388 tst x5, #~((1 << 29) - 1) // within 512MB?
389 csel x21, xzr, x21, ne // zero the FDT pointer
390 b.ne 1f
391 add x5, x5, x6 // __va(FDT blob)
392 add x6, x5, #1 << 21 // 2MB for the FDT blob
393 sub x6, x6, #1 // inclusive range
394 create_block_map x0, x7, x3, x5, x6
3951:
396 ret
397ENDPROC(__create_page_tables)
398 .ltorg
399
400 .align 3
401 .type __switch_data, %object
402__switch_data:
403 .quad __mmap_switched
404 .quad __data_loc // x4
405 .quad _data // x5
406 .quad __bss_start // x6
407 .quad _end // x7
408 .quad processor_id // x4
409 .quad __fdt_pointer // x5
410 .quad memstart_addr // x6
411 .quad init_thread_union + THREAD_START_SP // sp
412
413/*
414 * The following fragment of code is executed with the MMU on in MMU mode, and
415 * uses absolute addresses; this is not position independent.
416 */
417__mmap_switched:
418 adr x3, __switch_data + 8
419
420 ldp x4, x5, [x3], #16
421 ldp x6, x7, [x3], #16
422 cmp x4, x5 // Copy data segment if needed
4231: ccmp x5, x6, #4, ne
424 b.eq 2f
425 ldr x16, [x4], #8
426 str x16, [x5], #8
427 b 1b
4282:
4291: cmp x6, x7
430 b.hs 2f
431 str xzr, [x6], #8 // Clear BSS
432 b 1b
4332:
434 ldp x4, x5, [x3], #16
435 ldr x6, [x3], #8
436 ldr x16, [x3]
437 mov sp, x16
438 str x22, [x4] // Save processor ID
439 str x21, [x5] // Save FDT pointer
440 str x24, [x6] // Save PHYS_OFFSET
441 mov x29, #0
442 b start_kernel
443ENDPROC(__mmap_switched)
444
445/*
446 * Exception handling. Something went wrong and we can't proceed. We ought to
447 * tell the user, but since we don't have any guarantee that we're even
448 * running on the right architecture, we do virtually nothing.
449 */
450__error_p:
451ENDPROC(__error_p)
452
453__error:
4541: nop
455 b 1b
456ENDPROC(__error)
457
458/*
459 * This function gets the processor ID in w0 and searches the cpu_table[] for
460 * a match. It returns a pointer to the struct cpu_info it found. The
461 * cpu_table[] must end with an empty (all zeros) structure.
462 *
463 * This routine can be called via C code and it needs to work with the MMU
464 * both disabled and enabled (the offset is calculated automatically).
465 */
466ENTRY(lookup_processor_type)
467 adr x1, __lookup_processor_type_data
468 ldp x2, x3, [x1]
469 sub x1, x1, x2 // get offset between VA and PA
470 add x3, x3, x1 // convert VA to PA
4711:
472 ldp w5, w6, [x3] // load cpu_id_val and cpu_id_mask
473 cbz w5, 2f // end of list?
474 and w6, w6, w0
475 cmp w5, w6
476 b.eq 3f
477 add x3, x3, #CPU_INFO_SZ
478 b 1b
4792:
480 mov x3, #0 // unknown processor
4813:
482 mov x0, x3
483 ret
484ENDPROC(lookup_processor_type)
485
486 .align 3
487 .type __lookup_processor_type_data, %object
488__lookup_processor_type_data:
489 .quad .
490 .quad cpu_table
491 .size __lookup_processor_type_data, . - __lookup_processor_type_data
492
493/*
494 * Determine validity of the x21 FDT pointer.
495 * The dtb must be 8-byte aligned and live in the first 512M of memory.
496 */
497__vet_fdt:
498 tst x21, #0x7
499 b.ne 1f
500 cmp x21, x24
501 b.lt 1f
502 mov x0, #(1 << 29)
503 add x0, x0, x24
504 cmp x21, x0
505 b.ge 1f
506 ret
5071:
508 mov x21, #0
509 ret
510ENDPROC(__vet_fdt)
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
new file mode 100644
index 000000000000..5ab825c59db9
--- /dev/null
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -0,0 +1,880 @@
1/*
2 * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
3 * using the CPU's debug registers.
4 *
5 * Copyright (C) 2012 ARM Limited
6 * Author: Will Deacon <will.deacon@arm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#define pr_fmt(fmt) "hw-breakpoint: " fmt
22
23#include <linux/errno.h>
24#include <linux/hw_breakpoint.h>
25#include <linux/perf_event.h>
26#include <linux/ptrace.h>
27#include <linux/smp.h>
28
29#include <asm/compat.h>
30#include <asm/current.h>
31#include <asm/debug-monitors.h>
32#include <asm/hw_breakpoint.h>
33#include <asm/kdebug.h>
34#include <asm/traps.h>
35#include <asm/cputype.h>
36#include <asm/system_misc.h>
37
38/* Breakpoint currently in use for each BRP. */
39static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[ARM_MAX_BRP]);
40
41/* Watchpoint currently in use for each WRP. */
42static DEFINE_PER_CPU(struct perf_event *, wp_on_reg[ARM_MAX_WRP]);
43
44/* Currently stepping a per-CPU kernel breakpoint. */
45static DEFINE_PER_CPU(int, stepping_kernel_bp);
46
47/* Number of BRP/WRP registers on this CPU. */
48static int core_num_brps;
49static int core_num_wrps;
50
51/* Determine number of BRP registers available. */
52static int get_num_brps(void)
53{
54 return ((read_cpuid(ID_AA64DFR0_EL1) >> 12) & 0xf) + 1;
55}
56
57/* Determine number of WRP registers available. */
58static int get_num_wrps(void)
59{
60 return ((read_cpuid(ID_AA64DFR0_EL1) >> 20) & 0xf) + 1;
61}
62
63int hw_breakpoint_slots(int type)
64{
65 /*
66 * We can be called early, so don't rely on
67 * our static variables being initialised.
68 */
69 switch (type) {
70 case TYPE_INST:
71 return get_num_brps();
72 case TYPE_DATA:
73 return get_num_wrps();
74 default:
75 pr_warning("unknown slot type: %d\n", type);
76 return 0;
77 }
78}
79
80#define READ_WB_REG_CASE(OFF, N, REG, VAL) \
81 case (OFF + N): \
82 AARCH64_DBG_READ(N, REG, VAL); \
83 break
84
85#define WRITE_WB_REG_CASE(OFF, N, REG, VAL) \
86 case (OFF + N): \
87 AARCH64_DBG_WRITE(N, REG, VAL); \
88 break
89
90#define GEN_READ_WB_REG_CASES(OFF, REG, VAL) \
91 READ_WB_REG_CASE(OFF, 0, REG, VAL); \
92 READ_WB_REG_CASE(OFF, 1, REG, VAL); \
93 READ_WB_REG_CASE(OFF, 2, REG, VAL); \
94 READ_WB_REG_CASE(OFF, 3, REG, VAL); \
95 READ_WB_REG_CASE(OFF, 4, REG, VAL); \
96 READ_WB_REG_CASE(OFF, 5, REG, VAL); \
97 READ_WB_REG_CASE(OFF, 6, REG, VAL); \
98 READ_WB_REG_CASE(OFF, 7, REG, VAL); \
99 READ_WB_REG_CASE(OFF, 8, REG, VAL); \
100 READ_WB_REG_CASE(OFF, 9, REG, VAL); \
101 READ_WB_REG_CASE(OFF, 10, REG, VAL); \
102 READ_WB_REG_CASE(OFF, 11, REG, VAL); \
103 READ_WB_REG_CASE(OFF, 12, REG, VAL); \
104 READ_WB_REG_CASE(OFF, 13, REG, VAL); \
105 READ_WB_REG_CASE(OFF, 14, REG, VAL); \
106 READ_WB_REG_CASE(OFF, 15, REG, VAL)
107
108#define GEN_WRITE_WB_REG_CASES(OFF, REG, VAL) \
109 WRITE_WB_REG_CASE(OFF, 0, REG, VAL); \
110 WRITE_WB_REG_CASE(OFF, 1, REG, VAL); \
111 WRITE_WB_REG_CASE(OFF, 2, REG, VAL); \
112 WRITE_WB_REG_CASE(OFF, 3, REG, VAL); \
113 WRITE_WB_REG_CASE(OFF, 4, REG, VAL); \
114 WRITE_WB_REG_CASE(OFF, 5, REG, VAL); \
115 WRITE_WB_REG_CASE(OFF, 6, REG, VAL); \
116 WRITE_WB_REG_CASE(OFF, 7, REG, VAL); \
117 WRITE_WB_REG_CASE(OFF, 8, REG, VAL); \
118 WRITE_WB_REG_CASE(OFF, 9, REG, VAL); \
119 WRITE_WB_REG_CASE(OFF, 10, REG, VAL); \
120 WRITE_WB_REG_CASE(OFF, 11, REG, VAL); \
121 WRITE_WB_REG_CASE(OFF, 12, REG, VAL); \
122 WRITE_WB_REG_CASE(OFF, 13, REG, VAL); \
123 WRITE_WB_REG_CASE(OFF, 14, REG, VAL); \
124 WRITE_WB_REG_CASE(OFF, 15, REG, VAL)
125
126static u64 read_wb_reg(int reg, int n)
127{
128 u64 val = 0;
129
130 switch (reg + n) {
131 GEN_READ_WB_REG_CASES(AARCH64_DBG_REG_BVR, AARCH64_DBG_REG_NAME_BVR, val);
132 GEN_READ_WB_REG_CASES(AARCH64_DBG_REG_BCR, AARCH64_DBG_REG_NAME_BCR, val);
133 GEN_READ_WB_REG_CASES(AARCH64_DBG_REG_WVR, AARCH64_DBG_REG_NAME_WVR, val);
134 GEN_READ_WB_REG_CASES(AARCH64_DBG_REG_WCR, AARCH64_DBG_REG_NAME_WCR, val);
135 default:
136 pr_warning("attempt to read from unknown breakpoint register %d\n", n);
137 }
138
139 return val;
140}
141
142static void write_wb_reg(int reg, int n, u64 val)
143{
144 switch (reg + n) {
145 GEN_WRITE_WB_REG_CASES(AARCH64_DBG_REG_BVR, AARCH64_DBG_REG_NAME_BVR, val);
146 GEN_WRITE_WB_REG_CASES(AARCH64_DBG_REG_BCR, AARCH64_DBG_REG_NAME_BCR, val);
147 GEN_WRITE_WB_REG_CASES(AARCH64_DBG_REG_WVR, AARCH64_DBG_REG_NAME_WVR, val);
148 GEN_WRITE_WB_REG_CASES(AARCH64_DBG_REG_WCR, AARCH64_DBG_REG_NAME_WCR, val);
149 default:
150 pr_warning("attempt to write to unknown breakpoint register %d\n", n);
151 }
152 isb();
153}
154
155/*
156 * Convert a breakpoint privilege level to the corresponding exception
157 * level.
158 */
159static enum debug_el debug_exception_level(int privilege)
160{
161 switch (privilege) {
162 case AARCH64_BREAKPOINT_EL0:
163 return DBG_ACTIVE_EL0;
164 case AARCH64_BREAKPOINT_EL1:
165 return DBG_ACTIVE_EL1;
166 default:
167 pr_warning("invalid breakpoint privilege level %d\n", privilege);
168 return -EINVAL;
169 }
170}
171
172/*
173 * Install a perf counter breakpoint.
174 */
175int arch_install_hw_breakpoint(struct perf_event *bp)
176{
177 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
178 struct perf_event **slot, **slots;
179 struct debug_info *debug_info = &current->thread.debug;
180 int i, max_slots, ctrl_reg, val_reg, reg_enable;
181 u32 ctrl;
182
183 if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
184 /* Breakpoint */
185 ctrl_reg = AARCH64_DBG_REG_BCR;
186 val_reg = AARCH64_DBG_REG_BVR;
187 slots = __get_cpu_var(bp_on_reg);
188 max_slots = core_num_brps;
189 reg_enable = !debug_info->bps_disabled;
190 } else {
191 /* Watchpoint */
192 ctrl_reg = AARCH64_DBG_REG_WCR;
193 val_reg = AARCH64_DBG_REG_WVR;
194 slots = __get_cpu_var(wp_on_reg);
195 max_slots = core_num_wrps;
196 reg_enable = !debug_info->wps_disabled;
197 }
198
199 for (i = 0; i < max_slots; ++i) {
200 slot = &slots[i];
201
202 if (!*slot) {
203 *slot = bp;
204 break;
205 }
206 }
207
208 if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot"))
209 return -ENOSPC;
210
211 /* Ensure debug monitors are enabled at the correct exception level. */
212 enable_debug_monitors(debug_exception_level(info->ctrl.privilege));
213
214 /* Setup the address register. */
215 write_wb_reg(val_reg, i, info->address);
216
217 /* Setup the control register. */
218 ctrl = encode_ctrl_reg(info->ctrl);
219 write_wb_reg(ctrl_reg, i, reg_enable ? ctrl | 0x1 : ctrl & ~0x1);
220
221 return 0;
222}
223
224void arch_uninstall_hw_breakpoint(struct perf_event *bp)
225{
226 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
227 struct perf_event **slot, **slots;
228 int i, max_slots, base;
229
230 if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
231 /* Breakpoint */
232 base = AARCH64_DBG_REG_BCR;
233 slots = __get_cpu_var(bp_on_reg);
234 max_slots = core_num_brps;
235 } else {
236 /* Watchpoint */
237 base = AARCH64_DBG_REG_WCR;
238 slots = __get_cpu_var(wp_on_reg);
239 max_slots = core_num_wrps;
240 }
241
242 /* Remove the breakpoint. */
243 for (i = 0; i < max_slots; ++i) {
244 slot = &slots[i];
245
246 if (*slot == bp) {
247 *slot = NULL;
248 break;
249 }
250 }
251
252 if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot"))
253 return;
254
255 /* Reset the control register. */
256 write_wb_reg(base, i, 0);
257
258 /* Release the debug monitors for the correct exception level. */
259 disable_debug_monitors(debug_exception_level(info->ctrl.privilege));
260}
261
262static int get_hbp_len(u8 hbp_len)
263{
264 unsigned int len_in_bytes = 0;
265
266 switch (hbp_len) {
267 case ARM_BREAKPOINT_LEN_1:
268 len_in_bytes = 1;
269 break;
270 case ARM_BREAKPOINT_LEN_2:
271 len_in_bytes = 2;
272 break;
273 case ARM_BREAKPOINT_LEN_4:
274 len_in_bytes = 4;
275 break;
276 case ARM_BREAKPOINT_LEN_8:
277 len_in_bytes = 8;
278 break;
279 }
280
281 return len_in_bytes;
282}
283
284/*
285 * Check whether bp virtual address is in kernel space.
286 */
287int arch_check_bp_in_kernelspace(struct perf_event *bp)
288{
289 unsigned int len;
290 unsigned long va;
291 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
292
293 va = info->address;
294 len = get_hbp_len(info->ctrl.len);
295
296 return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
297}
298
299/*
300 * Extract generic type and length encodings from an arch_hw_breakpoint_ctrl.
301 * Hopefully this will disappear when ptrace can bypass the conversion
302 * to generic breakpoint descriptions.
303 */
304int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
305 int *gen_len, int *gen_type)
306{
307 /* Type */
308 switch (ctrl.type) {
309 case ARM_BREAKPOINT_EXECUTE:
310 *gen_type = HW_BREAKPOINT_X;
311 break;
312 case ARM_BREAKPOINT_LOAD:
313 *gen_type = HW_BREAKPOINT_R;
314 break;
315 case ARM_BREAKPOINT_STORE:
316 *gen_type = HW_BREAKPOINT_W;
317 break;
318 case ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE:
319 *gen_type = HW_BREAKPOINT_RW;
320 break;
321 default:
322 return -EINVAL;
323 }
324
325 /* Len */
326 switch (ctrl.len) {
327 case ARM_BREAKPOINT_LEN_1:
328 *gen_len = HW_BREAKPOINT_LEN_1;
329 break;
330 case ARM_BREAKPOINT_LEN_2:
331 *gen_len = HW_BREAKPOINT_LEN_2;
332 break;
333 case ARM_BREAKPOINT_LEN_4:
334 *gen_len = HW_BREAKPOINT_LEN_4;
335 break;
336 case ARM_BREAKPOINT_LEN_8:
337 *gen_len = HW_BREAKPOINT_LEN_8;
338 break;
339 default:
340 return -EINVAL;
341 }
342
343 return 0;
344}
345
346/*
347 * Construct an arch_hw_breakpoint from a perf_event.
348 */
349static int arch_build_bp_info(struct perf_event *bp)
350{
351 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
352
353 /* Type */
354 switch (bp->attr.bp_type) {
355 case HW_BREAKPOINT_X:
356 info->ctrl.type = ARM_BREAKPOINT_EXECUTE;
357 break;
358 case HW_BREAKPOINT_R:
359 info->ctrl.type = ARM_BREAKPOINT_LOAD;
360 break;
361 case HW_BREAKPOINT_W:
362 info->ctrl.type = ARM_BREAKPOINT_STORE;
363 break;
364 case HW_BREAKPOINT_RW:
365 info->ctrl.type = ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE;
366 break;
367 default:
368 return -EINVAL;
369 }
370
371 /* Len */
372 switch (bp->attr.bp_len) {
373 case HW_BREAKPOINT_LEN_1:
374 info->ctrl.len = ARM_BREAKPOINT_LEN_1;
375 break;
376 case HW_BREAKPOINT_LEN_2:
377 info->ctrl.len = ARM_BREAKPOINT_LEN_2;
378 break;
379 case HW_BREAKPOINT_LEN_4:
380 info->ctrl.len = ARM_BREAKPOINT_LEN_4;
381 break;
382 case HW_BREAKPOINT_LEN_8:
383 info->ctrl.len = ARM_BREAKPOINT_LEN_8;
384 break;
385 default:
386 return -EINVAL;
387 }
388
389 /*
390 * On AArch64, we only permit breakpoints of length 4, whereas
391 * AArch32 also requires breakpoints of length 2 for Thumb.
392 * Watchpoints can be of length 1, 2, 4 or 8 bytes.
393 */
394 if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
395 if (is_compat_task()) {
396 if (info->ctrl.len != ARM_BREAKPOINT_LEN_2 &&
397 info->ctrl.len != ARM_BREAKPOINT_LEN_4)
398 return -EINVAL;
399 } else if (info->ctrl.len != ARM_BREAKPOINT_LEN_4) {
400 /*
401 * FIXME: Some tools (I'm looking at you perf) assume
402 * that breakpoints should be sizeof(long). This
403 * is nonsense. For now, we fix up the parameter
404 * but we should probably return -EINVAL instead.
405 */
406 info->ctrl.len = ARM_BREAKPOINT_LEN_4;
407 }
408 }
409
410 /* Address */
411 info->address = bp->attr.bp_addr;
412
413 /*
414 * Privilege
415 * Note that we disallow combined EL0/EL1 breakpoints because
416 * that would complicate the stepping code.
417 */
418 if (arch_check_bp_in_kernelspace(bp))
419 info->ctrl.privilege = AARCH64_BREAKPOINT_EL1;
420 else
421 info->ctrl.privilege = AARCH64_BREAKPOINT_EL0;
422
423 /* Enabled? */
424 info->ctrl.enabled = !bp->attr.disabled;
425
426 return 0;
427}
428
429/*
430 * Validate the arch-specific HW Breakpoint register settings.
431 */
432int arch_validate_hwbkpt_settings(struct perf_event *bp)
433{
434 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
435 int ret;
436 u64 alignment_mask, offset;
437
438 /* Build the arch_hw_breakpoint. */
439 ret = arch_build_bp_info(bp);
440 if (ret)
441 return ret;
442
443 /*
444 * Check address alignment.
445 * We don't do any clever alignment correction for watchpoints
446 * because using 64-bit unaligned addresses is deprecated for
447 * AArch64.
448 *
449 * AArch32 tasks expect some simple alignment fixups, so emulate
450 * that here.
451 */
452 if (is_compat_task()) {
453 if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
454 alignment_mask = 0x7;
455 else
456 alignment_mask = 0x3;
457 offset = info->address & alignment_mask;
458 switch (offset) {
459 case 0:
460 /* Aligned */
461 break;
462 case 1:
463 /* Allow single byte watchpoint. */
464 if (info->ctrl.len == ARM_BREAKPOINT_LEN_1)
465 break;
466 case 2:
467 /* Allow halfword watchpoints and breakpoints. */
468 if (info->ctrl.len == ARM_BREAKPOINT_LEN_2)
469 break;
470 default:
471 return -EINVAL;
472 }
473
474 info->address &= ~alignment_mask;
475 info->ctrl.len <<= offset;
476 } else {
477 if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE)
478 alignment_mask = 0x3;
479 else
480 alignment_mask = 0x7;
481 if (info->address & alignment_mask)
482 return -EINVAL;
483 }
484
485 /*
486 * Disallow per-task kernel breakpoints since these would
487 * complicate the stepping code.
488 */
489 if (info->ctrl.privilege == AARCH64_BREAKPOINT_EL1 && bp->hw.bp_target)
490 return -EINVAL;
491
492 return 0;
493}
494
495/*
496 * Enable/disable all of the breakpoints active at the specified
497 * exception level at the register level.
498 * This is used when single-stepping after a breakpoint exception.
499 */
500static void toggle_bp_registers(int reg, enum debug_el el, int enable)
501{
502 int i, max_slots, privilege;
503 u32 ctrl;
504 struct perf_event **slots;
505
506 switch (reg) {
507 case AARCH64_DBG_REG_BCR:
508 slots = __get_cpu_var(bp_on_reg);
509 max_slots = core_num_brps;
510 break;
511 case AARCH64_DBG_REG_WCR:
512 slots = __get_cpu_var(wp_on_reg);
513 max_slots = core_num_wrps;
514 break;
515 default:
516 return;
517 }
518
519 for (i = 0; i < max_slots; ++i) {
520 if (!slots[i])
521 continue;
522
523 privilege = counter_arch_bp(slots[i])->ctrl.privilege;
524 if (debug_exception_level(privilege) != el)
525 continue;
526
527 ctrl = read_wb_reg(reg, i);
528 if (enable)
529 ctrl |= 0x1;
530 else
531 ctrl &= ~0x1;
532 write_wb_reg(reg, i, ctrl);
533 }
534}
535
536/*
537 * Debug exception handlers.
538 */
539static int breakpoint_handler(unsigned long unused, unsigned int esr,
540 struct pt_regs *regs)
541{
542 int i, step = 0, *kernel_step;
543 u32 ctrl_reg;
544 u64 addr, val;
545 struct perf_event *bp, **slots;
546 struct debug_info *debug_info;
547 struct arch_hw_breakpoint_ctrl ctrl;
548
549 slots = (struct perf_event **)__get_cpu_var(bp_on_reg);
550 addr = instruction_pointer(regs);
551 debug_info = &current->thread.debug;
552
553 for (i = 0; i < core_num_brps; ++i) {
554 rcu_read_lock();
555
556 bp = slots[i];
557
558 if (bp == NULL)
559 goto unlock;
560
561 /* Check if the breakpoint value matches. */
562 val = read_wb_reg(AARCH64_DBG_REG_BVR, i);
563 if (val != (addr & ~0x3))
564 goto unlock;
565
566 /* Possible match, check the byte address select to confirm. */
567 ctrl_reg = read_wb_reg(AARCH64_DBG_REG_BCR, i);
568 decode_ctrl_reg(ctrl_reg, &ctrl);
569 if (!((1 << (addr & 0x3)) & ctrl.len))
570 goto unlock;
571
572 counter_arch_bp(bp)->trigger = addr;
573 perf_bp_event(bp, regs);
574
575 /* Do we need to handle the stepping? */
576 if (!bp->overflow_handler)
577 step = 1;
578unlock:
579 rcu_read_unlock();
580 }
581
582 if (!step)
583 return 0;
584
585 if (user_mode(regs)) {
586 debug_info->bps_disabled = 1;
587 toggle_bp_registers(AARCH64_DBG_REG_BCR, DBG_ACTIVE_EL0, 0);
588
589 /* If we're already stepping a watchpoint, just return. */
590 if (debug_info->wps_disabled)
591 return 0;
592
593 if (test_thread_flag(TIF_SINGLESTEP))
594 debug_info->suspended_step = 1;
595 else
596 user_enable_single_step(current);
597 } else {
598 toggle_bp_registers(AARCH64_DBG_REG_BCR, DBG_ACTIVE_EL1, 0);
599 kernel_step = &__get_cpu_var(stepping_kernel_bp);
600
601 if (*kernel_step != ARM_KERNEL_STEP_NONE)
602 return 0;
603
604 if (kernel_active_single_step()) {
605 *kernel_step = ARM_KERNEL_STEP_SUSPEND;
606 } else {
607 *kernel_step = ARM_KERNEL_STEP_ACTIVE;
608 kernel_enable_single_step(regs);
609 }
610 }
611
612 return 0;
613}
614
615static int watchpoint_handler(unsigned long addr, unsigned int esr,
616 struct pt_regs *regs)
617{
618 int i, step = 0, *kernel_step, access;
619 u32 ctrl_reg;
620 u64 val, alignment_mask;
621 struct perf_event *wp, **slots;
622 struct debug_info *debug_info;
623 struct arch_hw_breakpoint *info;
624 struct arch_hw_breakpoint_ctrl ctrl;
625
626 slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
627 debug_info = &current->thread.debug;
628
629 for (i = 0; i < core_num_wrps; ++i) {
630 rcu_read_lock();
631
632 wp = slots[i];
633
634 if (wp == NULL)
635 goto unlock;
636
637 info = counter_arch_bp(wp);
638 /* AArch32 watchpoints are either 4 or 8 bytes aligned. */
639 if (is_compat_task()) {
640 if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
641 alignment_mask = 0x7;
642 else
643 alignment_mask = 0x3;
644 } else {
645 alignment_mask = 0x7;
646 }
647
648 /* Check if the watchpoint value matches. */
649 val = read_wb_reg(AARCH64_DBG_REG_WVR, i);
650 if (val != (addr & ~alignment_mask))
651 goto unlock;
652
653 /* Possible match, check the byte address select to confirm. */
654 ctrl_reg = read_wb_reg(AARCH64_DBG_REG_WCR, i);
655 decode_ctrl_reg(ctrl_reg, &ctrl);
656 if (!((1 << (addr & alignment_mask)) & ctrl.len))
657 goto unlock;
658
659 /*
660 * Check that the access type matches.
661 * 0 => load, otherwise => store
662 */
663 access = (esr & AARCH64_ESR_ACCESS_MASK) ? HW_BREAKPOINT_W :
664 HW_BREAKPOINT_R;
665 if (!(access & hw_breakpoint_type(wp)))
666 goto unlock;
667
668 info->trigger = addr;
669 perf_bp_event(wp, regs);
670
671 /* Do we need to handle the stepping? */
672 if (!wp->overflow_handler)
673 step = 1;
674
675unlock:
676 rcu_read_unlock();
677 }
678
679 if (!step)
680 return 0;
681
682 /*
683 * We always disable EL0 watchpoints because the kernel can
684 * cause these to fire via an unprivileged access.
685 */
686 toggle_bp_registers(AARCH64_DBG_REG_WCR, DBG_ACTIVE_EL0, 0);
687
688 if (user_mode(regs)) {
689 debug_info->wps_disabled = 1;
690
691 /* If we're already stepping a breakpoint, just return. */
692 if (debug_info->bps_disabled)
693 return 0;
694
695 if (test_thread_flag(TIF_SINGLESTEP))
696 debug_info->suspended_step = 1;
697 else
698 user_enable_single_step(current);
699 } else {
700 toggle_bp_registers(AARCH64_DBG_REG_WCR, DBG_ACTIVE_EL1, 0);
701 kernel_step = &__get_cpu_var(stepping_kernel_bp);
702
703 if (*kernel_step != ARM_KERNEL_STEP_NONE)
704 return 0;
705
706 if (kernel_active_single_step()) {
707 *kernel_step = ARM_KERNEL_STEP_SUSPEND;
708 } else {
709 *kernel_step = ARM_KERNEL_STEP_ACTIVE;
710 kernel_enable_single_step(regs);
711 }
712 }
713
714 return 0;
715}
716
717/*
718 * Handle single-step exception.
719 */
720int reinstall_suspended_bps(struct pt_regs *regs)
721{
722 struct debug_info *debug_info = &current->thread.debug;
723 int handled_exception = 0, *kernel_step;
724
725 kernel_step = &__get_cpu_var(stepping_kernel_bp);
726
727 /*
728 * Called from single-step exception handler.
729 * Return 0 if execution can resume, 1 if a SIGTRAP should be
730 * reported.
731 */
732 if (user_mode(regs)) {
733 if (debug_info->bps_disabled) {
734 debug_info->bps_disabled = 0;
735 toggle_bp_registers(AARCH64_DBG_REG_BCR, DBG_ACTIVE_EL0, 1);
736 handled_exception = 1;
737 }
738
739 if (debug_info->wps_disabled) {
740 debug_info->wps_disabled = 0;
741 toggle_bp_registers(AARCH64_DBG_REG_WCR, DBG_ACTIVE_EL0, 1);
742 handled_exception = 1;
743 }
744
745 if (handled_exception) {
746 if (debug_info->suspended_step) {
747 debug_info->suspended_step = 0;
748 /* Allow exception handling to fall-through. */
749 handled_exception = 0;
750 } else {
751 user_disable_single_step(current);
752 }
753 }
754 } else if (*kernel_step != ARM_KERNEL_STEP_NONE) {
755 toggle_bp_registers(AARCH64_DBG_REG_BCR, DBG_ACTIVE_EL1, 1);
756 toggle_bp_registers(AARCH64_DBG_REG_WCR, DBG_ACTIVE_EL1, 1);
757
758 if (!debug_info->wps_disabled)
759 toggle_bp_registers(AARCH64_DBG_REG_WCR, DBG_ACTIVE_EL0, 1);
760
761 if (*kernel_step != ARM_KERNEL_STEP_SUSPEND) {
762 kernel_disable_single_step();
763 handled_exception = 1;
764 } else {
765 handled_exception = 0;
766 }
767
768 *kernel_step = ARM_KERNEL_STEP_NONE;
769 }
770
771 return !handled_exception;
772}
773
774/*
775 * Context-switcher for restoring suspended breakpoints.
776 */
777void hw_breakpoint_thread_switch(struct task_struct *next)
778{
779 /*
780 * current next
781 * disabled: 0 0 => The usual case, NOTIFY_DONE
782 * 0 1 => Disable the registers
783 * 1 0 => Enable the registers
784 * 1 1 => NOTIFY_DONE. per-task bps will
785 * get taken care of by perf.
786 */
787
788 struct debug_info *current_debug_info, *next_debug_info;
789
790 current_debug_info = &current->thread.debug;
791 next_debug_info = &next->thread.debug;
792
793 /* Update breakpoints. */
794 if (current_debug_info->bps_disabled != next_debug_info->bps_disabled)
795 toggle_bp_registers(AARCH64_DBG_REG_BCR,
796 DBG_ACTIVE_EL0,
797 !next_debug_info->bps_disabled);
798
799 /* Update watchpoints. */
800 if (current_debug_info->wps_disabled != next_debug_info->wps_disabled)
801 toggle_bp_registers(AARCH64_DBG_REG_WCR,
802 DBG_ACTIVE_EL0,
803 !next_debug_info->wps_disabled);
804}
805
806/*
807 * CPU initialisation.
808 */
809static void reset_ctrl_regs(void *unused)
810{
811 int i;
812
813 for (i = 0; i < core_num_brps; ++i) {
814 write_wb_reg(AARCH64_DBG_REG_BCR, i, 0UL);
815 write_wb_reg(AARCH64_DBG_REG_BVR, i, 0UL);
816 }
817
818 for (i = 0; i < core_num_wrps; ++i) {
819 write_wb_reg(AARCH64_DBG_REG_WCR, i, 0UL);
820 write_wb_reg(AARCH64_DBG_REG_WVR, i, 0UL);
821 }
822}
823
824static int __cpuinit hw_breakpoint_reset_notify(struct notifier_block *self,
825 unsigned long action,
826 void *hcpu)
827{
828 int cpu = (long)hcpu;
829 if (action == CPU_ONLINE)
830 smp_call_function_single(cpu, reset_ctrl_regs, NULL, 1);
831 return NOTIFY_OK;
832}
833
834static struct notifier_block __cpuinitdata hw_breakpoint_reset_nb = {
835 .notifier_call = hw_breakpoint_reset_notify,
836};
837
838/*
839 * One-time initialisation.
840 */
841static int __init arch_hw_breakpoint_init(void)
842{
843 core_num_brps = get_num_brps();
844 core_num_wrps = get_num_wrps();
845
846 pr_info("found %d breakpoint and %d watchpoint registers.\n",
847 core_num_brps, core_num_wrps);
848
849 /*
850 * Reset the breakpoint resources. We assume that a halting
851 * debugger will leave the world in a nice state for us.
852 */
853 smp_call_function(reset_ctrl_regs, NULL, 1);
854 reset_ctrl_regs(NULL);
855
856 /* Register debug fault handlers. */
857 hook_debug_fault_code(DBG_ESR_EVT_HWBP, breakpoint_handler, SIGTRAP,
858 TRAP_HWBKPT, "hw-breakpoint handler");
859 hook_debug_fault_code(DBG_ESR_EVT_HWWP, watchpoint_handler, SIGTRAP,
860 TRAP_HWBKPT, "hw-watchpoint handler");
861
862 /* Register hotplug notifier. */
863 register_cpu_notifier(&hw_breakpoint_reset_nb);
864
865 return 0;
866}
867arch_initcall(arch_hw_breakpoint_init);
868
869void hw_breakpoint_pmu_read(struct perf_event *bp)
870{
871}
872
873/*
874 * Dummy function to register with die_notifier.
875 */
876int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
877 unsigned long val, void *data)
878{
879 return NOTIFY_DONE;
880}
diff --git a/arch/arm64/kernel/io.c b/arch/arm64/kernel/io.c
new file mode 100644
index 000000000000..7d37ead4d199
--- /dev/null
+++ b/arch/arm64/kernel/io.c
@@ -0,0 +1,64 @@
1/*
2 * Based on arch/arm/kernel/io.c
3 *
4 * Copyright (C) 2012 ARM Ltd.
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/export.h>
20#include <linux/types.h>
21#include <linux/io.h>
22
23/*
24 * Copy data from IO memory space to "real" memory space.
25 */
26void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
27{
28 unsigned char *t = to;
29 while (count) {
30 count--;
31 *t = readb(from);
32 t++;
33 from++;
34 }
35}
36EXPORT_SYMBOL(__memcpy_fromio);
37
38/*
39 * Copy data from "real" memory space to IO memory space.
40 */
41void __memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
42{
43 const unsigned char *f = from;
44 while (count) {
45 count--;
46 writeb(*f, to);
47 f++;
48 to++;
49 }
50}
51EXPORT_SYMBOL(__memcpy_toio);
52
53/*
54 * "memset" on IO memory space.
55 */
56void __memset_io(volatile void __iomem *dst, int c, size_t count)
57{
58 while (count) {
59 count--;
60 writeb(c, dst);
61 dst++;
62 }
63}
64EXPORT_SYMBOL(__memset_io);
diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c
new file mode 100644
index 000000000000..0373c6609eaf
--- /dev/null
+++ b/arch/arm64/kernel/irq.c
@@ -0,0 +1,84 @@
1/*
2 * Based on arch/arm/kernel/irq.c
3 *
4 * Copyright (C) 1992 Linus Torvalds
5 * Modifications for ARM processor Copyright (C) 1995-2000 Russell King.
6 * Support for Dynamic Tick Timer Copyright (C) 2004-2005 Nokia Corporation.
7 * Dynamic Tick Timer written by Tony Lindgren <tony@atomide.com> and
8 * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>.
9 * Copyright (C) 2012 ARM Ltd.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
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, see <http://www.gnu.org/licenses/>.
22 */
23
24#include <linux/kernel_stat.h>
25#include <linux/irq.h>
26#include <linux/smp.h>
27#include <linux/init.h>
28#include <linux/of_irq.h>
29#include <linux/seq_file.h>
30#include <linux/ratelimit.h>
31
32unsigned long irq_err_count;
33
34int arch_show_interrupts(struct seq_file *p, int prec)
35{
36#ifdef CONFIG_SMP
37 show_ipi_list(p, prec);
38#endif
39 seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
40 return 0;
41}
42
43/*
44 * handle_IRQ handles all hardware IRQ's. Decoded IRQs should
45 * not come via this function. Instead, they should provide their
46 * own 'handler'. Used by platform code implementing C-based 1st
47 * level decoding.
48 */
49void handle_IRQ(unsigned int irq, struct pt_regs *regs)
50{
51 struct pt_regs *old_regs = set_irq_regs(regs);
52
53 irq_enter();
54
55 /*
56 * Some hardware gives randomly wrong interrupts. Rather
57 * than crashing, do something sensible.
58 */
59 if (unlikely(irq >= nr_irqs)) {
60 pr_warn_ratelimited("Bad IRQ%u\n", irq);
61 ack_bad_irq(irq);
62 } else {
63 generic_handle_irq(irq);
64 }
65
66 irq_exit();
67 set_irq_regs(old_regs);
68}
69
70/*
71 * Interrupt controllers supported by the kernel.
72 */
73static const struct of_device_id intctrl_of_match[] __initconst = {
74 /* IRQ controllers { .compatible, .data } info to go here */
75 {}
76};
77
78void __init init_IRQ(void)
79{
80 of_irq_init(intctrl_of_match);
81
82 if (!handle_arch_irq)
83 panic("No interrupt controller found.");
84}
diff --git a/arch/arm64/kernel/kuser32.S b/arch/arm64/kernel/kuser32.S
new file mode 100644
index 000000000000..8b69ecb1d8bc
--- /dev/null
+++ b/arch/arm64/kernel/kuser32.S
@@ -0,0 +1,77 @@
1/*
2 * Low-level user helpers placed in the vectors page for AArch32.
3 * Based on the kuser helpers in arch/arm/kernel/entry-armv.S.
4 *
5 * Copyright (C) 2005-2011 Nicolas Pitre <nico@fluxnic.net>
6 * Copyright (C) 2012 ARM Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 *
21 * AArch32 user helpers.
22 *
23 * Each segment is 32-byte aligned and will be moved to the top of the high
24 * vector page. New segments (if ever needed) must be added in front of
25 * existing ones. This mechanism should be used only for things that are
26 * really small and justified, and not be abused freely.
27 *
28 * See Documentation/arm/kernel_user_helpers.txt for formal definitions.
29 */
30 .align 5
31 .globl __kuser_helper_start
32__kuser_helper_start:
33
34__kuser_cmpxchg64: // 0xffff0f60
35 .inst 0xe92d00f0 // push {r4, r5, r6, r7}
36 .inst 0xe1c040d0 // ldrd r4, r5, [r0]
37 .inst 0xe1c160d0 // ldrd r6, r7, [r1]
38 .inst 0xf57ff05f // dmb sy
39 .inst 0xe1b20f9f // 1: ldrexd r0, r1, [r2]
40 .inst 0xe0303004 // eors r3, r0, r4
41 .inst 0x00313005 // eoreqs r3, r1, r5
42 .inst 0x01a23f96 // strexdeq r3, r6, [r2]
43 .inst 0x03330001 // teqeq r3, #1
44 .inst 0x0afffff9 // beq 1b
45 .inst 0xf57ff05f // dmb sy
46 .inst 0xe2730000 // rsbs r0, r3, #0
47 .inst 0xe8bd00f0 // pop {r4, r5, r6, r7}
48 .inst 0xe12fff1e // bx lr
49
50 .align 5
51__kuser_memory_barrier: // 0xffff0fa0
52 .inst 0xf57ff05f // dmb sy
53 .inst 0xe12fff1e // bx lr
54
55 .align 5
56__kuser_cmpxchg: // 0xffff0fc0
57 .inst 0xf57ff05f // dmb sy
58 .inst 0xe1923f9f // 1: ldrex r3, [r2]
59 .inst 0xe0533000 // subs r3, r3, r0
60 .inst 0x01823f91 // strexeq r3, r1, [r2]
61 .inst 0x03330001 // teqeq r3, #1
62 .inst 0x0afffffa // beq 1b
63 .inst 0xe2730000 // rsbs r0, r3, #0
64 .inst 0xeaffffef // b <__kuser_memory_barrier>
65
66 .align 5
67__kuser_get_tls: // 0xffff0fe0
68 .inst 0xee1d0f70 // mrc p15, 0, r0, c13, c0, 3
69 .inst 0xe12fff1e // bx lr
70 .rep 5
71 .word 0
72 .endr
73
74__kuser_helper_version: // 0xffff0ffc
75 .word ((__kuser_helper_end - __kuser_helper_start) >> 5)
76 .globl __kuser_helper_end
77__kuser_helper_end:
diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
new file mode 100644
index 000000000000..ca0e3d55da99
--- /dev/null
+++ b/arch/arm64/kernel/module.c
@@ -0,0 +1,456 @@
1/*
2 * AArch64 loadable module support.
3 *
4 * Copyright (C) 2012 ARM Limited
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Author: Will Deacon <will.deacon@arm.com>
19 */
20
21#include <linux/bitops.h>
22#include <linux/elf.h>
23#include <linux/gfp.h>
24#include <linux/kernel.h>
25#include <linux/mm.h>
26#include <linux/moduleloader.h>
27#include <linux/vmalloc.h>
28
29void *module_alloc(unsigned long size)
30{
31 return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
32 GFP_KERNEL, PAGE_KERNEL_EXEC, -1,
33 __builtin_return_address(0));
34}
35
36enum aarch64_reloc_op {
37 RELOC_OP_NONE,
38 RELOC_OP_ABS,
39 RELOC_OP_PREL,
40 RELOC_OP_PAGE,
41};
42
43static u64 do_reloc(enum aarch64_reloc_op reloc_op, void *place, u64 val)
44{
45 switch (reloc_op) {
46 case RELOC_OP_ABS:
47 return val;
48 case RELOC_OP_PREL:
49 return val - (u64)place;
50 case RELOC_OP_PAGE:
51 return (val & ~0xfff) - ((u64)place & ~0xfff);
52 case RELOC_OP_NONE:
53 return 0;
54 }
55
56 pr_err("do_reloc: unknown relocation operation %d\n", reloc_op);
57 return 0;
58}
59
60static int reloc_data(enum aarch64_reloc_op op, void *place, u64 val, int len)
61{
62 u64 imm_mask = (1 << len) - 1;
63 s64 sval = do_reloc(op, place, val);
64
65 switch (len) {
66 case 16:
67 *(s16 *)place = sval;
68 break;
69 case 32:
70 *(s32 *)place = sval;
71 break;
72 case 64:
73 *(s64 *)place = sval;
74 break;
75 default:
76 pr_err("Invalid length (%d) for data relocation\n", len);
77 return 0;
78 }
79
80 /*
81 * Extract the upper value bits (including the sign bit) and
82 * shift them to bit 0.
83 */
84 sval = (s64)(sval & ~(imm_mask >> 1)) >> (len - 1);
85
86 /*
87 * Overflow has occurred if the value is not representable in
88 * len bits (i.e the bottom len bits are not sign-extended and
89 * the top bits are not all zero).
90 */
91 if ((u64)(sval + 1) > 2)
92 return -ERANGE;
93
94 return 0;
95}
96
97enum aarch64_imm_type {
98 INSN_IMM_MOVNZ,
99 INSN_IMM_MOVK,
100 INSN_IMM_ADR,
101 INSN_IMM_26,
102 INSN_IMM_19,
103 INSN_IMM_16,
104 INSN_IMM_14,
105 INSN_IMM_12,
106 INSN_IMM_9,
107};
108
109static u32 encode_insn_immediate(enum aarch64_imm_type type, u32 insn, u64 imm)
110{
111 u32 immlo, immhi, lomask, himask, mask;
112 int shift;
113
114 switch (type) {
115 case INSN_IMM_MOVNZ:
116 /*
117 * For signed MOVW relocations, we have to manipulate the
118 * instruction encoding depending on whether or not the
119 * immediate is less than zero.
120 */
121 insn &= ~(3 << 29);
122 if ((s64)imm >= 0) {
123 /* >=0: Set the instruction to MOVZ (opcode 10b). */
124 insn |= 2 << 29;
125 } else {
126 /*
127 * <0: Set the instruction to MOVN (opcode 00b).
128 * Since we've masked the opcode already, we
129 * don't need to do anything other than
130 * inverting the new immediate field.
131 */
132 imm = ~imm;
133 }
134 case INSN_IMM_MOVK:
135 mask = BIT(16) - 1;
136 shift = 5;
137 break;
138 case INSN_IMM_ADR:
139 lomask = 0x3;
140 himask = 0x7ffff;
141 immlo = imm & lomask;
142 imm >>= 2;
143 immhi = imm & himask;
144 imm = (immlo << 24) | (immhi);
145 mask = (lomask << 24) | (himask);
146 shift = 5;
147 break;
148 case INSN_IMM_26:
149 mask = BIT(26) - 1;
150 shift = 0;
151 break;
152 case INSN_IMM_19:
153 mask = BIT(19) - 1;
154 shift = 5;
155 break;
156 case INSN_IMM_16:
157 mask = BIT(16) - 1;
158 shift = 5;
159 break;
160 case INSN_IMM_14:
161 mask = BIT(14) - 1;
162 shift = 5;
163 break;
164 case INSN_IMM_12:
165 mask = BIT(12) - 1;
166 shift = 10;
167 break;
168 case INSN_IMM_9:
169 mask = BIT(9) - 1;
170 shift = 12;
171 break;
172 default:
173 pr_err("encode_insn_immediate: unknown immediate encoding %d\n",
174 type);
175 return 0;
176 }
177
178 /* Update the immediate field. */
179 insn &= ~(mask << shift);
180 insn |= (imm & mask) << shift;
181
182 return insn;
183}
184
185static int reloc_insn_movw(enum aarch64_reloc_op op, void *place, u64 val,
186 int lsb, enum aarch64_imm_type imm_type)
187{
188 u64 imm, limit = 0;
189 s64 sval;
190 u32 insn = *(u32 *)place;
191
192 sval = do_reloc(op, place, val);
193 sval >>= lsb;
194 imm = sval & 0xffff;
195
196 /* Update the instruction with the new encoding. */
197 *(u32 *)place = encode_insn_immediate(imm_type, insn, imm);
198
199 /* Shift out the immediate field. */
200 sval >>= 16;
201
202 /*
203 * For unsigned immediates, the overflow check is straightforward.
204 * For signed immediates, the sign bit is actually the bit past the
205 * most significant bit of the field.
206 * The INSN_IMM_16 immediate type is unsigned.
207 */
208 if (imm_type != INSN_IMM_16) {
209 sval++;
210 limit++;
211 }
212
213 /* Check the upper bits depending on the sign of the immediate. */
214 if ((u64)sval > limit)
215 return -ERANGE;
216
217 return 0;
218}
219
220static int reloc_insn_imm(enum aarch64_reloc_op op, void *place, u64 val,
221 int lsb, int len, enum aarch64_imm_type imm_type)
222{
223 u64 imm, imm_mask;
224 s64 sval;
225 u32 insn = *(u32 *)place;
226
227 /* Calculate the relocation value. */
228 sval = do_reloc(op, place, val);
229 sval >>= lsb;
230
231 /* Extract the value bits and shift them to bit 0. */
232 imm_mask = (BIT(lsb + len) - 1) >> lsb;
233 imm = sval & imm_mask;
234
235 /* Update the instruction's immediate field. */
236 *(u32 *)place = encode_insn_immediate(imm_type, insn, imm);
237
238 /*
239 * Extract the upper value bits (including the sign bit) and
240 * shift them to bit 0.
241 */
242 sval = (s64)(sval & ~(imm_mask >> 1)) >> (len - 1);
243
244 /*
245 * Overflow has occurred if the upper bits are not all equal to
246 * the sign bit of the value.
247 */
248 if ((u64)(sval + 1) >= 2)
249 return -ERANGE;
250
251 return 0;
252}
253
254int apply_relocate_add(Elf64_Shdr *sechdrs,
255 const char *strtab,
256 unsigned int symindex,
257 unsigned int relsec,
258 struct module *me)
259{
260 unsigned int i;
261 int ovf;
262 bool overflow_check;
263 Elf64_Sym *sym;
264 void *loc;
265 u64 val;
266 Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
267
268 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
269 /* loc corresponds to P in the AArch64 ELF document. */
270 loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
271 + rel[i].r_offset;
272
273 /* sym is the ELF symbol we're referring to. */
274 sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
275 + ELF64_R_SYM(rel[i].r_info);
276
277 /* val corresponds to (S + A) in the AArch64 ELF document. */
278 val = sym->st_value + rel[i].r_addend;
279
280 /* Check for overflow by default. */
281 overflow_check = true;
282
283 /* Perform the static relocation. */
284 switch (ELF64_R_TYPE(rel[i].r_info)) {
285 /* Null relocations. */
286 case R_ARM_NONE:
287 case R_AARCH64_NONE:
288 ovf = 0;
289 break;
290
291 /* Data relocations. */
292 case R_AARCH64_ABS64:
293 overflow_check = false;
294 ovf = reloc_data(RELOC_OP_ABS, loc, val, 64);
295 break;
296 case R_AARCH64_ABS32:
297 ovf = reloc_data(RELOC_OP_ABS, loc, val, 32);
298 break;
299 case R_AARCH64_ABS16:
300 ovf = reloc_data(RELOC_OP_ABS, loc, val, 16);
301 break;
302 case R_AARCH64_PREL64:
303 overflow_check = false;
304 ovf = reloc_data(RELOC_OP_PREL, loc, val, 64);
305 break;
306 case R_AARCH64_PREL32:
307 ovf = reloc_data(RELOC_OP_PREL, loc, val, 32);
308 break;
309 case R_AARCH64_PREL16:
310 ovf = reloc_data(RELOC_OP_PREL, loc, val, 16);
311 break;
312
313 /* MOVW instruction relocations. */
314 case R_AARCH64_MOVW_UABS_G0_NC:
315 overflow_check = false;
316 case R_AARCH64_MOVW_UABS_G0:
317 ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 0,
318 INSN_IMM_16);
319 break;
320 case R_AARCH64_MOVW_UABS_G1_NC:
321 overflow_check = false;
322 case R_AARCH64_MOVW_UABS_G1:
323 ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 16,
324 INSN_IMM_16);
325 break;
326 case R_AARCH64_MOVW_UABS_G2_NC:
327 overflow_check = false;
328 case R_AARCH64_MOVW_UABS_G2:
329 ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 32,
330 INSN_IMM_16);
331 break;
332 case R_AARCH64_MOVW_UABS_G3:
333 /* We're using the top bits so we can't overflow. */
334 overflow_check = false;
335 ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 48,
336 INSN_IMM_16);
337 break;
338 case R_AARCH64_MOVW_SABS_G0:
339 ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 0,
340 INSN_IMM_MOVNZ);
341 break;
342 case R_AARCH64_MOVW_SABS_G1:
343 ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 16,
344 INSN_IMM_MOVNZ);
345 break;
346 case R_AARCH64_MOVW_SABS_G2:
347 ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 32,
348 INSN_IMM_MOVNZ);
349 break;
350 case R_AARCH64_MOVW_PREL_G0_NC:
351 overflow_check = false;
352 ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 0,
353 INSN_IMM_MOVK);
354 break;
355 case R_AARCH64_MOVW_PREL_G0:
356 ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 0,
357 INSN_IMM_MOVNZ);
358 break;
359 case R_AARCH64_MOVW_PREL_G1_NC:
360 overflow_check = false;
361 ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 16,
362 INSN_IMM_MOVK);
363 break;
364 case R_AARCH64_MOVW_PREL_G1:
365 ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 16,
366 INSN_IMM_MOVNZ);
367 break;
368 case R_AARCH64_MOVW_PREL_G2_NC:
369 overflow_check = false;
370 ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 32,
371 INSN_IMM_MOVK);
372 break;
373 case R_AARCH64_MOVW_PREL_G2:
374 ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 32,
375 INSN_IMM_MOVNZ);
376 break;
377 case R_AARCH64_MOVW_PREL_G3:
378 /* We're using the top bits so we can't overflow. */
379 overflow_check = false;
380 ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 48,
381 INSN_IMM_MOVNZ);
382 break;
383
384 /* Immediate instruction relocations. */
385 case R_AARCH64_LD_PREL_LO19:
386 ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 2, 19,
387 INSN_IMM_19);
388 break;
389 case R_AARCH64_ADR_PREL_LO21:
390 ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 0, 21,
391 INSN_IMM_ADR);
392 break;
393 case R_AARCH64_ADR_PREL_PG_HI21_NC:
394 overflow_check = false;
395 case R_AARCH64_ADR_PREL_PG_HI21:
396 ovf = reloc_insn_imm(RELOC_OP_PAGE, loc, val, 12, 21,
397 INSN_IMM_ADR);
398 break;
399 case R_AARCH64_ADD_ABS_LO12_NC:
400 case R_AARCH64_LDST8_ABS_LO12_NC:
401 overflow_check = false;
402 ovf = reloc_insn_imm(RELOC_OP_ABS, loc, val, 0, 12,
403 INSN_IMM_12);
404 break;
405 case R_AARCH64_LDST16_ABS_LO12_NC:
406 overflow_check = false;
407 ovf = reloc_insn_imm(RELOC_OP_ABS, loc, val, 1, 11,
408 INSN_IMM_12);
409 break;
410 case R_AARCH64_LDST32_ABS_LO12_NC:
411 overflow_check = false;
412 ovf = reloc_insn_imm(RELOC_OP_ABS, loc, val, 2, 10,
413 INSN_IMM_12);
414 break;
415 case R_AARCH64_LDST64_ABS_LO12_NC:
416 overflow_check = false;
417 ovf = reloc_insn_imm(RELOC_OP_ABS, loc, val, 3, 9,
418 INSN_IMM_12);
419 break;
420 case R_AARCH64_LDST128_ABS_LO12_NC:
421 overflow_check = false;
422 ovf = reloc_insn_imm(RELOC_OP_ABS, loc, val, 4, 8,
423 INSN_IMM_12);
424 break;
425 case R_AARCH64_TSTBR14:
426 ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 2, 14,
427 INSN_IMM_14);
428 break;
429 case R_AARCH64_CONDBR19:
430 ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 2, 19,
431 INSN_IMM_19);
432 break;
433 case R_AARCH64_JUMP26:
434 case R_AARCH64_CALL26:
435 ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 2, 26,
436 INSN_IMM_26);
437 break;
438
439 default:
440 pr_err("module %s: unsupported RELA relocation: %llu\n",
441 me->name, ELF64_R_TYPE(rel[i].r_info));
442 return -ENOEXEC;
443 }
444
445 if (overflow_check && ovf == -ERANGE)
446 goto overflow;
447
448 }
449
450 return 0;
451
452overflow:
453 pr_err("module %s: overflow in relocation type %d val %Lx\n",
454 me->name, (int)ELF64_R_TYPE(rel[i].r_info), val);
455 return -ENOEXEC;
456}
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
new file mode 100644
index 000000000000..ecbf2d81ec5c
--- /dev/null
+++ b/arch/arm64/kernel/perf_event.c
@@ -0,0 +1,1368 @@
1/*
2 * PMU support
3 *
4 * Copyright (C) 2012 ARM Limited
5 * Author: Will Deacon <will.deacon@arm.com>
6 *
7 * This code is based heavily on the ARMv7 perf event code.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21#define pr_fmt(fmt) "hw perfevents: " fmt
22
23#include <linux/bitmap.h>
24#include <linux/interrupt.h>
25#include <linux/kernel.h>
26#include <linux/export.h>
27#include <linux/perf_event.h>
28#include <linux/platform_device.h>
29#include <linux/spinlock.h>
30#include <linux/uaccess.h>
31
32#include <asm/cputype.h>
33#include <asm/irq.h>
34#include <asm/irq_regs.h>
35#include <asm/pmu.h>
36#include <asm/stacktrace.h>
37
38/*
39 * ARMv8 supports a maximum of 32 events.
40 * The cycle counter is included in this total.
41 */
42#define ARMPMU_MAX_HWEVENTS 32
43
44static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events);
45static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask);
46static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events);
47
48#define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))
49
50/* Set at runtime when we know what CPU type we are. */
51static struct arm_pmu *cpu_pmu;
52
53int
54armpmu_get_max_events(void)
55{
56 int max_events = 0;
57
58 if (cpu_pmu != NULL)
59 max_events = cpu_pmu->num_events;
60
61 return max_events;
62}
63EXPORT_SYMBOL_GPL(armpmu_get_max_events);
64
65int perf_num_counters(void)
66{
67 return armpmu_get_max_events();
68}
69EXPORT_SYMBOL_GPL(perf_num_counters);
70
71#define HW_OP_UNSUPPORTED 0xFFFF
72
73#define C(_x) \
74 PERF_COUNT_HW_CACHE_##_x
75
76#define CACHE_OP_UNSUPPORTED 0xFFFF
77
78static int
79armpmu_map_cache_event(const unsigned (*cache_map)
80 [PERF_COUNT_HW_CACHE_MAX]
81 [PERF_COUNT_HW_CACHE_OP_MAX]
82 [PERF_COUNT_HW_CACHE_RESULT_MAX],
83 u64 config)
84{
85 unsigned int cache_type, cache_op, cache_result, ret;
86
87 cache_type = (config >> 0) & 0xff;
88 if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
89 return -EINVAL;
90
91 cache_op = (config >> 8) & 0xff;
92 if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
93 return -EINVAL;
94
95 cache_result = (config >> 16) & 0xff;
96 if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
97 return -EINVAL;
98
99 ret = (int)(*cache_map)[cache_type][cache_op][cache_result];
100
101 if (ret == CACHE_OP_UNSUPPORTED)
102 return -ENOENT;
103
104 return ret;
105}
106
107static int
108armpmu_map_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config)
109{
110 int mapping = (*event_map)[config];
111 return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping;
112}
113
114static int
115armpmu_map_raw_event(u32 raw_event_mask, u64 config)
116{
117 return (int)(config & raw_event_mask);
118}
119
120static int map_cpu_event(struct perf_event *event,
121 const unsigned (*event_map)[PERF_COUNT_HW_MAX],
122 const unsigned (*cache_map)
123 [PERF_COUNT_HW_CACHE_MAX]
124 [PERF_COUNT_HW_CACHE_OP_MAX]
125 [PERF_COUNT_HW_CACHE_RESULT_MAX],
126 u32 raw_event_mask)
127{
128 u64 config = event->attr.config;
129
130 switch (event->attr.type) {
131 case PERF_TYPE_HARDWARE:
132 return armpmu_map_event(event_map, config);
133 case PERF_TYPE_HW_CACHE:
134 return armpmu_map_cache_event(cache_map, config);
135 case PERF_TYPE_RAW:
136 return armpmu_map_raw_event(raw_event_mask, config);
137 }
138
139 return -ENOENT;
140}
141
142int
143armpmu_event_set_period(struct perf_event *event,
144 struct hw_perf_event *hwc,
145 int idx)
146{
147 struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
148 s64 left = local64_read(&hwc->period_left);
149 s64 period = hwc->sample_period;
150 int ret = 0;
151
152 if (unlikely(left <= -period)) {
153 left = period;
154 local64_set(&hwc->period_left, left);
155 hwc->last_period = period;
156 ret = 1;
157 }
158
159 if (unlikely(left <= 0)) {
160 left += period;
161 local64_set(&hwc->period_left, left);
162 hwc->last_period = period;
163 ret = 1;
164 }
165
166 if (left > (s64)armpmu->max_period)
167 left = armpmu->max_period;
168
169 local64_set(&hwc->prev_count, (u64)-left);
170
171 armpmu->write_counter(idx, (u64)(-left) & 0xffffffff);
172
173 perf_event_update_userpage(event);
174
175 return ret;
176}
177
178u64
179armpmu_event_update(struct perf_event *event,
180 struct hw_perf_event *hwc,
181 int idx)
182{
183 struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
184 u64 delta, prev_raw_count, new_raw_count;
185
186again:
187 prev_raw_count = local64_read(&hwc->prev_count);
188 new_raw_count = armpmu->read_counter(idx);
189
190 if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
191 new_raw_count) != prev_raw_count)
192 goto again;
193
194 delta = (new_raw_count - prev_raw_count) & armpmu->max_period;
195
196 local64_add(delta, &event->count);
197 local64_sub(delta, &hwc->period_left);
198
199 return new_raw_count;
200}
201
202static void
203armpmu_read(struct perf_event *event)
204{
205 struct hw_perf_event *hwc = &event->hw;
206
207 /* Don't read disabled counters! */
208 if (hwc->idx < 0)
209 return;
210
211 armpmu_event_update(event, hwc, hwc->idx);
212}
213
214static void
215armpmu_stop(struct perf_event *event, int flags)
216{
217 struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
218 struct hw_perf_event *hwc = &event->hw;
219
220 /*
221 * ARM pmu always has to update the counter, so ignore
222 * PERF_EF_UPDATE, see comments in armpmu_start().
223 */
224 if (!(hwc->state & PERF_HES_STOPPED)) {
225 armpmu->disable(hwc, hwc->idx);
226 barrier(); /* why? */
227 armpmu_event_update(event, hwc, hwc->idx);
228 hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
229 }
230}
231
232static void
233armpmu_start(struct perf_event *event, int flags)
234{
235 struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
236 struct hw_perf_event *hwc = &event->hw;
237
238 /*
239 * ARM pmu always has to reprogram the period, so ignore
240 * PERF_EF_RELOAD, see the comment below.
241 */
242 if (flags & PERF_EF_RELOAD)
243 WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
244
245 hwc->state = 0;
246 /*
247 * Set the period again. Some counters can't be stopped, so when we
248 * were stopped we simply disabled the IRQ source and the counter
249 * may have been left counting. If we don't do this step then we may
250 * get an interrupt too soon or *way* too late if the overflow has
251 * happened since disabling.
252 */
253 armpmu_event_set_period(event, hwc, hwc->idx);
254 armpmu->enable(hwc, hwc->idx);
255}
256
257static void
258armpmu_del(struct perf_event *event, int flags)
259{
260 struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
261 struct pmu_hw_events *hw_events = armpmu->get_hw_events();
262 struct hw_perf_event *hwc = &event->hw;
263 int idx = hwc->idx;
264
265 WARN_ON(idx < 0);
266
267 armpmu_stop(event, PERF_EF_UPDATE);
268 hw_events->events[idx] = NULL;
269 clear_bit(idx, hw_events->used_mask);
270
271 perf_event_update_userpage(event);
272}
273
274static int
275armpmu_add(struct perf_event *event, int flags)
276{
277 struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
278 struct pmu_hw_events *hw_events = armpmu->get_hw_events();
279 struct hw_perf_event *hwc = &event->hw;
280 int idx;
281 int err = 0;
282
283 perf_pmu_disable(event->pmu);
284
285 /* If we don't have a space for the counter then finish early. */
286 idx = armpmu->get_event_idx(hw_events, hwc);
287 if (idx < 0) {
288 err = idx;
289 goto out;
290 }
291
292 /*
293 * If there is an event in the counter we are going to use then make
294 * sure it is disabled.
295 */
296 event->hw.idx = idx;
297 armpmu->disable(hwc, idx);
298 hw_events->events[idx] = event;
299
300 hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
301 if (flags & PERF_EF_START)
302 armpmu_start(event, PERF_EF_RELOAD);
303
304 /* Propagate our changes to the userspace mapping. */
305 perf_event_update_userpage(event);
306
307out:
308 perf_pmu_enable(event->pmu);
309 return err;
310}
311
312static int
313validate_event(struct pmu_hw_events *hw_events,
314 struct perf_event *event)
315{
316 struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
317 struct hw_perf_event fake_event = event->hw;
318 struct pmu *leader_pmu = event->group_leader->pmu;
319
320 if (event->pmu != leader_pmu || event->state <= PERF_EVENT_STATE_OFF)
321 return 1;
322
323 return armpmu->get_event_idx(hw_events, &fake_event) >= 0;
324}
325
326static int
327validate_group(struct perf_event *event)
328{
329 struct perf_event *sibling, *leader = event->group_leader;
330 struct pmu_hw_events fake_pmu;
331 DECLARE_BITMAP(fake_used_mask, ARMPMU_MAX_HWEVENTS);
332
333 /*
334 * Initialise the fake PMU. We only need to populate the
335 * used_mask for the purposes of validation.
336 */
337 memset(fake_used_mask, 0, sizeof(fake_used_mask));
338 fake_pmu.used_mask = fake_used_mask;
339
340 if (!validate_event(&fake_pmu, leader))
341 return -EINVAL;
342
343 list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
344 if (!validate_event(&fake_pmu, sibling))
345 return -EINVAL;
346 }
347
348 if (!validate_event(&fake_pmu, event))
349 return -EINVAL;
350
351 return 0;
352}
353
354static void
355armpmu_release_hardware(struct arm_pmu *armpmu)
356{
357 int i, irq, irqs;
358 struct platform_device *pmu_device = armpmu->plat_device;
359
360 irqs = min(pmu_device->num_resources, num_possible_cpus());
361
362 for (i = 0; i < irqs; ++i) {
363 if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
364 continue;
365 irq = platform_get_irq(pmu_device, i);
366 if (irq >= 0)
367 free_irq(irq, armpmu);
368 }
369}
370
371static int
372armpmu_reserve_hardware(struct arm_pmu *armpmu)
373{
374 int i, err, irq, irqs;
375 struct platform_device *pmu_device = armpmu->plat_device;
376
377 if (!pmu_device) {
378 pr_err("no PMU device registered\n");
379 return -ENODEV;
380 }
381
382 irqs = min(pmu_device->num_resources, num_possible_cpus());
383 if (irqs < 1) {
384 pr_err("no irqs for PMUs defined\n");
385 return -ENODEV;
386 }
387
388 for (i = 0; i < irqs; ++i) {
389 err = 0;
390 irq = platform_get_irq(pmu_device, i);
391 if (irq < 0)
392 continue;
393
394 /*
395 * If we have a single PMU interrupt that we can't shift,
396 * assume that we're running on a uniprocessor machine and
397 * continue. Otherwise, continue without this interrupt.
398 */
399 if (irq_set_affinity(irq, cpumask_of(i)) && irqs > 1) {
400 pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n",
401 irq, i);
402 continue;
403 }
404
405 err = request_irq(irq, armpmu->handle_irq,
406 IRQF_NOBALANCING,
407 "arm-pmu", armpmu);
408 if (err) {
409 pr_err("unable to request IRQ%d for ARM PMU counters\n",
410 irq);
411 armpmu_release_hardware(armpmu);
412 return err;
413 }
414
415 cpumask_set_cpu(i, &armpmu->active_irqs);
416 }
417
418 return 0;
419}
420
421static void
422hw_perf_event_destroy(struct perf_event *event)
423{
424 struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
425 atomic_t *active_events = &armpmu->active_events;
426 struct mutex *pmu_reserve_mutex = &armpmu->reserve_mutex;
427
428 if (atomic_dec_and_mutex_lock(active_events, pmu_reserve_mutex)) {
429 armpmu_release_hardware(armpmu);
430 mutex_unlock(pmu_reserve_mutex);
431 }
432}
433
434static int
435event_requires_mode_exclusion(struct perf_event_attr *attr)
436{
437 return attr->exclude_idle || attr->exclude_user ||
438 attr->exclude_kernel || attr->exclude_hv;
439}
440
441static int
442__hw_perf_event_init(struct perf_event *event)
443{
444 struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
445 struct hw_perf_event *hwc = &event->hw;
446 int mapping, err;
447
448 mapping = armpmu->map_event(event);
449
450 if (mapping < 0) {
451 pr_debug("event %x:%llx not supported\n", event->attr.type,
452 event->attr.config);
453 return mapping;
454 }
455
456 /*
457 * We don't assign an index until we actually place the event onto
458 * hardware. Use -1 to signify that we haven't decided where to put it
459 * yet. For SMP systems, each core has it's own PMU so we can't do any
460 * clever allocation or constraints checking at this point.
461 */
462 hwc->idx = -1;
463 hwc->config_base = 0;
464 hwc->config = 0;
465 hwc->event_base = 0;
466
467 /*
468 * Check whether we need to exclude the counter from certain modes.
469 */
470 if ((!armpmu->set_event_filter ||
471 armpmu->set_event_filter(hwc, &event->attr)) &&
472 event_requires_mode_exclusion(&event->attr)) {
473 pr_debug("ARM performance counters do not support mode exclusion\n");
474 return -EPERM;
475 }
476
477 /*
478 * Store the event encoding into the config_base field.
479 */
480 hwc->config_base |= (unsigned long)mapping;
481
482 if (!hwc->sample_period) {
483 /*
484 * For non-sampling runs, limit the sample_period to half
485 * of the counter width. That way, the new counter value
486 * is far less likely to overtake the previous one unless
487 * you have some serious IRQ latency issues.
488 */
489 hwc->sample_period = armpmu->max_period >> 1;
490 hwc->last_period = hwc->sample_period;
491 local64_set(&hwc->period_left, hwc->sample_period);
492 }
493
494 err = 0;
495 if (event->group_leader != event) {
496 err = validate_group(event);
497 if (err)
498 return -EINVAL;
499 }
500
501 return err;
502}
503
504static int armpmu_event_init(struct perf_event *event)
505{
506 struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
507 int err = 0;
508 atomic_t *active_events = &armpmu->active_events;
509
510 if (armpmu->map_event(event) == -ENOENT)
511 return -ENOENT;
512
513 event->destroy = hw_perf_event_destroy;
514
515 if (!atomic_inc_not_zero(active_events)) {
516 mutex_lock(&armpmu->reserve_mutex);
517 if (atomic_read(active_events) == 0)
518 err = armpmu_reserve_hardware(armpmu);
519
520 if (!err)
521 atomic_inc(active_events);
522 mutex_unlock(&armpmu->reserve_mutex);
523 }
524
525 if (err)
526 return err;
527
528 err = __hw_perf_event_init(event);
529 if (err)
530 hw_perf_event_destroy(event);
531
532 return err;
533}
534
535static void armpmu_enable(struct pmu *pmu)
536{
537 struct arm_pmu *armpmu = to_arm_pmu(pmu);
538 struct pmu_hw_events *hw_events = armpmu->get_hw_events();
539 int enabled = bitmap_weight(hw_events->used_mask, armpmu->num_events);
540
541 if (enabled)
542 armpmu->start();
543}
544
545static void armpmu_disable(struct pmu *pmu)
546{
547 struct arm_pmu *armpmu = to_arm_pmu(pmu);
548 armpmu->stop();
549}
550
551static void __init armpmu_init(struct arm_pmu *armpmu)
552{
553 atomic_set(&armpmu->active_events, 0);
554 mutex_init(&armpmu->reserve_mutex);
555
556 armpmu->pmu = (struct pmu) {
557 .pmu_enable = armpmu_enable,
558 .pmu_disable = armpmu_disable,
559 .event_init = armpmu_event_init,
560 .add = armpmu_add,
561 .del = armpmu_del,
562 .start = armpmu_start,
563 .stop = armpmu_stop,
564 .read = armpmu_read,
565 };
566}
567
568int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type)
569{
570 armpmu_init(armpmu);
571 return perf_pmu_register(&armpmu->pmu, name, type);
572}
573
574/*
575 * ARMv8 PMUv3 Performance Events handling code.
576 * Common event types.
577 */
578enum armv8_pmuv3_perf_types {
579 /* Required events. */
580 ARMV8_PMUV3_PERFCTR_PMNC_SW_INCR = 0x00,
581 ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL = 0x03,
582 ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS = 0x04,
583 ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED = 0x10,
584 ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES = 0x11,
585 ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED = 0x12,
586
587 /* At least one of the following is required. */
588 ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED = 0x08,
589 ARMV8_PMUV3_PERFCTR_OP_SPEC = 0x1B,
590
591 /* Common architectural events. */
592 ARMV8_PMUV3_PERFCTR_MEM_READ = 0x06,
593 ARMV8_PMUV3_PERFCTR_MEM_WRITE = 0x07,
594 ARMV8_PMUV3_PERFCTR_EXC_TAKEN = 0x09,
595 ARMV8_PMUV3_PERFCTR_EXC_EXECUTED = 0x0A,
596 ARMV8_PMUV3_PERFCTR_CID_WRITE = 0x0B,
597 ARMV8_PMUV3_PERFCTR_PC_WRITE = 0x0C,
598 ARMV8_PMUV3_PERFCTR_PC_IMM_BRANCH = 0x0D,
599 ARMV8_PMUV3_PERFCTR_PC_PROC_RETURN = 0x0E,
600 ARMV8_PMUV3_PERFCTR_MEM_UNALIGNED_ACCESS = 0x0F,
601 ARMV8_PMUV3_PERFCTR_TTBR_WRITE = 0x1C,
602
603 /* Common microarchitectural events. */
604 ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL = 0x01,
605 ARMV8_PMUV3_PERFCTR_ITLB_REFILL = 0x02,
606 ARMV8_PMUV3_PERFCTR_DTLB_REFILL = 0x05,
607 ARMV8_PMUV3_PERFCTR_MEM_ACCESS = 0x13,
608 ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS = 0x14,
609 ARMV8_PMUV3_PERFCTR_L1_DCACHE_WB = 0x15,
610 ARMV8_PMUV3_PERFCTR_L2_CACHE_ACCESS = 0x16,
611 ARMV8_PMUV3_PERFCTR_L2_CACHE_REFILL = 0x17,
612 ARMV8_PMUV3_PERFCTR_L2_CACHE_WB = 0x18,
613 ARMV8_PMUV3_PERFCTR_BUS_ACCESS = 0x19,
614 ARMV8_PMUV3_PERFCTR_MEM_ERROR = 0x1A,
615 ARMV8_PMUV3_PERFCTR_BUS_CYCLES = 0x1D,
616
617 /*
618 * This isn't an architected event.
619 * We detect this event number and use the cycle counter instead.
620 */
621 ARMV8_PMUV3_PERFCTR_CPU_CYCLES = 0xFF,
622};
623
624/* PMUv3 HW events mapping. */
625static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = {
626 [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES,
627 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED,
628 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS,
629 [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL,
630 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = HW_OP_UNSUPPORTED,
631 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED,
632 [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
633 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED,
634 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED,
635};
636
637static const unsigned armv8_pmuv3_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
638 [PERF_COUNT_HW_CACHE_OP_MAX]
639 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
640 [C(L1D)] = {
641 [C(OP_READ)] = {
642 [C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS,
643 [C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL,
644 },
645 [C(OP_WRITE)] = {
646 [C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS,
647 [C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL,
648 },
649 [C(OP_PREFETCH)] = {
650 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
651 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
652 },
653 },
654 [C(L1I)] = {
655 [C(OP_READ)] = {
656 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
657 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
658 },
659 [C(OP_WRITE)] = {
660 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
661 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
662 },
663 [C(OP_PREFETCH)] = {
664 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
665 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
666 },
667 },
668 [C(LL)] = {
669 [C(OP_READ)] = {
670 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
671 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
672 },
673 [C(OP_WRITE)] = {
674 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
675 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
676 },
677 [C(OP_PREFETCH)] = {
678 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
679 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
680 },
681 },
682 [C(DTLB)] = {
683 [C(OP_READ)] = {
684 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
685 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
686 },
687 [C(OP_WRITE)] = {
688 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
689 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
690 },
691 [C(OP_PREFETCH)] = {
692 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
693 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
694 },
695 },
696 [C(ITLB)] = {
697 [C(OP_READ)] = {
698 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
699 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
700 },
701 [C(OP_WRITE)] = {
702 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
703 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
704 },
705 [C(OP_PREFETCH)] = {
706 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
707 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
708 },
709 },
710 [C(BPU)] = {
711 [C(OP_READ)] = {
712 [C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED,
713 [C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED,
714 },
715 [C(OP_WRITE)] = {
716 [C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED,
717 [C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED,
718 },
719 [C(OP_PREFETCH)] = {
720 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
721 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
722 },
723 },
724 [C(NODE)] = {
725 [C(OP_READ)] = {
726 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
727 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
728 },
729 [C(OP_WRITE)] = {
730 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
731 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
732 },
733 [C(OP_PREFETCH)] = {
734 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
735 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
736 },
737 },
738};
739
740/*
741 * Perf Events' indices
742 */
743#define ARMV8_IDX_CYCLE_COUNTER 0
744#define ARMV8_IDX_COUNTER0 1
745#define ARMV8_IDX_COUNTER_LAST (ARMV8_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1)
746
747#define ARMV8_MAX_COUNTERS 32
748#define ARMV8_COUNTER_MASK (ARMV8_MAX_COUNTERS - 1)
749
750/*
751 * ARMv8 low level PMU access
752 */
753
754/*
755 * Perf Event to low level counters mapping
756 */
757#define ARMV8_IDX_TO_COUNTER(x) \
758 (((x) - ARMV8_IDX_COUNTER0) & ARMV8_COUNTER_MASK)
759
760/*
761 * Per-CPU PMCR: config reg
762 */
763#define ARMV8_PMCR_E (1 << 0) /* Enable all counters */
764#define ARMV8_PMCR_P (1 << 1) /* Reset all counters */
765#define ARMV8_PMCR_C (1 << 2) /* Cycle counter reset */
766#define ARMV8_PMCR_D (1 << 3) /* CCNT counts every 64th cpu cycle */
767#define ARMV8_PMCR_X (1 << 4) /* Export to ETM */
768#define ARMV8_PMCR_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
769#define ARMV8_PMCR_N_SHIFT 11 /* Number of counters supported */
770#define ARMV8_PMCR_N_MASK 0x1f
771#define ARMV8_PMCR_MASK 0x3f /* Mask for writable bits */
772
773/*
774 * PMOVSR: counters overflow flag status reg
775 */
776#define ARMV8_OVSR_MASK 0xffffffff /* Mask for writable bits */
777#define ARMV8_OVERFLOWED_MASK ARMV8_OVSR_MASK
778
779/*
780 * PMXEVTYPER: Event selection reg
781 */
782#define ARMV8_EVTYPE_MASK 0xc00000ff /* Mask for writable bits */
783#define ARMV8_EVTYPE_EVENT 0xff /* Mask for EVENT bits */
784
785/*
786 * Event filters for PMUv3
787 */
788#define ARMV8_EXCLUDE_EL1 (1 << 31)
789#define ARMV8_EXCLUDE_EL0 (1 << 30)
790#define ARMV8_INCLUDE_EL2 (1 << 27)
791
792static inline u32 armv8pmu_pmcr_read(void)
793{
794 u32 val;
795 asm volatile("mrs %0, pmcr_el0" : "=r" (val));
796 return val;
797}
798
799static inline void armv8pmu_pmcr_write(u32 val)
800{
801 val &= ARMV8_PMCR_MASK;
802 isb();
803 asm volatile("msr pmcr_el0, %0" :: "r" (val));
804}
805
806static inline int armv8pmu_has_overflowed(u32 pmovsr)
807{
808 return pmovsr & ARMV8_OVERFLOWED_MASK;
809}
810
811static inline int armv8pmu_counter_valid(int idx)
812{
813 return idx >= ARMV8_IDX_CYCLE_COUNTER && idx <= ARMV8_IDX_COUNTER_LAST;
814}
815
816static inline int armv8pmu_counter_has_overflowed(u32 pmnc, int idx)
817{
818 int ret = 0;
819 u32 counter;
820
821 if (!armv8pmu_counter_valid(idx)) {
822 pr_err("CPU%u checking wrong counter %d overflow status\n",
823 smp_processor_id(), idx);
824 } else {
825 counter = ARMV8_IDX_TO_COUNTER(idx);
826 ret = pmnc & BIT(counter);
827 }
828
829 return ret;
830}
831
832static inline int armv8pmu_select_counter(int idx)
833{
834 u32 counter;
835
836 if (!armv8pmu_counter_valid(idx)) {
837 pr_err("CPU%u selecting wrong PMNC counter %d\n",
838 smp_processor_id(), idx);
839 return -EINVAL;
840 }
841
842 counter = ARMV8_IDX_TO_COUNTER(idx);
843 asm volatile("msr pmselr_el0, %0" :: "r" (counter));
844 isb();
845
846 return idx;
847}
848
849static inline u32 armv8pmu_read_counter(int idx)
850{
851 u32 value = 0;
852
853 if (!armv8pmu_counter_valid(idx))
854 pr_err("CPU%u reading wrong counter %d\n",
855 smp_processor_id(), idx);
856 else if (idx == ARMV8_IDX_CYCLE_COUNTER)
857 asm volatile("mrs %0, pmccntr_el0" : "=r" (value));
858 else if (armv8pmu_select_counter(idx) == idx)
859 asm volatile("mrs %0, pmxevcntr_el0" : "=r" (value));
860
861 return value;
862}
863
864static inline void armv8pmu_write_counter(int idx, u32 value)
865{
866 if (!armv8pmu_counter_valid(idx))
867 pr_err("CPU%u writing wrong counter %d\n",
868 smp_processor_id(), idx);
869 else if (idx == ARMV8_IDX_CYCLE_COUNTER)
870 asm volatile("msr pmccntr_el0, %0" :: "r" (value));
871 else if (armv8pmu_select_counter(idx) == idx)
872 asm volatile("msr pmxevcntr_el0, %0" :: "r" (value));
873}
874
875static inline void armv8pmu_write_evtype(int idx, u32 val)
876{
877 if (armv8pmu_select_counter(idx) == idx) {
878 val &= ARMV8_EVTYPE_MASK;
879 asm volatile("msr pmxevtyper_el0, %0" :: "r" (val));
880 }
881}
882
883static inline int armv8pmu_enable_counter(int idx)
884{
885 u32 counter;
886
887 if (!armv8pmu_counter_valid(idx)) {
888 pr_err("CPU%u enabling wrong PMNC counter %d\n",
889 smp_processor_id(), idx);
890 return -EINVAL;
891 }
892
893 counter = ARMV8_IDX_TO_COUNTER(idx);
894 asm volatile("msr pmcntenset_el0, %0" :: "r" (BIT(counter)));
895 return idx;
896}
897
898static inline int armv8pmu_disable_counter(int idx)
899{
900 u32 counter;
901
902 if (!armv8pmu_counter_valid(idx)) {
903 pr_err("CPU%u disabling wrong PMNC counter %d\n",
904 smp_processor_id(), idx);
905 return -EINVAL;
906 }
907
908 counter = ARMV8_IDX_TO_COUNTER(idx);
909 asm volatile("msr pmcntenclr_el0, %0" :: "r" (BIT(counter)));
910 return idx;
911}
912
913static inline int armv8pmu_enable_intens(int idx)
914{
915 u32 counter;
916
917 if (!armv8pmu_counter_valid(idx)) {
918 pr_err("CPU%u enabling wrong PMNC counter IRQ enable %d\n",
919 smp_processor_id(), idx);
920 return -EINVAL;
921 }
922
923 counter = ARMV8_IDX_TO_COUNTER(idx);
924 asm volatile("msr pmintenset_el1, %0" :: "r" (BIT(counter)));
925 return idx;
926}
927
928static inline int armv8pmu_disable_intens(int idx)
929{
930 u32 counter;
931
932 if (!armv8pmu_counter_valid(idx)) {
933 pr_err("CPU%u disabling wrong PMNC counter IRQ enable %d\n",
934 smp_processor_id(), idx);
935 return -EINVAL;
936 }
937
938 counter = ARMV8_IDX_TO_COUNTER(idx);
939 asm volatile("msr pmintenclr_el1, %0" :: "r" (BIT(counter)));
940 isb();
941 /* Clear the overflow flag in case an interrupt is pending. */
942 asm volatile("msr pmovsclr_el0, %0" :: "r" (BIT(counter)));
943 isb();
944 return idx;
945}
946
947static inline u32 armv8pmu_getreset_flags(void)
948{
949 u32 value;
950
951 /* Read */
952 asm volatile("mrs %0, pmovsclr_el0" : "=r" (value));
953
954 /* Write to clear flags */
955 value &= ARMV8_OVSR_MASK;
956 asm volatile("msr pmovsclr_el0, %0" :: "r" (value));
957
958 return value;
959}
960
961static void armv8pmu_enable_event(struct hw_perf_event *hwc, int idx)
962{
963 unsigned long flags;
964 struct pmu_hw_events *events = cpu_pmu->get_hw_events();
965
966 /*
967 * Enable counter and interrupt, and set the counter to count
968 * the event that we're interested in.
969 */
970 raw_spin_lock_irqsave(&events->pmu_lock, flags);
971
972 /*
973 * Disable counter
974 */
975 armv8pmu_disable_counter(idx);
976
977 /*
978 * Set event (if destined for PMNx counters).
979 */
980 armv8pmu_write_evtype(idx, hwc->config_base);
981
982 /*
983 * Enable interrupt for this counter
984 */
985 armv8pmu_enable_intens(idx);
986
987 /*
988 * Enable counter
989 */
990 armv8pmu_enable_counter(idx);
991
992 raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
993}
994
995static void armv8pmu_disable_event(struct hw_perf_event *hwc, int idx)
996{
997 unsigned long flags;
998 struct pmu_hw_events *events = cpu_pmu->get_hw_events();
999
1000 /*
1001 * Disable counter and interrupt
1002 */
1003 raw_spin_lock_irqsave(&events->pmu_lock, flags);
1004
1005 /*
1006 * Disable counter
1007 */
1008 armv8pmu_disable_counter(idx);
1009
1010 /*
1011 * Disable interrupt for this counter
1012 */
1013 armv8pmu_disable_intens(idx);
1014
1015 raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
1016}
1017
1018static irqreturn_t armv8pmu_handle_irq(int irq_num, void *dev)
1019{
1020 u32 pmovsr;
1021 struct perf_sample_data data;
1022 struct pmu_hw_events *cpuc;
1023 struct pt_regs *regs;
1024 int idx;
1025
1026 /*
1027 * Get and reset the IRQ flags
1028 */
1029 pmovsr = armv8pmu_getreset_flags();
1030
1031 /*
1032 * Did an overflow occur?
1033 */
1034 if (!armv8pmu_has_overflowed(pmovsr))
1035 return IRQ_NONE;
1036
1037 /*
1038 * Handle the counter(s) overflow(s)
1039 */
1040 regs = get_irq_regs();
1041
1042 cpuc = &__get_cpu_var(cpu_hw_events);
1043 for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
1044 struct perf_event *event = cpuc->events[idx];
1045 struct hw_perf_event *hwc;
1046
1047 /* Ignore if we don't have an event. */
1048 if (!event)
1049 continue;
1050
1051 /*
1052 * We have a single interrupt for all counters. Check that
1053 * each counter has overflowed before we process it.
1054 */
1055 if (!armv8pmu_counter_has_overflowed(pmovsr, idx))
1056 continue;
1057
1058 hwc = &event->hw;
1059 armpmu_event_update(event, hwc, idx);
1060 perf_sample_data_init(&data, 0, hwc->last_period);
1061 if (!armpmu_event_set_period(event, hwc, idx))
1062 continue;
1063
1064 if (perf_event_overflow(event, &data, regs))
1065 cpu_pmu->disable(hwc, idx);
1066 }
1067
1068 /*
1069 * Handle the pending perf events.
1070 *
1071 * Note: this call *must* be run with interrupts disabled. For
1072 * platforms that can have the PMU interrupts raised as an NMI, this
1073 * will not work.
1074 */
1075 irq_work_run();
1076
1077 return IRQ_HANDLED;
1078}
1079
1080static void armv8pmu_start(void)
1081{
1082 unsigned long flags;
1083 struct pmu_hw_events *events = cpu_pmu->get_hw_events();
1084
1085 raw_spin_lock_irqsave(&events->pmu_lock, flags);
1086 /* Enable all counters */
1087 armv8pmu_pmcr_write(armv8pmu_pmcr_read() | ARMV8_PMCR_E);
1088 raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
1089}
1090
1091static void armv8pmu_stop(void)
1092{
1093 unsigned long flags;
1094 struct pmu_hw_events *events = cpu_pmu->get_hw_events();
1095
1096 raw_spin_lock_irqsave(&events->pmu_lock, flags);
1097 /* Disable all counters */
1098 armv8pmu_pmcr_write(armv8pmu_pmcr_read() & ~ARMV8_PMCR_E);
1099 raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
1100}
1101
1102static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc,
1103 struct hw_perf_event *event)
1104{
1105 int idx;
1106 unsigned long evtype = event->config_base & ARMV8_EVTYPE_EVENT;
1107
1108 /* Always place a cycle counter into the cycle counter. */
1109 if (evtype == ARMV8_PMUV3_PERFCTR_CPU_CYCLES) {
1110 if (test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask))
1111 return -EAGAIN;
1112
1113 return ARMV8_IDX_CYCLE_COUNTER;
1114 }
1115
1116 /*
1117 * For anything other than a cycle counter, try and use
1118 * the events counters
1119 */
1120 for (idx = ARMV8_IDX_COUNTER0; idx < cpu_pmu->num_events; ++idx) {
1121 if (!test_and_set_bit(idx, cpuc->used_mask))
1122 return idx;
1123 }
1124
1125 /* The counters are all in use. */
1126 return -EAGAIN;
1127}
1128
1129/*
1130 * Add an event filter to a given event. This will only work for PMUv2 PMUs.
1131 */
1132static int armv8pmu_set_event_filter(struct hw_perf_event *event,
1133 struct perf_event_attr *attr)
1134{
1135 unsigned long config_base = 0;
1136
1137 if (attr->exclude_idle)
1138 return -EPERM;
1139 if (attr->exclude_user)
1140 config_base |= ARMV8_EXCLUDE_EL0;
1141 if (attr->exclude_kernel)
1142 config_base |= ARMV8_EXCLUDE_EL1;
1143 if (!attr->exclude_hv)
1144 config_base |= ARMV8_INCLUDE_EL2;
1145
1146 /*
1147 * Install the filter into config_base as this is used to
1148 * construct the event type.
1149 */
1150 event->config_base = config_base;
1151
1152 return 0;
1153}
1154
1155static void armv8pmu_reset(void *info)
1156{
1157 u32 idx, nb_cnt = cpu_pmu->num_events;
1158
1159 /* The counter and interrupt enable registers are unknown at reset. */
1160 for (idx = ARMV8_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx)
1161 armv8pmu_disable_event(NULL, idx);
1162
1163 /* Initialize & Reset PMNC: C and P bits. */
1164 armv8pmu_pmcr_write(ARMV8_PMCR_P | ARMV8_PMCR_C);
1165
1166 /* Disable access from userspace. */
1167 asm volatile("msr pmuserenr_el0, %0" :: "r" (0));
1168}
1169
1170static int armv8_pmuv3_map_event(struct perf_event *event)
1171{
1172 return map_cpu_event(event, &armv8_pmuv3_perf_map,
1173 &armv8_pmuv3_perf_cache_map, 0xFF);
1174}
1175
1176static struct arm_pmu armv8pmu = {
1177 .handle_irq = armv8pmu_handle_irq,
1178 .enable = armv8pmu_enable_event,
1179 .disable = armv8pmu_disable_event,
1180 .read_counter = armv8pmu_read_counter,
1181 .write_counter = armv8pmu_write_counter,
1182 .get_event_idx = armv8pmu_get_event_idx,
1183 .start = armv8pmu_start,
1184 .stop = armv8pmu_stop,
1185 .reset = armv8pmu_reset,
1186 .max_period = (1LLU << 32) - 1,
1187};
1188
1189static u32 __init armv8pmu_read_num_pmnc_events(void)
1190{
1191 u32 nb_cnt;
1192
1193 /* Read the nb of CNTx counters supported from PMNC */
1194 nb_cnt = (armv8pmu_pmcr_read() >> ARMV8_PMCR_N_SHIFT) & ARMV8_PMCR_N_MASK;
1195
1196 /* Add the CPU cycles counter and return */
1197 return nb_cnt + 1;
1198}
1199
1200static struct arm_pmu *__init armv8_pmuv3_pmu_init(void)
1201{
1202 armv8pmu.name = "arm/armv8-pmuv3";
1203 armv8pmu.map_event = armv8_pmuv3_map_event;
1204 armv8pmu.num_events = armv8pmu_read_num_pmnc_events();
1205 armv8pmu.set_event_filter = armv8pmu_set_event_filter;
1206 return &armv8pmu;
1207}
1208
1209/*
1210 * Ensure the PMU has sane values out of reset.
1211 * This requires SMP to be available, so exists as a separate initcall.
1212 */
1213static int __init
1214cpu_pmu_reset(void)
1215{
1216 if (cpu_pmu && cpu_pmu->reset)
1217 return on_each_cpu(cpu_pmu->reset, NULL, 1);
1218 return 0;
1219}
1220arch_initcall(cpu_pmu_reset);
1221
1222/*
1223 * PMU platform driver and devicetree bindings.
1224 */
1225static struct of_device_id armpmu_of_device_ids[] = {
1226 {.compatible = "arm,armv8-pmuv3"},
1227 {},
1228};
1229
1230static int __devinit armpmu_device_probe(struct platform_device *pdev)
1231{
1232 if (!cpu_pmu)
1233 return -ENODEV;
1234
1235 cpu_pmu->plat_device = pdev;
1236 return 0;
1237}
1238
1239static struct platform_driver armpmu_driver = {
1240 .driver = {
1241 .name = "arm-pmu",
1242 .of_match_table = armpmu_of_device_ids,
1243 },
1244 .probe = armpmu_device_probe,
1245};
1246
1247static int __init register_pmu_driver(void)
1248{
1249 return platform_driver_register(&armpmu_driver);
1250}
1251device_initcall(register_pmu_driver);
1252
1253static struct pmu_hw_events *armpmu_get_cpu_events(void)
1254{
1255 return &__get_cpu_var(cpu_hw_events);
1256}
1257
1258static void __init cpu_pmu_init(struct arm_pmu *armpmu)
1259{
1260 int cpu;
1261 for_each_possible_cpu(cpu) {
1262 struct pmu_hw_events *events = &per_cpu(cpu_hw_events, cpu);
1263 events->events = per_cpu(hw_events, cpu);
1264 events->used_mask = per_cpu(used_mask, cpu);
1265 raw_spin_lock_init(&events->pmu_lock);
1266 }
1267 armpmu->get_hw_events = armpmu_get_cpu_events;
1268}
1269
1270static int __init init_hw_perf_events(void)
1271{
1272 u64 dfr = read_cpuid(ID_AA64DFR0_EL1);
1273
1274 switch ((dfr >> 8) & 0xf) {
1275 case 0x1: /* PMUv3 */
1276 cpu_pmu = armv8_pmuv3_pmu_init();
1277 break;
1278 }
1279
1280 if (cpu_pmu) {
1281 pr_info("enabled with %s PMU driver, %d counters available\n",
1282 cpu_pmu->name, cpu_pmu->num_events);
1283 cpu_pmu_init(cpu_pmu);
1284 armpmu_register(cpu_pmu, "cpu", PERF_TYPE_RAW);
1285 } else {
1286 pr_info("no hardware support available\n");
1287 }
1288
1289 return 0;
1290}
1291early_initcall(init_hw_perf_events);
1292
1293/*
1294 * Callchain handling code.
1295 */
1296struct frame_tail {
1297 struct frame_tail __user *fp;
1298 unsigned long lr;
1299} __attribute__((packed));
1300
1301/*
1302 * Get the return address for a single stackframe and return a pointer to the
1303 * next frame tail.
1304 */
1305static struct frame_tail __user *
1306user_backtrace(struct frame_tail __user *tail,
1307 struct perf_callchain_entry *entry)
1308{
1309 struct frame_tail buftail;
1310 unsigned long err;
1311
1312 /* Also check accessibility of one struct frame_tail beyond */
1313 if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
1314 return NULL;
1315
1316 pagefault_disable();
1317 err = __copy_from_user_inatomic(&buftail, tail, sizeof(buftail));
1318 pagefault_enable();
1319
1320 if (err)
1321 return NULL;
1322
1323 perf_callchain_store(entry, buftail.lr);
1324
1325 /*
1326 * Frame pointers should strictly progress back up the stack
1327 * (towards higher addresses).
1328 */
1329 if (tail >= buftail.fp)
1330 return NULL;
1331
1332 return buftail.fp;
1333}
1334
1335void perf_callchain_user(struct perf_callchain_entry *entry,
1336 struct pt_regs *regs)
1337{
1338 struct frame_tail __user *tail;
1339
1340 tail = (struct frame_tail __user *)regs->regs[29];
1341
1342 while (entry->nr < PERF_MAX_STACK_DEPTH &&
1343 tail && !((unsigned long)tail & 0xf))
1344 tail = user_backtrace(tail, entry);
1345}
1346
1347/*
1348 * Gets called by walk_stackframe() for every stackframe. This will be called
1349 * whist unwinding the stackframe and is like a subroutine return so we use
1350 * the PC.
1351 */
1352static int callchain_trace(struct stackframe *frame, void *data)
1353{
1354 struct perf_callchain_entry *entry = data;
1355 perf_callchain_store(entry, frame->pc);
1356 return 0;
1357}
1358
1359void perf_callchain_kernel(struct perf_callchain_entry *entry,
1360 struct pt_regs *regs)
1361{
1362 struct stackframe frame;
1363
1364 frame.fp = regs->regs[29];
1365 frame.sp = regs->sp;
1366 frame.pc = regs->pc;
1367 walk_stackframe(&frame, callchain_trace, entry);
1368}
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
new file mode 100644
index 000000000000..f22965ea1cfc
--- /dev/null
+++ b/arch/arm64/kernel/process.c
@@ -0,0 +1,408 @@
1/*
2 * Based on arch/arm/kernel/process.c
3 *
4 * Original Copyright (C) 1995 Linus Torvalds
5 * Copyright (C) 1996-2000 Russell King - Converted to ARM.
6 * Copyright (C) 2012 ARM Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <stdarg.h>
22
23#include <linux/export.h>
24#include <linux/sched.h>
25#include <linux/kernel.h>
26#include <linux/mm.h>
27#include <linux/stddef.h>
28#include <linux/unistd.h>
29#include <linux/user.h>
30#include <linux/delay.h>
31#include <linux/reboot.h>
32#include <linux/interrupt.h>
33#include <linux/kallsyms.h>
34#include <linux/init.h>
35#include <linux/cpu.h>
36#include <linux/elfcore.h>
37#include <linux/pm.h>
38#include <linux/tick.h>
39#include <linux/utsname.h>
40#include <linux/uaccess.h>
41#include <linux/random.h>
42#include <linux/hw_breakpoint.h>
43#include <linux/personality.h>
44#include <linux/notifier.h>
45
46#include <asm/compat.h>
47#include <asm/cacheflush.h>
48#include <asm/processor.h>
49#include <asm/stacktrace.h>
50#include <asm/fpsimd.h>
51
52static void setup_restart(void)
53{
54 /*
55 * Tell the mm system that we are going to reboot -
56 * we may need it to insert some 1:1 mappings so that
57 * soft boot works.
58 */
59 setup_mm_for_reboot();
60
61 /* Clean and invalidate caches */
62 flush_cache_all();
63
64 /* Turn D-cache off */
65 cpu_cache_off();
66
67 /* Push out any further dirty data, and ensure cache is empty */
68 flush_cache_all();
69}
70
71void soft_restart(unsigned long addr)
72{
73 setup_restart();
74 cpu_reset(addr);
75}
76
77/*
78 * Function pointers to optional machine specific functions
79 */
80void (*pm_power_off)(void);
81EXPORT_SYMBOL_GPL(pm_power_off);
82
83void (*pm_restart)(const char *cmd);
84EXPORT_SYMBOL_GPL(pm_restart);
85
86
87/*
88 * This is our default idle handler.
89 */
90static void default_idle(void)
91{
92 /*
93 * This should do all the clock switching and wait for interrupt
94 * tricks
95 */
96 cpu_do_idle();
97 local_irq_enable();
98}
99
100void (*pm_idle)(void) = default_idle;
101EXPORT_SYMBOL_GPL(pm_idle);
102
103/*
104 * The idle thread, has rather strange semantics for calling pm_idle,
105 * but this is what x86 does and we need to do the same, so that
106 * things like cpuidle get called in the same way. The only difference
107 * is that we always respect 'hlt_counter' to prevent low power idle.
108 */
109void cpu_idle(void)
110{
111 local_fiq_enable();
112
113 /* endless idle loop with no priority at all */
114 while (1) {
115 tick_nohz_idle_enter();
116 rcu_idle_enter();
117 while (!need_resched()) {
118 /*
119 * We need to disable interrupts here to ensure
120 * we don't miss a wakeup call.
121 */
122 local_irq_disable();
123 if (!need_resched()) {
124 stop_critical_timings();
125 pm_idle();
126 start_critical_timings();
127 /*
128 * pm_idle functions should always return
129 * with IRQs enabled.
130 */
131 WARN_ON(irqs_disabled());
132 } else {
133 local_irq_enable();
134 }
135 }
136 rcu_idle_exit();
137 tick_nohz_idle_exit();
138 schedule_preempt_disabled();
139 }
140}
141
142void machine_shutdown(void)
143{
144#ifdef CONFIG_SMP
145 smp_send_stop();
146#endif
147}
148
149void machine_halt(void)
150{
151 machine_shutdown();
152 while (1);
153}
154
155void machine_power_off(void)
156{
157 machine_shutdown();
158 if (pm_power_off)
159 pm_power_off();
160}
161
162void machine_restart(char *cmd)
163{
164 machine_shutdown();
165
166 /* Disable interrupts first */
167 local_irq_disable();
168 local_fiq_disable();
169
170 /* Now call the architecture specific reboot code. */
171 if (pm_restart)
172 pm_restart(cmd);
173
174 /*
175 * Whoops - the architecture was unable to reboot.
176 */
177 printk("Reboot failed -- System halted\n");
178 while (1);
179}
180
181void __show_regs(struct pt_regs *regs)
182{
183 int i;
184
185 printk("CPU: %d %s (%s %.*s)\n",
186 raw_smp_processor_id(), print_tainted(),
187 init_utsname()->release,
188 (int)strcspn(init_utsname()->version, " "),
189 init_utsname()->version);
190 print_symbol("PC is at %s\n", instruction_pointer(regs));
191 print_symbol("LR is at %s\n", regs->regs[30]);
192 printk("pc : [<%016llx>] lr : [<%016llx>] pstate: %08llx\n",
193 regs->pc, regs->regs[30], regs->pstate);
194 printk("sp : %016llx\n", regs->sp);
195 for (i = 29; i >= 0; i--) {
196 printk("x%-2d: %016llx ", i, regs->regs[i]);
197 if (i % 2 == 0)
198 printk("\n");
199 }
200 printk("\n");
201}
202
203void show_regs(struct pt_regs * regs)
204{
205 printk("\n");
206 printk("Pid: %d, comm: %20s\n", task_pid_nr(current), current->comm);
207 __show_regs(regs);
208}
209
210/*
211 * Free current thread data structures etc..
212 */
213void exit_thread(void)
214{
215}
216
217void flush_thread(void)
218{
219 fpsimd_flush_thread();
220 flush_ptrace_hw_breakpoint(current);
221}
222
223void release_thread(struct task_struct *dead_task)
224{
225}
226
227int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
228{
229 fpsimd_save_state(&current->thread.fpsimd_state);
230 *dst = *src;
231 return 0;
232}
233
234asmlinkage void ret_from_fork(void) asm("ret_from_fork");
235
236int copy_thread(unsigned long clone_flags, unsigned long stack_start,
237 unsigned long stk_sz, struct task_struct *p,
238 struct pt_regs *regs)
239{
240 struct pt_regs *childregs = task_pt_regs(p);
241 unsigned long tls = p->thread.tp_value;
242
243 *childregs = *regs;
244 childregs->regs[0] = 0;
245
246 if (is_compat_thread(task_thread_info(p)))
247 childregs->compat_sp = stack_start;
248 else {
249 /*
250 * Read the current TLS pointer from tpidr_el0 as it may be
251 * out-of-sync with the saved value.
252 */
253 asm("mrs %0, tpidr_el0" : "=r" (tls));
254 childregs->sp = stack_start;
255 }
256
257 memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context));
258 p->thread.cpu_context.sp = (unsigned long)childregs;
259 p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
260
261 /* If a TLS pointer was passed to clone, use that for the new thread. */
262 if (clone_flags & CLONE_SETTLS)
263 tls = regs->regs[3];
264 p->thread.tp_value = tls;
265
266 ptrace_hw_copy_thread(p);
267
268 return 0;
269}
270
271static void tls_thread_switch(struct task_struct *next)
272{
273 unsigned long tpidr, tpidrro;
274
275 if (!is_compat_task()) {
276 asm("mrs %0, tpidr_el0" : "=r" (tpidr));
277 current->thread.tp_value = tpidr;
278 }
279
280 if (is_compat_thread(task_thread_info(next))) {
281 tpidr = 0;
282 tpidrro = next->thread.tp_value;
283 } else {
284 tpidr = next->thread.tp_value;
285 tpidrro = 0;
286 }
287
288 asm(
289 " msr tpidr_el0, %0\n"
290 " msr tpidrro_el0, %1"
291 : : "r" (tpidr), "r" (tpidrro));
292}
293
294/*
295 * Thread switching.
296 */
297struct task_struct *__switch_to(struct task_struct *prev,
298 struct task_struct *next)
299{
300 struct task_struct *last;
301
302 fpsimd_thread_switch(next);
303 tls_thread_switch(next);
304 hw_breakpoint_thread_switch(next);
305
306 /* the actual thread switch */
307 last = cpu_switch_to(prev, next);
308
309 return last;
310}
311
312/*
313 * Fill in the task's elfregs structure for a core dump.
314 */
315int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs)
316{
317 elf_core_copy_regs(elfregs, task_pt_regs(t));
318 return 1;
319}
320
321/*
322 * fill in the fpe structure for a core dump...
323 */
324int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
325{
326 return 0;
327}
328EXPORT_SYMBOL(dump_fpu);
329
330/*
331 * Shuffle the argument into the correct register before calling the
332 * thread function. x1 is the thread argument, x2 is the pointer to
333 * the thread function, and x3 points to the exit function.
334 */
335extern void kernel_thread_helper(void);
336asm( ".section .text\n"
337" .align\n"
338" .type kernel_thread_helper, #function\n"
339"kernel_thread_helper:\n"
340" mov x0, x1\n"
341" mov x30, x3\n"
342" br x2\n"
343" .size kernel_thread_helper, . - kernel_thread_helper\n"
344" .previous");
345
346#define kernel_thread_exit do_exit
347
348/*
349 * Create a kernel thread.
350 */
351pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
352{
353 struct pt_regs regs;
354
355 memset(&regs, 0, sizeof(regs));
356
357 regs.regs[1] = (unsigned long)arg;
358 regs.regs[2] = (unsigned long)fn;
359 regs.regs[3] = (unsigned long)kernel_thread_exit;
360 regs.pc = (unsigned long)kernel_thread_helper;
361 regs.pstate = PSR_MODE_EL1h;
362
363 return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
364}
365EXPORT_SYMBOL(kernel_thread);
366
367unsigned long get_wchan(struct task_struct *p)
368{
369 struct stackframe frame;
370 int count = 0;
371 if (!p || p == current || p->state == TASK_RUNNING)
372 return 0;
373
374 frame.fp = thread_saved_fp(p);
375 frame.sp = thread_saved_sp(p);
376 frame.pc = thread_saved_pc(p);
377 do {
378 int ret = unwind_frame(&frame);
379 if (ret < 0)
380 return 0;
381 if (!in_sched_functions(frame.pc))
382 return frame.pc;
383 } while (count ++ < 16);
384 return 0;
385}
386
387unsigned long arch_align_stack(unsigned long sp)
388{
389 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
390 sp -= get_random_int() & ~PAGE_MASK;
391 return sp & ~0xf;
392}
393
394static unsigned long randomize_base(unsigned long base)
395{
396 unsigned long range_end = base + (STACK_RND_MASK << PAGE_SHIFT) + 1;
397 return randomize_range(base, range_end, 0) ? : base;
398}
399
400unsigned long arch_randomize_brk(struct mm_struct *mm)
401{
402 return randomize_base(mm->brk);
403}
404
405unsigned long randomize_et_dyn(unsigned long base)
406{
407 return randomize_base(base);
408}
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
new file mode 100644
index 000000000000..ac3550ecc7b5
--- /dev/null
+++ b/arch/arm64/kernel/ptrace.c
@@ -0,0 +1,1126 @@
1/*
2 * Based on arch/arm/kernel/ptrace.c
3 *
4 * By Ross Biro 1/23/92
5 * edited by Linus Torvalds
6 * ARM modifications Copyright (C) 2000 Russell King
7 * Copyright (C) 2012 ARM Ltd.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <linux/kernel.h>
23#include <linux/sched.h>
24#include <linux/mm.h>
25#include <linux/smp.h>
26#include <linux/ptrace.h>
27#include <linux/user.h>
28#include <linux/security.h>
29#include <linux/init.h>
30#include <linux/signal.h>
31#include <linux/uaccess.h>
32#include <linux/perf_event.h>
33#include <linux/hw_breakpoint.h>
34#include <linux/regset.h>
35#include <linux/tracehook.h>
36#include <linux/elf.h>
37
38#include <asm/compat.h>
39#include <asm/debug-monitors.h>
40#include <asm/pgtable.h>
41#include <asm/traps.h>
42#include <asm/system_misc.h>
43
44/*
45 * TODO: does not yet catch signals sent when the child dies.
46 * in exit.c or in signal.c.
47 */
48
49/*
50 * Called by kernel/ptrace.c when detaching..
51 */
52void ptrace_disable(struct task_struct *child)
53{
54}
55
56/*
57 * Handle hitting a breakpoint.
58 */
59static int ptrace_break(struct pt_regs *regs)
60{
61 siginfo_t info = {
62 .si_signo = SIGTRAP,
63 .si_errno = 0,
64 .si_code = TRAP_BRKPT,
65 .si_addr = (void __user *)instruction_pointer(regs),
66 };
67
68 force_sig_info(SIGTRAP, &info, current);
69 return 0;
70}
71
72static int arm64_break_trap(unsigned long addr, unsigned int esr,
73 struct pt_regs *regs)
74{
75 return ptrace_break(regs);
76}
77
78#ifdef CONFIG_HAVE_HW_BREAKPOINT
79/*
80 * Handle hitting a HW-breakpoint.
81 */
82static void ptrace_hbptriggered(struct perf_event *bp,
83 struct perf_sample_data *data,
84 struct pt_regs *regs)
85{
86 struct arch_hw_breakpoint *bkpt = counter_arch_bp(bp);
87 siginfo_t info = {
88 .si_signo = SIGTRAP,
89 .si_errno = 0,
90 .si_code = TRAP_HWBKPT,
91 .si_addr = (void __user *)(bkpt->trigger),
92 };
93
94#ifdef CONFIG_COMPAT
95 int i;
96
97 if (!is_compat_task())
98 goto send_sig;
99
100 for (i = 0; i < ARM_MAX_BRP; ++i) {
101 if (current->thread.debug.hbp_break[i] == bp) {
102 info.si_errno = (i << 1) + 1;
103 break;
104 }
105 }
106 for (i = ARM_MAX_BRP; i < ARM_MAX_HBP_SLOTS && !bp; ++i) {
107 if (current->thread.debug.hbp_watch[i] == bp) {
108 info.si_errno = -((i << 1) + 1);
109 break;
110 }
111 }
112
113send_sig:
114#endif
115 force_sig_info(SIGTRAP, &info, current);
116}
117
118/*
119 * Unregister breakpoints from this task and reset the pointers in
120 * the thread_struct.
121 */
122void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
123{
124 int i;
125 struct thread_struct *t = &tsk->thread;
126
127 for (i = 0; i < ARM_MAX_BRP; i++) {
128 if (t->debug.hbp_break[i]) {
129 unregister_hw_breakpoint(t->debug.hbp_break[i]);
130 t->debug.hbp_break[i] = NULL;
131 }
132 }
133
134 for (i = 0; i < ARM_MAX_WRP; i++) {
135 if (t->debug.hbp_watch[i]) {
136 unregister_hw_breakpoint(t->debug.hbp_watch[i]);
137 t->debug.hbp_watch[i] = NULL;
138 }
139 }
140}
141
142void ptrace_hw_copy_thread(struct task_struct *tsk)
143{
144 memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
145}
146
147static struct perf_event *ptrace_hbp_get_event(unsigned int note_type,
148 struct task_struct *tsk,
149 unsigned long idx)
150{
151 struct perf_event *bp = ERR_PTR(-EINVAL);
152
153 switch (note_type) {
154 case NT_ARM_HW_BREAK:
155 if (idx < ARM_MAX_BRP)
156 bp = tsk->thread.debug.hbp_break[idx];
157 break;
158 case NT_ARM_HW_WATCH:
159 if (idx < ARM_MAX_WRP)
160 bp = tsk->thread.debug.hbp_watch[idx];
161 break;
162 }
163
164 return bp;
165}
166
167static int ptrace_hbp_set_event(unsigned int note_type,
168 struct task_struct *tsk,
169 unsigned long idx,
170 struct perf_event *bp)
171{
172 int err = -EINVAL;
173
174 switch (note_type) {
175 case NT_ARM_HW_BREAK:
176 if (idx < ARM_MAX_BRP) {
177 tsk->thread.debug.hbp_break[idx] = bp;
178 err = 0;
179 }
180 break;
181 case NT_ARM_HW_WATCH:
182 if (idx < ARM_MAX_WRP) {
183 tsk->thread.debug.hbp_watch[idx] = bp;
184 err = 0;
185 }
186 break;
187 }
188
189 return err;
190}
191
192static struct perf_event *ptrace_hbp_create(unsigned int note_type,
193 struct task_struct *tsk,
194 unsigned long idx)
195{
196 struct perf_event *bp;
197 struct perf_event_attr attr;
198 int err, type;
199
200 switch (note_type) {
201 case NT_ARM_HW_BREAK:
202 type = HW_BREAKPOINT_X;
203 break;
204 case NT_ARM_HW_WATCH:
205 type = HW_BREAKPOINT_RW;
206 break;
207 default:
208 return ERR_PTR(-EINVAL);
209 }
210
211 ptrace_breakpoint_init(&attr);
212
213 /*
214 * Initialise fields to sane defaults
215 * (i.e. values that will pass validation).
216 */
217 attr.bp_addr = 0;
218 attr.bp_len = HW_BREAKPOINT_LEN_4;
219 attr.bp_type = type;
220 attr.disabled = 1;
221
222 bp = register_user_hw_breakpoint(&attr, ptrace_hbptriggered, NULL, tsk);
223 if (IS_ERR(bp))
224 return bp;
225
226 err = ptrace_hbp_set_event(note_type, tsk, idx, bp);
227 if (err)
228 return ERR_PTR(err);
229
230 return bp;
231}
232
233static int ptrace_hbp_fill_attr_ctrl(unsigned int note_type,
234 struct arch_hw_breakpoint_ctrl ctrl,
235 struct perf_event_attr *attr)
236{
237 int err, len, type;
238
239 err = arch_bp_generic_fields(ctrl, &len, &type);
240 if (err)
241 return err;
242
243 switch (note_type) {
244 case NT_ARM_HW_BREAK:
245 if ((type & HW_BREAKPOINT_X) != type)
246 return -EINVAL;
247 break;
248 case NT_ARM_HW_WATCH:
249 if ((type & HW_BREAKPOINT_RW) != type)
250 return -EINVAL;
251 break;
252 default:
253 return -EINVAL;
254 }
255
256 attr->bp_len = len;
257 attr->bp_type = type;
258 attr->disabled = !ctrl.enabled;
259
260 return 0;
261}
262
263static int ptrace_hbp_get_resource_info(unsigned int note_type, u32 *info)
264{
265 u8 num;
266 u32 reg = 0;
267
268 switch (note_type) {
269 case NT_ARM_HW_BREAK:
270 num = hw_breakpoint_slots(TYPE_INST);
271 break;
272 case NT_ARM_HW_WATCH:
273 num = hw_breakpoint_slots(TYPE_DATA);
274 break;
275 default:
276 return -EINVAL;
277 }
278
279 reg |= debug_monitors_arch();
280 reg <<= 8;
281 reg |= num;
282
283 *info = reg;
284 return 0;
285}
286
287static int ptrace_hbp_get_ctrl(unsigned int note_type,
288 struct task_struct *tsk,
289 unsigned long idx,
290 u32 *ctrl)
291{
292 struct perf_event *bp = ptrace_hbp_get_event(note_type, tsk, idx);
293
294 if (IS_ERR(bp))
295 return PTR_ERR(bp);
296
297 *ctrl = bp ? encode_ctrl_reg(counter_arch_bp(bp)->ctrl) : 0;
298 return 0;
299}
300
301static int ptrace_hbp_get_addr(unsigned int note_type,
302 struct task_struct *tsk,
303 unsigned long idx,
304 u64 *addr)
305{
306 struct perf_event *bp = ptrace_hbp_get_event(note_type, tsk, idx);
307
308 if (IS_ERR(bp))
309 return PTR_ERR(bp);
310
311 *addr = bp ? bp->attr.bp_addr : 0;
312 return 0;
313}
314
315static struct perf_event *ptrace_hbp_get_initialised_bp(unsigned int note_type,
316 struct task_struct *tsk,
317 unsigned long idx)
318{
319 struct perf_event *bp = ptrace_hbp_get_event(note_type, tsk, idx);
320
321 if (!bp)
322 bp = ptrace_hbp_create(note_type, tsk, idx);
323
324 return bp;
325}
326
327static int ptrace_hbp_set_ctrl(unsigned int note_type,
328 struct task_struct *tsk,
329 unsigned long idx,
330 u32 uctrl)
331{
332 int err;
333 struct perf_event *bp;
334 struct perf_event_attr attr;
335 struct arch_hw_breakpoint_ctrl ctrl;
336
337 bp = ptrace_hbp_get_initialised_bp(note_type, tsk, idx);
338 if (IS_ERR(bp)) {
339 err = PTR_ERR(bp);
340 return err;
341 }
342
343 attr = bp->attr;
344 decode_ctrl_reg(uctrl, &ctrl);
345 err = ptrace_hbp_fill_attr_ctrl(note_type, ctrl, &attr);
346 if (err)
347 return err;
348
349 return modify_user_hw_breakpoint(bp, &attr);
350}
351
352static int ptrace_hbp_set_addr(unsigned int note_type,
353 struct task_struct *tsk,
354 unsigned long idx,
355 u64 addr)
356{
357 int err;
358 struct perf_event *bp;
359 struct perf_event_attr attr;
360
361 bp = ptrace_hbp_get_initialised_bp(note_type, tsk, idx);
362 if (IS_ERR(bp)) {
363 err = PTR_ERR(bp);
364 return err;
365 }
366
367 attr = bp->attr;
368 attr.bp_addr = addr;
369 err = modify_user_hw_breakpoint(bp, &attr);
370 return err;
371}
372
373#define PTRACE_HBP_ADDR_SZ sizeof(u64)
374#define PTRACE_HBP_CTRL_SZ sizeof(u32)
375#define PTRACE_HBP_REG_OFF sizeof(u32)
376
377static int hw_break_get(struct task_struct *target,
378 const struct user_regset *regset,
379 unsigned int pos, unsigned int count,
380 void *kbuf, void __user *ubuf)
381{
382 unsigned int note_type = regset->core_note_type;
383 int ret, idx = 0, offset = PTRACE_HBP_REG_OFF, limit;
384 u32 info, ctrl;
385 u64 addr;
386
387 /* Resource info */
388 ret = ptrace_hbp_get_resource_info(note_type, &info);
389 if (ret)
390 return ret;
391
392 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &info, 0, 4);
393 if (ret)
394 return ret;
395
396 /* (address, ctrl) registers */
397 limit = regset->n * regset->size;
398 while (count && offset < limit) {
399 ret = ptrace_hbp_get_addr(note_type, target, idx, &addr);
400 if (ret)
401 return ret;
402 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &addr,
403 offset, offset + PTRACE_HBP_ADDR_SZ);
404 if (ret)
405 return ret;
406 offset += PTRACE_HBP_ADDR_SZ;
407
408 ret = ptrace_hbp_get_ctrl(note_type, target, idx, &ctrl);
409 if (ret)
410 return ret;
411 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &ctrl,
412 offset, offset + PTRACE_HBP_CTRL_SZ);
413 if (ret)
414 return ret;
415 offset += PTRACE_HBP_CTRL_SZ;
416 idx++;
417 }
418
419 return 0;
420}
421
422static int hw_break_set(struct task_struct *target,
423 const struct user_regset *regset,
424 unsigned int pos, unsigned int count,
425 const void *kbuf, const void __user *ubuf)
426{
427 unsigned int note_type = regset->core_note_type;
428 int ret, idx = 0, offset = PTRACE_HBP_REG_OFF, limit;
429 u32 ctrl;
430 u64 addr;
431
432 /* Resource info */
433 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, 4);
434 if (ret)
435 return ret;
436
437 /* (address, ctrl) registers */
438 limit = regset->n * regset->size;
439 while (count && offset < limit) {
440 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &addr,
441 offset, offset + PTRACE_HBP_ADDR_SZ);
442 if (ret)
443 return ret;
444 ret = ptrace_hbp_set_addr(note_type, target, idx, addr);
445 if (ret)
446 return ret;
447 offset += PTRACE_HBP_ADDR_SZ;
448
449 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ctrl,
450 offset, offset + PTRACE_HBP_CTRL_SZ);
451 if (ret)
452 return ret;
453 ret = ptrace_hbp_set_ctrl(note_type, target, idx, ctrl);
454 if (ret)
455 return ret;
456 offset += PTRACE_HBP_CTRL_SZ;
457 idx++;
458 }
459
460 return 0;
461}
462#endif /* CONFIG_HAVE_HW_BREAKPOINT */
463
464static int gpr_get(struct task_struct *target,
465 const struct user_regset *regset,
466 unsigned int pos, unsigned int count,
467 void *kbuf, void __user *ubuf)
468{
469 struct user_pt_regs *uregs = &task_pt_regs(target)->user_regs;
470 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0, -1);
471}
472
473static int gpr_set(struct task_struct *target, const struct user_regset *regset,
474 unsigned int pos, unsigned int count,
475 const void *kbuf, const void __user *ubuf)
476{
477 int ret;
478 struct user_pt_regs newregs;
479
480 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newregs, 0, -1);
481 if (ret)
482 return ret;
483
484 if (!valid_user_regs(&newregs))
485 return -EINVAL;
486
487 task_pt_regs(target)->user_regs = newregs;
488 return 0;
489}
490
491/*
492 * TODO: update fp accessors for lazy context switching (sync/flush hwstate)
493 */
494static int fpr_get(struct task_struct *target, const struct user_regset *regset,
495 unsigned int pos, unsigned int count,
496 void *kbuf, void __user *ubuf)
497{
498 struct user_fpsimd_state *uregs;
499 uregs = &target->thread.fpsimd_state.user_fpsimd;
500 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0, -1);
501}
502
503static int fpr_set(struct task_struct *target, const struct user_regset *regset,
504 unsigned int pos, unsigned int count,
505 const void *kbuf, const void __user *ubuf)
506{
507 int ret;
508 struct user_fpsimd_state newstate;
509
510 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newstate, 0, -1);
511 if (ret)
512 return ret;
513
514 target->thread.fpsimd_state.user_fpsimd = newstate;
515 return ret;
516}
517
518static int tls_get(struct task_struct *target, const struct user_regset *regset,
519 unsigned int pos, unsigned int count,
520 void *kbuf, void __user *ubuf)
521{
522 unsigned long *tls = &target->thread.tp_value;
523 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, tls, 0, -1);
524}
525
526static int tls_set(struct task_struct *target, const struct user_regset *regset,
527 unsigned int pos, unsigned int count,
528 const void *kbuf, const void __user *ubuf)
529{
530 int ret;
531 unsigned long tls;
532
533 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &tls, 0, -1);
534 if (ret)
535 return ret;
536
537 target->thread.tp_value = tls;
538 return ret;
539}
540
541enum aarch64_regset {
542 REGSET_GPR,
543 REGSET_FPR,
544 REGSET_TLS,
545#ifdef CONFIG_HAVE_HW_BREAKPOINT
546 REGSET_HW_BREAK,
547 REGSET_HW_WATCH,
548#endif
549};
550
551static const struct user_regset aarch64_regsets[] = {
552 [REGSET_GPR] = {
553 .core_note_type = NT_PRSTATUS,
554 .n = sizeof(struct user_pt_regs) / sizeof(u64),
555 .size = sizeof(u64),
556 .align = sizeof(u64),
557 .get = gpr_get,
558 .set = gpr_set
559 },
560 [REGSET_FPR] = {
561 .core_note_type = NT_PRFPREG,
562 .n = sizeof(struct user_fpsimd_state) / sizeof(u32),
563 /*
564 * We pretend we have 32-bit registers because the fpsr and
565 * fpcr are 32-bits wide.
566 */
567 .size = sizeof(u32),
568 .align = sizeof(u32),
569 .get = fpr_get,
570 .set = fpr_set
571 },
572 [REGSET_TLS] = {
573 .core_note_type = NT_ARM_TLS,
574 .n = 1,
575 .size = sizeof(void *),
576 .align = sizeof(void *),
577 .get = tls_get,
578 .set = tls_set,
579 },
580#ifdef CONFIG_HAVE_HW_BREAKPOINT
581 [REGSET_HW_BREAK] = {
582 .core_note_type = NT_ARM_HW_BREAK,
583 .n = sizeof(struct user_hwdebug_state) / sizeof(u32),
584 .size = sizeof(u32),
585 .align = sizeof(u32),
586 .get = hw_break_get,
587 .set = hw_break_set,
588 },
589 [REGSET_HW_WATCH] = {
590 .core_note_type = NT_ARM_HW_WATCH,
591 .n = sizeof(struct user_hwdebug_state) / sizeof(u32),
592 .size = sizeof(u32),
593 .align = sizeof(u32),
594 .get = hw_break_get,
595 .set = hw_break_set,
596 },
597#endif
598};
599
600static const struct user_regset_view user_aarch64_view = {
601 .name = "aarch64", .e_machine = EM_AARCH64,
602 .regsets = aarch64_regsets, .n = ARRAY_SIZE(aarch64_regsets)
603};
604
605#ifdef CONFIG_COMPAT
606#include <linux/compat.h>
607
608enum compat_regset {
609 REGSET_COMPAT_GPR,
610 REGSET_COMPAT_VFP,
611};
612
613static int compat_gpr_get(struct task_struct *target,
614 const struct user_regset *regset,
615 unsigned int pos, unsigned int count,
616 void *kbuf, void __user *ubuf)
617{
618 int ret = 0;
619 unsigned int i, start, num_regs;
620
621 /* Calculate the number of AArch32 registers contained in count */
622 num_regs = count / regset->size;
623
624 /* Convert pos into an register number */
625 start = pos / regset->size;
626
627 if (start + num_regs > regset->n)
628 return -EIO;
629
630 for (i = 0; i < num_regs; ++i) {
631 unsigned int idx = start + i;
632 void *reg;
633
634 switch (idx) {
635 case 15:
636 reg = (void *)&task_pt_regs(target)->pc;
637 break;
638 case 16:
639 reg = (void *)&task_pt_regs(target)->pstate;
640 break;
641 case 17:
642 reg = (void *)&task_pt_regs(target)->orig_x0;
643 break;
644 default:
645 reg = (void *)&task_pt_regs(target)->regs[idx];
646 }
647
648 ret = copy_to_user(ubuf, reg, sizeof(compat_ulong_t));
649
650 if (ret)
651 break;
652 else
653 ubuf += sizeof(compat_ulong_t);
654 }
655
656 return ret;
657}
658
659static int compat_gpr_set(struct task_struct *target,
660 const struct user_regset *regset,
661 unsigned int pos, unsigned int count,
662 const void *kbuf, const void __user *ubuf)
663{
664 struct pt_regs newregs;
665 int ret = 0;
666 unsigned int i, start, num_regs;
667
668 /* Calculate the number of AArch32 registers contained in count */
669 num_regs = count / regset->size;
670
671 /* Convert pos into an register number */
672 start = pos / regset->size;
673
674 if (start + num_regs > regset->n)
675 return -EIO;
676
677 newregs = *task_pt_regs(target);
678
679 for (i = 0; i < num_regs; ++i) {
680 unsigned int idx = start + i;
681 void *reg;
682
683 switch (idx) {
684 case 15:
685 reg = (void *)&newregs.pc;
686 break;
687 case 16:
688 reg = (void *)&newregs.pstate;
689 break;
690 case 17:
691 reg = (void *)&newregs.orig_x0;
692 break;
693 default:
694 reg = (void *)&newregs.regs[idx];
695 }
696
697 ret = copy_from_user(reg, ubuf, sizeof(compat_ulong_t));
698
699 if (ret)
700 goto out;
701 else
702 ubuf += sizeof(compat_ulong_t);
703 }
704
705 if (valid_user_regs(&newregs.user_regs))
706 *task_pt_regs(target) = newregs;
707 else
708 ret = -EINVAL;
709
710out:
711 return ret;
712}
713
714static int compat_vfp_get(struct task_struct *target,
715 const struct user_regset *regset,
716 unsigned int pos, unsigned int count,
717 void *kbuf, void __user *ubuf)
718{
719 struct user_fpsimd_state *uregs;
720 compat_ulong_t fpscr;
721 int ret;
722
723 uregs = &target->thread.fpsimd_state.user_fpsimd;
724
725 /*
726 * The VFP registers are packed into the fpsimd_state, so they all sit
727 * nicely together for us. We just need to create the fpscr separately.
728 */
729 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0,
730 VFP_STATE_SIZE - sizeof(compat_ulong_t));
731
732 if (count && !ret) {
733 fpscr = (uregs->fpsr & VFP_FPSCR_STAT_MASK) |
734 (uregs->fpcr & VFP_FPSCR_CTRL_MASK);
735 ret = put_user(fpscr, (compat_ulong_t *)ubuf);
736 }
737
738 return ret;
739}
740
741static int compat_vfp_set(struct task_struct *target,
742 const struct user_regset *regset,
743 unsigned int pos, unsigned int count,
744 const void *kbuf, const void __user *ubuf)
745{
746 struct user_fpsimd_state *uregs;
747 compat_ulong_t fpscr;
748 int ret;
749
750 if (pos + count > VFP_STATE_SIZE)
751 return -EIO;
752
753 uregs = &target->thread.fpsimd_state.user_fpsimd;
754
755 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 0,
756 VFP_STATE_SIZE - sizeof(compat_ulong_t));
757
758 if (count && !ret) {
759 ret = get_user(fpscr, (compat_ulong_t *)ubuf);
760 uregs->fpsr = fpscr & VFP_FPSCR_STAT_MASK;
761 uregs->fpcr = fpscr & VFP_FPSCR_CTRL_MASK;
762 }
763
764 return ret;
765}
766
767static const struct user_regset aarch32_regsets[] = {
768 [REGSET_COMPAT_GPR] = {
769 .core_note_type = NT_PRSTATUS,
770 .n = COMPAT_ELF_NGREG,
771 .size = sizeof(compat_elf_greg_t),
772 .align = sizeof(compat_elf_greg_t),
773 .get = compat_gpr_get,
774 .set = compat_gpr_set
775 },
776 [REGSET_COMPAT_VFP] = {
777 .core_note_type = NT_ARM_VFP,
778 .n = VFP_STATE_SIZE / sizeof(compat_ulong_t),
779 .size = sizeof(compat_ulong_t),
780 .align = sizeof(compat_ulong_t),
781 .get = compat_vfp_get,
782 .set = compat_vfp_set
783 },
784};
785
786static const struct user_regset_view user_aarch32_view = {
787 .name = "aarch32", .e_machine = EM_ARM,
788 .regsets = aarch32_regsets, .n = ARRAY_SIZE(aarch32_regsets)
789};
790
791int aarch32_break_trap(struct pt_regs *regs)
792{
793 unsigned int instr;
794 bool bp = false;
795 void __user *pc = (void __user *)instruction_pointer(regs);
796
797 if (compat_thumb_mode(regs)) {
798 /* get 16-bit Thumb instruction */
799 get_user(instr, (u16 __user *)pc);
800 if (instr == AARCH32_BREAK_THUMB2_LO) {
801 /* get second half of 32-bit Thumb-2 instruction */
802 get_user(instr, (u16 __user *)(pc + 2));
803 bp = instr == AARCH32_BREAK_THUMB2_HI;
804 } else {
805 bp = instr == AARCH32_BREAK_THUMB;
806 }
807 } else {
808 /* 32-bit ARM instruction */
809 get_user(instr, (u32 __user *)pc);
810 bp = (instr & ~0xf0000000) == AARCH32_BREAK_ARM;
811 }
812
813 if (bp)
814 return ptrace_break(regs);
815 return 1;
816}
817
818static int compat_ptrace_read_user(struct task_struct *tsk, compat_ulong_t off,
819 compat_ulong_t __user *ret)
820{
821 compat_ulong_t tmp;
822
823 if (off & 3)
824 return -EIO;
825
826 if (off == PT_TEXT_ADDR)
827 tmp = tsk->mm->start_code;
828 else if (off == PT_DATA_ADDR)
829 tmp = tsk->mm->start_data;
830 else if (off == PT_TEXT_END_ADDR)
831 tmp = tsk->mm->end_code;
832 else if (off < sizeof(compat_elf_gregset_t))
833 return copy_regset_to_user(tsk, &user_aarch32_view,
834 REGSET_COMPAT_GPR, off,
835 sizeof(compat_ulong_t), ret);
836 else if (off >= COMPAT_USER_SZ)
837 return -EIO;
838 else
839 tmp = 0;
840
841 return put_user(tmp, ret);
842}
843
844static int compat_ptrace_write_user(struct task_struct *tsk, compat_ulong_t off,
845 compat_ulong_t val)
846{
847 int ret;
848
849 if (off & 3 || off >= COMPAT_USER_SZ)
850 return -EIO;
851
852 if (off >= sizeof(compat_elf_gregset_t))
853 return 0;
854
855 ret = copy_regset_from_user(tsk, &user_aarch32_view,
856 REGSET_COMPAT_GPR, off,
857 sizeof(compat_ulong_t),
858 &val);
859 return ret;
860}
861
862#ifdef CONFIG_HAVE_HW_BREAKPOINT
863
864/*
865 * Convert a virtual register number into an index for a thread_info
866 * breakpoint array. Breakpoints are identified using positive numbers
867 * whilst watchpoints are negative. The registers are laid out as pairs
868 * of (address, control), each pair mapping to a unique hw_breakpoint struct.
869 * Register 0 is reserved for describing resource information.
870 */
871static int compat_ptrace_hbp_num_to_idx(compat_long_t num)
872{
873 return (abs(num) - 1) >> 1;
874}
875
876static int compat_ptrace_hbp_get_resource_info(u32 *kdata)
877{
878 u8 num_brps, num_wrps, debug_arch, wp_len;
879 u32 reg = 0;
880
881 num_brps = hw_breakpoint_slots(TYPE_INST);
882 num_wrps = hw_breakpoint_slots(TYPE_DATA);
883
884 debug_arch = debug_monitors_arch();
885 wp_len = 8;
886 reg |= debug_arch;
887 reg <<= 8;
888 reg |= wp_len;
889 reg <<= 8;
890 reg |= num_wrps;
891 reg <<= 8;
892 reg |= num_brps;
893
894 *kdata = reg;
895 return 0;
896}
897
898static int compat_ptrace_hbp_get(unsigned int note_type,
899 struct task_struct *tsk,
900 compat_long_t num,
901 u32 *kdata)
902{
903 u64 addr = 0;
904 u32 ctrl = 0;
905
906 int err, idx = compat_ptrace_hbp_num_to_idx(num);;
907
908 if (num & 1) {
909 err = ptrace_hbp_get_addr(note_type, tsk, idx, &addr);
910 *kdata = (u32)addr;
911 } else {
912 err = ptrace_hbp_get_ctrl(note_type, tsk, idx, &ctrl);
913 *kdata = ctrl;
914 }
915
916 return err;
917}
918
919static int compat_ptrace_hbp_set(unsigned int note_type,
920 struct task_struct *tsk,
921 compat_long_t num,
922 u32 *kdata)
923{
924 u64 addr;
925 u32 ctrl;
926
927 int err, idx = compat_ptrace_hbp_num_to_idx(num);
928
929 if (num & 1) {
930 addr = *kdata;
931 err = ptrace_hbp_set_addr(note_type, tsk, idx, addr);
932 } else {
933 ctrl = *kdata;
934 err = ptrace_hbp_set_ctrl(note_type, tsk, idx, ctrl);
935 }
936
937 return err;
938}
939
940static int compat_ptrace_gethbpregs(struct task_struct *tsk, compat_long_t num,
941 compat_ulong_t __user *data)
942{
943 int ret;
944 u32 kdata;
945 mm_segment_t old_fs = get_fs();
946
947 set_fs(KERNEL_DS);
948 /* Watchpoint */
949 if (num < 0) {
950 ret = compat_ptrace_hbp_get(NT_ARM_HW_WATCH, tsk, num, &kdata);
951 /* Resource info */
952 } else if (num == 0) {
953 ret = compat_ptrace_hbp_get_resource_info(&kdata);
954 /* Breakpoint */
955 } else {
956 ret = compat_ptrace_hbp_get(NT_ARM_HW_BREAK, tsk, num, &kdata);
957 }
958 set_fs(old_fs);
959
960 if (!ret)
961 ret = put_user(kdata, data);
962
963 return ret;
964}
965
966static int compat_ptrace_sethbpregs(struct task_struct *tsk, compat_long_t num,
967 compat_ulong_t __user *data)
968{
969 int ret;
970 u32 kdata = 0;
971 mm_segment_t old_fs = get_fs();
972
973 if (num == 0)
974 return 0;
975
976 ret = get_user(kdata, data);
977 if (ret)
978 return ret;
979
980 set_fs(KERNEL_DS);
981 if (num < 0)
982 ret = compat_ptrace_hbp_set(NT_ARM_HW_WATCH, tsk, num, &kdata);
983 else
984 ret = compat_ptrace_hbp_set(NT_ARM_HW_BREAK, tsk, num, &kdata);
985 set_fs(old_fs);
986
987 return ret;
988}
989#endif /* CONFIG_HAVE_HW_BREAKPOINT */
990
991long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
992 compat_ulong_t caddr, compat_ulong_t cdata)
993{
994 unsigned long addr = caddr;
995 unsigned long data = cdata;
996 void __user *datap = compat_ptr(data);
997 int ret;
998
999 switch (request) {
1000 case PTRACE_PEEKUSR:
1001 ret = compat_ptrace_read_user(child, addr, datap);
1002 break;
1003
1004 case PTRACE_POKEUSR:
1005 ret = compat_ptrace_write_user(child, addr, data);
1006 break;
1007
1008 case COMPAT_PTRACE_GETREGS:
1009 ret = copy_regset_to_user(child,
1010 &user_aarch32_view,
1011 REGSET_COMPAT_GPR,
1012 0, sizeof(compat_elf_gregset_t),
1013 datap);
1014 break;
1015
1016 case COMPAT_PTRACE_SETREGS:
1017 ret = copy_regset_from_user(child,
1018 &user_aarch32_view,
1019 REGSET_COMPAT_GPR,
1020 0, sizeof(compat_elf_gregset_t),
1021 datap);
1022 break;
1023
1024 case COMPAT_PTRACE_GET_THREAD_AREA:
1025 ret = put_user((compat_ulong_t)child->thread.tp_value,
1026 (compat_ulong_t __user *)datap);
1027 break;
1028
1029 case COMPAT_PTRACE_SET_SYSCALL:
1030 task_pt_regs(child)->syscallno = data;
1031 ret = 0;
1032 break;
1033
1034 case COMPAT_PTRACE_GETVFPREGS:
1035 ret = copy_regset_to_user(child,
1036 &user_aarch32_view,
1037 REGSET_COMPAT_VFP,
1038 0, VFP_STATE_SIZE,
1039 datap);
1040 break;
1041
1042 case COMPAT_PTRACE_SETVFPREGS:
1043 ret = copy_regset_from_user(child,
1044 &user_aarch32_view,
1045 REGSET_COMPAT_VFP,
1046 0, VFP_STATE_SIZE,
1047 datap);
1048 break;
1049
1050#ifdef CONFIG_HAVE_HW_BREAKPOINT
1051 case COMPAT_PTRACE_GETHBPREGS:
1052 ret = compat_ptrace_gethbpregs(child, addr, datap);
1053 break;
1054
1055 case COMPAT_PTRACE_SETHBPREGS:
1056 ret = compat_ptrace_sethbpregs(child, addr, datap);
1057 break;
1058#endif
1059
1060 default:
1061 ret = compat_ptrace_request(child, request, addr,
1062 data);
1063 break;
1064 }
1065
1066 return ret;
1067}
1068#endif /* CONFIG_COMPAT */
1069
1070const struct user_regset_view *task_user_regset_view(struct task_struct *task)
1071{
1072#ifdef CONFIG_COMPAT
1073 if (is_compat_thread(task_thread_info(task)))
1074 return &user_aarch32_view;
1075#endif
1076 return &user_aarch64_view;
1077}
1078
1079long arch_ptrace(struct task_struct *child, long request,
1080 unsigned long addr, unsigned long data)
1081{
1082 return ptrace_request(child, request, addr, data);
1083}
1084
1085
1086static int __init ptrace_break_init(void)
1087{
1088 hook_debug_fault_code(DBG_ESR_EVT_BRK, arm64_break_trap, SIGTRAP,
1089 TRAP_BRKPT, "ptrace BRK handler");
1090 return 0;
1091}
1092core_initcall(ptrace_break_init);
1093
1094
1095asmlinkage int syscall_trace(int dir, struct pt_regs *regs)
1096{
1097 unsigned long saved_reg;
1098
1099 if (!test_thread_flag(TIF_SYSCALL_TRACE))
1100 return regs->syscallno;
1101
1102 if (is_compat_task()) {
1103 /* AArch32 uses ip (r12) for scratch */
1104 saved_reg = regs->regs[12];
1105 regs->regs[12] = dir;
1106 } else {
1107 /*
1108 * Save X7. X7 is used to denote syscall entry/exit:
1109 * X7 = 0 -> entry, = 1 -> exit
1110 */
1111 saved_reg = regs->regs[7];
1112 regs->regs[7] = dir;
1113 }
1114
1115 if (dir)
1116 tracehook_report_syscall_exit(regs, 0);
1117 else if (tracehook_report_syscall_entry(regs))
1118 regs->syscallno = ~0UL;
1119
1120 if (is_compat_task())
1121 regs->regs[12] = saved_reg;
1122 else
1123 regs->regs[7] = saved_reg;
1124
1125 return regs->syscallno;
1126}
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
new file mode 100644
index 000000000000..48ffb9fb3fe3
--- /dev/null
+++ b/arch/arm64/kernel/setup.c
@@ -0,0 +1,347 @@
1/*
2 * Based on arch/arm/kernel/setup.c
3 *
4 * Copyright (C) 1995-2001 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/export.h>
21#include <linux/kernel.h>
22#include <linux/stddef.h>
23#include <linux/ioport.h>
24#include <linux/delay.h>
25#include <linux/utsname.h>
26#include <linux/initrd.h>
27#include <linux/console.h>
28#include <linux/bootmem.h>
29#include <linux/seq_file.h>
30#include <linux/screen_info.h>
31#include <linux/init.h>
32#include <linux/kexec.h>
33#include <linux/crash_dump.h>
34#include <linux/root_dev.h>
35#include <linux/cpu.h>
36#include <linux/interrupt.h>
37#include <linux/smp.h>
38#include <linux/fs.h>
39#include <linux/proc_fs.h>
40#include <linux/memblock.h>
41#include <linux/of_fdt.h>
42
43#include <asm/cputype.h>
44#include <asm/elf.h>
45#include <asm/cputable.h>
46#include <asm/sections.h>
47#include <asm/setup.h>
48#include <asm/cacheflush.h>
49#include <asm/tlbflush.h>
50#include <asm/traps.h>
51#include <asm/memblock.h>
52
53unsigned int processor_id;
54EXPORT_SYMBOL(processor_id);
55
56unsigned int elf_hwcap __read_mostly;
57EXPORT_SYMBOL_GPL(elf_hwcap);
58
59static const char *cpu_name;
60static const char *machine_name;
61phys_addr_t __fdt_pointer __initdata;
62
63/*
64 * Standard memory resources
65 */
66static struct resource mem_res[] = {
67 {
68 .name = "Kernel code",
69 .start = 0,
70 .end = 0,
71 .flags = IORESOURCE_MEM
72 },
73 {
74 .name = "Kernel data",
75 .start = 0,
76 .end = 0,
77 .flags = IORESOURCE_MEM
78 }
79};
80
81#define kernel_code mem_res[0]
82#define kernel_data mem_res[1]
83
84void __init early_print(const char *str, ...)
85{
86 char buf[256];
87 va_list ap;
88
89 va_start(ap, str);
90 vsnprintf(buf, sizeof(buf), str, ap);
91 va_end(ap);
92
93 printk("%s", buf);
94}
95
96static void __init setup_processor(void)
97{
98 struct cpu_info *cpu_info;
99
100 /*
101 * locate processor in the list of supported processor
102 * types. The linker builds this table for us from the
103 * entries in arch/arm/mm/proc.S
104 */
105 cpu_info = lookup_processor_type(read_cpuid_id());
106 if (!cpu_info) {
107 printk("CPU configuration botched (ID %08x), unable to continue.\n",
108 read_cpuid_id());
109 while (1);
110 }
111
112 cpu_name = cpu_info->cpu_name;
113
114 printk("CPU: %s [%08x] revision %d\n",
115 cpu_name, read_cpuid_id(), read_cpuid_id() & 15);
116
117 sprintf(init_utsname()->machine, "aarch64");
118 elf_hwcap = 0;
119}
120
121static void __init setup_machine_fdt(phys_addr_t dt_phys)
122{
123 struct boot_param_header *devtree;
124 unsigned long dt_root;
125
126 /* Check we have a non-NULL DT pointer */
127 if (!dt_phys) {
128 early_print("\n"
129 "Error: NULL or invalid device tree blob\n"
130 "The dtb must be 8-byte aligned and passed in the first 512MB of memory\n"
131 "\nPlease check your bootloader.\n");
132
133 while (true)
134 cpu_relax();
135
136 }
137
138 devtree = phys_to_virt(dt_phys);
139
140 /* Check device tree validity */
141 if (be32_to_cpu(devtree->magic) != OF_DT_HEADER) {
142 early_print("\n"
143 "Error: invalid device tree blob at physical address 0x%p (virtual address 0x%p)\n"
144 "Expected 0x%x, found 0x%x\n"
145 "\nPlease check your bootloader.\n",
146 dt_phys, devtree, OF_DT_HEADER,
147 be32_to_cpu(devtree->magic));
148
149 while (true)
150 cpu_relax();
151 }
152
153 initial_boot_params = devtree;
154 dt_root = of_get_flat_dt_root();
155
156 machine_name = of_get_flat_dt_prop(dt_root, "model", NULL);
157 if (!machine_name)
158 machine_name = of_get_flat_dt_prop(dt_root, "compatible", NULL);
159 if (!machine_name)
160 machine_name = "<unknown>";
161 pr_info("Machine: %s\n", machine_name);
162
163 /* Retrieve various information from the /chosen node */
164 of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);
165 /* Initialize {size,address}-cells info */
166 of_scan_flat_dt(early_init_dt_scan_root, NULL);
167 /* Setup memory, calling early_init_dt_add_memory_arch */
168 of_scan_flat_dt(early_init_dt_scan_memory, NULL);
169}
170
171void __init early_init_dt_add_memory_arch(u64 base, u64 size)
172{
173 size &= PAGE_MASK;
174 memblock_add(base, size);
175}
176
177void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
178{
179 return __va(memblock_alloc(size, align));
180}
181
182/*
183 * Limit the memory size that was specified via FDT.
184 */
185static int __init early_mem(char *p)
186{
187 phys_addr_t limit;
188
189 if (!p)
190 return 1;
191
192 limit = memparse(p, &p) & PAGE_MASK;
193 pr_notice("Memory limited to %lldMB\n", limit >> 20);
194
195 memblock_enforce_memory_limit(limit);
196
197 return 0;
198}
199early_param("mem", early_mem);
200
201static void __init request_standard_resources(void)
202{
203 struct memblock_region *region;
204 struct resource *res;
205
206 kernel_code.start = virt_to_phys(_text);
207 kernel_code.end = virt_to_phys(_etext - 1);
208 kernel_data.start = virt_to_phys(_sdata);
209 kernel_data.end = virt_to_phys(_end - 1);
210
211 for_each_memblock(memory, region) {
212 res = alloc_bootmem_low(sizeof(*res));
213 res->name = "System RAM";
214 res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
215 res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
216 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
217
218 request_resource(&iomem_resource, res);
219
220 if (kernel_code.start >= res->start &&
221 kernel_code.end <= res->end)
222 request_resource(res, &kernel_code);
223 if (kernel_data.start >= res->start &&
224 kernel_data.end <= res->end)
225 request_resource(res, &kernel_data);
226 }
227}
228
229void __init setup_arch(char **cmdline_p)
230{
231 setup_processor();
232
233 setup_machine_fdt(__fdt_pointer);
234
235 init_mm.start_code = (unsigned long) _text;
236 init_mm.end_code = (unsigned long) _etext;
237 init_mm.end_data = (unsigned long) _edata;
238 init_mm.brk = (unsigned long) _end;
239
240 *cmdline_p = boot_command_line;
241
242 parse_early_param();
243
244 arm64_memblock_init();
245
246 paging_init();
247 request_standard_resources();
248
249 unflatten_device_tree();
250
251#ifdef CONFIG_SMP
252 smp_init_cpus();
253#endif
254
255#ifdef CONFIG_VT
256#if defined(CONFIG_VGA_CONSOLE)
257 conswitchp = &vga_con;
258#elif defined(CONFIG_DUMMY_CONSOLE)
259 conswitchp = &dummy_con;
260#endif
261#endif
262}
263
264static DEFINE_PER_CPU(struct cpu, cpu_data);
265
266static int __init topology_init(void)
267{
268 int i;
269
270 for_each_possible_cpu(i) {
271 struct cpu *cpu = &per_cpu(cpu_data, i);
272 cpu->hotpluggable = 1;
273 register_cpu(cpu, i);
274 }
275
276 return 0;
277}
278subsys_initcall(topology_init);
279
280static const char *hwcap_str[] = {
281 "fp",
282 "asimd",
283 NULL
284};
285
286static int c_show(struct seq_file *m, void *v)
287{
288 int i;
289
290 seq_printf(m, "Processor\t: %s rev %d (%s)\n",
291 cpu_name, read_cpuid_id() & 15, ELF_PLATFORM);
292
293 for_each_online_cpu(i) {
294 /*
295 * glibc reads /proc/cpuinfo to determine the number of
296 * online processors, looking for lines beginning with
297 * "processor". Give glibc what it expects.
298 */
299#ifdef CONFIG_SMP
300 seq_printf(m, "processor\t: %d\n", i);
301#endif
302 seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n",
303 loops_per_jiffy / (500000UL/HZ),
304 loops_per_jiffy / (5000UL/HZ) % 100);
305 }
306
307 /* dump out the processor features */
308 seq_puts(m, "Features\t: ");
309
310 for (i = 0; hwcap_str[i]; i++)
311 if (elf_hwcap & (1 << i))
312 seq_printf(m, "%s ", hwcap_str[i]);
313
314 seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24);
315 seq_printf(m, "CPU architecture: AArch64\n");
316 seq_printf(m, "CPU variant\t: 0x%x\n", (read_cpuid_id() >> 20) & 15);
317 seq_printf(m, "CPU part\t: 0x%03x\n", (read_cpuid_id() >> 4) & 0xfff);
318 seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15);
319
320 seq_puts(m, "\n");
321
322 seq_printf(m, "Hardware\t: %s\n", machine_name);
323
324 return 0;
325}
326
327static void *c_start(struct seq_file *m, loff_t *pos)
328{
329 return *pos < 1 ? (void *)1 : NULL;
330}
331
332static void *c_next(struct seq_file *m, void *v, loff_t *pos)
333{
334 ++*pos;
335 return NULL;
336}
337
338static void c_stop(struct seq_file *m, void *v)
339{
340}
341
342const struct seq_operations cpuinfo_op = {
343 .start = c_start,
344 .next = c_next,
345 .stop = c_stop,
346 .show = c_show
347};
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
new file mode 100644
index 000000000000..8807ba2cf262
--- /dev/null
+++ b/arch/arm64/kernel/signal.c
@@ -0,0 +1,437 @@
1/*
2 * Based on arch/arm/kernel/signal.c
3 *
4 * Copyright (C) 1995-2009 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/errno.h>
21#include <linux/signal.h>
22#include <linux/personality.h>
23#include <linux/freezer.h>
24#include <linux/uaccess.h>
25#include <linux/tracehook.h>
26#include <linux/ratelimit.h>
27
28#include <asm/compat.h>
29#include <asm/debug-monitors.h>
30#include <asm/elf.h>
31#include <asm/cacheflush.h>
32#include <asm/ucontext.h>
33#include <asm/unistd.h>
34#include <asm/fpsimd.h>
35#include <asm/signal32.h>
36#include <asm/vdso.h>
37
38/*
39 * Do a signal return; undo the signal stack. These are aligned to 128-bit.
40 */
41struct rt_sigframe {
42 struct siginfo info;
43 struct ucontext uc;
44};
45
46static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
47{
48 struct fpsimd_state *fpsimd = &current->thread.fpsimd_state;
49 int err;
50
51 /* dump the hardware registers to the fpsimd_state structure */
52 fpsimd_save_state(fpsimd);
53
54 /* copy the FP and status/control registers */
55 err = __copy_to_user(ctx->vregs, fpsimd->vregs, sizeof(fpsimd->vregs));
56 __put_user_error(fpsimd->fpsr, &ctx->fpsr, err);
57 __put_user_error(fpsimd->fpcr, &ctx->fpcr, err);
58
59 /* copy the magic/size information */
60 __put_user_error(FPSIMD_MAGIC, &ctx->head.magic, err);
61 __put_user_error(sizeof(struct fpsimd_context), &ctx->head.size, err);
62
63 return err ? -EFAULT : 0;
64}
65
66static int restore_fpsimd_context(struct fpsimd_context __user *ctx)
67{
68 struct fpsimd_state fpsimd;
69 __u32 magic, size;
70 int err = 0;
71
72 /* check the magic/size information */
73 __get_user_error(magic, &ctx->head.magic, err);
74 __get_user_error(size, &ctx->head.size, err);
75 if (err)
76 return -EFAULT;
77 if (magic != FPSIMD_MAGIC || size != sizeof(struct fpsimd_context))
78 return -EINVAL;
79
80 /* copy the FP and status/control registers */
81 err = __copy_from_user(fpsimd.vregs, ctx->vregs,
82 sizeof(fpsimd.vregs));
83 __get_user_error(fpsimd.fpsr, &ctx->fpsr, err);
84 __get_user_error(fpsimd.fpcr, &ctx->fpcr, err);
85
86 /* load the hardware registers from the fpsimd_state structure */
87 if (!err) {
88 preempt_disable();
89 fpsimd_load_state(&fpsimd);
90 preempt_enable();
91 }
92
93 return err ? -EFAULT : 0;
94}
95
96static int restore_sigframe(struct pt_regs *regs,
97 struct rt_sigframe __user *sf)
98{
99 sigset_t set;
100 int i, err;
101 struct aux_context __user *aux =
102 (struct aux_context __user *)sf->uc.uc_mcontext.__reserved;
103
104 err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
105 if (err == 0)
106 set_current_blocked(&set);
107
108 for (i = 0; i < 31; i++)
109 __get_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i],
110 err);
111 __get_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err);
112 __get_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err);
113 __get_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err);
114
115 /*
116 * Avoid sys_rt_sigreturn() restarting.
117 */
118 regs->syscallno = ~0UL;
119
120 err |= !valid_user_regs(&regs->user_regs);
121
122 if (err == 0)
123 err |= restore_fpsimd_context(&aux->fpsimd);
124
125 return err;
126}
127
128asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
129{
130 struct rt_sigframe __user *frame;
131
132 /* Always make any pending restarted system calls return -EINTR */
133 current_thread_info()->restart_block.fn = do_no_restart_syscall;
134
135 /*
136 * Since we stacked the signal on a 128-bit boundary, then 'sp' should
137 * be word aligned here.
138 */
139 if (regs->sp & 15)
140 goto badframe;
141
142 frame = (struct rt_sigframe __user *)regs->sp;
143
144 if (!access_ok(VERIFY_READ, frame, sizeof (*frame)))
145 goto badframe;
146
147 if (restore_sigframe(regs, frame))
148 goto badframe;
149
150 if (do_sigaltstack(&frame->uc.uc_stack,
151 NULL, regs->sp) == -EFAULT)
152 goto badframe;
153
154 return regs->regs[0];
155
156badframe:
157 if (show_unhandled_signals)
158 pr_info_ratelimited("%s[%d]: bad frame in %s: pc=%08llx sp=%08llx\n",
159 current->comm, task_pid_nr(current), __func__,
160 regs->pc, regs->sp);
161 force_sig(SIGSEGV, current);
162 return 0;
163}
164
165asmlinkage long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
166 unsigned long sp)
167{
168 return do_sigaltstack(uss, uoss, sp);
169}
170
171static int setup_sigframe(struct rt_sigframe __user *sf,
172 struct pt_regs *regs, sigset_t *set)
173{
174 int i, err = 0;
175 struct aux_context __user *aux =
176 (struct aux_context __user *)sf->uc.uc_mcontext.__reserved;
177
178 for (i = 0; i < 31; i++)
179 __put_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i],
180 err);
181 __put_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err);
182 __put_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err);
183 __put_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err);
184
185 __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err);
186
187 err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
188
189 if (err == 0)
190 err |= preserve_fpsimd_context(&aux->fpsimd);
191
192 /* set the "end" magic */
193 __put_user_error(0, &aux->end.magic, err);
194 __put_user_error(0, &aux->end.size, err);
195
196 return err;
197}
198
199static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
200 int framesize)
201{
202 unsigned long sp, sp_top;
203 void __user *frame;
204
205 sp = sp_top = regs->sp;
206
207 /*
208 * This is the X/Open sanctioned signal stack switching.
209 */
210 if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
211 sp = sp_top = current->sas_ss_sp + current->sas_ss_size;
212
213 /* room for stack frame (FP, LR) */
214 sp -= 16;
215
216 sp = (sp - framesize) & ~15;
217 frame = (void __user *)sp;
218
219 /*
220 * Check that we can actually write to the signal frame.
221 */
222 if (!access_ok(VERIFY_WRITE, frame, sp_top - sp))
223 frame = NULL;
224
225 return frame;
226}
227
228static int setup_return(struct pt_regs *regs, struct k_sigaction *ka,
229 void __user *frame, int usig)
230{
231 int err = 0;
232 __sigrestore_t sigtramp;
233 unsigned long __user *sp = (unsigned long __user *)regs->sp;
234
235 /* set up the stack frame */
236 __put_user_error(regs->regs[29], sp - 2, err);
237 __put_user_error(regs->regs[30], sp - 1, err);
238
239 regs->regs[0] = usig;
240 regs->regs[29] = regs->sp - 16;
241 regs->sp = (unsigned long)frame;
242 regs->pc = (unsigned long)ka->sa.sa_handler;
243
244 if (ka->sa.sa_flags & SA_RESTORER)
245 sigtramp = ka->sa.sa_restorer;
246 else
247 sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
248
249 regs->regs[30] = (unsigned long)sigtramp;
250
251 return err;
252}
253
254static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
255 sigset_t *set, struct pt_regs *regs)
256{
257 struct rt_sigframe __user *frame;
258 stack_t stack;
259 int err = 0;
260
261 frame = get_sigframe(ka, regs, sizeof(*frame));
262 if (!frame)
263 return 1;
264
265 __put_user_error(0, &frame->uc.uc_flags, err);
266 __put_user_error(NULL, &frame->uc.uc_link, err);
267
268 memset(&stack, 0, sizeof(stack));
269 stack.ss_sp = (void __user *)current->sas_ss_sp;
270 stack.ss_flags = sas_ss_flags(regs->sp);
271 stack.ss_size = current->sas_ss_size;
272 err |= __copy_to_user(&frame->uc.uc_stack, &stack, sizeof(stack));
273
274 err |= setup_sigframe(frame, regs, set);
275 if (err == 0)
276 err = setup_return(regs, ka, frame, usig);
277
278 if (err == 0 && ka->sa.sa_flags & SA_SIGINFO) {
279 err |= copy_siginfo_to_user(&frame->info, info);
280 regs->regs[1] = (unsigned long)&frame->info;
281 regs->regs[2] = (unsigned long)&frame->uc;
282 }
283
284 return err;
285}
286
287static void setup_restart_syscall(struct pt_regs *regs)
288{
289 if (is_compat_task())
290 compat_setup_restart_syscall(regs);
291 else
292 regs->regs[8] = __NR_restart_syscall;
293}
294
295/*
296 * OK, we're invoking a handler
297 */
298static void handle_signal(unsigned long sig, struct k_sigaction *ka,
299 siginfo_t *info, struct pt_regs *regs)
300{
301 struct thread_info *thread = current_thread_info();
302 struct task_struct *tsk = current;
303 sigset_t *oldset = sigmask_to_save();
304 int usig = sig;
305 int ret;
306
307 /*
308 * translate the signal
309 */
310 if (usig < 32 && thread->exec_domain && thread->exec_domain->signal_invmap)
311 usig = thread->exec_domain->signal_invmap[usig];
312
313 /*
314 * Set up the stack frame
315 */
316 if (is_compat_task()) {
317 if (ka->sa.sa_flags & SA_SIGINFO)
318 ret = compat_setup_rt_frame(usig, ka, info, oldset,
319 regs);
320 else
321 ret = compat_setup_frame(usig, ka, oldset, regs);
322 } else {
323 ret = setup_rt_frame(usig, ka, info, oldset, regs);
324 }
325
326 /*
327 * Check that the resulting registers are actually sane.
328 */
329 ret |= !valid_user_regs(&regs->user_regs);
330
331 if (ret != 0) {
332 force_sigsegv(sig, tsk);
333 return;
334 }
335
336 /*
337 * Fast forward the stepping logic so we step into the signal
338 * handler.
339 */
340 user_fastforward_single_step(tsk);
341
342 signal_delivered(sig, info, ka, regs, 0);
343}
344
345/*
346 * Note that 'init' is a special process: it doesn't get signals it doesn't
347 * want to handle. Thus you cannot kill init even with a SIGKILL even by
348 * mistake.
349 *
350 * Note that we go through the signals twice: once to check the signals that
351 * the kernel can handle, and then we build all the user-level signal handling
352 * stack-frames in one go after that.
353 */
354static void do_signal(struct pt_regs *regs)
355{
356 unsigned long continue_addr = 0, restart_addr = 0;
357 struct k_sigaction ka;
358 siginfo_t info;
359 int signr, retval = 0;
360 int syscall = (int)regs->syscallno;
361
362 /*
363 * If we were from a system call, check for system call restarting...
364 */
365 if (syscall >= 0) {
366 continue_addr = regs->pc;
367 restart_addr = continue_addr - (compat_thumb_mode(regs) ? 2 : 4);
368 retval = regs->regs[0];
369
370 /*
371 * Avoid additional syscall restarting via ret_to_user.
372 */
373 regs->syscallno = ~0UL;
374
375 /*
376 * Prepare for system call restart. We do this here so that a
377 * debugger will see the already changed PC.
378 */
379 switch (retval) {
380 case -ERESTARTNOHAND:
381 case -ERESTARTSYS:
382 case -ERESTARTNOINTR:
383 case -ERESTART_RESTARTBLOCK:
384 regs->regs[0] = regs->orig_x0;
385 regs->pc = restart_addr;
386 break;
387 }
388 }
389
390 /*
391 * Get the signal to deliver. When running under ptrace, at this point
392 * the debugger may change all of our registers.
393 */
394 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
395 if (signr > 0) {
396 /*
397 * Depending on the signal settings, we may need to revert the
398 * decision to restart the system call, but skip this if a
399 * debugger has chosen to restart at a different PC.
400 */
401 if (regs->pc == restart_addr &&
402 (retval == -ERESTARTNOHAND ||
403 retval == -ERESTART_RESTARTBLOCK ||
404 (retval == -ERESTARTSYS &&
405 !(ka.sa.sa_flags & SA_RESTART)))) {
406 regs->regs[0] = -EINTR;
407 regs->pc = continue_addr;
408 }
409
410 handle_signal(signr, &ka, &info, regs);
411 return;
412 }
413
414 /*
415 * Handle restarting a different system call. As above, if a debugger
416 * has chosen to restart at a different PC, ignore the restart.
417 */
418 if (syscall >= 0 && regs->pc == restart_addr) {
419 if (retval == -ERESTART_RESTARTBLOCK)
420 setup_restart_syscall(regs);
421 user_rewind_single_step(current);
422 }
423
424 restore_saved_sigmask();
425}
426
427asmlinkage void do_notify_resume(struct pt_regs *regs,
428 unsigned int thread_flags)
429{
430 if (thread_flags & _TIF_SIGPENDING)
431 do_signal(regs);
432
433 if (thread_flags & _TIF_NOTIFY_RESUME) {
434 clear_thread_flag(TIF_NOTIFY_RESUME);
435 tracehook_notify_resume(regs);
436 }
437}
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
new file mode 100644
index 000000000000..ac74c2f261e3
--- /dev/null
+++ b/arch/arm64/kernel/signal32.c
@@ -0,0 +1,876 @@
1/*
2 * Based on arch/arm/kernel/signal.c
3 *
4 * Copyright (C) 1995-2009 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 * Modified by Will Deacon <will.deacon@arm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#define __SYSCALL_COMPAT
22
23#include <linux/compat.h>
24#include <linux/signal.h>
25#include <linux/syscalls.h>
26#include <linux/ratelimit.h>
27
28#include <asm/fpsimd.h>
29#include <asm/signal32.h>
30#include <asm/uaccess.h>
31#include <asm/unistd.h>
32
33typedef struct compat_siginfo {
34 int si_signo;
35 int si_errno;
36 int si_code;
37
38 union {
39 /* The padding is the same size as AArch64. */
40 int _pad[SI_PAD_SIZE];
41
42 /* kill() */
43 struct {
44 compat_pid_t _pid; /* sender's pid */
45 __compat_uid32_t _uid; /* sender's uid */
46 } _kill;
47
48 /* POSIX.1b timers */
49 struct {
50 compat_timer_t _tid; /* timer id */
51 int _overrun; /* overrun count */
52 compat_sigval_t _sigval; /* same as below */
53 int _sys_private; /* not to be passed to user */
54 } _timer;
55
56 /* POSIX.1b signals */
57 struct {
58 compat_pid_t _pid; /* sender's pid */
59 __compat_uid32_t _uid; /* sender's uid */
60 compat_sigval_t _sigval;
61 } _rt;
62
63 /* SIGCHLD */
64 struct {
65 compat_pid_t _pid; /* which child */
66 __compat_uid32_t _uid; /* sender's uid */
67 int _status; /* exit code */
68 compat_clock_t _utime;
69 compat_clock_t _stime;
70 } _sigchld;
71
72 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
73 struct {
74 compat_uptr_t _addr; /* faulting insn/memory ref. */
75 short _addr_lsb; /* LSB of the reported address */
76 } _sigfault;
77
78 /* SIGPOLL */
79 struct {
80 compat_long_t _band; /* POLL_IN, POLL_OUT, POLL_MSG */
81 int _fd;
82 } _sigpoll;
83 } _sifields;
84} compat_siginfo_t;
85
86struct compat_sigaction {
87 compat_uptr_t sa_handler;
88 compat_ulong_t sa_flags;
89 compat_uptr_t sa_restorer;
90 compat_sigset_t sa_mask;
91};
92
93struct compat_old_sigaction {
94 compat_uptr_t sa_handler;
95 compat_old_sigset_t sa_mask;
96 compat_ulong_t sa_flags;
97 compat_uptr_t sa_restorer;
98};
99
100typedef struct compat_sigaltstack {
101 compat_uptr_t ss_sp;
102 int ss_flags;
103 compat_size_t ss_size;
104} compat_stack_t;
105
106struct compat_sigcontext {
107 /* We always set these two fields to 0 */
108 compat_ulong_t trap_no;
109 compat_ulong_t error_code;
110
111 compat_ulong_t oldmask;
112 compat_ulong_t arm_r0;
113 compat_ulong_t arm_r1;
114 compat_ulong_t arm_r2;
115 compat_ulong_t arm_r3;
116 compat_ulong_t arm_r4;
117 compat_ulong_t arm_r5;
118 compat_ulong_t arm_r6;
119 compat_ulong_t arm_r7;
120 compat_ulong_t arm_r8;
121 compat_ulong_t arm_r9;
122 compat_ulong_t arm_r10;
123 compat_ulong_t arm_fp;
124 compat_ulong_t arm_ip;
125 compat_ulong_t arm_sp;
126 compat_ulong_t arm_lr;
127 compat_ulong_t arm_pc;
128 compat_ulong_t arm_cpsr;
129 compat_ulong_t fault_address;
130};
131
132struct compat_ucontext {
133 compat_ulong_t uc_flags;
134 struct compat_ucontext *uc_link;
135 compat_stack_t uc_stack;
136 struct compat_sigcontext uc_mcontext;
137 compat_sigset_t uc_sigmask;
138 int __unused[32 - (sizeof (compat_sigset_t) / sizeof (int))];
139 compat_ulong_t uc_regspace[128] __attribute__((__aligned__(8)));
140};
141
142struct compat_vfp_sigframe {
143 compat_ulong_t magic;
144 compat_ulong_t size;
145 struct compat_user_vfp {
146 compat_u64 fpregs[32];
147 compat_ulong_t fpscr;
148 } ufp;
149 struct compat_user_vfp_exc {
150 compat_ulong_t fpexc;
151 compat_ulong_t fpinst;
152 compat_ulong_t fpinst2;
153 } ufp_exc;
154} __attribute__((__aligned__(8)));
155
156#define VFP_MAGIC 0x56465001
157#define VFP_STORAGE_SIZE sizeof(struct compat_vfp_sigframe)
158
159struct compat_aux_sigframe {
160 struct compat_vfp_sigframe vfp;
161
162 /* Something that isn't a valid magic number for any coprocessor. */
163 unsigned long end_magic;
164} __attribute__((__aligned__(8)));
165
166struct compat_sigframe {
167 struct compat_ucontext uc;
168 compat_ulong_t retcode[2];
169};
170
171struct compat_rt_sigframe {
172 struct compat_siginfo info;
173 struct compat_sigframe sig;
174};
175
176#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
177
178/*
179 * For ARM syscalls, the syscall number has to be loaded into r7.
180 * We do not support an OABI userspace.
181 */
182#define MOV_R7_NR_SIGRETURN (0xe3a07000 | __NR_sigreturn)
183#define SVC_SYS_SIGRETURN (0xef000000 | __NR_sigreturn)
184#define MOV_R7_NR_RT_SIGRETURN (0xe3a07000 | __NR_rt_sigreturn)
185#define SVC_SYS_RT_SIGRETURN (0xef000000 | __NR_rt_sigreturn)
186
187/*
188 * For Thumb syscalls, we also pass the syscall number via r7. We therefore
189 * need two 16-bit instructions.
190 */
191#define SVC_THUMB_SIGRETURN (((0xdf00 | __NR_sigreturn) << 16) | \
192 0x2700 | __NR_sigreturn)
193#define SVC_THUMB_RT_SIGRETURN (((0xdf00 | __NR_rt_sigreturn) << 16) | \
194 0x2700 | __NR_rt_sigreturn)
195
196const compat_ulong_t aarch32_sigret_code[6] = {
197 /*
198 * AArch32 sigreturn code.
199 * We don't construct an OABI SWI - instead we just set the imm24 field
200 * to the EABI syscall number so that we create a sane disassembly.
201 */
202 MOV_R7_NR_SIGRETURN, SVC_SYS_SIGRETURN, SVC_THUMB_SIGRETURN,
203 MOV_R7_NR_RT_SIGRETURN, SVC_SYS_RT_SIGRETURN, SVC_THUMB_RT_SIGRETURN,
204};
205
206static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
207{
208 compat_sigset_t cset;
209
210 cset.sig[0] = set->sig[0] & 0xffffffffull;
211 cset.sig[1] = set->sig[0] >> 32;
212
213 return copy_to_user(uset, &cset, sizeof(*uset));
214}
215
216static inline int get_sigset_t(sigset_t *set,
217 const compat_sigset_t __user *uset)
218{
219 compat_sigset_t s32;
220
221 if (copy_from_user(&s32, uset, sizeof(*uset)))
222 return -EFAULT;
223
224 set->sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
225 return 0;
226}
227
228int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
229{
230 int err;
231
232 if (!access_ok(VERIFY_WRITE, to, sizeof(*to)))
233 return -EFAULT;
234
235 /* If you change siginfo_t structure, please be sure
236 * this code is fixed accordingly.
237 * It should never copy any pad contained in the structure
238 * to avoid security leaks, but must copy the generic
239 * 3 ints plus the relevant union member.
240 * This routine must convert siginfo from 64bit to 32bit as well
241 * at the same time.
242 */
243 err = __put_user(from->si_signo, &to->si_signo);
244 err |= __put_user(from->si_errno, &to->si_errno);
245 err |= __put_user((short)from->si_code, &to->si_code);
246 if (from->si_code < 0)
247 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad,
248 SI_PAD_SIZE);
249 else switch (from->si_code & __SI_MASK) {
250 case __SI_KILL:
251 err |= __put_user(from->si_pid, &to->si_pid);
252 err |= __put_user(from->si_uid, &to->si_uid);
253 break;
254 case __SI_TIMER:
255 err |= __put_user(from->si_tid, &to->si_tid);
256 err |= __put_user(from->si_overrun, &to->si_overrun);
257 err |= __put_user((compat_uptr_t)(unsigned long)from->si_ptr,
258 &to->si_ptr);
259 break;
260 case __SI_POLL:
261 err |= __put_user(from->si_band, &to->si_band);
262 err |= __put_user(from->si_fd, &to->si_fd);
263 break;
264 case __SI_FAULT:
265 err |= __put_user((compat_uptr_t)(unsigned long)from->si_addr,
266 &to->si_addr);
267#ifdef BUS_MCEERR_AO
268 /*
269 * Other callers might not initialize the si_lsb field,
270 * so check explicitely for the right codes here.
271 */
272 if (from->si_code == BUS_MCEERR_AR || from->si_code == BUS_MCEERR_AO)
273 err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb);
274#endif
275 break;
276 case __SI_CHLD:
277 err |= __put_user(from->si_pid, &to->si_pid);
278 err |= __put_user(from->si_uid, &to->si_uid);
279 err |= __put_user(from->si_status, &to->si_status);
280 err |= __put_user(from->si_utime, &to->si_utime);
281 err |= __put_user(from->si_stime, &to->si_stime);
282 break;
283 case __SI_RT: /* This is not generated by the kernel as of now. */
284 case __SI_MESGQ: /* But this is */
285 err |= __put_user(from->si_pid, &to->si_pid);
286 err |= __put_user(from->si_uid, &to->si_uid);
287 err |= __put_user((compat_uptr_t)(unsigned long)from->si_ptr, &to->si_ptr);
288 break;
289 default: /* this is just in case for now ... */
290 err |= __put_user(from->si_pid, &to->si_pid);
291 err |= __put_user(from->si_uid, &to->si_uid);
292 break;
293 }
294 return err;
295}
296
297int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
298{
299 memset(to, 0, sizeof *to);
300
301 if (copy_from_user(to, from, __ARCH_SI_PREAMBLE_SIZE) ||
302 copy_from_user(to->_sifields._pad,
303 from->_sifields._pad, SI_PAD_SIZE))
304 return -EFAULT;
305
306 return 0;
307}
308
309/*
310 * VFP save/restore code.
311 */
312static int compat_preserve_vfp_context(struct compat_vfp_sigframe __user *frame)
313{
314 struct fpsimd_state *fpsimd = &current->thread.fpsimd_state;
315 compat_ulong_t magic = VFP_MAGIC;
316 compat_ulong_t size = VFP_STORAGE_SIZE;
317 compat_ulong_t fpscr, fpexc;
318 int err = 0;
319
320 /*
321 * Save the hardware registers to the fpsimd_state structure.
322 * Note that this also saves V16-31, which aren't visible
323 * in AArch32.
324 */
325 fpsimd_save_state(fpsimd);
326
327 /* Place structure header on the stack */
328 __put_user_error(magic, &frame->magic, err);
329 __put_user_error(size, &frame->size, err);
330
331 /*
332 * Now copy the FP registers. Since the registers are packed,
333 * we can copy the prefix we want (V0-V15) as it is.
334 * FIXME: Won't work if big endian.
335 */
336 err |= __copy_to_user(&frame->ufp.fpregs, fpsimd->vregs,
337 sizeof(frame->ufp.fpregs));
338
339 /* Create an AArch32 fpscr from the fpsr and the fpcr. */
340 fpscr = (fpsimd->fpsr & VFP_FPSCR_STAT_MASK) |
341 (fpsimd->fpcr & VFP_FPSCR_CTRL_MASK);
342 __put_user_error(fpscr, &frame->ufp.fpscr, err);
343
344 /*
345 * The exception register aren't available so we fake up a
346 * basic FPEXC and zero everything else.
347 */
348 fpexc = (1 << 30);
349 __put_user_error(fpexc, &frame->ufp_exc.fpexc, err);
350 __put_user_error(0, &frame->ufp_exc.fpinst, err);
351 __put_user_error(0, &frame->ufp_exc.fpinst2, err);
352
353 return err ? -EFAULT : 0;
354}
355
356static int compat_restore_vfp_context(struct compat_vfp_sigframe __user *frame)
357{
358 struct fpsimd_state fpsimd;
359 compat_ulong_t magic = VFP_MAGIC;
360 compat_ulong_t size = VFP_STORAGE_SIZE;
361 compat_ulong_t fpscr;
362 int err = 0;
363
364 __get_user_error(magic, &frame->magic, err);
365 __get_user_error(size, &frame->size, err);
366
367 if (err)
368 return -EFAULT;
369 if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
370 return -EINVAL;
371
372 /*
373 * Copy the FP registers into the start of the fpsimd_state.
374 * FIXME: Won't work if big endian.
375 */
376 err |= __copy_from_user(fpsimd.vregs, frame->ufp.fpregs,
377 sizeof(frame->ufp.fpregs));
378
379 /* Extract the fpsr and the fpcr from the fpscr */
380 __get_user_error(fpscr, &frame->ufp.fpscr, err);
381 fpsimd.fpsr = fpscr & VFP_FPSCR_STAT_MASK;
382 fpsimd.fpcr = fpscr & VFP_FPSCR_CTRL_MASK;
383
384 /*
385 * We don't need to touch the exception register, so
386 * reload the hardware state.
387 */
388 if (!err) {
389 preempt_disable();
390 fpsimd_load_state(&fpsimd);
391 preempt_enable();
392 }
393
394 return err ? -EFAULT : 0;
395}
396
397/*
398 * atomically swap in the new signal mask, and wait for a signal.
399 */
400asmlinkage int compat_sys_sigsuspend(int restart, compat_ulong_t oldmask,
401 compat_old_sigset_t mask)
402{
403 sigset_t blocked;
404
405 siginitset(&current->blocked, mask);
406 return sigsuspend(&blocked);
407}
408
409asmlinkage int compat_sys_sigaction(int sig,
410 const struct compat_old_sigaction __user *act,
411 struct compat_old_sigaction __user *oact)
412{
413 struct k_sigaction new_ka, old_ka;
414 int ret;
415 compat_old_sigset_t mask;
416 compat_uptr_t handler, restorer;
417
418 if (act) {
419 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
420 __get_user(handler, &act->sa_handler) ||
421 __get_user(restorer, &act->sa_restorer) ||
422 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
423 __get_user(mask, &act->sa_mask))
424 return -EFAULT;
425
426 new_ka.sa.sa_handler = compat_ptr(handler);
427 new_ka.sa.sa_restorer = compat_ptr(restorer);
428 siginitset(&new_ka.sa.sa_mask, mask);
429 }
430
431 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
432
433 if (!ret && oact) {
434 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
435 __put_user(ptr_to_compat(old_ka.sa.sa_handler),
436 &oact->sa_handler) ||
437 __put_user(ptr_to_compat(old_ka.sa.sa_restorer),
438 &oact->sa_restorer) ||
439 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
440 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
441 return -EFAULT;
442 }
443
444 return ret;
445}
446
447asmlinkage int compat_sys_rt_sigaction(int sig,
448 const struct compat_sigaction __user *act,
449 struct compat_sigaction __user *oact,
450 compat_size_t sigsetsize)
451{
452 struct k_sigaction new_ka, old_ka;
453 int ret;
454
455 /* XXX: Don't preclude handling different sized sigset_t's. */
456 if (sigsetsize != sizeof(compat_sigset_t))
457 return -EINVAL;
458
459 if (act) {
460 compat_uptr_t handler, restorer;
461
462 ret = get_user(handler, &act->sa_handler);
463 new_ka.sa.sa_handler = compat_ptr(handler);
464 ret |= get_user(restorer, &act->sa_restorer);
465 new_ka.sa.sa_restorer = compat_ptr(restorer);
466 ret |= get_sigset_t(&new_ka.sa.sa_mask, &act->sa_mask);
467 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
468 if (ret)
469 return -EFAULT;
470 }
471
472 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
473 if (!ret && oact) {
474 ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler);
475 ret |= put_sigset_t(&oact->sa_mask, &old_ka.sa.sa_mask);
476 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
477 }
478 return ret;
479}
480
481int compat_do_sigaltstack(compat_uptr_t compat_uss, compat_uptr_t compat_uoss,
482 compat_ulong_t sp)
483{
484 compat_stack_t __user *newstack = compat_ptr(compat_uss);
485 compat_stack_t __user *oldstack = compat_ptr(compat_uoss);
486 compat_uptr_t ss_sp;
487 int ret;
488 mm_segment_t old_fs;
489 stack_t uss, uoss;
490
491 /* Marshall the compat new stack into a stack_t */
492 if (newstack) {
493 if (get_user(ss_sp, &newstack->ss_sp) ||
494 __get_user(uss.ss_flags, &newstack->ss_flags) ||
495 __get_user(uss.ss_size, &newstack->ss_size))
496 return -EFAULT;
497 uss.ss_sp = compat_ptr(ss_sp);
498 }
499
500 old_fs = get_fs();
501 set_fs(KERNEL_DS);
502 /* The __user pointer casts are valid because of the set_fs() */
503 ret = do_sigaltstack(
504 newstack ? (stack_t __user *) &uss : NULL,
505 oldstack ? (stack_t __user *) &uoss : NULL,
506 (unsigned long)sp);
507 set_fs(old_fs);
508
509 /* Convert the old stack_t into a compat stack. */
510 if (!ret && oldstack &&
511 (put_user(ptr_to_compat(uoss.ss_sp), &oldstack->ss_sp) ||
512 __put_user(uoss.ss_flags, &oldstack->ss_flags) ||
513 __put_user(uoss.ss_size, &oldstack->ss_size)))
514 return -EFAULT;
515 return ret;
516}
517
518static int compat_restore_sigframe(struct pt_regs *regs,
519 struct compat_sigframe __user *sf)
520{
521 int err;
522 sigset_t set;
523 struct compat_aux_sigframe __user *aux;
524
525 err = get_sigset_t(&set, &sf->uc.uc_sigmask);
526 if (err == 0) {
527 sigdelsetmask(&set, ~_BLOCKABLE);
528 set_current_blocked(&set);
529 }
530
531 __get_user_error(regs->regs[0], &sf->uc.uc_mcontext.arm_r0, err);
532 __get_user_error(regs->regs[1], &sf->uc.uc_mcontext.arm_r1, err);
533 __get_user_error(regs->regs[2], &sf->uc.uc_mcontext.arm_r2, err);
534 __get_user_error(regs->regs[3], &sf->uc.uc_mcontext.arm_r3, err);
535 __get_user_error(regs->regs[4], &sf->uc.uc_mcontext.arm_r4, err);
536 __get_user_error(regs->regs[5], &sf->uc.uc_mcontext.arm_r5, err);
537 __get_user_error(regs->regs[6], &sf->uc.uc_mcontext.arm_r6, err);
538 __get_user_error(regs->regs[7], &sf->uc.uc_mcontext.arm_r7, err);
539 __get_user_error(regs->regs[8], &sf->uc.uc_mcontext.arm_r8, err);
540 __get_user_error(regs->regs[9], &sf->uc.uc_mcontext.arm_r9, err);
541 __get_user_error(regs->regs[10], &sf->uc.uc_mcontext.arm_r10, err);
542 __get_user_error(regs->regs[11], &sf->uc.uc_mcontext.arm_fp, err);
543 __get_user_error(regs->regs[12], &sf->uc.uc_mcontext.arm_ip, err);
544 __get_user_error(regs->compat_sp, &sf->uc.uc_mcontext.arm_sp, err);
545 __get_user_error(regs->compat_lr, &sf->uc.uc_mcontext.arm_lr, err);
546 __get_user_error(regs->pc, &sf->uc.uc_mcontext.arm_pc, err);
547 __get_user_error(regs->pstate, &sf->uc.uc_mcontext.arm_cpsr, err);
548
549 /*
550 * Avoid compat_sys_sigreturn() restarting.
551 */
552 regs->syscallno = ~0UL;
553
554 err |= !valid_user_regs(&regs->user_regs);
555
556 aux = (struct compat_aux_sigframe __user *) sf->uc.uc_regspace;
557 if (err == 0)
558 err |= compat_restore_vfp_context(&aux->vfp);
559
560 return err;
561}
562
563asmlinkage int compat_sys_sigreturn(struct pt_regs *regs)
564{
565 struct compat_sigframe __user *frame;
566
567 /* Always make any pending restarted system calls return -EINTR */
568 current_thread_info()->restart_block.fn = do_no_restart_syscall;
569
570 /*
571 * Since we stacked the signal on a 64-bit boundary,
572 * then 'sp' should be word aligned here. If it's
573 * not, then the user is trying to mess with us.
574 */
575 if (regs->compat_sp & 7)
576 goto badframe;
577
578 frame = (struct compat_sigframe __user *)regs->compat_sp;
579
580 if (!access_ok(VERIFY_READ, frame, sizeof (*frame)))
581 goto badframe;
582
583 if (compat_restore_sigframe(regs, frame))
584 goto badframe;
585
586 return regs->regs[0];
587
588badframe:
589 if (show_unhandled_signals)
590 pr_info_ratelimited("%s[%d]: bad frame in %s: pc=%08llx sp=%08llx\n",
591 current->comm, task_pid_nr(current), __func__,
592 regs->pc, regs->sp);
593 force_sig(SIGSEGV, current);
594 return 0;
595}
596
597asmlinkage int compat_sys_rt_sigreturn(struct pt_regs *regs)
598{
599 struct compat_rt_sigframe __user *frame;
600
601 /* Always make any pending restarted system calls return -EINTR */
602 current_thread_info()->restart_block.fn = do_no_restart_syscall;
603
604 /*
605 * Since we stacked the signal on a 64-bit boundary,
606 * then 'sp' should be word aligned here. If it's
607 * not, then the user is trying to mess with us.
608 */
609 if (regs->compat_sp & 7)
610 goto badframe;
611
612 frame = (struct compat_rt_sigframe __user *)regs->compat_sp;
613
614 if (!access_ok(VERIFY_READ, frame, sizeof (*frame)))
615 goto badframe;
616
617 if (compat_restore_sigframe(regs, &frame->sig))
618 goto badframe;
619
620 if (compat_do_sigaltstack(ptr_to_compat(&frame->sig.uc.uc_stack),
621 ptr_to_compat((void __user *)NULL),
622 regs->compat_sp) == -EFAULT)
623 goto badframe;
624
625 return regs->regs[0];
626
627badframe:
628 if (show_unhandled_signals)
629 pr_info_ratelimited("%s[%d]: bad frame in %s: pc=%08llx sp=%08llx\n",
630 current->comm, task_pid_nr(current), __func__,
631 regs->pc, regs->sp);
632 force_sig(SIGSEGV, current);
633 return 0;
634}
635
636static inline void __user *compat_get_sigframe(struct k_sigaction *ka,
637 struct pt_regs *regs,
638 int framesize)
639{
640 compat_ulong_t sp = regs->compat_sp;
641 void __user *frame;
642
643 /*
644 * This is the X/Open sanctioned signal stack switching.
645 */
646 if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
647 sp = current->sas_ss_sp + current->sas_ss_size;
648
649 /*
650 * ATPCS B01 mandates 8-byte alignment
651 */
652 frame = compat_ptr((compat_uptr_t)((sp - framesize) & ~7));
653
654 /*
655 * Check that we can actually write to the signal frame.
656 */
657 if (!access_ok(VERIFY_WRITE, frame, framesize))
658 frame = NULL;
659
660 return frame;
661}
662
663static int compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka,
664 compat_ulong_t __user *rc, void __user *frame,
665 int usig)
666{
667 compat_ulong_t handler = ptr_to_compat(ka->sa.sa_handler);
668 compat_ulong_t retcode;
669 compat_ulong_t spsr = regs->pstate & ~PSR_f;
670 int thumb;
671
672 /* Check if the handler is written for ARM or Thumb */
673 thumb = handler & 1;
674
675 if (thumb) {
676 spsr |= COMPAT_PSR_T_BIT;
677 spsr &= ~COMPAT_PSR_IT_MASK;
678 } else {
679 spsr &= ~COMPAT_PSR_T_BIT;
680 }
681
682 if (ka->sa.sa_flags & SA_RESTORER) {
683 retcode = ptr_to_compat(ka->sa.sa_restorer);
684 } else {
685 /* Set up sigreturn pointer */
686 unsigned int idx = thumb << 1;
687
688 if (ka->sa.sa_flags & SA_SIGINFO)
689 idx += 3;
690
691 retcode = AARCH32_VECTORS_BASE +
692 AARCH32_KERN_SIGRET_CODE_OFFSET +
693 (idx << 2) + thumb;
694 }
695
696 regs->regs[0] = usig;
697 regs->compat_sp = ptr_to_compat(frame);
698 regs->compat_lr = retcode;
699 regs->pc = handler;
700 regs->pstate = spsr;
701
702 return 0;
703}
704
705static int compat_setup_sigframe(struct compat_sigframe __user *sf,
706 struct pt_regs *regs, sigset_t *set)
707{
708 struct compat_aux_sigframe __user *aux;
709 int err = 0;
710
711 __put_user_error(regs->regs[0], &sf->uc.uc_mcontext.arm_r0, err);
712 __put_user_error(regs->regs[1], &sf->uc.uc_mcontext.arm_r1, err);
713 __put_user_error(regs->regs[2], &sf->uc.uc_mcontext.arm_r2, err);
714 __put_user_error(regs->regs[3], &sf->uc.uc_mcontext.arm_r3, err);
715 __put_user_error(regs->regs[4], &sf->uc.uc_mcontext.arm_r4, err);
716 __put_user_error(regs->regs[5], &sf->uc.uc_mcontext.arm_r5, err);
717 __put_user_error(regs->regs[6], &sf->uc.uc_mcontext.arm_r6, err);
718 __put_user_error(regs->regs[7], &sf->uc.uc_mcontext.arm_r7, err);
719 __put_user_error(regs->regs[8], &sf->uc.uc_mcontext.arm_r8, err);
720 __put_user_error(regs->regs[9], &sf->uc.uc_mcontext.arm_r9, err);
721 __put_user_error(regs->regs[10], &sf->uc.uc_mcontext.arm_r10, err);
722 __put_user_error(regs->regs[11], &sf->uc.uc_mcontext.arm_fp, err);
723 __put_user_error(regs->regs[12], &sf->uc.uc_mcontext.arm_ip, err);
724 __put_user_error(regs->compat_sp, &sf->uc.uc_mcontext.arm_sp, err);
725 __put_user_error(regs->compat_lr, &sf->uc.uc_mcontext.arm_lr, err);
726 __put_user_error(regs->pc, &sf->uc.uc_mcontext.arm_pc, err);
727 __put_user_error(regs->pstate, &sf->uc.uc_mcontext.arm_cpsr, err);
728
729 __put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.trap_no, err);
730 __put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.error_code, err);
731 __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err);
732 __put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err);
733
734 err |= put_sigset_t(&sf->uc.uc_sigmask, set);
735
736 aux = (struct compat_aux_sigframe __user *) sf->uc.uc_regspace;
737
738 if (err == 0)
739 err |= compat_preserve_vfp_context(&aux->vfp);
740 __put_user_error(0, &aux->end_magic, err);
741
742 return err;
743}
744
745/*
746 * 32-bit signal handling routines called from signal.c
747 */
748int compat_setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
749 sigset_t *set, struct pt_regs *regs)
750{
751 struct compat_rt_sigframe __user *frame;
752 compat_stack_t stack;
753 int err = 0;
754
755 frame = compat_get_sigframe(ka, regs, sizeof(*frame));
756
757 if (!frame)
758 return 1;
759
760 err |= copy_siginfo_to_user32(&frame->info, info);
761
762 __put_user_error(0, &frame->sig.uc.uc_flags, err);
763 __put_user_error(NULL, &frame->sig.uc.uc_link, err);
764
765 memset(&stack, 0, sizeof(stack));
766 stack.ss_sp = (compat_uptr_t)current->sas_ss_sp;
767 stack.ss_flags = sas_ss_flags(regs->compat_sp);
768 stack.ss_size = current->sas_ss_size;
769 err |= __copy_to_user(&frame->sig.uc.uc_stack, &stack, sizeof(stack));
770
771 err |= compat_setup_sigframe(&frame->sig, regs, set);
772 if (err == 0)
773 err = compat_setup_return(regs, ka, frame->sig.retcode, frame,
774 usig);
775
776 if (err == 0) {
777 regs->regs[1] = (compat_ulong_t)(unsigned long)&frame->info;
778 regs->regs[2] = (compat_ulong_t)(unsigned long)&frame->sig.uc;
779 }
780
781 return err;
782}
783
784int compat_setup_frame(int usig, struct k_sigaction *ka, sigset_t *set,
785 struct pt_regs *regs)
786{
787 struct compat_sigframe __user *frame;
788 int err = 0;
789
790 frame = compat_get_sigframe(ka, regs, sizeof(*frame));
791
792 if (!frame)
793 return 1;
794
795 __put_user_error(0x5ac3c35a, &frame->uc.uc_flags, err);
796
797 err |= compat_setup_sigframe(frame, regs, set);
798 if (err == 0)
799 err = compat_setup_return(regs, ka, frame->retcode, frame, usig);
800
801 return err;
802}
803
804/*
805 * RT signals don't have generic compat wrappers.
806 * See arch/powerpc/kernel/signal_32.c
807 */
808asmlinkage int compat_sys_rt_sigprocmask(int how, compat_sigset_t __user *set,
809 compat_sigset_t __user *oset,
810 compat_size_t sigsetsize)
811{
812 sigset_t s;
813 sigset_t __user *up;
814 int ret;
815 mm_segment_t old_fs = get_fs();
816
817 if (set) {
818 if (get_sigset_t(&s, set))
819 return -EFAULT;
820 }
821
822 set_fs(KERNEL_DS);
823 /* This is valid because of the set_fs() */
824 up = (sigset_t __user *) &s;
825 ret = sys_rt_sigprocmask(how, set ? up : NULL, oset ? up : NULL,
826 sigsetsize);
827 set_fs(old_fs);
828 if (ret)
829 return ret;
830 if (oset) {
831 if (put_sigset_t(oset, &s))
832 return -EFAULT;
833 }
834 return 0;
835}
836
837asmlinkage int compat_sys_rt_sigpending(compat_sigset_t __user *set,
838 compat_size_t sigsetsize)
839{
840 sigset_t s;
841 int ret;
842 mm_segment_t old_fs = get_fs();
843
844 set_fs(KERNEL_DS);
845 /* The __user pointer cast is valid because of the set_fs() */
846 ret = sys_rt_sigpending((sigset_t __user *) &s, sigsetsize);
847 set_fs(old_fs);
848 if (!ret) {
849 if (put_sigset_t(set, &s))
850 return -EFAULT;
851 }
852 return ret;
853}
854
855asmlinkage int compat_sys_rt_sigqueueinfo(int pid, int sig,
856 compat_siginfo_t __user *uinfo)
857{
858 siginfo_t info;
859 int ret;
860 mm_segment_t old_fs = get_fs();
861
862 ret = copy_siginfo_from_user32(&info, uinfo);
863 if (unlikely(ret))
864 return ret;
865
866 set_fs (KERNEL_DS);
867 /* The __user pointer cast is valid because of the set_fs() */
868 ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info);
869 set_fs (old_fs);
870 return ret;
871}
872
873void compat_setup_restart_syscall(struct pt_regs *regs)
874{
875 regs->regs[7] = __NR_restart_syscall;
876}
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
new file mode 100644
index 000000000000..b711525be21f
--- /dev/null
+++ b/arch/arm64/kernel/smp.c
@@ -0,0 +1,469 @@
1/*
2 * SMP initialisation and IPI support
3 * Based on arch/arm/kernel/smp.c
4 *
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/delay.h>
21#include <linux/init.h>
22#include <linux/spinlock.h>
23#include <linux/sched.h>
24#include <linux/interrupt.h>
25#include <linux/cache.h>
26#include <linux/profile.h>
27#include <linux/errno.h>
28#include <linux/mm.h>
29#include <linux/err.h>
30#include <linux/cpu.h>
31#include <linux/smp.h>
32#include <linux/seq_file.h>
33#include <linux/irq.h>
34#include <linux/percpu.h>
35#include <linux/clockchips.h>
36#include <linux/completion.h>
37#include <linux/of.h>
38
39#include <asm/atomic.h>
40#include <asm/cacheflush.h>
41#include <asm/cputype.h>
42#include <asm/mmu_context.h>
43#include <asm/pgtable.h>
44#include <asm/pgalloc.h>
45#include <asm/processor.h>
46#include <asm/sections.h>
47#include <asm/tlbflush.h>
48#include <asm/ptrace.h>
49#include <asm/mmu_context.h>
50
51/*
52 * as from 2.5, kernels no longer have an init_tasks structure
53 * so we need some other way of telling a new secondary core
54 * where to place its SVC stack
55 */
56struct secondary_data secondary_data;
57volatile unsigned long secondary_holding_pen_release = -1;
58
59enum ipi_msg_type {
60 IPI_RESCHEDULE,
61 IPI_CALL_FUNC,
62 IPI_CALL_FUNC_SINGLE,
63 IPI_CPU_STOP,
64};
65
66static DEFINE_RAW_SPINLOCK(boot_lock);
67
68/*
69 * Write secondary_holding_pen_release in a way that is guaranteed to be
70 * visible to all observers, irrespective of whether they're taking part
71 * in coherency or not. This is necessary for the hotplug code to work
72 * reliably.
73 */
74static void __cpuinit write_pen_release(int val)
75{
76 void *start = (void *)&secondary_holding_pen_release;
77 unsigned long size = sizeof(secondary_holding_pen_release);
78
79 secondary_holding_pen_release = val;
80 __flush_dcache_area(start, size);
81}
82
83/*
84 * Boot a secondary CPU, and assign it the specified idle task.
85 * This also gives us the initial stack to use for this CPU.
86 */
87static int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
88{
89 unsigned long timeout;
90
91 /*
92 * Set synchronisation state between this boot processor
93 * and the secondary one
94 */
95 raw_spin_lock(&boot_lock);
96
97 /*
98 * Update the pen release flag.
99 */
100 write_pen_release(cpu);
101
102 /*
103 * Send an event, causing the secondaries to read pen_release.
104 */
105 sev();
106
107 timeout = jiffies + (1 * HZ);
108 while (time_before(jiffies, timeout)) {
109 if (secondary_holding_pen_release == -1UL)
110 break;
111 udelay(10);
112 }
113
114 /*
115 * Now the secondary core is starting up let it run its
116 * calibrations, then wait for it to finish
117 */
118 raw_spin_unlock(&boot_lock);
119
120 return secondary_holding_pen_release != -1 ? -ENOSYS : 0;
121}
122
123static DECLARE_COMPLETION(cpu_running);
124
125int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
126{
127 int ret;
128
129 /*
130 * We need to tell the secondary core where to find its stack and the
131 * page tables.
132 */
133 secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
134 __flush_dcache_area(&secondary_data, sizeof(secondary_data));
135
136 /*
137 * Now bring the CPU into our world.
138 */
139 ret = boot_secondary(cpu, idle);
140 if (ret == 0) {
141 /*
142 * CPU was successfully started, wait for it to come online or
143 * time out.
144 */
145 wait_for_completion_timeout(&cpu_running,
146 msecs_to_jiffies(1000));
147
148 if (!cpu_online(cpu)) {
149 pr_crit("CPU%u: failed to come online\n", cpu);
150 ret = -EIO;
151 }
152 } else {
153 pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
154 }
155
156 secondary_data.stack = NULL;
157
158 return ret;
159}
160
161/*
162 * This is the secondary CPU boot entry. We're using this CPUs
163 * idle thread stack, but a set of temporary page tables.
164 */
165asmlinkage void __cpuinit secondary_start_kernel(void)
166{
167 struct mm_struct *mm = &init_mm;
168 unsigned int cpu = smp_processor_id();
169
170 printk("CPU%u: Booted secondary processor\n", cpu);
171
172 /*
173 * All kernel threads share the same mm context; grab a
174 * reference and switch to it.
175 */
176 atomic_inc(&mm->mm_count);
177 current->active_mm = mm;
178 cpumask_set_cpu(cpu, mm_cpumask(mm));
179
180 /*
181 * TTBR0 is only used for the identity mapping at this stage. Make it
182 * point to zero page to avoid speculatively fetching new entries.
183 */
184 cpu_set_reserved_ttbr0();
185 flush_tlb_all();
186
187 preempt_disable();
188 trace_hardirqs_off();
189
190 /*
191 * Let the primary processor know we're out of the
192 * pen, then head off into the C entry point
193 */
194 write_pen_release(-1);
195
196 /*
197 * Synchronise with the boot thread.
198 */
199 raw_spin_lock(&boot_lock);
200 raw_spin_unlock(&boot_lock);
201
202 /*
203 * Enable local interrupts.
204 */
205 notify_cpu_starting(cpu);
206 local_irq_enable();
207 local_fiq_enable();
208
209 /*
210 * OK, now it's safe to let the boot CPU continue. Wait for
211 * the CPU migration code to notice that the CPU is online
212 * before we continue.
213 */
214 set_cpu_online(cpu, true);
215 while (!cpu_active(cpu))
216 cpu_relax();
217
218 /*
219 * OK, it's off to the idle thread for us
220 */
221 cpu_idle();
222}
223
224void __init smp_cpus_done(unsigned int max_cpus)
225{
226 unsigned long bogosum = loops_per_jiffy * num_online_cpus();
227
228 pr_info("SMP: Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
229 num_online_cpus(), bogosum / (500000/HZ),
230 (bogosum / (5000/HZ)) % 100);
231}
232
233void __init smp_prepare_boot_cpu(void)
234{
235}
236
237static void (*smp_cross_call)(const struct cpumask *, unsigned int);
238static phys_addr_t cpu_release_addr[NR_CPUS];
239
240/*
241 * Enumerate the possible CPU set from the device tree.
242 */
243void __init smp_init_cpus(void)
244{
245 const char *enable_method;
246 struct device_node *dn = NULL;
247 int cpu = 0;
248
249 while ((dn = of_find_node_by_type(dn, "cpu"))) {
250 if (cpu >= NR_CPUS)
251 goto next;
252
253 /*
254 * We currently support only the "spin-table" enable-method.
255 */
256 enable_method = of_get_property(dn, "enable-method", NULL);
257 if (!enable_method || strcmp(enable_method, "spin-table")) {
258 pr_err("CPU %d: missing or invalid enable-method property: %s\n",
259 cpu, enable_method);
260 goto next;
261 }
262
263 /*
264 * Determine the address from which the CPU is polling.
265 */
266 if (of_property_read_u64(dn, "cpu-release-addr",
267 &cpu_release_addr[cpu])) {
268 pr_err("CPU %d: missing or invalid cpu-release-addr property\n",
269 cpu);
270 goto next;
271 }
272
273 set_cpu_possible(cpu, true);
274next:
275 cpu++;
276 }
277
278 /* sanity check */
279 if (cpu > NR_CPUS)
280 pr_warning("no. of cores (%d) greater than configured maximum of %d - clipping\n",
281 cpu, NR_CPUS);
282}
283
284void __init smp_prepare_cpus(unsigned int max_cpus)
285{
286 int cpu;
287 void **release_addr;
288 unsigned int ncores = num_possible_cpus();
289
290 /*
291 * are we trying to boot more cores than exist?
292 */
293 if (max_cpus > ncores)
294 max_cpus = ncores;
295
296 /*
297 * Initialise the present map (which describes the set of CPUs
298 * actually populated at the present time) and release the
299 * secondaries from the bootloader.
300 */
301 for_each_possible_cpu(cpu) {
302 if (max_cpus == 0)
303 break;
304
305 if (!cpu_release_addr[cpu])
306 continue;
307
308 release_addr = __va(cpu_release_addr[cpu]);
309 release_addr[0] = (void *)__pa(secondary_holding_pen);
310 __flush_dcache_area(release_addr, sizeof(release_addr[0]));
311
312 set_cpu_present(cpu, true);
313 max_cpus--;
314 }
315
316 /*
317 * Send an event to wake up the secondaries.
318 */
319 sev();
320}
321
322
323void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
324{
325 smp_cross_call = fn;
326}
327
328void arch_send_call_function_ipi_mask(const struct cpumask *mask)
329{
330 smp_cross_call(mask, IPI_CALL_FUNC);
331}
332
333void arch_send_call_function_single_ipi(int cpu)
334{
335 smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
336}
337
338static const char *ipi_types[NR_IPI] = {
339#define S(x,s) [x - IPI_RESCHEDULE] = s
340 S(IPI_RESCHEDULE, "Rescheduling interrupts"),
341 S(IPI_CALL_FUNC, "Function call interrupts"),
342 S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
343 S(IPI_CPU_STOP, "CPU stop interrupts"),
344};
345
346void show_ipi_list(struct seq_file *p, int prec)
347{
348 unsigned int cpu, i;
349
350 for (i = 0; i < NR_IPI; i++) {
351 seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i + IPI_RESCHEDULE,
352 prec >= 4 ? " " : "");
353 for_each_present_cpu(cpu)
354 seq_printf(p, "%10u ",
355 __get_irq_stat(cpu, ipi_irqs[i]));
356 seq_printf(p, " %s\n", ipi_types[i]);
357 }
358}
359
360u64 smp_irq_stat_cpu(unsigned int cpu)
361{
362 u64 sum = 0;
363 int i;
364
365 for (i = 0; i < NR_IPI; i++)
366 sum += __get_irq_stat(cpu, ipi_irqs[i]);
367
368 return sum;
369}
370
371static DEFINE_RAW_SPINLOCK(stop_lock);
372
373/*
374 * ipi_cpu_stop - handle IPI from smp_send_stop()
375 */
376static void ipi_cpu_stop(unsigned int cpu)
377{
378 if (system_state == SYSTEM_BOOTING ||
379 system_state == SYSTEM_RUNNING) {
380 raw_spin_lock(&stop_lock);
381 pr_crit("CPU%u: stopping\n", cpu);
382 dump_stack();
383 raw_spin_unlock(&stop_lock);
384 }
385
386 set_cpu_online(cpu, false);
387
388 local_fiq_disable();
389 local_irq_disable();
390
391 while (1)
392 cpu_relax();
393}
394
395/*
396 * Main handler for inter-processor interrupts
397 */
398void handle_IPI(int ipinr, struct pt_regs *regs)
399{
400 unsigned int cpu = smp_processor_id();
401 struct pt_regs *old_regs = set_irq_regs(regs);
402
403 if (ipinr >= IPI_RESCHEDULE && ipinr < IPI_RESCHEDULE + NR_IPI)
404 __inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_RESCHEDULE]);
405
406 switch (ipinr) {
407 case IPI_RESCHEDULE:
408 scheduler_ipi();
409 break;
410
411 case IPI_CALL_FUNC:
412 irq_enter();
413 generic_smp_call_function_interrupt();
414 irq_exit();
415 break;
416
417 case IPI_CALL_FUNC_SINGLE:
418 irq_enter();
419 generic_smp_call_function_single_interrupt();
420 irq_exit();
421 break;
422
423 case IPI_CPU_STOP:
424 irq_enter();
425 ipi_cpu_stop(cpu);
426 irq_exit();
427 break;
428
429 default:
430 pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
431 break;
432 }
433 set_irq_regs(old_regs);
434}
435
436void smp_send_reschedule(int cpu)
437{
438 smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
439}
440
441void smp_send_stop(void)
442{
443 unsigned long timeout;
444
445 if (num_online_cpus() > 1) {
446 cpumask_t mask;
447
448 cpumask_copy(&mask, cpu_online_mask);
449 cpu_clear(smp_processor_id(), mask);
450
451 smp_cross_call(&mask, IPI_CPU_STOP);
452 }
453
454 /* Wait up to one second for other CPUs to stop */
455 timeout = USEC_PER_SEC;
456 while (num_online_cpus() > 1 && timeout--)
457 udelay(1);
458
459 if (num_online_cpus() > 1)
460 pr_warning("SMP: failed to stop secondary CPUs\n");
461}
462
463/*
464 * not supported here
465 */
466int setup_profiling_timer(unsigned int multiplier)
467{
468 return -EINVAL;
469}
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
new file mode 100644
index 000000000000..d25459ff57fc
--- /dev/null
+++ b/arch/arm64/kernel/stacktrace.c
@@ -0,0 +1,127 @@
1/*
2 * Stack tracing support
3 *
4 * Copyright (C) 2012 ARM Ltd.
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#include <linux/kernel.h>
19#include <linux/export.h>
20#include <linux/sched.h>
21#include <linux/stacktrace.h>
22
23#include <asm/stacktrace.h>
24
25/*
26 * AArch64 PCS assigns the frame pointer to x29.
27 *
28 * A simple function prologue looks like this:
29 * sub sp, sp, #0x10
30 * stp x29, x30, [sp]
31 * mov x29, sp
32 *
33 * A simple function epilogue looks like this:
34 * mov sp, x29
35 * ldp x29, x30, [sp]
36 * add sp, sp, #0x10
37 */
38int unwind_frame(struct stackframe *frame)
39{
40 unsigned long high, low;
41 unsigned long fp = frame->fp;
42
43 low = frame->sp;
44 high = ALIGN(low, THREAD_SIZE);
45
46 if (fp < low || fp > high || fp & 0xf)
47 return -EINVAL;
48
49 frame->sp = fp + 0x10;
50 frame->fp = *(unsigned long *)(fp);
51 frame->pc = *(unsigned long *)(fp + 8);
52
53 return 0;
54}
55
56void notrace walk_stackframe(struct stackframe *frame,
57 int (*fn)(struct stackframe *, void *), void *data)
58{
59 while (1) {
60 int ret;
61
62 if (fn(frame, data))
63 break;
64 ret = unwind_frame(frame);
65 if (ret < 0)
66 break;
67 }
68}
69EXPORT_SYMBOL(walk_stackframe);
70
71#ifdef CONFIG_STACKTRACE
72struct stack_trace_data {
73 struct stack_trace *trace;
74 unsigned int no_sched_functions;
75 unsigned int skip;
76};
77
78static int save_trace(struct stackframe *frame, void *d)
79{
80 struct stack_trace_data *data = d;
81 struct stack_trace *trace = data->trace;
82 unsigned long addr = frame->pc;
83
84 if (data->no_sched_functions && in_sched_functions(addr))
85 return 0;
86 if (data->skip) {
87 data->skip--;
88 return 0;
89 }
90
91 trace->entries[trace->nr_entries++] = addr;
92
93 return trace->nr_entries >= trace->max_entries;
94}
95
96void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
97{
98 struct stack_trace_data data;
99 struct stackframe frame;
100
101 data.trace = trace;
102 data.skip = trace->skip;
103
104 if (tsk != current) {
105 data.no_sched_functions = 1;
106 frame.fp = thread_saved_fp(tsk);
107 frame.sp = thread_saved_sp(tsk);
108 frame.pc = thread_saved_pc(tsk);
109 } else {
110 register unsigned long current_sp asm("sp");
111 data.no_sched_functions = 0;
112 frame.fp = (unsigned long)__builtin_frame_address(0);
113 frame.sp = current_sp;
114 frame.pc = (unsigned long)save_stack_trace_tsk;
115 }
116
117 walk_stackframe(&frame, save_trace, &data);
118 if (trace->nr_entries < trace->max_entries)
119 trace->entries[trace->nr_entries++] = ULONG_MAX;
120}
121
122void save_stack_trace(struct stack_trace *trace)
123{
124 save_stack_trace_tsk(current, trace);
125}
126EXPORT_SYMBOL_GPL(save_stack_trace);
127#endif
diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c
new file mode 100644
index 000000000000..905fcfb0ddd0
--- /dev/null
+++ b/arch/arm64/kernel/sys.c
@@ -0,0 +1,138 @@
1/*
2 * AArch64-specific system calls implementation
3 *
4 * Copyright (C) 2012 ARM Ltd.
5 * Author: Catalin Marinas <catalin.marinas@arm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/compiler.h>
21#include <linux/errno.h>
22#include <linux/fs.h>
23#include <linux/mm.h>
24#include <linux/export.h>
25#include <linux/sched.h>
26#include <linux/slab.h>
27#include <linux/syscalls.h>
28
29/*
30 * Clone a task - this clones the calling program thread.
31 */
32asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp,
33 int __user *parent_tidptr, unsigned long tls_val,
34 int __user *child_tidptr, struct pt_regs *regs)
35{
36 if (!newsp)
37 newsp = regs->sp;
38 /* 16-byte aligned stack mandatory on AArch64 */
39 if (newsp & 15)
40 return -EINVAL;
41 return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
42}
43
44/*
45 * sys_execve() executes a new program.
46 */
47asmlinkage long sys_execve(const char __user *filenamei,
48 const char __user *const __user *argv,
49 const char __user *const __user *envp,
50 struct pt_regs *regs)
51{
52 long error;
53 char * filename;
54
55 filename = getname(filenamei);
56 error = PTR_ERR(filename);
57 if (IS_ERR(filename))
58 goto out;
59 error = do_execve(filename, argv, envp, regs);
60 putname(filename);
61out:
62 return error;
63}
64
65int kernel_execve(const char *filename,
66 const char *const argv[],
67 const char *const envp[])
68{
69 struct pt_regs regs;
70 int ret;
71
72 memset(&regs, 0, sizeof(struct pt_regs));
73 ret = do_execve(filename,
74 (const char __user *const __user *)argv,
75 (const char __user *const __user *)envp, &regs);
76 if (ret < 0)
77 goto out;
78
79 /*
80 * Save argc to the register structure for userspace.
81 */
82 regs.regs[0] = ret;
83
84 /*
85 * We were successful. We won't be returning to our caller, but
86 * instead to user space by manipulating the kernel stack.
87 */
88 asm( "add x0, %0, %1\n\t"
89 "mov x1, %2\n\t"
90 "mov x2, %3\n\t"
91 "bl memmove\n\t" /* copy regs to top of stack */
92 "mov x27, #0\n\t" /* not a syscall */
93 "mov x28, %0\n\t" /* thread structure */
94 "mov sp, x0\n\t" /* reposition stack pointer */
95 "b ret_to_user"
96 :
97 : "r" (current_thread_info()),
98 "Ir" (THREAD_START_SP - sizeof(regs)),
99 "r" (&regs),
100 "Ir" (sizeof(regs))
101 : "x0", "x1", "x2", "x27", "x28", "x30", "memory");
102
103 out:
104 return ret;
105}
106EXPORT_SYMBOL(kernel_execve);
107
108asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
109 unsigned long prot, unsigned long flags,
110 unsigned long fd, off_t off)
111{
112 if (offset_in_page(off) != 0)
113 return -EINVAL;
114
115 return sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
116}
117
118/*
119 * Wrappers to pass the pt_regs argument.
120 */
121#define sys_execve sys_execve_wrapper
122#define sys_clone sys_clone_wrapper
123#define sys_rt_sigreturn sys_rt_sigreturn_wrapper
124#define sys_sigaltstack sys_sigaltstack_wrapper
125
126#include <asm/syscalls.h>
127
128#undef __SYSCALL
129#define __SYSCALL(nr, sym) [nr] = sym,
130
131/*
132 * The sys_call_table array must be 4K aligned to be accessible from
133 * kernel/entry.S.
134 */
135void *sys_call_table[__NR_syscalls] __aligned(4096) = {
136 [0 ... __NR_syscalls - 1] = sys_ni_syscall,
137#include <asm/unistd.h>
138};
diff --git a/arch/arm64/kernel/sys32.S b/arch/arm64/kernel/sys32.S
new file mode 100644
index 000000000000..5e4dc93cc31f
--- /dev/null
+++ b/arch/arm64/kernel/sys32.S
@@ -0,0 +1,282 @@
1/*
2 * Compat system call wrappers
3 *
4 * Copyright (C) 2012 ARM Ltd.
5 * Authors: Will Deacon <will.deacon@arm.com>
6 * Catalin Marinas <catalin.marinas@arm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <linux/linkage.h>
22
23#include <asm/assembler.h>
24#include <asm/asm-offsets.h>
25
26/*
27 * System call wrappers for the AArch32 compatibility layer.
28 */
29compat_sys_fork_wrapper:
30 mov x0, sp
31 b compat_sys_fork
32ENDPROC(compat_sys_fork_wrapper)
33
34compat_sys_vfork_wrapper:
35 mov x0, sp
36 b compat_sys_vfork
37ENDPROC(compat_sys_vfork_wrapper)
38
39compat_sys_execve_wrapper:
40 mov x3, sp
41 b compat_sys_execve
42ENDPROC(compat_sys_execve_wrapper)
43
44compat_sys_clone_wrapper:
45 mov x5, sp
46 b compat_sys_clone
47ENDPROC(compat_sys_clone_wrapper)
48
49compat_sys_sigreturn_wrapper:
50 mov x0, sp
51 mov x27, #0 // prevent syscall restart handling (why)
52 b compat_sys_sigreturn
53ENDPROC(compat_sys_sigreturn_wrapper)
54
55compat_sys_rt_sigreturn_wrapper:
56 mov x0, sp
57 mov x27, #0 // prevent syscall restart handling (why)
58 b compat_sys_rt_sigreturn
59ENDPROC(compat_sys_rt_sigreturn_wrapper)
60
61compat_sys_sigaltstack_wrapper:
62 ldr x2, [sp, #S_COMPAT_SP]
63 b compat_do_sigaltstack
64ENDPROC(compat_sys_sigaltstack_wrapper)
65
66compat_sys_statfs64_wrapper:
67 mov w3, #84
68 cmp w1, #88
69 csel w1, w3, w1, eq
70 b compat_sys_statfs64
71ENDPROC(compat_sys_statfs64_wrapper)
72
73compat_sys_fstatfs64_wrapper:
74 mov w3, #84
75 cmp w1, #88
76 csel w1, w3, w1, eq
77 b compat_sys_fstatfs64
78ENDPROC(compat_sys_fstatfs64_wrapper)
79
80/*
81 * Wrappers for AArch32 syscalls that either take 64-bit parameters
82 * in registers or that take 32-bit parameters which require sign
83 * extension.
84 */
85compat_sys_lseek_wrapper:
86 sxtw x1, w1
87 b sys_lseek
88ENDPROC(compat_sys_lseek_wrapper)
89
90compat_sys_pread64_wrapper:
91 orr x3, x4, x5, lsl #32
92 b sys_pread64
93ENDPROC(compat_sys_pread64_wrapper)
94
95compat_sys_pwrite64_wrapper:
96 orr x3, x4, x5, lsl #32
97 b sys_pwrite64
98ENDPROC(compat_sys_pwrite64_wrapper)
99
100compat_sys_truncate64_wrapper:
101 orr x1, x2, x3, lsl #32
102 b sys_truncate
103ENDPROC(compat_sys_truncate64_wrapper)
104
105compat_sys_ftruncate64_wrapper:
106 orr x1, x2, x3, lsl #32
107 b sys_ftruncate
108ENDPROC(compat_sys_ftruncate64_wrapper)
109
110compat_sys_readahead_wrapper:
111 orr x1, x2, x3, lsl #32
112 mov w2, w4
113 b sys_readahead
114ENDPROC(compat_sys_readahead_wrapper)
115
116compat_sys_lookup_dcookie:
117 orr x0, x0, x1, lsl #32
118 mov w1, w2
119 mov w2, w3
120 b sys_lookup_dcookie
121ENDPROC(compat_sys_lookup_dcookie)
122
123compat_sys_fadvise64_64_wrapper:
124 mov w6, w1
125 orr x1, x2, x3, lsl #32
126 orr x2, x4, x5, lsl #32
127 mov w3, w6
128 b sys_fadvise64_64
129ENDPROC(compat_sys_fadvise64_64_wrapper)
130
131compat_sys_sync_file_range2_wrapper:
132 orr x2, x2, x3, lsl #32
133 orr x3, x4, x5, lsl #32
134 b sys_sync_file_range2
135ENDPROC(compat_sys_sync_file_range2_wrapper)
136
137compat_sys_fallocate_wrapper:
138 orr x2, x2, x3, lsl #32
139 orr x3, x4, x5, lsl #32
140 b sys_fallocate
141ENDPROC(compat_sys_fallocate_wrapper)
142
143compat_sys_fanotify_mark_wrapper:
144 orr x2, x2, x3, lsl #32
145 mov w3, w4
146 mov w4, w5
147 b sys_fanotify_mark
148ENDPROC(compat_sys_fanotify_mark_wrapper)
149
150/*
151 * Use the compat system call wrappers.
152 */
153#define sys_fork compat_sys_fork_wrapper
154#define sys_open compat_sys_open
155#define sys_execve compat_sys_execve_wrapper
156#define sys_lseek compat_sys_lseek_wrapper
157#define sys_mount compat_sys_mount
158#define sys_ptrace compat_sys_ptrace
159#define sys_times compat_sys_times
160#define sys_ioctl compat_sys_ioctl
161#define sys_fcntl compat_sys_fcntl
162#define sys_ustat compat_sys_ustat
163#define sys_sigaction compat_sys_sigaction
164#define sys_sigsuspend compat_sys_sigsuspend
165#define sys_sigpending compat_sys_sigpending
166#define sys_setrlimit compat_sys_setrlimit
167#define sys_getrusage compat_sys_getrusage
168#define sys_gettimeofday compat_sys_gettimeofday
169#define sys_settimeofday compat_sys_settimeofday
170#define sys_statfs compat_sys_statfs
171#define sys_fstatfs compat_sys_fstatfs
172#define sys_setitimer compat_sys_setitimer
173#define sys_getitimer compat_sys_getitimer
174#define sys_newstat compat_sys_newstat
175#define sys_newlstat compat_sys_newlstat
176#define sys_newfstat compat_sys_newfstat
177#define sys_wait4 compat_sys_wait4
178#define sys_sysinfo compat_sys_sysinfo
179#define sys_sigreturn compat_sys_sigreturn_wrapper
180#define sys_clone compat_sys_clone_wrapper
181#define sys_adjtimex compat_sys_adjtimex
182#define sys_sigprocmask compat_sys_sigprocmask
183#define sys_getdents compat_sys_getdents
184#define sys_select compat_sys_select
185#define sys_readv compat_sys_readv
186#define sys_writev compat_sys_writev
187#define sys_sysctl compat_sys_sysctl
188#define sys_sched_rr_get_interval compat_sys_sched_rr_get_interval
189#define sys_nanosleep compat_sys_nanosleep
190#define sys_rt_sigreturn compat_sys_rt_sigreturn_wrapper
191#define sys_rt_sigaction compat_sys_rt_sigaction
192#define sys_rt_sigprocmask compat_sys_rt_sigprocmask
193#define sys_rt_sigpending compat_sys_rt_sigpending
194#define sys_rt_sigtimedwait compat_sys_rt_sigtimedwait
195#define sys_rt_sigqueueinfo compat_sys_rt_sigqueueinfo
196#define sys_rt_sigsuspend compat_sys_rt_sigsuspend
197#define sys_pread64 compat_sys_pread64_wrapper
198#define sys_pwrite64 compat_sys_pwrite64_wrapper
199#define sys_sigaltstack compat_sys_sigaltstack_wrapper
200#define sys_sendfile compat_sys_sendfile
201#define sys_vfork compat_sys_vfork_wrapper
202#define sys_getrlimit compat_sys_getrlimit
203#define sys_mmap2 sys_mmap_pgoff
204#define sys_truncate64 compat_sys_truncate64_wrapper
205#define sys_ftruncate64 compat_sys_ftruncate64_wrapper
206#define sys_getdents64 compat_sys_getdents64
207#define sys_fcntl64 compat_sys_fcntl64
208#define sys_readahead compat_sys_readahead_wrapper
209#define sys_futex compat_sys_futex
210#define sys_sched_setaffinity compat_sys_sched_setaffinity
211#define sys_sched_getaffinity compat_sys_sched_getaffinity
212#define sys_io_setup compat_sys_io_setup
213#define sys_io_getevents compat_sys_io_getevents
214#define sys_io_submit compat_sys_io_submit
215#define sys_lookup_dcookie compat_sys_lookup_dcookie
216#define sys_timer_create compat_sys_timer_create
217#define sys_timer_settime compat_sys_timer_settime
218#define sys_timer_gettime compat_sys_timer_gettime
219#define sys_clock_settime compat_sys_clock_settime
220#define sys_clock_gettime compat_sys_clock_gettime
221#define sys_clock_getres compat_sys_clock_getres
222#define sys_clock_nanosleep compat_sys_clock_nanosleep
223#define sys_statfs64 compat_sys_statfs64_wrapper
224#define sys_fstatfs64 compat_sys_fstatfs64_wrapper
225#define sys_utimes compat_sys_utimes
226#define sys_fadvise64_64 compat_sys_fadvise64_64_wrapper
227#define sys_mq_open compat_sys_mq_open
228#define sys_mq_timedsend compat_sys_mq_timedsend
229#define sys_mq_timedreceive compat_sys_mq_timedreceive
230#define sys_mq_notify compat_sys_mq_notify
231#define sys_mq_getsetattr compat_sys_mq_getsetattr
232#define sys_waitid compat_sys_waitid
233#define sys_recv compat_sys_recv
234#define sys_recvfrom compat_sys_recvfrom
235#define sys_setsockopt compat_sys_setsockopt
236#define sys_getsockopt compat_sys_getsockopt
237#define sys_sendmsg compat_sys_sendmsg
238#define sys_recvmsg compat_sys_recvmsg
239#define sys_semctl compat_sys_semctl
240#define sys_msgsnd compat_sys_msgsnd
241#define sys_msgrcv compat_sys_msgrcv
242#define sys_msgctl compat_sys_msgctl
243#define sys_shmat compat_sys_shmat
244#define sys_shmctl compat_sys_shmctl
245#define sys_keyctl compat_sys_keyctl
246#define sys_semtimedop compat_sys_semtimedop
247#define sys_mbind compat_sys_mbind
248#define sys_get_mempolicy compat_sys_get_mempolicy
249#define sys_set_mempolicy compat_sys_set_mempolicy
250#define sys_openat compat_sys_openat
251#define sys_futimesat compat_sys_futimesat
252#define sys_pselect6 compat_sys_pselect6
253#define sys_ppoll compat_sys_ppoll
254#define sys_set_robust_list compat_sys_set_robust_list
255#define sys_get_robust_list compat_sys_get_robust_list
256#define sys_sync_file_range2 compat_sys_sync_file_range2_wrapper
257#define sys_vmsplice compat_sys_vmsplice
258#define sys_move_pages compat_sys_move_pages
259#define sys_epoll_pwait compat_sys_epoll_pwait
260#define sys_kexec_load compat_sys_kexec_load
261#define sys_utimensat compat_sys_utimensat
262#define sys_signalfd compat_sys_signalfd
263#define sys_fallocate compat_sys_fallocate_wrapper
264#define sys_timerfd_settime compat_sys_timerfd_settime
265#define sys_timerfd_gettime compat_sys_timerfd_gettime
266#define sys_signalfd4 compat_sys_signalfd4
267#define sys_preadv compat_sys_preadv
268#define sys_pwritev compat_sys_pwritev
269#define sys_rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo
270#define sys_recvmmsg compat_sys_recvmmsg
271#define sys_fanotify_mark compat_sys_fanotify_mark_wrapper
272
273#undef __SYSCALL
274#define __SYSCALL(x, y) .quad y // x
275#define __SYSCALL_COMPAT
276
277/*
278 * The system calls table must be 4KB aligned.
279 */
280 .align 12
281ENTRY(compat_sys_call_table)
282#include <asm/unistd.h>
diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c
new file mode 100644
index 000000000000..967e92fdff01
--- /dev/null
+++ b/arch/arm64/kernel/sys_compat.c
@@ -0,0 +1,164 @@
1/*
2 * Based on arch/arm/kernel/sys_arm.c
3 *
4 * Copyright (C) People who wrote linux/arch/i386/kernel/sys_i386.c
5 * Copyright (C) 1995, 1996 Russell King.
6 * Copyright (C) 2012 ARM Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#define __SYSCALL_COMPAT
22
23#include <linux/compat.h>
24#include <linux/personality.h>
25#include <linux/sched.h>
26#include <linux/slab.h>
27#include <linux/syscalls.h>
28#include <linux/uaccess.h>
29
30#include <asm/cacheflush.h>
31#include <asm/unistd.h>
32
33asmlinkage int compat_sys_fork(struct pt_regs *regs)
34{
35 return do_fork(SIGCHLD, regs->compat_sp, regs, 0, NULL, NULL);
36}
37
38asmlinkage int compat_sys_clone(unsigned long clone_flags, unsigned long newsp,
39 int __user *parent_tidptr, int tls_val,
40 int __user *child_tidptr, struct pt_regs *regs)
41{
42 if (!newsp)
43 newsp = regs->compat_sp;
44
45 return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
46}
47
48asmlinkage int compat_sys_vfork(struct pt_regs *regs)
49{
50 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->compat_sp,
51 regs, 0, NULL, NULL);
52}
53
54asmlinkage int compat_sys_execve(const char __user *filenamei,
55 compat_uptr_t argv, compat_uptr_t envp,
56 struct pt_regs *regs)
57{
58 int error;
59 char * filename;
60
61 filename = getname(filenamei);
62 error = PTR_ERR(filename);
63 if (IS_ERR(filename))
64 goto out;
65 error = compat_do_execve(filename, compat_ptr(argv), compat_ptr(envp),
66 regs);
67 putname(filename);
68out:
69 return error;
70}
71
72asmlinkage int compat_sys_sched_rr_get_interval(compat_pid_t pid,
73 struct compat_timespec __user *interval)
74{
75 struct timespec t;
76 int ret;
77 mm_segment_t old_fs = get_fs();
78
79 set_fs(KERNEL_DS);
80 ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t);
81 set_fs(old_fs);
82 if (put_compat_timespec(&t, interval))
83 return -EFAULT;
84 return ret;
85}
86
87asmlinkage int compat_sys_sendfile(int out_fd, int in_fd,
88 compat_off_t __user *offset, s32 count)
89{
90 mm_segment_t old_fs = get_fs();
91 int ret;
92 off_t of;
93
94 if (offset && get_user(of, offset))
95 return -EFAULT;
96
97 set_fs(KERNEL_DS);
98 ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL,
99 count);
100 set_fs(old_fs);
101
102 if (offset && put_user(of, offset))
103 return -EFAULT;
104 return ret;
105}
106
107static inline void
108do_compat_cache_op(unsigned long start, unsigned long end, int flags)
109{
110 struct mm_struct *mm = current->active_mm;
111 struct vm_area_struct *vma;
112
113 if (end < start || flags)
114 return;
115
116 down_read(&mm->mmap_sem);
117 vma = find_vma(mm, start);
118 if (vma && vma->vm_start < end) {
119 if (start < vma->vm_start)
120 start = vma->vm_start;
121 if (end > vma->vm_end)
122 end = vma->vm_end;
123 up_read(&mm->mmap_sem);
124 __flush_cache_user_range(start & PAGE_MASK, PAGE_ALIGN(end));
125 return;
126 }
127 up_read(&mm->mmap_sem);
128}
129
130/*
131 * Handle all unrecognised system calls.
132 */
133long compat_arm_syscall(struct pt_regs *regs)
134{
135 unsigned int no = regs->regs[7];
136
137 switch (no) {
138 /*
139 * Flush a region from virtual address 'r0' to virtual address 'r1'
140 * _exclusive_. There is no alignment requirement on either address;
141 * user space does not need to know the hardware cache layout.
142 *
143 * r2 contains flags. It should ALWAYS be passed as ZERO until it
144 * is defined to be something else. For now we ignore it, but may
145 * the fires of hell burn in your belly if you break this rule. ;)
146 *
147 * (at a later date, we may want to allow this call to not flush
148 * various aspects of the cache. Passing '0' will guarantee that
149 * everything necessary gets flushed to maintain consistency in
150 * the specified region).
151 */
152 case __ARM_NR_compat_cacheflush:
153 do_compat_cache_op(regs->regs[0], regs->regs[1], regs->regs[2]);
154 return 0;
155
156 case __ARM_NR_compat_set_tls:
157 current->thread.tp_value = regs->regs[0];
158 asm ("msr tpidrro_el0, %0" : : "r" (regs->regs[0]));
159 return 0;
160
161 default:
162 return -ENOSYS;
163 }
164}
diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c
new file mode 100644
index 000000000000..3b4b7258f492
--- /dev/null
+++ b/arch/arm64/kernel/time.c
@@ -0,0 +1,65 @@
1/*
2 * Based on arch/arm/kernel/time.c
3 *
4 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
5 * Modifications for ARM (C) 1994-2001 Russell King
6 * Copyright (C) 2012 ARM Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <linux/export.h>
22#include <linux/kernel.h>
23#include <linux/interrupt.h>
24#include <linux/time.h>
25#include <linux/init.h>
26#include <linux/sched.h>
27#include <linux/smp.h>
28#include <linux/timex.h>
29#include <linux/errno.h>
30#include <linux/profile.h>
31#include <linux/syscore_ops.h>
32#include <linux/timer.h>
33#include <linux/irq.h>
34
35#include <clocksource/arm_generic.h>
36
37#include <asm/thread_info.h>
38#include <asm/stacktrace.h>
39
40#ifdef CONFIG_SMP
41unsigned long profile_pc(struct pt_regs *regs)
42{
43 struct stackframe frame;
44
45 if (!in_lock_functions(regs->pc))
46 return regs->pc;
47
48 frame.fp = regs->regs[29];
49 frame.sp = regs->sp;
50 frame.pc = regs->pc;
51 do {
52 int ret = unwind_frame(&frame);
53 if (ret < 0)
54 return 0;
55 } while (in_lock_functions(frame.pc));
56
57 return frame.pc;
58}
59EXPORT_SYMBOL(profile_pc);
60#endif
61
62void __init time_init(void)
63{
64 arm_generic_timer_init();
65}
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
new file mode 100644
index 000000000000..3883f842434f
--- /dev/null
+++ b/arch/arm64/kernel/traps.c
@@ -0,0 +1,348 @@
1/*
2 * Based on arch/arm/kernel/traps.c
3 *
4 * Copyright (C) 1995-2009 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/signal.h>
21#include <linux/personality.h>
22#include <linux/kallsyms.h>
23#include <linux/spinlock.h>
24#include <linux/uaccess.h>
25#include <linux/hardirq.h>
26#include <linux/kdebug.h>
27#include <linux/module.h>
28#include <linux/kexec.h>
29#include <linux/delay.h>
30#include <linux/init.h>
31#include <linux/sched.h>
32#include <linux/syscalls.h>
33
34#include <asm/atomic.h>
35#include <asm/traps.h>
36#include <asm/stacktrace.h>
37#include <asm/exception.h>
38#include <asm/system_misc.h>
39
40static const char *handler[]= {
41 "Synchronous Abort",
42 "IRQ",
43 "FIQ",
44 "Error"
45};
46
47int show_unhandled_signals = 1;
48
49/*
50 * Dump out the contents of some memory nicely...
51 */
52static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
53 unsigned long top)
54{
55 unsigned long first;
56 mm_segment_t fs;
57 int i;
58
59 /*
60 * We need to switch to kernel mode so that we can use __get_user
61 * to safely read from kernel space. Note that we now dump the
62 * code first, just in case the backtrace kills us.
63 */
64 fs = get_fs();
65 set_fs(KERNEL_DS);
66
67 printk("%s%s(0x%016lx to 0x%016lx)\n", lvl, str, bottom, top);
68
69 for (first = bottom & ~31; first < top; first += 32) {
70 unsigned long p;
71 char str[sizeof(" 12345678") * 8 + 1];
72
73 memset(str, ' ', sizeof(str));
74 str[sizeof(str) - 1] = '\0';
75
76 for (p = first, i = 0; i < 8 && p < top; i++, p += 4) {
77 if (p >= bottom && p < top) {
78 unsigned int val;
79 if (__get_user(val, (unsigned int *)p) == 0)
80 sprintf(str + i * 9, " %08x", val);
81 else
82 sprintf(str + i * 9, " ????????");
83 }
84 }
85 printk("%s%04lx:%s\n", lvl, first & 0xffff, str);
86 }
87
88 set_fs(fs);
89}
90
91static void dump_backtrace_entry(unsigned long where, unsigned long stack)
92{
93 print_ip_sym(where);
94 if (in_exception_text(where))
95 dump_mem("", "Exception stack", stack,
96 stack + sizeof(struct pt_regs));
97}
98
99static void dump_instr(const char *lvl, struct pt_regs *regs)
100{
101 unsigned long addr = instruction_pointer(regs);
102 mm_segment_t fs;
103 char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
104 int i;
105
106 /*
107 * We need to switch to kernel mode so that we can use __get_user
108 * to safely read from kernel space. Note that we now dump the
109 * code first, just in case the backtrace kills us.
110 */
111 fs = get_fs();
112 set_fs(KERNEL_DS);
113
114 for (i = -4; i < 1; i++) {
115 unsigned int val, bad;
116
117 bad = __get_user(val, &((u32 *)addr)[i]);
118
119 if (!bad)
120 p += sprintf(p, i == 0 ? "(%08x) " : "%08x ", val);
121 else {
122 p += sprintf(p, "bad PC value");
123 break;
124 }
125 }
126 printk("%sCode: %s\n", lvl, str);
127
128 set_fs(fs);
129}
130
131static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
132{
133 struct stackframe frame;
134 const register unsigned long current_sp asm ("sp");
135
136 pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
137
138 if (!tsk)
139 tsk = current;
140
141 if (regs) {
142 frame.fp = regs->regs[29];
143 frame.sp = regs->sp;
144 frame.pc = regs->pc;
145 } else if (tsk == current) {
146 frame.fp = (unsigned long)__builtin_frame_address(0);
147 frame.sp = current_sp;
148 frame.pc = (unsigned long)dump_backtrace;
149 } else {
150 /*
151 * task blocked in __switch_to
152 */
153 frame.fp = thread_saved_fp(tsk);
154 frame.sp = thread_saved_sp(tsk);
155 frame.pc = thread_saved_pc(tsk);
156 }
157
158 printk("Call trace:\n");
159 while (1) {
160 unsigned long where = frame.pc;
161 int ret;
162
163 ret = unwind_frame(&frame);
164 if (ret < 0)
165 break;
166 dump_backtrace_entry(where, frame.sp);
167 }
168}
169
170void dump_stack(void)
171{
172 dump_backtrace(NULL, NULL);
173}
174
175EXPORT_SYMBOL(dump_stack);
176
177void show_stack(struct task_struct *tsk, unsigned long *sp)
178{
179 dump_backtrace(NULL, tsk);
180 barrier();
181}
182
183#ifdef CONFIG_PREEMPT
184#define S_PREEMPT " PREEMPT"
185#else
186#define S_PREEMPT ""
187#endif
188#ifdef CONFIG_SMP
189#define S_SMP " SMP"
190#else
191#define S_SMP ""
192#endif
193
194static int __die(const char *str, int err, struct thread_info *thread,
195 struct pt_regs *regs)
196{
197 struct task_struct *tsk = thread->task;
198 static int die_counter;
199 int ret;
200
201 pr_emerg("Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
202 str, err, ++die_counter);
203
204 /* trap and error numbers are mostly meaningless on ARM */
205 ret = notify_die(DIE_OOPS, str, regs, err, 0, SIGSEGV);
206 if (ret == NOTIFY_STOP)
207 return ret;
208
209 print_modules();
210 __show_regs(regs);
211 pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n",
212 TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1);
213
214 if (!user_mode(regs) || in_interrupt()) {
215 dump_mem(KERN_EMERG, "Stack: ", regs->sp,
216 THREAD_SIZE + (unsigned long)task_stack_page(tsk));
217 dump_backtrace(regs, tsk);
218 dump_instr(KERN_EMERG, regs);
219 }
220
221 return ret;
222}
223
224static DEFINE_RAW_SPINLOCK(die_lock);
225
226/*
227 * This function is protected against re-entrancy.
228 */
229void die(const char *str, struct pt_regs *regs, int err)
230{
231 struct thread_info *thread = current_thread_info();
232 int ret;
233
234 oops_enter();
235
236 raw_spin_lock_irq(&die_lock);
237 console_verbose();
238 bust_spinlocks(1);
239 ret = __die(str, err, thread, regs);
240
241 if (regs && kexec_should_crash(thread->task))
242 crash_kexec(regs);
243
244 bust_spinlocks(0);
245 add_taint(TAINT_DIE);
246 raw_spin_unlock_irq(&die_lock);
247 oops_exit();
248
249 if (in_interrupt())
250 panic("Fatal exception in interrupt");
251 if (panic_on_oops)
252 panic("Fatal exception");
253 if (ret != NOTIFY_STOP)
254 do_exit(SIGSEGV);
255}
256
257void arm64_notify_die(const char *str, struct pt_regs *regs,
258 struct siginfo *info, int err)
259{
260 if (user_mode(regs))
261 force_sig_info(info->si_signo, info, current);
262 else
263 die(str, regs, err);
264}
265
266asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
267{
268 siginfo_t info;
269 void __user *pc = (void __user *)instruction_pointer(regs);
270
271#ifdef CONFIG_COMPAT
272 /* check for AArch32 breakpoint instructions */
273 if (compat_user_mode(regs) && aarch32_break_trap(regs) == 0)
274 return;
275#endif
276
277 if (show_unhandled_signals) {
278 pr_info("%s[%d]: undefined instruction: pc=%p\n",
279 current->comm, task_pid_nr(current), pc);
280 dump_instr(KERN_INFO, regs);
281 }
282
283 info.si_signo = SIGILL;
284 info.si_errno = 0;
285 info.si_code = ILL_ILLOPC;
286 info.si_addr = pc;
287
288 arm64_notify_die("Oops - undefined instruction", regs, &info, 0);
289}
290
291long compat_arm_syscall(struct pt_regs *regs);
292
293asmlinkage long do_ni_syscall(struct pt_regs *regs)
294{
295#ifdef CONFIG_COMPAT
296 long ret;
297 if (is_compat_task()) {
298 ret = compat_arm_syscall(regs);
299 if (ret != -ENOSYS)
300 return ret;
301 }
302#endif
303
304 if (show_unhandled_signals) {
305 pr_info("%s[%d]: syscall %d\n", current->comm,
306 task_pid_nr(current), (int)regs->syscallno);
307 dump_instr("", regs);
308 if (user_mode(regs))
309 __show_regs(regs);
310 }
311
312 return sys_ni_syscall();
313}
314
315/*
316 * bad_mode handles the impossible case in the exception vector.
317 */
318asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr)
319{
320 console_verbose();
321
322 pr_crit("Bad mode in %s handler detected, code 0x%08x\n",
323 handler[reason], esr);
324
325 die("Oops - bad mode", regs, 0);
326 local_irq_disable();
327 panic("bad mode");
328}
329
330void __pte_error(const char *file, int line, unsigned long val)
331{
332 printk("%s:%d: bad pte %016lx.\n", file, line, val);
333}
334
335void __pmd_error(const char *file, int line, unsigned long val)
336{
337 printk("%s:%d: bad pmd %016lx.\n", file, line, val);
338}
339
340void __pgd_error(const char *file, int line, unsigned long val)
341{
342 printk("%s:%d: bad pgd %016lx.\n", file, line, val);
343}
344
345void __init trap_init(void)
346{
347 return;
348}
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
new file mode 100644
index 000000000000..17948fc7d663
--- /dev/null
+++ b/arch/arm64/kernel/vdso.c
@@ -0,0 +1,261 @@
1/*
2 * VDSO implementation for AArch64 and vector page setup for AArch32.
3 *
4 * Copyright (C) 2012 ARM Limited
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Author: Will Deacon <will.deacon@arm.com>
19 */
20
21#include <linux/kernel.h>
22#include <linux/clocksource.h>
23#include <linux/elf.h>
24#include <linux/err.h>
25#include <linux/errno.h>
26#include <linux/gfp.h>
27#include <linux/mm.h>
28#include <linux/sched.h>
29#include <linux/signal.h>
30#include <linux/slab.h>
31#include <linux/vmalloc.h>
32
33#include <asm/cacheflush.h>
34#include <asm/signal32.h>
35#include <asm/vdso.h>
36#include <asm/vdso_datapage.h>
37
38extern char vdso_start, vdso_end;
39static unsigned long vdso_pages;
40static struct page **vdso_pagelist;
41
42/*
43 * The vDSO data page.
44 */
45static union {
46 struct vdso_data data;
47 u8 page[PAGE_SIZE];
48} vdso_data_store __page_aligned_data;
49struct vdso_data *vdso_data = &vdso_data_store.data;
50
51#ifdef CONFIG_COMPAT
52/*
53 * Create and map the vectors page for AArch32 tasks.
54 */
55static struct page *vectors_page[1];
56
57static int alloc_vectors_page(void)
58{
59 extern char __kuser_helper_start[], __kuser_helper_end[];
60 int kuser_sz = __kuser_helper_end - __kuser_helper_start;
61 unsigned long vpage;
62
63 vpage = get_zeroed_page(GFP_ATOMIC);
64
65 if (!vpage)
66 return -ENOMEM;
67
68 /* kuser helpers */
69 memcpy((void *)vpage + 0x1000 - kuser_sz, __kuser_helper_start,
70 kuser_sz);
71
72 /* sigreturn code */
73 memcpy((void *)vpage + AARCH32_KERN_SIGRET_CODE_OFFSET,
74 aarch32_sigret_code, sizeof(aarch32_sigret_code));
75
76 flush_icache_range(vpage, vpage + PAGE_SIZE);
77 vectors_page[0] = virt_to_page(vpage);
78
79 return 0;
80}
81arch_initcall(alloc_vectors_page);
82
83int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
84{
85 struct mm_struct *mm = current->mm;
86 unsigned long addr = AARCH32_VECTORS_BASE;
87 int ret;
88
89 down_write(&mm->mmap_sem);
90 current->mm->context.vdso = (void *)addr;
91
92 /* Map vectors page at the high address. */
93 ret = install_special_mapping(mm, addr, PAGE_SIZE,
94 VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC,
95 vectors_page);
96
97 up_write(&mm->mmap_sem);
98
99 return ret;
100}
101#endif /* CONFIG_COMPAT */
102
103static int __init vdso_init(void)
104{
105 struct page *pg;
106 char *vbase;
107 int i, ret = 0;
108
109 vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
110 pr_info("vdso: %ld pages (%ld code, %ld data) at base %p\n",
111 vdso_pages + 1, vdso_pages, 1L, &vdso_start);
112
113 /* Allocate the vDSO pagelist, plus a page for the data. */
114 vdso_pagelist = kzalloc(sizeof(struct page *) * (vdso_pages + 1),
115 GFP_KERNEL);
116 if (vdso_pagelist == NULL) {
117 pr_err("Failed to allocate vDSO pagelist!\n");
118 return -ENOMEM;
119 }
120
121 /* Grab the vDSO code pages. */
122 for (i = 0; i < vdso_pages; i++) {
123 pg = virt_to_page(&vdso_start + i*PAGE_SIZE);
124 ClearPageReserved(pg);
125 get_page(pg);
126 vdso_pagelist[i] = pg;
127 }
128
129 /* Sanity check the shared object header. */
130 vbase = vmap(vdso_pagelist, 1, 0, PAGE_KERNEL);
131 if (vbase == NULL) {
132 pr_err("Failed to map vDSO pagelist!\n");
133 return -ENOMEM;
134 } else if (memcmp(vbase, "\177ELF", 4)) {
135 pr_err("vDSO is not a valid ELF object!\n");
136 ret = -EINVAL;
137 goto unmap;
138 }
139
140 /* Grab the vDSO data page. */
141 pg = virt_to_page(vdso_data);
142 get_page(pg);
143 vdso_pagelist[i] = pg;
144
145unmap:
146 vunmap(vbase);
147 return ret;
148}
149arch_initcall(vdso_init);
150
151int arch_setup_additional_pages(struct linux_binprm *bprm,
152 int uses_interp)
153{
154 struct mm_struct *mm = current->mm;
155 unsigned long vdso_base, vdso_mapping_len;
156 int ret;
157
158 /* Be sure to map the data page */
159 vdso_mapping_len = (vdso_pages + 1) << PAGE_SHIFT;
160
161 down_write(&mm->mmap_sem);
162 vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
163 if (IS_ERR_VALUE(vdso_base)) {
164 ret = vdso_base;
165 goto up_fail;
166 }
167 mm->context.vdso = (void *)vdso_base;
168
169 ret = install_special_mapping(mm, vdso_base, vdso_mapping_len,
170 VM_READ|VM_EXEC|
171 VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
172 vdso_pagelist);
173 if (ret) {
174 mm->context.vdso = NULL;
175 goto up_fail;
176 }
177
178up_fail:
179 up_write(&mm->mmap_sem);
180
181 return ret;
182}
183
184const char *arch_vma_name(struct vm_area_struct *vma)
185{
186 /*
187 * We can re-use the vdso pointer in mm_context_t for identifying
188 * the vectors page for compat applications. The vDSO will always
189 * sit above TASK_UNMAPPED_BASE and so we don't need to worry about
190 * it conflicting with the vectors base.
191 */
192 if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) {
193#ifdef CONFIG_COMPAT
194 if (vma->vm_start == AARCH32_VECTORS_BASE)
195 return "[vectors]";
196#endif
197 return "[vdso]";
198 }
199
200 return NULL;
201}
202
203/*
204 * We define AT_SYSINFO_EHDR, so we need these function stubs to keep
205 * Linux happy.
206 */
207int in_gate_area_no_mm(unsigned long addr)
208{
209 return 0;
210}
211
212int in_gate_area(struct mm_struct *mm, unsigned long addr)
213{
214 return 0;
215}
216
217struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
218{
219 return NULL;
220}
221
222/*
223 * Update the vDSO data page to keep in sync with kernel timekeeping.
224 */
225void update_vsyscall(struct timespec *ts, struct timespec *wtm,
226 struct clocksource *clock, u32 mult)
227{
228 struct timespec xtime_coarse;
229 u32 use_syscall = strcmp(clock->name, "arch_sys_counter");
230
231 ++vdso_data->tb_seq_count;
232 smp_wmb();
233
234 xtime_coarse = __current_kernel_time();
235 vdso_data->use_syscall = use_syscall;
236 vdso_data->xtime_coarse_sec = xtime_coarse.tv_sec;
237 vdso_data->xtime_coarse_nsec = xtime_coarse.tv_nsec;
238
239 if (!use_syscall) {
240 vdso_data->cs_cycle_last = clock->cycle_last;
241 vdso_data->xtime_clock_sec = ts->tv_sec;
242 vdso_data->xtime_clock_nsec = ts->tv_nsec;
243 vdso_data->cs_mult = mult;
244 vdso_data->cs_shift = clock->shift;
245 vdso_data->wtm_clock_sec = wtm->tv_sec;
246 vdso_data->wtm_clock_nsec = wtm->tv_nsec;
247 }
248
249 smp_wmb();
250 ++vdso_data->tb_seq_count;
251}
252
253void update_vsyscall_tz(void)
254{
255 ++vdso_data->tb_seq_count;
256 smp_wmb();
257 vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
258 vdso_data->tz_dsttime = sys_tz.tz_dsttime;
259 smp_wmb();
260 ++vdso_data->tb_seq_count;
261}
diff --git a/arch/arm64/kernel/vdso/.gitignore b/arch/arm64/kernel/vdso/.gitignore
new file mode 100644
index 000000000000..b8cc94e9698b
--- /dev/null
+++ b/arch/arm64/kernel/vdso/.gitignore
@@ -0,0 +1,2 @@
1vdso.lds
2vdso-offsets.h
diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
new file mode 100644
index 000000000000..d8064af42e62
--- /dev/null
+++ b/arch/arm64/kernel/vdso/Makefile
@@ -0,0 +1,63 @@
1#
2# Building a vDSO image for AArch64.
3#
4# Author: Will Deacon <will.deacon@arm.com>
5# Heavily based on the vDSO Makefiles for other archs.
6#
7
8obj-vdso := gettimeofday.o note.o sigreturn.o
9
10# Build rules
11targets := $(obj-vdso) vdso.so vdso.so.dbg
12obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
13
14ccflags-y := -shared -fno-common -fno-builtin
15ccflags-y += -nostdlib -Wl,-soname=linux-vdso.so.1 \
16 $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
17
18obj-y += vdso.o
19extra-y += vdso.lds vdso-offsets.h
20CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
21
22# Force dependency (incbin is bad)
23$(obj)/vdso.o : $(obj)/vdso.so
24
25# Link rule for the .so file, .lds has to be first
26$(obj)/vdso.so.dbg: $(src)/vdso.lds $(obj-vdso)
27 $(call if_changed,vdsold)
28
29# Strip rule for the .so file
30$(obj)/%.so: OBJCOPYFLAGS := -S
31$(obj)/%.so: $(obj)/%.so.dbg FORCE
32 $(call if_changed,objcopy)
33
34# Generate VDSO offsets using helper script
35gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh
36quiet_cmd_vdsosym = VDSOSYM $@
37define cmd_vdsosym
38 $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ && \
39 cp $@ include/generated/
40endef
41
42$(obj)/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE
43 $(call if_changed,vdsosym)
44
45# Assembly rules for the .S files
46$(obj-vdso): %.o: %.S
47 $(call if_changed_dep,vdsoas)
48
49# Actual build commands
50quiet_cmd_vdsold = VDSOL $@
51 cmd_vdsold = $(CC) $(c_flags) -Wl,-T $^ -o $@
52quiet_cmd_vdsoas = VDSOA $@
53 cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $<
54
55# Install commands for the unstripped file
56quiet_cmd_vdso_install = INSTALL $@
57 cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
58
59vdso.so: $(obj)/vdso.so.dbg
60 @mkdir -p $(MODLIB)/vdso
61 $(call cmd,vdso_install)
62
63vdso_install: vdso.so
diff --git a/arch/arm64/kernel/vdso/gen_vdso_offsets.sh b/arch/arm64/kernel/vdso/gen_vdso_offsets.sh
new file mode 100755
index 000000000000..01924ff071ad
--- /dev/null
+++ b/arch/arm64/kernel/vdso/gen_vdso_offsets.sh
@@ -0,0 +1,15 @@
1#!/bin/sh
2
3#
4# Match symbols in the DSO that look like VDSO_*; produce a header file
5# of constant offsets into the shared object.
6#
7# Doing this inside the Makefile will break the $(filter-out) function,
8# causing Kbuild to rebuild the vdso-offsets header file every time.
9#
10# Author: Will Deacon <will.deacon@arm.com
11#
12
13LC_ALL=C
14sed -n -e 's/^00*/0/' -e \
15's/^\([0-9a-fA-F]*\) . VDSO_\([a-zA-Z0-9_]*\)$/\#define vdso_offset_\2\t0x\1/p'
diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S
new file mode 100644
index 000000000000..dcb8c203a3b2
--- /dev/null
+++ b/arch/arm64/kernel/vdso/gettimeofday.S
@@ -0,0 +1,242 @@
1/*
2 * Userspace implementations of gettimeofday() and friends.
3 *
4 * Copyright (C) 2012 ARM Limited
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Author: Will Deacon <will.deacon@arm.com>
19 */
20
21#include <linux/linkage.h>
22#include <asm/asm-offsets.h>
23#include <asm/unistd.h>
24
25#define NSEC_PER_SEC_LO16 0xca00
26#define NSEC_PER_SEC_HI16 0x3b9a
27
28vdso_data .req x6
29use_syscall .req w7
30seqcnt .req w8
31
32 .macro seqcnt_acquire
339999: ldr seqcnt, [vdso_data, #VDSO_TB_SEQ_COUNT]
34 tbnz seqcnt, #0, 9999b
35 dmb ishld
36 ldr use_syscall, [vdso_data, #VDSO_USE_SYSCALL]
37 .endm
38
39 .macro seqcnt_read, cnt
40 dmb ishld
41 ldr \cnt, [vdso_data, #VDSO_TB_SEQ_COUNT]
42 .endm
43
44 .macro seqcnt_check, cnt, fail
45 cmp \cnt, seqcnt
46 b.ne \fail
47 .endm
48
49 .text
50
51/* int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); */
52ENTRY(__kernel_gettimeofday)
53 .cfi_startproc
54 mov x2, x30
55 .cfi_register x30, x2
56
57 /* Acquire the sequence counter and get the timespec. */
58 adr vdso_data, _vdso_data
591: seqcnt_acquire
60 cbnz use_syscall, 4f
61
62 /* If tv is NULL, skip to the timezone code. */
63 cbz x0, 2f
64 bl __do_get_tspec
65 seqcnt_check w13, 1b
66
67 /* Convert ns to us. */
68 mov x11, #1000
69 udiv x10, x10, x11
70 stp x9, x10, [x0, #TVAL_TV_SEC]
712:
72 /* If tz is NULL, return 0. */
73 cbz x1, 3f
74 ldp w4, w5, [vdso_data, #VDSO_TZ_MINWEST]
75 seqcnt_read w13
76 seqcnt_check w13, 1b
77 stp w4, w5, [x1, #TZ_MINWEST]
783:
79 mov x0, xzr
80 ret x2
814:
82 /* Syscall fallback. */
83 mov x8, #__NR_gettimeofday
84 svc #0
85 ret x2
86 .cfi_endproc
87ENDPROC(__kernel_gettimeofday)
88
89/* int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp); */
90ENTRY(__kernel_clock_gettime)
91 .cfi_startproc
92 cmp w0, #CLOCK_REALTIME
93 ccmp w0, #CLOCK_MONOTONIC, #0x4, ne
94 b.ne 2f
95
96 mov x2, x30
97 .cfi_register x30, x2
98
99 /* Get kernel timespec. */
100 adr vdso_data, _vdso_data
1011: seqcnt_acquire
102 cbnz use_syscall, 7f
103
104 bl __do_get_tspec
105 seqcnt_check w13, 1b
106
107 cmp w0, #CLOCK_MONOTONIC
108 b.ne 6f
109
110 /* Get wtm timespec. */
111 ldp x14, x15, [vdso_data, #VDSO_WTM_CLK_SEC]
112
113 /* Check the sequence counter. */
114 seqcnt_read w13
115 seqcnt_check w13, 1b
116 b 4f
1172:
118 cmp w0, #CLOCK_REALTIME_COARSE
119 ccmp w0, #CLOCK_MONOTONIC_COARSE, #0x4, ne
120 b.ne 8f
121
122 /* Get coarse timespec. */
123 adr vdso_data, _vdso_data
1243: seqcnt_acquire
125 ldp x9, x10, [vdso_data, #VDSO_XTIME_CRS_SEC]
126
127 cmp w0, #CLOCK_MONOTONIC_COARSE
128 b.ne 6f
129
130 /* Get wtm timespec. */
131 ldp x14, x15, [vdso_data, #VDSO_WTM_CLK_SEC]
132
133 /* Check the sequence counter. */
134 seqcnt_read w13
135 seqcnt_check w13, 3b
1364:
137 /* Add on wtm timespec. */
138 add x9, x9, x14
139 add x10, x10, x15
140
141 /* Normalise the new timespec. */
142 mov x14, #NSEC_PER_SEC_LO16
143 movk x14, #NSEC_PER_SEC_HI16, lsl #16
144 cmp x10, x14
145 b.lt 5f
146 sub x10, x10, x14
147 add x9, x9, #1
1485:
149 cmp x10, #0
150 b.ge 6f
151 add x10, x10, x14
152 sub x9, x9, #1
153
1546: /* Store to the user timespec. */
155 stp x9, x10, [x1, #TSPEC_TV_SEC]
156 mov x0, xzr
157 ret x2
1587:
159 mov x30, x2
1608: /* Syscall fallback. */
161 mov x8, #__NR_clock_gettime
162 svc #0
163 ret
164 .cfi_endproc
165ENDPROC(__kernel_clock_gettime)
166
167/* int __kernel_clock_getres(clockid_t clock_id, struct timespec *res); */
168ENTRY(__kernel_clock_getres)
169 .cfi_startproc
170 cbz w1, 3f
171
172 cmp w0, #CLOCK_REALTIME
173 ccmp w0, #CLOCK_MONOTONIC, #0x4, ne
174 b.ne 1f
175
176 ldr x2, 5f
177 b 2f
1781:
179 cmp w0, #CLOCK_REALTIME_COARSE
180 ccmp w0, #CLOCK_MONOTONIC_COARSE, #0x4, ne
181 b.ne 4f
182 ldr x2, 6f
1832:
184 stp xzr, x2, [x1]
185
1863: /* res == NULL. */
187 mov w0, wzr
188 ret
189
1904: /* Syscall fallback. */
191 mov x8, #__NR_clock_getres
192 svc #0
193 ret
1945:
195 .quad CLOCK_REALTIME_RES
1966:
197 .quad CLOCK_COARSE_RES
198 .cfi_endproc
199ENDPROC(__kernel_clock_getres)
200
201/*
202 * Read the current time from the architected counter.
203 * Expects vdso_data to be initialised.
204 * Clobbers the temporary registers (x9 - x15).
205 * Returns:
206 * - (x9, x10) = (ts->tv_sec, ts->tv_nsec)
207 * - (x11, x12) = (xtime->tv_sec, xtime->tv_nsec)
208 * - w13 = vDSO sequence counter
209 */
210ENTRY(__do_get_tspec)
211 .cfi_startproc
212
213 /* Read from the vDSO data page. */
214 ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST]
215 ldp x11, x12, [vdso_data, #VDSO_XTIME_CLK_SEC]
216 ldp w14, w15, [vdso_data, #VDSO_CS_MULT]
217 seqcnt_read w13
218
219 /* Read the physical counter. */
220 isb
221 mrs x9, cntpct_el0
222
223 /* Calculate cycle delta and convert to ns. */
224 sub x10, x9, x10
225 /* We can only guarantee 56 bits of precision. */
226 movn x9, #0xff0, lsl #48
227 and x10, x9, x10
228 mul x10, x10, x14
229 lsr x10, x10, x15
230
231 /* Use the kernel time to calculate the new timespec. */
232 add x10, x12, x10
233 mov x14, #NSEC_PER_SEC_LO16
234 movk x14, #NSEC_PER_SEC_HI16, lsl #16
235 udiv x15, x10, x14
236 add x9, x15, x11
237 mul x14, x14, x15
238 sub x10, x10, x14
239
240 ret
241 .cfi_endproc
242ENDPROC(__do_get_tspec)
diff --git a/arch/arm64/kernel/vdso/note.S b/arch/arm64/kernel/vdso/note.S
new file mode 100644
index 000000000000..b82c85e5d972
--- /dev/null
+++ b/arch/arm64/kernel/vdso/note.S
@@ -0,0 +1,28 @@
1/*
2 * Copyright (C) 2012 ARM Limited
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Author: Will Deacon <will.deacon@arm.com>
17 *
18 * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
19 * Here we can supply some information useful to userland.
20 */
21
22#include <linux/uts.h>
23#include <linux/version.h>
24#include <linux/elfnote.h>
25
26ELFNOTE_START(Linux, 0, "a")
27 .long LINUX_VERSION_CODE
28ELFNOTE_END
diff --git a/arch/arm64/kernel/vdso/sigreturn.S b/arch/arm64/kernel/vdso/sigreturn.S
new file mode 100644
index 000000000000..20d98effa7dd
--- /dev/null
+++ b/arch/arm64/kernel/vdso/sigreturn.S
@@ -0,0 +1,37 @@
1/*
2 * Sigreturn trampoline for returning from a signal when the SA_RESTORER
3 * flag is not set.
4 *
5 * Copyright (C) 2012 ARM Limited
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Author: Will Deacon <will.deacon@arm.com>
20 */
21
22#include <linux/linkage.h>
23#include <asm/unistd.h>
24
25 .text
26
27 nop
28ENTRY(__kernel_rt_sigreturn)
29 .cfi_startproc
30 .cfi_signal_frame
31 .cfi_def_cfa x29, 0
32 .cfi_offset x29, 0 * 8
33 .cfi_offset x30, 1 * 8
34 mov x8, #__NR_rt_sigreturn
35 svc #0
36 .cfi_endproc
37ENDPROC(__kernel_rt_sigreturn)
diff --git a/arch/arm64/kernel/vdso/vdso.S b/arch/arm64/kernel/vdso/vdso.S
new file mode 100644
index 000000000000..60c1db54b41a
--- /dev/null
+++ b/arch/arm64/kernel/vdso/vdso.S
@@ -0,0 +1,33 @@
1/*
2 * Copyright (C) 2012 ARM Limited
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Author: Will Deacon <will.deacon@arm.com>
17 */
18
19#include <linux/init.h>
20#include <linux/linkage.h>
21#include <linux/const.h>
22#include <asm/page.h>
23
24 __PAGE_ALIGNED_DATA
25
26 .globl vdso_start, vdso_end
27 .balign PAGE_SIZE
28vdso_start:
29 .incbin "arch/arm64/kernel/vdso/vdso.so"
30 .balign PAGE_SIZE
31vdso_end:
32
33 .previous
diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vdso.lds.S
new file mode 100644
index 000000000000..8154b8d1c826
--- /dev/null
+++ b/arch/arm64/kernel/vdso/vdso.lds.S
@@ -0,0 +1,100 @@
1/*
2 * GNU linker script for the VDSO library.
3*
4 * Copyright (C) 2012 ARM Limited
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Author: Will Deacon <will.deacon@arm.com>
19 * Heavily based on the vDSO linker scripts for other archs.
20 */
21
22#include <linux/const.h>
23#include <asm/page.h>
24#include <asm/vdso.h>
25
26OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64", "elf64-littleaarch64")
27OUTPUT_ARCH(aarch64)
28
29SECTIONS
30{
31 . = VDSO_LBASE + SIZEOF_HEADERS;
32
33 .hash : { *(.hash) } :text
34 .gnu.hash : { *(.gnu.hash) }
35 .dynsym : { *(.dynsym) }
36 .dynstr : { *(.dynstr) }
37 .gnu.version : { *(.gnu.version) }
38 .gnu.version_d : { *(.gnu.version_d) }
39 .gnu.version_r : { *(.gnu.version_r) }
40
41 .note : { *(.note.*) } :text :note
42
43 . = ALIGN(16);
44
45 .text : { *(.text*) } :text =0xd503201f
46 PROVIDE (__etext = .);
47 PROVIDE (_etext = .);
48 PROVIDE (etext = .);
49
50 .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
51 .eh_frame : { KEEP (*(.eh_frame)) } :text
52
53 .dynamic : { *(.dynamic) } :text :dynamic
54
55 .rodata : { *(.rodata*) } :text
56
57 _end = .;
58 PROVIDE(end = .);
59
60 . = ALIGN(PAGE_SIZE);
61 PROVIDE(_vdso_data = .);
62
63 /DISCARD/ : {
64 *(.note.GNU-stack)
65 *(.data .data.* .gnu.linkonce.d.* .sdata*)
66 *(.bss .sbss .dynbss .dynsbss)
67 }
68}
69
70/*
71 * We must supply the ELF program headers explicitly to get just one
72 * PT_LOAD segment, and set the flags explicitly to make segments read-only.
73 */
74PHDRS
75{
76 text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
77 dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
78 note PT_NOTE FLAGS(4); /* PF_R */
79 eh_frame_hdr PT_GNU_EH_FRAME;
80}
81
82/*
83 * This controls what symbols we export from the DSO.
84 */
85VERSION
86{
87 LINUX_2.6.39 {
88 global:
89 __kernel_rt_sigreturn;
90 __kernel_gettimeofday;
91 __kernel_clock_gettime;
92 __kernel_clock_getres;
93 local: *;
94 };
95}
96
97/*
98 * Make the sigreturn code visible to the kernel.
99 */
100VDSO_sigtramp = __kernel_rt_sigreturn;
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
new file mode 100644
index 000000000000..3fae2be8b016
--- /dev/null
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -0,0 +1,126 @@
1/*
2 * ld script to make ARM Linux kernel
3 * taken from the i386 version by Russell King
4 * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
5 */
6
7#include <asm-generic/vmlinux.lds.h>
8#include <asm/thread_info.h>
9#include <asm/memory.h>
10#include <asm/page.h>
11
12#define ARM_EXIT_KEEP(x)
13#define ARM_EXIT_DISCARD(x) x
14
15OUTPUT_ARCH(aarch64)
16ENTRY(stext)
17
18jiffies = jiffies_64;
19
20SECTIONS
21{
22 /*
23 * XXX: The linker does not define how output sections are
24 * assigned to input sections when there are multiple statements
25 * matching the same input section name. There is no documented
26 * order of matching.
27 */
28 /DISCARD/ : {
29 ARM_EXIT_DISCARD(EXIT_TEXT)
30 ARM_EXIT_DISCARD(EXIT_DATA)
31 EXIT_CALL
32 *(.discard)
33 *(.discard.*)
34 }
35
36 . = PAGE_OFFSET + TEXT_OFFSET;
37
38 .head.text : {
39 _text = .;
40 HEAD_TEXT
41 }
42 .text : { /* Real text segment */
43 _stext = .; /* Text and read-only data */
44 *(.smp.pen.text)
45 __exception_text_start = .;
46 *(.exception.text)
47 __exception_text_end = .;
48 IRQENTRY_TEXT
49 TEXT_TEXT
50 SCHED_TEXT
51 LOCK_TEXT
52 *(.fixup)
53 *(.gnu.warning)
54 . = ALIGN(16);
55 *(.got) /* Global offset table */
56 }
57
58 RO_DATA(PAGE_SIZE)
59
60 _etext = .; /* End of text and rodata section */
61
62 . = ALIGN(PAGE_SIZE);
63 __init_begin = .;
64
65 INIT_TEXT_SECTION(8)
66 .exit.text : {
67 ARM_EXIT_KEEP(EXIT_TEXT)
68 }
69 . = ALIGN(16);
70 .init.data : {
71 INIT_DATA
72 INIT_SETUP(16)
73 INIT_CALLS
74 CON_INITCALL
75 SECURITY_INITCALL
76 INIT_RAM_FS
77 }
78 .exit.data : {
79 ARM_EXIT_KEEP(EXIT_DATA)
80 }
81
82 PERCPU_SECTION(64)
83
84 __init_end = .;
85 . = ALIGN(THREAD_SIZE);
86 __data_loc = .;
87
88 .data : AT(__data_loc) {
89 _data = .; /* address in memory */
90 _sdata = .;
91
92 /*
93 * first, the init task union, aligned
94 * to an 8192 byte boundary.
95 */
96 INIT_TASK_DATA(THREAD_SIZE)
97 NOSAVE_DATA
98 CACHELINE_ALIGNED_DATA(64)
99 READ_MOSTLY_DATA(64)
100
101 /*
102 * The exception fixup table (might need resorting at runtime)
103 */
104 . = ALIGN(32);
105 __start___ex_table = .;
106 *(__ex_table)
107 __stop___ex_table = .;
108
109 /*
110 * and the usual data section
111 */
112 DATA_DATA
113 CONSTRUCTORS
114
115 _edata = .;
116 }
117 _edata_loc = __data_loc + SIZEOF(.data);
118
119 NOTES
120
121 BSS_SECTION(0, 0, 0)
122 _end = .;
123
124 STABS_DEBUG
125 .comment 0 : { *(.comment) }
126}
diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile
new file mode 100644
index 000000000000..2fb7f6092aae
--- /dev/null
+++ b/arch/arm64/lib/Makefile
@@ -0,0 +1,4 @@
1lib-y := bitops.o delay.o \
2 strncpy_from_user.o strnlen_user.o clear_user.o \
3 copy_from_user.o copy_to_user.o copy_in_user.o \
4 copy_page.o clear_page.o
diff --git a/arch/arm64/lib/bitops.c b/arch/arm64/lib/bitops.c
new file mode 100644
index 000000000000..aa4965e60acc
--- /dev/null
+++ b/arch/arm64/lib/bitops.c
@@ -0,0 +1,25 @@
1/*
2 * Copyright (C) 2012 ARM Limited
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/kernel.h>
18#include <linux/spinlock.h>
19#include <linux/atomic.h>
20
21#ifdef CONFIG_SMP
22arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = {
23 [0 ... (ATOMIC_HASH_SIZE-1)] = __ARCH_SPIN_LOCK_UNLOCKED
24};
25#endif
diff --git a/arch/arm64/lib/clear_page.S b/arch/arm64/lib/clear_page.S
new file mode 100644
index 000000000000..ef08e905e35b
--- /dev/null
+++ b/arch/arm64/lib/clear_page.S
@@ -0,0 +1,39 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/linkage.h>
18#include <linux/const.h>
19#include <asm/assembler.h>
20#include <asm/page.h>
21
22/*
23 * Clear page @dest
24 *
25 * Parameters:
26 * x0 - dest
27 */
28ENTRY(clear_page)
29 mrs x1, dczid_el0
30 and w1, w1, #0xf
31 mov x2, #4
32 lsl x1, x2, x1
33
341: dc zva, x0
35 add x0, x0, x1
36 tst x0, #(PAGE_SIZE - 1)
37 b.ne 1b
38 ret
39ENDPROC(clear_page)
diff --git a/arch/arm64/lib/clear_user.S b/arch/arm64/lib/clear_user.S
new file mode 100644
index 000000000000..6e0ed93d51fe
--- /dev/null
+++ b/arch/arm64/lib/clear_user.S
@@ -0,0 +1,58 @@
1/*
2 * Based on arch/arm/lib/clear_user.S
3 *
4 * Copyright (C) 2012 ARM Ltd.
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#include <linux/linkage.h>
19#include <asm/assembler.h>
20
21 .text
22
23/* Prototype: int __clear_user(void *addr, size_t sz)
24 * Purpose : clear some user memory
25 * Params : addr - user memory address to clear
26 * : sz - number of bytes to clear
27 * Returns : number of bytes NOT cleared
28 *
29 * Alignment fixed up by hardware.
30 */
31ENTRY(__clear_user)
32 mov x2, x1 // save the size for fixup return
33 subs x1, x1, #8
34 b.mi 2f
351:
36USER(9f, str xzr, [x0], #8 )
37 subs x1, x1, #8
38 b.pl 1b
392: adds x1, x1, #4
40 b.mi 3f
41USER(9f, str wzr, [x0], #4 )
42 sub x1, x1, #4
433: adds x1, x1, #2
44 b.mi 4f
45USER(9f, strh wzr, [x0], #2 )
46 sub x1, x1, #2
474: adds x1, x1, #1
48 b.mi 5f
49 strb wzr, [x0]
505: mov x0, #0
51 ret
52ENDPROC(__clear_user)
53
54 .section .fixup,"ax"
55 .align 2
569: mov x0, x2 // return the original size
57 ret
58 .previous
diff --git a/arch/arm64/lib/copy_from_user.S b/arch/arm64/lib/copy_from_user.S
new file mode 100644
index 000000000000..5e27add9d362
--- /dev/null
+++ b/arch/arm64/lib/copy_from_user.S
@@ -0,0 +1,66 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/linkage.h>
18#include <asm/assembler.h>
19
20/*
21 * Copy from user space to a kernel buffer (alignment handled by the hardware)
22 *
23 * Parameters:
24 * x0 - to
25 * x1 - from
26 * x2 - n
27 * Returns:
28 * x0 - bytes not copied
29 */
30ENTRY(__copy_from_user)
31 add x4, x1, x2 // upper user buffer boundary
32 subs x2, x2, #8
33 b.mi 2f
341:
35USER(9f, ldr x3, [x1], #8 )
36 subs x2, x2, #8
37 str x3, [x0], #8
38 b.pl 1b
392: adds x2, x2, #4
40 b.mi 3f
41USER(9f, ldr w3, [x1], #4 )
42 sub x2, x2, #4
43 str w3, [x0], #4
443: adds x2, x2, #2
45 b.mi 4f
46USER(9f, ldrh w3, [x1], #2 )
47 sub x2, x2, #2
48 strh w3, [x0], #2
494: adds x2, x2, #1
50 b.mi 5f
51USER(9f, ldrb w3, [x1] )
52 strb w3, [x0]
535: mov x0, #0
54 ret
55ENDPROC(__copy_from_user)
56
57 .section .fixup,"ax"
58 .align 2
599: sub x2, x4, x1
60 mov x3, x2
6110: strb wzr, [x0], #1 // zero remaining buffer space
62 subs x3, x3, #1
63 b.ne 10b
64 mov x0, x2 // bytes not copied
65 ret
66 .previous
diff --git a/arch/arm64/lib/copy_in_user.S b/arch/arm64/lib/copy_in_user.S
new file mode 100644
index 000000000000..84b6c9bb9b93
--- /dev/null
+++ b/arch/arm64/lib/copy_in_user.S
@@ -0,0 +1,63 @@
1/*
2 * Copy from user space to user space
3 *
4 * Copyright (C) 2012 ARM Ltd.
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/linkage.h>
20#include <asm/assembler.h>
21
22/*
23 * Copy from user space to user space (alignment handled by the hardware)
24 *
25 * Parameters:
26 * x0 - to
27 * x1 - from
28 * x2 - n
29 * Returns:
30 * x0 - bytes not copied
31 */
32ENTRY(__copy_in_user)
33 add x4, x0, x2 // upper user buffer boundary
34 subs x2, x2, #8
35 b.mi 2f
361:
37USER(9f, ldr x3, [x1], #8 )
38 subs x2, x2, #8
39USER(9f, str x3, [x0], #8 )
40 b.pl 1b
412: adds x2, x2, #4
42 b.mi 3f
43USER(9f, ldr w3, [x1], #4 )
44 sub x2, x2, #4
45USER(9f, str w3, [x0], #4 )
463: adds x2, x2, #2
47 b.mi 4f
48USER(9f, ldrh w3, [x1], #2 )
49 sub x2, x2, #2
50USER(9f, strh w3, [x0], #2 )
514: adds x2, x2, #1
52 b.mi 5f
53USER(9f, ldrb w3, [x1] )
54USER(9f, strb w3, [x0] )
555: mov x0, #0
56 ret
57ENDPROC(__copy_in_user)
58
59 .section .fixup,"ax"
60 .align 2
619: sub x0, x4, x0 // bytes not copied
62 ret
63 .previous
diff --git a/arch/arm64/lib/copy_page.S b/arch/arm64/lib/copy_page.S
new file mode 100644
index 000000000000..512b9a7b980e
--- /dev/null
+++ b/arch/arm64/lib/copy_page.S
@@ -0,0 +1,46 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/linkage.h>
18#include <linux/const.h>
19#include <asm/assembler.h>
20#include <asm/page.h>
21
22/*
23 * Copy a page from src to dest (both are page aligned)
24 *
25 * Parameters:
26 * x0 - dest
27 * x1 - src
28 */
29ENTRY(copy_page)
30 /* Assume cache line size is 64 bytes. */
31 prfm pldl1strm, [x1, #64]
321: ldp x2, x3, [x1]
33 ldp x4, x5, [x1, #16]
34 ldp x6, x7, [x1, #32]
35 ldp x8, x9, [x1, #48]
36 add x1, x1, #64
37 prfm pldl1strm, [x1, #64]
38 stnp x2, x3, [x0]
39 stnp x4, x5, [x0, #16]
40 stnp x6, x7, [x0, #32]
41 stnp x8, x9, [x0, #48]
42 add x0, x0, #64
43 tst x1, #(PAGE_SIZE - 1)
44 b.ne 1b
45 ret
46ENDPROC(copy_page)
diff --git a/arch/arm64/lib/copy_to_user.S b/arch/arm64/lib/copy_to_user.S
new file mode 100644
index 000000000000..a0aeeb9b7a28
--- /dev/null
+++ b/arch/arm64/lib/copy_to_user.S
@@ -0,0 +1,61 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/linkage.h>
18#include <asm/assembler.h>
19
20/*
21 * Copy to user space from a kernel buffer (alignment handled by the hardware)
22 *
23 * Parameters:
24 * x0 - to
25 * x1 - from
26 * x2 - n
27 * Returns:
28 * x0 - bytes not copied
29 */
30ENTRY(__copy_to_user)
31 add x4, x0, x2 // upper user buffer boundary
32 subs x2, x2, #8
33 b.mi 2f
341:
35 ldr x3, [x1], #8
36 subs x2, x2, #8
37USER(9f, str x3, [x0], #8 )
38 b.pl 1b
392: adds x2, x2, #4
40 b.mi 3f
41 ldr w3, [x1], #4
42 sub x2, x2, #4
43USER(9f, str w3, [x0], #4 )
443: adds x2, x2, #2
45 b.mi 4f
46 ldrh w3, [x1], #2
47 sub x2, x2, #2
48USER(9f, strh w3, [x0], #2 )
494: adds x2, x2, #1
50 b.mi 5f
51 ldrb w3, [x1]
52USER(9f, strb w3, [x0] )
535: mov x0, #0
54 ret
55ENDPROC(__copy_to_user)
56
57 .section .fixup,"ax"
58 .align 2
599: sub x0, x4, x0 // bytes not copied
60 ret
61 .previous
diff --git a/arch/arm64/lib/delay.c b/arch/arm64/lib/delay.c
new file mode 100644
index 000000000000..dad4ec9bbfd1
--- /dev/null
+++ b/arch/arm64/lib/delay.c
@@ -0,0 +1,55 @@
1/*
2 * Delay loops based on the OpenRISC implementation.
3 *
4 * Copyright (C) 2012 ARM Limited
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Author: Will Deacon <will.deacon@arm.com>
19 */
20
21#include <linux/delay.h>
22#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/timex.h>
26
27void __delay(unsigned long cycles)
28{
29 cycles_t start = get_cycles();
30
31 while ((get_cycles() - start) < cycles)
32 cpu_relax();
33}
34EXPORT_SYMBOL(__delay);
35
36inline void __const_udelay(unsigned long xloops)
37{
38 unsigned long loops;
39
40 loops = xloops * loops_per_jiffy * HZ;
41 __delay(loops >> 32);
42}
43EXPORT_SYMBOL(__const_udelay);
44
45void __udelay(unsigned long usecs)
46{
47 __const_udelay(usecs * 0x10C7UL); /* 2**32 / 1000000 (rounded up) */
48}
49EXPORT_SYMBOL(__udelay);
50
51void __ndelay(unsigned long nsecs)
52{
53 __const_udelay(nsecs * 0x5UL); /* 2**32 / 1000000000 (rounded up) */
54}
55EXPORT_SYMBOL(__ndelay);
diff --git a/arch/arm64/lib/strncpy_from_user.S b/arch/arm64/lib/strncpy_from_user.S
new file mode 100644
index 000000000000..56e448a831a0
--- /dev/null
+++ b/arch/arm64/lib/strncpy_from_user.S
@@ -0,0 +1,50 @@
1/*
2 * Based on arch/arm/lib/strncpy_from_user.S
3 *
4 * Copyright (C) 1995-2000 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/linkage.h>
21#include <asm/assembler.h>
22#include <asm/errno.h>
23
24 .text
25 .align 5
26
27/*
28 * Copy a string from user space to kernel space.
29 * x0 = dst, x1 = src, x2 = byte length
30 * returns the number of characters copied (strlen of copied string),
31 * -EFAULT on exception, or "len" if we fill the whole buffer
32 */
33ENTRY(__strncpy_from_user)
34 mov x4, x1
351: subs x2, x2, #1
36 bmi 2f
37USER(9f, ldrb w3, [x1], #1 )
38 strb w3, [x0], #1
39 cbnz w3, 1b
40 sub x1, x1, #1 // take NUL character out of count
412: sub x0, x1, x4
42 ret
43ENDPROC(__strncpy_from_user)
44
45 .section .fixup,"ax"
46 .align 0
479: strb wzr, [x0] // null terminate
48 mov x0, #-EFAULT
49 ret
50 .previous
diff --git a/arch/arm64/lib/strnlen_user.S b/arch/arm64/lib/strnlen_user.S
new file mode 100644
index 000000000000..7f7b176a5646
--- /dev/null
+++ b/arch/arm64/lib/strnlen_user.S
@@ -0,0 +1,47 @@
1/*
2 * Based on arch/arm/lib/strnlen_user.S
3 *
4 * Copyright (C) 1995-2000 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/linkage.h>
21#include <asm/assembler.h>
22#include <asm/errno.h>
23
24 .text
25 .align 5
26
27/* Prototype: unsigned long __strnlen_user(const char *str, long n)
28 * Purpose : get length of a string in user memory
29 * Params : str - address of string in user memory
30 * Returns : length of string *including terminator*
31 * or zero on exception, or n if too long
32 */
33ENTRY(__strnlen_user)
34 mov x2, x0
351: subs x1, x1, #1
36 b.mi 2f
37USER(9f, ldrb w3, [x0], #1 )
38 cbnz w3, 1b
392: sub x0, x0, x2
40 ret
41ENDPROC(__strnlen_user)
42
43 .section .fixup,"ax"
44 .align 0
459: mov x0, #0
46 ret
47 .previous
diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
new file mode 100644
index 000000000000..3140a2abcdc2
--- /dev/null
+++ b/arch/arm64/mm/Makefile
@@ -0,0 +1,4 @@
1obj-y := dma-mapping.o extable.o fault.o init.o \
2 cache.o copypage.o flush.o \
3 ioremap.o mmap.o pgd.o mmu.o \
4 context.o tlb.o proc.o
diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S
new file mode 100644
index 000000000000..abe69b80cf7f
--- /dev/null
+++ b/arch/arm64/mm/cache.S
@@ -0,0 +1,168 @@
1/*
2 * Cache maintenance
3 *
4 * Copyright (C) 2001 Deep Blue Solutions Ltd.
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/linkage.h>
21#include <linux/init.h>
22#include <asm/assembler.h>
23
24#include "proc-macros.S"
25
26/*
27 * __flush_dcache_all()
28 *
29 * Flush the whole D-cache.
30 *
31 * Corrupted registers: x0-x7, x9-x11
32 */
33ENTRY(__flush_dcache_all)
34 dsb sy // ensure ordering with previous memory accesses
35 mrs x0, clidr_el1 // read clidr
36 and x3, x0, #0x7000000 // extract loc from clidr
37 lsr x3, x3, #23 // left align loc bit field
38 cbz x3, finished // if loc is 0, then no need to clean
39 mov x10, #0 // start clean at cache level 0
40loop1:
41 add x2, x10, x10, lsr #1 // work out 3x current cache level
42 lsr x1, x0, x2 // extract cache type bits from clidr
43 and x1, x1, #7 // mask of the bits for current cache only
44 cmp x1, #2 // see what cache we have at this level
45 b.lt skip // skip if no cache, or just i-cache
46 save_and_disable_irqs x9 // make CSSELR and CCSIDR access atomic
47 msr csselr_el1, x10 // select current cache level in csselr
48 isb // isb to sych the new cssr&csidr
49 mrs x1, ccsidr_el1 // read the new ccsidr
50 restore_irqs x9
51 and x2, x1, #7 // extract the length of the cache lines
52 add x2, x2, #4 // add 4 (line length offset)
53 mov x4, #0x3ff
54 and x4, x4, x1, lsr #3 // find maximum number on the way size
55 clz x5, x4 // find bit position of way size increment
56 mov x7, #0x7fff
57 and x7, x7, x1, lsr #13 // extract max number of the index size
58loop2:
59 mov x9, x4 // create working copy of max way size
60loop3:
61 lsl x6, x9, x5
62 orr x11, x10, x6 // factor way and cache number into x11
63 lsl x6, x7, x2
64 orr x11, x11, x6 // factor index number into x11
65 dc cisw, x11 // clean & invalidate by set/way
66 subs x9, x9, #1 // decrement the way
67 b.ge loop3
68 subs x7, x7, #1 // decrement the index
69 b.ge loop2
70skip:
71 add x10, x10, #2 // increment cache number
72 cmp x3, x10
73 b.gt loop1
74finished:
75 mov x10, #0 // swith back to cache level 0
76 msr csselr_el1, x10 // select current cache level in csselr
77 dsb sy
78 isb
79 ret
80ENDPROC(__flush_dcache_all)
81
82/*
83 * flush_cache_all()
84 *
85 * Flush the entire cache system. The data cache flush is now achieved
86 * using atomic clean / invalidates working outwards from L1 cache. This
87 * is done using Set/Way based cache maintainance instructions. The
88 * instruction cache can still be invalidated back to the point of
89 * unification in a single instruction.
90 */
91ENTRY(flush_cache_all)
92 mov x12, lr
93 bl __flush_dcache_all
94 mov x0, #0
95 ic ialluis // I+BTB cache invalidate
96 ret x12
97ENDPROC(flush_cache_all)
98
99/*
100 * flush_icache_range(start,end)
101 *
102 * Ensure that the I and D caches are coherent within specified region.
103 * This is typically used when code has been written to a memory region,
104 * and will be executed.
105 *
106 * - start - virtual start address of region
107 * - end - virtual end address of region
108 */
109ENTRY(flush_icache_range)
110 /* FALLTHROUGH */
111
112/*
113 * __flush_cache_user_range(start,end)
114 *
115 * Ensure that the I and D caches are coherent within specified region.
116 * This is typically used when code has been written to a memory region,
117 * and will be executed.
118 *
119 * - start - virtual start address of region
120 * - end - virtual end address of region
121 */
122ENTRY(__flush_cache_user_range)
123 dcache_line_size x2, x3
124 sub x3, x2, #1
125 bic x4, x0, x3
1261:
127USER(9f, dc cvau, x4 ) // clean D line to PoU
128 add x4, x4, x2
129 cmp x4, x1
130 b.lo 1b
131 dsb sy
132
133 icache_line_size x2, x3
134 sub x3, x2, #1
135 bic x4, x0, x3
1361:
137USER(9f, ic ivau, x4 ) // invalidate I line PoU
138 add x4, x4, x2
139 cmp x4, x1
140 b.lo 1b
1419: // ignore any faulting cache operation
142 dsb sy
143 isb
144 ret
145ENDPROC(flush_icache_range)
146ENDPROC(__flush_cache_user_range)
147
148/*
149 * __flush_kern_dcache_page(kaddr)
150 *
151 * Ensure that the data held in the page kaddr is written back to the
152 * page in question.
153 *
154 * - kaddr - kernel address
155 * - size - size in question
156 */
157ENTRY(__flush_dcache_area)
158 dcache_line_size x2, x3
159 add x1, x0, x1
160 sub x3, x2, #1
161 bic x0, x0, x3
1621: dc civac, x0 // clean & invalidate D line / unified line
163 add x0, x0, x2
164 cmp x0, x1
165 b.lo 1b
166 dsb sy
167 ret
168ENDPROC(__flush_dcache_area)
diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c
new file mode 100644
index 000000000000..baa758d37021
--- /dev/null
+++ b/arch/arm64/mm/context.c
@@ -0,0 +1,159 @@
1/*
2 * Based on arch/arm/mm/context.c
3 *
4 * Copyright (C) 2002-2003 Deep Blue Solutions Ltd, all rights reserved.
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/init.h>
21#include <linux/sched.h>
22#include <linux/mm.h>
23#include <linux/smp.h>
24#include <linux/percpu.h>
25
26#include <asm/mmu_context.h>
27#include <asm/tlbflush.h>
28#include <asm/cachetype.h>
29
30#define asid_bits(reg) \
31 (((read_cpuid(ID_AA64MMFR0_EL1) & 0xf0) >> 2) + 8)
32
33#define ASID_FIRST_VERSION (1 << MAX_ASID_BITS)
34
35static DEFINE_RAW_SPINLOCK(cpu_asid_lock);
36unsigned int cpu_last_asid = ASID_FIRST_VERSION;
37
38/*
39 * We fork()ed a process, and we need a new context for the child to run in.
40 */
41void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
42{
43 mm->context.id = 0;
44 raw_spin_lock_init(&mm->context.id_lock);
45}
46
47static void flush_context(void)
48{
49 /* set the reserved TTBR0 before flushing the TLB */
50 cpu_set_reserved_ttbr0();
51 flush_tlb_all();
52 if (icache_is_aivivt())
53 __flush_icache_all();
54}
55
56#ifdef CONFIG_SMP
57
58static void set_mm_context(struct mm_struct *mm, unsigned int asid)
59{
60 unsigned long flags;
61
62 /*
63 * Locking needed for multi-threaded applications where the same
64 * mm->context.id could be set from different CPUs during the
65 * broadcast. This function is also called via IPI so the
66 * mm->context.id_lock has to be IRQ-safe.
67 */
68 raw_spin_lock_irqsave(&mm->context.id_lock, flags);
69 if (likely((mm->context.id ^ cpu_last_asid) >> MAX_ASID_BITS)) {
70 /*
71 * Old version of ASID found. Set the new one and reset
72 * mm_cpumask(mm).
73 */
74 mm->context.id = asid;
75 cpumask_clear(mm_cpumask(mm));
76 }
77 raw_spin_unlock_irqrestore(&mm->context.id_lock, flags);
78
79 /*
80 * Set the mm_cpumask(mm) bit for the current CPU.
81 */
82 cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
83}
84
85/*
86 * Reset the ASID on the current CPU. This function call is broadcast from the
87 * CPU handling the ASID rollover and holding cpu_asid_lock.
88 */
89static void reset_context(void *info)
90{
91 unsigned int asid;
92 unsigned int cpu = smp_processor_id();
93 struct mm_struct *mm = current->active_mm;
94
95 smp_rmb();
96 asid = cpu_last_asid + cpu;
97
98 flush_context();
99 set_mm_context(mm, asid);
100
101 /* set the new ASID */
102 cpu_switch_mm(mm->pgd, mm);
103}
104
105#else
106
107static inline void set_mm_context(struct mm_struct *mm, unsigned int asid)
108{
109 mm->context.id = asid;
110 cpumask_copy(mm_cpumask(mm), cpumask_of(smp_processor_id()));
111}
112
113#endif
114
115void __new_context(struct mm_struct *mm)
116{
117 unsigned int asid;
118 unsigned int bits = asid_bits();
119
120 raw_spin_lock(&cpu_asid_lock);
121#ifdef CONFIG_SMP
122 /*
123 * Check the ASID again, in case the change was broadcast from another
124 * CPU before we acquired the lock.
125 */
126 if (!unlikely((mm->context.id ^ cpu_last_asid) >> MAX_ASID_BITS)) {
127 cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
128 raw_spin_unlock(&cpu_asid_lock);
129 return;
130 }
131#endif
132 /*
133 * At this point, it is guaranteed that the current mm (with an old
134 * ASID) isn't active on any other CPU since the ASIDs are changed
135 * simultaneously via IPI.
136 */
137 asid = ++cpu_last_asid;
138
139 /*
140 * If we've used up all our ASIDs, we need to start a new version and
141 * flush the TLB.
142 */
143 if (unlikely((asid & ((1 << bits) - 1)) == 0)) {
144 /* increment the ASID version */
145 cpu_last_asid += (1 << MAX_ASID_BITS) - (1 << bits);
146 if (cpu_last_asid == 0)
147 cpu_last_asid = ASID_FIRST_VERSION;
148 asid = cpu_last_asid + smp_processor_id();
149 flush_context();
150#ifdef CONFIG_SMP
151 smp_wmb();
152 smp_call_function(reset_context, NULL, 1);
153#endif
154 cpu_last_asid += NR_CPUS - 1;
155 }
156
157 set_mm_context(mm, asid);
158 raw_spin_unlock(&cpu_asid_lock);
159}
diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
new file mode 100644
index 000000000000..9aecbace4128
--- /dev/null
+++ b/arch/arm64/mm/copypage.c
@@ -0,0 +1,34 @@
1/*
2 * Based on arch/arm/mm/copypage.c
3 *
4 * Copyright (C) 2002 Deep Blue Solutions Ltd, All Rights Reserved.
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/mm.h>
21
22#include <asm/page.h>
23#include <asm/cacheflush.h>
24
25void __cpu_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
26{
27 copy_page(kto, kfrom);
28 __flush_dcache_area(kto, PAGE_SIZE);
29}
30
31void __cpu_clear_user_page(void *kaddr, unsigned long vaddr)
32{
33 clear_page(kaddr);
34}
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
new file mode 100644
index 000000000000..5eb244453a5b
--- /dev/null
+++ b/arch/arm64/mm/dma-mapping.c
@@ -0,0 +1,79 @@
1/*
2 * SWIOTLB-based DMA API implementation
3 *
4 * Copyright (C) 2012 ARM Ltd.
5 * Author: Catalin Marinas <catalin.marinas@arm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/gfp.h>
21#include <linux/export.h>
22#include <linux/slab.h>
23#include <linux/dma-mapping.h>
24#include <linux/vmalloc.h>
25#include <linux/swiotlb.h>
26
27#include <asm/cacheflush.h>
28
29struct dma_map_ops *dma_ops;
30EXPORT_SYMBOL(dma_ops);
31
32static void *arm64_swiotlb_alloc_coherent(struct device *dev, size_t size,
33 dma_addr_t *dma_handle, gfp_t flags,
34 struct dma_attrs *attrs)
35{
36 if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
37 dev->coherent_dma_mask <= DMA_BIT_MASK(32))
38 flags |= GFP_DMA32;
39 return swiotlb_alloc_coherent(dev, size, dma_handle, flags);
40}
41
42static void arm64_swiotlb_free_coherent(struct device *dev, size_t size,
43 void *vaddr, dma_addr_t dma_handle,
44 struct dma_attrs *attrs)
45{
46 swiotlb_free_coherent(dev, size, vaddr, dma_handle);
47}
48
49static struct dma_map_ops arm64_swiotlb_dma_ops = {
50 .alloc = arm64_swiotlb_alloc_coherent,
51 .free = arm64_swiotlb_free_coherent,
52 .map_page = swiotlb_map_page,
53 .unmap_page = swiotlb_unmap_page,
54 .map_sg = swiotlb_map_sg_attrs,
55 .unmap_sg = swiotlb_unmap_sg_attrs,
56 .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
57 .sync_single_for_device = swiotlb_sync_single_for_device,
58 .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
59 .sync_sg_for_device = swiotlb_sync_sg_for_device,
60 .dma_supported = swiotlb_dma_supported,
61 .mapping_error = swiotlb_dma_mapping_error,
62};
63
64void __init swiotlb_init_with_default_size(size_t default_size, int verbose);
65
66void __init arm64_swiotlb_init(size_t max_size)
67{
68 dma_ops = &arm64_swiotlb_dma_ops;
69 swiotlb_init_with_default_size(min((size_t)SZ_64M, max_size), 1);
70}
71
72#define PREALLOC_DMA_DEBUG_ENTRIES 4096
73
74static int __init dma_debug_do_init(void)
75{
76 dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
77 return 0;
78}
79fs_initcall(dma_debug_do_init);
diff --git a/arch/arm64/mm/extable.c b/arch/arm64/mm/extable.c
new file mode 100644
index 000000000000..79444279ba8c
--- /dev/null
+++ b/arch/arm64/mm/extable.c
@@ -0,0 +1,17 @@
1/*
2 * Based on arch/arm/mm/extable.c
3 */
4
5#include <linux/module.h>
6#include <linux/uaccess.h>
7
8int fixup_exception(struct pt_regs *regs)
9{
10 const struct exception_table_entry *fixup;
11
12 fixup = search_exception_tables(instruction_pointer(regs));
13 if (fixup)
14 regs->pc = fixup->fixup;
15
16 return fixup != NULL;
17}
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
new file mode 100644
index 000000000000..1909a69983ca
--- /dev/null
+++ b/arch/arm64/mm/fault.c
@@ -0,0 +1,534 @@
1/*
2 * Based on arch/arm/mm/fault.c
3 *
4 * Copyright (C) 1995 Linus Torvalds
5 * Copyright (C) 1995-2004 Russell King
6 * Copyright (C) 2012 ARM Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <linux/module.h>
22#include <linux/signal.h>
23#include <linux/mm.h>
24#include <linux/hardirq.h>
25#include <linux/init.h>
26#include <linux/kprobes.h>
27#include <linux/uaccess.h>
28#include <linux/page-flags.h>
29#include <linux/sched.h>
30#include <linux/highmem.h>
31#include <linux/perf_event.h>
32
33#include <asm/exception.h>
34#include <asm/debug-monitors.h>
35#include <asm/system_misc.h>
36#include <asm/pgtable.h>
37#include <asm/tlbflush.h>
38
39/*
40 * Dump out the page tables associated with 'addr' in mm 'mm'.
41 */
42void show_pte(struct mm_struct *mm, unsigned long addr)
43{
44 pgd_t *pgd;
45
46 if (!mm)
47 mm = &init_mm;
48
49 pr_alert("pgd = %p\n", mm->pgd);
50 pgd = pgd_offset(mm, addr);
51 pr_alert("[%08lx] *pgd=%016llx", addr, pgd_val(*pgd));
52
53 do {
54 pud_t *pud;
55 pmd_t *pmd;
56 pte_t *pte;
57
58 if (pgd_none_or_clear_bad(pgd))
59 break;
60
61 pud = pud_offset(pgd, addr);
62 if (pud_none_or_clear_bad(pud))
63 break;
64
65 pmd = pmd_offset(pud, addr);
66 printk(", *pmd=%016llx", pmd_val(*pmd));
67 if (pmd_none_or_clear_bad(pmd))
68 break;
69
70 pte = pte_offset_map(pmd, addr);
71 printk(", *pte=%016llx", pte_val(*pte));
72 pte_unmap(pte);
73 } while(0);
74
75 printk("\n");
76}
77
78/*
79 * The kernel tried to access some page that wasn't present.
80 */
81static void __do_kernel_fault(struct mm_struct *mm, unsigned long addr,
82 unsigned int esr, struct pt_regs *regs)
83{
84 /*
85 * Are we prepared to handle this kernel fault?
86 */
87 if (fixup_exception(regs))
88 return;
89
90 /*
91 * No handler, we'll have to terminate things with extreme prejudice.
92 */
93 bust_spinlocks(1);
94 pr_alert("Unable to handle kernel %s at virtual address %08lx\n",
95 (addr < PAGE_SIZE) ? "NULL pointer dereference" :
96 "paging request", addr);
97
98 show_pte(mm, addr);
99 die("Oops", regs, esr);
100 bust_spinlocks(0);
101 do_exit(SIGKILL);
102}
103
104/*
105 * Something tried to access memory that isn't in our memory map. User mode
106 * accesses just cause a SIGSEGV
107 */
108static void __do_user_fault(struct task_struct *tsk, unsigned long addr,
109 unsigned int esr, unsigned int sig, int code,
110 struct pt_regs *regs)
111{
112 struct siginfo si;
113
114 if (show_unhandled_signals) {
115 pr_info("%s[%d]: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n",
116 tsk->comm, task_pid_nr(tsk), sig, addr, esr);
117 show_pte(tsk->mm, addr);
118 show_regs(regs);
119 }
120
121 tsk->thread.fault_address = addr;
122 si.si_signo = sig;
123 si.si_errno = 0;
124 si.si_code = code;
125 si.si_addr = (void __user *)addr;
126 force_sig_info(sig, &si, tsk);
127}
128
129void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *regs)
130{
131 struct task_struct *tsk = current;
132 struct mm_struct *mm = tsk->active_mm;
133
134 /*
135 * If we are in kernel mode at this point, we have no context to
136 * handle this fault with.
137 */
138 if (user_mode(regs))
139 __do_user_fault(tsk, addr, esr, SIGSEGV, SEGV_MAPERR, regs);
140 else
141 __do_kernel_fault(mm, addr, esr, regs);
142}
143
144#define VM_FAULT_BADMAP 0x010000
145#define VM_FAULT_BADACCESS 0x020000
146
147#define ESR_WRITE (1 << 6)
148#define ESR_LNX_EXEC (1 << 24)
149
150/*
151 * Check that the permissions on the VMA allow for the fault which occurred.
152 * If we encountered a write fault, we must have write permission, otherwise
153 * we allow any permission.
154 */
155static inline bool access_error(unsigned int esr, struct vm_area_struct *vma)
156{
157 unsigned int mask = VM_READ | VM_WRITE | VM_EXEC;
158
159 if (esr & ESR_WRITE)
160 mask = VM_WRITE;
161 if (esr & ESR_LNX_EXEC)
162 mask = VM_EXEC;
163
164 return vma->vm_flags & mask ? false : true;
165}
166
167static int __do_page_fault(struct mm_struct *mm, unsigned long addr,
168 unsigned int esr, unsigned int flags,
169 struct task_struct *tsk)
170{
171 struct vm_area_struct *vma;
172 int fault;
173
174 vma = find_vma(mm, addr);
175 fault = VM_FAULT_BADMAP;
176 if (unlikely(!vma))
177 goto out;
178 if (unlikely(vma->vm_start > addr))
179 goto check_stack;
180
181 /*
182 * Ok, we have a good vm_area for this memory access, so we can handle
183 * it.
184 */
185good_area:
186 if (access_error(esr, vma)) {
187 fault = VM_FAULT_BADACCESS;
188 goto out;
189 }
190
191 return handle_mm_fault(mm, vma, addr & PAGE_MASK, flags);
192
193check_stack:
194 if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr))
195 goto good_area;
196out:
197 return fault;
198}
199
200static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
201 struct pt_regs *regs)
202{
203 struct task_struct *tsk;
204 struct mm_struct *mm;
205 int fault, sig, code;
206 int write = esr & ESR_WRITE;
207 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
208 (write ? FAULT_FLAG_WRITE : 0);
209
210 tsk = current;
211 mm = tsk->mm;
212
213 /* Enable interrupts if they were enabled in the parent context. */
214 if (interrupts_enabled(regs))
215 local_irq_enable();
216
217 /*
218 * If we're in an interrupt or have no user context, we must not take
219 * the fault.
220 */
221 if (in_atomic() || !mm)
222 goto no_context;
223
224 /*
225 * As per x86, we may deadlock here. However, since the kernel only
226 * validly references user space from well defined areas of the code,
227 * we can bug out early if this is from code which shouldn't.
228 */
229 if (!down_read_trylock(&mm->mmap_sem)) {
230 if (!user_mode(regs) && !search_exception_tables(regs->pc))
231 goto no_context;
232retry:
233 down_read(&mm->mmap_sem);
234 } else {
235 /*
236 * The above down_read_trylock() might have succeeded in which
237 * case, we'll have missed the might_sleep() from down_read().
238 */
239 might_sleep();
240#ifdef CONFIG_DEBUG_VM
241 if (!user_mode(regs) && !search_exception_tables(regs->pc))
242 goto no_context;
243#endif
244 }
245
246 fault = __do_page_fault(mm, addr, esr, flags, tsk);
247
248 /*
249 * If we need to retry but a fatal signal is pending, handle the
250 * signal first. We do not need to release the mmap_sem because it
251 * would already be released in __lock_page_or_retry in mm/filemap.c.
252 */
253 if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
254 return 0;
255
256 /*
257 * Major/minor page fault accounting is only done on the initial
258 * attempt. If we go through a retry, it is extremely likely that the
259 * page will be found in page cache at that point.
260 */
261
262 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr);
263 if (flags & FAULT_FLAG_ALLOW_RETRY) {
264 if (fault & VM_FAULT_MAJOR) {
265 tsk->maj_flt++;
266 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs,
267 addr);
268 } else {
269 tsk->min_flt++;
270 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs,
271 addr);
272 }
273 if (fault & VM_FAULT_RETRY) {
274 /*
275 * Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk of
276 * starvation.
277 */
278 flags &= ~FAULT_FLAG_ALLOW_RETRY;
279 goto retry;
280 }
281 }
282
283 up_read(&mm->mmap_sem);
284
285 /*
286 * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR
287 */
288 if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP |
289 VM_FAULT_BADACCESS))))
290 return 0;
291
292 if (fault & VM_FAULT_OOM) {
293 /*
294 * We ran out of memory, call the OOM killer, and return to
295 * userspace (which will retry the fault, or kill us if we got
296 * oom-killed).
297 */
298 pagefault_out_of_memory();
299 return 0;
300 }
301
302 /*
303 * If we are in kernel mode at this point, we have no context to
304 * handle this fault with.
305 */
306 if (!user_mode(regs))
307 goto no_context;
308
309 if (fault & VM_FAULT_SIGBUS) {
310 /*
311 * We had some memory, but were unable to successfully fix up
312 * this page fault.
313 */
314 sig = SIGBUS;
315 code = BUS_ADRERR;
316 } else {
317 /*
318 * Something tried to access memory that isn't in our memory
319 * map.
320 */
321 sig = SIGSEGV;
322 code = fault == VM_FAULT_BADACCESS ?
323 SEGV_ACCERR : SEGV_MAPERR;
324 }
325
326 __do_user_fault(tsk, addr, esr, sig, code, regs);
327 return 0;
328
329no_context:
330 __do_kernel_fault(mm, addr, esr, regs);
331 return 0;
332}
333
334/*
335 * First Level Translation Fault Handler
336 *
337 * We enter here because the first level page table doesn't contain a valid
338 * entry for the address.
339 *
340 * If the address is in kernel space (>= TASK_SIZE), then we are probably
341 * faulting in the vmalloc() area.
342 *
343 * If the init_task's first level page tables contains the relevant entry, we
344 * copy the it to this task. If not, we send the process a signal, fixup the
345 * exception, or oops the kernel.
346 *
347 * NOTE! We MUST NOT take any locks for this case. We may be in an interrupt
348 * or a critical region, and should only copy the information from the master
349 * page table, nothing more.
350 */
351static int __kprobes do_translation_fault(unsigned long addr,
352 unsigned int esr,
353 struct pt_regs *regs)
354{
355 if (addr < TASK_SIZE)
356 return do_page_fault(addr, esr, regs);
357
358 do_bad_area(addr, esr, regs);
359 return 0;
360}
361
362/*
363 * Some section permission faults need to be handled gracefully. They can
364 * happen due to a __{get,put}_user during an oops.
365 */
366static int do_sect_fault(unsigned long addr, unsigned int esr,
367 struct pt_regs *regs)
368{
369 do_bad_area(addr, esr, regs);
370 return 0;
371}
372
373/*
374 * This abort handler always returns "fault".
375 */
376static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs)
377{
378 return 1;
379}
380
381static struct fault_info {
382 int (*fn)(unsigned long addr, unsigned int esr, struct pt_regs *regs);
383 int sig;
384 int code;
385 const char *name;
386} fault_info[] = {
387 { do_bad, SIGBUS, 0, "ttbr address size fault" },
388 { do_bad, SIGBUS, 0, "level 1 address size fault" },
389 { do_bad, SIGBUS, 0, "level 2 address size fault" },
390 { do_bad, SIGBUS, 0, "level 3 address size fault" },
391 { do_translation_fault, SIGSEGV, SEGV_MAPERR, "input address range fault" },
392 { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 1 translation fault" },
393 { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 2 translation fault" },
394 { do_page_fault, SIGSEGV, SEGV_MAPERR, "level 3 translation fault" },
395 { do_bad, SIGBUS, 0, "reserved access flag fault" },
396 { do_bad, SIGSEGV, SEGV_ACCERR, "level 1 access flag fault" },
397 { do_bad, SIGSEGV, SEGV_ACCERR, "level 2 access flag fault" },
398 { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 access flag fault" },
399 { do_bad, SIGBUS, 0, "reserved permission fault" },
400 { do_bad, SIGSEGV, SEGV_ACCERR, "level 1 permission fault" },
401 { do_sect_fault, SIGSEGV, SEGV_ACCERR, "level 2 permission fault" },
402 { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 permission fault" },
403 { do_bad, SIGBUS, 0, "synchronous external abort" },
404 { do_bad, SIGBUS, 0, "asynchronous external abort" },
405 { do_bad, SIGBUS, 0, "unknown 18" },
406 { do_bad, SIGBUS, 0, "unknown 19" },
407 { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
408 { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
409 { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
410 { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
411 { do_bad, SIGBUS, 0, "synchronous parity error" },
412 { do_bad, SIGBUS, 0, "asynchronous parity error" },
413 { do_bad, SIGBUS, 0, "unknown 26" },
414 { do_bad, SIGBUS, 0, "unknown 27" },
415 { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk" },
416 { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk" },
417 { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk" },
418 { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk" },
419 { do_bad, SIGBUS, 0, "unknown 32" },
420 { do_bad, SIGBUS, BUS_ADRALN, "alignment fault" },
421 { do_bad, SIGBUS, 0, "debug event" },
422 { do_bad, SIGBUS, 0, "unknown 35" },
423 { do_bad, SIGBUS, 0, "unknown 36" },
424 { do_bad, SIGBUS, 0, "unknown 37" },
425 { do_bad, SIGBUS, 0, "unknown 38" },
426 { do_bad, SIGBUS, 0, "unknown 39" },
427 { do_bad, SIGBUS, 0, "unknown 40" },
428 { do_bad, SIGBUS, 0, "unknown 41" },
429 { do_bad, SIGBUS, 0, "unknown 42" },
430 { do_bad, SIGBUS, 0, "unknown 43" },
431 { do_bad, SIGBUS, 0, "unknown 44" },
432 { do_bad, SIGBUS, 0, "unknown 45" },
433 { do_bad, SIGBUS, 0, "unknown 46" },
434 { do_bad, SIGBUS, 0, "unknown 47" },
435 { do_bad, SIGBUS, 0, "unknown 48" },
436 { do_bad, SIGBUS, 0, "unknown 49" },
437 { do_bad, SIGBUS, 0, "unknown 50" },
438 { do_bad, SIGBUS, 0, "unknown 51" },
439 { do_bad, SIGBUS, 0, "implementation fault (lockdown abort)" },
440 { do_bad, SIGBUS, 0, "unknown 53" },
441 { do_bad, SIGBUS, 0, "unknown 54" },
442 { do_bad, SIGBUS, 0, "unknown 55" },
443 { do_bad, SIGBUS, 0, "unknown 56" },
444 { do_bad, SIGBUS, 0, "unknown 57" },
445 { do_bad, SIGBUS, 0, "implementation fault (coprocessor abort)" },
446 { do_bad, SIGBUS, 0, "unknown 59" },
447 { do_bad, SIGBUS, 0, "unknown 60" },
448 { do_bad, SIGBUS, 0, "unknown 61" },
449 { do_bad, SIGBUS, 0, "unknown 62" },
450 { do_bad, SIGBUS, 0, "unknown 63" },
451};
452
453/*
454 * Dispatch a data abort to the relevant handler.
455 */
456asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
457 struct pt_regs *regs)
458{
459 const struct fault_info *inf = fault_info + (esr & 63);
460 struct siginfo info;
461
462 if (!inf->fn(addr, esr, regs))
463 return;
464
465 pr_alert("Unhandled fault: %s (0x%08x) at 0x%016lx\n",
466 inf->name, esr, addr);
467
468 info.si_signo = inf->sig;
469 info.si_errno = 0;
470 info.si_code = inf->code;
471 info.si_addr = (void __user *)addr;
472 arm64_notify_die("", regs, &info, esr);
473}
474
475/*
476 * Handle stack alignment exceptions.
477 */
478asmlinkage void __exception do_sp_pc_abort(unsigned long addr,
479 unsigned int esr,
480 struct pt_regs *regs)
481{
482 struct siginfo info;
483
484 info.si_signo = SIGBUS;
485 info.si_errno = 0;
486 info.si_code = BUS_ADRALN;
487 info.si_addr = (void __user *)addr;
488 arm64_notify_die("", regs, &info, esr);
489}
490
491static struct fault_info debug_fault_info[] = {
492 { do_bad, SIGTRAP, TRAP_HWBKPT, "hardware breakpoint" },
493 { do_bad, SIGTRAP, TRAP_HWBKPT, "hardware single-step" },
494 { do_bad, SIGTRAP, TRAP_HWBKPT, "hardware watchpoint" },
495 { do_bad, SIGBUS, 0, "unknown 3" },
496 { do_bad, SIGTRAP, TRAP_BRKPT, "aarch32 BKPT" },
497 { do_bad, SIGTRAP, 0, "aarch32 vector catch" },
498 { do_bad, SIGTRAP, TRAP_BRKPT, "aarch64 BRK" },
499 { do_bad, SIGBUS, 0, "unknown 7" },
500};
501
502void __init hook_debug_fault_code(int nr,
503 int (*fn)(unsigned long, unsigned int, struct pt_regs *),
504 int sig, int code, const char *name)
505{
506 BUG_ON(nr < 0 || nr >= ARRAY_SIZE(debug_fault_info));
507
508 debug_fault_info[nr].fn = fn;
509 debug_fault_info[nr].sig = sig;
510 debug_fault_info[nr].code = code;
511 debug_fault_info[nr].name = name;
512}
513
514asmlinkage int __exception do_debug_exception(unsigned long addr,
515 unsigned int esr,
516 struct pt_regs *regs)
517{
518 const struct fault_info *inf = debug_fault_info + DBG_ESR_EVT(esr);
519 struct siginfo info;
520
521 if (!inf->fn(addr, esr, regs))
522 return 1;
523
524 pr_alert("Unhandled debug exception: %s (0x%08x) at 0x%016lx\n",
525 inf->name, esr, addr);
526
527 info.si_signo = inf->sig;
528 info.si_errno = 0;
529 info.si_code = inf->code;
530 info.si_addr = (void __user *)addr;
531 arm64_notify_die("", regs, &info, esr);
532
533 return 0;
534}
diff --git a/arch/arm64/mm/flush.c b/arch/arm64/mm/flush.c
new file mode 100644
index 000000000000..c144adb1682f
--- /dev/null
+++ b/arch/arm64/mm/flush.c
@@ -0,0 +1,135 @@
1/*
2 * Based on arch/arm/mm/flush.c
3 *
4 * Copyright (C) 1995-2002 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/export.h>
21#include <linux/mm.h>
22#include <linux/pagemap.h>
23
24#include <asm/cacheflush.h>
25#include <asm/cachetype.h>
26#include <asm/tlbflush.h>
27
28#include "mm.h"
29
30void flush_cache_mm(struct mm_struct *mm)
31{
32}
33
34void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
35 unsigned long end)
36{
37 if (vma->vm_flags & VM_EXEC)
38 __flush_icache_all();
39}
40
41void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr,
42 unsigned long pfn)
43{
44}
45
46static void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
47 unsigned long uaddr, void *kaddr,
48 unsigned long len)
49{
50 if (vma->vm_flags & VM_EXEC) {
51 unsigned long addr = (unsigned long)kaddr;
52 if (icache_is_aliasing()) {
53 __flush_dcache_area(kaddr, len);
54 __flush_icache_all();
55 } else {
56 flush_icache_range(addr, addr + len);
57 }
58 }
59}
60
61/*
62 * Copy user data from/to a page which is mapped into a different processes
63 * address space. Really, we want to allow our "user space" model to handle
64 * this.
65 *
66 * Note that this code needs to run on the current CPU.
67 */
68void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
69 unsigned long uaddr, void *dst, const void *src,
70 unsigned long len)
71{
72#ifdef CONFIG_SMP
73 preempt_disable();
74#endif
75 memcpy(dst, src, len);
76 flush_ptrace_access(vma, page, uaddr, dst, len);
77#ifdef CONFIG_SMP
78 preempt_enable();
79#endif
80}
81
82void __flush_dcache_page(struct page *page)
83{
84 __flush_dcache_area(page_address(page), PAGE_SIZE);
85}
86
87void __sync_icache_dcache(pte_t pte, unsigned long addr)
88{
89 unsigned long pfn;
90 struct page *page;
91
92 pfn = pte_pfn(pte);
93 if (!pfn_valid(pfn))
94 return;
95
96 page = pfn_to_page(pfn);
97 if (!test_and_set_bit(PG_dcache_clean, &page->flags)) {
98 __flush_dcache_page(page);
99 __flush_icache_all();
100 } else if (icache_is_aivivt()) {
101 __flush_icache_all();
102 }
103}
104
105/*
106 * Ensure cache coherency between kernel mapping and userspace mapping of this
107 * page.
108 */
109void flush_dcache_page(struct page *page)
110{
111 struct address_space *mapping;
112
113 /*
114 * The zero page is never written to, so never has any dirty cache
115 * lines, and therefore never needs to be flushed.
116 */
117 if (page == ZERO_PAGE(0))
118 return;
119
120 mapping = page_mapping(page);
121 if (mapping && mapping_mapped(mapping)) {
122 __flush_dcache_page(page);
123 __flush_icache_all();
124 set_bit(PG_dcache_clean, &page->flags);
125 } else {
126 clear_bit(PG_dcache_clean, &page->flags);
127 }
128}
129EXPORT_SYMBOL(flush_dcache_page);
130
131/*
132 * Additional functions defined in assembly.
133 */
134EXPORT_SYMBOL(flush_cache_all);
135EXPORT_SYMBOL(flush_icache_range);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
new file mode 100644
index 000000000000..5f719ba949bc
--- /dev/null
+++ b/arch/arm64/mm/init.c
@@ -0,0 +1,437 @@
1/*
2 * Based on arch/arm/mm/init.c
3 *
4 * Copyright (C) 1995-2005 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/kernel.h>
21#include <linux/export.h>
22#include <linux/errno.h>
23#include <linux/swap.h>
24#include <linux/init.h>
25#include <linux/bootmem.h>
26#include <linux/mman.h>
27#include <linux/nodemask.h>
28#include <linux/initrd.h>
29#include <linux/gfp.h>
30#include <linux/memblock.h>
31#include <linux/sort.h>
32#include <linux/of_fdt.h>
33
34#include <asm/prom.h>
35#include <asm/sections.h>
36#include <asm/setup.h>
37#include <asm/sizes.h>
38#include <asm/tlb.h>
39
40#include "mm.h"
41
42static unsigned long phys_initrd_start __initdata = 0;
43static unsigned long phys_initrd_size __initdata = 0;
44
45phys_addr_t memstart_addr __read_mostly = 0;
46
47void __init early_init_dt_setup_initrd_arch(unsigned long start,
48 unsigned long end)
49{
50 phys_initrd_start = start;
51 phys_initrd_size = end - start;
52}
53
54static int __init early_initrd(char *p)
55{
56 unsigned long start, size;
57 char *endp;
58
59 start = memparse(p, &endp);
60 if (*endp == ',') {
61 size = memparse(endp + 1, NULL);
62
63 phys_initrd_start = start;
64 phys_initrd_size = size;
65 }
66 return 0;
67}
68early_param("initrd", early_initrd);
69
70#define MAX_DMA32_PFN ((4UL * 1024 * 1024 * 1024) >> PAGE_SHIFT)
71
72static void __init zone_sizes_init(unsigned long min, unsigned long max)
73{
74 struct memblock_region *reg;
75 unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
76 unsigned long max_dma32 = min;
77
78 memset(zone_size, 0, sizeof(zone_size));
79
80#ifdef CONFIG_ZONE_DMA32
81 /* 4GB maximum for 32-bit only capable devices */
82 max_dma32 = min(max, MAX_DMA32_PFN);
83 zone_size[ZONE_DMA32] = max_dma32 - min;
84#endif
85 zone_size[ZONE_NORMAL] = max - max_dma32;
86
87 memcpy(zhole_size, zone_size, sizeof(zhole_size));
88
89 for_each_memblock(memory, reg) {
90 unsigned long start = memblock_region_memory_base_pfn(reg);
91 unsigned long end = memblock_region_memory_end_pfn(reg);
92
93 if (start >= max)
94 continue;
95#ifdef CONFIG_ZONE_DMA32
96 if (start < max_dma32) {
97 unsigned long dma_end = min(end, max_dma32);
98 zhole_size[ZONE_DMA32] -= dma_end - start;
99 }
100#endif
101 if (end > max_dma32) {
102 unsigned long normal_end = min(end, max);
103 unsigned long normal_start = max(start, max_dma32);
104 zhole_size[ZONE_NORMAL] -= normal_end - normal_start;
105 }
106 }
107
108 free_area_init_node(0, zone_size, min, zhole_size);
109}
110
111#ifdef CONFIG_HAVE_ARCH_PFN_VALID
112int pfn_valid(unsigned long pfn)
113{
114 return memblock_is_memory(pfn << PAGE_SHIFT);
115}
116EXPORT_SYMBOL(pfn_valid);
117#endif
118
119#ifndef CONFIG_SPARSEMEM
120static void arm64_memory_present(void)
121{
122}
123#else
124static void arm64_memory_present(void)
125{
126 struct memblock_region *reg;
127
128 for_each_memblock(memory, reg)
129 memory_present(0, memblock_region_memory_base_pfn(reg),
130 memblock_region_memory_end_pfn(reg));
131}
132#endif
133
134void __init arm64_memblock_init(void)
135{
136 u64 *reserve_map, base, size;
137
138 /* Register the kernel text, kernel data and initrd with memblock */
139 memblock_reserve(__pa(_text), _end - _text);
140#ifdef CONFIG_BLK_DEV_INITRD
141 if (phys_initrd_size) {
142 memblock_reserve(phys_initrd_start, phys_initrd_size);
143
144 /* Now convert initrd to virtual addresses */
145 initrd_start = __phys_to_virt(phys_initrd_start);
146 initrd_end = initrd_start + phys_initrd_size;
147 }
148#endif
149
150 /*
151 * Reserve the page tables. These are already in use,
152 * and can only be in node 0.
153 */
154 memblock_reserve(__pa(swapper_pg_dir), SWAPPER_DIR_SIZE);
155 memblock_reserve(__pa(idmap_pg_dir), IDMAP_DIR_SIZE);
156
157 /* Reserve the dtb region */
158 memblock_reserve(virt_to_phys(initial_boot_params),
159 be32_to_cpu(initial_boot_params->totalsize));
160
161 /*
162 * Process the reserve map. This will probably overlap the initrd
163 * and dtb locations which are already reserved, but overlapping
164 * doesn't hurt anything
165 */
166 reserve_map = ((void*)initial_boot_params) +
167 be32_to_cpu(initial_boot_params->off_mem_rsvmap);
168 while (1) {
169 base = be64_to_cpup(reserve_map++);
170 size = be64_to_cpup(reserve_map++);
171 if (!size)
172 break;
173 memblock_reserve(base, size);
174 }
175
176 memblock_allow_resize();
177 memblock_dump_all();
178}
179
180void __init bootmem_init(void)
181{
182 unsigned long min, max;
183
184 min = PFN_UP(memblock_start_of_DRAM());
185 max = PFN_DOWN(memblock_end_of_DRAM());
186
187 /*
188 * Sparsemem tries to allocate bootmem in memory_present(), so must be
189 * done after the fixed reservations.
190 */
191 arm64_memory_present();
192
193 sparse_init();
194 zone_sizes_init(min, max);
195
196 high_memory = __va((max << PAGE_SHIFT) - 1) + 1;
197 max_pfn = max_low_pfn = max;
198}
199
200static inline int free_area(unsigned long pfn, unsigned long end, char *s)
201{
202 unsigned int pages = 0, size = (end - pfn) << (PAGE_SHIFT - 10);
203
204 for (; pfn < end; pfn++) {
205 struct page *page = pfn_to_page(pfn);
206 ClearPageReserved(page);
207 init_page_count(page);
208 __free_page(page);
209 pages++;
210 }
211
212 if (size && s)
213 pr_info("Freeing %s memory: %dK\n", s, size);
214
215 return pages;
216}
217
218/*
219 * Poison init memory with an undefined instruction (0x0).
220 */
221static inline void poison_init_mem(void *s, size_t count)
222{
223 memset(s, 0, count);
224}
225
226#ifndef CONFIG_SPARSEMEM_VMEMMAP
227static inline void free_memmap(unsigned long start_pfn, unsigned long end_pfn)
228{
229 struct page *start_pg, *end_pg;
230 unsigned long pg, pgend;
231
232 /*
233 * Convert start_pfn/end_pfn to a struct page pointer.
234 */
235 start_pg = pfn_to_page(start_pfn - 1) + 1;
236 end_pg = pfn_to_page(end_pfn - 1) + 1;
237
238 /*
239 * Convert to physical addresses, and round start upwards and end
240 * downwards.
241 */
242 pg = (unsigned long)PAGE_ALIGN(__pa(start_pg));
243 pgend = (unsigned long)__pa(end_pg) & PAGE_MASK;
244
245 /*
246 * If there are free pages between these, free the section of the
247 * memmap array.
248 */
249 if (pg < pgend)
250 free_bootmem(pg, pgend - pg);
251}
252
253/*
254 * The mem_map array can get very big. Free the unused area of the memory map.
255 */
256static void __init free_unused_memmap(void)
257{
258 unsigned long start, prev_end = 0;
259 struct memblock_region *reg;
260
261 for_each_memblock(memory, reg) {
262 start = __phys_to_pfn(reg->base);
263
264#ifdef CONFIG_SPARSEMEM
265 /*
266 * Take care not to free memmap entries that don't exist due
267 * to SPARSEMEM sections which aren't present.
268 */
269 start = min(start, ALIGN(prev_end, PAGES_PER_SECTION));
270#endif
271 /*
272 * If we had a previous bank, and there is a space between the
273 * current bank and the previous, free it.
274 */
275 if (prev_end && prev_end < start)
276 free_memmap(prev_end, start);
277
278 /*
279 * Align up here since the VM subsystem insists that the
280 * memmap entries are valid from the bank end aligned to
281 * MAX_ORDER_NR_PAGES.
282 */
283 prev_end = ALIGN(start + __phys_to_pfn(reg->size),
284 MAX_ORDER_NR_PAGES);
285 }
286
287#ifdef CONFIG_SPARSEMEM
288 if (!IS_ALIGNED(prev_end, PAGES_PER_SECTION))
289 free_memmap(prev_end, ALIGN(prev_end, PAGES_PER_SECTION));
290#endif
291}
292#endif /* !CONFIG_SPARSEMEM_VMEMMAP */
293
294/*
295 * mem_init() marks the free areas in the mem_map and tells us how much memory
296 * is free. This is done after various parts of the system have claimed their
297 * memory after the kernel image.
298 */
299void __init mem_init(void)
300{
301 unsigned long reserved_pages, free_pages;
302 struct memblock_region *reg;
303
304#if CONFIG_SWIOTLB
305 extern void __init arm64_swiotlb_init(size_t max_size);
306 arm64_swiotlb_init(max_pfn << (PAGE_SHIFT - 1));
307#endif
308
309 max_mapnr = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
310
311#ifndef CONFIG_SPARSEMEM_VMEMMAP
312 /* this will put all unused low memory onto the freelists */
313 free_unused_memmap();
314#endif
315
316 totalram_pages += free_all_bootmem();
317
318 reserved_pages = free_pages = 0;
319
320 for_each_memblock(memory, reg) {
321 unsigned int pfn1, pfn2;
322 struct page *page, *end;
323
324 pfn1 = __phys_to_pfn(reg->base);
325 pfn2 = pfn1 + __phys_to_pfn(reg->size);
326
327 page = pfn_to_page(pfn1);
328 end = pfn_to_page(pfn2 - 1) + 1;
329
330 do {
331 if (PageReserved(page))
332 reserved_pages++;
333 else if (!page_count(page))
334 free_pages++;
335 page++;
336 } while (page < end);
337 }
338
339 /*
340 * Since our memory may not be contiguous, calculate the real number
341 * of pages we have in this system.
342 */
343 pr_info("Memory:");
344 num_physpages = 0;
345 for_each_memblock(memory, reg) {
346 unsigned long pages = memblock_region_memory_end_pfn(reg) -
347 memblock_region_memory_base_pfn(reg);
348 num_physpages += pages;
349 printk(" %ldMB", pages >> (20 - PAGE_SHIFT));
350 }
351 printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
352
353 pr_notice("Memory: %luk/%luk available, %luk reserved\n",
354 nr_free_pages() << (PAGE_SHIFT-10),
355 free_pages << (PAGE_SHIFT-10),
356 reserved_pages << (PAGE_SHIFT-10));
357
358#define MLK(b, t) b, t, ((t) - (b)) >> 10
359#define MLM(b, t) b, t, ((t) - (b)) >> 20
360#define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K)
361
362 pr_notice("Virtual kernel memory layout:\n"
363 " vmalloc : 0x%16lx - 0x%16lx (%6ld MB)\n"
364#ifdef CONFIG_SPARSEMEM_VMEMMAP
365 " vmemmap : 0x%16lx - 0x%16lx (%6ld MB)\n"
366#endif
367 " modules : 0x%16lx - 0x%16lx (%6ld MB)\n"
368 " memory : 0x%16lx - 0x%16lx (%6ld MB)\n"
369 " .init : 0x%p" " - 0x%p" " (%6ld kB)\n"
370 " .text : 0x%p" " - 0x%p" " (%6ld kB)\n"
371 " .data : 0x%p" " - 0x%p" " (%6ld kB)\n",
372 MLM(VMALLOC_START, VMALLOC_END),
373#ifdef CONFIG_SPARSEMEM_VMEMMAP
374 MLM((unsigned long)virt_to_page(PAGE_OFFSET),
375 (unsigned long)virt_to_page(high_memory)),
376#endif
377 MLM(MODULES_VADDR, MODULES_END),
378 MLM(PAGE_OFFSET, (unsigned long)high_memory),
379
380 MLK_ROUNDUP(__init_begin, __init_end),
381 MLK_ROUNDUP(_text, _etext),
382 MLK_ROUNDUP(_sdata, _edata));
383
384#undef MLK
385#undef MLM
386#undef MLK_ROUNDUP
387
388 /*
389 * Check boundaries twice: Some fundamental inconsistencies can be
390 * detected at build time already.
391 */
392#ifdef CONFIG_COMPAT
393 BUILD_BUG_ON(TASK_SIZE_32 > TASK_SIZE_64);
394#endif
395 BUILD_BUG_ON(TASK_SIZE_64 > MODULES_VADDR);
396 BUG_ON(TASK_SIZE_64 > MODULES_VADDR);
397
398 if (PAGE_SIZE >= 16384 && num_physpages <= 128) {
399 extern int sysctl_overcommit_memory;
400 /*
401 * On a machine this small we won't get anywhere without
402 * overcommit, so turn it on by default.
403 */
404 sysctl_overcommit_memory = OVERCOMMIT_ALWAYS;
405 }
406}
407
408void free_initmem(void)
409{
410 poison_init_mem(__init_begin, __init_end - __init_begin);
411 totalram_pages += free_area(__phys_to_pfn(__pa(__init_begin)),
412 __phys_to_pfn(__pa(__init_end)),
413 "init");
414}
415
416#ifdef CONFIG_BLK_DEV_INITRD
417
418static int keep_initrd;
419
420void free_initrd_mem(unsigned long start, unsigned long end)
421{
422 if (!keep_initrd) {
423 poison_init_mem((void *)start, PAGE_ALIGN(end) - start);
424 totalram_pages += free_area(__phys_to_pfn(__pa(start)),
425 __phys_to_pfn(__pa(end)),
426 "initrd");
427 }
428}
429
430static int __init keepinitrd_setup(char *__unused)
431{
432 keep_initrd = 1;
433 return 1;
434}
435
436__setup("keepinitrd", keepinitrd_setup);
437#endif
diff --git a/arch/arm64/mm/ioremap.c b/arch/arm64/mm/ioremap.c
new file mode 100644
index 000000000000..1725cd6db37a
--- /dev/null
+++ b/arch/arm64/mm/ioremap.c
@@ -0,0 +1,84 @@
1/*
2 * Based on arch/arm/mm/ioremap.c
3 *
4 * (C) Copyright 1995 1996 Linus Torvalds
5 * Hacked for ARM by Phil Blundell <philb@gnu.org>
6 * Hacked to allow all architectures to build, and various cleanups
7 * by Russell King
8 * Copyright (C) 2012 ARM Ltd.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23#include <linux/export.h>
24#include <linux/mm.h>
25#include <linux/vmalloc.h>
26#include <linux/io.h>
27
28static void __iomem *__ioremap_caller(phys_addr_t phys_addr, size_t size,
29 pgprot_t prot, void *caller)
30{
31 unsigned long last_addr;
32 unsigned long offset = phys_addr & ~PAGE_MASK;
33 int err;
34 unsigned long addr;
35 struct vm_struct *area;
36
37 /*
38 * Page align the mapping address and size, taking account of any
39 * offset.
40 */
41 phys_addr &= PAGE_MASK;
42 size = PAGE_ALIGN(size + offset);
43
44 /*
45 * Don't allow wraparound, zero size or outside PHYS_MASK.
46 */
47 last_addr = phys_addr + size - 1;
48 if (!size || last_addr < phys_addr || (last_addr & ~PHYS_MASK))
49 return NULL;
50
51 /*
52 * Don't allow RAM to be mapped.
53 */
54 if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr))))
55 return NULL;
56
57 area = get_vm_area_caller(size, VM_IOREMAP, caller);
58 if (!area)
59 return NULL;
60 addr = (unsigned long)area->addr;
61
62 err = ioremap_page_range(addr, addr + size, phys_addr, prot);
63 if (err) {
64 vunmap((void *)addr);
65 return NULL;
66 }
67
68 return (void __iomem *)(offset + addr);
69}
70
71void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot)
72{
73 return __ioremap_caller(phys_addr, size, prot,
74 __builtin_return_address(0));
75}
76EXPORT_SYMBOL(__ioremap);
77
78void __iounmap(volatile void __iomem *io_addr)
79{
80 void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr);
81
82 vunmap(addr);
83}
84EXPORT_SYMBOL(__iounmap);
diff --git a/arch/arm64/mm/mm.h b/arch/arm64/mm/mm.h
new file mode 100644
index 000000000000..d8d6e7851c14
--- /dev/null
+++ b/arch/arm64/mm/mm.h
@@ -0,0 +1,2 @@
1extern void __flush_dcache_page(struct page *page);
2extern void __init bootmem_init(void);
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
new file mode 100644
index 000000000000..7c7be7855638
--- /dev/null
+++ b/arch/arm64/mm/mmap.c
@@ -0,0 +1,144 @@
1/*
2 * Based on arch/arm/mm/mmap.c
3 *
4 * Copyright (C) 2012 ARM Ltd.
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/elf.h>
20#include <linux/fs.h>
21#include <linux/mm.h>
22#include <linux/mman.h>
23#include <linux/export.h>
24#include <linux/shm.h>
25#include <linux/sched.h>
26#include <linux/io.h>
27#include <linux/personality.h>
28#include <linux/random.h>
29
30#include <asm/cputype.h>
31
32/*
33 * Leave enough space between the mmap area and the stack to honour ulimit in
34 * the face of randomisation.
35 */
36#define MIN_GAP (SZ_128M + ((STACK_RND_MASK << PAGE_SHIFT) + 1))
37#define MAX_GAP (STACK_TOP/6*5)
38
39static int mmap_is_legacy(void)
40{
41 if (current->personality & ADDR_COMPAT_LAYOUT)
42 return 1;
43
44 if (rlimit(RLIMIT_STACK) == RLIM_INFINITY)
45 return 1;
46
47 return sysctl_legacy_va_layout;
48}
49
50/*
51 * Since get_random_int() returns the same value within a 1 jiffy window, we
52 * will almost always get the same randomisation for the stack and mmap
53 * region. This will mean the relative distance between stack and mmap will be
54 * the same.
55 *
56 * To avoid this we can shift the randomness by 1 bit.
57 */
58static unsigned long mmap_rnd(void)
59{
60 unsigned long rnd = 0;
61
62 if (current->flags & PF_RANDOMIZE)
63 rnd = (long)get_random_int() & (STACK_RND_MASK >> 1);
64
65 return rnd << (PAGE_SHIFT + 1);
66}
67
68static unsigned long mmap_base(void)
69{
70 unsigned long gap = rlimit(RLIMIT_STACK);
71
72 if (gap < MIN_GAP)
73 gap = MIN_GAP;
74 else if (gap > MAX_GAP)
75 gap = MAX_GAP;
76
77 return PAGE_ALIGN(STACK_TOP - gap - mmap_rnd());
78}
79
80/*
81 * This function, called very early during the creation of a new process VM
82 * image, sets up which VM layout function to use:
83 */
84void arch_pick_mmap_layout(struct mm_struct *mm)
85{
86 /*
87 * Fall back to the standard layout if the personality bit is set, or
88 * if the expected stack growth is unlimited:
89 */
90 if (mmap_is_legacy()) {
91 mm->mmap_base = TASK_UNMAPPED_BASE;
92 mm->get_unmapped_area = arch_get_unmapped_area;
93 mm->unmap_area = arch_unmap_area;
94 } else {
95 mm->mmap_base = mmap_base();
96 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
97 mm->unmap_area = arch_unmap_area_topdown;
98 }
99}
100EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
101
102
103/*
104 * You really shouldn't be using read() or write() on /dev/mem. This might go
105 * away in the future.
106 */
107int valid_phys_addr_range(unsigned long addr, size_t size)
108{
109 if (addr < PHYS_OFFSET)
110 return 0;
111 if (addr + size > __pa(high_memory - 1) + 1)
112 return 0;
113
114 return 1;
115}
116
117/*
118 * Do not allow /dev/mem mappings beyond the supported physical range.
119 */
120int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
121{
122 return !(((pfn << PAGE_SHIFT) + size) & ~PHYS_MASK);
123}
124
125#ifdef CONFIG_STRICT_DEVMEM
126
127#include <linux/ioport.h>
128
129/*
130 * devmem_is_allowed() checks to see if /dev/mem access to a certain address
131 * is valid. The argument is a physical page number. We mimic x86 here by
132 * disallowing access to system RAM as well as device-exclusive MMIO regions.
133 * This effectively disable read()/write() on /dev/mem.
134 */
135int devmem_is_allowed(unsigned long pfn)
136{
137 if (iomem_is_exclusive(pfn << PAGE_SHIFT))
138 return 0;
139 if (!page_is_ram(pfn))
140 return 1;
141 return 0;
142}
143
144#endif
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
new file mode 100644
index 000000000000..a6885d896ab6
--- /dev/null
+++ b/arch/arm64/mm/mmu.c
@@ -0,0 +1,395 @@
1/*
2 * Based on arch/arm/mm/mmu.c
3 *
4 * Copyright (C) 1995-2005 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/export.h>
21#include <linux/kernel.h>
22#include <linux/errno.h>
23#include <linux/init.h>
24#include <linux/mman.h>
25#include <linux/nodemask.h>
26#include <linux/memblock.h>
27#include <linux/fs.h>
28
29#include <asm/cputype.h>
30#include <asm/sections.h>
31#include <asm/setup.h>
32#include <asm/sizes.h>
33#include <asm/tlb.h>
34#include <asm/mmu_context.h>
35
36#include "mm.h"
37
38/*
39 * Empty_zero_page is a special page that is used for zero-initialized data
40 * and COW.
41 */
42struct page *empty_zero_page;
43EXPORT_SYMBOL(empty_zero_page);
44
45pgprot_t pgprot_default;
46EXPORT_SYMBOL(pgprot_default);
47
48static pmdval_t prot_sect_kernel;
49
50struct cachepolicy {
51 const char policy[16];
52 u64 mair;
53 u64 tcr;
54};
55
56static struct cachepolicy cache_policies[] __initdata = {
57 {
58 .policy = "uncached",
59 .mair = 0x44, /* inner, outer non-cacheable */
60 .tcr = TCR_IRGN_NC | TCR_ORGN_NC,
61 }, {
62 .policy = "writethrough",
63 .mair = 0xaa, /* inner, outer write-through, read-allocate */
64 .tcr = TCR_IRGN_WT | TCR_ORGN_WT,
65 }, {
66 .policy = "writeback",
67 .mair = 0xee, /* inner, outer write-back, read-allocate */
68 .tcr = TCR_IRGN_WBnWA | TCR_ORGN_WBnWA,
69 }
70};
71
72/*
73 * These are useful for identifying cache coherency problems by allowing the
74 * cache or the cache and writebuffer to be turned off. It changes the Normal
75 * memory caching attributes in the MAIR_EL1 register.
76 */
77static int __init early_cachepolicy(char *p)
78{
79 int i;
80 u64 tmp;
81
82 for (i = 0; i < ARRAY_SIZE(cache_policies); i++) {
83 int len = strlen(cache_policies[i].policy);
84
85 if (memcmp(p, cache_policies[i].policy, len) == 0)
86 break;
87 }
88 if (i == ARRAY_SIZE(cache_policies)) {
89 pr_err("ERROR: unknown or unsupported cache policy: %s\n", p);
90 return 0;
91 }
92
93 flush_cache_all();
94
95 /*
96 * Modify MT_NORMAL attributes in MAIR_EL1.
97 */
98 asm volatile(
99 " mrs %0, mair_el1\n"
100 " bfi %0, %1, #%2, #8\n"
101 " msr mair_el1, %0\n"
102 " isb\n"
103 : "=&r" (tmp)
104 : "r" (cache_policies[i].mair), "i" (MT_NORMAL * 8));
105
106 /*
107 * Modify TCR PTW cacheability attributes.
108 */
109 asm volatile(
110 " mrs %0, tcr_el1\n"
111 " bic %0, %0, %2\n"
112 " orr %0, %0, %1\n"
113 " msr tcr_el1, %0\n"
114 " isb\n"
115 : "=&r" (tmp)
116 : "r" (cache_policies[i].tcr), "r" (TCR_IRGN_MASK | TCR_ORGN_MASK));
117
118 flush_cache_all();
119
120 return 0;
121}
122early_param("cachepolicy", early_cachepolicy);
123
124/*
125 * Adjust the PMD section entries according to the CPU in use.
126 */
127static void __init init_mem_pgprot(void)
128{
129 pteval_t default_pgprot;
130 int i;
131
132 default_pgprot = PTE_ATTRINDX(MT_NORMAL);
133 prot_sect_kernel = PMD_TYPE_SECT | PMD_SECT_AF | PMD_ATTRINDX(MT_NORMAL);
134
135#ifdef CONFIG_SMP
136 /*
137 * Mark memory with the "shared" attribute for SMP systems
138 */
139 default_pgprot |= PTE_SHARED;
140 prot_sect_kernel |= PMD_SECT_S;
141#endif
142
143 for (i = 0; i < 16; i++) {
144 unsigned long v = pgprot_val(protection_map[i]);
145 protection_map[i] = __pgprot(v | default_pgprot);
146 }
147
148 pgprot_default = __pgprot(PTE_TYPE_PAGE | PTE_AF | default_pgprot);
149}
150
151pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
152 unsigned long size, pgprot_t vma_prot)
153{
154 if (!pfn_valid(pfn))
155 return pgprot_noncached(vma_prot);
156 else if (file->f_flags & O_SYNC)
157 return pgprot_writecombine(vma_prot);
158 return vma_prot;
159}
160EXPORT_SYMBOL(phys_mem_access_prot);
161
162static void __init *early_alloc(unsigned long sz)
163{
164 void *ptr = __va(memblock_alloc(sz, sz));
165 memset(ptr, 0, sz);
166 return ptr;
167}
168
169static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
170 unsigned long end, unsigned long pfn)
171{
172 pte_t *pte;
173
174 if (pmd_none(*pmd)) {
175 pte = early_alloc(PTRS_PER_PTE * sizeof(pte_t));
176 __pmd_populate(pmd, __pa(pte), PMD_TYPE_TABLE);
177 }
178 BUG_ON(pmd_bad(*pmd));
179
180 pte = pte_offset_kernel(pmd, addr);
181 do {
182 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
183 pfn++;
184 } while (pte++, addr += PAGE_SIZE, addr != end);
185}
186
187static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
188 unsigned long end, phys_addr_t phys)
189{
190 pmd_t *pmd;
191 unsigned long next;
192
193 /*
194 * Check for initial section mappings in the pgd/pud and remove them.
195 */
196 if (pud_none(*pud) || pud_bad(*pud)) {
197 pmd = early_alloc(PTRS_PER_PMD * sizeof(pmd_t));
198 pud_populate(&init_mm, pud, pmd);
199 }
200
201 pmd = pmd_offset(pud, addr);
202 do {
203 next = pmd_addr_end(addr, end);
204 /* try section mapping first */
205 if (((addr | next | phys) & ~SECTION_MASK) == 0)
206 set_pmd(pmd, __pmd(phys | prot_sect_kernel));
207 else
208 alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys));
209 phys += next - addr;
210 } while (pmd++, addr = next, addr != end);
211}
212
213static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
214 unsigned long end, unsigned long phys)
215{
216 pud_t *pud = pud_offset(pgd, addr);
217 unsigned long next;
218
219 do {
220 next = pud_addr_end(addr, end);
221 alloc_init_pmd(pud, addr, next, phys);
222 phys += next - addr;
223 } while (pud++, addr = next, addr != end);
224}
225
226/*
227 * Create the page directory entries and any necessary page tables for the
228 * mapping specified by 'md'.
229 */
230static void __init create_mapping(phys_addr_t phys, unsigned long virt,
231 phys_addr_t size)
232{
233 unsigned long addr, length, end, next;
234 pgd_t *pgd;
235
236 if (virt < VMALLOC_START) {
237 pr_warning("BUG: not creating mapping for 0x%016llx at 0x%016lx - outside kernel range\n",
238 phys, virt);
239 return;
240 }
241
242 addr = virt & PAGE_MASK;
243 length = PAGE_ALIGN(size + (virt & ~PAGE_MASK));
244
245 pgd = pgd_offset_k(addr);
246 end = addr + length;
247 do {
248 next = pgd_addr_end(addr, end);
249 alloc_init_pud(pgd, addr, next, phys);
250 phys += next - addr;
251 } while (pgd++, addr = next, addr != end);
252}
253
254static void __init map_mem(void)
255{
256 struct memblock_region *reg;
257
258 /* map all the memory banks */
259 for_each_memblock(memory, reg) {
260 phys_addr_t start = reg->base;
261 phys_addr_t end = start + reg->size;
262
263 if (start >= end)
264 break;
265
266 create_mapping(start, __phys_to_virt(start), end - start);
267 }
268}
269
270/*
271 * paging_init() sets up the page tables, initialises the zone memory
272 * maps and sets up the zero page.
273 */
274void __init paging_init(void)
275{
276 void *zero_page;
277
278 /*
279 * Maximum PGDIR_SIZE addressable via the initial direct kernel
280 * mapping in swapper_pg_dir.
281 */
282 memblock_set_current_limit((PHYS_OFFSET & PGDIR_MASK) + PGDIR_SIZE);
283
284 init_mem_pgprot();
285 map_mem();
286
287 /*
288 * Finally flush the caches and tlb to ensure that we're in a
289 * consistent state.
290 */
291 flush_cache_all();
292 flush_tlb_all();
293
294 /* allocate the zero page. */
295 zero_page = early_alloc(PAGE_SIZE);
296
297 bootmem_init();
298
299 empty_zero_page = virt_to_page(zero_page);
300 __flush_dcache_page(empty_zero_page);
301
302 /*
303 * TTBR0 is only used for the identity mapping at this stage. Make it
304 * point to zero page to avoid speculatively fetching new entries.
305 */
306 cpu_set_reserved_ttbr0();
307 flush_tlb_all();
308}
309
310/*
311 * Enable the identity mapping to allow the MMU disabling.
312 */
313void setup_mm_for_reboot(void)
314{
315 cpu_switch_mm(idmap_pg_dir, &init_mm);
316 flush_tlb_all();
317}
318
319/*
320 * Check whether a kernel address is valid (derived from arch/x86/).
321 */
322int kern_addr_valid(unsigned long addr)
323{
324 pgd_t *pgd;
325 pud_t *pud;
326 pmd_t *pmd;
327 pte_t *pte;
328
329 if ((((long)addr) >> VA_BITS) != -1UL)
330 return 0;
331
332 pgd = pgd_offset_k(addr);
333 if (pgd_none(*pgd))
334 return 0;
335
336 pud = pud_offset(pgd, addr);
337 if (pud_none(*pud))
338 return 0;
339
340 pmd = pmd_offset(pud, addr);
341 if (pmd_none(*pmd))
342 return 0;
343
344 pte = pte_offset_kernel(pmd, addr);
345 if (pte_none(*pte))
346 return 0;
347
348 return pfn_valid(pte_pfn(*pte));
349}
350#ifdef CONFIG_SPARSEMEM_VMEMMAP
351#ifdef CONFIG_ARM64_64K_PAGES
352int __meminit vmemmap_populate(struct page *start_page,
353 unsigned long size, int node)
354{
355 return vmemmap_populate_basepages(start_page, size, node);
356}
357#else /* !CONFIG_ARM64_64K_PAGES */
358int __meminit vmemmap_populate(struct page *start_page,
359 unsigned long size, int node)
360{
361 unsigned long addr = (unsigned long)start_page;
362 unsigned long end = (unsigned long)(start_page + size);
363 unsigned long next;
364 pgd_t *pgd;
365 pud_t *pud;
366 pmd_t *pmd;
367
368 do {
369 next = pmd_addr_end(addr, end);
370
371 pgd = vmemmap_pgd_populate(addr, node);
372 if (!pgd)
373 return -ENOMEM;
374
375 pud = vmemmap_pud_populate(pgd, addr, node);
376 if (!pud)
377 return -ENOMEM;
378
379 pmd = pmd_offset(pud, addr);
380 if (pmd_none(*pmd)) {
381 void *p = NULL;
382
383 p = vmemmap_alloc_block_buf(PMD_SIZE, node);
384 if (!p)
385 return -ENOMEM;
386
387 set_pmd(pmd, __pmd(__pa(p) | prot_sect_kernel));
388 } else
389 vmemmap_verify((pte_t *)pmd, node, addr, next);
390 } while (addr = next, addr != end);
391
392 return 0;
393}
394#endif /* CONFIG_ARM64_64K_PAGES */
395#endif /* CONFIG_SPARSEMEM_VMEMMAP */
diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c
new file mode 100644
index 000000000000..7083cdada657
--- /dev/null
+++ b/arch/arm64/mm/pgd.c
@@ -0,0 +1,54 @@
1/*
2 * PGD allocation/freeing
3 *
4 * Copyright (C) 2012 ARM Ltd.
5 * Author: Catalin Marinas <catalin.marinas@arm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/mm.h>
21#include <linux/gfp.h>
22#include <linux/highmem.h>
23#include <linux/slab.h>
24
25#include <asm/pgalloc.h>
26#include <asm/page.h>
27#include <asm/tlbflush.h>
28
29#include "mm.h"
30
31#define PGD_SIZE (PTRS_PER_PGD * sizeof(pgd_t))
32
33pgd_t *pgd_alloc(struct mm_struct *mm)
34{
35 pgd_t *new_pgd;
36
37 if (PGD_SIZE == PAGE_SIZE)
38 new_pgd = (pgd_t *)get_zeroed_page(GFP_KERNEL);
39 else
40 new_pgd = kzalloc(PGD_SIZE, GFP_KERNEL);
41
42 if (!new_pgd)
43 return NULL;
44
45 return new_pgd;
46}
47
48void pgd_free(struct mm_struct *mm, pgd_t *pgd)
49{
50 if (PGD_SIZE == PAGE_SIZE)
51 free_page((unsigned long)pgd);
52 else
53 kfree(pgd);
54}
diff --git a/arch/arm64/mm/proc-macros.S b/arch/arm64/mm/proc-macros.S
new file mode 100644
index 000000000000..8957b822010b
--- /dev/null
+++ b/arch/arm64/mm/proc-macros.S
@@ -0,0 +1,55 @@
1/*
2 * Based on arch/arm/mm/proc-macros.S
3 *
4 * Copyright (C) 2012 ARM Ltd.
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 program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <asm/asm-offsets.h>
20#include <asm/thread_info.h>
21
22/*
23 * vma_vm_mm - get mm pointer from vma pointer (vma->vm_mm)
24 */
25 .macro vma_vm_mm, rd, rn
26 ldr \rd, [\rn, #VMA_VM_MM]
27 .endm
28
29/*
30 * mmid - get context id from mm pointer (mm->context.id)
31 */
32 .macro mmid, rd, rn
33 ldr \rd, [\rn, #MM_CONTEXT_ID]
34 .endm
35
36/*
37 * dcache_line_size - get the minimum D-cache line size from the CTR register.
38 */
39 .macro dcache_line_size, reg, tmp
40 mrs \tmp, ctr_el0 // read CTR
41 lsr \tmp, \tmp, #16
42 and \tmp, \tmp, #0xf // cache line size encoding
43 mov \reg, #4 // bytes per word
44 lsl \reg, \reg, \tmp // actual cache line size
45 .endm
46
47/*
48 * icache_line_size - get the minimum I-cache line size from the CTR register.
49 */
50 .macro icache_line_size, reg, tmp
51 mrs \tmp, ctr_el0 // read CTR
52 and \tmp, \tmp, #0xf // cache line size encoding
53 mov \reg, #4 // bytes per word
54 lsl \reg, \reg, \tmp // actual cache line size
55 .endm
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
new file mode 100644
index 000000000000..f1d8b9bbfdad
--- /dev/null
+++ b/arch/arm64/mm/proc.S
@@ -0,0 +1,175 @@
1/*
2 * Based on arch/arm/mm/proc.S
3 *
4 * Copyright (C) 2001 Deep Blue Solutions Ltd.
5 * Copyright (C) 2012 ARM Ltd.
6 * Author: Catalin Marinas <catalin.marinas@arm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <linux/init.h>
22#include <linux/linkage.h>
23#include <asm/assembler.h>
24#include <asm/asm-offsets.h>
25#include <asm/hwcap.h>
26#include <asm/pgtable-hwdef.h>
27#include <asm/pgtable.h>
28
29#include "proc-macros.S"
30
31#ifndef CONFIG_SMP
32/* PTWs cacheable, inner/outer WBWA not shareable */
33#define TCR_FLAGS TCR_IRGN_WBWA | TCR_ORGN_WBWA
34#else
35/* PTWs cacheable, inner/outer WBWA shareable */
36#define TCR_FLAGS TCR_IRGN_WBWA | TCR_ORGN_WBWA | TCR_SHARED
37#endif
38
39#define MAIR(attr, mt) ((attr) << ((mt) * 8))
40
41/*
42 * cpu_cache_off()
43 *
44 * Turn the CPU D-cache off.
45 */
46ENTRY(cpu_cache_off)
47 mrs x0, sctlr_el1
48 bic x0, x0, #1 << 2 // clear SCTLR.C
49 msr sctlr_el1, x0
50 isb
51 ret
52ENDPROC(cpu_cache_off)
53
54/*
55 * cpu_reset(loc)
56 *
57 * Perform a soft reset of the system. Put the CPU into the same state
58 * as it would be if it had been reset, and branch to what would be the
59 * reset vector. It must be executed with the flat identity mapping.
60 *
61 * - loc - location to jump to for soft reset
62 */
63 .align 5
64ENTRY(cpu_reset)
65 mrs x1, sctlr_el1
66 bic x1, x1, #1
67 msr sctlr_el1, x1 // disable the MMU
68 isb
69 ret x0
70ENDPROC(cpu_reset)
71
72/*
73 * cpu_do_idle()
74 *
75 * Idle the processor (wait for interrupt).
76 */
77ENTRY(cpu_do_idle)
78 dsb sy // WFI may enter a low-power mode
79 wfi
80 ret
81ENDPROC(cpu_do_idle)
82
83/*
84 * cpu_switch_mm(pgd_phys, tsk)
85 *
86 * Set the translation table base pointer to be pgd_phys.
87 *
88 * - pgd_phys - physical address of new TTB
89 */
90ENTRY(cpu_do_switch_mm)
91 mmid w1, x1 // get mm->context.id
92 bfi x0, x1, #48, #16 // set the ASID
93 msr ttbr0_el1, x0 // set TTBR0
94 isb
95 ret
96ENDPROC(cpu_do_switch_mm)
97
98cpu_name:
99 .ascii "AArch64 Processor"
100 .align
101
102 .section ".text.init", #alloc, #execinstr
103
104/*
105 * __cpu_setup
106 *
107 * Initialise the processor for turning the MMU on. Return in x0 the
108 * value of the SCTLR_EL1 register.
109 */
110ENTRY(__cpu_setup)
111 /*
112 * Preserve the link register across the function call.
113 */
114 mov x28, lr
115 bl __flush_dcache_all
116 mov lr, x28
117 ic iallu // I+BTB cache invalidate
118 dsb sy
119
120 mov x0, #3 << 20
121 msr cpacr_el1, x0 // Enable FP/ASIMD
122 mov x0, #1
123 msr oslar_el1, x0 // Set the debug OS lock
124 tlbi vmalle1is // invalidate I + D TLBs
125 /*
126 * Memory region attributes for LPAE:
127 *
128 * n = AttrIndx[2:0]
129 * n MAIR
130 * DEVICE_nGnRnE 000 00000000
131 * DEVICE_nGnRE 001 00000100
132 * DEVICE_GRE 010 00001100
133 * NORMAL_NC 011 01000100
134 * NORMAL 100 11111111
135 */
136 ldr x5, =MAIR(0x00, MT_DEVICE_nGnRnE) | \
137 MAIR(0x04, MT_DEVICE_nGnRE) | \
138 MAIR(0x0c, MT_DEVICE_GRE) | \
139 MAIR(0x44, MT_NORMAL_NC) | \
140 MAIR(0xff, MT_NORMAL)
141 msr mair_el1, x5
142 /*
143 * Prepare SCTLR
144 */
145 adr x5, crval
146 ldp w5, w6, [x5]
147 mrs x0, sctlr_el1
148 bic x0, x0, x5 // clear bits
149 orr x0, x0, x6 // set bits
150 /*
151 * Set/prepare TCR and TTBR. We use 512GB (39-bit) address range for
152 * both user and kernel.
153 */
154 ldr x10, =TCR_TxSZ(VA_BITS) | TCR_FLAGS | TCR_IPS_40BIT | \
155 TCR_ASID16 | (1 << 31)
156#ifdef CONFIG_ARM64_64K_PAGES
157 orr x10, x10, TCR_TG0_64K
158 orr x10, x10, TCR_TG1_64K
159#endif
160 msr tcr_el1, x10
161 ret // return to head.S
162ENDPROC(__cpu_setup)
163
164 /*
165 * n n T
166 * U E WT T UD US IHBS
167 * CE0 XWHW CZ ME TEEA S
168 * .... .IEE .... NEAI TE.I ..AD DEN0 ACAM
169 * 0011 0... 1101 ..0. ..0. 10.. .... .... < hardware reserved
170 * .... .100 .... 01.1 11.1 ..01 0001 1101 < software settings
171 */
172 .type crval, #object
173crval:
174 .word 0x030802e2 // clear
175 .word 0x0405d11d // set
diff --git a/arch/arm64/mm/tlb.S b/arch/arm64/mm/tlb.S
new file mode 100644
index 000000000000..8ae80a18e8ec
--- /dev/null
+++ b/arch/arm64/mm/tlb.S
@@ -0,0 +1,71 @@
1/*
2 * Based on arch/arm/mm/tlb.S
3 *
4 * Copyright (C) 1997-2002 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 * Written by Catalin Marinas <catalin.marinas@arm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20#include <linux/linkage.h>
21#include <asm/assembler.h>
22#include <asm/asm-offsets.h>
23#include <asm/page.h>
24#include <asm/tlbflush.h>
25#include "proc-macros.S"
26
27/*
28 * __cpu_flush_user_tlb_range(start, end, vma)
29 *
30 * Invalidate a range of TLB entries in the specified address space.
31 *
32 * - start - start address (may not be aligned)
33 * - end - end address (exclusive, may not be aligned)
34 * - vma - vma_struct describing address range
35 */
36ENTRY(__cpu_flush_user_tlb_range)
37 vma_vm_mm x3, x2 // get vma->vm_mm
38 mmid x3, x3 // get vm_mm->context.id
39 dsb sy
40 lsr x0, x0, #12 // align address
41 lsr x1, x1, #12
42 bfi x0, x3, #48, #16 // start VA and ASID
43 bfi x1, x3, #48, #16 // end VA and ASID
441: tlbi vae1is, x0 // TLB invalidate by address and ASID
45 add x0, x0, #1
46 cmp x0, x1
47 b.lo 1b
48 dsb sy
49 ret
50ENDPROC(__cpu_flush_user_tlb_range)
51
52/*
53 * __cpu_flush_kern_tlb_range(start,end)
54 *
55 * Invalidate a range of kernel TLB entries.
56 *
57 * - start - start address (may not be aligned)
58 * - end - end address (exclusive, may not be aligned)
59 */
60ENTRY(__cpu_flush_kern_tlb_range)
61 dsb sy
62 lsr x0, x0, #12 // align address
63 lsr x1, x1, #12
641: tlbi vaae1is, x0 // TLB invalidate by address
65 add x0, x0, #1
66 cmp x0, x1
67 b.lo 1b
68 dsb sy
69 isb
70 ret
71ENDPROC(__cpu_flush_kern_tlb_range)
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index f34861920634..c7092e6057c5 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -38,6 +38,7 @@ config BLACKFIN
38 select GENERIC_ATOMIC64 38 select GENERIC_ATOMIC64
39 select GENERIC_IRQ_PROBE 39 select GENERIC_IRQ_PROBE
40 select IRQ_PER_CPU if SMP 40 select IRQ_PER_CPU if SMP
41 select USE_GENERIC_SMP_HELPERS if SMP
41 select HAVE_NMI_WATCHDOG if NMI_WATCHDOG 42 select HAVE_NMI_WATCHDOG if NMI_WATCHDOG
42 select GENERIC_SMP_IDLE_THREAD 43 select GENERIC_SMP_IDLE_THREAD
43 select ARCH_USES_GETTIMEOFFSET if !GENERIC_CLOCKEVENTS 44 select ARCH_USES_GETTIMEOFFSET if !GENERIC_CLOCKEVENTS
diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile
index d3d7e64ca96d..66cf00095b84 100644
--- a/arch/blackfin/Makefile
+++ b/arch/blackfin/Makefile
@@ -20,7 +20,6 @@ endif
20KBUILD_AFLAGS += $(call cc-option,-mno-fdpic) 20KBUILD_AFLAGS += $(call cc-option,-mno-fdpic)
21KBUILD_CFLAGS_MODULE += -mlong-calls 21KBUILD_CFLAGS_MODULE += -mlong-calls
22LDFLAGS += -m elf32bfin 22LDFLAGS += -m elf32bfin
23KALLSYMS += --symbol-prefix=_
24 23
25KBUILD_DEFCONFIG := BF537-STAMP_defconfig 24KBUILD_DEFCONFIG := BF537-STAMP_defconfig
26 25
diff --git a/arch/blackfin/include/asm/smp.h b/arch/blackfin/include/asm/smp.h
index dc3d144b4bb5..9631598dcc5d 100644
--- a/arch/blackfin/include/asm/smp.h
+++ b/arch/blackfin/include/asm/smp.h
@@ -18,6 +18,8 @@
18#define raw_smp_processor_id() blackfin_core_id() 18#define raw_smp_processor_id() blackfin_core_id()
19 19
20extern void bfin_relocate_coreb_l1_mem(void); 20extern void bfin_relocate_coreb_l1_mem(void);
21extern void arch_send_call_function_single_ipi(int cpu);
22extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
21 23
22#if defined(CONFIG_SMP) && defined(CONFIG_ICACHE_FLUSH_L1) 24#if defined(CONFIG_SMP) && defined(CONFIG_ICACHE_FLUSH_L1)
23asmlinkage void blackfin_icache_flush_range_l1(unsigned long *ptr); 25asmlinkage void blackfin_icache_flush_range_l1(unsigned long *ptr);
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c
index 00bbe672b3b3..a40151306b77 100644
--- a/arch/blackfin/mach-common/smp.c
+++ b/arch/blackfin/mach-common/smp.c
@@ -48,10 +48,13 @@ unsigned long blackfin_iflush_l1_entry[NR_CPUS];
48 48
49struct blackfin_initial_pda __cpuinitdata initial_pda_coreb; 49struct blackfin_initial_pda __cpuinitdata initial_pda_coreb;
50 50
51#define BFIN_IPI_TIMER 0 51enum ipi_message_type {
52#define BFIN_IPI_RESCHEDULE 1 52 BFIN_IPI_TIMER,
53#define BFIN_IPI_CALL_FUNC 2 53 BFIN_IPI_RESCHEDULE,
54#define BFIN_IPI_CPU_STOP 3 54 BFIN_IPI_CALL_FUNC,
55 BFIN_IPI_CALL_FUNC_SINGLE,
56 BFIN_IPI_CPU_STOP,
57};
55 58
56struct blackfin_flush_data { 59struct blackfin_flush_data {
57 unsigned long start; 60 unsigned long start;
@@ -60,35 +63,20 @@ struct blackfin_flush_data {
60 63
61void *secondary_stack; 64void *secondary_stack;
62 65
63
64struct smp_call_struct {
65 void (*func)(void *info);
66 void *info;
67 int wait;
68 cpumask_t *waitmask;
69};
70
71static struct blackfin_flush_data smp_flush_data; 66static struct blackfin_flush_data smp_flush_data;
72 67
73static DEFINE_SPINLOCK(stop_lock); 68static DEFINE_SPINLOCK(stop_lock);
74 69
75struct ipi_message {
76 unsigned long type;
77 struct smp_call_struct call_struct;
78};
79
80/* A magic number - stress test shows this is safe for common cases */ 70/* A magic number - stress test shows this is safe for common cases */
81#define BFIN_IPI_MSGQ_LEN 5 71#define BFIN_IPI_MSGQ_LEN 5
82 72
83/* Simple FIFO buffer, overflow leads to panic */ 73/* Simple FIFO buffer, overflow leads to panic */
84struct ipi_message_queue { 74struct ipi_data {
85 spinlock_t lock;
86 unsigned long count; 75 unsigned long count;
87 unsigned long head; /* head of the queue */ 76 unsigned long bits;
88 struct ipi_message ipi_message[BFIN_IPI_MSGQ_LEN];
89}; 77};
90 78
91static DEFINE_PER_CPU(struct ipi_message_queue, ipi_msg_queue); 79static DEFINE_PER_CPU(struct ipi_data, bfin_ipi);
92 80
93static void ipi_cpu_stop(unsigned int cpu) 81static void ipi_cpu_stop(unsigned int cpu)
94{ 82{
@@ -129,28 +117,6 @@ static void ipi_flush_icache(void *info)
129 blackfin_icache_flush_range(fdata->start, fdata->end); 117 blackfin_icache_flush_range(fdata->start, fdata->end);
130} 118}
131 119
132static void ipi_call_function(unsigned int cpu, struct ipi_message *msg)
133{
134 int wait;
135 void (*func)(void *info);
136 void *info;
137 func = msg->call_struct.func;
138 info = msg->call_struct.info;
139 wait = msg->call_struct.wait;
140 func(info);
141 if (wait) {
142#ifdef __ARCH_SYNC_CORE_DCACHE
143 /*
144 * 'wait' usually means synchronization between CPUs.
145 * Invalidate D cache in case shared data was changed
146 * by func() to ensure cache coherence.
147 */
148 resync_core_dcache();
149#endif
150 cpumask_clear_cpu(cpu, msg->call_struct.waitmask);
151 }
152}
153
154/* Use IRQ_SUPPLE_0 to request reschedule. 120/* Use IRQ_SUPPLE_0 to request reschedule.
155 * When returning from interrupt to user space, 121 * When returning from interrupt to user space,
156 * there is chance to reschedule */ 122 * there is chance to reschedule */
@@ -172,152 +138,95 @@ void ipi_timer(void)
172 138
173static irqreturn_t ipi_handler_int1(int irq, void *dev_instance) 139static irqreturn_t ipi_handler_int1(int irq, void *dev_instance)
174{ 140{
175 struct ipi_message *msg; 141 struct ipi_data *bfin_ipi_data;
176 struct ipi_message_queue *msg_queue;
177 unsigned int cpu = smp_processor_id(); 142 unsigned int cpu = smp_processor_id();
178 unsigned long flags; 143 unsigned long pending;
144 unsigned long msg;
179 145
180 platform_clear_ipi(cpu, IRQ_SUPPLE_1); 146 platform_clear_ipi(cpu, IRQ_SUPPLE_1);
181 147
182 msg_queue = &__get_cpu_var(ipi_msg_queue); 148 bfin_ipi_data = &__get_cpu_var(bfin_ipi);
183 149
184 spin_lock_irqsave(&msg_queue->lock, flags); 150 while ((pending = xchg(&bfin_ipi_data->bits, 0)) != 0) {
185 151 msg = 0;
186 while (msg_queue->count) { 152 do {
187 msg = &msg_queue->ipi_message[msg_queue->head]; 153 msg = find_next_bit(&pending, BITS_PER_LONG, msg + 1);
188 switch (msg->type) { 154 switch (msg) {
189 case BFIN_IPI_TIMER: 155 case BFIN_IPI_TIMER:
190 ipi_timer(); 156 ipi_timer();
191 break; 157 break;
192 case BFIN_IPI_RESCHEDULE: 158 case BFIN_IPI_RESCHEDULE:
193 scheduler_ipi(); 159 scheduler_ipi();
194 break; 160 break;
195 case BFIN_IPI_CALL_FUNC: 161 case BFIN_IPI_CALL_FUNC:
196 ipi_call_function(cpu, msg); 162 generic_smp_call_function_interrupt();
197 break; 163 break;
198 case BFIN_IPI_CPU_STOP: 164
199 ipi_cpu_stop(cpu); 165 case BFIN_IPI_CALL_FUNC_SINGLE:
200 break; 166 generic_smp_call_function_single_interrupt();
201 default: 167 break;
202 printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%lx\n", 168
203 cpu, msg->type); 169 case BFIN_IPI_CPU_STOP:
204 break; 170 ipi_cpu_stop(cpu);
205 } 171 break;
206 msg_queue->head++; 172 }
207 msg_queue->head %= BFIN_IPI_MSGQ_LEN; 173 } while (msg < BITS_PER_LONG);
208 msg_queue->count--; 174
175 smp_mb();
209 } 176 }
210 spin_unlock_irqrestore(&msg_queue->lock, flags);
211 return IRQ_HANDLED; 177 return IRQ_HANDLED;
212} 178}
213 179
214static void ipi_queue_init(void) 180static void bfin_ipi_init(void)
215{ 181{
216 unsigned int cpu; 182 unsigned int cpu;
217 struct ipi_message_queue *msg_queue; 183 struct ipi_data *bfin_ipi_data;
218 for_each_possible_cpu(cpu) { 184 for_each_possible_cpu(cpu) {
219 msg_queue = &per_cpu(ipi_msg_queue, cpu); 185 bfin_ipi_data = &per_cpu(bfin_ipi, cpu);
220 spin_lock_init(&msg_queue->lock); 186 bfin_ipi_data->bits = 0;
221 msg_queue->count = 0; 187 bfin_ipi_data->count = 0;
222 msg_queue->head = 0;
223 } 188 }
224} 189}
225 190
226static inline void smp_send_message(cpumask_t callmap, unsigned long type, 191void send_ipi(const struct cpumask *cpumask, enum ipi_message_type msg)
227 void (*func) (void *info), void *info, int wait)
228{ 192{
229 unsigned int cpu; 193 unsigned int cpu;
230 struct ipi_message_queue *msg_queue; 194 struct ipi_data *bfin_ipi_data;
231 struct ipi_message *msg; 195 unsigned long flags;
232 unsigned long flags, next_msg; 196
233 cpumask_t waitmask; /* waitmask is shared by all cpus */ 197 local_irq_save(flags);
234 198
235 cpumask_copy(&waitmask, &callmap); 199 for_each_cpu(cpu, cpumask) {
236 for_each_cpu(cpu, &callmap) { 200 bfin_ipi_data = &per_cpu(bfin_ipi, cpu);
237 msg_queue = &per_cpu(ipi_msg_queue, cpu); 201 smp_mb();
238 spin_lock_irqsave(&msg_queue->lock, flags); 202 set_bit(msg, &bfin_ipi_data->bits);
239 if (msg_queue->count < BFIN_IPI_MSGQ_LEN) { 203 bfin_ipi_data->count++;
240 next_msg = (msg_queue->head + msg_queue->count)
241 % BFIN_IPI_MSGQ_LEN;
242 msg = &msg_queue->ipi_message[next_msg];
243 msg->type = type;
244 if (type == BFIN_IPI_CALL_FUNC) {
245 msg->call_struct.func = func;
246 msg->call_struct.info = info;
247 msg->call_struct.wait = wait;
248 msg->call_struct.waitmask = &waitmask;
249 }
250 msg_queue->count++;
251 } else
252 panic("IPI message queue overflow\n");
253 spin_unlock_irqrestore(&msg_queue->lock, flags);
254 platform_send_ipi_cpu(cpu, IRQ_SUPPLE_1); 204 platform_send_ipi_cpu(cpu, IRQ_SUPPLE_1);
255 } 205 }
256 206
257 if (wait) { 207 local_irq_restore(flags);
258 while (!cpumask_empty(&waitmask))
259 blackfin_dcache_invalidate_range(
260 (unsigned long)(&waitmask),
261 (unsigned long)(&waitmask));
262#ifdef __ARCH_SYNC_CORE_DCACHE
263 /*
264 * Invalidate D cache in case shared data was changed by
265 * other processors to ensure cache coherence.
266 */
267 resync_core_dcache();
268#endif
269 }
270} 208}
271 209
272int smp_call_function(void (*func)(void *info), void *info, int wait) 210void arch_send_call_function_single_ipi(int cpu)
273{ 211{
274 cpumask_t callmap; 212 send_ipi(cpumask_of(cpu), BFIN_IPI_CALL_FUNC_SINGLE);
275
276 preempt_disable();
277 cpumask_copy(&callmap, cpu_online_mask);
278 cpumask_clear_cpu(smp_processor_id(), &callmap);
279 if (!cpumask_empty(&callmap))
280 smp_send_message(callmap, BFIN_IPI_CALL_FUNC, func, info, wait);
281
282 preempt_enable();
283
284 return 0;
285} 213}
286EXPORT_SYMBOL_GPL(smp_call_function);
287 214
288int smp_call_function_single(int cpuid, void (*func) (void *info), void *info, 215void arch_send_call_function_ipi_mask(const struct cpumask *mask)
289 int wait)
290{ 216{
291 unsigned int cpu = cpuid; 217 send_ipi(mask, BFIN_IPI_CALL_FUNC);
292 cpumask_t callmap;
293
294 if (cpu_is_offline(cpu))
295 return 0;
296 cpumask_clear(&callmap);
297 cpumask_set_cpu(cpu, &callmap);
298
299 smp_send_message(callmap, BFIN_IPI_CALL_FUNC, func, info, wait);
300
301 return 0;
302} 218}
303EXPORT_SYMBOL_GPL(smp_call_function_single);
304 219
305void smp_send_reschedule(int cpu) 220void smp_send_reschedule(int cpu)
306{ 221{
307 cpumask_t callmap; 222 send_ipi(cpumask_of(cpu), BFIN_IPI_RESCHEDULE);
308 /* simply trigger an ipi */
309
310 cpumask_clear(&callmap);
311 cpumask_set_cpu(cpu, &callmap);
312
313 smp_send_message(callmap, BFIN_IPI_RESCHEDULE, NULL, NULL, 0);
314 223
315 return; 224 return;
316} 225}
317 226
318void smp_send_msg(const struct cpumask *mask, unsigned long type) 227void smp_send_msg(const struct cpumask *mask, unsigned long type)
319{ 228{
320 smp_send_message(*mask, type, NULL, NULL, 0); 229 send_ipi(mask, type);
321} 230}
322 231
323void smp_timer_broadcast(const struct cpumask *mask) 232void smp_timer_broadcast(const struct cpumask *mask)
@@ -333,7 +242,7 @@ void smp_send_stop(void)
333 cpumask_copy(&callmap, cpu_online_mask); 242 cpumask_copy(&callmap, cpu_online_mask);
334 cpumask_clear_cpu(smp_processor_id(), &callmap); 243 cpumask_clear_cpu(smp_processor_id(), &callmap);
335 if (!cpumask_empty(&callmap)) 244 if (!cpumask_empty(&callmap))
336 smp_send_message(callmap, BFIN_IPI_CPU_STOP, NULL, NULL, 0); 245 send_ipi(&callmap, BFIN_IPI_CPU_STOP);
337 246
338 preempt_enable(); 247 preempt_enable();
339 248
@@ -436,7 +345,7 @@ void __init smp_prepare_boot_cpu(void)
436void __init smp_prepare_cpus(unsigned int max_cpus) 345void __init smp_prepare_cpus(unsigned int max_cpus)
437{ 346{
438 platform_prepare_cpus(max_cpus); 347 platform_prepare_cpus(max_cpus);
439 ipi_queue_init(); 348 bfin_ipi_init();
440 platform_request_ipi(IRQ_SUPPLE_0, ipi_handler_int0); 349 platform_request_ipi(IRQ_SUPPLE_0, ipi_handler_int0);
441 platform_request_ipi(IRQ_SUPPLE_1, ipi_handler_int1); 350 platform_request_ipi(IRQ_SUPPLE_1, ipi_handler_int1);
442} 351}
diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild
index 3af601e31e66..f08e89183cda 100644
--- a/arch/c6x/include/asm/Kbuild
+++ b/arch/c6x/include/asm/Kbuild
@@ -2,6 +2,7 @@ include include/asm-generic/Kbuild.asm
2 2
3generic-y += atomic.h 3generic-y += atomic.h
4generic-y += auxvec.h 4generic-y += auxvec.h
5generic-y += barrier.h
5generic-y += bitsperlong.h 6generic-y += bitsperlong.h
6generic-y += bugs.h 7generic-y += bugs.h
7generic-y += cputime.h 8generic-y += cputime.h
diff --git a/arch/c6x/include/asm/barrier.h b/arch/c6x/include/asm/barrier.h
deleted file mode 100644
index 538240e85909..000000000000
--- a/arch/c6x/include/asm/barrier.h
+++ /dev/null
@@ -1,27 +0,0 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef _ASM_C6X_BARRIER_H
12#define _ASM_C6X_BARRIER_H
13
14#define nop() asm("NOP\n");
15
16#define mb() barrier()
17#define rmb() barrier()
18#define wmb() barrier()
19#define set_mb(var, value) do { var = value; mb(); } while (0)
20#define set_wmb(var, value) do { var = value; wmb(); } while (0)
21
22#define smp_mb() barrier()
23#define smp_rmb() barrier()
24#define smp_wmb() barrier()
25#define smp_read_barrier_depends() do { } while (0)
26
27#endif /* _ASM_C6X_BARRIER_H */
diff --git a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c
index 66fd01728790..7f65be6f7f17 100644
--- a/arch/cris/kernel/process.c
+++ b/arch/cris/kernel/process.c
@@ -25,6 +25,7 @@
25#include <linux/elfcore.h> 25#include <linux/elfcore.h>
26#include <linux/mqueue.h> 26#include <linux/mqueue.h>
27#include <linux/reboot.h> 27#include <linux/reboot.h>
28#include <linux/rcupdate.h>
28 29
29//#define DEBUG 30//#define DEBUG
30 31
@@ -74,6 +75,7 @@ void cpu_idle (void)
74{ 75{
75 /* endless idle loop with no priority at all */ 76 /* endless idle loop with no priority at all */
76 while (1) { 77 while (1) {
78 rcu_idle_enter();
77 while (!need_resched()) { 79 while (!need_resched()) {
78 void (*idle)(void); 80 void (*idle)(void);
79 /* 81 /*
@@ -86,6 +88,7 @@ void cpu_idle (void)
86 idle = default_idle; 88 idle = default_idle;
87 idle(); 89 idle();
88 } 90 }
91 rcu_idle_exit();
89 schedule_preempt_disabled(); 92 schedule_preempt_disabled();
90 } 93 }
91} 94}
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c
index ff95f50efea5..2eb7fa5bf9d8 100644
--- a/arch/frv/kernel/process.c
+++ b/arch/frv/kernel/process.c
@@ -25,6 +25,7 @@
25#include <linux/reboot.h> 25#include <linux/reboot.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/pagemap.h> 27#include <linux/pagemap.h>
28#include <linux/rcupdate.h>
28 29
29#include <asm/asm-offsets.h> 30#include <asm/asm-offsets.h>
30#include <asm/uaccess.h> 31#include <asm/uaccess.h>
@@ -69,12 +70,14 @@ void cpu_idle(void)
69{ 70{
70 /* endless idle loop with no priority at all */ 71 /* endless idle loop with no priority at all */
71 while (1) { 72 while (1) {
73 rcu_idle_enter();
72 while (!need_resched()) { 74 while (!need_resched()) {
73 check_pgt_cache(); 75 check_pgt_cache();
74 76
75 if (!frv_dma_inprogress && idle) 77 if (!frv_dma_inprogress && idle)
76 idle(); 78 idle();
77 } 79 }
80 rcu_idle_exit();
78 81
79 schedule_preempt_disabled(); 82 schedule_preempt_disabled();
80 } 83 }
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index 0e9c315be104..f153ed1a4c08 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -36,6 +36,7 @@
36#include <linux/reboot.h> 36#include <linux/reboot.h>
37#include <linux/fs.h> 37#include <linux/fs.h>
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <linux/rcupdate.h>
39 40
40#include <asm/uaccess.h> 41#include <asm/uaccess.h>
41#include <asm/traps.h> 42#include <asm/traps.h>
@@ -78,8 +79,10 @@ void (*idle)(void) = default_idle;
78void cpu_idle(void) 79void cpu_idle(void)
79{ 80{
80 while (1) { 81 while (1) {
82 rcu_idle_enter();
81 while (!need_resched()) 83 while (!need_resched())
82 idle(); 84 idle();
85 rcu_idle_exit();
83 schedule_preempt_disabled(); 86 schedule_preempt_disabled();
84 } 87 }
85} 88}
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 310cf5781fad..3c720ef6c32d 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -25,6 +25,7 @@ config IA64
25 select HAVE_GENERIC_HARDIRQS 25 select HAVE_GENERIC_HARDIRQS
26 select HAVE_MEMBLOCK 26 select HAVE_MEMBLOCK
27 select HAVE_MEMBLOCK_NODE_MAP 27 select HAVE_MEMBLOCK_NODE_MAP
28 select HAVE_VIRT_CPU_ACCOUNTING
28 select ARCH_DISCARD_MEMBLOCK 29 select ARCH_DISCARD_MEMBLOCK
29 select GENERIC_IRQ_PROBE 30 select GENERIC_IRQ_PROBE
30 select GENERIC_PENDING_IRQ if SMP 31 select GENERIC_PENDING_IRQ if SMP
@@ -340,17 +341,6 @@ config FORCE_MAX_ZONEORDER
340 default "17" if HUGETLB_PAGE 341 default "17" if HUGETLB_PAGE
341 default "11" 342 default "11"
342 343
343config VIRT_CPU_ACCOUNTING
344 bool "Deterministic task and CPU time accounting"
345 default n
346 help
347 Select this option to enable more accurate task and CPU time
348 accounting. This is done by reading a CPU counter on each
349 kernel entry and exit and on transitions within the kernel
350 between system, softirq and hardirq state, so there is a
351 small performance impact.
352 If in doubt, say N here.
353
354config SMP 344config SMP
355 bool "Symmetric multi-processing support" 345 bool "Symmetric multi-processing support"
356 select USE_GENERIC_SMP_HELPERS 346 select USE_GENERIC_SMP_HELPERS
diff --git a/arch/ia64/include/asm/switch_to.h b/arch/ia64/include/asm/switch_to.h
index cb2412fcd17f..d38c7ea5eea5 100644
--- a/arch/ia64/include/asm/switch_to.h
+++ b/arch/ia64/include/asm/switch_to.h
@@ -30,13 +30,6 @@ extern struct task_struct *ia64_switch_to (void *next_task);
30extern void ia64_save_extra (struct task_struct *task); 30extern void ia64_save_extra (struct task_struct *task);
31extern void ia64_load_extra (struct task_struct *task); 31extern void ia64_load_extra (struct task_struct *task);
32 32
33#ifdef CONFIG_VIRT_CPU_ACCOUNTING
34extern void ia64_account_on_switch (struct task_struct *prev, struct task_struct *next);
35# define IA64_ACCOUNT_ON_SWITCH(p,n) ia64_account_on_switch(p,n)
36#else
37# define IA64_ACCOUNT_ON_SWITCH(p,n)
38#endif
39
40#ifdef CONFIG_PERFMON 33#ifdef CONFIG_PERFMON
41 DECLARE_PER_CPU(unsigned long, pfm_syst_info); 34 DECLARE_PER_CPU(unsigned long, pfm_syst_info);
42# define PERFMON_IS_SYSWIDE() (__get_cpu_var(pfm_syst_info) & 0x1) 35# define PERFMON_IS_SYSWIDE() (__get_cpu_var(pfm_syst_info) & 0x1)
@@ -49,7 +42,6 @@ extern void ia64_account_on_switch (struct task_struct *prev, struct task_struct
49 || PERFMON_IS_SYSWIDE()) 42 || PERFMON_IS_SYSWIDE())
50 43
51#define __switch_to(prev,next,last) do { \ 44#define __switch_to(prev,next,last) do { \
52 IA64_ACCOUNT_ON_SWITCH(prev, next); \
53 if (IA64_HAS_EXTRA_STATE(prev)) \ 45 if (IA64_HAS_EXTRA_STATE(prev)) \
54 ia64_save_extra(prev); \ 46 ia64_save_extra(prev); \
55 if (IA64_HAS_EXTRA_STATE(next)) \ 47 if (IA64_HAS_EXTRA_STATE(next)) \
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index dd6fc1449741..3e316ec0b835 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -29,6 +29,7 @@
29#include <linux/kdebug.h> 29#include <linux/kdebug.h>
30#include <linux/utsname.h> 30#include <linux/utsname.h>
31#include <linux/tracehook.h> 31#include <linux/tracehook.h>
32#include <linux/rcupdate.h>
32 33
33#include <asm/cpu.h> 34#include <asm/cpu.h>
34#include <asm/delay.h> 35#include <asm/delay.h>
@@ -279,6 +280,7 @@ cpu_idle (void)
279 280
280 /* endless idle loop with no priority at all */ 281 /* endless idle loop with no priority at all */
281 while (1) { 282 while (1) {
283 rcu_idle_enter();
282 if (can_do_pal_halt) { 284 if (can_do_pal_halt) {
283 current_thread_info()->status &= ~TS_POLLING; 285 current_thread_info()->status &= ~TS_POLLING;
284 /* 286 /*
@@ -309,6 +311,7 @@ cpu_idle (void)
309 normal_xtp(); 311 normal_xtp();
310#endif 312#endif
311 } 313 }
314 rcu_idle_exit();
312 schedule_preempt_disabled(); 315 schedule_preempt_disabled();
313 check_pgt_cache(); 316 check_pgt_cache();
314 if (cpu_is_offline(cpu)) 317 if (cpu_is_offline(cpu))
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index ecc904b33c5f..80ff9acc5edf 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -83,32 +83,36 @@ static struct clocksource *itc_clocksource;
83 83
84extern cputime_t cycle_to_cputime(u64 cyc); 84extern cputime_t cycle_to_cputime(u64 cyc);
85 85
86static void vtime_account_user(struct task_struct *tsk)
87{
88 cputime_t delta_utime;
89 struct thread_info *ti = task_thread_info(tsk);
90
91 if (ti->ac_utime) {
92 delta_utime = cycle_to_cputime(ti->ac_utime);
93 account_user_time(tsk, delta_utime, delta_utime);
94 ti->ac_utime = 0;
95 }
96}
97
86/* 98/*
87 * Called from the context switch with interrupts disabled, to charge all 99 * Called from the context switch with interrupts disabled, to charge all
88 * accumulated times to the current process, and to prepare accounting on 100 * accumulated times to the current process, and to prepare accounting on
89 * the next process. 101 * the next process.
90 */ 102 */
91void ia64_account_on_switch(struct task_struct *prev, struct task_struct *next) 103void vtime_task_switch(struct task_struct *prev)
92{ 104{
93 struct thread_info *pi = task_thread_info(prev); 105 struct thread_info *pi = task_thread_info(prev);
94 struct thread_info *ni = task_thread_info(next); 106 struct thread_info *ni = task_thread_info(current);
95 cputime_t delta_stime, delta_utime;
96 __u64 now;
97 107
98 now = ia64_get_itc();
99
100 delta_stime = cycle_to_cputime(pi->ac_stime + (now - pi->ac_stamp));
101 if (idle_task(smp_processor_id()) != prev) 108 if (idle_task(smp_processor_id()) != prev)
102 account_system_time(prev, 0, delta_stime, delta_stime); 109 vtime_account_system(prev);
103 else 110 else
104 account_idle_time(delta_stime); 111 vtime_account_idle(prev);
105 112
106 if (pi->ac_utime) { 113 vtime_account_user(prev);
107 delta_utime = cycle_to_cputime(pi->ac_utime);
108 account_user_time(prev, delta_utime, delta_utime);
109 }
110 114
111 pi->ac_stamp = ni->ac_stamp = now; 115 pi->ac_stamp = ni->ac_stamp;
112 ni->ac_stime = ni->ac_utime = 0; 116 ni->ac_stime = ni->ac_utime = 0;
113} 117}
114 118
@@ -116,29 +120,32 @@ void ia64_account_on_switch(struct task_struct *prev, struct task_struct *next)
116 * Account time for a transition between system, hard irq or soft irq state. 120 * Account time for a transition between system, hard irq or soft irq state.
117 * Note that this function is called with interrupts enabled. 121 * Note that this function is called with interrupts enabled.
118 */ 122 */
119void account_system_vtime(struct task_struct *tsk) 123static cputime_t vtime_delta(struct task_struct *tsk)
120{ 124{
121 struct thread_info *ti = task_thread_info(tsk); 125 struct thread_info *ti = task_thread_info(tsk);
122 unsigned long flags;
123 cputime_t delta_stime; 126 cputime_t delta_stime;
124 __u64 now; 127 __u64 now;
125 128
126 local_irq_save(flags);
127
128 now = ia64_get_itc(); 129 now = ia64_get_itc();
129 130
130 delta_stime = cycle_to_cputime(ti->ac_stime + (now - ti->ac_stamp)); 131 delta_stime = cycle_to_cputime(ti->ac_stime + (now - ti->ac_stamp));
131 if (irq_count() || idle_task(smp_processor_id()) != tsk)
132 account_system_time(tsk, 0, delta_stime, delta_stime);
133 else
134 account_idle_time(delta_stime);
135 ti->ac_stime = 0; 132 ti->ac_stime = 0;
136
137 ti->ac_stamp = now; 133 ti->ac_stamp = now;
138 134
139 local_irq_restore(flags); 135 return delta_stime;
136}
137
138void vtime_account_system(struct task_struct *tsk)
139{
140 cputime_t delta = vtime_delta(tsk);
141
142 account_system_time(tsk, 0, delta, delta);
143}
144
145void vtime_account_idle(struct task_struct *tsk)
146{
147 account_idle_time(vtime_delta(tsk));
140} 148}
141EXPORT_SYMBOL_GPL(account_system_vtime);
142 149
143/* 150/*
144 * Called from the timer interrupt handler to charge accumulated user time 151 * Called from the timer interrupt handler to charge accumulated user time
@@ -146,14 +153,7 @@ EXPORT_SYMBOL_GPL(account_system_vtime);
146 */ 153 */
147void account_process_tick(struct task_struct *p, int user_tick) 154void account_process_tick(struct task_struct *p, int user_tick)
148{ 155{
149 struct thread_info *ti = task_thread_info(p); 156 vtime_account_user(p);
150 cputime_t delta_utime;
151
152 if (ti->ac_utime) {
153 delta_utime = cycle_to_cputime(ti->ac_utime);
154 account_user_time(p, delta_utime, delta_utime);
155 ti->ac_utime = 0;
156 }
157} 157}
158 158
159#endif /* CONFIG_VIRT_CPU_ACCOUNTING */ 159#endif /* CONFIG_VIRT_CPU_ACCOUNTING */
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c
index 3a4a32b27208..384e63f3a4c4 100644
--- a/arch/m32r/kernel/process.c
+++ b/arch/m32r/kernel/process.c
@@ -26,6 +26,7 @@
26#include <linux/ptrace.h> 26#include <linux/ptrace.h>
27#include <linux/unistd.h> 27#include <linux/unistd.h>
28#include <linux/hardirq.h> 28#include <linux/hardirq.h>
29#include <linux/rcupdate.h>
29 30
30#include <asm/io.h> 31#include <asm/io.h>
31#include <asm/uaccess.h> 32#include <asm/uaccess.h>
@@ -82,6 +83,7 @@ void cpu_idle (void)
82{ 83{
83 /* endless idle loop with no priority at all */ 84 /* endless idle loop with no priority at all */
84 while (1) { 85 while (1) {
86 rcu_idle_enter();
85 while (!need_resched()) { 87 while (!need_resched()) {
86 void (*idle)(void) = pm_idle; 88 void (*idle)(void) = pm_idle;
87 89
@@ -90,6 +92,7 @@ void cpu_idle (void)
90 92
91 idle(); 93 idle();
92 } 94 }
95 rcu_idle_exit();
93 schedule_preempt_disabled(); 96 schedule_preempt_disabled();
94 } 97 }
95} 98}
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index c488e3cfab53..ac2892e49c7c 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -25,6 +25,7 @@
25#include <linux/reboot.h> 25#include <linux/reboot.h>
26#include <linux/init_task.h> 26#include <linux/init_task.h>
27#include <linux/mqueue.h> 27#include <linux/mqueue.h>
28#include <linux/rcupdate.h>
28 29
29#include <asm/uaccess.h> 30#include <asm/uaccess.h>
30#include <asm/traps.h> 31#include <asm/traps.h>
@@ -75,8 +76,10 @@ void cpu_idle(void)
75{ 76{
76 /* endless idle loop with no priority at all */ 77 /* endless idle loop with no priority at all */
77 while (1) { 78 while (1) {
79 rcu_idle_enter();
78 while (!need_resched()) 80 while (!need_resched())
79 idle(); 81 idle();
82 rcu_idle_exit();
80 schedule_preempt_disabled(); 83 schedule_preempt_disabled();
81 } 84 }
82} 85}
diff --git a/arch/m68k/platform/coldfire/clk.c b/arch/m68k/platform/coldfire/clk.c
index 75f9ee967ea7..9cd13b4ce42b 100644
--- a/arch/m68k/platform/coldfire/clk.c
+++ b/arch/m68k/platform/coldfire/clk.c
@@ -146,9 +146,3 @@ struct clk_ops clk_ops1 = {
146}; 146};
147#endif /* MCFPM_PPMCR1 */ 147#endif /* MCFPM_PPMCR1 */
148#endif /* MCFPM_PPMCR0 */ 148#endif /* MCFPM_PPMCR0 */
149
150struct clk *devm_clk_get(struct device *dev, const char *id)
151{
152 return NULL;
153}
154EXPORT_SYMBOL(devm_clk_get);
diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c
index e7e03ecf5495..afc379ca3753 100644
--- a/arch/mips/kernel/smp-cmp.c
+++ b/arch/mips/kernel/smp-cmp.c
@@ -102,7 +102,7 @@ static void cmp_init_secondary(void)
102 c->vpe_id = (read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE; 102 c->vpe_id = (read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE;
103#endif 103#endif
104#ifdef CONFIG_MIPS_MT_SMTC 104#ifdef CONFIG_MIPS_MT_SMTC
105 c->tc_id = (read_c0_tcbind() >> TCBIND_CURTC_SHIFT) & TCBIND_CURTC; 105 c->tc_id = (read_c0_tcbind() & TCBIND_CURTC) >> TCBIND_CURTC_SHIFT;
106#endif 106#endif
107} 107}
108 108
diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c
index 33aadbcf170b..dcfd573871c1 100644
--- a/arch/mips/mm/gup.c
+++ b/arch/mips/mm/gup.c
@@ -152,6 +152,8 @@ static int gup_huge_pud(pud_t pud, unsigned long addr, unsigned long end,
152 do { 152 do {
153 VM_BUG_ON(compound_head(page) != head); 153 VM_BUG_ON(compound_head(page) != head);
154 pages[*nr] = page; 154 pages[*nr] = page;
155 if (PageTail(page))
156 get_huge_page_tail(page);
155 (*nr)++; 157 (*nr)++;
156 page++; 158 page++;
157 refs++; 159 refs++;
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index 7b13a4caeea4..fea823f18479 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -273,16 +273,19 @@ asmlinkage void plat_irq_dispatch(void)
273 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; 273 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
274 int irq; 274 int irq;
275 275
276 if (unlikely(!pending)) {
277 spurious_interrupt();
278 return;
279 }
280
276 irq = irq_ffs(pending); 281 irq = irq_ffs(pending);
277 282
278 if (irq == MIPSCPU_INT_I8259A) 283 if (irq == MIPSCPU_INT_I8259A)
279 malta_hw0_irqdispatch(); 284 malta_hw0_irqdispatch();
280 else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()])) 285 else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()]))
281 malta_ipi_irqdispatch(); 286 malta_ipi_irqdispatch();
282 else if (irq >= 0)
283 do_IRQ(MIPS_CPU_IRQ_BASE + irq);
284 else 287 else
285 spurious_interrupt(); 288 do_IRQ(MIPS_CPU_IRQ_BASE + irq);
286} 289}
287 290
288#ifdef CONFIG_MIPS_MT_SMP 291#ifdef CONFIG_MIPS_MT_SMP
diff --git a/arch/mips/mti-malta/malta-platform.c b/arch/mips/mti-malta/malta-platform.c
index 4c35301720e7..80562b81f0f2 100644
--- a/arch/mips/mti-malta/malta-platform.c
+++ b/arch/mips/mti-malta/malta-platform.c
@@ -138,11 +138,6 @@ static int __init malta_add_devices(void)
138 if (err) 138 if (err)
139 return err; 139 return err;
140 140
141 /*
142 * Set RTC to BCD mode to support current alarm code.
143 */
144 CMOS_WRITE(CMOS_READ(RTC_CONTROL) & ~RTC_DM_BINARY, RTC_CONTROL);
145
146 return 0; 141 return 0;
147} 142}
148 143
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c
index 7dab0cd36466..e9cceba193b6 100644
--- a/arch/mn10300/kernel/process.c
+++ b/arch/mn10300/kernel/process.c
@@ -25,6 +25,7 @@
25#include <linux/err.h> 25#include <linux/err.h>
26#include <linux/fs.h> 26#include <linux/fs.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/rcupdate.h>
28#include <asm/uaccess.h> 29#include <asm/uaccess.h>
29#include <asm/pgtable.h> 30#include <asm/pgtable.h>
30#include <asm/io.h> 31#include <asm/io.h>
@@ -107,6 +108,7 @@ void cpu_idle(void)
107{ 108{
108 /* endless idle loop with no priority at all */ 109 /* endless idle loop with no priority at all */
109 for (;;) { 110 for (;;) {
111 rcu_idle_enter();
110 while (!need_resched()) { 112 while (!need_resched()) {
111 void (*idle)(void); 113 void (*idle)(void);
112 114
@@ -121,6 +123,7 @@ void cpu_idle(void)
121 } 123 }
122 idle(); 124 idle();
123 } 125 }
126 rcu_idle_exit();
124 127
125 schedule_preempt_disabled(); 128 schedule_preempt_disabled();
126 } 129 }
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 2c05a9292a81..8c6b6b6561f0 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -48,6 +48,7 @@
48#include <linux/unistd.h> 48#include <linux/unistd.h>
49#include <linux/kallsyms.h> 49#include <linux/kallsyms.h>
50#include <linux/uaccess.h> 50#include <linux/uaccess.h>
51#include <linux/rcupdate.h>
51 52
52#include <asm/io.h> 53#include <asm/io.h>
53#include <asm/asm-offsets.h> 54#include <asm/asm-offsets.h>
@@ -69,8 +70,10 @@ void cpu_idle(void)
69 70
70 /* endless idle loop with no priority at all */ 71 /* endless idle loop with no priority at all */
71 while (1) { 72 while (1) {
73 rcu_idle_enter();
72 while (!need_resched()) 74 while (!need_resched())
73 barrier(); 75 barrier();
76 rcu_idle_exit();
74 schedule_preempt_disabled(); 77 schedule_preempt_disabled();
75 check_pgt_cache(); 78 check_pgt_cache();
76 } 79 }
diff --git a/arch/powerpc/boot/.gitignore b/arch/powerpc/boot/.gitignore
index 1c1aadc8c48f..c32ae5ce9fff 100644
--- a/arch/powerpc/boot/.gitignore
+++ b/arch/powerpc/boot/.gitignore
@@ -1,10 +1,6 @@
1addnote 1addnote
2empty.c 2empty.c
3hack-coff 3hack-coff
4infblock.c
5infblock.h
6infcodes.c
7infcodes.h
8inffast.c 4inffast.c
9inffast.h 5inffast.h
10inffixed.h 6inffixed.h
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h
index 3b4b4a8da922..c1f267694acb 100644
--- a/arch/powerpc/include/asm/time.h
+++ b/arch/powerpc/include/asm/time.h
@@ -197,12 +197,6 @@ struct cpu_usage {
197 197
198DECLARE_PER_CPU(struct cpu_usage, cpu_usage_array); 198DECLARE_PER_CPU(struct cpu_usage, cpu_usage_array);
199 199
200#if defined(CONFIG_VIRT_CPU_ACCOUNTING)
201#define account_process_vtime(tsk) account_process_tick(tsk, 0)
202#else
203#define account_process_vtime(tsk) do { } while (0)
204#endif
205
206extern void secondary_cpu_time_init(void); 200extern void secondary_cpu_time_init(void);
207 201
208DECLARE_PER_CPU(u64, decrementers_next_tb); 202DECLARE_PER_CPU(u64, decrementers_next_tb);
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 1a1f2ddfb581..e9cb51f5f801 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -514,9 +514,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
514 514
515 local_irq_save(flags); 515 local_irq_save(flags);
516 516
517 account_system_vtime(current);
518 account_process_vtime(current);
519
520 /* 517 /*
521 * We can't take a PMU exception inside _switch() since there is a 518 * We can't take a PMU exception inside _switch() since there is a
522 * window where the kernel stack SLB and the kernel stack are out 519 * window where the kernel stack SLB and the kernel stack are out
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index e49e93191b69..eaa9d0e6abca 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -291,13 +291,12 @@ static inline u64 calculate_stolen_time(u64 stop_tb)
291 * Account time for a transition between system, hard irq 291 * Account time for a transition between system, hard irq
292 * or soft irq state. 292 * or soft irq state.
293 */ 293 */
294void account_system_vtime(struct task_struct *tsk) 294static u64 vtime_delta(struct task_struct *tsk,
295 u64 *sys_scaled, u64 *stolen)
295{ 296{
296 u64 now, nowscaled, delta, deltascaled; 297 u64 now, nowscaled, deltascaled;
297 unsigned long flags; 298 u64 udelta, delta, user_scaled;
298 u64 stolen, udelta, sys_scaled, user_scaled;
299 299
300 local_irq_save(flags);
301 now = mftb(); 300 now = mftb();
302 nowscaled = read_spurr(now); 301 nowscaled = read_spurr(now);
303 get_paca()->system_time += now - get_paca()->starttime; 302 get_paca()->system_time += now - get_paca()->starttime;
@@ -305,7 +304,7 @@ void account_system_vtime(struct task_struct *tsk)
305 deltascaled = nowscaled - get_paca()->startspurr; 304 deltascaled = nowscaled - get_paca()->startspurr;
306 get_paca()->startspurr = nowscaled; 305 get_paca()->startspurr = nowscaled;
307 306
308 stolen = calculate_stolen_time(now); 307 *stolen = calculate_stolen_time(now);
309 308
310 delta = get_paca()->system_time; 309 delta = get_paca()->system_time;
311 get_paca()->system_time = 0; 310 get_paca()->system_time = 0;
@@ -322,35 +321,45 @@ void account_system_vtime(struct task_struct *tsk)
322 * the user ticks get saved up in paca->user_time_scaled to be 321 * the user ticks get saved up in paca->user_time_scaled to be
323 * used by account_process_tick. 322 * used by account_process_tick.
324 */ 323 */
325 sys_scaled = delta; 324 *sys_scaled = delta;
326 user_scaled = udelta; 325 user_scaled = udelta;
327 if (deltascaled != delta + udelta) { 326 if (deltascaled != delta + udelta) {
328 if (udelta) { 327 if (udelta) {
329 sys_scaled = deltascaled * delta / (delta + udelta); 328 *sys_scaled = deltascaled * delta / (delta + udelta);
330 user_scaled = deltascaled - sys_scaled; 329 user_scaled = deltascaled - *sys_scaled;
331 } else { 330 } else {
332 sys_scaled = deltascaled; 331 *sys_scaled = deltascaled;
333 } 332 }
334 } 333 }
335 get_paca()->user_time_scaled += user_scaled; 334 get_paca()->user_time_scaled += user_scaled;
336 335
337 if (in_interrupt() || idle_task(smp_processor_id()) != tsk) { 336 return delta;
338 account_system_time(tsk, 0, delta, sys_scaled); 337}
339 if (stolen) 338
340 account_steal_time(stolen); 339void vtime_account_system(struct task_struct *tsk)
341 } else { 340{
342 account_idle_time(delta + stolen); 341 u64 delta, sys_scaled, stolen;
343 } 342
344 local_irq_restore(flags); 343 delta = vtime_delta(tsk, &sys_scaled, &stolen);
344 account_system_time(tsk, 0, delta, sys_scaled);
345 if (stolen)
346 account_steal_time(stolen);
347}
348
349void vtime_account_idle(struct task_struct *tsk)
350{
351 u64 delta, sys_scaled, stolen;
352
353 delta = vtime_delta(tsk, &sys_scaled, &stolen);
354 account_idle_time(delta + stolen);
345} 355}
346EXPORT_SYMBOL_GPL(account_system_vtime);
347 356
348/* 357/*
349 * Transfer the user and system times accumulated in the paca 358 * Transfer the user and system times accumulated in the paca
350 * by the exception entry and exit code to the generic process 359 * by the exception entry and exit code to the generic process
351 * user and system time records. 360 * user and system time records.
352 * Must be called with interrupts disabled. 361 * Must be called with interrupts disabled.
353 * Assumes that account_system_vtime() has been called recently 362 * Assumes that vtime_account() has been called recently
354 * (i.e. since the last entry from usermode) so that 363 * (i.e. since the last entry from usermode) so that
355 * get_paca()->user_time_scaled is up to date. 364 * get_paca()->user_time_scaled is up to date.
356 */ 365 */
@@ -366,6 +375,12 @@ void account_process_tick(struct task_struct *tsk, int user_tick)
366 account_user_time(tsk, utime, utimescaled); 375 account_user_time(tsk, utime, utimescaled);
367} 376}
368 377
378void vtime_task_switch(struct task_struct *prev)
379{
380 vtime_account(prev);
381 account_process_tick(prev, 0);
382}
383
369#else /* ! CONFIG_VIRT_CPU_ACCOUNTING */ 384#else /* ! CONFIG_VIRT_CPU_ACCOUNTING */
370#define calc_cputime_factors() 385#define calc_cputime_factors()
371#endif 386#endif
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 30fd01de6bed..72afd2888cad 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -1,6 +1,7 @@
1config PPC64 1config PPC64
2 bool "64-bit kernel" 2 bool "64-bit kernel"
3 default n 3 default n
4 select HAVE_VIRT_CPU_ACCOUNTING
4 help 5 help
5 This option selects whether a 32-bit or a 64-bit kernel 6 This option selects whether a 32-bit or a 64-bit kernel
6 will be built. 7 will be built.
@@ -337,21 +338,6 @@ config PPC_MM_SLICES
337 default y if (!PPC_FSL_BOOK3E && PPC64 && HUGETLB_PAGE) || (PPC_STD_MMU_64 && PPC_64K_PAGES) 338 default y if (!PPC_FSL_BOOK3E && PPC64 && HUGETLB_PAGE) || (PPC_STD_MMU_64 && PPC_64K_PAGES)
338 default n 339 default n
339 340
340config VIRT_CPU_ACCOUNTING
341 bool "Deterministic task and CPU time accounting"
342 depends on PPC64
343 default y
344 help
345 Select this option to enable more accurate task and CPU time
346 accounting. This is done by reading a CPU counter on each
347 kernel entry and exit and on transitions within the kernel
348 between system, softirq and hardirq state, so there is a
349 small performance impact. This also enables accounting of
350 stolen time on logically-partitioned systems running on
351 IBM POWER5-based machines.
352
353 If in doubt, say Y here.
354
355config PPC_HAVE_PMU_SUPPORT 341config PPC_HAVE_PMU_SUPPORT
356 bool 342 bool
357 343
diff --git a/arch/s390/Kbuild b/arch/s390/Kbuild
index 9858476fa0fe..cc45d25487b0 100644
--- a/arch/s390/Kbuild
+++ b/arch/s390/Kbuild
@@ -5,3 +5,4 @@ obj-$(CONFIG_CRYPTO_HW) += crypto/
5obj-$(CONFIG_S390_HYPFS_FS) += hypfs/ 5obj-$(CONFIG_S390_HYPFS_FS) += hypfs/
6obj-$(CONFIG_APPLDATA_BASE) += appldata/ 6obj-$(CONFIG_APPLDATA_BASE) += appldata/
7obj-$(CONFIG_MATHEMU) += math-emu/ 7obj-$(CONFIG_MATHEMU) += math-emu/
8obj-y += net/
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 107610e01a29..f9acddd9ace3 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -49,10 +49,13 @@ config GENERIC_LOCKBREAK
49config PGSTE 49config PGSTE
50 def_bool y if KVM 50 def_bool y if KVM
51 51
52config VIRT_CPU_ACCOUNTING 52config ARCH_SUPPORTS_DEBUG_PAGEALLOC
53 def_bool y 53 def_bool y
54 54
55config ARCH_SUPPORTS_DEBUG_PAGEALLOC 55config KEXEC
56 def_bool y
57
58config AUDIT_ARCH
56 def_bool y 59 def_bool y
57 60
58config S390 61config S390
@@ -84,11 +87,15 @@ config S390
84 select HAVE_KERNEL_XZ 87 select HAVE_KERNEL_XZ
85 select HAVE_ARCH_MUTEX_CPU_RELAX 88 select HAVE_ARCH_MUTEX_CPU_RELAX
86 select HAVE_ARCH_JUMP_LABEL if !MARCH_G5 89 select HAVE_ARCH_JUMP_LABEL if !MARCH_G5
90 select HAVE_BPF_JIT if 64BIT && PACK_STACK
87 select ARCH_SAVE_PAGE_KEYS if HIBERNATION 91 select ARCH_SAVE_PAGE_KEYS if HIBERNATION
88 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE 92 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
89 select HAVE_MEMBLOCK 93 select HAVE_MEMBLOCK
90 select HAVE_MEMBLOCK_NODE_MAP 94 select HAVE_MEMBLOCK_NODE_MAP
91 select HAVE_CMPXCHG_LOCAL 95 select HAVE_CMPXCHG_LOCAL
96 select HAVE_CMPXCHG_DOUBLE
97 select HAVE_VIRT_CPU_ACCOUNTING
98 select VIRT_CPU_ACCOUNTING
92 select ARCH_DISCARD_MEMBLOCK 99 select ARCH_DISCARD_MEMBLOCK
93 select BUILDTIME_EXTABLE_SORT 100 select BUILDTIME_EXTABLE_SORT
94 select ARCH_INLINE_SPIN_TRYLOCK 101 select ARCH_INLINE_SPIN_TRYLOCK
@@ -133,9 +140,79 @@ source "init/Kconfig"
133 140
134source "kernel/Kconfig.freezer" 141source "kernel/Kconfig.freezer"
135 142
136menu "Base setup" 143menu "Processor type and features"
144
145config HAVE_MARCH_Z900_FEATURES
146 def_bool n
147
148config HAVE_MARCH_Z990_FEATURES
149 def_bool n
150 select HAVE_MARCH_Z900_FEATURES
151
152config HAVE_MARCH_Z9_109_FEATURES
153 def_bool n
154 select HAVE_MARCH_Z990_FEATURES
155
156config HAVE_MARCH_Z10_FEATURES
157 def_bool n
158 select HAVE_MARCH_Z9_109_FEATURES
159
160config HAVE_MARCH_Z196_FEATURES
161 def_bool n
162 select HAVE_MARCH_Z10_FEATURES
163
164choice
165 prompt "Processor type"
166 default MARCH_G5
167
168config MARCH_G5
169 bool "System/390 model G5 and G6"
170 depends on !64BIT
171 help
172 Select this to build a 31 bit kernel that works
173 on all ESA/390 and z/Architecture machines.
137 174
138comment "Processor type and features" 175config MARCH_Z900
176 bool "IBM zSeries model z800 and z900"
177 select HAVE_MARCH_Z900_FEATURES if 64BIT
178 help
179 Select this to enable optimizations for model z800/z900 (2064 and
180 2066 series). This will enable some optimizations that are not
181 available on older ESA/390 (31 Bit) only CPUs.
182
183config MARCH_Z990
184 bool "IBM zSeries model z890 and z990"
185 select HAVE_MARCH_Z990_FEATURES if 64BIT
186 help
187 Select this to enable optimizations for model z890/z990 (2084 and
188 2086 series). The kernel will be slightly faster but will not work
189 on older machines.
190
191config MARCH_Z9_109
192 bool "IBM System z9"
193 select HAVE_MARCH_Z9_109_FEATURES if 64BIT
194 help
195 Select this to enable optimizations for IBM System z9 (2094 and
196 2096 series). The kernel will be slightly faster but will not work
197 on older machines.
198
199config MARCH_Z10
200 bool "IBM System z10"
201 select HAVE_MARCH_Z10_FEATURES if 64BIT
202 help
203 Select this to enable optimizations for IBM System z10 (2097 and
204 2098 series). The kernel will be slightly faster but will not work
205 on older machines.
206
207config MARCH_Z196
208 bool "IBM zEnterprise 114 and 196"
209 select HAVE_MARCH_Z196_FEATURES if 64BIT
210 help
211 Select this to enable optimizations for IBM zEnterprise 114 and 196
212 (2818 and 2817 series). The kernel will be slightly faster but will
213 not work on older machines.
214
215endchoice
139 216
140config 64BIT 217config 64BIT
141 def_bool y 218 def_bool y
@@ -147,6 +224,24 @@ config 64BIT
147config 32BIT 224config 32BIT
148 def_bool y if !64BIT 225 def_bool y if !64BIT
149 226
227config COMPAT
228 def_bool y
229 prompt "Kernel support for 31 bit emulation"
230 depends on 64BIT
231 select COMPAT_BINFMT_ELF if BINFMT_ELF
232 select ARCH_WANT_OLD_COMPAT_IPC
233 help
234 Select this option if you want to enable your system kernel to
235 handle system-calls from ELF binaries for 31 bit ESA. This option
236 (and some other stuff like libraries and such) is needed for
237 executing 31 bit applications. It is safe to say "Y".
238
239config SYSVIPC_COMPAT
240 def_bool y if COMPAT && SYSVIPC
241
242config KEYS_COMPAT
243 def_bool y if COMPAT && KEYS
244
150config SMP 245config SMP
151 def_bool y 246 def_bool y
152 prompt "Symmetric multi-processing support" 247 prompt "Symmetric multi-processing support"
@@ -202,6 +297,8 @@ config SCHED_BOOK
202 Book scheduler support improves the CPU scheduler's decision making 297 Book scheduler support improves the CPU scheduler's decision making
203 when dealing with machines that have several books. 298 when dealing with machines that have several books.
204 299
300source kernel/Kconfig.preempt
301
205config MATHEMU 302config MATHEMU
206 def_bool y 303 def_bool y
207 prompt "IEEE FPU emulation" 304 prompt "IEEE FPU emulation"
@@ -211,100 +308,35 @@ config MATHEMU
211 on older ESA/390 machines. Say Y unless you know your machine doesn't 308 on older ESA/390 machines. Say Y unless you know your machine doesn't
212 need this. 309 need this.
213 310
214config COMPAT 311source kernel/Kconfig.hz
215 def_bool y
216 prompt "Kernel support for 31 bit emulation"
217 depends on 64BIT
218 select COMPAT_BINFMT_ELF if BINFMT_ELF
219 select ARCH_WANT_OLD_COMPAT_IPC
220 help
221 Select this option if you want to enable your system kernel to
222 handle system-calls from ELF binaries for 31 bit ESA. This option
223 (and some other stuff like libraries and such) is needed for
224 executing 31 bit applications. It is safe to say "Y".
225 312
226config SYSVIPC_COMPAT 313endmenu
227 def_bool y if COMPAT && SYSVIPC
228 314
229config KEYS_COMPAT 315menu "Memory setup"
230 def_bool y if COMPAT && KEYS
231 316
232config AUDIT_ARCH 317config ARCH_SPARSEMEM_ENABLE
233 def_bool y 318 def_bool y
319 select SPARSEMEM_VMEMMAP_ENABLE
320 select SPARSEMEM_VMEMMAP
321 select SPARSEMEM_STATIC if !64BIT
234 322
235config HAVE_MARCH_Z900_FEATURES 323config ARCH_SPARSEMEM_DEFAULT
236 def_bool n 324 def_bool y
237
238config HAVE_MARCH_Z990_FEATURES
239 def_bool n
240 select HAVE_MARCH_Z900_FEATURES
241
242config HAVE_MARCH_Z9_109_FEATURES
243 def_bool n
244 select HAVE_MARCH_Z990_FEATURES
245
246config HAVE_MARCH_Z10_FEATURES
247 def_bool n
248 select HAVE_MARCH_Z9_109_FEATURES
249
250config HAVE_MARCH_Z196_FEATURES
251 def_bool n
252 select HAVE_MARCH_Z10_FEATURES
253
254comment "Code generation options"
255
256choice
257 prompt "Processor type"
258 default MARCH_G5
259
260config MARCH_G5
261 bool "System/390 model G5 and G6"
262 depends on !64BIT
263 help
264 Select this to build a 31 bit kernel that works
265 on all ESA/390 and z/Architecture machines.
266
267config MARCH_Z900
268 bool "IBM zSeries model z800 and z900"
269 select HAVE_MARCH_Z900_FEATURES if 64BIT
270 help
271 Select this to enable optimizations for model z800/z900 (2064 and
272 2066 series). This will enable some optimizations that are not
273 available on older ESA/390 (31 Bit) only CPUs.
274 325
275config MARCH_Z990 326config ARCH_SELECT_MEMORY_MODEL
276 bool "IBM zSeries model z890 and z990" 327 def_bool y
277 select HAVE_MARCH_Z990_FEATURES if 64BIT
278 help
279 Select this to enable optimizations for model z890/z990 (2084 and
280 2086 series). The kernel will be slightly faster but will not work
281 on older machines.
282 328
283config MARCH_Z9_109 329config ARCH_ENABLE_MEMORY_HOTPLUG
284 bool "IBM System z9" 330 def_bool y if SPARSEMEM
285 select HAVE_MARCH_Z9_109_FEATURES if 64BIT
286 help
287 Select this to enable optimizations for IBM System z9 (2094 and
288 2096 series). The kernel will be slightly faster but will not work
289 on older machines.
290 331
291config MARCH_Z10 332config ARCH_ENABLE_MEMORY_HOTREMOVE
292 bool "IBM System z10" 333 def_bool y
293 select HAVE_MARCH_Z10_FEATURES if 64BIT
294 help
295 Select this to enable optimizations for IBM System z10 (2097 and
296 2098 series). The kernel will be slightly faster but will not work
297 on older machines.
298 334
299config MARCH_Z196 335config FORCE_MAX_ZONEORDER
300 bool "IBM zEnterprise 114 and 196" 336 int
301 select HAVE_MARCH_Z196_FEATURES if 64BIT 337 default "9"
302 help
303 Select this to enable optimizations for IBM zEnterprise 114 and 196
304 (2818 and 2817 series). The kernel will be slightly faster but will
305 not work on older machines.
306 338
307endchoice 339source "mm/Kconfig"
308 340
309config PACK_STACK 341config PACK_STACK
310 def_bool y 342 def_bool y
@@ -368,34 +400,9 @@ config WARN_DYNAMIC_STACK
368 400
369 Say N if you are unsure. 401 Say N if you are unsure.
370 402
371comment "Kernel preemption" 403endmenu
372
373source "kernel/Kconfig.preempt"
374
375config ARCH_SPARSEMEM_ENABLE
376 def_bool y
377 select SPARSEMEM_VMEMMAP_ENABLE
378 select SPARSEMEM_VMEMMAP
379 select SPARSEMEM_STATIC if !64BIT
380
381config ARCH_SPARSEMEM_DEFAULT
382 def_bool y
383
384config ARCH_SELECT_MEMORY_MODEL
385 def_bool y
386
387config ARCH_ENABLE_MEMORY_HOTPLUG
388 def_bool y if SPARSEMEM
389
390config ARCH_ENABLE_MEMORY_HOTREMOVE
391 def_bool y
392
393config ARCH_HIBERNATION_POSSIBLE
394 def_bool y if 64BIT
395
396source "mm/Kconfig"
397 404
398comment "I/O subsystem configuration" 405menu "I/O subsystem"
399 406
400config QDIO 407config QDIO
401 def_tristate y 408 def_tristate y
@@ -426,13 +433,102 @@ config CHSC_SCH
426 433
427 If unsure, say N. 434 If unsure, say N.
428 435
429comment "Misc" 436config SCM_BUS
437 def_bool y
438 depends on 64BIT
439 prompt "SCM bus driver"
440 help
441 Bus driver for Storage Class Memory.
442
443config EADM_SCH
444 def_tristate m
445 prompt "Support for EADM subchannels"
446 depends on SCM_BUS
447 help
448 This driver allows usage of EADM subchannels. EADM subchannels act
449 as a communication vehicle for SCM increments.
450
451 To compile this driver as a module, choose M here: the
452 module will be called eadm_sch.
453
454endmenu
455
456menu "Dump support"
457
458config CRASH_DUMP
459 bool "kernel crash dumps"
460 depends on 64BIT && SMP
461 select KEXEC
462 help
463 Generate crash dump after being started by kexec.
464 Crash dump kernels are loaded in the main kernel with kexec-tools
465 into a specially reserved region and then later executed after
466 a crash by kdump/kexec.
467 For more details see Documentation/kdump/kdump.txt
468
469config ZFCPDUMP
470 def_bool n
471 prompt "zfcpdump support"
472 select SMP
473 help
474 Select this option if you want to build an zfcpdump enabled kernel.
475 Refer to <file:Documentation/s390/zfcpdump.txt> for more details on this.
476
477endmenu
478
479menu "Executable file formats / Emulations"
430 480
431source "fs/Kconfig.binfmt" 481source "fs/Kconfig.binfmt"
432 482
433config FORCE_MAX_ZONEORDER 483config SECCOMP
434 int 484 def_bool y
435 default "9" 485 prompt "Enable seccomp to safely compute untrusted bytecode"
486 depends on PROC_FS
487 help
488 This kernel feature is useful for number crunching applications
489 that may need to compute untrusted bytecode during their
490 execution. By using pipes or other transports made available to
491 the process as file descriptors supporting the read/write
492 syscalls, it's possible to isolate those applications in
493 their own address space using seccomp. Once seccomp is
494 enabled via /proc/<pid>/seccomp, it cannot be disabled
495 and the task is only allowed to execute a few safe syscalls
496 defined by each seccomp mode.
497
498 If unsure, say Y.
499
500endmenu
501
502menu "Power Management"
503
504config ARCH_HIBERNATION_POSSIBLE
505 def_bool y if 64BIT
506
507source "kernel/power/Kconfig"
508
509endmenu
510
511source "net/Kconfig"
512
513config PCMCIA
514 def_bool n
515
516config CCW
517 def_bool y
518
519source "drivers/Kconfig"
520
521source "fs/Kconfig"
522
523source "arch/s390/Kconfig.debug"
524
525source "security/Kconfig"
526
527source "crypto/Kconfig"
528
529source "lib/Kconfig"
530
531menu "Virtualization"
436 532
437config PFAULT 533config PFAULT
438 def_bool y 534 def_bool y
@@ -448,8 +544,8 @@ config PFAULT
448 this option. 544 this option.
449 545
450config SHARED_KERNEL 546config SHARED_KERNEL
451 def_bool y 547 bool "VM shared kernel support"
452 prompt "VM shared kernel support" 548 depends on !JUMP_LABEL
453 help 549 help
454 Select this option, if you want to share the text segment of the 550 Select this option, if you want to share the text segment of the
455 Linux kernel between different VM guests. This reduces memory 551 Linux kernel between different VM guests. This reduces memory
@@ -544,8 +640,6 @@ config APPLDATA_NET_SUM
544 This can also be compiled as a module, which will be called 640 This can also be compiled as a module, which will be called
545 appldata_net_sum.o. 641 appldata_net_sum.o.
546 642
547source kernel/Kconfig.hz
548
549config S390_HYPFS_FS 643config S390_HYPFS_FS
550 def_bool y 644 def_bool y
551 prompt "s390 hypervisor file system support" 645 prompt "s390 hypervisor file system support"
@@ -554,90 +648,21 @@ config S390_HYPFS_FS
554 This is a virtual file system intended to provide accounting 648 This is a virtual file system intended to provide accounting
555 information in an s390 hypervisor environment. 649 information in an s390 hypervisor environment.
556 650
557config KEXEC 651source "arch/s390/kvm/Kconfig"
558 def_bool n
559 prompt "kexec system call"
560 help
561 kexec is a system call that implements the ability to shutdown your
562 current kernel, and to start another kernel. It is like a reboot
563 but is independent of hardware/microcode support.
564
565config CRASH_DUMP
566 bool "kernel crash dumps"
567 depends on 64BIT && SMP
568 select KEXEC
569 help
570 Generate crash dump after being started by kexec.
571 Crash dump kernels are loaded in the main kernel with kexec-tools
572 into a specially reserved region and then later executed after
573 a crash by kdump/kexec.
574 For more details see Documentation/kdump/kdump.txt
575
576config ZFCPDUMP
577 def_bool n
578 prompt "zfcpdump support"
579 select SMP
580 help
581 Select this option if you want to build an zfcpdump enabled kernel.
582 Refer to <file:Documentation/s390/zfcpdump.txt> for more details on this.
583 652
584config S390_GUEST 653config S390_GUEST
585 def_bool y 654 def_bool y
586 prompt "s390 guest support for KVM (EXPERIMENTAL)" 655 prompt "s390 support for virtio devices (EXPERIMENTAL)"
587 depends on 64BIT && EXPERIMENTAL 656 depends on 64BIT && EXPERIMENTAL
588 select VIRTUALIZATION 657 select VIRTUALIZATION
589 select VIRTIO 658 select VIRTIO
590 select VIRTIO_RING 659 select VIRTIO_RING
591 select VIRTIO_CONSOLE 660 select VIRTIO_CONSOLE
592 help 661 help
593 Select this option if you want to run the kernel as a guest under 662 Enabling this option adds support for virtio based paravirtual device
594 the KVM hypervisor. This will add detection for KVM as well as a 663 drivers on s390.
595 virtio transport. If KVM is detected, the virtio console will be
596 the default console.
597
598config SECCOMP
599 def_bool y
600 prompt "Enable seccomp to safely compute untrusted bytecode"
601 depends on PROC_FS
602 help
603 This kernel feature is useful for number crunching applications
604 that may need to compute untrusted bytecode during their
605 execution. By using pipes or other transports made available to
606 the process as file descriptors supporting the read/write
607 syscalls, it's possible to isolate those applications in
608 their own address space using seccomp. Once seccomp is
609 enabled via /proc/<pid>/seccomp, it cannot be disabled
610 and the task is only allowed to execute a few safe syscalls
611 defined by each seccomp mode.
612
613 If unsure, say Y.
614
615endmenu
616 664
617menu "Power Management" 665 Select this option if you want to run the kernel as a guest under
618 666 the KVM hypervisor.
619source "kernel/power/Kconfig"
620 667
621endmenu 668endmenu
622
623source "net/Kconfig"
624
625config PCMCIA
626 def_bool n
627
628config CCW
629 def_bool y
630
631source "drivers/Kconfig"
632
633source "fs/Kconfig"
634
635source "arch/s390/Kconfig.debug"
636
637source "security/Kconfig"
638
639source "crypto/Kconfig"
640
641source "lib/Kconfig"
642
643source "arch/s390/kvm/Kconfig"
diff --git a/arch/s390/boot/compressed/Makefile b/arch/s390/boot/compressed/Makefile
index 10e22c4ec4a7..3ad8f61c9985 100644
--- a/arch/s390/boot/compressed/Makefile
+++ b/arch/s390/boot/compressed/Makefile
@@ -11,6 +11,7 @@ targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
11 sizes.h head$(BITS).o 11 sizes.h head$(BITS).o
12 12
13KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 13KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
14KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
14KBUILD_CFLAGS += $(cflags-y) 15KBUILD_CFLAGS += $(cflags-y)
15KBUILD_CFLAGS += $(call cc-option,-mpacked-stack) 16KBUILD_CFLAGS += $(call cc-option,-mpacked-stack)
16KBUILD_CFLAGS += $(call cc-option,-ffreestanding) 17KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
diff --git a/arch/s390/boot/compressed/misc.c b/arch/s390/boot/compressed/misc.c
index 465eca756feb..c4c6a1cf221b 100644
--- a/arch/s390/boot/compressed/misc.c
+++ b/arch/s390/boot/compressed/misc.c
@@ -71,34 +71,37 @@ void *memset(void *s, int c, size_t n)
71{ 71{
72 char *xs; 72 char *xs;
73 73
74 if (c == 0) 74 xs = s;
75 return __builtin_memset(s, 0, n); 75 while (n--)
76 76 *xs++ = c;
77 xs = (char *) s;
78 if (n > 0)
79 do {
80 *xs++ = c;
81 } while (--n > 0);
82 return s; 77 return s;
83} 78}
84 79
85void *memcpy(void *__dest, __const void *__src, size_t __n) 80void *memcpy(void *dest, const void *src, size_t n)
86{ 81{
87 return __builtin_memcpy(__dest, __src, __n); 82 const char *s = src;
83 char *d = dest;
84
85 while (n--)
86 *d++ = *s++;
87 return dest;
88} 88}
89 89
90void *memmove(void *__dest, __const void *__src, size_t __n) 90void *memmove(void *dest, const void *src, size_t n)
91{ 91{
92 char *d; 92 const char *s = src;
93 const char *s; 93 char *d = dest;
94 94
95 if (__dest <= __src) 95 if (d <= s) {
96 return __builtin_memcpy(__dest, __src, __n); 96 while (n--)
97 d = __dest + __n; 97 *d++ = *s++;
98 s = __src + __n; 98 } else {
99 while (__n--) 99 d += n;
100 *--d = *--s; 100 s += n;
101 return __dest; 101 while (n--)
102 *--d = *--s;
103 }
104 return dest;
102} 105}
103 106
104static void error(char *x) 107static void error(char *x)
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index f39cd710980b..b74400e3e035 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -16,8 +16,8 @@ CONFIG_CGROUPS=y
16CONFIG_CPUSETS=y 16CONFIG_CPUSETS=y
17CONFIG_CGROUP_CPUACCT=y 17CONFIG_CGROUP_CPUACCT=y
18CONFIG_RESOURCE_COUNTERS=y 18CONFIG_RESOURCE_COUNTERS=y
19CONFIG_CGROUP_MEMCG=y 19CONFIG_MEMCG=y
20CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y 20CONFIG_MEMCG_SWAP=y
21CONFIG_CGROUP_SCHED=y 21CONFIG_CGROUP_SCHED=y
22CONFIG_RT_GROUP_SCHED=y 22CONFIG_RT_GROUP_SCHED=y
23CONFIG_BLK_CGROUP=y 23CONFIG_BLK_CGROUP=y
@@ -32,20 +32,19 @@ CONFIG_EXPERT=y
32CONFIG_PROFILING=y 32CONFIG_PROFILING=y
33CONFIG_OPROFILE=y 33CONFIG_OPROFILE=y
34CONFIG_KPROBES=y 34CONFIG_KPROBES=y
35CONFIG_JUMP_LABEL=y
35CONFIG_MODULES=y 36CONFIG_MODULES=y
36CONFIG_MODULE_UNLOAD=y 37CONFIG_MODULE_UNLOAD=y
37CONFIG_MODVERSIONS=y 38CONFIG_MODVERSIONS=y
38CONFIG_PARTITION_ADVANCED=y 39CONFIG_PARTITION_ADVANCED=y
39CONFIG_IBM_PARTITION=y 40CONFIG_IBM_PARTITION=y
40CONFIG_DEFAULT_DEADLINE=y 41CONFIG_DEFAULT_DEADLINE=y
41CONFIG_PREEMPT=y 42CONFIG_HZ_100=y
42CONFIG_MEMORY_HOTPLUG=y 43CONFIG_MEMORY_HOTPLUG=y
43CONFIG_MEMORY_HOTREMOVE=y 44CONFIG_MEMORY_HOTREMOVE=y
44CONFIG_KSM=y 45CONFIG_KSM=y
45CONFIG_BINFMT_MISC=m
46CONFIG_CMM=m
47CONFIG_HZ_100=y
48CONFIG_CRASH_DUMP=y 46CONFIG_CRASH_DUMP=y
47CONFIG_BINFMT_MISC=m
49CONFIG_HIBERNATION=y 48CONFIG_HIBERNATION=y
50CONFIG_PACKET=y 49CONFIG_PACKET=y
51CONFIG_UNIX=y 50CONFIG_UNIX=y
@@ -75,6 +74,7 @@ CONFIG_NET_CLS_RSVP=m
75CONFIG_NET_CLS_RSVP6=m 74CONFIG_NET_CLS_RSVP6=m
76CONFIG_NET_CLS_ACT=y 75CONFIG_NET_CLS_ACT=y
77CONFIG_NET_ACT_POLICE=y 76CONFIG_NET_ACT_POLICE=y
77CONFIG_BPF_JIT=y
78CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 78CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
79CONFIG_DEVTMPFS=y 79CONFIG_DEVTMPFS=y
80CONFIG_BLK_DEV_LOOP=m 80CONFIG_BLK_DEV_LOOP=m
@@ -121,7 +121,6 @@ CONFIG_DEBUG_NOTIFIERS=y
121CONFIG_RCU_TRACE=y 121CONFIG_RCU_TRACE=y
122CONFIG_KPROBES_SANITY_TEST=y 122CONFIG_KPROBES_SANITY_TEST=y
123CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y 123CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
124CONFIG_CPU_NOTIFIER_ERROR_INJECT=m
125CONFIG_LATENCYTOP=y 124CONFIG_LATENCYTOP=y
126CONFIG_DEBUG_PAGEALLOC=y 125CONFIG_DEBUG_PAGEALLOC=y
127CONFIG_BLK_DEV_IO_TRACE=y 126CONFIG_BLK_DEV_IO_TRACE=y
@@ -173,3 +172,4 @@ CONFIG_CRYPTO_SHA512_S390=m
173CONFIG_CRYPTO_DES_S390=m 172CONFIG_CRYPTO_DES_S390=m
174CONFIG_CRYPTO_AES_S390=m 173CONFIG_CRYPTO_AES_S390=m
175CONFIG_CRC7=m 174CONFIG_CRC7=m
175CONFIG_CMM=m
diff --git a/arch/s390/include/asm/appldata.h b/arch/s390/include/asm/appldata.h
index f328294faeae..32a705987156 100644
--- a/arch/s390/include/asm/appldata.h
+++ b/arch/s390/include/asm/appldata.h
@@ -70,7 +70,7 @@ static inline int appldata_asm(struct appldata_product_id *id,
70 int ry; 70 int ry;
71 71
72 if (!MACHINE_IS_VM) 72 if (!MACHINE_IS_VM)
73 return -ENOSYS; 73 return -EOPNOTSUPP;
74 parm_list.diag = 0xdc; 74 parm_list.diag = 0xdc;
75 parm_list.function = fn; 75 parm_list.function = fn;
76 parm_list.parlist_length = sizeof(parm_list); 76 parm_list.parlist_length = sizeof(parm_list);
diff --git a/arch/s390/include/asm/chsc.h b/arch/s390/include/asm/chsc.h
index bf115b49f444..aea451fd182e 100644
--- a/arch/s390/include/asm/chsc.h
+++ b/arch/s390/include/asm/chsc.h
@@ -125,32 +125,4 @@ struct chsc_cpd_info {
125#define CHSC_INFO_CPD _IOWR(CHSC_IOCTL_MAGIC, 0x87, struct chsc_cpd_info) 125#define CHSC_INFO_CPD _IOWR(CHSC_IOCTL_MAGIC, 0x87, struct chsc_cpd_info)
126#define CHSC_INFO_DCAL _IOWR(CHSC_IOCTL_MAGIC, 0x88, struct chsc_dcal) 126#define CHSC_INFO_DCAL _IOWR(CHSC_IOCTL_MAGIC, 0x88, struct chsc_dcal)
127 127
128#ifdef __KERNEL__
129
130struct css_general_char {
131 u64 : 12;
132 u32 dynio : 1; /* bit 12 */
133 u32 : 28;
134 u32 aif : 1; /* bit 41 */
135 u32 : 3;
136 u32 mcss : 1; /* bit 45 */
137 u32 fcs : 1; /* bit 46 */
138 u32 : 1;
139 u32 ext_mb : 1; /* bit 48 */
140 u32 : 7;
141 u32 aif_tdd : 1; /* bit 56 */
142 u32 : 1;
143 u32 qebsm : 1; /* bit 58 */
144 u32 : 8;
145 u32 aif_osa : 1; /* bit 67 */
146 u32 : 14;
147 u32 cib : 1; /* bit 82 */
148 u32 : 5;
149 u32 fcx : 1; /* bit 88 */
150 u32 : 7;
151}__attribute__((packed));
152
153extern struct css_general_char css_general_characteristics;
154
155#endif /* __KERNEL__ */
156#endif 128#endif
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h
index 77043aa44d67..55bde6035216 100644
--- a/arch/s390/include/asm/cio.h
+++ b/arch/s390/include/asm/cio.h
@@ -80,6 +80,18 @@ struct erw {
80} __attribute__ ((packed)); 80} __attribute__ ((packed));
81 81
82/** 82/**
83 * struct erw_eadm - EADM Subchannel extended report word
84 * @b: aob error
85 * @r: arsb error
86 */
87struct erw_eadm {
88 __u32 : 16;
89 __u32 b : 1;
90 __u32 r : 1;
91 __u32 : 14;
92} __packed;
93
94/**
83 * struct sublog - subchannel logout area 95 * struct sublog - subchannel logout area
84 * @res0: reserved 96 * @res0: reserved
85 * @esf: extended status flags 97 * @esf: extended status flags
@@ -170,9 +182,22 @@ struct esw3 {
170} __attribute__ ((packed)); 182} __attribute__ ((packed));
171 183
172/** 184/**
185 * struct esw_eadm - EADM Subchannel Extended Status Word (ESW)
186 * @sublog: subchannel logout
187 * @erw: extended report word
188 */
189struct esw_eadm {
190 __u32 sublog;
191 struct erw_eadm erw;
192 __u32 : 32;
193 __u32 : 32;
194 __u32 : 32;
195} __packed;
196
197/**
173 * struct irb - interruption response block 198 * struct irb - interruption response block
174 * @scsw: subchannel status word 199 * @scsw: subchannel status word
175 * @esw: extened status word, 4 formats 200 * @esw: extened status word
176 * @ecw: extended control word 201 * @ecw: extended control word
177 * 202 *
178 * The irb that is handed to the device driver when an interrupt occurs. For 203 * The irb that is handed to the device driver when an interrupt occurs. For
@@ -191,6 +216,7 @@ struct irb {
191 struct esw1 esw1; 216 struct esw1 esw1;
192 struct esw2 esw2; 217 struct esw2 esw2;
193 struct esw3 esw3; 218 struct esw3 esw3;
219 struct esw_eadm eadm;
194 } esw; 220 } esw;
195 __u8 ecw[32]; 221 __u8 ecw[32];
196} __attribute__ ((packed,aligned(4))); 222} __attribute__ ((packed,aligned(4)));
diff --git a/arch/s390/include/asm/cmpxchg.h b/arch/s390/include/asm/cmpxchg.h
index 8d798e962b63..0f636cbdf342 100644
--- a/arch/s390/include/asm/cmpxchg.h
+++ b/arch/s390/include/asm/cmpxchg.h
@@ -7,7 +7,9 @@
7#ifndef __ASM_CMPXCHG_H 7#ifndef __ASM_CMPXCHG_H
8#define __ASM_CMPXCHG_H 8#define __ASM_CMPXCHG_H
9 9
10#include <linux/mmdebug.h>
10#include <linux/types.h> 11#include <linux/types.h>
12#include <linux/bug.h>
11 13
12extern void __xchg_called_with_bad_pointer(void); 14extern void __xchg_called_with_bad_pointer(void);
13 15
@@ -203,6 +205,65 @@ static inline unsigned long long __cmpxchg64(void *ptr,
203}) 205})
204#endif /* CONFIG_64BIT */ 206#endif /* CONFIG_64BIT */
205 207
208#define __cmpxchg_double_op(p1, p2, o1, o2, n1, n2, insn) \
209({ \
210 register __typeof__(*(p1)) __old1 asm("2") = (o1); \
211 register __typeof__(*(p2)) __old2 asm("3") = (o2); \
212 register __typeof__(*(p1)) __new1 asm("4") = (n1); \
213 register __typeof__(*(p2)) __new2 asm("5") = (n2); \
214 int cc; \
215 asm volatile( \
216 insn " %[old],%[new],%[ptr]\n" \
217 " ipm %[cc]\n" \
218 " srl %[cc],28" \
219 : [cc] "=d" (cc), [old] "+d" (__old1), "+d" (__old2) \
220 : [new] "d" (__new1), "d" (__new2), \
221 [ptr] "Q" (*(p1)), "Q" (*(p2)) \
222 : "memory", "cc"); \
223 !cc; \
224})
225
226#define __cmpxchg_double_4(p1, p2, o1, o2, n1, n2) \
227 __cmpxchg_double_op(p1, p2, o1, o2, n1, n2, "cds")
228
229#define __cmpxchg_double_8(p1, p2, o1, o2, n1, n2) \
230 __cmpxchg_double_op(p1, p2, o1, o2, n1, n2, "cdsg")
231
232extern void __cmpxchg_double_called_with_bad_pointer(void);
233
234#define __cmpxchg_double(p1, p2, o1, o2, n1, n2) \
235({ \
236 int __ret; \
237 switch (sizeof(*(p1))) { \
238 case 4: \
239 __ret = __cmpxchg_double_4(p1, p2, o1, o2, n1, n2); \
240 break; \
241 case 8: \
242 __ret = __cmpxchg_double_8(p1, p2, o1, o2, n1, n2); \
243 break; \
244 default: \
245 __cmpxchg_double_called_with_bad_pointer(); \
246 } \
247 __ret; \
248})
249
250#define cmpxchg_double(p1, p2, o1, o2, n1, n2) \
251({ \
252 __typeof__(p1) __p1 = (p1); \
253 __typeof__(p2) __p2 = (p2); \
254 int __ret; \
255 BUILD_BUG_ON(sizeof(*(p1)) != sizeof(long)); \
256 BUILD_BUG_ON(sizeof(*(p2)) != sizeof(long)); \
257 VM_BUG_ON((unsigned long)((__p1) + 1) != (unsigned long)(__p2));\
258 if (sizeof(long) == 4) \
259 __ret = __cmpxchg_double_4(__p1, __p2, o1, o2, n1, n2); \
260 else \
261 __ret = __cmpxchg_double_8(__p1, __p2, o1, o2, n1, n2); \
262 __ret; \
263})
264
265#define system_has_cmpxchg_double() 1
266
206#include <asm-generic/cmpxchg-local.h> 267#include <asm-generic/cmpxchg-local.h>
207 268
208static inline unsigned long __cmpxchg_local(void *ptr, 269static inline unsigned long __cmpxchg_local(void *ptr,
diff --git a/arch/s390/include/asm/cpu_mf.h b/arch/s390/include/asm/cpu_mf.h
index a3afecdae145..35f0020b7ba7 100644
--- a/arch/s390/include/asm/cpu_mf.h
+++ b/arch/s390/include/asm/cpu_mf.h
@@ -21,11 +21,15 @@
21#define CPU_MF_INT_SF_LSDA (1 << 22) /* loss of sample data alert */ 21#define CPU_MF_INT_SF_LSDA (1 << 22) /* loss of sample data alert */
22#define CPU_MF_INT_CF_CACA (1 << 7) /* counter auth. change alert */ 22#define CPU_MF_INT_CF_CACA (1 << 7) /* counter auth. change alert */
23#define CPU_MF_INT_CF_LCDA (1 << 6) /* loss of counter data alert */ 23#define CPU_MF_INT_CF_LCDA (1 << 6) /* loss of counter data alert */
24#define CPU_MF_INT_RI_HALTED (1 << 5) /* run-time instr. halted */
25#define CPU_MF_INT_RI_BUF_FULL (1 << 4) /* run-time instr. program
26 buffer full */
24 27
25#define CPU_MF_INT_CF_MASK (CPU_MF_INT_CF_CACA|CPU_MF_INT_CF_LCDA) 28#define CPU_MF_INT_CF_MASK (CPU_MF_INT_CF_CACA|CPU_MF_INT_CF_LCDA)
26#define CPU_MF_INT_SF_MASK (CPU_MF_INT_SF_IAE|CPU_MF_INT_SF_ISE| \ 29#define CPU_MF_INT_SF_MASK (CPU_MF_INT_SF_IAE|CPU_MF_INT_SF_ISE| \
27 CPU_MF_INT_SF_PRA|CPU_MF_INT_SF_SACA| \ 30 CPU_MF_INT_SF_PRA|CPU_MF_INT_SF_SACA| \
28 CPU_MF_INT_SF_LSDA) 31 CPU_MF_INT_SF_LSDA)
32#define CPU_MF_INT_RI_MASK (CPU_MF_INT_RI_HALTED|CPU_MF_INT_RI_BUF_FULL)
29 33
30/* CPU measurement facility support */ 34/* CPU measurement facility support */
31static inline int cpum_cf_avail(void) 35static inline int cpum_cf_avail(void)
diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h
index 8709bdef233c..023d5ae24482 100644
--- a/arch/s390/include/asm/cputime.h
+++ b/arch/s390/include/asm/cputime.h
@@ -12,6 +12,9 @@
12#include <linux/spinlock.h> 12#include <linux/spinlock.h>
13#include <asm/div64.h> 13#include <asm/div64.h>
14 14
15
16#define __ARCH_HAS_VTIME_ACCOUNT
17
15/* We want to use full resolution of the CPU timer: 2**-12 micro-seconds. */ 18/* We want to use full resolution of the CPU timer: 2**-12 micro-seconds. */
16 19
17typedef unsigned long long __nocast cputime_t; 20typedef unsigned long long __nocast cputime_t;
diff --git a/arch/s390/include/asm/css_chars.h b/arch/s390/include/asm/css_chars.h
new file mode 100644
index 000000000000..a06ebc2623fb
--- /dev/null
+++ b/arch/s390/include/asm/css_chars.h
@@ -0,0 +1,39 @@
1#ifndef _ASM_CSS_CHARS_H
2#define _ASM_CSS_CHARS_H
3
4#include <linux/types.h>
5
6#ifdef __KERNEL__
7
8struct css_general_char {
9 u64 : 12;
10 u32 dynio : 1; /* bit 12 */
11 u32 : 4;
12 u32 eadm : 1; /* bit 17 */
13 u32 : 23;
14 u32 aif : 1; /* bit 41 */
15 u32 : 3;
16 u32 mcss : 1; /* bit 45 */
17 u32 fcs : 1; /* bit 46 */
18 u32 : 1;
19 u32 ext_mb : 1; /* bit 48 */
20 u32 : 7;
21 u32 aif_tdd : 1; /* bit 56 */
22 u32 : 1;
23 u32 qebsm : 1; /* bit 58 */
24 u32 : 8;
25 u32 aif_osa : 1; /* bit 67 */
26 u32 : 12;
27 u32 eadm_rf : 1; /* bit 80 */
28 u32 : 1;
29 u32 cib : 1; /* bit 82 */
30 u32 : 5;
31 u32 fcx : 1; /* bit 88 */
32 u32 : 19;
33 u32 alt_ssi : 1; /* bit 108 */
34} __packed;
35
36extern struct css_general_char css_general_characteristics;
37
38#endif /* __KERNEL__ */
39#endif
diff --git a/arch/s390/include/asm/eadm.h b/arch/s390/include/asm/eadm.h
new file mode 100644
index 000000000000..8d4847191ecc
--- /dev/null
+++ b/arch/s390/include/asm/eadm.h
@@ -0,0 +1,124 @@
1#ifndef _ASM_S390_EADM_H
2#define _ASM_S390_EADM_H
3
4#include <linux/types.h>
5#include <linux/device.h>
6
7struct arqb {
8 u64 data;
9 u16 fmt:4;
10 u16:12;
11 u16 cmd_code;
12 u16:16;
13 u16 msb_count;
14 u32 reserved[12];
15} __packed;
16
17#define ARQB_CMD_MOVE 1
18
19struct arsb {
20 u16 fmt:4;
21 u32:28;
22 u8 ef;
23 u8:8;
24 u8 ecbi;
25 u8:8;
26 u8 fvf;
27 u16:16;
28 u8 eqc;
29 u32:32;
30 u64 fail_msb;
31 u64 fail_aidaw;
32 u64 fail_ms;
33 u64 fail_scm;
34 u32 reserved[4];
35} __packed;
36
37struct msb {
38 u8 fmt:4;
39 u8 oc:4;
40 u8 flags;
41 u16:12;
42 u16 bs:4;
43 u32 blk_count;
44 u64 data_addr;
45 u64 scm_addr;
46 u64:64;
47} __packed;
48
49struct aidaw {
50 u8 flags;
51 u32 :24;
52 u32 :32;
53 u64 data_addr;
54} __packed;
55
56#define MSB_OC_CLEAR 0
57#define MSB_OC_READ 1
58#define MSB_OC_WRITE 2
59#define MSB_OC_RELEASE 3
60
61#define MSB_FLAG_BNM 0x80
62#define MSB_FLAG_IDA 0x40
63
64#define MSB_BS_4K 0
65#define MSB_BS_1M 1
66
67#define AOB_NR_MSB 124
68
69struct aob {
70 struct arqb request;
71 struct arsb response;
72 struct msb msb[AOB_NR_MSB];
73} __packed __aligned(PAGE_SIZE);
74
75struct aob_rq_header {
76 struct scm_device *scmdev;
77 char data[0];
78};
79
80struct scm_device {
81 u64 address;
82 u64 size;
83 unsigned int nr_max_block;
84 struct device dev;
85 struct {
86 unsigned int persistence:4;
87 unsigned int oper_state:4;
88 unsigned int data_state:4;
89 unsigned int rank:4;
90 unsigned int release:1;
91 unsigned int res_id:8;
92 } __packed attrs;
93};
94
95#define OP_STATE_GOOD 1
96#define OP_STATE_TEMP_ERR 2
97#define OP_STATE_PERM_ERR 3
98
99struct scm_driver {
100 struct device_driver drv;
101 int (*probe) (struct scm_device *scmdev);
102 int (*remove) (struct scm_device *scmdev);
103 void (*notify) (struct scm_device *scmdev);
104 void (*handler) (struct scm_device *scmdev, void *data, int error);
105};
106
107int scm_driver_register(struct scm_driver *scmdrv);
108void scm_driver_unregister(struct scm_driver *scmdrv);
109
110int scm_start_aob(struct aob *aob);
111void scm_irq_handler(struct aob *aob, int error);
112
113struct eadm_ops {
114 int (*eadm_start) (struct aob *aob);
115 struct module *owner;
116};
117
118int scm_get_ref(void);
119void scm_put_ref(void);
120
121void register_eadm_ops(struct eadm_ops *ops);
122void unregister_eadm_ops(struct eadm_ops *ops);
123
124#endif /* _ASM_S390_EADM_H */
diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h
index 9b94a160fe7f..178ff966a8ba 100644
--- a/arch/s390/include/asm/elf.h
+++ b/arch/s390/include/asm/elf.h
@@ -101,6 +101,7 @@
101#define HWCAP_S390_HPAGE 128 101#define HWCAP_S390_HPAGE 128
102#define HWCAP_S390_ETF3EH 256 102#define HWCAP_S390_ETF3EH 256
103#define HWCAP_S390_HIGH_GPRS 512 103#define HWCAP_S390_HIGH_GPRS 512
104#define HWCAP_S390_TE 1024
104 105
105/* 106/*
106 * These are used to set parameters in the core dumps. 107 * These are used to set parameters in the core dumps.
@@ -212,4 +213,6 @@ int arch_setup_additional_pages(struct linux_binprm *, int);
212extern unsigned long arch_randomize_brk(struct mm_struct *mm); 213extern unsigned long arch_randomize_brk(struct mm_struct *mm);
213#define arch_randomize_brk arch_randomize_brk 214#define arch_randomize_brk arch_randomize_brk
214 215
216void *fill_cpu_elf_notes(void *ptr, struct save_area *sa);
217
215#endif 218#endif
diff --git a/arch/s390/include/asm/etr.h b/arch/s390/include/asm/etr.h
index a24b03b9fb64..629b79a93165 100644
--- a/arch/s390/include/asm/etr.h
+++ b/arch/s390/include/asm/etr.h
@@ -140,7 +140,7 @@ struct etr_ptff_qto {
140/* Inline assembly helper functions */ 140/* Inline assembly helper functions */
141static inline int etr_setr(struct etr_eacr *ctrl) 141static inline int etr_setr(struct etr_eacr *ctrl)
142{ 142{
143 int rc = -ENOSYS; 143 int rc = -EOPNOTSUPP;
144 144
145 asm volatile( 145 asm volatile(
146 " .insn s,0xb2160000,%1\n" 146 " .insn s,0xb2160000,%1\n"
@@ -154,7 +154,7 @@ static inline int etr_setr(struct etr_eacr *ctrl)
154/* Stores a format 1 aib with 64 bytes */ 154/* Stores a format 1 aib with 64 bytes */
155static inline int etr_stetr(struct etr_aib *aib) 155static inline int etr_stetr(struct etr_aib *aib)
156{ 156{
157 int rc = -ENOSYS; 157 int rc = -EOPNOTSUPP;
158 158
159 asm volatile( 159 asm volatile(
160 " .insn s,0xb2170000,%1\n" 160 " .insn s,0xb2170000,%1\n"
@@ -169,7 +169,7 @@ static inline int etr_stetr(struct etr_aib *aib)
169static inline int etr_steai(struct etr_aib *aib, unsigned int func) 169static inline int etr_steai(struct etr_aib *aib, unsigned int func)
170{ 170{
171 register unsigned int reg0 asm("0") = func; 171 register unsigned int reg0 asm("0") = func;
172 int rc = -ENOSYS; 172 int rc = -EOPNOTSUPP;
173 173
174 asm volatile( 174 asm volatile(
175 " .insn s,0xb2b30000,%1\n" 175 " .insn s,0xb2b30000,%1\n"
@@ -190,7 +190,7 @@ static inline int etr_ptff(void *ptff_block, unsigned int func)
190{ 190{
191 register unsigned int reg0 asm("0") = func; 191 register unsigned int reg0 asm("0") = func;
192 register unsigned long reg1 asm("1") = (unsigned long) ptff_block; 192 register unsigned long reg1 asm("1") = (unsigned long) ptff_block;
193 int rc = -ENOSYS; 193 int rc = -EOPNOTSUPP;
194 194
195 asm volatile( 195 asm volatile(
196 " .word 0x0104\n" 196 " .word 0x0104\n"
diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h
index 799ed0f1643d..2d6e6e380564 100644
--- a/arch/s390/include/asm/hugetlb.h
+++ b/arch/s390/include/asm/hugetlb.h
@@ -66,16 +66,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep)
66 return pte; 66 return pte;
67} 67}
68 68
69static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
70 unsigned long addr, pte_t *ptep)
71{
72 pte_t pte = huge_ptep_get(ptep);
73
74 mm->context.flush_mm = 1;
75 pmd_clear((pmd_t *) ptep);
76 return pte;
77}
78
79static inline void __pmd_csp(pmd_t *pmdp) 69static inline void __pmd_csp(pmd_t *pmdp)
80{ 70{
81 register unsigned long reg2 asm("2") = pmd_val(*pmdp); 71 register unsigned long reg2 asm("2") = pmd_val(*pmdp);
@@ -117,6 +107,15 @@ static inline void huge_ptep_invalidate(struct mm_struct *mm,
117 __pmd_csp(pmdp); 107 __pmd_csp(pmdp);
118} 108}
119 109
110static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
111 unsigned long addr, pte_t *ptep)
112{
113 pte_t pte = huge_ptep_get(ptep);
114
115 huge_ptep_invalidate(mm, addr, ptep);
116 return pte;
117}
118
120#define huge_ptep_set_access_flags(__vma, __addr, __ptep, __entry, __dirty) \ 119#define huge_ptep_set_access_flags(__vma, __addr, __ptep, __entry, __dirty) \
121({ \ 120({ \
122 int __changed = !pte_same(huge_ptep_get(__ptep), __entry); \ 121 int __changed = !pte_same(huge_ptep_get(__ptep), __entry); \
@@ -131,10 +130,7 @@ static inline void huge_ptep_invalidate(struct mm_struct *mm,
131({ \ 130({ \
132 pte_t __pte = huge_ptep_get(__ptep); \ 131 pte_t __pte = huge_ptep_get(__ptep); \
133 if (pte_write(__pte)) { \ 132 if (pte_write(__pte)) { \
134 (__mm)->context.flush_mm = 1; \ 133 huge_ptep_invalidate(__mm, __addr, __ptep); \
135 if (atomic_read(&(__mm)->context.attach_count) > 1 || \
136 (__mm) != current->active_mm) \
137 huge_ptep_invalidate(__mm, __addr, __ptep); \
138 set_huge_pte_at(__mm, __addr, __ptep, \ 134 set_huge_pte_at(__mm, __addr, __ptep, \
139 huge_pte_wrprotect(__pte)); \ 135 huge_pte_wrprotect(__pte)); \
140 } \ 136 } \
diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h
index 2b9d41899d21..6703dd986fd4 100644
--- a/arch/s390/include/asm/irq.h
+++ b/arch/s390/include/asm/irq.h
@@ -19,6 +19,7 @@ enum interruption_class {
19 EXTINT_IUC, 19 EXTINT_IUC,
20 EXTINT_CMS, 20 EXTINT_CMS,
21 EXTINT_CMC, 21 EXTINT_CMC,
22 EXTINT_CMR,
22 IOINT_CIO, 23 IOINT_CIO,
23 IOINT_QAI, 24 IOINT_QAI,
24 IOINT_DAS, 25 IOINT_DAS,
@@ -30,6 +31,7 @@ enum interruption_class {
30 IOINT_CLW, 31 IOINT_CLW,
31 IOINT_CTC, 32 IOINT_CTC,
32 IOINT_APB, 33 IOINT_APB,
34 IOINT_ADM,
33 IOINT_CSC, 35 IOINT_CSC,
34 NMI_NMI, 36 NMI_NMI,
35 NR_IRQS, 37 NR_IRQS,
diff --git a/arch/s390/include/asm/isc.h b/arch/s390/include/asm/isc.h
index 1420a1115948..5ae606456b0a 100644
--- a/arch/s390/include/asm/isc.h
+++ b/arch/s390/include/asm/isc.h
@@ -14,6 +14,7 @@
14/* Regular I/O interrupts. */ 14/* Regular I/O interrupts. */
15#define IO_SCH_ISC 3 /* regular I/O subchannels */ 15#define IO_SCH_ISC 3 /* regular I/O subchannels */
16#define CONSOLE_ISC 1 /* console I/O subchannel */ 16#define CONSOLE_ISC 1 /* console I/O subchannel */
17#define EADM_SCH_ISC 4 /* EADM subchannels */
17#define CHSC_SCH_ISC 7 /* CHSC subchannels */ 18#define CHSC_SCH_ISC 7 /* CHSC subchannels */
18/* Adapter interrupts. */ 19/* Adapter interrupts. */
19#define QDIO_AIRQ_ISC IO_SCH_ISC /* I/O subchannel in qdio mode */ 20#define QDIO_AIRQ_ISC IO_SCH_ISC /* I/O subchannel in qdio mode */
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h
index aab5555bbbda..bbf8141408cd 100644
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -329,9 +329,13 @@ struct _lowcore {
329 __u8 pad_0x1338[0x1340-0x1338]; /* 0x1338 */ 329 __u8 pad_0x1338[0x1340-0x1338]; /* 0x1338 */
330 __u32 access_regs_save_area[16]; /* 0x1340 */ 330 __u32 access_regs_save_area[16]; /* 0x1340 */
331 __u64 cregs_save_area[16]; /* 0x1380 */ 331 __u64 cregs_save_area[16]; /* 0x1380 */
332 __u8 pad_0x1400[0x1800-0x1400]; /* 0x1400 */
333
334 /* Transaction abort diagnostic block */
335 __u8 pgm_tdb[256]; /* 0x1800 */
332 336
333 /* align to the top of the prefix area */ 337 /* align to the top of the prefix area */
334 __u8 pad_0x1400[0x2000-0x1400]; /* 0x1400 */ 338 __u8 pad_0x1900[0x2000-0x1900]; /* 0x1900 */
335} __packed; 339} __packed;
336 340
337#endif /* CONFIG_32BIT */ 341#endif /* CONFIG_32BIT */
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h
index b749c5733657..084e7755ed9b 100644
--- a/arch/s390/include/asm/mmu_context.h
+++ b/arch/s390/include/asm/mmu_context.h
@@ -57,7 +57,7 @@ static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk)
57 pgd_t *pgd = mm->pgd; 57 pgd_t *pgd = mm->pgd;
58 58
59 S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd); 59 S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd);
60 if (addressing_mode != HOME_SPACE_MODE) { 60 if (s390_user_mode != HOME_SPACE_MODE) {
61 /* Load primary space page table origin. */ 61 /* Load primary space page table origin. */
62 asm volatile(LCTL_OPCODE" 1,1,%0\n" 62 asm volatile(LCTL_OPCODE" 1,1,%0\n"
63 : : "m" (S390_lowcore.user_asce) ); 63 : : "m" (S390_lowcore.user_asce) );
diff --git a/arch/s390/include/asm/percpu.h b/arch/s390/include/asm/percpu.h
index 6537e72e0853..86fe0ee2cee5 100644
--- a/arch/s390/include/asm/percpu.h
+++ b/arch/s390/include/asm/percpu.h
@@ -20,7 +20,7 @@
20#endif 20#endif
21 21
22#define arch_this_cpu_to_op(pcp, val, op) \ 22#define arch_this_cpu_to_op(pcp, val, op) \
23do { \ 23({ \
24 typedef typeof(pcp) pcp_op_T__; \ 24 typedef typeof(pcp) pcp_op_T__; \
25 pcp_op_T__ old__, new__, prev__; \ 25 pcp_op_T__ old__, new__, prev__; \
26 pcp_op_T__ *ptr__; \ 26 pcp_op_T__ *ptr__; \
@@ -39,13 +39,19 @@ do { \
39 } \ 39 } \
40 } while (prev__ != old__); \ 40 } while (prev__ != old__); \
41 preempt_enable(); \ 41 preempt_enable(); \
42} while (0) 42 new__; \
43})
43 44
44#define this_cpu_add_1(pcp, val) arch_this_cpu_to_op(pcp, val, +) 45#define this_cpu_add_1(pcp, val) arch_this_cpu_to_op(pcp, val, +)
45#define this_cpu_add_2(pcp, val) arch_this_cpu_to_op(pcp, val, +) 46#define this_cpu_add_2(pcp, val) arch_this_cpu_to_op(pcp, val, +)
46#define this_cpu_add_4(pcp, val) arch_this_cpu_to_op(pcp, val, +) 47#define this_cpu_add_4(pcp, val) arch_this_cpu_to_op(pcp, val, +)
47#define this_cpu_add_8(pcp, val) arch_this_cpu_to_op(pcp, val, +) 48#define this_cpu_add_8(pcp, val) arch_this_cpu_to_op(pcp, val, +)
48 49
50#define this_cpu_add_return_1(pcp, val) arch_this_cpu_to_op(pcp, val, +)
51#define this_cpu_add_return_2(pcp, val) arch_this_cpu_to_op(pcp, val, +)
52#define this_cpu_add_return_4(pcp, val) arch_this_cpu_to_op(pcp, val, +)
53#define this_cpu_add_return_8(pcp, val) arch_this_cpu_to_op(pcp, val, +)
54
49#define this_cpu_and_1(pcp, val) arch_this_cpu_to_op(pcp, val, &) 55#define this_cpu_and_1(pcp, val) arch_this_cpu_to_op(pcp, val, &)
50#define this_cpu_and_2(pcp, val) arch_this_cpu_to_op(pcp, val, &) 56#define this_cpu_and_2(pcp, val) arch_this_cpu_to_op(pcp, val, &)
51#define this_cpu_and_4(pcp, val) arch_this_cpu_to_op(pcp, val, &) 57#define this_cpu_and_4(pcp, val) arch_this_cpu_to_op(pcp, val, &)
@@ -61,7 +67,7 @@ do { \
61#define this_cpu_xor_4(pcp, val) arch_this_cpu_to_op(pcp, val, ^) 67#define this_cpu_xor_4(pcp, val) arch_this_cpu_to_op(pcp, val, ^)
62#define this_cpu_xor_8(pcp, val) arch_this_cpu_to_op(pcp, val, ^) 68#define this_cpu_xor_8(pcp, val) arch_this_cpu_to_op(pcp, val, ^)
63 69
64#define arch_this_cpu_cmpxchg(pcp, oval, nval) \ 70#define arch_this_cpu_cmpxchg(pcp, oval, nval) \
65({ \ 71({ \
66 typedef typeof(pcp) pcp_op_T__; \ 72 typedef typeof(pcp) pcp_op_T__; \
67 pcp_op_T__ ret__; \ 73 pcp_op_T__ ret__; \
@@ -84,6 +90,44 @@ do { \
84#define this_cpu_cmpxchg_4(pcp, oval, nval) arch_this_cpu_cmpxchg(pcp, oval, nval) 90#define this_cpu_cmpxchg_4(pcp, oval, nval) arch_this_cpu_cmpxchg(pcp, oval, nval)
85#define this_cpu_cmpxchg_8(pcp, oval, nval) arch_this_cpu_cmpxchg(pcp, oval, nval) 91#define this_cpu_cmpxchg_8(pcp, oval, nval) arch_this_cpu_cmpxchg(pcp, oval, nval)
86 92
93#define arch_this_cpu_xchg(pcp, nval) \
94({ \
95 typeof(pcp) *ptr__; \
96 typeof(pcp) ret__; \
97 preempt_disable(); \
98 ptr__ = __this_cpu_ptr(&(pcp)); \
99 ret__ = xchg(ptr__, nval); \
100 preempt_enable(); \
101 ret__; \
102})
103
104#define this_cpu_xchg_1(pcp, nval) arch_this_cpu_xchg(pcp, nval)
105#define this_cpu_xchg_2(pcp, nval) arch_this_cpu_xchg(pcp, nval)
106#define this_cpu_xchg_4(pcp, nval) arch_this_cpu_xchg(pcp, nval)
107#ifdef CONFIG_64BIT
108#define this_cpu_xchg_8(pcp, nval) arch_this_cpu_xchg(pcp, nval)
109#endif
110
111#define arch_this_cpu_cmpxchg_double(pcp1, pcp2, o1, o2, n1, n2) \
112({ \
113 typeof(pcp1) o1__ = (o1), n1__ = (n1); \
114 typeof(pcp2) o2__ = (o2), n2__ = (n2); \
115 typeof(pcp1) *p1__; \
116 typeof(pcp2) *p2__; \
117 int ret__; \
118 preempt_disable(); \
119 p1__ = __this_cpu_ptr(&(pcp1)); \
120 p2__ = __this_cpu_ptr(&(pcp2)); \
121 ret__ = __cmpxchg_double(p1__, p2__, o1__, o2__, n1__, n2__); \
122 preempt_enable(); \
123 ret__; \
124})
125
126#define this_cpu_cmpxchg_double_4 arch_this_cpu_cmpxchg_double
127#ifdef CONFIG_64BIT
128#define this_cpu_cmpxchg_double_8 arch_this_cpu_cmpxchg_double
129#endif
130
87#include <asm-generic/percpu.h> 131#include <asm-generic/percpu.h>
88 132
89#endif /* __ARCH_S390_PERCPU__ */ 133#endif /* __ARCH_S390_PERCPU__ */
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index 11e4e3236937..f3e0aabfc6bc 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -11,12 +11,15 @@
11#ifndef __ASM_S390_PROCESSOR_H 11#ifndef __ASM_S390_PROCESSOR_H
12#define __ASM_S390_PROCESSOR_H 12#define __ASM_S390_PROCESSOR_H
13 13
14#ifndef __ASSEMBLY__
15
14#include <linux/linkage.h> 16#include <linux/linkage.h>
15#include <linux/irqflags.h> 17#include <linux/irqflags.h>
16#include <asm/cpu.h> 18#include <asm/cpu.h>
17#include <asm/page.h> 19#include <asm/page.h>
18#include <asm/ptrace.h> 20#include <asm/ptrace.h>
19#include <asm/setup.h> 21#include <asm/setup.h>
22#include <asm/runtime_instr.h>
20 23
21/* 24/*
22 * Default implementation of macro that returns current 25 * Default implementation of macro that returns current
@@ -75,11 +78,20 @@ struct thread_struct {
75 unsigned long gmap_addr; /* address of last gmap fault. */ 78 unsigned long gmap_addr; /* address of last gmap fault. */
76 struct per_regs per_user; /* User specified PER registers */ 79 struct per_regs per_user; /* User specified PER registers */
77 struct per_event per_event; /* Cause of the last PER trap */ 80 struct per_event per_event; /* Cause of the last PER trap */
81 unsigned long per_flags; /* Flags to control debug behavior */
78 /* pfault_wait is used to block the process on a pfault event */ 82 /* pfault_wait is used to block the process on a pfault event */
79 unsigned long pfault_wait; 83 unsigned long pfault_wait;
80 struct list_head list; 84 struct list_head list;
85 /* cpu runtime instrumentation */
86 struct runtime_instr_cb *ri_cb;
87 int ri_signum;
88#ifdef CONFIG_64BIT
89 unsigned char trap_tdb[256]; /* Transaction abort diagnose block */
90#endif
81}; 91};
82 92
93#define PER_FLAG_NO_TE 1UL /* Flag to disable transactions. */
94
83typedef struct thread_struct thread_struct; 95typedef struct thread_struct thread_struct;
84 96
85/* 97/*
@@ -130,6 +142,12 @@ struct task_struct;
130struct mm_struct; 142struct mm_struct;
131struct seq_file; 143struct seq_file;
132 144
145#ifdef CONFIG_64BIT
146extern void show_cacheinfo(struct seq_file *m);
147#else
148static inline void show_cacheinfo(struct seq_file *m) { }
149#endif
150
133/* Free all resources held by a thread. */ 151/* Free all resources held by a thread. */
134extern void release_thread(struct task_struct *); 152extern void release_thread(struct task_struct *);
135extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); 153extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
@@ -140,6 +158,7 @@ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
140extern unsigned long thread_saved_pc(struct task_struct *t); 158extern unsigned long thread_saved_pc(struct task_struct *t);
141 159
142extern void show_code(struct pt_regs *regs); 160extern void show_code(struct pt_regs *regs);
161extern void print_fn_code(unsigned char *code, unsigned long len);
143 162
144unsigned long get_wchan(struct task_struct *p); 163unsigned long get_wchan(struct task_struct *p);
145#define task_pt_regs(tsk) ((struct pt_regs *) \ 164#define task_pt_regs(tsk) ((struct pt_regs *) \
@@ -331,23 +350,6 @@ extern void (*s390_base_ext_handler_fn)(void);
331 350
332#define ARCH_LOW_ADDRESS_LIMIT 0x7fffffffUL 351#define ARCH_LOW_ADDRESS_LIMIT 0x7fffffffUL
333 352
334/*
335 * Helper macro for exception table entries
336 */
337#ifndef CONFIG_64BIT
338#define EX_TABLE(_fault,_target) \
339 ".section __ex_table,\"a\"\n" \
340 " .align 4\n" \
341 " .long " #_fault "," #_target "\n" \
342 ".previous\n"
343#else
344#define EX_TABLE(_fault,_target) \
345 ".section __ex_table,\"a\"\n" \
346 " .align 8\n" \
347 " .quad " #_fault "," #_target "\n" \
348 ".previous\n"
349#endif
350
351extern int memcpy_real(void *, void *, size_t); 353extern int memcpy_real(void *, void *, size_t);
352extern void memcpy_absolute(void *, void *, size_t); 354extern void memcpy_absolute(void *, void *, size_t);
353 355
@@ -358,4 +360,25 @@ extern void memcpy_absolute(void *, void *, size_t);
358 memcpy_absolute(&(dest), &__tmp, sizeof(__tmp)); \ 360 memcpy_absolute(&(dest), &__tmp, sizeof(__tmp)); \
359} 361}
360 362
361#endif /* __ASM_S390_PROCESSOR_H */ 363/*
364 * Helper macro for exception table entries
365 */
366#define EX_TABLE(_fault, _target) \
367 ".section __ex_table,\"a\"\n" \
368 ".align 4\n" \
369 ".long (" #_fault ") - .\n" \
370 ".long (" #_target ") - .\n" \
371 ".previous\n"
372
373#else /* __ASSEMBLY__ */
374
375#define EX_TABLE(_fault, _target) \
376 .section __ex_table,"a" ; \
377 .align 4 ; \
378 .long (_fault) - . ; \
379 .long (_target) - . ; \
380 .previous
381
382#endif /* __ASSEMBLY__ */
383
384#endif /* __ASM_S390_PROCESSOR_H */
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h
index d5f08ea566ed..ce20a53afe91 100644
--- a/arch/s390/include/asm/ptrace.h
+++ b/arch/s390/include/asm/ptrace.h
@@ -235,6 +235,7 @@ typedef struct
235#define PSW_MASK_ASC 0x0000C000UL 235#define PSW_MASK_ASC 0x0000C000UL
236#define PSW_MASK_CC 0x00003000UL 236#define PSW_MASK_CC 0x00003000UL
237#define PSW_MASK_PM 0x00000F00UL 237#define PSW_MASK_PM 0x00000F00UL
238#define PSW_MASK_RI 0x00000000UL
238#define PSW_MASK_EA 0x00000000UL 239#define PSW_MASK_EA 0x00000000UL
239#define PSW_MASK_BA 0x00000000UL 240#define PSW_MASK_BA 0x00000000UL
240 241
@@ -264,10 +265,11 @@ typedef struct
264#define PSW_MASK_ASC 0x0000C00000000000UL 265#define PSW_MASK_ASC 0x0000C00000000000UL
265#define PSW_MASK_CC 0x0000300000000000UL 266#define PSW_MASK_CC 0x0000300000000000UL
266#define PSW_MASK_PM 0x00000F0000000000UL 267#define PSW_MASK_PM 0x00000F0000000000UL
268#define PSW_MASK_RI 0x0000008000000000UL
267#define PSW_MASK_EA 0x0000000100000000UL 269#define PSW_MASK_EA 0x0000000100000000UL
268#define PSW_MASK_BA 0x0000000080000000UL 270#define PSW_MASK_BA 0x0000000080000000UL
269 271
270#define PSW_MASK_USER 0x00003F0180000000UL 272#define PSW_MASK_USER 0x00003F8180000000UL
271 273
272#define PSW_ADDR_AMODE 0x0000000000000000UL 274#define PSW_ADDR_AMODE 0x0000000000000000UL
273#define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL 275#define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL
@@ -359,17 +361,19 @@ struct per_struct_kernel {
359 unsigned char access_id; /* PER trap access identification */ 361 unsigned char access_id; /* PER trap access identification */
360}; 362};
361 363
362#define PER_EVENT_MASK 0xE9000000UL 364#define PER_EVENT_MASK 0xEB000000UL
363 365
364#define PER_EVENT_BRANCH 0x80000000UL 366#define PER_EVENT_BRANCH 0x80000000UL
365#define PER_EVENT_IFETCH 0x40000000UL 367#define PER_EVENT_IFETCH 0x40000000UL
366#define PER_EVENT_STORE 0x20000000UL 368#define PER_EVENT_STORE 0x20000000UL
367#define PER_EVENT_STORE_REAL 0x08000000UL 369#define PER_EVENT_STORE_REAL 0x08000000UL
370#define PER_EVENT_TRANSACTION_END 0x02000000UL
368#define PER_EVENT_NULLIFICATION 0x01000000UL 371#define PER_EVENT_NULLIFICATION 0x01000000UL
369 372
370#define PER_CONTROL_MASK 0x00a00000UL 373#define PER_CONTROL_MASK 0x00e00000UL
371 374
372#define PER_CONTROL_BRANCH_ADDRESS 0x00800000UL 375#define PER_CONTROL_BRANCH_ADDRESS 0x00800000UL
376#define PER_CONTROL_SUSPENSION 0x00400000UL
373#define PER_CONTROL_ALTERATION 0x00200000UL 377#define PER_CONTROL_ALTERATION 0x00200000UL
374 378
375#endif 379#endif
@@ -483,6 +487,8 @@ typedef struct
483#define PTRACE_GET_LAST_BREAK 0x5006 487#define PTRACE_GET_LAST_BREAK 0x5006
484#define PTRACE_PEEK_SYSTEM_CALL 0x5007 488#define PTRACE_PEEK_SYSTEM_CALL 0x5007
485#define PTRACE_POKE_SYSTEM_CALL 0x5008 489#define PTRACE_POKE_SYSTEM_CALL 0x5008
490#define PTRACE_ENABLE_TE 0x5009
491#define PTRACE_DISABLE_TE 0x5010
486 492
487/* 493/*
488 * PT_PROT definition is loosely based on hppa bsd definition in 494 * PT_PROT definition is loosely based on hppa bsd definition in
diff --git a/arch/s390/include/asm/runtime_instr.h b/arch/s390/include/asm/runtime_instr.h
new file mode 100644
index 000000000000..830da737ff85
--- /dev/null
+++ b/arch/s390/include/asm/runtime_instr.h
@@ -0,0 +1,98 @@
1#ifndef _RUNTIME_INSTR_H
2#define _RUNTIME_INSTR_H
3
4#define S390_RUNTIME_INSTR_START 0x1
5#define S390_RUNTIME_INSTR_STOP 0x2
6
7struct runtime_instr_cb {
8 __u64 buf_current;
9 __u64 buf_origin;
10 __u64 buf_limit;
11
12 __u32 valid : 1;
13 __u32 pstate : 1;
14 __u32 pstate_set_buf : 1;
15 __u32 home_space : 1;
16 __u32 altered : 1;
17 __u32 : 3;
18 __u32 pstate_sample : 1;
19 __u32 sstate_sample : 1;
20 __u32 pstate_collect : 1;
21 __u32 sstate_collect : 1;
22 __u32 : 1;
23 __u32 halted_int : 1;
24 __u32 int_requested : 1;
25 __u32 buffer_full_int : 1;
26 __u32 key : 4;
27 __u32 : 9;
28 __u32 rgs : 3;
29
30 __u32 mode : 4;
31 __u32 next : 1;
32 __u32 mae : 1;
33 __u32 : 2;
34 __u32 call_type_br : 1;
35 __u32 return_type_br : 1;
36 __u32 other_type_br : 1;
37 __u32 bc_other_type : 1;
38 __u32 emit : 1;
39 __u32 tx_abort : 1;
40 __u32 : 2;
41 __u32 bp_xn : 1;
42 __u32 bp_xt : 1;
43 __u32 bp_ti : 1;
44 __u32 bp_ni : 1;
45 __u32 suppr_y : 1;
46 __u32 suppr_z : 1;
47
48 __u32 dc_miss_extra : 1;
49 __u32 lat_lev_ignore : 1;
50 __u32 ic_lat_lev : 4;
51 __u32 dc_lat_lev : 4;
52
53 __u64 reserved1;
54 __u64 scaling_factor;
55 __u64 rsic;
56 __u64 reserved2;
57} __packed __aligned(8);
58
59extern struct runtime_instr_cb runtime_instr_empty_cb;
60
61static inline void load_runtime_instr_cb(struct runtime_instr_cb *cb)
62{
63 asm volatile(".insn rsy,0xeb0000000060,0,0,%0" /* LRIC */
64 : : "Q" (*cb));
65}
66
67static inline void store_runtime_instr_cb(struct runtime_instr_cb *cb)
68{
69 asm volatile(".insn rsy,0xeb0000000061,0,0,%0" /* STRIC */
70 : "=Q" (*cb) : : "cc");
71}
72
73static inline void save_ri_cb(struct runtime_instr_cb *cb_prev)
74{
75#ifdef CONFIG_64BIT
76 if (cb_prev)
77 store_runtime_instr_cb(cb_prev);
78#endif
79}
80
81static inline void restore_ri_cb(struct runtime_instr_cb *cb_next,
82 struct runtime_instr_cb *cb_prev)
83{
84#ifdef CONFIG_64BIT
85 if (cb_next)
86 load_runtime_instr_cb(cb_next);
87 else if (cb_prev)
88 load_runtime_instr_cb(&runtime_instr_empty_cb);
89#endif
90}
91
92#ifdef CONFIG_64BIT
93extern void exit_thread_runtime_instr(void);
94#else
95static inline void exit_thread_runtime_instr(void) { }
96#endif
97
98#endif /* _RUNTIME_INSTR_H */
diff --git a/arch/s390/include/asm/scsw.h b/arch/s390/include/asm/scsw.h
index 4071d00978cb..4af99cdaddf5 100644
--- a/arch/s390/include/asm/scsw.h
+++ b/arch/s390/include/asm/scsw.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Helper functions for scsw access. 2 * Helper functions for scsw access.
3 * 3 *
4 * Copyright IBM Corp. 2008, 2009 4 * Copyright IBM Corp. 2008, 2012
5 * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> 5 * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
6 */ 6 */
7 7
@@ -9,7 +9,7 @@
9#define _ASM_S390_SCSW_H_ 9#define _ASM_S390_SCSW_H_
10 10
11#include <linux/types.h> 11#include <linux/types.h>
12#include <asm/chsc.h> 12#include <asm/css_chars.h>
13#include <asm/cio.h> 13#include <asm/cio.h>
14 14
15/** 15/**
@@ -100,14 +100,46 @@ struct tm_scsw {
100} __attribute__ ((packed)); 100} __attribute__ ((packed));
101 101
102/** 102/**
103 * struct eadm_scsw - subchannel status word for eadm subchannels
104 * @key: subchannel key
105 * @eswf: esw format
106 * @cc: deferred condition code
107 * @ectl: extended control
108 * @fctl: function control
109 * @actl: activity control
110 * @stctl: status control
111 * @aob: AOB address
112 * @dstat: device status
113 * @cstat: subchannel status
114 */
115struct eadm_scsw {
116 u32 key:4;
117 u32:1;
118 u32 eswf:1;
119 u32 cc:2;
120 u32:6;
121 u32 ectl:1;
122 u32:2;
123 u32 fctl:3;
124 u32 actl:7;
125 u32 stctl:5;
126 u32 aob;
127 u32 dstat:8;
128 u32 cstat:8;
129 u32:16;
130} __packed;
131
132/**
103 * union scsw - subchannel status word 133 * union scsw - subchannel status word
104 * @cmd: command-mode SCSW 134 * @cmd: command-mode SCSW
105 * @tm: transport-mode SCSW 135 * @tm: transport-mode SCSW
136 * @eadm: eadm SCSW
106 */ 137 */
107union scsw { 138union scsw {
108 struct cmd_scsw cmd; 139 struct cmd_scsw cmd;
109 struct tm_scsw tm; 140 struct tm_scsw tm;
110} __attribute__ ((packed)); 141 struct eadm_scsw eadm;
142} __packed;
111 143
112#define SCSW_FCTL_CLEAR_FUNC 0x1 144#define SCSW_FCTL_CLEAR_FUNC 0x1
113#define SCSW_FCTL_HALT_FUNC 0x2 145#define SCSW_FCTL_HALT_FUNC 0x2
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h
index e6859d16ee2d..87b47ca954f1 100644
--- a/arch/s390/include/asm/setup.h
+++ b/arch/s390/include/asm/setup.h
@@ -60,7 +60,7 @@ void create_mem_hole(struct mem_chunk memory_chunk[], unsigned long addr,
60#define SECONDARY_SPACE_MODE 2 60#define SECONDARY_SPACE_MODE 2
61#define HOME_SPACE_MODE 3 61#define HOME_SPACE_MODE 3
62 62
63extern unsigned int addressing_mode; 63extern unsigned int s390_user_mode;
64 64
65/* 65/*
66 * Machine features detected in head.S 66 * Machine features detected in head.S
@@ -80,6 +80,7 @@ extern unsigned int addressing_mode;
80#define MACHINE_FLAG_LPAR (1UL << 12) 80#define MACHINE_FLAG_LPAR (1UL << 12)
81#define MACHINE_FLAG_SPP (1UL << 13) 81#define MACHINE_FLAG_SPP (1UL << 13)
82#define MACHINE_FLAG_TOPOLOGY (1UL << 14) 82#define MACHINE_FLAG_TOPOLOGY (1UL << 14)
83#define MACHINE_FLAG_TE (1UL << 15)
83 84
84#define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM) 85#define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM)
85#define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM) 86#define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM)
@@ -98,6 +99,7 @@ extern unsigned int addressing_mode;
98#define MACHINE_HAS_PFMF (0) 99#define MACHINE_HAS_PFMF (0)
99#define MACHINE_HAS_SPP (0) 100#define MACHINE_HAS_SPP (0)
100#define MACHINE_HAS_TOPOLOGY (0) 101#define MACHINE_HAS_TOPOLOGY (0)
102#define MACHINE_HAS_TE (0)
101#else /* CONFIG_64BIT */ 103#else /* CONFIG_64BIT */
102#define MACHINE_HAS_IEEE (1) 104#define MACHINE_HAS_IEEE (1)
103#define MACHINE_HAS_CSP (1) 105#define MACHINE_HAS_CSP (1)
@@ -109,6 +111,7 @@ extern unsigned int addressing_mode;
109#define MACHINE_HAS_PFMF (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF) 111#define MACHINE_HAS_PFMF (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF)
110#define MACHINE_HAS_SPP (S390_lowcore.machine_flags & MACHINE_FLAG_SPP) 112#define MACHINE_HAS_SPP (S390_lowcore.machine_flags & MACHINE_FLAG_SPP)
111#define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY) 113#define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY)
114#define MACHINE_HAS_TE (S390_lowcore.machine_flags & MACHINE_FLAG_TE)
112#endif /* CONFIG_64BIT */ 115#endif /* CONFIG_64BIT */
113 116
114#define ZFCPDUMP_HSA_SIZE (32UL<<20) 117#define ZFCPDUMP_HSA_SIZE (32UL<<20)
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h
index ce26ac3cb162..b64f15c3b4cc 100644
--- a/arch/s390/include/asm/smp.h
+++ b/arch/s390/include/asm/smp.h
@@ -30,6 +30,8 @@ extern int smp_vcpu_scheduled(int cpu);
30extern void smp_yield_cpu(int cpu); 30extern void smp_yield_cpu(int cpu);
31extern void smp_yield(void); 31extern void smp_yield(void);
32extern void smp_stop_cpu(void); 32extern void smp_stop_cpu(void);
33extern void smp_cpu_set_polarization(int cpu, int val);
34extern int smp_cpu_get_polarization(int cpu);
33 35
34#else /* CONFIG_SMP */ 36#else /* CONFIG_SMP */
35 37
@@ -43,7 +45,7 @@ static inline void smp_call_online_cpu(void (*func)(void *), void *data)
43 func(data); 45 func(data);
44} 46}
45 47
46static inline int smp_find_processor_id(int address) { return 0; } 48static inline int smp_find_processor_id(u16 address) { return 0; }
47static inline int smp_store_status(int cpu) { return 0; } 49static inline int smp_store_status(int cpu) { return 0; }
48static inline int smp_vcpu_scheduled(int cpu) { return 1; } 50static inline int smp_vcpu_scheduled(int cpu) { return 1; }
49static inline void smp_yield_cpu(int cpu) { } 51static inline void smp_yield_cpu(int cpu) { }
diff --git a/arch/s390/include/asm/string.h b/arch/s390/include/asm/string.h
index 1bd1352fa3b5..7e2dcd7c57ef 100644
--- a/arch/s390/include/asm/string.h
+++ b/arch/s390/include/asm/string.h
@@ -96,7 +96,6 @@ static inline char *strcat(char *dst, const char *src)
96 96
97static inline char *strcpy(char *dst, const char *src) 97static inline char *strcpy(char *dst, const char *src)
98{ 98{
99#if __GNUC__ < 4
100 register int r0 asm("0") = 0; 99 register int r0 asm("0") = 0;
101 char *ret = dst; 100 char *ret = dst;
102 101
@@ -106,14 +105,10 @@ static inline char *strcpy(char *dst, const char *src)
106 : "+&a" (dst), "+&a" (src) : "d" (r0) 105 : "+&a" (dst), "+&a" (src) : "d" (r0)
107 : "cc", "memory"); 106 : "cc", "memory");
108 return ret; 107 return ret;
109#else
110 return __builtin_strcpy(dst, src);
111#endif
112} 108}
113 109
114static inline size_t strlen(const char *s) 110static inline size_t strlen(const char *s)
115{ 111{
116#if __GNUC__ < 4
117 register unsigned long r0 asm("0") = 0; 112 register unsigned long r0 asm("0") = 0;
118 const char *tmp = s; 113 const char *tmp = s;
119 114
@@ -122,9 +117,6 @@ static inline size_t strlen(const char *s)
122 " jo 0b" 117 " jo 0b"
123 : "+d" (r0), "+a" (tmp) : : "cc"); 118 : "+d" (r0), "+a" (tmp) : : "cc");
124 return r0 - (unsigned long) s; 119 return r0 - (unsigned long) s;
125#else
126 return __builtin_strlen(s);
127#endif
128} 120}
129 121
130static inline size_t strnlen(const char * s, size_t n) 122static inline size_t strnlen(const char * s, size_t n)
diff --git a/arch/s390/include/asm/switch_to.h b/arch/s390/include/asm/switch_to.h
index f223068b7822..f3a9e0f92704 100644
--- a/arch/s390/include/asm/switch_to.h
+++ b/arch/s390/include/asm/switch_to.h
@@ -80,21 +80,19 @@ static inline void restore_access_regs(unsigned int *acrs)
80 if (prev->mm) { \ 80 if (prev->mm) { \
81 save_fp_regs(&prev->thread.fp_regs); \ 81 save_fp_regs(&prev->thread.fp_regs); \
82 save_access_regs(&prev->thread.acrs[0]); \ 82 save_access_regs(&prev->thread.acrs[0]); \
83 save_ri_cb(prev->thread.ri_cb); \
83 } \ 84 } \
84 if (next->mm) { \ 85 if (next->mm) { \
85 restore_fp_regs(&next->thread.fp_regs); \ 86 restore_fp_regs(&next->thread.fp_regs); \
86 restore_access_regs(&next->thread.acrs[0]); \ 87 restore_access_regs(&next->thread.acrs[0]); \
88 restore_ri_cb(next->thread.ri_cb, prev->thread.ri_cb); \
87 update_per_regs(next); \ 89 update_per_regs(next); \
88 } \ 90 } \
89 prev = __switch_to(prev,next); \ 91 prev = __switch_to(prev,next); \
90} while (0) 92} while (0)
91 93
92extern void account_vtime(struct task_struct *, struct task_struct *);
93extern void account_tick_vtime(struct task_struct *);
94
95#define finish_arch_switch(prev) do { \ 94#define finish_arch_switch(prev) do { \
96 set_fs(current->thread.mm_segment); \ 95 set_fs(current->thread.mm_segment); \
97 account_vtime(prev, current); \
98} while (0) 96} while (0)
99 97
100#endif /* __ASM_SWITCH_TO_H */ 98#endif /* __ASM_SWITCH_TO_H */
diff --git a/arch/s390/include/asm/sysinfo.h b/arch/s390/include/asm/sysinfo.h
index 282ee36f6162..f92428e459f8 100644
--- a/arch/s390/include/asm/sysinfo.h
+++ b/arch/s390/include/asm/sysinfo.h
@@ -17,7 +17,10 @@
17#include <asm/bitsperlong.h> 17#include <asm/bitsperlong.h>
18 18
19struct sysinfo_1_1_1 { 19struct sysinfo_1_1_1 {
20 unsigned short :16; 20 unsigned char p:1;
21 unsigned char :6;
22 unsigned char t:1;
23 unsigned char :8;
21 unsigned char ccr; 24 unsigned char ccr;
22 unsigned char cai; 25 unsigned char cai;
23 char reserved_0[28]; 26 char reserved_0[28];
@@ -30,9 +33,14 @@ struct sysinfo_1_1_1 {
30 char model[16]; 33 char model[16];
31 char model_perm_cap[16]; 34 char model_perm_cap[16];
32 char model_temp_cap[16]; 35 char model_temp_cap[16];
33 char model_cap_rating[4]; 36 unsigned int model_cap_rating;
34 char model_perm_cap_rating[4]; 37 unsigned int model_perm_cap_rating;
35 char model_temp_cap_rating[4]; 38 unsigned int model_temp_cap_rating;
39 unsigned char typepct[5];
40 unsigned char reserved_2[3];
41 unsigned int ncr;
42 unsigned int npr;
43 unsigned int ntr;
36}; 44};
37 45
38struct sysinfo_1_2_1 { 46struct sysinfo_1_2_1 {
@@ -47,8 +55,9 @@ struct sysinfo_1_2_2 {
47 char format; 55 char format;
48 char reserved_0[1]; 56 char reserved_0[1];
49 unsigned short acc_offset; 57 unsigned short acc_offset;
50 char reserved_1[24]; 58 char reserved_1[20];
51 unsigned int secondary_capability; 59 unsigned int nominal_cap;
60 unsigned int secondary_cap;
52 unsigned int capability; 61 unsigned int capability;
53 unsigned short cpus_total; 62 unsigned short cpus_total;
54 unsigned short cpus_configured; 63 unsigned short cpus_configured;
@@ -109,6 +118,8 @@ struct sysinfo_3_2_2 {
109 char reserved_544[3552]; 118 char reserved_544[3552];
110}; 119};
111 120
121extern int topology_max_mnest;
122
112#define TOPOLOGY_CPU_BITS 64 123#define TOPOLOGY_CPU_BITS 64
113#define TOPOLOGY_NR_MAG 6 124#define TOPOLOGY_NR_MAG 6
114 125
@@ -142,21 +153,7 @@ struct sysinfo_15_1_x {
142 union topology_entry tle[0]; 153 union topology_entry tle[0];
143}; 154};
144 155
145static inline int stsi(void *sysinfo, int fc, int sel1, int sel2) 156int stsi(void *sysinfo, int fc, int sel1, int sel2);
146{
147 register int r0 asm("0") = (fc << 28) | sel1;
148 register int r1 asm("1") = sel2;
149
150 asm volatile(
151 " stsi 0(%2)\n"
152 "0: jz 2f\n"
153 "1: lhi %0,%3\n"
154 "2:\n"
155 EX_TABLE(0b, 1b)
156 : "+d" (r0) : "d" (r1), "a" (sysinfo), "K" (-ENOSYS)
157 : "cc", "memory");
158 return r0;
159}
160 157
161/* 158/*
162 * Service level reporting interface. 159 * Service level reporting interface.
diff --git a/arch/s390/include/asm/tlbflush.h b/arch/s390/include/asm/tlbflush.h
index 9fde315f3a7c..1d8fe2b17ef6 100644
--- a/arch/s390/include/asm/tlbflush.h
+++ b/arch/s390/include/asm/tlbflush.h
@@ -90,12 +90,10 @@ static inline void __tlb_flush_mm(struct mm_struct * mm)
90 90
91static inline void __tlb_flush_mm_cond(struct mm_struct * mm) 91static inline void __tlb_flush_mm_cond(struct mm_struct * mm)
92{ 92{
93 spin_lock(&mm->page_table_lock);
94 if (mm->context.flush_mm) { 93 if (mm->context.flush_mm) {
95 __tlb_flush_mm(mm); 94 __tlb_flush_mm(mm);
96 mm->context.flush_mm = 0; 95 mm->context.flush_mm = 0;
97 } 96 }
98 spin_unlock(&mm->page_table_lock);
99} 97}
100 98
101/* 99/*
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h
index 0837de80c351..9ca305383760 100644
--- a/arch/s390/include/asm/topology.h
+++ b/arch/s390/include/asm/topology.h
@@ -2,8 +2,8 @@
2#define _ASM_S390_TOPOLOGY_H 2#define _ASM_S390_TOPOLOGY_H
3 3
4#include <linux/cpumask.h> 4#include <linux/cpumask.h>
5#include <asm/sysinfo.h>
6 5
6struct sysinfo_15_1_x;
7struct cpu; 7struct cpu;
8 8
9#ifdef CONFIG_SCHED_BOOK 9#ifdef CONFIG_SCHED_BOOK
@@ -51,24 +51,6 @@ static inline void topology_expect_change(void) { }
51#define POLARIZATION_VM (2) 51#define POLARIZATION_VM (2)
52#define POLARIZATION_VH (3) 52#define POLARIZATION_VH (3)
53 53
54extern int cpu_polarization[];
55
56static inline void cpu_set_polarization(int cpu, int val)
57{
58#ifdef CONFIG_SCHED_BOOK
59 cpu_polarization[cpu] = val;
60#endif
61}
62
63static inline int cpu_read_polarization(int cpu)
64{
65#ifdef CONFIG_SCHED_BOOK
66 return cpu_polarization[cpu];
67#else
68 return POLARIZATION_HRZ;
69#endif
70}
71
72#ifdef CONFIG_SCHED_BOOK 54#ifdef CONFIG_SCHED_BOOK
73void s390_init_cpu_topology(void); 55void s390_init_cpu_topology(void);
74#else 56#else
diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h
index a8ab18b18b54..34268df959a3 100644
--- a/arch/s390/include/asm/uaccess.h
+++ b/arch/s390/include/asm/uaccess.h
@@ -76,9 +76,22 @@ static inline int __range_ok(unsigned long addr, unsigned long size)
76 76
77struct exception_table_entry 77struct exception_table_entry
78{ 78{
79 unsigned long insn, fixup; 79 int insn, fixup;
80}; 80};
81 81
82static inline unsigned long extable_insn(const struct exception_table_entry *x)
83{
84 return (unsigned long)&x->insn + x->insn;
85}
86
87static inline unsigned long extable_fixup(const struct exception_table_entry *x)
88{
89 return (unsigned long)&x->fixup + x->fixup;
90}
91
92#define ARCH_HAS_SORT_EXTABLE
93#define ARCH_HAS_SEARCH_EXTABLE
94
82struct uaccess_ops { 95struct uaccess_ops {
83 size_t (*copy_from_user)(size_t, const void __user *, void *); 96 size_t (*copy_from_user)(size_t, const void __user *, void *);
84 size_t (*copy_from_user_small)(size_t, const void __user *, void *); 97 size_t (*copy_from_user_small)(size_t, const void __user *, void *);
diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h
index 6756e78f4808..4e64b5cd1558 100644
--- a/arch/s390/include/asm/unistd.h
+++ b/arch/s390/include/asm/unistd.h
@@ -277,7 +277,9 @@
277#define __NR_setns 339 277#define __NR_setns 339
278#define __NR_process_vm_readv 340 278#define __NR_process_vm_readv 340
279#define __NR_process_vm_writev 341 279#define __NR_process_vm_writev 341
280#define NR_syscalls 342 280#define __NR_s390_runtime_instr 342
281#define __NR_kcmp 343
282#define NR_syscalls 344
281 283
282/* 284/*
283 * There are some system calls that are not present on 64 bit, some 285 * There are some system calls that are not present on 64 bit, some
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 9733b3f0eb6d..4da52fe31743 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -23,10 +23,11 @@ CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w
23obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o vtime.o \ 23obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o vtime.o \
24 processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o \ 24 processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o \
25 debug.o irq.o ipl.o dis.o diag.o mem_detect.o sclp.o vdso.o \ 25 debug.o irq.o ipl.o dis.o diag.o mem_detect.o sclp.o vdso.o \
26 sysinfo.o jump_label.o lgr.o os_info.o 26 sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o
27 27
28obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) 28obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o)
29obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) 29obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
30obj-y += $(if $(CONFIG_64BIT),relocate_kernel64.o,relocate_kernel.o)
30 31
31extra-y += head.o vmlinux.lds 32extra-y += head.o vmlinux.lds
32extra-y += $(if $(CONFIG_64BIT),head64.o,head31.o) 33extra-y += $(if $(CONFIG_64BIT),head64.o,head31.o)
@@ -48,12 +49,11 @@ obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
48obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o 49obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
49obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o 50obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
50obj-$(CONFIG_CRASH_DUMP) += crash_dump.o 51obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
51obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_cpum_cf.o
52 52
53# Kexec part 53ifdef CONFIG_64BIT
54S390_KEXEC_OBJS := machine_kexec.o crash.o 54obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_cpum_cf.o
55S390_KEXEC_OBJS += $(if $(CONFIG_64BIT),relocate_kernel64.o,relocate_kernel.o) 55obj-y += runtime_instr.o cache.o
56obj-$(CONFIG_KEXEC) += $(S390_KEXEC_OBJS) 56endif
57 57
58# vdso 58# vdso
59obj-$(CONFIG_64BIT) += vdso64/ 59obj-$(CONFIG_64BIT) += vdso64/
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index 45ef1a7b08f9..fface87056eb 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -157,6 +157,8 @@ int main(void)
157 DEFINE(__LC_LAST_BREAK, offsetof(struct _lowcore, breaking_event_addr)); 157 DEFINE(__LC_LAST_BREAK, offsetof(struct _lowcore, breaking_event_addr));
158 DEFINE(__LC_VDSO_PER_CPU, offsetof(struct _lowcore, vdso_per_cpu_data)); 158 DEFINE(__LC_VDSO_PER_CPU, offsetof(struct _lowcore, vdso_per_cpu_data));
159 DEFINE(__LC_GMAP, offsetof(struct _lowcore, gmap)); 159 DEFINE(__LC_GMAP, offsetof(struct _lowcore, gmap));
160 DEFINE(__LC_PGM_TDB, offsetof(struct _lowcore, pgm_tdb));
161 DEFINE(__THREAD_trap_tdb, offsetof(struct task_struct, thread.trap_tdb));
160 DEFINE(__GMAP_ASCE, offsetof(struct gmap, asce)); 162 DEFINE(__GMAP_ASCE, offsetof(struct gmap, asce));
161#endif /* CONFIG_32BIT */ 163#endif /* CONFIG_32BIT */
162 return 0; 164 return 0;
diff --git a/arch/s390/kernel/cache.c b/arch/s390/kernel/cache.c
new file mode 100644
index 000000000000..8df8d8a19c98
--- /dev/null
+++ b/arch/s390/kernel/cache.c
@@ -0,0 +1,385 @@
1/*
2 * Extract CPU cache information and expose them via sysfs.
3 *
4 * Copyright IBM Corp. 2012
5 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
6 */
7
8#include <linux/notifier.h>
9#include <linux/seq_file.h>
10#include <linux/init.h>
11#include <linux/list.h>
12#include <linux/slab.h>
13#include <linux/cpu.h>
14#include <asm/facility.h>
15
16struct cache {
17 unsigned long size;
18 unsigned int line_size;
19 unsigned int associativity;
20 unsigned int nr_sets;
21 unsigned int level : 3;
22 unsigned int type : 2;
23 unsigned int private : 1;
24 struct list_head list;
25};
26
27struct cache_dir {
28 struct kobject *kobj;
29 struct cache_index_dir *index;
30};
31
32struct cache_index_dir {
33 struct kobject kobj;
34 int cpu;
35 struct cache *cache;
36 struct cache_index_dir *next;
37};
38
39enum {
40 CACHE_SCOPE_NOTEXISTS,
41 CACHE_SCOPE_PRIVATE,
42 CACHE_SCOPE_SHARED,
43 CACHE_SCOPE_RESERVED,
44};
45
46enum {
47 CACHE_TYPE_SEPARATE,
48 CACHE_TYPE_DATA,
49 CACHE_TYPE_INSTRUCTION,
50 CACHE_TYPE_UNIFIED,
51};
52
53enum {
54 EXTRACT_TOPOLOGY,
55 EXTRACT_LINE_SIZE,
56 EXTRACT_SIZE,
57 EXTRACT_ASSOCIATIVITY,
58};
59
60enum {
61 CACHE_TI_UNIFIED = 0,
62 CACHE_TI_INSTRUCTION = 0,
63 CACHE_TI_DATA,
64};
65
66struct cache_info {
67 unsigned char : 4;
68 unsigned char scope : 2;
69 unsigned char type : 2;
70};
71
72#define CACHE_MAX_LEVEL 8
73
74union cache_topology {
75 struct cache_info ci[CACHE_MAX_LEVEL];
76 unsigned long long raw;
77};
78
79static const char * const cache_type_string[] = {
80 "Data",
81 "Instruction",
82 "Unified",
83};
84
85static struct cache_dir *cache_dir_cpu[NR_CPUS];
86static LIST_HEAD(cache_list);
87
88void show_cacheinfo(struct seq_file *m)
89{
90 struct cache *cache;
91 int index = 0;
92
93 list_for_each_entry(cache, &cache_list, list) {
94 seq_printf(m, "cache%-11d: ", index);
95 seq_printf(m, "level=%d ", cache->level);
96 seq_printf(m, "type=%s ", cache_type_string[cache->type]);
97 seq_printf(m, "scope=%s ", cache->private ? "Private" : "Shared");
98 seq_printf(m, "size=%luK ", cache->size >> 10);
99 seq_printf(m, "line_size=%u ", cache->line_size);
100 seq_printf(m, "associativity=%d", cache->associativity);
101 seq_puts(m, "\n");
102 index++;
103 }
104}
105
106static inline unsigned long ecag(int ai, int li, int ti)
107{
108 unsigned long cmd, val;
109
110 cmd = ai << 4 | li << 1 | ti;
111 asm volatile(".insn rsy,0xeb000000004c,%0,0,0(%1)" /* ecag */
112 : "=d" (val) : "a" (cmd));
113 return val;
114}
115
116static int __init cache_add(int level, int private, int type)
117{
118 struct cache *cache;
119 int ti;
120
121 cache = kzalloc(sizeof(*cache), GFP_KERNEL);
122 if (!cache)
123 return -ENOMEM;
124 ti = type == CACHE_TYPE_DATA ? CACHE_TI_DATA : CACHE_TI_UNIFIED;
125 cache->size = ecag(EXTRACT_SIZE, level, ti);
126 cache->line_size = ecag(EXTRACT_LINE_SIZE, level, ti);
127 cache->associativity = ecag(EXTRACT_ASSOCIATIVITY, level, ti);
128 cache->nr_sets = cache->size / cache->associativity;
129 cache->nr_sets /= cache->line_size;
130 cache->private = private;
131 cache->level = level + 1;
132 cache->type = type - 1;
133 list_add_tail(&cache->list, &cache_list);
134 return 0;
135}
136
137static void __init cache_build_info(void)
138{
139 struct cache *cache, *next;
140 union cache_topology ct;
141 int level, private, rc;
142
143 ct.raw = ecag(EXTRACT_TOPOLOGY, 0, 0);
144 for (level = 0; level < CACHE_MAX_LEVEL; level++) {
145 switch (ct.ci[level].scope) {
146 case CACHE_SCOPE_NOTEXISTS:
147 case CACHE_SCOPE_RESERVED:
148 return;
149 case CACHE_SCOPE_SHARED:
150 private = 0;
151 break;
152 case CACHE_SCOPE_PRIVATE:
153 private = 1;
154 break;
155 }
156 if (ct.ci[level].type == CACHE_TYPE_SEPARATE) {
157 rc = cache_add(level, private, CACHE_TYPE_DATA);
158 rc |= cache_add(level, private, CACHE_TYPE_INSTRUCTION);
159 } else {
160 rc = cache_add(level, private, ct.ci[level].type);
161 }
162 if (rc)
163 goto error;
164 }
165 return;
166error:
167 list_for_each_entry_safe(cache, next, &cache_list, list) {
168 list_del(&cache->list);
169 kfree(cache);
170 }
171}
172
173static struct cache_dir *__cpuinit cache_create_cache_dir(int cpu)
174{
175 struct cache_dir *cache_dir;
176 struct kobject *kobj = NULL;
177 struct device *dev;
178
179 dev = get_cpu_device(cpu);
180 if (!dev)
181 goto out;
182 kobj = kobject_create_and_add("cache", &dev->kobj);
183 if (!kobj)
184 goto out;
185 cache_dir = kzalloc(sizeof(*cache_dir), GFP_KERNEL);
186 if (!cache_dir)
187 goto out;
188 cache_dir->kobj = kobj;
189 cache_dir_cpu[cpu] = cache_dir;
190 return cache_dir;
191out:
192 kobject_put(kobj);
193 return NULL;
194}
195
196static struct cache_index_dir *kobj_to_cache_index_dir(struct kobject *kobj)
197{
198 return container_of(kobj, struct cache_index_dir, kobj);
199}
200
201static void cache_index_release(struct kobject *kobj)
202{
203 struct cache_index_dir *index;
204
205 index = kobj_to_cache_index_dir(kobj);
206 kfree(index);
207}
208
209static ssize_t cache_index_show(struct kobject *kobj,
210 struct attribute *attr, char *buf)
211{
212 struct kobj_attribute *kobj_attr;
213
214 kobj_attr = container_of(attr, struct kobj_attribute, attr);
215 return kobj_attr->show(kobj, kobj_attr, buf);
216}
217
218#define DEFINE_CACHE_ATTR(_name, _format, _value) \
219static ssize_t cache_##_name##_show(struct kobject *kobj, \
220 struct kobj_attribute *attr, \
221 char *buf) \
222{ \
223 struct cache_index_dir *index; \
224 \
225 index = kobj_to_cache_index_dir(kobj); \
226 return sprintf(buf, _format, _value); \
227} \
228static struct kobj_attribute cache_##_name##_attr = \
229 __ATTR(_name, 0444, cache_##_name##_show, NULL);
230
231DEFINE_CACHE_ATTR(size, "%luK\n", index->cache->size >> 10);
232DEFINE_CACHE_ATTR(coherency_line_size, "%u\n", index->cache->line_size);
233DEFINE_CACHE_ATTR(number_of_sets, "%u\n", index->cache->nr_sets);
234DEFINE_CACHE_ATTR(ways_of_associativity, "%u\n", index->cache->associativity);
235DEFINE_CACHE_ATTR(type, "%s\n", cache_type_string[index->cache->type]);
236DEFINE_CACHE_ATTR(level, "%d\n", index->cache->level);
237
238static ssize_t shared_cpu_map_func(struct kobject *kobj, int type, char *buf)
239{
240 struct cache_index_dir *index;
241 int len;
242
243 index = kobj_to_cache_index_dir(kobj);
244 len = type ?
245 cpulist_scnprintf(buf, PAGE_SIZE - 2, cpumask_of(index->cpu)) :
246 cpumask_scnprintf(buf, PAGE_SIZE - 2, cpumask_of(index->cpu));
247 len += sprintf(&buf[len], "\n");
248 return len;
249}
250
251static ssize_t shared_cpu_map_show(struct kobject *kobj,
252 struct kobj_attribute *attr, char *buf)
253{
254 return shared_cpu_map_func(kobj, 0, buf);
255}
256static struct kobj_attribute cache_shared_cpu_map_attr =
257 __ATTR(shared_cpu_map, 0444, shared_cpu_map_show, NULL);
258
259static ssize_t shared_cpu_list_show(struct kobject *kobj,
260 struct kobj_attribute *attr, char *buf)
261{
262 return shared_cpu_map_func(kobj, 1, buf);
263}
264static struct kobj_attribute cache_shared_cpu_list_attr =
265 __ATTR(shared_cpu_list, 0444, shared_cpu_list_show, NULL);
266
267static struct attribute *cache_index_default_attrs[] = {
268 &cache_type_attr.attr,
269 &cache_size_attr.attr,
270 &cache_number_of_sets_attr.attr,
271 &cache_ways_of_associativity_attr.attr,
272 &cache_level_attr.attr,
273 &cache_coherency_line_size_attr.attr,
274 &cache_shared_cpu_map_attr.attr,
275 &cache_shared_cpu_list_attr.attr,
276 NULL,
277};
278
279static const struct sysfs_ops cache_index_ops = {
280 .show = cache_index_show,
281};
282
283static struct kobj_type cache_index_type = {
284 .sysfs_ops = &cache_index_ops,
285 .release = cache_index_release,
286 .default_attrs = cache_index_default_attrs,
287};
288
289static int __cpuinit cache_create_index_dir(struct cache_dir *cache_dir,
290 struct cache *cache, int index,
291 int cpu)
292{
293 struct cache_index_dir *index_dir;
294 int rc;
295
296 index_dir = kzalloc(sizeof(*index_dir), GFP_KERNEL);
297 if (!index_dir)
298 return -ENOMEM;
299 index_dir->cache = cache;
300 index_dir->cpu = cpu;
301 rc = kobject_init_and_add(&index_dir->kobj, &cache_index_type,
302 cache_dir->kobj, "index%d", index);
303 if (rc)
304 goto out;
305 index_dir->next = cache_dir->index;
306 cache_dir->index = index_dir;
307 return 0;
308out:
309 kfree(index_dir);
310 return rc;
311}
312
313static int __cpuinit cache_add_cpu(int cpu)
314{
315 struct cache_dir *cache_dir;
316 struct cache *cache;
317 int rc, index = 0;
318
319 if (list_empty(&cache_list))
320 return 0;
321 cache_dir = cache_create_cache_dir(cpu);
322 if (!cache_dir)
323 return -ENOMEM;
324 list_for_each_entry(cache, &cache_list, list) {
325 if (!cache->private)
326 break;
327 rc = cache_create_index_dir(cache_dir, cache, index, cpu);
328 if (rc)
329 return rc;
330 index++;
331 }
332 return 0;
333}
334
335static void __cpuinit cache_remove_cpu(int cpu)
336{
337 struct cache_index_dir *index, *next;
338 struct cache_dir *cache_dir;
339
340 cache_dir = cache_dir_cpu[cpu];
341 if (!cache_dir)
342 return;
343 index = cache_dir->index;
344 while (index) {
345 next = index->next;
346 kobject_put(&index->kobj);
347 index = next;
348 }
349 kobject_put(cache_dir->kobj);
350 kfree(cache_dir);
351 cache_dir_cpu[cpu] = NULL;
352}
353
354static int __cpuinit cache_hotplug(struct notifier_block *nfb,
355 unsigned long action, void *hcpu)
356{
357 int cpu = (long)hcpu;
358 int rc = 0;
359
360 switch (action & ~CPU_TASKS_FROZEN) {
361 case CPU_ONLINE:
362 rc = cache_add_cpu(cpu);
363 if (rc)
364 cache_remove_cpu(cpu);
365 break;
366 case CPU_DEAD:
367 cache_remove_cpu(cpu);
368 break;
369 }
370 return rc ? NOTIFY_BAD : NOTIFY_OK;
371}
372
373static int __init cache_init(void)
374{
375 int cpu;
376
377 if (!test_facility(34))
378 return 0;
379 cache_build_info();
380 for_each_online_cpu(cpu)
381 cache_add_cpu(cpu);
382 hotcpu_notifier(cache_hotplug, 0);
383 return 0;
384}
385device_initcall(cache_init);
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 2d82cfcbce5b..3afba804fe97 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -1646,3 +1646,16 @@ ENTRY(compat_sys_process_vm_writev_wrapper)
1646 llgf %r0,164(%r15) # unsigned long 1646 llgf %r0,164(%r15) # unsigned long
1647 stg %r0,160(%r15) 1647 stg %r0,160(%r15)
1648 jg compat_sys_process_vm_writev 1648 jg compat_sys_process_vm_writev
1649
1650ENTRY(sys_s390_runtime_instr_wrapper)
1651 lgfr %r2,%r2 # int
1652 lgfr %r3,%r3 # int
1653 jg sys_s390_runtime_instr
1654
1655ENTRY(sys_kcmp_wrapper)
1656 lgfr %r2,%r2 # pid_t
1657 lgfr %r3,%r3 # pid_t
1658 lgfr %r4,%r4 # int
1659 llgfr %r5,%r5 # unsigned long
1660 llgfr %r6,%r6 # unsigned long
1661 jg sys_kcmp
diff --git a/arch/s390/kernel/crash.c b/arch/s390/kernel/crash.c
deleted file mode 100644
index 3819153de8bd..000000000000
--- a/arch/s390/kernel/crash.c
+++ /dev/null
@@ -1,14 +0,0 @@
1/*
2 * Copyright IBM Corp. 2005
3 *
4 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
5 *
6 */
7
8#include <linux/threads.h>
9#include <linux/kexec.h>
10#include <linux/reboot.h>
11
12void machine_crash_shutdown(struct pt_regs *regs)
13{
14}
diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
index cc1172b26873..fb8d8781a011 100644
--- a/arch/s390/kernel/crash_dump.c
+++ b/arch/s390/kernel/crash_dump.c
@@ -13,8 +13,9 @@
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/bootmem.h> 14#include <linux/bootmem.h>
15#include <linux/elf.h> 15#include <linux/elf.h>
16#include <asm/ipl.h>
17#include <asm/os_info.h> 16#include <asm/os_info.h>
17#include <asm/elf.h>
18#include <asm/ipl.h>
18 19
19#define PTR_ADD(x, y) (((char *) (x)) + ((unsigned long) (y))) 20#define PTR_ADD(x, y) (((char *) (x)) + ((unsigned long) (y)))
20#define PTR_SUB(x, y) (((char *) (x)) - ((unsigned long) (y))) 21#define PTR_SUB(x, y) (((char *) (x)) - ((unsigned long) (y)))
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c
index 619c5d350726..cc84a24c023f 100644
--- a/arch/s390/kernel/dis.c
+++ b/arch/s390/kernel/dis.c
@@ -315,6 +315,11 @@ enum {
315 LONG_INSN_POPCNT, 315 LONG_INSN_POPCNT,
316 LONG_INSN_RISBHG, 316 LONG_INSN_RISBHG,
317 LONG_INSN_RISBLG, 317 LONG_INSN_RISBLG,
318 LONG_INSN_RINEXT,
319 LONG_INSN_RIEMIT,
320 LONG_INSN_TABORT,
321 LONG_INSN_TBEGIN,
322 LONG_INSN_TBEGINC,
318}; 323};
319 324
320static char *long_insn_name[] = { 325static char *long_insn_name[] = {
@@ -329,7 +334,12 @@ static char *long_insn_name[] = {
329 [LONG_INSN_LLGHRL] = "llghrl", 334 [LONG_INSN_LLGHRL] = "llghrl",
330 [LONG_INSN_POPCNT] = "popcnt", 335 [LONG_INSN_POPCNT] = "popcnt",
331 [LONG_INSN_RISBHG] = "risbhg", 336 [LONG_INSN_RISBHG] = "risbhg",
332 [LONG_INSN_RISBLG] = "risblk", 337 [LONG_INSN_RISBLG] = "risblg",
338 [LONG_INSN_RINEXT] = "rinext",
339 [LONG_INSN_RIEMIT] = "riemit",
340 [LONG_INSN_TABORT] = "tabort",
341 [LONG_INSN_TBEGIN] = "tbegin",
342 [LONG_INSN_TBEGINC] = "tbeginc",
333}; 343};
334 344
335static struct insn opcode[] = { 345static struct insn opcode[] = {
@@ -582,6 +592,17 @@ static struct insn opcode_a7[] = {
582 { "", 0, INSTR_INVALID } 592 { "", 0, INSTR_INVALID }
583}; 593};
584 594
595static struct insn opcode_aa[] = {
596#ifdef CONFIG_64BIT
597 { { 0, LONG_INSN_RINEXT }, 0x00, INSTR_RI_RI },
598 { "rion", 0x01, INSTR_RI_RI },
599 { "tric", 0x02, INSTR_RI_RI },
600 { "rioff", 0x03, INSTR_RI_RI },
601 { { 0, LONG_INSN_RIEMIT }, 0x04, INSTR_RI_RI },
602#endif
603 { "", 0, INSTR_INVALID }
604};
605
585static struct insn opcode_b2[] = { 606static struct insn opcode_b2[] = {
586#ifdef CONFIG_64BIT 607#ifdef CONFIG_64BIT
587 { "sske", 0x2b, INSTR_RRF_M0RR }, 608 { "sske", 0x2b, INSTR_RRF_M0RR },
@@ -594,6 +615,9 @@ static struct insn opcode_b2[] = {
594 { "lpswe", 0xb2, INSTR_S_RD }, 615 { "lpswe", 0xb2, INSTR_S_RD },
595 { "srnmt", 0xb9, INSTR_S_RD }, 616 { "srnmt", 0xb9, INSTR_S_RD },
596 { "lfas", 0xbd, INSTR_S_RD }, 617 { "lfas", 0xbd, INSTR_S_RD },
618 { "etndg", 0xec, INSTR_RRE_R0 },
619 { { 0, LONG_INSN_TABORT }, 0xfc, INSTR_S_RD },
620 { "tend", 0xf8, INSTR_S_RD },
597#endif 621#endif
598 { "stidp", 0x02, INSTR_S_RD }, 622 { "stidp", 0x02, INSTR_S_RD },
599 { "sck", 0x04, INSTR_S_RD }, 623 { "sck", 0x04, INSTR_S_RD },
@@ -1150,6 +1174,7 @@ static struct insn opcode_e3[] = {
1150 { "stfh", 0xcb, INSTR_RXY_RRRD }, 1174 { "stfh", 0xcb, INSTR_RXY_RRRD },
1151 { "chf", 0xcd, INSTR_RXY_RRRD }, 1175 { "chf", 0xcd, INSTR_RXY_RRRD },
1152 { "clhf", 0xcf, INSTR_RXY_RRRD }, 1176 { "clhf", 0xcf, INSTR_RXY_RRRD },
1177 { "ntstg", 0x25, INSTR_RXY_RRRD },
1153#endif 1178#endif
1154 { "lrv", 0x1e, INSTR_RXY_RRRD }, 1179 { "lrv", 0x1e, INSTR_RXY_RRRD },
1155 { "lrvh", 0x1f, INSTR_RXY_RRRD }, 1180 { "lrvh", 0x1f, INSTR_RXY_RRRD },
@@ -1173,6 +1198,8 @@ static struct insn opcode_e5[] = {
1173 { "mvhhi", 0x44, INSTR_SIL_RDI }, 1198 { "mvhhi", 0x44, INSTR_SIL_RDI },
1174 { "mvhi", 0x4c, INSTR_SIL_RDI }, 1199 { "mvhi", 0x4c, INSTR_SIL_RDI },
1175 { "mvghi", 0x48, INSTR_SIL_RDI }, 1200 { "mvghi", 0x48, INSTR_SIL_RDI },
1201 { { 0, LONG_INSN_TBEGIN }, 0x60, INSTR_SIL_RDU },
1202 { { 0, LONG_INSN_TBEGINC }, 0x61, INSTR_SIL_RDU },
1176#endif 1203#endif
1177 { "lasp", 0x00, INSTR_SSE_RDRD }, 1204 { "lasp", 0x00, INSTR_SSE_RDRD },
1178 { "tprot", 0x01, INSTR_SSE_RDRD }, 1205 { "tprot", 0x01, INSTR_SSE_RDRD },
@@ -1210,6 +1237,9 @@ static struct insn opcode_eb[] = {
1210 { "cliy", 0x55, INSTR_SIY_URD }, 1237 { "cliy", 0x55, INSTR_SIY_URD },
1211 { "oiy", 0x56, INSTR_SIY_URD }, 1238 { "oiy", 0x56, INSTR_SIY_URD },
1212 { "xiy", 0x57, INSTR_SIY_URD }, 1239 { "xiy", 0x57, INSTR_SIY_URD },
1240 { "lric", 0x60, INSTR_RSY_RDRM },
1241 { "stric", 0x61, INSTR_RSY_RDRM },
1242 { "mric", 0x62, INSTR_RSY_RDRM },
1213 { "icmh", 0x80, INSTR_RSE_RURD }, 1243 { "icmh", 0x80, INSTR_RSE_RURD },
1214 { "icmh", 0x80, INSTR_RSY_RURD }, 1244 { "icmh", 0x80, INSTR_RSY_RURD },
1215 { "icmy", 0x81, INSTR_RSY_RURD }, 1245 { "icmy", 0x81, INSTR_RSY_RURD },
@@ -1408,6 +1438,9 @@ static struct insn *find_insn(unsigned char *code)
1408 case 0xa7: 1438 case 0xa7:
1409 table = opcode_a7; 1439 table = opcode_a7;
1410 break; 1440 break;
1441 case 0xaa:
1442 table = opcode_aa;
1443 break;
1411 case 0xb2: 1444 case 0xb2:
1412 table = opcode_b2; 1445 table = opcode_b2;
1413 break; 1446 break;
@@ -1601,3 +1634,26 @@ void show_code(struct pt_regs *regs)
1601 } 1634 }
1602 printk("\n"); 1635 printk("\n");
1603} 1636}
1637
1638void print_fn_code(unsigned char *code, unsigned long len)
1639{
1640 char buffer[64], *ptr;
1641 int opsize, i;
1642
1643 while (len) {
1644 ptr = buffer;
1645 opsize = insn_length(*code);
1646 ptr += sprintf(ptr, "%p: ", code);
1647 for (i = 0; i < opsize; i++)
1648 ptr += sprintf(ptr, "%02x", code[i]);
1649 *ptr++ = '\t';
1650 if (i < 4)
1651 *ptr++ = '\t';
1652 ptr += print_insn(ptr, code, (unsigned long) code);
1653 *ptr++ = '\n';
1654 *ptr++ = 0;
1655 printk(buffer);
1656 code += opsize;
1657 len -= opsize;
1658 }
1659}
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 83c3271c442b..7f4717675c19 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -215,36 +215,54 @@ static noinline __init void init_kernel_storage_key(void)
215 PAGE_DEFAULT_KEY, 0); 215 PAGE_DEFAULT_KEY, 0);
216} 216}
217 217
218static __initdata struct sysinfo_3_2_2 vmms __aligned(PAGE_SIZE); 218static __initdata char sysinfo_page[PAGE_SIZE] __aligned(PAGE_SIZE);
219 219
220static noinline __init void detect_machine_type(void) 220static noinline __init void detect_machine_type(void)
221{ 221{
222 struct sysinfo_3_2_2 *vmms = (struct sysinfo_3_2_2 *)&sysinfo_page;
223
222 /* Check current-configuration-level */ 224 /* Check current-configuration-level */
223 if ((stsi(NULL, 0, 0, 0) >> 28) <= 2) { 225 if (stsi(NULL, 0, 0, 0) <= 2) {
224 S390_lowcore.machine_flags |= MACHINE_FLAG_LPAR; 226 S390_lowcore.machine_flags |= MACHINE_FLAG_LPAR;
225 return; 227 return;
226 } 228 }
227 /* Get virtual-machine cpu information. */ 229 /* Get virtual-machine cpu information. */
228 if (stsi(&vmms, 3, 2, 2) == -ENOSYS || !vmms.count) 230 if (stsi(vmms, 3, 2, 2) || !vmms->count)
229 return; 231 return;
230 232
231 /* Running under KVM? If not we assume z/VM */ 233 /* Running under KVM? If not we assume z/VM */
232 if (!memcmp(vmms.vm[0].cpi, "\xd2\xe5\xd4", 3)) 234 if (!memcmp(vmms->vm[0].cpi, "\xd2\xe5\xd4", 3))
233 S390_lowcore.machine_flags |= MACHINE_FLAG_KVM; 235 S390_lowcore.machine_flags |= MACHINE_FLAG_KVM;
234 else 236 else
235 S390_lowcore.machine_flags |= MACHINE_FLAG_VM; 237 S390_lowcore.machine_flags |= MACHINE_FLAG_VM;
236} 238}
237 239
240static __init void setup_topology(void)
241{
242#ifdef CONFIG_64BIT
243 int max_mnest;
244
245 if (!test_facility(11))
246 return;
247 S390_lowcore.machine_flags |= MACHINE_FLAG_TOPOLOGY;
248 for (max_mnest = 6; max_mnest > 1; max_mnest--) {
249 if (stsi(&sysinfo_page, 15, 1, max_mnest) == 0)
250 break;
251 }
252 topology_max_mnest = max_mnest;
253#endif
254}
255
238static void early_pgm_check_handler(void) 256static void early_pgm_check_handler(void)
239{ 257{
240 unsigned long addr;
241 const struct exception_table_entry *fixup; 258 const struct exception_table_entry *fixup;
259 unsigned long addr;
242 260
243 addr = S390_lowcore.program_old_psw.addr; 261 addr = S390_lowcore.program_old_psw.addr;
244 fixup = search_exception_tables(addr & PSW_ADDR_INSN); 262 fixup = search_exception_tables(addr & PSW_ADDR_INSN);
245 if (!fixup) 263 if (!fixup)
246 disabled_wait(0); 264 disabled_wait(0);
247 S390_lowcore.program_old_psw.addr = fixup->fixup | PSW_ADDR_AMODE; 265 S390_lowcore.program_old_psw.addr = extable_fixup(fixup)|PSW_ADDR_AMODE;
248} 266}
249 267
250static noinline __init void setup_lowcore_early(void) 268static noinline __init void setup_lowcore_early(void)
@@ -267,12 +285,10 @@ static noinline __init void setup_facility_list(void)
267 285
268static noinline __init void setup_hpage(void) 286static noinline __init void setup_hpage(void)
269{ 287{
270#ifndef CONFIG_DEBUG_PAGEALLOC
271 if (!test_facility(2) || !test_facility(8)) 288 if (!test_facility(2) || !test_facility(8))
272 return; 289 return;
273 S390_lowcore.machine_flags |= MACHINE_FLAG_HPAGE; 290 S390_lowcore.machine_flags |= MACHINE_FLAG_HPAGE;
274 __ctl_set_bit(0, 23); 291 __ctl_set_bit(0, 23);
275#endif
276} 292}
277 293
278static __init void detect_mvpg(void) 294static __init void detect_mvpg(void)
@@ -366,12 +382,12 @@ static __init void detect_machine_facilities(void)
366 S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE; 382 S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE;
367 if (test_facility(8)) 383 if (test_facility(8))
368 S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF; 384 S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF;
369 if (test_facility(11))
370 S390_lowcore.machine_flags |= MACHINE_FLAG_TOPOLOGY;
371 if (test_facility(27)) 385 if (test_facility(27))
372 S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS; 386 S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS;
373 if (test_facility(40)) 387 if (test_facility(40))
374 S390_lowcore.machine_flags |= MACHINE_FLAG_SPP; 388 S390_lowcore.machine_flags |= MACHINE_FLAG_SPP;
389 if (test_facility(50) && test_facility(73))
390 S390_lowcore.machine_flags |= MACHINE_FLAG_TE;
375#endif 391#endif
376} 392}
377 393
@@ -441,7 +457,6 @@ static void __init setup_boot_command_line(void)
441 append_to_cmdline(append_ipl_scpdata); 457 append_to_cmdline(append_ipl_scpdata);
442} 458}
443 459
444
445/* 460/*
446 * Save ipl parameters, clear bss memory, initialize storage keys 461 * Save ipl parameters, clear bss memory, initialize storage keys
447 * and create a kernel NSS at startup if the SAVESYS= parm is defined 462 * and create a kernel NSS at startup if the SAVESYS= parm is defined
@@ -468,6 +483,7 @@ void __init startup_init(void)
468 detect_diag44(); 483 detect_diag44();
469 detect_machine_facilities(); 484 detect_machine_facilities();
470 setup_hpage(); 485 setup_hpage();
486 setup_topology();
471 sclp_facilities_detect(); 487 sclp_facilities_detect();
472 detect_memory_layout(memory_chunk); 488 detect_memory_layout(memory_chunk);
473#ifdef CONFIG_DYNAMIC_FTRACE 489#ifdef CONFIG_DYNAMIC_FTRACE
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 349b7eeb348a..7549985402f7 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -10,6 +10,7 @@
10 10
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/linkage.h> 12#include <linux/linkage.h>
13#include <asm/processor.h>
13#include <asm/cache.h> 14#include <asm/cache.h>
14#include <asm/errno.h> 15#include <asm/errno.h>
15#include <asm/ptrace.h> 16#include <asm/ptrace.h>
@@ -412,6 +413,11 @@ ENTRY(pgm_check_handler)
4121: UPDATE_VTIME %r14,__LC_SYNC_ENTER_TIMER 4131: UPDATE_VTIME %r14,__LC_SYNC_ENTER_TIMER
413 LAST_BREAK %r14 414 LAST_BREAK %r14
414 lg %r15,__LC_KERNEL_STACK 415 lg %r15,__LC_KERNEL_STACK
416 lg %r14,__TI_task(%r12)
417 lghi %r13,__LC_PGM_TDB
418 tm __LC_PGM_ILC+2,0x02 # check for transaction abort
419 jz 2f
420 mvc __THREAD_trap_tdb(256,%r14),0(%r13)
4152: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 4212: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
416 la %r11,STACK_FRAME_OVERHEAD(%r15) 422 la %r11,STACK_FRAME_OVERHEAD(%r15)
417 stmg %r0,%r7,__PT_R0(%r11) 423 stmg %r0,%r7,__PT_R0(%r11)
@@ -422,13 +428,12 @@ ENTRY(pgm_check_handler)
422 stg %r10,__PT_ARGS(%r11) 428 stg %r10,__PT_ARGS(%r11)
423 tm __LC_PGM_ILC+3,0x80 # check for per exception 429 tm __LC_PGM_ILC+3,0x80 # check for per exception
424 jz 0f 430 jz 0f
425 lg %r1,__TI_task(%r12)
426 tmhh %r8,0x0001 # kernel per event ? 431 tmhh %r8,0x0001 # kernel per event ?
427 jz pgm_kprobe 432 jz pgm_kprobe
428 oi __TI_flags+7(%r12),_TIF_PER_TRAP 433 oi __TI_flags+7(%r12),_TIF_PER_TRAP
429 mvc __THREAD_per_address(8,%r1),__LC_PER_ADDRESS 434 mvc __THREAD_per_address(8,%r14),__LC_PER_ADDRESS
430 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE 435 mvc __THREAD_per_cause(2,%r14),__LC_PER_CAUSE
431 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID 436 mvc __THREAD_per_paid(1,%r14),__LC_PER_PAID
4320: REENABLE_IRQS 4370: REENABLE_IRQS
433 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 438 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
434 larl %r1,pgm_check_table 439 larl %r1,pgm_check_table
@@ -1004,9 +1009,7 @@ sie_fault:
1004.Lhost_id: 1009.Lhost_id:
1005 .quad 0 1010 .quad 0
1006 1011
1007 .section __ex_table,"a" 1012 EX_TABLE(sie_loop,sie_fault)
1008 .quad sie_loop,sie_fault
1009 .previous
1010#endif 1013#endif
1011 1014
1012 .section .rodata, "a" 1015 .section .rodata, "a"
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index dd7630d8aab7..6cdc55b26d68 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -30,33 +30,35 @@ struct irq_class {
30}; 30};
31 31
32static const struct irq_class intrclass_names[] = { 32static const struct irq_class intrclass_names[] = {
33 {.name = "EXT" }, 33 [EXTERNAL_INTERRUPT] = {.name = "EXT"},
34 {.name = "I/O" }, 34 [IO_INTERRUPT] = {.name = "I/O"},
35 {.name = "CLK", .desc = "[EXT] Clock Comparator" }, 35 [EXTINT_CLK] = {.name = "CLK", .desc = "[EXT] Clock Comparator"},
36 {.name = "EXC", .desc = "[EXT] External Call" }, 36 [EXTINT_EXC] = {.name = "EXC", .desc = "[EXT] External Call"},
37 {.name = "EMS", .desc = "[EXT] Emergency Signal" }, 37 [EXTINT_EMS] = {.name = "EMS", .desc = "[EXT] Emergency Signal"},
38 {.name = "TMR", .desc = "[EXT] CPU Timer" }, 38 [EXTINT_TMR] = {.name = "TMR", .desc = "[EXT] CPU Timer"},
39 {.name = "TAL", .desc = "[EXT] Timing Alert" }, 39 [EXTINT_TLA] = {.name = "TAL", .desc = "[EXT] Timing Alert"},
40 {.name = "PFL", .desc = "[EXT] Pseudo Page Fault" }, 40 [EXTINT_PFL] = {.name = "PFL", .desc = "[EXT] Pseudo Page Fault"},
41 {.name = "DSD", .desc = "[EXT] DASD Diag" }, 41 [EXTINT_DSD] = {.name = "DSD", .desc = "[EXT] DASD Diag"},
42 {.name = "VRT", .desc = "[EXT] Virtio" }, 42 [EXTINT_VRT] = {.name = "VRT", .desc = "[EXT] Virtio"},
43 {.name = "SCP", .desc = "[EXT] Service Call" }, 43 [EXTINT_SCP] = {.name = "SCP", .desc = "[EXT] Service Call"},
44 {.name = "IUC", .desc = "[EXT] IUCV" }, 44 [EXTINT_IUC] = {.name = "IUC", .desc = "[EXT] IUCV"},
45 {.name = "CMS", .desc = "[EXT] CPU-Measurement: Sampling" }, 45 [EXTINT_CMS] = {.name = "CMS", .desc = "[EXT] CPU-Measurement: Sampling"},
46 {.name = "CMC", .desc = "[EXT] CPU-Measurement: Counter" }, 46 [EXTINT_CMC] = {.name = "CMC", .desc = "[EXT] CPU-Measurement: Counter"},
47 {.name = "CIO", .desc = "[I/O] Common I/O Layer Interrupt" }, 47 [EXTINT_CMR] = {.name = "CMR", .desc = "[EXT] CPU-Measurement: RI"},
48 {.name = "QAI", .desc = "[I/O] QDIO Adapter Interrupt" }, 48 [IOINT_CIO] = {.name = "CIO", .desc = "[I/O] Common I/O Layer Interrupt"},
49 {.name = "DAS", .desc = "[I/O] DASD" }, 49 [IOINT_QAI] = {.name = "QAI", .desc = "[I/O] QDIO Adapter Interrupt"},
50 {.name = "C15", .desc = "[I/O] 3215" }, 50 [IOINT_DAS] = {.name = "DAS", .desc = "[I/O] DASD"},
51 {.name = "C70", .desc = "[I/O] 3270" }, 51 [IOINT_C15] = {.name = "C15", .desc = "[I/O] 3215"},
52 {.name = "TAP", .desc = "[I/O] Tape" }, 52 [IOINT_C70] = {.name = "C70", .desc = "[I/O] 3270"},
53 {.name = "VMR", .desc = "[I/O] Unit Record Devices" }, 53 [IOINT_TAP] = {.name = "TAP", .desc = "[I/O] Tape"},
54 {.name = "LCS", .desc = "[I/O] LCS" }, 54 [IOINT_VMR] = {.name = "VMR", .desc = "[I/O] Unit Record Devices"},
55 {.name = "CLW", .desc = "[I/O] CLAW" }, 55 [IOINT_LCS] = {.name = "LCS", .desc = "[I/O] LCS"},
56 {.name = "CTC", .desc = "[I/O] CTC" }, 56 [IOINT_CLW] = {.name = "CLW", .desc = "[I/O] CLAW"},
57 {.name = "APB", .desc = "[I/O] AP Bus" }, 57 [IOINT_CTC] = {.name = "CTC", .desc = "[I/O] CTC"},
58 {.name = "CSC", .desc = "[I/O] CHSC Subchannel" }, 58 [IOINT_APB] = {.name = "APB", .desc = "[I/O] AP Bus"},
59 {.name = "NMI", .desc = "[NMI] Machine Check" }, 59 [IOINT_ADM] = {.name = "ADM", .desc = "[I/O] EADM Subchannel"},
60 [IOINT_CSC] = {.name = "CSC", .desc = "[I/O] CHSC Subchannel"},
61 [NMI_NMI] = {.name = "NMI", .desc = "[NMI] Machine Check"},
60}; 62};
61 63
62/* 64/*
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index 8aa634f5944b..d1c7214e157c 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -547,7 +547,7 @@ static int __kprobes kprobe_trap_handler(struct pt_regs *regs, int trapnr)
547 */ 547 */
548 entry = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); 548 entry = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
549 if (entry) { 549 if (entry) {
550 regs->psw.addr = entry->fixup | PSW_ADDR_AMODE; 550 regs->psw.addr = extable_fixup(entry) | PSW_ADDR_AMODE;
551 return 1; 551 return 1;
552 } 552 }
553 553
diff --git a/arch/s390/kernel/lgr.c b/arch/s390/kernel/lgr.c
index eca94e74d19a..6ea6d69339b5 100644
--- a/arch/s390/kernel/lgr.c
+++ b/arch/s390/kernel/lgr.c
@@ -51,16 +51,6 @@ static struct lgr_info lgr_info_cur;
51static struct debug_info *lgr_dbf; 51static struct debug_info *lgr_dbf;
52 52
53/* 53/*
54 * Return number of valid stsi levels
55 */
56static inline int stsi_0(void)
57{
58 int rc = stsi(NULL, 0, 0, 0);
59
60 return rc == -ENOSYS ? rc : (((unsigned int) rc) >> 28);
61}
62
63/*
64 * Copy buffer and then convert it to ASCII 54 * Copy buffer and then convert it to ASCII
65 */ 55 */
66static void cpascii(char *dst, char *src, int size) 56static void cpascii(char *dst, char *src, int size)
@@ -76,7 +66,7 @@ static void lgr_stsi_1_1_1(struct lgr_info *lgr_info)
76{ 66{
77 struct sysinfo_1_1_1 *si = (void *) lgr_page; 67 struct sysinfo_1_1_1 *si = (void *) lgr_page;
78 68
79 if (stsi(si, 1, 1, 1) == -ENOSYS) 69 if (stsi(si, 1, 1, 1))
80 return; 70 return;
81 cpascii(lgr_info->manufacturer, si->manufacturer, 71 cpascii(lgr_info->manufacturer, si->manufacturer,
82 sizeof(si->manufacturer)); 72 sizeof(si->manufacturer));
@@ -93,7 +83,7 @@ static void lgr_stsi_2_2_2(struct lgr_info *lgr_info)
93{ 83{
94 struct sysinfo_2_2_2 *si = (void *) lgr_page; 84 struct sysinfo_2_2_2 *si = (void *) lgr_page;
95 85
96 if (stsi(si, 2, 2, 2) == -ENOSYS) 86 if (stsi(si, 2, 2, 2))
97 return; 87 return;
98 cpascii(lgr_info->name, si->name, sizeof(si->name)); 88 cpascii(lgr_info->name, si->name, sizeof(si->name));
99 memcpy(&lgr_info->lpar_number, &si->lpar_number, 89 memcpy(&lgr_info->lpar_number, &si->lpar_number,
@@ -108,7 +98,7 @@ static void lgr_stsi_3_2_2(struct lgr_info *lgr_info)
108 struct sysinfo_3_2_2 *si = (void *) lgr_page; 98 struct sysinfo_3_2_2 *si = (void *) lgr_page;
109 int i; 99 int i;
110 100
111 if (stsi(si, 3, 2, 2) == -ENOSYS) 101 if (stsi(si, 3, 2, 2))
112 return; 102 return;
113 for (i = 0; i < min_t(u8, si->count, VM_LEVEL_MAX); i++) { 103 for (i = 0; i < min_t(u8, si->count, VM_LEVEL_MAX); i++) {
114 cpascii(lgr_info->vm[i].name, si->vm[i].name, 104 cpascii(lgr_info->vm[i].name, si->vm[i].name,
@@ -124,16 +114,17 @@ static void lgr_stsi_3_2_2(struct lgr_info *lgr_info)
124 */ 114 */
125static void lgr_info_get(struct lgr_info *lgr_info) 115static void lgr_info_get(struct lgr_info *lgr_info)
126{ 116{
117 int level;
118
127 memset(lgr_info, 0, sizeof(*lgr_info)); 119 memset(lgr_info, 0, sizeof(*lgr_info));
128 stfle(lgr_info->stfle_fac_list, ARRAY_SIZE(lgr_info->stfle_fac_list)); 120 stfle(lgr_info->stfle_fac_list, ARRAY_SIZE(lgr_info->stfle_fac_list));
129 lgr_info->level = stsi_0(); 121 level = stsi(NULL, 0, 0, 0);
130 if (lgr_info->level == -ENOSYS) 122 lgr_info->level = level;
131 return; 123 if (level >= 1)
132 if (lgr_info->level >= 1)
133 lgr_stsi_1_1_1(lgr_info); 124 lgr_stsi_1_1_1(lgr_info);
134 if (lgr_info->level >= 2) 125 if (level >= 2)
135 lgr_stsi_2_2_2(lgr_info); 126 lgr_stsi_2_2_2(lgr_info);
136 if (lgr_info->level >= 3) 127 if (level >= 3)
137 lgr_stsi_3_2_2(lgr_info); 128 lgr_stsi_3_2_2(lgr_info);
138} 129}
139 130
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index 493304bdf1c7..b3de27700016 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -21,6 +21,7 @@
21#include <asm/reset.h> 21#include <asm/reset.h>
22#include <asm/ipl.h> 22#include <asm/ipl.h>
23#include <asm/diag.h> 23#include <asm/diag.h>
24#include <asm/elf.h>
24#include <asm/asm-offsets.h> 25#include <asm/asm-offsets.h>
25#include <asm/os_info.h> 26#include <asm/os_info.h>
26 27
@@ -31,8 +32,6 @@ extern const unsigned long long relocate_kernel_len;
31 32
32#ifdef CONFIG_CRASH_DUMP 33#ifdef CONFIG_CRASH_DUMP
33 34
34void *fill_cpu_elf_notes(void *ptr, struct save_area *sa);
35
36/* 35/*
37 * Create ELF notes for one CPU 36 * Create ELF notes for one CPU
38 */ 37 */
@@ -159,7 +158,7 @@ int machine_kexec_prepare(struct kimage *image)
159 158
160 /* Can't replace kernel image since it is read-only. */ 159 /* Can't replace kernel image since it is read-only. */
161 if (ipl_flags & IPL_NSS_VALID) 160 if (ipl_flags & IPL_NSS_VALID)
162 return -ENOSYS; 161 return -EOPNOTSUPP;
163 162
164 if (image->type == KEXEC_TYPE_CRASH) 163 if (image->type == KEXEC_TYPE_CRASH)
165 return machine_kexec_prepare_kdump(); 164 return machine_kexec_prepare_kdump();
@@ -191,6 +190,10 @@ void machine_shutdown(void)
191{ 190{
192} 191}
193 192
193void machine_crash_shutdown(struct pt_regs *regs)
194{
195}
196
194/* 197/*
195 * Do normal kexec 198 * Do normal kexec
196 */ 199 */
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 733175373a4c..5024be27df44 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -26,10 +26,12 @@
26#include <asm/io.h> 26#include <asm/io.h>
27#include <asm/processor.h> 27#include <asm/processor.h>
28#include <asm/vtimer.h> 28#include <asm/vtimer.h>
29#include <asm/exec.h>
29#include <asm/irq.h> 30#include <asm/irq.h>
30#include <asm/nmi.h> 31#include <asm/nmi.h>
31#include <asm/smp.h> 32#include <asm/smp.h>
32#include <asm/switch_to.h> 33#include <asm/switch_to.h>
34#include <asm/runtime_instr.h>
33#include "entry.h" 35#include "entry.h"
34 36
35asmlinkage void ret_from_fork(void) asm ("ret_from_fork"); 37asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
@@ -132,6 +134,7 @@ EXPORT_SYMBOL(kernel_thread);
132 */ 134 */
133void exit_thread(void) 135void exit_thread(void)
134{ 136{
137 exit_thread_runtime_instr();
135} 138}
136 139
137void flush_thread(void) 140void flush_thread(void)
@@ -170,6 +173,11 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
170 /* Save access registers to new thread structure. */ 173 /* Save access registers to new thread structure. */
171 save_access_regs(&p->thread.acrs[0]); 174 save_access_regs(&p->thread.acrs[0]);
172 175
176 /* Don't copy runtime instrumentation info */
177 p->thread.ri_cb = NULL;
178 p->thread.ri_signum = 0;
179 frame->childregs.psw.mask &= ~PSW_MASK_RI;
180
173#ifndef CONFIG_64BIT 181#ifndef CONFIG_64BIT
174 /* 182 /*
175 * save fprs to current->thread.fp_regs to merge them with 183 * save fprs to current->thread.fp_regs to merge them with
diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c
index 572d4c9cb33b..753c41d0ffd3 100644
--- a/arch/s390/kernel/processor.c
+++ b/arch/s390/kernel/processor.c
@@ -39,9 +39,9 @@ void __cpuinit cpu_init(void)
39 */ 39 */
40static int show_cpuinfo(struct seq_file *m, void *v) 40static int show_cpuinfo(struct seq_file *m, void *v)
41{ 41{
42 static const char *hwcap_str[10] = { 42 static const char *hwcap_str[] = {
43 "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", 43 "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp",
44 "edat", "etf3eh", "highgprs" 44 "edat", "etf3eh", "highgprs", "te"
45 }; 45 };
46 unsigned long n = (unsigned long) v - 1; 46 unsigned long n = (unsigned long) v - 1;
47 int i; 47 int i;
@@ -54,10 +54,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)
54 num_online_cpus(), loops_per_jiffy/(500000/HZ), 54 num_online_cpus(), loops_per_jiffy/(500000/HZ),
55 (loops_per_jiffy/(5000/HZ))%100); 55 (loops_per_jiffy/(5000/HZ))%100);
56 seq_puts(m, "features\t: "); 56 seq_puts(m, "features\t: ");
57 for (i = 0; i < 10; i++) 57 for (i = 0; i < ARRAY_SIZE(hwcap_str); i++)
58 if (hwcap_str[i] && (elf_hwcap & (1UL << i))) 58 if (hwcap_str[i] && (elf_hwcap & (1UL << i)))
59 seq_printf(m, "%s ", hwcap_str[i]); 59 seq_printf(m, "%s ", hwcap_str[i]);
60 seq_puts(m, "\n"); 60 seq_puts(m, "\n");
61 show_cacheinfo(m);
61 } 62 }
62 get_online_cpus(); 63 get_online_cpus();
63 if (cpu_online(n)) { 64 if (cpu_online(n)) {
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index e4be113fbac6..a314c57f4e94 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -42,6 +42,7 @@ enum s390_regset {
42 REGSET_GENERAL, 42 REGSET_GENERAL,
43 REGSET_FP, 43 REGSET_FP,
44 REGSET_LAST_BREAK, 44 REGSET_LAST_BREAK,
45 REGSET_TDB,
45 REGSET_SYSTEM_CALL, 46 REGSET_SYSTEM_CALL,
46 REGSET_GENERAL_EXTENDED, 47 REGSET_GENERAL_EXTENDED,
47}; 48};
@@ -52,6 +53,22 @@ void update_per_regs(struct task_struct *task)
52 struct thread_struct *thread = &task->thread; 53 struct thread_struct *thread = &task->thread;
53 struct per_regs old, new; 54 struct per_regs old, new;
54 55
56#ifdef CONFIG_64BIT
57 /* Take care of the enable/disable of transactional execution. */
58 if (MACHINE_HAS_TE) {
59 unsigned long cr0, cr0_new;
60
61 __ctl_store(cr0, 0, 0);
62 /* set or clear transaction execution bits 8 and 9. */
63 if (task->thread.per_flags & PER_FLAG_NO_TE)
64 cr0_new = cr0 & ~(3UL << 54);
65 else
66 cr0_new = cr0 | (3UL << 54);
67 /* Only load control register 0 if necessary. */
68 if (cr0 != cr0_new)
69 __ctl_load(cr0_new, 0, 0);
70 }
71#endif
55 /* Copy user specified PER registers */ 72 /* Copy user specified PER registers */
56 new.control = thread->per_user.control; 73 new.control = thread->per_user.control;
57 new.start = thread->per_user.start; 74 new.start = thread->per_user.start;
@@ -60,6 +77,10 @@ void update_per_regs(struct task_struct *task)
60 /* merge TIF_SINGLE_STEP into user specified PER registers. */ 77 /* merge TIF_SINGLE_STEP into user specified PER registers. */
61 if (test_tsk_thread_flag(task, TIF_SINGLE_STEP)) { 78 if (test_tsk_thread_flag(task, TIF_SINGLE_STEP)) {
62 new.control |= PER_EVENT_IFETCH; 79 new.control |= PER_EVENT_IFETCH;
80#ifdef CONFIG_64BIT
81 new.control |= PER_CONTROL_SUSPENSION;
82 new.control |= PER_EVENT_TRANSACTION_END;
83#endif
63 new.start = 0; 84 new.start = 0;
64 new.end = PSW_ADDR_INSN; 85 new.end = PSW_ADDR_INSN;
65 } 86 }
@@ -100,6 +121,7 @@ void ptrace_disable(struct task_struct *task)
100 memset(&task->thread.per_event, 0, sizeof(task->thread.per_event)); 121 memset(&task->thread.per_event, 0, sizeof(task->thread.per_event));
101 clear_tsk_thread_flag(task, TIF_SINGLE_STEP); 122 clear_tsk_thread_flag(task, TIF_SINGLE_STEP);
102 clear_tsk_thread_flag(task, TIF_PER_TRAP); 123 clear_tsk_thread_flag(task, TIF_PER_TRAP);
124 task->thread.per_flags = 0;
103} 125}
104 126
105#ifndef CONFIG_64BIT 127#ifndef CONFIG_64BIT
@@ -416,6 +438,16 @@ long arch_ptrace(struct task_struct *child, long request,
416 put_user(task_thread_info(child)->last_break, 438 put_user(task_thread_info(child)->last_break,
417 (unsigned long __user *) data); 439 (unsigned long __user *) data);
418 return 0; 440 return 0;
441 case PTRACE_ENABLE_TE:
442 if (!MACHINE_HAS_TE)
443 return -EIO;
444 child->thread.per_flags &= ~PER_FLAG_NO_TE;
445 return 0;
446 case PTRACE_DISABLE_TE:
447 if (!MACHINE_HAS_TE)
448 return -EIO;
449 child->thread.per_flags |= PER_FLAG_NO_TE;
450 return 0;
419 default: 451 default:
420 /* Removing high order bit from addr (only for 31 bit). */ 452 /* Removing high order bit from addr (only for 31 bit). */
421 addr &= PSW_ADDR_INSN; 453 addr &= PSW_ADDR_INSN;
@@ -903,6 +935,28 @@ static int s390_last_break_set(struct task_struct *target,
903 return 0; 935 return 0;
904} 936}
905 937
938static int s390_tdb_get(struct task_struct *target,
939 const struct user_regset *regset,
940 unsigned int pos, unsigned int count,
941 void *kbuf, void __user *ubuf)
942{
943 struct pt_regs *regs = task_pt_regs(target);
944 unsigned char *data;
945
946 if (!(regs->int_code & 0x200))
947 return -ENODATA;
948 data = target->thread.trap_tdb;
949 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, data, 0, 256);
950}
951
952static int s390_tdb_set(struct task_struct *target,
953 const struct user_regset *regset,
954 unsigned int pos, unsigned int count,
955 const void *kbuf, const void __user *ubuf)
956{
957 return 0;
958}
959
906#endif 960#endif
907 961
908static int s390_system_call_get(struct task_struct *target, 962static int s390_system_call_get(struct task_struct *target,
@@ -951,6 +1005,14 @@ static const struct user_regset s390_regsets[] = {
951 .get = s390_last_break_get, 1005 .get = s390_last_break_get,
952 .set = s390_last_break_set, 1006 .set = s390_last_break_set,
953 }, 1007 },
1008 [REGSET_TDB] = {
1009 .core_note_type = NT_S390_TDB,
1010 .n = 1,
1011 .size = 256,
1012 .align = 1,
1013 .get = s390_tdb_get,
1014 .set = s390_tdb_set,
1015 },
954#endif 1016#endif
955 [REGSET_SYSTEM_CALL] = { 1017 [REGSET_SYSTEM_CALL] = {
956 .core_note_type = NT_S390_SYSTEM_CALL, 1018 .core_note_type = NT_S390_SYSTEM_CALL,
@@ -1148,6 +1210,14 @@ static const struct user_regset s390_compat_regsets[] = {
1148 .get = s390_compat_last_break_get, 1210 .get = s390_compat_last_break_get,
1149 .set = s390_compat_last_break_set, 1211 .set = s390_compat_last_break_set,
1150 }, 1212 },
1213 [REGSET_TDB] = {
1214 .core_note_type = NT_S390_TDB,
1215 .n = 1,
1216 .size = 256,
1217 .align = 1,
1218 .get = s390_tdb_get,
1219 .set = s390_tdb_set,
1220 },
1151 [REGSET_SYSTEM_CALL] = { 1221 [REGSET_SYSTEM_CALL] = {
1152 .core_note_type = NT_S390_SYSTEM_CALL, 1222 .core_note_type = NT_S390_SYSTEM_CALL,
1153 .n = 1, 1223 .n = 1,
diff --git a/arch/s390/kernel/runtime_instr.c b/arch/s390/kernel/runtime_instr.c
new file mode 100644
index 000000000000..61066f6f71a5
--- /dev/null
+++ b/arch/s390/kernel/runtime_instr.c
@@ -0,0 +1,150 @@
1/*
2 * Copyright IBM Corp. 2012
3 * Author(s): Jan Glauber <jang@linux.vnet.ibm.com>
4 */
5
6#include <linux/kernel.h>
7#include <linux/syscalls.h>
8#include <linux/signal.h>
9#include <linux/mm.h>
10#include <linux/slab.h>
11#include <linux/init.h>
12#include <linux/errno.h>
13#include <linux/kernel_stat.h>
14#include <asm/runtime_instr.h>
15#include <asm/cpu_mf.h>
16#include <asm/irq.h>
17
18/* empty control block to disable RI by loading it */
19struct runtime_instr_cb runtime_instr_empty_cb;
20
21static int runtime_instr_avail(void)
22{
23 return test_facility(64);
24}
25
26static void disable_runtime_instr(void)
27{
28 struct pt_regs *regs = task_pt_regs(current);
29
30 load_runtime_instr_cb(&runtime_instr_empty_cb);
31
32 /*
33 * Make sure the RI bit is deleted from the PSW. If the user did not
34 * switch off RI before the system call the process will get a
35 * specification exception otherwise.
36 */
37 regs->psw.mask &= ~PSW_MASK_RI;
38}
39
40static void init_runtime_instr_cb(struct runtime_instr_cb *cb)
41{
42 cb->buf_limit = 0xfff;
43 if (s390_user_mode == HOME_SPACE_MODE)
44 cb->home_space = 1;
45 cb->int_requested = 1;
46 cb->pstate = 1;
47 cb->pstate_set_buf = 1;
48 cb->pstate_sample = 1;
49 cb->pstate_collect = 1;
50 cb->key = PAGE_DEFAULT_KEY;
51 cb->valid = 1;
52}
53
54void exit_thread_runtime_instr(void)
55{
56 struct task_struct *task = current;
57
58 if (!task->thread.ri_cb)
59 return;
60 disable_runtime_instr();
61 kfree(task->thread.ri_cb);
62 task->thread.ri_signum = 0;
63 task->thread.ri_cb = NULL;
64}
65
66static void runtime_instr_int_handler(struct ext_code ext_code,
67 unsigned int param32, unsigned long param64)
68{
69 struct siginfo info;
70
71 if (!(param32 & CPU_MF_INT_RI_MASK))
72 return;
73
74 kstat_cpu(smp_processor_id()).irqs[EXTINT_CMR]++;
75
76 if (!current->thread.ri_cb)
77 return;
78 if (current->thread.ri_signum < SIGRTMIN ||
79 current->thread.ri_signum > SIGRTMAX) {
80 WARN_ON_ONCE(1);
81 return;
82 }
83
84 memset(&info, 0, sizeof(info));
85 info.si_signo = current->thread.ri_signum;
86 info.si_code = SI_QUEUE;
87 if (param32 & CPU_MF_INT_RI_BUF_FULL)
88 info.si_int = ENOBUFS;
89 else if (param32 & CPU_MF_INT_RI_HALTED)
90 info.si_int = ECANCELED;
91 else
92 return; /* unknown reason */
93
94 send_sig_info(current->thread.ri_signum, &info, current);
95}
96
97SYSCALL_DEFINE2(s390_runtime_instr, int, command, int, signum)
98{
99 struct runtime_instr_cb *cb;
100
101 if (!runtime_instr_avail())
102 return -EOPNOTSUPP;
103
104 if (command == S390_RUNTIME_INSTR_STOP) {
105 preempt_disable();
106 exit_thread_runtime_instr();
107 preempt_enable();
108 return 0;
109 }
110
111 if (command != S390_RUNTIME_INSTR_START ||
112 (signum < SIGRTMIN || signum > SIGRTMAX))
113 return -EINVAL;
114
115 if (!current->thread.ri_cb) {
116 cb = kzalloc(sizeof(*cb), GFP_KERNEL);
117 if (!cb)
118 return -ENOMEM;
119 } else {
120 cb = current->thread.ri_cb;
121 memset(cb, 0, sizeof(*cb));
122 }
123
124 init_runtime_instr_cb(cb);
125 current->thread.ri_signum = signum;
126
127 /* now load the control block to make it available */
128 preempt_disable();
129 current->thread.ri_cb = cb;
130 load_runtime_instr_cb(cb);
131 preempt_enable();
132 return 0;
133}
134
135static int __init runtime_instr_init(void)
136{
137 int rc;
138
139 if (!runtime_instr_avail())
140 return 0;
141
142 measurement_alert_subclass_register();
143 rc = register_external_interrupt(0x1407, runtime_instr_int_handler);
144 if (rc)
145 measurement_alert_subclass_unregister();
146 else
147 pr_info("Runtime instrumentation facility initialized\n");
148 return rc;
149}
150device_initcall(runtime_instr_init);
diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c
index 57b536649b00..9bdbcef1da9e 100644
--- a/arch/s390/kernel/s390_ksyms.c
+++ b/arch/s390/kernel/s390_ksyms.c
@@ -8,3 +8,5 @@ EXPORT_SYMBOL(_mcount);
8#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) 8#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
9EXPORT_SYMBOL(sie64a); 9EXPORT_SYMBOL(sie64a);
10#endif 10#endif
11EXPORT_SYMBOL(memcpy);
12EXPORT_SYMBOL(memset);
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index f86c81e13c37..afa9fdba200e 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -302,10 +302,10 @@ static int __init parse_vmalloc(char *arg)
302} 302}
303early_param("vmalloc", parse_vmalloc); 303early_param("vmalloc", parse_vmalloc);
304 304
305unsigned int addressing_mode = HOME_SPACE_MODE; 305unsigned int s390_user_mode = PRIMARY_SPACE_MODE;
306EXPORT_SYMBOL_GPL(addressing_mode); 306EXPORT_SYMBOL_GPL(s390_user_mode);
307 307
308static int set_amode_primary(void) 308static void __init set_user_mode_primary(void)
309{ 309{
310 psw_kernel_bits = (psw_kernel_bits & ~PSW_MASK_ASC) | PSW_ASC_HOME; 310 psw_kernel_bits = (psw_kernel_bits & ~PSW_MASK_ASC) | PSW_ASC_HOME;
311 psw_user_bits = (psw_user_bits & ~PSW_MASK_ASC) | PSW_ASC_PRIMARY; 311 psw_user_bits = (psw_user_bits & ~PSW_MASK_ASC) | PSW_ASC_PRIMARY;
@@ -313,48 +313,30 @@ static int set_amode_primary(void)
313 psw32_user_bits = 313 psw32_user_bits =
314 (psw32_user_bits & ~PSW32_MASK_ASC) | PSW32_ASC_PRIMARY; 314 (psw32_user_bits & ~PSW32_MASK_ASC) | PSW32_ASC_PRIMARY;
315#endif 315#endif
316 316 uaccess = MACHINE_HAS_MVCOS ? uaccess_mvcos_switch : uaccess_pt;
317 if (MACHINE_HAS_MVCOS) {
318 memcpy(&uaccess, &uaccess_mvcos_switch, sizeof(uaccess));
319 return 1;
320 } else {
321 memcpy(&uaccess, &uaccess_pt, sizeof(uaccess));
322 return 0;
323 }
324}
325
326/*
327 * Switch kernel/user addressing modes?
328 */
329static int __init early_parse_switch_amode(char *p)
330{
331 addressing_mode = PRIMARY_SPACE_MODE;
332 return 0;
333} 317}
334early_param("switch_amode", early_parse_switch_amode);
335 318
336static int __init early_parse_user_mode(char *p) 319static int __init early_parse_user_mode(char *p)
337{ 320{
338 if (p && strcmp(p, "primary") == 0) 321 if (p && strcmp(p, "primary") == 0)
339 addressing_mode = PRIMARY_SPACE_MODE; 322 s390_user_mode = PRIMARY_SPACE_MODE;
340 else if (!p || strcmp(p, "home") == 0) 323 else if (!p || strcmp(p, "home") == 0)
341 addressing_mode = HOME_SPACE_MODE; 324 s390_user_mode = HOME_SPACE_MODE;
342 else 325 else
343 return 1; 326 return 1;
344 return 0; 327 return 0;
345} 328}
346early_param("user_mode", early_parse_user_mode); 329early_param("user_mode", early_parse_user_mode);
347 330
348static void setup_addressing_mode(void) 331static void __init setup_addressing_mode(void)
349{ 332{
350 if (addressing_mode == PRIMARY_SPACE_MODE) { 333 if (s390_user_mode != PRIMARY_SPACE_MODE)
351 if (set_amode_primary()) 334 return;
352 pr_info("Address spaces switched, " 335 set_user_mode_primary();
353 "mvcos available\n"); 336 if (MACHINE_HAS_MVCOS)
354 else 337 pr_info("Address spaces switched, mvcos available\n");
355 pr_info("Address spaces switched, " 338 else
356 "mvcos not available\n"); 339 pr_info("Address spaces switched, mvcos not available\n");
357 }
358} 340}
359 341
360void *restart_stack __attribute__((__section__(".data"))); 342void *restart_stack __attribute__((__section__(".data")));
@@ -602,9 +584,7 @@ static void __init setup_memory_end(void)
602 584
603static void __init setup_vmcoreinfo(void) 585static void __init setup_vmcoreinfo(void)
604{ 586{
605#ifdef CONFIG_KEXEC
606 mem_assign_absolute(S390_lowcore.vmcore_info, paddr_vmcoreinfo_note()); 587 mem_assign_absolute(S390_lowcore.vmcore_info, paddr_vmcoreinfo_note());
607#endif
608} 588}
609 589
610#ifdef CONFIG_CRASH_DUMP 590#ifdef CONFIG_CRASH_DUMP
@@ -974,12 +954,20 @@ static void __init setup_hwcaps(void)
974 if (MACHINE_HAS_HPAGE) 954 if (MACHINE_HAS_HPAGE)
975 elf_hwcap |= HWCAP_S390_HPAGE; 955 elf_hwcap |= HWCAP_S390_HPAGE;
976 956
957#if defined(CONFIG_64BIT)
977 /* 958 /*
978 * 64-bit register support for 31-bit processes 959 * 64-bit register support for 31-bit processes
979 * HWCAP_S390_HIGH_GPRS is bit 9. 960 * HWCAP_S390_HIGH_GPRS is bit 9.
980 */ 961 */
981 elf_hwcap |= HWCAP_S390_HIGH_GPRS; 962 elf_hwcap |= HWCAP_S390_HIGH_GPRS;
982 963
964 /*
965 * Transactional execution support HWCAP_S390_TE is bit 10.
966 */
967 if (test_facility(50) && test_facility(73))
968 elf_hwcap |= HWCAP_S390_TE;
969#endif
970
983 get_cpu_id(&cpu_id); 971 get_cpu_id(&cpu_id);
984 switch (cpu_id.machine) { 972 switch (cpu_id.machine) {
985 case 0x9672: 973 case 0x9672:
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 720fda1620f2..ea431e551c6b 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -66,7 +66,7 @@ struct pcpu {
66 unsigned long panic_stack; /* panic stack for the cpu */ 66 unsigned long panic_stack; /* panic stack for the cpu */
67 unsigned long ec_mask; /* bit mask for ec_xxx functions */ 67 unsigned long ec_mask; /* bit mask for ec_xxx functions */
68 int state; /* physical cpu state */ 68 int state; /* physical cpu state */
69 u32 status; /* last status received via sigp */ 69 int polarization; /* physical polarization */
70 u16 address; /* physical cpu address */ 70 u16 address; /* physical cpu address */
71}; 71};
72 72
@@ -74,6 +74,10 @@ static u8 boot_cpu_type;
74static u16 boot_cpu_address; 74static u16 boot_cpu_address;
75static struct pcpu pcpu_devices[NR_CPUS]; 75static struct pcpu pcpu_devices[NR_CPUS];
76 76
77/*
78 * The smp_cpu_state_mutex must be held when changing the state or polarization
79 * member of a pcpu data structure within the pcpu_devices arreay.
80 */
77DEFINE_MUTEX(smp_cpu_state_mutex); 81DEFINE_MUTEX(smp_cpu_state_mutex);
78 82
79/* 83/*
@@ -99,7 +103,7 @@ static inline int __pcpu_sigp_relax(u16 addr, u8 order, u32 parm, u32 *status)
99 int cc; 103 int cc;
100 104
101 while (1) { 105 while (1) {
102 cc = __pcpu_sigp(addr, order, parm, status); 106 cc = __pcpu_sigp(addr, order, parm, NULL);
103 if (cc != SIGP_CC_BUSY) 107 if (cc != SIGP_CC_BUSY)
104 return cc; 108 return cc;
105 cpu_relax(); 109 cpu_relax();
@@ -111,7 +115,7 @@ static int pcpu_sigp_retry(struct pcpu *pcpu, u8 order, u32 parm)
111 int cc, retry; 115 int cc, retry;
112 116
113 for (retry = 0; ; retry++) { 117 for (retry = 0; ; retry++) {
114 cc = __pcpu_sigp(pcpu->address, order, parm, &pcpu->status); 118 cc = __pcpu_sigp(pcpu->address, order, parm, NULL);
115 if (cc != SIGP_CC_BUSY) 119 if (cc != SIGP_CC_BUSY)
116 break; 120 break;
117 if (retry >= 3) 121 if (retry >= 3)
@@ -122,16 +126,18 @@ static int pcpu_sigp_retry(struct pcpu *pcpu, u8 order, u32 parm)
122 126
123static inline int pcpu_stopped(struct pcpu *pcpu) 127static inline int pcpu_stopped(struct pcpu *pcpu)
124{ 128{
129 u32 uninitialized_var(status);
130
125 if (__pcpu_sigp(pcpu->address, SIGP_SENSE, 131 if (__pcpu_sigp(pcpu->address, SIGP_SENSE,
126 0, &pcpu->status) != SIGP_CC_STATUS_STORED) 132 0, &status) != SIGP_CC_STATUS_STORED)
127 return 0; 133 return 0;
128 return !!(pcpu->status & (SIGP_STATUS_CHECK_STOP|SIGP_STATUS_STOPPED)); 134 return !!(status & (SIGP_STATUS_CHECK_STOP|SIGP_STATUS_STOPPED));
129} 135}
130 136
131static inline int pcpu_running(struct pcpu *pcpu) 137static inline int pcpu_running(struct pcpu *pcpu)
132{ 138{
133 if (__pcpu_sigp(pcpu->address, SIGP_SENSE_RUNNING, 139 if (__pcpu_sigp(pcpu->address, SIGP_SENSE_RUNNING,
134 0, &pcpu->status) != SIGP_CC_STATUS_STORED) 140 0, NULL) != SIGP_CC_STATUS_STORED)
135 return 1; 141 return 1;
136 /* Status stored condition code is equivalent to cpu not running. */ 142 /* Status stored condition code is equivalent to cpu not running. */
137 return 0; 143 return 0;
@@ -586,6 +592,16 @@ static inline void smp_get_save_area(int cpu, u16 address) { }
586 592
587#endif /* CONFIG_ZFCPDUMP || CONFIG_CRASH_DUMP */ 593#endif /* CONFIG_ZFCPDUMP || CONFIG_CRASH_DUMP */
588 594
595void smp_cpu_set_polarization(int cpu, int val)
596{
597 pcpu_devices[cpu].polarization = val;
598}
599
600int smp_cpu_get_polarization(int cpu)
601{
602 return pcpu_devices[cpu].polarization;
603}
604
589static struct sclp_cpu_info *smp_get_cpu_info(void) 605static struct sclp_cpu_info *smp_get_cpu_info(void)
590{ 606{
591 static int use_sigp_detection; 607 static int use_sigp_detection;
@@ -628,7 +644,7 @@ static int __devinit __smp_rescan_cpus(struct sclp_cpu_info *info,
628 pcpu->address = info->cpu[i].address; 644 pcpu->address = info->cpu[i].address;
629 pcpu->state = (cpu >= info->configured) ? 645 pcpu->state = (cpu >= info->configured) ?
630 CPU_STATE_STANDBY : CPU_STATE_CONFIGURED; 646 CPU_STATE_STANDBY : CPU_STATE_CONFIGURED;
631 cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); 647 smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
632 set_cpu_present(cpu, true); 648 set_cpu_present(cpu, true);
633 if (sysfs_add && smp_add_present_cpu(cpu) != 0) 649 if (sysfs_add && smp_add_present_cpu(cpu) != 0)
634 set_cpu_present(cpu, false); 650 set_cpu_present(cpu, false);
@@ -796,7 +812,7 @@ void __init smp_prepare_boot_cpu(void)
796 pcpu->async_stack = S390_lowcore.async_stack - ASYNC_SIZE; 812 pcpu->async_stack = S390_lowcore.async_stack - ASYNC_SIZE;
797 pcpu->panic_stack = S390_lowcore.panic_stack - PAGE_SIZE; 813 pcpu->panic_stack = S390_lowcore.panic_stack - PAGE_SIZE;
798 S390_lowcore.percpu_offset = __per_cpu_offset[0]; 814 S390_lowcore.percpu_offset = __per_cpu_offset[0];
799 cpu_set_polarization(0, POLARIZATION_UNKNOWN); 815 smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN);
800 set_cpu_present(0, true); 816 set_cpu_present(0, true);
801 set_cpu_online(0, true); 817 set_cpu_online(0, true);
802} 818}
@@ -862,7 +878,7 @@ static ssize_t cpu_configure_store(struct device *dev,
862 if (rc) 878 if (rc)
863 break; 879 break;
864 pcpu->state = CPU_STATE_STANDBY; 880 pcpu->state = CPU_STATE_STANDBY;
865 cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); 881 smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
866 topology_expect_change(); 882 topology_expect_change();
867 break; 883 break;
868 case 1: 884 case 1:
@@ -872,7 +888,7 @@ static ssize_t cpu_configure_store(struct device *dev,
872 if (rc) 888 if (rc)
873 break; 889 break;
874 pcpu->state = CPU_STATE_CONFIGURED; 890 pcpu->state = CPU_STATE_CONFIGURED;
875 cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); 891 smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
876 topology_expect_change(); 892 topology_expect_change();
877 break; 893 break;
878 default: 894 default:
@@ -959,23 +975,17 @@ static int __cpuinit smp_cpu_notify(struct notifier_block *self,
959 struct device *s = &c->dev; 975 struct device *s = &c->dev;
960 int err = 0; 976 int err = 0;
961 977
962 switch (action) { 978 switch (action & ~CPU_TASKS_FROZEN) {
963 case CPU_ONLINE: 979 case CPU_ONLINE:
964 case CPU_ONLINE_FROZEN:
965 err = sysfs_create_group(&s->kobj, &cpu_online_attr_group); 980 err = sysfs_create_group(&s->kobj, &cpu_online_attr_group);
966 break; 981 break;
967 case CPU_DEAD: 982 case CPU_DEAD:
968 case CPU_DEAD_FROZEN:
969 sysfs_remove_group(&s->kobj, &cpu_online_attr_group); 983 sysfs_remove_group(&s->kobj, &cpu_online_attr_group);
970 break; 984 break;
971 } 985 }
972 return notifier_from_errno(err); 986 return notifier_from_errno(err);
973} 987}
974 988
975static struct notifier_block __cpuinitdata smp_cpu_nb = {
976 .notifier_call = smp_cpu_notify,
977};
978
979static int __devinit smp_add_present_cpu(int cpu) 989static int __devinit smp_add_present_cpu(int cpu)
980{ 990{
981 struct cpu *c = &pcpu_devices[cpu].cpu; 991 struct cpu *c = &pcpu_devices[cpu].cpu;
@@ -1050,7 +1060,7 @@ static int __init s390_smp_init(void)
1050{ 1060{
1051 int cpu, rc; 1061 int cpu, rc;
1052 1062
1053 register_cpu_notifier(&smp_cpu_nb); 1063 hotcpu_notifier(smp_cpu_notify, 0);
1054#ifdef CONFIG_HOTPLUG_CPU 1064#ifdef CONFIG_HOTPLUG_CPU
1055 rc = device_create_file(cpu_subsys.dev_root, &dev_attr_rescan); 1065 rc = device_create_file(cpu_subsys.dev_root, &dev_attr_rescan);
1056 if (rc) 1066 if (rc)
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index bcab2f04ba58..48174850f3b0 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -350,3 +350,5 @@ SYSCALL(sys_syncfs,sys_syncfs,sys_syncfs_wrapper)
350SYSCALL(sys_setns,sys_setns,sys_setns_wrapper) 350SYSCALL(sys_setns,sys_setns,sys_setns_wrapper)
351SYSCALL(sys_process_vm_readv,sys_process_vm_readv,compat_sys_process_vm_readv_wrapper) /* 340 */ 351SYSCALL(sys_process_vm_readv,sys_process_vm_readv,compat_sys_process_vm_readv_wrapper) /* 340 */
352SYSCALL(sys_process_vm_writev,sys_process_vm_writev,compat_sys_process_vm_writev_wrapper) 352SYSCALL(sys_process_vm_writev,sys_process_vm_writev,compat_sys_process_vm_writev_wrapper)
353SYSCALL(sys_ni_syscall,sys_s390_runtime_instr,sys_s390_runtime_instr_wrapper)
354SYSCALL(sys_kcmp,sys_kcmp,sys_kcmp_wrapper)
diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c
index fa0eb238dac7..62f89d98e880 100644
--- a/arch/s390/kernel/sysinfo.c
+++ b/arch/s390/kernel/sysinfo.c
@@ -22,17 +22,41 @@
22#include <math-emu/soft-fp.h> 22#include <math-emu/soft-fp.h>
23#include <math-emu/single.h> 23#include <math-emu/single.h>
24 24
25static inline int stsi_0(void) 25int topology_max_mnest;
26
27/*
28 * stsi - store system information
29 *
30 * Returns the current configuration level if function code 0 was specified.
31 * Otherwise returns 0 on success or a negative value on error.
32 */
33int stsi(void *sysinfo, int fc, int sel1, int sel2)
26{ 34{
27 int rc = stsi(NULL, 0, 0, 0); 35 register int r0 asm("0") = (fc << 28) | sel1;
28 return rc == -ENOSYS ? rc : (((unsigned int) rc) >> 28); 36 register int r1 asm("1") = sel2;
37 int rc = 0;
38
39 asm volatile(
40 " stsi 0(%3)\n"
41 "0: jz 2f\n"
42 "1: lhi %1,%4\n"
43 "2:\n"
44 EX_TABLE(0b, 1b)
45 : "+d" (r0), "+d" (rc)
46 : "d" (r1), "a" (sysinfo), "K" (-EOPNOTSUPP)
47 : "cc", "memory");
48 if (rc)
49 return rc;
50 return fc ? 0 : ((unsigned int) r0) >> 28;
29} 51}
52EXPORT_SYMBOL(stsi);
30 53
31static int stsi_1_1_1(struct sysinfo_1_1_1 *info, char *page, int len) 54static void stsi_1_1_1(struct seq_file *m, struct sysinfo_1_1_1 *info)
32{ 55{
33 if (stsi(info, 1, 1, 1) == -ENOSYS) 56 int i;
34 return len;
35 57
58 if (stsi(info, 1, 1, 1))
59 return;
36 EBCASC(info->manufacturer, sizeof(info->manufacturer)); 60 EBCASC(info->manufacturer, sizeof(info->manufacturer));
37 EBCASC(info->type, sizeof(info->type)); 61 EBCASC(info->type, sizeof(info->type));
38 EBCASC(info->model, sizeof(info->model)); 62 EBCASC(info->model, sizeof(info->model));
@@ -41,242 +65,197 @@ static int stsi_1_1_1(struct sysinfo_1_1_1 *info, char *page, int len)
41 EBCASC(info->model_capacity, sizeof(info->model_capacity)); 65 EBCASC(info->model_capacity, sizeof(info->model_capacity));
42 EBCASC(info->model_perm_cap, sizeof(info->model_perm_cap)); 66 EBCASC(info->model_perm_cap, sizeof(info->model_perm_cap));
43 EBCASC(info->model_temp_cap, sizeof(info->model_temp_cap)); 67 EBCASC(info->model_temp_cap, sizeof(info->model_temp_cap));
44 len += sprintf(page + len, "Manufacturer: %-16.16s\n", 68 seq_printf(m, "Manufacturer: %-16.16s\n", info->manufacturer);
45 info->manufacturer); 69 seq_printf(m, "Type: %-4.4s\n", info->type);
46 len += sprintf(page + len, "Type: %-4.4s\n", 70 /*
47 info->type); 71 * Sigh: the model field has been renamed with System z9
72 * to model_capacity and a new model field has been added
73 * after the plant field. To avoid confusing older programs
74 * the "Model:" prints "model_capacity model" or just
75 * "model_capacity" if the model string is empty .
76 */
77 seq_printf(m, "Model: %-16.16s", info->model_capacity);
48 if (info->model[0] != '\0') 78 if (info->model[0] != '\0')
49 /* 79 seq_printf(m, " %-16.16s", info->model);
50 * Sigh: the model field has been renamed with System z9 80 seq_putc(m, '\n');
51 * to model_capacity and a new model field has been added 81 seq_printf(m, "Sequence Code: %-16.16s\n", info->sequence);
52 * after the plant field. To avoid confusing older programs 82 seq_printf(m, "Plant: %-4.4s\n", info->plant);
53 * the "Model:" prints "model_capacity model" or just 83 seq_printf(m, "Model Capacity: %-16.16s %08u\n",
54 * "model_capacity" if the model string is empty . 84 info->model_capacity, info->model_cap_rating);
55 */ 85 if (info->model_perm_cap_rating)
56 len += sprintf(page + len, 86 seq_printf(m, "Model Perm. Capacity: %-16.16s %08u\n",
57 "Model: %-16.16s %-16.16s\n", 87 info->model_perm_cap,
58 info->model_capacity, info->model); 88 info->model_perm_cap_rating);
59 else 89 if (info->model_temp_cap_rating)
60 len += sprintf(page + len, "Model: %-16.16s\n", 90 seq_printf(m, "Model Temp. Capacity: %-16.16s %08u\n",
61 info->model_capacity); 91 info->model_temp_cap,
62 len += sprintf(page + len, "Sequence Code: %-16.16s\n", 92 info->model_temp_cap_rating);
63 info->sequence); 93 if (info->ncr)
64 len += sprintf(page + len, "Plant: %-4.4s\n", 94 seq_printf(m, "Nominal Cap. Rating: %08u\n", info->ncr);
65 info->plant); 95 if (info->npr)
66 len += sprintf(page + len, "Model Capacity: %-16.16s %08u\n", 96 seq_printf(m, "Nominal Perm. Rating: %08u\n", info->npr);
67 info->model_capacity, *(u32 *) info->model_cap_rating); 97 if (info->ntr)
68 if (info->model_perm_cap[0] != '\0') 98 seq_printf(m, "Nominal Temp. Rating: %08u\n", info->ntr);
69 len += sprintf(page + len,
70 "Model Perm. Capacity: %-16.16s %08u\n",
71 info->model_perm_cap,
72 *(u32 *) info->model_perm_cap_rating);
73 if (info->model_temp_cap[0] != '\0')
74 len += sprintf(page + len,
75 "Model Temp. Capacity: %-16.16s %08u\n",
76 info->model_temp_cap,
77 *(u32 *) info->model_temp_cap_rating);
78 if (info->cai) { 99 if (info->cai) {
79 len += sprintf(page + len, 100 seq_printf(m, "Capacity Adj. Ind.: %d\n", info->cai);
80 "Capacity Adj. Ind.: %d\n", 101 seq_printf(m, "Capacity Ch. Reason: %d\n", info->ccr);
81 info->cai); 102 seq_printf(m, "Capacity Transient: %d\n", info->t);
82 len += sprintf(page + len, "Capacity Ch. Reason: %d\n", 103 }
83 info->ccr); 104 if (info->p) {
105 for (i = 1; i <= ARRAY_SIZE(info->typepct); i++) {
106 seq_printf(m, "Type %d Percentage: %d\n",
107 i, info->typepct[i - 1]);
108 }
84 } 109 }
85 return len;
86} 110}
87 111
88static int stsi_15_1_x(struct sysinfo_15_1_x *info, char *page, int len) 112static void stsi_15_1_x(struct seq_file *m, struct sysinfo_15_1_x *info)
89{ 113{
90 static int max_mnest; 114 static int max_mnest;
91 int i, rc; 115 int i, rc;
92 116
93 len += sprintf(page + len, "\n"); 117 seq_putc(m, '\n');
94 if (!MACHINE_HAS_TOPOLOGY) 118 if (!MACHINE_HAS_TOPOLOGY)
95 return len; 119 return;
96 if (max_mnest) { 120 if (stsi(info, 15, 1, topology_max_mnest))
97 stsi(info, 15, 1, max_mnest); 121 return;
98 } else { 122 seq_printf(m, "CPU Topology HW: ");
99 for (max_mnest = 6; max_mnest > 1; max_mnest--) {
100 rc = stsi(info, 15, 1, max_mnest);
101 if (rc != -ENOSYS)
102 break;
103 }
104 }
105 len += sprintf(page + len, "CPU Topology HW: ");
106 for (i = 0; i < TOPOLOGY_NR_MAG; i++) 123 for (i = 0; i < TOPOLOGY_NR_MAG; i++)
107 len += sprintf(page + len, " %d", info->mag[i]); 124 seq_printf(m, " %d", info->mag[i]);
108 len += sprintf(page + len, "\n"); 125 seq_putc(m, '\n');
109#ifdef CONFIG_SCHED_MC 126#ifdef CONFIG_SCHED_MC
110 store_topology(info); 127 store_topology(info);
111 len += sprintf(page + len, "CPU Topology SW: "); 128 seq_printf(m, "CPU Topology SW: ");
112 for (i = 0; i < TOPOLOGY_NR_MAG; i++) 129 for (i = 0; i < TOPOLOGY_NR_MAG; i++)
113 len += sprintf(page + len, " %d", info->mag[i]); 130 seq_printf(m, " %d", info->mag[i]);
114 len += sprintf(page + len, "\n"); 131 seq_putc(m, '\n');
115#endif 132#endif
116 return len;
117} 133}
118 134
119static int stsi_1_2_2(struct sysinfo_1_2_2 *info, char *page, int len) 135static void stsi_1_2_2(struct seq_file *m, struct sysinfo_1_2_2 *info)
120{ 136{
121 struct sysinfo_1_2_2_extension *ext; 137 struct sysinfo_1_2_2_extension *ext;
122 int i; 138 int i;
123 139
124 if (stsi(info, 1, 2, 2) == -ENOSYS) 140 if (stsi(info, 1, 2, 2))
125 return len; 141 return;
126 ext = (struct sysinfo_1_2_2_extension *) 142 ext = (struct sysinfo_1_2_2_extension *)
127 ((unsigned long) info + info->acc_offset); 143 ((unsigned long) info + info->acc_offset);
128 144 seq_printf(m, "CPUs Total: %d\n", info->cpus_total);
129 len += sprintf(page + len, "CPUs Total: %d\n", 145 seq_printf(m, "CPUs Configured: %d\n", info->cpus_configured);
130 info->cpus_total); 146 seq_printf(m, "CPUs Standby: %d\n", info->cpus_standby);
131 len += sprintf(page + len, "CPUs Configured: %d\n", 147 seq_printf(m, "CPUs Reserved: %d\n", info->cpus_reserved);
132 info->cpus_configured); 148 /*
133 len += sprintf(page + len, "CPUs Standby: %d\n", 149 * Sigh 2. According to the specification the alternate
134 info->cpus_standby); 150 * capability field is a 32 bit floating point number
135 len += sprintf(page + len, "CPUs Reserved: %d\n", 151 * if the higher order 8 bits are not zero. Printing
136 info->cpus_reserved); 152 * a floating point number in the kernel is a no-no,
137 153 * always print the number as 32 bit unsigned integer.
138 if (info->format == 1) { 154 * The user-space needs to know about the strange
139 /* 155 * encoding of the alternate cpu capability.
140 * Sigh 2. According to the specification the alternate 156 */
141 * capability field is a 32 bit floating point number 157 seq_printf(m, "Capability: %u", info->capability);
142 * if the higher order 8 bits are not zero. Printing 158 if (info->format == 1)
143 * a floating point number in the kernel is a no-no, 159 seq_printf(m, " %u", ext->alt_capability);
144 * always print the number as 32 bit unsigned integer. 160 seq_putc(m, '\n');
145 * The user-space needs to know about the strange 161 if (info->nominal_cap)
146 * encoding of the alternate cpu capability. 162 seq_printf(m, "Nominal Capability: %d\n", info->nominal_cap);
147 */ 163 if (info->secondary_cap)
148 len += sprintf(page + len, "Capability: %u %u\n", 164 seq_printf(m, "Secondary Capability: %d\n", info->secondary_cap);
149 info->capability, ext->alt_capability); 165 for (i = 2; i <= info->cpus_total; i++) {
150 for (i = 2; i <= info->cpus_total; i++) 166 seq_printf(m, "Adjustment %02d-way: %u",
151 len += sprintf(page + len, 167 i, info->adjustment[i-2]);
152 "Adjustment %02d-way: %u %u\n", 168 if (info->format == 1)
153 i, info->adjustment[i-2], 169 seq_printf(m, " %u", ext->alt_adjustment[i-2]);
154 ext->alt_adjustment[i-2]); 170 seq_putc(m, '\n');
155
156 } else {
157 len += sprintf(page + len, "Capability: %u\n",
158 info->capability);
159 for (i = 2; i <= info->cpus_total; i++)
160 len += sprintf(page + len,
161 "Adjustment %02d-way: %u\n",
162 i, info->adjustment[i-2]);
163 } 171 }
164
165 if (info->secondary_capability != 0)
166 len += sprintf(page + len, "Secondary Capability: %d\n",
167 info->secondary_capability);
168 return len;
169} 172}
170 173
171static int stsi_2_2_2(struct sysinfo_2_2_2 *info, char *page, int len) 174static void stsi_2_2_2(struct seq_file *m, struct sysinfo_2_2_2 *info)
172{ 175{
173 if (stsi(info, 2, 2, 2) == -ENOSYS) 176 if (stsi(info, 2, 2, 2))
174 return len; 177 return;
175
176 EBCASC(info->name, sizeof(info->name)); 178 EBCASC(info->name, sizeof(info->name));
177 179 seq_putc(m, '\n');
178 len += sprintf(page + len, "\n"); 180 seq_printf(m, "LPAR Number: %d\n", info->lpar_number);
179 len += sprintf(page + len, "LPAR Number: %d\n", 181 seq_printf(m, "LPAR Characteristics: ");
180 info->lpar_number);
181
182 len += sprintf(page + len, "LPAR Characteristics: ");
183 if (info->characteristics & LPAR_CHAR_DEDICATED) 182 if (info->characteristics & LPAR_CHAR_DEDICATED)
184 len += sprintf(page + len, "Dedicated "); 183 seq_printf(m, "Dedicated ");
185 if (info->characteristics & LPAR_CHAR_SHARED) 184 if (info->characteristics & LPAR_CHAR_SHARED)
186 len += sprintf(page + len, "Shared "); 185 seq_printf(m, "Shared ");
187 if (info->characteristics & LPAR_CHAR_LIMITED) 186 if (info->characteristics & LPAR_CHAR_LIMITED)
188 len += sprintf(page + len, "Limited "); 187 seq_printf(m, "Limited ");
189 len += sprintf(page + len, "\n"); 188 seq_putc(m, '\n');
190 189 seq_printf(m, "LPAR Name: %-8.8s\n", info->name);
191 len += sprintf(page + len, "LPAR Name: %-8.8s\n", 190 seq_printf(m, "LPAR Adjustment: %d\n", info->caf);
192 info->name); 191 seq_printf(m, "LPAR CPUs Total: %d\n", info->cpus_total);
193 192 seq_printf(m, "LPAR CPUs Configured: %d\n", info->cpus_configured);
194 len += sprintf(page + len, "LPAR Adjustment: %d\n", 193 seq_printf(m, "LPAR CPUs Standby: %d\n", info->cpus_standby);
195 info->caf); 194 seq_printf(m, "LPAR CPUs Reserved: %d\n", info->cpus_reserved);
196 195 seq_printf(m, "LPAR CPUs Dedicated: %d\n", info->cpus_dedicated);
197 len += sprintf(page + len, "LPAR CPUs Total: %d\n", 196 seq_printf(m, "LPAR CPUs Shared: %d\n", info->cpus_shared);
198 info->cpus_total);
199 len += sprintf(page + len, "LPAR CPUs Configured: %d\n",
200 info->cpus_configured);
201 len += sprintf(page + len, "LPAR CPUs Standby: %d\n",
202 info->cpus_standby);
203 len += sprintf(page + len, "LPAR CPUs Reserved: %d\n",
204 info->cpus_reserved);
205 len += sprintf(page + len, "LPAR CPUs Dedicated: %d\n",
206 info->cpus_dedicated);
207 len += sprintf(page + len, "LPAR CPUs Shared: %d\n",
208 info->cpus_shared);
209 return len;
210} 197}
211 198
212static int stsi_3_2_2(struct sysinfo_3_2_2 *info, char *page, int len) 199static void stsi_3_2_2(struct seq_file *m, struct sysinfo_3_2_2 *info)
213{ 200{
214 int i; 201 int i;
215 202
216 if (stsi(info, 3, 2, 2) == -ENOSYS) 203 if (stsi(info, 3, 2, 2))
217 return len; 204 return;
218 for (i = 0; i < info->count; i++) { 205 for (i = 0; i < info->count; i++) {
219 EBCASC(info->vm[i].name, sizeof(info->vm[i].name)); 206 EBCASC(info->vm[i].name, sizeof(info->vm[i].name));
220 EBCASC(info->vm[i].cpi, sizeof(info->vm[i].cpi)); 207 EBCASC(info->vm[i].cpi, sizeof(info->vm[i].cpi));
221 len += sprintf(page + len, "\n"); 208 seq_putc(m, '\n');
222 len += sprintf(page + len, "VM%02d Name: %-8.8s\n", 209 seq_printf(m, "VM%02d Name: %-8.8s\n", i, info->vm[i].name);
223 i, info->vm[i].name); 210 seq_printf(m, "VM%02d Control Program: %-16.16s\n", i, info->vm[i].cpi);
224 len += sprintf(page + len, "VM%02d Control Program: %-16.16s\n", 211 seq_printf(m, "VM%02d Adjustment: %d\n", i, info->vm[i].caf);
225 i, info->vm[i].cpi); 212 seq_printf(m, "VM%02d CPUs Total: %d\n", i, info->vm[i].cpus_total);
226 213 seq_printf(m, "VM%02d CPUs Configured: %d\n", i, info->vm[i].cpus_configured);
227 len += sprintf(page + len, "VM%02d Adjustment: %d\n", 214 seq_printf(m, "VM%02d CPUs Standby: %d\n", i, info->vm[i].cpus_standby);
228 i, info->vm[i].caf); 215 seq_printf(m, "VM%02d CPUs Reserved: %d\n", i, info->vm[i].cpus_reserved);
229
230 len += sprintf(page + len, "VM%02d CPUs Total: %d\n",
231 i, info->vm[i].cpus_total);
232 len += sprintf(page + len, "VM%02d CPUs Configured: %d\n",
233 i, info->vm[i].cpus_configured);
234 len += sprintf(page + len, "VM%02d CPUs Standby: %d\n",
235 i, info->vm[i].cpus_standby);
236 len += sprintf(page + len, "VM%02d CPUs Reserved: %d\n",
237 i, info->vm[i].cpus_reserved);
238 } 216 }
239 return len;
240} 217}
241 218
242static int proc_read_sysinfo(char *page, char **start, 219static int sysinfo_show(struct seq_file *m, void *v)
243 off_t off, int count,
244 int *eof, void *data)
245{ 220{
246 unsigned long info = get_zeroed_page(GFP_KERNEL); 221 void *info = (void *)get_zeroed_page(GFP_KERNEL);
247 int level, len; 222 int level;
248 223
249 if (!info) 224 if (!info)
250 return 0; 225 return 0;
251 226 level = stsi(NULL, 0, 0, 0);
252 len = 0;
253 level = stsi_0();
254 if (level >= 1) 227 if (level >= 1)
255 len = stsi_1_1_1((struct sysinfo_1_1_1 *) info, page, len); 228 stsi_1_1_1(m, info);
256
257 if (level >= 1) 229 if (level >= 1)
258 len = stsi_15_1_x((struct sysinfo_15_1_x *) info, page, len); 230 stsi_15_1_x(m, info);
259
260 if (level >= 1) 231 if (level >= 1)
261 len = stsi_1_2_2((struct sysinfo_1_2_2 *) info, page, len); 232 stsi_1_2_2(m, info);
262
263 if (level >= 2) 233 if (level >= 2)
264 len = stsi_2_2_2((struct sysinfo_2_2_2 *) info, page, len); 234 stsi_2_2_2(m, info);
265
266 if (level >= 3) 235 if (level >= 3)
267 len = stsi_3_2_2((struct sysinfo_3_2_2 *) info, page, len); 236 stsi_3_2_2(m, info);
237 free_page((unsigned long)info);
238 return 0;
239}
268 240
269 free_page(info); 241static int sysinfo_open(struct inode *inode, struct file *file)
270 return len; 242{
243 return single_open(file, sysinfo_show, NULL);
271} 244}
272 245
273static __init int create_proc_sysinfo(void) 246static const struct file_operations sysinfo_fops = {
247 .open = sysinfo_open,
248 .read = seq_read,
249 .llseek = seq_lseek,
250 .release = single_release,
251};
252
253static int __init sysinfo_create_proc(void)
274{ 254{
275 create_proc_read_entry("sysinfo", 0444, NULL, 255 proc_create("sysinfo", 0444, NULL, &sysinfo_fops);
276 proc_read_sysinfo, NULL);
277 return 0; 256 return 0;
278} 257}
279device_initcall(create_proc_sysinfo); 258device_initcall(sysinfo_create_proc);
280 259
281/* 260/*
282 * Service levels interface. 261 * Service levels interface.
@@ -407,7 +386,7 @@ void s390_adjust_jiffies(void)
407 if (!info) 386 if (!info)
408 return; 387 return;
409 388
410 if (stsi(info, 1, 2, 2) != -ENOSYS) { 389 if (stsi(info, 1, 2, 2) == 0) {
411 /* 390 /*
412 * Major sigh. The cpu capability encoding is "special". 391 * Major sigh. The cpu capability encoding is "special".
413 * If the first 9 bits of info->capability are 0 then it 392 * If the first 9 bits of info->capability are 0 then it
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index dcec960fc724..2db1011b8b19 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -329,7 +329,7 @@ static unsigned long clock_sync_flags;
329 * The synchronous get_clock function. It will write the current clock 329 * The synchronous get_clock function. It will write the current clock
330 * value to the clock pointer and return 0 if the clock is in sync with 330 * value to the clock pointer and return 0 if the clock is in sync with
331 * the external time source. If the clock mode is local it will return 331 * the external time source. If the clock mode is local it will return
332 * -ENOSYS and -EAGAIN if the clock is not in sync with the external 332 * -EOPNOTSUPP and -EAGAIN if the clock is not in sync with the external
333 * reference. 333 * reference.
334 */ 334 */
335int get_sync_clock(unsigned long long *clock) 335int get_sync_clock(unsigned long long *clock)
@@ -347,7 +347,7 @@ int get_sync_clock(unsigned long long *clock)
347 return 0; 347 return 0;
348 if (!test_bit(CLOCK_SYNC_HAS_ETR, &clock_sync_flags) && 348 if (!test_bit(CLOCK_SYNC_HAS_ETR, &clock_sync_flags) &&
349 !test_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags)) 349 !test_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags))
350 return -ENOSYS; 350 return -EOPNOTSUPP;
351 if (!test_bit(CLOCK_SYNC_ETR, &clock_sync_flags) && 351 if (!test_bit(CLOCK_SYNC_ETR, &clock_sync_flags) &&
352 !test_bit(CLOCK_SYNC_STP, &clock_sync_flags)) 352 !test_bit(CLOCK_SYNC_STP, &clock_sync_flags))
353 return -EACCES; 353 return -EACCES;
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index 05151e06c388..54d93f4b6818 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -17,6 +17,7 @@
17#include <linux/cpu.h> 17#include <linux/cpu.h>
18#include <linux/smp.h> 18#include <linux/smp.h>
19#include <linux/mm.h> 19#include <linux/mm.h>
20#include <asm/sysinfo.h>
20 21
21#define PTF_HORIZONTAL (0UL) 22#define PTF_HORIZONTAL (0UL)
22#define PTF_VERTICAL (1UL) 23#define PTF_VERTICAL (1UL)
@@ -44,9 +45,6 @@ static struct mask_info book_info;
44cpumask_t cpu_book_map[NR_CPUS]; 45cpumask_t cpu_book_map[NR_CPUS];
45unsigned char cpu_book_id[NR_CPUS]; 46unsigned char cpu_book_id[NR_CPUS];
46 47
47/* smp_cpu_state_mutex must be held when accessing this array */
48int cpu_polarization[NR_CPUS];
49
50static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu) 48static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu)
51{ 49{
52 cpumask_t mask; 50 cpumask_t mask;
@@ -75,10 +73,7 @@ static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu,
75{ 73{
76 unsigned int cpu; 74 unsigned int cpu;
77 75
78 for (cpu = find_first_bit(&tl_cpu->mask[0], TOPOLOGY_CPU_BITS); 76 for_each_set_bit(cpu, &tl_cpu->mask[0], TOPOLOGY_CPU_BITS) {
79 cpu < TOPOLOGY_CPU_BITS;
80 cpu = find_next_bit(&tl_cpu->mask[0], TOPOLOGY_CPU_BITS, cpu + 1))
81 {
82 unsigned int rcpu; 77 unsigned int rcpu;
83 int lcpu; 78 int lcpu;
84 79
@@ -94,7 +89,7 @@ static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu,
94 } else { 89 } else {
95 cpu_core_id[lcpu] = core->id; 90 cpu_core_id[lcpu] = core->id;
96 } 91 }
97 cpu_set_polarization(lcpu, tl_cpu->pp); 92 smp_cpu_set_polarization(lcpu, tl_cpu->pp);
98 } 93 }
99 } 94 }
100 return core; 95 return core;
@@ -201,7 +196,7 @@ static void topology_update_polarization_simple(void)
201 196
202 mutex_lock(&smp_cpu_state_mutex); 197 mutex_lock(&smp_cpu_state_mutex);
203 for_each_possible_cpu(cpu) 198 for_each_possible_cpu(cpu)
204 cpu_set_polarization(cpu, POLARIZATION_HRZ); 199 smp_cpu_set_polarization(cpu, POLARIZATION_HRZ);
205 mutex_unlock(&smp_cpu_state_mutex); 200 mutex_unlock(&smp_cpu_state_mutex);
206} 201}
207 202
@@ -231,7 +226,7 @@ int topology_set_cpu_management(int fc)
231 if (rc) 226 if (rc)
232 return -EBUSY; 227 return -EBUSY;
233 for_each_possible_cpu(cpu) 228 for_each_possible_cpu(cpu)
234 cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); 229 smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
235 return rc; 230 return rc;
236} 231}
237 232
@@ -250,12 +245,10 @@ static void update_cpu_core_map(void)
250 245
251void store_topology(struct sysinfo_15_1_x *info) 246void store_topology(struct sysinfo_15_1_x *info)
252{ 247{
253 int rc; 248 if (topology_max_mnest >= 3)
254 249 stsi(info, 15, 1, 3);
255 rc = stsi(info, 15, 1, 3); 250 else
256 if (rc != -ENOSYS) 251 stsi(info, 15, 1, 2);
257 return;
258 stsi(info, 15, 1, 2);
259} 252}
260 253
261int arch_update_cpu_topology(void) 254int arch_update_cpu_topology(void)
@@ -415,7 +408,7 @@ static ssize_t cpu_polarization_show(struct device *dev,
415 ssize_t count; 408 ssize_t count;
416 409
417 mutex_lock(&smp_cpu_state_mutex); 410 mutex_lock(&smp_cpu_state_mutex);
418 switch (cpu_read_polarization(cpu)) { 411 switch (smp_cpu_get_polarization(cpu)) {
419 case POLARIZATION_HRZ: 412 case POLARIZATION_HRZ:
420 count = sprintf(buf, "horizontal\n"); 413 count = sprintf(buf, "horizontal\n");
421 break; 414 break;
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 01775c04a90e..3d2b0fa37db0 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -57,6 +57,23 @@ static int kstack_depth_to_print = 12;
57static int kstack_depth_to_print = 20; 57static int kstack_depth_to_print = 20;
58#endif /* CONFIG_64BIT */ 58#endif /* CONFIG_64BIT */
59 59
60static inline void __user *get_trap_ip(struct pt_regs *regs)
61{
62#ifdef CONFIG_64BIT
63 unsigned long address;
64
65 if (regs->int_code & 0x200)
66 address = *(unsigned long *)(current->thread.trap_tdb + 24);
67 else
68 address = regs->psw.addr;
69 return (void __user *)
70 ((address - (regs->int_code >> 16)) & PSW_ADDR_INSN);
71#else
72 return (void __user *)
73 ((regs->psw.addr - (regs->int_code >> 16)) & PSW_ADDR_INSN);
74#endif
75}
76
60/* 77/*
61 * For show_trace we have tree different stack to consider: 78 * For show_trace we have tree different stack to consider:
62 * - the panic stack which is used if the kernel stack has overflown 79 * - the panic stack which is used if the kernel stack has overflown
@@ -214,7 +231,6 @@ void show_registers(struct pt_regs *regs)
214 231
215void show_regs(struct pt_regs *regs) 232void show_regs(struct pt_regs *regs)
216{ 233{
217 print_modules();
218 printk("CPU: %d %s %s %.*s\n", 234 printk("CPU: %d %s %s %.*s\n",
219 task_thread_info(current)->cpu, print_tainted(), 235 task_thread_info(current)->cpu, print_tainted(),
220 init_utsname()->release, 236 init_utsname()->release,
@@ -254,6 +270,7 @@ void die(struct pt_regs *regs, const char *str)
254#endif 270#endif
255 printk("\n"); 271 printk("\n");
256 notify_die(DIE_OOPS, str, regs, 0, regs->int_code & 0xffff, SIGSEGV); 272 notify_die(DIE_OOPS, str, regs, 0, regs->int_code & 0xffff, SIGSEGV);
273 print_modules();
257 show_regs(regs); 274 show_regs(regs);
258 bust_spinlocks(0); 275 bust_spinlocks(0);
259 add_taint(TAINT_DIE); 276 add_taint(TAINT_DIE);
@@ -285,12 +302,6 @@ int is_valid_bugaddr(unsigned long addr)
285 return 1; 302 return 1;
286} 303}
287 304
288static inline void __user *get_psw_address(struct pt_regs *regs)
289{
290 return (void __user *)
291 ((regs->psw.addr - (regs->int_code >> 16)) & PSW_ADDR_INSN);
292}
293
294static void __kprobes do_trap(struct pt_regs *regs, 305static void __kprobes do_trap(struct pt_regs *regs,
295 int si_signo, int si_code, char *str) 306 int si_signo, int si_code, char *str)
296{ 307{
@@ -304,14 +315,14 @@ static void __kprobes do_trap(struct pt_regs *regs,
304 info.si_signo = si_signo; 315 info.si_signo = si_signo;
305 info.si_errno = 0; 316 info.si_errno = 0;
306 info.si_code = si_code; 317 info.si_code = si_code;
307 info.si_addr = get_psw_address(regs); 318 info.si_addr = get_trap_ip(regs);
308 force_sig_info(si_signo, &info, current); 319 force_sig_info(si_signo, &info, current);
309 report_user_fault(regs, si_signo); 320 report_user_fault(regs, si_signo);
310 } else { 321 } else {
311 const struct exception_table_entry *fixup; 322 const struct exception_table_entry *fixup;
312 fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); 323 fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
313 if (fixup) 324 if (fixup)
314 regs->psw.addr = fixup->fixup | PSW_ADDR_AMODE; 325 regs->psw.addr = extable_fixup(fixup) | PSW_ADDR_AMODE;
315 else { 326 else {
316 enum bug_trap_type btt; 327 enum bug_trap_type btt;
317 328
@@ -381,6 +392,11 @@ DO_ERROR_INFO(special_op_exception, SIGILL, ILL_ILLOPN,
381DO_ERROR_INFO(translation_exception, SIGILL, ILL_ILLOPN, 392DO_ERROR_INFO(translation_exception, SIGILL, ILL_ILLOPN,
382 "translation exception") 393 "translation exception")
383 394
395#ifdef CONFIG_64BIT
396DO_ERROR_INFO(transaction_exception, SIGILL, ILL_ILLOPN,
397 "transaction constraint exception")
398#endif
399
384static inline void do_fp_trap(struct pt_regs *regs, int fpc) 400static inline void do_fp_trap(struct pt_regs *regs, int fpc)
385{ 401{
386 int si_code = 0; 402 int si_code = 0;
@@ -408,7 +424,7 @@ static void __kprobes illegal_op(struct pt_regs *regs)
408 __u16 __user *location; 424 __u16 __user *location;
409 int signal = 0; 425 int signal = 0;
410 426
411 location = get_psw_address(regs); 427 location = get_trap_ip(regs);
412 428
413 if (user_mode(regs)) { 429 if (user_mode(regs)) {
414 if (get_user(*((__u16 *) opcode), (__u16 __user *) location)) 430 if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
@@ -476,7 +492,7 @@ void specification_exception(struct pt_regs *regs)
476 __u16 __user *location = NULL; 492 __u16 __user *location = NULL;
477 int signal = 0; 493 int signal = 0;
478 494
479 location = (__u16 __user *) get_psw_address(regs); 495 location = (__u16 __user *) get_trap_ip(regs);
480 496
481 if (user_mode(regs)) { 497 if (user_mode(regs)) {
482 get_user(*((__u16 *) opcode), location); 498 get_user(*((__u16 *) opcode), location);
@@ -525,7 +541,7 @@ static void data_exception(struct pt_regs *regs)
525 __u16 __user *location; 541 __u16 __user *location;
526 int signal = 0; 542 int signal = 0;
527 543
528 location = get_psw_address(regs); 544 location = get_trap_ip(regs);
529 545
530 if (MACHINE_HAS_IEEE) 546 if (MACHINE_HAS_IEEE)
531 asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc)); 547 asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc));
@@ -641,6 +657,7 @@ void __init trap_init(void)
641 pgm_check_table[0x12] = &translation_exception; 657 pgm_check_table[0x12] = &translation_exception;
642 pgm_check_table[0x13] = &special_op_exception; 658 pgm_check_table[0x13] = &special_op_exception;
643#ifdef CONFIG_64BIT 659#ifdef CONFIG_64BIT
660 pgm_check_table[0x18] = &transaction_exception;
644 pgm_check_table[0x38] = &do_asce_exception; 661 pgm_check_table[0x38] = &do_asce_exception;
645 pgm_check_table[0x39] = &do_dat_exception; 662 pgm_check_table[0x39] = &do_dat_exception;
646 pgm_check_table[0x3A] = &do_dat_exception; 663 pgm_check_table[0x3A] = &do_dat_exception;
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c
index 9a19ca367c17..d7776281cb60 100644
--- a/arch/s390/kernel/vdso.c
+++ b/arch/s390/kernel/vdso.c
@@ -85,7 +85,7 @@ struct vdso_data *vdso_data = &vdso_data_store.data;
85static void vdso_init_data(struct vdso_data *vd) 85static void vdso_init_data(struct vdso_data *vd)
86{ 86{
87 vd->ectg_available = 87 vd->ectg_available =
88 addressing_mode != HOME_SPACE_MODE && test_facility(31); 88 s390_user_mode != HOME_SPACE_MODE && test_facility(31);
89} 89}
90 90
91#ifdef CONFIG_64BIT 91#ifdef CONFIG_64BIT
@@ -102,7 +102,7 @@ int vdso_alloc_per_cpu(struct _lowcore *lowcore)
102 102
103 lowcore->vdso_per_cpu_data = __LC_PASTE; 103 lowcore->vdso_per_cpu_data = __LC_PASTE;
104 104
105 if (addressing_mode == HOME_SPACE_MODE || !vdso_enabled) 105 if (s390_user_mode == HOME_SPACE_MODE || !vdso_enabled)
106 return 0; 106 return 0;
107 107
108 segment_table = __get_free_pages(GFP_KERNEL, SEGMENT_ORDER); 108 segment_table = __get_free_pages(GFP_KERNEL, SEGMENT_ORDER);
@@ -147,7 +147,7 @@ void vdso_free_per_cpu(struct _lowcore *lowcore)
147 unsigned long segment_table, page_table, page_frame; 147 unsigned long segment_table, page_table, page_frame;
148 u32 *psal, *aste; 148 u32 *psal, *aste;
149 149
150 if (addressing_mode == HOME_SPACE_MODE || !vdso_enabled) 150 if (s390_user_mode == HOME_SPACE_MODE || !vdso_enabled)
151 return; 151 return;
152 152
153 psal = (u32 *)(addr_t) lowcore->paste[4]; 153 psal = (u32 *)(addr_t) lowcore->paste[4];
@@ -165,7 +165,7 @@ static void vdso_init_cr5(void)
165{ 165{
166 unsigned long cr5; 166 unsigned long cr5;
167 167
168 if (addressing_mode == HOME_SPACE_MODE || !vdso_enabled) 168 if (s390_user_mode == HOME_SPACE_MODE || !vdso_enabled)
169 return; 169 return;
170 cr5 = offsetof(struct _lowcore, paste); 170 cr5 = offsetof(struct _lowcore, paste);
171 __ctl_load(cr5, 5, 5); 171 __ctl_load(cr5, 5, 5);
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 4fc97b40a6e1..790334427895 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -99,7 +99,7 @@ static int do_account_vtime(struct task_struct *tsk, int hardirq_offset)
99 return virt_timer_forward(user + system); 99 return virt_timer_forward(user + system);
100} 100}
101 101
102void account_vtime(struct task_struct *prev, struct task_struct *next) 102void vtime_task_switch(struct task_struct *prev)
103{ 103{
104 struct thread_info *ti; 104 struct thread_info *ti;
105 105
@@ -107,7 +107,7 @@ void account_vtime(struct task_struct *prev, struct task_struct *next)
107 ti = task_thread_info(prev); 107 ti = task_thread_info(prev);
108 ti->user_timer = S390_lowcore.user_timer; 108 ti->user_timer = S390_lowcore.user_timer;
109 ti->system_timer = S390_lowcore.system_timer; 109 ti->system_timer = S390_lowcore.system_timer;
110 ti = task_thread_info(next); 110 ti = task_thread_info(current);
111 S390_lowcore.user_timer = ti->user_timer; 111 S390_lowcore.user_timer = ti->user_timer;
112 S390_lowcore.system_timer = ti->system_timer; 112 S390_lowcore.system_timer = ti->system_timer;
113} 113}
@@ -122,7 +122,7 @@ void account_process_tick(struct task_struct *tsk, int user_tick)
122 * Update process times based on virtual cpu times stored by entry.S 122 * Update process times based on virtual cpu times stored by entry.S
123 * to the lowcore fields user_timer, system_timer & steal_clock. 123 * to the lowcore fields user_timer, system_timer & steal_clock.
124 */ 124 */
125void account_system_vtime(struct task_struct *tsk) 125void vtime_account(struct task_struct *tsk)
126{ 126{
127 struct thread_info *ti = task_thread_info(tsk); 127 struct thread_info *ti = task_thread_info(tsk);
128 u64 timer, system; 128 u64 timer, system;
@@ -138,7 +138,7 @@ void account_system_vtime(struct task_struct *tsk)
138 138
139 virt_timer_forward(system); 139 virt_timer_forward(system);
140} 140}
141EXPORT_SYMBOL_GPL(account_system_vtime); 141EXPORT_SYMBOL_GPL(vtime_account);
142 142
143void __kprobes vtime_stop_cpu(void) 143void __kprobes vtime_stop_cpu(void)
144{ 144{
@@ -378,9 +378,8 @@ static int __cpuinit s390_nohz_notify(struct notifier_block *self,
378 long cpu = (long) hcpu; 378 long cpu = (long) hcpu;
379 379
380 idle = &per_cpu(s390_idle, cpu); 380 idle = &per_cpu(s390_idle, cpu);
381 switch (action) { 381 switch (action & ~CPU_TASKS_FROZEN) {
382 case CPU_DYING: 382 case CPU_DYING:
383 case CPU_DYING_FROZEN:
384 idle->nohz_delay = 0; 383 idle->nohz_delay = 0;
385 default: 384 default:
386 break; 385 break;
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
index 78eb9847008f..9b04a32e5695 100644
--- a/arch/s390/kvm/Kconfig
+++ b/arch/s390/kvm/Kconfig
@@ -5,7 +5,7 @@ source "virt/kvm/Kconfig"
5 5
6menuconfig VIRTUALIZATION 6menuconfig VIRTUALIZATION
7 def_bool y 7 def_bool y
8 prompt "Virtualization" 8 prompt "KVM"
9 ---help--- 9 ---help---
10 Say Y here to get to see options for using your Linux host to run other 10 Say Y here to get to see options for using your Linux host to run other
11 operating systems inside virtual machines (guests). 11 operating systems inside virtual machines (guests).
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 60da903d6f3e..310be61bead7 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -211,7 +211,7 @@ static void handle_stsi_3_2_2(struct kvm_vcpu *vcpu, struct sysinfo_3_2_2 *mem)
211 spin_unlock(&fi->lock); 211 spin_unlock(&fi->lock);
212 212
213 /* deal with other level 3 hypervisors */ 213 /* deal with other level 3 hypervisors */
214 if (stsi(mem, 3, 2, 2) == -ENOSYS) 214 if (stsi(mem, 3, 2, 2))
215 mem->count = 0; 215 mem->count = 0;
216 if (mem->count < 8) 216 if (mem->count < 8)
217 mem->count++; 217 mem->count++;
@@ -259,7 +259,7 @@ static int handle_stsi(struct kvm_vcpu *vcpu)
259 mem = get_zeroed_page(GFP_KERNEL); 259 mem = get_zeroed_page(GFP_KERNEL);
260 if (!mem) 260 if (!mem)
261 goto out_fail; 261 goto out_fail;
262 if (stsi((void *) mem, fc, sel1, sel2) == -ENOSYS) 262 if (stsi((void *) mem, fc, sel1, sel2))
263 goto out_mem; 263 goto out_mem;
264 break; 264 break;
265 case 3: 265 case 3:
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index 761ab8b56afc..6ab0d0b5cec8 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -4,6 +4,7 @@
4 4
5lib-y += delay.o string.o uaccess_std.o uaccess_pt.o 5lib-y += delay.o string.o uaccess_std.o uaccess_pt.o
6obj-y += usercopy.o 6obj-y += usercopy.o
7obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o 7obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o mem32.o
8obj-$(CONFIG_64BIT) += mem64.o
8lib-$(CONFIG_64BIT) += uaccess_mvcos.o 9lib-$(CONFIG_64BIT) += uaccess_mvcos.o
9lib-$(CONFIG_SMP) += spinlock.o 10lib-$(CONFIG_SMP) += spinlock.o
diff --git a/arch/s390/lib/mem32.S b/arch/s390/lib/mem32.S
new file mode 100644
index 000000000000..14ca9244b615
--- /dev/null
+++ b/arch/s390/lib/mem32.S
@@ -0,0 +1,92 @@
1/*
2 * String handling functions.
3 *
4 * Copyright IBM Corp. 2012
5 */
6
7#include <linux/linkage.h>
8
9/*
10 * memset implementation
11 *
12 * This code corresponds to the C construct below. We do distinguish
13 * between clearing (c == 0) and setting a memory array (c != 0) simply
14 * because nearly all memset invocations in the kernel clear memory and
15 * the xc instruction is preferred in such cases.
16 *
17 * void *memset(void *s, int c, size_t n)
18 * {
19 * if (likely(c == 0))
20 * return __builtin_memset(s, 0, n);
21 * return __builtin_memset(s, c, n);
22 * }
23 */
24ENTRY(memset)
25 basr %r5,%r0
26.Lmemset_base:
27 ltr %r4,%r4
28 bzr %r14
29 ltr %r3,%r3
30 jnz .Lmemset_fill
31 ahi %r4,-1
32 lr %r3,%r4
33 srl %r3,8
34 ltr %r3,%r3
35 lr %r1,%r2
36 je .Lmemset_clear_rest
37.Lmemset_clear_loop:
38 xc 0(256,%r1),0(%r1)
39 la %r1,256(%r1)
40 brct %r3,.Lmemset_clear_loop
41.Lmemset_clear_rest:
42 ex %r4,.Lmemset_xc-.Lmemset_base(%r5)
43 br %r14
44.Lmemset_fill:
45 stc %r3,0(%r2)
46 chi %r4,1
47 lr %r1,%r2
48 ber %r14
49 ahi %r4,-2
50 lr %r3,%r4
51 srl %r3,8
52 ltr %r3,%r3
53 je .Lmemset_fill_rest
54.Lmemset_fill_loop:
55 mvc 1(256,%r1),0(%r1)
56 la %r1,256(%r1)
57 brct %r3,.Lmemset_fill_loop
58.Lmemset_fill_rest:
59 ex %r4,.Lmemset_mvc-.Lmemset_base(%r5)
60 br %r14
61.Lmemset_xc:
62 xc 0(1,%r1),0(%r1)
63.Lmemset_mvc:
64 mvc 1(1,%r1),0(%r1)
65
66/*
67 * memcpy implementation
68 *
69 * void *memcpy(void *dest, const void *src, size_t n)
70 */
71ENTRY(memcpy)
72 basr %r5,%r0
73.Lmemcpy_base:
74 ltr %r4,%r4
75 bzr %r14
76 ahi %r4,-1
77 lr %r0,%r4
78 srl %r0,8
79 ltr %r0,%r0
80 lr %r1,%r2
81 jnz .Lmemcpy_loop
82.Lmemcpy_rest:
83 ex %r4,.Lmemcpy_mvc-.Lmemcpy_base(%r5)
84 br %r14
85.Lmemcpy_loop:
86 mvc 0(256,%r1),0(%r3)
87 la %r1,256(%r1)
88 la %r3,256(%r3)
89 brct %r0,.Lmemcpy_loop
90 j .Lmemcpy_rest
91.Lmemcpy_mvc:
92 mvc 0(1,%r1),0(%r3)
diff --git a/arch/s390/lib/mem64.S b/arch/s390/lib/mem64.S
new file mode 100644
index 000000000000..c6d553e85ab1
--- /dev/null
+++ b/arch/s390/lib/mem64.S
@@ -0,0 +1,88 @@
1/*
2 * String handling functions.
3 *
4 * Copyright IBM Corp. 2012
5 */
6
7#include <linux/linkage.h>
8
9/*
10 * memset implementation
11 *
12 * This code corresponds to the C construct below. We do distinguish
13 * between clearing (c == 0) and setting a memory array (c != 0) simply
14 * because nearly all memset invocations in the kernel clear memory and
15 * the xc instruction is preferred in such cases.
16 *
17 * void *memset(void *s, int c, size_t n)
18 * {
19 * if (likely(c == 0))
20 * return __builtin_memset(s, 0, n);
21 * return __builtin_memset(s, c, n);
22 * }
23 */
24ENTRY(memset)
25 ltgr %r4,%r4
26 bzr %r14
27 ltgr %r3,%r3
28 jnz .Lmemset_fill
29 aghi %r4,-1
30 srlg %r3,%r4,8
31 ltgr %r3,%r3
32 lgr %r1,%r2
33 jz .Lmemset_clear_rest
34.Lmemset_clear_loop:
35 xc 0(256,%r1),0(%r1)
36 la %r1,256(%r1)
37 brctg %r3,.Lmemset_clear_loop
38.Lmemset_clear_rest:
39 larl %r3,.Lmemset_xc
40 ex %r4,0(%r3)
41 br %r14
42.Lmemset_fill:
43 stc %r3,0(%r2)
44 cghi %r4,1
45 lgr %r1,%r2
46 ber %r14
47 aghi %r4,-2
48 srlg %r3,%r4,8
49 ltgr %r3,%r3
50 jz .Lmemset_fill_rest
51.Lmemset_fill_loop:
52 mvc 1(256,%r1),0(%r1)
53 la %r1,256(%r1)
54 brctg %r3,.Lmemset_fill_loop
55.Lmemset_fill_rest:
56 larl %r3,.Lmemset_mvc
57 ex %r4,0(%r3)
58 br %r14
59.Lmemset_xc:
60 xc 0(1,%r1),0(%r1)
61.Lmemset_mvc:
62 mvc 1(1,%r1),0(%r1)
63
64/*
65 * memcpy implementation
66 *
67 * void *memcpy(void *dest, const void *src, size_t n)
68 */
69ENTRY(memcpy)
70 ltgr %r4,%r4
71 bzr %r14
72 aghi %r4,-1
73 srlg %r5,%r4,8
74 ltgr %r5,%r5
75 lgr %r1,%r2
76 jnz .Lmemcpy_loop
77.Lmemcpy_rest:
78 larl %r5,.Lmemcpy_mvc
79 ex %r4,0(%r5)
80 br %r14
81.Lmemcpy_loop:
82 mvc 0(256,%r1),0(%r3)
83 la %r1,256(%r1)
84 la %r3,256(%r3)
85 brctg %r5,.Lmemcpy_loop
86 j .Lmemcpy_rest
87.Lmemcpy_mvc:
88 mvc 0(1,%r1),0(%r3)
diff --git a/arch/s390/lib/string.c b/arch/s390/lib/string.c
index 846ec64ab2c9..b647d5ff0ad9 100644
--- a/arch/s390/lib/string.c
+++ b/arch/s390/lib/string.c
@@ -43,11 +43,7 @@ static inline char *__strnend(const char *s, size_t n)
43 */ 43 */
44size_t strlen(const char *s) 44size_t strlen(const char *s)
45{ 45{
46#if __GNUC__ < 4
47 return __strend(s) - s; 46 return __strend(s) - s;
48#else
49 return __builtin_strlen(s);
50#endif
51} 47}
52EXPORT_SYMBOL(strlen); 48EXPORT_SYMBOL(strlen);
53 49
@@ -73,7 +69,6 @@ EXPORT_SYMBOL(strnlen);
73 */ 69 */
74char *strcpy(char *dest, const char *src) 70char *strcpy(char *dest, const char *src)
75{ 71{
76#if __GNUC__ < 4
77 register int r0 asm("0") = 0; 72 register int r0 asm("0") = 0;
78 char *ret = dest; 73 char *ret = dest;
79 74
@@ -82,9 +77,6 @@ char *strcpy(char *dest, const char *src)
82 : "+&a" (dest), "+&a" (src) : "d" (r0) 77 : "+&a" (dest), "+&a" (src) : "d" (r0)
83 : "cc", "memory" ); 78 : "cc", "memory" );
84 return ret; 79 return ret;
85#else
86 return __builtin_strcpy(dest, src);
87#endif
88} 80}
89EXPORT_SYMBOL(strcpy); 81EXPORT_SYMBOL(strcpy);
90 82
@@ -106,7 +98,7 @@ size_t strlcpy(char *dest, const char *src, size_t size)
106 if (size) { 98 if (size) {
107 size_t len = (ret >= size) ? size-1 : ret; 99 size_t len = (ret >= size) ? size-1 : ret;
108 dest[len] = '\0'; 100 dest[len] = '\0';
109 __builtin_memcpy(dest, src, len); 101 memcpy(dest, src, len);
110 } 102 }
111 return ret; 103 return ret;
112} 104}
@@ -124,8 +116,8 @@ EXPORT_SYMBOL(strlcpy);
124char *strncpy(char *dest, const char *src, size_t n) 116char *strncpy(char *dest, const char *src, size_t n)
125{ 117{
126 size_t len = __strnend(src, n) - src; 118 size_t len = __strnend(src, n) - src;
127 __builtin_memset(dest + len, 0, n - len); 119 memset(dest + len, 0, n - len);
128 __builtin_memcpy(dest, src, len); 120 memcpy(dest, src, len);
129 return dest; 121 return dest;
130} 122}
131EXPORT_SYMBOL(strncpy); 123EXPORT_SYMBOL(strncpy);
@@ -171,7 +163,7 @@ size_t strlcat(char *dest, const char *src, size_t n)
171 if (len >= n) 163 if (len >= n)
172 len = n - 1; 164 len = n - 1;
173 dest[len] = '\0'; 165 dest[len] = '\0';
174 __builtin_memcpy(dest, src, len); 166 memcpy(dest, src, len);
175 } 167 }
176 return res; 168 return res;
177} 169}
@@ -194,7 +186,7 @@ char *strncat(char *dest, const char *src, size_t n)
194 char *p = __strend(dest); 186 char *p = __strend(dest);
195 187
196 p[len] = '\0'; 188 p[len] = '\0';
197 __builtin_memcpy(p, src, len); 189 memcpy(p, src, len);
198 return dest; 190 return dest;
199} 191}
200EXPORT_SYMBOL(strncat); 192EXPORT_SYMBOL(strncat);
@@ -348,41 +340,3 @@ void *memscan(void *s, int c, size_t n)
348 return (void *) ret; 340 return (void *) ret;
349} 341}
350EXPORT_SYMBOL(memscan); 342EXPORT_SYMBOL(memscan);
351
352/**
353 * memcpy - Copy one area of memory to another
354 * @dest: Where to copy to
355 * @src: Where to copy from
356 * @n: The size of the area.
357 *
358 * returns a pointer to @dest
359 */
360void *memcpy(void *dest, const void *src, size_t n)
361{
362 return __builtin_memcpy(dest, src, n);
363}
364EXPORT_SYMBOL(memcpy);
365
366/**
367 * memset - Fill a region of memory with the given value
368 * @s: Pointer to the start of the area.
369 * @c: The byte to fill the area with
370 * @n: The size of the area.
371 *
372 * returns a pointer to @s
373 */
374void *memset(void *s, int c, size_t n)
375{
376 char *xs;
377
378 if (c == 0)
379 return __builtin_memset(s, 0, n);
380
381 xs = (char *) s;
382 if (n > 0)
383 do {
384 *xs++ = c;
385 } while (--n > 0);
386 return s;
387}
388EXPORT_SYMBOL(memset);
diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c
index 60ee2b883797..2d37bb861faf 100644
--- a/arch/s390/lib/uaccess_pt.c
+++ b/arch/s390/lib/uaccess_pt.c
@@ -2,69 +2,82 @@
2 * User access functions based on page table walks for enhanced 2 * User access functions based on page table walks for enhanced
3 * system layout without hardware support. 3 * system layout without hardware support.
4 * 4 *
5 * Copyright IBM Corp. 2006 5 * Copyright IBM Corp. 2006, 2012
6 * Author(s): Gerald Schaefer (gerald.schaefer@de.ibm.com) 6 * Author(s): Gerald Schaefer (gerald.schaefer@de.ibm.com)
7 */ 7 */
8 8
9#include <linux/errno.h> 9#include <linux/errno.h>
10#include <linux/hardirq.h> 10#include <linux/hardirq.h>
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/hugetlb.h>
12#include <asm/uaccess.h> 13#include <asm/uaccess.h>
13#include <asm/futex.h> 14#include <asm/futex.h>
14#include "uaccess.h" 15#include "uaccess.h"
15 16
16static inline pte_t *follow_table(struct mm_struct *mm, unsigned long addr) 17
18/*
19 * Returns kernel address for user virtual address. If the returned address is
20 * >= -4095 (IS_ERR_VALUE(x) returns true), a fault has occured and the address
21 * contains the (negative) exception code.
22 */
23static __always_inline unsigned long follow_table(struct mm_struct *mm,
24 unsigned long addr, int write)
17{ 25{
18 pgd_t *pgd; 26 pgd_t *pgd;
19 pud_t *pud; 27 pud_t *pud;
20 pmd_t *pmd; 28 pmd_t *pmd;
29 pte_t *ptep;
21 30
22 pgd = pgd_offset(mm, addr); 31 pgd = pgd_offset(mm, addr);
23 if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) 32 if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
24 return (pte_t *) 0x3a; 33 return -0x3aUL;
25 34
26 pud = pud_offset(pgd, addr); 35 pud = pud_offset(pgd, addr);
27 if (pud_none(*pud) || unlikely(pud_bad(*pud))) 36 if (pud_none(*pud) || unlikely(pud_bad(*pud)))
28 return (pte_t *) 0x3b; 37 return -0x3bUL;
29 38
30 pmd = pmd_offset(pud, addr); 39 pmd = pmd_offset(pud, addr);
31 if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) 40 if (pmd_none(*pmd))
32 return (pte_t *) 0x10; 41 return -0x10UL;
42 if (pmd_huge(*pmd)) {
43 if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO))
44 return -0x04UL;
45 return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK);
46 }
47 if (unlikely(pmd_bad(*pmd)))
48 return -0x10UL;
49
50 ptep = pte_offset_map(pmd, addr);
51 if (!pte_present(*ptep))
52 return -0x11UL;
53 if (write && !pte_write(*ptep))
54 return -0x04UL;
33 55
34 return pte_offset_map(pmd, addr); 56 return (pte_val(*ptep) & PAGE_MASK) + (addr & ~PAGE_MASK);
35} 57}
36 58
37static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr, 59static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr,
38 size_t n, int write_user) 60 size_t n, int write_user)
39{ 61{
40 struct mm_struct *mm = current->mm; 62 struct mm_struct *mm = current->mm;
41 unsigned long offset, pfn, done, size; 63 unsigned long offset, done, size, kaddr;
42 pte_t *pte;
43 void *from, *to; 64 void *from, *to;
44 65
45 done = 0; 66 done = 0;
46retry: 67retry:
47 spin_lock(&mm->page_table_lock); 68 spin_lock(&mm->page_table_lock);
48 do { 69 do {
49 pte = follow_table(mm, uaddr); 70 kaddr = follow_table(mm, uaddr, write_user);
50 if ((unsigned long) pte < 0x1000) 71 if (IS_ERR_VALUE(kaddr))
51 goto fault; 72 goto fault;
52 if (!pte_present(*pte)) {
53 pte = (pte_t *) 0x11;
54 goto fault;
55 } else if (write_user && !pte_write(*pte)) {
56 pte = (pte_t *) 0x04;
57 goto fault;
58 }
59 73
60 pfn = pte_pfn(*pte); 74 offset = uaddr & ~PAGE_MASK;
61 offset = uaddr & (PAGE_SIZE - 1);
62 size = min(n - done, PAGE_SIZE - offset); 75 size = min(n - done, PAGE_SIZE - offset);
63 if (write_user) { 76 if (write_user) {
64 to = (void *)((pfn << PAGE_SHIFT) + offset); 77 to = (void *) kaddr;
65 from = kptr + done; 78 from = kptr + done;
66 } else { 79 } else {
67 from = (void *)((pfn << PAGE_SHIFT) + offset); 80 from = (void *) kaddr;
68 to = kptr + done; 81 to = kptr + done;
69 } 82 }
70 memcpy(to, from, size); 83 memcpy(to, from, size);
@@ -75,7 +88,7 @@ retry:
75 return n - done; 88 return n - done;
76fault: 89fault:
77 spin_unlock(&mm->page_table_lock); 90 spin_unlock(&mm->page_table_lock);
78 if (__handle_fault(uaddr, (unsigned long) pte, write_user)) 91 if (__handle_fault(uaddr, -kaddr, write_user))
79 return n - done; 92 return n - done;
80 goto retry; 93 goto retry;
81} 94}
@@ -84,27 +97,22 @@ fault:
84 * Do DAT for user address by page table walk, return kernel address. 97 * Do DAT for user address by page table walk, return kernel address.
85 * This function needs to be called with current->mm->page_table_lock held. 98 * This function needs to be called with current->mm->page_table_lock held.
86 */ 99 */
87static __always_inline unsigned long __dat_user_addr(unsigned long uaddr) 100static __always_inline unsigned long __dat_user_addr(unsigned long uaddr,
101 int write)
88{ 102{
89 struct mm_struct *mm = current->mm; 103 struct mm_struct *mm = current->mm;
90 unsigned long pfn; 104 unsigned long kaddr;
91 pte_t *pte;
92 int rc; 105 int rc;
93 106
94retry: 107retry:
95 pte = follow_table(mm, uaddr); 108 kaddr = follow_table(mm, uaddr, write);
96 if ((unsigned long) pte < 0x1000) 109 if (IS_ERR_VALUE(kaddr))
97 goto fault;
98 if (!pte_present(*pte)) {
99 pte = (pte_t *) 0x11;
100 goto fault; 110 goto fault;
101 }
102 111
103 pfn = pte_pfn(*pte); 112 return kaddr;
104 return (pfn << PAGE_SHIFT) + (uaddr & (PAGE_SIZE - 1));
105fault: 113fault:
106 spin_unlock(&mm->page_table_lock); 114 spin_unlock(&mm->page_table_lock);
107 rc = __handle_fault(uaddr, (unsigned long) pte, 0); 115 rc = __handle_fault(uaddr, -kaddr, write);
108 spin_lock(&mm->page_table_lock); 116 spin_lock(&mm->page_table_lock);
109 if (!rc) 117 if (!rc)
110 goto retry; 118 goto retry;
@@ -159,11 +167,9 @@ static size_t clear_user_pt(size_t n, void __user *to)
159 167
160static size_t strnlen_user_pt(size_t count, const char __user *src) 168static size_t strnlen_user_pt(size_t count, const char __user *src)
161{ 169{
162 char *addr;
163 unsigned long uaddr = (unsigned long) src; 170 unsigned long uaddr = (unsigned long) src;
164 struct mm_struct *mm = current->mm; 171 struct mm_struct *mm = current->mm;
165 unsigned long offset, pfn, done, len; 172 unsigned long offset, done, len, kaddr;
166 pte_t *pte;
167 size_t len_str; 173 size_t len_str;
168 174
169 if (segment_eq(get_fs(), KERNEL_DS)) 175 if (segment_eq(get_fs(), KERNEL_DS))
@@ -172,19 +178,13 @@ static size_t strnlen_user_pt(size_t count, const char __user *src)
172retry: 178retry:
173 spin_lock(&mm->page_table_lock); 179 spin_lock(&mm->page_table_lock);
174 do { 180 do {
175 pte = follow_table(mm, uaddr); 181 kaddr = follow_table(mm, uaddr, 0);
176 if ((unsigned long) pte < 0x1000) 182 if (IS_ERR_VALUE(kaddr))
177 goto fault;
178 if (!pte_present(*pte)) {
179 pte = (pte_t *) 0x11;
180 goto fault; 183 goto fault;
181 }
182 184
183 pfn = pte_pfn(*pte); 185 offset = uaddr & ~PAGE_MASK;
184 offset = uaddr & (PAGE_SIZE-1);
185 addr = (char *)(pfn << PAGE_SHIFT) + offset;
186 len = min(count - done, PAGE_SIZE - offset); 186 len = min(count - done, PAGE_SIZE - offset);
187 len_str = strnlen(addr, len); 187 len_str = strnlen((char *) kaddr, len);
188 done += len_str; 188 done += len_str;
189 uaddr += len_str; 189 uaddr += len_str;
190 } while ((len_str == len) && (done < count)); 190 } while ((len_str == len) && (done < count));
@@ -192,7 +192,7 @@ retry:
192 return done + 1; 192 return done + 1;
193fault: 193fault:
194 spin_unlock(&mm->page_table_lock); 194 spin_unlock(&mm->page_table_lock);
195 if (__handle_fault(uaddr, (unsigned long) pte, 0)) 195 if (__handle_fault(uaddr, -kaddr, 0))
196 return 0; 196 return 0;
197 goto retry; 197 goto retry;
198} 198}
@@ -225,11 +225,10 @@ static size_t copy_in_user_pt(size_t n, void __user *to,
225 const void __user *from) 225 const void __user *from)
226{ 226{
227 struct mm_struct *mm = current->mm; 227 struct mm_struct *mm = current->mm;
228 unsigned long offset_from, offset_to, offset_max, pfn_from, pfn_to, 228 unsigned long offset_max, uaddr, done, size, error_code;
229 uaddr, done, size, error_code;
230 unsigned long uaddr_from = (unsigned long) from; 229 unsigned long uaddr_from = (unsigned long) from;
231 unsigned long uaddr_to = (unsigned long) to; 230 unsigned long uaddr_to = (unsigned long) to;
232 pte_t *pte_from, *pte_to; 231 unsigned long kaddr_to, kaddr_from;
233 int write_user; 232 int write_user;
234 233
235 if (segment_eq(get_fs(), KERNEL_DS)) { 234 if (segment_eq(get_fs(), KERNEL_DS)) {
@@ -242,38 +241,23 @@ retry:
242 do { 241 do {
243 write_user = 0; 242 write_user = 0;
244 uaddr = uaddr_from; 243 uaddr = uaddr_from;
245 pte_from = follow_table(mm, uaddr_from); 244 kaddr_from = follow_table(mm, uaddr_from, 0);
246 error_code = (unsigned long) pte_from; 245 error_code = kaddr_from;
247 if (error_code < 0x1000) 246 if (IS_ERR_VALUE(error_code))
248 goto fault;
249 if (!pte_present(*pte_from)) {
250 error_code = 0x11;
251 goto fault; 247 goto fault;
252 }
253 248
254 write_user = 1; 249 write_user = 1;
255 uaddr = uaddr_to; 250 uaddr = uaddr_to;
256 pte_to = follow_table(mm, uaddr_to); 251 kaddr_to = follow_table(mm, uaddr_to, 1);
257 error_code = (unsigned long) pte_to; 252 error_code = (unsigned long) kaddr_to;
258 if (error_code < 0x1000) 253 if (IS_ERR_VALUE(error_code))
259 goto fault;
260 if (!pte_present(*pte_to)) {
261 error_code = 0x11;
262 goto fault; 254 goto fault;
263 } else if (!pte_write(*pte_to)) {
264 error_code = 0x04;
265 goto fault;
266 }
267 255
268 pfn_from = pte_pfn(*pte_from); 256 offset_max = max(uaddr_from & ~PAGE_MASK,
269 pfn_to = pte_pfn(*pte_to); 257 uaddr_to & ~PAGE_MASK);
270 offset_from = uaddr_from & (PAGE_SIZE-1);
271 offset_to = uaddr_from & (PAGE_SIZE-1);
272 offset_max = max(offset_from, offset_to);
273 size = min(n - done, PAGE_SIZE - offset_max); 258 size = min(n - done, PAGE_SIZE - offset_max);
274 259
275 memcpy((void *)(pfn_to << PAGE_SHIFT) + offset_to, 260 memcpy((void *) kaddr_to, (void *) kaddr_from, size);
276 (void *)(pfn_from << PAGE_SHIFT) + offset_from, size);
277 done += size; 261 done += size;
278 uaddr_from += size; 262 uaddr_from += size;
279 uaddr_to += size; 263 uaddr_to += size;
@@ -282,7 +266,7 @@ retry:
282 return n - done; 266 return n - done;
283fault: 267fault:
284 spin_unlock(&mm->page_table_lock); 268 spin_unlock(&mm->page_table_lock);
285 if (__handle_fault(uaddr, error_code, write_user)) 269 if (__handle_fault(uaddr, -error_code, write_user))
286 return n - done; 270 return n - done;
287 goto retry; 271 goto retry;
288} 272}
@@ -341,7 +325,7 @@ int futex_atomic_op_pt(int op, u32 __user *uaddr, int oparg, int *old)
341 return __futex_atomic_op_pt(op, uaddr, oparg, old); 325 return __futex_atomic_op_pt(op, uaddr, oparg, old);
342 spin_lock(&current->mm->page_table_lock); 326 spin_lock(&current->mm->page_table_lock);
343 uaddr = (u32 __force __user *) 327 uaddr = (u32 __force __user *)
344 __dat_user_addr((__force unsigned long) uaddr); 328 __dat_user_addr((__force unsigned long) uaddr, 1);
345 if (!uaddr) { 329 if (!uaddr) {
346 spin_unlock(&current->mm->page_table_lock); 330 spin_unlock(&current->mm->page_table_lock);
347 return -EFAULT; 331 return -EFAULT;
@@ -378,7 +362,7 @@ int futex_atomic_cmpxchg_pt(u32 *uval, u32 __user *uaddr,
378 return __futex_atomic_cmpxchg_pt(uval, uaddr, oldval, newval); 362 return __futex_atomic_cmpxchg_pt(uval, uaddr, oldval, newval);
379 spin_lock(&current->mm->page_table_lock); 363 spin_lock(&current->mm->page_table_lock);
380 uaddr = (u32 __force __user *) 364 uaddr = (u32 __force __user *)
381 __dat_user_addr((__force unsigned long) uaddr); 365 __dat_user_addr((__force unsigned long) uaddr, 1);
382 if (!uaddr) { 366 if (!uaddr) {
383 spin_unlock(&current->mm->page_table_lock); 367 spin_unlock(&current->mm->page_table_lock);
384 return -EFAULT; 368 return -EFAULT;
diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile
index d98fe9004a52..0f5536b0c1a1 100644
--- a/arch/s390/mm/Makefile
+++ b/arch/s390/mm/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o \ 5obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o \
6 page-states.o gup.o 6 page-states.o gup.o extable.o
7obj-$(CONFIG_CMM) += cmm.o 7obj-$(CONFIG_CMM) += cmm.o
8obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 8obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
9obj-$(CONFIG_DEBUG_SET_MODULE_RONX) += pageattr.o 9obj-$(CONFIG_DEBUG_SET_MODULE_RONX) += pageattr.o
diff --git a/arch/s390/mm/extable.c b/arch/s390/mm/extable.c
new file mode 100644
index 000000000000..4d1ee88864e8
--- /dev/null
+++ b/arch/s390/mm/extable.c
@@ -0,0 +1,81 @@
1#include <linux/module.h>
2#include <linux/sort.h>
3#include <asm/uaccess.h>
4
5/*
6 * Search one exception table for an entry corresponding to the
7 * given instruction address, and return the address of the entry,
8 * or NULL if none is found.
9 * We use a binary search, and thus we assume that the table is
10 * already sorted.
11 */
12const struct exception_table_entry *
13search_extable(const struct exception_table_entry *first,
14 const struct exception_table_entry *last,
15 unsigned long value)
16{
17 const struct exception_table_entry *mid;
18 unsigned long addr;
19
20 while (first <= last) {
21 mid = ((last - first) >> 1) + first;
22 addr = extable_insn(mid);
23 if (addr < value)
24 first = mid + 1;
25 else if (addr > value)
26 last = mid - 1;
27 else
28 return mid;
29 }
30 return NULL;
31}
32
33/*
34 * The exception table needs to be sorted so that the binary
35 * search that we use to find entries in it works properly.
36 * This is used both for the kernel exception table and for
37 * the exception tables of modules that get loaded.
38 *
39 */
40static int cmp_ex(const void *a, const void *b)
41{
42 const struct exception_table_entry *x = a, *y = b;
43
44 /* This compare is only valid after normalization. */
45 return x->insn - y->insn;
46}
47
48void sort_extable(struct exception_table_entry *start,
49 struct exception_table_entry *finish)
50{
51 struct exception_table_entry *p;
52 int i;
53
54 /* Normalize entries to being relative to the start of the section */
55 for (p = start, i = 0; p < finish; p++, i += 8)
56 p->insn += i;
57 sort(start, finish - start, sizeof(*start), cmp_ex, NULL);
58 /* Denormalize all entries */
59 for (p = start, i = 0; p < finish; p++, i += 8)
60 p->insn -= i;
61}
62
63#ifdef CONFIG_MODULES
64/*
65 * If the exception table is sorted, any referring to the module init
66 * will be at the beginning or the end.
67 */
68void trim_init_extable(struct module *m)
69{
70 /* Trim the beginning */
71 while (m->num_exentries &&
72 within_module_init(extable_insn(&m->extable[0]), m)) {
73 m->extable++;
74 m->num_exentries--;
75 }
76 /* Trim the end */
77 while (m->num_exentries &&
78 within_module_init(extable_insn(&m->extable[m->num_exentries-1]), m))
79 m->num_exentries--;
80}
81#endif /* CONFIG_MODULES */
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 6c013f544146..ac9122ca1152 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -111,7 +111,7 @@ static inline int user_space_fault(unsigned long trans_exc_code)
111 if (trans_exc_code == 2) 111 if (trans_exc_code == 2)
112 /* Access via secondary space, set_fs setting decides */ 112 /* Access via secondary space, set_fs setting decides */
113 return current->thread.mm_segment.ar4; 113 return current->thread.mm_segment.ar4;
114 if (addressing_mode == HOME_SPACE_MODE) 114 if (s390_user_mode == HOME_SPACE_MODE)
115 /* User space if the access has been done via home space. */ 115 /* User space if the access has been done via home space. */
116 return trans_exc_code == 3; 116 return trans_exc_code == 3;
117 /* 117 /*
@@ -163,7 +163,7 @@ static noinline void do_no_context(struct pt_regs *regs)
163 /* Are we prepared to handle this kernel fault? */ 163 /* Are we prepared to handle this kernel fault? */
164 fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); 164 fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
165 if (fixup) { 165 if (fixup) {
166 regs->psw.addr = fixup->fixup | PSW_ADDR_AMODE; 166 regs->psw.addr = extable_fixup(fixup) | PSW_ADDR_AMODE;
167 return; 167 return;
168 } 168 }
169 169
@@ -628,9 +628,8 @@ static int __cpuinit pfault_cpu_notify(struct notifier_block *self,
628 struct thread_struct *thread, *next; 628 struct thread_struct *thread, *next;
629 struct task_struct *tsk; 629 struct task_struct *tsk;
630 630
631 switch (action) { 631 switch (action & ~CPU_TASKS_FROZEN) {
632 case CPU_DEAD: 632 case CPU_DEAD:
633 case CPU_DEAD_FROZEN:
634 spin_lock_irq(&pfault_lock); 633 spin_lock_irq(&pfault_lock);
635 list_for_each_entry_safe(thread, next, &pfault_list, list) { 634 list_for_each_entry_safe(thread, next, &pfault_list, list) {
636 thread->pfault_wait = 0; 635 thread->pfault_wait = 0;
diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c
index 65cb06e2af4e..eeaf8023851f 100644
--- a/arch/s390/mm/gup.c
+++ b/arch/s390/mm/gup.c
@@ -154,6 +154,43 @@ static inline int gup_pud_range(pgd_t *pgdp, pgd_t pgd, unsigned long addr,
154 return 1; 154 return 1;
155} 155}
156 156
157/*
158 * Like get_user_pages_fast() except its IRQ-safe in that it won't fall
159 * back to the regular GUP.
160 */
161int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
162 struct page **pages)
163{
164 struct mm_struct *mm = current->mm;
165 unsigned long addr, len, end;
166 unsigned long next, flags;
167 pgd_t *pgdp, pgd;
168 int nr = 0;
169
170 start &= PAGE_MASK;
171 addr = start;
172 len = (unsigned long) nr_pages << PAGE_SHIFT;
173 end = start + len;
174 if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
175 (void __user *)start, len)))
176 return 0;
177
178 local_irq_save(flags);
179 pgdp = pgd_offset(mm, addr);
180 do {
181 pgd = *pgdp;
182 barrier();
183 next = pgd_addr_end(addr, end);
184 if (pgd_none(pgd))
185 break;
186 if (!gup_pud_range(pgdp, pgd, addr, next, write, pages, &nr))
187 break;
188 } while (pgdp++, addr = next, addr != end);
189 local_irq_restore(flags);
190
191 return nr;
192}
193
157/** 194/**
158 * get_user_pages_fast() - pin user pages in memory 195 * get_user_pages_fast() - pin user pages in memory
159 * @start: starting user address 196 * @start: starting user address
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 6adbc082618a..81e596c65dee 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -42,7 +42,7 @@ pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE)));
42unsigned long empty_zero_page, zero_page_mask; 42unsigned long empty_zero_page, zero_page_mask;
43EXPORT_SYMBOL(empty_zero_page); 43EXPORT_SYMBOL(empty_zero_page);
44 44
45static unsigned long setup_zero_pages(void) 45static unsigned long __init setup_zero_pages(void)
46{ 46{
47 struct cpuid cpu_id; 47 struct cpuid cpu_id;
48 unsigned int order; 48 unsigned int order;
@@ -212,7 +212,7 @@ void free_initmem(void)
212} 212}
213 213
214#ifdef CONFIG_BLK_DEV_INITRD 214#ifdef CONFIG_BLK_DEV_INITRD
215void free_initrd_mem(unsigned long start, unsigned long end) 215void __init free_initrd_mem(unsigned long start, unsigned long end)
216{ 216{
217 free_init_pages("initrd memory", start, end); 217 free_init_pages("initrd memory", start, end);
218} 218}
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 18df31d1f2c9..b402991e43d7 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -609,8 +609,8 @@ static inline unsigned int atomic_xor_bits(atomic_t *v, unsigned int bits)
609 */ 609 */
610unsigned long *page_table_alloc(struct mm_struct *mm, unsigned long vmaddr) 610unsigned long *page_table_alloc(struct mm_struct *mm, unsigned long vmaddr)
611{ 611{
612 struct page *page; 612 unsigned long *uninitialized_var(table);
613 unsigned long *table; 613 struct page *uninitialized_var(page);
614 unsigned int mask, bit; 614 unsigned int mask, bit;
615 615
616 if (mm_has_pgste(mm)) 616 if (mm_has_pgste(mm))
@@ -796,7 +796,7 @@ int s390_enable_sie(void)
796 struct mm_struct *mm, *old_mm; 796 struct mm_struct *mm, *old_mm;
797 797
798 /* Do we have switched amode? If no, we cannot do sie */ 798 /* Do we have switched amode? If no, we cannot do sie */
799 if (addressing_mode == HOME_SPACE_MODE) 799 if (s390_user_mode == HOME_SPACE_MODE)
800 return -EINVAL; 800 return -EINVAL;
801 801
802 /* Do we have pgstes? if yes, we are done */ 802 /* Do we have pgstes? if yes, we are done */
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
index 6f896e75ab49..c22abf900c9e 100644
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -107,7 +107,7 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro)
107 pte = mk_pte_phys(address, __pgprot(ro ? _PAGE_RO : 0)); 107 pte = mk_pte_phys(address, __pgprot(ro ? _PAGE_RO : 0));
108 pm_dir = pmd_offset(pu_dir, address); 108 pm_dir = pmd_offset(pu_dir, address);
109 109
110#ifdef CONFIG_64BIT 110#if defined(CONFIG_64BIT) && !defined(CONFIG_DEBUG_PAGEALLOC)
111 if (MACHINE_HAS_HPAGE && !(address & ~HPAGE_MASK) && 111 if (MACHINE_HAS_HPAGE && !(address & ~HPAGE_MASK) &&
112 (address + HPAGE_SIZE <= start + size) && 112 (address + HPAGE_SIZE <= start + size) &&
113 (address >= HPAGE_SIZE)) { 113 (address >= HPAGE_SIZE)) {
diff --git a/arch/s390/net/Makefile b/arch/s390/net/Makefile
new file mode 100644
index 000000000000..90568c33ddb0
--- /dev/null
+++ b/arch/s390/net/Makefile
@@ -0,0 +1,4 @@
1#
2# Arch-specific network modules
3#
4obj-$(CONFIG_BPF_JIT) += bpf_jit.o bpf_jit_comp.o
diff --git a/arch/s390/net/bpf_jit.S b/arch/s390/net/bpf_jit.S
new file mode 100644
index 000000000000..7e45d13816c1
--- /dev/null
+++ b/arch/s390/net/bpf_jit.S
@@ -0,0 +1,130 @@
1/*
2 * BPF Jit compiler for s390, help functions.
3 *
4 * Copyright IBM Corp. 2012
5 *
6 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
7 */
8#include <linux/linkage.h>
9
10/*
11 * Calling convention:
12 * registers %r2, %r6-%r8, %r10-%r11, %r13, %r15 are call saved
13 * %r2: skb pointer
14 * %r3: offset parameter
15 * %r5: BPF A accumulator
16 * %r8: return address
17 * %r9: save register for skb pointer
18 * %r10: skb->data
19 * %r11: skb->len - skb->data_len (headlen)
20 * %r12: BPF X accumulator
21 *
22 * skb_copy_bits takes 4 parameters:
23 * %r2 = skb pointer
24 * %r3 = offset into skb data
25 * %r4 = length to copy
26 * %r5 = pointer to temp buffer
27 */
28#define SKBDATA %r8
29
30 /* A = *(u32 *) (skb->data+K+X) */
31ENTRY(sk_load_word_ind)
32 ar %r3,%r12 # offset += X
33 bmr %r8 # < 0 -> return with cc
34
35 /* A = *(u32 *) (skb->data+K) */
36ENTRY(sk_load_word)
37 llgfr %r1,%r3 # extend offset
38 ahi %r3,4 # offset + 4
39 clr %r11,%r3 # hlen <= offset + 4 ?
40 jl sk_load_word_slow
41 l %r5,0(%r1,%r10) # get word from skb
42 xr %r1,%r1 # set cc to zero
43 br %r8
44
45sk_load_word_slow:
46 lgr %r9,%r2 # save %r2
47 lhi %r4,4 # 4 bytes
48 la %r5,160(%r15) # pointer to temp buffer
49 brasl %r14,skb_copy_bits # get data from skb
50 l %r5,160(%r15) # load result from temp buffer
51 ltgr %r2,%r2 # set cc to (%r2 != 0)
52 lgr %r2,%r9 # restore %r2
53 br %r8
54
55 /* A = *(u16 *) (skb->data+K+X) */
56ENTRY(sk_load_half_ind)
57 ar %r3,%r12 # offset += X
58 bmr %r8 # < 0 -> return with cc
59
60 /* A = *(u16 *) (skb->data+K) */
61ENTRY(sk_load_half)
62 llgfr %r1,%r3 # extend offset
63 ahi %r3,2 # offset + 2
64 clr %r11,%r3 # hlen <= offset + 2 ?
65 jl sk_load_half_slow
66 llgh %r5,0(%r1,%r10) # get half from skb
67 xr %r1,%r1 # set cc to zero
68 br %r8
69
70sk_load_half_slow:
71 lgr %r9,%r2 # save %r2
72 lhi %r4,2 # 2 bytes
73 la %r5,162(%r15) # pointer to temp buffer
74 brasl %r14,skb_copy_bits # get data from skb
75 xc 160(2,%r15),160(%r15)
76 l %r5,160(%r15) # load result from temp buffer
77 ltgr %r2,%r2 # set cc to (%r2 != 0)
78 lgr %r2,%r9 # restore %r2
79 br %r8
80
81 /* A = *(u8 *) (skb->data+K+X) */
82ENTRY(sk_load_byte_ind)
83 ar %r3,%r12 # offset += X
84 bmr %r8 # < 0 -> return with cc
85
86 /* A = *(u8 *) (skb->data+K) */
87ENTRY(sk_load_byte)
88 llgfr %r1,%r3 # extend offset
89 clr %r11,%r3 # hlen < offset ?
90 jle sk_load_byte_slow
91 lhi %r5,0
92 ic %r5,0(%r1,%r10) # get byte from skb
93 xr %r1,%r1 # set cc to zero
94 br %r8
95
96sk_load_byte_slow:
97 lgr %r9,%r2 # save %r2
98 lhi %r4,1 # 1 bytes
99 la %r5,163(%r15) # pointer to temp buffer
100 brasl %r14,skb_copy_bits # get data from skb
101 xc 160(3,%r15),160(%r15)
102 l %r5,160(%r15) # load result from temp buffer
103 ltgr %r2,%r2 # set cc to (%r2 != 0)
104 lgr %r2,%r9 # restore %r2
105 br %r8
106
107 /* A = (*(u8 *)(skb->data+K) & 0xf) << 2 */
108ENTRY(sk_load_byte_msh)
109 llgfr %r1,%r3 # extend offset
110 clr %r11,%r3 # hlen < offset ?
111 jle sk_load_byte_slow
112 lhi %r12,0
113 ic %r12,0(%r1,%r10) # get byte from skb
114 nill %r12,0x0f
115 sll %r12,2
116 xr %r1,%r1 # set cc to zero
117 br %r8
118
119sk_load_byte_msh_slow:
120 lgr %r9,%r2 # save %r2
121 lhi %r4,2 # 2 bytes
122 la %r5,162(%r15) # pointer to temp buffer
123 brasl %r14,skb_copy_bits # get data from skb
124 xc 160(3,%r15),160(%r15)
125 l %r12,160(%r15) # load result from temp buffer
126 nill %r12,0x0f
127 sll %r12,2
128 ltgr %r2,%r2 # set cc to (%r2 != 0)
129 lgr %r2,%r9 # restore %r2
130 br %r8
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
new file mode 100644
index 000000000000..9b355b406afa
--- /dev/null
+++ b/arch/s390/net/bpf_jit_comp.c
@@ -0,0 +1,776 @@
1/*
2 * BPF Jit compiler for s390.
3 *
4 * Copyright IBM Corp. 2012
5 *
6 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
7 */
8#include <linux/moduleloader.h>
9#include <linux/netdevice.h>
10#include <linux/filter.h>
11#include <asm/cacheflush.h>
12#include <asm/processor.h>
13#include <asm/facility.h>
14
15/*
16 * Conventions:
17 * %r2 = skb pointer
18 * %r3 = offset parameter
19 * %r4 = scratch register / length parameter
20 * %r5 = BPF A accumulator
21 * %r8 = return address
22 * %r9 = save register for skb pointer
23 * %r10 = skb->data
24 * %r11 = skb->len - skb->data_len (headlen)
25 * %r12 = BPF X accumulator
26 * %r13 = literal pool pointer
27 * 0(%r15) - 63(%r15) scratch memory array with BPF_MEMWORDS
28 */
29int bpf_jit_enable __read_mostly;
30
31/*
32 * assembly code in arch/x86/net/bpf_jit.S
33 */
34extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[];
35extern u8 sk_load_word_ind[], sk_load_half_ind[], sk_load_byte_ind[];
36
37struct bpf_jit {
38 unsigned int seen;
39 u8 *start;
40 u8 *prg;
41 u8 *mid;
42 u8 *lit;
43 u8 *end;
44 u8 *base_ip;
45 u8 *ret0_ip;
46 u8 *exit_ip;
47 unsigned int off_load_word;
48 unsigned int off_load_half;
49 unsigned int off_load_byte;
50 unsigned int off_load_bmsh;
51 unsigned int off_load_iword;
52 unsigned int off_load_ihalf;
53 unsigned int off_load_ibyte;
54};
55
56#define BPF_SIZE_MAX 4096 /* Max size for program */
57
58#define SEEN_DATAREF 1 /* might call external helpers */
59#define SEEN_XREG 2 /* ebx is used */
60#define SEEN_MEM 4 /* use mem[] for temporary storage */
61#define SEEN_RET0 8 /* pc_ret0 points to a valid return 0 */
62#define SEEN_LITERAL 16 /* code uses literals */
63#define SEEN_LOAD_WORD 32 /* code uses sk_load_word */
64#define SEEN_LOAD_HALF 64 /* code uses sk_load_half */
65#define SEEN_LOAD_BYTE 128 /* code uses sk_load_byte */
66#define SEEN_LOAD_BMSH 256 /* code uses sk_load_byte_msh */
67#define SEEN_LOAD_IWORD 512 /* code uses sk_load_word_ind */
68#define SEEN_LOAD_IHALF 1024 /* code uses sk_load_half_ind */
69#define SEEN_LOAD_IBYTE 2048 /* code uses sk_load_byte_ind */
70
71#define EMIT2(op) \
72({ \
73 if (jit->prg + 2 <= jit->mid) \
74 *(u16 *) jit->prg = op; \
75 jit->prg += 2; \
76})
77
78#define EMIT4(op) \
79({ \
80 if (jit->prg + 4 <= jit->mid) \
81 *(u32 *) jit->prg = op; \
82 jit->prg += 4; \
83})
84
85#define EMIT4_DISP(op, disp) \
86({ \
87 unsigned int __disp = (disp) & 0xfff; \
88 EMIT4(op | __disp); \
89})
90
91#define EMIT4_IMM(op, imm) \
92({ \
93 unsigned int __imm = (imm) & 0xffff; \
94 EMIT4(op | __imm); \
95})
96
97#define EMIT4_PCREL(op, pcrel) \
98({ \
99 long __pcrel = ((pcrel) >> 1) & 0xffff; \
100 EMIT4(op | __pcrel); \
101})
102
103#define EMIT6(op1, op2) \
104({ \
105 if (jit->prg + 6 <= jit->mid) { \
106 *(u32 *) jit->prg = op1; \
107 *(u16 *) (jit->prg + 4) = op2; \
108 } \
109 jit->prg += 6; \
110})
111
112#define EMIT6_DISP(op1, op2, disp) \
113({ \
114 unsigned int __disp = (disp) & 0xfff; \
115 EMIT6(op1 | __disp, op2); \
116})
117
118#define EMIT6_IMM(op, imm) \
119({ \
120 unsigned int __imm = (imm); \
121 EMIT6(op | (__imm >> 16), __imm & 0xffff); \
122})
123
124#define EMIT_CONST(val) \
125({ \
126 unsigned int ret; \
127 ret = (unsigned int) (jit->lit - jit->base_ip); \
128 jit->seen |= SEEN_LITERAL; \
129 if (jit->lit + 4 <= jit->end) \
130 *(u32 *) jit->lit = val; \
131 jit->lit += 4; \
132 ret; \
133})
134
135#define EMIT_FN_CONST(bit, fn) \
136({ \
137 unsigned int ret; \
138 ret = (unsigned int) (jit->lit - jit->base_ip); \
139 if (jit->seen & bit) { \
140 jit->seen |= SEEN_LITERAL; \
141 if (jit->lit + 8 <= jit->end) \
142 *(void **) jit->lit = fn; \
143 jit->lit += 8; \
144 } \
145 ret; \
146})
147
148static void bpf_jit_prologue(struct bpf_jit *jit)
149{
150 /* Save registers and create stack frame if necessary */
151 if (jit->seen & SEEN_DATAREF) {
152 /* stmg %r8,%r15,88(%r15) */
153 EMIT6(0xeb8ff058, 0x0024);
154 /* lgr %r14,%r15 */
155 EMIT4(0xb90400ef);
156 /* ahi %r15,<offset> */
157 EMIT4_IMM(0xa7fa0000, (jit->seen & SEEN_MEM) ? -112 : -80);
158 /* stg %r14,152(%r15) */
159 EMIT6(0xe3e0f098, 0x0024);
160 } else if ((jit->seen & SEEN_XREG) && (jit->seen & SEEN_LITERAL))
161 /* stmg %r12,%r13,120(%r15) */
162 EMIT6(0xebcdf078, 0x0024);
163 else if (jit->seen & SEEN_XREG)
164 /* stg %r12,120(%r15) */
165 EMIT6(0xe3c0f078, 0x0024);
166 else if (jit->seen & SEEN_LITERAL)
167 /* stg %r13,128(%r15) */
168 EMIT6(0xe3d0f080, 0x0024);
169
170 /* Setup literal pool */
171 if (jit->seen & SEEN_LITERAL) {
172 /* basr %r13,0 */
173 EMIT2(0x0dd0);
174 jit->base_ip = jit->prg;
175 }
176 jit->off_load_word = EMIT_FN_CONST(SEEN_LOAD_WORD, sk_load_word);
177 jit->off_load_half = EMIT_FN_CONST(SEEN_LOAD_HALF, sk_load_half);
178 jit->off_load_byte = EMIT_FN_CONST(SEEN_LOAD_BYTE, sk_load_byte);
179 jit->off_load_bmsh = EMIT_FN_CONST(SEEN_LOAD_BMSH, sk_load_byte_msh);
180 jit->off_load_iword = EMIT_FN_CONST(SEEN_LOAD_IWORD, sk_load_word_ind);
181 jit->off_load_ihalf = EMIT_FN_CONST(SEEN_LOAD_IHALF, sk_load_half_ind);
182 jit->off_load_ibyte = EMIT_FN_CONST(SEEN_LOAD_IBYTE, sk_load_byte_ind);
183
184 /* Filter needs to access skb data */
185 if (jit->seen & SEEN_DATAREF) {
186 /* l %r11,<len>(%r2) */
187 EMIT4_DISP(0x58b02000, offsetof(struct sk_buff, len));
188 /* s %r11,<data_len>(%r2) */
189 EMIT4_DISP(0x5bb02000, offsetof(struct sk_buff, data_len));
190 /* lg %r10,<data>(%r2) */
191 EMIT6_DISP(0xe3a02000, 0x0004,
192 offsetof(struct sk_buff, data));
193 }
194}
195
196static void bpf_jit_epilogue(struct bpf_jit *jit)
197{
198 /* Return 0 */
199 if (jit->seen & SEEN_RET0) {
200 jit->ret0_ip = jit->prg;
201 /* lghi %r2,0 */
202 EMIT4(0xa7290000);
203 }
204 jit->exit_ip = jit->prg;
205 /* Restore registers */
206 if (jit->seen & SEEN_DATAREF)
207 /* lmg %r8,%r15,<offset>(%r15) */
208 EMIT6_DISP(0xeb8ff000, 0x0004,
209 (jit->seen & SEEN_MEM) ? 200 : 168);
210 else if ((jit->seen & SEEN_XREG) && (jit->seen & SEEN_LITERAL))
211 /* lmg %r12,%r13,120(%r15) */
212 EMIT6(0xebcdf078, 0x0004);
213 else if (jit->seen & SEEN_XREG)
214 /* lg %r12,120(%r15) */
215 EMIT6(0xe3c0f078, 0x0004);
216 else if (jit->seen & SEEN_LITERAL)
217 /* lg %r13,128(%r15) */
218 EMIT6(0xe3d0f080, 0x0004);
219 /* br %r14 */
220 EMIT2(0x07fe);
221}
222
223/*
224 * make sure we dont leak kernel information to user
225 */
226static void bpf_jit_noleaks(struct bpf_jit *jit, struct sock_filter *filter)
227{
228 /* Clear temporary memory if (seen & SEEN_MEM) */
229 if (jit->seen & SEEN_MEM)
230 /* xc 0(64,%r15),0(%r15) */
231 EMIT6(0xd73ff000, 0xf000);
232 /* Clear X if (seen & SEEN_XREG) */
233 if (jit->seen & SEEN_XREG)
234 /* lhi %r12,0 */
235 EMIT4(0xa7c80000);
236 /* Clear A if the first register does not set it. */
237 switch (filter[0].code) {
238 case BPF_S_LD_W_ABS:
239 case BPF_S_LD_H_ABS:
240 case BPF_S_LD_B_ABS:
241 case BPF_S_LD_W_LEN:
242 case BPF_S_LD_W_IND:
243 case BPF_S_LD_H_IND:
244 case BPF_S_LD_B_IND:
245 case BPF_S_LDX_B_MSH:
246 case BPF_S_LD_IMM:
247 case BPF_S_LD_MEM:
248 case BPF_S_MISC_TXA:
249 case BPF_S_ANC_PROTOCOL:
250 case BPF_S_ANC_PKTTYPE:
251 case BPF_S_ANC_IFINDEX:
252 case BPF_S_ANC_MARK:
253 case BPF_S_ANC_QUEUE:
254 case BPF_S_ANC_HATYPE:
255 case BPF_S_ANC_RXHASH:
256 case BPF_S_ANC_CPU:
257 case BPF_S_RET_K:
258 /* first instruction sets A register */
259 break;
260 default: /* A = 0 */
261 /* lhi %r5,0 */
262 EMIT4(0xa7580000);
263 }
264}
265
266static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter,
267 unsigned int *addrs, int i, int last)
268{
269 unsigned int K;
270 int offset;
271 unsigned int mask;
272
273 K = filter->k;
274 switch (filter->code) {
275 case BPF_S_ALU_ADD_X: /* A += X */
276 jit->seen |= SEEN_XREG;
277 /* ar %r5,%r12 */
278 EMIT2(0x1a5c);
279 break;
280 case BPF_S_ALU_ADD_K: /* A += K */
281 if (!K)
282 break;
283 if (K <= 16383)
284 /* ahi %r5,<K> */
285 EMIT4_IMM(0xa75a0000, K);
286 else if (test_facility(21))
287 /* alfi %r5,<K> */
288 EMIT6_IMM(0xc25b0000, K);
289 else
290 /* a %r5,<d(K)>(%r13) */
291 EMIT4_DISP(0x5a50d000, EMIT_CONST(K));
292 break;
293 case BPF_S_ALU_SUB_X: /* A -= X */
294 jit->seen |= SEEN_XREG;
295 /* sr %r5,%r12 */
296 EMIT2(0x1b5c);
297 break;
298 case BPF_S_ALU_SUB_K: /* A -= K */
299 if (!K)
300 break;
301 if (K <= 16384)
302 /* ahi %r5,-K */
303 EMIT4_IMM(0xa75a0000, -K);
304 else if (test_facility(21))
305 /* alfi %r5,-K */
306 EMIT6_IMM(0xc25b0000, -K);
307 else
308 /* s %r5,<d(K)>(%r13) */
309 EMIT4_DISP(0x5b50d000, EMIT_CONST(K));
310 break;
311 case BPF_S_ALU_MUL_X: /* A *= X */
312 jit->seen |= SEEN_XREG;
313 /* msr %r5,%r12 */
314 EMIT4(0xb252005c);
315 break;
316 case BPF_S_ALU_MUL_K: /* A *= K */
317 if (K <= 16383)
318 /* mhi %r5,K */
319 EMIT4_IMM(0xa75c0000, K);
320 else if (test_facility(34))
321 /* msfi %r5,<K> */
322 EMIT6_IMM(0xc2510000, K);
323 else
324 /* ms %r5,<d(K)>(%r13) */
325 EMIT4_DISP(0x7150d000, EMIT_CONST(K));
326 break;
327 case BPF_S_ALU_DIV_X: /* A /= X */
328 jit->seen |= SEEN_XREG | SEEN_RET0;
329 /* ltr %r12,%r12 */
330 EMIT2(0x12cc);
331 /* jz <ret0> */
332 EMIT4_PCREL(0xa7840000, (jit->ret0_ip - jit->prg));
333 /* lhi %r4,0 */
334 EMIT4(0xa7480000);
335 /* dr %r4,%r12 */
336 EMIT2(0x1d4c);
337 break;
338 case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K) */
339 /* m %r4,<d(K)>(%r13) */
340 EMIT4_DISP(0x5c40d000, EMIT_CONST(K));
341 /* lr %r5,%r4 */
342 EMIT2(0x1854);
343 break;
344 case BPF_S_ALU_AND_X: /* A &= X */
345 jit->seen |= SEEN_XREG;
346 /* nr %r5,%r12 */
347 EMIT2(0x145c);
348 break;
349 case BPF_S_ALU_AND_K: /* A &= K */
350 if (test_facility(21))
351 /* nilf %r5,<K> */
352 EMIT6_IMM(0xc05b0000, K);
353 else
354 /* n %r5,<d(K)>(%r13) */
355 EMIT4_DISP(0x5450d000, EMIT_CONST(K));
356 break;
357 case BPF_S_ALU_OR_X: /* A |= X */
358 jit->seen |= SEEN_XREG;
359 /* or %r5,%r12 */
360 EMIT2(0x165c);
361 break;
362 case BPF_S_ALU_OR_K: /* A |= K */
363 if (test_facility(21))
364 /* oilf %r5,<K> */
365 EMIT6_IMM(0xc05d0000, K);
366 else
367 /* o %r5,<d(K)>(%r13) */
368 EMIT4_DISP(0x5650d000, EMIT_CONST(K));
369 break;
370 case BPF_S_ANC_ALU_XOR_X: /* A ^= X; */
371 jit->seen |= SEEN_XREG;
372 /* xr %r5,%r12 */
373 EMIT2(0x175c);
374 break;
375 case BPF_S_ALU_LSH_X: /* A <<= X; */
376 jit->seen |= SEEN_XREG;
377 /* sll %r5,0(%r12) */
378 EMIT4(0x8950c000);
379 break;
380 case BPF_S_ALU_LSH_K: /* A <<= K */
381 if (K == 0)
382 break;
383 /* sll %r5,K */
384 EMIT4_DISP(0x89500000, K);
385 break;
386 case BPF_S_ALU_RSH_X: /* A >>= X; */
387 jit->seen |= SEEN_XREG;
388 /* srl %r5,0(%r12) */
389 EMIT4(0x8850c000);
390 break;
391 case BPF_S_ALU_RSH_K: /* A >>= K; */
392 if (K == 0)
393 break;
394 /* srl %r5,K */
395 EMIT4_DISP(0x88500000, K);
396 break;
397 case BPF_S_ALU_NEG: /* A = -A */
398 /* lnr %r5,%r5 */
399 EMIT2(0x1155);
400 break;
401 case BPF_S_JMP_JA: /* ip += K */
402 offset = addrs[i + K] + jit->start - jit->prg;
403 EMIT4_PCREL(0xa7f40000, offset);
404 break;
405 case BPF_S_JMP_JGT_K: /* ip += (A > K) ? jt : jf */
406 mask = 0x200000; /* jh */
407 goto kbranch;
408 case BPF_S_JMP_JGE_K: /* ip += (A >= K) ? jt : jf */
409 mask = 0xa00000; /* jhe */
410 goto kbranch;
411 case BPF_S_JMP_JEQ_K: /* ip += (A == K) ? jt : jf */
412 mask = 0x800000; /* je */
413kbranch: /* Emit compare if the branch targets are different */
414 if (filter->jt != filter->jf) {
415 if (K <= 16383)
416 /* chi %r5,<K> */
417 EMIT4_IMM(0xa75e0000, K);
418 else if (test_facility(21))
419 /* clfi %r5,<K> */
420 EMIT6_IMM(0xc25f0000, K);
421 else
422 /* c %r5,<d(K)>(%r13) */
423 EMIT4_DISP(0x5950d000, EMIT_CONST(K));
424 }
425branch: if (filter->jt == filter->jf) {
426 if (filter->jt == 0)
427 break;
428 /* j <jt> */
429 offset = addrs[i + filter->jt] + jit->start - jit->prg;
430 EMIT4_PCREL(0xa7f40000, offset);
431 break;
432 }
433 if (filter->jt != 0) {
434 /* brc <mask>,<jt> */
435 offset = addrs[i + filter->jt] + jit->start - jit->prg;
436 EMIT4_PCREL(0xa7040000 | mask, offset);
437 }
438 if (filter->jf != 0) {
439 /* brc <mask^15>,<jf> */
440 offset = addrs[i + filter->jf] + jit->start - jit->prg;
441 EMIT4_PCREL(0xa7040000 | (mask ^ 0xf00000), offset);
442 }
443 break;
444 case BPF_S_JMP_JSET_K: /* ip += (A & K) ? jt : jf */
445 mask = 0x700000; /* jnz */
446 /* Emit test if the branch targets are different */
447 if (filter->jt != filter->jf) {
448 if (K > 65535) {
449 /* lr %r4,%r5 */
450 EMIT2(0x1845);
451 /* n %r4,<d(K)>(%r13) */
452 EMIT4_DISP(0x5440d000, EMIT_CONST(K));
453 } else
454 /* tmll %r5,K */
455 EMIT4_IMM(0xa7510000, K);
456 }
457 goto branch;
458 case BPF_S_JMP_JGT_X: /* ip += (A > X) ? jt : jf */
459 mask = 0x200000; /* jh */
460 goto xbranch;
461 case BPF_S_JMP_JGE_X: /* ip += (A >= X) ? jt : jf */
462 mask = 0xa00000; /* jhe */
463 goto xbranch;
464 case BPF_S_JMP_JEQ_X: /* ip += (A == X) ? jt : jf */
465 mask = 0x800000; /* je */
466xbranch: /* Emit compare if the branch targets are different */
467 if (filter->jt != filter->jf) {
468 jit->seen |= SEEN_XREG;
469 /* cr %r5,%r12 */
470 EMIT2(0x195c);
471 }
472 goto branch;
473 case BPF_S_JMP_JSET_X: /* ip += (A & X) ? jt : jf */
474 mask = 0x700000; /* jnz */
475 /* Emit test if the branch targets are different */
476 if (filter->jt != filter->jf) {
477 jit->seen |= SEEN_XREG;
478 /* lr %r4,%r5 */
479 EMIT2(0x1845);
480 /* nr %r4,%r12 */
481 EMIT2(0x144c);
482 }
483 goto branch;
484 case BPF_S_LD_W_ABS: /* A = *(u32 *) (skb->data+K) */
485 jit->seen |= SEEN_DATAREF | SEEN_RET0 | SEEN_LOAD_WORD;
486 offset = jit->off_load_word;
487 goto load_abs;
488 case BPF_S_LD_H_ABS: /* A = *(u16 *) (skb->data+K) */
489 jit->seen |= SEEN_DATAREF | SEEN_RET0 | SEEN_LOAD_HALF;
490 offset = jit->off_load_half;
491 goto load_abs;
492 case BPF_S_LD_B_ABS: /* A = *(u8 *) (skb->data+K) */
493 jit->seen |= SEEN_DATAREF | SEEN_RET0 | SEEN_LOAD_BYTE;
494 offset = jit->off_load_byte;
495load_abs: if ((int) K < 0)
496 goto out;
497call_fn: /* lg %r1,<d(function)>(%r13) */
498 EMIT6_DISP(0xe310d000, 0x0004, offset);
499 /* l %r3,<d(K)>(%r13) */
500 EMIT4_DISP(0x5830d000, EMIT_CONST(K));
501 /* basr %r8,%r1 */
502 EMIT2(0x0d81);
503 /* jnz <ret0> */
504 EMIT4_PCREL(0xa7740000, (jit->ret0_ip - jit->prg));
505 break;
506 case BPF_S_LD_W_IND: /* A = *(u32 *) (skb->data+K+X) */
507 jit->seen |= SEEN_DATAREF | SEEN_RET0 | SEEN_LOAD_IWORD;
508 offset = jit->off_load_iword;
509 goto call_fn;
510 case BPF_S_LD_H_IND: /* A = *(u16 *) (skb->data+K+X) */
511 jit->seen |= SEEN_DATAREF | SEEN_RET0 | SEEN_LOAD_IHALF;
512 offset = jit->off_load_ihalf;
513 goto call_fn;
514 case BPF_S_LD_B_IND: /* A = *(u8 *) (skb->data+K+X) */
515 jit->seen |= SEEN_DATAREF | SEEN_RET0 | SEEN_LOAD_IBYTE;
516 offset = jit->off_load_ibyte;
517 goto call_fn;
518 case BPF_S_LDX_B_MSH:
519 /* X = (*(u8 *)(skb->data+K) & 0xf) << 2 */
520 jit->seen |= SEEN_RET0;
521 if ((int) K < 0) {
522 /* j <ret0> */
523 EMIT4_PCREL(0xa7f40000, (jit->ret0_ip - jit->prg));
524 break;
525 }
526 jit->seen |= SEEN_DATAREF | SEEN_LOAD_BMSH;
527 offset = jit->off_load_bmsh;
528 goto call_fn;
529 case BPF_S_LD_W_LEN: /* A = skb->len; */
530 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
531 /* l %r5,<d(len)>(%r2) */
532 EMIT4_DISP(0x58502000, offsetof(struct sk_buff, len));
533 break;
534 case BPF_S_LDX_W_LEN: /* X = skb->len; */
535 jit->seen |= SEEN_XREG;
536 /* l %r12,<d(len)>(%r2) */
537 EMIT4_DISP(0x58c02000, offsetof(struct sk_buff, len));
538 break;
539 case BPF_S_LD_IMM: /* A = K */
540 if (K <= 16383)
541 /* lhi %r5,K */
542 EMIT4_IMM(0xa7580000, K);
543 else if (test_facility(21))
544 /* llilf %r5,<K> */
545 EMIT6_IMM(0xc05f0000, K);
546 else
547 /* l %r5,<d(K)>(%r13) */
548 EMIT4_DISP(0x5850d000, EMIT_CONST(K));
549 break;
550 case BPF_S_LDX_IMM: /* X = K */
551 jit->seen |= SEEN_XREG;
552 if (K <= 16383)
553 /* lhi %r12,<K> */
554 EMIT4_IMM(0xa7c80000, K);
555 else if (test_facility(21))
556 /* llilf %r12,<K> */
557 EMIT6_IMM(0xc0cf0000, K);
558 else
559 /* l %r12,<d(K)>(%r13) */
560 EMIT4_DISP(0x58c0d000, EMIT_CONST(K));
561 break;
562 case BPF_S_LD_MEM: /* A = mem[K] */
563 jit->seen |= SEEN_MEM;
564 /* l %r5,<K>(%r15) */
565 EMIT4_DISP(0x5850f000,
566 (jit->seen & SEEN_DATAREF) ? 160 + K*4 : K*4);
567 break;
568 case BPF_S_LDX_MEM: /* X = mem[K] */
569 jit->seen |= SEEN_XREG | SEEN_MEM;
570 /* l %r12,<K>(%r15) */
571 EMIT4_DISP(0x58c0f000,
572 (jit->seen & SEEN_DATAREF) ? 160 + K*4 : K*4);
573 break;
574 case BPF_S_MISC_TAX: /* X = A */
575 jit->seen |= SEEN_XREG;
576 /* lr %r12,%r5 */
577 EMIT2(0x18c5);
578 break;
579 case BPF_S_MISC_TXA: /* A = X */
580 jit->seen |= SEEN_XREG;
581 /* lr %r5,%r12 */
582 EMIT2(0x185c);
583 break;
584 case BPF_S_RET_K:
585 if (K == 0) {
586 jit->seen |= SEEN_RET0;
587 if (last)
588 break;
589 /* j <ret0> */
590 EMIT4_PCREL(0xa7f40000, jit->ret0_ip - jit->prg);
591 } else {
592 if (K <= 16383)
593 /* lghi %r2,K */
594 EMIT4_IMM(0xa7290000, K);
595 else
596 /* llgf %r2,<K>(%r13) */
597 EMIT6_DISP(0xe320d000, 0x0016, EMIT_CONST(K));
598 /* j <exit> */
599 if (last && !(jit->seen & SEEN_RET0))
600 break;
601 EMIT4_PCREL(0xa7f40000, jit->exit_ip - jit->prg);
602 }
603 break;
604 case BPF_S_RET_A:
605 /* llgfr %r2,%r5 */
606 EMIT4(0xb9160025);
607 /* j <exit> */
608 EMIT4_PCREL(0xa7f40000, jit->exit_ip - jit->prg);
609 break;
610 case BPF_S_ST: /* mem[K] = A */
611 jit->seen |= SEEN_MEM;
612 /* st %r5,<K>(%r15) */
613 EMIT4_DISP(0x5050f000,
614 (jit->seen & SEEN_DATAREF) ? 160 + K*4 : K*4);
615 break;
616 case BPF_S_STX: /* mem[K] = X : mov %ebx,off8(%rbp) */
617 jit->seen |= SEEN_XREG | SEEN_MEM;
618 /* st %r12,<K>(%r15) */
619 EMIT4_DISP(0x50c0f000,
620 (jit->seen & SEEN_DATAREF) ? 160 + K*4 : K*4);
621 break;
622 case BPF_S_ANC_PROTOCOL: /* A = ntohs(skb->protocol); */
623 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, protocol) != 2);
624 /* lhi %r5,0 */
625 EMIT4(0xa7580000);
626 /* icm %r5,3,<d(protocol)>(%r2) */
627 EMIT4_DISP(0xbf532000, offsetof(struct sk_buff, protocol));
628 break;
629 case BPF_S_ANC_IFINDEX: /* if (!skb->dev) return 0;
630 * A = skb->dev->ifindex */
631 BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, ifindex) != 4);
632 jit->seen |= SEEN_RET0;
633 /* lg %r1,<d(dev)>(%r2) */
634 EMIT6_DISP(0xe3102000, 0x0004, offsetof(struct sk_buff, dev));
635 /* ltgr %r1,%r1 */
636 EMIT4(0xb9020011);
637 /* jz <ret0> */
638 EMIT4_PCREL(0xa7840000, jit->ret0_ip - jit->prg);
639 /* l %r5,<d(ifindex)>(%r1) */
640 EMIT4_DISP(0x58501000, offsetof(struct net_device, ifindex));
641 break;
642 case BPF_S_ANC_MARK: /* A = skb->mark */
643 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4);
644 /* l %r5,<d(mark)>(%r2) */
645 EMIT4_DISP(0x58502000, offsetof(struct sk_buff, mark));
646 break;
647 case BPF_S_ANC_QUEUE: /* A = skb->queue_mapping */
648 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, queue_mapping) != 2);
649 /* lhi %r5,0 */
650 EMIT4(0xa7580000);
651 /* icm %r5,3,<d(queue_mapping)>(%r2) */
652 EMIT4_DISP(0xbf532000, offsetof(struct sk_buff, queue_mapping));
653 break;
654 case BPF_S_ANC_HATYPE: /* if (!skb->dev) return 0;
655 * A = skb->dev->type */
656 BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, type) != 2);
657 jit->seen |= SEEN_RET0;
658 /* lg %r1,<d(dev)>(%r2) */
659 EMIT6_DISP(0xe3102000, 0x0004, offsetof(struct sk_buff, dev));
660 /* ltgr %r1,%r1 */
661 EMIT4(0xb9020011);
662 /* jz <ret0> */
663 EMIT4_PCREL(0xa7840000, jit->ret0_ip - jit->prg);
664 /* lhi %r5,0 */
665 EMIT4(0xa7580000);
666 /* icm %r5,3,<d(type)>(%r1) */
667 EMIT4_DISP(0xbf531000, offsetof(struct net_device, type));
668 break;
669 case BPF_S_ANC_RXHASH: /* A = skb->rxhash */
670 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4);
671 /* l %r5,<d(rxhash)>(%r2) */
672 EMIT4_DISP(0x58502000, offsetof(struct sk_buff, rxhash));
673 break;
674 case BPF_S_ANC_CPU: /* A = smp_processor_id() */
675#ifdef CONFIG_SMP
676 /* l %r5,<d(cpu_nr)> */
677 EMIT4_DISP(0x58500000, offsetof(struct _lowcore, cpu_nr));
678#else
679 /* lhi %r5,0 */
680 EMIT4(0xa7580000);
681#endif
682 break;
683 default: /* too complex, give up */
684 goto out;
685 }
686 addrs[i] = jit->prg - jit->start;
687 return 0;
688out:
689 return -1;
690}
691
692void bpf_jit_compile(struct sk_filter *fp)
693{
694 unsigned long size, prg_len, lit_len;
695 struct bpf_jit jit, cjit;
696 unsigned int *addrs;
697 int pass, i;
698
699 if (!bpf_jit_enable)
700 return;
701 addrs = kmalloc(fp->len * sizeof(*addrs), GFP_KERNEL);
702 if (addrs == NULL)
703 return;
704 memset(addrs, 0, fp->len * sizeof(*addrs));
705 memset(&jit, 0, sizeof(cjit));
706 memset(&cjit, 0, sizeof(cjit));
707
708 for (pass = 0; pass < 10; pass++) {
709 jit.prg = jit.start;
710 jit.lit = jit.mid;
711
712 bpf_jit_prologue(&jit);
713 bpf_jit_noleaks(&jit, fp->insns);
714 for (i = 0; i < fp->len; i++) {
715 if (bpf_jit_insn(&jit, fp->insns + i, addrs, i,
716 i == fp->len - 1))
717 goto out;
718 }
719 bpf_jit_epilogue(&jit);
720 if (jit.start) {
721 WARN_ON(jit.prg > cjit.prg || jit.lit > cjit.lit);
722 if (memcmp(&jit, &cjit, sizeof(jit)) == 0)
723 break;
724 } else if (jit.prg == cjit.prg && jit.lit == cjit.lit) {
725 prg_len = jit.prg - jit.start;
726 lit_len = jit.lit - jit.mid;
727 size = max_t(unsigned long, prg_len + lit_len,
728 sizeof(struct work_struct));
729 if (size >= BPF_SIZE_MAX)
730 goto out;
731 jit.start = module_alloc(size);
732 if (!jit.start)
733 goto out;
734 jit.prg = jit.mid = jit.start + prg_len;
735 jit.lit = jit.end = jit.start + prg_len + lit_len;
736 jit.base_ip += (unsigned long) jit.start;
737 jit.exit_ip += (unsigned long) jit.start;
738 jit.ret0_ip += (unsigned long) jit.start;
739 }
740 cjit = jit;
741 }
742 if (bpf_jit_enable > 1) {
743 pr_err("flen=%d proglen=%lu pass=%d image=%p\n",
744 fp->len, jit.end - jit.start, pass, jit.start);
745 if (jit.start) {
746 printk(KERN_ERR "JIT code:\n");
747 print_fn_code(jit.start, jit.mid - jit.start);
748 print_hex_dump(KERN_ERR, "JIT literals:\n",
749 DUMP_PREFIX_ADDRESS, 16, 1,
750 jit.mid, jit.end - jit.mid, false);
751 }
752 }
753 if (jit.start)
754 fp->bpf_func = (void *) jit.start;
755out:
756 kfree(addrs);
757}
758
759static void jit_free_defer(struct work_struct *arg)
760{
761 module_free(NULL, arg);
762}
763
764/* run from softirq, we must use a work_struct to call
765 * module_free() from process context
766 */
767void bpf_jit_free(struct sk_filter *fp)
768{
769 struct work_struct *work;
770
771 if (fp->bpf_func == sk_run_filter)
772 return;
773 work = (struct work_struct *)fp->bpf_func;
774 INIT_WORK(work, jit_free_defer);
775 schedule_work(work);
776}
diff --git a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c
index a1e9d69a9c90..584b93674ea4 100644
--- a/arch/s390/oprofile/init.c
+++ b/arch/s390/oprofile/init.c
@@ -169,7 +169,7 @@ static ssize_t hw_interval_write(struct file *file, char const __user *buf,
169 if (*offset) 169 if (*offset)
170 return -EINVAL; 170 return -EINVAL;
171 retval = oprofilefs_ulong_from_user(&val, buf, count); 171 retval = oprofilefs_ulong_from_user(&val, buf, count);
172 if (retval) 172 if (retval <= 0)
173 return retval; 173 return retval;
174 if (val < oprofile_min_interval) 174 if (val < oprofile_min_interval)
175 oprofile_hw_interval = oprofile_min_interval; 175 oprofile_hw_interval = oprofile_min_interval;
@@ -212,7 +212,7 @@ static ssize_t hwsampler_zero_write(struct file *file, char const __user *buf,
212 return -EINVAL; 212 return -EINVAL;
213 213
214 retval = oprofilefs_ulong_from_user(&val, buf, count); 214 retval = oprofilefs_ulong_from_user(&val, buf, count);
215 if (retval) 215 if (retval <= 0)
216 return retval; 216 return retval;
217 if (val != 0) 217 if (val != 0)
218 return -EINVAL; 218 return -EINVAL;
@@ -243,7 +243,7 @@ static ssize_t hwsampler_kernel_write(struct file *file, char const __user *buf,
243 return -EINVAL; 243 return -EINVAL;
244 244
245 retval = oprofilefs_ulong_from_user(&val, buf, count); 245 retval = oprofilefs_ulong_from_user(&val, buf, count);
246 if (retval) 246 if (retval <= 0)
247 return retval; 247 return retval;
248 248
249 if (val != 0 && val != 1) 249 if (val != 0 && val != 1)
@@ -278,7 +278,7 @@ static ssize_t hwsampler_user_write(struct file *file, char const __user *buf,
278 return -EINVAL; 278 return -EINVAL;
279 279
280 retval = oprofilefs_ulong_from_user(&val, buf, count); 280 retval = oprofilefs_ulong_from_user(&val, buf, count);
281 if (retval) 281 if (retval <= 0)
282 return retval; 282 return retval;
283 283
284 if (val != 0 && val != 1) 284 if (val != 0 && val != 1)
@@ -317,7 +317,7 @@ static ssize_t timer_enabled_write(struct file *file, char const __user *buf,
317 return -EINVAL; 317 return -EINVAL;
318 318
319 retval = oprofilefs_ulong_from_user(&val, buf, count); 319 retval = oprofilefs_ulong_from_user(&val, buf, count);
320 if (retval) 320 if (retval <= 0)
321 return retval; 321 return retval;
322 322
323 if (val != 0 && val != 1) 323 if (val != 0 && val != 1)
diff --git a/arch/score/kernel/process.c b/arch/score/kernel/process.c
index 2707023c7563..637970cfd3f4 100644
--- a/arch/score/kernel/process.c
+++ b/arch/score/kernel/process.c
@@ -27,6 +27,7 @@
27#include <linux/reboot.h> 27#include <linux/reboot.h>
28#include <linux/elfcore.h> 28#include <linux/elfcore.h>
29#include <linux/pm.h> 29#include <linux/pm.h>
30#include <linux/rcupdate.h>
30 31
31void (*pm_power_off)(void); 32void (*pm_power_off)(void);
32EXPORT_SYMBOL(pm_power_off); 33EXPORT_SYMBOL(pm_power_off);
@@ -50,9 +51,10 @@ void __noreturn cpu_idle(void)
50{ 51{
51 /* endless idle loop with no priority at all */ 52 /* endless idle loop with no priority at all */
52 while (1) { 53 while (1) {
54 rcu_idle_enter();
53 while (!need_resched()) 55 while (!need_resched())
54 barrier(); 56 barrier();
55 57 rcu_idle_exit();
56 schedule_preempt_disabled(); 58 schedule_preempt_disabled();
57 } 59 }
58} 60}
diff --git a/arch/sh/kernel/cpu/sh5/entry.S b/arch/sh/kernel/cpu/sh5/entry.S
index b7cf6a547f11..7e605b95592a 100644
--- a/arch/sh/kernel/cpu/sh5/entry.S
+++ b/arch/sh/kernel/cpu/sh5/entry.S
@@ -933,7 +933,7 @@ ret_with_reschedule:
933 933
934 pta restore_all, tr1 934 pta restore_all, tr1
935 935
936 movi _TIF_SIGPENDING, r8 936 movi (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), r8
937 and r8, r7, r8 937 and r8, r7, r8
938 pta work_notifysig, tr0 938 pta work_notifysig, tr0
939 bne r8, ZERO, tr0 939 bne r8, ZERO, tr0
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index f67601cb3f1f..b96489d8b27d 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -139,7 +139,7 @@ work_pending:
139 ! r8: current_thread_info 139 ! r8: current_thread_info
140 ! t: result of "tst #_TIF_NEED_RESCHED, r0" 140 ! t: result of "tst #_TIF_NEED_RESCHED, r0"
141 bf/s work_resched 141 bf/s work_resched
142 tst #_TIF_SIGPENDING, r0 142 tst #(_TIF_SIGPENDING | _TIF_NOTIFY_RESUME), r0
143work_notifysig: 143work_notifysig:
144 bt/s __restore_all 144 bt/s __restore_all
145 mov r15, r4 145 mov r15, r4
diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c
index 15e0a1693976..f1ddc0d23679 100644
--- a/arch/sparc/kernel/module.c
+++ b/arch/sparc/kernel/module.c
@@ -48,9 +48,7 @@ void *module_alloc(unsigned long size)
48 return NULL; 48 return NULL;
49 49
50 ret = module_map(size); 50 ret = module_map(size);
51 if (!ret) 51 if (ret)
52 ret = ERR_PTR(-ENOMEM);
53 else
54 memset(ret, 0, size); 52 memset(ret, 0, size);
55 53
56 return ret; 54 return ret;
@@ -116,6 +114,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
116 v = sym->st_value + rel[i].r_addend; 114 v = sym->st_value + rel[i].r_addend;
117 115
118 switch (ELF_R_TYPE(rel[i].r_info) & 0xff) { 116 switch (ELF_R_TYPE(rel[i].r_info) & 0xff) {
117 case R_SPARC_DISP32:
118 v -= (Elf_Addr) location;
119 *loc32 = v;
120 break;
119#ifdef CONFIG_SPARC64 121#ifdef CONFIG_SPARC64
120 case R_SPARC_64: 122 case R_SPARC_64:
121 location[0] = v >> 56; 123 location[0] = v >> 56;
@@ -128,11 +130,6 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
128 location[7] = v >> 0; 130 location[7] = v >> 0;
129 break; 131 break;
130 132
131 case R_SPARC_DISP32:
132 v -= (Elf_Addr) location;
133 *loc32 = v;
134 break;
135
136 case R_SPARC_WDISP19: 133 case R_SPARC_WDISP19:
137 v -= (Elf_Addr) location; 134 v -= (Elf_Addr) location;
138 *loc32 = (*loc32 & ~0x7ffff) | 135 *loc32 = (*loc32 & ~0x7ffff) |
diff --git a/arch/tile/include/asm/topology.h b/arch/tile/include/asm/topology.h
index 7a7ce390534f..d5e86c9f74fd 100644
--- a/arch/tile/include/asm/topology.h
+++ b/arch/tile/include/asm/topology.h
@@ -69,7 +69,6 @@ static inline const struct cpumask *cpumask_of_node(int node)
69 | 1*SD_BALANCE_FORK \ 69 | 1*SD_BALANCE_FORK \
70 | 0*SD_BALANCE_WAKE \ 70 | 0*SD_BALANCE_WAKE \
71 | 0*SD_WAKE_AFFINE \ 71 | 0*SD_WAKE_AFFINE \
72 | 0*SD_PREFER_LOCAL \
73 | 0*SD_SHARE_CPUPOWER \ 72 | 0*SD_SHARE_CPUPOWER \
74 | 0*SD_SHARE_PKG_RESOURCES \ 73 | 0*SD_SHARE_PKG_RESOURCES \
75 | 0*SD_SERIALIZE \ 74 | 0*SD_SERIALIZE \
diff --git a/arch/tile/include/gxio/iorpc_trio.h b/arch/tile/include/gxio/iorpc_trio.h
index 15fb77992083..58105c31228b 100644
--- a/arch/tile/include/gxio/iorpc_trio.h
+++ b/arch/tile/include/gxio/iorpc_trio.h
@@ -25,21 +25,23 @@
25#include <linux/module.h> 25#include <linux/module.h>
26#include <asm/pgtable.h> 26#include <asm/pgtable.h>
27 27
28#define GXIO_TRIO_OP_ALLOC_ASIDS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1400) 28#define GXIO_TRIO_OP_DEALLOC_ASID IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1400)
29#define GXIO_TRIO_OP_ALLOC_ASIDS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1401)
29 30
30#define GXIO_TRIO_OP_ALLOC_MEMORY_MAPS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1402) 31#define GXIO_TRIO_OP_ALLOC_MEMORY_MAPS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1404)
31 32
32#define GXIO_TRIO_OP_ALLOC_PIO_REGIONS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x140e) 33#define GXIO_TRIO_OP_ALLOC_PIO_REGIONS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1412)
33#define GXIO_TRIO_OP_INIT_PIO_REGION_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x140f)
34 34
35#define GXIO_TRIO_OP_INIT_MEMORY_MAP_MMU_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1417) 35#define GXIO_TRIO_OP_INIT_PIO_REGION_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1414)
36#define GXIO_TRIO_OP_GET_PORT_PROPERTY IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1418)
37#define GXIO_TRIO_OP_CONFIG_LEGACY_INTR IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x1419)
38#define GXIO_TRIO_OP_CONFIG_MSI_INTR IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x141a)
39 36
40#define GXIO_TRIO_OP_SET_MPS_MRS IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141c) 37#define GXIO_TRIO_OP_INIT_MEMORY_MAP_MMU_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141e)
41#define GXIO_TRIO_OP_FORCE_RC_LINK_UP IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141d) 38#define GXIO_TRIO_OP_GET_PORT_PROPERTY IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141f)
42#define GXIO_TRIO_OP_FORCE_EP_LINK_UP IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141e) 39#define GXIO_TRIO_OP_CONFIG_LEGACY_INTR IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x1420)
40#define GXIO_TRIO_OP_CONFIG_MSI_INTR IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x1421)
41
42#define GXIO_TRIO_OP_SET_MPS_MRS IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1423)
43#define GXIO_TRIO_OP_FORCE_RC_LINK_UP IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1424)
44#define GXIO_TRIO_OP_FORCE_EP_LINK_UP IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1425)
43#define GXIO_TRIO_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000) 45#define GXIO_TRIO_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
44#define GXIO_TRIO_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001) 46#define GXIO_TRIO_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001)
45 47
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 664a60e8dfb4..c17de0db6736 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -705,6 +705,7 @@ static void stack_proc(void *arg)
705 struct task_struct *from = current, *to = arg; 705 struct task_struct *from = current, *to = arg;
706 706
707 to->thread.saved_task = from; 707 to->thread.saved_task = from;
708 rcu_switch(from, to);
708 switch_to(from, to, from); 709 switch_to(from, to, from);
709} 710}
710 711
diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h
index 69f1c57a8d0d..33a6a2423bd2 100644
--- a/arch/um/include/asm/processor-generic.h
+++ b/arch/um/include/asm/processor-generic.h
@@ -20,14 +20,6 @@ struct mm_struct;
20 20
21struct thread_struct { 21struct thread_struct {
22 struct task_struct *saved_task; 22 struct task_struct *saved_task;
23 /*
24 * This flag is set to 1 before calling do_fork (and analyzed in
25 * copy_thread) to mark that we are begin called from userspace (fork /
26 * vfork / clone), and reset to 0 after. It is left to 0 when called
27 * from kernelspace (i.e. kernel_thread() or fork_idle(),
28 * as of 2.6.11).
29 */
30 int forking;
31 struct pt_regs regs; 23 struct pt_regs regs;
32 int singlestep_syscall; 24 int singlestep_syscall;
33 void *fault_addr; 25 void *fault_addr;
@@ -58,7 +50,6 @@ struct thread_struct {
58 50
59#define INIT_THREAD \ 51#define INIT_THREAD \
60{ \ 52{ \
61 .forking = 0, \
62 .regs = EMPTY_REGS, \ 53 .regs = EMPTY_REGS, \
63 .fault_addr = NULL, \ 54 .fault_addr = NULL, \
64 .prev_sched = NULL, \ 55 .prev_sched = NULL, \
diff --git a/arch/um/include/shared/common-offsets.h b/arch/um/include/shared/common-offsets.h
index 40db8f71deae..2df313b6a586 100644
--- a/arch/um/include/shared/common-offsets.h
+++ b/arch/um/include/shared/common-offsets.h
@@ -7,16 +7,6 @@ DEFINE(UM_KERN_PAGE_MASK, PAGE_MASK);
7DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT); 7DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT);
8DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); 8DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
9 9
10DEFINE_STR(UM_KERN_EMERG, KERN_EMERG);
11DEFINE_STR(UM_KERN_ALERT, KERN_ALERT);
12DEFINE_STR(UM_KERN_CRIT, KERN_CRIT);
13DEFINE_STR(UM_KERN_ERR, KERN_ERR);
14DEFINE_STR(UM_KERN_WARNING, KERN_WARNING);
15DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE);
16DEFINE_STR(UM_KERN_INFO, KERN_INFO);
17DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG);
18DEFINE_STR(UM_KERN_CONT, KERN_CONT);
19
20DEFINE(UM_ELF_CLASS, ELF_CLASS); 10DEFINE(UM_ELF_CLASS, ELF_CLASS);
21DEFINE(UM_ELFCLASS32, ELFCLASS32); 11DEFINE(UM_ELFCLASS32, ELFCLASS32);
22DEFINE(UM_ELFCLASS64, ELFCLASS64); 12DEFINE(UM_ELFCLASS64, ELFCLASS64);
diff --git a/arch/um/include/shared/user.h b/arch/um/include/shared/user.h
index 4fa82c055aab..cef068563336 100644
--- a/arch/um/include/shared/user.h
+++ b/arch/um/include/shared/user.h
@@ -26,6 +26,17 @@
26extern void panic(const char *fmt, ...) 26extern void panic(const char *fmt, ...)
27 __attribute__ ((format (printf, 1, 2))); 27 __attribute__ ((format (printf, 1, 2)));
28 28
29/* Requires preincluding include/linux/kern_levels.h */
30#define UM_KERN_EMERG KERN_EMERG
31#define UM_KERN_ALERT KERN_ALERT
32#define UM_KERN_CRIT KERN_CRIT
33#define UM_KERN_ERR KERN_ERR
34#define UM_KERN_WARNING KERN_WARNING
35#define UM_KERN_NOTICE KERN_NOTICE
36#define UM_KERN_INFO KERN_INFO
37#define UM_KERN_DEBUG KERN_DEBUG
38#define UM_KERN_CONT KERN_CONT
39
29#ifdef UML_CONFIG_PRINTK 40#ifdef UML_CONFIG_PRINTK
30extern int printk(const char *fmt, ...) 41extern int printk(const char *fmt, ...)
31 __attribute__ ((format (printf, 1, 2))); 42 __attribute__ ((format (printf, 1, 2)));
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c
index 6cade9366364..8c82786da823 100644
--- a/arch/um/kernel/exec.c
+++ b/arch/um/kernel/exec.c
@@ -39,34 +39,21 @@ void flush_thread(void)
39 39
40void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) 40void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
41{ 41{
42 get_safe_registers(regs->regs.gp, regs->regs.fp);
42 PT_REGS_IP(regs) = eip; 43 PT_REGS_IP(regs) = eip;
43 PT_REGS_SP(regs) = esp; 44 PT_REGS_SP(regs) = esp;
44} 45 current->ptrace &= ~PT_DTRACE;
45EXPORT_SYMBOL(start_thread);
46
47static long execve1(const char *file,
48 const char __user *const __user *argv,
49 const char __user *const __user *env)
50{
51 long error;
52
53 error = do_execve(file, argv, env, &current->thread.regs);
54 if (error == 0) {
55 task_lock(current);
56 current->ptrace &= ~PT_DTRACE;
57#ifdef SUBARCH_EXECVE1 46#ifdef SUBARCH_EXECVE1
58 SUBARCH_EXECVE1(&current->thread.regs.regs); 47 SUBARCH_EXECVE1(regs->regs);
59#endif 48#endif
60 task_unlock(current);
61 }
62 return error;
63} 49}
50EXPORT_SYMBOL(start_thread);
64 51
65long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env) 52long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env)
66{ 53{
67 long err; 54 long err;
68 55
69 err = execve1(file, argv, env); 56 err = do_execve(file, argv, env, &current->thread.regs);
70 if (!err) 57 if (!err)
71 UML_LONGJMP(current->thread.exec_buf, 1); 58 UML_LONGJMP(current->thread.exec_buf, 1);
72 return err; 59 return err;
@@ -81,7 +68,7 @@ long sys_execve(const char __user *file, const char __user *const __user *argv,
81 filename = getname(file); 68 filename = getname(file);
82 error = PTR_ERR(filename); 69 error = PTR_ERR(filename);
83 if (IS_ERR(filename)) goto out; 70 if (IS_ERR(filename)) goto out;
84 error = execve1(filename, argv, env); 71 error = do_execve(filename, argv, env, &current->thread.regs);
85 putname(filename); 72 putname(filename);
86 out: 73 out:
87 return error; 74 return error;
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index 57fc7028714a..c5f5afa50745 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -181,11 +181,12 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
181 struct pt_regs *regs) 181 struct pt_regs *regs)
182{ 182{
183 void (*handler)(void); 183 void (*handler)(void);
184 int kthread = current->flags & PF_KTHREAD;
184 int ret = 0; 185 int ret = 0;
185 186
186 p->thread = (struct thread_struct) INIT_THREAD; 187 p->thread = (struct thread_struct) INIT_THREAD;
187 188
188 if (current->thread.forking) { 189 if (!kthread) {
189 memcpy(&p->thread.regs.regs, &regs->regs, 190 memcpy(&p->thread.regs.regs, &regs->regs,
190 sizeof(p->thread.regs.regs)); 191 sizeof(p->thread.regs.regs));
191 PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0); 192 PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0);
@@ -195,8 +196,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
195 handler = fork_handler; 196 handler = fork_handler;
196 197
197 arch_copy_thread(&current->thread.arch, &p->thread.arch); 198 arch_copy_thread(&current->thread.arch, &p->thread.arch);
198 } 199 } else {
199 else {
200 get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp); 200 get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp);
201 p->thread.request.u.thread = current->thread.request.u.thread; 201 p->thread.request.u.thread = current->thread.request.u.thread;
202 handler = new_thread_handler; 202 handler = new_thread_handler;
@@ -204,7 +204,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
204 204
205 new_thread(task_stack_page(p), &p->thread.switch_buf, handler); 205 new_thread(task_stack_page(p), &p->thread.switch_buf, handler);
206 206
207 if (current->thread.forking) { 207 if (!kthread) {
208 clear_flushed_tls(p); 208 clear_flushed_tls(p);
209 209
210 /* 210 /*
diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c
index 7362d58efc29..cc9c2350e417 100644
--- a/arch/um/kernel/signal.c
+++ b/arch/um/kernel/signal.c
@@ -22,9 +22,13 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
22 struct k_sigaction *ka, siginfo_t *info) 22 struct k_sigaction *ka, siginfo_t *info)
23{ 23{
24 sigset_t *oldset = sigmask_to_save(); 24 sigset_t *oldset = sigmask_to_save();
25 int singlestep = 0;
25 unsigned long sp; 26 unsigned long sp;
26 int err; 27 int err;
27 28
29 if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
30 singlestep = 1;
31
28 /* Did we come from a system call? */ 32 /* Did we come from a system call? */
29 if (PT_REGS_SYSCALL_NR(regs) >= 0) { 33 if (PT_REGS_SYSCALL_NR(regs) >= 0) {
30 /* If so, check system call restarting.. */ 34 /* If so, check system call restarting.. */
@@ -61,7 +65,7 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
61 if (err) 65 if (err)
62 force_sigsegv(signr, current); 66 force_sigsegv(signr, current);
63 else 67 else
64 signal_delivered(signr, info, ka, regs, 0); 68 signal_delivered(signr, info, ka, regs, singlestep);
65} 69}
66 70
67static int kern_do_signal(struct pt_regs *regs) 71static int kern_do_signal(struct pt_regs *regs)
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
index f958cb876ee3..a4c6d8eee74c 100644
--- a/arch/um/kernel/syscall.c
+++ b/arch/um/kernel/syscall.c
@@ -17,25 +17,25 @@
17 17
18long sys_fork(void) 18long sys_fork(void)
19{ 19{
20 long ret; 20 return do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
21
22 current->thread.forking = 1;
23 ret = do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
24 &current->thread.regs, 0, NULL, NULL); 21 &current->thread.regs, 0, NULL, NULL);
25 current->thread.forking = 0;
26 return ret;
27} 22}
28 23
29long sys_vfork(void) 24long sys_vfork(void)
30{ 25{
31 long ret; 26 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
32
33 current->thread.forking = 1;
34 ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
35 UPT_SP(&current->thread.regs.regs), 27 UPT_SP(&current->thread.regs.regs),
36 &current->thread.regs, 0, NULL, NULL); 28 &current->thread.regs, 0, NULL, NULL);
37 current->thread.forking = 0; 29}
38 return ret; 30
31long sys_clone(unsigned long clone_flags, unsigned long newsp,
32 void __user *parent_tid, void __user *child_tid)
33{
34 if (!newsp)
35 newsp = UPT_SP(&current->thread.regs.regs);
36
37 return do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
38 child_tid);
39} 39}
40 40
41long old_mmap(unsigned long addr, unsigned long len, 41long old_mmap(unsigned long addr, unsigned long len,
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index d50270d26b42..15889df9b466 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -8,7 +8,7 @@ USER_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:.o=.%): \ 10$(USER_OBJS:.o=.%): \
11 c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) -include user.h $(CFLAGS_$(basetarget).o) 11 c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) -include $(srctree)/include/linux/kern_levels.h -include user.h $(CFLAGS_$(basetarget).o)
12 12
13# These are like USER_OBJS but filter USER_CFLAGS through unprofile instead of 13# These are like USER_OBJS but filter USER_CFLAGS through unprofile instead of
14# using it directly. 14# using it directly.
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 8ec3a1aa4abd..943667050dae 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -7,11 +7,13 @@ config 64BIT
7 Say no to build a 32-bit kernel - formerly known as i386 7 Say no to build a 32-bit kernel - formerly known as i386
8 8
9config X86_32 9config X86_32
10 def_bool !64BIT 10 def_bool y
11 depends on !64BIT
11 select CLKSRC_I8253 12 select CLKSRC_I8253
12 13
13config X86_64 14config X86_64
14 def_bool 64BIT 15 def_bool y
16 depends on 64BIT
15 select X86_DEV_DMA_OPS 17 select X86_DEV_DMA_OPS
16 18
17### Arch settings 19### Arch settings
@@ -36,6 +38,7 @@ config X86
36 select HAVE_KRETPROBES 38 select HAVE_KRETPROBES
37 select HAVE_OPTPROBES 39 select HAVE_OPTPROBES
38 select HAVE_FTRACE_MCOUNT_RECORD 40 select HAVE_FTRACE_MCOUNT_RECORD
41 select HAVE_FENTRY if X86_64
39 select HAVE_C_RECORDMCOUNT 42 select HAVE_C_RECORDMCOUNT
40 select HAVE_DYNAMIC_FTRACE 43 select HAVE_DYNAMIC_FTRACE
41 select HAVE_FUNCTION_TRACER 44 select HAVE_FUNCTION_TRACER
@@ -60,6 +63,8 @@ config X86
60 select HAVE_MIXED_BREAKPOINTS_REGS 63 select HAVE_MIXED_BREAKPOINTS_REGS
61 select PERF_EVENTS 64 select PERF_EVENTS
62 select HAVE_PERF_EVENTS_NMI 65 select HAVE_PERF_EVENTS_NMI
66 select HAVE_PERF_REGS
67 select HAVE_PERF_USER_STACK_DUMP
63 select ANON_INODES 68 select ANON_INODES
64 select HAVE_ALIGNED_STRUCT_PAGE if SLUB && !M386 69 select HAVE_ALIGNED_STRUCT_PAGE if SLUB && !M386
65 select HAVE_CMPXCHG_LOCAL if !M386 70 select HAVE_CMPXCHG_LOCAL if !M386
@@ -97,9 +102,12 @@ config X86
97 select KTIME_SCALAR if X86_32 102 select KTIME_SCALAR if X86_32
98 select GENERIC_STRNCPY_FROM_USER 103 select GENERIC_STRNCPY_FROM_USER
99 select GENERIC_STRNLEN_USER 104 select GENERIC_STRNLEN_USER
105 select HAVE_RCU_USER_QS if X86_64
106 select HAVE_IRQ_TIME_ACCOUNTING
100 107
101config INSTRUCTION_DECODER 108config INSTRUCTION_DECODER
102 def_bool (KPROBES || PERF_EVENTS || UPROBES) 109 def_bool y
110 depends on KPROBES || PERF_EVENTS || UPROBES
103 111
104config OUTPUT_FORMAT 112config OUTPUT_FORMAT
105 string 113 string
@@ -127,13 +135,15 @@ config SBUS
127 bool 135 bool
128 136
129config NEED_DMA_MAP_STATE 137config NEED_DMA_MAP_STATE
130 def_bool (X86_64 || INTEL_IOMMU || DMA_API_DEBUG) 138 def_bool y
139 depends on X86_64 || INTEL_IOMMU || DMA_API_DEBUG
131 140
132config NEED_SG_DMA_LENGTH 141config NEED_SG_DMA_LENGTH
133 def_bool y 142 def_bool y
134 143
135config GENERIC_ISA_DMA 144config GENERIC_ISA_DMA
136 def_bool ISA_DMA_API 145 def_bool y
146 depends on ISA_DMA_API
137 147
138config GENERIC_BUG 148config GENERIC_BUG
139 def_bool y 149 def_bool y
@@ -150,13 +160,16 @@ config GENERIC_GPIO
150 bool 160 bool
151 161
152config ARCH_MAY_HAVE_PC_FDC 162config ARCH_MAY_HAVE_PC_FDC
153 def_bool ISA_DMA_API 163 def_bool y
164 depends on ISA_DMA_API
154 165
155config RWSEM_GENERIC_SPINLOCK 166config RWSEM_GENERIC_SPINLOCK
156 def_bool !X86_XADD 167 def_bool y
168 depends on !X86_XADD
157 169
158config RWSEM_XCHGADD_ALGORITHM 170config RWSEM_XCHGADD_ALGORITHM
159 def_bool X86_XADD 171 def_bool y
172 depends on X86_XADD
160 173
161config GENERIC_CALIBRATE_DELAY 174config GENERIC_CALIBRATE_DELAY
162 def_bool y 175 def_bool y
@@ -746,13 +759,14 @@ config SWIOTLB
746 def_bool y if X86_64 759 def_bool y if X86_64
747 ---help--- 760 ---help---
748 Support for software bounce buffers used on x86-64 systems 761 Support for software bounce buffers used on x86-64 systems
749 which don't have a hardware IOMMU (e.g. the current generation 762 which don't have a hardware IOMMU. Using this PCI devices
750 of Intel's x86-64 CPUs). Using this PCI devices which can only 763 which can only access 32-bits of memory can be used on systems
751 access 32-bits of memory can be used on systems with more than 764 with more than 3 GB of memory.
752 3 GB of memory. If unsure, say Y. 765 If unsure, say Y.
753 766
754config IOMMU_HELPER 767config IOMMU_HELPER
755 def_bool (CALGARY_IOMMU || GART_IOMMU || SWIOTLB || AMD_IOMMU) 768 def_bool y
769 depends on CALGARY_IOMMU || GART_IOMMU || SWIOTLB || AMD_IOMMU
756 770
757config MAXSMP 771config MAXSMP
758 bool "Enable Maximum number of SMP Processors and NUMA Nodes" 772 bool "Enable Maximum number of SMP Processors and NUMA Nodes"
@@ -796,17 +810,6 @@ config SCHED_MC
796 making when dealing with multi-core CPU chips at a cost of slightly 810 making when dealing with multi-core CPU chips at a cost of slightly
797 increased overhead in some places. If unsure say N here. 811 increased overhead in some places. If unsure say N here.
798 812
799config IRQ_TIME_ACCOUNTING
800 bool "Fine granularity task level IRQ time accounting"
801 default n
802 ---help---
803 Select this option to enable fine granularity task irq time
804 accounting. This is done by reading a timestamp on each
805 transitions between softirq and hardirq state, so there can be a
806 small performance impact.
807
808 If in doubt, say N here.
809
810source "kernel/Kconfig.preempt" 813source "kernel/Kconfig.preempt"
811 814
812config X86_UP_APIC 815config X86_UP_APIC
@@ -871,6 +874,7 @@ config X86_REROUTE_FOR_BROKEN_BOOT_IRQS
871 874
872config X86_MCE 875config X86_MCE
873 bool "Machine Check / overheating reporting" 876 bool "Machine Check / overheating reporting"
877 default y
874 ---help--- 878 ---help---
875 Machine Check support allows the processor to notify the 879 Machine Check support allows the processor to notify the
876 kernel if it detects a problem (e.g. overheating, data corruption). 880 kernel if it detects a problem (e.g. overheating, data corruption).
@@ -982,25 +986,25 @@ config X86_REBOOTFIXUPS
982 Say N otherwise. 986 Say N otherwise.
983 987
984config MICROCODE 988config MICROCODE
985 tristate "/dev/cpu/microcode - microcode support" 989 tristate "CPU microcode loading support"
986 select FW_LOADER 990 select FW_LOADER
987 ---help--- 991 ---help---
992
988 If you say Y here, you will be able to update the microcode on 993 If you say Y here, you will be able to update the microcode on
989 certain Intel and AMD processors. The Intel support is for the 994 certain Intel and AMD processors. The Intel support is for the
990 IA32 family, e.g. Pentium Pro, Pentium II, Pentium III, 995 IA32 family, e.g. Pentium Pro, Pentium II, Pentium III, Pentium 4,
991 Pentium 4, Xeon etc. The AMD support is for family 0x10 and 996 Xeon etc. The AMD support is for families 0x10 and later. You will
992 0x11 processors, e.g. Opteron, Phenom and Turion 64 Ultra. 997 obviously need the actual microcode binary data itself which is not
993 You will obviously need the actual microcode binary data itself 998 shipped with the Linux kernel.
994 which is not shipped with the Linux kernel.
995 999
996 This option selects the general module only, you need to select 1000 This option selects the general module only, you need to select
997 at least one vendor specific module as well. 1001 at least one vendor specific module as well.
998 1002
999 To compile this driver as a module, choose M here: the 1003 To compile this driver as a module, choose M here: the module
1000 module will be called microcode. 1004 will be called microcode.
1001 1005
1002config MICROCODE_INTEL 1006config MICROCODE_INTEL
1003 bool "Intel microcode patch loading support" 1007 bool "Intel microcode loading support"
1004 depends on MICROCODE 1008 depends on MICROCODE
1005 default MICROCODE 1009 default MICROCODE
1006 select FW_LOADER 1010 select FW_LOADER
@@ -1013,7 +1017,7 @@ config MICROCODE_INTEL
1013 <http://www.urbanmyth.org/microcode/>. 1017 <http://www.urbanmyth.org/microcode/>.
1014 1018
1015config MICROCODE_AMD 1019config MICROCODE_AMD
1016 bool "AMD microcode patch loading support" 1020 bool "AMD microcode loading support"
1017 depends on MICROCODE 1021 depends on MICROCODE
1018 select FW_LOADER 1022 select FW_LOADER
1019 ---help--- 1023 ---help---
@@ -1159,10 +1163,12 @@ config X86_PAE
1159 consumes more pagetable space per process. 1163 consumes more pagetable space per process.
1160 1164
1161config ARCH_PHYS_ADDR_T_64BIT 1165config ARCH_PHYS_ADDR_T_64BIT
1162 def_bool X86_64 || X86_PAE 1166 def_bool y
1167 depends on X86_64 || X86_PAE
1163 1168
1164config ARCH_DMA_ADDR_T_64BIT 1169config ARCH_DMA_ADDR_T_64BIT
1165 def_bool X86_64 || HIGHMEM64G 1170 def_bool y
1171 depends on X86_64 || HIGHMEM64G
1166 1172
1167config DIRECT_GBPAGES 1173config DIRECT_GBPAGES
1168 bool "Enable 1GB pages for kernel pagetables" if EXPERT 1174 bool "Enable 1GB pages for kernel pagetables" if EXPERT
@@ -1285,8 +1291,8 @@ config ARCH_SELECT_MEMORY_MODEL
1285 depends on ARCH_SPARSEMEM_ENABLE 1291 depends on ARCH_SPARSEMEM_ENABLE
1286 1292
1287config ARCH_MEMORY_PROBE 1293config ARCH_MEMORY_PROBE
1288 def_bool X86_64 1294 def_bool y
1289 depends on MEMORY_HOTPLUG 1295 depends on X86_64 && MEMORY_HOTPLUG
1290 1296
1291config ARCH_PROC_KCORE_TEXT 1297config ARCH_PROC_KCORE_TEXT
1292 def_bool y 1298 def_bool y
@@ -1975,7 +1981,6 @@ config PCI_MMCONFIG
1975 1981
1976config PCI_CNB20LE_QUIRK 1982config PCI_CNB20LE_QUIRK
1977 bool "Read CNB20LE Host Bridge Windows" if EXPERT 1983 bool "Read CNB20LE Host Bridge Windows" if EXPERT
1978 default n
1979 depends on PCI && EXPERIMENTAL 1984 depends on PCI && EXPERIMENTAL
1980 help 1985 help
1981 Read the PCI windows out of the CNB20LE host bridge. This allows 1986 Read the PCI windows out of the CNB20LE host bridge. This allows
@@ -2186,18 +2191,18 @@ config COMPAT
2186 depends on IA32_EMULATION || X86_X32 2191 depends on IA32_EMULATION || X86_X32
2187 select ARCH_WANT_OLD_COMPAT_IPC 2192 select ARCH_WANT_OLD_COMPAT_IPC
2188 2193
2194if COMPAT
2189config COMPAT_FOR_U64_ALIGNMENT 2195config COMPAT_FOR_U64_ALIGNMENT
2190 def_bool COMPAT 2196 def_bool y
2191 depends on X86_64
2192 2197
2193config SYSVIPC_COMPAT 2198config SYSVIPC_COMPAT
2194 def_bool y 2199 def_bool y
2195 depends on COMPAT && SYSVIPC 2200 depends on SYSVIPC
2196 2201
2197config KEYS_COMPAT 2202config KEYS_COMPAT
2198 bool 2203 def_bool y
2199 depends on COMPAT && KEYS 2204 depends on KEYS
2200 default y 2205endif
2201 2206
2202endmenu 2207endmenu
2203 2208
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 706e12e9984b..f3b86d0df44e 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -306,7 +306,8 @@ config X86_INTERNODE_CACHE_SHIFT
306 default X86_L1_CACHE_SHIFT 306 default X86_L1_CACHE_SHIFT
307 307
308config X86_CMPXCHG 308config X86_CMPXCHG
309 def_bool X86_64 || (X86_32 && !M386) 309 def_bool y
310 depends on X86_64 || (X86_32 && !M386)
310 311
311config X86_L1_CACHE_SHIFT 312config X86_L1_CACHE_SHIFT
312 int 313 int
@@ -317,7 +318,7 @@ config X86_L1_CACHE_SHIFT
317 318
318config X86_XADD 319config X86_XADD
319 def_bool y 320 def_bool y
320 depends on X86_64 || !M386 321 depends on !M386
321 322
322config X86_PPRO_FENCE 323config X86_PPRO_FENCE
323 bool "PentiumPro memory ordering errata workaround" 324 bool "PentiumPro memory ordering errata workaround"
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 682e9c210baa..474ca35b1bce 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -142,7 +142,7 @@ KBUILD_CFLAGS += $(call cc-option,-mno-avx,)
142KBUILD_CFLAGS += $(mflags-y) 142KBUILD_CFLAGS += $(mflags-y)
143KBUILD_AFLAGS += $(mflags-y) 143KBUILD_AFLAGS += $(mflags-y)
144 144
145archscripts: 145archscripts: scripts_basic
146 $(Q)$(MAKE) $(build)=arch/x86/tools relocs 146 $(Q)$(MAKE) $(build)=arch/x86/tools relocs
147 147
148### 148###
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index e398bb5d63bb..8a84501acb1b 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -28,6 +28,9 @@ VMLINUX_OBJS = $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o \
28 $(obj)/string.o $(obj)/cmdline.o $(obj)/early_serial_console.o \ 28 $(obj)/string.o $(obj)/cmdline.o $(obj)/early_serial_console.o \
29 $(obj)/piggy.o 29 $(obj)/piggy.o
30 30
31$(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone
32$(obj)/efi_stub_$(BITS).o: KBUILD_CLFAGS += -fshort-wchar -mno-red-zone
33
31ifeq ($(CONFIG_EFI_STUB), y) 34ifeq ($(CONFIG_EFI_STUB), y)
32 VMLINUX_OBJS += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o 35 VMLINUX_OBJS += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o
33endif 36endif
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index b3e0227df2c9..c760e073963e 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -276,8 +276,9 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
276 nr_gops = size / sizeof(void *); 276 nr_gops = size / sizeof(void *);
277 for (i = 0; i < nr_gops; i++) { 277 for (i = 0; i < nr_gops; i++) {
278 struct efi_graphics_output_mode_info *info; 278 struct efi_graphics_output_mode_info *info;
279 efi_guid_t pciio_proto = EFI_PCI_IO_PROTOCOL_GUID; 279 efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID;
280 void *pciio; 280 bool conout_found = false;
281 void *dummy;
281 void *h = gop_handle[i]; 282 void *h = gop_handle[i];
282 283
283 status = efi_call_phys3(sys_table->boottime->handle_protocol, 284 status = efi_call_phys3(sys_table->boottime->handle_protocol,
@@ -285,19 +286,21 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
285 if (status != EFI_SUCCESS) 286 if (status != EFI_SUCCESS)
286 continue; 287 continue;
287 288
288 efi_call_phys3(sys_table->boottime->handle_protocol, 289 status = efi_call_phys3(sys_table->boottime->handle_protocol,
289 h, &pciio_proto, &pciio); 290 h, &conout_proto, &dummy);
291
292 if (status == EFI_SUCCESS)
293 conout_found = true;
290 294
291 status = efi_call_phys4(gop->query_mode, gop, 295 status = efi_call_phys4(gop->query_mode, gop,
292 gop->mode->mode, &size, &info); 296 gop->mode->mode, &size, &info);
293 if (status == EFI_SUCCESS && (!first_gop || pciio)) { 297 if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
294 /* 298 /*
295 * Apple provide GOPs that are not backed by 299 * Systems that use the UEFI Console Splitter may
296 * real hardware (they're used to handle 300 * provide multiple GOP devices, not all of which are
297 * multiple displays). The workaround is to 301 * backed by real hardware. The workaround is to search
298 * search for a GOP implementing the PCIIO 302 * for a GOP implementing the ConOut protocol, and if
299 * protocol, and if one isn't found, to just 303 * one isn't found, to just fall back to the first GOP.
300 * fallback to the first GOP.
301 */ 304 */
302 width = info->horizontal_resolution; 305 width = info->horizontal_resolution;
303 height = info->vertical_resolution; 306 height = info->vertical_resolution;
@@ -308,10 +311,10 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
308 pixels_per_scan_line = info->pixels_per_scan_line; 311 pixels_per_scan_line = info->pixels_per_scan_line;
309 312
310 /* 313 /*
311 * Once we've found a GOP supporting PCIIO, 314 * Once we've found a GOP supporting ConOut,
312 * don't bother looking any further. 315 * don't bother looking any further.
313 */ 316 */
314 if (pciio) 317 if (conout_found)
315 break; 318 break;
316 319
317 first_gop = gop; 320 first_gop = gop;
@@ -328,7 +331,6 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
328 si->lfb_width = width; 331 si->lfb_width = width;
329 si->lfb_height = height; 332 si->lfb_height = height;
330 si->lfb_base = fb_base; 333 si->lfb_base = fb_base;
331 si->lfb_size = fb_size;
332 si->pages = 1; 334 si->pages = 1;
333 335
334 if (pixel_format == PIXEL_RGB_RESERVED_8BIT_PER_COLOR) { 336 if (pixel_format == PIXEL_RGB_RESERVED_8BIT_PER_COLOR) {
@@ -376,6 +378,10 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
376 si->rsvd_pos = 0; 378 si->rsvd_pos = 0;
377 } 379 }
378 380
381 si->lfb_size = si->lfb_linelength * si->lfb_height;
382
383 si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS;
384
379free_handle: 385free_handle:
380 efi_call_phys1(sys_table->boottime->free_pool, gop_handle); 386 efi_call_phys1(sys_table->boottime->free_pool, gop_handle);
381 return status; 387 return status;
diff --git a/arch/x86/boot/compressed/eboot.h b/arch/x86/boot/compressed/eboot.h
index 3b6e15627c55..e5b0a8f91c5f 100644
--- a/arch/x86/boot/compressed/eboot.h
+++ b/arch/x86/boot/compressed/eboot.h
@@ -14,6 +14,10 @@
14#define EFI_PAGE_SIZE (1UL << EFI_PAGE_SHIFT) 14#define EFI_PAGE_SIZE (1UL << EFI_PAGE_SHIFT)
15#define EFI_READ_CHUNK_SIZE (1024 * 1024) 15#define EFI_READ_CHUNK_SIZE (1024 * 1024)
16 16
17#define EFI_CONSOLE_OUT_DEVICE_GUID \
18 EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x0, 0x90, 0x27, \
19 0x3f, 0xc1, 0x4d)
20
17#define PIXEL_RGB_RESERVED_8BIT_PER_COLOR 0 21#define PIXEL_RGB_RESERVED_8BIT_PER_COLOR 0
18#define PIXEL_BGR_RESERVED_8BIT_PER_COLOR 1 22#define PIXEL_BGR_RESERVED_8BIT_PER_COLOR 1
19#define PIXEL_BIT_MASK 2 23#define PIXEL_BIT_MASK 2
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index b4e15dd6786a..2a017441b8b2 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -32,10 +32,6 @@ SYSSEG = 0x1000 /* historical load address >> 4 */
32#define SVGA_MODE ASK_VGA 32#define SVGA_MODE ASK_VGA
33#endif 33#endif
34 34
35#ifndef RAMDISK
36#define RAMDISK 0
37#endif
38
39#ifndef ROOT_RDONLY 35#ifndef ROOT_RDONLY
40#define ROOT_RDONLY 1 36#define ROOT_RDONLY 1
41#endif 37#endif
diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig
index 119db67dcb03..5598547281a7 100644
--- a/arch/x86/configs/i386_defconfig
+++ b/arch/x86/configs/i386_defconfig
@@ -8,6 +8,8 @@ CONFIG_TASK_DELAY_ACCT=y
8CONFIG_TASK_XACCT=y 8CONFIG_TASK_XACCT=y
9CONFIG_TASK_IO_ACCOUNTING=y 9CONFIG_TASK_IO_ACCOUNTING=y
10CONFIG_AUDIT=y 10CONFIG_AUDIT=y
11CONFIG_NO_HZ=y
12CONFIG_HIGH_RES_TIMERS=y
11CONFIG_LOG_BUF_SHIFT=18 13CONFIG_LOG_BUF_SHIFT=18
12CONFIG_CGROUPS=y 14CONFIG_CGROUPS=y
13CONFIG_CGROUP_FREEZER=y 15CONFIG_CGROUP_FREEZER=y
@@ -34,8 +36,6 @@ CONFIG_SGI_PARTITION=y
34CONFIG_SUN_PARTITION=y 36CONFIG_SUN_PARTITION=y
35CONFIG_KARMA_PARTITION=y 37CONFIG_KARMA_PARTITION=y
36CONFIG_EFI_PARTITION=y 38CONFIG_EFI_PARTITION=y
37CONFIG_NO_HZ=y
38CONFIG_HIGH_RES_TIMERS=y
39CONFIG_SMP=y 39CONFIG_SMP=y
40CONFIG_X86_GENERIC=y 40CONFIG_X86_GENERIC=y
41CONFIG_HPET_TIMER=y 41CONFIG_HPET_TIMER=y
@@ -144,8 +144,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
144CONFIG_DEBUG_DEVRES=y 144CONFIG_DEBUG_DEVRES=y
145CONFIG_CONNECTOR=y 145CONFIG_CONNECTOR=y
146CONFIG_BLK_DEV_LOOP=y 146CONFIG_BLK_DEV_LOOP=y
147CONFIG_BLK_DEV_RAM=y
148CONFIG_BLK_DEV_RAM_SIZE=16384
149CONFIG_BLK_DEV_SD=y 147CONFIG_BLK_DEV_SD=y
150CONFIG_BLK_DEV_SR=y 148CONFIG_BLK_DEV_SR=y
151CONFIG_BLK_DEV_SR_VENDOR=y 149CONFIG_BLK_DEV_SR_VENDOR=y
@@ -231,8 +229,6 @@ CONFIG_SND_HRTIMER=y
231CONFIG_SND_HDA_INTEL=y 229CONFIG_SND_HDA_INTEL=y
232CONFIG_SND_HDA_HWDEP=y 230CONFIG_SND_HDA_HWDEP=y
233CONFIG_HIDRAW=y 231CONFIG_HIDRAW=y
234CONFIG_HID_PID=y
235CONFIG_USB_HIDDEV=y
236CONFIG_HID_GYRATION=y 232CONFIG_HID_GYRATION=y
237CONFIG_LOGITECH_FF=y 233CONFIG_LOGITECH_FF=y
238CONFIG_HID_NTRIG=y 234CONFIG_HID_NTRIG=y
@@ -243,11 +239,11 @@ CONFIG_HID_SAMSUNG=y
243CONFIG_HID_SONY=y 239CONFIG_HID_SONY=y
244CONFIG_HID_SUNPLUS=y 240CONFIG_HID_SUNPLUS=y
245CONFIG_HID_TOPSEED=y 241CONFIG_HID_TOPSEED=y
242CONFIG_HID_PID=y
243CONFIG_USB_HIDDEV=y
246CONFIG_USB=y 244CONFIG_USB=y
247CONFIG_USB_DEBUG=y 245CONFIG_USB_DEBUG=y
248CONFIG_USB_ANNOUNCE_NEW_DEVICES=y 246CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
249CONFIG_USB_DEVICEFS=y
250# CONFIG_USB_DEVICE_CLASS is not set
251CONFIG_USB_MON=y 247CONFIG_USB_MON=y
252CONFIG_USB_EHCI_HCD=y 248CONFIG_USB_EHCI_HCD=y
253# CONFIG_USB_EHCI_TT_NEWSCHED is not set 249# CONFIG_USB_EHCI_TT_NEWSCHED is not set
@@ -262,10 +258,9 @@ CONFIG_RTC_CLASS=y
262CONFIG_DMADEVICES=y 258CONFIG_DMADEVICES=y
263CONFIG_EEEPC_LAPTOP=y 259CONFIG_EEEPC_LAPTOP=y
264CONFIG_EFI_VARS=y 260CONFIG_EFI_VARS=y
265CONFIG_EXT3_FS=y 261CONFIG_EXT4_FS=y
266# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set 262CONFIG_EXT4_FS_POSIX_ACL=y
267CONFIG_EXT3_FS_POSIX_ACL=y 263CONFIG_EXT4_FS_SECURITY=y
268CONFIG_EXT3_FS_SECURITY=y
269CONFIG_QUOTA=y 264CONFIG_QUOTA=y
270CONFIG_QUOTA_NETLINK_INTERFACE=y 265CONFIG_QUOTA_NETLINK_INTERFACE=y
271# CONFIG_PRINT_QUOTA_WARNING is not set 266# CONFIG_PRINT_QUOTA_WARNING is not set
@@ -280,7 +275,6 @@ CONFIG_PROC_KCORE=y
280CONFIG_TMPFS_POSIX_ACL=y 275CONFIG_TMPFS_POSIX_ACL=y
281CONFIG_HUGETLBFS=y 276CONFIG_HUGETLBFS=y
282CONFIG_NFS_FS=y 277CONFIG_NFS_FS=y
283CONFIG_NFS_V3=y
284CONFIG_NFS_V3_ACL=y 278CONFIG_NFS_V3_ACL=y
285CONFIG_NFS_V4=y 279CONFIG_NFS_V4=y
286CONFIG_ROOT_NFS=y 280CONFIG_ROOT_NFS=y
@@ -299,13 +293,11 @@ CONFIG_DEBUG_KERNEL=y
299CONFIG_SCHEDSTATS=y 293CONFIG_SCHEDSTATS=y
300CONFIG_TIMER_STATS=y 294CONFIG_TIMER_STATS=y
301CONFIG_DEBUG_STACK_USAGE=y 295CONFIG_DEBUG_STACK_USAGE=y
302CONFIG_SYSCTL_SYSCALL_CHECK=y
303CONFIG_BLK_DEV_IO_TRACE=y 296CONFIG_BLK_DEV_IO_TRACE=y
304CONFIG_PROVIDE_OHCI1394_DMA_INIT=y 297CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
305CONFIG_EARLY_PRINTK_DBGP=y 298CONFIG_EARLY_PRINTK_DBGP=y
306CONFIG_DEBUG_STACKOVERFLOW=y 299CONFIG_DEBUG_STACKOVERFLOW=y
307# CONFIG_DEBUG_RODATA_TEST is not set 300# CONFIG_DEBUG_RODATA_TEST is not set
308CONFIG_DEBUG_NX_TEST=m
309CONFIG_DEBUG_BOOT_PARAMS=y 301CONFIG_DEBUG_BOOT_PARAMS=y
310CONFIG_OPTIMIZE_INLINING=y 302CONFIG_OPTIMIZE_INLINING=y
311CONFIG_KEYS_DEBUG_PROC_KEYS=y 303CONFIG_KEYS_DEBUG_PROC_KEYS=y
@@ -316,4 +308,3 @@ CONFIG_SECURITY_SELINUX_BOOTPARAM=y
316CONFIG_SECURITY_SELINUX_DISABLE=y 308CONFIG_SECURITY_SELINUX_DISABLE=y
317CONFIG_CRYPTO_AES_586=y 309CONFIG_CRYPTO_AES_586=y
318# CONFIG_CRYPTO_ANSI_CPRNG is not set 310# CONFIG_CRYPTO_ANSI_CPRNG is not set
319CONFIG_CRC_T10DIF=y
diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig
index 76eb2903809f..671524d0f6c0 100644
--- a/arch/x86/configs/x86_64_defconfig
+++ b/arch/x86/configs/x86_64_defconfig
@@ -8,6 +8,8 @@ CONFIG_TASK_DELAY_ACCT=y
8CONFIG_TASK_XACCT=y 8CONFIG_TASK_XACCT=y
9CONFIG_TASK_IO_ACCOUNTING=y 9CONFIG_TASK_IO_ACCOUNTING=y
10CONFIG_AUDIT=y 10CONFIG_AUDIT=y
11CONFIG_NO_HZ=y
12CONFIG_HIGH_RES_TIMERS=y
11CONFIG_LOG_BUF_SHIFT=18 13CONFIG_LOG_BUF_SHIFT=18
12CONFIG_CGROUPS=y 14CONFIG_CGROUPS=y
13CONFIG_CGROUP_FREEZER=y 15CONFIG_CGROUP_FREEZER=y
@@ -34,8 +36,6 @@ CONFIG_SGI_PARTITION=y
34CONFIG_SUN_PARTITION=y 36CONFIG_SUN_PARTITION=y
35CONFIG_KARMA_PARTITION=y 37CONFIG_KARMA_PARTITION=y
36CONFIG_EFI_PARTITION=y 38CONFIG_EFI_PARTITION=y
37CONFIG_NO_HZ=y
38CONFIG_HIGH_RES_TIMERS=y
39CONFIG_SMP=y 39CONFIG_SMP=y
40CONFIG_CALGARY_IOMMU=y 40CONFIG_CALGARY_IOMMU=y
41CONFIG_NR_CPUS=64 41CONFIG_NR_CPUS=64
@@ -144,8 +144,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
144CONFIG_DEBUG_DEVRES=y 144CONFIG_DEBUG_DEVRES=y
145CONFIG_CONNECTOR=y 145CONFIG_CONNECTOR=y
146CONFIG_BLK_DEV_LOOP=y 146CONFIG_BLK_DEV_LOOP=y
147CONFIG_BLK_DEV_RAM=y
148CONFIG_BLK_DEV_RAM_SIZE=16384
149CONFIG_BLK_DEV_SD=y 147CONFIG_BLK_DEV_SD=y
150CONFIG_BLK_DEV_SR=y 148CONFIG_BLK_DEV_SR=y
151CONFIG_BLK_DEV_SR_VENDOR=y 149CONFIG_BLK_DEV_SR_VENDOR=y
@@ -227,8 +225,6 @@ CONFIG_SND_HRTIMER=y
227CONFIG_SND_HDA_INTEL=y 225CONFIG_SND_HDA_INTEL=y
228CONFIG_SND_HDA_HWDEP=y 226CONFIG_SND_HDA_HWDEP=y
229CONFIG_HIDRAW=y 227CONFIG_HIDRAW=y
230CONFIG_HID_PID=y
231CONFIG_USB_HIDDEV=y
232CONFIG_HID_GYRATION=y 228CONFIG_HID_GYRATION=y
233CONFIG_LOGITECH_FF=y 229CONFIG_LOGITECH_FF=y
234CONFIG_HID_NTRIG=y 230CONFIG_HID_NTRIG=y
@@ -239,11 +235,11 @@ CONFIG_HID_SAMSUNG=y
239CONFIG_HID_SONY=y 235CONFIG_HID_SONY=y
240CONFIG_HID_SUNPLUS=y 236CONFIG_HID_SUNPLUS=y
241CONFIG_HID_TOPSEED=y 237CONFIG_HID_TOPSEED=y
238CONFIG_HID_PID=y
239CONFIG_USB_HIDDEV=y
242CONFIG_USB=y 240CONFIG_USB=y
243CONFIG_USB_DEBUG=y 241CONFIG_USB_DEBUG=y
244CONFIG_USB_ANNOUNCE_NEW_DEVICES=y 242CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
245CONFIG_USB_DEVICEFS=y
246# CONFIG_USB_DEVICE_CLASS is not set
247CONFIG_USB_MON=y 243CONFIG_USB_MON=y
248CONFIG_USB_EHCI_HCD=y 244CONFIG_USB_EHCI_HCD=y
249# CONFIG_USB_EHCI_TT_NEWSCHED is not set 245# CONFIG_USB_EHCI_TT_NEWSCHED is not set
@@ -262,10 +258,9 @@ CONFIG_AMD_IOMMU_STATS=y
262CONFIG_INTEL_IOMMU=y 258CONFIG_INTEL_IOMMU=y
263# CONFIG_INTEL_IOMMU_DEFAULT_ON is not set 259# CONFIG_INTEL_IOMMU_DEFAULT_ON is not set
264CONFIG_EFI_VARS=y 260CONFIG_EFI_VARS=y
265CONFIG_EXT3_FS=y 261CONFIG_EXT4_FS=y
266# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set 262CONFIG_EXT4_FS_POSIX_ACL=y
267CONFIG_EXT3_FS_POSIX_ACL=y 263CONFIG_EXT4_FS_SECURITY=y
268CONFIG_EXT3_FS_SECURITY=y
269CONFIG_QUOTA=y 264CONFIG_QUOTA=y
270CONFIG_QUOTA_NETLINK_INTERFACE=y 265CONFIG_QUOTA_NETLINK_INTERFACE=y
271# CONFIG_PRINT_QUOTA_WARNING is not set 266# CONFIG_PRINT_QUOTA_WARNING is not set
@@ -280,7 +275,6 @@ CONFIG_PROC_KCORE=y
280CONFIG_TMPFS_POSIX_ACL=y 275CONFIG_TMPFS_POSIX_ACL=y
281CONFIG_HUGETLBFS=y 276CONFIG_HUGETLBFS=y
282CONFIG_NFS_FS=y 277CONFIG_NFS_FS=y
283CONFIG_NFS_V3=y
284CONFIG_NFS_V3_ACL=y 278CONFIG_NFS_V3_ACL=y
285CONFIG_NFS_V4=y 279CONFIG_NFS_V4=y
286CONFIG_ROOT_NFS=y 280CONFIG_ROOT_NFS=y
@@ -298,13 +292,11 @@ CONFIG_DEBUG_KERNEL=y
298CONFIG_SCHEDSTATS=y 292CONFIG_SCHEDSTATS=y
299CONFIG_TIMER_STATS=y 293CONFIG_TIMER_STATS=y
300CONFIG_DEBUG_STACK_USAGE=y 294CONFIG_DEBUG_STACK_USAGE=y
301CONFIG_SYSCTL_SYSCALL_CHECK=y
302CONFIG_BLK_DEV_IO_TRACE=y 295CONFIG_BLK_DEV_IO_TRACE=y
303CONFIG_PROVIDE_OHCI1394_DMA_INIT=y 296CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
304CONFIG_EARLY_PRINTK_DBGP=y 297CONFIG_EARLY_PRINTK_DBGP=y
305CONFIG_DEBUG_STACKOVERFLOW=y 298CONFIG_DEBUG_STACKOVERFLOW=y
306# CONFIG_DEBUG_RODATA_TEST is not set 299# CONFIG_DEBUG_RODATA_TEST is not set
307CONFIG_DEBUG_NX_TEST=m
308CONFIG_DEBUG_BOOT_PARAMS=y 300CONFIG_DEBUG_BOOT_PARAMS=y
309CONFIG_OPTIMIZE_INLINING=y 301CONFIG_OPTIMIZE_INLINING=y
310CONFIG_KEYS_DEBUG_PROC_KEYS=y 302CONFIG_KEYS_DEBUG_PROC_KEYS=y
@@ -314,4 +306,3 @@ CONFIG_SECURITY_SELINUX=y
314CONFIG_SECURITY_SELINUX_BOOTPARAM=y 306CONFIG_SECURITY_SELINUX_BOOTPARAM=y
315CONFIG_SECURITY_SELINUX_DISABLE=y 307CONFIG_SECURITY_SELINUX_DISABLE=y
316# CONFIG_CRYPTO_ANSI_CPRNG is not set 308# CONFIG_CRYPTO_ANSI_CPRNG is not set
317CONFIG_CRC_T10DIF=y
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index 673ac9b63d6b..8c77c64fbd27 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -162,7 +162,8 @@ asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
162 } 162 }
163 seg = get_fs(); 163 seg = get_fs();
164 set_fs(KERNEL_DS); 164 set_fs(KERNEL_DS);
165 ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->sp); 165 ret = do_sigaltstack((stack_t __force __user *) (uss_ptr ? &uss : NULL),
166 (stack_t __force __user *) &uoss, regs->sp);
166 set_fs(seg); 167 set_fs(seg);
167 if (ret >= 0 && uoss_ptr) { 168 if (ret >= 0 && uoss_ptr) {
168 if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t))) 169 if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)))
@@ -250,7 +251,7 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
250 251
251 get_user_ex(tmp, &sc->fpstate); 252 get_user_ex(tmp, &sc->fpstate);
252 buf = compat_ptr(tmp); 253 buf = compat_ptr(tmp);
253 err |= restore_i387_xstate_ia32(buf); 254 err |= restore_xstate_sig(buf, 1);
254 255
255 get_user_ex(*pax, &sc->ax); 256 get_user_ex(*pax, &sc->ax);
256 } get_user_catch(err); 257 } get_user_catch(err);
@@ -361,7 +362,7 @@ static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
361 */ 362 */
362static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, 363static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
363 size_t frame_size, 364 size_t frame_size,
364 void **fpstate) 365 void __user **fpstate)
365{ 366{
366 unsigned long sp; 367 unsigned long sp;
367 368
@@ -381,9 +382,12 @@ static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
381 sp = (unsigned long) ka->sa.sa_restorer; 382 sp = (unsigned long) ka->sa.sa_restorer;
382 383
383 if (used_math()) { 384 if (used_math()) {
384 sp = sp - sig_xstate_ia32_size; 385 unsigned long fx_aligned, math_size;
385 *fpstate = (struct _fpstate_ia32 *) sp; 386
386 if (save_i387_xstate_ia32(*fpstate) < 0) 387 sp = alloc_mathframe(sp, 1, &fx_aligned, &math_size);
388 *fpstate = (struct _fpstate_ia32 __user *) sp;
389 if (save_xstate_sig(*fpstate, (void __user *)fx_aligned,
390 math_size) < 0)
387 return (void __user *) -1L; 391 return (void __user *) -1L;
388 } 392 }
389 393
@@ -448,7 +452,7 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
448 * These are actually not used anymore, but left because some 452 * These are actually not used anymore, but left because some
449 * gdb versions depend on them as a marker. 453 * gdb versions depend on them as a marker.
450 */ 454 */
451 put_user_ex(*((u64 *)&code), (u64 *)frame->retcode); 455 put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
452 } put_user_catch(err); 456 } put_user_catch(err);
453 457
454 if (err) 458 if (err)
@@ -529,7 +533,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
529 * Not actually used anymore, but left because some gdb 533 * Not actually used anymore, but left because some gdb
530 * versions need it. 534 * versions need it.
531 */ 535 */
532 put_user_ex(*((u64 *)&code), (u64 *)frame->retcode); 536 put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
533 } put_user_catch(err); 537 } put_user_catch(err);
534 538
535 if (err) 539 if (err)
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
index 4540bece0946..c5b938d92eab 100644
--- a/arch/x86/ia32/sys_ia32.c
+++ b/arch/x86/ia32/sys_ia32.c
@@ -287,7 +287,7 @@ asmlinkage long sys32_sigaction(int sig, struct old_sigaction32 __user *act,
287 return ret; 287 return ret;
288} 288}
289 289
290asmlinkage long sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, 290asmlinkage long sys32_waitpid(compat_pid_t pid, unsigned int __user *stat_addr,
291 int options) 291 int options)
292{ 292{
293 return compat_sys_wait4(pid, stat_addr, options, NULL); 293 return compat_sys_wait4(pid, stat_addr, options, NULL);
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index 70780689599a..444704c8e186 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -60,7 +60,7 @@ extern void alternatives_smp_module_add(struct module *mod, char *name,
60 void *locks, void *locks_end, 60 void *locks, void *locks_end,
61 void *text, void *text_end); 61 void *text, void *text_end);
62extern void alternatives_smp_module_del(struct module *mod); 62extern void alternatives_smp_module_del(struct module *mod);
63extern void alternatives_smp_switch(int smp); 63extern void alternatives_enable_smp(void);
64extern int alternatives_text_reserved(void *start, void *end); 64extern int alternatives_text_reserved(void *start, void *end);
65extern bool skip_smp_alternatives; 65extern bool skip_smp_alternatives;
66#else 66#else
@@ -68,7 +68,7 @@ static inline void alternatives_smp_module_add(struct module *mod, char *name,
68 void *locks, void *locks_end, 68 void *locks, void *locks_end,
69 void *text, void *text_end) {} 69 void *text, void *text_end) {}
70static inline void alternatives_smp_module_del(struct module *mod) {} 70static inline void alternatives_smp_module_del(struct module *mod) {}
71static inline void alternatives_smp_switch(int smp) {} 71static inline void alternatives_enable_smp(void) {}
72static inline int alternatives_text_reserved(void *start, void *end) 72static inline int alternatives_text_reserved(void *start, void *end)
73{ 73{
74 return 0; 74 return 0;
diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h
index 72f5009deb5a..6dfd0195bb55 100644
--- a/arch/x86/include/asm/bitops.h
+++ b/arch/x86/include/asm/bitops.h
@@ -355,7 +355,7 @@ static int test_bit(int nr, const volatile unsigned long *addr);
355 */ 355 */
356static inline unsigned long __ffs(unsigned long word) 356static inline unsigned long __ffs(unsigned long word)
357{ 357{
358 asm("bsf %1,%0" 358 asm("rep; bsf %1,%0"
359 : "=r" (word) 359 : "=r" (word)
360 : "rm" (word)); 360 : "rm" (word));
361 return word; 361 return word;
@@ -369,7 +369,7 @@ static inline unsigned long __ffs(unsigned long word)
369 */ 369 */
370static inline unsigned long ffz(unsigned long word) 370static inline unsigned long ffz(unsigned long word)
371{ 371{
372 asm("bsf %1,%0" 372 asm("rep; bsf %1,%0"
373 : "=r" (word) 373 : "=r" (word)
374 : "r" (~word)); 374 : "r" (~word));
375 return word; 375 return word;
@@ -417,10 +417,9 @@ static inline int ffs(int x)
417 * We cannot do this on 32 bits because at the very least some 417 * We cannot do this on 32 bits because at the very least some
418 * 486 CPUs did not behave this way. 418 * 486 CPUs did not behave this way.
419 */ 419 */
420 long tmp = -1;
421 asm("bsfl %1,%0" 420 asm("bsfl %1,%0"
422 : "=r" (r) 421 : "=r" (r)
423 : "rm" (x), "0" (tmp)); 422 : "rm" (x), "0" (-1));
424#elif defined(CONFIG_X86_CMOV) 423#elif defined(CONFIG_X86_CMOV)
425 asm("bsfl %1,%0\n\t" 424 asm("bsfl %1,%0\n\t"
426 "cmovzl %2,%0" 425 "cmovzl %2,%0"
@@ -459,10 +458,9 @@ static inline int fls(int x)
459 * We cannot do this on 32 bits because at the very least some 458 * We cannot do this on 32 bits because at the very least some
460 * 486 CPUs did not behave this way. 459 * 486 CPUs did not behave this way.
461 */ 460 */
462 long tmp = -1;
463 asm("bsrl %1,%0" 461 asm("bsrl %1,%0"
464 : "=r" (r) 462 : "=r" (r)
465 : "rm" (x), "0" (tmp)); 463 : "rm" (x), "0" (-1));
466#elif defined(CONFIG_X86_CMOV) 464#elif defined(CONFIG_X86_CMOV)
467 asm("bsrl %1,%0\n\t" 465 asm("bsrl %1,%0\n\t"
468 "cmovzl %2,%0" 466 "cmovzl %2,%0"
@@ -490,13 +488,13 @@ static inline int fls(int x)
490#ifdef CONFIG_X86_64 488#ifdef CONFIG_X86_64
491static __always_inline int fls64(__u64 x) 489static __always_inline int fls64(__u64 x)
492{ 490{
493 long bitpos = -1; 491 int bitpos = -1;
494 /* 492 /*
495 * AMD64 says BSRQ won't clobber the dest reg if x==0; Intel64 says the 493 * AMD64 says BSRQ won't clobber the dest reg if x==0; Intel64 says the
496 * dest reg is undefined if x==0, but their CPU architect says its 494 * dest reg is undefined if x==0, but their CPU architect says its
497 * value is written to set it to the same as before. 495 * value is written to set it to the same as before.
498 */ 496 */
499 asm("bsrq %1,%0" 497 asm("bsrq %1,%q0"
500 : "+r" (bitpos) 498 : "+r" (bitpos)
501 : "rm" (x)); 499 : "rm" (x));
502 return bitpos + 1; 500 return bitpos + 1;
diff --git a/arch/x86/include/asm/calling.h b/arch/x86/include/asm/calling.h
index a9e3a740f697..7f8422a28a46 100644
--- a/arch/x86/include/asm/calling.h
+++ b/arch/x86/include/asm/calling.h
@@ -49,38 +49,36 @@ For 32-bit we have the following conventions - kernel is built with
49#include "dwarf2.h" 49#include "dwarf2.h"
50 50
51/* 51/*
52 * 64-bit system call stack frame layout defines and helpers, for 52 * 64-bit system call stack frame layout defines and helpers,
53 * assembly code (note that the seemingly unnecessary parentheses 53 * for assembly code:
54 * are to prevent cpp from inserting spaces in expressions that get
55 * passed to macros):
56 */ 54 */
57 55
58#define R15 (0) 56#define R15 0
59#define R14 (8) 57#define R14 8
60#define R13 (16) 58#define R13 16
61#define R12 (24) 59#define R12 24
62#define RBP (32) 60#define RBP 32
63#define RBX (40) 61#define RBX 40
64 62
65/* arguments: interrupts/non tracing syscalls only save up to here: */ 63/* arguments: interrupts/non tracing syscalls only save up to here: */
66#define R11 (48) 64#define R11 48
67#define R10 (56) 65#define R10 56
68#define R9 (64) 66#define R9 64
69#define R8 (72) 67#define R8 72
70#define RAX (80) 68#define RAX 80
71#define RCX (88) 69#define RCX 88
72#define RDX (96) 70#define RDX 96
73#define RSI (104) 71#define RSI 104
74#define RDI (112) 72#define RDI 112
75#define ORIG_RAX (120) /* + error_code */ 73#define ORIG_RAX 120 /* + error_code */
76/* end of arguments */ 74/* end of arguments */
77 75
78/* cpu exception frame or undefined in case of fast syscall: */ 76/* cpu exception frame or undefined in case of fast syscall: */
79#define RIP (128) 77#define RIP 128
80#define CS (136) 78#define CS 136
81#define EFLAGS (144) 79#define EFLAGS 144
82#define RSP (152) 80#define RSP 152
83#define SS (160) 81#define SS 160
84 82
85#define ARGOFFSET R11 83#define ARGOFFSET R11
86#define SWFRAME ORIG_RAX 84#define SWFRAME ORIG_RAX
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 6b7ee5ff6820..16cae425d1f8 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -97,6 +97,7 @@
97#define X86_FEATURE_EXTD_APICID (3*32+26) /* has extended APICID (8 bits) */ 97#define X86_FEATURE_EXTD_APICID (3*32+26) /* has extended APICID (8 bits) */
98#define X86_FEATURE_AMD_DCM (3*32+27) /* multi-node processor */ 98#define X86_FEATURE_AMD_DCM (3*32+27) /* multi-node processor */
99#define X86_FEATURE_APERFMPERF (3*32+28) /* APERFMPERF */ 99#define X86_FEATURE_APERFMPERF (3*32+28) /* APERFMPERF */
100#define X86_FEATURE_EAGER_FPU (3*32+29) /* "eagerfpu" Non lazy FPU restore */
100 101
101/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ 102/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
102#define X86_FEATURE_XMM3 (4*32+ 0) /* "pni" SSE-3 */ 103#define X86_FEATURE_XMM3 (4*32+ 0) /* "pni" SSE-3 */
@@ -209,6 +210,7 @@
209#define X86_FEATURE_RTM (9*32+11) /* Restricted Transactional Memory */ 210#define X86_FEATURE_RTM (9*32+11) /* Restricted Transactional Memory */
210#define X86_FEATURE_RDSEED (9*32+18) /* The RDSEED instruction */ 211#define X86_FEATURE_RDSEED (9*32+18) /* The RDSEED instruction */
211#define X86_FEATURE_ADX (9*32+19) /* The ADCX and ADOX instructions */ 212#define X86_FEATURE_ADX (9*32+19) /* The ADCX and ADOX instructions */
213#define X86_FEATURE_SMAP (9*32+20) /* Supervisor Mode Access Prevention */
212 214
213#if defined(__KERNEL__) && !defined(__ASSEMBLY__) 215#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
214 216
@@ -299,12 +301,14 @@ extern const char * const x86_power_flags[32];
299#define cpu_has_xmm4_2 boot_cpu_has(X86_FEATURE_XMM4_2) 301#define cpu_has_xmm4_2 boot_cpu_has(X86_FEATURE_XMM4_2)
300#define cpu_has_x2apic boot_cpu_has(X86_FEATURE_X2APIC) 302#define cpu_has_x2apic boot_cpu_has(X86_FEATURE_X2APIC)
301#define cpu_has_xsave boot_cpu_has(X86_FEATURE_XSAVE) 303#define cpu_has_xsave boot_cpu_has(X86_FEATURE_XSAVE)
304#define cpu_has_xsaveopt boot_cpu_has(X86_FEATURE_XSAVEOPT)
302#define cpu_has_osxsave boot_cpu_has(X86_FEATURE_OSXSAVE) 305#define cpu_has_osxsave boot_cpu_has(X86_FEATURE_OSXSAVE)
303#define cpu_has_hypervisor boot_cpu_has(X86_FEATURE_HYPERVISOR) 306#define cpu_has_hypervisor boot_cpu_has(X86_FEATURE_HYPERVISOR)
304#define cpu_has_pclmulqdq boot_cpu_has(X86_FEATURE_PCLMULQDQ) 307#define cpu_has_pclmulqdq boot_cpu_has(X86_FEATURE_PCLMULQDQ)
305#define cpu_has_perfctr_core boot_cpu_has(X86_FEATURE_PERFCTR_CORE) 308#define cpu_has_perfctr_core boot_cpu_has(X86_FEATURE_PERFCTR_CORE)
306#define cpu_has_cx8 boot_cpu_has(X86_FEATURE_CX8) 309#define cpu_has_cx8 boot_cpu_has(X86_FEATURE_CX8)
307#define cpu_has_cx16 boot_cpu_has(X86_FEATURE_CX16) 310#define cpu_has_cx16 boot_cpu_has(X86_FEATURE_CX16)
311#define cpu_has_eager_fpu boot_cpu_has(X86_FEATURE_EAGER_FPU)
308 312
309#if defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_64) 313#if defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_64)
310# define cpu_has_invlpg 1 314# define cpu_has_invlpg 1
diff --git a/arch/x86/include/asm/fpu-internal.h b/arch/x86/include/asm/fpu-internal.h
index 75f4c6d6a331..92f3c6ed817f 100644
--- a/arch/x86/include/asm/fpu-internal.h
+++ b/arch/x86/include/asm/fpu-internal.h
@@ -12,6 +12,7 @@
12 12
13#include <linux/kernel_stat.h> 13#include <linux/kernel_stat.h>
14#include <linux/regset.h> 14#include <linux/regset.h>
15#include <linux/compat.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <asm/asm.h> 17#include <asm/asm.h>
17#include <asm/cpufeature.h> 18#include <asm/cpufeature.h>
@@ -21,42 +22,74 @@
21#include <asm/uaccess.h> 22#include <asm/uaccess.h>
22#include <asm/xsave.h> 23#include <asm/xsave.h>
23 24
24extern unsigned int sig_xstate_size; 25#ifdef CONFIG_X86_64
26# include <asm/sigcontext32.h>
27# include <asm/user32.h>
28int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
29 compat_sigset_t *set, struct pt_regs *regs);
30int ia32_setup_frame(int sig, struct k_sigaction *ka,
31 compat_sigset_t *set, struct pt_regs *regs);
32#else
33# define user_i387_ia32_struct user_i387_struct
34# define user32_fxsr_struct user_fxsr_struct
35# define ia32_setup_frame __setup_frame
36# define ia32_setup_rt_frame __setup_rt_frame
37#endif
38
39extern unsigned int mxcsr_feature_mask;
25extern void fpu_init(void); 40extern void fpu_init(void);
41extern void eager_fpu_init(void);
26 42
27DECLARE_PER_CPU(struct task_struct *, fpu_owner_task); 43DECLARE_PER_CPU(struct task_struct *, fpu_owner_task);
28 44
45extern void convert_from_fxsr(struct user_i387_ia32_struct *env,
46 struct task_struct *tsk);
47extern void convert_to_fxsr(struct task_struct *tsk,
48 const struct user_i387_ia32_struct *env);
49
29extern user_regset_active_fn fpregs_active, xfpregs_active; 50extern user_regset_active_fn fpregs_active, xfpregs_active;
30extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get, 51extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get,
31 xstateregs_get; 52 xstateregs_get;
32extern user_regset_set_fn fpregs_set, xfpregs_set, fpregs_soft_set, 53extern user_regset_set_fn fpregs_set, xfpregs_set, fpregs_soft_set,
33 xstateregs_set; 54 xstateregs_set;
34 55
35
36/* 56/*
37 * xstateregs_active == fpregs_active. Please refer to the comment 57 * xstateregs_active == fpregs_active. Please refer to the comment
38 * at the definition of fpregs_active. 58 * at the definition of fpregs_active.
39 */ 59 */
40#define xstateregs_active fpregs_active 60#define xstateregs_active fpregs_active
41 61
42extern struct _fpx_sw_bytes fx_sw_reserved;
43#ifdef CONFIG_IA32_EMULATION
44extern unsigned int sig_xstate_ia32_size;
45extern struct _fpx_sw_bytes fx_sw_reserved_ia32;
46struct _fpstate_ia32;
47struct _xstate_ia32;
48extern int save_i387_xstate_ia32(void __user *buf);
49extern int restore_i387_xstate_ia32(void __user *buf);
50#endif
51
52#ifdef CONFIG_MATH_EMULATION 62#ifdef CONFIG_MATH_EMULATION
63# define HAVE_HWFP (boot_cpu_data.hard_math)
53extern void finit_soft_fpu(struct i387_soft_struct *soft); 64extern void finit_soft_fpu(struct i387_soft_struct *soft);
54#else 65#else
66# define HAVE_HWFP 1
55static inline void finit_soft_fpu(struct i387_soft_struct *soft) {} 67static inline void finit_soft_fpu(struct i387_soft_struct *soft) {}
56#endif 68#endif
57 69
70static inline int is_ia32_compat_frame(void)
71{
72 return config_enabled(CONFIG_IA32_EMULATION) &&
73 test_thread_flag(TIF_IA32);
74}
75
76static inline int is_ia32_frame(void)
77{
78 return config_enabled(CONFIG_X86_32) || is_ia32_compat_frame();
79}
80
81static inline int is_x32_frame(void)
82{
83 return config_enabled(CONFIG_X86_X32_ABI) && test_thread_flag(TIF_X32);
84}
85
58#define X87_FSW_ES (1 << 7) /* Exception Summary */ 86#define X87_FSW_ES (1 << 7) /* Exception Summary */
59 87
88static __always_inline __pure bool use_eager_fpu(void)
89{
90 return static_cpu_has(X86_FEATURE_EAGER_FPU);
91}
92
60static __always_inline __pure bool use_xsaveopt(void) 93static __always_inline __pure bool use_xsaveopt(void)
61{ 94{
62 return static_cpu_has(X86_FEATURE_XSAVEOPT); 95 return static_cpu_has(X86_FEATURE_XSAVEOPT);
@@ -72,6 +105,13 @@ static __always_inline __pure bool use_fxsr(void)
72 return static_cpu_has(X86_FEATURE_FXSR); 105 return static_cpu_has(X86_FEATURE_FXSR);
73} 106}
74 107
108static inline void fx_finit(struct i387_fxsave_struct *fx)
109{
110 memset(fx, 0, xstate_size);
111 fx->cwd = 0x37f;
112 fx->mxcsr = MXCSR_DEFAULT;
113}
114
75extern void __sanitize_i387_state(struct task_struct *); 115extern void __sanitize_i387_state(struct task_struct *);
76 116
77static inline void sanitize_i387_state(struct task_struct *tsk) 117static inline void sanitize_i387_state(struct task_struct *tsk)
@@ -81,131 +121,88 @@ static inline void sanitize_i387_state(struct task_struct *tsk)
81 __sanitize_i387_state(tsk); 121 __sanitize_i387_state(tsk);
82} 122}
83 123
84#ifdef CONFIG_X86_64 124#define check_insn(insn, output, input...) \
85static inline int fxrstor_checking(struct i387_fxsave_struct *fx) 125({ \
126 int err; \
127 asm volatile("1:" #insn "\n\t" \
128 "2:\n" \
129 ".section .fixup,\"ax\"\n" \
130 "3: movl $-1,%[err]\n" \
131 " jmp 2b\n" \
132 ".previous\n" \
133 _ASM_EXTABLE(1b, 3b) \
134 : [err] "=r" (err), output \
135 : "0"(0), input); \
136 err; \
137})
138
139static inline int fsave_user(struct i387_fsave_struct __user *fx)
86{ 140{
87 int err; 141 return check_insn(fnsave %[fx]; fwait, [fx] "=m" (*fx), "m" (*fx));
88
89 /* See comment in fxsave() below. */
90#ifdef CONFIG_AS_FXSAVEQ
91 asm volatile("1: fxrstorq %[fx]\n\t"
92 "2:\n"
93 ".section .fixup,\"ax\"\n"
94 "3: movl $-1,%[err]\n"
95 " jmp 2b\n"
96 ".previous\n"
97 _ASM_EXTABLE(1b, 3b)
98 : [err] "=r" (err)
99 : [fx] "m" (*fx), "0" (0));
100#else
101 asm volatile("1: rex64/fxrstor (%[fx])\n\t"
102 "2:\n"
103 ".section .fixup,\"ax\"\n"
104 "3: movl $-1,%[err]\n"
105 " jmp 2b\n"
106 ".previous\n"
107 _ASM_EXTABLE(1b, 3b)
108 : [err] "=r" (err)
109 : [fx] "R" (fx), "m" (*fx), "0" (0));
110#endif
111 return err;
112} 142}
113 143
114static inline int fxsave_user(struct i387_fxsave_struct __user *fx) 144static inline int fxsave_user(struct i387_fxsave_struct __user *fx)
115{ 145{
116 int err; 146 if (config_enabled(CONFIG_X86_32))
147 return check_insn(fxsave %[fx], [fx] "=m" (*fx), "m" (*fx));
148 else if (config_enabled(CONFIG_AS_FXSAVEQ))
149 return check_insn(fxsaveq %[fx], [fx] "=m" (*fx), "m" (*fx));
117 150
118 /* 151 /* See comment in fpu_fxsave() below. */
119 * Clear the bytes not touched by the fxsave and reserved 152 return check_insn(rex64/fxsave (%[fx]), "=m" (*fx), [fx] "R" (fx));
120 * for the SW usage.
121 */
122 err = __clear_user(&fx->sw_reserved,
123 sizeof(struct _fpx_sw_bytes));
124 if (unlikely(err))
125 return -EFAULT;
126
127 /* See comment in fxsave() below. */
128#ifdef CONFIG_AS_FXSAVEQ
129 asm volatile("1: fxsaveq %[fx]\n\t"
130 "2:\n"
131 ".section .fixup,\"ax\"\n"
132 "3: movl $-1,%[err]\n"
133 " jmp 2b\n"
134 ".previous\n"
135 _ASM_EXTABLE(1b, 3b)
136 : [err] "=r" (err), [fx] "=m" (*fx)
137 : "0" (0));
138#else
139 asm volatile("1: rex64/fxsave (%[fx])\n\t"
140 "2:\n"
141 ".section .fixup,\"ax\"\n"
142 "3: movl $-1,%[err]\n"
143 " jmp 2b\n"
144 ".previous\n"
145 _ASM_EXTABLE(1b, 3b)
146 : [err] "=r" (err), "=m" (*fx)
147 : [fx] "R" (fx), "0" (0));
148#endif
149 if (unlikely(err) &&
150 __clear_user(fx, sizeof(struct i387_fxsave_struct)))
151 err = -EFAULT;
152 /* No need to clear here because the caller clears USED_MATH */
153 return err;
154} 153}
155 154
156static inline void fpu_fxsave(struct fpu *fpu) 155static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
157{ 156{
158 /* Using "rex64; fxsave %0" is broken because, if the memory operand 157 if (config_enabled(CONFIG_X86_32))
159 uses any extended registers for addressing, a second REX prefix 158 return check_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
160 will be generated (to the assembler, rex64 followed by semicolon 159 else if (config_enabled(CONFIG_AS_FXSAVEQ))
161 is a separate instruction), and hence the 64-bitness is lost. */ 160 return check_insn(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx));
162 161
163#ifdef CONFIG_AS_FXSAVEQ 162 /* See comment in fpu_fxsave() below. */
164 /* Using "fxsaveq %0" would be the ideal choice, but is only supported 163 return check_insn(rex64/fxrstor (%[fx]), "=m" (*fx), [fx] "R" (fx),
165 starting with gas 2.16. */ 164 "m" (*fx));
166 __asm__ __volatile__("fxsaveq %0"
167 : "=m" (fpu->state->fxsave));
168#else
169 /* Using, as a workaround, the properly prefixed form below isn't
170 accepted by any binutils version so far released, complaining that
171 the same type of prefix is used twice if an extended register is
172 needed for addressing (fix submitted to mainline 2005-11-21).
173 asm volatile("rex64/fxsave %0"
174 : "=m" (fpu->state->fxsave));
175 This, however, we can work around by forcing the compiler to select
176 an addressing mode that doesn't require extended registers. */
177 asm volatile("rex64/fxsave (%[fx])"
178 : "=m" (fpu->state->fxsave)
179 : [fx] "R" (&fpu->state->fxsave));
180#endif
181} 165}
182 166
183#else /* CONFIG_X86_32 */ 167static inline int frstor_checking(struct i387_fsave_struct *fx)
184
185/* perform fxrstor iff the processor has extended states, otherwise frstor */
186static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
187{ 168{
188 /* 169 return check_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
189 * The "nop" is needed to make the instructions the same
190 * length.
191 */
192 alternative_input(
193 "nop ; frstor %1",
194 "fxrstor %1",
195 X86_FEATURE_FXSR,
196 "m" (*fx));
197
198 return 0;
199} 170}
200 171
201static inline void fpu_fxsave(struct fpu *fpu) 172static inline void fpu_fxsave(struct fpu *fpu)
202{ 173{
203 asm volatile("fxsave %[fx]" 174 if (config_enabled(CONFIG_X86_32))
204 : [fx] "=m" (fpu->state->fxsave)); 175 asm volatile( "fxsave %[fx]" : [fx] "=m" (fpu->state->fxsave));
176 else if (config_enabled(CONFIG_AS_FXSAVEQ))
177 asm volatile("fxsaveq %0" : "=m" (fpu->state->fxsave));
178 else {
179 /* Using "rex64; fxsave %0" is broken because, if the memory
180 * operand uses any extended registers for addressing, a second
181 * REX prefix will be generated (to the assembler, rex64
182 * followed by semicolon is a separate instruction), and hence
183 * the 64-bitness is lost.
184 *
185 * Using "fxsaveq %0" would be the ideal choice, but is only
186 * supported starting with gas 2.16.
187 *
188 * Using, as a workaround, the properly prefixed form below
189 * isn't accepted by any binutils version so far released,
190 * complaining that the same type of prefix is used twice if
191 * an extended register is needed for addressing (fix submitted
192 * to mainline 2005-11-21).
193 *
194 * asm volatile("rex64/fxsave %0" : "=m" (fpu->state->fxsave));
195 *
196 * This, however, we can work around by forcing the compiler to
197 * select an addressing mode that doesn't require extended
198 * registers.
199 */
200 asm volatile( "rex64/fxsave (%[fx])"
201 : "=m" (fpu->state->fxsave)
202 : [fx] "R" (&fpu->state->fxsave));
203 }
205} 204}
206 205
207#endif /* CONFIG_X86_64 */
208
209/* 206/*
210 * These must be called with preempt disabled. Returns 207 * These must be called with preempt disabled. Returns
211 * 'true' if the FPU state is still intact. 208 * 'true' if the FPU state is still intact.
@@ -248,17 +245,14 @@ static inline int __save_init_fpu(struct task_struct *tsk)
248 return fpu_save_init(&tsk->thread.fpu); 245 return fpu_save_init(&tsk->thread.fpu);
249} 246}
250 247
251static inline int fpu_fxrstor_checking(struct fpu *fpu)
252{
253 return fxrstor_checking(&fpu->state->fxsave);
254}
255
256static inline int fpu_restore_checking(struct fpu *fpu) 248static inline int fpu_restore_checking(struct fpu *fpu)
257{ 249{
258 if (use_xsave()) 250 if (use_xsave())
259 return fpu_xrstor_checking(fpu); 251 return fpu_xrstor_checking(&fpu->state->xsave);
252 else if (use_fxsr())
253 return fxrstor_checking(&fpu->state->fxsave);
260 else 254 else
261 return fpu_fxrstor_checking(fpu); 255 return frstor_checking(&fpu->state->fsave);
262} 256}
263 257
264static inline int restore_fpu_checking(struct task_struct *tsk) 258static inline int restore_fpu_checking(struct task_struct *tsk)
@@ -310,15 +304,52 @@ static inline void __thread_set_has_fpu(struct task_struct *tsk)
310static inline void __thread_fpu_end(struct task_struct *tsk) 304static inline void __thread_fpu_end(struct task_struct *tsk)
311{ 305{
312 __thread_clear_has_fpu(tsk); 306 __thread_clear_has_fpu(tsk);
313 stts(); 307 if (!use_eager_fpu())
308 stts();
314} 309}
315 310
316static inline void __thread_fpu_begin(struct task_struct *tsk) 311static inline void __thread_fpu_begin(struct task_struct *tsk)
317{ 312{
318 clts(); 313 if (!use_eager_fpu())
314 clts();
319 __thread_set_has_fpu(tsk); 315 __thread_set_has_fpu(tsk);
320} 316}
321 317
318static inline void __drop_fpu(struct task_struct *tsk)
319{
320 if (__thread_has_fpu(tsk)) {
321 /* Ignore delayed exceptions from user space */
322 asm volatile("1: fwait\n"
323 "2:\n"
324 _ASM_EXTABLE(1b, 2b));
325 __thread_fpu_end(tsk);
326 }
327}
328
329static inline void drop_fpu(struct task_struct *tsk)
330{
331 /*
332 * Forget coprocessor state..
333 */
334 preempt_disable();
335 tsk->fpu_counter = 0;
336 __drop_fpu(tsk);
337 clear_used_math();
338 preempt_enable();
339}
340
341static inline void drop_init_fpu(struct task_struct *tsk)
342{
343 if (!use_eager_fpu())
344 drop_fpu(tsk);
345 else {
346 if (use_xsave())
347 xrstor_state(init_xstate_buf, -1);
348 else
349 fxrstor_checking(&init_xstate_buf->i387);
350 }
351}
352
322/* 353/*
323 * FPU state switching for scheduling. 354 * FPU state switching for scheduling.
324 * 355 *
@@ -352,7 +383,12 @@ static inline fpu_switch_t switch_fpu_prepare(struct task_struct *old, struct ta
352{ 383{
353 fpu_switch_t fpu; 384 fpu_switch_t fpu;
354 385
355 fpu.preload = tsk_used_math(new) && new->fpu_counter > 5; 386 /*
387 * If the task has used the math, pre-load the FPU on xsave processors
388 * or if the past 5 consecutive context-switches used math.
389 */
390 fpu.preload = tsk_used_math(new) && (use_eager_fpu() ||
391 new->fpu_counter > 5);
356 if (__thread_has_fpu(old)) { 392 if (__thread_has_fpu(old)) {
357 if (!__save_init_fpu(old)) 393 if (!__save_init_fpu(old))
358 cpu = ~0; 394 cpu = ~0;
@@ -364,14 +400,14 @@ static inline fpu_switch_t switch_fpu_prepare(struct task_struct *old, struct ta
364 new->fpu_counter++; 400 new->fpu_counter++;
365 __thread_set_has_fpu(new); 401 __thread_set_has_fpu(new);
366 prefetch(new->thread.fpu.state); 402 prefetch(new->thread.fpu.state);
367 } else 403 } else if (!use_eager_fpu())
368 stts(); 404 stts();
369 } else { 405 } else {
370 old->fpu_counter = 0; 406 old->fpu_counter = 0;
371 old->thread.fpu.last_cpu = ~0; 407 old->thread.fpu.last_cpu = ~0;
372 if (fpu.preload) { 408 if (fpu.preload) {
373 new->fpu_counter++; 409 new->fpu_counter++;
374 if (fpu_lazy_restore(new, cpu)) 410 if (!use_eager_fpu() && fpu_lazy_restore(new, cpu))
375 fpu.preload = 0; 411 fpu.preload = 0;
376 else 412 else
377 prefetch(new->thread.fpu.state); 413 prefetch(new->thread.fpu.state);
@@ -391,44 +427,40 @@ static inline void switch_fpu_finish(struct task_struct *new, fpu_switch_t fpu)
391{ 427{
392 if (fpu.preload) { 428 if (fpu.preload) {
393 if (unlikely(restore_fpu_checking(new))) 429 if (unlikely(restore_fpu_checking(new)))
394 __thread_fpu_end(new); 430 drop_init_fpu(new);
395 } 431 }
396} 432}
397 433
398/* 434/*
399 * Signal frame handlers... 435 * Signal frame handlers...
400 */ 436 */
401extern int save_i387_xstate(void __user *buf); 437extern int save_xstate_sig(void __user *buf, void __user *fx, int size);
402extern int restore_i387_xstate(void __user *buf); 438extern int __restore_xstate_sig(void __user *buf, void __user *fx, int size);
403 439
404static inline void __clear_fpu(struct task_struct *tsk) 440static inline int xstate_sigframe_size(void)
405{ 441{
406 if (__thread_has_fpu(tsk)) { 442 return use_xsave() ? xstate_size + FP_XSTATE_MAGIC2_SIZE : xstate_size;
407 /* Ignore delayed exceptions from user space */ 443}
408 asm volatile("1: fwait\n" 444
409 "2:\n" 445static inline int restore_xstate_sig(void __user *buf, int ia32_frame)
410 _ASM_EXTABLE(1b, 2b)); 446{
411 __thread_fpu_end(tsk); 447 void __user *buf_fx = buf;
448 int size = xstate_sigframe_size();
449
450 if (ia32_frame && use_fxsr()) {
451 buf_fx = buf + sizeof(struct i387_fsave_struct);
452 size += sizeof(struct i387_fsave_struct);
412 } 453 }
454
455 return __restore_xstate_sig(buf, buf_fx, size);
413} 456}
414 457
415/* 458/*
416 * The actual user_fpu_begin/end() functions 459 * Need to be preemption-safe.
417 * need to be preemption-safe.
418 * 460 *
419 * NOTE! user_fpu_end() must be used only after you 461 * NOTE! user_fpu_begin() must be used only immediately before restoring
420 * have saved the FP state, and user_fpu_begin() must 462 * it. This function does not do any save/restore on their own.
421 * be used only immediately before restoring it.
422 * These functions do not do any save/restore on
423 * their own.
424 */ 463 */
425static inline void user_fpu_end(void)
426{
427 preempt_disable();
428 __thread_fpu_end(current);
429 preempt_enable();
430}
431
432static inline void user_fpu_begin(void) 464static inline void user_fpu_begin(void)
433{ 465{
434 preempt_disable(); 466 preempt_disable();
@@ -437,25 +469,32 @@ static inline void user_fpu_begin(void)
437 preempt_enable(); 469 preempt_enable();
438} 470}
439 471
472static inline void __save_fpu(struct task_struct *tsk)
473{
474 if (use_xsave())
475 xsave_state(&tsk->thread.fpu.state->xsave, -1);
476 else
477 fpu_fxsave(&tsk->thread.fpu);
478}
479
440/* 480/*
441 * These disable preemption on their own and are safe 481 * These disable preemption on their own and are safe
442 */ 482 */
443static inline void save_init_fpu(struct task_struct *tsk) 483static inline void save_init_fpu(struct task_struct *tsk)
444{ 484{
445 WARN_ON_ONCE(!__thread_has_fpu(tsk)); 485 WARN_ON_ONCE(!__thread_has_fpu(tsk));
486
487 if (use_eager_fpu()) {
488 __save_fpu(tsk);
489 return;
490 }
491
446 preempt_disable(); 492 preempt_disable();
447 __save_init_fpu(tsk); 493 __save_init_fpu(tsk);
448 __thread_fpu_end(tsk); 494 __thread_fpu_end(tsk);
449 preempt_enable(); 495 preempt_enable();
450} 496}
451 497
452static inline void clear_fpu(struct task_struct *tsk)
453{
454 preempt_disable();
455 __clear_fpu(tsk);
456 preempt_enable();
457}
458
459/* 498/*
460 * i387 state interaction 499 * i387 state interaction
461 */ 500 */
@@ -510,11 +549,34 @@ static inline void fpu_free(struct fpu *fpu)
510 } 549 }
511} 550}
512 551
513static inline void fpu_copy(struct fpu *dst, struct fpu *src) 552static inline void fpu_copy(struct task_struct *dst, struct task_struct *src)
514{ 553{
515 memcpy(dst->state, src->state, xstate_size); 554 if (use_eager_fpu()) {
555 memset(&dst->thread.fpu.state->xsave, 0, xstate_size);
556 __save_fpu(dst);
557 } else {
558 struct fpu *dfpu = &dst->thread.fpu;
559 struct fpu *sfpu = &src->thread.fpu;
560
561 unlazy_fpu(src);
562 memcpy(dfpu->state, sfpu->state, xstate_size);
563 }
516} 564}
517 565
518extern void fpu_finit(struct fpu *fpu); 566static inline unsigned long
567alloc_mathframe(unsigned long sp, int ia32_frame, unsigned long *buf_fx,
568 unsigned long *size)
569{
570 unsigned long frame_size = xstate_sigframe_size();
571
572 *buf_fx = sp = round_down(sp - frame_size, 64);
573 if (ia32_frame && use_fxsr()) {
574 frame_size += sizeof(struct i387_fsave_struct);
575 sp -= sizeof(struct i387_fsave_struct);
576 }
577
578 *size = frame_size;
579 return sp;
580}
519 581
520#endif 582#endif
diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h
index b0767bc08740..9a25b522d377 100644
--- a/arch/x86/include/asm/ftrace.h
+++ b/arch/x86/include/asm/ftrace.h
@@ -3,38 +3,54 @@
3 3
4#ifdef __ASSEMBLY__ 4#ifdef __ASSEMBLY__
5 5
6 .macro MCOUNT_SAVE_FRAME 6 /* skip is set if the stack was already partially adjusted */
7 /* taken from glibc */ 7 .macro MCOUNT_SAVE_FRAME skip=0
8 subq $0x38, %rsp 8 /*
9 movq %rax, (%rsp) 9 * We add enough stack to save all regs.
10 movq %rcx, 8(%rsp) 10 */
11 movq %rdx, 16(%rsp) 11 subq $(SS+8-\skip), %rsp
12 movq %rsi, 24(%rsp) 12 movq %rax, RAX(%rsp)
13 movq %rdi, 32(%rsp) 13 movq %rcx, RCX(%rsp)
14 movq %r8, 40(%rsp) 14 movq %rdx, RDX(%rsp)
15 movq %r9, 48(%rsp) 15 movq %rsi, RSI(%rsp)
16 movq %rdi, RDI(%rsp)
17 movq %r8, R8(%rsp)
18 movq %r9, R9(%rsp)
19 /* Move RIP to its proper location */
20 movq SS+8(%rsp), %rdx
21 movq %rdx, RIP(%rsp)
16 .endm 22 .endm
17 23
18 .macro MCOUNT_RESTORE_FRAME 24 .macro MCOUNT_RESTORE_FRAME skip=0
19 movq 48(%rsp), %r9 25 movq R9(%rsp), %r9
20 movq 40(%rsp), %r8 26 movq R8(%rsp), %r8
21 movq 32(%rsp), %rdi 27 movq RDI(%rsp), %rdi
22 movq 24(%rsp), %rsi 28 movq RSI(%rsp), %rsi
23 movq 16(%rsp), %rdx 29 movq RDX(%rsp), %rdx
24 movq 8(%rsp), %rcx 30 movq RCX(%rsp), %rcx
25 movq (%rsp), %rax 31 movq RAX(%rsp), %rax
26 addq $0x38, %rsp 32 addq $(SS+8-\skip), %rsp
27 .endm 33 .endm
28 34
29#endif 35#endif
30 36
31#ifdef CONFIG_FUNCTION_TRACER 37#ifdef CONFIG_FUNCTION_TRACER
32#define MCOUNT_ADDR ((long)(mcount)) 38#ifdef CC_USING_FENTRY
39# define MCOUNT_ADDR ((long)(__fentry__))
40#else
41# define MCOUNT_ADDR ((long)(mcount))
42#endif
33#define MCOUNT_INSN_SIZE 5 /* sizeof mcount call */ 43#define MCOUNT_INSN_SIZE 5 /* sizeof mcount call */
34 44
45#ifdef CONFIG_DYNAMIC_FTRACE
46#define ARCH_SUPPORTS_FTRACE_OPS 1
47#define ARCH_SUPPORTS_FTRACE_SAVE_REGS
48#endif
49
35#ifndef __ASSEMBLY__ 50#ifndef __ASSEMBLY__
36extern void mcount(void); 51extern void mcount(void);
37extern atomic_t modifying_ftrace_code; 52extern atomic_t modifying_ftrace_code;
53extern void __fentry__(void);
38 54
39static inline unsigned long ftrace_call_adjust(unsigned long addr) 55static inline unsigned long ftrace_call_adjust(unsigned long addr)
40{ 56{
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index d3895dbf4ddb..81f04cee5f74 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -18,6 +18,10 @@ typedef struct {
18#ifdef CONFIG_SMP 18#ifdef CONFIG_SMP
19 unsigned int irq_resched_count; 19 unsigned int irq_resched_count;
20 unsigned int irq_call_count; 20 unsigned int irq_call_count;
21 /*
22 * irq_tlb_count is double-counted in irq_call_count, so it must be
23 * subtracted from irq_call_count when displaying irq_call_count
24 */
21 unsigned int irq_tlb_count; 25 unsigned int irq_tlb_count;
22#endif 26#endif
23#ifdef CONFIG_X86_THERMAL_VECTOR 27#ifdef CONFIG_X86_THERMAL_VECTOR
diff --git a/arch/x86/include/asm/hpet.h b/arch/x86/include/asm/hpet.h
index 2c392d663dce..434e2106cc87 100644
--- a/arch/x86/include/asm/hpet.h
+++ b/arch/x86/include/asm/hpet.h
@@ -35,8 +35,6 @@
35#define HPET_ID_NUMBER_SHIFT 8 35#define HPET_ID_NUMBER_SHIFT 8
36#define HPET_ID_VENDOR_SHIFT 16 36#define HPET_ID_VENDOR_SHIFT 16
37 37
38#define HPET_ID_VENDOR_8086 0x8086
39
40#define HPET_CFG_ENABLE 0x001 38#define HPET_CFG_ENABLE 0x001
41#define HPET_CFG_LEGACY 0x002 39#define HPET_CFG_LEGACY 0x002
42#define HPET_LEGACY_8254 2 40#define HPET_LEGACY_8254 2
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h
index 257d9cca214f..ed8089d69094 100644
--- a/arch/x86/include/asm/i387.h
+++ b/arch/x86/include/asm/i387.h
@@ -19,12 +19,37 @@ struct pt_regs;
19struct user_i387_struct; 19struct user_i387_struct;
20 20
21extern int init_fpu(struct task_struct *child); 21extern int init_fpu(struct task_struct *child);
22extern void fpu_finit(struct fpu *fpu);
22extern int dump_fpu(struct pt_regs *, struct user_i387_struct *); 23extern int dump_fpu(struct pt_regs *, struct user_i387_struct *);
23extern void math_state_restore(void); 24extern void math_state_restore(void);
24 25
25extern bool irq_fpu_usable(void); 26extern bool irq_fpu_usable(void);
26extern void kernel_fpu_begin(void); 27
27extern void kernel_fpu_end(void); 28/*
29 * Careful: __kernel_fpu_begin/end() must be called with preempt disabled
30 * and they don't touch the preempt state on their own.
31 * If you enable preemption after __kernel_fpu_begin(), preempt notifier
32 * should call the __kernel_fpu_end() to prevent the kernel/user FPU
33 * state from getting corrupted. KVM for example uses this model.
34 *
35 * All other cases use kernel_fpu_begin/end() which disable preemption
36 * during kernel FPU usage.
37 */
38extern void __kernel_fpu_begin(void);
39extern void __kernel_fpu_end(void);
40
41static inline void kernel_fpu_begin(void)
42{
43 WARN_ON_ONCE(!irq_fpu_usable());
44 preempt_disable();
45 __kernel_fpu_begin();
46}
47
48static inline void kernel_fpu_end(void)
49{
50 __kernel_fpu_end();
51 preempt_enable();
52}
28 53
29/* 54/*
30 * Some instructions like VIA's padlock instructions generate a spurious 55 * Some instructions like VIA's padlock instructions generate a spurious
diff --git a/arch/x86/include/asm/iommu_table.h b/arch/x86/include/asm/iommu_table.h
index f229b13a5f30..f42a04735a0a 100644
--- a/arch/x86/include/asm/iommu_table.h
+++ b/arch/x86/include/asm/iommu_table.h
@@ -48,7 +48,7 @@ struct iommu_table_entry {
48 48
49 49
50#define __IOMMU_INIT(_detect, _depend, _early_init, _late_init, _finish)\ 50#define __IOMMU_INIT(_detect, _depend, _early_init, _late_init, _finish)\
51 static const struct iommu_table_entry const \ 51 static const struct iommu_table_entry \
52 __iommu_entry_##_detect __used \ 52 __iommu_entry_##_detect __used \
53 __attribute__ ((unused, __section__(".iommu_table"), \ 53 __attribute__ ((unused, __section__(".iommu_table"), \
54 aligned((sizeof(void *))))) \ 54 aligned((sizeof(void *))))) \
@@ -63,10 +63,10 @@ struct iommu_table_entry {
63 * to stop detecting the other IOMMUs after yours has been detected. 63 * to stop detecting the other IOMMUs after yours has been detected.
64 */ 64 */
65#define IOMMU_INIT_POST(_detect) \ 65#define IOMMU_INIT_POST(_detect) \
66 __IOMMU_INIT(_detect, pci_swiotlb_detect_4gb, 0, 0, 0) 66 __IOMMU_INIT(_detect, pci_swiotlb_detect_4gb, NULL, NULL, 0)
67 67
68#define IOMMU_INIT_POST_FINISH(detect) \ 68#define IOMMU_INIT_POST_FINISH(detect) \
69 __IOMMU_INIT(_detect, pci_swiotlb_detect_4gb, 0, 0, 1) 69 __IOMMU_INIT(_detect, pci_swiotlb_detect_4gb, NULL, NULL, 1)
70 70
71/* 71/*
72 * A more sophisticated version of IOMMU_INIT. This variant requires: 72 * A more sophisticated version of IOMMU_INIT. This variant requires:
diff --git a/arch/x86/include/asm/kprobes.h b/arch/x86/include/asm/kprobes.h
index 547882539157..d3ddd17405d0 100644
--- a/arch/x86/include/asm/kprobes.h
+++ b/arch/x86/include/asm/kprobes.h
@@ -27,6 +27,7 @@
27#include <asm/insn.h> 27#include <asm/insn.h>
28 28
29#define __ARCH_WANT_KPROBES_INSN_SLOT 29#define __ARCH_WANT_KPROBES_INSN_SLOT
30#define ARCH_SUPPORTS_KPROBES_ON_FTRACE
30 31
31struct pt_regs; 32struct pt_regs;
32struct kprobe; 33struct kprobe;
diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h
index 246617efd67f..41e08cb6a092 100644
--- a/arch/x86/include/asm/kvm.h
+++ b/arch/x86/include/asm/kvm.h
@@ -9,6 +9,22 @@
9#include <linux/types.h> 9#include <linux/types.h>
10#include <linux/ioctl.h> 10#include <linux/ioctl.h>
11 11
12#define DE_VECTOR 0
13#define DB_VECTOR 1
14#define BP_VECTOR 3
15#define OF_VECTOR 4
16#define BR_VECTOR 5
17#define UD_VECTOR 6
18#define NM_VECTOR 7
19#define DF_VECTOR 8
20#define TS_VECTOR 10
21#define NP_VECTOR 11
22#define SS_VECTOR 12
23#define GP_VECTOR 13
24#define PF_VECTOR 14
25#define MF_VECTOR 16
26#define MC_VECTOR 18
27
12/* Select x86 specific features in <linux/kvm.h> */ 28/* Select x86 specific features in <linux/kvm.h> */
13#define __KVM_HAVE_PIT 29#define __KVM_HAVE_PIT
14#define __KVM_HAVE_IOAPIC 30#define __KVM_HAVE_IOAPIC
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 09155d64cf7e..1eaa6b056670 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -75,22 +75,6 @@
75#define KVM_HPAGE_MASK(x) (~(KVM_HPAGE_SIZE(x) - 1)) 75#define KVM_HPAGE_MASK(x) (~(KVM_HPAGE_SIZE(x) - 1))
76#define KVM_PAGES_PER_HPAGE(x) (KVM_HPAGE_SIZE(x) / PAGE_SIZE) 76#define KVM_PAGES_PER_HPAGE(x) (KVM_HPAGE_SIZE(x) / PAGE_SIZE)
77 77
78#define DE_VECTOR 0
79#define DB_VECTOR 1
80#define BP_VECTOR 3
81#define OF_VECTOR 4
82#define BR_VECTOR 5
83#define UD_VECTOR 6
84#define NM_VECTOR 7
85#define DF_VECTOR 8
86#define TS_VECTOR 10
87#define NP_VECTOR 11
88#define SS_VECTOR 12
89#define GP_VECTOR 13
90#define PF_VECTOR 14
91#define MF_VECTOR 16
92#define MC_VECTOR 18
93
94#define SELECTOR_TI_MASK (1 << 2) 78#define SELECTOR_TI_MASK (1 << 2)
95#define SELECTOR_RPL_MASK 0x03 79#define SELECTOR_RPL_MASK 0x03
96 80
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index a3ac52b29cbf..54d73b1f00a0 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -116,19 +116,9 @@ struct mce_log {
116/* Software defined banks */ 116/* Software defined banks */
117#define MCE_EXTENDED_BANK 128 117#define MCE_EXTENDED_BANK 128
118#define MCE_THERMAL_BANK MCE_EXTENDED_BANK + 0 118#define MCE_THERMAL_BANK MCE_EXTENDED_BANK + 0
119 119#define K8_MCE_THRESHOLD_BASE (MCE_EXTENDED_BANK + 1)
120#define K8_MCE_THRESHOLD_BASE (MCE_EXTENDED_BANK + 1) /* MCE_AMD */
121#define K8_MCE_THRESHOLD_BANK_0 (MCE_THRESHOLD_BASE + 0 * 9)
122#define K8_MCE_THRESHOLD_BANK_1 (MCE_THRESHOLD_BASE + 1 * 9)
123#define K8_MCE_THRESHOLD_BANK_2 (MCE_THRESHOLD_BASE + 2 * 9)
124#define K8_MCE_THRESHOLD_BANK_3 (MCE_THRESHOLD_BASE + 3 * 9)
125#define K8_MCE_THRESHOLD_BANK_4 (MCE_THRESHOLD_BASE + 4 * 9)
126#define K8_MCE_THRESHOLD_BANK_5 (MCE_THRESHOLD_BASE + 5 * 9)
127#define K8_MCE_THRESHOLD_DRAM_ECC (MCE_THRESHOLD_BANK_4 + 0)
128
129 120
130#ifdef __KERNEL__ 121#ifdef __KERNEL__
131
132extern void mce_register_decode_chain(struct notifier_block *nb); 122extern void mce_register_decode_chain(struct notifier_block *nb);
133extern void mce_unregister_decode_chain(struct notifier_block *nb); 123extern void mce_unregister_decode_chain(struct notifier_block *nb);
134 124
@@ -171,6 +161,7 @@ DECLARE_PER_CPU(struct device *, mce_device);
171#ifdef CONFIG_X86_MCE_INTEL 161#ifdef CONFIG_X86_MCE_INTEL
172extern int mce_cmci_disabled; 162extern int mce_cmci_disabled;
173extern int mce_ignore_ce; 163extern int mce_ignore_ce;
164extern int mce_bios_cmci_threshold;
174void mce_intel_feature_init(struct cpuinfo_x86 *c); 165void mce_intel_feature_init(struct cpuinfo_x86 *c);
175void cmci_clear(void); 166void cmci_clear(void);
176void cmci_reenable(void); 167void cmci_reenable(void);
diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index 4ebe157bf73d..43d921b4752c 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -15,8 +15,8 @@ struct microcode_ops {
15 enum ucode_state (*request_microcode_user) (int cpu, 15 enum ucode_state (*request_microcode_user) (int cpu,
16 const void __user *buf, size_t size); 16 const void __user *buf, size_t size);
17 17
18 enum ucode_state (*request_microcode_fw) (int cpu, 18 enum ucode_state (*request_microcode_fw) (int cpu, struct device *,
19 struct device *device); 19 bool refresh_fw);
20 20
21 void (*microcode_fini_cpu) (int cpu); 21 void (*microcode_fini_cpu) (int cpu);
22 22
@@ -49,12 +49,6 @@ static inline struct microcode_ops * __init init_intel_microcode(void)
49#ifdef CONFIG_MICROCODE_AMD 49#ifdef CONFIG_MICROCODE_AMD
50extern struct microcode_ops * __init init_amd_microcode(void); 50extern struct microcode_ops * __init init_amd_microcode(void);
51extern void __exit exit_amd_microcode(void); 51extern void __exit exit_amd_microcode(void);
52
53static inline void get_ucode_data(void *to, const u8 *from, size_t n)
54{
55 memcpy(to, from, n);
56}
57
58#else 52#else
59static inline struct microcode_ops * __init init_amd_microcode(void) 53static inline struct microcode_ops * __init init_amd_microcode(void)
60{ 54{
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index cb4e43bce98a..4fabcdf1cfa7 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -262,4 +262,6 @@ static inline void perf_check_microcode(void) { }
262 static inline void amd_pmu_disable_virt(void) { } 262 static inline void amd_pmu_disable_virt(void) { }
263#endif 263#endif
264 264
265#define arch_perf_out_copy_user copy_from_user_nmi
266
265#endif /* _ASM_X86_PERF_EVENT_H */ 267#endif /* _ASM_X86_PERF_EVENT_H */
diff --git a/arch/x86/include/asm/perf_regs.h b/arch/x86/include/asm/perf_regs.h
new file mode 100644
index 000000000000..3f2207bfd17b
--- /dev/null
+++ b/arch/x86/include/asm/perf_regs.h
@@ -0,0 +1,33 @@
1#ifndef _ASM_X86_PERF_REGS_H
2#define _ASM_X86_PERF_REGS_H
3
4enum perf_event_x86_regs {
5 PERF_REG_X86_AX,
6 PERF_REG_X86_BX,
7 PERF_REG_X86_CX,
8 PERF_REG_X86_DX,
9 PERF_REG_X86_SI,
10 PERF_REG_X86_DI,
11 PERF_REG_X86_BP,
12 PERF_REG_X86_SP,
13 PERF_REG_X86_IP,
14 PERF_REG_X86_FLAGS,
15 PERF_REG_X86_CS,
16 PERF_REG_X86_SS,
17 PERF_REG_X86_DS,
18 PERF_REG_X86_ES,
19 PERF_REG_X86_FS,
20 PERF_REG_X86_GS,
21 PERF_REG_X86_R8,
22 PERF_REG_X86_R9,
23 PERF_REG_X86_R10,
24 PERF_REG_X86_R11,
25 PERF_REG_X86_R12,
26 PERF_REG_X86_R13,
27 PERF_REG_X86_R14,
28 PERF_REG_X86_R15,
29
30 PERF_REG_X86_32_MAX = PERF_REG_X86_GS + 1,
31 PERF_REG_X86_64_MAX = PERF_REG_X86_R15 + 1,
32};
33#endif /* _ASM_X86_PERF_REGS_H */
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
index 013286a10c2c..db8fec6d2953 100644
--- a/arch/x86/include/asm/pgtable_types.h
+++ b/arch/x86/include/asm/pgtable_types.h
@@ -303,11 +303,9 @@ void set_pte_vaddr(unsigned long vaddr, pte_t pte);
303 303
304extern void native_pagetable_reserve(u64 start, u64 end); 304extern void native_pagetable_reserve(u64 start, u64 end);
305#ifdef CONFIG_X86_32 305#ifdef CONFIG_X86_32
306extern void native_pagetable_setup_start(pgd_t *base); 306extern void native_pagetable_init(void);
307extern void native_pagetable_setup_done(pgd_t *base);
308#else 307#else
309#define native_pagetable_setup_start x86_init_pgd_noop 308#define native_pagetable_init paging_init
310#define native_pagetable_setup_done x86_init_pgd_noop
311#endif 309#endif
312 310
313struct seq_file; 311struct seq_file;
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index d048cad9bcad..b98c0d958ebb 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -423,7 +423,6 @@ DECLARE_INIT_PER_CPU(irq_stack_union);
423 423
424DECLARE_PER_CPU(char *, irq_stack_ptr); 424DECLARE_PER_CPU(char *, irq_stack_ptr);
425DECLARE_PER_CPU(unsigned int, irq_count); 425DECLARE_PER_CPU(unsigned int, irq_count);
426extern unsigned long kernel_eflags;
427extern asmlinkage void ignore_sysret(void); 426extern asmlinkage void ignore_sysret(void);
428#else /* X86_64 */ 427#else /* X86_64 */
429#ifdef CONFIG_CC_STACKPROTECTOR 428#ifdef CONFIG_CC_STACKPROTECTOR
@@ -759,6 +758,8 @@ static inline void update_debugctlmsr(unsigned long debugctlmsr)
759 wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr); 758 wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr);
760} 759}
761 760
761extern void set_task_blockstep(struct task_struct *task, bool on);
762
762/* 763/*
763 * from system description table in BIOS. Mostly for MCA use, but 764 * from system description table in BIOS. Mostly for MCA use, but
764 * others may find it useful: 765 * others may find it useful:
diff --git a/arch/x86/include/asm/rcu.h b/arch/x86/include/asm/rcu.h
new file mode 100644
index 000000000000..d1ac07a23979
--- /dev/null
+++ b/arch/x86/include/asm/rcu.h
@@ -0,0 +1,32 @@
1#ifndef _ASM_X86_RCU_H
2#define _ASM_X86_RCU_H
3
4#ifndef __ASSEMBLY__
5
6#include <linux/rcupdate.h>
7#include <asm/ptrace.h>
8
9static inline void exception_enter(struct pt_regs *regs)
10{
11 rcu_user_exit();
12}
13
14static inline void exception_exit(struct pt_regs *regs)
15{
16#ifdef CONFIG_RCU_USER_QS
17 if (user_mode(regs))
18 rcu_user_enter();
19#endif
20}
21
22#else /* __ASSEMBLY__ */
23
24#ifdef CONFIG_RCU_USER_QS
25# define SCHEDULE_USER call schedule_user
26#else
27# define SCHEDULE_USER call schedule
28#endif
29
30#endif /* !__ASSEMBLY__ */
31
32#endif
diff --git a/arch/x86/include/asm/signal.h b/arch/x86/include/asm/signal.h
index 598457cbd0f8..323973f4abf1 100644
--- a/arch/x86/include/asm/signal.h
+++ b/arch/x86/include/asm/signal.h
@@ -31,6 +31,10 @@ typedef struct {
31 unsigned long sig[_NSIG_WORDS]; 31 unsigned long sig[_NSIG_WORDS];
32} sigset_t; 32} sigset_t;
33 33
34#ifndef CONFIG_COMPAT
35typedef sigset_t compat_sigset_t;
36#endif
37
34#else 38#else
35/* Here we must cater to libcs that poke about in kernel headers. */ 39/* Here we must cater to libcs that poke about in kernel headers. */
36 40
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index f2b83bc7d784..cdf5674dd23a 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -1,6 +1,135 @@
1#ifndef __SVM_H 1#ifndef __SVM_H
2#define __SVM_H 2#define __SVM_H
3 3
4#define SVM_EXIT_READ_CR0 0x000
5#define SVM_EXIT_READ_CR3 0x003
6#define SVM_EXIT_READ_CR4 0x004
7#define SVM_EXIT_READ_CR8 0x008
8#define SVM_EXIT_WRITE_CR0 0x010
9#define SVM_EXIT_WRITE_CR3 0x013
10#define SVM_EXIT_WRITE_CR4 0x014
11#define SVM_EXIT_WRITE_CR8 0x018
12#define SVM_EXIT_READ_DR0 0x020
13#define SVM_EXIT_READ_DR1 0x021
14#define SVM_EXIT_READ_DR2 0x022
15#define SVM_EXIT_READ_DR3 0x023
16#define SVM_EXIT_READ_DR4 0x024
17#define SVM_EXIT_READ_DR5 0x025
18#define SVM_EXIT_READ_DR6 0x026
19#define SVM_EXIT_READ_DR7 0x027
20#define SVM_EXIT_WRITE_DR0 0x030
21#define SVM_EXIT_WRITE_DR1 0x031
22#define SVM_EXIT_WRITE_DR2 0x032
23#define SVM_EXIT_WRITE_DR3 0x033
24#define SVM_EXIT_WRITE_DR4 0x034
25#define SVM_EXIT_WRITE_DR5 0x035
26#define SVM_EXIT_WRITE_DR6 0x036
27#define SVM_EXIT_WRITE_DR7 0x037
28#define SVM_EXIT_EXCP_BASE 0x040
29#define SVM_EXIT_INTR 0x060
30#define SVM_EXIT_NMI 0x061
31#define SVM_EXIT_SMI 0x062
32#define SVM_EXIT_INIT 0x063
33#define SVM_EXIT_VINTR 0x064
34#define SVM_EXIT_CR0_SEL_WRITE 0x065
35#define SVM_EXIT_IDTR_READ 0x066
36#define SVM_EXIT_GDTR_READ 0x067
37#define SVM_EXIT_LDTR_READ 0x068
38#define SVM_EXIT_TR_READ 0x069
39#define SVM_EXIT_IDTR_WRITE 0x06a
40#define SVM_EXIT_GDTR_WRITE 0x06b
41#define SVM_EXIT_LDTR_WRITE 0x06c
42#define SVM_EXIT_TR_WRITE 0x06d
43#define SVM_EXIT_RDTSC 0x06e
44#define SVM_EXIT_RDPMC 0x06f
45#define SVM_EXIT_PUSHF 0x070
46#define SVM_EXIT_POPF 0x071
47#define SVM_EXIT_CPUID 0x072
48#define SVM_EXIT_RSM 0x073
49#define SVM_EXIT_IRET 0x074
50#define SVM_EXIT_SWINT 0x075
51#define SVM_EXIT_INVD 0x076
52#define SVM_EXIT_PAUSE 0x077
53#define SVM_EXIT_HLT 0x078
54#define SVM_EXIT_INVLPG 0x079
55#define SVM_EXIT_INVLPGA 0x07a
56#define SVM_EXIT_IOIO 0x07b
57#define SVM_EXIT_MSR 0x07c
58#define SVM_EXIT_TASK_SWITCH 0x07d
59#define SVM_EXIT_FERR_FREEZE 0x07e
60#define SVM_EXIT_SHUTDOWN 0x07f
61#define SVM_EXIT_VMRUN 0x080
62#define SVM_EXIT_VMMCALL 0x081
63#define SVM_EXIT_VMLOAD 0x082
64#define SVM_EXIT_VMSAVE 0x083
65#define SVM_EXIT_STGI 0x084
66#define SVM_EXIT_CLGI 0x085
67#define SVM_EXIT_SKINIT 0x086
68#define SVM_EXIT_RDTSCP 0x087
69#define SVM_EXIT_ICEBP 0x088
70#define SVM_EXIT_WBINVD 0x089
71#define SVM_EXIT_MONITOR 0x08a
72#define SVM_EXIT_MWAIT 0x08b
73#define SVM_EXIT_MWAIT_COND 0x08c
74#define SVM_EXIT_XSETBV 0x08d
75#define SVM_EXIT_NPF 0x400
76
77#define SVM_EXIT_ERR -1
78
79#define SVM_EXIT_REASONS \
80 { SVM_EXIT_READ_CR0, "read_cr0" }, \
81 { SVM_EXIT_READ_CR3, "read_cr3" }, \
82 { SVM_EXIT_READ_CR4, "read_cr4" }, \
83 { SVM_EXIT_READ_CR8, "read_cr8" }, \
84 { SVM_EXIT_WRITE_CR0, "write_cr0" }, \
85 { SVM_EXIT_WRITE_CR3, "write_cr3" }, \
86 { SVM_EXIT_WRITE_CR4, "write_cr4" }, \
87 { SVM_EXIT_WRITE_CR8, "write_cr8" }, \
88 { SVM_EXIT_READ_DR0, "read_dr0" }, \
89 { SVM_EXIT_READ_DR1, "read_dr1" }, \
90 { SVM_EXIT_READ_DR2, "read_dr2" }, \
91 { SVM_EXIT_READ_DR3, "read_dr3" }, \
92 { SVM_EXIT_WRITE_DR0, "write_dr0" }, \
93 { SVM_EXIT_WRITE_DR1, "write_dr1" }, \
94 { SVM_EXIT_WRITE_DR2, "write_dr2" }, \
95 { SVM_EXIT_WRITE_DR3, "write_dr3" }, \
96 { SVM_EXIT_WRITE_DR5, "write_dr5" }, \
97 { SVM_EXIT_WRITE_DR7, "write_dr7" }, \
98 { SVM_EXIT_EXCP_BASE + DB_VECTOR, "DB excp" }, \
99 { SVM_EXIT_EXCP_BASE + BP_VECTOR, "BP excp" }, \
100 { SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" }, \
101 { SVM_EXIT_EXCP_BASE + PF_VECTOR, "PF excp" }, \
102 { SVM_EXIT_EXCP_BASE + NM_VECTOR, "NM excp" }, \
103 { SVM_EXIT_EXCP_BASE + MC_VECTOR, "MC excp" }, \
104 { SVM_EXIT_INTR, "interrupt" }, \
105 { SVM_EXIT_NMI, "nmi" }, \
106 { SVM_EXIT_SMI, "smi" }, \
107 { SVM_EXIT_INIT, "init" }, \
108 { SVM_EXIT_VINTR, "vintr" }, \
109 { SVM_EXIT_CPUID, "cpuid" }, \
110 { SVM_EXIT_INVD, "invd" }, \
111 { SVM_EXIT_HLT, "hlt" }, \
112 { SVM_EXIT_INVLPG, "invlpg" }, \
113 { SVM_EXIT_INVLPGA, "invlpga" }, \
114 { SVM_EXIT_IOIO, "io" }, \
115 { SVM_EXIT_MSR, "msr" }, \
116 { SVM_EXIT_TASK_SWITCH, "task_switch" }, \
117 { SVM_EXIT_SHUTDOWN, "shutdown" }, \
118 { SVM_EXIT_VMRUN, "vmrun" }, \
119 { SVM_EXIT_VMMCALL, "hypercall" }, \
120 { SVM_EXIT_VMLOAD, "vmload" }, \
121 { SVM_EXIT_VMSAVE, "vmsave" }, \
122 { SVM_EXIT_STGI, "stgi" }, \
123 { SVM_EXIT_CLGI, "clgi" }, \
124 { SVM_EXIT_SKINIT, "skinit" }, \
125 { SVM_EXIT_WBINVD, "wbinvd" }, \
126 { SVM_EXIT_MONITOR, "monitor" }, \
127 { SVM_EXIT_MWAIT, "mwait" }, \
128 { SVM_EXIT_XSETBV, "xsetbv" }, \
129 { SVM_EXIT_NPF, "npf" }
130
131#ifdef __KERNEL__
132
4enum { 133enum {
5 INTERCEPT_INTR, 134 INTERCEPT_INTR,
6 INTERCEPT_NMI, 135 INTERCEPT_NMI,
@@ -264,81 +393,6 @@ struct __attribute__ ((__packed__)) vmcb {
264 393
265#define SVM_EXITINFO_REG_MASK 0x0F 394#define SVM_EXITINFO_REG_MASK 0x0F
266 395
267#define SVM_EXIT_READ_CR0 0x000
268#define SVM_EXIT_READ_CR3 0x003
269#define SVM_EXIT_READ_CR4 0x004
270#define SVM_EXIT_READ_CR8 0x008
271#define SVM_EXIT_WRITE_CR0 0x010
272#define SVM_EXIT_WRITE_CR3 0x013
273#define SVM_EXIT_WRITE_CR4 0x014
274#define SVM_EXIT_WRITE_CR8 0x018
275#define SVM_EXIT_READ_DR0 0x020
276#define SVM_EXIT_READ_DR1 0x021
277#define SVM_EXIT_READ_DR2 0x022
278#define SVM_EXIT_READ_DR3 0x023
279#define SVM_EXIT_READ_DR4 0x024
280#define SVM_EXIT_READ_DR5 0x025
281#define SVM_EXIT_READ_DR6 0x026
282#define SVM_EXIT_READ_DR7 0x027
283#define SVM_EXIT_WRITE_DR0 0x030
284#define SVM_EXIT_WRITE_DR1 0x031
285#define SVM_EXIT_WRITE_DR2 0x032
286#define SVM_EXIT_WRITE_DR3 0x033
287#define SVM_EXIT_WRITE_DR4 0x034
288#define SVM_EXIT_WRITE_DR5 0x035
289#define SVM_EXIT_WRITE_DR6 0x036
290#define SVM_EXIT_WRITE_DR7 0x037
291#define SVM_EXIT_EXCP_BASE 0x040
292#define SVM_EXIT_INTR 0x060
293#define SVM_EXIT_NMI 0x061
294#define SVM_EXIT_SMI 0x062
295#define SVM_EXIT_INIT 0x063
296#define SVM_EXIT_VINTR 0x064
297#define SVM_EXIT_CR0_SEL_WRITE 0x065
298#define SVM_EXIT_IDTR_READ 0x066
299#define SVM_EXIT_GDTR_READ 0x067
300#define SVM_EXIT_LDTR_READ 0x068
301#define SVM_EXIT_TR_READ 0x069
302#define SVM_EXIT_IDTR_WRITE 0x06a
303#define SVM_EXIT_GDTR_WRITE 0x06b
304#define SVM_EXIT_LDTR_WRITE 0x06c
305#define SVM_EXIT_TR_WRITE 0x06d
306#define SVM_EXIT_RDTSC 0x06e
307#define SVM_EXIT_RDPMC 0x06f
308#define SVM_EXIT_PUSHF 0x070
309#define SVM_EXIT_POPF 0x071
310#define SVM_EXIT_CPUID 0x072
311#define SVM_EXIT_RSM 0x073
312#define SVM_EXIT_IRET 0x074
313#define SVM_EXIT_SWINT 0x075
314#define SVM_EXIT_INVD 0x076
315#define SVM_EXIT_PAUSE 0x077
316#define SVM_EXIT_HLT 0x078
317#define SVM_EXIT_INVLPG 0x079
318#define SVM_EXIT_INVLPGA 0x07a
319#define SVM_EXIT_IOIO 0x07b
320#define SVM_EXIT_MSR 0x07c
321#define SVM_EXIT_TASK_SWITCH 0x07d
322#define SVM_EXIT_FERR_FREEZE 0x07e
323#define SVM_EXIT_SHUTDOWN 0x07f
324#define SVM_EXIT_VMRUN 0x080
325#define SVM_EXIT_VMMCALL 0x081
326#define SVM_EXIT_VMLOAD 0x082
327#define SVM_EXIT_VMSAVE 0x083
328#define SVM_EXIT_STGI 0x084
329#define SVM_EXIT_CLGI 0x085
330#define SVM_EXIT_SKINIT 0x086
331#define SVM_EXIT_RDTSCP 0x087
332#define SVM_EXIT_ICEBP 0x088
333#define SVM_EXIT_WBINVD 0x089
334#define SVM_EXIT_MONITOR 0x08a
335#define SVM_EXIT_MWAIT 0x08b
336#define SVM_EXIT_MWAIT_COND 0x08c
337#define SVM_EXIT_XSETBV 0x08d
338#define SVM_EXIT_NPF 0x400
339
340#define SVM_EXIT_ERR -1
341
342#define SVM_CR0_SELECTIVE_MASK (X86_CR0_TS | X86_CR0_MP) 396#define SVM_CR0_SELECTIVE_MASK (X86_CR0_TS | X86_CR0_MP)
343 397
344#define SVM_VMLOAD ".byte 0x0f, 0x01, 0xda" 398#define SVM_VMLOAD ".byte 0x0f, 0x01, 0xda"
@@ -350,3 +404,4 @@ struct __attribute__ ((__packed__)) vmcb {
350 404
351#endif 405#endif
352 406
407#endif
diff --git a/arch/x86/include/asm/sys_ia32.h b/arch/x86/include/asm/sys_ia32.h
index 3fda9db48819..4ca1c611b552 100644
--- a/arch/x86/include/asm/sys_ia32.h
+++ b/arch/x86/include/asm/sys_ia32.h
@@ -40,7 +40,7 @@ asmlinkage long sys32_sigaction(int, struct old_sigaction32 __user *,
40 struct old_sigaction32 __user *); 40 struct old_sigaction32 __user *);
41asmlinkage long sys32_alarm(unsigned int); 41asmlinkage long sys32_alarm(unsigned int);
42 42
43asmlinkage long sys32_waitpid(compat_pid_t, unsigned int *, int); 43asmlinkage long sys32_waitpid(compat_pid_t, unsigned int __user *, int);
44asmlinkage long sys32_sysfs(int, u32, u32); 44asmlinkage long sys32_sysfs(int, u32, u32);
45 45
46asmlinkage long sys32_sched_rr_get_interval(compat_pid_t, 46asmlinkage long sys32_sched_rr_get_interval(compat_pid_t,
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index 89f794f007ec..c535d847e3b5 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -89,6 +89,7 @@ struct thread_info {
89#define TIF_NOTSC 16 /* TSC is not accessible in userland */ 89#define TIF_NOTSC 16 /* TSC is not accessible in userland */
90#define TIF_IA32 17 /* IA32 compatibility process */ 90#define TIF_IA32 17 /* IA32 compatibility process */
91#define TIF_FORK 18 /* ret_from_fork */ 91#define TIF_FORK 18 /* ret_from_fork */
92#define TIF_NOHZ 19 /* in adaptive nohz mode */
92#define TIF_MEMDIE 20 /* is terminating due to OOM killer */ 93#define TIF_MEMDIE 20 /* is terminating due to OOM killer */
93#define TIF_DEBUG 21 /* uses debug registers */ 94#define TIF_DEBUG 21 /* uses debug registers */
94#define TIF_IO_BITMAP 22 /* uses I/O bitmap */ 95#define TIF_IO_BITMAP 22 /* uses I/O bitmap */
@@ -114,6 +115,7 @@ struct thread_info {
114#define _TIF_NOTSC (1 << TIF_NOTSC) 115#define _TIF_NOTSC (1 << TIF_NOTSC)
115#define _TIF_IA32 (1 << TIF_IA32) 116#define _TIF_IA32 (1 << TIF_IA32)
116#define _TIF_FORK (1 << TIF_FORK) 117#define _TIF_FORK (1 << TIF_FORK)
118#define _TIF_NOHZ (1 << TIF_NOHZ)
117#define _TIF_DEBUG (1 << TIF_DEBUG) 119#define _TIF_DEBUG (1 << TIF_DEBUG)
118#define _TIF_IO_BITMAP (1 << TIF_IO_BITMAP) 120#define _TIF_IO_BITMAP (1 << TIF_IO_BITMAP)
119#define _TIF_FORCED_TF (1 << TIF_FORCED_TF) 121#define _TIF_FORCED_TF (1 << TIF_FORCED_TF)
@@ -126,12 +128,13 @@ struct thread_info {
126/* work to do in syscall_trace_enter() */ 128/* work to do in syscall_trace_enter() */
127#define _TIF_WORK_SYSCALL_ENTRY \ 129#define _TIF_WORK_SYSCALL_ENTRY \
128 (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | _TIF_SYSCALL_AUDIT | \ 130 (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | _TIF_SYSCALL_AUDIT | \
129 _TIF_SECCOMP | _TIF_SINGLESTEP | _TIF_SYSCALL_TRACEPOINT) 131 _TIF_SECCOMP | _TIF_SINGLESTEP | _TIF_SYSCALL_TRACEPOINT | \
132 _TIF_NOHZ)
130 133
131/* work to do in syscall_trace_leave() */ 134/* work to do in syscall_trace_leave() */
132#define _TIF_WORK_SYSCALL_EXIT \ 135#define _TIF_WORK_SYSCALL_EXIT \
133 (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP | \ 136 (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP | \
134 _TIF_SYSCALL_TRACEPOINT) 137 _TIF_SYSCALL_TRACEPOINT | _TIF_NOHZ)
135 138
136/* work to do on interrupt/exception return */ 139/* work to do on interrupt/exception return */
137#define _TIF_WORK_MASK \ 140#define _TIF_WORK_MASK \
@@ -141,7 +144,8 @@ struct thread_info {
141 144
142/* work to do on any return to user space */ 145/* work to do on any return to user space */
143#define _TIF_ALLWORK_MASK \ 146#define _TIF_ALLWORK_MASK \
144 ((0x0000FFFF & ~_TIF_SECCOMP) | _TIF_SYSCALL_TRACEPOINT) 147 ((0x0000FFFF & ~_TIF_SECCOMP) | _TIF_SYSCALL_TRACEPOINT | \
148 _TIF_NOHZ)
145 149
146/* Only used for 64 bit */ 150/* Only used for 64 bit */
147#define _TIF_DO_NOTIFY_MASK \ 151#define _TIF_DO_NOTIFY_MASK \
diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h
index f3971bbcd1de..8ff8be7835ab 100644
--- a/arch/x86/include/asm/uprobes.h
+++ b/arch/x86/include/asm/uprobes.h
@@ -42,10 +42,11 @@ struct arch_uprobe {
42}; 42};
43 43
44struct arch_uprobe_task { 44struct arch_uprobe_task {
45 unsigned long saved_trap_nr;
46#ifdef CONFIG_X86_64 45#ifdef CONFIG_X86_64
47 unsigned long saved_scratch_register; 46 unsigned long saved_scratch_register;
48#endif 47#endif
48 unsigned int saved_trap_nr;
49 unsigned int saved_tf;
49}; 50};
50 51
51extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr); 52extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr);
diff --git a/arch/x86/include/asm/vdso.h b/arch/x86/include/asm/vdso.h
index bb0522850b74..fddb53d63915 100644
--- a/arch/x86/include/asm/vdso.h
+++ b/arch/x86/include/asm/vdso.h
@@ -11,7 +11,8 @@ extern const char VDSO32_PRELINK[];
11#define VDSO32_SYMBOL(base, name) \ 11#define VDSO32_SYMBOL(base, name) \
12({ \ 12({ \
13 extern const char VDSO32_##name[]; \ 13 extern const char VDSO32_##name[]; \
14 (void *)(VDSO32_##name - VDSO32_PRELINK + (unsigned long)(base)); \ 14 (void __user *)(VDSO32_##name - VDSO32_PRELINK + \
15 (unsigned long)(base)); \
15}) 16})
16#endif 17#endif
17 18
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
index 74fcb963595b..36ec21c36d68 100644
--- a/arch/x86/include/asm/vmx.h
+++ b/arch/x86/include/asm/vmx.h
@@ -25,6 +25,88 @@
25 * 25 *
26 */ 26 */
27 27
28#define VMX_EXIT_REASONS_FAILED_VMENTRY 0x80000000
29
30#define EXIT_REASON_EXCEPTION_NMI 0
31#define EXIT_REASON_EXTERNAL_INTERRUPT 1
32#define EXIT_REASON_TRIPLE_FAULT 2
33
34#define EXIT_REASON_PENDING_INTERRUPT 7
35#define EXIT_REASON_NMI_WINDOW 8
36#define EXIT_REASON_TASK_SWITCH 9
37#define EXIT_REASON_CPUID 10
38#define EXIT_REASON_HLT 12
39#define EXIT_REASON_INVD 13
40#define EXIT_REASON_INVLPG 14
41#define EXIT_REASON_RDPMC 15
42#define EXIT_REASON_RDTSC 16
43#define EXIT_REASON_VMCALL 18
44#define EXIT_REASON_VMCLEAR 19
45#define EXIT_REASON_VMLAUNCH 20
46#define EXIT_REASON_VMPTRLD 21
47#define EXIT_REASON_VMPTRST 22
48#define EXIT_REASON_VMREAD 23
49#define EXIT_REASON_VMRESUME 24
50#define EXIT_REASON_VMWRITE 25
51#define EXIT_REASON_VMOFF 26
52#define EXIT_REASON_VMON 27
53#define EXIT_REASON_CR_ACCESS 28
54#define EXIT_REASON_DR_ACCESS 29
55#define EXIT_REASON_IO_INSTRUCTION 30
56#define EXIT_REASON_MSR_READ 31
57#define EXIT_REASON_MSR_WRITE 32
58#define EXIT_REASON_INVALID_STATE 33
59#define EXIT_REASON_MWAIT_INSTRUCTION 36
60#define EXIT_REASON_MONITOR_INSTRUCTION 39
61#define EXIT_REASON_PAUSE_INSTRUCTION 40
62#define EXIT_REASON_MCE_DURING_VMENTRY 41
63#define EXIT_REASON_TPR_BELOW_THRESHOLD 43
64#define EXIT_REASON_APIC_ACCESS 44
65#define EXIT_REASON_EPT_VIOLATION 48
66#define EXIT_REASON_EPT_MISCONFIG 49
67#define EXIT_REASON_WBINVD 54
68#define EXIT_REASON_XSETBV 55
69#define EXIT_REASON_INVPCID 58
70
71#define VMX_EXIT_REASONS \
72 { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, \
73 { EXIT_REASON_EXTERNAL_INTERRUPT, "EXTERNAL_INTERRUPT" }, \
74 { EXIT_REASON_TRIPLE_FAULT, "TRIPLE_FAULT" }, \
75 { EXIT_REASON_PENDING_INTERRUPT, "PENDING_INTERRUPT" }, \
76 { EXIT_REASON_NMI_WINDOW, "NMI_WINDOW" }, \
77 { EXIT_REASON_TASK_SWITCH, "TASK_SWITCH" }, \
78 { EXIT_REASON_CPUID, "CPUID" }, \
79 { EXIT_REASON_HLT, "HLT" }, \
80 { EXIT_REASON_INVLPG, "INVLPG" }, \
81 { EXIT_REASON_RDPMC, "RDPMC" }, \
82 { EXIT_REASON_RDTSC, "RDTSC" }, \
83 { EXIT_REASON_VMCALL, "VMCALL" }, \
84 { EXIT_REASON_VMCLEAR, "VMCLEAR" }, \
85 { EXIT_REASON_VMLAUNCH, "VMLAUNCH" }, \
86 { EXIT_REASON_VMPTRLD, "VMPTRLD" }, \
87 { EXIT_REASON_VMPTRST, "VMPTRST" }, \
88 { EXIT_REASON_VMREAD, "VMREAD" }, \
89 { EXIT_REASON_VMRESUME, "VMRESUME" }, \
90 { EXIT_REASON_VMWRITE, "VMWRITE" }, \
91 { EXIT_REASON_VMOFF, "VMOFF" }, \
92 { EXIT_REASON_VMON, "VMON" }, \
93 { EXIT_REASON_CR_ACCESS, "CR_ACCESS" }, \
94 { EXIT_REASON_DR_ACCESS, "DR_ACCESS" }, \
95 { EXIT_REASON_IO_INSTRUCTION, "IO_INSTRUCTION" }, \
96 { EXIT_REASON_MSR_READ, "MSR_READ" }, \
97 { EXIT_REASON_MSR_WRITE, "MSR_WRITE" }, \
98 { EXIT_REASON_MWAIT_INSTRUCTION, "MWAIT_INSTRUCTION" }, \
99 { EXIT_REASON_MONITOR_INSTRUCTION, "MONITOR_INSTRUCTION" }, \
100 { EXIT_REASON_PAUSE_INSTRUCTION, "PAUSE_INSTRUCTION" }, \
101 { EXIT_REASON_MCE_DURING_VMENTRY, "MCE_DURING_VMENTRY" }, \
102 { EXIT_REASON_TPR_BELOW_THRESHOLD, "TPR_BELOW_THRESHOLD" }, \
103 { EXIT_REASON_APIC_ACCESS, "APIC_ACCESS" }, \
104 { EXIT_REASON_EPT_VIOLATION, "EPT_VIOLATION" }, \
105 { EXIT_REASON_EPT_MISCONFIG, "EPT_MISCONFIG" }, \
106 { EXIT_REASON_WBINVD, "WBINVD" }
107
108#ifdef __KERNEL__
109
28#include <linux/types.h> 110#include <linux/types.h>
29 111
30/* 112/*
@@ -241,49 +323,6 @@ enum vmcs_field {
241 HOST_RIP = 0x00006c16, 323 HOST_RIP = 0x00006c16,
242}; 324};
243 325
244#define VMX_EXIT_REASONS_FAILED_VMENTRY 0x80000000
245
246#define EXIT_REASON_EXCEPTION_NMI 0
247#define EXIT_REASON_EXTERNAL_INTERRUPT 1
248#define EXIT_REASON_TRIPLE_FAULT 2
249
250#define EXIT_REASON_PENDING_INTERRUPT 7
251#define EXIT_REASON_NMI_WINDOW 8
252#define EXIT_REASON_TASK_SWITCH 9
253#define EXIT_REASON_CPUID 10
254#define EXIT_REASON_HLT 12
255#define EXIT_REASON_INVD 13
256#define EXIT_REASON_INVLPG 14
257#define EXIT_REASON_RDPMC 15
258#define EXIT_REASON_RDTSC 16
259#define EXIT_REASON_VMCALL 18
260#define EXIT_REASON_VMCLEAR 19
261#define EXIT_REASON_VMLAUNCH 20
262#define EXIT_REASON_VMPTRLD 21
263#define EXIT_REASON_VMPTRST 22
264#define EXIT_REASON_VMREAD 23
265#define EXIT_REASON_VMRESUME 24
266#define EXIT_REASON_VMWRITE 25
267#define EXIT_REASON_VMOFF 26
268#define EXIT_REASON_VMON 27
269#define EXIT_REASON_CR_ACCESS 28
270#define EXIT_REASON_DR_ACCESS 29
271#define EXIT_REASON_IO_INSTRUCTION 30
272#define EXIT_REASON_MSR_READ 31
273#define EXIT_REASON_MSR_WRITE 32
274#define EXIT_REASON_INVALID_STATE 33
275#define EXIT_REASON_MWAIT_INSTRUCTION 36
276#define EXIT_REASON_MONITOR_INSTRUCTION 39
277#define EXIT_REASON_PAUSE_INSTRUCTION 40
278#define EXIT_REASON_MCE_DURING_VMENTRY 41
279#define EXIT_REASON_TPR_BELOW_THRESHOLD 43
280#define EXIT_REASON_APIC_ACCESS 44
281#define EXIT_REASON_EPT_VIOLATION 48
282#define EXIT_REASON_EPT_MISCONFIG 49
283#define EXIT_REASON_WBINVD 54
284#define EXIT_REASON_XSETBV 55
285#define EXIT_REASON_INVPCID 58
286
287/* 326/*
288 * Interruption-information format 327 * Interruption-information format
289 */ 328 */
@@ -488,3 +527,5 @@ enum vm_instruction_error_number {
488}; 527};
489 528
490#endif 529#endif
530
531#endif
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 38155f667144..57693498519c 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -81,12 +81,13 @@ struct x86_init_mapping {
81 81
82/** 82/**
83 * struct x86_init_paging - platform specific paging functions 83 * struct x86_init_paging - platform specific paging functions
84 * @pagetable_setup_start: platform specific pre paging_init() call 84 * @pagetable_init: platform specific paging initialization call to setup
85 * @pagetable_setup_done: platform specific post paging_init() call 85 * the kernel pagetables and prepare accessors functions.
86 * Callback must call paging_init(). Called once after the
87 * direct mapping for phys memory is available.
86 */ 88 */
87struct x86_init_paging { 89struct x86_init_paging {
88 void (*pagetable_setup_start)(pgd_t *base); 90 void (*pagetable_init)(void);
89 void (*pagetable_setup_done)(pgd_t *base);
90}; 91};
91 92
92/** 93/**
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
index 93971e841dd5..472b9b783019 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -51,7 +51,8 @@ extern unsigned long set_phys_range_identity(unsigned long pfn_s,
51 51
52extern int m2p_add_override(unsigned long mfn, struct page *page, 52extern int m2p_add_override(unsigned long mfn, struct page *page,
53 struct gnttab_map_grant_ref *kmap_op); 53 struct gnttab_map_grant_ref *kmap_op);
54extern int m2p_remove_override(struct page *page, bool clear_pte); 54extern int m2p_remove_override(struct page *page,
55 struct gnttab_map_grant_ref *kmap_op);
55extern struct page *m2p_find_override(unsigned long mfn); 56extern struct page *m2p_find_override(unsigned long mfn);
56extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn); 57extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn);
57 58
diff --git a/arch/x86/include/asm/xor_32.h b/arch/x86/include/asm/xor_32.h
index 454570891bdc..aabd5850bdb9 100644
--- a/arch/x86/include/asm/xor_32.h
+++ b/arch/x86/include/asm/xor_32.h
@@ -534,38 +534,6 @@ static struct xor_block_template xor_block_p5_mmx = {
534 * Copyright (C) 1999 Zach Brown (with obvious credit due Ingo) 534 * Copyright (C) 1999 Zach Brown (with obvious credit due Ingo)
535 */ 535 */
536 536
537#define XMMS_SAVE \
538do { \
539 preempt_disable(); \
540 cr0 = read_cr0(); \
541 clts(); \
542 asm volatile( \
543 "movups %%xmm0,(%0) ;\n\t" \
544 "movups %%xmm1,0x10(%0) ;\n\t" \
545 "movups %%xmm2,0x20(%0) ;\n\t" \
546 "movups %%xmm3,0x30(%0) ;\n\t" \
547 : \
548 : "r" (xmm_save) \
549 : "memory"); \
550} while (0)
551
552#define XMMS_RESTORE \
553do { \
554 asm volatile( \
555 "sfence ;\n\t" \
556 "movups (%0),%%xmm0 ;\n\t" \
557 "movups 0x10(%0),%%xmm1 ;\n\t" \
558 "movups 0x20(%0),%%xmm2 ;\n\t" \
559 "movups 0x30(%0),%%xmm3 ;\n\t" \
560 : \
561 : "r" (xmm_save) \
562 : "memory"); \
563 write_cr0(cr0); \
564 preempt_enable(); \
565} while (0)
566
567#define ALIGN16 __attribute__((aligned(16)))
568
569#define OFFS(x) "16*("#x")" 537#define OFFS(x) "16*("#x")"
570#define PF_OFFS(x) "256+16*("#x")" 538#define PF_OFFS(x) "256+16*("#x")"
571#define PF0(x) " prefetchnta "PF_OFFS(x)"(%1) ;\n" 539#define PF0(x) " prefetchnta "PF_OFFS(x)"(%1) ;\n"
@@ -587,10 +555,8 @@ static void
587xor_sse_2(unsigned long bytes, unsigned long *p1, unsigned long *p2) 555xor_sse_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
588{ 556{
589 unsigned long lines = bytes >> 8; 557 unsigned long lines = bytes >> 8;
590 char xmm_save[16*4] ALIGN16;
591 int cr0;
592 558
593 XMMS_SAVE; 559 kernel_fpu_begin();
594 560
595 asm volatile( 561 asm volatile(
596#undef BLOCK 562#undef BLOCK
@@ -633,7 +599,7 @@ xor_sse_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
633 : 599 :
634 : "memory"); 600 : "memory");
635 601
636 XMMS_RESTORE; 602 kernel_fpu_end();
637} 603}
638 604
639static void 605static void
@@ -641,10 +607,8 @@ xor_sse_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
641 unsigned long *p3) 607 unsigned long *p3)
642{ 608{
643 unsigned long lines = bytes >> 8; 609 unsigned long lines = bytes >> 8;
644 char xmm_save[16*4] ALIGN16;
645 int cr0;
646 610
647 XMMS_SAVE; 611 kernel_fpu_begin();
648 612
649 asm volatile( 613 asm volatile(
650#undef BLOCK 614#undef BLOCK
@@ -694,7 +658,7 @@ xor_sse_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
694 : 658 :
695 : "memory" ); 659 : "memory" );
696 660
697 XMMS_RESTORE; 661 kernel_fpu_end();
698} 662}
699 663
700static void 664static void
@@ -702,10 +666,8 @@ xor_sse_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
702 unsigned long *p3, unsigned long *p4) 666 unsigned long *p3, unsigned long *p4)
703{ 667{
704 unsigned long lines = bytes >> 8; 668 unsigned long lines = bytes >> 8;
705 char xmm_save[16*4] ALIGN16;
706 int cr0;
707 669
708 XMMS_SAVE; 670 kernel_fpu_begin();
709 671
710 asm volatile( 672 asm volatile(
711#undef BLOCK 673#undef BLOCK
@@ -762,7 +724,7 @@ xor_sse_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
762 : 724 :
763 : "memory" ); 725 : "memory" );
764 726
765 XMMS_RESTORE; 727 kernel_fpu_end();
766} 728}
767 729
768static void 730static void
@@ -770,10 +732,8 @@ xor_sse_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
770 unsigned long *p3, unsigned long *p4, unsigned long *p5) 732 unsigned long *p3, unsigned long *p4, unsigned long *p5)
771{ 733{
772 unsigned long lines = bytes >> 8; 734 unsigned long lines = bytes >> 8;
773 char xmm_save[16*4] ALIGN16;
774 int cr0;
775 735
776 XMMS_SAVE; 736 kernel_fpu_begin();
777 737
778 /* Make sure GCC forgets anything it knows about p4 or p5, 738 /* Make sure GCC forgets anything it knows about p4 or p5,
779 such that it won't pass to the asm volatile below a 739 such that it won't pass to the asm volatile below a
@@ -850,7 +810,7 @@ xor_sse_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
850 like assuming they have some legal value. */ 810 like assuming they have some legal value. */
851 asm("" : "=r" (p4), "=r" (p5)); 811 asm("" : "=r" (p4), "=r" (p5));
852 812
853 XMMS_RESTORE; 813 kernel_fpu_end();
854} 814}
855 815
856static struct xor_block_template xor_block_pIII_sse = { 816static struct xor_block_template xor_block_pIII_sse = {
diff --git a/arch/x86/include/asm/xor_64.h b/arch/x86/include/asm/xor_64.h
index b9b2323e90fe..5fc06d0b7eb5 100644
--- a/arch/x86/include/asm/xor_64.h
+++ b/arch/x86/include/asm/xor_64.h
@@ -34,41 +34,7 @@
34 * no advantages to be gotten from x86-64 here anyways. 34 * no advantages to be gotten from x86-64 here anyways.
35 */ 35 */
36 36
37typedef struct { 37#include <asm/i387.h>
38 unsigned long a, b;
39} __attribute__((aligned(16))) xmm_store_t;
40
41/* Doesn't use gcc to save the XMM registers, because there is no easy way to
42 tell it to do a clts before the register saving. */
43#define XMMS_SAVE \
44do { \
45 preempt_disable(); \
46 asm volatile( \
47 "movq %%cr0,%0 ;\n\t" \
48 "clts ;\n\t" \
49 "movups %%xmm0,(%1) ;\n\t" \
50 "movups %%xmm1,0x10(%1) ;\n\t" \
51 "movups %%xmm2,0x20(%1) ;\n\t" \
52 "movups %%xmm3,0x30(%1) ;\n\t" \
53 : "=&r" (cr0) \
54 : "r" (xmm_save) \
55 : "memory"); \
56} while (0)
57
58#define XMMS_RESTORE \
59do { \
60 asm volatile( \
61 "sfence ;\n\t" \
62 "movups (%1),%%xmm0 ;\n\t" \
63 "movups 0x10(%1),%%xmm1 ;\n\t" \
64 "movups 0x20(%1),%%xmm2 ;\n\t" \
65 "movups 0x30(%1),%%xmm3 ;\n\t" \
66 "movq %0,%%cr0 ;\n\t" \
67 : \
68 : "r" (cr0), "r" (xmm_save) \
69 : "memory"); \
70 preempt_enable(); \
71} while (0)
72 38
73#define OFFS(x) "16*("#x")" 39#define OFFS(x) "16*("#x")"
74#define PF_OFFS(x) "256+16*("#x")" 40#define PF_OFFS(x) "256+16*("#x")"
@@ -91,10 +57,8 @@ static void
91xor_sse_2(unsigned long bytes, unsigned long *p1, unsigned long *p2) 57xor_sse_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
92{ 58{
93 unsigned int lines = bytes >> 8; 59 unsigned int lines = bytes >> 8;
94 unsigned long cr0;
95 xmm_store_t xmm_save[4];
96 60
97 XMMS_SAVE; 61 kernel_fpu_begin();
98 62
99 asm volatile( 63 asm volatile(
100#undef BLOCK 64#undef BLOCK
@@ -135,7 +99,7 @@ xor_sse_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
135 : [inc] "r" (256UL) 99 : [inc] "r" (256UL)
136 : "memory"); 100 : "memory");
137 101
138 XMMS_RESTORE; 102 kernel_fpu_end();
139} 103}
140 104
141static void 105static void
@@ -143,11 +107,8 @@ xor_sse_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
143 unsigned long *p3) 107 unsigned long *p3)
144{ 108{
145 unsigned int lines = bytes >> 8; 109 unsigned int lines = bytes >> 8;
146 xmm_store_t xmm_save[4];
147 unsigned long cr0;
148
149 XMMS_SAVE;
150 110
111 kernel_fpu_begin();
151 asm volatile( 112 asm volatile(
152#undef BLOCK 113#undef BLOCK
153#define BLOCK(i) \ 114#define BLOCK(i) \
@@ -194,7 +155,7 @@ xor_sse_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
194 [p1] "+r" (p1), [p2] "+r" (p2), [p3] "+r" (p3) 155 [p1] "+r" (p1), [p2] "+r" (p2), [p3] "+r" (p3)
195 : [inc] "r" (256UL) 156 : [inc] "r" (256UL)
196 : "memory"); 157 : "memory");
197 XMMS_RESTORE; 158 kernel_fpu_end();
198} 159}
199 160
200static void 161static void
@@ -202,10 +163,8 @@ xor_sse_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
202 unsigned long *p3, unsigned long *p4) 163 unsigned long *p3, unsigned long *p4)
203{ 164{
204 unsigned int lines = bytes >> 8; 165 unsigned int lines = bytes >> 8;
205 xmm_store_t xmm_save[4];
206 unsigned long cr0;
207 166
208 XMMS_SAVE; 167 kernel_fpu_begin();
209 168
210 asm volatile( 169 asm volatile(
211#undef BLOCK 170#undef BLOCK
@@ -261,7 +220,7 @@ xor_sse_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
261 : [inc] "r" (256UL) 220 : [inc] "r" (256UL)
262 : "memory" ); 221 : "memory" );
263 222
264 XMMS_RESTORE; 223 kernel_fpu_end();
265} 224}
266 225
267static void 226static void
@@ -269,10 +228,8 @@ xor_sse_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
269 unsigned long *p3, unsigned long *p4, unsigned long *p5) 228 unsigned long *p3, unsigned long *p4, unsigned long *p5)
270{ 229{
271 unsigned int lines = bytes >> 8; 230 unsigned int lines = bytes >> 8;
272 xmm_store_t xmm_save[4];
273 unsigned long cr0;
274 231
275 XMMS_SAVE; 232 kernel_fpu_begin();
276 233
277 asm volatile( 234 asm volatile(
278#undef BLOCK 235#undef BLOCK
@@ -336,7 +293,7 @@ xor_sse_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
336 : [inc] "r" (256UL) 293 : [inc] "r" (256UL)
337 : "memory"); 294 : "memory");
338 295
339 XMMS_RESTORE; 296 kernel_fpu_end();
340} 297}
341 298
342static struct xor_block_template xor_block_sse = { 299static struct xor_block_template xor_block_sse = {
diff --git a/arch/x86/include/asm/xor_avx.h b/arch/x86/include/asm/xor_avx.h
index 2510d35f480e..7ea79c5fa1f2 100644
--- a/arch/x86/include/asm/xor_avx.h
+++ b/arch/x86/include/asm/xor_avx.h
@@ -20,32 +20,6 @@
20#include <linux/compiler.h> 20#include <linux/compiler.h>
21#include <asm/i387.h> 21#include <asm/i387.h>
22 22
23#define ALIGN32 __aligned(32)
24
25#define YMM_SAVED_REGS 4
26
27#define YMMS_SAVE \
28do { \
29 preempt_disable(); \
30 cr0 = read_cr0(); \
31 clts(); \
32 asm volatile("vmovaps %%ymm0, %0" : "=m" (ymm_save[0]) : : "memory"); \
33 asm volatile("vmovaps %%ymm1, %0" : "=m" (ymm_save[32]) : : "memory"); \
34 asm volatile("vmovaps %%ymm2, %0" : "=m" (ymm_save[64]) : : "memory"); \
35 asm volatile("vmovaps %%ymm3, %0" : "=m" (ymm_save[96]) : : "memory"); \
36} while (0);
37
38#define YMMS_RESTORE \
39do { \
40 asm volatile("sfence" : : : "memory"); \
41 asm volatile("vmovaps %0, %%ymm3" : : "m" (ymm_save[96])); \
42 asm volatile("vmovaps %0, %%ymm2" : : "m" (ymm_save[64])); \
43 asm volatile("vmovaps %0, %%ymm1" : : "m" (ymm_save[32])); \
44 asm volatile("vmovaps %0, %%ymm0" : : "m" (ymm_save[0])); \
45 write_cr0(cr0); \
46 preempt_enable(); \
47} while (0);
48
49#define BLOCK4(i) \ 23#define BLOCK4(i) \
50 BLOCK(32 * i, 0) \ 24 BLOCK(32 * i, 0) \
51 BLOCK(32 * (i + 1), 1) \ 25 BLOCK(32 * (i + 1), 1) \
@@ -60,10 +34,9 @@ do { \
60 34
61static void xor_avx_2(unsigned long bytes, unsigned long *p0, unsigned long *p1) 35static void xor_avx_2(unsigned long bytes, unsigned long *p0, unsigned long *p1)
62{ 36{
63 unsigned long cr0, lines = bytes >> 9; 37 unsigned long lines = bytes >> 9;
64 char ymm_save[32 * YMM_SAVED_REGS] ALIGN32;
65 38
66 YMMS_SAVE 39 kernel_fpu_begin();
67 40
68 while (lines--) { 41 while (lines--) {
69#undef BLOCK 42#undef BLOCK
@@ -82,16 +55,15 @@ do { \
82 p1 = (unsigned long *)((uintptr_t)p1 + 512); 55 p1 = (unsigned long *)((uintptr_t)p1 + 512);
83 } 56 }
84 57
85 YMMS_RESTORE 58 kernel_fpu_end();
86} 59}
87 60
88static void xor_avx_3(unsigned long bytes, unsigned long *p0, unsigned long *p1, 61static void xor_avx_3(unsigned long bytes, unsigned long *p0, unsigned long *p1,
89 unsigned long *p2) 62 unsigned long *p2)
90{ 63{
91 unsigned long cr0, lines = bytes >> 9; 64 unsigned long lines = bytes >> 9;
92 char ymm_save[32 * YMM_SAVED_REGS] ALIGN32;
93 65
94 YMMS_SAVE 66 kernel_fpu_begin();
95 67
96 while (lines--) { 68 while (lines--) {
97#undef BLOCK 69#undef BLOCK
@@ -113,16 +85,15 @@ do { \
113 p2 = (unsigned long *)((uintptr_t)p2 + 512); 85 p2 = (unsigned long *)((uintptr_t)p2 + 512);
114 } 86 }
115 87
116 YMMS_RESTORE 88 kernel_fpu_end();
117} 89}
118 90
119static void xor_avx_4(unsigned long bytes, unsigned long *p0, unsigned long *p1, 91static void xor_avx_4(unsigned long bytes, unsigned long *p0, unsigned long *p1,
120 unsigned long *p2, unsigned long *p3) 92 unsigned long *p2, unsigned long *p3)
121{ 93{
122 unsigned long cr0, lines = bytes >> 9; 94 unsigned long lines = bytes >> 9;
123 char ymm_save[32 * YMM_SAVED_REGS] ALIGN32;
124 95
125 YMMS_SAVE 96 kernel_fpu_begin();
126 97
127 while (lines--) { 98 while (lines--) {
128#undef BLOCK 99#undef BLOCK
@@ -147,16 +118,15 @@ do { \
147 p3 = (unsigned long *)((uintptr_t)p3 + 512); 118 p3 = (unsigned long *)((uintptr_t)p3 + 512);
148 } 119 }
149 120
150 YMMS_RESTORE 121 kernel_fpu_end();
151} 122}
152 123
153static void xor_avx_5(unsigned long bytes, unsigned long *p0, unsigned long *p1, 124static void xor_avx_5(unsigned long bytes, unsigned long *p0, unsigned long *p1,
154 unsigned long *p2, unsigned long *p3, unsigned long *p4) 125 unsigned long *p2, unsigned long *p3, unsigned long *p4)
155{ 126{
156 unsigned long cr0, lines = bytes >> 9; 127 unsigned long lines = bytes >> 9;
157 char ymm_save[32 * YMM_SAVED_REGS] ALIGN32;
158 128
159 YMMS_SAVE 129 kernel_fpu_begin();
160 130
161 while (lines--) { 131 while (lines--) {
162#undef BLOCK 132#undef BLOCK
@@ -184,7 +154,7 @@ do { \
184 p4 = (unsigned long *)((uintptr_t)p4 + 512); 154 p4 = (unsigned long *)((uintptr_t)p4 + 512);
185 } 155 }
186 156
187 YMMS_RESTORE 157 kernel_fpu_end();
188} 158}
189 159
190static struct xor_block_template xor_block_avx = { 160static struct xor_block_template xor_block_avx = {
diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h
index 8a1b6f9b594a..2ddee1b87793 100644
--- a/arch/x86/include/asm/xsave.h
+++ b/arch/x86/include/asm/xsave.h
@@ -34,17 +34,14 @@
34extern unsigned int xstate_size; 34extern unsigned int xstate_size;
35extern u64 pcntxt_mask; 35extern u64 pcntxt_mask;
36extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS]; 36extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS];
37extern struct xsave_struct *init_xstate_buf;
37 38
38extern void xsave_init(void); 39extern void xsave_init(void);
39extern void update_regset_xstate_info(unsigned int size, u64 xstate_mask); 40extern void update_regset_xstate_info(unsigned int size, u64 xstate_mask);
40extern int init_fpu(struct task_struct *child); 41extern int init_fpu(struct task_struct *child);
41extern int check_for_xstate(struct i387_fxsave_struct __user *buf,
42 void __user *fpstate,
43 struct _fpx_sw_bytes *sw);
44 42
45static inline int fpu_xrstor_checking(struct fpu *fpu) 43static inline int fpu_xrstor_checking(struct xsave_struct *fx)
46{ 44{
47 struct xsave_struct *fx = &fpu->state->xsave;
48 int err; 45 int err;
49 46
50 asm volatile("1: .byte " REX_PREFIX "0x0f,0xae,0x2f\n\t" 47 asm volatile("1: .byte " REX_PREFIX "0x0f,0xae,0x2f\n\t"
@@ -69,8 +66,7 @@ static inline int xsave_user(struct xsave_struct __user *buf)
69 * Clear the xsave header first, so that reserved fields are 66 * Clear the xsave header first, so that reserved fields are
70 * initialized to zero. 67 * initialized to zero.
71 */ 68 */
72 err = __clear_user(&buf->xsave_hdr, 69 err = __clear_user(&buf->xsave_hdr, sizeof(buf->xsave_hdr));
73 sizeof(struct xsave_hdr_struct));
74 if (unlikely(err)) 70 if (unlikely(err))
75 return -EFAULT; 71 return -EFAULT;
76 72
@@ -84,9 +80,6 @@ static inline int xsave_user(struct xsave_struct __user *buf)
84 : [err] "=r" (err) 80 : [err] "=r" (err)
85 : "D" (buf), "a" (-1), "d" (-1), "0" (0) 81 : "D" (buf), "a" (-1), "d" (-1), "0" (0)
86 : "memory"); 82 : "memory");
87 if (unlikely(err) && __clear_user(buf, xstate_size))
88 err = -EFAULT;
89 /* No need to clear here because the caller clears USED_MATH */
90 return err; 83 return err;
91} 84}
92 85
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 8215e5652d97..8d7a619718b5 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -100,6 +100,8 @@ obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o
100obj-$(CONFIG_OF) += devicetree.o 100obj-$(CONFIG_OF) += devicetree.o
101obj-$(CONFIG_UPROBES) += uprobes.o 101obj-$(CONFIG_UPROBES) += uprobes.o
102 102
103obj-$(CONFIG_PERF_EVENTS) += perf_regs.o
104
103### 105###
104# 64 bit specific files 106# 64 bit specific files
105ifeq ($(CONFIG_X86_64),y) 107ifeq ($(CONFIG_X86_64),y)
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index b2297e58c6ed..e651f7a589ac 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -656,7 +656,7 @@ static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu)
656 acpi_register_lapic(physid, ACPI_MADT_ENABLED); 656 acpi_register_lapic(physid, ACPI_MADT_ENABLED);
657 657
658 /* 658 /*
659 * If mp_register_lapic successfully generates a new logical cpu 659 * If acpi_register_lapic successfully generates a new logical cpu
660 * number, then the following will get us exactly what was mapped 660 * number, then the following will get us exactly what was mapped
661 */ 661 */
662 cpumask_andnot(new_map, cpu_present_mask, tmp_map); 662 cpumask_andnot(new_map, cpu_present_mask, tmp_map);
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index ced4534baed5..ef5ccca79a6c 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -23,19 +23,6 @@
23 23
24#define MAX_PATCH_LEN (255-1) 24#define MAX_PATCH_LEN (255-1)
25 25
26#ifdef CONFIG_HOTPLUG_CPU
27static int smp_alt_once;
28
29static int __init bootonly(char *str)
30{
31 smp_alt_once = 1;
32 return 1;
33}
34__setup("smp-alt-boot", bootonly);
35#else
36#define smp_alt_once 1
37#endif
38
39static int __initdata_or_module debug_alternative; 26static int __initdata_or_module debug_alternative;
40 27
41static int __init debug_alt(char *str) 28static int __init debug_alt(char *str)
@@ -317,7 +304,7 @@ static void alternatives_smp_lock(const s32 *start, const s32 *end,
317 /* turn DS segment override prefix into lock prefix */ 304 /* turn DS segment override prefix into lock prefix */
318 if (*ptr == 0x3e) 305 if (*ptr == 0x3e)
319 text_poke(ptr, ((unsigned char []){0xf0}), 1); 306 text_poke(ptr, ((unsigned char []){0xf0}), 1);
320 }; 307 }
321 mutex_unlock(&text_mutex); 308 mutex_unlock(&text_mutex);
322} 309}
323 310
@@ -326,9 +313,6 @@ static void alternatives_smp_unlock(const s32 *start, const s32 *end,
326{ 313{
327 const s32 *poff; 314 const s32 *poff;
328 315
329 if (noreplace_smp)
330 return;
331
332 mutex_lock(&text_mutex); 316 mutex_lock(&text_mutex);
333 for (poff = start; poff < end; poff++) { 317 for (poff = start; poff < end; poff++) {
334 u8 *ptr = (u8 *)poff + *poff; 318 u8 *ptr = (u8 *)poff + *poff;
@@ -338,7 +322,7 @@ static void alternatives_smp_unlock(const s32 *start, const s32 *end,
338 /* turn lock prefix into DS segment override prefix */ 322 /* turn lock prefix into DS segment override prefix */
339 if (*ptr == 0xf0) 323 if (*ptr == 0xf0)
340 text_poke(ptr, ((unsigned char []){0x3E}), 1); 324 text_poke(ptr, ((unsigned char []){0x3E}), 1);
341 }; 325 }
342 mutex_unlock(&text_mutex); 326 mutex_unlock(&text_mutex);
343} 327}
344 328
@@ -359,7 +343,7 @@ struct smp_alt_module {
359}; 343};
360static LIST_HEAD(smp_alt_modules); 344static LIST_HEAD(smp_alt_modules);
361static DEFINE_MUTEX(smp_alt); 345static DEFINE_MUTEX(smp_alt);
362static int smp_mode = 1; /* protected by smp_alt */ 346static bool uniproc_patched = false; /* protected by smp_alt */
363 347
364void __init_or_module alternatives_smp_module_add(struct module *mod, 348void __init_or_module alternatives_smp_module_add(struct module *mod,
365 char *name, 349 char *name,
@@ -368,19 +352,18 @@ void __init_or_module alternatives_smp_module_add(struct module *mod,
368{ 352{
369 struct smp_alt_module *smp; 353 struct smp_alt_module *smp;
370 354
371 if (noreplace_smp) 355 mutex_lock(&smp_alt);
372 return; 356 if (!uniproc_patched)
357 goto unlock;
373 358
374 if (smp_alt_once) { 359 if (num_possible_cpus() == 1)
375 if (boot_cpu_has(X86_FEATURE_UP)) 360 /* Don't bother remembering, we'll never have to undo it. */
376 alternatives_smp_unlock(locks, locks_end, 361 goto smp_unlock;
377 text, text_end);
378 return;
379 }
380 362
381 smp = kzalloc(sizeof(*smp), GFP_KERNEL); 363 smp = kzalloc(sizeof(*smp), GFP_KERNEL);
382 if (NULL == smp) 364 if (NULL == smp)
383 return; /* we'll run the (safe but slow) SMP code then ... */ 365 /* we'll run the (safe but slow) SMP code then ... */
366 goto unlock;
384 367
385 smp->mod = mod; 368 smp->mod = mod;
386 smp->name = name; 369 smp->name = name;
@@ -392,11 +375,10 @@ void __init_or_module alternatives_smp_module_add(struct module *mod,
392 __func__, smp->locks, smp->locks_end, 375 __func__, smp->locks, smp->locks_end,
393 smp->text, smp->text_end, smp->name); 376 smp->text, smp->text_end, smp->name);
394 377
395 mutex_lock(&smp_alt);
396 list_add_tail(&smp->next, &smp_alt_modules); 378 list_add_tail(&smp->next, &smp_alt_modules);
397 if (boot_cpu_has(X86_FEATURE_UP)) 379smp_unlock:
398 alternatives_smp_unlock(smp->locks, smp->locks_end, 380 alternatives_smp_unlock(locks, locks_end, text, text_end);
399 smp->text, smp->text_end); 381unlock:
400 mutex_unlock(&smp_alt); 382 mutex_unlock(&smp_alt);
401} 383}
402 384
@@ -404,24 +386,18 @@ void __init_or_module alternatives_smp_module_del(struct module *mod)
404{ 386{
405 struct smp_alt_module *item; 387 struct smp_alt_module *item;
406 388
407 if (smp_alt_once || noreplace_smp)
408 return;
409
410 mutex_lock(&smp_alt); 389 mutex_lock(&smp_alt);
411 list_for_each_entry(item, &smp_alt_modules, next) { 390 list_for_each_entry(item, &smp_alt_modules, next) {
412 if (mod != item->mod) 391 if (mod != item->mod)
413 continue; 392 continue;
414 list_del(&item->next); 393 list_del(&item->next);
415 mutex_unlock(&smp_alt);
416 DPRINTK("%s: %s\n", __func__, item->name);
417 kfree(item); 394 kfree(item);
418 return; 395 break;
419 } 396 }
420 mutex_unlock(&smp_alt); 397 mutex_unlock(&smp_alt);
421} 398}
422 399
423bool skip_smp_alternatives; 400void alternatives_enable_smp(void)
424void alternatives_smp_switch(int smp)
425{ 401{
426 struct smp_alt_module *mod; 402 struct smp_alt_module *mod;
427 403
@@ -436,34 +412,21 @@ void alternatives_smp_switch(int smp)
436 pr_info("lockdep: fixing up alternatives\n"); 412 pr_info("lockdep: fixing up alternatives\n");
437#endif 413#endif
438 414
439 if (noreplace_smp || smp_alt_once || skip_smp_alternatives) 415 /* Why bother if there are no other CPUs? */
440 return; 416 BUG_ON(num_possible_cpus() == 1);
441 BUG_ON(!smp && (num_online_cpus() > 1));
442 417
443 mutex_lock(&smp_alt); 418 mutex_lock(&smp_alt);
444 419
445 /* 420 if (uniproc_patched) {
446 * Avoid unnecessary switches because it forces JIT based VMs to
447 * throw away all cached translations, which can be quite costly.
448 */
449 if (smp == smp_mode) {
450 /* nothing */
451 } else if (smp) {
452 pr_info("switching to SMP code\n"); 421 pr_info("switching to SMP code\n");
422 BUG_ON(num_online_cpus() != 1);
453 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_UP); 423 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_UP);
454 clear_cpu_cap(&cpu_data(0), X86_FEATURE_UP); 424 clear_cpu_cap(&cpu_data(0), X86_FEATURE_UP);
455 list_for_each_entry(mod, &smp_alt_modules, next) 425 list_for_each_entry(mod, &smp_alt_modules, next)
456 alternatives_smp_lock(mod->locks, mod->locks_end, 426 alternatives_smp_lock(mod->locks, mod->locks_end,
457 mod->text, mod->text_end); 427 mod->text, mod->text_end);
458 } else { 428 uniproc_patched = false;
459 pr_info("switching to UP code\n");
460 set_cpu_cap(&boot_cpu_data, X86_FEATURE_UP);
461 set_cpu_cap(&cpu_data(0), X86_FEATURE_UP);
462 list_for_each_entry(mod, &smp_alt_modules, next)
463 alternatives_smp_unlock(mod->locks, mod->locks_end,
464 mod->text, mod->text_end);
465 } 429 }
466 smp_mode = smp;
467 mutex_unlock(&smp_alt); 430 mutex_unlock(&smp_alt);
468} 431}
469 432
@@ -540,40 +503,22 @@ void __init alternative_instructions(void)
540 503
541 apply_alternatives(__alt_instructions, __alt_instructions_end); 504 apply_alternatives(__alt_instructions, __alt_instructions_end);
542 505
543 /* switch to patch-once-at-boottime-only mode and free the
544 * tables in case we know the number of CPUs will never ever
545 * change */
546#ifdef CONFIG_HOTPLUG_CPU
547 if (num_possible_cpus() < 2)
548 smp_alt_once = 1;
549#endif
550
551#ifdef CONFIG_SMP 506#ifdef CONFIG_SMP
552 if (smp_alt_once) { 507 /* Patch to UP if other cpus not imminent. */
553 if (1 == num_possible_cpus()) { 508 if (!noreplace_smp && (num_present_cpus() == 1 || setup_max_cpus <= 1)) {
554 pr_info("switching to UP code\n"); 509 uniproc_patched = true;
555 set_cpu_cap(&boot_cpu_data, X86_FEATURE_UP);
556 set_cpu_cap(&cpu_data(0), X86_FEATURE_UP);
557
558 alternatives_smp_unlock(__smp_locks, __smp_locks_end,
559 _text, _etext);
560 }
561 } else {
562 alternatives_smp_module_add(NULL, "core kernel", 510 alternatives_smp_module_add(NULL, "core kernel",
563 __smp_locks, __smp_locks_end, 511 __smp_locks, __smp_locks_end,
564 _text, _etext); 512 _text, _etext);
565
566 /* Only switch to UP mode if we don't immediately boot others */
567 if (num_present_cpus() == 1 || setup_max_cpus <= 1)
568 alternatives_smp_switch(0);
569 } 513 }
570#endif
571 apply_paravirt(__parainstructions, __parainstructions_end);
572 514
573 if (smp_alt_once) 515 if (!uniproc_patched || num_possible_cpus() == 1)
574 free_init_pages("SMP alternatives", 516 free_init_pages("SMP alternatives",
575 (unsigned long)__smp_locks, 517 (unsigned long)__smp_locks,
576 (unsigned long)__smp_locks_end); 518 (unsigned long)__smp_locks_end);
519#endif
520
521 apply_paravirt(__parainstructions, __parainstructions_end);
577 522
578 restart_nmi(); 523 restart_nmi();
579} 524}
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 24deb3082328..b17416e72fbd 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1934,7 +1934,7 @@ void smp_error_interrupt(struct pt_regs *regs)
1934 apic_printk(APIC_DEBUG, KERN_CONT " : %s", error_interrupt_reason[i]); 1934 apic_printk(APIC_DEBUG, KERN_CONT " : %s", error_interrupt_reason[i]);
1935 i++; 1935 i++;
1936 v1 >>= 1; 1936 v1 >>= 1;
1937 }; 1937 }
1938 1938
1939 apic_printk(APIC_DEBUG, KERN_CONT "\n"); 1939 apic_printk(APIC_DEBUG, KERN_CONT "\n");
1940 1940
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 9d92e19039f0..f7e98a2c0d12 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -737,6 +737,72 @@ static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c,
737} 737}
738#endif 738#endif
739 739
740static void __cpuinit cpu_set_tlb_flushall_shift(struct cpuinfo_x86 *c)
741{
742 if (!cpu_has_invlpg)
743 return;
744
745 tlb_flushall_shift = 5;
746
747 if (c->x86 <= 0x11)
748 tlb_flushall_shift = 4;
749}
750
751static void __cpuinit cpu_detect_tlb_amd(struct cpuinfo_x86 *c)
752{
753 u32 ebx, eax, ecx, edx;
754 u16 mask = 0xfff;
755
756 if (c->x86 < 0xf)
757 return;
758
759 if (c->extended_cpuid_level < 0x80000006)
760 return;
761
762 cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
763
764 tlb_lld_4k[ENTRIES] = (ebx >> 16) & mask;
765 tlb_lli_4k[ENTRIES] = ebx & mask;
766
767 /*
768 * K8 doesn't have 2M/4M entries in the L2 TLB so read out the L1 TLB
769 * characteristics from the CPUID function 0x80000005 instead.
770 */
771 if (c->x86 == 0xf) {
772 cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
773 mask = 0xff;
774 }
775
776 /* Handle DTLB 2M and 4M sizes, fall back to L1 if L2 is disabled */
777 if (!((eax >> 16) & mask)) {
778 u32 a, b, c, d;
779
780 cpuid(0x80000005, &a, &b, &c, &d);
781 tlb_lld_2m[ENTRIES] = (a >> 16) & 0xff;
782 } else {
783 tlb_lld_2m[ENTRIES] = (eax >> 16) & mask;
784 }
785
786 /* a 4M entry uses two 2M entries */
787 tlb_lld_4m[ENTRIES] = tlb_lld_2m[ENTRIES] >> 1;
788
789 /* Handle ITLB 2M and 4M sizes, fall back to L1 if L2 is disabled */
790 if (!(eax & mask)) {
791 /* Erratum 658 */
792 if (c->x86 == 0x15 && c->x86_model <= 0x1f) {
793 tlb_lli_2m[ENTRIES] = 1024;
794 } else {
795 cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
796 tlb_lli_2m[ENTRIES] = eax & 0xff;
797 }
798 } else
799 tlb_lli_2m[ENTRIES] = eax & mask;
800
801 tlb_lli_4m[ENTRIES] = tlb_lli_2m[ENTRIES] >> 1;
802
803 cpu_set_tlb_flushall_shift(c);
804}
805
740static const struct cpu_dev __cpuinitconst amd_cpu_dev = { 806static const struct cpu_dev __cpuinitconst amd_cpu_dev = {
741 .c_vendor = "AMD", 807 .c_vendor = "AMD",
742 .c_ident = { "AuthenticAMD" }, 808 .c_ident = { "AuthenticAMD" },
@@ -756,6 +822,7 @@ static const struct cpu_dev __cpuinitconst amd_cpu_dev = {
756 .c_size_cache = amd_size_cache, 822 .c_size_cache = amd_size_cache,
757#endif 823#endif
758 .c_early_init = early_init_amd, 824 .c_early_init = early_init_amd,
825 .c_detect_tlb = cpu_detect_tlb_amd,
759 .c_bsp_init = bsp_init_amd, 826 .c_bsp_init = bsp_init_amd,
760 .c_init = init_amd, 827 .c_init = init_amd,
761 .c_x86_vendor = X86_VENDOR_AMD, 828 .c_x86_vendor = X86_VENDOR_AMD,
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index c97bb7b5a9f8..d0e910da16c5 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -165,10 +165,15 @@ void __init check_bugs(void)
165 print_cpu_info(&boot_cpu_data); 165 print_cpu_info(&boot_cpu_data);
166#endif 166#endif
167 check_config(); 167 check_config();
168 check_fpu();
169 check_hlt(); 168 check_hlt();
170 check_popad(); 169 check_popad();
171 init_utsname()->machine[1] = 170 init_utsname()->machine[1] =
172 '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86); 171 '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86);
173 alternative_instructions(); 172 alternative_instructions();
173
174 /*
175 * kernel_fpu_begin/end() in check_fpu() relies on the patched
176 * alternative instructions.
177 */
178 check_fpu();
174} 179}
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index a5fbc3c5fccc..532691b6c8fe 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -476,7 +476,7 @@ void __cpuinit cpu_detect_tlb(struct cpuinfo_x86 *c)
476 476
477 printk(KERN_INFO "Last level iTLB entries: 4KB %d, 2MB %d, 4MB %d\n" \ 477 printk(KERN_INFO "Last level iTLB entries: 4KB %d, 2MB %d, 4MB %d\n" \
478 "Last level dTLB entries: 4KB %d, 2MB %d, 4MB %d\n" \ 478 "Last level dTLB entries: 4KB %d, 2MB %d, 4MB %d\n" \
479 "tlb_flushall_shift is 0x%x\n", 479 "tlb_flushall_shift: %d\n",
480 tlb_lli_4k[ENTRIES], tlb_lli_2m[ENTRIES], 480 tlb_lli_4k[ENTRIES], tlb_lli_2m[ENTRIES],
481 tlb_lli_4m[ENTRIES], tlb_lld_4k[ENTRIES], 481 tlb_lli_4m[ENTRIES], tlb_lld_4k[ENTRIES],
482 tlb_lld_2m[ENTRIES], tlb_lld_4m[ENTRIES], 482 tlb_lld_2m[ENTRIES], tlb_lld_4m[ENTRIES],
@@ -942,8 +942,7 @@ void __init identify_boot_cpu(void)
942#else 942#else
943 vgetcpu_set_mode(); 943 vgetcpu_set_mode();
944#endif 944#endif
945 if (boot_cpu_data.cpuid_level >= 2) 945 cpu_detect_tlb(&boot_cpu_data);
946 cpu_detect_tlb(&boot_cpu_data);
947} 946}
948 947
949void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) 948void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c)
@@ -1023,14 +1022,16 @@ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
1023 printk(KERN_CONT "%s ", vendor); 1022 printk(KERN_CONT "%s ", vendor);
1024 1023
1025 if (c->x86_model_id[0]) 1024 if (c->x86_model_id[0])
1026 printk(KERN_CONT "%s", c->x86_model_id); 1025 printk(KERN_CONT "%s", strim(c->x86_model_id));
1027 else 1026 else
1028 printk(KERN_CONT "%d86", c->x86); 1027 printk(KERN_CONT "%d86", c->x86);
1029 1028
1029 printk(KERN_CONT " (fam: %02x, model: %02x", c->x86, c->x86_model);
1030
1030 if (c->x86_mask || c->cpuid_level >= 0) 1031 if (c->x86_mask || c->cpuid_level >= 0)
1031 printk(KERN_CONT " stepping %02x\n", c->x86_mask); 1032 printk(KERN_CONT ", stepping: %02x)\n", c->x86_mask);
1032 else 1033 else
1033 printk(KERN_CONT "\n"); 1034 printk(KERN_CONT ")\n");
1034 1035
1035 print_cpu_msr(c); 1036 print_cpu_msr(c);
1036} 1037}
@@ -1116,8 +1117,6 @@ void syscall_init(void)
1116 X86_EFLAGS_TF|X86_EFLAGS_DF|X86_EFLAGS_IF|X86_EFLAGS_IOPL); 1117 X86_EFLAGS_TF|X86_EFLAGS_DF|X86_EFLAGS_IF|X86_EFLAGS_IOPL);
1117} 1118}
1118 1119
1119unsigned long kernel_eflags;
1120
1121/* 1120/*
1122 * Copies of the original ist values from the tss are only accessed during 1121 * Copies of the original ist values from the tss are only accessed during
1123 * debugging, no special alignment required. 1122 * debugging, no special alignment required.
@@ -1297,9 +1296,6 @@ void __cpuinit cpu_init(void)
1297 dbg_restore_debug_regs(); 1296 dbg_restore_debug_regs();
1298 1297
1299 fpu_init(); 1298 fpu_init();
1300 xsave_init();
1301
1302 raw_local_save_flags(kernel_eflags);
1303 1299
1304 if (is_uv_system()) 1300 if (is_uv_system())
1305 uv_cpu_init(); 1301 uv_cpu_init();
@@ -1352,6 +1348,5 @@ void __cpuinit cpu_init(void)
1352 dbg_restore_debug_regs(); 1348 dbg_restore_debug_regs();
1353 1349
1354 fpu_init(); 1350 fpu_init();
1355 xsave_init();
1356} 1351}
1357#endif 1352#endif
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 0a4ce2980a5a..198e019a531a 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -648,6 +648,10 @@ static void __cpuinit intel_detect_tlb(struct cpuinfo_x86 *c)
648 int i, j, n; 648 int i, j, n;
649 unsigned int regs[4]; 649 unsigned int regs[4];
650 unsigned char *desc = (unsigned char *)regs; 650 unsigned char *desc = (unsigned char *)regs;
651
652 if (c->cpuid_level < 2)
653 return;
654
651 /* Number of times to iterate */ 655 /* Number of times to iterate */
652 n = cpuid_eax(2) & 0xFF; 656 n = cpuid_eax(2) & 0xFF;
653 657
diff --git a/arch/x86/kernel/cpu/mcheck/mce-inject.c b/arch/x86/kernel/cpu/mcheck/mce-inject.c
index fc4beb393577..ddc72f839332 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-inject.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-inject.c
@@ -78,6 +78,7 @@ static void raise_exception(struct mce *m, struct pt_regs *pregs)
78} 78}
79 79
80static cpumask_var_t mce_inject_cpumask; 80static cpumask_var_t mce_inject_cpumask;
81static DEFINE_MUTEX(mce_inject_mutex);
81 82
82static int mce_raise_notify(unsigned int cmd, struct pt_regs *regs) 83static int mce_raise_notify(unsigned int cmd, struct pt_regs *regs)
83{ 84{
@@ -194,7 +195,11 @@ static void raise_mce(struct mce *m)
194 put_online_cpus(); 195 put_online_cpus();
195 } else 196 } else
196#endif 197#endif
198 {
199 preempt_disable();
197 raise_local(); 200 raise_local();
201 preempt_enable();
202 }
198} 203}
199 204
200/* Error injection interface */ 205/* Error injection interface */
@@ -225,7 +230,10 @@ static ssize_t mce_write(struct file *filp, const char __user *ubuf,
225 * so do it a jiffie or two later everywhere. 230 * so do it a jiffie or two later everywhere.
226 */ 231 */
227 schedule_timeout(2); 232 schedule_timeout(2);
233
234 mutex_lock(&mce_inject_mutex);
228 raise_mce(&m); 235 raise_mce(&m);
236 mutex_unlock(&mce_inject_mutex);
229 return usize; 237 return usize;
230} 238}
231 239
diff --git a/arch/x86/kernel/cpu/mcheck/mce-internal.h b/arch/x86/kernel/cpu/mcheck/mce-internal.h
index ed44c8a65858..6a05c1d327a9 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-internal.h
+++ b/arch/x86/kernel/cpu/mcheck/mce-internal.h
@@ -28,6 +28,18 @@ extern int mce_ser;
28 28
29extern struct mce_bank *mce_banks; 29extern struct mce_bank *mce_banks;
30 30
31#ifdef CONFIG_X86_MCE_INTEL
32unsigned long mce_intel_adjust_timer(unsigned long interval);
33void mce_intel_cmci_poll(void);
34void mce_intel_hcpu_update(unsigned long cpu);
35#else
36# define mce_intel_adjust_timer mce_adjust_timer_default
37static inline void mce_intel_cmci_poll(void) { }
38static inline void mce_intel_hcpu_update(unsigned long cpu) { }
39#endif
40
41void mce_timer_kick(unsigned long interval);
42
31#ifdef CONFIG_ACPI_APEI 43#ifdef CONFIG_ACPI_APEI
32int apei_write_mce(struct mce *m); 44int apei_write_mce(struct mce *m);
33ssize_t apei_read_mce(struct mce *m, u64 *record_id); 45ssize_t apei_read_mce(struct mce *m, u64 *record_id);
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 292d0258311c..29e87d3b2843 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -83,6 +83,7 @@ static int mce_dont_log_ce __read_mostly;
83int mce_cmci_disabled __read_mostly; 83int mce_cmci_disabled __read_mostly;
84int mce_ignore_ce __read_mostly; 84int mce_ignore_ce __read_mostly;
85int mce_ser __read_mostly; 85int mce_ser __read_mostly;
86int mce_bios_cmci_threshold __read_mostly;
86 87
87struct mce_bank *mce_banks __read_mostly; 88struct mce_bank *mce_banks __read_mostly;
88 89
@@ -1266,6 +1267,14 @@ static unsigned long check_interval = 5 * 60; /* 5 minutes */
1266static DEFINE_PER_CPU(unsigned long, mce_next_interval); /* in jiffies */ 1267static DEFINE_PER_CPU(unsigned long, mce_next_interval); /* in jiffies */
1267static DEFINE_PER_CPU(struct timer_list, mce_timer); 1268static DEFINE_PER_CPU(struct timer_list, mce_timer);
1268 1269
1270static unsigned long mce_adjust_timer_default(unsigned long interval)
1271{
1272 return interval;
1273}
1274
1275static unsigned long (*mce_adjust_timer)(unsigned long interval) =
1276 mce_adjust_timer_default;
1277
1269static void mce_timer_fn(unsigned long data) 1278static void mce_timer_fn(unsigned long data)
1270{ 1279{
1271 struct timer_list *t = &__get_cpu_var(mce_timer); 1280 struct timer_list *t = &__get_cpu_var(mce_timer);
@@ -1276,6 +1285,7 @@ static void mce_timer_fn(unsigned long data)
1276 if (mce_available(__this_cpu_ptr(&cpu_info))) { 1285 if (mce_available(__this_cpu_ptr(&cpu_info))) {
1277 machine_check_poll(MCP_TIMESTAMP, 1286 machine_check_poll(MCP_TIMESTAMP,
1278 &__get_cpu_var(mce_poll_banks)); 1287 &__get_cpu_var(mce_poll_banks));
1288 mce_intel_cmci_poll();
1279 } 1289 }
1280 1290
1281 /* 1291 /*
@@ -1283,14 +1293,38 @@ static void mce_timer_fn(unsigned long data)
1283 * polling interval, otherwise increase the polling interval. 1293 * polling interval, otherwise increase the polling interval.
1284 */ 1294 */
1285 iv = __this_cpu_read(mce_next_interval); 1295 iv = __this_cpu_read(mce_next_interval);
1286 if (mce_notify_irq()) 1296 if (mce_notify_irq()) {
1287 iv = max(iv / 2, (unsigned long) HZ/100); 1297 iv = max(iv / 2, (unsigned long) HZ/100);
1288 else 1298 } else {
1289 iv = min(iv * 2, round_jiffies_relative(check_interval * HZ)); 1299 iv = min(iv * 2, round_jiffies_relative(check_interval * HZ));
1300 iv = mce_adjust_timer(iv);
1301 }
1290 __this_cpu_write(mce_next_interval, iv); 1302 __this_cpu_write(mce_next_interval, iv);
1303 /* Might have become 0 after CMCI storm subsided */
1304 if (iv) {
1305 t->expires = jiffies + iv;
1306 add_timer_on(t, smp_processor_id());
1307 }
1308}
1291 1309
1292 t->expires = jiffies + iv; 1310/*
1293 add_timer_on(t, smp_processor_id()); 1311 * Ensure that the timer is firing in @interval from now.
1312 */
1313void mce_timer_kick(unsigned long interval)
1314{
1315 struct timer_list *t = &__get_cpu_var(mce_timer);
1316 unsigned long when = jiffies + interval;
1317 unsigned long iv = __this_cpu_read(mce_next_interval);
1318
1319 if (timer_pending(t)) {
1320 if (time_before(when, t->expires))
1321 mod_timer_pinned(t, when);
1322 } else {
1323 t->expires = round_jiffies(when);
1324 add_timer_on(t, smp_processor_id());
1325 }
1326 if (interval < iv)
1327 __this_cpu_write(mce_next_interval, interval);
1294} 1328}
1295 1329
1296/* Must not be called in IRQ context where del_timer_sync() can deadlock */ 1330/* Must not be called in IRQ context where del_timer_sync() can deadlock */
@@ -1585,6 +1619,7 @@ static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c)
1585 switch (c->x86_vendor) { 1619 switch (c->x86_vendor) {
1586 case X86_VENDOR_INTEL: 1620 case X86_VENDOR_INTEL:
1587 mce_intel_feature_init(c); 1621 mce_intel_feature_init(c);
1622 mce_adjust_timer = mce_intel_adjust_timer;
1588 break; 1623 break;
1589 case X86_VENDOR_AMD: 1624 case X86_VENDOR_AMD:
1590 mce_amd_feature_init(c); 1625 mce_amd_feature_init(c);
@@ -1594,23 +1629,28 @@ static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c)
1594 } 1629 }
1595} 1630}
1596 1631
1597static void __mcheck_cpu_init_timer(void) 1632static void mce_start_timer(unsigned int cpu, struct timer_list *t)
1598{ 1633{
1599 struct timer_list *t = &__get_cpu_var(mce_timer); 1634 unsigned long iv = mce_adjust_timer(check_interval * HZ);
1600 unsigned long iv = check_interval * HZ;
1601 1635
1602 setup_timer(t, mce_timer_fn, smp_processor_id()); 1636 __this_cpu_write(mce_next_interval, iv);
1603 1637
1604 if (mce_ignore_ce) 1638 if (mce_ignore_ce || !iv)
1605 return; 1639 return;
1606 1640
1607 __this_cpu_write(mce_next_interval, iv);
1608 if (!iv)
1609 return;
1610 t->expires = round_jiffies(jiffies + iv); 1641 t->expires = round_jiffies(jiffies + iv);
1611 add_timer_on(t, smp_processor_id()); 1642 add_timer_on(t, smp_processor_id());
1612} 1643}
1613 1644
1645static void __mcheck_cpu_init_timer(void)
1646{
1647 struct timer_list *t = &__get_cpu_var(mce_timer);
1648 unsigned int cpu = smp_processor_id();
1649
1650 setup_timer(t, mce_timer_fn, cpu);
1651 mce_start_timer(cpu, t);
1652}
1653
1614/* Handle unconfigured int18 (should never happen) */ 1654/* Handle unconfigured int18 (should never happen) */
1615static void unexpected_machine_check(struct pt_regs *regs, long error_code) 1655static void unexpected_machine_check(struct pt_regs *regs, long error_code)
1616{ 1656{
@@ -1907,6 +1947,7 @@ static struct miscdevice mce_chrdev_device = {
1907 * check, or 0 to not wait 1947 * check, or 0 to not wait
1908 * mce=bootlog Log MCEs from before booting. Disabled by default on AMD. 1948 * mce=bootlog Log MCEs from before booting. Disabled by default on AMD.
1909 * mce=nobootlog Don't log MCEs from before booting. 1949 * mce=nobootlog Don't log MCEs from before booting.
1950 * mce=bios_cmci_threshold Don't program the CMCI threshold
1910 */ 1951 */
1911static int __init mcheck_enable(char *str) 1952static int __init mcheck_enable(char *str)
1912{ 1953{
@@ -1926,6 +1967,8 @@ static int __init mcheck_enable(char *str)
1926 mce_ignore_ce = 1; 1967 mce_ignore_ce = 1;
1927 else if (!strcmp(str, "bootlog") || !strcmp(str, "nobootlog")) 1968 else if (!strcmp(str, "bootlog") || !strcmp(str, "nobootlog"))
1928 mce_bootlog = (str[0] == 'b'); 1969 mce_bootlog = (str[0] == 'b');
1970 else if (!strcmp(str, "bios_cmci_threshold"))
1971 mce_bios_cmci_threshold = 1;
1929 else if (isdigit(str[0])) { 1972 else if (isdigit(str[0])) {
1930 get_option(&str, &tolerant); 1973 get_option(&str, &tolerant);
1931 if (*str == ',') { 1974 if (*str == ',') {
@@ -2166,6 +2209,11 @@ static struct dev_ext_attribute dev_attr_cmci_disabled = {
2166 &mce_cmci_disabled 2209 &mce_cmci_disabled
2167}; 2210};
2168 2211
2212static struct dev_ext_attribute dev_attr_bios_cmci_threshold = {
2213 __ATTR(bios_cmci_threshold, 0444, device_show_int, NULL),
2214 &mce_bios_cmci_threshold
2215};
2216
2169static struct device_attribute *mce_device_attrs[] = { 2217static struct device_attribute *mce_device_attrs[] = {
2170 &dev_attr_tolerant.attr, 2218 &dev_attr_tolerant.attr,
2171 &dev_attr_check_interval.attr, 2219 &dev_attr_check_interval.attr,
@@ -2174,6 +2222,7 @@ static struct device_attribute *mce_device_attrs[] = {
2174 &dev_attr_dont_log_ce.attr, 2222 &dev_attr_dont_log_ce.attr,
2175 &dev_attr_ignore_ce.attr, 2223 &dev_attr_ignore_ce.attr,
2176 &dev_attr_cmci_disabled.attr, 2224 &dev_attr_cmci_disabled.attr,
2225 &dev_attr_bios_cmci_threshold.attr,
2177 NULL 2226 NULL
2178}; 2227};
2179 2228
@@ -2294,38 +2343,33 @@ mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
2294 unsigned int cpu = (unsigned long)hcpu; 2343 unsigned int cpu = (unsigned long)hcpu;
2295 struct timer_list *t = &per_cpu(mce_timer, cpu); 2344 struct timer_list *t = &per_cpu(mce_timer, cpu);
2296 2345
2297 switch (action) { 2346 switch (action & ~CPU_TASKS_FROZEN) {
2298 case CPU_ONLINE: 2347 case CPU_ONLINE:
2299 case CPU_ONLINE_FROZEN:
2300 mce_device_create(cpu); 2348 mce_device_create(cpu);
2301 if (threshold_cpu_callback) 2349 if (threshold_cpu_callback)
2302 threshold_cpu_callback(action, cpu); 2350 threshold_cpu_callback(action, cpu);
2303 break; 2351 break;
2304 case CPU_DEAD: 2352 case CPU_DEAD:
2305 case CPU_DEAD_FROZEN:
2306 if (threshold_cpu_callback) 2353 if (threshold_cpu_callback)
2307 threshold_cpu_callback(action, cpu); 2354 threshold_cpu_callback(action, cpu);
2308 mce_device_remove(cpu); 2355 mce_device_remove(cpu);
2356 mce_intel_hcpu_update(cpu);
2309 break; 2357 break;
2310 case CPU_DOWN_PREPARE: 2358 case CPU_DOWN_PREPARE:
2311 case CPU_DOWN_PREPARE_FROZEN:
2312 del_timer_sync(t);
2313 smp_call_function_single(cpu, mce_disable_cpu, &action, 1); 2359 smp_call_function_single(cpu, mce_disable_cpu, &action, 1);
2360 del_timer_sync(t);
2314 break; 2361 break;
2315 case CPU_DOWN_FAILED: 2362 case CPU_DOWN_FAILED:
2316 case CPU_DOWN_FAILED_FROZEN:
2317 if (!mce_ignore_ce && check_interval) {
2318 t->expires = round_jiffies(jiffies +
2319 per_cpu(mce_next_interval, cpu));
2320 add_timer_on(t, cpu);
2321 }
2322 smp_call_function_single(cpu, mce_reenable_cpu, &action, 1); 2363 smp_call_function_single(cpu, mce_reenable_cpu, &action, 1);
2364 mce_start_timer(cpu, t);
2323 break; 2365 break;
2324 case CPU_POST_DEAD: 2366 }
2367
2368 if (action == CPU_POST_DEAD) {
2325 /* intentionally ignoring frozen here */ 2369 /* intentionally ignoring frozen here */
2326 cmci_rediscover(cpu); 2370 cmci_rediscover(cpu);
2327 break;
2328 } 2371 }
2372
2329 return NOTIFY_OK; 2373 return NOTIFY_OK;
2330} 2374}
2331 2375
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c
index 38e49bc95ffc..5f88abf07e9c 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_intel.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c
@@ -15,6 +15,8 @@
15#include <asm/msr.h> 15#include <asm/msr.h>
16#include <asm/mce.h> 16#include <asm/mce.h>
17 17
18#include "mce-internal.h"
19
18/* 20/*
19 * Support for Intel Correct Machine Check Interrupts. This allows 21 * Support for Intel Correct Machine Check Interrupts. This allows
20 * the CPU to raise an interrupt when a corrected machine check happened. 22 * the CPU to raise an interrupt when a corrected machine check happened.
@@ -30,7 +32,22 @@ static DEFINE_PER_CPU(mce_banks_t, mce_banks_owned);
30 */ 32 */
31static DEFINE_RAW_SPINLOCK(cmci_discover_lock); 33static DEFINE_RAW_SPINLOCK(cmci_discover_lock);
32 34
33#define CMCI_THRESHOLD 1 35#define CMCI_THRESHOLD 1
36#define CMCI_POLL_INTERVAL (30 * HZ)
37#define CMCI_STORM_INTERVAL (1 * HZ)
38#define CMCI_STORM_THRESHOLD 15
39
40static DEFINE_PER_CPU(unsigned long, cmci_time_stamp);
41static DEFINE_PER_CPU(unsigned int, cmci_storm_cnt);
42static DEFINE_PER_CPU(unsigned int, cmci_storm_state);
43
44enum {
45 CMCI_STORM_NONE,
46 CMCI_STORM_ACTIVE,
47 CMCI_STORM_SUBSIDED,
48};
49
50static atomic_t cmci_storm_on_cpus;
34 51
35static int cmci_supported(int *banks) 52static int cmci_supported(int *banks)
36{ 53{
@@ -53,6 +70,93 @@ static int cmci_supported(int *banks)
53 return !!(cap & MCG_CMCI_P); 70 return !!(cap & MCG_CMCI_P);
54} 71}
55 72
73void mce_intel_cmci_poll(void)
74{
75 if (__this_cpu_read(cmci_storm_state) == CMCI_STORM_NONE)
76 return;
77 machine_check_poll(MCP_TIMESTAMP, &__get_cpu_var(mce_banks_owned));
78}
79
80void mce_intel_hcpu_update(unsigned long cpu)
81{
82 if (per_cpu(cmci_storm_state, cpu) == CMCI_STORM_ACTIVE)
83 atomic_dec(&cmci_storm_on_cpus);
84
85 per_cpu(cmci_storm_state, cpu) = CMCI_STORM_NONE;
86}
87
88unsigned long mce_intel_adjust_timer(unsigned long interval)
89{
90 int r;
91
92 if (interval < CMCI_POLL_INTERVAL)
93 return interval;
94
95 switch (__this_cpu_read(cmci_storm_state)) {
96 case CMCI_STORM_ACTIVE:
97 /*
98 * We switch back to interrupt mode once the poll timer has
99 * silenced itself. That means no events recorded and the
100 * timer interval is back to our poll interval.
101 */
102 __this_cpu_write(cmci_storm_state, CMCI_STORM_SUBSIDED);
103 r = atomic_sub_return(1, &cmci_storm_on_cpus);
104 if (r == 0)
105 pr_notice("CMCI storm subsided: switching to interrupt mode\n");
106 /* FALLTHROUGH */
107
108 case CMCI_STORM_SUBSIDED:
109 /*
110 * We wait for all cpus to go back to SUBSIDED
111 * state. When that happens we switch back to
112 * interrupt mode.
113 */
114 if (!atomic_read(&cmci_storm_on_cpus)) {
115 __this_cpu_write(cmci_storm_state, CMCI_STORM_NONE);
116 cmci_reenable();
117 cmci_recheck();
118 }
119 return CMCI_POLL_INTERVAL;
120 default:
121 /*
122 * We have shiny weather. Let the poll do whatever it
123 * thinks.
124 */
125 return interval;
126 }
127}
128
129static bool cmci_storm_detect(void)
130{
131 unsigned int cnt = __this_cpu_read(cmci_storm_cnt);
132 unsigned long ts = __this_cpu_read(cmci_time_stamp);
133 unsigned long now = jiffies;
134 int r;
135
136 if (__this_cpu_read(cmci_storm_state) != CMCI_STORM_NONE)
137 return true;
138
139 if (time_before_eq(now, ts + CMCI_STORM_INTERVAL)) {
140 cnt++;
141 } else {
142 cnt = 1;
143 __this_cpu_write(cmci_time_stamp, now);
144 }
145 __this_cpu_write(cmci_storm_cnt, cnt);
146
147 if (cnt <= CMCI_STORM_THRESHOLD)
148 return false;
149
150 cmci_clear();
151 __this_cpu_write(cmci_storm_state, CMCI_STORM_ACTIVE);
152 r = atomic_add_return(1, &cmci_storm_on_cpus);
153 mce_timer_kick(CMCI_POLL_INTERVAL);
154
155 if (r == 1)
156 pr_notice("CMCI storm detected: switching to poll mode\n");
157 return true;
158}
159
56/* 160/*
57 * The interrupt handler. This is called on every event. 161 * The interrupt handler. This is called on every event.
58 * Just call the poller directly to log any events. 162 * Just call the poller directly to log any events.
@@ -61,33 +165,28 @@ static int cmci_supported(int *banks)
61 */ 165 */
62static void intel_threshold_interrupt(void) 166static void intel_threshold_interrupt(void)
63{ 167{
168 if (cmci_storm_detect())
169 return;
64 machine_check_poll(MCP_TIMESTAMP, &__get_cpu_var(mce_banks_owned)); 170 machine_check_poll(MCP_TIMESTAMP, &__get_cpu_var(mce_banks_owned));
65 mce_notify_irq(); 171 mce_notify_irq();
66} 172}
67 173
68static void print_update(char *type, int *hdr, int num)
69{
70 if (*hdr == 0)
71 printk(KERN_INFO "CPU %d MCA banks", smp_processor_id());
72 *hdr = 1;
73 printk(KERN_CONT " %s:%d", type, num);
74}
75
76/* 174/*
77 * Enable CMCI (Corrected Machine Check Interrupt) for available MCE banks 175 * Enable CMCI (Corrected Machine Check Interrupt) for available MCE banks
78 * on this CPU. Use the algorithm recommended in the SDM to discover shared 176 * on this CPU. Use the algorithm recommended in the SDM to discover shared
79 * banks. 177 * banks.
80 */ 178 */
81static void cmci_discover(int banks, int boot) 179static void cmci_discover(int banks)
82{ 180{
83 unsigned long *owned = (void *)&__get_cpu_var(mce_banks_owned); 181 unsigned long *owned = (void *)&__get_cpu_var(mce_banks_owned);
84 unsigned long flags; 182 unsigned long flags;
85 int hdr = 0;
86 int i; 183 int i;
184 int bios_wrong_thresh = 0;
87 185
88 raw_spin_lock_irqsave(&cmci_discover_lock, flags); 186 raw_spin_lock_irqsave(&cmci_discover_lock, flags);
89 for (i = 0; i < banks; i++) { 187 for (i = 0; i < banks; i++) {
90 u64 val; 188 u64 val;
189 int bios_zero_thresh = 0;
91 190
92 if (test_bit(i, owned)) 191 if (test_bit(i, owned))
93 continue; 192 continue;
@@ -96,29 +195,52 @@ static void cmci_discover(int banks, int boot)
96 195
97 /* Already owned by someone else? */ 196 /* Already owned by someone else? */
98 if (val & MCI_CTL2_CMCI_EN) { 197 if (val & MCI_CTL2_CMCI_EN) {
99 if (test_and_clear_bit(i, owned) && !boot) 198 clear_bit(i, owned);
100 print_update("SHD", &hdr, i);
101 __clear_bit(i, __get_cpu_var(mce_poll_banks)); 199 __clear_bit(i, __get_cpu_var(mce_poll_banks));
102 continue; 200 continue;
103 } 201 }
104 202
105 val &= ~MCI_CTL2_CMCI_THRESHOLD_MASK; 203 if (!mce_bios_cmci_threshold) {
106 val |= MCI_CTL2_CMCI_EN | CMCI_THRESHOLD; 204 val &= ~MCI_CTL2_CMCI_THRESHOLD_MASK;
205 val |= CMCI_THRESHOLD;
206 } else if (!(val & MCI_CTL2_CMCI_THRESHOLD_MASK)) {
207 /*
208 * If bios_cmci_threshold boot option was specified
209 * but the threshold is zero, we'll try to initialize
210 * it to 1.
211 */
212 bios_zero_thresh = 1;
213 val |= CMCI_THRESHOLD;
214 }
215
216 val |= MCI_CTL2_CMCI_EN;
107 wrmsrl(MSR_IA32_MCx_CTL2(i), val); 217 wrmsrl(MSR_IA32_MCx_CTL2(i), val);
108 rdmsrl(MSR_IA32_MCx_CTL2(i), val); 218 rdmsrl(MSR_IA32_MCx_CTL2(i), val);
109 219
110 /* Did the enable bit stick? -- the bank supports CMCI */ 220 /* Did the enable bit stick? -- the bank supports CMCI */
111 if (val & MCI_CTL2_CMCI_EN) { 221 if (val & MCI_CTL2_CMCI_EN) {
112 if (!test_and_set_bit(i, owned) && !boot) 222 set_bit(i, owned);
113 print_update("CMCI", &hdr, i);
114 __clear_bit(i, __get_cpu_var(mce_poll_banks)); 223 __clear_bit(i, __get_cpu_var(mce_poll_banks));
224 /*
225 * We are able to set thresholds for some banks that
226 * had a threshold of 0. This means the BIOS has not
227 * set the thresholds properly or does not work with
228 * this boot option. Note down now and report later.
229 */
230 if (mce_bios_cmci_threshold && bios_zero_thresh &&
231 (val & MCI_CTL2_CMCI_THRESHOLD_MASK))
232 bios_wrong_thresh = 1;
115 } else { 233 } else {
116 WARN_ON(!test_bit(i, __get_cpu_var(mce_poll_banks))); 234 WARN_ON(!test_bit(i, __get_cpu_var(mce_poll_banks)));
117 } 235 }
118 } 236 }
119 raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); 237 raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
120 if (hdr) 238 if (mce_bios_cmci_threshold && bios_wrong_thresh) {
121 printk(KERN_CONT "\n"); 239 pr_info_once(
240 "bios_cmci_threshold: Some banks do not have valid thresholds set\n");
241 pr_info_once(
242 "bios_cmci_threshold: Make sure your BIOS supports this boot option\n");
243 }
122} 244}
123 245
124/* 246/*
@@ -156,7 +278,7 @@ void cmci_clear(void)
156 continue; 278 continue;
157 /* Disable CMCI */ 279 /* Disable CMCI */
158 rdmsrl(MSR_IA32_MCx_CTL2(i), val); 280 rdmsrl(MSR_IA32_MCx_CTL2(i), val);
159 val &= ~(MCI_CTL2_CMCI_EN|MCI_CTL2_CMCI_THRESHOLD_MASK); 281 val &= ~MCI_CTL2_CMCI_EN;
160 wrmsrl(MSR_IA32_MCx_CTL2(i), val); 282 wrmsrl(MSR_IA32_MCx_CTL2(i), val);
161 __clear_bit(i, __get_cpu_var(mce_banks_owned)); 283 __clear_bit(i, __get_cpu_var(mce_banks_owned));
162 } 284 }
@@ -186,7 +308,7 @@ void cmci_rediscover(int dying)
186 continue; 308 continue;
187 /* Recheck banks in case CPUs don't all have the same */ 309 /* Recheck banks in case CPUs don't all have the same */
188 if (cmci_supported(&banks)) 310 if (cmci_supported(&banks))
189 cmci_discover(banks, 0); 311 cmci_discover(banks);
190 } 312 }
191 313
192 set_cpus_allowed_ptr(current, old); 314 set_cpus_allowed_ptr(current, old);
@@ -200,7 +322,7 @@ void cmci_reenable(void)
200{ 322{
201 int banks; 323 int banks;
202 if (cmci_supported(&banks)) 324 if (cmci_supported(&banks))
203 cmci_discover(banks, 0); 325 cmci_discover(banks);
204} 326}
205 327
206static void intel_init_cmci(void) 328static void intel_init_cmci(void)
@@ -211,7 +333,7 @@ static void intel_init_cmci(void)
211 return; 333 return;
212 334
213 mce_threshold_vector = intel_threshold_interrupt; 335 mce_threshold_vector = intel_threshold_interrupt;
214 cmci_discover(banks, 1); 336 cmci_discover(banks);
215 /* 337 /*
216 * For CPU #0 this runs with still disabled APIC, but that's 338 * For CPU #0 this runs with still disabled APIC, but that's
217 * ok because only the vector is set up. We still do another 339 * ok because only the vector is set up. We still do another
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 6605a81ba339..8b6defe7eefc 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -586,6 +586,8 @@ extern struct event_constraint intel_westmere_pebs_event_constraints[];
586 586
587extern struct event_constraint intel_snb_pebs_event_constraints[]; 587extern struct event_constraint intel_snb_pebs_event_constraints[];
588 588
589extern struct event_constraint intel_ivb_pebs_event_constraints[];
590
589struct event_constraint *intel_pebs_constraints(struct perf_event *event); 591struct event_constraint *intel_pebs_constraints(struct perf_event *event);
590 592
591void intel_pmu_pebs_enable(struct perf_event *event); 593void intel_pmu_pebs_enable(struct perf_event *event);
diff --git a/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
index 7bfb5bec8630..eebd5ffe1bba 100644
--- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c
+++ b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
@@ -209,6 +209,15 @@ static int perf_ibs_precise_event(struct perf_event *event, u64 *config)
209 return -EOPNOTSUPP; 209 return -EOPNOTSUPP;
210} 210}
211 211
212static const struct perf_event_attr ibs_notsupp = {
213 .exclude_user = 1,
214 .exclude_kernel = 1,
215 .exclude_hv = 1,
216 .exclude_idle = 1,
217 .exclude_host = 1,
218 .exclude_guest = 1,
219};
220
212static int perf_ibs_init(struct perf_event *event) 221static int perf_ibs_init(struct perf_event *event)
213{ 222{
214 struct hw_perf_event *hwc = &event->hw; 223 struct hw_perf_event *hwc = &event->hw;
@@ -229,6 +238,9 @@ static int perf_ibs_init(struct perf_event *event)
229 if (event->pmu != &perf_ibs->pmu) 238 if (event->pmu != &perf_ibs->pmu)
230 return -ENOENT; 239 return -ENOENT;
231 240
241 if (perf_flags(&event->attr) & perf_flags(&ibs_notsupp))
242 return -EINVAL;
243
232 if (config & ~perf_ibs->config_mask) 244 if (config & ~perf_ibs->config_mask)
233 return -EINVAL; 245 return -EINVAL;
234 246
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 7f2739e03e79..6bca492b8547 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -2008,6 +2008,7 @@ __init int intel_pmu_init(void)
2008 break; 2008 break;
2009 2009
2010 case 28: /* Atom */ 2010 case 28: /* Atom */
2011 case 54: /* Cedariew */
2011 memcpy(hw_cache_event_ids, atom_hw_cache_event_ids, 2012 memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
2012 sizeof(hw_cache_event_ids)); 2013 sizeof(hw_cache_event_ids));
2013 2014
@@ -2047,7 +2048,6 @@ __init int intel_pmu_init(void)
2047 case 42: /* SandyBridge */ 2048 case 42: /* SandyBridge */
2048 case 45: /* SandyBridge, "Romely-EP" */ 2049 case 45: /* SandyBridge, "Romely-EP" */
2049 x86_add_quirk(intel_sandybridge_quirk); 2050 x86_add_quirk(intel_sandybridge_quirk);
2050 case 58: /* IvyBridge */
2051 memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, 2051 memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
2052 sizeof(hw_cache_event_ids)); 2052 sizeof(hw_cache_event_ids));
2053 memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, 2053 memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
@@ -2072,6 +2072,29 @@ __init int intel_pmu_init(void)
2072 2072
2073 pr_cont("SandyBridge events, "); 2073 pr_cont("SandyBridge events, ");
2074 break; 2074 break;
2075 case 58: /* IvyBridge */
2076 memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
2077 sizeof(hw_cache_event_ids));
2078 memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
2079 sizeof(hw_cache_extra_regs));
2080
2081 intel_pmu_lbr_init_snb();
2082
2083 x86_pmu.event_constraints = intel_snb_event_constraints;
2084 x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints;
2085 x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
2086 x86_pmu.extra_regs = intel_snb_extra_regs;
2087 /* all extra regs are per-cpu when HT is on */
2088 x86_pmu.er_flags |= ERF_HAS_RSP_1;
2089 x86_pmu.er_flags |= ERF_NO_HT_SHARING;
2090
2091 /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */
2092 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
2093 X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
2094
2095 pr_cont("IvyBridge events, ");
2096 break;
2097
2075 2098
2076 default: 2099 default:
2077 switch (x86_pmu.version) { 2100 switch (x86_pmu.version) {
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index e38d97bf4259..826054a4f2ee 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -407,6 +407,20 @@ struct event_constraint intel_snb_pebs_event_constraints[] = {
407 EVENT_CONSTRAINT_END 407 EVENT_CONSTRAINT_END
408}; 408};
409 409
410struct event_constraint intel_ivb_pebs_event_constraints[] = {
411 INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
412 INTEL_UEVENT_CONSTRAINT(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
413 INTEL_UEVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */
414 INTEL_EVENT_CONSTRAINT(0xc4, 0xf), /* BR_INST_RETIRED.* */
415 INTEL_EVENT_CONSTRAINT(0xc5, 0xf), /* BR_MISP_RETIRED.* */
416 INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.* */
417 INTEL_EVENT_CONSTRAINT(0xd0, 0xf), /* MEM_UOP_RETIRED.* */
418 INTEL_EVENT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
419 INTEL_EVENT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
420 INTEL_EVENT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
421 EVENT_CONSTRAINT_END
422};
423
410struct event_constraint *intel_pebs_constraints(struct perf_event *event) 424struct event_constraint *intel_pebs_constraints(struct perf_event *event)
411{ 425{
412 struct event_constraint *c; 426 struct event_constraint *c;
diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
index 520b4265fcd2..da02e9cc3754 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
@@ -686,7 +686,8 @@ void intel_pmu_lbr_init_atom(void)
686 * to have an operational LBR which can freeze 686 * to have an operational LBR which can freeze
687 * on PMU interrupt 687 * on PMU interrupt
688 */ 688 */
689 if (boot_cpu_data.x86_mask < 10) { 689 if (boot_cpu_data.x86_model == 28
690 && boot_cpu_data.x86_mask < 10) {
690 pr_cont("LBR disabled due to erratum"); 691 pr_cont("LBR disabled due to erratum");
691 return; 692 return;
692 } 693 }
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
index 0a5571080e74..99d96a4978b5 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
@@ -661,6 +661,11 @@ static void snb_uncore_msr_init_box(struct intel_uncore_box *box)
661 } 661 }
662} 662}
663 663
664static struct uncore_event_desc snb_uncore_events[] = {
665 INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
666 { /* end: all zeroes */ },
667};
668
664static struct attribute *snb_uncore_formats_attr[] = { 669static struct attribute *snb_uncore_formats_attr[] = {
665 &format_attr_event.attr, 670 &format_attr_event.attr,
666 &format_attr_umask.attr, 671 &format_attr_umask.attr,
@@ -704,6 +709,7 @@ static struct intel_uncore_type snb_uncore_cbox = {
704 .constraints = snb_uncore_cbox_constraints, 709 .constraints = snb_uncore_cbox_constraints,
705 .ops = &snb_uncore_msr_ops, 710 .ops = &snb_uncore_msr_ops,
706 .format_group = &snb_uncore_format_group, 711 .format_group = &snb_uncore_format_group,
712 .event_descs = snb_uncore_events,
707}; 713};
708 714
709static struct intel_uncore_type *snb_msr_uncores[] = { 715static struct intel_uncore_type *snb_msr_uncores[] = {
@@ -1944,7 +1950,7 @@ struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, int cp
1944static struct intel_uncore_box * 1950static struct intel_uncore_box *
1945uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu) 1951uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu)
1946{ 1952{
1947 static struct intel_uncore_box *box; 1953 struct intel_uncore_box *box;
1948 1954
1949 box = *per_cpu_ptr(pmu->box, cpu); 1955 box = *per_cpu_ptr(pmu->box, cpu);
1950 if (box) 1956 if (box)
@@ -2341,6 +2347,27 @@ int uncore_pmu_event_init(struct perf_event *event)
2341 return ret; 2347 return ret;
2342} 2348}
2343 2349
2350static ssize_t uncore_get_attr_cpumask(struct device *dev,
2351 struct device_attribute *attr, char *buf)
2352{
2353 int n = cpulist_scnprintf(buf, PAGE_SIZE - 2, &uncore_cpu_mask);
2354
2355 buf[n++] = '\n';
2356 buf[n] = '\0';
2357 return n;
2358}
2359
2360static DEVICE_ATTR(cpumask, S_IRUGO, uncore_get_attr_cpumask, NULL);
2361
2362static struct attribute *uncore_pmu_attrs[] = {
2363 &dev_attr_cpumask.attr,
2364 NULL,
2365};
2366
2367static struct attribute_group uncore_pmu_attr_group = {
2368 .attrs = uncore_pmu_attrs,
2369};
2370
2344static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu) 2371static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu)
2345{ 2372{
2346 int ret; 2373 int ret;
@@ -2378,8 +2405,8 @@ static void __init uncore_type_exit(struct intel_uncore_type *type)
2378 free_percpu(type->pmus[i].box); 2405 free_percpu(type->pmus[i].box);
2379 kfree(type->pmus); 2406 kfree(type->pmus);
2380 type->pmus = NULL; 2407 type->pmus = NULL;
2381 kfree(type->attr_groups[1]); 2408 kfree(type->events_group);
2382 type->attr_groups[1] = NULL; 2409 type->events_group = NULL;
2383} 2410}
2384 2411
2385static void __init uncore_types_exit(struct intel_uncore_type **types) 2412static void __init uncore_types_exit(struct intel_uncore_type **types)
@@ -2431,9 +2458,10 @@ static int __init uncore_type_init(struct intel_uncore_type *type)
2431 for (j = 0; j < i; j++) 2458 for (j = 0; j < i; j++)
2432 attrs[j] = &type->event_descs[j].attr.attr; 2459 attrs[j] = &type->event_descs[j].attr.attr;
2433 2460
2434 type->attr_groups[1] = events_group; 2461 type->events_group = events_group;
2435 } 2462 }
2436 2463
2464 type->pmu_group = &uncore_pmu_attr_group;
2437 type->pmus = pmus; 2465 type->pmus = pmus;
2438 return 0; 2466 return 0;
2439fail: 2467fail:
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h
index 5b81c1856aac..e68a4550e952 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h
@@ -369,10 +369,12 @@ struct intel_uncore_type {
369 struct intel_uncore_pmu *pmus; 369 struct intel_uncore_pmu *pmus;
370 struct intel_uncore_ops *ops; 370 struct intel_uncore_ops *ops;
371 struct uncore_event_desc *event_descs; 371 struct uncore_event_desc *event_descs;
372 const struct attribute_group *attr_groups[3]; 372 const struct attribute_group *attr_groups[4];
373}; 373};
374 374
375#define format_group attr_groups[0] 375#define pmu_group attr_groups[0]
376#define format_group attr_groups[1]
377#define events_group attr_groups[2]
376 378
377struct intel_uncore_ops { 379struct intel_uncore_ops {
378 void (*init_box)(struct intel_uncore_box *); 380 void (*init_box)(struct intel_uncore_box *);
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index 8022c6681485..fbd895562292 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -140,10 +140,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
140 140
141static void *c_start(struct seq_file *m, loff_t *pos) 141static void *c_start(struct seq_file *m, loff_t *pos)
142{ 142{
143 if (*pos == 0) /* just in case, cpu 0 is not the first */ 143 *pos = cpumask_next(*pos - 1, cpu_online_mask);
144 *pos = cpumask_first(cpu_online_mask);
145 else
146 *pos = cpumask_next(*pos - 1, cpu_online_mask);
147 if ((*pos) < nr_cpu_ids) 144 if ((*pos) < nr_cpu_ids)
148 return &cpu_data(*pos); 145 return &cpu_data(*pos);
149 return NULL; 146 return NULL;
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
index 39472dd2323f..60c78917190c 100644
--- a/arch/x86/kernel/cpuid.c
+++ b/arch/x86/kernel/cpuid.c
@@ -199,12 +199,14 @@ static int __init cpuid_init(void)
199 goto out_chrdev; 199 goto out_chrdev;
200 } 200 }
201 cpuid_class->devnode = cpuid_devnode; 201 cpuid_class->devnode = cpuid_devnode;
202 get_online_cpus();
202 for_each_online_cpu(i) { 203 for_each_online_cpu(i) {
203 err = cpuid_device_create(i); 204 err = cpuid_device_create(i);
204 if (err != 0) 205 if (err != 0)
205 goto out_class; 206 goto out_class;
206 } 207 }
207 register_hotcpu_notifier(&cpuid_class_cpu_notifier); 208 register_hotcpu_notifier(&cpuid_class_cpu_notifier);
209 put_online_cpus();
208 210
209 err = 0; 211 err = 0;
210 goto out; 212 goto out;
@@ -214,6 +216,7 @@ out_class:
214 for_each_online_cpu(i) { 216 for_each_online_cpu(i) {
215 cpuid_device_destroy(i); 217 cpuid_device_destroy(i);
216 } 218 }
219 put_online_cpus();
217 class_destroy(cpuid_class); 220 class_destroy(cpuid_class);
218out_chrdev: 221out_chrdev:
219 __unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid"); 222 __unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid");
@@ -225,11 +228,13 @@ static void __exit cpuid_exit(void)
225{ 228{
226 int cpu = 0; 229 int cpu = 0;
227 230
231 get_online_cpus();
228 for_each_online_cpu(cpu) 232 for_each_online_cpu(cpu)
229 cpuid_device_destroy(cpu); 233 cpuid_device_destroy(cpu);
230 class_destroy(cpuid_class); 234 class_destroy(cpuid_class);
231 __unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid"); 235 __unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid");
232 unregister_hotcpu_notifier(&cpuid_class_cpu_notifier); 236 unregister_hotcpu_notifier(&cpuid_class_cpu_notifier);
237 put_online_cpus();
233} 238}
234 239
235module_init(cpuid_init); 240module_init(cpuid_init);
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index 3ae2ced4a874..b1581527a236 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -342,6 +342,47 @@ const struct irq_domain_ops ioapic_irq_domain_ops = {
342 .xlate = ioapic_xlate, 342 .xlate = ioapic_xlate,
343}; 343};
344 344
345static void dt_add_ioapic_domain(unsigned int ioapic_num,
346 struct device_node *np)
347{
348 struct irq_domain *id;
349 struct mp_ioapic_gsi *gsi_cfg;
350 int ret;
351 int num;
352
353 gsi_cfg = mp_ioapic_gsi_routing(ioapic_num);
354 num = gsi_cfg->gsi_end - gsi_cfg->gsi_base + 1;
355
356 id = irq_domain_add_linear(np, num, &ioapic_irq_domain_ops,
357 (void *)ioapic_num);
358 BUG_ON(!id);
359 if (gsi_cfg->gsi_base == 0) {
360 /*
361 * The first NR_IRQS_LEGACY irq descs are allocated in
362 * early_irq_init() and need just a mapping. The
363 * remaining irqs need both. All of them are preallocated
364 * and assigned so we can keep the 1:1 mapping which the ioapic
365 * is having.
366 */
367 ret = irq_domain_associate_many(id, 0, 0, NR_IRQS_LEGACY);
368 if (ret)
369 pr_err("Error mapping legacy IRQs: %d\n", ret);
370
371 if (num > NR_IRQS_LEGACY) {
372 ret = irq_create_strict_mappings(id, NR_IRQS_LEGACY,
373 NR_IRQS_LEGACY, num - NR_IRQS_LEGACY);
374 if (ret)
375 pr_err("Error creating mapping for the "
376 "remaining IRQs: %d\n", ret);
377 }
378 irq_set_default_host(id);
379 } else {
380 ret = irq_create_strict_mappings(id, gsi_cfg->gsi_base, 0, num);
381 if (ret)
382 pr_err("Error creating IRQ mapping: %d\n", ret);
383 }
384}
385
345static void __init ioapic_add_ofnode(struct device_node *np) 386static void __init ioapic_add_ofnode(struct device_node *np)
346{ 387{
347 struct resource r; 388 struct resource r;
@@ -356,15 +397,7 @@ static void __init ioapic_add_ofnode(struct device_node *np)
356 397
357 for (i = 0; i < nr_ioapics; i++) { 398 for (i = 0; i < nr_ioapics; i++) {
358 if (r.start == mpc_ioapic_addr(i)) { 399 if (r.start == mpc_ioapic_addr(i)) {
359 struct irq_domain *id; 400 dt_add_ioapic_domain(i, np);
360 struct mp_ioapic_gsi *gsi_cfg;
361
362 gsi_cfg = mp_ioapic_gsi_routing(i);
363
364 id = irq_domain_add_legacy(np, 32, gsi_cfg->gsi_base, 0,
365 &ioapic_irq_domain_ops,
366 (void*)i);
367 BUG_ON(!id);
368 return; 401 return;
369 } 402 }
370 } 403 }
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 623f28837476..f438a44bf8f9 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -1109,17 +1109,21 @@ ENTRY(ftrace_caller)
1109 pushl %eax 1109 pushl %eax
1110 pushl %ecx 1110 pushl %ecx
1111 pushl %edx 1111 pushl %edx
1112 movl 0xc(%esp), %eax 1112 pushl $0 /* Pass NULL as regs pointer */
1113 movl 4*4(%esp), %eax
1113 movl 0x4(%ebp), %edx 1114 movl 0x4(%ebp), %edx
1115 leal function_trace_op, %ecx
1114 subl $MCOUNT_INSN_SIZE, %eax 1116 subl $MCOUNT_INSN_SIZE, %eax
1115 1117
1116.globl ftrace_call 1118.globl ftrace_call
1117ftrace_call: 1119ftrace_call:
1118 call ftrace_stub 1120 call ftrace_stub
1119 1121
1122 addl $4,%esp /* skip NULL pointer */
1120 popl %edx 1123 popl %edx
1121 popl %ecx 1124 popl %ecx
1122 popl %eax 1125 popl %eax
1126ftrace_ret:
1123#ifdef CONFIG_FUNCTION_GRAPH_TRACER 1127#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1124.globl ftrace_graph_call 1128.globl ftrace_graph_call
1125ftrace_graph_call: 1129ftrace_graph_call:
@@ -1131,6 +1135,71 @@ ftrace_stub:
1131 ret 1135 ret
1132END(ftrace_caller) 1136END(ftrace_caller)
1133 1137
1138ENTRY(ftrace_regs_caller)
1139 pushf /* push flags before compare (in cs location) */
1140 cmpl $0, function_trace_stop
1141 jne ftrace_restore_flags
1142
1143 /*
1144 * i386 does not save SS and ESP when coming from kernel.
1145 * Instead, to get sp, &regs->sp is used (see ptrace.h).
1146 * Unfortunately, that means eflags must be at the same location
1147 * as the current return ip is. We move the return ip into the
1148 * ip location, and move flags into the return ip location.
1149 */
1150 pushl 4(%esp) /* save return ip into ip slot */
1151
1152 pushl $0 /* Load 0 into orig_ax */
1153 pushl %gs
1154 pushl %fs
1155 pushl %es
1156 pushl %ds
1157 pushl %eax
1158 pushl %ebp
1159 pushl %edi
1160 pushl %esi
1161 pushl %edx
1162 pushl %ecx
1163 pushl %ebx
1164
1165 movl 13*4(%esp), %eax /* Get the saved flags */
1166 movl %eax, 14*4(%esp) /* Move saved flags into regs->flags location */
1167 /* clobbering return ip */
1168 movl $__KERNEL_CS,13*4(%esp)
1169
1170 movl 12*4(%esp), %eax /* Load ip (1st parameter) */
1171 subl $MCOUNT_INSN_SIZE, %eax /* Adjust ip */
1172 movl 0x4(%ebp), %edx /* Load parent ip (2nd parameter) */
1173 leal function_trace_op, %ecx /* Save ftrace_pos in 3rd parameter */
1174 pushl %esp /* Save pt_regs as 4th parameter */
1175
1176GLOBAL(ftrace_regs_call)
1177 call ftrace_stub
1178
1179 addl $4, %esp /* Skip pt_regs */
1180 movl 14*4(%esp), %eax /* Move flags back into cs */
1181 movl %eax, 13*4(%esp) /* Needed to keep addl from modifying flags */
1182 movl 12*4(%esp), %eax /* Get return ip from regs->ip */
1183 movl %eax, 14*4(%esp) /* Put return ip back for ret */
1184
1185 popl %ebx
1186 popl %ecx
1187 popl %edx
1188 popl %esi
1189 popl %edi
1190 popl %ebp
1191 popl %eax
1192 popl %ds
1193 popl %es
1194 popl %fs
1195 popl %gs
1196 addl $8, %esp /* Skip orig_ax and ip */
1197 popf /* Pop flags at end (no addl to corrupt flags) */
1198 jmp ftrace_ret
1199
1200ftrace_restore_flags:
1201 popf
1202 jmp ftrace_stub
1134#else /* ! CONFIG_DYNAMIC_FTRACE */ 1203#else /* ! CONFIG_DYNAMIC_FTRACE */
1135 1204
1136ENTRY(mcount) 1205ENTRY(mcount)
@@ -1171,9 +1240,6 @@ END(mcount)
1171 1240
1172#ifdef CONFIG_FUNCTION_GRAPH_TRACER 1241#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1173ENTRY(ftrace_graph_caller) 1242ENTRY(ftrace_graph_caller)
1174 cmpl $0, function_trace_stop
1175 jne ftrace_stub
1176
1177 pushl %eax 1243 pushl %eax
1178 pushl %ecx 1244 pushl %ecx
1179 pushl %edx 1245 pushl %edx
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 69babd8c834f..066334be7b74 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -56,6 +56,7 @@
56#include <asm/ftrace.h> 56#include <asm/ftrace.h>
57#include <asm/percpu.h> 57#include <asm/percpu.h>
58#include <asm/asm.h> 58#include <asm/asm.h>
59#include <asm/rcu.h>
59#include <linux/err.h> 60#include <linux/err.h>
60 61
61/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */ 62/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
@@ -68,25 +69,51 @@
68 .section .entry.text, "ax" 69 .section .entry.text, "ax"
69 70
70#ifdef CONFIG_FUNCTION_TRACER 71#ifdef CONFIG_FUNCTION_TRACER
72
73#ifdef CC_USING_FENTRY
74# define function_hook __fentry__
75#else
76# define function_hook mcount
77#endif
78
71#ifdef CONFIG_DYNAMIC_FTRACE 79#ifdef CONFIG_DYNAMIC_FTRACE
72ENTRY(mcount) 80
81ENTRY(function_hook)
73 retq 82 retq
74END(mcount) 83END(function_hook)
84
85/* skip is set if stack has been adjusted */
86.macro ftrace_caller_setup skip=0
87 MCOUNT_SAVE_FRAME \skip
88
89 /* Load the ftrace_ops into the 3rd parameter */
90 leaq function_trace_op, %rdx
91
92 /* Load ip into the first parameter */
93 movq RIP(%rsp), %rdi
94 subq $MCOUNT_INSN_SIZE, %rdi
95 /* Load the parent_ip into the second parameter */
96#ifdef CC_USING_FENTRY
97 movq SS+16(%rsp), %rsi
98#else
99 movq 8(%rbp), %rsi
100#endif
101.endm
75 102
76ENTRY(ftrace_caller) 103ENTRY(ftrace_caller)
104 /* Check if tracing was disabled (quick check) */
77 cmpl $0, function_trace_stop 105 cmpl $0, function_trace_stop
78 jne ftrace_stub 106 jne ftrace_stub
79 107
80 MCOUNT_SAVE_FRAME 108 ftrace_caller_setup
81 109 /* regs go into 4th parameter (but make it NULL) */
82 movq 0x38(%rsp), %rdi 110 movq $0, %rcx
83 movq 8(%rbp), %rsi
84 subq $MCOUNT_INSN_SIZE, %rdi
85 111
86GLOBAL(ftrace_call) 112GLOBAL(ftrace_call)
87 call ftrace_stub 113 call ftrace_stub
88 114
89 MCOUNT_RESTORE_FRAME 115 MCOUNT_RESTORE_FRAME
116ftrace_return:
90 117
91#ifdef CONFIG_FUNCTION_GRAPH_TRACER 118#ifdef CONFIG_FUNCTION_GRAPH_TRACER
92GLOBAL(ftrace_graph_call) 119GLOBAL(ftrace_graph_call)
@@ -97,8 +124,78 @@ GLOBAL(ftrace_stub)
97 retq 124 retq
98END(ftrace_caller) 125END(ftrace_caller)
99 126
127ENTRY(ftrace_regs_caller)
128 /* Save the current flags before compare (in SS location)*/
129 pushfq
130
131 /* Check if tracing was disabled (quick check) */
132 cmpl $0, function_trace_stop
133 jne ftrace_restore_flags
134
135 /* skip=8 to skip flags saved in SS */
136 ftrace_caller_setup 8
137
138 /* Save the rest of pt_regs */
139 movq %r15, R15(%rsp)
140 movq %r14, R14(%rsp)
141 movq %r13, R13(%rsp)
142 movq %r12, R12(%rsp)
143 movq %r11, R11(%rsp)
144 movq %r10, R10(%rsp)
145 movq %rbp, RBP(%rsp)
146 movq %rbx, RBX(%rsp)
147 /* Copy saved flags */
148 movq SS(%rsp), %rcx
149 movq %rcx, EFLAGS(%rsp)
150 /* Kernel segments */
151 movq $__KERNEL_DS, %rcx
152 movq %rcx, SS(%rsp)
153 movq $__KERNEL_CS, %rcx
154 movq %rcx, CS(%rsp)
155 /* Stack - skipping return address */
156 leaq SS+16(%rsp), %rcx
157 movq %rcx, RSP(%rsp)
158
159 /* regs go into 4th parameter */
160 leaq (%rsp), %rcx
161
162GLOBAL(ftrace_regs_call)
163 call ftrace_stub
164
165 /* Copy flags back to SS, to restore them */
166 movq EFLAGS(%rsp), %rax
167 movq %rax, SS(%rsp)
168
169 /* Handlers can change the RIP */
170 movq RIP(%rsp), %rax
171 movq %rax, SS+8(%rsp)
172
173 /* restore the rest of pt_regs */
174 movq R15(%rsp), %r15
175 movq R14(%rsp), %r14
176 movq R13(%rsp), %r13
177 movq R12(%rsp), %r12
178 movq R10(%rsp), %r10
179 movq RBP(%rsp), %rbp
180 movq RBX(%rsp), %rbx
181
182 /* skip=8 to skip flags saved in SS */
183 MCOUNT_RESTORE_FRAME 8
184
185 /* Restore flags */
186 popfq
187
188 jmp ftrace_return
189ftrace_restore_flags:
190 popfq
191 jmp ftrace_stub
192
193END(ftrace_regs_caller)
194
195
100#else /* ! CONFIG_DYNAMIC_FTRACE */ 196#else /* ! CONFIG_DYNAMIC_FTRACE */
101ENTRY(mcount) 197
198ENTRY(function_hook)
102 cmpl $0, function_trace_stop 199 cmpl $0, function_trace_stop
103 jne ftrace_stub 200 jne ftrace_stub
104 201
@@ -119,8 +216,12 @@ GLOBAL(ftrace_stub)
119trace: 216trace:
120 MCOUNT_SAVE_FRAME 217 MCOUNT_SAVE_FRAME
121 218
122 movq 0x38(%rsp), %rdi 219 movq RIP(%rsp), %rdi
220#ifdef CC_USING_FENTRY
221 movq SS+16(%rsp), %rsi
222#else
123 movq 8(%rbp), %rsi 223 movq 8(%rbp), %rsi
224#endif
124 subq $MCOUNT_INSN_SIZE, %rdi 225 subq $MCOUNT_INSN_SIZE, %rdi
125 226
126 call *ftrace_trace_function 227 call *ftrace_trace_function
@@ -128,20 +229,22 @@ trace:
128 MCOUNT_RESTORE_FRAME 229 MCOUNT_RESTORE_FRAME
129 230
130 jmp ftrace_stub 231 jmp ftrace_stub
131END(mcount) 232END(function_hook)
132#endif /* CONFIG_DYNAMIC_FTRACE */ 233#endif /* CONFIG_DYNAMIC_FTRACE */
133#endif /* CONFIG_FUNCTION_TRACER */ 234#endif /* CONFIG_FUNCTION_TRACER */
134 235
135#ifdef CONFIG_FUNCTION_GRAPH_TRACER 236#ifdef CONFIG_FUNCTION_GRAPH_TRACER
136ENTRY(ftrace_graph_caller) 237ENTRY(ftrace_graph_caller)
137 cmpl $0, function_trace_stop
138 jne ftrace_stub
139
140 MCOUNT_SAVE_FRAME 238 MCOUNT_SAVE_FRAME
141 239
240#ifdef CC_USING_FENTRY
241 leaq SS+16(%rsp), %rdi
242 movq $0, %rdx /* No framepointers needed */
243#else
142 leaq 8(%rbp), %rdi 244 leaq 8(%rbp), %rdi
143 movq 0x38(%rsp), %rsi
144 movq (%rbp), %rdx 245 movq (%rbp), %rdx
246#endif
247 movq RIP(%rsp), %rsi
145 subq $MCOUNT_INSN_SIZE, %rsi 248 subq $MCOUNT_INSN_SIZE, %rsi
146 249
147 call prepare_ftrace_return 250 call prepare_ftrace_return
@@ -342,15 +445,15 @@ ENDPROC(native_usergs_sysret64)
342 .macro SAVE_ARGS_IRQ 445 .macro SAVE_ARGS_IRQ
343 cld 446 cld
344 /* start from rbp in pt_regs and jump over */ 447 /* start from rbp in pt_regs and jump over */
345 movq_cfi rdi, RDI-RBP 448 movq_cfi rdi, (RDI-RBP)
346 movq_cfi rsi, RSI-RBP 449 movq_cfi rsi, (RSI-RBP)
347 movq_cfi rdx, RDX-RBP 450 movq_cfi rdx, (RDX-RBP)
348 movq_cfi rcx, RCX-RBP 451 movq_cfi rcx, (RCX-RBP)
349 movq_cfi rax, RAX-RBP 452 movq_cfi rax, (RAX-RBP)
350 movq_cfi r8, R8-RBP 453 movq_cfi r8, (R8-RBP)
351 movq_cfi r9, R9-RBP 454 movq_cfi r9, (R9-RBP)
352 movq_cfi r10, R10-RBP 455 movq_cfi r10, (R10-RBP)
353 movq_cfi r11, R11-RBP 456 movq_cfi r11, (R11-RBP)
354 457
355 /* Save rbp so that we can unwind from get_irq_regs() */ 458 /* Save rbp so that we can unwind from get_irq_regs() */
356 movq_cfi rbp, 0 459 movq_cfi rbp, 0
@@ -384,7 +487,7 @@ ENDPROC(native_usergs_sysret64)
384 .endm 487 .endm
385 488
386ENTRY(save_rest) 489ENTRY(save_rest)
387 PARTIAL_FRAME 1 REST_SKIP+8 490 PARTIAL_FRAME 1 (REST_SKIP+8)
388 movq 5*8+16(%rsp), %r11 /* save return address */ 491 movq 5*8+16(%rsp), %r11 /* save return address */
389 movq_cfi rbx, RBX+16 492 movq_cfi rbx, RBX+16
390 movq_cfi rbp, RBP+16 493 movq_cfi rbp, RBP+16
@@ -440,7 +543,7 @@ ENTRY(ret_from_fork)
440 543
441 LOCK ; btr $TIF_FORK,TI_flags(%r8) 544 LOCK ; btr $TIF_FORK,TI_flags(%r8)
442 545
443 pushq_cfi kernel_eflags(%rip) 546 pushq_cfi $0x0002
444 popfq_cfi # reset kernel eflags 547 popfq_cfi # reset kernel eflags
445 548
446 call schedule_tail # rdi: 'prev' task parameter 549 call schedule_tail # rdi: 'prev' task parameter
@@ -565,7 +668,7 @@ sysret_careful:
565 TRACE_IRQS_ON 668 TRACE_IRQS_ON
566 ENABLE_INTERRUPTS(CLBR_NONE) 669 ENABLE_INTERRUPTS(CLBR_NONE)
567 pushq_cfi %rdi 670 pushq_cfi %rdi
568 call schedule 671 SCHEDULE_USER
569 popq_cfi %rdi 672 popq_cfi %rdi
570 jmp sysret_check 673 jmp sysret_check
571 674
@@ -678,7 +781,7 @@ int_careful:
678 TRACE_IRQS_ON 781 TRACE_IRQS_ON
679 ENABLE_INTERRUPTS(CLBR_NONE) 782 ENABLE_INTERRUPTS(CLBR_NONE)
680 pushq_cfi %rdi 783 pushq_cfi %rdi
681 call schedule 784 SCHEDULE_USER
682 popq_cfi %rdi 785 popq_cfi %rdi
683 DISABLE_INTERRUPTS(CLBR_NONE) 786 DISABLE_INTERRUPTS(CLBR_NONE)
684 TRACE_IRQS_OFF 787 TRACE_IRQS_OFF
@@ -974,7 +1077,7 @@ retint_careful:
974 TRACE_IRQS_ON 1077 TRACE_IRQS_ON
975 ENABLE_INTERRUPTS(CLBR_NONE) 1078 ENABLE_INTERRUPTS(CLBR_NONE)
976 pushq_cfi %rdi 1079 pushq_cfi %rdi
977 call schedule 1080 SCHEDULE_USER
978 popq_cfi %rdi 1081 popq_cfi %rdi
979 GET_THREAD_INFO(%rcx) 1082 GET_THREAD_INFO(%rcx)
980 DISABLE_INTERRUPTS(CLBR_NONE) 1083 DISABLE_INTERRUPTS(CLBR_NONE)
@@ -1449,7 +1552,7 @@ paranoid_userspace:
1449paranoid_schedule: 1552paranoid_schedule:
1450 TRACE_IRQS_ON 1553 TRACE_IRQS_ON
1451 ENABLE_INTERRUPTS(CLBR_ANY) 1554 ENABLE_INTERRUPTS(CLBR_ANY)
1452 call schedule 1555 SCHEDULE_USER
1453 DISABLE_INTERRUPTS(CLBR_ANY) 1556 DISABLE_INTERRUPTS(CLBR_ANY)
1454 TRACE_IRQS_OFF 1557 TRACE_IRQS_OFF
1455 jmp paranoid_userspace 1558 jmp paranoid_userspace
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index c3a7cb4bf6e6..1d414029f1d8 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -206,6 +206,21 @@ static int
206ftrace_modify_code(unsigned long ip, unsigned const char *old_code, 206ftrace_modify_code(unsigned long ip, unsigned const char *old_code,
207 unsigned const char *new_code); 207 unsigned const char *new_code);
208 208
209/*
210 * Should never be called:
211 * As it is only called by __ftrace_replace_code() which is called by
212 * ftrace_replace_code() that x86 overrides, and by ftrace_update_code()
213 * which is called to turn mcount into nops or nops into function calls
214 * but not to convert a function from not using regs to one that uses
215 * regs, which ftrace_modify_call() is for.
216 */
217int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
218 unsigned long addr)
219{
220 WARN_ON(1);
221 return -EINVAL;
222}
223
209int ftrace_update_ftrace_func(ftrace_func_t func) 224int ftrace_update_ftrace_func(ftrace_func_t func)
210{ 225{
211 unsigned long ip = (unsigned long)(&ftrace_call); 226 unsigned long ip = (unsigned long)(&ftrace_call);
@@ -220,6 +235,14 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
220 235
221 ret = ftrace_modify_code(ip, old, new); 236 ret = ftrace_modify_code(ip, old, new);
222 237
238 /* Also update the regs callback function */
239 if (!ret) {
240 ip = (unsigned long)(&ftrace_regs_call);
241 memcpy(old, &ftrace_regs_call, MCOUNT_INSN_SIZE);
242 new = ftrace_call_replace(ip, (unsigned long)func);
243 ret = ftrace_modify_code(ip, old, new);
244 }
245
223 atomic_dec(&modifying_ftrace_code); 246 atomic_dec(&modifying_ftrace_code);
224 247
225 return ret; 248 return ret;
@@ -299,6 +322,32 @@ static int add_brk_on_nop(struct dyn_ftrace *rec)
299 return add_break(rec->ip, old); 322 return add_break(rec->ip, old);
300} 323}
301 324
325/*
326 * If the record has the FTRACE_FL_REGS set, that means that it
327 * wants to convert to a callback that saves all regs. If FTRACE_FL_REGS
328 * is not not set, then it wants to convert to the normal callback.
329 */
330static unsigned long get_ftrace_addr(struct dyn_ftrace *rec)
331{
332 if (rec->flags & FTRACE_FL_REGS)
333 return (unsigned long)FTRACE_REGS_ADDR;
334 else
335 return (unsigned long)FTRACE_ADDR;
336}
337
338/*
339 * The FTRACE_FL_REGS_EN is set when the record already points to
340 * a function that saves all the regs. Basically the '_EN' version
341 * represents the current state of the function.
342 */
343static unsigned long get_ftrace_old_addr(struct dyn_ftrace *rec)
344{
345 if (rec->flags & FTRACE_FL_REGS_EN)
346 return (unsigned long)FTRACE_REGS_ADDR;
347 else
348 return (unsigned long)FTRACE_ADDR;
349}
350
302static int add_breakpoints(struct dyn_ftrace *rec, int enable) 351static int add_breakpoints(struct dyn_ftrace *rec, int enable)
303{ 352{
304 unsigned long ftrace_addr; 353 unsigned long ftrace_addr;
@@ -306,7 +355,7 @@ static int add_breakpoints(struct dyn_ftrace *rec, int enable)
306 355
307 ret = ftrace_test_record(rec, enable); 356 ret = ftrace_test_record(rec, enable);
308 357
309 ftrace_addr = (unsigned long)FTRACE_ADDR; 358 ftrace_addr = get_ftrace_addr(rec);
310 359
311 switch (ret) { 360 switch (ret) {
312 case FTRACE_UPDATE_IGNORE: 361 case FTRACE_UPDATE_IGNORE:
@@ -316,6 +365,10 @@ static int add_breakpoints(struct dyn_ftrace *rec, int enable)
316 /* converting nop to call */ 365 /* converting nop to call */
317 return add_brk_on_nop(rec); 366 return add_brk_on_nop(rec);
318 367
368 case FTRACE_UPDATE_MODIFY_CALL_REGS:
369 case FTRACE_UPDATE_MODIFY_CALL:
370 ftrace_addr = get_ftrace_old_addr(rec);
371 /* fall through */
319 case FTRACE_UPDATE_MAKE_NOP: 372 case FTRACE_UPDATE_MAKE_NOP:
320 /* converting a call to a nop */ 373 /* converting a call to a nop */
321 return add_brk_on_call(rec, ftrace_addr); 374 return add_brk_on_call(rec, ftrace_addr);
@@ -360,13 +413,21 @@ static int remove_breakpoint(struct dyn_ftrace *rec)
360 * If not, don't touch the breakpoint, we make just create 413 * If not, don't touch the breakpoint, we make just create
361 * a disaster. 414 * a disaster.
362 */ 415 */
363 ftrace_addr = (unsigned long)FTRACE_ADDR; 416 ftrace_addr = get_ftrace_addr(rec);
417 nop = ftrace_call_replace(ip, ftrace_addr);
418
419 if (memcmp(&ins[1], &nop[1], MCOUNT_INSN_SIZE - 1) == 0)
420 goto update;
421
422 /* Check both ftrace_addr and ftrace_old_addr */
423 ftrace_addr = get_ftrace_old_addr(rec);
364 nop = ftrace_call_replace(ip, ftrace_addr); 424 nop = ftrace_call_replace(ip, ftrace_addr);
365 425
366 if (memcmp(&ins[1], &nop[1], MCOUNT_INSN_SIZE - 1) != 0) 426 if (memcmp(&ins[1], &nop[1], MCOUNT_INSN_SIZE - 1) != 0)
367 return -EINVAL; 427 return -EINVAL;
368 } 428 }
369 429
430 update:
370 return probe_kernel_write((void *)ip, &nop[0], 1); 431 return probe_kernel_write((void *)ip, &nop[0], 1);
371} 432}
372 433
@@ -405,12 +466,14 @@ static int add_update(struct dyn_ftrace *rec, int enable)
405 466
406 ret = ftrace_test_record(rec, enable); 467 ret = ftrace_test_record(rec, enable);
407 468
408 ftrace_addr = (unsigned long)FTRACE_ADDR; 469 ftrace_addr = get_ftrace_addr(rec);
409 470
410 switch (ret) { 471 switch (ret) {
411 case FTRACE_UPDATE_IGNORE: 472 case FTRACE_UPDATE_IGNORE:
412 return 0; 473 return 0;
413 474
475 case FTRACE_UPDATE_MODIFY_CALL_REGS:
476 case FTRACE_UPDATE_MODIFY_CALL:
414 case FTRACE_UPDATE_MAKE_CALL: 477 case FTRACE_UPDATE_MAKE_CALL:
415 /* converting nop to call */ 478 /* converting nop to call */
416 return add_update_call(rec, ftrace_addr); 479 return add_update_call(rec, ftrace_addr);
@@ -455,12 +518,14 @@ static int finish_update(struct dyn_ftrace *rec, int enable)
455 518
456 ret = ftrace_update_record(rec, enable); 519 ret = ftrace_update_record(rec, enable);
457 520
458 ftrace_addr = (unsigned long)FTRACE_ADDR; 521 ftrace_addr = get_ftrace_addr(rec);
459 522
460 switch (ret) { 523 switch (ret) {
461 case FTRACE_UPDATE_IGNORE: 524 case FTRACE_UPDATE_IGNORE:
462 return 0; 525 return 0;
463 526
527 case FTRACE_UPDATE_MODIFY_CALL_REGS:
528 case FTRACE_UPDATE_MODIFY_CALL:
464 case FTRACE_UPDATE_MAKE_CALL: 529 case FTRACE_UPDATE_MAKE_CALL:
465 /* converting nop to call */ 530 /* converting nop to call */
466 return finish_update_call(rec, ftrace_addr); 531 return finish_update_call(rec, ftrace_addr);
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
index f250431fb505..675a05012449 100644
--- a/arch/x86/kernel/i387.c
+++ b/arch/x86/kernel/i387.c
@@ -19,24 +19,17 @@
19#include <asm/fpu-internal.h> 19#include <asm/fpu-internal.h>
20#include <asm/user.h> 20#include <asm/user.h>
21 21
22#ifdef CONFIG_X86_64
23# include <asm/sigcontext32.h>
24# include <asm/user32.h>
25#else
26# define save_i387_xstate_ia32 save_i387_xstate
27# define restore_i387_xstate_ia32 restore_i387_xstate
28# define _fpstate_ia32 _fpstate
29# define _xstate_ia32 _xstate
30# define sig_xstate_ia32_size sig_xstate_size
31# define fx_sw_reserved_ia32 fx_sw_reserved
32# define user_i387_ia32_struct user_i387_struct
33# define user32_fxsr_struct user_fxsr_struct
34#endif
35
36/* 22/*
37 * Were we in an interrupt that interrupted kernel mode? 23 * Were we in an interrupt that interrupted kernel mode?
38 * 24 *
39 * We can do a kernel_fpu_begin/end() pair *ONLY* if that 25 * For now, with eagerfpu we will return interrupted kernel FPU
26 * state as not-idle. TBD: Ideally we can change the return value
27 * to something like __thread_has_fpu(current). But we need to
28 * be careful of doing __thread_clear_has_fpu() before saving
29 * the FPU etc for supporting nested uses etc. For now, take
30 * the simple route!
31 *
32 * On others, we can do a kernel_fpu_begin/end() pair *ONLY* if that
40 * pair does nothing at all: the thread must not have fpu (so 33 * pair does nothing at all: the thread must not have fpu (so
41 * that we don't try to save the FPU state), and TS must 34 * that we don't try to save the FPU state), and TS must
42 * be set (so that the clts/stts pair does nothing that is 35 * be set (so that the clts/stts pair does nothing that is
@@ -44,6 +37,9 @@
44 */ 37 */
45static inline bool interrupted_kernel_fpu_idle(void) 38static inline bool interrupted_kernel_fpu_idle(void)
46{ 39{
40 if (use_eager_fpu())
41 return 0;
42
47 return !__thread_has_fpu(current) && 43 return !__thread_has_fpu(current) &&
48 (read_cr0() & X86_CR0_TS); 44 (read_cr0() & X86_CR0_TS);
49} 45}
@@ -77,29 +73,29 @@ bool irq_fpu_usable(void)
77} 73}
78EXPORT_SYMBOL(irq_fpu_usable); 74EXPORT_SYMBOL(irq_fpu_usable);
79 75
80void kernel_fpu_begin(void) 76void __kernel_fpu_begin(void)
81{ 77{
82 struct task_struct *me = current; 78 struct task_struct *me = current;
83 79
84 WARN_ON_ONCE(!irq_fpu_usable());
85 preempt_disable();
86 if (__thread_has_fpu(me)) { 80 if (__thread_has_fpu(me)) {
87 __save_init_fpu(me); 81 __save_init_fpu(me);
88 __thread_clear_has_fpu(me); 82 __thread_clear_has_fpu(me);
89 /* We do 'stts()' in kernel_fpu_end() */ 83 /* We do 'stts()' in __kernel_fpu_end() */
90 } else { 84 } else if (!use_eager_fpu()) {
91 this_cpu_write(fpu_owner_task, NULL); 85 this_cpu_write(fpu_owner_task, NULL);
92 clts(); 86 clts();
93 } 87 }
94} 88}
95EXPORT_SYMBOL(kernel_fpu_begin); 89EXPORT_SYMBOL(__kernel_fpu_begin);
96 90
97void kernel_fpu_end(void) 91void __kernel_fpu_end(void)
98{ 92{
99 stts(); 93 if (use_eager_fpu())
100 preempt_enable(); 94 math_state_restore();
95 else
96 stts();
101} 97}
102EXPORT_SYMBOL(kernel_fpu_end); 98EXPORT_SYMBOL(__kernel_fpu_end);
103 99
104void unlazy_fpu(struct task_struct *tsk) 100void unlazy_fpu(struct task_struct *tsk)
105{ 101{
@@ -113,23 +109,15 @@ void unlazy_fpu(struct task_struct *tsk)
113} 109}
114EXPORT_SYMBOL(unlazy_fpu); 110EXPORT_SYMBOL(unlazy_fpu);
115 111
116#ifdef CONFIG_MATH_EMULATION 112unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu;
117# define HAVE_HWFP (boot_cpu_data.hard_math)
118#else
119# define HAVE_HWFP 1
120#endif
121
122static unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu;
123unsigned int xstate_size; 113unsigned int xstate_size;
124EXPORT_SYMBOL_GPL(xstate_size); 114EXPORT_SYMBOL_GPL(xstate_size);
125unsigned int sig_xstate_ia32_size = sizeof(struct _fpstate_ia32);
126static struct i387_fxsave_struct fx_scratch __cpuinitdata; 115static struct i387_fxsave_struct fx_scratch __cpuinitdata;
127 116
128static void __cpuinit mxcsr_feature_mask_init(void) 117static void __cpuinit mxcsr_feature_mask_init(void)
129{ 118{
130 unsigned long mask = 0; 119 unsigned long mask = 0;
131 120
132 clts();
133 if (cpu_has_fxsr) { 121 if (cpu_has_fxsr) {
134 memset(&fx_scratch, 0, sizeof(struct i387_fxsave_struct)); 122 memset(&fx_scratch, 0, sizeof(struct i387_fxsave_struct));
135 asm volatile("fxsave %0" : : "m" (fx_scratch)); 123 asm volatile("fxsave %0" : : "m" (fx_scratch));
@@ -138,7 +126,6 @@ static void __cpuinit mxcsr_feature_mask_init(void)
138 mask = 0x0000ffbf; 126 mask = 0x0000ffbf;
139 } 127 }
140 mxcsr_feature_mask &= mask; 128 mxcsr_feature_mask &= mask;
141 stts();
142} 129}
143 130
144static void __cpuinit init_thread_xstate(void) 131static void __cpuinit init_thread_xstate(void)
@@ -192,9 +179,8 @@ void __cpuinit fpu_init(void)
192 init_thread_xstate(); 179 init_thread_xstate();
193 180
194 mxcsr_feature_mask_init(); 181 mxcsr_feature_mask_init();
195 /* clean state in init */ 182 xsave_init();
196 current_thread_info()->status = 0; 183 eager_fpu_init();
197 clear_used_math();
198} 184}
199 185
200void fpu_finit(struct fpu *fpu) 186void fpu_finit(struct fpu *fpu)
@@ -205,12 +191,7 @@ void fpu_finit(struct fpu *fpu)
205 } 191 }
206 192
207 if (cpu_has_fxsr) { 193 if (cpu_has_fxsr) {
208 struct i387_fxsave_struct *fx = &fpu->state->fxsave; 194 fx_finit(&fpu->state->fxsave);
209
210 memset(fx, 0, xstate_size);
211 fx->cwd = 0x37f;
212 if (cpu_has_xmm)
213 fx->mxcsr = MXCSR_DEFAULT;
214 } else { 195 } else {
215 struct i387_fsave_struct *fp = &fpu->state->fsave; 196 struct i387_fsave_struct *fp = &fpu->state->fsave;
216 memset(fp, 0, xstate_size); 197 memset(fp, 0, xstate_size);
@@ -454,7 +435,7 @@ static inline u32 twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave)
454 * FXSR floating point environment conversions. 435 * FXSR floating point environment conversions.
455 */ 436 */
456 437
457static void 438void
458convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk) 439convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk)
459{ 440{
460 struct i387_fxsave_struct *fxsave = &tsk->thread.fpu.state->fxsave; 441 struct i387_fxsave_struct *fxsave = &tsk->thread.fpu.state->fxsave;
@@ -491,8 +472,8 @@ convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk)
491 memcpy(&to[i], &from[i], sizeof(to[0])); 472 memcpy(&to[i], &from[i], sizeof(to[0]));
492} 473}
493 474
494static void convert_to_fxsr(struct task_struct *tsk, 475void convert_to_fxsr(struct task_struct *tsk,
495 const struct user_i387_ia32_struct *env) 476 const struct user_i387_ia32_struct *env)
496 477
497{ 478{
498 struct i387_fxsave_struct *fxsave = &tsk->thread.fpu.state->fxsave; 479 struct i387_fxsave_struct *fxsave = &tsk->thread.fpu.state->fxsave;
@@ -589,223 +570,6 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset,
589} 570}
590 571
591/* 572/*
592 * Signal frame handlers.
593 */
594
595static inline int save_i387_fsave(struct _fpstate_ia32 __user *buf)
596{
597 struct task_struct *tsk = current;
598 struct i387_fsave_struct *fp = &tsk->thread.fpu.state->fsave;
599
600 fp->status = fp->swd;
601 if (__copy_to_user(buf, fp, sizeof(struct i387_fsave_struct)))
602 return -1;
603 return 1;
604}
605
606static int save_i387_fxsave(struct _fpstate_ia32 __user *buf)
607{
608 struct task_struct *tsk = current;
609 struct i387_fxsave_struct *fx = &tsk->thread.fpu.state->fxsave;
610 struct user_i387_ia32_struct env;
611 int err = 0;
612
613 convert_from_fxsr(&env, tsk);
614 if (__copy_to_user(buf, &env, sizeof(env)))
615 return -1;
616
617 err |= __put_user(fx->swd, &buf->status);
618 err |= __put_user(X86_FXSR_MAGIC, &buf->magic);
619 if (err)
620 return -1;
621
622 if (__copy_to_user(&buf->_fxsr_env[0], fx, xstate_size))
623 return -1;
624 return 1;
625}
626
627static int save_i387_xsave(void __user *buf)
628{
629 struct task_struct *tsk = current;
630 struct _fpstate_ia32 __user *fx = buf;
631 int err = 0;
632
633
634 sanitize_i387_state(tsk);
635
636 /*
637 * For legacy compatible, we always set FP/SSE bits in the bit
638 * vector while saving the state to the user context.
639 * This will enable us capturing any changes(during sigreturn) to
640 * the FP/SSE bits by the legacy applications which don't touch
641 * xstate_bv in the xsave header.
642 *
643 * xsave aware applications can change the xstate_bv in the xsave
644 * header as well as change any contents in the memory layout.
645 * xrestore as part of sigreturn will capture all the changes.
646 */
647 tsk->thread.fpu.state->xsave.xsave_hdr.xstate_bv |= XSTATE_FPSSE;
648
649 if (save_i387_fxsave(fx) < 0)
650 return -1;
651
652 err = __copy_to_user(&fx->sw_reserved, &fx_sw_reserved_ia32,
653 sizeof(struct _fpx_sw_bytes));
654 err |= __put_user(FP_XSTATE_MAGIC2,
655 (__u32 __user *) (buf + sig_xstate_ia32_size
656 - FP_XSTATE_MAGIC2_SIZE));
657 if (err)
658 return -1;
659
660 return 1;
661}
662
663int save_i387_xstate_ia32(void __user *buf)
664{
665 struct _fpstate_ia32 __user *fp = (struct _fpstate_ia32 __user *) buf;
666 struct task_struct *tsk = current;
667
668 if (!used_math())
669 return 0;
670
671 if (!access_ok(VERIFY_WRITE, buf, sig_xstate_ia32_size))
672 return -EACCES;
673 /*
674 * This will cause a "finit" to be triggered by the next
675 * attempted FPU operation by the 'current' process.
676 */
677 clear_used_math();
678
679 if (!HAVE_HWFP) {
680 return fpregs_soft_get(current, NULL,
681 0, sizeof(struct user_i387_ia32_struct),
682 NULL, fp) ? -1 : 1;
683 }
684
685 unlazy_fpu(tsk);
686
687 if (cpu_has_xsave)
688 return save_i387_xsave(fp);
689 if (cpu_has_fxsr)
690 return save_i387_fxsave(fp);
691 else
692 return save_i387_fsave(fp);
693}
694
695static inline int restore_i387_fsave(struct _fpstate_ia32 __user *buf)
696{
697 struct task_struct *tsk = current;
698
699 return __copy_from_user(&tsk->thread.fpu.state->fsave, buf,
700 sizeof(struct i387_fsave_struct));
701}
702
703static int restore_i387_fxsave(struct _fpstate_ia32 __user *buf,
704 unsigned int size)
705{
706 struct task_struct *tsk = current;
707 struct user_i387_ia32_struct env;
708 int err;
709
710 err = __copy_from_user(&tsk->thread.fpu.state->fxsave, &buf->_fxsr_env[0],
711 size);
712 /* mxcsr reserved bits must be masked to zero for security reasons */
713 tsk->thread.fpu.state->fxsave.mxcsr &= mxcsr_feature_mask;
714 if (err || __copy_from_user(&env, buf, sizeof(env)))
715 return 1;
716 convert_to_fxsr(tsk, &env);
717
718 return 0;
719}
720
721static int restore_i387_xsave(void __user *buf)
722{
723 struct _fpx_sw_bytes fx_sw_user;
724 struct _fpstate_ia32 __user *fx_user =
725 ((struct _fpstate_ia32 __user *) buf);
726 struct i387_fxsave_struct __user *fx =
727 (struct i387_fxsave_struct __user *) &fx_user->_fxsr_env[0];
728 struct xsave_hdr_struct *xsave_hdr =
729 &current->thread.fpu.state->xsave.xsave_hdr;
730 u64 mask;
731 int err;
732
733 if (check_for_xstate(fx, buf, &fx_sw_user))
734 goto fx_only;
735
736 mask = fx_sw_user.xstate_bv;
737
738 err = restore_i387_fxsave(buf, fx_sw_user.xstate_size);
739
740 xsave_hdr->xstate_bv &= pcntxt_mask;
741 /*
742 * These bits must be zero.
743 */
744 xsave_hdr->reserved1[0] = xsave_hdr->reserved1[1] = 0;
745
746 /*
747 * Init the state that is not present in the memory layout
748 * and enabled by the OS.
749 */
750 mask = ~(pcntxt_mask & ~mask);
751 xsave_hdr->xstate_bv &= mask;
752
753 return err;
754fx_only:
755 /*
756 * Couldn't find the extended state information in the memory
757 * layout. Restore the FP/SSE and init the other extended state
758 * enabled by the OS.
759 */
760 xsave_hdr->xstate_bv = XSTATE_FPSSE;
761 return restore_i387_fxsave(buf, sizeof(struct i387_fxsave_struct));
762}
763
764int restore_i387_xstate_ia32(void __user *buf)
765{
766 int err;
767 struct task_struct *tsk = current;
768 struct _fpstate_ia32 __user *fp = (struct _fpstate_ia32 __user *) buf;
769
770 if (HAVE_HWFP)
771 clear_fpu(tsk);
772
773 if (!buf) {
774 if (used_math()) {
775 clear_fpu(tsk);
776 clear_used_math();
777 }
778
779 return 0;
780 } else
781 if (!access_ok(VERIFY_READ, buf, sig_xstate_ia32_size))
782 return -EACCES;
783
784 if (!used_math()) {
785 err = init_fpu(tsk);
786 if (err)
787 return err;
788 }
789
790 if (HAVE_HWFP) {
791 if (cpu_has_xsave)
792 err = restore_i387_xsave(buf);
793 else if (cpu_has_fxsr)
794 err = restore_i387_fxsave(fp, sizeof(struct
795 i387_fxsave_struct));
796 else
797 err = restore_i387_fsave(fp);
798 } else {
799 err = fpregs_soft_set(current, NULL,
800 0, sizeof(struct user_i387_ia32_struct),
801 NULL, fp) != 0;
802 }
803 set_used_math();
804
805 return err;
806}
807
808/*
809 * FPU state for core dumps. 573 * FPU state for core dumps.
810 * This is only used for a.out dumps now. 574 * This is only used for a.out dumps now.
811 * It is declared generically using elf_fpregset_t (which is 575 * It is declared generically using elf_fpregset_t (which is
diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c
index 36d1853e91af..9a5c460404dc 100644
--- a/arch/x86/kernel/i8259.c
+++ b/arch/x86/kernel/i8259.c
@@ -263,7 +263,7 @@ static void i8259A_shutdown(void)
263 * out of. 263 * out of.
264 */ 264 */
265 outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ 265 outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
266 outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */ 266 outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */
267} 267}
268 268
269static struct syscore_ops i8259_syscore_ops = { 269static struct syscore_ops i8259_syscore_ops = {
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index d44f7829968e..e4595f105910 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -92,7 +92,8 @@ int arch_show_interrupts(struct seq_file *p, int prec)
92 seq_printf(p, " Rescheduling interrupts\n"); 92 seq_printf(p, " Rescheduling interrupts\n");
93 seq_printf(p, "%*s: ", prec, "CAL"); 93 seq_printf(p, "%*s: ", prec, "CAL");
94 for_each_online_cpu(j) 94 for_each_online_cpu(j)
95 seq_printf(p, "%10u ", irq_stats(j)->irq_call_count); 95 seq_printf(p, "%10u ", irq_stats(j)->irq_call_count -
96 irq_stats(j)->irq_tlb_count);
96 seq_printf(p, " Function call interrupts\n"); 97 seq_printf(p, " Function call interrupts\n");
97 seq_printf(p, "%*s: ", prec, "TLB"); 98 seq_printf(p, "%*s: ", prec, "TLB");
98 for_each_online_cpu(j) 99 for_each_online_cpu(j)
@@ -147,7 +148,6 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
147#ifdef CONFIG_SMP 148#ifdef CONFIG_SMP
148 sum += irq_stats(cpu)->irq_resched_count; 149 sum += irq_stats(cpu)->irq_resched_count;
149 sum += irq_stats(cpu)->irq_call_count; 150 sum += irq_stats(cpu)->irq_call_count;
150 sum += irq_stats(cpu)->irq_tlb_count;
151#endif 151#endif
152#ifdef CONFIG_X86_THERMAL_VECTOR 152#ifdef CONFIG_X86_THERMAL_VECTOR
153 sum += irq_stats(cpu)->irq_thermal_count; 153 sum += irq_stats(cpu)->irq_thermal_count;
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index e2f751efb7b1..57916c0d3cf6 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -541,6 +541,23 @@ reenter_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb
541 return 1; 541 return 1;
542} 542}
543 543
544#ifdef KPROBES_CAN_USE_FTRACE
545static void __kprobes skip_singlestep(struct kprobe *p, struct pt_regs *regs,
546 struct kprobe_ctlblk *kcb)
547{
548 /*
549 * Emulate singlestep (and also recover regs->ip)
550 * as if there is a 5byte nop
551 */
552 regs->ip = (unsigned long)p->addr + MCOUNT_INSN_SIZE;
553 if (unlikely(p->post_handler)) {
554 kcb->kprobe_status = KPROBE_HIT_SSDONE;
555 p->post_handler(p, regs, 0);
556 }
557 __this_cpu_write(current_kprobe, NULL);
558}
559#endif
560
544/* 561/*
545 * Interrupts are disabled on entry as trap3 is an interrupt gate and they 562 * Interrupts are disabled on entry as trap3 is an interrupt gate and they
546 * remain disabled throughout this function. 563 * remain disabled throughout this function.
@@ -599,6 +616,12 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
599 } else if (kprobe_running()) { 616 } else if (kprobe_running()) {
600 p = __this_cpu_read(current_kprobe); 617 p = __this_cpu_read(current_kprobe);
601 if (p->break_handler && p->break_handler(p, regs)) { 618 if (p->break_handler && p->break_handler(p, regs)) {
619#ifdef KPROBES_CAN_USE_FTRACE
620 if (kprobe_ftrace(p)) {
621 skip_singlestep(p, regs, kcb);
622 return 1;
623 }
624#endif
602 setup_singlestep(p, regs, kcb, 0); 625 setup_singlestep(p, regs, kcb, 0);
603 return 1; 626 return 1;
604 } 627 }
@@ -1052,6 +1075,50 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
1052 return 0; 1075 return 0;
1053} 1076}
1054 1077
1078#ifdef KPROBES_CAN_USE_FTRACE
1079/* Ftrace callback handler for kprobes */
1080void __kprobes kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
1081 struct ftrace_ops *ops, struct pt_regs *regs)
1082{
1083 struct kprobe *p;
1084 struct kprobe_ctlblk *kcb;
1085 unsigned long flags;
1086
1087 /* Disable irq for emulating a breakpoint and avoiding preempt */
1088 local_irq_save(flags);
1089
1090 p = get_kprobe((kprobe_opcode_t *)ip);
1091 if (unlikely(!p) || kprobe_disabled(p))
1092 goto end;
1093
1094 kcb = get_kprobe_ctlblk();
1095 if (kprobe_running()) {
1096 kprobes_inc_nmissed_count(p);
1097 } else {
1098 /* Kprobe handler expects regs->ip = ip + 1 as breakpoint hit */
1099 regs->ip = ip + sizeof(kprobe_opcode_t);
1100
1101 __this_cpu_write(current_kprobe, p);
1102 kcb->kprobe_status = KPROBE_HIT_ACTIVE;
1103 if (!p->pre_handler || !p->pre_handler(p, regs))
1104 skip_singlestep(p, regs, kcb);
1105 /*
1106 * If pre_handler returns !0, it sets regs->ip and
1107 * resets current kprobe.
1108 */
1109 }
1110end:
1111 local_irq_restore(flags);
1112}
1113
1114int __kprobes arch_prepare_kprobe_ftrace(struct kprobe *p)
1115{
1116 p->ainsn.insn = NULL;
1117 p->ainsn.boostable = -1;
1118 return 0;
1119}
1120#endif
1121
1055int __init arch_init_kprobes(void) 1122int __init arch_init_kprobes(void)
1056{ 1123{
1057 return arch_init_optprobes(); 1124 return arch_init_optprobes();
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c
index 82746f942cd8..7720ff5a9ee2 100644
--- a/arch/x86/kernel/microcode_amd.c
+++ b/arch/x86/kernel/microcode_amd.c
@@ -75,20 +75,113 @@ struct microcode_amd {
75 75
76static struct equiv_cpu_entry *equiv_cpu_table; 76static struct equiv_cpu_entry *equiv_cpu_table;
77 77
78/* page-sized ucode patch buffer */ 78struct ucode_patch {
79void *patch; 79 struct list_head plist;
80 void *data;
81 u32 patch_id;
82 u16 equiv_cpu;
83};
84
85static LIST_HEAD(pcache);
86
87static u16 find_equiv_id(unsigned int cpu)
88{
89 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
90 int i = 0;
91
92 if (!equiv_cpu_table)
93 return 0;
94
95 while (equiv_cpu_table[i].installed_cpu != 0) {
96 if (uci->cpu_sig.sig == equiv_cpu_table[i].installed_cpu)
97 return equiv_cpu_table[i].equiv_cpu;
98
99 i++;
100 }
101 return 0;
102}
103
104static u32 find_cpu_family_by_equiv_cpu(u16 equiv_cpu)
105{
106 int i = 0;
107
108 BUG_ON(!equiv_cpu_table);
109
110 while (equiv_cpu_table[i].equiv_cpu != 0) {
111 if (equiv_cpu == equiv_cpu_table[i].equiv_cpu)
112 return equiv_cpu_table[i].installed_cpu;
113 i++;
114 }
115 return 0;
116}
117
118/*
119 * a small, trivial cache of per-family ucode patches
120 */
121static struct ucode_patch *cache_find_patch(u16 equiv_cpu)
122{
123 struct ucode_patch *p;
124
125 list_for_each_entry(p, &pcache, plist)
126 if (p->equiv_cpu == equiv_cpu)
127 return p;
128 return NULL;
129}
130
131static void update_cache(struct ucode_patch *new_patch)
132{
133 struct ucode_patch *p;
134
135 list_for_each_entry(p, &pcache, plist) {
136 if (p->equiv_cpu == new_patch->equiv_cpu) {
137 if (p->patch_id >= new_patch->patch_id)
138 /* we already have the latest patch */
139 return;
140
141 list_replace(&p->plist, &new_patch->plist);
142 kfree(p->data);
143 kfree(p);
144 return;
145 }
146 }
147 /* no patch found, add it */
148 list_add_tail(&new_patch->plist, &pcache);
149}
150
151static void free_cache(void)
152{
153 struct ucode_patch *p, *tmp;
154
155 list_for_each_entry_safe(p, tmp, &pcache, plist) {
156 __list_del(p->plist.prev, p->plist.next);
157 kfree(p->data);
158 kfree(p);
159 }
160}
161
162static struct ucode_patch *find_patch(unsigned int cpu)
163{
164 u16 equiv_id;
165
166 equiv_id = find_equiv_id(cpu);
167 if (!equiv_id)
168 return NULL;
169
170 return cache_find_patch(equiv_id);
171}
80 172
81static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) 173static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig)
82{ 174{
83 struct cpuinfo_x86 *c = &cpu_data(cpu); 175 struct cpuinfo_x86 *c = &cpu_data(cpu);
84 176
177 csig->sig = cpuid_eax(0x00000001);
85 csig->rev = c->microcode; 178 csig->rev = c->microcode;
86 pr_info("CPU%d: patch_level=0x%08x\n", cpu, csig->rev); 179 pr_info("CPU%d: patch_level=0x%08x\n", cpu, csig->rev);
87 180
88 return 0; 181 return 0;
89} 182}
90 183
91static unsigned int verify_ucode_size(int cpu, u32 patch_size, 184static unsigned int verify_patch_size(int cpu, u32 patch_size,
92 unsigned int size) 185 unsigned int size)
93{ 186{
94 struct cpuinfo_x86 *c = &cpu_data(cpu); 187 struct cpuinfo_x86 *c = &cpu_data(cpu);
@@ -118,95 +211,37 @@ static unsigned int verify_ucode_size(int cpu, u32 patch_size,
118 return patch_size; 211 return patch_size;
119} 212}
120 213
121static u16 find_equiv_id(void) 214static int apply_microcode_amd(int cpu)
122{ 215{
123 unsigned int current_cpu_id, i = 0; 216 struct cpuinfo_x86 *c = &cpu_data(cpu);
124 217 struct microcode_amd *mc_amd;
125 BUG_ON(equiv_cpu_table == NULL); 218 struct ucode_cpu_info *uci;
126 219 struct ucode_patch *p;
127 current_cpu_id = cpuid_eax(0x00000001); 220 u32 rev, dummy;
128
129 while (equiv_cpu_table[i].installed_cpu != 0) {
130 if (current_cpu_id == equiv_cpu_table[i].installed_cpu)
131 return equiv_cpu_table[i].equiv_cpu;
132
133 i++;
134 }
135 return 0;
136}
137 221
138/* 222 BUG_ON(raw_smp_processor_id() != cpu);
139 * we signal a good patch is found by returning its size > 0
140 */
141static int get_matching_microcode(int cpu, const u8 *ucode_ptr,
142 unsigned int leftover_size, int rev,
143 unsigned int *current_size)
144{
145 struct microcode_header_amd *mc_hdr;
146 unsigned int actual_size, patch_size;
147 u16 equiv_cpu_id;
148 223
149 /* size of the current patch we're staring at */ 224 uci = ucode_cpu_info + cpu;
150 patch_size = *(u32 *)(ucode_ptr + 4);
151 *current_size = patch_size + SECTION_HDR_SIZE;
152 225
153 equiv_cpu_id = find_equiv_id(); 226 p = find_patch(cpu);
154 if (!equiv_cpu_id) 227 if (!p)
155 return 0; 228 return 0;
156 229
157 /* 230 mc_amd = p->data;
158 * let's look at the patch header itself now 231 uci->mc = p->data;
159 */
160 mc_hdr = (struct microcode_header_amd *)(ucode_ptr + SECTION_HDR_SIZE);
161 232
162 if (mc_hdr->processor_rev_id != equiv_cpu_id) 233 rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
163 return 0;
164 234
165 /* ucode might be chipset specific -- currently we don't support this */ 235 /* need to apply patch? */
166 if (mc_hdr->nb_dev_id || mc_hdr->sb_dev_id) { 236 if (rev >= mc_amd->hdr.patch_id) {
167 pr_err("CPU%d: chipset specific code not yet supported\n", 237 c->microcode = rev;
168 cpu);
169 return 0; 238 return 0;
170 } 239 }
171 240
172 if (mc_hdr->patch_id <= rev)
173 return 0;
174
175 /*
176 * now that the header looks sane, verify its size
177 */
178 actual_size = verify_ucode_size(cpu, patch_size, leftover_size);
179 if (!actual_size)
180 return 0;
181
182 /* clear the patch buffer */
183 memset(patch, 0, PAGE_SIZE);
184
185 /* all looks ok, get the binary patch */
186 get_ucode_data(patch, ucode_ptr + SECTION_HDR_SIZE, actual_size);
187
188 return actual_size;
189}
190
191static int apply_microcode_amd(int cpu)
192{
193 u32 rev, dummy;
194 int cpu_num = raw_smp_processor_id();
195 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
196 struct microcode_amd *mc_amd = uci->mc;
197 struct cpuinfo_x86 *c = &cpu_data(cpu);
198
199 /* We should bind the task to the CPU */
200 BUG_ON(cpu_num != cpu);
201
202 if (mc_amd == NULL)
203 return 0;
204
205 wrmsrl(MSR_AMD64_PATCH_LOADER, (u64)(long)&mc_amd->hdr.data_code); 241 wrmsrl(MSR_AMD64_PATCH_LOADER, (u64)(long)&mc_amd->hdr.data_code);
206 /* get patch id after patching */
207 rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
208 242
209 /* check current patch id and patch's id for match */ 243 /* verify patch application was successful */
244 rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
210 if (rev != mc_amd->hdr.patch_id) { 245 if (rev != mc_amd->hdr.patch_id) {
211 pr_err("CPU%d: update failed for patch_level=0x%08x\n", 246 pr_err("CPU%d: update failed for patch_level=0x%08x\n",
212 cpu, mc_amd->hdr.patch_id); 247 cpu, mc_amd->hdr.patch_id);
@@ -238,7 +273,7 @@ static int install_equiv_cpu_table(const u8 *buf)
238 return -ENOMEM; 273 return -ENOMEM;
239 } 274 }
240 275
241 get_ucode_data(equiv_cpu_table, buf + CONTAINER_HDR_SZ, size); 276 memcpy(equiv_cpu_table, buf + CONTAINER_HDR_SZ, size);
242 277
243 /* add header length */ 278 /* add header length */
244 return size + CONTAINER_HDR_SZ; 279 return size + CONTAINER_HDR_SZ;
@@ -250,61 +285,113 @@ static void free_equiv_cpu_table(void)
250 equiv_cpu_table = NULL; 285 equiv_cpu_table = NULL;
251} 286}
252 287
253static enum ucode_state 288static void cleanup(void)
254generic_load_microcode(int cpu, const u8 *data, size_t size)
255{ 289{
256 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 290 free_equiv_cpu_table();
257 struct microcode_header_amd *mc_hdr = NULL; 291 free_cache();
258 unsigned int mc_size, leftover, current_size = 0; 292}
293
294/*
295 * We return the current size even if some of the checks failed so that
296 * we can skip over the next patch. If we return a negative value, we
297 * signal a grave error like a memory allocation has failed and the
298 * driver cannot continue functioning normally. In such cases, we tear
299 * down everything we've used up so far and exit.
300 */
301static int verify_and_add_patch(unsigned int cpu, u8 *fw, unsigned int leftover)
302{
303 struct cpuinfo_x86 *c = &cpu_data(cpu);
304 struct microcode_header_amd *mc_hdr;
305 struct ucode_patch *patch;
306 unsigned int patch_size, crnt_size, ret;
307 u32 proc_fam;
308 u16 proc_id;
309
310 patch_size = *(u32 *)(fw + 4);
311 crnt_size = patch_size + SECTION_HDR_SIZE;
312 mc_hdr = (struct microcode_header_amd *)(fw + SECTION_HDR_SIZE);
313 proc_id = mc_hdr->processor_rev_id;
314
315 proc_fam = find_cpu_family_by_equiv_cpu(proc_id);
316 if (!proc_fam) {
317 pr_err("No patch family for equiv ID: 0x%04x\n", proc_id);
318 return crnt_size;
319 }
320
321 /* check if patch is for the current family */
322 proc_fam = ((proc_fam >> 8) & 0xf) + ((proc_fam >> 20) & 0xff);
323 if (proc_fam != c->x86)
324 return crnt_size;
325
326 if (mc_hdr->nb_dev_id || mc_hdr->sb_dev_id) {
327 pr_err("Patch-ID 0x%08x: chipset-specific code unsupported.\n",
328 mc_hdr->patch_id);
329 return crnt_size;
330 }
331
332 ret = verify_patch_size(cpu, patch_size, leftover);
333 if (!ret) {
334 pr_err("Patch-ID 0x%08x: size mismatch.\n", mc_hdr->patch_id);
335 return crnt_size;
336 }
337
338 patch = kzalloc(sizeof(*patch), GFP_KERNEL);
339 if (!patch) {
340 pr_err("Patch allocation failure.\n");
341 return -EINVAL;
342 }
343
344 patch->data = kzalloc(patch_size, GFP_KERNEL);
345 if (!patch->data) {
346 pr_err("Patch data allocation failure.\n");
347 kfree(patch);
348 return -EINVAL;
349 }
350
351 /* All looks ok, copy patch... */
352 memcpy(patch->data, fw + SECTION_HDR_SIZE, patch_size);
353 INIT_LIST_HEAD(&patch->plist);
354 patch->patch_id = mc_hdr->patch_id;
355 patch->equiv_cpu = proc_id;
356
357 /* ... and add to cache. */
358 update_cache(patch);
359
360 return crnt_size;
361}
362
363static enum ucode_state load_microcode_amd(int cpu, const u8 *data, size_t size)
364{
365 enum ucode_state ret = UCODE_ERROR;
366 unsigned int leftover;
367 u8 *fw = (u8 *)data;
368 int crnt_size = 0;
259 int offset; 369 int offset;
260 const u8 *ucode_ptr = data;
261 void *new_mc = NULL;
262 unsigned int new_rev = uci->cpu_sig.rev;
263 enum ucode_state state = UCODE_ERROR;
264 370
265 offset = install_equiv_cpu_table(ucode_ptr); 371 offset = install_equiv_cpu_table(data);
266 if (offset < 0) { 372 if (offset < 0) {
267 pr_err("failed to create equivalent cpu table\n"); 373 pr_err("failed to create equivalent cpu table\n");
268 goto out; 374 return ret;
269 } 375 }
270 ucode_ptr += offset; 376 fw += offset;
271 leftover = size - offset; 377 leftover = size - offset;
272 378
273 if (*(u32 *)ucode_ptr != UCODE_UCODE_TYPE) { 379 if (*(u32 *)fw != UCODE_UCODE_TYPE) {
274 pr_err("invalid type field in container file section header\n"); 380 pr_err("invalid type field in container file section header\n");
275 goto free_table; 381 free_equiv_cpu_table();
382 return ret;
276 } 383 }
277 384
278 while (leftover) { 385 while (leftover) {
279 mc_size = get_matching_microcode(cpu, ucode_ptr, leftover, 386 crnt_size = verify_and_add_patch(cpu, fw, leftover);
280 new_rev, &current_size); 387 if (crnt_size < 0)
281 if (mc_size) { 388 return ret;
282 mc_hdr = patch;
283 new_mc = patch;
284 new_rev = mc_hdr->patch_id;
285 goto out_ok;
286 }
287
288 ucode_ptr += current_size;
289 leftover -= current_size;
290 }
291 389
292 if (!new_mc) { 390 fw += crnt_size;
293 state = UCODE_NFOUND; 391 leftover -= crnt_size;
294 goto free_table;
295 } 392 }
296 393
297out_ok: 394 return UCODE_OK;
298 uci->mc = new_mc;
299 state = UCODE_OK;
300 pr_debug("CPU%d update ucode (0x%08x -> 0x%08x)\n",
301 cpu, uci->cpu_sig.rev, new_rev);
302
303free_table:
304 free_equiv_cpu_table();
305
306out:
307 return state;
308} 395}
309 396
310/* 397/*
@@ -315,7 +402,7 @@ out:
315 * 402 *
316 * This legacy file is always smaller than 2K in size. 403 * This legacy file is always smaller than 2K in size.
317 * 404 *
318 * Starting at family 15h they are in family specific firmware files: 405 * Beginning with family 15h, they are in family-specific firmware files:
319 * 406 *
320 * amd-ucode/microcode_amd_fam15h.bin 407 * amd-ucode/microcode_amd_fam15h.bin
321 * amd-ucode/microcode_amd_fam16h.bin 408 * amd-ucode/microcode_amd_fam16h.bin
@@ -323,12 +410,17 @@ out:
323 * 410 *
324 * These might be larger than 2K. 411 * These might be larger than 2K.
325 */ 412 */
326static enum ucode_state request_microcode_amd(int cpu, struct device *device) 413static enum ucode_state request_microcode_amd(int cpu, struct device *device,
414 bool refresh_fw)
327{ 415{
328 char fw_name[36] = "amd-ucode/microcode_amd.bin"; 416 char fw_name[36] = "amd-ucode/microcode_amd.bin";
329 const struct firmware *fw;
330 enum ucode_state ret = UCODE_NFOUND;
331 struct cpuinfo_x86 *c = &cpu_data(cpu); 417 struct cpuinfo_x86 *c = &cpu_data(cpu);
418 enum ucode_state ret = UCODE_NFOUND;
419 const struct firmware *fw;
420
421 /* reload ucode container only on the boot cpu */
422 if (!refresh_fw || c->cpu_index != boot_cpu_data.cpu_index)
423 return UCODE_OK;
332 424
333 if (c->x86 >= 0x15) 425 if (c->x86 >= 0x15)
334 snprintf(fw_name, sizeof(fw_name), "amd-ucode/microcode_amd_fam%.2xh.bin", c->x86); 426 snprintf(fw_name, sizeof(fw_name), "amd-ucode/microcode_amd_fam%.2xh.bin", c->x86);
@@ -344,12 +436,17 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device)
344 goto fw_release; 436 goto fw_release;
345 } 437 }
346 438
347 ret = generic_load_microcode(cpu, fw->data, fw->size); 439 /* free old equiv table */
440 free_equiv_cpu_table();
441
442 ret = load_microcode_amd(cpu, fw->data, fw->size);
443 if (ret != UCODE_OK)
444 cleanup();
348 445
349fw_release: 446 fw_release:
350 release_firmware(fw); 447 release_firmware(fw);
351 448
352out: 449 out:
353 return ret; 450 return ret;
354} 451}
355 452
@@ -383,14 +480,10 @@ struct microcode_ops * __init init_amd_microcode(void)
383 return NULL; 480 return NULL;
384 } 481 }
385 482
386 patch = (void *)get_zeroed_page(GFP_KERNEL);
387 if (!patch)
388 return NULL;
389
390 return &microcode_amd_ops; 483 return &microcode_amd_ops;
391} 484}
392 485
393void __exit exit_amd_microcode(void) 486void __exit exit_amd_microcode(void)
394{ 487{
395 free_page((unsigned long)patch); 488 cleanup();
396} 489}
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c
index 4873e62db6a1..3a04b224d0c0 100644
--- a/arch/x86/kernel/microcode_core.c
+++ b/arch/x86/kernel/microcode_core.c
@@ -225,6 +225,9 @@ static ssize_t microcode_write(struct file *file, const char __user *buf,
225 if (do_microcode_update(buf, len) == 0) 225 if (do_microcode_update(buf, len) == 0)
226 ret = (ssize_t)len; 226 ret = (ssize_t)len;
227 227
228 if (ret > 0)
229 perf_check_microcode();
230
228 mutex_unlock(&microcode_mutex); 231 mutex_unlock(&microcode_mutex);
229 put_online_cpus(); 232 put_online_cpus();
230 233
@@ -276,19 +279,18 @@ static struct platform_device *microcode_pdev;
276static int reload_for_cpu(int cpu) 279static int reload_for_cpu(int cpu)
277{ 280{
278 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 281 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
282 enum ucode_state ustate;
279 int err = 0; 283 int err = 0;
280 284
281 if (uci->valid) { 285 if (!uci->valid)
282 enum ucode_state ustate; 286 return err;
283
284 ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev);
285 if (ustate == UCODE_OK)
286 apply_microcode_on_target(cpu);
287 else
288 if (ustate == UCODE_ERROR)
289 err = -EINVAL;
290 }
291 287
288 ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev, true);
289 if (ustate == UCODE_OK)
290 apply_microcode_on_target(cpu);
291 else
292 if (ustate == UCODE_ERROR)
293 err = -EINVAL;
292 return err; 294 return err;
293} 295}
294 296
@@ -370,18 +372,15 @@ static void microcode_fini_cpu(int cpu)
370 372
371static enum ucode_state microcode_resume_cpu(int cpu) 373static enum ucode_state microcode_resume_cpu(int cpu)
372{ 374{
373 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
374
375 if (!uci->mc)
376 return UCODE_NFOUND;
377
378 pr_debug("CPU%d updated upon resume\n", cpu); 375 pr_debug("CPU%d updated upon resume\n", cpu);
379 apply_microcode_on_target(cpu); 376
377 if (apply_microcode_on_target(cpu))
378 return UCODE_ERROR;
380 379
381 return UCODE_OK; 380 return UCODE_OK;
382} 381}
383 382
384static enum ucode_state microcode_init_cpu(int cpu) 383static enum ucode_state microcode_init_cpu(int cpu, bool refresh_fw)
385{ 384{
386 enum ucode_state ustate; 385 enum ucode_state ustate;
387 386
@@ -392,7 +391,8 @@ static enum ucode_state microcode_init_cpu(int cpu)
392 if (system_state != SYSTEM_RUNNING) 391 if (system_state != SYSTEM_RUNNING)
393 return UCODE_NFOUND; 392 return UCODE_NFOUND;
394 393
395 ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev); 394 ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev,
395 refresh_fw);
396 396
397 if (ustate == UCODE_OK) { 397 if (ustate == UCODE_OK) {
398 pr_debug("CPU%d updated upon init\n", cpu); 398 pr_debug("CPU%d updated upon init\n", cpu);
@@ -405,14 +405,11 @@ static enum ucode_state microcode_init_cpu(int cpu)
405static enum ucode_state microcode_update_cpu(int cpu) 405static enum ucode_state microcode_update_cpu(int cpu)
406{ 406{
407 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 407 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
408 enum ucode_state ustate;
409 408
410 if (uci->valid) 409 if (uci->valid)
411 ustate = microcode_resume_cpu(cpu); 410 return microcode_resume_cpu(cpu);
412 else
413 ustate = microcode_init_cpu(cpu);
414 411
415 return ustate; 412 return microcode_init_cpu(cpu, false);
416} 413}
417 414
418static int mc_device_add(struct device *dev, struct subsys_interface *sif) 415static int mc_device_add(struct device *dev, struct subsys_interface *sif)
@@ -428,7 +425,7 @@ static int mc_device_add(struct device *dev, struct subsys_interface *sif)
428 if (err) 425 if (err)
429 return err; 426 return err;
430 427
431 if (microcode_init_cpu(cpu) == UCODE_ERROR) 428 if (microcode_init_cpu(cpu, true) == UCODE_ERROR)
432 return -EINVAL; 429 return -EINVAL;
433 430
434 return err; 431 return err;
@@ -477,34 +474,41 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
477 struct device *dev; 474 struct device *dev;
478 475
479 dev = get_cpu_device(cpu); 476 dev = get_cpu_device(cpu);
480 switch (action) { 477
478 switch (action & ~CPU_TASKS_FROZEN) {
481 case CPU_ONLINE: 479 case CPU_ONLINE:
482 case CPU_ONLINE_FROZEN:
483 microcode_update_cpu(cpu); 480 microcode_update_cpu(cpu);
484 case CPU_DOWN_FAILED:
485 case CPU_DOWN_FAILED_FROZEN:
486 pr_debug("CPU%d added\n", cpu); 481 pr_debug("CPU%d added\n", cpu);
482 /*
483 * "break" is missing on purpose here because we want to fall
484 * through in order to create the sysfs group.
485 */
486
487 case CPU_DOWN_FAILED:
487 if (sysfs_create_group(&dev->kobj, &mc_attr_group)) 488 if (sysfs_create_group(&dev->kobj, &mc_attr_group))
488 pr_err("Failed to create group for CPU%d\n", cpu); 489 pr_err("Failed to create group for CPU%d\n", cpu);
489 break; 490 break;
491
490 case CPU_DOWN_PREPARE: 492 case CPU_DOWN_PREPARE:
491 case CPU_DOWN_PREPARE_FROZEN:
492 /* Suspend is in progress, only remove the interface */ 493 /* Suspend is in progress, only remove the interface */
493 sysfs_remove_group(&dev->kobj, &mc_attr_group); 494 sysfs_remove_group(&dev->kobj, &mc_attr_group);
494 pr_debug("CPU%d removed\n", cpu); 495 pr_debug("CPU%d removed\n", cpu);
495 break; 496 break;
496 497
497 /* 498 /*
499 * case CPU_DEAD:
500 *
498 * When a CPU goes offline, don't free up or invalidate the copy of 501 * When a CPU goes offline, don't free up or invalidate the copy of
499 * the microcode in kernel memory, so that we can reuse it when the 502 * the microcode in kernel memory, so that we can reuse it when the
500 * CPU comes back online without unnecessarily requesting the userspace 503 * CPU comes back online without unnecessarily requesting the userspace
501 * for it again. 504 * for it again.
502 */ 505 */
503 case CPU_UP_CANCELED_FROZEN:
504 /* The CPU refused to come up during a system resume */
505 microcode_fini_cpu(cpu);
506 break;
507 } 506 }
507
508 /* The CPU refused to come up during a system resume */
509 if (action == CPU_UP_CANCELED_FROZEN)
510 microcode_fini_cpu(cpu);
511
508 return NOTIFY_OK; 512 return NOTIFY_OK;
509} 513}
510 514
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c
index 0327e2b3c408..3544aed39338 100644
--- a/arch/x86/kernel/microcode_intel.c
+++ b/arch/x86/kernel/microcode_intel.c
@@ -405,7 +405,8 @@ static int get_ucode_fw(void *to, const void *from, size_t n)
405 return 0; 405 return 0;
406} 406}
407 407
408static enum ucode_state request_microcode_fw(int cpu, struct device *device) 408static enum ucode_state request_microcode_fw(int cpu, struct device *device,
409 bool refresh_fw)
409{ 410{
410 char name[30]; 411 char name[30];
411 struct cpuinfo_x86 *c = &cpu_data(cpu); 412 struct cpuinfo_x86 *c = &cpu_data(cpu);
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index eb113693f043..a7c5661f8496 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -257,12 +257,14 @@ static int __init msr_init(void)
257 goto out_chrdev; 257 goto out_chrdev;
258 } 258 }
259 msr_class->devnode = msr_devnode; 259 msr_class->devnode = msr_devnode;
260 get_online_cpus();
260 for_each_online_cpu(i) { 261 for_each_online_cpu(i) {
261 err = msr_device_create(i); 262 err = msr_device_create(i);
262 if (err != 0) 263 if (err != 0)
263 goto out_class; 264 goto out_class;
264 } 265 }
265 register_hotcpu_notifier(&msr_class_cpu_notifier); 266 register_hotcpu_notifier(&msr_class_cpu_notifier);
267 put_online_cpus();
266 268
267 err = 0; 269 err = 0;
268 goto out; 270 goto out;
@@ -271,6 +273,7 @@ out_class:
271 i = 0; 273 i = 0;
272 for_each_online_cpu(i) 274 for_each_online_cpu(i)
273 msr_device_destroy(i); 275 msr_device_destroy(i);
276 put_online_cpus();
274 class_destroy(msr_class); 277 class_destroy(msr_class);
275out_chrdev: 278out_chrdev:
276 __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr"); 279 __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
@@ -281,11 +284,13 @@ out:
281static void __exit msr_exit(void) 284static void __exit msr_exit(void)
282{ 285{
283 int cpu = 0; 286 int cpu = 0;
287 get_online_cpus();
284 for_each_online_cpu(cpu) 288 for_each_online_cpu(cpu)
285 msr_device_destroy(cpu); 289 msr_device_destroy(cpu);
286 class_destroy(msr_class); 290 class_destroy(msr_class);
287 __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr"); 291 __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
288 unregister_hotcpu_notifier(&msr_class_cpu_notifier); 292 unregister_hotcpu_notifier(&msr_class_cpu_notifier);
293 put_online_cpus();
289} 294}
290 295
291module_init(msr_init); 296module_init(msr_init);
diff --git a/arch/x86/kernel/perf_regs.c b/arch/x86/kernel/perf_regs.c
new file mode 100644
index 000000000000..e309cc5c276e
--- /dev/null
+++ b/arch/x86/kernel/perf_regs.c
@@ -0,0 +1,105 @@
1#include <linux/errno.h>
2#include <linux/kernel.h>
3#include <linux/sched.h>
4#include <linux/perf_event.h>
5#include <linux/bug.h>
6#include <linux/stddef.h>
7#include <asm/perf_regs.h>
8#include <asm/ptrace.h>
9
10#ifdef CONFIG_X86_32
11#define PERF_REG_X86_MAX PERF_REG_X86_32_MAX
12#else
13#define PERF_REG_X86_MAX PERF_REG_X86_64_MAX
14#endif
15
16#define PT_REGS_OFFSET(id, r) [id] = offsetof(struct pt_regs, r)
17
18static unsigned int pt_regs_offset[PERF_REG_X86_MAX] = {
19 PT_REGS_OFFSET(PERF_REG_X86_AX, ax),
20 PT_REGS_OFFSET(PERF_REG_X86_BX, bx),
21 PT_REGS_OFFSET(PERF_REG_X86_CX, cx),
22 PT_REGS_OFFSET(PERF_REG_X86_DX, dx),
23 PT_REGS_OFFSET(PERF_REG_X86_SI, si),
24 PT_REGS_OFFSET(PERF_REG_X86_DI, di),
25 PT_REGS_OFFSET(PERF_REG_X86_BP, bp),
26 PT_REGS_OFFSET(PERF_REG_X86_SP, sp),
27 PT_REGS_OFFSET(PERF_REG_X86_IP, ip),
28 PT_REGS_OFFSET(PERF_REG_X86_FLAGS, flags),
29 PT_REGS_OFFSET(PERF_REG_X86_CS, cs),
30 PT_REGS_OFFSET(PERF_REG_X86_SS, ss),
31#ifdef CONFIG_X86_32
32 PT_REGS_OFFSET(PERF_REG_X86_DS, ds),
33 PT_REGS_OFFSET(PERF_REG_X86_ES, es),
34 PT_REGS_OFFSET(PERF_REG_X86_FS, fs),
35 PT_REGS_OFFSET(PERF_REG_X86_GS, gs),
36#else
37 /*
38 * The pt_regs struct does not store
39 * ds, es, fs, gs in 64 bit mode.
40 */
41 (unsigned int) -1,
42 (unsigned int) -1,
43 (unsigned int) -1,
44 (unsigned int) -1,
45#endif
46#ifdef CONFIG_X86_64
47 PT_REGS_OFFSET(PERF_REG_X86_R8, r8),
48 PT_REGS_OFFSET(PERF_REG_X86_R9, r9),
49 PT_REGS_OFFSET(PERF_REG_X86_R10, r10),
50 PT_REGS_OFFSET(PERF_REG_X86_R11, r11),
51 PT_REGS_OFFSET(PERF_REG_X86_R12, r12),
52 PT_REGS_OFFSET(PERF_REG_X86_R13, r13),
53 PT_REGS_OFFSET(PERF_REG_X86_R14, r14),
54 PT_REGS_OFFSET(PERF_REG_X86_R15, r15),
55#endif
56};
57
58u64 perf_reg_value(struct pt_regs *regs, int idx)
59{
60 if (WARN_ON_ONCE(idx >= ARRAY_SIZE(pt_regs_offset)))
61 return 0;
62
63 return regs_get_register(regs, pt_regs_offset[idx]);
64}
65
66#define REG_RESERVED (~((1ULL << PERF_REG_X86_MAX) - 1ULL))
67
68#ifdef CONFIG_X86_32
69int perf_reg_validate(u64 mask)
70{
71 if (!mask || mask & REG_RESERVED)
72 return -EINVAL;
73
74 return 0;
75}
76
77u64 perf_reg_abi(struct task_struct *task)
78{
79 return PERF_SAMPLE_REGS_ABI_32;
80}
81#else /* CONFIG_X86_64 */
82#define REG_NOSUPPORT ((1ULL << PERF_REG_X86_DS) | \
83 (1ULL << PERF_REG_X86_ES) | \
84 (1ULL << PERF_REG_X86_FS) | \
85 (1ULL << PERF_REG_X86_GS))
86
87int perf_reg_validate(u64 mask)
88{
89 if (!mask || mask & REG_RESERVED)
90 return -EINVAL;
91
92 if (mask & REG_NOSUPPORT)
93 return -EINVAL;
94
95 return 0;
96}
97
98u64 perf_reg_abi(struct task_struct *task)
99{
100 if (test_tsk_thread_flag(task, TIF_IA32))
101 return PERF_SAMPLE_REGS_ABI_32;
102 else
103 return PERF_SAMPLE_REGS_ABI_64;
104}
105#endif /* CONFIG_X86_32 */
diff --git a/arch/x86/kernel/probe_roms.c b/arch/x86/kernel/probe_roms.c
index 0bc72e2069e3..d5f15c3f7b25 100644
--- a/arch/x86/kernel/probe_roms.c
+++ b/arch/x86/kernel/probe_roms.c
@@ -150,7 +150,7 @@ static struct resource *find_oprom(struct pci_dev *pdev)
150 return oprom; 150 return oprom;
151} 151}
152 152
153void *pci_map_biosrom(struct pci_dev *pdev) 153void __iomem *pci_map_biosrom(struct pci_dev *pdev)
154{ 154{
155 struct resource *oprom = find_oprom(pdev); 155 struct resource *oprom = find_oprom(pdev);
156 156
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index ef6a8456f719..dc3567e083f9 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -66,15 +66,13 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
66{ 66{
67 int ret; 67 int ret;
68 68
69 unlazy_fpu(src);
70
71 *dst = *src; 69 *dst = *src;
72 if (fpu_allocated(&src->thread.fpu)) { 70 if (fpu_allocated(&src->thread.fpu)) {
73 memset(&dst->thread.fpu, 0, sizeof(dst->thread.fpu)); 71 memset(&dst->thread.fpu, 0, sizeof(dst->thread.fpu));
74 ret = fpu_alloc(&dst->thread.fpu); 72 ret = fpu_alloc(&dst->thread.fpu);
75 if (ret) 73 if (ret)
76 return ret; 74 return ret;
77 fpu_copy(&dst->thread.fpu, &src->thread.fpu); 75 fpu_copy(dst, src);
78 } 76 }
79 return 0; 77 return 0;
80} 78}
@@ -97,16 +95,6 @@ void arch_task_cache_init(void)
97 SLAB_PANIC | SLAB_NOTRACK, NULL); 95 SLAB_PANIC | SLAB_NOTRACK, NULL);
98} 96}
99 97
100static inline void drop_fpu(struct task_struct *tsk)
101{
102 /*
103 * Forget coprocessor state..
104 */
105 tsk->fpu_counter = 0;
106 clear_fpu(tsk);
107 clear_used_math();
108}
109
110/* 98/*
111 * Free current thread data structures etc.. 99 * Free current thread data structures etc..
112 */ 100 */
@@ -163,7 +151,13 @@ void flush_thread(void)
163 151
164 flush_ptrace_hw_breakpoint(tsk); 152 flush_ptrace_hw_breakpoint(tsk);
165 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); 153 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
166 drop_fpu(tsk); 154 drop_init_fpu(tsk);
155 /*
156 * Free the FPU state for non xsave platforms. They get reallocated
157 * lazily at the first use.
158 */
159 if (!use_eager_fpu())
160 free_thread_xstate(tsk);
167} 161}
168 162
169static void hard_disable_TSC(void) 163static void hard_disable_TSC(void)
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 516fa186121b..b9ff83c7135b 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -190,10 +190,6 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
190 regs->cs = __USER_CS; 190 regs->cs = __USER_CS;
191 regs->ip = new_ip; 191 regs->ip = new_ip;
192 regs->sp = new_sp; 192 regs->sp = new_sp;
193 /*
194 * Free the old FP and other extended state
195 */
196 free_thread_xstate(current);
197} 193}
198EXPORT_SYMBOL_GPL(start_thread); 194EXPORT_SYMBOL_GPL(start_thread);
199 195
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 0a980c9d7cb8..8a6d20ce1978 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -232,10 +232,6 @@ start_thread_common(struct pt_regs *regs, unsigned long new_ip,
232 regs->cs = _cs; 232 regs->cs = _cs;
233 regs->ss = _ss; 233 regs->ss = _ss;
234 regs->flags = X86_EFLAGS_IF; 234 regs->flags = X86_EFLAGS_IF;
235 /*
236 * Free the old FP and other extended state
237 */
238 free_thread_xstate(current);
239} 235}
240 236
241void 237void
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index c4c6a5c2bf0f..b00b33a18390 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -21,6 +21,7 @@
21#include <linux/signal.h> 21#include <linux/signal.h>
22#include <linux/perf_event.h> 22#include <linux/perf_event.h>
23#include <linux/hw_breakpoint.h> 23#include <linux/hw_breakpoint.h>
24#include <linux/rcupdate.h>
24 25
25#include <asm/uaccess.h> 26#include <asm/uaccess.h>
26#include <asm/pgtable.h> 27#include <asm/pgtable.h>
@@ -1332,9 +1333,6 @@ static const struct user_regset_view user_x86_64_view = {
1332#define genregs32_get genregs_get 1333#define genregs32_get genregs_get
1333#define genregs32_set genregs_set 1334#define genregs32_set genregs_set
1334 1335
1335#define user_i387_ia32_struct user_i387_struct
1336#define user32_fxsr_struct user_fxsr_struct
1337
1338#endif /* CONFIG_X86_64 */ 1336#endif /* CONFIG_X86_64 */
1339 1337
1340#if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION 1338#if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
@@ -1463,6 +1461,8 @@ long syscall_trace_enter(struct pt_regs *regs)
1463{ 1461{
1464 long ret = 0; 1462 long ret = 0;
1465 1463
1464 rcu_user_exit();
1465
1466 /* 1466 /*
1467 * If we stepped into a sysenter/syscall insn, it trapped in 1467 * If we stepped into a sysenter/syscall insn, it trapped in
1468 * kernel mode; do_debug() cleared TF and set TIF_SINGLESTEP. 1468 * kernel mode; do_debug() cleared TF and set TIF_SINGLESTEP.
@@ -1526,4 +1526,6 @@ void syscall_trace_leave(struct pt_regs *regs)
1526 !test_thread_flag(TIF_SYSCALL_EMU); 1526 !test_thread_flag(TIF_SYSCALL_EMU);
1527 if (step || test_thread_flag(TIF_SYSCALL_TRACE)) 1527 if (step || test_thread_flag(TIF_SYSCALL_TRACE))
1528 tracehook_report_syscall_exit(regs, step); 1528 tracehook_report_syscall_exit(regs, step);
1529
1530 rcu_user_enter();
1529} 1531}
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index f4b9b80e1b95..4f165479c453 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -961,9 +961,7 @@ void __init setup_arch(char **cmdline_p)
961 kvmclock_init(); 961 kvmclock_init();
962#endif 962#endif
963 963
964 x86_init.paging.pagetable_setup_start(swapper_pg_dir); 964 x86_init.paging.pagetable_init();
965 paging_init();
966 x86_init.paging.pagetable_setup_done(swapper_pg_dir);
967 965
968 if (boot_cpu_data.cpuid_level >= 0) { 966 if (boot_cpu_data.cpuid_level >= 0) {
969 /* A CPU has %cr4 if and only if it has CPUID */ 967 /* A CPU has %cr4 if and only if it has CPUID */
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index b280908a376e..3160c26db5e7 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -114,7 +114,7 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
114 regs->orig_ax = -1; /* disable syscall checks */ 114 regs->orig_ax = -1; /* disable syscall checks */
115 115
116 get_user_ex(buf, &sc->fpstate); 116 get_user_ex(buf, &sc->fpstate);
117 err |= restore_i387_xstate(buf); 117 err |= restore_xstate_sig(buf, config_enabled(CONFIG_X86_32));
118 118
119 get_user_ex(*pax, &sc->ax); 119 get_user_ex(*pax, &sc->ax);
120 } get_user_catch(err); 120 } get_user_catch(err);
@@ -206,35 +206,32 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
206 void __user **fpstate) 206 void __user **fpstate)
207{ 207{
208 /* Default to using normal stack */ 208 /* Default to using normal stack */
209 unsigned long math_size = 0;
209 unsigned long sp = regs->sp; 210 unsigned long sp = regs->sp;
211 unsigned long buf_fx = 0;
210 int onsigstack = on_sig_stack(sp); 212 int onsigstack = on_sig_stack(sp);
211 213
212#ifdef CONFIG_X86_64
213 /* redzone */ 214 /* redzone */
214 sp -= 128; 215 if (config_enabled(CONFIG_X86_64))
215#endif /* CONFIG_X86_64 */ 216 sp -= 128;
216 217
217 if (!onsigstack) { 218 if (!onsigstack) {
218 /* This is the X/Open sanctioned signal stack switching. */ 219 /* This is the X/Open sanctioned signal stack switching. */
219 if (ka->sa.sa_flags & SA_ONSTACK) { 220 if (ka->sa.sa_flags & SA_ONSTACK) {
220 if (current->sas_ss_size) 221 if (current->sas_ss_size)
221 sp = current->sas_ss_sp + current->sas_ss_size; 222 sp = current->sas_ss_sp + current->sas_ss_size;
222 } else { 223 } else if (config_enabled(CONFIG_X86_32) &&
223#ifdef CONFIG_X86_32 224 (regs->ss & 0xffff) != __USER_DS &&
224 /* This is the legacy signal stack switching. */ 225 !(ka->sa.sa_flags & SA_RESTORER) &&
225 if ((regs->ss & 0xffff) != __USER_DS && 226 ka->sa.sa_restorer) {
226 !(ka->sa.sa_flags & SA_RESTORER) && 227 /* This is the legacy signal stack switching. */
227 ka->sa.sa_restorer)
228 sp = (unsigned long) ka->sa.sa_restorer; 228 sp = (unsigned long) ka->sa.sa_restorer;
229#endif /* CONFIG_X86_32 */
230 } 229 }
231 } 230 }
232 231
233 if (used_math()) { 232 if (used_math()) {
234 sp -= sig_xstate_size; 233 sp = alloc_mathframe(sp, config_enabled(CONFIG_X86_32),
235#ifdef CONFIG_X86_64 234 &buf_fx, &math_size);
236 sp = round_down(sp, 64);
237#endif /* CONFIG_X86_64 */
238 *fpstate = (void __user *)sp; 235 *fpstate = (void __user *)sp;
239 } 236 }
240 237
@@ -247,8 +244,9 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
247 if (onsigstack && !likely(on_sig_stack(sp))) 244 if (onsigstack && !likely(on_sig_stack(sp)))
248 return (void __user *)-1L; 245 return (void __user *)-1L;
249 246
250 /* save i387 state */ 247 /* save i387 and extended state */
251 if (used_math() && save_i387_xstate(*fpstate) < 0) 248 if (used_math() &&
249 save_xstate_sig(*fpstate, (void __user *)buf_fx, math_size) < 0)
252 return (void __user *)-1L; 250 return (void __user *)-1L;
253 251
254 return (void __user *)sp; 252 return (void __user *)sp;
@@ -474,6 +472,74 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
474} 472}
475#endif /* CONFIG_X86_32 */ 473#endif /* CONFIG_X86_32 */
476 474
475static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
476 siginfo_t *info, compat_sigset_t *set,
477 struct pt_regs *regs)
478{
479#ifdef CONFIG_X86_X32_ABI
480 struct rt_sigframe_x32 __user *frame;
481 void __user *restorer;
482 int err = 0;
483 void __user *fpstate = NULL;
484
485 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
486
487 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
488 return -EFAULT;
489
490 if (ka->sa.sa_flags & SA_SIGINFO) {
491 if (copy_siginfo_to_user32(&frame->info, info))
492 return -EFAULT;
493 }
494
495 put_user_try {
496 /* Create the ucontext. */
497 if (cpu_has_xsave)
498 put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
499 else
500 put_user_ex(0, &frame->uc.uc_flags);
501 put_user_ex(0, &frame->uc.uc_link);
502 put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
503 put_user_ex(sas_ss_flags(regs->sp),
504 &frame->uc.uc_stack.ss_flags);
505 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
506 put_user_ex(0, &frame->uc.uc__pad0);
507 err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
508 regs, set->sig[0]);
509 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
510
511 if (ka->sa.sa_flags & SA_RESTORER) {
512 restorer = ka->sa.sa_restorer;
513 } else {
514 /* could use a vstub here */
515 restorer = NULL;
516 err |= -EFAULT;
517 }
518 put_user_ex(restorer, &frame->pretcode);
519 } put_user_catch(err);
520
521 if (err)
522 return -EFAULT;
523
524 /* Set up registers for signal handler */
525 regs->sp = (unsigned long) frame;
526 regs->ip = (unsigned long) ka->sa.sa_handler;
527
528 /* We use the x32 calling convention here... */
529 regs->di = sig;
530 regs->si = (unsigned long) &frame->info;
531 regs->dx = (unsigned long) &frame->uc;
532
533 loadsegment(ds, __USER_DS);
534 loadsegment(es, __USER_DS);
535
536 regs->cs = __USER_CS;
537 regs->ss = __USER_DS;
538#endif /* CONFIG_X86_X32_ABI */
539
540 return 0;
541}
542
477#ifdef CONFIG_X86_32 543#ifdef CONFIG_X86_32
478/* 544/*
479 * Atomically swap in the new signal mask, and wait for a signal. 545 * Atomically swap in the new signal mask, and wait for a signal.
@@ -612,55 +678,22 @@ static int signr_convert(int sig)
612 return sig; 678 return sig;
613} 679}
614 680
615#ifdef CONFIG_X86_32
616
617#define is_ia32 1
618#define ia32_setup_frame __setup_frame
619#define ia32_setup_rt_frame __setup_rt_frame
620
621#else /* !CONFIG_X86_32 */
622
623#ifdef CONFIG_IA32_EMULATION
624#define is_ia32 test_thread_flag(TIF_IA32)
625#else /* !CONFIG_IA32_EMULATION */
626#define is_ia32 0
627#endif /* CONFIG_IA32_EMULATION */
628
629#ifdef CONFIG_X86_X32_ABI
630#define is_x32 test_thread_flag(TIF_X32)
631
632static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
633 siginfo_t *info, compat_sigset_t *set,
634 struct pt_regs *regs);
635#else /* !CONFIG_X86_X32_ABI */
636#define is_x32 0
637#endif /* CONFIG_X86_X32_ABI */
638
639int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
640 sigset_t *set, struct pt_regs *regs);
641int ia32_setup_frame(int sig, struct k_sigaction *ka,
642 sigset_t *set, struct pt_regs *regs);
643
644#endif /* CONFIG_X86_32 */
645
646static int 681static int
647setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 682setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
648 struct pt_regs *regs) 683 struct pt_regs *regs)
649{ 684{
650 int usig = signr_convert(sig); 685 int usig = signr_convert(sig);
651 sigset_t *set = sigmask_to_save(); 686 sigset_t *set = sigmask_to_save();
687 compat_sigset_t *cset = (compat_sigset_t *) set;
652 688
653 /* Set up the stack frame */ 689 /* Set up the stack frame */
654 if (is_ia32) { 690 if (is_ia32_frame()) {
655 if (ka->sa.sa_flags & SA_SIGINFO) 691 if (ka->sa.sa_flags & SA_SIGINFO)
656 return ia32_setup_rt_frame(usig, ka, info, set, regs); 692 return ia32_setup_rt_frame(usig, ka, info, cset, regs);
657 else 693 else
658 return ia32_setup_frame(usig, ka, set, regs); 694 return ia32_setup_frame(usig, ka, cset, regs);
659#ifdef CONFIG_X86_X32_ABI 695 } else if (is_x32_frame()) {
660 } else if (is_x32) { 696 return x32_setup_rt_frame(usig, ka, info, cset, regs);
661 return x32_setup_rt_frame(usig, ka, info,
662 (compat_sigset_t *)set, regs);
663#endif
664 } else { 697 } else {
665 return __setup_rt_frame(sig, ka, info, set, regs); 698 return __setup_rt_frame(sig, ka, info, set, regs);
666 } 699 }
@@ -779,6 +812,8 @@ static void do_signal(struct pt_regs *regs)
779void 812void
780do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) 813do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
781{ 814{
815 rcu_user_exit();
816
782#ifdef CONFIG_X86_MCE 817#ifdef CONFIG_X86_MCE
783 /* notify userspace of pending MCEs */ 818 /* notify userspace of pending MCEs */
784 if (thread_info_flags & _TIF_MCE_NOTIFY) 819 if (thread_info_flags & _TIF_MCE_NOTIFY)
@@ -804,6 +839,8 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
804#ifdef CONFIG_X86_32 839#ifdef CONFIG_X86_32
805 clear_thread_flag(TIF_IRET); 840 clear_thread_flag(TIF_IRET);
806#endif /* CONFIG_X86_32 */ 841#endif /* CONFIG_X86_32 */
842
843 rcu_user_enter();
807} 844}
808 845
809void signal_fault(struct pt_regs *regs, void __user *frame, char *where) 846void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
@@ -824,72 +861,6 @@ void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
824} 861}
825 862
826#ifdef CONFIG_X86_X32_ABI 863#ifdef CONFIG_X86_X32_ABI
827static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
828 siginfo_t *info, compat_sigset_t *set,
829 struct pt_regs *regs)
830{
831 struct rt_sigframe_x32 __user *frame;
832 void __user *restorer;
833 int err = 0;
834 void __user *fpstate = NULL;
835
836 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
837
838 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
839 return -EFAULT;
840
841 if (ka->sa.sa_flags & SA_SIGINFO) {
842 if (copy_siginfo_to_user32(&frame->info, info))
843 return -EFAULT;
844 }
845
846 put_user_try {
847 /* Create the ucontext. */
848 if (cpu_has_xsave)
849 put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
850 else
851 put_user_ex(0, &frame->uc.uc_flags);
852 put_user_ex(0, &frame->uc.uc_link);
853 put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
854 put_user_ex(sas_ss_flags(regs->sp),
855 &frame->uc.uc_stack.ss_flags);
856 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
857 put_user_ex(0, &frame->uc.uc__pad0);
858 err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
859 regs, set->sig[0]);
860 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
861
862 if (ka->sa.sa_flags & SA_RESTORER) {
863 restorer = ka->sa.sa_restorer;
864 } else {
865 /* could use a vstub here */
866 restorer = NULL;
867 err |= -EFAULT;
868 }
869 put_user_ex(restorer, &frame->pretcode);
870 } put_user_catch(err);
871
872 if (err)
873 return -EFAULT;
874
875 /* Set up registers for signal handler */
876 regs->sp = (unsigned long) frame;
877 regs->ip = (unsigned long) ka->sa.sa_handler;
878
879 /* We use the x32 calling convention here... */
880 regs->di = sig;
881 regs->si = (unsigned long) &frame->info;
882 regs->dx = (unsigned long) &frame->uc;
883
884 loadsegment(ds, __USER_DS);
885 loadsegment(es, __USER_DS);
886
887 regs->cs = __USER_CS;
888 regs->ss = __USER_DS;
889
890 return 0;
891}
892
893asmlinkage long sys32_x32_rt_sigreturn(struct pt_regs *regs) 864asmlinkage long sys32_x32_rt_sigreturn(struct pt_regs *regs)
894{ 865{
895 struct rt_sigframe_x32 __user *frame; 866 struct rt_sigframe_x32 __user *frame;
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 7c5a8c314c02..c80a33bc528b 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -665,7 +665,8 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
665 unsigned long boot_error = 0; 665 unsigned long boot_error = 0;
666 int timeout; 666 int timeout;
667 667
668 alternatives_smp_switch(1); 668 /* Just in case we booted with a single CPU. */
669 alternatives_enable_smp();
669 670
670 idle->thread.sp = (unsigned long) (((struct pt_regs *) 671 idle->thread.sp = (unsigned long) (((struct pt_regs *)
671 (THREAD_SIZE + task_stack_page(idle))) - 1); 672 (THREAD_SIZE + task_stack_page(idle))) - 1);
@@ -1053,20 +1054,6 @@ out:
1053 preempt_enable(); 1054 preempt_enable();
1054} 1055}
1055 1056
1056void arch_disable_nonboot_cpus_begin(void)
1057{
1058 /*
1059 * Avoid the smp alternatives switch during the disable_nonboot_cpus().
1060 * In the suspend path, we will be back in the SMP mode shortly anyways.
1061 */
1062 skip_smp_alternatives = true;
1063}
1064
1065void arch_disable_nonboot_cpus_end(void)
1066{
1067 skip_smp_alternatives = false;
1068}
1069
1070void arch_enable_nonboot_cpus_begin(void) 1057void arch_enable_nonboot_cpus_begin(void)
1071{ 1058{
1072 set_mtrr_aps_delayed_init(); 1059 set_mtrr_aps_delayed_init();
@@ -1256,9 +1243,6 @@ void native_cpu_die(unsigned int cpu)
1256 if (per_cpu(cpu_state, cpu) == CPU_DEAD) { 1243 if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
1257 if (system_state == SYSTEM_RUNNING) 1244 if (system_state == SYSTEM_RUNNING)
1258 pr_info("CPU %u is now offline\n", cpu); 1245 pr_info("CPU %u is now offline\n", cpu);
1259
1260 if (1 == num_online_cpus())
1261 alternatives_smp_switch(0);
1262 return; 1246 return;
1263 } 1247 }
1264 msleep(100); 1248 msleep(100);
diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c
index c346d1161488..cd3b2438a980 100644
--- a/arch/x86/kernel/step.c
+++ b/arch/x86/kernel/step.c
@@ -157,6 +157,33 @@ static int enable_single_step(struct task_struct *child)
157 return 1; 157 return 1;
158} 158}
159 159
160void set_task_blockstep(struct task_struct *task, bool on)
161{
162 unsigned long debugctl;
163
164 /*
165 * Ensure irq/preemption can't change debugctl in between.
166 * Note also that both TIF_BLOCKSTEP and debugctl should
167 * be changed atomically wrt preemption.
168 * FIXME: this means that set/clear TIF_BLOCKSTEP is simply
169 * wrong if task != current, SIGKILL can wakeup the stopped
170 * tracee and set/clear can play with the running task, this
171 * can confuse the next __switch_to_xtra().
172 */
173 local_irq_disable();
174 debugctl = get_debugctlmsr();
175 if (on) {
176 debugctl |= DEBUGCTLMSR_BTF;
177 set_tsk_thread_flag(task, TIF_BLOCKSTEP);
178 } else {
179 debugctl &= ~DEBUGCTLMSR_BTF;
180 clear_tsk_thread_flag(task, TIF_BLOCKSTEP);
181 }
182 if (task == current)
183 update_debugctlmsr(debugctl);
184 local_irq_enable();
185}
186
160/* 187/*
161 * Enable single or block step. 188 * Enable single or block step.
162 */ 189 */
@@ -169,19 +196,10 @@ static void enable_step(struct task_struct *child, bool block)
169 * So no one should try to use debugger block stepping in a program 196 * So no one should try to use debugger block stepping in a program
170 * that uses user-mode single stepping itself. 197 * that uses user-mode single stepping itself.
171 */ 198 */
172 if (enable_single_step(child) && block) { 199 if (enable_single_step(child) && block)
173 unsigned long debugctl = get_debugctlmsr(); 200 set_task_blockstep(child, true);
174 201 else if (test_tsk_thread_flag(child, TIF_BLOCKSTEP))
175 debugctl |= DEBUGCTLMSR_BTF; 202 set_task_blockstep(child, false);
176 update_debugctlmsr(debugctl);
177 set_tsk_thread_flag(child, TIF_BLOCKSTEP);
178 } else if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) {
179 unsigned long debugctl = get_debugctlmsr();
180
181 debugctl &= ~DEBUGCTLMSR_BTF;
182 update_debugctlmsr(debugctl);
183 clear_tsk_thread_flag(child, TIF_BLOCKSTEP);
184 }
185} 203}
186 204
187void user_enable_single_step(struct task_struct *child) 205void user_enable_single_step(struct task_struct *child)
@@ -199,13 +217,8 @@ void user_disable_single_step(struct task_struct *child)
199 /* 217 /*
200 * Make sure block stepping (BTF) is disabled. 218 * Make sure block stepping (BTF) is disabled.
201 */ 219 */
202 if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) { 220 if (test_tsk_thread_flag(child, TIF_BLOCKSTEP))
203 unsigned long debugctl = get_debugctlmsr(); 221 set_task_blockstep(child, false);
204
205 debugctl &= ~DEBUGCTLMSR_BTF;
206 update_debugctlmsr(debugctl);
207 clear_tsk_thread_flag(child, TIF_BLOCKSTEP);
208 }
209 222
210 /* Always clear TIF_SINGLESTEP... */ 223 /* Always clear TIF_SINGLESTEP... */
211 clear_tsk_thread_flag(child, TIF_SINGLESTEP); 224 clear_tsk_thread_flag(child, TIF_SINGLESTEP);
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index b481341c9369..8276dc6794cc 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -55,6 +55,7 @@
55#include <asm/i387.h> 55#include <asm/i387.h>
56#include <asm/fpu-internal.h> 56#include <asm/fpu-internal.h>
57#include <asm/mce.h> 57#include <asm/mce.h>
58#include <asm/rcu.h>
58 59
59#include <asm/mach_traps.h> 60#include <asm/mach_traps.h>
60 61
@@ -107,30 +108,45 @@ static inline void preempt_conditional_cli(struct pt_regs *regs)
107 dec_preempt_count(); 108 dec_preempt_count();
108} 109}
109 110
110static void __kprobes 111static int __kprobes
111do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, 112do_trap_no_signal(struct task_struct *tsk, int trapnr, char *str,
112 long error_code, siginfo_t *info) 113 struct pt_regs *regs, long error_code)
113{ 114{
114 struct task_struct *tsk = current;
115
116#ifdef CONFIG_X86_32 115#ifdef CONFIG_X86_32
117 if (regs->flags & X86_VM_MASK) { 116 if (regs->flags & X86_VM_MASK) {
118 /* 117 /*
119 * traps 0, 1, 3, 4, and 5 should be forwarded to vm86. 118 * Traps 0, 1, 3, 4, and 5 should be forwarded to vm86.
120 * On nmi (interrupt 2), do_trap should not be called. 119 * On nmi (interrupt 2), do_trap should not be called.
121 */ 120 */
122 if (trapnr < X86_TRAP_UD) 121 if (trapnr < X86_TRAP_UD) {
123 goto vm86_trap; 122 if (!handle_vm86_trap((struct kernel_vm86_regs *) regs,
124 goto trap_signal; 123 error_code, trapnr))
124 return 0;
125 }
126 return -1;
125 } 127 }
126#endif 128#endif
129 if (!user_mode(regs)) {
130 if (!fixup_exception(regs)) {
131 tsk->thread.error_code = error_code;
132 tsk->thread.trap_nr = trapnr;
133 die(str, regs, error_code);
134 }
135 return 0;
136 }
127 137
128 if (!user_mode(regs)) 138 return -1;
129 goto kernel_trap; 139}
130 140
131#ifdef CONFIG_X86_32 141static void __kprobes
132trap_signal: 142do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
133#endif 143 long error_code, siginfo_t *info)
144{
145 struct task_struct *tsk = current;
146
147
148 if (!do_trap_no_signal(tsk, trapnr, str, regs, error_code))
149 return;
134 /* 150 /*
135 * We want error_code and trap_nr set for userspace faults and 151 * We want error_code and trap_nr set for userspace faults and
136 * kernelspace faults which result in die(), but not 152 * kernelspace faults which result in die(), but not
@@ -158,33 +174,20 @@ trap_signal:
158 force_sig_info(signr, info, tsk); 174 force_sig_info(signr, info, tsk);
159 else 175 else
160 force_sig(signr, tsk); 176 force_sig(signr, tsk);
161 return;
162
163kernel_trap:
164 if (!fixup_exception(regs)) {
165 tsk->thread.error_code = error_code;
166 tsk->thread.trap_nr = trapnr;
167 die(str, regs, error_code);
168 }
169 return;
170
171#ifdef CONFIG_X86_32
172vm86_trap:
173 if (handle_vm86_trap((struct kernel_vm86_regs *) regs,
174 error_code, trapnr))
175 goto trap_signal;
176 return;
177#endif
178} 177}
179 178
180#define DO_ERROR(trapnr, signr, str, name) \ 179#define DO_ERROR(trapnr, signr, str, name) \
181dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ 180dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
182{ \ 181{ \
183 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ 182 exception_enter(regs); \
184 == NOTIFY_STOP) \ 183 if (notify_die(DIE_TRAP, str, regs, error_code, \
184 trapnr, signr) == NOTIFY_STOP) { \
185 exception_exit(regs); \
185 return; \ 186 return; \
187 } \
186 conditional_sti(regs); \ 188 conditional_sti(regs); \
187 do_trap(trapnr, signr, str, regs, error_code, NULL); \ 189 do_trap(trapnr, signr, str, regs, error_code, NULL); \
190 exception_exit(regs); \
188} 191}
189 192
190#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ 193#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
@@ -195,11 +198,15 @@ dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
195 info.si_errno = 0; \ 198 info.si_errno = 0; \
196 info.si_code = sicode; \ 199 info.si_code = sicode; \
197 info.si_addr = (void __user *)siaddr; \ 200 info.si_addr = (void __user *)siaddr; \
198 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ 201 exception_enter(regs); \
199 == NOTIFY_STOP) \ 202 if (notify_die(DIE_TRAP, str, regs, error_code, \
203 trapnr, signr) == NOTIFY_STOP) { \
204 exception_exit(regs); \
200 return; \ 205 return; \
206 } \
201 conditional_sti(regs); \ 207 conditional_sti(regs); \
202 do_trap(trapnr, signr, str, regs, error_code, &info); \ 208 do_trap(trapnr, signr, str, regs, error_code, &info); \
209 exception_exit(regs); \
203} 210}
204 211
205DO_ERROR_INFO(X86_TRAP_DE, SIGFPE, "divide error", divide_error, FPE_INTDIV, 212DO_ERROR_INFO(X86_TRAP_DE, SIGFPE, "divide error", divide_error, FPE_INTDIV,
@@ -222,12 +229,14 @@ DO_ERROR_INFO(X86_TRAP_AC, SIGBUS, "alignment check", alignment_check,
222/* Runs on IST stack */ 229/* Runs on IST stack */
223dotraplinkage void do_stack_segment(struct pt_regs *regs, long error_code) 230dotraplinkage void do_stack_segment(struct pt_regs *regs, long error_code)
224{ 231{
232 exception_enter(regs);
225 if (notify_die(DIE_TRAP, "stack segment", regs, error_code, 233 if (notify_die(DIE_TRAP, "stack segment", regs, error_code,
226 X86_TRAP_SS, SIGBUS) == NOTIFY_STOP) 234 X86_TRAP_SS, SIGBUS) != NOTIFY_STOP) {
227 return; 235 preempt_conditional_sti(regs);
228 preempt_conditional_sti(regs); 236 do_trap(X86_TRAP_SS, SIGBUS, "stack segment", regs, error_code, NULL);
229 do_trap(X86_TRAP_SS, SIGBUS, "stack segment", regs, error_code, NULL); 237 preempt_conditional_cli(regs);
230 preempt_conditional_cli(regs); 238 }
239 exception_exit(regs);
231} 240}
232 241
233dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code) 242dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
@@ -235,6 +244,7 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
235 static const char str[] = "double fault"; 244 static const char str[] = "double fault";
236 struct task_struct *tsk = current; 245 struct task_struct *tsk = current;
237 246
247 exception_enter(regs);
238 /* Return not checked because double check cannot be ignored */ 248 /* Return not checked because double check cannot be ignored */
239 notify_die(DIE_TRAP, str, regs, error_code, X86_TRAP_DF, SIGSEGV); 249 notify_die(DIE_TRAP, str, regs, error_code, X86_TRAP_DF, SIGSEGV);
240 250
@@ -255,16 +265,29 @@ do_general_protection(struct pt_regs *regs, long error_code)
255{ 265{
256 struct task_struct *tsk; 266 struct task_struct *tsk;
257 267
268 exception_enter(regs);
258 conditional_sti(regs); 269 conditional_sti(regs);
259 270
260#ifdef CONFIG_X86_32 271#ifdef CONFIG_X86_32
261 if (regs->flags & X86_VM_MASK) 272 if (regs->flags & X86_VM_MASK) {
262 goto gp_in_vm86; 273 local_irq_enable();
274 handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
275 goto exit;
276 }
263#endif 277#endif
264 278
265 tsk = current; 279 tsk = current;
266 if (!user_mode(regs)) 280 if (!user_mode(regs)) {
267 goto gp_in_kernel; 281 if (fixup_exception(regs))
282 goto exit;
283
284 tsk->thread.error_code = error_code;
285 tsk->thread.trap_nr = X86_TRAP_GP;
286 if (notify_die(DIE_GPF, "general protection fault", regs, error_code,
287 X86_TRAP_GP, SIGSEGV) != NOTIFY_STOP)
288 die("general protection fault", regs, error_code);
289 goto exit;
290 }
268 291
269 tsk->thread.error_code = error_code; 292 tsk->thread.error_code = error_code;
270 tsk->thread.trap_nr = X86_TRAP_GP; 293 tsk->thread.trap_nr = X86_TRAP_GP;
@@ -279,25 +302,8 @@ do_general_protection(struct pt_regs *regs, long error_code)
279 } 302 }
280 303
281 force_sig(SIGSEGV, tsk); 304 force_sig(SIGSEGV, tsk);
282 return; 305exit:
283 306 exception_exit(regs);
284#ifdef CONFIG_X86_32
285gp_in_vm86:
286 local_irq_enable();
287 handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
288 return;
289#endif
290
291gp_in_kernel:
292 if (fixup_exception(regs))
293 return;
294
295 tsk->thread.error_code = error_code;
296 tsk->thread.trap_nr = X86_TRAP_GP;
297 if (notify_die(DIE_GPF, "general protection fault", regs, error_code,
298 X86_TRAP_GP, SIGSEGV) == NOTIFY_STOP)
299 return;
300 die("general protection fault", regs, error_code);
301} 307}
302 308
303/* May run on IST stack. */ 309/* May run on IST stack. */
@@ -312,15 +318,16 @@ dotraplinkage void __kprobes notrace do_int3(struct pt_regs *regs, long error_co
312 ftrace_int3_handler(regs)) 318 ftrace_int3_handler(regs))
313 return; 319 return;
314#endif 320#endif
321 exception_enter(regs);
315#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP 322#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
316 if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP, 323 if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP,
317 SIGTRAP) == NOTIFY_STOP) 324 SIGTRAP) == NOTIFY_STOP)
318 return; 325 goto exit;
319#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */ 326#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
320 327
321 if (notify_die(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP, 328 if (notify_die(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP,
322 SIGTRAP) == NOTIFY_STOP) 329 SIGTRAP) == NOTIFY_STOP)
323 return; 330 goto exit;
324 331
325 /* 332 /*
326 * Let others (NMI) know that the debug stack is in use 333 * Let others (NMI) know that the debug stack is in use
@@ -331,6 +338,8 @@ dotraplinkage void __kprobes notrace do_int3(struct pt_regs *regs, long error_co
331 do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, error_code, NULL); 338 do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, error_code, NULL);
332 preempt_conditional_cli(regs); 339 preempt_conditional_cli(regs);
333 debug_stack_usage_dec(); 340 debug_stack_usage_dec();
341exit:
342 exception_exit(regs);
334} 343}
335 344
336#ifdef CONFIG_X86_64 345#ifdef CONFIG_X86_64
@@ -391,6 +400,8 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
391 unsigned long dr6; 400 unsigned long dr6;
392 int si_code; 401 int si_code;
393 402
403 exception_enter(regs);
404
394 get_debugreg(dr6, 6); 405 get_debugreg(dr6, 6);
395 406
396 /* Filter out all the reserved bits which are preset to 1 */ 407 /* Filter out all the reserved bits which are preset to 1 */
@@ -406,7 +417,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
406 417
407 /* Catch kmemcheck conditions first of all! */ 418 /* Catch kmemcheck conditions first of all! */
408 if ((dr6 & DR_STEP) && kmemcheck_trap(regs)) 419 if ((dr6 & DR_STEP) && kmemcheck_trap(regs))
409 return; 420 goto exit;
410 421
411 /* DR6 may or may not be cleared by the CPU */ 422 /* DR6 may or may not be cleared by the CPU */
412 set_debugreg(0, 6); 423 set_debugreg(0, 6);
@@ -421,7 +432,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
421 432
422 if (notify_die(DIE_DEBUG, "debug", regs, PTR_ERR(&dr6), error_code, 433 if (notify_die(DIE_DEBUG, "debug", regs, PTR_ERR(&dr6), error_code,
423 SIGTRAP) == NOTIFY_STOP) 434 SIGTRAP) == NOTIFY_STOP)
424 return; 435 goto exit;
425 436
426 /* 437 /*
427 * Let others (NMI) know that the debug stack is in use 438 * Let others (NMI) know that the debug stack is in use
@@ -437,7 +448,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
437 X86_TRAP_DB); 448 X86_TRAP_DB);
438 preempt_conditional_cli(regs); 449 preempt_conditional_cli(regs);
439 debug_stack_usage_dec(); 450 debug_stack_usage_dec();
440 return; 451 goto exit;
441 } 452 }
442 453
443 /* 454 /*
@@ -458,7 +469,8 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
458 preempt_conditional_cli(regs); 469 preempt_conditional_cli(regs);
459 debug_stack_usage_dec(); 470 debug_stack_usage_dec();
460 471
461 return; 472exit:
473 exception_exit(regs);
462} 474}
463 475
464/* 476/*
@@ -555,14 +567,17 @@ dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
555#ifdef CONFIG_X86_32 567#ifdef CONFIG_X86_32
556 ignore_fpu_irq = 1; 568 ignore_fpu_irq = 1;
557#endif 569#endif
558 570 exception_enter(regs);
559 math_error(regs, error_code, X86_TRAP_MF); 571 math_error(regs, error_code, X86_TRAP_MF);
572 exception_exit(regs);
560} 573}
561 574
562dotraplinkage void 575dotraplinkage void
563do_simd_coprocessor_error(struct pt_regs *regs, long error_code) 576do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
564{ 577{
578 exception_enter(regs);
565 math_error(regs, error_code, X86_TRAP_XF); 579 math_error(regs, error_code, X86_TRAP_XF);
580 exception_exit(regs);
566} 581}
567 582
568dotraplinkage void 583dotraplinkage void
@@ -613,11 +628,12 @@ void math_state_restore(void)
613 } 628 }
614 629
615 __thread_fpu_begin(tsk); 630 __thread_fpu_begin(tsk);
631
616 /* 632 /*
617 * Paranoid restore. send a SIGSEGV if we fail to restore the state. 633 * Paranoid restore. send a SIGSEGV if we fail to restore the state.
618 */ 634 */
619 if (unlikely(restore_fpu_checking(tsk))) { 635 if (unlikely(restore_fpu_checking(tsk))) {
620 __thread_fpu_end(tsk); 636 drop_init_fpu(tsk);
621 force_sig(SIGSEGV, tsk); 637 force_sig(SIGSEGV, tsk);
622 return; 638 return;
623 } 639 }
@@ -629,6 +645,9 @@ EXPORT_SYMBOL_GPL(math_state_restore);
629dotraplinkage void __kprobes 645dotraplinkage void __kprobes
630do_device_not_available(struct pt_regs *regs, long error_code) 646do_device_not_available(struct pt_regs *regs, long error_code)
631{ 647{
648 exception_enter(regs);
649 BUG_ON(use_eager_fpu());
650
632#ifdef CONFIG_MATH_EMULATION 651#ifdef CONFIG_MATH_EMULATION
633 if (read_cr0() & X86_CR0_EM) { 652 if (read_cr0() & X86_CR0_EM) {
634 struct math_emu_info info = { }; 653 struct math_emu_info info = { };
@@ -637,6 +656,7 @@ do_device_not_available(struct pt_regs *regs, long error_code)
637 656
638 info.regs = regs; 657 info.regs = regs;
639 math_emulate(&info); 658 math_emulate(&info);
659 exception_exit(regs);
640 return; 660 return;
641 } 661 }
642#endif 662#endif
@@ -644,12 +664,15 @@ do_device_not_available(struct pt_regs *regs, long error_code)
644#ifdef CONFIG_X86_32 664#ifdef CONFIG_X86_32
645 conditional_sti(regs); 665 conditional_sti(regs);
646#endif 666#endif
667 exception_exit(regs);
647} 668}
648 669
649#ifdef CONFIG_X86_32 670#ifdef CONFIG_X86_32
650dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code) 671dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code)
651{ 672{
652 siginfo_t info; 673 siginfo_t info;
674
675 exception_enter(regs);
653 local_irq_enable(); 676 local_irq_enable();
654 677
655 info.si_signo = SIGILL; 678 info.si_signo = SIGILL;
@@ -657,10 +680,11 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code)
657 info.si_code = ILL_BADSTK; 680 info.si_code = ILL_BADSTK;
658 info.si_addr = NULL; 681 info.si_addr = NULL;
659 if (notify_die(DIE_TRAP, "iret exception", regs, error_code, 682 if (notify_die(DIE_TRAP, "iret exception", regs, error_code,
660 X86_TRAP_IRET, SIGILL) == NOTIFY_STOP) 683 X86_TRAP_IRET, SIGILL) != NOTIFY_STOP) {
661 return; 684 do_trap(X86_TRAP_IRET, SIGILL, "iret exception", regs, error_code,
662 do_trap(X86_TRAP_IRET, SIGILL, "iret exception", regs, error_code, 685 &info);
663 &info); 686 }
687 exception_exit(regs);
664} 688}
665#endif 689#endif
666 690
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 36fd42091fa7..9538f00827a9 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -41,6 +41,9 @@
41/* Adjust the return address of a call insn */ 41/* Adjust the return address of a call insn */
42#define UPROBE_FIX_CALL 0x2 42#define UPROBE_FIX_CALL 0x2
43 43
44/* Instruction will modify TF, don't change it */
45#define UPROBE_FIX_SETF 0x4
46
44#define UPROBE_FIX_RIP_AX 0x8000 47#define UPROBE_FIX_RIP_AX 0x8000
45#define UPROBE_FIX_RIP_CX 0x4000 48#define UPROBE_FIX_RIP_CX 0x4000
46 49
@@ -239,6 +242,10 @@ static void prepare_fixups(struct arch_uprobe *auprobe, struct insn *insn)
239 insn_get_opcode(insn); /* should be a nop */ 242 insn_get_opcode(insn); /* should be a nop */
240 243
241 switch (OPCODE1(insn)) { 244 switch (OPCODE1(insn)) {
245 case 0x9d:
246 /* popf */
247 auprobe->fixups |= UPROBE_FIX_SETF;
248 break;
242 case 0xc3: /* ret/lret */ 249 case 0xc3: /* ret/lret */
243 case 0xcb: 250 case 0xcb:
244 case 0xc2: 251 case 0xc2:
@@ -646,7 +653,7 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
646 * Skip these instructions as per the currently known x86 ISA. 653 * Skip these instructions as per the currently known x86 ISA.
647 * 0x66* { 0x90 | 0x0f 0x1f | 0x0f 0x19 | 0x87 0xc0 } 654 * 0x66* { 0x90 | 0x0f 0x1f | 0x0f 0x19 | 0x87 0xc0 }
648 */ 655 */
649bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) 656static bool __skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
650{ 657{
651 int i; 658 int i;
652 659
@@ -673,3 +680,46 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
673 } 680 }
674 return false; 681 return false;
675} 682}
683
684bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
685{
686 bool ret = __skip_sstep(auprobe, regs);
687 if (ret && (regs->flags & X86_EFLAGS_TF))
688 send_sig(SIGTRAP, current, 0);
689 return ret;
690}
691
692void arch_uprobe_enable_step(struct arch_uprobe *auprobe)
693{
694 struct task_struct *task = current;
695 struct arch_uprobe_task *autask = &task->utask->autask;
696 struct pt_regs *regs = task_pt_regs(task);
697
698 autask->saved_tf = !!(regs->flags & X86_EFLAGS_TF);
699
700 regs->flags |= X86_EFLAGS_TF;
701 if (test_tsk_thread_flag(task, TIF_BLOCKSTEP))
702 set_task_blockstep(task, false);
703}
704
705void arch_uprobe_disable_step(struct arch_uprobe *auprobe)
706{
707 struct task_struct *task = current;
708 struct arch_uprobe_task *autask = &task->utask->autask;
709 bool trapped = (task->utask->state == UTASK_SSTEP_TRAPPED);
710 struct pt_regs *regs = task_pt_regs(task);
711 /*
712 * The state of TIF_BLOCKSTEP was not saved so we can get an extra
713 * SIGTRAP if we do not clear TF. We need to examine the opcode to
714 * make it right.
715 */
716 if (unlikely(trapped)) {
717 if (!autask->saved_tf)
718 regs->flags &= ~X86_EFLAGS_TF;
719 } else {
720 if (autask->saved_tf)
721 send_sig(SIGTRAP, task, 0);
722 else if (!(auprobe->fixups & UPROBE_FIX_SETF))
723 regs->flags &= ~X86_EFLAGS_TF;
724 }
725}
diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c
index 6020f6f5927c..1330dd102950 100644
--- a/arch/x86/kernel/x8664_ksyms_64.c
+++ b/arch/x86/kernel/x8664_ksyms_64.c
@@ -13,9 +13,13 @@
13#include <asm/ftrace.h> 13#include <asm/ftrace.h>
14 14
15#ifdef CONFIG_FUNCTION_TRACER 15#ifdef CONFIG_FUNCTION_TRACER
16/* mcount is defined in assembly */ 16/* mcount and __fentry__ are defined in assembly */
17#ifdef CC_USING_FENTRY
18EXPORT_SYMBOL(__fentry__);
19#else
17EXPORT_SYMBOL(mcount); 20EXPORT_SYMBOL(mcount);
18#endif 21#endif
22#endif
19 23
20EXPORT_SYMBOL(__get_user_1); 24EXPORT_SYMBOL(__get_user_1);
21EXPORT_SYMBOL(__get_user_2); 25EXPORT_SYMBOL(__get_user_2);
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 9f3167e891ef..7a3d075a814a 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -26,7 +26,6 @@
26 26
27void __cpuinit x86_init_noop(void) { } 27void __cpuinit x86_init_noop(void) { }
28void __init x86_init_uint_noop(unsigned int unused) { } 28void __init x86_init_uint_noop(unsigned int unused) { }
29void __init x86_init_pgd_noop(pgd_t *unused) { }
30int __init iommu_init_noop(void) { return 0; } 29int __init iommu_init_noop(void) { return 0; }
31void iommu_shutdown_noop(void) { } 30void iommu_shutdown_noop(void) { }
32 31
@@ -68,8 +67,7 @@ struct x86_init_ops x86_init __initdata = {
68 }, 67 },
69 68
70 .paging = { 69 .paging = {
71 .pagetable_setup_start = native_pagetable_setup_start, 70 .pagetable_init = native_pagetable_init,
72 .pagetable_setup_done = native_pagetable_setup_done,
73 }, 71 },
74 72
75 .timers = { 73 .timers = {
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c
index 3d3e20709119..4e89b3dd408d 100644
--- a/arch/x86/kernel/xsave.c
+++ b/arch/x86/kernel/xsave.c
@@ -10,9 +10,7 @@
10#include <linux/compat.h> 10#include <linux/compat.h>
11#include <asm/i387.h> 11#include <asm/i387.h>
12#include <asm/fpu-internal.h> 12#include <asm/fpu-internal.h>
13#ifdef CONFIG_IA32_EMULATION 13#include <asm/sigframe.h>
14#include <asm/sigcontext32.h>
15#endif
16#include <asm/xcr.h> 14#include <asm/xcr.h>
17 15
18/* 16/*
@@ -23,13 +21,9 @@ u64 pcntxt_mask;
23/* 21/*
24 * Represents init state for the supported extended state. 22 * Represents init state for the supported extended state.
25 */ 23 */
26static struct xsave_struct *init_xstate_buf; 24struct xsave_struct *init_xstate_buf;
27
28struct _fpx_sw_bytes fx_sw_reserved;
29#ifdef CONFIG_IA32_EMULATION
30struct _fpx_sw_bytes fx_sw_reserved_ia32;
31#endif
32 25
26static struct _fpx_sw_bytes fx_sw_reserved, fx_sw_reserved_ia32;
33static unsigned int *xstate_offsets, *xstate_sizes, xstate_features; 27static unsigned int *xstate_offsets, *xstate_sizes, xstate_features;
34 28
35/* 29/*
@@ -44,9 +38,9 @@ static unsigned int *xstate_offsets, *xstate_sizes, xstate_features;
44 */ 38 */
45void __sanitize_i387_state(struct task_struct *tsk) 39void __sanitize_i387_state(struct task_struct *tsk)
46{ 40{
47 u64 xstate_bv;
48 int feature_bit = 0x2;
49 struct i387_fxsave_struct *fx = &tsk->thread.fpu.state->fxsave; 41 struct i387_fxsave_struct *fx = &tsk->thread.fpu.state->fxsave;
42 int feature_bit = 0x2;
43 u64 xstate_bv;
50 44
51 if (!fx) 45 if (!fx)
52 return; 46 return;
@@ -104,213 +98,326 @@ void __sanitize_i387_state(struct task_struct *tsk)
104 * Check for the presence of extended state information in the 98 * Check for the presence of extended state information in the
105 * user fpstate pointer in the sigcontext. 99 * user fpstate pointer in the sigcontext.
106 */ 100 */
107int check_for_xstate(struct i387_fxsave_struct __user *buf, 101static inline int check_for_xstate(struct i387_fxsave_struct __user *buf,
108 void __user *fpstate, 102 void __user *fpstate,
109 struct _fpx_sw_bytes *fx_sw_user) 103 struct _fpx_sw_bytes *fx_sw)
110{ 104{
111 int min_xstate_size = sizeof(struct i387_fxsave_struct) + 105 int min_xstate_size = sizeof(struct i387_fxsave_struct) +
112 sizeof(struct xsave_hdr_struct); 106 sizeof(struct xsave_hdr_struct);
113 unsigned int magic2; 107 unsigned int magic2;
114 int err;
115 108
116 err = __copy_from_user(fx_sw_user, &buf->sw_reserved[0], 109 if (__copy_from_user(fx_sw, &buf->sw_reserved[0], sizeof(*fx_sw)))
117 sizeof(struct _fpx_sw_bytes)); 110 return -1;
118 if (err)
119 return -EFAULT;
120 111
121 /* 112 /* Check for the first magic field and other error scenarios. */
122 * First Magic check failed. 113 if (fx_sw->magic1 != FP_XSTATE_MAGIC1 ||
123 */ 114 fx_sw->xstate_size < min_xstate_size ||
124 if (fx_sw_user->magic1 != FP_XSTATE_MAGIC1) 115 fx_sw->xstate_size > xstate_size ||
125 return -EINVAL; 116 fx_sw->xstate_size > fx_sw->extended_size)
117 return -1;
126 118
127 /* 119 /*
128 * Check for error scenarios.
129 */
130 if (fx_sw_user->xstate_size < min_xstate_size ||
131 fx_sw_user->xstate_size > xstate_size ||
132 fx_sw_user->xstate_size > fx_sw_user->extended_size)
133 return -EINVAL;
134
135 err = __get_user(magic2, (__u32 *) (((void *)fpstate) +
136 fx_sw_user->extended_size -
137 FP_XSTATE_MAGIC2_SIZE));
138 if (err)
139 return err;
140 /*
141 * Check for the presence of second magic word at the end of memory 120 * Check for the presence of second magic word at the end of memory
142 * layout. This detects the case where the user just copied the legacy 121 * layout. This detects the case where the user just copied the legacy
143 * fpstate layout with out copying the extended state information 122 * fpstate layout with out copying the extended state information
144 * in the memory layout. 123 * in the memory layout.
145 */ 124 */
146 if (magic2 != FP_XSTATE_MAGIC2) 125 if (__get_user(magic2, (__u32 __user *)(fpstate + fx_sw->xstate_size))
147 return -EFAULT; 126 || magic2 != FP_XSTATE_MAGIC2)
127 return -1;
148 128
149 return 0; 129 return 0;
150} 130}
151 131
152#ifdef CONFIG_X86_64
153/* 132/*
154 * Signal frame handlers. 133 * Signal frame handlers.
155 */ 134 */
156 135static inline int save_fsave_header(struct task_struct *tsk, void __user *buf)
157int save_i387_xstate(void __user *buf)
158{ 136{
159 struct task_struct *tsk = current; 137 if (use_fxsr()) {
160 int err = 0; 138 struct xsave_struct *xsave = &tsk->thread.fpu.state->xsave;
161 139 struct user_i387_ia32_struct env;
162 if (!access_ok(VERIFY_WRITE, buf, sig_xstate_size)) 140 struct _fpstate_ia32 __user *fp = buf;
163 return -EACCES;
164 141
165 BUG_ON(sig_xstate_size < xstate_size); 142 convert_from_fxsr(&env, tsk);
166 143
167 if ((unsigned long)buf % 64) 144 if (__copy_to_user(buf, &env, sizeof(env)) ||
168 pr_err("%s: bad fpstate %p\n", __func__, buf); 145 __put_user(xsave->i387.swd, &fp->status) ||
169 146 __put_user(X86_FXSR_MAGIC, &fp->magic))
170 if (!used_math()) 147 return -1;
171 return 0;
172
173 if (user_has_fpu()) {
174 if (use_xsave())
175 err = xsave_user(buf);
176 else
177 err = fxsave_user(buf);
178
179 if (err)
180 return err;
181 user_fpu_end();
182 } else { 148 } else {
183 sanitize_i387_state(tsk); 149 struct i387_fsave_struct __user *fp = buf;
184 if (__copy_to_user(buf, &tsk->thread.fpu.state->fxsave, 150 u32 swd;
185 xstate_size)) 151 if (__get_user(swd, &fp->swd) || __put_user(swd, &fp->status))
186 return -1; 152 return -1;
187 } 153 }
188 154
189 clear_used_math(); /* trigger finit */ 155 return 0;
156}
190 157
191 if (use_xsave()) { 158static inline int save_xstate_epilog(void __user *buf, int ia32_frame)
192 struct _fpstate __user *fx = buf; 159{
193 struct _xstate __user *x = buf; 160 struct xsave_struct __user *x = buf;
194 u64 xstate_bv; 161 struct _fpx_sw_bytes *sw_bytes;
162 u32 xstate_bv;
163 int err;
195 164
196 err = __copy_to_user(&fx->sw_reserved, &fx_sw_reserved, 165 /* Setup the bytes not touched by the [f]xsave and reserved for SW. */
197 sizeof(struct _fpx_sw_bytes)); 166 sw_bytes = ia32_frame ? &fx_sw_reserved_ia32 : &fx_sw_reserved;
167 err = __copy_to_user(&x->i387.sw_reserved, sw_bytes, sizeof(*sw_bytes));
198 168
199 err |= __put_user(FP_XSTATE_MAGIC2, 169 if (!use_xsave())
200 (__u32 __user *) (buf + sig_xstate_size 170 return err;
201 - FP_XSTATE_MAGIC2_SIZE));
202 171
203 /* 172 err |= __put_user(FP_XSTATE_MAGIC2, (__u32 *)(buf + xstate_size));
204 * Read the xstate_bv which we copied (directly from the cpu or
205 * from the state in task struct) to the user buffers and
206 * set the FP/SSE bits.
207 */
208 err |= __get_user(xstate_bv, &x->xstate_hdr.xstate_bv);
209 173
210 /* 174 /*
211 * For legacy compatible, we always set FP/SSE bits in the bit 175 * Read the xstate_bv which we copied (directly from the cpu or
212 * vector while saving the state to the user context. This will 176 * from the state in task struct) to the user buffers.
213 * enable us capturing any changes(during sigreturn) to 177 */
214 * the FP/SSE bits by the legacy applications which don't touch 178 err |= __get_user(xstate_bv, (__u32 *)&x->xsave_hdr.xstate_bv);
215 * xstate_bv in the xsave header.
216 *
217 * xsave aware apps can change the xstate_bv in the xsave
218 * header as well as change any contents in the memory layout.
219 * xrestore as part of sigreturn will capture all the changes.
220 */
221 xstate_bv |= XSTATE_FPSSE;
222 179
223 err |= __put_user(xstate_bv, &x->xstate_hdr.xstate_bv); 180 /*
181 * For legacy compatible, we always set FP/SSE bits in the bit
182 * vector while saving the state to the user context. This will
183 * enable us capturing any changes(during sigreturn) to
184 * the FP/SSE bits by the legacy applications which don't touch
185 * xstate_bv in the xsave header.
186 *
187 * xsave aware apps can change the xstate_bv in the xsave
188 * header as well as change any contents in the memory layout.
189 * xrestore as part of sigreturn will capture all the changes.
190 */
191 xstate_bv |= XSTATE_FPSSE;
224 192
225 if (err) 193 err |= __put_user(xstate_bv, (__u32 *)&x->xsave_hdr.xstate_bv);
226 return err;
227 }
228 194
229 return 1; 195 return err;
196}
197
198static inline int save_user_xstate(struct xsave_struct __user *buf)
199{
200 int err;
201
202 if (use_xsave())
203 err = xsave_user(buf);
204 else if (use_fxsr())
205 err = fxsave_user((struct i387_fxsave_struct __user *) buf);
206 else
207 err = fsave_user((struct i387_fsave_struct __user *) buf);
208
209 if (unlikely(err) && __clear_user(buf, xstate_size))
210 err = -EFAULT;
211 return err;
230} 212}
231 213
232/* 214/*
233 * Restore the extended state if present. Otherwise, restore the FP/SSE 215 * Save the fpu, extended register state to the user signal frame.
234 * state. 216 *
217 * 'buf_fx' is the 64-byte aligned pointer at which the [f|fx|x]save
218 * state is copied.
219 * 'buf' points to the 'buf_fx' or to the fsave header followed by 'buf_fx'.
220 *
221 * buf == buf_fx for 64-bit frames and 32-bit fsave frame.
222 * buf != buf_fx for 32-bit frames with fxstate.
223 *
224 * If the fpu, extended register state is live, save the state directly
225 * to the user frame pointed by the aligned pointer 'buf_fx'. Otherwise,
226 * copy the thread's fpu state to the user frame starting at 'buf_fx'.
227 *
228 * If this is a 32-bit frame with fxstate, put a fsave header before
229 * the aligned state at 'buf_fx'.
230 *
231 * For [f]xsave state, update the SW reserved fields in the [f]xsave frame
232 * indicating the absence/presence of the extended state to the user.
235 */ 233 */
236static int restore_user_xstate(void __user *buf) 234int save_xstate_sig(void __user *buf, void __user *buf_fx, int size)
237{ 235{
238 struct _fpx_sw_bytes fx_sw_user; 236 struct xsave_struct *xsave = &current->thread.fpu.state->xsave;
239 u64 mask; 237 struct task_struct *tsk = current;
240 int err; 238 int ia32_fxstate = (buf != buf_fx);
241 239
242 if (((unsigned long)buf % 64) || 240 ia32_fxstate &= (config_enabled(CONFIG_X86_32) ||
243 check_for_xstate(buf, buf, &fx_sw_user)) 241 config_enabled(CONFIG_IA32_EMULATION));
244 goto fx_only;
245 242
246 mask = fx_sw_user.xstate_bv; 243 if (!access_ok(VERIFY_WRITE, buf, size))
244 return -EACCES;
247 245
248 /* 246 if (!HAVE_HWFP)
249 * restore the state passed by the user. 247 return fpregs_soft_get(current, NULL, 0,
250 */ 248 sizeof(struct user_i387_ia32_struct), NULL,
251 err = xrestore_user(buf, mask); 249 (struct _fpstate_ia32 __user *) buf) ? -1 : 1;
252 if (err)
253 return err;
254 250
255 /* 251 if (user_has_fpu()) {
256 * init the state skipped by the user. 252 /* Save the live register state to the user directly. */
257 */ 253 if (save_user_xstate(buf_fx))
258 mask = pcntxt_mask & ~mask; 254 return -1;
259 if (unlikely(mask)) 255 /* Update the thread's fxstate to save the fsave header. */
260 xrstor_state(init_xstate_buf, mask); 256 if (ia32_fxstate)
257 fpu_fxsave(&tsk->thread.fpu);
258 } else {
259 sanitize_i387_state(tsk);
260 if (__copy_to_user(buf_fx, xsave, xstate_size))
261 return -1;
262 }
263
264 /* Save the fsave header for the 32-bit frames. */
265 if ((ia32_fxstate || !use_fxsr()) && save_fsave_header(tsk, buf))
266 return -1;
267
268 if (use_fxsr() && save_xstate_epilog(buf_fx, ia32_fxstate))
269 return -1;
270
271 drop_init_fpu(tsk); /* trigger finit */
261 272
262 return 0; 273 return 0;
274}
263 275
264fx_only: 276static inline void
265 /* 277sanitize_restored_xstate(struct task_struct *tsk,
266 * couldn't find the extended state information in the 278 struct user_i387_ia32_struct *ia32_env,
267 * memory layout. Restore just the FP/SSE and init all 279 u64 xstate_bv, int fx_only)
268 * the other extended state. 280{
269 */ 281 struct xsave_struct *xsave = &tsk->thread.fpu.state->xsave;
270 xrstor_state(init_xstate_buf, pcntxt_mask & ~XSTATE_FPSSE); 282 struct xsave_hdr_struct *xsave_hdr = &xsave->xsave_hdr;
271 return fxrstor_checking((__force struct i387_fxsave_struct *)buf); 283
284 if (use_xsave()) {
285 /* These bits must be zero. */
286 xsave_hdr->reserved1[0] = xsave_hdr->reserved1[1] = 0;
287
288 /*
289 * Init the state that is not present in the memory
290 * layout and not enabled by the OS.
291 */
292 if (fx_only)
293 xsave_hdr->xstate_bv = XSTATE_FPSSE;
294 else
295 xsave_hdr->xstate_bv &= (pcntxt_mask & xstate_bv);
296 }
297
298 if (use_fxsr()) {
299 /*
300 * mscsr reserved bits must be masked to zero for security
301 * reasons.
302 */
303 xsave->i387.mxcsr &= mxcsr_feature_mask;
304
305 convert_to_fxsr(tsk, ia32_env);
306 }
272} 307}
273 308
274/* 309/*
275 * This restores directly out of user space. Exceptions are handled. 310 * Restore the extended state if present. Otherwise, restore the FP/SSE state.
276 */ 311 */
277int restore_i387_xstate(void __user *buf) 312static inline int restore_user_xstate(void __user *buf, u64 xbv, int fx_only)
278{ 313{
314 if (use_xsave()) {
315 if ((unsigned long)buf % 64 || fx_only) {
316 u64 init_bv = pcntxt_mask & ~XSTATE_FPSSE;
317 xrstor_state(init_xstate_buf, init_bv);
318 return fxrstor_checking((__force void *) buf);
319 } else {
320 u64 init_bv = pcntxt_mask & ~xbv;
321 if (unlikely(init_bv))
322 xrstor_state(init_xstate_buf, init_bv);
323 return xrestore_user(buf, xbv);
324 }
325 } else if (use_fxsr()) {
326 return fxrstor_checking((__force void *) buf);
327 } else
328 return frstor_checking((__force void *) buf);
329}
330
331int __restore_xstate_sig(void __user *buf, void __user *buf_fx, int size)
332{
333 int ia32_fxstate = (buf != buf_fx);
279 struct task_struct *tsk = current; 334 struct task_struct *tsk = current;
280 int err = 0; 335 int state_size = xstate_size;
336 u64 xstate_bv = 0;
337 int fx_only = 0;
338
339 ia32_fxstate &= (config_enabled(CONFIG_X86_32) ||
340 config_enabled(CONFIG_IA32_EMULATION));
281 341
282 if (!buf) { 342 if (!buf) {
283 if (used_math()) 343 drop_init_fpu(tsk);
284 goto clear;
285 return 0; 344 return 0;
286 } else 345 }
287 if (!access_ok(VERIFY_READ, buf, sig_xstate_size))
288 return -EACCES;
289 346
290 if (!used_math()) { 347 if (!access_ok(VERIFY_READ, buf, size))
291 err = init_fpu(tsk); 348 return -EACCES;
292 if (err) 349
293 return err; 350 if (!used_math() && init_fpu(tsk))
351 return -1;
352
353 if (!HAVE_HWFP) {
354 return fpregs_soft_set(current, NULL,
355 0, sizeof(struct user_i387_ia32_struct),
356 NULL, buf) != 0;
294 } 357 }
295 358
296 user_fpu_begin(); 359 if (use_xsave()) {
297 if (use_xsave()) 360 struct _fpx_sw_bytes fx_sw_user;
298 err = restore_user_xstate(buf); 361 if (unlikely(check_for_xstate(buf_fx, buf_fx, &fx_sw_user))) {
299 else 362 /*
300 err = fxrstor_checking((__force struct i387_fxsave_struct *) 363 * Couldn't find the extended state information in the
301 buf); 364 * memory layout. Restore just the FP/SSE and init all
302 if (unlikely(err)) { 365 * the other extended state.
366 */
367 state_size = sizeof(struct i387_fxsave_struct);
368 fx_only = 1;
369 } else {
370 state_size = fx_sw_user.xstate_size;
371 xstate_bv = fx_sw_user.xstate_bv;
372 }
373 }
374
375 if (ia32_fxstate) {
376 /*
377 * For 32-bit frames with fxstate, copy the user state to the
378 * thread's fpu state, reconstruct fxstate from the fsave
379 * header. Sanitize the copied state etc.
380 */
381 struct xsave_struct *xsave = &tsk->thread.fpu.state->xsave;
382 struct user_i387_ia32_struct env;
383 int err = 0;
384
385 /*
386 * Drop the current fpu which clears used_math(). This ensures
387 * that any context-switch during the copy of the new state,
388 * avoids the intermediate state from getting restored/saved.
389 * Thus avoiding the new restored state from getting corrupted.
390 * We will be ready to restore/save the state only after
391 * set_used_math() is again set.
392 */
393 drop_fpu(tsk);
394
395 if (__copy_from_user(xsave, buf_fx, state_size) ||
396 __copy_from_user(&env, buf, sizeof(env))) {
397 err = -1;
398 } else {
399 sanitize_restored_xstate(tsk, &env, xstate_bv, fx_only);
400 set_used_math();
401 }
402
403 if (use_eager_fpu())
404 math_state_restore();
405
406 return err;
407 } else {
303 /* 408 /*
304 * Encountered an error while doing the restore from the 409 * For 64-bit frames and 32-bit fsave frames, restore the user
305 * user buffer, clear the fpu state. 410 * state to the registers directly (with exceptions handled).
306 */ 411 */
307clear: 412 user_fpu_begin();
308 clear_fpu(tsk); 413 if (restore_user_xstate(buf_fx, xstate_bv, fx_only)) {
309 clear_used_math(); 414 drop_init_fpu(tsk);
415 return -1;
416 }
310 } 417 }
311 return err; 418
419 return 0;
312} 420}
313#endif
314 421
315/* 422/*
316 * Prepare the SW reserved portion of the fxsave memory layout, indicating 423 * Prepare the SW reserved portion of the fxsave memory layout, indicating
@@ -321,31 +428,22 @@ clear:
321 */ 428 */
322static void prepare_fx_sw_frame(void) 429static void prepare_fx_sw_frame(void)
323{ 430{
324 int size_extended = (xstate_size - sizeof(struct i387_fxsave_struct)) + 431 int fsave_header_size = sizeof(struct i387_fsave_struct);
325 FP_XSTATE_MAGIC2_SIZE; 432 int size = xstate_size + FP_XSTATE_MAGIC2_SIZE;
326 433
327 sig_xstate_size = sizeof(struct _fpstate) + size_extended; 434 if (config_enabled(CONFIG_X86_32))
328 435 size += fsave_header_size;
329#ifdef CONFIG_IA32_EMULATION
330 sig_xstate_ia32_size = sizeof(struct _fpstate_ia32) + size_extended;
331#endif
332
333 memset(&fx_sw_reserved, 0, sizeof(fx_sw_reserved));
334 436
335 fx_sw_reserved.magic1 = FP_XSTATE_MAGIC1; 437 fx_sw_reserved.magic1 = FP_XSTATE_MAGIC1;
336 fx_sw_reserved.extended_size = sig_xstate_size; 438 fx_sw_reserved.extended_size = size;
337 fx_sw_reserved.xstate_bv = pcntxt_mask; 439 fx_sw_reserved.xstate_bv = pcntxt_mask;
338 fx_sw_reserved.xstate_size = xstate_size; 440 fx_sw_reserved.xstate_size = xstate_size;
339#ifdef CONFIG_IA32_EMULATION
340 memcpy(&fx_sw_reserved_ia32, &fx_sw_reserved,
341 sizeof(struct _fpx_sw_bytes));
342 fx_sw_reserved_ia32.extended_size = sig_xstate_ia32_size;
343#endif
344}
345 441
346#ifdef CONFIG_X86_64 442 if (config_enabled(CONFIG_IA32_EMULATION)) {
347unsigned int sig_xstate_size = sizeof(struct _fpstate); 443 fx_sw_reserved_ia32 = fx_sw_reserved;
348#endif 444 fx_sw_reserved_ia32.extended_size += fsave_header_size;
445 }
446}
349 447
350/* 448/*
351 * Enable the extended processor state save/restore feature 449 * Enable the extended processor state save/restore feature
@@ -384,19 +482,21 @@ static void __init setup_xstate_features(void)
384/* 482/*
385 * setup the xstate image representing the init state 483 * setup the xstate image representing the init state
386 */ 484 */
387static void __init setup_xstate_init(void) 485static void __init setup_init_fpu_buf(void)
388{ 486{
389 setup_xstate_features();
390
391 /* 487 /*
392 * Setup init_xstate_buf to represent the init state of 488 * Setup init_xstate_buf to represent the init state of
393 * all the features managed by the xsave 489 * all the features managed by the xsave
394 */ 490 */
395 init_xstate_buf = alloc_bootmem_align(xstate_size, 491 init_xstate_buf = alloc_bootmem_align(xstate_size,
396 __alignof__(struct xsave_struct)); 492 __alignof__(struct xsave_struct));
397 init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT; 493 fx_finit(&init_xstate_buf->i387);
494
495 if (!cpu_has_xsave)
496 return;
497
498 setup_xstate_features();
398 499
399 clts();
400 /* 500 /*
401 * Init all the features state with header_bv being 0x0 501 * Init all the features state with header_bv being 0x0
402 */ 502 */
@@ -406,9 +506,21 @@ static void __init setup_xstate_init(void)
406 * of any feature which is not represented by all zero's. 506 * of any feature which is not represented by all zero's.
407 */ 507 */
408 xsave_state(init_xstate_buf, -1); 508 xsave_state(init_xstate_buf, -1);
409 stts();
410} 509}
411 510
511static enum { AUTO, ENABLE, DISABLE } eagerfpu = AUTO;
512static int __init eager_fpu_setup(char *s)
513{
514 if (!strcmp(s, "on"))
515 eagerfpu = ENABLE;
516 else if (!strcmp(s, "off"))
517 eagerfpu = DISABLE;
518 else if (!strcmp(s, "auto"))
519 eagerfpu = AUTO;
520 return 1;
521}
522__setup("eagerfpu=", eager_fpu_setup);
523
412/* 524/*
413 * Enable and initialize the xsave feature. 525 * Enable and initialize the xsave feature.
414 */ 526 */
@@ -445,8 +557,11 @@ static void __init xstate_enable_boot_cpu(void)
445 557
446 update_regset_xstate_info(xstate_size, pcntxt_mask); 558 update_regset_xstate_info(xstate_size, pcntxt_mask);
447 prepare_fx_sw_frame(); 559 prepare_fx_sw_frame();
560 setup_init_fpu_buf();
448 561
449 setup_xstate_init(); 562 /* Auto enable eagerfpu for xsaveopt */
563 if (cpu_has_xsaveopt && eagerfpu != DISABLE)
564 eagerfpu = ENABLE;
450 565
451 pr_info("enabled xstate_bv 0x%llx, cntxt size 0x%x\n", 566 pr_info("enabled xstate_bv 0x%llx, cntxt size 0x%x\n",
452 pcntxt_mask, xstate_size); 567 pcntxt_mask, xstate_size);
@@ -471,3 +586,43 @@ void __cpuinit xsave_init(void)
471 next_func = xstate_enable; 586 next_func = xstate_enable;
472 this_func(); 587 this_func();
473} 588}
589
590static inline void __init eager_fpu_init_bp(void)
591{
592 current->thread.fpu.state =
593 alloc_bootmem_align(xstate_size, __alignof__(struct xsave_struct));
594 if (!init_xstate_buf)
595 setup_init_fpu_buf();
596}
597
598void __cpuinit eager_fpu_init(void)
599{
600 static __refdata void (*boot_func)(void) = eager_fpu_init_bp;
601
602 clear_used_math();
603 current_thread_info()->status = 0;
604
605 if (eagerfpu == ENABLE)
606 setup_force_cpu_cap(X86_FEATURE_EAGER_FPU);
607
608 if (!cpu_has_eager_fpu) {
609 stts();
610 return;
611 }
612
613 if (boot_func) {
614 boot_func();
615 boot_func = NULL;
616 }
617
618 /*
619 * This is same as math_state_restore(). But use_xsave() is
620 * not yet patched to use math_state_restore().
621 */
622 init_fpu(current);
623 __thread_fpu_begin(current);
624 if (cpu_has_xsave)
625 xrstor_state(init_xstate_buf, -1);
626 else
627 fxrstor_checking(&init_xstate_buf->i387);
628}
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index e498b18f010c..9fc9aa7ac703 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -318,7 +318,7 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val)
318 if (val & 0x10) { 318 if (val & 0x10) {
319 u8 edge_irr = s->irr & ~s->elcr; 319 u8 edge_irr = s->irr & ~s->elcr;
320 int i; 320 int i;
321 bool found; 321 bool found = false;
322 struct kvm_vcpu *vcpu; 322 struct kvm_vcpu *vcpu;
323 323
324 s->init4 = val & 1; 324 s->init4 = val & 1;
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
index a71faf727ff3..bca63f04dccb 100644
--- a/arch/x86/kvm/trace.h
+++ b/arch/x86/kvm/trace.h
@@ -183,95 +183,6 @@ TRACE_EVENT(kvm_apic,
183#define KVM_ISA_VMX 1 183#define KVM_ISA_VMX 1
184#define KVM_ISA_SVM 2 184#define KVM_ISA_SVM 2
185 185
186#define VMX_EXIT_REASONS \
187 { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, \
188 { EXIT_REASON_EXTERNAL_INTERRUPT, "EXTERNAL_INTERRUPT" }, \
189 { EXIT_REASON_TRIPLE_FAULT, "TRIPLE_FAULT" }, \
190 { EXIT_REASON_PENDING_INTERRUPT, "PENDING_INTERRUPT" }, \
191 { EXIT_REASON_NMI_WINDOW, "NMI_WINDOW" }, \
192 { EXIT_REASON_TASK_SWITCH, "TASK_SWITCH" }, \
193 { EXIT_REASON_CPUID, "CPUID" }, \
194 { EXIT_REASON_HLT, "HLT" }, \
195 { EXIT_REASON_INVLPG, "INVLPG" }, \
196 { EXIT_REASON_RDPMC, "RDPMC" }, \
197 { EXIT_REASON_RDTSC, "RDTSC" }, \
198 { EXIT_REASON_VMCALL, "VMCALL" }, \
199 { EXIT_REASON_VMCLEAR, "VMCLEAR" }, \
200 { EXIT_REASON_VMLAUNCH, "VMLAUNCH" }, \
201 { EXIT_REASON_VMPTRLD, "VMPTRLD" }, \
202 { EXIT_REASON_VMPTRST, "VMPTRST" }, \
203 { EXIT_REASON_VMREAD, "VMREAD" }, \
204 { EXIT_REASON_VMRESUME, "VMRESUME" }, \
205 { EXIT_REASON_VMWRITE, "VMWRITE" }, \
206 { EXIT_REASON_VMOFF, "VMOFF" }, \
207 { EXIT_REASON_VMON, "VMON" }, \
208 { EXIT_REASON_CR_ACCESS, "CR_ACCESS" }, \
209 { EXIT_REASON_DR_ACCESS, "DR_ACCESS" }, \
210 { EXIT_REASON_IO_INSTRUCTION, "IO_INSTRUCTION" }, \
211 { EXIT_REASON_MSR_READ, "MSR_READ" }, \
212 { EXIT_REASON_MSR_WRITE, "MSR_WRITE" }, \
213 { EXIT_REASON_MWAIT_INSTRUCTION, "MWAIT_INSTRUCTION" }, \
214 { EXIT_REASON_MONITOR_INSTRUCTION, "MONITOR_INSTRUCTION" }, \
215 { EXIT_REASON_PAUSE_INSTRUCTION, "PAUSE_INSTRUCTION" }, \
216 { EXIT_REASON_MCE_DURING_VMENTRY, "MCE_DURING_VMENTRY" }, \
217 { EXIT_REASON_TPR_BELOW_THRESHOLD, "TPR_BELOW_THRESHOLD" }, \
218 { EXIT_REASON_APIC_ACCESS, "APIC_ACCESS" }, \
219 { EXIT_REASON_EPT_VIOLATION, "EPT_VIOLATION" }, \
220 { EXIT_REASON_EPT_MISCONFIG, "EPT_MISCONFIG" }, \
221 { EXIT_REASON_WBINVD, "WBINVD" }
222
223#define SVM_EXIT_REASONS \
224 { SVM_EXIT_READ_CR0, "read_cr0" }, \
225 { SVM_EXIT_READ_CR3, "read_cr3" }, \
226 { SVM_EXIT_READ_CR4, "read_cr4" }, \
227 { SVM_EXIT_READ_CR8, "read_cr8" }, \
228 { SVM_EXIT_WRITE_CR0, "write_cr0" }, \
229 { SVM_EXIT_WRITE_CR3, "write_cr3" }, \
230 { SVM_EXIT_WRITE_CR4, "write_cr4" }, \
231 { SVM_EXIT_WRITE_CR8, "write_cr8" }, \
232 { SVM_EXIT_READ_DR0, "read_dr0" }, \
233 { SVM_EXIT_READ_DR1, "read_dr1" }, \
234 { SVM_EXIT_READ_DR2, "read_dr2" }, \
235 { SVM_EXIT_READ_DR3, "read_dr3" }, \
236 { SVM_EXIT_WRITE_DR0, "write_dr0" }, \
237 { SVM_EXIT_WRITE_DR1, "write_dr1" }, \
238 { SVM_EXIT_WRITE_DR2, "write_dr2" }, \
239 { SVM_EXIT_WRITE_DR3, "write_dr3" }, \
240 { SVM_EXIT_WRITE_DR5, "write_dr5" }, \
241 { SVM_EXIT_WRITE_DR7, "write_dr7" }, \
242 { SVM_EXIT_EXCP_BASE + DB_VECTOR, "DB excp" }, \
243 { SVM_EXIT_EXCP_BASE + BP_VECTOR, "BP excp" }, \
244 { SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" }, \
245 { SVM_EXIT_EXCP_BASE + PF_VECTOR, "PF excp" }, \
246 { SVM_EXIT_EXCP_BASE + NM_VECTOR, "NM excp" }, \
247 { SVM_EXIT_EXCP_BASE + MC_VECTOR, "MC excp" }, \
248 { SVM_EXIT_INTR, "interrupt" }, \
249 { SVM_EXIT_NMI, "nmi" }, \
250 { SVM_EXIT_SMI, "smi" }, \
251 { SVM_EXIT_INIT, "init" }, \
252 { SVM_EXIT_VINTR, "vintr" }, \
253 { SVM_EXIT_CPUID, "cpuid" }, \
254 { SVM_EXIT_INVD, "invd" }, \
255 { SVM_EXIT_HLT, "hlt" }, \
256 { SVM_EXIT_INVLPG, "invlpg" }, \
257 { SVM_EXIT_INVLPGA, "invlpga" }, \
258 { SVM_EXIT_IOIO, "io" }, \
259 { SVM_EXIT_MSR, "msr" }, \
260 { SVM_EXIT_TASK_SWITCH, "task_switch" }, \
261 { SVM_EXIT_SHUTDOWN, "shutdown" }, \
262 { SVM_EXIT_VMRUN, "vmrun" }, \
263 { SVM_EXIT_VMMCALL, "hypercall" }, \
264 { SVM_EXIT_VMLOAD, "vmload" }, \
265 { SVM_EXIT_VMSAVE, "vmsave" }, \
266 { SVM_EXIT_STGI, "stgi" }, \
267 { SVM_EXIT_CLGI, "clgi" }, \
268 { SVM_EXIT_SKINIT, "skinit" }, \
269 { SVM_EXIT_WBINVD, "wbinvd" }, \
270 { SVM_EXIT_MONITOR, "monitor" }, \
271 { SVM_EXIT_MWAIT, "mwait" }, \
272 { SVM_EXIT_XSETBV, "xsetbv" }, \
273 { SVM_EXIT_NPF, "npf" }
274
275/* 186/*
276 * Tracepoint for kvm guest exit: 187 * Tracepoint for kvm guest exit:
277 */ 188 */
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index c00f03de1b79..851aa7c3b890 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1493,8 +1493,12 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx)
1493#ifdef CONFIG_X86_64 1493#ifdef CONFIG_X86_64
1494 wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base); 1494 wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
1495#endif 1495#endif
1496 if (user_has_fpu()) 1496 /*
1497 clts(); 1497 * If the FPU is not active (through the host task or
1498 * the guest vcpu), then restore the cr0.TS bit.
1499 */
1500 if (!user_has_fpu() && !vmx->vcpu.guest_fpu_loaded)
1501 stts();
1498 load_gdt(&__get_cpu_var(host_gdt)); 1502 load_gdt(&__get_cpu_var(host_gdt));
1499} 1503}
1500 1504
@@ -3619,6 +3623,7 @@ static void seg_setup(int seg)
3619 3623
3620static int alloc_apic_access_page(struct kvm *kvm) 3624static int alloc_apic_access_page(struct kvm *kvm)
3621{ 3625{
3626 struct page *page;
3622 struct kvm_userspace_memory_region kvm_userspace_mem; 3627 struct kvm_userspace_memory_region kvm_userspace_mem;
3623 int r = 0; 3628 int r = 0;
3624 3629
@@ -3633,7 +3638,13 @@ static int alloc_apic_access_page(struct kvm *kvm)
3633 if (r) 3638 if (r)
3634 goto out; 3639 goto out;
3635 3640
3636 kvm->arch.apic_access_page = gfn_to_page(kvm, 0xfee00); 3641 page = gfn_to_page(kvm, 0xfee00);
3642 if (is_error_page(page)) {
3643 r = -EFAULT;
3644 goto out;
3645 }
3646
3647 kvm->arch.apic_access_page = page;
3637out: 3648out:
3638 mutex_unlock(&kvm->slots_lock); 3649 mutex_unlock(&kvm->slots_lock);
3639 return r; 3650 return r;
@@ -3641,6 +3652,7 @@ out:
3641 3652
3642static int alloc_identity_pagetable(struct kvm *kvm) 3653static int alloc_identity_pagetable(struct kvm *kvm)
3643{ 3654{
3655 struct page *page;
3644 struct kvm_userspace_memory_region kvm_userspace_mem; 3656 struct kvm_userspace_memory_region kvm_userspace_mem;
3645 int r = 0; 3657 int r = 0;
3646 3658
@@ -3656,8 +3668,13 @@ static int alloc_identity_pagetable(struct kvm *kvm)
3656 if (r) 3668 if (r)
3657 goto out; 3669 goto out;
3658 3670
3659 kvm->arch.ept_identity_pagetable = gfn_to_page(kvm, 3671 page = gfn_to_page(kvm, kvm->arch.ept_identity_map_addr >> PAGE_SHIFT);
3660 kvm->arch.ept_identity_map_addr >> PAGE_SHIFT); 3672 if (is_error_page(page)) {
3673 r = -EFAULT;
3674 goto out;
3675 }
3676
3677 kvm->arch.ept_identity_pagetable = page;
3661out: 3678out:
3662 mutex_unlock(&kvm->slots_lock); 3679 mutex_unlock(&kvm->slots_lock);
3663 return r; 3680 return r;
@@ -3730,7 +3747,7 @@ static void vmx_set_constant_host_state(void)
3730 unsigned long tmpl; 3747 unsigned long tmpl;
3731 struct desc_ptr dt; 3748 struct desc_ptr dt;
3732 3749
3733 vmcs_writel(HOST_CR0, read_cr0() | X86_CR0_TS); /* 22.2.3 */ 3750 vmcs_writel(HOST_CR0, read_cr0() & ~X86_CR0_TS); /* 22.2.3 */
3734 vmcs_writel(HOST_CR4, read_cr4()); /* 22.2.3, 22.2.5 */ 3751 vmcs_writel(HOST_CR4, read_cr4()); /* 22.2.3, 22.2.5 */
3735 vmcs_writel(HOST_CR3, read_cr3()); /* 22.2.3 FIXME: shadow tables */ 3752 vmcs_writel(HOST_CR3, read_cr3()); /* 22.2.3 FIXME: shadow tables */
3736 3753
@@ -4530,7 +4547,7 @@ static int handle_cr(struct kvm_vcpu *vcpu)
4530 vcpu->run->exit_reason = KVM_EXIT_SET_TPR; 4547 vcpu->run->exit_reason = KVM_EXIT_SET_TPR;
4531 return 0; 4548 return 0;
4532 } 4549 }
4533 }; 4550 }
4534 break; 4551 break;
4535 case 2: /* clts */ 4552 case 2: /* clts */
4536 handle_clts(vcpu); 4553 handle_clts(vcpu);
@@ -6575,7 +6592,7 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
6575 /* Exposing INVPCID only when PCID is exposed */ 6592 /* Exposing INVPCID only when PCID is exposed */
6576 best = kvm_find_cpuid_entry(vcpu, 0x7, 0); 6593 best = kvm_find_cpuid_entry(vcpu, 0x7, 0);
6577 if (vmx_invpcid_supported() && 6594 if (vmx_invpcid_supported() &&
6578 best && (best->ecx & bit(X86_FEATURE_INVPCID)) && 6595 best && (best->ebx & bit(X86_FEATURE_INVPCID)) &&
6579 guest_cpuid_has_pcid(vcpu)) { 6596 guest_cpuid_has_pcid(vcpu)) {
6580 exec_control |= SECONDARY_EXEC_ENABLE_INVPCID; 6597 exec_control |= SECONDARY_EXEC_ENABLE_INVPCID;
6581 vmcs_write32(SECONDARY_VM_EXEC_CONTROL, 6598 vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
@@ -6585,7 +6602,7 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
6585 vmcs_write32(SECONDARY_VM_EXEC_CONTROL, 6602 vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
6586 exec_control); 6603 exec_control);
6587 if (best) 6604 if (best)
6588 best->ecx &= ~bit(X86_FEATURE_INVPCID); 6605 best->ebx &= ~bit(X86_FEATURE_INVPCID);
6589 } 6606 }
6590} 6607}
6591 6608
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 148ed666e311..1f09552572fa 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5113,17 +5113,20 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu)
5113 !kvm_event_needs_reinjection(vcpu); 5113 !kvm_event_needs_reinjection(vcpu);
5114} 5114}
5115 5115
5116static void vapic_enter(struct kvm_vcpu *vcpu) 5116static int vapic_enter(struct kvm_vcpu *vcpu)
5117{ 5117{
5118 struct kvm_lapic *apic = vcpu->arch.apic; 5118 struct kvm_lapic *apic = vcpu->arch.apic;
5119 struct page *page; 5119 struct page *page;
5120 5120
5121 if (!apic || !apic->vapic_addr) 5121 if (!apic || !apic->vapic_addr)
5122 return; 5122 return 0;
5123 5123
5124 page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT); 5124 page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT);
5125 if (is_error_page(page))
5126 return -EFAULT;
5125 5127
5126 vcpu->arch.apic->vapic_page = page; 5128 vcpu->arch.apic->vapic_page = page;
5129 return 0;
5127} 5130}
5128 5131
5129static void vapic_exit(struct kvm_vcpu *vcpu) 5132static void vapic_exit(struct kvm_vcpu *vcpu)
@@ -5430,7 +5433,11 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
5430 } 5433 }
5431 5434
5432 vcpu->srcu_idx = srcu_read_lock(&kvm->srcu); 5435 vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
5433 vapic_enter(vcpu); 5436 r = vapic_enter(vcpu);
5437 if (r) {
5438 srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
5439 return r;
5440 }
5434 5441
5435 r = 1; 5442 r = 1;
5436 while (r > 0) { 5443 while (r > 0) {
@@ -5972,7 +5979,7 @@ void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
5972 */ 5979 */
5973 kvm_put_guest_xcr0(vcpu); 5980 kvm_put_guest_xcr0(vcpu);
5974 vcpu->guest_fpu_loaded = 1; 5981 vcpu->guest_fpu_loaded = 1;
5975 unlazy_fpu(current); 5982 __kernel_fpu_begin();
5976 fpu_restore_checking(&vcpu->arch.guest_fpu); 5983 fpu_restore_checking(&vcpu->arch.guest_fpu);
5977 trace_kvm_fpu(1); 5984 trace_kvm_fpu(1);
5978} 5985}
@@ -5986,6 +5993,7 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
5986 5993
5987 vcpu->guest_fpu_loaded = 0; 5994 vcpu->guest_fpu_loaded = 0;
5988 fpu_save_init(&vcpu->arch.guest_fpu); 5995 fpu_save_init(&vcpu->arch.guest_fpu);
5996 __kernel_fpu_end();
5989 ++vcpu->stat.fpu_reload; 5997 ++vcpu->stat.fpu_reload;
5990 kvm_make_request(KVM_REQ_DEACTIVATE_FPU, vcpu); 5998 kvm_make_request(KVM_REQ_DEACTIVATE_FPU, vcpu);
5991 trace_kvm_fpu(0); 5999 trace_kvm_fpu(0);
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 76dcd9d8e0bc..7dde46d68a25 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -18,6 +18,7 @@
18#include <asm/pgalloc.h> /* pgd_*(), ... */ 18#include <asm/pgalloc.h> /* pgd_*(), ... */
19#include <asm/kmemcheck.h> /* kmemcheck_*(), ... */ 19#include <asm/kmemcheck.h> /* kmemcheck_*(), ... */
20#include <asm/fixmap.h> /* VSYSCALL_START */ 20#include <asm/fixmap.h> /* VSYSCALL_START */
21#include <asm/rcu.h> /* exception_enter(), ... */
21 22
22/* 23/*
23 * Page fault error code bits: 24 * Page fault error code bits:
@@ -1000,8 +1001,8 @@ static int fault_in_kernel_space(unsigned long address)
1000 * and the problem, and then passes it off to one of the appropriate 1001 * and the problem, and then passes it off to one of the appropriate
1001 * routines. 1002 * routines.
1002 */ 1003 */
1003dotraplinkage void __kprobes 1004static void __kprobes
1004do_page_fault(struct pt_regs *regs, unsigned long error_code) 1005__do_page_fault(struct pt_regs *regs, unsigned long error_code)
1005{ 1006{
1006 struct vm_area_struct *vma; 1007 struct vm_area_struct *vma;
1007 struct task_struct *tsk; 1008 struct task_struct *tsk;
@@ -1209,3 +1210,11 @@ good_area:
1209 1210
1210 up_read(&mm->mmap_sem); 1211 up_read(&mm->mmap_sem);
1211} 1212}
1213
1214dotraplinkage void __kprobes
1215do_page_fault(struct pt_regs *regs, unsigned long error_code)
1216{
1217 exception_enter(regs);
1218 __do_page_fault(regs, error_code);
1219 exception_exit(regs);
1220}
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index e0e6990723e9..ab1f6a93b527 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -319,7 +319,7 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
319 */ 319 */
320int devmem_is_allowed(unsigned long pagenr) 320int devmem_is_allowed(unsigned long pagenr)
321{ 321{
322 if (pagenr <= 256) 322 if (pagenr < 256)
323 return 1; 323 return 1;
324 if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) 324 if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
325 return 0; 325 return 0;
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 575d86f85ce4..4f04db150027 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -445,10 +445,10 @@ static inline void permanent_kmaps_init(pgd_t *pgd_base)
445} 445}
446#endif /* CONFIG_HIGHMEM */ 446#endif /* CONFIG_HIGHMEM */
447 447
448void __init native_pagetable_setup_start(pgd_t *base) 448void __init native_pagetable_init(void)
449{ 449{
450 unsigned long pfn, va; 450 unsigned long pfn, va;
451 pgd_t *pgd; 451 pgd_t *pgd, *base = swapper_pg_dir;
452 pud_t *pud; 452 pud_t *pud;
453 pmd_t *pmd; 453 pmd_t *pmd;
454 pte_t *pte; 454 pte_t *pte;
@@ -475,10 +475,7 @@ void __init native_pagetable_setup_start(pgd_t *base)
475 pte_clear(NULL, va, pte); 475 pte_clear(NULL, va, pte);
476 } 476 }
477 paravirt_alloc_pmd(&init_mm, __pa(base) >> PAGE_SHIFT); 477 paravirt_alloc_pmd(&init_mm, __pa(base) >> PAGE_SHIFT);
478} 478 paging_init();
479
480void __init native_pagetable_setup_done(pgd_t *base)
481{
482} 479}
483 480
484/* 481/*
@@ -493,7 +490,7 @@ void __init native_pagetable_setup_done(pgd_t *base)
493 * If we're booting paravirtualized under a hypervisor, then there are 490 * If we're booting paravirtualized under a hypervisor, then there are
494 * more options: we may already be running PAE, and the pagetable may 491 * more options: we may already be running PAE, and the pagetable may
495 * or may not be based in swapper_pg_dir. In any case, 492 * or may not be based in swapper_pg_dir. In any case,
496 * paravirt_pagetable_setup_start() will set up swapper_pg_dir 493 * paravirt_pagetable_init() will set up swapper_pg_dir
497 * appropriately for the rest of the initialization to work. 494 * appropriately for the rest of the initialization to work.
498 * 495 *
499 * In general, pagetable_init() assumes that the pagetable may already 496 * In general, pagetable_init() assumes that the pagetable may already
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 613cd83e8c0c..0777f042e400 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -98,6 +98,8 @@ static void flush_tlb_func(void *info)
98{ 98{
99 struct flush_tlb_info *f = info; 99 struct flush_tlb_info *f = info;
100 100
101 inc_irq_stat(irq_tlb_count);
102
101 if (f->flush_mm != this_cpu_read(cpu_tlbstate.active_mm)) 103 if (f->flush_mm != this_cpu_read(cpu_tlbstate.active_mm))
102 return; 104 return;
103 105
@@ -320,7 +322,7 @@ static ssize_t tlbflush_write_file(struct file *file,
320 if (kstrtos8(buf, 0, &shift)) 322 if (kstrtos8(buf, 0, &shift))
321 return -EINVAL; 323 return -EINVAL;
322 324
323 if (shift > 64) 325 if (shift < -1 || shift >= BITS_PER_LONG)
324 return -EINVAL; 326 return -EINVAL;
325 327
326 tlb_flushall_shift = shift; 328 tlb_flushall_shift = shift;
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 937bcece7006..704b9ec043d7 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -585,7 +585,7 @@ static int __init pci_parse_mcfg(struct acpi_table_header *header)
585 while (i >= sizeof(struct acpi_mcfg_allocation)) { 585 while (i >= sizeof(struct acpi_mcfg_allocation)) {
586 entries++; 586 entries++;
587 i -= sizeof(struct acpi_mcfg_allocation); 587 i -= sizeof(struct acpi_mcfg_allocation);
588 }; 588 }
589 if (entries == 0) { 589 if (entries == 0) {
590 pr_err(PREFIX "MMCONFIG has no entries\n"); 590 pr_err(PREFIX "MMCONFIG has no entries\n");
591 return -ENODEV; 591 return -ENODEV;
diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile
index 73b8be0f3675..6db1cc4c7534 100644
--- a/arch/x86/platform/efi/Makefile
+++ b/arch/x86/platform/efi/Makefile
@@ -1 +1,2 @@
1obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o 1obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o
2obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o
diff --git a/arch/x86/platform/efi/efi-bgrt.c b/arch/x86/platform/efi/efi-bgrt.c
new file mode 100644
index 000000000000..f6a0c1b8e518
--- /dev/null
+++ b/arch/x86/platform/efi/efi-bgrt.c
@@ -0,0 +1,76 @@
1/*
2 * Copyright 2012 Intel Corporation
3 * Author: Josh Triplett <josh@joshtriplett.org>
4 *
5 * Based on the bgrt driver:
6 * Copyright 2012 Red Hat, Inc <mjg@redhat.com>
7 * Author: Matthew Garrett
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#include <linux/kernel.h>
14#include <linux/acpi.h>
15#include <linux/efi.h>
16#include <linux/efi-bgrt.h>
17
18struct acpi_table_bgrt *bgrt_tab;
19void *bgrt_image;
20size_t bgrt_image_size;
21
22struct bmp_header {
23 u16 id;
24 u32 size;
25} __packed;
26
27void efi_bgrt_init(void)
28{
29 acpi_status status;
30 void __iomem *image;
31 bool ioremapped = false;
32 struct bmp_header bmp_header;
33
34 if (acpi_disabled)
35 return;
36
37 status = acpi_get_table("BGRT", 0,
38 (struct acpi_table_header **)&bgrt_tab);
39 if (ACPI_FAILURE(status))
40 return;
41
42 if (bgrt_tab->version != 1)
43 return;
44 if (bgrt_tab->image_type != 0 || !bgrt_tab->image_address)
45 return;
46
47 image = efi_lookup_mapped_addr(bgrt_tab->image_address);
48 if (!image) {
49 image = ioremap(bgrt_tab->image_address, sizeof(bmp_header));
50 ioremapped = true;
51 if (!image)
52 return;
53 }
54
55 memcpy_fromio(&bmp_header, image, sizeof(bmp_header));
56 if (ioremapped)
57 iounmap(image);
58 bgrt_image_size = bmp_header.size;
59
60 bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL);
61 if (!bgrt_image)
62 return;
63
64 if (ioremapped) {
65 image = ioremap(bgrt_tab->image_address, bmp_header.size);
66 if (!image) {
67 kfree(bgrt_image);
68 bgrt_image = NULL;
69 return;
70 }
71 }
72
73 memcpy_fromio(bgrt_image, image, bgrt_image_size);
74 if (ioremapped)
75 iounmap(image);
76}
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 92660edaa1e7..aded2a91162a 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -31,6 +31,7 @@
31#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/init.h> 32#include <linux/init.h>
33#include <linux/efi.h> 33#include <linux/efi.h>
34#include <linux/efi-bgrt.h>
34#include <linux/export.h> 35#include <linux/export.h>
35#include <linux/bootmem.h> 36#include <linux/bootmem.h>
36#include <linux/memblock.h> 37#include <linux/memblock.h>
@@ -419,10 +420,21 @@ void __init efi_reserve_boot_services(void)
419 } 420 }
420} 421}
421 422
422static void __init efi_free_boot_services(void) 423static void __init efi_unmap_memmap(void)
424{
425 if (memmap.map) {
426 early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size);
427 memmap.map = NULL;
428 }
429}
430
431void __init efi_free_boot_services(void)
423{ 432{
424 void *p; 433 void *p;
425 434
435 if (!efi_native)
436 return;
437
426 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { 438 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
427 efi_memory_desc_t *md = p; 439 efi_memory_desc_t *md = p;
428 unsigned long long start = md->phys_addr; 440 unsigned long long start = md->phys_addr;
@@ -438,6 +450,8 @@ static void __init efi_free_boot_services(void)
438 450
439 free_bootmem_late(start, size); 451 free_bootmem_late(start, size);
440 } 452 }
453
454 efi_unmap_memmap();
441} 455}
442 456
443static int __init efi_systab_init(void *phys) 457static int __init efi_systab_init(void *phys)
@@ -732,6 +746,11 @@ void __init efi_init(void)
732#endif 746#endif
733} 747}
734 748
749void __init efi_late_init(void)
750{
751 efi_bgrt_init();
752}
753
735void __init efi_set_executable(efi_memory_desc_t *md, bool executable) 754void __init efi_set_executable(efi_memory_desc_t *md, bool executable)
736{ 755{
737 u64 addr, npages; 756 u64 addr, npages;
@@ -764,6 +783,34 @@ static void __init runtime_code_page_mkexec(void)
764} 783}
765 784
766/* 785/*
786 * We can't ioremap data in EFI boot services RAM, because we've already mapped
787 * it as RAM. So, look it up in the existing EFI memory map instead. Only
788 * callable after efi_enter_virtual_mode and before efi_free_boot_services.
789 */
790void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
791{
792 void *p;
793 if (WARN_ON(!memmap.map))
794 return NULL;
795 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
796 efi_memory_desc_t *md = p;
797 u64 size = md->num_pages << EFI_PAGE_SHIFT;
798 u64 end = md->phys_addr + size;
799 if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
800 md->type != EFI_BOOT_SERVICES_CODE &&
801 md->type != EFI_BOOT_SERVICES_DATA)
802 continue;
803 if (!md->virt_addr)
804 continue;
805 if (phys_addr >= md->phys_addr && phys_addr < end) {
806 phys_addr += md->virt_addr - md->phys_addr;
807 return (__force void __iomem *)(unsigned long)phys_addr;
808 }
809 }
810 return NULL;
811}
812
813/*
767 * This function will switch the EFI runtime services to virtual mode. 814 * This function will switch the EFI runtime services to virtual mode.
768 * Essentially, look through the EFI memmap and map every region that 815 * Essentially, look through the EFI memmap and map every region that
769 * has the runtime attribute bit set in its memory descriptor and update 816 * has the runtime attribute bit set in its memory descriptor and update
@@ -787,8 +834,10 @@ void __init efi_enter_virtual_mode(void)
787 * non-native EFI 834 * non-native EFI
788 */ 835 */
789 836
790 if (!efi_native) 837 if (!efi_native) {
791 goto out; 838 efi_unmap_memmap();
839 return;
840 }
792 841
793 /* Merge contiguous regions of the same type and attribute */ 842 /* Merge contiguous regions of the same type and attribute */
794 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { 843 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
@@ -878,18 +927,12 @@ void __init efi_enter_virtual_mode(void)
878 } 927 }
879 928
880 /* 929 /*
881 * Thankfully, it does seem that no runtime services other than
882 * SetVirtualAddressMap() will touch boot services code, so we can
883 * get rid of it all at this point
884 */
885 efi_free_boot_services();
886
887 /*
888 * Now that EFI is in virtual mode, update the function 930 * Now that EFI is in virtual mode, update the function
889 * pointers in the runtime service table to the new virtual addresses. 931 * pointers in the runtime service table to the new virtual addresses.
890 * 932 *
891 * Call EFI services through wrapper functions. 933 * Call EFI services through wrapper functions.
892 */ 934 */
935 efi.runtime_version = efi_systab.fw_revision;
893 efi.get_time = virt_efi_get_time; 936 efi.get_time = virt_efi_get_time;
894 efi.set_time = virt_efi_set_time; 937 efi.set_time = virt_efi_set_time;
895 efi.get_wakeup_time = virt_efi_get_wakeup_time; 938 efi.get_wakeup_time = virt_efi_get_wakeup_time;
@@ -906,9 +949,6 @@ void __init efi_enter_virtual_mode(void)
906 if (__supported_pte_mask & _PAGE_NX) 949 if (__supported_pte_mask & _PAGE_NX)
907 runtime_code_page_mkexec(); 950 runtime_code_page_mkexec();
908 951
909out:
910 early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size);
911 memmap.map = NULL;
912 kfree(new_memmap); 952 kfree(new_memmap);
913} 953}
914 954
diff --git a/arch/x86/um/Kconfig b/arch/x86/um/Kconfig
index 9926e11a772d..aeaff8bef2f1 100644
--- a/arch/x86/um/Kconfig
+++ b/arch/x86/um/Kconfig
@@ -21,6 +21,7 @@ config 64BIT
21config X86_32 21config X86_32
22 def_bool !64BIT 22 def_bool !64BIT
23 select HAVE_AOUT 23 select HAVE_AOUT
24 select ARCH_WANT_IPC_PARSE_VERSION
24 25
25config X86_64 26config X86_64
26 def_bool 64BIT 27 def_bool 64BIT
diff --git a/arch/x86/um/shared/sysdep/kernel-offsets.h b/arch/x86/um/shared/sysdep/kernel-offsets.h
index 5868526b5eef..46a9df99f3c5 100644
--- a/arch/x86/um/shared/sysdep/kernel-offsets.h
+++ b/arch/x86/um/shared/sysdep/kernel-offsets.h
@@ -7,9 +7,6 @@
7#define DEFINE(sym, val) \ 7#define DEFINE(sym, val) \
8 asm volatile("\n->" #sym " %0 " #val : : "i" (val)) 8 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
9 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->" : : ) 10#define BLANK() asm volatile("\n->" : : )
14 11
15#define OFFSET(sym, str, mem) \ 12#define OFFSET(sym, str, mem) \
diff --git a/arch/x86/um/shared/sysdep/syscalls.h b/arch/x86/um/shared/sysdep/syscalls.h
index bd9a89b67e41..ca255a805ed9 100644
--- a/arch/x86/um/shared/sysdep/syscalls.h
+++ b/arch/x86/um/shared/sysdep/syscalls.h
@@ -1,3 +1,5 @@
1extern long sys_clone(unsigned long clone_flags, unsigned long newsp,
2 void __user *parent_tid, void __user *child_tid);
1#ifdef __i386__ 3#ifdef __i386__
2#include "syscalls_32.h" 4#include "syscalls_32.h"
3#else 5#else
diff --git a/arch/x86/um/signal.c b/arch/x86/um/signal.c
index a508cea13503..ba7363ecf896 100644
--- a/arch/x86/um/signal.c
+++ b/arch/x86/um/signal.c
@@ -416,9 +416,6 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
416 PT_REGS_AX(regs) = (unsigned long) sig; 416 PT_REGS_AX(regs) = (unsigned long) sig;
417 PT_REGS_DX(regs) = (unsigned long) 0; 417 PT_REGS_DX(regs) = (unsigned long) 0;
418 PT_REGS_CX(regs) = (unsigned long) 0; 418 PT_REGS_CX(regs) = (unsigned long) 0;
419
420 if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
421 ptrace_notify(SIGTRAP);
422 return 0; 419 return 0;
423} 420}
424 421
@@ -466,9 +463,6 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
466 PT_REGS_AX(regs) = (unsigned long) sig; 463 PT_REGS_AX(regs) = (unsigned long) sig;
467 PT_REGS_DX(regs) = (unsigned long) &frame->info; 464 PT_REGS_DX(regs) = (unsigned long) &frame->info;
468 PT_REGS_CX(regs) = (unsigned long) &frame->uc; 465 PT_REGS_CX(regs) = (unsigned long) &frame->uc;
469
470 if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
471 ptrace_notify(SIGTRAP);
472 return 0; 466 return 0;
473} 467}
474 468
diff --git a/arch/x86/um/sys_call_table_32.c b/arch/x86/um/sys_call_table_32.c
index 68d1dc91b37b..b5408cecac6c 100644
--- a/arch/x86/um/sys_call_table_32.c
+++ b/arch/x86/um/sys_call_table_32.c
@@ -28,7 +28,7 @@
28#define ptregs_execve sys_execve 28#define ptregs_execve sys_execve
29#define ptregs_iopl sys_iopl 29#define ptregs_iopl sys_iopl
30#define ptregs_vm86old sys_vm86old 30#define ptregs_vm86old sys_vm86old
31#define ptregs_clone sys_clone 31#define ptregs_clone i386_clone
32#define ptregs_vm86 sys_vm86 32#define ptregs_vm86 sys_vm86
33#define ptregs_sigaltstack sys_sigaltstack 33#define ptregs_sigaltstack sys_sigaltstack
34#define ptregs_vfork sys_vfork 34#define ptregs_vfork sys_vfork
diff --git a/arch/x86/um/syscalls_32.c b/arch/x86/um/syscalls_32.c
index b853e8600b9d..db444c7218fe 100644
--- a/arch/x86/um/syscalls_32.c
+++ b/arch/x86/um/syscalls_32.c
@@ -3,37 +3,24 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/sched.h" 6#include <linux/syscalls.h>
7#include "linux/shm.h" 7#include <sysdep/syscalls.h>
8#include "linux/ipc.h"
9#include "linux/syscalls.h"
10#include "asm/mman.h"
11#include "asm/uaccess.h"
12#include "asm/unistd.h"
13 8
14/* 9/*
15 * The prototype on i386 is: 10 * The prototype on i386 is:
16 * 11 *
17 * int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr) 12 * int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls
18 * 13 *
19 * and the "newtls" arg. on i386 is read by copy_thread directly from the 14 * and the "newtls" arg. on i386 is read by copy_thread directly from the
20 * register saved on the stack. 15 * register saved on the stack.
21 */ 16 */
22long sys_clone(unsigned long clone_flags, unsigned long newsp, 17long i386_clone(unsigned long clone_flags, unsigned long newsp,
23 int __user *parent_tid, void *newtls, int __user *child_tid) 18 int __user *parent_tid, void *newtls, int __user *child_tid)
24{ 19{
25 long ret; 20 return sys_clone(clone_flags, newsp, parent_tid, child_tid);
26
27 if (!newsp)
28 newsp = UPT_SP(&current->thread.regs.regs);
29
30 current->thread.forking = 1;
31 ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
32 child_tid);
33 current->thread.forking = 0;
34 return ret;
35} 21}
36 22
23
37long sys_sigaction(int sig, const struct old_sigaction __user *act, 24long sys_sigaction(int sig, const struct old_sigaction __user *act,
38 struct old_sigaction __user *oact) 25 struct old_sigaction __user *oact)
39{ 26{
diff --git a/arch/x86/um/syscalls_64.c b/arch/x86/um/syscalls_64.c
index f3d82bb6e15a..adb08eb5c22a 100644
--- a/arch/x86/um/syscalls_64.c
+++ b/arch/x86/um/syscalls_64.c
@@ -5,12 +5,9 @@
5 * Licensed under the GPL 5 * Licensed under the GPL
6 */ 6 */
7 7
8#include "linux/linkage.h" 8#include <linux/sched.h>
9#include "linux/personality.h" 9#include <asm/prctl.h> /* XXX This should get the constants from libc */
10#include "linux/utsname.h" 10#include <os.h>
11#include "asm/prctl.h" /* XXX This should get the constants from libc */
12#include "asm/uaccess.h"
13#include "os.h"
14 11
15long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr) 12long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
16{ 13{
@@ -79,20 +76,6 @@ long sys_arch_prctl(int code, unsigned long addr)
79 return arch_prctl(current, code, (unsigned long __user *) addr); 76 return arch_prctl(current, code, (unsigned long __user *) addr);
80} 77}
81 78
82long sys_clone(unsigned long clone_flags, unsigned long newsp,
83 void __user *parent_tid, void __user *child_tid)
84{
85 long ret;
86
87 if (!newsp)
88 newsp = UPT_SP(&current->thread.regs.regs);
89 current->thread.forking = 1;
90 ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
91 child_tid);
92 current->thread.forking = 0;
93 return ret;
94}
95
96void arch_switch_to(struct task_struct *to) 79void arch_switch_to(struct task_struct *to)
97{ 80{
98 if ((to->thread.arch.fs == 0) || (to->mm == NULL)) 81 if ((to->thread.arch.fs == 0) || (to->mm == NULL))
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 9642d4a38602..1fbe75a95f15 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1452,6 +1452,10 @@ asmlinkage void __init xen_start_kernel(void)
1452 pci_request_acs(); 1452 pci_request_acs();
1453 1453
1454 xen_acpi_sleep_register(); 1454 xen_acpi_sleep_register();
1455
1456 /* Avoid searching for BIOS MP tables */
1457 x86_init.mpparse.find_smp_config = x86_init_noop;
1458 x86_init.mpparse.get_smp_config = x86_init_uint_noop;
1455 } 1459 }
1456#ifdef CONFIG_PCI 1460#ifdef CONFIG_PCI
1457 /* PCI BIOS service won't work from a PV guest. */ 1461 /* PCI BIOS service won't work from a PV guest. */
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 5141d808e751..7a769b7526cb 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1174,8 +1174,13 @@ static void xen_exit_mmap(struct mm_struct *mm)
1174 spin_unlock(&mm->page_table_lock); 1174 spin_unlock(&mm->page_table_lock);
1175} 1175}
1176 1176
1177static void __init xen_pagetable_setup_start(pgd_t *base) 1177static void xen_post_allocator_init(void);
1178
1179static void __init xen_pagetable_init(void)
1178{ 1180{
1181 paging_init();
1182 xen_setup_shared_info();
1183 xen_post_allocator_init();
1179} 1184}
1180 1185
1181static __init void xen_mapping_pagetable_reserve(u64 start, u64 end) 1186static __init void xen_mapping_pagetable_reserve(u64 start, u64 end)
@@ -1192,14 +1197,6 @@ static __init void xen_mapping_pagetable_reserve(u64 start, u64 end)
1192 } 1197 }
1193} 1198}
1194 1199
1195static void xen_post_allocator_init(void);
1196
1197static void __init xen_pagetable_setup_done(pgd_t *base)
1198{
1199 xen_setup_shared_info();
1200 xen_post_allocator_init();
1201}
1202
1203static void xen_write_cr2(unsigned long cr2) 1200static void xen_write_cr2(unsigned long cr2)
1204{ 1201{
1205 this_cpu_read(xen_vcpu)->arch.cr2 = cr2; 1202 this_cpu_read(xen_vcpu)->arch.cr2 = cr2;
@@ -2068,8 +2065,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = {
2068void __init xen_init_mmu_ops(void) 2065void __init xen_init_mmu_ops(void)
2069{ 2066{
2070 x86_init.mapping.pagetable_reserve = xen_mapping_pagetable_reserve; 2067 x86_init.mapping.pagetable_reserve = xen_mapping_pagetable_reserve;
2071 x86_init.paging.pagetable_setup_start = xen_pagetable_setup_start; 2068 x86_init.paging.pagetable_init = xen_pagetable_init;
2072 x86_init.paging.pagetable_setup_done = xen_pagetable_setup_done;
2073 pv_mmu_ops = xen_mmu_ops; 2069 pv_mmu_ops = xen_mmu_ops;
2074 2070
2075 memset(dummy_mapping, 0xff, PAGE_SIZE); 2071 memset(dummy_mapping, 0xff, PAGE_SIZE);
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c
index 76ba0e97e530..72213da605f5 100644
--- a/arch/x86/xen/p2m.c
+++ b/arch/x86/xen/p2m.c
@@ -828,9 +828,6 @@ int m2p_add_override(unsigned long mfn, struct page *page,
828 828
829 xen_mc_issue(PARAVIRT_LAZY_MMU); 829 xen_mc_issue(PARAVIRT_LAZY_MMU);
830 } 830 }
831 /* let's use dev_bus_addr to record the old mfn instead */
832 kmap_op->dev_bus_addr = page->index;
833 page->index = (unsigned long) kmap_op;
834 } 831 }
835 spin_lock_irqsave(&m2p_override_lock, flags); 832 spin_lock_irqsave(&m2p_override_lock, flags);
836 list_add(&page->lru, &m2p_overrides[mfn_hash(mfn)]); 833 list_add(&page->lru, &m2p_overrides[mfn_hash(mfn)]);
@@ -857,7 +854,8 @@ int m2p_add_override(unsigned long mfn, struct page *page,
857 return 0; 854 return 0;
858} 855}
859EXPORT_SYMBOL_GPL(m2p_add_override); 856EXPORT_SYMBOL_GPL(m2p_add_override);
860int m2p_remove_override(struct page *page, bool clear_pte) 857int m2p_remove_override(struct page *page,
858 struct gnttab_map_grant_ref *kmap_op)
861{ 859{
862 unsigned long flags; 860 unsigned long flags;
863 unsigned long mfn; 861 unsigned long mfn;
@@ -887,10 +885,8 @@ int m2p_remove_override(struct page *page, bool clear_pte)
887 WARN_ON(!PagePrivate(page)); 885 WARN_ON(!PagePrivate(page));
888 ClearPagePrivate(page); 886 ClearPagePrivate(page);
889 887
890 if (clear_pte) { 888 set_phys_to_machine(pfn, page->index);
891 struct gnttab_map_grant_ref *map_op = 889 if (kmap_op != NULL) {
892 (struct gnttab_map_grant_ref *) page->index;
893 set_phys_to_machine(pfn, map_op->dev_bus_addr);
894 if (!PageHighMem(page)) { 890 if (!PageHighMem(page)) {
895 struct multicall_space mcs; 891 struct multicall_space mcs;
896 struct gnttab_unmap_grant_ref *unmap_op; 892 struct gnttab_unmap_grant_ref *unmap_op;
@@ -902,13 +898,13 @@ int m2p_remove_override(struct page *page, bool clear_pte)
902 * issued. In this case handle is going to -1 because 898 * issued. In this case handle is going to -1 because
903 * it hasn't been modified yet. 899 * it hasn't been modified yet.
904 */ 900 */
905 if (map_op->handle == -1) 901 if (kmap_op->handle == -1)
906 xen_mc_flush(); 902 xen_mc_flush();
907 /* 903 /*
908 * Now if map_op->handle is negative it means that the 904 * Now if kmap_op->handle is negative it means that the
909 * hypercall actually returned an error. 905 * hypercall actually returned an error.
910 */ 906 */
911 if (map_op->handle == GNTST_general_error) { 907 if (kmap_op->handle == GNTST_general_error) {
912 printk(KERN_WARNING "m2p_remove_override: " 908 printk(KERN_WARNING "m2p_remove_override: "
913 "pfn %lx mfn %lx, failed to modify kernel mappings", 909 "pfn %lx mfn %lx, failed to modify kernel mappings",
914 pfn, mfn); 910 pfn, mfn);
@@ -918,8 +914,8 @@ int m2p_remove_override(struct page *page, bool clear_pte)
918 mcs = xen_mc_entry( 914 mcs = xen_mc_entry(
919 sizeof(struct gnttab_unmap_grant_ref)); 915 sizeof(struct gnttab_unmap_grant_ref));
920 unmap_op = mcs.args; 916 unmap_op = mcs.args;
921 unmap_op->host_addr = map_op->host_addr; 917 unmap_op->host_addr = kmap_op->host_addr;
922 unmap_op->handle = map_op->handle; 918 unmap_op->handle = kmap_op->handle;
923 unmap_op->dev_bus_addr = 0; 919 unmap_op->dev_bus_addr = 0;
924 920
925 MULTI_grant_table_op(mcs.mc, 921 MULTI_grant_table_op(mcs.mc,
@@ -930,10 +926,9 @@ int m2p_remove_override(struct page *page, bool clear_pte)
930 set_pte_at(&init_mm, address, ptep, 926 set_pte_at(&init_mm, address, ptep,
931 pfn_pte(pfn, PAGE_KERNEL)); 927 pfn_pte(pfn, PAGE_KERNEL));
932 __flush_tlb_single(address); 928 __flush_tlb_single(address);
933 map_op->host_addr = 0; 929 kmap_op->host_addr = 0;
934 } 930 }
935 } else 931 }
936 set_phys_to_machine(pfn, page->index);
937 932
938 /* p2m(m2p(mfn)) == FOREIGN_FRAME(mfn): the mfn is already present 933 /* p2m(m2p(mfn)) == FOREIGN_FRAME(mfn): the mfn is already present
939 * somewhere in this domain, even before being added to the 934 * somewhere in this domain, even before being added to the
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index d11ca11d14fc..e2d62d697b5d 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -17,6 +17,7 @@
17#include <asm/e820.h> 17#include <asm/e820.h>
18#include <asm/setup.h> 18#include <asm/setup.h>
19#include <asm/acpi.h> 19#include <asm/acpi.h>
20#include <asm/numa.h>
20#include <asm/xen/hypervisor.h> 21#include <asm/xen/hypervisor.h>
21#include <asm/xen/hypercall.h> 22#include <asm/xen/hypercall.h>
22 23
@@ -544,4 +545,7 @@ void __init xen_arch_setup(void)
544 disable_cpufreq(); 545 disable_cpufreq();
545 WARN_ON(set_pm_idle_to_default()); 546 WARN_ON(set_pm_idle_to_default());
546 fiddle_vdso(); 547 fiddle_vdso();
548#ifdef CONFIG_NUMA
549 numa_off = 1;
550#endif
547} 551}
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index f58dca7a6e52..353c50f18702 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -377,7 +377,8 @@ static int __cpuinit xen_cpu_up(unsigned int cpu, struct task_struct *idle)
377 return rc; 377 return rc;
378 378
379 if (num_online_cpus() == 1) 379 if (num_online_cpus() == 1)
380 alternatives_smp_switch(1); 380 /* Just in case we booted with a single CPU. */
381 alternatives_enable_smp();
381 382
382 rc = xen_smp_intr_init(cpu); 383 rc = xen_smp_intr_init(cpu);
383 if (rc) 384 if (rc)
@@ -424,9 +425,6 @@ static void xen_cpu_die(unsigned int cpu)
424 unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL); 425 unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL);
425 xen_uninit_lock_cpu(cpu); 426 xen_uninit_lock_cpu(cpu);
426 xen_teardown_timer(cpu); 427 xen_teardown_timer(cpu);
427
428 if (num_online_cpus() == 1)
429 alternatives_smp_switch(0);
430} 428}
431 429
432static void __cpuinit xen_play_dead(void) /* used only with HOTPLUG_CPU */ 430static void __cpuinit xen_play_dead(void) /* used only with HOTPLUG_CPU */
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index 2c8d6a3d250a..bc44311aa18c 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -31,6 +31,7 @@
31#include <linux/mqueue.h> 31#include <linux/mqueue.h>
32#include <linux/fs.h> 32#include <linux/fs.h>
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/rcupdate.h>
34 35
35#include <asm/pgtable.h> 36#include <asm/pgtable.h>
36#include <asm/uaccess.h> 37#include <asm/uaccess.h>
@@ -110,8 +111,10 @@ void cpu_idle(void)
110 111
111 /* endless idle loop with no priority at all */ 112 /* endless idle loop with no priority at all */
112 while (1) { 113 while (1) {
114 rcu_idle_enter();
113 while (!need_resched()) 115 while (!need_resched())
114 platform_idle(); 116 platform_idle();
117 rcu_idle_exit();
115 schedule_preempt_disabled(); 118 schedule_preempt_disabled();
116 } 119 }
117} 120}