Merge branch 'p-ti-linux-3.14.y-common' into p-ti-linux-3.14.y-android
authorVishal Mahaveer <vishalm@ti.com>
Thu, 17 Sep 2015 12:10:55 +0000 (07:10 -0500)
committerVishal Mahaveer <vishalm@ti.com>
Thu, 17 Sep 2015 12:10:55 +0000 (07:10 -0500)
* p-ti-linux-3.14.y-common:
  dmaengine: omap-dma: Support for polled memcpy transfers
  hack: increase tty buffer size and complain if tty buffer full
  dma: omap-dma: don't return an error if pause failed due to completion
  dma: omap-dma: don't return an error if pause a non-existent transfers
  serial: 8250: omap: restore registers on shutdown
  serial: 8250: move rx_running out of the bitfield
  dma: omap-dma: add support for pause of non-cyclic transfers
  dma: add __must_check annotation for dmaengine_pause()
  tty: serial: 8250_omap: do not use RX DMA if pause is not supported

Change-Id: Iecf0f9f2f72b340fad72cd2f9552995caad7371b
Signed-off-by: Vishal Mahaveer <vishalm@ti.com>
521 files changed:
Documentation/ABI/testing/sysfs-kernel-wakeup_reasons [new file with mode: 0644]
Documentation/android.txt [new file with mode: 0644]
Documentation/arm64/legacy_instructions.txt [new file with mode: 0644]
Documentation/cgroups/cgroups.txt
Documentation/cpu-freq/governors.txt
Documentation/filesystems/proc.txt
Documentation/networking/ip-sysctl.txt
Documentation/sync.txt [new file with mode: 0644]
Documentation/sysctl/vm.txt
Documentation/trace/ftrace.txt
android/configs/README [new file with mode: 0644]
android/configs/android-base.cfg [new file with mode: 0644]
android/configs/android-recommended.cfg [new file with mode: 0644]
arch/Kconfig
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/Makefile
arch/arm/boot/Makefile
arch/arm/boot/compressed/head.S
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/dra7-evm.dts
arch/arm/boot/dts/dra72-evm.dts
arch/arm/common/Kconfig
arch/arm/common/Makefile
arch/arm/common/fiq_glue.S [new file with mode: 0644]
arch/arm/common/fiq_glue_setup.c [new file with mode: 0644]
arch/arm/crypto/Makefile
arch/arm/crypto/sha1-armv7-neon.S [new file with mode: 0644]
arch/arm/crypto/sha1_glue.c
arch/arm/crypto/sha1_neon_glue.c [new file with mode: 0644]
arch/arm/crypto/sha512-armv7-neon.S [new file with mode: 0644]
arch/arm/crypto/sha512_neon_glue.c [new file with mode: 0644]
arch/arm/include/asm/crypto/sha1.h [new file with mode: 0644]
arch/arm/include/asm/fiq_glue.h [new file with mode: 0644]
arch/arm/include/asm/hardirq.h
arch/arm/include/asm/hardware/cache-l2x0.h
arch/arm/include/asm/hardware/coresight.h
arch/arm/include/asm/irq.h
arch/arm/include/asm/mach/mmc.h [new file with mode: 0644]
arch/arm/include/asm/smp.h
arch/arm/include/asm/syscall.h
arch/arm/include/uapi/asm/unistd.h
arch/arm/kernel/calls.S
arch/arm/kernel/etm.c
arch/arm/kernel/kgdb.c
arch/arm/kernel/process.c
arch/arm/kernel/ptrace.c
arch/arm/kernel/smp.c
arch/arm/mach-omap2/board-generic.c
arch/arm/mm/cache-l2x0.c
arch/arm/mm/cache-v6.S
arch/arm/mm/fault.c
arch/arm/mm/mmu.c
arch/arm64/Kconfig
arch/arm64/Makefile
arch/arm64/boot/.gitignore
arch/arm64/boot/Makefile
arch/arm64/boot/dts/Makefile
arch/arm64/crypto/Kconfig [new file with mode: 0644]
arch/arm64/crypto/Makefile [new file with mode: 0644]
arch/arm64/crypto/aes-ce-ccm-core.S [new file with mode: 0644]
arch/arm64/crypto/aes-ce-ccm-glue.c [new file with mode: 0644]
arch/arm64/crypto/aes-ce-cipher.c [new file with mode: 0644]
arch/arm64/crypto/aes-ce.S [new file with mode: 0644]
arch/arm64/crypto/aes-glue.c [new file with mode: 0644]
arch/arm64/crypto/aes-modes.S [new file with mode: 0644]
arch/arm64/crypto/aes-neon.S [new file with mode: 0644]
arch/arm64/crypto/ghash-ce-core.S [new file with mode: 0644]
arch/arm64/crypto/ghash-ce-glue.c [new file with mode: 0644]
arch/arm64/crypto/sha1-ce-core.S [new file with mode: 0644]
arch/arm64/crypto/sha1-ce-glue.c [new file with mode: 0644]
arch/arm64/crypto/sha2-ce-core.S [new file with mode: 0644]
arch/arm64/crypto/sha2-ce-glue.c [new file with mode: 0644]
arch/arm64/include/asm/Kbuild
arch/arm64/include/asm/barrier.h
arch/arm64/include/asm/compat.h
arch/arm64/include/asm/cpu.h [new file with mode: 0644]
arch/arm64/include/asm/cpufeature.h [new file with mode: 0644]
arch/arm64/include/asm/cputype.h
arch/arm64/include/asm/debug-monitors.h
arch/arm64/include/asm/fpsimd.h
arch/arm64/include/asm/fpsimdmacros.h
arch/arm64/include/asm/hwcap.h
arch/arm64/include/asm/insn.h
arch/arm64/include/asm/neon.h
arch/arm64/include/asm/opcodes.h [new file with mode: 0644]
arch/arm64/include/asm/processor.h
arch/arm64/include/asm/ptrace.h
arch/arm64/include/asm/seccomp.h [new file with mode: 0644]
arch/arm64/include/asm/syscall.h
arch/arm64/include/asm/thread_info.h
arch/arm64/include/asm/traps.h
arch/arm64/include/asm/unistd.h
arch/arm64/include/asm/unistd32.h
arch/arm64/include/uapi/asm/ptrace.h
arch/arm64/kernel/Makefile
arch/arm64/kernel/armv8_deprecated.c [new file with mode: 0644]
arch/arm64/kernel/cpuinfo.c [new file with mode: 0644]
arch/arm64/kernel/entry-fpsimd.S
arch/arm64/kernel/entry.S
arch/arm64/kernel/fpsimd.c
arch/arm64/kernel/hw_breakpoint.c
arch/arm64/kernel/insn.c
arch/arm64/kernel/kuser32.S
arch/arm64/kernel/process.c
arch/arm64/kernel/ptrace.c
arch/arm64/kernel/setup.c
arch/arm64/kernel/signal.c
arch/arm64/kernel/signal32.c
arch/arm64/kernel/smp.c
arch/arm64/kernel/sys_compat.c
arch/arm64/kernel/trace-events-emulation.h [new file with mode: 0644]
arch/arm64/kernel/traps.c
arch/arm64/mm/init.c
arch/mips/include/uapi/asm/unistd.h
arch/s390/include/asm/syscall.h
arch/x86/include/asm/idle.h
arch/x86/include/asm/syscall.h
arch/x86/kernel/process.c
arch/x86/syscalls/syscall_32.tbl
arch/x86/syscalls/syscall_64.tbl
block/genhd.c
block/partition-generic.c
crypto/Kconfig
crypto/blkcipher.c
drivers/Kconfig
drivers/Makefile
drivers/base/Kconfig
drivers/base/cpu.c
drivers/base/power/main.c
drivers/base/power/wakeup.c
drivers/base/syscore.c
drivers/char/Kconfig
drivers/char/Makefile
drivers/char/dcc_tty.c [new file with mode: 0644]
drivers/char/mem.c
drivers/cpufreq/Kconfig
drivers/cpufreq/Makefile
drivers/cpufreq/cpufreq_interactive.c [new file with mode: 0644]
drivers/cpufreq/cpufreq_stats.c
drivers/cpuidle/governors/menu.c
drivers/hid/hid-debug.c
drivers/hid/hid-input.c
drivers/hid/hid-multitouch.c
drivers/hid/hid-steelseries.c
drivers/iio/industrialio-event.c
drivers/input/Kconfig
drivers/input/Makefile
drivers/input/evdev.c
drivers/input/keycombo.c [new file with mode: 0644]
drivers/input/keyreset.c [new file with mode: 0644]
drivers/input/misc/Kconfig
drivers/input/misc/Makefile
drivers/input/misc/gpio_axis.c [new file with mode: 0644]
drivers/input/misc/gpio_event.c [new file with mode: 0644]
drivers/input/misc/gpio_input.c [new file with mode: 0644]
drivers/input/misc/gpio_matrix.c [new file with mode: 0644]
drivers/input/misc/gpio_output.c [new file with mode: 0644]
drivers/input/misc/keychord.c [new file with mode: 0644]
drivers/media/platform/ti-vpe/vip.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/uid_cputime.c [new file with mode: 0644]
drivers/misc/uid_stat.c [new file with mode: 0644]
drivers/mmc/card/Kconfig
drivers/mmc/card/block.c
drivers/mmc/core/Kconfig
drivers/mmc/core/core.c
drivers/mmc/core/host.c
drivers/mmc/core/sd.c
drivers/mmc/core/sdio.c
drivers/mmc/core/sdio_bus.c
drivers/mmc/core/sdio_io.c [changed mode: 0644->0755]
drivers/mtd/nand/Kconfig
drivers/net/ppp/Kconfig
drivers/net/ppp/Makefile
drivers/net/ppp/pppolac.c [new file with mode: 0644]
drivers/net/ppp/pppopns.c [new file with mode: 0644]
drivers/net/tun.c
drivers/net/wireless/Kconfig
drivers/of/fdt.c
drivers/power/power_supply_sysfs.c
drivers/staging/android/Kconfig
drivers/staging/android/Makefile
drivers/staging/android/TODO [deleted file]
drivers/staging/android/alarm-dev.c [deleted file]
drivers/staging/android/android_alarm.h [deleted file]
drivers/staging/android/ashmem.c
drivers/staging/android/ashmem.h
drivers/staging/android/binder.c
drivers/staging/android/binder.h
drivers/staging/android/binder_trace.h
drivers/staging/android/fiq_debugger/Kconfig [new file with mode: 0644]
drivers/staging/android/fiq_debugger/Makefile [new file with mode: 0644]
drivers/staging/android/fiq_debugger/fiq_debugger.c [new file with mode: 0644]
drivers/staging/android/fiq_debugger/fiq_debugger.h [new file with mode: 0644]
drivers/staging/android/fiq_debugger/fiq_debugger_arm.c [new file with mode: 0644]
drivers/staging/android/fiq_debugger/fiq_debugger_arm64.c [new file with mode: 0644]
drivers/staging/android/fiq_debugger/fiq_debugger_priv.h [new file with mode: 0644]
drivers/staging/android/fiq_debugger/fiq_debugger_ringbuf.h [new file with mode: 0644]
drivers/staging/android/fiq_debugger/fiq_watchdog.c [new file with mode: 0644]
drivers/staging/android/fiq_debugger/fiq_watchdog.h [new file with mode: 0644]
drivers/staging/android/ion/Kconfig
drivers/staging/android/ion/ion.c
drivers/staging/android/ion/ion_heap.c
drivers/staging/android/ion/ion_page_pool.c
drivers/staging/android/ion/ion_priv.h
drivers/staging/android/ion/ion_system_heap.c
drivers/staging/android/logger.c [deleted file]
drivers/staging/android/logger.h [deleted file]
drivers/staging/android/lowmemorykiller.c
drivers/staging/android/sw_sync.h
drivers/staging/android/sync.h
drivers/staging/android/uapi/ashmem.h [new file with mode: 0644]
drivers/staging/android/uapi/binder.h [new file with mode: 0644]
drivers/staging/android/uapi/sw_sync.h [new file with mode: 0644]
drivers/staging/android/uapi/sync.h [new file with mode: 0644]
drivers/switch/Kconfig [new file with mode: 0644]
drivers/switch/Makefile [new file with mode: 0644]
drivers/switch/switch_class.c [new file with mode: 0644]
drivers/switch/switch_gpio.c [new file with mode: 0644]
drivers/tty/serial/serial_core.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/Makefile
drivers/usb/gadget/composite.c
drivers/usb/gadget/configfs.c
drivers/usb/gadget/function/Makefile
drivers/usb/gadget/function/f_accessory.c [new file with mode: 0644]
drivers/usb/gadget/function/f_audio_source.c [new file with mode: 0644]
drivers/usb/gadget/function/f_fs.c
drivers/usb/gadget/function/f_mtp.c [new file with mode: 0644]
drivers/usb/gadget/function/f_mtp.h [new file with mode: 0644]
drivers/usb/gadget/function/f_ptp.c [new file with mode: 0644]
drivers/usb/gadget/function/f_rndis.c
drivers/usb/gadget/function/rndis.c
drivers/usb/gadget/function/rndis.h
drivers/usb/gadget/function/u_ether.c
drivers/usb/gadget/function/u_ether.h
drivers/usb/gadget/function/u_serial.c
drivers/usb/gadget/functions.c
drivers/usb/gadget/legacy/Kconfig
drivers/usb/gadget/legacy/Makefile
drivers/usb/gadget/legacy/android.c [new file with mode: 0644]
drivers/usb/gadget/udc/udc-core.c
drivers/usb/phy/Kconfig
drivers/usb/phy/Makefile
drivers/usb/phy/otg-wakelock.c [new file with mode: 0644]
drivers/video/Makefile
drivers/video/adf/Kconfig [new file with mode: 0644]
drivers/video/adf/Makefile [new file with mode: 0644]
drivers/video/adf/adf.c [new file with mode: 0644]
drivers/video/adf/adf.h [new file with mode: 0644]
drivers/video/adf/adf_client.c [new file with mode: 0644]
drivers/video/adf/adf_fbdev.c [new file with mode: 0644]
drivers/video/adf/adf_fops.c [new file with mode: 0644]
drivers/video/adf/adf_fops.h [new file with mode: 0644]
drivers/video/adf/adf_fops32.c [new file with mode: 0644]
drivers/video/adf/adf_fops32.h [new file with mode: 0644]
drivers/video/adf/adf_format.c [new file with mode: 0644]
drivers/video/adf/adf_memblock.c [new file with mode: 0644]
drivers/video/adf/adf_sysfs.c [new file with mode: 0644]
drivers/video/adf/adf_sysfs.h [new file with mode: 0644]
drivers/video/adf/adf_trace.h [new file with mode: 0644]
drivers/video/fbdev/omap2/dss/Kconfig
drivers/video/fbdev/omap2/dss/hdmi.h
drivers/video/fbdev/omap2/dss/hdmi4.c
drivers/video/fbdev/omap2/dss/hdmi5.c
drivers/w1/masters/ds2482.c
fs/compat_binfmt_elf.c
fs/eventpoll.c
fs/exec.c
fs/ext4/ext4.h
fs/ext4/ioctl.c
fs/ext4/mballoc.c
fs/ext4/super.c
fs/fs-writeback.c
fs/fuse/dev.c
fs/proc/base.c
fs/proc/task_mmu.c
fs/pstore/Kconfig
fs/pstore/Makefile
fs/pstore/inode.c
fs/pstore/internal.h
fs/pstore/platform.c
fs/pstore/pmsg.c [new file with mode: 0644]
fs/pstore/ram.c
fs/seq_file.c
fs/super.c
fs/timerfd.c
include/asm-generic/seccomp.h [new file with mode: 0644]
include/asm-generic/syscall.h
include/crypto/algapi.h
include/linux/Kbuild [new file with mode: 0644]
include/linux/amba/mmci.h
include/linux/android_aid.h [new file with mode: 0644]
include/linux/cgroup.h
include/linux/cpu.h
include/linux/cpufeature.h [new file with mode: 0644]
include/linux/cpufreq.h
include/linux/gpio_event.h [new file with mode: 0644]
include/linux/hid.h
include/linux/if_pppolac.h [new file with mode: 0644]
include/linux/if_pppopns.h [new file with mode: 0644]
include/linux/if_pppox.h
include/linux/initramfs.h [new file with mode: 0644]
include/linux/ipv6.h
include/linux/kernel.h
include/linux/keychord.h [new file with mode: 0644]
include/linux/keycombo.h [new file with mode: 0644]
include/linux/keyreset.h [new file with mode: 0644]
include/linux/lsm_audit.h
include/linux/mm.h
include/linux/mm_types.h
include/linux/mmc/host.h
include/linux/mmc/pm.h
include/linux/mmc/sdio_func.h [changed mode: 0644->0755]
include/linux/mod_devicetable.h
include/linux/netfilter/xt_qtaguid.h [new file with mode: 0644]
include/linux/netfilter/xt_quota2.h [new file with mode: 0644]
include/linux/nmi.h
include/linux/of.h
include/linux/of_fdt.h
include/linux/platform_data/ds2482.h [new file with mode: 0644]
include/linux/power_supply.h
include/linux/pstore.h
include/linux/pstore_ram.h
include/linux/sched.h
include/linux/seccomp.h
include/linux/security.h
include/linux/serial_core.h
include/linux/suspend.h
include/linux/switch.h [new file with mode: 0644]
include/linux/syscalls.h
include/linux/uid_stat.h [new file with mode: 0644]
include/linux/usb/composite.h
include/linux/usb/f_accessory.h [new file with mode: 0644]
include/linux/usb/f_mtp.h [new file with mode: 0644]
include/linux/wakelock.h [new file with mode: 0644]
include/linux/wakeup_reason.h [new file with mode: 0644]
include/linux/wifi_tiwlan.h [new file with mode: 0644]
include/linux/wlan_plat.h [new file with mode: 0644]
include/net/activity_stats.h [new file with mode: 0644]
include/net/addrconf.h
include/net/bluetooth/hci.h
include/net/bluetooth/hci_core.h
include/net/fib_rules.h
include/net/flow.h
include/net/inet_sock.h
include/net/ip.h
include/net/ip6_route.h
include/net/ipv6.h
include/net/netfilter/ipv4/nf_reject.h
include/net/netfilter/ipv6/nf_reject.h
include/net/netns/ipv4.h
include/net/netns/ipv6.h
include/net/route.h
include/net/tcp.h
include/trace/events/cpufreq_interactive.h [new file with mode: 0644]
include/trace/events/gpu.h [new file with mode: 0644]
include/trace/events/mmc.h [new file with mode: 0644]
include/trace/events/power.h
include/uapi/asm-generic/unistd.h
include/uapi/linux/audit.h
include/uapi/linux/fib_rules.h
include/uapi/linux/fs.h
include/uapi/linux/if_pppolac.h [new file with mode: 0644]
include/uapi/linux/if_pppopns.h [new file with mode: 0644]
include/uapi/linux/if_pppox.h
include/uapi/linux/input.h
include/uapi/linux/ipv6.h
include/uapi/linux/keychord.h [new file with mode: 0644]
include/uapi/linux/netfilter/xt_IDLETIMER.h
include/uapi/linux/netfilter/xt_socket.h
include/uapi/linux/prctl.h
include/uapi/linux/rtnetlink.h
include/uapi/linux/seccomp.h
include/uapi/linux/sockios.h
include/uapi/linux/usb/f_accessory.h [new file with mode: 0644]
include/uapi/linux/usb/f_mtp.h [new file with mode: 0644]
include/uapi/video/adf.h [new file with mode: 0644]
include/video/adf.h [new file with mode: 0644]
include/video/adf_client.h [new file with mode: 0644]
include/video/adf_fbdev.h [new file with mode: 0644]
include/video/adf_format.h [new file with mode: 0644]
include/video/adf_memblock.h [new file with mode: 0644]
init/Makefile
init/initramfs.c
init/noinitramfs.c
kernel/cgroup.c
kernel/cpu.c
kernel/debug/debug_core.c
kernel/debug/kdb/kdb_io.c
kernel/fork.c
kernel/futex.c
kernel/irq/pm.c
kernel/panic.c
kernel/power/Kconfig
kernel/power/Makefile
kernel/power/process.c
kernel/power/suspend.c
kernel/power/suspend_time.c [new file with mode: 0644]
kernel/power/wakelock.c
kernel/power/wakeup_reason.c [new file with mode: 0644]
kernel/printk/printk.c
kernel/sched/core.c
kernel/sched/cputime.c
kernel/seccomp.c
kernel/sys.c
kernel/sys_ni.c
kernel/sysctl.c
kernel/trace/Kconfig
kernel/trace/Makefile
kernel/trace/gpu-traces.c [new file with mode: 0644]
kernel/trace/trace.c
kernel/trace/trace.h
kernel/trace/trace_functions_graph.c
kernel/trace/trace_output.c
kernel/watchdog.c
lib/Kconfig.debug
mm/madvise.c
mm/memcontrol.c
mm/mempolicy.c
mm/mlock.c
mm/mmap.c
mm/mprotect.c
mm/page_alloc.c
mm/shmem.c
mm/util.c
mm/vmscan.c
net/Kconfig
net/Makefile
net/activity_stats.c [new file with mode: 0644]
net/bluetooth/af_bluetooth.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_event.c
net/bluetooth/rfcomm/core.c
net/bridge/br_device.c
net/core/fib_rules.c
net/ipv4/Makefile
net/ipv4/af_inet.c
net/ipv4/devinet.c
net/ipv4/fib_frontend.c
net/ipv4/icmp.c
net/ipv4/inet_connection_sock.c
net/ipv4/ip_output.c
net/ipv4/netfilter/Kconfig
net/ipv4/ping.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv4/syncookies.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/sysfs_net_ipv4.c [new file with mode: 0644]
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/udp.c
net/ipv6/addrconf.c
net/ipv6/af_inet6.c
net/ipv6/ah6.c
net/ipv6/datagram.c
net/ipv6/esp6.c
net/ipv6/exthdrs_core.c
net/ipv6/icmp.c
net/ipv6/inet6_connection_sock.c
net/ipv6/ipcomp6.c
net/ipv6/netfilter/Kconfig
net/ipv6/ping.c
net/ipv6/raw.c
net/ipv6/route.c
net/ipv6/syncookies.c
net/ipv6/sysctl_net_ipv6.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/netfilter/Kconfig
net/netfilter/Makefile
net/netfilter/xt_IDLETIMER.c
net/netfilter/xt_qtaguid.c [new file with mode: 0644]
net/netfilter/xt_qtaguid_internal.h [new file with mode: 0644]
net/netfilter/xt_qtaguid_print.c [new file with mode: 0644]
net/netfilter/xt_qtaguid_print.h [new file with mode: 0644]
net/netfilter/xt_quota2.c [new file with mode: 0644]
net/netfilter/xt_socket.c
net/rfkill/Kconfig
net/rfkill/core.c
net/wireless/Kconfig
net/wireless/scan.c
net/wireless/sme.c
scripts/Makefile.lib
scripts/Makefile.modinst
scripts/mod/devicetable-offsets.c
scripts/mod/file2alias.c
security/apparmor/domain.c
security/apparmor/include/apparmor.h
security/apparmor/lib.c
security/capability.c
security/commoncap.c
security/lsm_audit.c
security/security.c
security/selinux/avc.c
security/selinux/hooks.c
security/selinux/include/avc.h
security/selinux/include/classmap.h
security/selinux/include/netif.h
security/selinux/include/netnode.h
security/selinux/include/netport.h
security/selinux/include/objsec.h
security/selinux/include/security.h
security/selinux/netif.c
security/selinux/netnode.c
security/selinux/netport.c
security/selinux/nlmsgtab.c
security/selinux/ss/avtab.c
security/selinux/ss/avtab.h
security/selinux/ss/conditional.c
security/selinux/ss/conditional.h
security/selinux/ss/policydb.c
security/selinux/ss/services.c
security/selinux/ss/services.h
ti_config_fragments/android_config.sh [new file with mode: 0755]
ti_config_fragments/android_omap.cfg [new file with mode: 0644]

diff --git a/Documentation/ABI/testing/sysfs-kernel-wakeup_reasons b/Documentation/ABI/testing/sysfs-kernel-wakeup_reasons
new file mode 100644 (file)
index 0000000..acb19b9
--- /dev/null
@@ -0,0 +1,16 @@
+What:          /sys/kernel/wakeup_reasons/last_resume_reason
+Date:          February 2014
+Contact:       Ruchi Kandoi <kandoiruchi@google.com>
+Description:
+               The /sys/kernel/wakeup_reasons/last_resume_reason is
+               used to report wakeup reasons after system exited suspend.
+
+What:          /sys/kernel/wakeup_reasons/last_suspend_time
+Date:          March 2015
+Contact:       jinqian <jinqian@google.com>
+Description:
+               The /sys/kernel/wakeup_reasons/last_suspend_time is
+               used to report time spent in last suspend cycle. It contains
+               two numbers (in seconds) separated by space. First number is
+               the time spent in suspend and resume processes. Second number
+               is the time spent in sleep state.
\ No newline at end of file
diff --git a/Documentation/android.txt b/Documentation/android.txt
new file mode 100644 (file)
index 0000000..0f40a78
--- /dev/null
@@ -0,0 +1,121 @@
+                               =============
+                               A N D R O I D
+                               =============
+
+Copyright (C) 2009 Google, Inc.
+Written by Mike Chan <mike@android.com>
+
+CONTENTS:
+---------
+
+1. Android
+  1.1 Required enabled config options
+  1.2 Required disabled config options
+  1.3 Recommended enabled config options
+2. Contact
+
+
+1. Android
+==========
+
+Android (www.android.com) is an open source operating system for mobile devices.
+This document describes configurations needed to run the Android framework on
+top of the Linux kernel.
+
+To see a working defconfig look at msm_defconfig or goldfish_defconfig
+which can be found at http://android.git.kernel.org in kernel/common.git
+and kernel/msm.git
+
+
+1.1 Required enabled config options
+-----------------------------------
+After building a standard defconfig, ensure that these options are enabled in
+your .config or defconfig if they are not already. Based off the msm_defconfig.
+You should keep the rest of the default options enabled in the defconfig
+unless you know what you are doing.
+
+ANDROID_PARANOID_NETWORK
+ASHMEM
+CONFIG_FB_MODE_HELPERS
+CONFIG_FONT_8x16
+CONFIG_FONT_8x8
+CONFIG_YAFFS_SHORT_NAMES_IN_RAM
+DAB
+EARLYSUSPEND
+FB
+FB_CFB_COPYAREA
+FB_CFB_FILLRECT
+FB_CFB_IMAGEBLIT
+FB_DEFERRED_IO
+FB_TILEBLITTING
+HIGH_RES_TIMERS
+INOTIFY
+INOTIFY_USER
+INPUT_EVDEV
+INPUT_GPIO
+INPUT_MISC
+LEDS_CLASS
+LEDS_GPIO
+LOCK_KERNEL
+LkOGGER
+LOW_MEMORY_KILLER
+MISC_DEVICES
+NEW_LEDS
+NO_HZ
+POWER_SUPPLY
+PREEMPT
+RAMFS
+RTC_CLASS
+RTC_LIB
+SWITCH
+SWITCH_GPIO
+TMPFS
+UID_STAT
+UID16
+USB_FUNCTION
+USB_FUNCTION_ADB
+USER_WAKELOCK
+VIDEO_OUTPUT_CONTROL
+WAKELOCK
+YAFFS_AUTO_YAFFS2
+YAFFS_FS
+YAFFS_YAFFS1
+YAFFS_YAFFS2
+
+
+1.2 Required disabled config options
+------------------------------------
+CONFIG_YAFFS_DISABLE_LAZY_LOAD
+DNOTIFY
+
+
+1.3 Recommended enabled config options
+------------------------------
+ANDROID_PMEM
+PSTORE_CONSOLE
+PSTORE_RAM
+SCHEDSTATS
+DEBUG_PREEMPT
+DEBUG_MUTEXES
+DEBUG_SPINLOCK_SLEEP
+DEBUG_INFO
+FRAME_POINTER
+CPU_FREQ
+CPU_FREQ_TABLE
+CPU_FREQ_DEFAULT_GOV_ONDEMAND
+CPU_FREQ_GOV_ONDEMAND
+CRC_CCITT
+EMBEDDED
+INPUT_TOUCHSCREEN
+I2C
+I2C_BOARDINFO
+LOG_BUF_SHIFT=17
+SERIAL_CORE
+SERIAL_CORE_CONSOLE
+
+
+2. Contact
+==========
+website: http://android.git.kernel.org
+
+mailing-lists: android-kernel@googlegroups.com
diff --git a/Documentation/arm64/legacy_instructions.txt b/Documentation/arm64/legacy_instructions.txt
new file mode 100644 (file)
index 0000000..01bf3d9
--- /dev/null
@@ -0,0 +1,57 @@
+The arm64 port of the Linux kernel provides infrastructure to support
+emulation of instructions which have been deprecated, or obsoleted in
+the architecture. The infrastructure code uses undefined instruction
+hooks to support emulation. Where available it also allows turning on
+the instruction execution in hardware.
+
+The emulation mode can be controlled by writing to sysctl nodes
+(/proc/sys/abi). The following explains the different execution
+behaviours and the corresponding values of the sysctl nodes -
+
+* Undef
+  Value: 0
+  Generates undefined instruction abort. Default for instructions that
+  have been obsoleted in the architecture, e.g., SWP
+
+* Emulate
+  Value: 1
+  Uses software emulation. To aid migration of software, in this mode
+  usage of emulated instruction is traced as well as rate limited
+  warnings are issued. This is the default for deprecated
+  instructions, .e.g., CP15 barriers
+
+* Hardware Execution
+  Value: 2
+  Although marked as deprecated, some implementations may support the
+  enabling/disabling of hardware support for the execution of these
+  instructions. Using hardware execution generally provides better
+  performance, but at the loss of ability to gather runtime statistics
+  about the use of the deprecated instructions.
+
+The default mode depends on the status of the instruction in the
+architecture. Deprecated instructions should default to emulation
+while obsolete instructions must be undefined by default.
+
+Note: Instruction emulation may not be possible in all cases. See
+individual instruction notes for further information.
+
+Supported legacy instructions
+-----------------------------
+* SWP{B}
+Node: /proc/sys/abi/swp
+Status: Obsolete
+Default: Undef (0)
+
+* CP15 Barriers
+Node: /proc/sys/abi/cp15_barrier
+Status: Deprecated
+Default: Emulate (1)
+
+* SETEND
+Node: /proc/sys/abi/setend
+Status: Deprecated
+Default: Emulate (1)*
+Note: All the cpus on the system must have mixed endian support at EL0
+for this feature to be enabled. If a new CPU - which doesn't support mixed
+endian - is hotplugged in after this feature has been enabled, there could
+be unexpected results in the application.
index 821de56d15802c3e41a18d4aac41dbb64f272832..91bd5e0d34e40bbc4791bc866675fce0f2aa54bb 100644 (file)
@@ -578,6 +578,15 @@ is completely unused; @cgrp->parent is still valid. (Note - can also
 be called for a newly-created cgroup if an error occurs after this
 subsystem's create() method has been called for the new cgroup).
 
+int allow_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
+(cgroup_mutex held by caller)
+
+Called prior to moving a task into a cgroup; if the subsystem
+returns an error, this will abort the attach operation.  Used
+to extend the permission checks - if all subsystems in a cgroup
+return 0, the attach will be allowed to proceed, even if the
+default permission check (root or same user) fails.
+
 int can_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
 (cgroup_mutex held by caller)
 
index 77ec21574fb1873c37dfdd9791c2e82a97198de7..2ed766ec75fc294e464249b40f29923c78891201 100644 (file)
@@ -28,6 +28,7 @@ Contents:
 2.3  Userspace
 2.4  Ondemand
 2.5  Conservative
+2.6  Interactive
 
 3.   The Governor Interface in the CPUfreq Core
 
@@ -218,6 +219,90 @@ a decision on when to decrease the frequency while running in any
 speed. Load for frequency increase is still evaluated every
 sampling rate.
 
+2.6 Interactive
+---------------
+
+The CPUfreq governor "interactive" is designed for latency-sensitive,
+interactive workloads. This governor sets the CPU speed depending on
+usage, similar to "ondemand" and "conservative" governors, but with a
+different set of configurable behaviors.
+
+The tuneable values for this governor are:
+
+target_loads: CPU load values used to adjust speed to influence the
+current CPU load toward that value.  In general, the lower the target
+load, the more often the governor will raise CPU speeds to bring load
+below the target.  The format is a single target load, optionally
+followed by pairs of CPU speeds and CPU loads to target at or above
+those speeds.  Colons can be used between the speeds and associated
+target loads for readability.  For example:
+
+   85 1000000:90 1700000:99
+
+targets CPU load 85% below speed 1GHz, 90% at or above 1GHz, until
+1.7GHz and above, at which load 99% is targeted.  If speeds are
+specified these must appear in ascending order.  Higher target load
+values are typically specified for higher speeds, that is, target load
+values also usually appear in an ascending order. The default is
+target load 90% for all speeds.
+
+min_sample_time: The minimum amount of time to spend at the current
+frequency before ramping down. Default is 80000 uS.
+
+hispeed_freq: An intermediate "hi speed" at which to initially ramp
+when CPU load hits the value specified in go_hispeed_load.  If load
+stays high for the amount of time specified in above_hispeed_delay,
+then speed may be bumped higher.  Default is the maximum speed
+allowed by the policy at governor initialization time.
+
+go_hispeed_load: The CPU load at which to ramp to hispeed_freq.
+Default is 99%.
+
+above_hispeed_delay: When speed is at or above hispeed_freq, wait for
+this long before raising speed in response to continued high load.
+The format is a single delay value, optionally followed by pairs of
+CPU speeds and the delay to use at or above those speeds.  Colons can
+be used between the speeds and associated delays for readability.  For
+example:
+
+   80000 1300000:200000 1500000:40000
+
+uses delay 80000 uS until CPU speed 1.3 GHz, at which speed delay
+200000 uS is used until speed 1.5 GHz, at which speed (and above)
+delay 40000 uS is used.  If speeds are specified these must appear in
+ascending order.  Default is 20000 uS.
+
+timer_rate: Sample rate for reevaluating CPU load when the CPU is not
+idle.  A deferrable timer is used, such that the CPU will not be woken
+from idle to service this timer until something else needs to run.
+(The maximum time to allow deferring this timer when not running at
+minimum speed is configurable via timer_slack.)  Default is 20000 uS.
+
+timer_slack: Maximum additional time to defer handling the governor
+sampling timer beyond timer_rate when running at speeds above the
+minimum.  For platforms that consume additional power at idle when
+CPUs are running at speeds greater than minimum, this places an upper
+bound on how long the timer will be deferred prior to re-evaluating
+load and dropping speed.  For example, if timer_rate is 20000uS and
+timer_slack is 10000uS then timers will be deferred for up to 30msec
+when not at lowest speed.  A value of -1 means defer timers
+indefinitely at all speeds.  Default is 80000 uS.
+
+boost: If non-zero, immediately boost speed of all CPUs to at least
+hispeed_freq until zero is written to this attribute.  If zero, allow
+CPU speeds to drop below hispeed_freq according to load as usual.
+Default is zero.
+
+boostpulse: On each write, immediately boost speed of all CPUs to
+hispeed_freq for at least the period of time specified by
+boostpulse_duration, after which speeds are allowed to drop below
+hispeed_freq according to load as usual.
+
+boostpulse_duration: Length of time to hold CPU speed at hispeed_freq
+on a write to boostpulse, before allowing speed to drop according to
+load as usual.  Default is 80000 uS.
+
+
 3. The Governor Interface in the CPUfreq Core
 =============================================
 
index f00bee144addc5dcda3f7784c3b943824efbafd4..90adc374351dab01ca967053bfd765f8fb923fc2 100644 (file)
@@ -369,6 +369,8 @@ is not associated with a file:
  [stack:1001]             = the stack of the thread with tid 1001
  [vdso]                   = the "virtual dynamic shared object",
                             the kernel system call handler
+ [anon:<name>]            = an anonymous mapping that has been
+                            named by userspace
 
  or if empty, the mapping is anonymous.
 
@@ -419,6 +421,7 @@ KernelPageSize:        4 kB
 MMUPageSize:           4 kB
 Locked:              374 kB
 VmFlags: rd ex mr mw me de
+Name:           name from userspace
 
 the first of these lines shows the same information as is displayed for the
 mapping in /proc/PID/maps.  The remaining lines show the size of the mapping
@@ -470,6 +473,9 @@ Note that there is no guarantee that every flag and associated mnemonic will
 be present in all further kernel releases. Things get changed, the flags may
 be vanished or the reverse -- new added.
 
+The "Name" field will only be present on a mapping that has been named by
+userspace, and will show the name passed in by userspace.
+
 This file is only present if the CONFIG_MMU kernel configuration option is
 enabled.
 
index ab42c95f9985c0172109308c052cfe426a5bed9a..982587b9237395d39246f64764d297c58849bea2 100644 (file)
@@ -56,6 +56,15 @@ ip_forward_use_pmtu - BOOLEAN
        0 - disabled
        1 - enabled
 
+fwmark_reflect - BOOLEAN
+       Controls the fwmark of kernel-generated IPv4 reply packets that are not
+       associated with a socket for example, TCP RSTs or ICMP echo replies).
+       If unset, these packets have a fwmark of zero. If set, they have the
+       fwmark of the packet they are replying to. Similarly affects the fwmark
+       used by internal routing lookups triggered by incoming packets, such as
+       the ones used for Path MTU Discovery.
+       Default: 0
+
 route/max_size - INTEGER
        Maximum number of routes allowed in the kernel.  Increase
        this when using large numbers of interfaces and/or routes.
@@ -505,6 +514,16 @@ tcp_fastopen - INTEGER
 
        See include/net/tcp.h and the code for more details.
 
+tcp_fwmark_accept - BOOLEAN
+       If set, incoming connections to listening sockets that do not have a
+       socket mark will set the mark of the accepting socket to the fwmark of
+       the incoming SYN packet. This will cause all packets on that connection
+       (starting from the first SYNACK) to be sent with that fwmark. The
+       listening socket's mark is unchanged. Listening sockets that already
+       have a fwmark set via setsockopt(SOL_SOCKET, SO_MARK, ...) are
+       unaffected.
+       Default: 0
+
 tcp_syn_retries - INTEGER
        Number of times initial SYNs for an active TCP connection attempt
        will be retransmitted. Should not be higher than 255. Default value
@@ -1181,6 +1200,15 @@ conf/all/forwarding - BOOLEAN
 proxy_ndp - BOOLEAN
        Do proxy ndp.
 
+fwmark_reflect - BOOLEAN
+       Controls the fwmark of kernel-generated IPv6 reply packets that are not
+       associated with a socket for example, TCP RSTs or ICMPv6 echo replies).
+       If unset, these packets have a fwmark of zero. If set, they have the
+       fwmark of the packet they are replying to. Similarly affects the fwmark
+       used by internal routing lookups triggered by incoming packets, such as
+       the ones used for Path MTU Discovery.
+       Default: 0
+
 conf/interface/*:
        Change special settings per interface.
 
@@ -1420,6 +1448,19 @@ suppress_frag_ndisc - INTEGER
        1 - (default) discard fragmented neighbor discovery packets
        0 - allow fragmented neighbor discovery packets
 
+optimistic_dad - BOOLEAN
+       Whether to perform Optimistic Duplicate Address Detection (RFC 4429).
+               0: disabled (default)
+               1: enabled
+
+use_optimistic - BOOLEAN
+       If enabled, do not classify optimistic addresses as deprecated during
+       source address selection.  Preferred addresses will still be chosen
+       before optimistic addresses, subject to other ranking in the source
+       address selection algorithm.
+               0: disabled (default)
+               1: enabled
+
 icmp/*:
 ratelimit - INTEGER
        Limit the maximal rates for sending ICMPv6 packets.
diff --git a/Documentation/sync.txt b/Documentation/sync.txt
new file mode 100644 (file)
index 0000000..a2d05e7
--- /dev/null
@@ -0,0 +1,75 @@
+Motivation:
+
+In complicated DMA pipelines such as graphics (multimedia, camera, gpu, display)
+a consumer of a buffer needs to know when the producer has finished producing
+it.  Likewise the producer needs to know when the consumer is finished with the
+buffer so it can reuse it.  A particular buffer may be consumed by multiple
+consumers which will retain the buffer for different amounts of time.  In
+addition, a consumer may consume multiple buffers atomically.
+The sync framework adds an API which allows synchronization between the
+producers and consumers in a generic way while also allowing platforms which
+have shared hardware synchronization primitives to exploit them.
+
+Goals:
+       * provide a generic API for expressing synchronization dependencies
+       * allow drivers to exploit hardware synchronization between hardware
+         blocks
+       * provide a userspace API that allows a compositor to manage
+         dependencies.
+       * provide rich telemetry data to allow debugging slowdowns and stalls of
+          the graphics pipeline.
+
+Objects:
+       * sync_timeline
+       * sync_pt
+       * sync_fence
+
+sync_timeline:
+
+A sync_timeline is an abstract monotonically increasing counter. In general,
+each driver/hardware block context will have one of these.  They can be backed
+by the appropriate hardware or rely on the generic sw_sync implementation.
+Timelines are only ever created through their specific implementations
+(i.e. sw_sync.)
+
+sync_pt:
+
+A sync_pt is an abstract value which marks a point on a sync_timeline. Sync_pts
+have a single timeline parent.  They have 3 states: active, signaled, and error.
+They start in active state and transition, once, to either signaled (when the
+timeline counter advances beyond the sync_pt’s value) or error state.
+
+sync_fence:
+
+Sync_fences are the primary primitives used by drivers to coordinate
+synchronization of their buffers.  They are a collection of sync_pts which may
+or may not have the same timeline parent.  A sync_pt can only exist in one fence
+and the fence's list of sync_pts is immutable once created.  Fences can be
+waited on synchronously or asynchronously.  Two fences can also be merged to
+create a third fence containing a copy of the two fences’ sync_pts.  Fences are
+backed by file descriptors to allow userspace to coordinate the display pipeline
+dependencies.
+
+Use:
+
+A driver implementing sync support should have a work submission function which:
+     * takes a fence argument specifying when to begin work
+     * asynchronously queues that work to kick off when the fence is signaled
+     * returns a fence to indicate when its work will be done.
+     * signals the returned fence once the work is completed.
+
+Consider an imaginary display driver that has the following API:
+/*
+ * assumes buf is ready to be displayed.
+ * blocks until the buffer is on screen.
+ */
+    void display_buffer(struct dma_buf *buf);
+
+The new API will become:
+/*
+ * will display buf when fence is signaled.
+ * returns immediately with a fence that will signal when buf
+ * is no longer displayed.
+ */
+struct sync_fence* display_buffer(struct dma_buf *buf,
+                                 struct sync_fence *fence);
index b602784b289fb5dd09feee95705fb0526999537b..0c17688632a2bd3f0e57b611c44c246af77ef414 100644 (file)
@@ -29,6 +29,7 @@ Currently, these files are in /proc/sys/vm:
 - dirty_writeback_centisecs
 - drop_caches
 - extfrag_threshold
+- extra_free_kbytes
 - hugepages_treat_as_movable
 - hugetlb_shm_group
 - laptop_mode
@@ -204,6 +205,21 @@ fragmentation index is <= extfrag_threshold. The default value is 500.
 
 ==============================================================
 
+extra_free_kbytes
+
+This parameter tells the VM to keep extra free memory between the threshold
+where background reclaim (kswapd) kicks in, and the threshold where direct
+reclaim (by allocating processes) kicks in.
+
+This is useful for workloads that require low latency memory allocations
+and have a bounded burstiness in memory allocations, for example a
+realtime application that receives and transmits network traffic
+(causing in-kernel memory allocations) with a maximum total message burst
+size of 200MB may need 200MB of extra free memory to avoid direct reclaim
+related latencies.
+
+==============================================================
+
 hugepages_treat_as_movable
 
 This parameter controls whether we can allocate hugepages from ZONE_MOVABLE
index bd365988e8d8d8b94d10188cd26f0b70e42061c9..a0dcdbc112ee479138b3ba71e6acc5ea3ee2bad4 100644 (file)
@@ -2017,6 +2017,35 @@ will produce:
  1)   1.449 us    |             }
 
 
+You can disable the hierarchical function call formatting and instead print a
+flat list of function entry and return events.  This uses the format described
+in the Output Formatting section and respects all the trace options that
+control that formatting.  Hierarchical formatting is the default.
+
+       hierachical: echo nofuncgraph-flat > trace_options
+       flat: echo funcgraph-flat > trace_options
+
+  ie:
+
+  # tracer: function_graph
+  #
+  # entries-in-buffer/entries-written: 68355/68355   #P:2
+  #
+  #                              _-----=> irqs-off
+  #                             / _----=> need-resched
+  #                            | / _---=> hardirq/softirq
+  #                            || / _--=> preempt-depth
+  #                            ||| /     delay
+  #           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
+  #              | |       |   ||||       |         |
+                sh-1806  [001] d...   198.843443: graph_ent: func=_raw_spin_lock
+                sh-1806  [001] d...   198.843445: graph_ent: func=__raw_spin_lock
+                sh-1806  [001] d..1   198.843447: graph_ret: func=__raw_spin_lock
+                sh-1806  [001] d..1   198.843449: graph_ret: func=_raw_spin_lock
+                sh-1806  [001] d..1   198.843451: graph_ent: func=_raw_spin_unlock_irqrestore
+                sh-1806  [001] d...   198.843453: graph_ret: func=_raw_spin_unlock_irqrestore
+
+
 You might find other useful features for this tracer in the
 following "dynamic ftrace" section such as tracing only specific
 functions or tasks.
diff --git a/android/configs/README b/android/configs/README
new file mode 100644 (file)
index 0000000..8798731
--- /dev/null
@@ -0,0 +1,15 @@
+The files in this directory are meant to be used as a base for an Android
+kernel config. All devices should have the options in android-base.cfg enabled.
+While not mandatory, the options in android-recommended.cfg enable advanced
+Android features.
+
+Assuming you already have a minimalist defconfig for your device, a possible
+way to enable these options would be:
+
+     ARCH=<arch> scripts/kconfig/merge_config.sh <path_to>/<device>_defconfig android/configs/android-base.cfg android/configs/android-recommended.cfg
+
+This will generate a .config that can then be used to save a new defconfig or
+compile a new kernel with Android features enabled.
+
+Because there is no tool to consistently generate these config fragments,
+lets keep them alphabetically sorted instead of random.
diff --git a/android/configs/android-base.cfg b/android/configs/android-base.cfg
new file mode 100644 (file)
index 0000000..81ac358
--- /dev/null
@@ -0,0 +1,153 @@
+#  KEEP ALPHABETICALLY SORTED
+# CONFIG_DEVKMEM is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_MODULES is not set
+# CONFIG_OABI_COMPAT is not set
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_ARMV8_DEPRECATED=y
+CONFIG_ASHMEM=y
+CONFIG_AUDIT=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_CP15_BARRIER_EMULATION=y
+CONFIG_DM_CRYPT=y
+CONFIG_DM_VERITY=y
+CONFIG_EMBEDDED=y
+CONFIG_FB=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_INET=y
+CONFIG_INET_ESP=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP6_NF_TARGET_REJECT_SKERR=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_SECURITY=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_TARGET_REJECT_SKERR=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_TPROXY=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_SECMARK=y
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
+CONFIG_NETFILTER_XT_TARGET_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_TRACE=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_CLS_U32=y
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_U32=y
+CONFIG_NET_KEY=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_NAT=y
+CONFIG_NO_HZ=y
+CONFIG_PACKET=y
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PPP=y
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_MPPE=y
+CONFIG_PREEMPT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SETEND_EMULATION=y
+CONFIG_STAGING=y
+CONFIG_SWITCH=y
+CONFIG_SWP_EMULATION=y
+CONFIG_SYNC=y
+CONFIG_SYSVIPC=y
+CONFIG_TUN=y
+CONFIG_UNIX=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_G_ANDROID=y
+CONFIG_USB_OTG_WAKELOCK=y
+CONFIG_XFRM_USER=y
diff --git a/android/configs/android-recommended.cfg b/android/configs/android-recommended.cfg
new file mode 100644 (file)
index 0000000..960b9de
--- /dev/null
@@ -0,0 +1,121 @@
+#  KEEP ALPHABETICALLY SORTED
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_NF_CONNTRACK_SIP is not set
+# CONFIG_PM_WAKELOCKS_GC is not set
+# CONFIG_VT is not set
+CONFIG_ANDROID_TIMED_GPIO=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_COMPACTION=y
+CONFIG_DM_UEVENT=y
+CONFIG_DRAGONRISE_FF=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_FUSE_FS=y
+CONFIG_GREENASIA_FF=y
+CONFIG_HIDRAW=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_ACRUX=y
+CONFIG_HID_ACRUX_FF=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DRAGONRISE=y
+CONFIG_HID_ELECOM=y
+CONFIG_HID_EMS_FF=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_GREENASIA=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_HOLTEK=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_KEYTOUCH=y
+CONFIG_HID_KYE=y
+CONFIG_HID_LCPOWER=y
+CONFIG_HID_LOGITECH=y
+CONFIG_HID_LOGITECH_DJ=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_ORTEK=y
+CONFIG_HID_PANTHERLORD=y
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_PICOLCD=y
+CONFIG_HID_PRIMAX=y
+CONFIG_HID_PRODIKEYS=y
+CONFIG_HID_ROCCAT=y
+CONFIG_HID_SAITEK=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SMARTJOYPLUS=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SPEEDLINK=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_THRUSTMASTER=y
+CONFIG_HID_TIVO=y
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_UCLOGIC=y
+CONFIG_HID_WACOM=y
+CONFIG_HID_WALTOP=y
+CONFIG_HID_WIIMOTE=y
+CONFIG_HID_ZEROPLUS=y
+CONFIG_HID_ZYDACRON=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_GPIO=y
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_INPUT_KEYCHORD=y
+CONFIG_INPUT_KEYRESET=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_TABLET=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_ION=y
+CONFIG_JOYSTICK_XPAD=y
+CONFIG_JOYSTICK_XPAD_FF=y
+CONFIG_JOYSTICK_XPAD_LEDS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KSM=y
+CONFIG_LOGIG940_FF=y
+CONFIG_LOGIRUMBLEPAD2_FF=y
+CONFIG_LOGITECH_FF=y
+CONFIG_MD=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MSDOS_FS=y
+CONFIG_PANIC_TIMEOUT=5
+CONFIG_PANTHERLORD_FF=y
+CONFIG_PERF_EVENTS=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_RUNTIME=y
+CONFIG_PM_WAKELOCKS_LIMIT=0
+CONFIG_POWER_SUPPLY=y
+CONFIG_PSTORE=y
+CONFIG_PSTORE_CONSOLE=y
+CONFIG_PSTORE_RAM=y
+CONFIG_SCHEDSTATS=y
+CONFIG_SMARTJOYPLUS_FF=y
+CONFIG_SND=y
+CONFIG_SOUND=y
+CONFIG_SUSPEND_TIME=y
+CONFIG_TABLET_USB_ACECAD=y
+CONFIG_TABLET_USB_AIPTEK=y
+CONFIG_TABLET_USB_GTCO=y
+CONFIG_TABLET_USB_HANWANG=y
+CONFIG_TABLET_USB_KBTAB=y
+CONFIG_TABLET_USB_WACOM=y
+CONFIG_TIMER_STATS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_UHID=y
+CONFIG_UID_STAT=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_USBNET=y
+CONFIG_VFAT_FS=y
index 80bbb8ccd0d10b319d932d1be08a2d742f957cfa..34e8b9160da7425391b008e64eaadd79fd5a3051 100644 (file)
@@ -325,6 +325,7 @@ config HAVE_ARCH_SECCOMP_FILTER
          - secure_computing is called from a ptrace_event()-safe context
          - secure_computing return value is checked and a return value of -1
            results in the system call being skipped immediately.
+         - seccomp syscall wired up
 
 config SECCOMP_FILTER
        def_bool y
index a1bc1ae7f78ba770c6980a30af51e5479e439db7..bd0279fcc8315ac10f6c0e6035adfc0d22b022ee 100644 (file)
@@ -27,7 +27,7 @@ config ARM
        select HARDIRQS_SW_RESEND
        select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
        select HAVE_ARCH_KGDB
-       select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT)
+       select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_TRACEHOOK
        select HAVE_BPF_JIT
        select HAVE_CONTEXT_TRACKING
@@ -1763,11 +1763,6 @@ config OABI_COMPAT
          in memory differs between the legacy ABI and the new ARM EABI
          (only for non "thumb" binaries). This option adds a tiny
          overhead to all syscalls and produces a slightly larger kernel.
-
-         The seccomp filter system will not be available when this is
-         selected, since there is no way yet to sensibly distinguish
-         between calling conventions during filtering.
-
          If you know you'll be using only pure EABI user space then you
          can say N here. If this option is not selected and you attempt
          to execute a legacy ABI binary then the result will be
@@ -1914,6 +1909,15 @@ config XEN
        help
          Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
 
+config ARM_FLUSH_CONSOLE_ON_RESTART
+       bool "Force flush the console on restart"
+       help
+         If the console is locked while the system is rebooted, the messages
+         in the temporary logbuffer would not have propogated to all the
+         console drivers. This option forces the console lock to be
+         released if it failed to be acquired, which will cause all the
+         pending messages to be flushed.
+
 endmenu
 
 menu "Boot options"
@@ -1944,6 +1948,21 @@ config DEPRECATED_PARAM_STRUCT
          This was deprecated in 2001 and announced to live on for 5 years.
          Some old boot loaders still use this way.
 
+config BUILD_ARM_APPENDED_DTB_IMAGE
+       bool "Build a concatenated zImage/dtb by default"
+       depends on OF
+       help
+         Enabling this option will cause a concatenated zImage and DTB to
+         be built by default (instead of a standalone zImage.)  The image
+         will built in arch/arm/boot/zImage-dtb.<dtb name>
+
+config BUILD_ARM_APPENDED_DTB_IMAGE_NAME
+       string "Default dtb name"
+       depends on BUILD_ARM_APPENDED_DTB_IMAGE
+       help
+         name of the dtb to append when building a concatenated
+         zImage/dtb.
+
 # Compressed boot loader in ROM.  Yes, we really want to ask about
 # TEXT and BSS so we preserve their values in the config files.
 config ZBOOT_ROM_TEXT
index 0531da8e5216e442ee1f9c8878e4fb9d84611581..ef7b03cae2465801ee84ae8b101b5eebf3b1c243 100644 (file)
@@ -1172,6 +1172,14 @@ config EARLY_PRINTK
          kernel low-level debugging functions. Add earlyprintk to your
          kernel parameters to enable this console.
 
+config EARLY_PRINTK_DIRECT
+       bool "Early printk direct"
+       depends on DEBUG_LL
+       help
+         Say Y here if you want to have an early console using the
+         kernel low-level debugging functions and EARLY_PRINTK is
+         not early enough.
+
 config OC_ETM
        bool "On-chip ETM and ETB"
        depends on ARM_AMBA
index 08a9ef58d9c3567f1b78862ed136546416ad241d..1115c76d9d90e1d379be621c7d8fbf0427a59b65 100644 (file)
@@ -277,6 +277,8 @@ libs-y                              := arch/arm/lib/ $(libs-y)
 # Default target when executing plain make
 ifeq ($(CONFIG_XIP_KERNEL),y)
 KBUILD_IMAGE := xipImage
+else ifeq ($(CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE),y)
+KBUILD_IMAGE := zImage-dtb.$(CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE_NAME)
 else
 KBUILD_IMAGE := zImage
 endif
index ec2f8065f955c5c31a69888bf261c58ea56ffb6d..a2e18ef0bdb719681fc12671852c7d0dd6e30bb7 100644 (file)
@@ -14,6 +14,7 @@
 ifneq ($(MACHINE),)
 include $(srctree)/$(MACHINE)/Makefile.boot
 endif
+include $(srctree)/arch/arm/boot/dts/Makefile
 
 # Note: the following conditions must always be true:
 #   ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)
index 8017cde136482a33495c5f52f684d98cd38358cb..a3565154aded4a55e3f01bceb590a47dac369b49 100644 (file)
@@ -733,6 +733,8 @@ __armv7_mmu_cache_on:
                bic     r6, r6, #1 << 31        @ 32-bit translation system
                bic     r6, r6, #3 << 0         @ use only ttbr0
                mcrne   p15, 0, r3, c2, c0, 0   @ load page table pointer
+               mcrne   p15, 0, r0, c8, c7, 0   @ flush I,D TLBs
+               mcr     p15, 0, r0, c7, c5, 4   @ ISB
                mcrne   p15, 0, r1, c3, c0, 0   @ load domain access control
                mcrne   p15, 0, r6, c2, c0, 2   @ load ttb control
 #endif
index 9b245574acdb974b8606105e300b293c775744c8..6abd129b32cd722ecb6b5fa266f07b4d53202de1 100644 (file)
@@ -345,8 +345,15 @@ dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb \
        zynq-zc706.dtb \
        zynq-zed.dtb
 
+DTB_NAMES := $(subst $\",,$(CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE_NAMES))
+ifneq ($(DTB_NAMES),)
+DTB_LIST := $(addsuffix .dtb,$(DTB_NAMES))
+else
+DTB_LIST := $(dtb-y)
+endif
+
 targets += dtbs
-targets += $(dtb-y)
+targets += $(DTB_LIST)
 endif
 
 # Pad DTB by 4KB to allow fdt manipulation in MLO
index f68b4992c3a8c5b8667be32e4051ae1036f348a3..f24b50bea7011af4dd5787dddbd47f20eee8f1a4 100644 (file)
@@ -780,7 +780,7 @@ i2c_p3_exp: &i2c2 {
        #address-cells = <1>;
        #size-cells = <0>;
        wlcore: wlcore@0 {
-               compatible = "ti,wlcore";
+               compatible = "ti,wl1835";
                reg = <2>;
                interrupt-parent = <&gpio5>;
                interrupts = <7 IRQ_TYPE_LEVEL_HIGH>;
@@ -884,7 +884,7 @@ i2c_p3_exp: &i2c2 {
 };
 
 &usb1 {
-       dr_mode = "otg";
+       dr_mode = "peripheral";
 };
 
 &usb2 {
index cf1c8d409608ab1ca726750b10e303bfe0988469..c027e3fcd4e0067d7af62883c39d24d1634aacfa 100644 (file)
@@ -818,7 +818,7 @@ i2c_p3_exp: &i2c5 {
        #address-cells = <1>;
        #size-cells = <0>;
        wlcore: wlcore@0 {
-               compatible = "ti,wlcore";
+               compatible = "ti,wl1835";
                reg = <2>;
                interrupt-parent = <&gpio5>;
                interrupts = <7 IRQ_TYPE_LEVEL_HIGH>;
@@ -1110,7 +1110,7 @@ i2c_p3_exp: &i2c5 {
 };
 
 &usb1 {
-       dr_mode = "otg";
+       dr_mode = "peripheral";
        pinctrl-names = "default";
        pinctrl-0 = <&usb1_pins>;
 };
index c3a4e9ceba34e3a71b1248874f27f888268255fa..f4a38a76db64a90130b2d821e07c90a7b43cabbc 100644 (file)
@@ -20,3 +20,7 @@ config SHARP_SCOOP
 
 config TI_PRIV_EDMA
        bool
+
+config FIQ_GLUE
+       bool
+       select FIQ
index 4bdc41622c36686df868e2134d6453fe60684b5b..f51fd9b5d59026b9ca5ac8e858eaddeb0e2e32ef 100644 (file)
@@ -4,6 +4,7 @@
 
 obj-y                          += firmware.o
 
+obj-$(CONFIG_FIQ_GLUE)         += fiq_glue.o fiq_glue_setup.o
 obj-$(CONFIG_ICST)             += icst.o
 obj-$(CONFIG_SA1111)           += sa1111.o
 obj-$(CONFIG_DMABOUNCE)                += dmabounce.o
diff --git a/arch/arm/common/fiq_glue.S b/arch/arm/common/fiq_glue.S
new file mode 100644 (file)
index 0000000..24b42ce
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+               .text
+
+               .global fiq_glue_end
+
+               /* fiq stack: r0-r15,cpsr,spsr of interrupted mode */
+
+ENTRY(fiq_glue)
+               /* store pc, cpsr from previous mode, reserve space for spsr */
+               mrs     r12, spsr
+               sub     lr, lr, #4
+               subs    r10, #1
+               bne     nested_fiq
+
+               str     r12, [sp, #-8]!
+               str     lr, [sp, #-4]!
+
+               /* store r8-r14 from previous mode */
+               sub     sp, sp, #(7 * 4)
+               stmia   sp, {r8-r14}^
+               nop
+
+               /* store r0-r7 from previous mode */
+               stmfd   sp!, {r0-r7}
+
+               /* setup func(data,regs) arguments */
+               mov     r0, r9
+               mov     r1, sp
+               mov     r3, r8
+
+               mov     r7, sp
+
+               /* Get sp and lr from non-user modes */
+               and     r4, r12, #MODE_MASK
+               cmp     r4, #USR_MODE
+               beq     fiq_from_usr_mode
+
+               mov     r7, sp
+               orr     r4, r4, #(PSR_I_BIT | PSR_F_BIT)
+               msr     cpsr_c, r4
+               str     sp, [r7, #(4 * 13)]
+               str     lr, [r7, #(4 * 14)]
+               mrs     r5, spsr
+               str     r5, [r7, #(4 * 17)]
+
+               cmp     r4, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT)
+               /* use fiq stack if we reenter this mode */
+               subne   sp, r7, #(4 * 3)
+
+fiq_from_usr_mode:
+               msr     cpsr_c, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT)
+               mov     r2, sp
+               sub     sp, r7, #12
+               stmfd   sp!, {r2, ip, lr}
+               /* call func(data,regs) */
+               blx     r3
+               ldmfd   sp, {r2, ip, lr}
+               mov     sp, r2
+
+               /* restore/discard saved state */
+               cmp     r4, #USR_MODE
+               beq     fiq_from_usr_mode_exit
+
+               msr     cpsr_c, r4
+               ldr     sp, [r7, #(4 * 13)]
+               ldr     lr, [r7, #(4 * 14)]
+               msr     spsr_cxsf, r5
+
+fiq_from_usr_mode_exit:
+               msr     cpsr_c, #(FIQ_MODE | PSR_I_BIT | PSR_F_BIT)
+
+               ldmfd   sp!, {r0-r7}
+               ldr     lr, [sp, #(4 * 7)]
+               ldr     r12, [sp, #(4 * 8)]
+               add     sp, sp, #(10 * 4)
+exit_fiq:
+               msr     spsr_cxsf, r12
+               add     r10, #1
+               cmp     r11, #0
+               moveqs  pc, lr
+               bx      r11 /* jump to custom fiq return function */
+
+nested_fiq:
+               orr     r12, r12, #(PSR_F_BIT)
+               b       exit_fiq
+
+fiq_glue_end:
+
+ENTRY(fiq_glue_setup) /* func, data, sp, smc call number */
+               stmfd           sp!, {r4}
+               mrs             r4, cpsr
+               msr             cpsr_c, #(FIQ_MODE | PSR_I_BIT | PSR_F_BIT)
+               movs            r8, r0
+               mov             r9, r1
+               mov             sp, r2
+               mov             r11, r3
+               moveq           r10, #0
+               movne           r10, #1
+               msr             cpsr_c, r4
+               ldmfd           sp!, {r4}
+               bx              lr
+
diff --git a/arch/arm/common/fiq_glue_setup.c b/arch/arm/common/fiq_glue_setup.c
new file mode 100644 (file)
index 0000000..8cb1b61
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/percpu.h>
+#include <linux/slab.h>
+#include <asm/fiq.h>
+#include <asm/fiq_glue.h>
+
+extern unsigned char fiq_glue, fiq_glue_end;
+extern void fiq_glue_setup(void *func, void *data, void *sp,
+                          fiq_return_handler_t fiq_return_handler);
+
+static struct fiq_handler fiq_debbuger_fiq_handler = {
+       .name = "fiq_glue",
+};
+DEFINE_PER_CPU(void *, fiq_stack);
+static struct fiq_glue_handler *current_handler;
+static fiq_return_handler_t fiq_return_handler;
+static DEFINE_MUTEX(fiq_glue_lock);
+
+static void fiq_glue_setup_helper(void *info)
+{
+       struct fiq_glue_handler *handler = info;
+       fiq_glue_setup(handler->fiq, handler,
+               __get_cpu_var(fiq_stack) + THREAD_START_SP,
+               fiq_return_handler);
+}
+
+int fiq_glue_register_handler(struct fiq_glue_handler *handler)
+{
+       int ret;
+       int cpu;
+
+       if (!handler || !handler->fiq)
+               return -EINVAL;
+
+       mutex_lock(&fiq_glue_lock);
+       if (fiq_stack) {
+               ret = -EBUSY;
+               goto err_busy;
+       }
+
+       for_each_possible_cpu(cpu) {
+               void *stack;
+               stack = (void *)__get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER);
+               if (WARN_ON(!stack)) {
+                       ret = -ENOMEM;
+                       goto err_alloc_fiq_stack;
+               }
+               per_cpu(fiq_stack, cpu) = stack;
+       }
+
+       ret = claim_fiq(&fiq_debbuger_fiq_handler);
+       if (WARN_ON(ret))
+               goto err_claim_fiq;
+
+       current_handler = handler;
+       on_each_cpu(fiq_glue_setup_helper, handler, true);
+       set_fiq_handler(&fiq_glue, &fiq_glue_end - &fiq_glue);
+
+       mutex_unlock(&fiq_glue_lock);
+       return 0;
+
+err_claim_fiq:
+err_alloc_fiq_stack:
+       for_each_possible_cpu(cpu) {
+               __free_pages(per_cpu(fiq_stack, cpu), THREAD_SIZE_ORDER);
+               per_cpu(fiq_stack, cpu) = NULL;
+       }
+err_busy:
+       mutex_unlock(&fiq_glue_lock);
+       return ret;
+}
+
+static void fiq_glue_update_return_handler(void (*fiq_return)(void))
+{
+       fiq_return_handler = fiq_return;
+       if (current_handler)
+               on_each_cpu(fiq_glue_setup_helper, current_handler, true);
+}
+
+int fiq_glue_set_return_handler(void (*fiq_return)(void))
+{
+       int ret;
+
+       mutex_lock(&fiq_glue_lock);
+       if (fiq_return_handler) {
+               ret = -EBUSY;
+               goto err_busy;
+       }
+       fiq_glue_update_return_handler(fiq_return);
+       ret = 0;
+err_busy:
+       mutex_unlock(&fiq_glue_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL(fiq_glue_set_return_handler);
+
+int fiq_glue_clear_return_handler(void (*fiq_return)(void))
+{
+       int ret;
+
+       mutex_lock(&fiq_glue_lock);
+       if (WARN_ON(fiq_return_handler != fiq_return)) {
+               ret = -EINVAL;
+               goto err_inval;
+       }
+       fiq_glue_update_return_handler(NULL);
+       ret = 0;
+err_inval:
+       mutex_unlock(&fiq_glue_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL(fiq_glue_clear_return_handler);
+
+/**
+ * fiq_glue_resume - Restore fiqs after suspend or low power idle states
+ *
+ * This must be called before calling local_fiq_enable after returning from a
+ * power state where the fiq mode registers were lost. If a driver provided
+ * a resume hook when it registered the handler it will be called.
+ */
+
+void fiq_glue_resume(void)
+{
+       if (!current_handler)
+               return;
+       fiq_glue_setup(current_handler->fiq, current_handler,
+               __get_cpu_var(fiq_stack) + THREAD_START_SP,
+               fiq_return_handler);
+       if (current_handler->resume)
+               current_handler->resume(current_handler);
+}
+
index 81cda39860c5c7ad90a6710727011ec79296e5d8..b48fa341648d1766a49bf4553e3149836d264c66 100644 (file)
@@ -5,10 +5,14 @@
 obj-$(CONFIG_CRYPTO_AES_ARM) += aes-arm.o
 obj-$(CONFIG_CRYPTO_AES_ARM_BS) += aes-arm-bs.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM) += sha1-arm.o
+obj-$(CONFIG_CRYPTO_SHA1_ARM_NEON) += sha1-arm-neon.o
+obj-$(CONFIG_CRYPTO_SHA512_ARM_NEON) += sha512-arm-neon.o
 
 aes-arm-y      := aes-armv4.o aes_glue.o
 aes-arm-bs-y   := aesbs-core.o aesbs-glue.o
 sha1-arm-y     := sha1-armv4-large.o sha1_glue.o
+sha1-arm-neon-y        := sha1-armv7-neon.o sha1_neon_glue.o
+sha512-arm-neon-y := sha512-armv7-neon.o sha512_neon_glue.o
 
 quiet_cmd_perl = PERL    $@
       cmd_perl = $(PERL) $(<) > $(@)
diff --git a/arch/arm/crypto/sha1-armv7-neon.S b/arch/arm/crypto/sha1-armv7-neon.S
new file mode 100644 (file)
index 0000000..50013c0
--- /dev/null
@@ -0,0 +1,634 @@
+/* sha1-armv7-neon.S - ARM/NEON accelerated SHA-1 transform function
+ *
+ * Copyright © 2013-2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/linkage.h>
+
+
+.syntax unified
+.code   32
+.fpu neon
+
+.text
+
+
+/* Context structure */
+
+#define state_h0 0
+#define state_h1 4
+#define state_h2 8
+#define state_h3 12
+#define state_h4 16
+
+
+/* Constants */
+
+#define K1  0x5A827999
+#define K2  0x6ED9EBA1
+#define K3  0x8F1BBCDC
+#define K4  0xCA62C1D6
+.align 4
+.LK_VEC:
+.LK1:  .long K1, K1, K1, K1
+.LK2:  .long K2, K2, K2, K2
+.LK3:  .long K3, K3, K3, K3
+.LK4:  .long K4, K4, K4, K4
+
+
+/* Register macros */
+
+#define RSTATE r0
+#define RDATA r1
+#define RNBLKS r2
+#define ROLDSTACK r3
+#define RWK lr
+
+#define _a r4
+#define _b r5
+#define _c r6
+#define _d r7
+#define _e r8
+
+#define RT0 r9
+#define RT1 r10
+#define RT2 r11
+#define RT3 r12
+
+#define W0 q0
+#define W1 q1
+#define W2 q2
+#define W3 q3
+#define W4 q4
+#define W5 q5
+#define W6 q6
+#define W7 q7
+
+#define tmp0 q8
+#define tmp1 q9
+#define tmp2 q10
+#define tmp3 q11
+
+#define qK1 q12
+#define qK2 q13
+#define qK3 q14
+#define qK4 q15
+
+
+/* Round function macros. */
+
+#define WK_offs(i) (((i) & 15) * 4)
+
+#define _R_F1(a,b,c,d,e,i,pre1,pre2,pre3,i16,\
+             W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       ldr RT3, [sp, WK_offs(i)]; \
+               pre1(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+       bic RT0, d, b; \
+       add e, e, a, ror #(32 - 5); \
+       and RT1, c, b; \
+               pre2(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+       add RT0, RT0, RT3; \
+       add e, e, RT1; \
+       ror b, #(32 - 30); \
+               pre3(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+       add e, e, RT0;
+
+#define _R_F2(a,b,c,d,e,i,pre1,pre2,pre3,i16,\
+             W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       ldr RT3, [sp, WK_offs(i)]; \
+               pre1(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+       eor RT0, d, b; \
+       add e, e, a, ror #(32 - 5); \
+       eor RT0, RT0, c; \
+               pre2(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+       add e, e, RT3; \
+       ror b, #(32 - 30); \
+               pre3(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+       add e, e, RT0; \
+
+#define _R_F3(a,b,c,d,e,i,pre1,pre2,pre3,i16,\
+             W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       ldr RT3, [sp, WK_offs(i)]; \
+               pre1(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+       eor RT0, b, c; \
+       and RT1, b, c; \
+       add e, e, a, ror #(32 - 5); \
+               pre2(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+       and RT0, RT0, d; \
+       add RT1, RT1, RT3; \
+       add e, e, RT0; \
+       ror b, #(32 - 30); \
+               pre3(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+       add e, e, RT1;
+
+#define _R_F4(a,b,c,d,e,i,pre1,pre2,pre3,i16,\
+             W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       _R_F2(a,b,c,d,e,i,pre1,pre2,pre3,i16,\
+             W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28)
+
+#define _R(a,b,c,d,e,f,i,pre1,pre2,pre3,i16,\
+           W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       _R_##f(a,b,c,d,e,i,pre1,pre2,pre3,i16,\
+              W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28)
+
+#define R(a,b,c,d,e,f,i) \
+       _R_##f(a,b,c,d,e,i,dummy,dummy,dummy,i16,\
+              W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28)
+
+#define dummy(...)
+
+
+/* Input expansion macros. */
+
+/********* Precalc macros for rounds 0-15 *************************************/
+
+#define W_PRECALC_00_15() \
+       add       RWK, sp, #(WK_offs(0));                       \
+       \
+       vld1.32   {tmp0, tmp1}, [RDATA]!;                       \
+       vrev32.8  W0, tmp0;             /* big => little */     \
+       vld1.32   {tmp2, tmp3}, [RDATA]!;                       \
+       vadd.u32  tmp0, W0, curK;                               \
+       vrev32.8  W7, tmp1;             /* big => little */     \
+       vrev32.8  W6, tmp2;             /* big => little */     \
+       vadd.u32  tmp1, W7, curK;                               \
+       vrev32.8  W5, tmp3;             /* big => little */     \
+       vadd.u32  tmp2, W6, curK;                               \
+       vst1.32   {tmp0, tmp1}, [RWK]!;                         \
+       vadd.u32  tmp3, W5, curK;                               \
+       vst1.32   {tmp2, tmp3}, [RWK];                          \
+
+#define WPRECALC_00_15_0(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vld1.32   {tmp0, tmp1}, [RDATA]!;                       \
+
+#define WPRECALC_00_15_1(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       add       RWK, sp, #(WK_offs(0));                       \
+
+#define WPRECALC_00_15_2(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vrev32.8  W0, tmp0;             /* big => little */     \
+
+#define WPRECALC_00_15_3(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vld1.32   {tmp2, tmp3}, [RDATA]!;                       \
+
+#define WPRECALC_00_15_4(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vadd.u32  tmp0, W0, curK;                               \
+
+#define WPRECALC_00_15_5(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vrev32.8  W7, tmp1;             /* big => little */     \
+
+#define WPRECALC_00_15_6(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vrev32.8  W6, tmp2;             /* big => little */     \
+
+#define WPRECALC_00_15_7(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vadd.u32  tmp1, W7, curK;                               \
+
+#define WPRECALC_00_15_8(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vrev32.8  W5, tmp3;             /* big => little */     \
+
+#define WPRECALC_00_15_9(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vadd.u32  tmp2, W6, curK;                               \
+
+#define WPRECALC_00_15_10(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vst1.32   {tmp0, tmp1}, [RWK]!;                         \
+
+#define WPRECALC_00_15_11(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vadd.u32  tmp3, W5, curK;                               \
+
+#define WPRECALC_00_15_12(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vst1.32   {tmp2, tmp3}, [RWK];                          \
+
+
+/********* Precalc macros for rounds 16-31 ************************************/
+
+#define WPRECALC_16_31_0(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       veor      tmp0, tmp0;                   \
+       vext.8    W, W_m16, W_m12, #8;          \
+
+#define WPRECALC_16_31_1(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       add       RWK, sp, #(WK_offs(i));       \
+       vext.8    tmp0, W_m04, tmp0, #4;        \
+
+#define WPRECALC_16_31_2(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       veor      tmp0, tmp0, W_m16;            \
+       veor.32   W, W, W_m08;                  \
+
+#define WPRECALC_16_31_3(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       veor      tmp1, tmp1;                   \
+       veor      W, W, tmp0;                   \
+
+#define WPRECALC_16_31_4(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vshl.u32  tmp0, W, #1;                  \
+
+#define WPRECALC_16_31_5(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vext.8    tmp1, tmp1, W, #(16-12);      \
+       vshr.u32  W, W, #31;                    \
+
+#define WPRECALC_16_31_6(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vorr      tmp0, tmp0, W;                \
+       vshr.u32  W, tmp1, #30;                 \
+
+#define WPRECALC_16_31_7(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vshl.u32  tmp1, tmp1, #2;               \
+
+#define WPRECALC_16_31_8(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       veor      tmp0, tmp0, W;                \
+
+#define WPRECALC_16_31_9(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       veor      W, tmp0, tmp1;                \
+
+#define WPRECALC_16_31_10(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vadd.u32  tmp0, W, curK;                \
+
+#define WPRECALC_16_31_11(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vst1.32   {tmp0}, [RWK];
+
+
+/********* Precalc macros for rounds 32-79 ************************************/
+
+#define WPRECALC_32_79_0(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       veor W, W_m28; \
+
+#define WPRECALC_32_79_1(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vext.8 tmp0, W_m08, W_m04, #8; \
+
+#define WPRECALC_32_79_2(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       veor W, W_m16; \
+
+#define WPRECALC_32_79_3(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       veor W, tmp0; \
+
+#define WPRECALC_32_79_4(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       add RWK, sp, #(WK_offs(i&~3)); \
+
+#define WPRECALC_32_79_5(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vshl.u32 tmp1, W, #2; \
+
+#define WPRECALC_32_79_6(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vshr.u32 tmp0, W, #30; \
+
+#define WPRECALC_32_79_7(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vorr W, tmp0, tmp1; \
+
+#define WPRECALC_32_79_8(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vadd.u32 tmp0, W, curK; \
+
+#define WPRECALC_32_79_9(i,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       vst1.32 {tmp0}, [RWK];
+
+
+/*
+ * Transform nblks*64 bytes (nblks*16 32-bit words) at DATA.
+ *
+ * unsigned int
+ * sha1_transform_neon (void *ctx, const unsigned char *data,
+ *                      unsigned int nblks)
+ */
+.align 3
+ENTRY(sha1_transform_neon)
+  /* input:
+   *   r0: ctx, CTX
+   *   r1: data (64*nblks bytes)
+   *   r2: nblks
+   */
+
+  cmp RNBLKS, #0;
+  beq .Ldo_nothing;
+
+  push {r4-r12, lr};
+  /*vpush {q4-q7};*/
+
+  adr RT3, .LK_VEC;
+
+  mov ROLDSTACK, sp;
+
+  /* Align stack. */
+  sub RT0, sp, #(16*4);
+  and RT0, #(~(16-1));
+  mov sp, RT0;
+
+  vld1.32 {qK1-qK2}, [RT3]!; /* Load K1,K2 */
+
+  /* Get the values of the chaining variables. */
+  ldm RSTATE, {_a-_e};
+
+  vld1.32 {qK3-qK4}, [RT3]; /* Load K3,K4 */
+
+#undef curK
+#define curK qK1
+  /* Precalc 0-15. */
+  W_PRECALC_00_15();
+
+.Loop:
+  /* Transform 0-15 + Precalc 16-31. */
+  _R( _a, _b, _c, _d, _e, F1,  0,
+      WPRECALC_16_31_0, WPRECALC_16_31_1, WPRECALC_16_31_2, 16,
+      W4, W5, W6, W7, W0, _, _, _ );
+  _R( _e, _a, _b, _c, _d, F1,  1,
+      WPRECALC_16_31_3, WPRECALC_16_31_4, WPRECALC_16_31_5, 16,
+      W4, W5, W6, W7, W0, _, _, _ );
+  _R( _d, _e, _a, _b, _c, F1,  2,
+      WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 16,
+      W4, W5, W6, W7, W0, _, _, _ );
+  _R( _c, _d, _e, _a, _b, F1,  3,
+      WPRECALC_16_31_9, WPRECALC_16_31_10,WPRECALC_16_31_11,16,
+      W4, W5, W6, W7, W0, _, _, _ );
+
+#undef curK
+#define curK qK2
+  _R( _b, _c, _d, _e, _a, F1,  4,
+      WPRECALC_16_31_0, WPRECALC_16_31_1, WPRECALC_16_31_2, 20,
+      W3, W4, W5, W6, W7, _, _, _ );
+  _R( _a, _b, _c, _d, _e, F1,  5,
+      WPRECALC_16_31_3, WPRECALC_16_31_4, WPRECALC_16_31_5, 20,
+      W3, W4, W5, W6, W7, _, _, _ );
+  _R( _e, _a, _b, _c, _d, F1,  6,
+      WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 20,
+      W3, W4, W5, W6, W7, _, _, _ );
+  _R( _d, _e, _a, _b, _c, F1,  7,
+      WPRECALC_16_31_9, WPRECALC_16_31_10,WPRECALC_16_31_11,20,
+      W3, W4, W5, W6, W7, _, _, _ );
+
+  _R( _c, _d, _e, _a, _b, F1,  8,
+      WPRECALC_16_31_0, WPRECALC_16_31_1, WPRECALC_16_31_2, 24,
+      W2, W3, W4, W5, W6, _, _, _ );
+  _R( _b, _c, _d, _e, _a, F1,  9,
+      WPRECALC_16_31_3, WPRECALC_16_31_4, WPRECALC_16_31_5, 24,
+      W2, W3, W4, W5, W6, _, _, _ );
+  _R( _a, _b, _c, _d, _e, F1, 10,
+      WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 24,
+      W2, W3, W4, W5, W6, _, _, _ );
+  _R( _e, _a, _b, _c, _d, F1, 11,
+      WPRECALC_16_31_9, WPRECALC_16_31_10,WPRECALC_16_31_11,24,
+      W2, W3, W4, W5, W6, _, _, _ );
+
+  _R( _d, _e, _a, _b, _c, F1, 12,
+      WPRECALC_16_31_0, WPRECALC_16_31_1, WPRECALC_16_31_2, 28,
+      W1, W2, W3, W4, W5, _, _, _ );
+  _R( _c, _d, _e, _a, _b, F1, 13,
+      WPRECALC_16_31_3, WPRECALC_16_31_4, WPRECALC_16_31_5, 28,
+      W1, W2, W3, W4, W5, _, _, _ );
+  _R( _b, _c, _d, _e, _a, F1, 14,
+      WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 28,
+      W1, W2, W3, W4, W5, _, _, _ );
+  _R( _a, _b, _c, _d, _e, F1, 15,
+      WPRECALC_16_31_9, WPRECALC_16_31_10,WPRECALC_16_31_11,28,
+      W1, W2, W3, W4, W5, _, _, _ );
+
+  /* Transform 16-63 + Precalc 32-79. */
+  _R( _e, _a, _b, _c, _d, F1, 16,
+      WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 32,
+      W0, W1, W2, W3, W4, W5, W6, W7);
+  _R( _d, _e, _a, _b, _c, F1, 17,
+      WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 32,
+      W0, W1, W2, W3, W4, W5, W6, W7);
+  _R( _c, _d, _e, _a, _b, F1, 18,
+      WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 32,
+      W0, W1, W2, W3, W4, W5, W6, W7);
+  _R( _b, _c, _d, _e, _a, F1, 19,
+      WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 32,
+      W0, W1, W2, W3, W4, W5, W6, W7);
+
+  _R( _a, _b, _c, _d, _e, F2, 20,
+      WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 36,
+      W7, W0, W1, W2, W3, W4, W5, W6);
+  _R( _e, _a, _b, _c, _d, F2, 21,
+      WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 36,
+      W7, W0, W1, W2, W3, W4, W5, W6);
+  _R( _d, _e, _a, _b, _c, F2, 22,
+      WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 36,
+      W7, W0, W1, W2, W3, W4, W5, W6);
+  _R( _c, _d, _e, _a, _b, F2, 23,
+      WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 36,
+      W7, W0, W1, W2, W3, W4, W5, W6);
+
+#undef curK
+#define curK qK3
+  _R( _b, _c, _d, _e, _a, F2, 24,
+      WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 40,
+      W6, W7, W0, W1, W2, W3, W4, W5);
+  _R( _a, _b, _c, _d, _e, F2, 25,
+      WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 40,
+      W6, W7, W0, W1, W2, W3, W4, W5);
+  _R( _e, _a, _b, _c, _d, F2, 26,
+      WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 40,
+      W6, W7, W0, W1, W2, W3, W4, W5);
+  _R( _d, _e, _a, _b, _c, F2, 27,
+      WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 40,
+      W6, W7, W0, W1, W2, W3, W4, W5);
+
+  _R( _c, _d, _e, _a, _b, F2, 28,
+      WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 44,
+      W5, W6, W7, W0, W1, W2, W3, W4);
+  _R( _b, _c, _d, _e, _a, F2, 29,
+      WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 44,
+      W5, W6, W7, W0, W1, W2, W3, W4);
+  _R( _a, _b, _c, _d, _e, F2, 30,
+      WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 44,
+      W5, W6, W7, W0, W1, W2, W3, W4);
+  _R( _e, _a, _b, _c, _d, F2, 31,
+      WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 44,
+      W5, W6, W7, W0, W1, W2, W3, W4);
+
+  _R( _d, _e, _a, _b, _c, F2, 32,
+      WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 48,
+      W4, W5, W6, W7, W0, W1, W2, W3);
+  _R( _c, _d, _e, _a, _b, F2, 33,
+      WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 48,
+      W4, W5, W6, W7, W0, W1, W2, W3);
+  _R( _b, _c, _d, _e, _a, F2, 34,
+      WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 48,
+      W4, W5, W6, W7, W0, W1, W2, W3);
+  _R( _a, _b, _c, _d, _e, F2, 35,
+      WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 48,
+      W4, W5, W6, W7, W0, W1, W2, W3);
+
+  _R( _e, _a, _b, _c, _d, F2, 36,
+      WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 52,
+      W3, W4, W5, W6, W7, W0, W1, W2);
+  _R( _d, _e, _a, _b, _c, F2, 37,
+      WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 52,
+      W3, W4, W5, W6, W7, W0, W1, W2);
+  _R( _c, _d, _e, _a, _b, F2, 38,
+      WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 52,
+      W3, W4, W5, W6, W7, W0, W1, W2);
+  _R( _b, _c, _d, _e, _a, F2, 39,
+      WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 52,
+      W3, W4, W5, W6, W7, W0, W1, W2);
+
+  _R( _a, _b, _c, _d, _e, F3, 40,
+      WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 56,
+      W2, W3, W4, W5, W6, W7, W0, W1);
+  _R( _e, _a, _b, _c, _d, F3, 41,
+      WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 56,
+      W2, W3, W4, W5, W6, W7, W0, W1);
+  _R( _d, _e, _a, _b, _c, F3, 42,
+      WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 56,
+      W2, W3, W4, W5, W6, W7, W0, W1);
+  _R( _c, _d, _e, _a, _b, F3, 43,
+      WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 56,
+      W2, W3, W4, W5, W6, W7, W0, W1);
+
+#undef curK
+#define curK qK4
+  _R( _b, _c, _d, _e, _a, F3, 44,
+      WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 60,
+      W1, W2, W3, W4, W5, W6, W7, W0);
+  _R( _a, _b, _c, _d, _e, F3, 45,
+      WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 60,
+      W1, W2, W3, W4, W5, W6, W7, W0);
+  _R( _e, _a, _b, _c, _d, F3, 46,
+      WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 60,
+      W1, W2, W3, W4, W5, W6, W7, W0);
+  _R( _d, _e, _a, _b, _c, F3, 47,
+      WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 60,
+      W1, W2, W3, W4, W5, W6, W7, W0);
+
+  _R( _c, _d, _e, _a, _b, F3, 48,
+      WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 64,
+      W0, W1, W2, W3, W4, W5, W6, W7);
+  _R( _b, _c, _d, _e, _a, F3, 49,
+      WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 64,
+      W0, W1, W2, W3, W4, W5, W6, W7);
+  _R( _a, _b, _c, _d, _e, F3, 50,
+      WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 64,
+      W0, W1, W2, W3, W4, W5, W6, W7);
+  _R( _e, _a, _b, _c, _d, F3, 51,
+      WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 64,
+      W0, W1, W2, W3, W4, W5, W6, W7);
+
+  _R( _d, _e, _a, _b, _c, F3, 52,
+      WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 68,
+      W7, W0, W1, W2, W3, W4, W5, W6);
+  _R( _c, _d, _e, _a, _b, F3, 53,
+      WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 68,
+      W7, W0, W1, W2, W3, W4, W5, W6);
+  _R( _b, _c, _d, _e, _a, F3, 54,
+      WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 68,
+      W7, W0, W1, W2, W3, W4, W5, W6);
+  _R( _a, _b, _c, _d, _e, F3, 55,
+      WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 68,
+      W7, W0, W1, W2, W3, W4, W5, W6);
+
+  _R( _e, _a, _b, _c, _d, F3, 56,
+      WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 72,
+      W6, W7, W0, W1, W2, W3, W4, W5);
+  _R( _d, _e, _a, _b, _c, F3, 57,
+      WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 72,
+      W6, W7, W0, W1, W2, W3, W4, W5);
+  _R( _c, _d, _e, _a, _b, F3, 58,
+      WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 72,
+      W6, W7, W0, W1, W2, W3, W4, W5);
+  _R( _b, _c, _d, _e, _a, F3, 59,
+      WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 72,
+      W6, W7, W0, W1, W2, W3, W4, W5);
+
+  subs RNBLKS, #1;
+
+  _R( _a, _b, _c, _d, _e, F4, 60,
+      WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 76,
+      W5, W6, W7, W0, W1, W2, W3, W4);
+  _R( _e, _a, _b, _c, _d, F4, 61,
+      WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 76,
+      W5, W6, W7, W0, W1, W2, W3, W4);
+  _R( _d, _e, _a, _b, _c, F4, 62,
+      WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 76,
+      W5, W6, W7, W0, W1, W2, W3, W4);
+  _R( _c, _d, _e, _a, _b, F4, 63,
+      WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 76,
+      W5, W6, W7, W0, W1, W2, W3, W4);
+
+  beq .Lend;
+
+  /* Transform 64-79 + Precalc 0-15 of next block. */
+#undef curK
+#define curK qK1
+  _R( _b, _c, _d, _e, _a, F4, 64,
+      WPRECALC_00_15_0, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _a, _b, _c, _d, _e, F4, 65,
+      WPRECALC_00_15_1, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _e, _a, _b, _c, _d, F4, 66,
+      WPRECALC_00_15_2, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _d, _e, _a, _b, _c, F4, 67,
+      WPRECALC_00_15_3, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+
+  _R( _c, _d, _e, _a, _b, F4, 68,
+      dummy,            dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _b, _c, _d, _e, _a, F4, 69,
+      dummy,            dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _a, _b, _c, _d, _e, F4, 70,
+      WPRECALC_00_15_4, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _e, _a, _b, _c, _d, F4, 71,
+      WPRECALC_00_15_5, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+
+  _R( _d, _e, _a, _b, _c, F4, 72,
+      dummy,            dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _c, _d, _e, _a, _b, F4, 73,
+      dummy,            dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _b, _c, _d, _e, _a, F4, 74,
+      WPRECALC_00_15_6, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _a, _b, _c, _d, _e, F4, 75,
+      WPRECALC_00_15_7, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+
+  _R( _e, _a, _b, _c, _d, F4, 76,
+      WPRECALC_00_15_8, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _d, _e, _a, _b, _c, F4, 77,
+      WPRECALC_00_15_9, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _c, _d, _e, _a, _b, F4, 78,
+      WPRECALC_00_15_10, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _b, _c, _d, _e, _a, F4, 79,
+      WPRECALC_00_15_11, dummy, WPRECALC_00_15_12, _, _, _, _, _, _, _, _, _ );
+
+  /* Update the chaining variables. */
+  ldm RSTATE, {RT0-RT3};
+  add _a, RT0;
+  ldr RT0, [RSTATE, #state_h4];
+  add _b, RT1;
+  add _c, RT2;
+  add _d, RT3;
+  add _e, RT0;
+  stm RSTATE, {_a-_e};
+
+  b .Loop;
+
+.Lend:
+  /* Transform 64-79 */
+  R( _b, _c, _d, _e, _a, F4, 64 );
+  R( _a, _b, _c, _d, _e, F4, 65 );
+  R( _e, _a, _b, _c, _d, F4, 66 );
+  R( _d, _e, _a, _b, _c, F4, 67 );
+  R( _c, _d, _e, _a, _b, F4, 68 );
+  R( _b, _c, _d, _e, _a, F4, 69 );
+  R( _a, _b, _c, _d, _e, F4, 70 );
+  R( _e, _a, _b, _c, _d, F4, 71 );
+  R( _d, _e, _a, _b, _c, F4, 72 );
+  R( _c, _d, _e, _a, _b, F4, 73 );
+  R( _b, _c, _d, _e, _a, F4, 74 );
+  R( _a, _b, _c, _d, _e, F4, 75 );
+  R( _e, _a, _b, _c, _d, F4, 76 );
+  R( _d, _e, _a, _b, _c, F4, 77 );
+  R( _c, _d, _e, _a, _b, F4, 78 );
+  R( _b, _c, _d, _e, _a, F4, 79 );
+
+  mov sp, ROLDSTACK;
+
+  /* Update the chaining variables. */
+  ldm RSTATE, {RT0-RT3};
+  add _a, RT0;
+  ldr RT0, [RSTATE, #state_h4];
+  add _b, RT1;
+  add _c, RT2;
+  add _d, RT3;
+  /*vpop {q4-q7};*/
+  add _e, RT0;
+  stm RSTATE, {_a-_e};
+
+  pop {r4-r12, pc};
+
+.Ldo_nothing:
+  bx lr
+ENDPROC(sha1_transform_neon)
index ace4cd67464cfbfbc5e4e9a84ec3e39774336c28..e31b0440c6139dc932b0efd4b98aaab077cb862d 100644 (file)
 #include <linux/types.h>
 #include <crypto/sha.h>
 #include <asm/byteorder.h>
+#include <asm/crypto/sha1.h>
 
-struct SHA1_CTX {
-       uint32_t h0,h1,h2,h3,h4;
-       u64 count;
-       u8 data[SHA1_BLOCK_SIZE];
-};
 
-asmlinkage void sha1_block_data_order(struct SHA1_CTX *digest,
+asmlinkage void sha1_block_data_order(u32 *digest,
                const unsigned char *data, unsigned int rounds);
 
 
 static int sha1_init(struct shash_desc *desc)
 {
-       struct SHA1_CTX *sctx = shash_desc_ctx(desc);
-       memset(sctx, 0, sizeof(*sctx));
-       sctx->h0 = SHA1_H0;
-       sctx->h1 = SHA1_H1;
-       sctx->h2 = SHA1_H2;
-       sctx->h3 = SHA1_H3;
-       sctx->h4 = SHA1_H4;
+       struct sha1_state *sctx = shash_desc_ctx(desc);
+
+       *sctx = (struct sha1_state){
+               .state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 },
+       };
+
        return 0;
 }
 
 
-static int __sha1_update(struct SHA1_CTX *sctx, const u8 *data,
-                              unsigned int len, unsigned int partial)
+static int __sha1_update(struct sha1_state *sctx, const u8 *data,
+                        unsigned int len, unsigned int partial)
 {
        unsigned int done = 0;
 
@@ -56,43 +51,44 @@ static int __sha1_update(struct SHA1_CTX *sctx, const u8 *data,
 
        if (partial) {
                done = SHA1_BLOCK_SIZE - partial;
-               memcpy(sctx->data + partial, data, done);
-               sha1_block_data_order(sctx, sctx->data, 1);
+               memcpy(sctx->buffer + partial, data, done);
+               sha1_block_data_order(sctx->state, sctx->buffer, 1);
        }
 
        if (len - done >= SHA1_BLOCK_SIZE) {
                const unsigned int rounds = (len - done) / SHA1_BLOCK_SIZE;
-               sha1_block_data_order(sctx, data + done, rounds);
+               sha1_block_data_order(sctx->state, data + done, rounds);
                done += rounds * SHA1_BLOCK_SIZE;
        }
 
-       memcpy(sctx->data, data + done, len - done);
+       memcpy(sctx->buffer, data + done, len - done);
        return 0;
 }
 
 
-static int sha1_update(struct shash_desc *desc, const u8 *data,
-                            unsigned int len)
+int sha1_update_arm(struct shash_desc *desc, const u8 *data,
+                   unsigned int len)
 {
-       struct SHA1_CTX *sctx = shash_desc_ctx(desc);
+       struct sha1_state *sctx = shash_desc_ctx(desc);
        unsigned int partial = sctx->count % SHA1_BLOCK_SIZE;
        int res;
 
        /* Handle the fast case right here */
        if (partial + len < SHA1_BLOCK_SIZE) {
                sctx->count += len;
-               memcpy(sctx->data + partial, data, len);
+               memcpy(sctx->buffer + partial, data, len);
                return 0;
        }
        res = __sha1_update(sctx, data, len, partial);
        return res;
 }
+EXPORT_SYMBOL_GPL(sha1_update_arm);
 
 
 /* Add padding and return the message digest. */
 static int sha1_final(struct shash_desc *desc, u8 *out)
 {
-       struct SHA1_CTX *sctx = shash_desc_ctx(desc);
+       struct sha1_state *sctx = shash_desc_ctx(desc);
        unsigned int i, index, padlen;
        __be32 *dst = (__be32 *)out;
        __be64 bits;
@@ -106,7 +102,7 @@ static int sha1_final(struct shash_desc *desc, u8 *out)
        /* We need to fill a whole block for __sha1_update() */
        if (padlen <= 56) {
                sctx->count += padlen;
-               memcpy(sctx->data + index, padding, padlen);
+               memcpy(sctx->buffer + index, padding, padlen);
        } else {
                __sha1_update(sctx, padding, padlen, index);
        }
@@ -114,7 +110,7 @@ static int sha1_final(struct shash_desc *desc, u8 *out)
 
        /* Store state in digest */
        for (i = 0; i < 5; i++)
-               dst[i] = cpu_to_be32(((u32 *)sctx)[i]);
+               dst[i] = cpu_to_be32(sctx->state[i]);
 
        /* Wipe context */
        memset(sctx, 0, sizeof(*sctx));
@@ -124,7 +120,7 @@ static int sha1_final(struct shash_desc *desc, u8 *out)
 
 static int sha1_export(struct shash_desc *desc, void *out)
 {
-       struct SHA1_CTX *sctx = shash_desc_ctx(desc);
+       struct sha1_state *sctx = shash_desc_ctx(desc);
        memcpy(out, sctx, sizeof(*sctx));
        return 0;
 }
@@ -132,7 +128,7 @@ static int sha1_export(struct shash_desc *desc, void *out)
 
 static int sha1_import(struct shash_desc *desc, const void *in)
 {
-       struct SHA1_CTX *sctx = shash_desc_ctx(desc);
+       struct sha1_state *sctx = shash_desc_ctx(desc);
        memcpy(sctx, in, sizeof(*sctx));
        return 0;
 }
@@ -141,12 +137,12 @@ static int sha1_import(struct shash_desc *desc, const void *in)
 static struct shash_alg alg = {
        .digestsize     =       SHA1_DIGEST_SIZE,
        .init           =       sha1_init,
-       .update         =       sha1_update,
+       .update         =       sha1_update_arm,
        .final          =       sha1_final,
        .export         =       sha1_export,
        .import         =       sha1_import,
-       .descsize       =       sizeof(struct SHA1_CTX),
-       .statesize      =       sizeof(struct SHA1_CTX),
+       .descsize       =       sizeof(struct sha1_state),
+       .statesize      =       sizeof(struct sha1_state),
        .base           =       {
                .cra_name       =       "sha1",
                .cra_driver_name=       "sha1-asm",
diff --git a/arch/arm/crypto/sha1_neon_glue.c b/arch/arm/crypto/sha1_neon_glue.c
new file mode 100644 (file)
index 0000000..6f1b411
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Glue code for the SHA1 Secure Hash Algorithm assembler implementation using
+ * ARM NEON instructions.
+ *
+ * Copyright © 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is based on sha1_generic.c and sha1_ssse3_glue.c:
+ *  Copyright (c) Alan Smithee.
+ *  Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
+ *  Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
+ *  Copyright (c) Mathias Krause <minipli@googlemail.com>
+ *  Copyright (c) Chandramouli Narayanan <mouli@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#include <crypto/internal/hash.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/cryptohash.h>
+#include <linux/types.h>
+#include <crypto/sha.h>
+#include <asm/byteorder.h>
+#include <asm/neon.h>
+#include <asm/simd.h>
+#include <asm/crypto/sha1.h>
+
+
+asmlinkage void sha1_transform_neon(void *state_h, const char *data,
+                                   unsigned int rounds);
+
+
+static int sha1_neon_init(struct shash_desc *desc)
+{
+       struct sha1_state *sctx = shash_desc_ctx(desc);
+
+       *sctx = (struct sha1_state){
+               .state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 },
+       };
+
+       return 0;
+}
+
+static int __sha1_neon_update(struct shash_desc *desc, const u8 *data,
+                              unsigned int len, unsigned int partial)
+{
+       struct sha1_state *sctx = shash_desc_ctx(desc);
+       unsigned int done = 0;
+
+       sctx->count += len;
+
+       if (partial) {
+               done = SHA1_BLOCK_SIZE - partial;
+               memcpy(sctx->buffer + partial, data, done);
+               sha1_transform_neon(sctx->state, sctx->buffer, 1);
+       }
+
+       if (len - done >= SHA1_BLOCK_SIZE) {
+               const unsigned int rounds = (len - done) / SHA1_BLOCK_SIZE;
+
+               sha1_transform_neon(sctx->state, data + done, rounds);
+               done += rounds * SHA1_BLOCK_SIZE;
+       }
+
+       memcpy(sctx->buffer, data + done, len - done);
+
+       return 0;
+}
+
+static int sha1_neon_update(struct shash_desc *desc, const u8 *data,
+                            unsigned int len)
+{
+       struct sha1_state *sctx = shash_desc_ctx(desc);
+       unsigned int partial = sctx->count % SHA1_BLOCK_SIZE;
+       int res;
+
+       /* Handle the fast case right here */
+       if (partial + len < SHA1_BLOCK_SIZE) {
+               sctx->count += len;
+               memcpy(sctx->buffer + partial, data, len);
+
+               return 0;
+       }
+
+       if (!may_use_simd()) {
+               res = sha1_update_arm(desc, data, len);
+       } else {
+               kernel_neon_begin();
+               res = __sha1_neon_update(desc, data, len, partial);
+               kernel_neon_end();
+       }
+
+       return res;
+}
+
+
+/* Add padding and return the message digest. */
+static int sha1_neon_final(struct shash_desc *desc, u8 *out)
+{
+       struct sha1_state *sctx = shash_desc_ctx(desc);
+       unsigned int i, index, padlen;
+       __be32 *dst = (__be32 *)out;
+       __be64 bits;
+       static const u8 padding[SHA1_BLOCK_SIZE] = { 0x80, };
+
+       bits = cpu_to_be64(sctx->count << 3);
+
+       /* Pad out to 56 mod 64 and append length */
+       index = sctx->count % SHA1_BLOCK_SIZE;
+       padlen = (index < 56) ? (56 - index) : ((SHA1_BLOCK_SIZE+56) - index);
+       if (!may_use_simd()) {
+               sha1_update_arm(desc, padding, padlen);
+               sha1_update_arm(desc, (const u8 *)&bits, sizeof(bits));
+       } else {
+               kernel_neon_begin();
+               /* We need to fill a whole block for __sha1_neon_update() */
+               if (padlen <= 56) {
+                       sctx->count += padlen;
+                       memcpy(sctx->buffer + index, padding, padlen);
+               } else {
+                       __sha1_neon_update(desc, padding, padlen, index);
+               }
+               __sha1_neon_update(desc, (const u8 *)&bits, sizeof(bits), 56);
+               kernel_neon_end();
+       }
+
+       /* Store state in digest */
+       for (i = 0; i < 5; i++)
+               dst[i] = cpu_to_be32(sctx->state[i]);
+
+       /* Wipe context */
+       memset(sctx, 0, sizeof(*sctx));
+
+       return 0;
+}
+
+static int sha1_neon_export(struct shash_desc *desc, void *out)
+{
+       struct sha1_state *sctx = shash_desc_ctx(desc);
+
+       memcpy(out, sctx, sizeof(*sctx));
+
+       return 0;
+}
+
+static int sha1_neon_import(struct shash_desc *desc, const void *in)
+{
+       struct sha1_state *sctx = shash_desc_ctx(desc);
+
+       memcpy(sctx, in, sizeof(*sctx));
+
+       return 0;
+}
+
+static struct shash_alg alg = {
+       .digestsize     =       SHA1_DIGEST_SIZE,
+       .init           =       sha1_neon_init,
+       .update         =       sha1_neon_update,
+       .final          =       sha1_neon_final,
+       .export         =       sha1_neon_export,
+       .import         =       sha1_neon_import,
+       .descsize       =       sizeof(struct sha1_state),
+       .statesize      =       sizeof(struct sha1_state),
+       .base           =       {
+               .cra_name               = "sha1",
+               .cra_driver_name        = "sha1-neon",
+               .cra_priority           = 250,
+               .cra_flags              = CRYPTO_ALG_TYPE_SHASH,
+               .cra_blocksize          = SHA1_BLOCK_SIZE,
+               .cra_module             = THIS_MODULE,
+       }
+};
+
+static int __init sha1_neon_mod_init(void)
+{
+       if (!cpu_has_neon())
+               return -ENODEV;
+
+       return crypto_register_shash(&alg);
+}
+
+static void __exit sha1_neon_mod_fini(void)
+{
+       crypto_unregister_shash(&alg);
+}
+
+module_init(sha1_neon_mod_init);
+module_exit(sha1_neon_mod_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, NEON accelerated");
+MODULE_ALIAS("sha1");
diff --git a/arch/arm/crypto/sha512-armv7-neon.S b/arch/arm/crypto/sha512-armv7-neon.S
new file mode 100644 (file)
index 0000000..fe99472
--- /dev/null
@@ -0,0 +1,455 @@
+/* sha512-armv7-neon.S  -  ARM/NEON assembly implementation of SHA-512 transform
+ *
+ * Copyright © 2013-2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/linkage.h>
+
+
+.syntax unified
+.code   32
+.fpu neon
+
+.text
+
+/* structure of SHA512_CONTEXT */
+#define hd_a 0
+#define hd_b ((hd_a) + 8)
+#define hd_c ((hd_b) + 8)
+#define hd_d ((hd_c) + 8)
+#define hd_e ((hd_d) + 8)
+#define hd_f ((hd_e) + 8)
+#define hd_g ((hd_f) + 8)
+
+/* register macros */
+#define RK %r2
+
+#define RA d0
+#define RB d1
+#define RC d2
+#define RD d3
+#define RE d4
+#define RF d5
+#define RG d6
+#define RH d7
+
+#define RT0 d8
+#define RT1 d9
+#define RT2 d10
+#define RT3 d11
+#define RT4 d12
+#define RT5 d13
+#define RT6 d14
+#define RT7 d15
+
+#define RT01q q4
+#define RT23q q5
+#define RT45q q6
+#define RT67q q7
+
+#define RW0 d16
+#define RW1 d17
+#define RW2 d18
+#define RW3 d19
+#define RW4 d20
+#define RW5 d21
+#define RW6 d22
+#define RW7 d23
+#define RW8 d24
+#define RW9 d25
+#define RW10 d26
+#define RW11 d27
+#define RW12 d28
+#define RW13 d29
+#define RW14 d30
+#define RW15 d31
+
+#define RW01q q8
+#define RW23q q9
+#define RW45q q10
+#define RW67q q11
+#define RW89q q12
+#define RW1011q q13
+#define RW1213q q14
+#define RW1415q q15
+
+/***********************************************************************
+ * ARM assembly implementation of sha512 transform
+ ***********************************************************************/
+#define rounds2_0_63(ra, rb, rc, rd, re, rf, rg, rh, rw0, rw1, rw01q, rw2, \
+                     rw23q, rw1415q, rw9, rw10, interleave_op, arg1) \
+       /* t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t]; */ \
+       vshr.u64 RT2, re, #14; \
+       vshl.u64 RT3, re, #64 - 14; \
+       interleave_op(arg1); \
+       vshr.u64 RT4, re, #18; \
+       vshl.u64 RT5, re, #64 - 18; \
+       vld1.64 {RT0}, [RK]!; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vshr.u64 RT4, re, #41; \
+       vshl.u64 RT5, re, #64 - 41; \
+       vadd.u64 RT0, RT0, rw0; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vmov.64 RT7, re; \
+       veor.64 RT1, RT2, RT3; \
+       vbsl.64 RT7, rf, rg; \
+       \
+       vadd.u64 RT1, RT1, rh; \
+       vshr.u64 RT2, ra, #28; \
+       vshl.u64 RT3, ra, #64 - 28; \
+       vadd.u64 RT1, RT1, RT0; \
+       vshr.u64 RT4, ra, #34; \
+       vshl.u64 RT5, ra, #64 - 34; \
+       vadd.u64 RT1, RT1, RT7; \
+       \
+       /* h = Sum0 (a) + Maj (a, b, c); */ \
+       veor.64 RT23q, RT23q, RT45q; \
+       vshr.u64 RT4, ra, #39; \
+       vshl.u64 RT5, ra, #64 - 39; \
+       veor.64 RT0, ra, rb; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vbsl.64 RT0, rc, rb; \
+       vadd.u64 rd, rd, RT1; /* d+=t1; */ \
+       veor.64 rh, RT2, RT3; \
+       \
+       /* t1 = g + Sum1 (d) + Ch (d, e, f) + k[t] + w[t]; */ \
+       vshr.u64 RT2, rd, #14; \
+       vshl.u64 RT3, rd, #64 - 14; \
+       vadd.u64 rh, rh, RT0; \
+       vshr.u64 RT4, rd, #18; \
+       vshl.u64 RT5, rd, #64 - 18; \
+       vadd.u64 rh, rh, RT1; /* h+=t1; */ \
+       vld1.64 {RT0}, [RK]!; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vshr.u64 RT4, rd, #41; \
+       vshl.u64 RT5, rd, #64 - 41; \
+       vadd.u64 RT0, RT0, rw1; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vmov.64 RT7, rd; \
+       veor.64 RT1, RT2, RT3; \
+       vbsl.64 RT7, re, rf; \
+       \
+       vadd.u64 RT1, RT1, rg; \
+       vshr.u64 RT2, rh, #28; \
+       vshl.u64 RT3, rh, #64 - 28; \
+       vadd.u64 RT1, RT1, RT0; \
+       vshr.u64 RT4, rh, #34; \
+       vshl.u64 RT5, rh, #64 - 34; \
+       vadd.u64 RT1, RT1, RT7; \
+       \
+       /* g = Sum0 (h) + Maj (h, a, b); */ \
+       veor.64 RT23q, RT23q, RT45q; \
+       vshr.u64 RT4, rh, #39; \
+       vshl.u64 RT5, rh, #64 - 39; \
+       veor.64 RT0, rh, ra; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vbsl.64 RT0, rb, ra; \
+       vadd.u64 rc, rc, RT1; /* c+=t1; */ \
+       veor.64 rg, RT2, RT3; \
+       \
+       /* w[0] += S1 (w[14]) + w[9] + S0 (w[1]); */ \
+       /* w[1] += S1 (w[15]) + w[10] + S0 (w[2]); */ \
+       \
+       /**** S0(w[1:2]) */ \
+       \
+       /* w[0:1] += w[9:10] */ \
+       /* RT23q = rw1:rw2 */ \
+       vext.u64 RT23q, rw01q, rw23q, #1; \
+       vadd.u64 rw0, rw9; \
+       vadd.u64 rg, rg, RT0; \
+       vadd.u64 rw1, rw10;\
+       vadd.u64 rg, rg, RT1; /* g+=t1; */ \
+       \
+       vshr.u64 RT45q, RT23q, #1; \
+       vshl.u64 RT67q, RT23q, #64 - 1; \
+       vshr.u64 RT01q, RT23q, #8; \
+       veor.u64 RT45q, RT45q, RT67q; \
+       vshl.u64 RT67q, RT23q, #64 - 8; \
+       veor.u64 RT45q, RT45q, RT01q; \
+       vshr.u64 RT01q, RT23q, #7; \
+       veor.u64 RT45q, RT45q, RT67q; \
+       \
+       /**** S1(w[14:15]) */ \
+       vshr.u64 RT23q, rw1415q, #6; \
+       veor.u64 RT01q, RT01q, RT45q; \
+       vshr.u64 RT45q, rw1415q, #19; \
+       vshl.u64 RT67q, rw1415q, #64 - 19; \
+       veor.u64 RT23q, RT23q, RT45q; \
+       vshr.u64 RT45q, rw1415q, #61; \
+       veor.u64 RT23q, RT23q, RT67q; \
+       vshl.u64 RT67q, rw1415q, #64 - 61; \
+       veor.u64 RT23q, RT23q, RT45q; \
+       vadd.u64 rw01q, RT01q; /* w[0:1] += S(w[1:2]) */ \
+       veor.u64 RT01q, RT23q, RT67q;
+#define vadd_RT01q(rw01q) \
+       /* w[0:1] += S(w[14:15]) */ \
+       vadd.u64 rw01q, RT01q;
+
+#define dummy(_) /*_*/
+
+#define rounds2_64_79(ra, rb, rc, rd, re, rf, rg, rh, rw0, rw1, \
+                     interleave_op1, arg1, interleave_op2, arg2) \
+       /* t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t]; */ \
+       vshr.u64 RT2, re, #14; \
+       vshl.u64 RT3, re, #64 - 14; \
+       interleave_op1(arg1); \
+       vshr.u64 RT4, re, #18; \
+       vshl.u64 RT5, re, #64 - 18; \
+       interleave_op2(arg2); \
+       vld1.64 {RT0}, [RK]!; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vshr.u64 RT4, re, #41; \
+       vshl.u64 RT5, re, #64 - 41; \
+       vadd.u64 RT0, RT0, rw0; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vmov.64 RT7, re; \
+       veor.64 RT1, RT2, RT3; \
+       vbsl.64 RT7, rf, rg; \
+       \
+       vadd.u64 RT1, RT1, rh; \
+       vshr.u64 RT2, ra, #28; \
+       vshl.u64 RT3, ra, #64 - 28; \
+       vadd.u64 RT1, RT1, RT0; \
+       vshr.u64 RT4, ra, #34; \
+       vshl.u64 RT5, ra, #64 - 34; \
+       vadd.u64 RT1, RT1, RT7; \
+       \
+       /* h = Sum0 (a) + Maj (a, b, c); */ \
+       veor.64 RT23q, RT23q, RT45q; \
+       vshr.u64 RT4, ra, #39; \
+       vshl.u64 RT5, ra, #64 - 39; \
+       veor.64 RT0, ra, rb; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vbsl.64 RT0, rc, rb; \
+       vadd.u64 rd, rd, RT1; /* d+=t1; */ \
+       veor.64 rh, RT2, RT3; \
+       \
+       /* t1 = g + Sum1 (d) + Ch (d, e, f) + k[t] + w[t]; */ \
+       vshr.u64 RT2, rd, #14; \
+       vshl.u64 RT3, rd, #64 - 14; \
+       vadd.u64 rh, rh, RT0; \
+       vshr.u64 RT4, rd, #18; \
+       vshl.u64 RT5, rd, #64 - 18; \
+       vadd.u64 rh, rh, RT1; /* h+=t1; */ \
+       vld1.64 {RT0}, [RK]!; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vshr.u64 RT4, rd, #41; \
+       vshl.u64 RT5, rd, #64 - 41; \
+       vadd.u64 RT0, RT0, rw1; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vmov.64 RT7, rd; \
+       veor.64 RT1, RT2, RT3; \
+       vbsl.64 RT7, re, rf; \
+       \
+       vadd.u64 RT1, RT1, rg; \
+       vshr.u64 RT2, rh, #28; \
+       vshl.u64 RT3, rh, #64 - 28; \
+       vadd.u64 RT1, RT1, RT0; \
+       vshr.u64 RT4, rh, #34; \
+       vshl.u64 RT5, rh, #64 - 34; \
+       vadd.u64 RT1, RT1, RT7; \
+       \
+       /* g = Sum0 (h) + Maj (h, a, b); */ \
+       veor.64 RT23q, RT23q, RT45q; \
+       vshr.u64 RT4, rh, #39; \
+       vshl.u64 RT5, rh, #64 - 39; \
+       veor.64 RT0, rh, ra; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vbsl.64 RT0, rb, ra; \
+       vadd.u64 rc, rc, RT1; /* c+=t1; */ \
+       veor.64 rg, RT2, RT3;
+#define vadd_rg_RT0(rg) \
+       vadd.u64 rg, rg, RT0;
+#define vadd_rg_RT1(rg) \
+       vadd.u64 rg, rg, RT1; /* g+=t1; */
+
+.align 3
+ENTRY(sha512_transform_neon)
+       /* Input:
+        *      %r0: SHA512_CONTEXT
+        *      %r1: data
+        *      %r2: u64 k[] constants
+        *      %r3: nblks
+        */
+       push {%lr};
+
+       mov %lr, #0;
+
+       /* Load context to d0-d7 */
+       vld1.64 {RA-RD}, [%r0]!;
+       vld1.64 {RE-RH}, [%r0];
+       sub %r0, #(4*8);
+
+       /* Load input to w[16], d16-d31 */
+       /* NOTE: Assumes that on ARMv7 unaligned accesses are always allowed. */
+       vld1.64 {RW0-RW3}, [%r1]!;
+       vld1.64 {RW4-RW7}, [%r1]!;
+       vld1.64 {RW8-RW11}, [%r1]!;
+       vld1.64 {RW12-RW15}, [%r1]!;
+#ifdef __ARMEL__
+       /* byteswap */
+       vrev64.8 RW01q, RW01q;
+       vrev64.8 RW23q, RW23q;
+       vrev64.8 RW45q, RW45q;
+       vrev64.8 RW67q, RW67q;
+       vrev64.8 RW89q, RW89q;
+       vrev64.8 RW1011q, RW1011q;
+       vrev64.8 RW1213q, RW1213q;
+       vrev64.8 RW1415q, RW1415q;
+#endif
+
+       /* EABI says that d8-d15 must be preserved by callee. */
+       /*vpush {RT0-RT7};*/
+
+.Loop:
+       rounds2_0_63(RA, RB, RC, RD, RE, RF, RG, RH, RW0, RW1, RW01q, RW2,
+                    RW23q, RW1415q, RW9, RW10, dummy, _);
+       b .Lenter_rounds;
+
+.Loop_rounds:
+       rounds2_0_63(RA, RB, RC, RD, RE, RF, RG, RH, RW0, RW1, RW01q, RW2,
+                    RW23q, RW1415q, RW9, RW10, vadd_RT01q, RW1415q);
+.Lenter_rounds:
+       rounds2_0_63(RG, RH, RA, RB, RC, RD, RE, RF, RW2, RW3, RW23q, RW4,
+                    RW45q, RW01q, RW11, RW12, vadd_RT01q, RW01q);
+       rounds2_0_63(RE, RF, RG, RH, RA, RB, RC, RD, RW4, RW5, RW45q, RW6,
+                    RW67q, RW23q, RW13, RW14, vadd_RT01q, RW23q);
+       rounds2_0_63(RC, RD, RE, RF, RG, RH, RA, RB, RW6, RW7, RW67q, RW8,
+                    RW89q, RW45q, RW15, RW0, vadd_RT01q, RW45q);
+       rounds2_0_63(RA, RB, RC, RD, RE, RF, RG, RH, RW8, RW9, RW89q, RW10,
+                    RW1011q, RW67q, RW1, RW2, vadd_RT01q, RW67q);
+       rounds2_0_63(RG, RH, RA, RB, RC, RD, RE, RF, RW10, RW11, RW1011q, RW12,
+                    RW1213q, RW89q, RW3, RW4, vadd_RT01q, RW89q);
+       add %lr, #16;
+       rounds2_0_63(RE, RF, RG, RH, RA, RB, RC, RD, RW12, RW13, RW1213q, RW14,
+                    RW1415q, RW1011q, RW5, RW6, vadd_RT01q, RW1011q);
+       cmp %lr, #64;
+       rounds2_0_63(RC, RD, RE, RF, RG, RH, RA, RB, RW14, RW15, RW1415q, RW0,
+                    RW01q, RW1213q, RW7, RW8, vadd_RT01q, RW1213q);
+       bne .Loop_rounds;
+
+       subs %r3, #1;
+
+       rounds2_64_79(RA, RB, RC, RD, RE, RF, RG, RH, RW0, RW1,
+                     vadd_RT01q, RW1415q, dummy, _);
+       rounds2_64_79(RG, RH, RA, RB, RC, RD, RE, RF, RW2, RW3,
+                     vadd_rg_RT0, RG, vadd_rg_RT1, RG);
+       beq .Lhandle_tail;
+       vld1.64 {RW0-RW3}, [%r1]!;
+       rounds2_64_79(RE, RF, RG, RH, RA, RB, RC, RD, RW4, RW5,
+                     vadd_rg_RT0, RE, vadd_rg_RT1, RE);
+       rounds2_64_79(RC, RD, RE, RF, RG, RH, RA, RB, RW6, RW7,
+                     vadd_rg_RT0, RC, vadd_rg_RT1, RC);
+#ifdef __ARMEL__
+       vrev64.8 RW01q, RW01q;
+       vrev64.8 RW23q, RW23q;
+#endif
+       vld1.64 {RW4-RW7}, [%r1]!;
+       rounds2_64_79(RA, RB, RC, RD, RE, RF, RG, RH, RW8, RW9,
+                     vadd_rg_RT0, RA, vadd_rg_RT1, RA);
+       rounds2_64_79(RG, RH, RA, RB, RC, RD, RE, RF, RW10, RW11,
+                     vadd_rg_RT0, RG, vadd_rg_RT1, RG);
+#ifdef __ARMEL__
+       vrev64.8 RW45q, RW45q;
+       vrev64.8 RW67q, RW67q;
+#endif
+       vld1.64 {RW8-RW11}, [%r1]!;
+       rounds2_64_79(RE, RF, RG, RH, RA, RB, RC, RD, RW12, RW13,
+                     vadd_rg_RT0, RE, vadd_rg_RT1, RE);
+       rounds2_64_79(RC, RD, RE, RF, RG, RH, RA, RB, RW14, RW15,
+                     vadd_rg_RT0, RC, vadd_rg_RT1, RC);
+#ifdef __ARMEL__
+       vrev64.8 RW89q, RW89q;
+       vrev64.8 RW1011q, RW1011q;
+#endif
+       vld1.64 {RW12-RW15}, [%r1]!;
+       vadd_rg_RT0(RA);
+       vadd_rg_RT1(RA);
+
+       /* Load context */
+       vld1.64 {RT0-RT3}, [%r0]!;
+       vld1.64 {RT4-RT7}, [%r0];
+       sub %r0, #(4*8);
+
+#ifdef __ARMEL__
+       vrev64.8 RW1213q, RW1213q;
+       vrev64.8 RW1415q, RW1415q;
+#endif
+
+       vadd.u64 RA, RT0;
+       vadd.u64 RB, RT1;
+       vadd.u64 RC, RT2;
+       vadd.u64 RD, RT3;
+       vadd.u64 RE, RT4;
+       vadd.u64 RF, RT5;
+       vadd.u64 RG, RT6;
+       vadd.u64 RH, RT7;
+
+       /* Store the first half of context */
+       vst1.64 {RA-RD}, [%r0]!;
+       sub RK, $(8*80);
+       vst1.64 {RE-RH}, [%r0]; /* Store the last half of context */
+       mov %lr, #0;
+       sub %r0, #(4*8);
+
+       b .Loop;
+
+.Lhandle_tail:
+       rounds2_64_79(RE, RF, RG, RH, RA, RB, RC, RD, RW4, RW5,
+                     vadd_rg_RT0, RE, vadd_rg_RT1, RE);
+       rounds2_64_79(RC, RD, RE, RF, RG, RH, RA, RB, RW6, RW7,
+                     vadd_rg_RT0, RC, vadd_rg_RT1, RC);
+       rounds2_64_79(RA, RB, RC, RD, RE, RF, RG, RH, RW8, RW9,
+                     vadd_rg_RT0, RA, vadd_rg_RT1, RA);
+       rounds2_64_79(RG, RH, RA, RB, RC, RD, RE, RF, RW10, RW11,
+                     vadd_rg_RT0, RG, vadd_rg_RT1, RG);
+       rounds2_64_79(RE, RF, RG, RH, RA, RB, RC, RD, RW12, RW13,
+                     vadd_rg_RT0, RE, vadd_rg_RT1, RE);
+       rounds2_64_79(RC, RD, RE, RF, RG, RH, RA, RB, RW14, RW15,
+                     vadd_rg_RT0, RC, vadd_rg_RT1, RC);
+
+       /* Load context to d16-d23 */
+       vld1.64 {RW0-RW3}, [%r0]!;
+       vadd_rg_RT0(RA);
+       vld1.64 {RW4-RW7}, [%r0];
+       vadd_rg_RT1(RA);
+       sub %r0, #(4*8);
+
+       vadd.u64 RA, RW0;
+       vadd.u64 RB, RW1;
+       vadd.u64 RC, RW2;
+       vadd.u64 RD, RW3;
+       vadd.u64 RE, RW4;
+       vadd.u64 RF, RW5;
+       vadd.u64 RG, RW6;
+       vadd.u64 RH, RW7;
+
+       /* Store the first half of context */
+       vst1.64 {RA-RD}, [%r0]!;
+
+       /* Clear used registers */
+       /* d16-d31 */
+       veor.u64 RW01q, RW01q;
+       veor.u64 RW23q, RW23q;
+       veor.u64 RW45q, RW45q;
+       veor.u64 RW67q, RW67q;
+       vst1.64 {RE-RH}, [%r0]; /* Store the last half of context */
+       veor.u64 RW89q, RW89q;
+       veor.u64 RW1011q, RW1011q;
+       veor.u64 RW1213q, RW1213q;
+       veor.u64 RW1415q, RW1415q;
+       /* d8-d15 */
+       /*vpop {RT0-RT7};*/
+       /* d0-d7 (q0-q3) */
+       veor.u64 %q0, %q0;
+       veor.u64 %q1, %q1;
+       veor.u64 %q2, %q2;
+       veor.u64 %q3, %q3;
+
+       pop {%pc};
+ENDPROC(sha512_transform_neon)
diff --git a/arch/arm/crypto/sha512_neon_glue.c b/arch/arm/crypto/sha512_neon_glue.c
new file mode 100644 (file)
index 0000000..0d2758f
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+ * Glue code for the SHA512 Secure Hash Algorithm assembly implementation
+ * using NEON instructions.
+ *
+ * Copyright © 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is based on sha512_ssse3_glue.c:
+ *   Copyright (C) 2013 Intel Corporation
+ *   Author: Tim Chen <tim.c.chen@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#include <crypto/internal/hash.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/cryptohash.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <crypto/sha.h>
+#include <asm/byteorder.h>
+#include <asm/simd.h>
+#include <asm/neon.h>
+
+
+static const u64 sha512_k[] = {
+       0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
+       0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+       0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+       0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+       0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+       0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+       0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
+       0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+       0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+       0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+       0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
+       0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+       0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
+       0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+       0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+       0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+       0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
+       0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+       0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
+       0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+       0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+       0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+       0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
+       0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+       0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+       0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+       0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+       0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+       0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
+       0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+       0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
+       0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+       0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+       0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+       0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+       0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+       0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
+       0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+       0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+       0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
+};
+
+
+asmlinkage void sha512_transform_neon(u64 *digest, const void *data,
+                                     const u64 k[], unsigned int num_blks);
+
+
+static int sha512_neon_init(struct shash_desc *desc)
+{
+       struct sha512_state *sctx = shash_desc_ctx(desc);
+
+       sctx->state[0] = SHA512_H0;
+       sctx->state[1] = SHA512_H1;
+       sctx->state[2] = SHA512_H2;
+       sctx->state[3] = SHA512_H3;
+       sctx->state[4] = SHA512_H4;
+       sctx->state[5] = SHA512_H5;
+       sctx->state[6] = SHA512_H6;
+       sctx->state[7] = SHA512_H7;
+       sctx->count[0] = sctx->count[1] = 0;
+
+       return 0;
+}
+
+static int __sha512_neon_update(struct shash_desc *desc, const u8 *data,
+                               unsigned int len, unsigned int partial)
+{
+       struct sha512_state *sctx = shash_desc_ctx(desc);
+       unsigned int done = 0;
+
+       sctx->count[0] += len;
+       if (sctx->count[0] < len)
+               sctx->count[1]++;
+
+       if (partial) {
+               done = SHA512_BLOCK_SIZE - partial;
+               memcpy(sctx->buf + partial, data, done);
+               sha512_transform_neon(sctx->state, sctx->buf, sha512_k, 1);
+       }
+
+       if (len - done >= SHA512_BLOCK_SIZE) {
+               const unsigned int rounds = (len - done) / SHA512_BLOCK_SIZE;
+
+               sha512_transform_neon(sctx->state, data + done, sha512_k,
+                                     rounds);
+
+               done += rounds * SHA512_BLOCK_SIZE;
+       }
+
+       memcpy(sctx->buf, data + done, len - done);
+
+       return 0;
+}
+
+static int sha512_neon_update(struct shash_desc *desc, const u8 *data,
+                            unsigned int len)
+{
+       struct sha512_state *sctx = shash_desc_ctx(desc);
+       unsigned int partial = sctx->count[0] % SHA512_BLOCK_SIZE;
+       int res;
+
+       /* Handle the fast case right here */
+       if (partial + len < SHA512_BLOCK_SIZE) {
+               sctx->count[0] += len;
+               if (sctx->count[0] < len)
+                       sctx->count[1]++;
+               memcpy(sctx->buf + partial, data, len);
+
+               return 0;
+       }
+
+       if (!may_use_simd()) {
+               res = crypto_sha512_update(desc, data, len);
+       } else {
+               kernel_neon_begin();
+               res = __sha512_neon_update(desc, data, len, partial);
+               kernel_neon_end();
+       }
+
+       return res;
+}
+
+
+/* Add padding and return the message digest. */
+static int sha512_neon_final(struct shash_desc *desc, u8 *out)
+{
+       struct sha512_state *sctx = shash_desc_ctx(desc);
+       unsigned int i, index, padlen;
+       __be64 *dst = (__be64 *)out;
+       __be64 bits[2];
+       static const u8 padding[SHA512_BLOCK_SIZE] = { 0x80, };
+
+       /* save number of bits */
+       bits[1] = cpu_to_be64(sctx->count[0] << 3);
+       bits[0] = cpu_to_be64(sctx->count[1] << 3 | sctx->count[0] >> 61);
+
+       /* Pad out to 112 mod 128 and append length */
+       index = sctx->count[0] & 0x7f;
+       padlen = (index < 112) ? (112 - index) : ((128+112) - index);
+
+       if (!may_use_simd()) {
+               crypto_sha512_update(desc, padding, padlen);
+               crypto_sha512_update(desc, (const u8 *)&bits, sizeof(bits));
+       } else {
+               kernel_neon_begin();
+               /* We need to fill a whole block for __sha512_neon_update() */
+               if (padlen <= 112) {
+                       sctx->count[0] += padlen;
+                       if (sctx->count[0] < padlen)
+                               sctx->count[1]++;
+                       memcpy(sctx->buf + index, padding, padlen);
+               } else {
+                       __sha512_neon_update(desc, padding, padlen, index);
+               }
+               __sha512_neon_update(desc, (const u8 *)&bits,
+                                       sizeof(bits), 112);
+               kernel_neon_end();
+       }
+
+       /* Store state in digest */
+       for (i = 0; i < 8; i++)
+               dst[i] = cpu_to_be64(sctx->state[i]);
+
+       /* Wipe context */
+       memset(sctx, 0, sizeof(*sctx));
+
+       return 0;
+}
+
+static int sha512_neon_export(struct shash_desc *desc, void *out)
+{
+       struct sha512_state *sctx = shash_desc_ctx(desc);
+
+       memcpy(out, sctx, sizeof(*sctx));
+
+       return 0;
+}
+
+static int sha512_neon_import(struct shash_desc *desc, const void *in)
+{
+       struct sha512_state *sctx = shash_desc_ctx(desc);
+
+       memcpy(sctx, in, sizeof(*sctx));
+
+       return 0;
+}
+
+static int sha384_neon_init(struct shash_desc *desc)
+{
+       struct sha512_state *sctx = shash_desc_ctx(desc);
+
+       sctx->state[0] = SHA384_H0;
+       sctx->state[1] = SHA384_H1;
+       sctx->state[2] = SHA384_H2;
+       sctx->state[3] = SHA384_H3;
+       sctx->state[4] = SHA384_H4;
+       sctx->state[5] = SHA384_H5;
+       sctx->state[6] = SHA384_H6;
+       sctx->state[7] = SHA384_H7;
+
+       sctx->count[0] = sctx->count[1] = 0;
+
+       return 0;
+}
+
+static int sha384_neon_final(struct shash_desc *desc, u8 *hash)
+{
+       u8 D[SHA512_DIGEST_SIZE];
+
+       sha512_neon_final(desc, D);
+
+       memcpy(hash, D, SHA384_DIGEST_SIZE);
+       memset(D, 0, SHA512_DIGEST_SIZE);
+
+       return 0;
+}
+
+static struct shash_alg algs[] = { {
+       .digestsize     =       SHA512_DIGEST_SIZE,
+       .init           =       sha512_neon_init,
+       .update         =       sha512_neon_update,
+       .final          =       sha512_neon_final,
+       .export         =       sha512_neon_export,
+       .import         =       sha512_neon_import,
+       .descsize       =       sizeof(struct sha512_state),
+       .statesize      =       sizeof(struct sha512_state),
+       .base           =       {
+               .cra_name       =       "sha512",
+               .cra_driver_name =      "sha512-neon",
+               .cra_priority   =       250,
+               .cra_flags      =       CRYPTO_ALG_TYPE_SHASH,
+               .cra_blocksize  =       SHA512_BLOCK_SIZE,
+               .cra_module     =       THIS_MODULE,
+       }
+},  {
+       .digestsize     =       SHA384_DIGEST_SIZE,
+       .init           =       sha384_neon_init,
+       .update         =       sha512_neon_update,
+       .final          =       sha384_neon_final,
+       .export         =       sha512_neon_export,
+       .import         =       sha512_neon_import,
+       .descsize       =       sizeof(struct sha512_state),
+       .statesize      =       sizeof(struct sha512_state),
+       .base           =       {
+               .cra_name       =       "sha384",
+               .cra_driver_name =      "sha384-neon",
+               .cra_priority   =       250,
+               .cra_flags      =       CRYPTO_ALG_TYPE_SHASH,
+               .cra_blocksize  =       SHA384_BLOCK_SIZE,
+               .cra_module     =       THIS_MODULE,
+       }
+} };
+
+static int __init sha512_neon_mod_init(void)
+{
+       if (!cpu_has_neon())
+               return -ENODEV;
+
+       return crypto_register_shashes(algs, ARRAY_SIZE(algs));
+}
+
+static void __exit sha512_neon_mod_fini(void)
+{
+       crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
+}
+
+module_init(sha512_neon_mod_init);
+module_exit(sha512_neon_mod_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SHA512 Secure Hash Algorithm, NEON accelerated");
+
+MODULE_ALIAS("sha512");
+MODULE_ALIAS("sha384");
diff --git a/arch/arm/include/asm/crypto/sha1.h b/arch/arm/include/asm/crypto/sha1.h
new file mode 100644 (file)
index 0000000..75e6a41
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef ASM_ARM_CRYPTO_SHA1_H
+#define ASM_ARM_CRYPTO_SHA1_H
+
+#include <linux/crypto.h>
+#include <crypto/sha.h>
+
+extern int sha1_update_arm(struct shash_desc *desc, const u8 *data,
+                          unsigned int len);
+
+#endif
diff --git a/arch/arm/include/asm/fiq_glue.h b/arch/arm/include/asm/fiq_glue.h
new file mode 100644 (file)
index 0000000..a9e244f
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ASM_FIQ_GLUE_H
+#define __ASM_FIQ_GLUE_H
+
+struct fiq_glue_handler {
+       void (*fiq)(struct fiq_glue_handler *h, void *regs, void *svc_sp);
+       void (*resume)(struct fiq_glue_handler *h);
+};
+typedef void (*fiq_return_handler_t)(void);
+
+int fiq_glue_register_handler(struct fiq_glue_handler *handler);
+int fiq_glue_set_return_handler(fiq_return_handler_t fiq_return);
+int fiq_glue_clear_return_handler(fiq_return_handler_t fiq_return);
+
+#ifdef CONFIG_FIQ_GLUE
+void fiq_glue_resume(void);
+#else
+static inline void fiq_glue_resume(void) {}
+#endif
+
+#endif
index fe3ea776dc34267724f377465134e52b39434fed..5df33e30ae1b16693cbd8124f7f4e3e29e4e774c 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/threads.h>
 #include <asm/irq.h>
 
-#define NR_IPI 8
+#define NR_IPI 9
 
 typedef struct {
        unsigned int __softirq_pending;
index 6795ff743b3dbc8664760b54088f765e1790c06d..b1344186954c4ca8d4725ac2d475c1d36b09ae8d 100644 (file)
@@ -66,6 +66,7 @@
 #define   L2X0_STNDBY_MODE_EN          (1 << 0)
 
 /* Registers shifts and masks */
+#define L2X0_CACHE_ID_REV_MASK         (0x3f)
 #define L2X0_CACHE_ID_PART_MASK                (0xf << 6)
 #define L2X0_CACHE_ID_PART_L210                (1 << 6)
 #define L2X0_CACHE_ID_PART_L310                (3 << 6)
 
 #define L2X0_WAY_SIZE_SHIFT            3
 
+#define REV_PL310_R2P0                         4
+
 #ifndef __ASSEMBLY__
 extern void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask);
 #if defined(CONFIG_CACHE_L2X0) && defined(CONFIG_OF)
index ad774f37c47cda0f6201d7a7aad7d967cec4786b..b3507650b41c69744a49ae5742352a231b13c50b 100644 (file)
 #define TRACER_ACCESSED_BIT    0
 #define TRACER_RUNNING_BIT     1
 #define TRACER_CYCLE_ACC_BIT   2
+#define TRACER_TRACE_DATA_BIT  3
+#define TRACER_TIMESTAMP_BIT   4
+#define TRACER_BRANCHOUTPUT_BIT        5
+#define TRACER_RETURN_STACK_BIT        6
 #define TRACER_ACCESSED                BIT(TRACER_ACCESSED_BIT)
 #define TRACER_RUNNING         BIT(TRACER_RUNNING_BIT)
 #define TRACER_CYCLE_ACC       BIT(TRACER_CYCLE_ACC_BIT)
+#define TRACER_TRACE_DATA      BIT(TRACER_TRACE_DATA_BIT)
+#define TRACER_TIMESTAMP       BIT(TRACER_TIMESTAMP_BIT)
+#define TRACER_BRANCHOUTPUT    BIT(TRACER_BRANCHOUTPUT_BIT)
+#define TRACER_RETURN_STACK    BIT(TRACER_RETURN_STACK_BIT)
 
 #define TRACER_TIMEOUT 10000
 
-#define etm_writel(t, v, x) \
-       (writel_relaxed((v), (t)->etm_regs + (x)))
-#define etm_readl(t, x) (readl_relaxed((t)->etm_regs + (x)))
+#define etm_writel(t, id, v, x) \
+       (writel_relaxed((v), (t)->etm_regs[(id)] + (x)))
+#define etm_readl(t, id, x) (readl_relaxed((t)->etm_regs[(id)] + (x)))
 
 /* CoreSight Management Registers */
 #define CSMR_LOCKACCESS 0xfb0
@@ -43,7 +51,7 @@
 #define ETMCTRL_POWERDOWN      1
 #define ETMCTRL_PROGRAM                (1 << 10)
 #define ETMCTRL_PORTSEL                (1 << 11)
-#define ETMCTRL_DO_CONTEXTID   (3 << 14)
+#define ETMCTRL_CONTEXTIDSIZE(x) (((x) & 3) << 14)
 #define ETMCTRL_PORTMASK1      (7 << 4)
 #define ETMCTRL_PORTMASK2      (1 << 21)
 #define ETMCTRL_PORTMASK       (ETMCTRL_PORTMASK1 | ETMCTRL_PORTMASK2)
 #define ETMCTRL_DATA_DO_BOTH   (ETMCTRL_DATA_DO_DATA | ETMCTRL_DATA_DO_ADDR)
 #define ETMCTRL_BRANCH_OUTPUT  (1 << 8)
 #define ETMCTRL_CYCLEACCURATE  (1 << 12)
+#define ETMCTRL_TIMESTAMP_EN   (1 << 28)
+#define ETMCTRL_RETURN_STACK_EN        (1 << 29)
 
 /* ETM configuration code register */
 #define ETMR_CONFCODE          (0x04)
+#define ETMCCR_ETMIDR_PRESENT  BIT(31)
 
 /* ETM trace start/stop resource control register */
 #define ETMR_TRACESSCTRL       (0x18)
 #define ETMR_TRACEENCTRL       0x24
 #define ETMTE_INCLEXCL         BIT(24)
 #define ETMR_TRACEENEVT                0x20
-#define ETMCTRL_OPTS           (ETMCTRL_DO_CPRT | \
-                               ETMCTRL_DATA_DO_ADDR | \
-                               ETMCTRL_BRANCH_OUTPUT | \
-                               ETMCTRL_DO_CONTEXTID)
+
+#define ETMR_VIEWDATAEVT       0x30
+#define ETMR_VIEWDATACTRL1     0x34
+#define ETMR_VIEWDATACTRL2     0x38
+#define ETMR_VIEWDATACTRL3     0x3c
+#define ETMVDC3_EXCLONLY       BIT(16)
+
+#define ETMCTRL_OPTS           (ETMCTRL_DO_CPRT)
+
+#define ETMR_ID                        0x1e4
+#define ETMIDR_VERSION(x)      (((x) >> 4) & 0xff)
+#define ETMIDR_VERSION_3_1     0x21
+#define ETMIDR_VERSION_PFT_1_0 0x30
+
+#define ETMR_CCE               0x1e8
+#define ETMCCER_RETURN_STACK_IMPLEMENTED       BIT(23)
+#define ETMCCER_TIMESTAMPING_IMPLEMENTED       BIT(22)
+
+#define ETMR_TRACEIDR          0x200
 
 /* ETM management registers, "ETM Architecture", 3.5.24 */
 #define ETMMR_OSLAR    0x300
 #define ETBFF_TRIGIN           BIT(8)
 #define ETBFF_TRIGEVT          BIT(9)
 #define ETBFF_TRIGFL           BIT(10)
+#define ETBFF_STOPFL           BIT(12)
 
 #define etb_writel(t, v, x) \
        (writel_relaxed((v), (t)->etb_regs + (x)))
 #define etb_readl(t, x) (readl_relaxed((t)->etb_regs + (x)))
 
-#define etm_lock(t) do { etm_writel((t), 0, CSMR_LOCKACCESS); } while (0)
-#define etm_unlock(t) \
-       do { etm_writel((t), CS_LAR_KEY, CSMR_LOCKACCESS); } while (0)
+#define etm_lock(t, id) \
+       do { etm_writel((t), (id), 0, CSMR_LOCKACCESS); } while (0)
+#define etm_unlock(t, id) \
+       do { etm_writel((t), (id), CS_LAR_KEY, CSMR_LOCKACCESS); } while (0)
 
 #define etb_lock(t) do { etb_writel((t), 0, CSMR_LOCKACCESS); } while (0)
 #define etb_unlock(t) \
index 53c15dec7af6aa09faee9b1851782f9244365e56..809203a4b71befacd5ce807c7c3caf17224e980b 100644 (file)
@@ -35,6 +35,9 @@ extern void (*handle_arch_irq)(struct pt_regs *);
 extern void set_handle_irq(void (*handle_irq)(struct pt_regs *));
 #endif
 
+void arch_trigger_all_cpu_backtrace(void);
+#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace
+
 #endif
 
 #endif
diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h
new file mode 100644 (file)
index 0000000..bca864a
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  arch/arm/include/asm/mach/mmc.h
+ */
+#ifndef ASMARM_MACH_MMC_H
+#define ASMARM_MACH_MMC_H
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+
+struct embedded_sdio_data {
+        struct sdio_cis cis;
+        struct sdio_cccr cccr;
+        struct sdio_embedded_func *funcs;
+        int num_funcs;
+};
+
+struct mmc_platform_data {
+       unsigned int ocr_mask;                  /* available voltages */
+       int built_in;                           /* built-in device flag */
+       int card_present;                       /* card detect state */
+       u32 (*translate_vdd)(struct device *, unsigned int);
+       unsigned int (*status)(struct device *);
+       struct embedded_sdio_data *embedded_sdio;
+       int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id);
+};
+
+#endif
index 4157aec4e3076ce853a8497ce81743a38990504a..2a655ca5141d7077e6c00c47568b0796a2e0db99 100644 (file)
@@ -87,6 +87,8 @@ extern void arch_send_wakeup_ipi_mask(const struct cpumask *mask);
 
 extern int register_ipi_completion(struct completion *completion, int cpu);
 
+extern void smp_send_all_cpu_backtrace(void);
+
 struct smp_operations {
 #ifdef CONFIG_SMP
        /*
index 73ddd7239b33aa77d178ae1341c0c46c736a08e5..ed805f1d3785691fdb79eb36fbaa56b355766a21 100644 (file)
@@ -103,8 +103,7 @@ static inline void syscall_set_arguments(struct task_struct *task,
        memcpy(&regs->ARM_r0 + i, args, n * sizeof(args[0]));
 }
 
-static inline int syscall_get_arch(struct task_struct *task,
-                                  struct pt_regs *regs)
+static inline int syscall_get_arch(void)
 {
        /* ARM tasks don't change audit architectures on the fly. */
        return AUDIT_ARCH_ARM;
index c3776331f4072074d9714453f5d98f8a524fa295..6e104d9f103afefcb7e9a73d038c9836bd659cb0 100644 (file)
 #define __NR_finit_module              (__NR_SYSCALL_BASE+379)
 #define __NR_sched_setattr             (__NR_SYSCALL_BASE+380)
 #define __NR_sched_getattr             (__NR_SYSCALL_BASE+381)
+/* Reserve for later
+#define __NR_renameat2                 (__NR_SYSCALL_BASE+382)
+*/
+#define __NR_seccomp                   (__NR_SYSCALL_BASE+383)
 
 /*
  * The following SWIs are ARM private.
index 166e945de832f22b603d6b0de2ca3eb92f2ec732..b75c9688b3430279a393375d33086378c3e3c811 100644 (file)
                CALL(sys_finit_module)
 /* 380 */      CALL(sys_sched_setattr)
                CALL(sys_sched_getattr)
+               CALL(sys_ni_syscall)            /* reserved sys_renameat2     */
+               CALL(sys_seccomp)
+
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
index 131a6ab5f35504dfc70c6f9e1421632c25d5feae..a634e0ef6d1f147472e7b402b3cebdc71fa07de8 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/sysrq.h>
 #include <linux/device.h>
 #include <linux/clk.h>
@@ -37,26 +38,37 @@ MODULE_AUTHOR("Alexander Shishkin");
 struct tracectx {
        unsigned int    etb_bufsz;
        void __iomem    *etb_regs;
-       void __iomem    *etm_regs;
+       void __iomem    **etm_regs;
+       int             etm_regs_count;
        unsigned long   flags;
        int             ncmppairs;
        int             etm_portsz;
+       int             etm_contextid_size;
+       u32             etb_fc;
+       unsigned long   range_start;
+       unsigned long   range_end;
+       unsigned long   data_range_start;
+       unsigned long   data_range_end;
+       bool            dump_initial_etb;
        struct device   *dev;
        struct clk      *emu_clk;
        struct mutex    mutex;
 };
 
-static struct tracectx tracer;
+static struct tracectx tracer = {
+       .range_start = (unsigned long)_stext,
+       .range_end = (unsigned long)_etext,
+};
 
 static inline bool trace_isrunning(struct tracectx *t)
 {
        return !!(t->flags & TRACER_RUNNING);
 }
 
-static int etm_setup_address_range(struct tracectx *t, int n,
+static int etm_setup_address_range(struct tracectx *t, int id, int n,
                unsigned long start, unsigned long end, int exclude, int data)
 {
-       u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_NSONLY | \
+       u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_IGNSECURITY |
                    ETMAAT_NOVALCMP;
 
        if (n < 1 || n > t->ncmppairs)
@@ -72,95 +84,185 @@ static int etm_setup_address_range(struct tracectx *t, int n,
                flags |= ETMAAT_IEXEC;
 
        /* first comparator for the range */
-       etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2));
-       etm_writel(t, start, ETMR_COMP_VAL(n * 2));
+       etm_writel(t, id, flags, ETMR_COMP_ACC_TYPE(n * 2));
+       etm_writel(t, id, start, ETMR_COMP_VAL(n * 2));
 
        /* second comparator is right next to it */
-       etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1));
-       etm_writel(t, end, ETMR_COMP_VAL(n * 2 + 1));
-
-       flags = exclude ? ETMTE_INCLEXCL : 0;
-       etm_writel(t, flags | (1 << n), ETMR_TRACEENCTRL);
+       etm_writel(t, id, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1));
+       etm_writel(t, id, end, ETMR_COMP_VAL(n * 2 + 1));
+
+       if (data) {
+               flags = exclude ? ETMVDC3_EXCLONLY : 0;
+               if (exclude)
+                       n += 8;
+               etm_writel(t, id, flags | BIT(n), ETMR_VIEWDATACTRL3);
+       } else {
+               flags = exclude ? ETMTE_INCLEXCL : 0;
+               etm_writel(t, id, flags | (1 << n), ETMR_TRACEENCTRL);
+       }
 
        return 0;
 }
 
-static int trace_start(struct tracectx *t)
+static int trace_start_etm(struct tracectx *t, int id)
 {
        u32 v;
        unsigned long timeout = TRACER_TIMEOUT;
 
-       etb_unlock(t);
-
-       etb_writel(t, 0, ETBR_FORMATTERCTRL);
-       etb_writel(t, 1, ETBR_CTRL);
-
-       etb_lock(t);
-
-       /* configure etm */
        v = ETMCTRL_OPTS | ETMCTRL_PROGRAM | ETMCTRL_PORTSIZE(t->etm_portsz);
+       v |= ETMCTRL_CONTEXTIDSIZE(t->etm_contextid_size);
 
        if (t->flags & TRACER_CYCLE_ACC)
                v |= ETMCTRL_CYCLEACCURATE;
 
-       etm_unlock(t);
+       if (t->flags & TRACER_BRANCHOUTPUT)
+               v |= ETMCTRL_BRANCH_OUTPUT;
+
+       if (t->flags & TRACER_TRACE_DATA)
+               v |= ETMCTRL_DATA_DO_ADDR;
+
+       if (t->flags & TRACER_TIMESTAMP)
+               v |= ETMCTRL_TIMESTAMP_EN;
+
+       if (t->flags & TRACER_RETURN_STACK)
+               v |= ETMCTRL_RETURN_STACK_EN;
 
-       etm_writel(t, v, ETMR_CTRL);
+       etm_unlock(t, id);
 
-       while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
+       etm_writel(t, id, v, ETMR_CTRL);
+
+       while (!(etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
                ;
        if (!timeout) {
                dev_dbg(t->dev, "Waiting for progbit to assert timed out\n");
-               etm_lock(t);
+               etm_lock(t, id);
                return -EFAULT;
        }
 
-       etm_setup_address_range(t, 1, (unsigned long)_stext,
-                       (unsigned long)_etext, 0, 0);
-       etm_writel(t, 0, ETMR_TRACEENCTRL2);
-       etm_writel(t, 0, ETMR_TRACESSCTRL);
-       etm_writel(t, 0x6f, ETMR_TRACEENEVT);
+       if (t->range_start || t->range_end)
+               etm_setup_address_range(t, id, 1,
+                                       t->range_start, t->range_end, 0, 0);
+       else
+               etm_writel(t, id, ETMTE_INCLEXCL, ETMR_TRACEENCTRL);
+
+       etm_writel(t, id, 0, ETMR_TRACEENCTRL2);
+       etm_writel(t, id, 0, ETMR_TRACESSCTRL);
+       etm_writel(t, id, 0x6f, ETMR_TRACEENEVT);
+
+       etm_writel(t, id, 0, ETMR_VIEWDATACTRL1);
+       etm_writel(t, id, 0, ETMR_VIEWDATACTRL2);
+
+       if (t->data_range_start || t->data_range_end)
+               etm_setup_address_range(t, id, 2, t->data_range_start,
+                                       t->data_range_end, 0, 1);
+       else
+               etm_writel(t, id, ETMVDC3_EXCLONLY, ETMR_VIEWDATACTRL3);
+
+       etm_writel(t, id, 0x6f, ETMR_VIEWDATAEVT);
 
        v &= ~ETMCTRL_PROGRAM;
        v |= ETMCTRL_PORTSEL;
 
-       etm_writel(t, v, ETMR_CTRL);
+       etm_writel(t, id, v, ETMR_CTRL);
 
        timeout = TRACER_TIMEOUT;
-       while (etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM && --timeout)
+       while (etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM && --timeout)
                ;
        if (!timeout) {
                dev_dbg(t->dev, "Waiting for progbit to deassert timed out\n");
-               etm_lock(t);
+               etm_lock(t, id);
                return -EFAULT;
        }
 
-       etm_lock(t);
+       etm_lock(t, id);
+       return 0;
+}
+
+static int trace_start(struct tracectx *t)
+{
+       int ret;
+       int id;
+       u32 etb_fc = t->etb_fc;
+
+       etb_unlock(t);
+
+       t->dump_initial_etb = false;
+       etb_writel(t, 0, ETBR_WRITEADDR);
+       etb_writel(t, etb_fc, ETBR_FORMATTERCTRL);
+       etb_writel(t, 1, ETBR_CTRL);
+
+       etb_lock(t);
+
+       /* configure etm(s) */
+       for (id = 0; id < t->etm_regs_count; id++) {
+               ret = trace_start_etm(t, id);
+               if (ret)
+                       return ret;
+       }
 
        t->flags |= TRACER_RUNNING;
 
        return 0;
 }
 
-static int trace_stop(struct tracectx *t)
+static int trace_stop_etm(struct tracectx *t, int id)
 {
        unsigned long timeout = TRACER_TIMEOUT;
 
-       etm_unlock(t);
+       etm_unlock(t, id);
 
-       etm_writel(t, 0x440, ETMR_CTRL);
-       while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
+       etm_writel(t, id, 0x440, ETMR_CTRL);
+       while (!(etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
                ;
        if (!timeout) {
-               dev_dbg(t->dev, "Waiting for progbit to assert timed out\n");
-               etm_lock(t);
+               dev_err(t->dev,
+                       "etm%d: Waiting for progbit to assert timed out\n",
+                       id);
+               etm_lock(t, id);
                return -EFAULT;
        }
 
-       etm_lock(t);
+       etm_lock(t, id);
+       return 0;
+}
+
+static int trace_power_down_etm(struct tracectx *t, int id)
+{
+       unsigned long timeout = TRACER_TIMEOUT;
+       etm_unlock(t, id);
+       while (!(etm_readl(t, id, ETMR_STATUS) & ETMST_PROGBIT) && --timeout)
+               ;
+       if (!timeout) {
+               dev_err(t->dev, "etm%d: Waiting for status progbit to assert timed out\n",
+                       id);
+               etm_lock(t, id);
+               return -EFAULT;
+       }
+
+       etm_writel(t, id, 0x441, ETMR_CTRL);
+
+       etm_lock(t, id);
+       return 0;
+}
+
+static int trace_stop(struct tracectx *t)
+{
+       int id;
+       unsigned long timeout = TRACER_TIMEOUT;
+       u32 etb_fc = t->etb_fc;
+
+       for (id = 0; id < t->etm_regs_count; id++)
+               trace_stop_etm(t, id);
+
+       for (id = 0; id < t->etm_regs_count; id++)
+               trace_power_down_etm(t, id);
 
        etb_unlock(t);
-       etb_writel(t, ETBFF_MANUAL_FLUSH, ETBR_FORMATTERCTRL);
+       if (etb_fc) {
+               etb_fc |= ETBFF_STOPFL;
+               etb_writel(t, t->etb_fc, ETBR_FORMATTERCTRL);
+       }
+       etb_writel(t, etb_fc | ETBFF_MANUAL_FLUSH, ETBR_FORMATTERCTRL);
 
        timeout = TRACER_TIMEOUT;
        while (etb_readl(t, ETBR_FORMATTERCTRL) &
@@ -185,24 +287,15 @@ static int trace_stop(struct tracectx *t)
 static int etb_getdatalen(struct tracectx *t)
 {
        u32 v;
-       int rp, wp;
+       int wp;
 
        v = etb_readl(t, ETBR_STATUS);
 
        if (v & 1)
                return t->etb_bufsz;
 
-       rp = etb_readl(t, ETBR_READADDR);
        wp = etb_readl(t, ETBR_WRITEADDR);
-
-       if (rp > wp) {
-               etb_writel(t, 0, ETBR_READADDR);
-               etb_writel(t, 0, ETBR_WRITEADDR);
-
-               return 0;
-       }
-
-       return wp - rp;
+       return wp;
 }
 
 /* sysrq+v will always stop the running trace and leave it at that */
@@ -235,21 +328,18 @@ static void etm_dump(void)
                printk("%08x", cpu_to_be32(etb_readl(t, ETBR_READMEM)));
        printk(KERN_INFO "\n--- ETB buffer end ---\n");
 
-       /* deassert the overflow bit */
-       etb_writel(t, 1, ETBR_CTRL);
-       etb_writel(t, 0, ETBR_CTRL);
-
-       etb_writel(t, 0, ETBR_TRIGGERCOUNT);
-       etb_writel(t, 0, ETBR_READADDR);
-       etb_writel(t, 0, ETBR_WRITEADDR);
-
        etb_lock(t);
 }
 
 static void sysrq_etm_dump(int key)
 {
+       if (!mutex_trylock(&tracer.mutex)) {
+               printk(KERN_INFO "Tracing hardware busy\n");
+               return;
+       }
        dev_dbg(tracer.dev, "Dumping ETB buffer\n");
        etm_dump();
+       mutex_unlock(&tracer.mutex);
 }
 
 static struct sysrq_key_op sysrq_etm_op = {
@@ -276,6 +366,10 @@ static ssize_t etb_read(struct file *file, char __user *data,
        struct tracectx *t = file->private_data;
        u32 first = 0;
        u32 *buf;
+       int wpos;
+       int skip;
+       long wlength;
+       loff_t pos = *ppos;
 
        mutex_lock(&t->mutex);
 
@@ -287,31 +381,39 @@ static ssize_t etb_read(struct file *file, char __user *data,
        etb_unlock(t);
 
        total = etb_getdatalen(t);
+       if (total == 0 && t->dump_initial_etb)
+               total = t->etb_bufsz;
        if (total == t->etb_bufsz)
                first = etb_readl(t, ETBR_WRITEADDR);
 
+       if (pos > total * 4) {
+               skip = 0;
+               wpos = total;
+       } else {
+               skip = (int)pos % 4;
+               wpos = (int)pos / 4;
+       }
+       total -= wpos;
+       first = (first + wpos) % t->etb_bufsz;
+
        etb_writel(t, first, ETBR_READADDR);
 
-       length = min(total * 4, (int)len);
-       buf = vmalloc(length);
+       wlength = min(total, DIV_ROUND_UP(skip + (int)len, 4));
+       length = min(total * 4 - skip, (int)len);
+       buf = vmalloc(wlength * 4);
 
-       dev_dbg(t->dev, "ETB buffer length: %d\n", total);
+       dev_dbg(t->dev, "ETB read %ld bytes to %lld from %ld words at %d\n",
+               length, pos, wlength, first);
+       dev_dbg(t->dev, "ETB buffer length: %d\n", total + wpos);
        dev_dbg(t->dev, "ETB status reg: %x\n", etb_readl(t, ETBR_STATUS));
-       for (i = 0; i < length / 4; i++)
+       for (i = 0; i < wlength; i++)
                buf[i] = etb_readl(t, ETBR_READMEM);
 
-       /* the only way to deassert overflow bit in ETB status is this */
-       etb_writel(t, 1, ETBR_CTRL);
-       etb_writel(t, 0, ETBR_CTRL);
-
-       etb_writel(t, 0, ETBR_WRITEADDR);
-       etb_writel(t, 0, ETBR_READADDR);
-       etb_writel(t, 0, ETBR_TRIGGERCOUNT);
-
        etb_lock(t);
 
-       length -= copy_to_user(data, buf, length);
+       length -= copy_to_user(data, (u8 *)buf + skip, length);
        vfree(buf);
+       *ppos = pos + length;
 
 out:
        mutex_unlock(&t->mutex);
@@ -348,28 +450,17 @@ static int etb_probe(struct amba_device *dev, const struct amba_id *id)
        if (ret)
                goto out;
 
+       mutex_lock(&t->mutex);
        t->etb_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res));
        if (!t->etb_regs) {
                ret = -ENOMEM;
                goto out_release;
        }
 
+       t->dev = &dev->dev;
+       t->dump_initial_etb = true;
        amba_set_drvdata(dev, t);
 
-       etb_miscdev.parent = &dev->dev;
-
-       ret = misc_register(&etb_miscdev);
-       if (ret)
-               goto out_unmap;
-
-       t->emu_clk = clk_get(&dev->dev, "emu_src_ck");
-       if (IS_ERR(t->emu_clk)) {
-               dev_dbg(&dev->dev, "Failed to obtain emu_src_ck.\n");
-               return -EFAULT;
-       }
-
-       clk_enable(t->emu_clk);
-
        etb_unlock(t);
        t->etb_bufsz = etb_readl(t, ETBR_DEPTH);
        dev_dbg(&dev->dev, "Size: %x\n", t->etb_bufsz);
@@ -378,6 +469,20 @@ static int etb_probe(struct amba_device *dev, const struct amba_id *id)
        etb_writel(t, 0, ETBR_CTRL);
        etb_writel(t, 0x1000, ETBR_FORMATTERCTRL);
        etb_lock(t);
+       mutex_unlock(&t->mutex);
+
+       etb_miscdev.parent = &dev->dev;
+
+       ret = misc_register(&etb_miscdev);
+       if (ret)
+               goto out_unmap;
+
+       /* Get optional clock. Currently used to select clock source on omap3 */
+       t->emu_clk = clk_get(&dev->dev, "emu_src_ck");
+       if (IS_ERR(t->emu_clk))
+               dev_dbg(&dev->dev, "Failed to obtain emu_src_ck.\n");
+       else
+               clk_enable(t->emu_clk);
 
        dev_dbg(&dev->dev, "ETB AMBA driver initialized.\n");
 
@@ -385,9 +490,12 @@ out:
        return ret;
 
 out_unmap:
+       mutex_lock(&t->mutex);
        iounmap(t->etb_regs);
+       t->etb_regs = NULL;
 
 out_release:
+       mutex_unlock(&t->mutex);
        amba_release_regions(dev);
 
        return ret;
@@ -400,8 +508,10 @@ static int etb_remove(struct amba_device *dev)
        iounmap(t->etb_regs);
        t->etb_regs = NULL;
 
-       clk_disable(t->emu_clk);
-       clk_put(t->emu_clk);
+       if (!IS_ERR(t->emu_clk)) {
+               clk_disable(t->emu_clk);
+               clk_put(t->emu_clk);
+       }
 
        amba_release_regions(dev);
 
@@ -445,7 +555,10 @@ static ssize_t trace_running_store(struct kobject *kobj,
                return -EINVAL;
 
        mutex_lock(&tracer.mutex);
-       ret = value ? trace_start(&tracer) : trace_stop(&tracer);
+       if (!tracer.etb_regs)
+               ret = -ENODEV;
+       else
+               ret = value ? trace_start(&tracer) : trace_stop(&tracer);
        mutex_unlock(&tracer.mutex);
 
        return ret ? : n;
@@ -460,36 +573,50 @@ static ssize_t trace_info_show(struct kobject *kobj,
 {
        u32 etb_wa, etb_ra, etb_st, etb_fc, etm_ctrl, etm_st;
        int datalen;
+       int id;
+       int ret;
 
-       etb_unlock(&tracer);
-       datalen = etb_getdatalen(&tracer);
-       etb_wa = etb_readl(&tracer, ETBR_WRITEADDR);
-       etb_ra = etb_readl(&tracer, ETBR_READADDR);
-       etb_st = etb_readl(&tracer, ETBR_STATUS);
-       etb_fc = etb_readl(&tracer, ETBR_FORMATTERCTRL);
-       etb_lock(&tracer);
-
-       etm_unlock(&tracer);
-       etm_ctrl = etm_readl(&tracer, ETMR_CTRL);
-       etm_st = etm_readl(&tracer, ETMR_STATUS);
-       etm_lock(&tracer);
+       mutex_lock(&tracer.mutex);
+       if (tracer.etb_regs) {
+               etb_unlock(&tracer);
+               datalen = etb_getdatalen(&tracer);
+               etb_wa = etb_readl(&tracer, ETBR_WRITEADDR);
+               etb_ra = etb_readl(&tracer, ETBR_READADDR);
+               etb_st = etb_readl(&tracer, ETBR_STATUS);
+               etb_fc = etb_readl(&tracer, ETBR_FORMATTERCTRL);
+               etb_lock(&tracer);
+       } else {
+               etb_wa = etb_ra = etb_st = etb_fc = ~0;
+               datalen = -1;
+       }
 
-       return sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n"
+       ret = sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n"
                        "ETBR_WRITEADDR:\t%08x\n"
                        "ETBR_READADDR:\t%08x\n"
                        "ETBR_STATUS:\t%08x\n"
-                       "ETBR_FORMATTERCTRL:\t%08x\n"
-                       "ETMR_CTRL:\t%08x\n"
-                       "ETMR_STATUS:\t%08x\n",
+                       "ETBR_FORMATTERCTRL:\t%08x\n",
                        datalen,
                        tracer.ncmppairs,
                        etb_wa,
                        etb_ra,
                        etb_st,
-                       etb_fc,
+                       etb_fc
+                       );
+
+       for (id = 0; id < tracer.etm_regs_count; id++) {
+               etm_unlock(&tracer, id);
+               etm_ctrl = etm_readl(&tracer, id, ETMR_CTRL);
+               etm_st = etm_readl(&tracer, id, ETMR_STATUS);
+               etm_lock(&tracer, id);
+               ret += sprintf(buf + ret, "ETMR_CTRL:\t%08x\n"
+                       "ETMR_STATUS:\t%08x\n",
                        etm_ctrl,
                        etm_st
                        );
+       }
+       mutex_unlock(&tracer.mutex);
+
+       return ret;
 }
 
 static struct kobj_attribute trace_info_attr =
@@ -528,42 +655,260 @@ static ssize_t trace_mode_store(struct kobject *kobj,
 static struct kobj_attribute trace_mode_attr =
        __ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store);
 
+static ssize_t trace_contextid_size_show(struct kobject *kobj,
+                                        struct kobj_attribute *attr,
+                                        char *buf)
+{
+       /* 0: No context id tracing, 1: One byte, 2: Two bytes, 3: Four bytes */
+       return sprintf(buf, "%d\n", (1 << tracer.etm_contextid_size) >> 1);
+}
+
+static ssize_t trace_contextid_size_store(struct kobject *kobj,
+                                         struct kobj_attribute *attr,
+                                         const char *buf, size_t n)
+{
+       unsigned int contextid_size;
+
+       if (sscanf(buf, "%u", &contextid_size) != 1)
+               return -EINVAL;
+
+       if (contextid_size == 3 || contextid_size > 4)
+               return -EINVAL;
+
+       mutex_lock(&tracer.mutex);
+       tracer.etm_contextid_size = fls(contextid_size);
+       mutex_unlock(&tracer.mutex);
+
+       return n;
+}
+
+static struct kobj_attribute trace_contextid_size_attr =
+       __ATTR(trace_contextid_size, 0644,
+               trace_contextid_size_show, trace_contextid_size_store);
+
+static ssize_t trace_branch_output_show(struct kobject *kobj,
+                                       struct kobj_attribute *attr,
+                                       char *buf)
+{
+       return sprintf(buf, "%d\n", !!(tracer.flags & TRACER_BRANCHOUTPUT));
+}
+
+static ssize_t trace_branch_output_store(struct kobject *kobj,
+                                        struct kobj_attribute *attr,
+                                        const char *buf, size_t n)
+{
+       unsigned int branch_output;
+
+       if (sscanf(buf, "%u", &branch_output) != 1)
+               return -EINVAL;
+
+       mutex_lock(&tracer.mutex);
+       if (branch_output) {
+               tracer.flags |= TRACER_BRANCHOUTPUT;
+               /* Branch broadcasting is incompatible with the return stack */
+               tracer.flags &= ~TRACER_RETURN_STACK;
+       } else {
+               tracer.flags &= ~TRACER_BRANCHOUTPUT;
+       }
+       mutex_unlock(&tracer.mutex);
+
+       return n;
+}
+
+static struct kobj_attribute trace_branch_output_attr =
+       __ATTR(trace_branch_output, 0644,
+               trace_branch_output_show, trace_branch_output_store);
+
+static ssize_t trace_return_stack_show(struct kobject *kobj,
+                                 struct kobj_attribute *attr,
+                                 char *buf)
+{
+       return sprintf(buf, "%d\n", !!(tracer.flags & TRACER_RETURN_STACK));
+}
+
+static ssize_t trace_return_stack_store(struct kobject *kobj,
+                                  struct kobj_attribute *attr,
+                                  const char *buf, size_t n)
+{
+       unsigned int return_stack;
+
+       if (sscanf(buf, "%u", &return_stack) != 1)
+               return -EINVAL;
+
+       mutex_lock(&tracer.mutex);
+       if (return_stack) {
+               tracer.flags |= TRACER_RETURN_STACK;
+               /* Return stack is incompatible with branch broadcasting */
+               tracer.flags &= ~TRACER_BRANCHOUTPUT;
+       } else {
+               tracer.flags &= ~TRACER_RETURN_STACK;
+       }
+       mutex_unlock(&tracer.mutex);
+
+       return n;
+}
+
+static struct kobj_attribute trace_return_stack_attr =
+       __ATTR(trace_return_stack, 0644,
+               trace_return_stack_show, trace_return_stack_store);
+
+static ssize_t trace_timestamp_show(struct kobject *kobj,
+                                 struct kobj_attribute *attr,
+                                 char *buf)
+{
+       return sprintf(buf, "%d\n", !!(tracer.flags & TRACER_TIMESTAMP));
+}
+
+static ssize_t trace_timestamp_store(struct kobject *kobj,
+                                  struct kobj_attribute *attr,
+                                  const char *buf, size_t n)
+{
+       unsigned int timestamp;
+
+       if (sscanf(buf, "%u", &timestamp) != 1)
+               return -EINVAL;
+
+       mutex_lock(&tracer.mutex);
+       if (timestamp)
+               tracer.flags |= TRACER_TIMESTAMP;
+       else
+               tracer.flags &= ~TRACER_TIMESTAMP;
+       mutex_unlock(&tracer.mutex);
+
+       return n;
+}
+
+static struct kobj_attribute trace_timestamp_attr =
+       __ATTR(trace_timestamp, 0644,
+               trace_timestamp_show, trace_timestamp_store);
+
+static ssize_t trace_range_show(struct kobject *kobj,
+                                 struct kobj_attribute *attr,
+                                 char *buf)
+{
+       return sprintf(buf, "%08lx %08lx\n",
+                       tracer.range_start, tracer.range_end);
+}
+
+static ssize_t trace_range_store(struct kobject *kobj,
+                                  struct kobj_attribute *attr,
+                                  const char *buf, size_t n)
+{
+       unsigned long range_start, range_end;
+
+       if (sscanf(buf, "%lx %lx", &range_start, &range_end) != 2)
+               return -EINVAL;
+
+       mutex_lock(&tracer.mutex);
+       tracer.range_start = range_start;
+       tracer.range_end = range_end;
+       mutex_unlock(&tracer.mutex);
+
+       return n;
+}
+
+
+static struct kobj_attribute trace_range_attr =
+       __ATTR(trace_range, 0644, trace_range_show, trace_range_store);
+
+static ssize_t trace_data_range_show(struct kobject *kobj,
+                                 struct kobj_attribute *attr,
+                                 char *buf)
+{
+       unsigned long range_start;
+       u64 range_end;
+       mutex_lock(&tracer.mutex);
+       range_start = tracer.data_range_start;
+       range_end = tracer.data_range_end;
+       if (!range_end && (tracer.flags & TRACER_TRACE_DATA))
+               range_end = 0x100000000ULL;
+       mutex_unlock(&tracer.mutex);
+       return sprintf(buf, "%08lx %08llx\n", range_start, range_end);
+}
+
+static ssize_t trace_data_range_store(struct kobject *kobj,
+                                  struct kobj_attribute *attr,
+                                  const char *buf, size_t n)
+{
+       unsigned long range_start;
+       u64 range_end;
+
+       if (sscanf(buf, "%lx %llx", &range_start, &range_end) != 2)
+               return -EINVAL;
+
+       mutex_lock(&tracer.mutex);
+       tracer.data_range_start = range_start;
+       tracer.data_range_end = (unsigned long)range_end;
+       if (range_end)
+               tracer.flags |= TRACER_TRACE_DATA;
+       else
+               tracer.flags &= ~TRACER_TRACE_DATA;
+       mutex_unlock(&tracer.mutex);
+
+       return n;
+}
+
+
+static struct kobj_attribute trace_data_range_attr =
+       __ATTR(trace_data_range, 0644,
+               trace_data_range_show, trace_data_range_store);
+
 static int etm_probe(struct amba_device *dev, const struct amba_id *id)
 {
        struct tracectx *t = &tracer;
        int ret = 0;
+       void __iomem **new_regs;
+       int new_count;
+       u32 etmccr;
+       u32 etmidr;
+       u32 etmccer = 0;
+       u8 etm_version = 0;
+
+       mutex_lock(&t->mutex);
+       new_count = t->etm_regs_count + 1;
+       new_regs = krealloc(t->etm_regs,
+                               sizeof(t->etm_regs[0]) * new_count, GFP_KERNEL);
 
-       if (t->etm_regs) {
-               dev_dbg(&dev->dev, "ETM already initialized\n");
-               ret = -EBUSY;
+       if (!new_regs) {
+               dev_dbg(&dev->dev, "Failed to allocate ETM register array\n");
+               ret = -ENOMEM;
                goto out;
        }
+       t->etm_regs = new_regs;
 
        ret = amba_request_regions(dev, NULL);
        if (ret)
                goto out;
 
-       t->etm_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res));
-       if (!t->etm_regs) {
+       t->etm_regs[t->etm_regs_count] =
+               ioremap_nocache(dev->res.start, resource_size(&dev->res));
+       if (!t->etm_regs[t->etm_regs_count]) {
                ret = -ENOMEM;
                goto out_release;
        }
 
-       amba_set_drvdata(dev, t);
+       amba_set_drvdata(dev, t->etm_regs[t->etm_regs_count]);
 
-       mutex_init(&t->mutex);
-       t->dev = &dev->dev;
-       t->flags = TRACER_CYCLE_ACC;
+       t->flags = TRACER_CYCLE_ACC | TRACER_TRACE_DATA | TRACER_BRANCHOUTPUT;
        t->etm_portsz = 1;
+       t->etm_contextid_size = 3;
 
-       etm_unlock(t);
-       (void)etm_readl(t, ETMMR_PDSR);
+       etm_unlock(t, t->etm_regs_count);
+       (void)etm_readl(t, t->etm_regs_count, ETMMR_PDSR);
        /* dummy first read */
-       (void)etm_readl(&tracer, ETMMR_OSSRR);
-
-       t->ncmppairs = etm_readl(t, ETMR_CONFCODE) & 0xf;
-       etm_writel(t, 0x440, ETMR_CTRL);
-       etm_lock(t);
+       (void)etm_readl(&tracer, t->etm_regs_count, ETMMR_OSSRR);
+
+       etmccr = etm_readl(t, t->etm_regs_count, ETMR_CONFCODE);
+       t->ncmppairs = etmccr & 0xf;
+       if (etmccr & ETMCCR_ETMIDR_PRESENT) {
+               etmidr = etm_readl(t, t->etm_regs_count, ETMR_ID);
+               etm_version = ETMIDR_VERSION(etmidr);
+               if (etm_version >= ETMIDR_VERSION_3_1)
+                       etmccer = etm_readl(t, t->etm_regs_count, ETMR_CCE);
+       }
+       etm_writel(t, t->etm_regs_count, 0x441, ETMR_CTRL);
+       etm_writel(t, t->etm_regs_count, new_count, ETMR_TRACEIDR);
+       etm_lock(t, t->etm_regs_count);
 
        ret = sysfs_create_file(&dev->dev.kobj,
                        &trace_running_attr.attr);
@@ -579,32 +924,97 @@ static int etm_probe(struct amba_device *dev, const struct amba_id *id)
        if (ret)
                dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n");
 
-       dev_dbg(t->dev, "ETM AMBA driver initialized.\n");
+       ret = sysfs_create_file(&dev->dev.kobj,
+                               &trace_contextid_size_attr.attr);
+       if (ret)
+               dev_dbg(&dev->dev,
+                       "Failed to create trace_contextid_size in sysfs\n");
+
+       ret = sysfs_create_file(&dev->dev.kobj,
+                               &trace_branch_output_attr.attr);
+       if (ret)
+               dev_dbg(&dev->dev,
+                       "Failed to create trace_branch_output in sysfs\n");
+
+       if (etmccer & ETMCCER_RETURN_STACK_IMPLEMENTED) {
+               ret = sysfs_create_file(&dev->dev.kobj,
+                                       &trace_return_stack_attr.attr);
+               if (ret)
+                       dev_dbg(&dev->dev,
+                             "Failed to create trace_return_stack in sysfs\n");
+       }
+
+       if (etmccer & ETMCCER_TIMESTAMPING_IMPLEMENTED) {
+               ret = sysfs_create_file(&dev->dev.kobj,
+                                       &trace_timestamp_attr.attr);
+               if (ret)
+                       dev_dbg(&dev->dev,
+                               "Failed to create trace_timestamp in sysfs\n");
+       }
+
+       ret = sysfs_create_file(&dev->dev.kobj, &trace_range_attr.attr);
+       if (ret)
+               dev_dbg(&dev->dev, "Failed to create trace_range in sysfs\n");
+
+       if (etm_version < ETMIDR_VERSION_PFT_1_0) {
+               ret = sysfs_create_file(&dev->dev.kobj,
+                                       &trace_data_range_attr.attr);
+               if (ret)
+                       dev_dbg(&dev->dev,
+                               "Failed to create trace_data_range in sysfs\n");
+       } else {
+               tracer.flags &= ~TRACER_TRACE_DATA;
+       }
+
+       dev_dbg(&dev->dev, "ETM AMBA driver initialized.\n");
+
+       /* Enable formatter if there are multiple trace sources */
+       if (new_count > 1)
+               t->etb_fc = ETBFF_ENFCONT | ETBFF_ENFTC;
+
+       t->etm_regs_count = new_count;
 
 out:
+       mutex_unlock(&t->mutex);
        return ret;
 
 out_unmap:
-       iounmap(t->etm_regs);
+       iounmap(t->etm_regs[t->etm_regs_count]);
 
 out_release:
        amba_release_regions(dev);
 
+       mutex_unlock(&t->mutex);
        return ret;
 }
 
 static int etm_remove(struct amba_device *dev)
 {
-       struct tracectx *t = amba_get_drvdata(dev);
-
-       iounmap(t->etm_regs);
-       t->etm_regs = NULL;
-
-       amba_release_regions(dev);
+       int i;
+       struct tracectx *t = &tracer;
+       void __iomem    *etm_regs = amba_get_drvdata(dev);
 
        sysfs_remove_file(&dev->dev.kobj, &trace_running_attr.attr);
        sysfs_remove_file(&dev->dev.kobj, &trace_info_attr.attr);
        sysfs_remove_file(&dev->dev.kobj, &trace_mode_attr.attr);
+       sysfs_remove_file(&dev->dev.kobj, &trace_range_attr.attr);
+       sysfs_remove_file(&dev->dev.kobj, &trace_data_range_attr.attr);
+
+       mutex_lock(&t->mutex);
+       for (i = 0; i < t->etm_regs_count; i++)
+               if (t->etm_regs[i] == etm_regs)
+                       break;
+       for (; i < t->etm_regs_count - 1; i++)
+               t->etm_regs[i] = t->etm_regs[i + 1];
+       t->etm_regs_count--;
+       if (!t->etm_regs_count) {
+               kfree(t->etm_regs);
+               t->etm_regs = NULL;
+       }
+       mutex_unlock(&t->mutex);
+
+       iounmap(etm_regs);
+       amba_release_regions(dev);
 
        return 0;
 }
@@ -614,6 +1024,10 @@ static struct amba_id etm_ids[] = {
                .id     = 0x0003b921,
                .mask   = 0x0007ffff,
        },
+       {
+               .id     = 0x0003b950,
+               .mask   = 0x0007ffff,
+       },
        { 0, 0 },
 };
 
@@ -631,6 +1045,8 @@ static int __init etm_init(void)
 {
        int retval;
 
+       mutex_init(&tracer.mutex);
+
        retval = amba_driver_register(&etb_driver);
        if (retval) {
                printk(KERN_ERR "Failed to register etb\n");
index 778c2f7024ff57304227ce67665e749f39b05fc7..b321c8fbb87dc8d68b60712c6f74c5d306ca8777 100644 (file)
@@ -144,6 +144,8 @@ int kgdb_arch_handle_exception(int exception_vector, int signo,
 
 static int kgdb_brk_fn(struct pt_regs *regs, unsigned int instr)
 {
+       if (user_mode(regs))
+               return -1;
        kgdb_handle_exception(1, SIGTRAP, 0, regs);
 
        return 0;
@@ -151,6 +153,8 @@ static int kgdb_brk_fn(struct pt_regs *regs, unsigned int instr)
 
 static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr)
 {
+       if (user_mode(regs))
+               return -1;
        compiled_break = 1;
        kgdb_handle_exception(1, SIGTRAP, 0, regs);
 
index 5f6e650ec9abceb1b5dbf4151f11c4b4103a69f5..ed1a0af96b66a9e0a6397f4835585e290015de5f 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/cpuidle.h>
 #include <linux/leds.h>
 #include <linux/reboot.h>
+#include <linux/console.h>
 
 #include <asm/cacheflush.h>
 #include <asm/idmap.h>
@@ -59,9 +60,46 @@ static const char *isa_modes[] = {
   "ARM" , "Thumb" , "Jazelle", "ThumbEE"
 };
 
+#ifdef CONFIG_SMP
+void arch_trigger_all_cpu_backtrace(void)
+{
+       smp_send_all_cpu_backtrace();
+}
+#else
+void arch_trigger_all_cpu_backtrace(void)
+{
+       dump_stack();
+}
+#endif
+
 extern void call_with_stack(void (*fn)(void *), void *arg, void *sp);
 typedef void (*phys_reset_t)(unsigned long);
 
+#ifdef CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART
+void arm_machine_flush_console(void)
+{
+       printk("\n");
+       pr_emerg("Restarting %s\n", linux_banner);
+       if (console_trylock()) {
+               console_unlock();
+               return;
+       }
+
+       mdelay(50);
+
+       local_irq_disable();
+       if (!console_trylock())
+               pr_emerg("arm_restart: Console was locked! Busting\n");
+       else
+               pr_emerg("arm_restart: Console was locked!\n");
+       console_unlock();
+}
+#else
+void arm_machine_flush_console(void)
+{
+}
+#endif
+
 /*
  * A temporary stack to use for CPU reset. This is static so that we
  * don't clobber it with the identity mapping. When running with this
@@ -149,6 +187,7 @@ void arch_cpu_idle_prepare(void)
 
 void arch_cpu_idle_enter(void)
 {
+       idle_notifier_call_chain(IDLE_START);
        ledtrig_cpu(CPU_LED_IDLE_START);
 #ifdef CONFIG_PL310_ERRATA_769419
        wmb();
@@ -158,6 +197,7 @@ void arch_cpu_idle_enter(void)
 void arch_cpu_idle_exit(void)
 {
        ledtrig_cpu(CPU_LED_IDLE_END);
+       idle_notifier_call_chain(IDLE_END);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -187,6 +227,16 @@ void arch_cpu_idle(void)
  */
 void machine_shutdown(void)
 {
+#ifdef CONFIG_SMP
+       /*
+        * Disable preemption so we're guaranteed to
+        * run to power off or reboot and prevent
+        * the possibility of switching to another
+        * thread that might wind up blocking on
+        * one of the stopped CPUs.
+        */
+       preempt_disable();
+#endif
        disable_nonboot_cpus();
 }
 
@@ -235,6 +285,10 @@ void machine_restart(char *cmd)
        local_irq_disable();
        smp_send_stop();
 
+       /* Flush the console to make sure all the relevant messages make it
+        * out to the console drivers */
+       arm_machine_flush_console();
+
        arm_pm_restart(reboot_mode, cmd);
 
        /* Give a grace period for failure to restart of 1s */
@@ -246,6 +300,77 @@ void machine_restart(char *cmd)
        while (1);
 }
 
+/*
+ * dump a block of kernel memory from around the given address
+ */
+static void show_data(unsigned long addr, int nbytes, const char *name)
+{
+       int     i, j;
+       int     nlines;
+       u32     *p;
+
+       /*
+        * don't attempt to dump non-kernel addresses or
+        * values that are probably just small negative numbers
+        */
+       if (addr < PAGE_OFFSET || addr > -256UL)
+               return;
+
+       printk("\n%s: %#lx:\n", name, addr);
+
+       /*
+        * round address down to a 32 bit boundary
+        * and always dump a multiple of 32 bytes
+        */
+       p = (u32 *)(addr & ~(sizeof(u32) - 1));
+       nbytes += (addr & (sizeof(u32) - 1));
+       nlines = (nbytes + 31) / 32;
+
+
+       for (i = 0; i < nlines; i++) {
+               /*
+                * just display low 16 bits of address to keep
+                * each line of the dump < 80 characters
+                */
+               printk("%04lx ", (unsigned long)p & 0xffff);
+               for (j = 0; j < 8; j++) {
+                       u32     data;
+                       if (probe_kernel_address(p, data)) {
+                               printk(" ********");
+                       } else {
+                               printk(" %08x", data);
+                       }
+                       ++p;
+               }
+               printk("\n");
+       }
+}
+
+static void show_extra_register_data(struct pt_regs *regs, int nbytes)
+{
+       mm_segment_t fs;
+
+       fs = get_fs();
+       set_fs(KERNEL_DS);
+       show_data(regs->ARM_pc - nbytes, nbytes * 2, "PC");
+       show_data(regs->ARM_lr - nbytes, nbytes * 2, "LR");
+       show_data(regs->ARM_sp - nbytes, nbytes * 2, "SP");
+       show_data(regs->ARM_ip - nbytes, nbytes * 2, "IP");
+       show_data(regs->ARM_fp - nbytes, nbytes * 2, "FP");
+       show_data(regs->ARM_r0 - nbytes, nbytes * 2, "R0");
+       show_data(regs->ARM_r1 - nbytes, nbytes * 2, "R1");
+       show_data(regs->ARM_r2 - nbytes, nbytes * 2, "R2");
+       show_data(regs->ARM_r3 - nbytes, nbytes * 2, "R3");
+       show_data(regs->ARM_r4 - nbytes, nbytes * 2, "R4");
+       show_data(regs->ARM_r5 - nbytes, nbytes * 2, "R5");
+       show_data(regs->ARM_r6 - nbytes, nbytes * 2, "R6");
+       show_data(regs->ARM_r7 - nbytes, nbytes * 2, "R7");
+       show_data(regs->ARM_r8 - nbytes, nbytes * 2, "R8");
+       show_data(regs->ARM_r9 - nbytes, nbytes * 2, "R9");
+       show_data(regs->ARM_r10 - nbytes, nbytes * 2, "R10");
+       set_fs(fs);
+}
+
 void __show_regs(struct pt_regs *regs)
 {
        unsigned long flags;
@@ -302,6 +427,8 @@ void __show_regs(struct pt_regs *regs)
                printk("Control: %08x%s\n", ctrl, buf);
        }
 #endif
+
+       show_extra_register_data(regs, 128);
 }
 
 void show_regs(struct pt_regs * regs)
index 0dd3b79b15c3d90f0ad54f52d4240392fb51258e..0c27ed6f3f2346e9bd9c13a8cea1265536572ba5 100644 (file)
@@ -908,7 +908,7 @@ enum ptrace_syscall_dir {
        PTRACE_SYSCALL_EXIT,
 };
 
-static int tracehook_report_syscall(struct pt_regs *regs,
+static void tracehook_report_syscall(struct pt_regs *regs,
                                    enum ptrace_syscall_dir dir)
 {
        unsigned long ip;
@@ -926,7 +926,6 @@ static int tracehook_report_syscall(struct pt_regs *regs,
                current_thread_info()->syscall = -1;
 
        regs->ARM_ip = ip;
-       return current_thread_info()->syscall;
 }
 
 asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
@@ -938,7 +937,9 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
                return -1;
 
        if (test_thread_flag(TIF_SYSCALL_TRACE))
-               scno = tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
+               tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
+
+       scno = current_thread_info()->syscall;
 
        if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
                trace_sys_enter(regs, scno);
index 8cd3724714fe980366285e2c0d78608be475fbfd..0bd8b58e2047e3f1bca77c20fa30399ea38e0ed8 100644 (file)
@@ -69,6 +69,7 @@ enum ipi_msg_type {
        IPI_CPU_STOP,
        IPI_IRQ_WORK,
        IPI_COMPLETION,
+       IPI_CPU_BACKTRACE,
 };
 
 static DECLARE_COMPLETION(cpu_running);
@@ -480,6 +481,7 @@ static const char *ipi_types[NR_IPI] = {
        S(IPI_CPU_STOP, "CPU stop interrupts"),
        S(IPI_IRQ_WORK, "IRQ work interrupts"),
        S(IPI_COMPLETION, "completion interrupts"),
+       S(IPI_CPU_BACKTRACE, "CPU backtrace"),
 };
 
 void show_ipi_list(struct seq_file *p, int prec)
@@ -552,6 +554,58 @@ static void ipi_complete(unsigned int cpu)
        complete(per_cpu(cpu_completion, cpu));
 }
 
+static cpumask_t backtrace_mask;
+static DEFINE_RAW_SPINLOCK(backtrace_lock);
+
+/* "in progress" flag of arch_trigger_all_cpu_backtrace */
+static unsigned long backtrace_flag;
+
+void smp_send_all_cpu_backtrace(void)
+{
+       unsigned int this_cpu = smp_processor_id();
+       int i;
+
+       if (test_and_set_bit(0, &backtrace_flag))
+               /*
+                * If there is already a trigger_all_cpu_backtrace() in progress
+                * (backtrace_flag == 1), don't output double cpu dump infos.
+                */
+               return;
+
+       cpumask_copy(&backtrace_mask, cpu_online_mask);
+       cpu_clear(this_cpu, backtrace_mask);
+
+       pr_info("Backtrace for cpu %d (current):\n", this_cpu);
+       dump_stack();
+
+       pr_info("\nsending IPI to all other CPUs:\n");
+       smp_cross_call(&backtrace_mask, IPI_CPU_BACKTRACE);
+
+       /* Wait for up to 10 seconds for all other CPUs to do the backtrace */
+       for (i = 0; i < 10 * 1000; i++) {
+               if (cpumask_empty(&backtrace_mask))
+                       break;
+               mdelay(1);
+       }
+
+       clear_bit(0, &backtrace_flag);
+       smp_mb__after_clear_bit();
+}
+
+/*
+ * ipi_cpu_backtrace - handle IPI from smp_send_all_cpu_backtrace()
+ */
+static void ipi_cpu_backtrace(unsigned int cpu, struct pt_regs *regs)
+{
+       if (cpu_isset(cpu, backtrace_mask)) {
+               raw_spin_lock(&backtrace_lock);
+               pr_warning("IPI backtrace for cpu %d\n", cpu);
+               show_regs(regs);
+               raw_spin_unlock(&backtrace_lock);
+               cpu_clear(cpu, backtrace_mask);
+       }
+}
+
 /*
  * Main handler for inter-processor interrupts
  */
@@ -616,6 +670,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
                irq_exit();
                break;
 
+       case IPI_CPU_BACKTRACE:
+               ipi_cpu_backtrace(cpu, regs);
+               break;
+
        default:
                printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n",
                       cpu, ipinr);
index dde2be2cb1b04c669c9afc8fedf7ddfcb8599dac..2acbaa89d2be5118c6927af86f5a9b177ca0235d 100644 (file)
@@ -239,6 +239,25 @@ MACHINE_END
 #endif
 
 #ifdef CONFIG_SOC_DRA7XX
+
+static const char *x15_android_compat[] __initconst = {
+       "ti,am572x-beagle-x15",
+       NULL,
+};
+
+DT_MACHINE_START(DRA74X_X15_DT, "Beagle X15 Board")
+       .reserve        = omap_reserve,
+       .smp            = smp_ops(omap4_smp_ops),
+       .map_io         = omap5_map_io,
+       .init_early     = dra7xx_init_early,
+       .init_late      = dra7xx_init_late,
+       .init_irq       = omap_gic_of_init,
+       .init_machine   = omap_generic_init,
+       .init_time      = omap5_realtime_timer_init,
+       .dt_compat      = x15_android_compat,
+       .restart        = omap44xx_restart,
+MACHINE_END
+
 static const char *dra74x_boards_compat[] __initconst = {
        "ti,am5728",
        "ti,am5726",
@@ -247,7 +266,7 @@ static const char *dra74x_boards_compat[] __initconst = {
        NULL,
 };
 
-DT_MACHINE_START(DRA74X_DT, "Generic DRA74X (Flattened Device Tree)")
+DT_MACHINE_START(DRA74X_DT, "Jacinto6 evm board")
        .reserve        = omap_reserve,
        .smp            = smp_ops(omap4_smp_ops),
        .map_io         = omap5_map_io,
@@ -267,7 +286,7 @@ static const char *dra72x_boards_compat[] __initconst = {
        NULL,
 };
 
-DT_MACHINE_START(DRA72X_DT, "Generic DRA72X (Flattened Device Tree)")
+DT_MACHINE_START(DRA72X_DT, "Jacinto6 evm board")
        .reserve        = omap_reserve,
        .map_io         = omap5_map_io,
        .init_early     = dra7xx_init_early,
index 7abde2ce897336939c24ffd02434b462ae8c938d..d96d5bd520e1d3bc7e56296e9ff6846915222855 100644 (file)
@@ -34,6 +34,9 @@ static void __iomem *l2x0_base;
 static DEFINE_RAW_SPINLOCK(l2x0_lock);
 static u32 l2x0_way_mask;      /* Bitmask of active ways */
 static u32 l2x0_size;
+static u32 l2x0_cache_id;
+static unsigned int l2x0_sets;
+static unsigned int l2x0_ways;
 static unsigned long sync_reg_offset = L2X0_CACHE_SYNC;
 
 /* Aurora don't have the cache ID register available, so we have to
@@ -50,6 +53,13 @@ struct l2x0_of_data {
 
 static bool of_init = false;
 
+static inline bool is_pl310_rev(int rev)
+{
+       return (l2x0_cache_id &
+               (L2X0_CACHE_ID_PART_MASK | L2X0_CACHE_ID_REV_MASK)) ==
+                       (L2X0_CACHE_ID_PART_L310 | rev);
+}
+
 static inline void cache_wait_way(void __iomem *reg, unsigned long mask)
 {
        /* wait for cache operation by line or way to complete */
@@ -138,6 +148,23 @@ static void l2x0_cache_sync(void)
        raw_spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
+#ifdef CONFIG_PL310_ERRATA_727915
+static void l2x0_for_each_set_way(void __iomem *reg)
+{
+       int set;
+       int way;
+       unsigned long flags;
+
+       for (way = 0; way < l2x0_ways; way++) {
+               raw_spin_lock_irqsave(&l2x0_lock, flags);
+               for (set = 0; set < l2x0_sets; set++)
+                       writel_relaxed((way << 28) | (set << 5), reg);
+               cache_sync();
+               raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+       }
+}
+#endif
+
 static void __l2x0_flush_all(void)
 {
        debug_writel(0x03);
@@ -151,6 +178,13 @@ static void l2x0_flush_all(void)
 {
        unsigned long flags;
 
+#ifdef CONFIG_PL310_ERRATA_727915
+       if (is_pl310_rev(REV_PL310_R2P0)) {
+               l2x0_for_each_set_way(l2x0_base + L2X0_CLEAN_INV_LINE_IDX);
+               return;
+       }
+#endif
+
        /* clean all ways */
        raw_spin_lock_irqsave(&l2x0_lock, flags);
        __l2x0_flush_all();
@@ -161,11 +195,20 @@ static void l2x0_clean_all(void)
 {
        unsigned long flags;
 
+#ifdef CONFIG_PL310_ERRATA_727915
+       if (is_pl310_rev(REV_PL310_R2P0)) {
+               l2x0_for_each_set_way(l2x0_base + L2X0_CLEAN_LINE_IDX);
+               return;
+       }
+#endif
+
        /* clean all ways */
        raw_spin_lock_irqsave(&l2x0_lock, flags);
+       debug_writel(0x03);
        writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_WAY);
        cache_wait_way(l2x0_base + L2X0_CLEAN_WAY, l2x0_way_mask);
        cache_sync();
+       debug_writel(0x00);
        raw_spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
@@ -324,65 +367,64 @@ static void l2x0_unlock(u32 cache_id)
 void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
 {
        u32 aux;
-       u32 cache_id;
        u32 way_size = 0;
-       int ways;
        int way_size_shift = L2X0_WAY_SIZE_SHIFT;
        const char *type;
 
        l2x0_base = base;
        if (cache_id_part_number_from_dt)
-               cache_id = cache_id_part_number_from_dt;
+               l2x0_cache_id = cache_id_part_number_from_dt;
        else
-               cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
+               l2x0_cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
        aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
 
        aux &= aux_mask;
        aux |= aux_val;
 
        /* Determine the number of ways */
-       switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
+       switch (l2x0_cache_id & L2X0_CACHE_ID_PART_MASK) {
        case L2X0_CACHE_ID_PART_L310:
                if (aux & (1 << 16))
-                       ways = 16;
+                       l2x0_ways = 16;
                else
-                       ways = 8;
+                       l2x0_ways = 8;
                type = "L310";
 #ifdef CONFIG_PL310_ERRATA_753970
                /* Unmapped register. */
                sync_reg_offset = L2X0_DUMMY_REG;
 #endif
-               if ((cache_id & L2X0_CACHE_ID_RTL_MASK) <= L2X0_CACHE_ID_RTL_R3P0)
+               if ((l2x0_cache_id & L2X0_CACHE_ID_RTL_MASK) <= L2X0_CACHE_ID_RTL_R3P0)
                        outer_cache.set_debug = pl310_set_debug;
                break;
        case L2X0_CACHE_ID_PART_L210:
-               ways = (aux >> 13) & 0xf;
+               l2x0_ways = (aux >> 13) & 0xf;
                type = "L210";
                break;
 
        case AURORA_CACHE_ID:
                sync_reg_offset = AURORA_SYNC_REG;
-               ways = (aux >> 13) & 0xf;
-               ways = 2 << ((ways + 1) >> 2);
+               l2x0_ways = (aux >> 13) & 0xf;
+               l2x0_ways = 2 << ((l2x0_ways + 1) >> 2);
                way_size_shift = AURORA_WAY_SIZE_SHIFT;
                type = "Aurora";
                break;
        default:
                /* Assume unknown chips have 8 ways */
-               ways = 8;
+               l2x0_ways = 8;
                type = "L2x0 series";
                break;
        }
 
-       l2x0_way_mask = (1 << ways) - 1;
+       l2x0_way_mask = (1 << l2x0_ways) - 1;
 
        /*
         * L2 cache Size =  Way size * Number of ways
         */
        way_size = (aux & L2X0_AUX_CTRL_WAY_SIZE_MASK) >> 17;
-       way_size = 1 << (way_size + way_size_shift);
+       way_size = SZ_1K << (way_size + way_size_shift);
 
-       l2x0_size = ways * way_size * SZ_1K;
+       l2x0_size = l2x0_ways * way_size;
+       l2x0_sets = way_size / CACHE_LINE_SIZE;
 
        /*
         * Check if l2x0 controller is already enabled.
@@ -391,7 +433,7 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
         */
        if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
                /* Make sure that I&D is not locked down when starting */
-               l2x0_unlock(cache_id);
+               l2x0_unlock(l2x0_cache_id);
 
                /* l2x0 controller is disabled */
                writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL);
@@ -420,7 +462,7 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
 
        pr_info("%s cache controller enabled\n", type);
        pr_info("l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d kB\n",
-               ways, cache_id, aux, l2x0_size >> 10);
+               l2x0_ways, l2x0_cache_id, aux, l2x0_size >> 10);
 }
 
 #ifdef CONFIG_OF
index d8fd4d4bd3d45ecdc66ad2c74885795df9681ea7..7a3d3d8d98d7fa384e998d271b1ccbbf5b3de256 100644 (file)
@@ -270,6 +270,11 @@ v6_dma_clean_range:
  *     - end     - virtual end address of region
  */
 ENTRY(v6_dma_flush_range)
+#ifdef CONFIG_CACHE_FLUSH_RANGE_LIMIT
+       sub     r2, r1, r0
+       cmp     r2, #CONFIG_CACHE_FLUSH_RANGE_LIMIT
+       bhi     v6_dma_flush_dcache_all
+#endif
 #ifdef CONFIG_DMA_CACHE_RWFO
        ldrb    r2, [r0]                @ read for ownership
        strb    r2, [r0]                @ write for ownership
@@ -292,6 +297,18 @@ ENTRY(v6_dma_flush_range)
        mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
        mov     pc, lr
 
+#ifdef CONFIG_CACHE_FLUSH_RANGE_LIMIT
+v6_dma_flush_dcache_all:
+       mov     r0, #0
+#ifdef HARVARD_CACHE
+       mcr     p15, 0, r0, c7, c14, 0          @ D cache clean+invalidate
+#else
+       mcr     p15, 0, r0, c7, c15, 0          @ Cache clean+invalidate
+#endif
+       mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
+       mov     pc, lr
+#endif
+
 /*
  *     dma_map_area(start, size, dir)
  *     - start - kernel virtual start address
index eb8830a4c5edeb8c1be7b9fa396cc100f020af42..b784579545e85e8e48a68729fa258fc7e9001643 100644 (file)
@@ -274,10 +274,10 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
                local_irq_enable();
 
        /*
-        * If we're in an interrupt or have no user
+        * If we're in an interrupt, or have no irqs, or have no user
         * context, we must not take the fault..
         */
-       if (in_atomic() || !mm)
+       if (in_atomic() || irqs_disabled() || !mm)
                goto no_context;
 
        if (user_mode(regs))
index f15c22e8bcd5a4228fbf29010568d54567f4cf1b..4bd2f2c38f5626da5046f5f7abb713442424580d 100644 (file)
@@ -1069,6 +1069,29 @@ void __init sanity_check_meminfo(void)
                phys_addr_t size_limit;
 
                *bank = meminfo.bank[i];
+
+#ifdef CONFIG_SPARSEMEM
+               if (pfn_to_section_nr(bank_pfn_start(bank)) !=
+                   pfn_to_section_nr(bank_pfn_end(bank) - 1)) {
+                       phys_addr_t sz;
+                       unsigned long start_pfn = bank_pfn_start(bank);
+                       unsigned long end_pfn = SECTION_ALIGN_UP(start_pfn + 1);
+                       sz = ((phys_addr_t)(end_pfn - start_pfn) << PAGE_SHIFT);
+
+                       if (meminfo.nr_banks >= NR_BANKS) {
+                               pr_crit("NR_BANKS too low, ignoring %lld bytes of memory\n",
+                                       (unsigned long long)(bank->size - sz));
+                       } else {
+                               memmove(bank + 1, bank,
+                                       (meminfo.nr_banks - i) * sizeof(*bank));
+                               meminfo.nr_banks++;
+                               bank[1].size -= sz;
+                               bank[1].start = __pfn_to_phys(end_pfn);
+                       }
+                       bank->size = sz;
+               }
+#endif
+
                size_limit = bank->size;
 
                if (bank->start >= vmalloc_limit)
index 76df876ad6947e84abc69f84726320af1b8f80f5..aa411187e6fa72aeeaa634f906f4cabf34cb42c9 100644 (file)
@@ -10,6 +10,7 @@ config ARM64
        select ARM_AMBA
        select ARM_ARCH_TIMER
        select ARM_GIC
+       select AUDIT_ARCH_COMPAT_GENERIC
        select BUILDTIME_EXTABLE_SORT
        select CLONE_BACKWARDS
        select COMMON_CLK
@@ -17,6 +18,7 @@ config ARM64
        select DCACHE_WORD_ACCESS
        select GENERIC_CLOCKEVENTS
        select GENERIC_CLOCKEVENTS_BROADCAST if SMP
+       select GENERIC_CPU_AUTOPROBE
        select GENERIC_IOMAP
        select GENERIC_IRQ_PROBE
        select GENERIC_IRQ_SHOW
@@ -26,7 +28,9 @@ config ARM64
        select GENERIC_STRNLEN_USER
        select GENERIC_TIME_VSYSCALL
        select HARDIRQS_SW_RESEND
+       select HAVE_ARCH_AUDITSYSCALL
        select HAVE_ARCH_JUMP_LABEL
+       select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_TRACEHOOK
        select HAVE_DEBUG_BUGVERBOSE
        select HAVE_DEBUG_KMEMLEAK
@@ -66,6 +70,10 @@ config MMU
 config NO_IOPORT
        def_bool y
 
+config ILLEGAL_POINTER_VALUE
+       hex
+       default 0xdead000000000000
+
 config STACKTRACE_SUPPORT
        def_bool y
 
@@ -222,6 +230,27 @@ config ARCH_WANT_HUGE_PMD_SHARE
 config HAVE_ARCH_TRANSPARENT_HUGEPAGE
        def_bool y
 
+config ARMV7_COMPAT
+       bool "Kernel support for ARMv7 applications"
+       depends on COMPAT
+       select SWP_EMULATE
+       help
+        This option enables features that allow that ran on an ARMv7 or older
+        processor to continue functioning.
+
+        If you want to execute ARMv7 applications, say Y
+
+config ARMV7_COMPAT_CPUINFO
+       bool "Report backwards compatible cpu features in /proc/cpuinfo"
+       depends on ARMV7_COMPAT
+       default y
+       help
+        This option makes /proc/cpuinfo list CPU features that an ARMv7 or
+        earlier kernel would report, but are not optional on an ARMv8 or later
+        processor.
+
+        If you want to execute ARMv7 applications, say Y
+
 source "mm/Kconfig"
 
 config XEN_DOM0
@@ -240,6 +269,87 @@ config FORCE_MAX_ZONEORDER
        default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
        default "11"
 
+config SECCOMP
+       bool "Enable seccomp to safely compute untrusted bytecode"
+       ---help---
+         This kernel feature is useful for number crunching applications
+         that may need to compute untrusted bytecode during their
+         execution. By using pipes or other transports made available to
+         the process as file descriptors supporting the read/write
+         syscalls, it's possible to isolate those applications in
+         their own address space using seccomp. Once seccomp is
+         enabled via prctl(PR_SET_SECCOMP), it cannot be disabled
+         and the task is only allowed to execute a few safe syscalls
+         defined by each seccomp mode.
+
+menuconfig ARMV8_DEPRECATED
+       bool "Emulate deprecated/obsolete ARMv8 instructions"
+       depends on COMPAT
+       help
+         Legacy software support may require certain instructions
+         that have been deprecated or obsoleted in the architecture.
+
+         Enable this config to enable selective emulation of these
+         features.
+
+         If unsure, say Y
+
+if ARMV8_DEPRECATED
+
+config SWP_EMULATION
+       bool "Emulate SWP/SWPB instructions"
+       help
+         ARMv8 obsoletes the use of A32 SWP/SWPB instructions such that
+         they are always undefined. Say Y here to enable software
+         emulation of these instructions for userspace using LDXR/STXR.
+
+         In some older versions of glibc [<=2.8] SWP is used during futex
+         trylock() operations with the assumption that the code will not
+         be preempted. This invalid assumption may be more likely to fail
+         with SWP emulation enabled, leading to deadlock of the user
+         application.
+
+         NOTE: when accessing uncached shared regions, LDXR/STXR rely
+         on an external transaction monitoring block called a global
+         monitor to maintain update atomicity. If your system does not
+         implement a global monitor, this option can cause programs that
+         perform SWP operations to uncached memory to deadlock.
+
+         If unsure, say Y
+
+config CP15_BARRIER_EMULATION
+       bool "Emulate CP15 Barrier instructions"
+       help
+         The CP15 barrier instructions - CP15ISB, CP15DSB, and
+         CP15DMB - are deprecated in ARMv8 (and ARMv7). It is
+         strongly recommended to use the ISB, DSB, and DMB
+         instructions instead.
+
+         Say Y here to enable software emulation of these
+         instructions for AArch32 userspace code. When this option is
+         enabled, CP15 barrier usage is traced which can help
+         identify software that needs updating.
+
+         If unsure, say Y
+
+config SETEND_EMULATION
+       bool "Emulate SETEND instruction"
+       help
+         The SETEND instruction alters the data-endianness of the
+         AArch32 EL0, and is deprecated in ARMv8.
+
+         Say Y here to enable software emulation of the instruction
+         for AArch32 userspace code.
+
+         Note: All the cpus on the system must have mixed endian support at EL0
+         for this feature to be enabled. If a new CPU - which doesn't support mixed
+         endian - is hotplugged in after this feature has been enabled, there could
+         be unexpected results in the applications.
+
+         If unsure, say Y
+
+endif
+
 endmenu
 
 menu "Boot options"
@@ -252,6 +362,23 @@ config CMDLINE
          entering them here. As a minimum, you should specify the the
          root device (e.g. root=/dev/nfs).
 
+choice
+       prompt "Kernel command line type" if CMDLINE != ""
+       default CMDLINE_FROM_BOOTLOADER
+
+config CMDLINE_FROM_BOOTLOADER
+       bool "Use bootloader kernel arguments if available"
+       help
+         Uses the command-line options passed by the boot loader. If
+         the boot loader doesn't provide any, the default kernel command
+         string provided in CMDLINE will be used.
+
+config CMDLINE_EXTEND
+       bool "Extend bootloader kernel arguments"
+       help
+         The command-line arguments provided by the boot loader will be
+         appended to the default kernel command string.
+
 config CMDLINE_FORCE
        bool "Always use the default kernel command string"
        help
@@ -259,6 +386,22 @@ config CMDLINE_FORCE
          loader passes other arguments to the kernel.
          This is useful if you cannot or don't want to change the
          command-line options your boot&nb