]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge commit 'fc69910f329d' into uaccess.mips
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 6 Apr 2017 06:07:33 +0000 (02:07 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 6 Apr 2017 06:07:33 +0000 (02:07 -0400)
backmerge of a build fix from mainline

115 files changed:
Documentation/admin-guide/kernel-parameters.txt
Documentation/trace/kprobetrace.txt
Documentation/trace/uprobetracer.txt
arch/arm/xen/mm.c
arch/avr32/oprofile/backtrace.c
arch/h8300/kernel/ptrace_h.c
arch/mips/cavium-octeon/cpu.c
arch/mips/cavium-octeon/crypto/octeon-crypto.c
arch/mips/cavium-octeon/smp.c
arch/mips/include/asm/fpu.h
arch/mips/kernel/smp-bmips.c
arch/mips/kernel/smp-mt.c
arch/mips/loongson64/loongson-3/cop2-ex.c
arch/mips/netlogic/common/smp.c
arch/mips/netlogic/xlp/cop2-ex.c
arch/mips/sgi-ip22/ip28-berr.c
arch/mips/sgi-ip27/ip27-berr.c
arch/mips/sgi-ip27/ip27-smp.c
arch/mips/sgi-ip32/ip32-berr.c
arch/mips/sgi-ip32/ip32-reset.c
arch/powerpc/Kconfig
arch/powerpc/Makefile
arch/powerpc/include/asm/checksum.h
arch/powerpc/include/asm/cpuidle.h
arch/powerpc/include/asm/elf.h
arch/powerpc/include/asm/nohash/pgtable.h
arch/powerpc/include/asm/ppc-opcode.h
arch/powerpc/include/asm/prom.h
arch/powerpc/kernel/idle_book3s.S
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/lib/Makefile
arch/powerpc/lib/sstep.c
arch/powerpc/lib/test_emulate_step.c [new file with mode: 0644]
arch/powerpc/mm/init_64.c
arch/powerpc/mm/pgtable-radix.c
arch/powerpc/platforms/powernv/opal-wrappers.S
arch/powerpc/sysdev/xics/icp-opal.c
arch/powerpc/sysdev/xics/xics-common.c
arch/s390/configs/default_defconfig
arch/s390/configs/gcov_defconfig
arch/s390/configs/performance_defconfig
arch/s390/defconfig
arch/x86/configs/x86_64_defconfig
arch/x86/events/amd/core.c
arch/x86/events/intel/cstate.c
arch/x86/events/intel/rapl.c
arch/x86/events/intel/uncore.h
arch/x86/hyperv/hv_init.c
arch/x86/include/asm/pkeys.h
arch/x86/include/uapi/asm/bootparam.h
arch/x86/kernel/apic/apic.c
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/centaur.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/cyrix.c
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
arch/x86/kernel/cpu/transmeta.c
arch/x86/kernel/cpu/vmware.c
arch/x86/kernel/hpet.c
arch/x86/kernel/kdebugfs.c
arch/x86/kernel/kprobes/common.h
arch/x86/kernel/kprobes/core.c
arch/x86/kernel/kprobes/opt.c
arch/x86/kernel/reboot.c
arch/x86/kernel/tsc.c
arch/x86/pci/common.c
arch/x86/platform/uv/tlb_uv.c
arch/x86/purgatory/purgatory.c
arch/x86/purgatory/purgatory.h [new file with mode: 0644]
arch/x86/purgatory/setup-x86_64.S
drivers/acpi/internal.h
drivers/acpi/ioapic.c
drivers/acpi/pci_root.c
drivers/char/nwbutton.c
drivers/firmware/efi/arm-runtime.c
drivers/firmware/efi/libstub/secureboot.c
drivers/irqchip/irq-crossbar.c
drivers/xen/swiotlb-xen.c
fs/timerfd.c
include/linux/jump_label.h
include/linux/user_namespace.h
include/trace/events/syscalls.h
include/xen/swiotlb-xen.h
kernel/locking/lockdep.c
kernel/locking/test-ww_mutex.c
kernel/sched/core.c
kernel/sched/fair.c
kernel/sched/features.h
kernel/time/jiffies.c
kernel/trace/Kconfig
kernel/trace/Makefile
kernel/trace/ftrace.c
kernel/trace/trace.c
kernel/trace/trace_probe.h
kernel/ucount.c
lib/radix-tree.c
lib/refcount.c
scripts/module-common.lds
tools/objtool/builtin-check.c
tools/objtool/elf.c
tools/objtool/elf.h
tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c
tools/testing/radix-tree/Makefile
tools/testing/radix-tree/benchmark.c
tools/testing/radix-tree/idr-test.c
tools/testing/radix-tree/main.c
tools/testing/radix-tree/tag_check.c
tools/testing/radix-tree/test.h
tools/testing/selftests/powerpc/harness.c
tools/testing/selftests/x86/fsgsbase.c
tools/testing/selftests/x86/ldt_gdt.c
tools/testing/selftests/x86/ptrace_syscall.c
tools/testing/selftests/x86/single_step_syscall.c

index 986e44387dad493e268ab93253120df73abc3045..9adcc803b9a54cbd51a63f024cc83cf5cf99a788 100644 (file)
                        functions that can be changed at run time by the
                        set_graph_notrace file in the debugfs tracing directory.
 
+       ftrace_graph_max_depth=<uint>
+                       [FTRACE] Used with the function graph tracer. This is
+                       the max depth it will trace into a function. This value
+                       can be changed at run time by the max_graph_depth file
+                       in the tracefs tracing directory. default: 0 (no limit)
+
        gamecon.map[2|3]=
                        [HW,JOY] Multisystem joystick and NES/SNES/PSX pad
                        support via parallel port (up to 5 devices per port)
index e4991fb1eedcd4efcd258a7b1290fd087e5f9923..41ef9d8efe9517f602e59b21bfe1448196cb3450 100644 (file)
@@ -12,7 +12,7 @@ kprobes can probe (this means, all functions body except for __kprobes
 functions). Unlike the Tracepoint based event, this can be added and removed
 dynamically, on the fly.
 
-To enable this feature, build your kernel with CONFIG_KPROBE_EVENT=y.
+To enable this feature, build your kernel with CONFIG_KPROBE_EVENTS=y.
 
 Similar to the events tracer, this doesn't need to be activated via
 current_tracer. Instead of that, add probe points via
index fa7b680ee8a005acf245ae60aa3404b8e9aaafb7..bf526a7c5559a87829fc05ea5f592d9609ed5f3b 100644 (file)
@@ -7,7 +7,7 @@
 Overview
 --------
 Uprobe based trace events are similar to kprobe based trace events.
-To enable this feature, build your kernel with CONFIG_UPROBE_EVENT=y.
+To enable this feature, build your kernel with CONFIG_UPROBE_EVENTS=y.
 
 Similar to the kprobe-event tracer, this doesn't need to be activated via
 current_tracer. Instead of that, add probe points via
index ce18c91b50a1cbac3fb6d38af60c63af9b031185..f0325d96b97aed734f86deb3a9f5b3266b5a16ed 100644 (file)
@@ -198,6 +198,8 @@ static const struct dma_map_ops xen_swiotlb_dma_ops = {
        .unmap_page = xen_swiotlb_unmap_page,
        .dma_supported = xen_swiotlb_dma_supported,
        .set_dma_mask = xen_swiotlb_set_dma_mask,
+       .mmap = xen_swiotlb_dma_mmap,
+       .get_sgtable = xen_swiotlb_get_sgtable,
 };
 
 int __init xen_mm_init(void)
index 75d9ad6f99cf56e8071eff21157ed3da0dfef4b7..29cf2f191bfd289902c7f29b55ac896c79697944 100644 (file)
@@ -14,7 +14,7 @@
  */
 
 #include <linux/oprofile.h>
-#include <linux/sched.h>
+#include <linux/ptrace.h>
 #include <linux/uaccess.h>
 
 /* The first two words of each frame on the stack look like this if we have
index fe3b5673babaa49428a90c1c56d64abec3d0c871..f5ff3b794c8512ce430812fd07b5c85752294d79 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 #include <linux/linkage.h>
-#include <linux/sched.h>
+#include <linux/sched/signal.h>
 #include <asm/ptrace.h>
 
 #define BREAKINST 0x5730 /* trapa #3 */
index a5b427909b5cac04d28c4da1b099342ee72df4ce..036d56cc459168a0087ce8eba3e69aae9f9197b6 100644 (file)
@@ -10,7 +10,9 @@
 #include <linux/irqflags.h>
 #include <linux/notifier.h>
 #include <linux/prefetch.h>
+#include <linux/ptrace.h>
 #include <linux/sched.h>
+#include <linux/sched/task_stack.h>
 
 #include <asm/cop2.h>
 #include <asm/current.h>
index 4d22365844af30b9bdd24cfd521b6a8e0a7f7cff..cfb4a146cf1786a73a28a781f26b363757164968 100644 (file)
@@ -9,6 +9,7 @@
 #include <asm/cop2.h>
 #include <linux/export.h>
 #include <linux/interrupt.h>
+#include <linux/sched/task_stack.h>
 
 #include "octeon-crypto.h"
 
index 4b94b7fbafa3602374477c99fd76acde79945565..3de786545ded10ac64f5fa77d2025fa3a9955fd9 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/sched.h>
 #include <linux/sched/hotplug.h>
+#include <linux/sched/task_stack.h>
 #include <linux/init.h>
 #include <linux/export.h>
 
index 321752bcbab6ec5fc6fa1d6a658b82bb1a58e7ed..f94455f964ec00b1e1b17120349b1543ed9dec97 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/sched.h>
 #include <linux/sched/task_stack.h>
+#include <linux/ptrace.h>
 #include <linux/thread_info.h>
 #include <linux/bitops.h>
 
index 3daa2cae50b0b976942772c7c10656d8f4ffd3ab..1b070a76fcdd4c2e5f62a84bfff8e40ad0a8721b 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/sched/hotplug.h>
+#include <linux/sched/task_stack.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/smp.h>
index e077ea3e11fb36ee2d5f85f7e8415c97eeead1d9..e398cbc3d7767d50287d4c1e267b4e3e990efa4e 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/irqchip/mips-gic.h>
 #include <linux/compiler.h>
+#include <linux/sched/task_stack.h>
 #include <linux/smp.h>
 
 #include <linux/atomic.h>
index ea13764d0a035ccc5ec6cf443f021aa1f4f58103..621d6af5f6eb8ecc9e602ee085ceb39412678cc3 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/notifier.h>
+#include <linux/ptrace.h>
 
 #include <asm/fpu.h>
 #include <asm/cop2.h>
index 10d86d54880ab8541eecf01f8d1f0dd2b3d6ee18..bddf1ef553a4f695d320d4f88eb7f28b079cec94 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/sched/task_stack.h>
 #include <linux/smp.h>
 #include <linux/irq.h>
 
index 52bc5de420052ca4e604cd39a8ff4bfcbbba2fa1..21e439b3db707f4119229954e1eced768dd5162d 100644 (file)
@@ -9,11 +9,14 @@
  * Copyright (C) 2009 Wind River Systems,
  *   written by Ralf Baechle <ralf@linux-mips.org>
  */
+#include <linux/capability.h>
 #include <linux/init.h>
 #include <linux/irqflags.h>
 #include <linux/notifier.h>
 #include <linux/prefetch.h>
+#include <linux/ptrace.h>
 #include <linux/sched.h>
+#include <linux/sched/task_stack.h>
 
 #include <asm/cop2.h>
 #include <asm/current.h>
index 1f2a5bc4779e6a356a43f179608b98d605a8c343..75460e1e106b2c08799354139b869481d0b23abb 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/sched/debug.h>
+#include <linux/sched/signal.h>
 #include <linux/seq_file.h>
 
 #include <asm/addrspace.h>
index d12879eb2b1fa9f0b58cfc03fbd51d8ea2394134..83efe03d5c600f695d073279c1d594a7ca60b471 100644 (file)
@@ -12,7 +12,9 @@
 #include <linux/signal.h>      /* for SIGBUS */
 #include <linux/sched.h>       /* schow_regs(), force_sig() */
 #include <linux/sched/debug.h>
+#include <linux/sched/signal.h>
 
+#include <asm/ptrace.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/sn0/hub.h>
index f5ed45e8f442565ce0f7435585cff684ece5d764..4cd47d23d81a76105b5a5fc21a768cc50d478879 100644 (file)
@@ -8,10 +8,13 @@
  */
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/sched/task_stack.h>
 #include <linux/topology.h>
 #include <linux/nodemask.h>
+
 #include <asm/page.h>
 #include <asm/processor.h>
+#include <asm/ptrace.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/gda.h>
 #include <asm/sn/intr.h>
index 57d8c7486fe6b75b2f903fbd2673d869c9d63001..c1f12a9cf305f4196bd23cbe01b7dc73dc852b26 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/sched/debug.h>
+#include <linux/sched/signal.h>
 #include <asm/traps.h>
 #include <linux/uaccess.h>
 #include <asm/addrspace.h>
index 8bd415c8729f974a8e1e376d5a2b3e08c84e6053..b3b442def42383794289c6c07ea9a44ee5c4a873 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/sched/signal.h>
 #include <linux/notifier.h>
 #include <linux/delay.h>
 #include <linux/rtc/ds1685.h>
index 494091762bd7f3a43afe15945943343c4cb23fe0..97a8bc8a095ce4199ad2e4e0c88c2933fc3b6987 100644 (file)
@@ -80,93 +80,99 @@ config ARCH_HAS_DMA_SET_COHERENT_MASK
 config PPC
        bool
        default y
-       select BUILDTIME_EXTABLE_SORT
+       #
+       # Please keep this list sorted alphabetically.
+       #
+       select ARCH_HAS_DEVMEM_IS_ALLOWED
+       select ARCH_HAS_DMA_SET_COHERENT_MASK
+       select ARCH_HAS_ELF_RANDOMIZE
+       select ARCH_HAS_GCOV_PROFILE_ALL
+       select ARCH_HAS_SCALED_CPUTIME          if VIRT_CPU_ACCOUNTING_NATIVE
+       select ARCH_HAS_SG_CHAIN
+       select ARCH_HAS_TICK_BROADCAST          if GENERIC_CLOCKEVENTS_BROADCAST
+       select ARCH_HAS_UBSAN_SANITIZE_ALL
+       select ARCH_HAVE_NMI_SAFE_CMPXCHG
        select ARCH_MIGHT_HAVE_PC_PARPORT
        select ARCH_MIGHT_HAVE_PC_SERIO
+       select ARCH_SUPPORTS_ATOMIC_RMW
+       select ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT
+       select ARCH_USE_BUILTIN_BSWAP
+       select ARCH_USE_CMPXCHG_LOCKREF         if PPC64
+       select ARCH_WANT_IPC_PARSE_VERSION
        select BINFMT_ELF
-       select ARCH_HAS_ELF_RANDOMIZE
-       select OF
-       select OF_EARLY_FLATTREE
-       select OF_RESERVED_MEM
-       select HAVE_FTRACE_MCOUNT_RECORD
+       select BUILDTIME_EXTABLE_SORT
+       select CLONE_BACKWARDS
+       select DCACHE_WORD_ACCESS               if PPC64 && CPU_LITTLE_ENDIAN
+       select EDAC_ATOMIC_SCRUB
+       select EDAC_SUPPORT
+       select GENERIC_ATOMIC64                 if PPC32
+       select GENERIC_CLOCKEVENTS
+       select GENERIC_CLOCKEVENTS_BROADCAST    if SMP
+       select GENERIC_CMOS_UPDATE
+       select GENERIC_CPU_AUTOPROBE
+       select GENERIC_IRQ_SHOW
+       select GENERIC_IRQ_SHOW_LEVEL
+       select GENERIC_SMP_IDLE_THREAD
+       select GENERIC_STRNCPY_FROM_USER
+       select GENERIC_STRNLEN_USER
+       select GENERIC_TIME_VSYSCALL_OLD
+       select HAVE_ARCH_AUDITSYSCALL
+       select HAVE_ARCH_HARDENED_USERCOPY
+       select HAVE_ARCH_JUMP_LABEL
+       select HAVE_ARCH_KGDB
+       select HAVE_ARCH_SECCOMP_FILTER
+       select HAVE_ARCH_TRACEHOOK
+       select HAVE_CBPF_JIT                    if !PPC64
+       select HAVE_CONTEXT_TRACKING            if PPC64
+       select HAVE_DEBUG_KMEMLEAK
+       select HAVE_DEBUG_STACKOVERFLOW
+       select HAVE_DMA_API_DEBUG
        select HAVE_DYNAMIC_FTRACE
-       select HAVE_DYNAMIC_FTRACE_WITH_REGS if MPROFILE_KERNEL
-       select HAVE_FUNCTION_TRACER
+       select HAVE_DYNAMIC_FTRACE_WITH_REGS    if MPROFILE_KERNEL
+       select HAVE_EBPF_JIT                    if PPC64
+       select HAVE_EFFICIENT_UNALIGNED_ACCESS  if !(CPU_LITTLE_ENDIAN && POWER7_CPU)
+       select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_FUNCTION_GRAPH_TRACER
+       select HAVE_FUNCTION_TRACER
        select HAVE_GCC_PLUGINS
-       select SYSCTL_EXCEPTION_TRACE
-       select VIRT_TO_BUS if !PPC64
+       select HAVE_GENERIC_RCU_GUP
+       select HAVE_HW_BREAKPOINT               if PERF_EVENTS && (PPC_BOOK3S || PPC_8xx)
        select HAVE_IDE
        select HAVE_IOREMAP_PROT
-       select HAVE_EFFICIENT_UNALIGNED_ACCESS if !(CPU_LITTLE_ENDIAN && POWER7_CPU)
+       select HAVE_IRQ_EXIT_ON_IRQ_STACK
+       select HAVE_KERNEL_GZIP
        select HAVE_KPROBES
-       select HAVE_OPTPROBES if PPC64
-       select HAVE_ARCH_KGDB
        select HAVE_KRETPROBES
-       select HAVE_ARCH_TRACEHOOK
+       select HAVE_LIVEPATCH                   if HAVE_DYNAMIC_FTRACE_WITH_REGS
        select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
-       select HAVE_DMA_API_DEBUG
+       select HAVE_MOD_ARCH_SPECIFIC
+       select HAVE_NMI                         if PERF_EVENTS
        select HAVE_OPROFILE
-       select HAVE_DEBUG_KMEMLEAK
-       select ARCH_HAS_SG_CHAIN
-       select GENERIC_ATOMIC64 if PPC32
+       select HAVE_OPTPROBES                   if PPC64
        select HAVE_PERF_EVENTS
+       select HAVE_PERF_EVENTS_NMI             if PPC64
        select HAVE_PERF_REGS
        select HAVE_PERF_USER_STACK_DUMP
+       select HAVE_RCU_TABLE_FREE              if SMP
        select HAVE_REGS_AND_STACK_ACCESS_API
-       select HAVE_HW_BREAKPOINT if PERF_EVENTS && (PPC_BOOK3S || PPC_8xx)
-       select ARCH_WANT_IPC_PARSE_VERSION
-       select SPARSE_IRQ
+       select HAVE_SYSCALL_TRACEPOINTS
+       select HAVE_VIRT_CPU_ACCOUNTING
        select IRQ_DOMAIN
-       select GENERIC_IRQ_SHOW
-       select GENERIC_IRQ_SHOW_LEVEL
        select IRQ_FORCED_THREADING
-       select HAVE_RCU_TABLE_FREE if SMP
-       select HAVE_SYSCALL_TRACEPOINTS
-       select HAVE_CBPF_JIT if !PPC64
-       select HAVE_EBPF_JIT if PPC64
-       select HAVE_ARCH_JUMP_LABEL
-       select ARCH_HAVE_NMI_SAFE_CMPXCHG
-       select ARCH_HAS_GCOV_PROFILE_ALL
-       select GENERIC_SMP_IDLE_THREAD
-       select GENERIC_CMOS_UPDATE
-       select GENERIC_TIME_VSYSCALL_OLD
-       select GENERIC_CLOCKEVENTS
-       select GENERIC_CLOCKEVENTS_BROADCAST if SMP
-       select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
-       select GENERIC_STRNCPY_FROM_USER
-       select GENERIC_STRNLEN_USER
-       select HAVE_MOD_ARCH_SPECIFIC
        select MODULES_USE_ELF_RELA
-       select CLONE_BACKWARDS
-       select ARCH_USE_BUILTIN_BSWAP
-       select OLD_SIGSUSPEND
-       select OLD_SIGACTION if PPC32
-       select HAVE_DEBUG_STACKOVERFLOW
-       select HAVE_IRQ_EXIT_ON_IRQ_STACK
-       select ARCH_USE_CMPXCHG_LOCKREF if PPC64
-       select HAVE_ARCH_AUDITSYSCALL
-       select ARCH_SUPPORTS_ATOMIC_RMW
-       select DCACHE_WORD_ACCESS if PPC64 && CPU_LITTLE_ENDIAN
        select NO_BOOTMEM
-       select HAVE_GENERIC_RCU_GUP
-       select HAVE_PERF_EVENTS_NMI if PPC64
-       select HAVE_NMI if PERF_EVENTS
-       select EDAC_SUPPORT
-       select EDAC_ATOMIC_SCRUB
-       select ARCH_HAS_DMA_SET_COHERENT_MASK
-       select ARCH_HAS_DEVMEM_IS_ALLOWED
-       select HAVE_ARCH_SECCOMP_FILTER
-       select ARCH_HAS_UBSAN_SANITIZE_ALL
-       select ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT
-       select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS
-       select GENERIC_CPU_AUTOPROBE
-       select HAVE_VIRT_CPU_ACCOUNTING
-       select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE
-       select HAVE_ARCH_HARDENED_USERCOPY
-       select HAVE_KERNEL_GZIP
-       select HAVE_CONTEXT_TRACKING if PPC64
+       select OF
+       select OF_EARLY_FLATTREE
+       select OF_RESERVED_MEM
+       select OLD_SIGACTION                    if PPC32
+       select OLD_SIGSUSPEND
+       select SPARSE_IRQ
+       select SYSCTL_EXCEPTION_TRACE
+       select VIRT_TO_BUS                      if !PPC64
+       #
+       # Please keep this list sorted alphabetically.
+       #
 
 config GENERIC_CSUM
        def_bool n
index 31286fa7873c1df915814b9bc62156b140006cd2..19b0d1a819593081bc22164b9da26188c613bca8 100644 (file)
@@ -72,8 +72,15 @@ GNUTARGET    := powerpc
 MULTIPLEWORD   := -mmultiple
 endif
 
-cflags-$(CONFIG_CPU_BIG_ENDIAN)                += $(call cc-option,-mbig-endian)
+ifdef CONFIG_PPC64
+cflags-$(CONFIG_CPU_BIG_ENDIAN)                += $(call cc-option,-mabi=elfv1)
+cflags-$(CONFIG_CPU_BIG_ENDIAN)                += $(call cc-option,-mcall-aixdesc)
+aflags-$(CONFIG_CPU_BIG_ENDIAN)                += $(call cc-option,-mabi=elfv1)
+aflags-$(CONFIG_CPU_LITTLE_ENDIAN)     += -mabi=elfv2
+endif
+
 cflags-$(CONFIG_CPU_LITTLE_ENDIAN)     += -mlittle-endian
+cflags-$(CONFIG_CPU_BIG_ENDIAN)                += $(call cc-option,-mbig-endian)
 ifneq ($(cc-name),clang)
   cflags-$(CONFIG_CPU_LITTLE_ENDIAN)   += -mno-strict-align
 endif
@@ -113,7 +120,9 @@ ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y)
 CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv2,$(call cc-option,-mcall-aixdesc))
 AFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv2)
 else
+CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv1)
 CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcall-aixdesc)
+AFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv1)
 endif
 CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcmodel=medium,$(call cc-option,-mminimal-toc))
 CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mno-pointers-to-nested-functions)
index 4e63787dc3becfd6c9b832f50a8c2e1367bd4187..842124b199b5859f6d0f61cb6b7c09ed08854d96 100644 (file)
@@ -112,7 +112,7 @@ static inline __wsum csum_add(__wsum csum, __wsum addend)
 
 #ifdef __powerpc64__
        res += (__force u64)addend;
-       return (__force __wsum)((u32)res + (res >> 32));
+       return (__force __wsum) from64to32(res);
 #else
        asm("addc %0,%0,%1;"
            "addze %0,%0;"
index fd321eb423cb44fef259cf47547a05ee1cc1f6a8..155731557c9bc08673881520c13d6db825fd91b0 100644 (file)
@@ -70,8 +70,8 @@ static inline void report_invalid_psscr_val(u64 psscr_val, int err)
        std     r0,0(r1);                                       \
        ptesync;                                                \
        ld      r0,0(r1);                                       \
-1:     cmpd    cr0,r0,r0;                                      \
-       bne     1b;                                             \
+236:   cmpd    cr0,r0,r0;                                      \
+       bne     236b;                                           \
        IDLE_INST;                                              \
 
 #define        IDLE_STATE_ENTER_SEQ_NORET(IDLE_INST)                   \
index 93b9b84568e8175e4010b6544bb490685730408f..09bde6e34f5d524bd7b172f42b25484b1cca3f9d 100644 (file)
@@ -144,8 +144,8 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 #define ARCH_DLINFO_CACHE_GEOMETRY                                     \
        NEW_AUX_ENT(AT_L1I_CACHESIZE, ppc64_caches.l1i.size);           \
        NEW_AUX_ENT(AT_L1I_CACHEGEOMETRY, get_cache_geometry(l1i));     \
-       NEW_AUX_ENT(AT_L1D_CACHESIZE, ppc64_caches.l1i.size);           \
-       NEW_AUX_ENT(AT_L1D_CACHEGEOMETRY, get_cache_geometry(l1i));     \
+       NEW_AUX_ENT(AT_L1D_CACHESIZE, ppc64_caches.l1d.size);           \
+       NEW_AUX_ENT(AT_L1D_CACHEGEOMETRY, get_cache_geometry(l1d));     \
        NEW_AUX_ENT(AT_L2_CACHESIZE, ppc64_caches.l2.size);             \
        NEW_AUX_ENT(AT_L2_CACHEGEOMETRY, get_cache_geometry(l2));       \
        NEW_AUX_ENT(AT_L3_CACHESIZE, ppc64_caches.l3.size);             \
index 0cd8a3852763292eabe905b33960f888e875c978..e5805ad78e127ba456ba305abf09d30fdc38c5f4 100644 (file)
@@ -230,7 +230,7 @@ static inline int hugepd_ok(hugepd_t hpd)
        return ((hpd_val(hpd) & 0x4) != 0);
 #else
        /* We clear the top bit to indicate hugepd */
-       return ((hpd_val(hpd) & PD_HUGE) ==  0);
+       return (hpd_val(hpd) && (hpd_val(hpd) & PD_HUGE) == 0);
 #endif
 }
 
index d99bd442aacbe5747f605cd356de6aa3ae58e53a..e7d6d86563eeda924598b1079a491d0e5945c566 100644 (file)
 #define PPC_INST_BRANCH_COND           0x40800000
 #define PPC_INST_LBZCIX                        0x7c0006aa
 #define PPC_INST_STBCIX                        0x7c0007aa
+#define PPC_INST_LWZX                  0x7c00002e
+#define PPC_INST_LFSX                  0x7c00042e
+#define PPC_INST_STFSX                 0x7c00052e
+#define PPC_INST_LFDX                  0x7c0004ae
+#define PPC_INST_STFDX                 0x7c0005ae
+#define PPC_INST_LVX                   0x7c0000ce
+#define PPC_INST_STVX                  0x7c0001ce
 
 /* macros to insert fields into opcodes */
 #define ___PPC_RA(a)   (((a) & 0x1f) << 16)
index 4a90634e83223c25bdf839f54ca9b3f91cb76330..35c00d7a0cf81a4773d0fad7dc2747923cd2c643 100644 (file)
@@ -160,12 +160,18 @@ struct of_drconf_cell {
 #define OV5_PFO_HW_ENCR                0x1120  /* PFO Encryption Accelerator */
 #define OV5_SUB_PROCESSORS     0x1501  /* 1,2,or 4 Sub-Processors supported */
 #define OV5_XIVE_EXPLOIT       0x1701  /* XIVE exploitation supported */
-#define OV5_MMU_RADIX_300      0x1880  /* ISA v3.00 radix MMU supported */
-#define OV5_MMU_HASH_300       0x1840  /* ISA v3.00 hash MMU supported */
-#define OV5_MMU_SEGM_RADIX     0x1820  /* radix mode (no segmentation) */
-#define OV5_MMU_PROC_TBL       0x1810  /* hcall selects SLB or proc table */
-#define OV5_MMU_SLB            0x1800  /* always use SLB */
-#define OV5_MMU_GTSE           0x1808  /* Guest translation shootdown */
+/* MMU Base Architecture */
+#define OV5_MMU_SUPPORT                0x18C0  /* MMU Mode Support Mask */
+#define OV5_MMU_HASH           0x1800  /* Hash MMU Only */
+#define OV5_MMU_RADIX          0x1840  /* Radix MMU Only */
+#define OV5_MMU_EITHER         0x1880  /* Hash or Radix Supported */
+#define OV5_MMU_DYNAMIC                0x18C0  /* Hash or Radix Can Switch Later */
+#define OV5_NMMU               0x1820  /* Nest MMU Available */
+/* Hash Table Extensions */
+#define OV5_HASH_SEG_TBL       0x1980  /* In Memory Segment Tables Available */
+#define OV5_HASH_GTSE          0x1940  /* Guest Translation Shoot Down Avail */
+/* Radix Table Extensions */
+#define OV5_RADIX_GTSE         0x1A40  /* Guest Translation Shoot Down Avail */
 
 /* Option Vector 6: IBM PAPR hints */
 #define OV6_LINUX              0x02    /* Linux is our OS */
index 5f61cc0349c063f1abfd736c13104559cab9d2b0..995728736677071512b5eb40f04bff0045bd2bbb 100644 (file)
@@ -276,19 +276,21 @@ power_enter_stop:
  */
        andis.   r4,r3,PSSCR_EC_ESL_MASK_SHIFTED
        clrldi   r3,r3,60 /* r3 = Bits[60:63] = Requested Level (RL) */
-       bne      1f
+       bne      .Lhandle_esl_ec_set
        IDLE_STATE_ENTER_SEQ(PPC_STOP)
        li      r3,0  /* Since we didn't lose state, return 0 */
        b       pnv_wakeup_noloss
+
+.Lhandle_esl_ec_set:
 /*
  * Check if the requested state is a deep idle state.
  */
-1:     LOAD_REG_ADDRBASE(r5,pnv_first_deep_stop_state)
+       LOAD_REG_ADDRBASE(r5,pnv_first_deep_stop_state)
        ld      r4,ADDROFF(pnv_first_deep_stop_state)(r5)
        cmpd    r3,r4
-       bge     2f
+       bge     .Lhandle_deep_stop
        IDLE_STATE_ENTER_SEQ_NORET(PPC_STOP)
-2:
+.Lhandle_deep_stop:
 /*
  * Entering deep idle state.
  * Clear thread bit in PACA_CORE_IDLE_STATE, save SPRs to
index a3944540fe0d56b0245f65ffcc0c0719f3c57a54..1c1b44ec7642a531e116fa0d04b6269dd38e93b5 100644 (file)
@@ -168,6 +168,14 @@ static unsigned long __initdata prom_tce_alloc_start;
 static unsigned long __initdata prom_tce_alloc_end;
 #endif
 
+static bool __initdata prom_radix_disable;
+
+struct platform_support {
+       bool hash_mmu;
+       bool radix_mmu;
+       bool radix_gtse;
+};
+
 /* Platforms codes are now obsolete in the kernel. Now only used within this
  * file and ultimately gone too. Feel free to change them if you need, they
  * are not shared with anything outside of this file anymore
@@ -626,6 +634,12 @@ static void __init early_cmdline_parse(void)
                prom_memory_limit = ALIGN(prom_memory_limit, 0x1000000);
 #endif
        }
+
+       opt = strstr(prom_cmd_line, "disable_radix");
+       if (opt) {
+               prom_debug("Radix disabled from cmdline\n");
+               prom_radix_disable = true;
+       }
 }
 
 #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
@@ -695,6 +709,8 @@ struct option_vector5 {
        u8 byte22;
        u8 intarch;
        u8 mmu;
+       u8 hash_ext;
+       u8 radix_ext;
 } __packed;
 
 struct option_vector6 {
@@ -850,8 +866,9 @@ struct ibm_arch_vec __cacheline_aligned ibm_architecture_vec = {
                .reserved3 = 0,
                .subprocessors = 1,
                .intarch = 0,
-               .mmu = OV5_FEAT(OV5_MMU_RADIX_300) | OV5_FEAT(OV5_MMU_HASH_300) |
-                       OV5_FEAT(OV5_MMU_PROC_TBL) | OV5_FEAT(OV5_MMU_GTSE),
+               .mmu = 0,
+               .hash_ext = 0,
+               .radix_ext = 0,
        },
 
        /* option vector 6: IBM PAPR hints */
@@ -990,6 +1007,92 @@ static int __init prom_count_smt_threads(void)
 
 }
 
+static void __init prom_parse_mmu_model(u8 val,
+                                       struct platform_support *support)
+{
+       switch (val) {
+       case OV5_FEAT(OV5_MMU_DYNAMIC):
+       case OV5_FEAT(OV5_MMU_EITHER): /* Either Available */
+               prom_debug("MMU - either supported\n");
+               support->radix_mmu = !prom_radix_disable;
+               support->hash_mmu = true;
+               break;
+       case OV5_FEAT(OV5_MMU_RADIX): /* Only Radix */
+               prom_debug("MMU - radix only\n");
+               if (prom_radix_disable) {
+                       /*
+                        * If we __have__ to do radix, we're better off ignoring
+                        * the command line rather than not booting.
+                        */
+                       prom_printf("WARNING: Ignoring cmdline option disable_radix\n");
+               }
+               support->radix_mmu = true;
+               break;
+       case OV5_FEAT(OV5_MMU_HASH):
+               prom_debug("MMU - hash only\n");
+               support->hash_mmu = true;
+               break;
+       default:
+               prom_debug("Unknown mmu support option: 0x%x\n", val);
+               break;
+       }
+}
+
+static void __init prom_parse_platform_support(u8 index, u8 val,
+                                              struct platform_support *support)
+{
+       switch (index) {
+       case OV5_INDX(OV5_MMU_SUPPORT): /* MMU Model */
+               prom_parse_mmu_model(val & OV5_FEAT(OV5_MMU_SUPPORT), support);
+               break;
+       case OV5_INDX(OV5_RADIX_GTSE): /* Radix Extensions */
+               if (val & OV5_FEAT(OV5_RADIX_GTSE)) {
+                       prom_debug("Radix - GTSE supported\n");
+                       support->radix_gtse = true;
+               }
+               break;
+       }
+}
+
+static void __init prom_check_platform_support(void)
+{
+       struct platform_support supported = {
+               .hash_mmu = false,
+               .radix_mmu = false,
+               .radix_gtse = false
+       };
+       int prop_len = prom_getproplen(prom.chosen,
+                                      "ibm,arch-vec-5-platform-support");
+       if (prop_len > 1) {
+               int i;
+               u8 vec[prop_len];
+               prom_debug("Found ibm,arch-vec-5-platform-support, len: %d\n",
+                          prop_len);
+               prom_getprop(prom.chosen, "ibm,arch-vec-5-platform-support",
+                            &vec, sizeof(vec));
+               for (i = 0; i < prop_len; i += 2) {
+                       prom_debug("%d: index = 0x%x val = 0x%x\n", i / 2
+                                                                 , vec[i]
+                                                                 , vec[i + 1]);
+                       prom_parse_platform_support(vec[i], vec[i + 1],
+                                                   &supported);
+               }
+       }
+
+       if (supported.radix_mmu && supported.radix_gtse) {
+               /* Radix preferred - but we require GTSE for now */
+               prom_debug("Asking for radix with GTSE\n");
+               ibm_architecture_vec.vec5.mmu = OV5_FEAT(OV5_MMU_RADIX);
+               ibm_architecture_vec.vec5.radix_ext = OV5_FEAT(OV5_RADIX_GTSE);
+       } else if (supported.hash_mmu) {
+               /* Default to hash mmu (if we can) */
+               prom_debug("Asking for hash\n");
+               ibm_architecture_vec.vec5.mmu = OV5_FEAT(OV5_MMU_HASH);
+       } else {
+               /* We're probably on a legacy hypervisor */
+               prom_debug("Assuming legacy hash support\n");
+       }
+}
 
 static void __init prom_send_capabilities(void)
 {
@@ -997,6 +1100,9 @@ static void __init prom_send_capabilities(void)
        prom_arg_t ret;
        u32 cores;
 
+       /* Check ibm,arch-vec-5-platform-support and fixup vec5 if required */
+       prom_check_platform_support();
+
        root = call_prom("open", 1, 1, ADDR("/"));
        if (root != 0) {
                /* We need to tell the FW about the number of cores we support.
@@ -2993,6 +3099,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
         */
        prom_check_initrd(r3, r4);
 
+       /*
+        * Do early parsing of command line
+        */
+       early_cmdline_parse();
+
 #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
        /*
         * On pSeries, inform the firmware about our capabilities
@@ -3008,11 +3119,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
        if (of_platform != PLATFORM_POWERMAC)
                copy_and_flush(0, kbase, 0x100, 0);
 
-       /*
-        * Do early parsing of command line
-        */
-       early_cmdline_parse();
-
        /*
         * Initialize memory management within prom_init
         */
index adf2084f214b2bd01d5aa3ef2a613e66b7b66a05..9cfaa8b69b5f32eb64d7adcd8504ccdb6cd87b32 100644 (file)
@@ -408,7 +408,10 @@ static void init_cache_info(struct ppc_cache_info *info, u32 size, u32 lsize,
        info->line_size = lsize;
        info->block_size = bsize;
        info->log_block_size = __ilog2(bsize);
-       info->blocks_per_page = PAGE_SIZE / bsize;
+       if (bsize)
+               info->blocks_per_page = PAGE_SIZE / bsize;
+       else
+               info->blocks_per_page = 0;
 
        if (sets == 0)
                info->assoc = 0xffff;
index 0e649d72fe8d0d3a95f5b1c5216e4bf6f2a4bdd2..2b5e09020cfe379abfb3c56dd497215b07eb8931 100644 (file)
@@ -20,6 +20,7 @@ obj64-y       += copypage_64.o copyuser_64.o usercopy_64.o mem_64.o hweight_64.o \
 
 obj64-$(CONFIG_SMP)    += locks.o
 obj64-$(CONFIG_ALTIVEC)        += vmx-helper.o
+obj64-$(CONFIG_KPROBES_SANITY_TEST) += test_emulate_step.o
 
 obj-y                  += checksum_$(BITS).o checksum_wrappers.o
 
index 846dba2c6360002b5343dc17d5b0744fb5525e85..9c542ec70c5bc8b77810e34f9ab8c96e8cd51522 100644 (file)
@@ -1799,8 +1799,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
                goto instr_done;
 
        case LARX:
-               if (regs->msr & MSR_LE)
-                       return 0;
                if (op.ea & (size - 1))
                        break;          /* can't handle misaligned */
                if (!address_ok(regs, op.ea, size))
@@ -1823,8 +1821,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
                goto ldst_done;
 
        case STCX:
-               if (regs->msr & MSR_LE)
-                       return 0;
                if (op.ea & (size - 1))
                        break;          /* can't handle misaligned */
                if (!address_ok(regs, op.ea, size))
@@ -1849,8 +1845,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
                goto ldst_done;
 
        case LOAD:
-               if (regs->msr & MSR_LE)
-                       return 0;
                err = read_mem(&regs->gpr[op.reg], op.ea, size, regs);
                if (!err) {
                        if (op.type & SIGNEXT)
@@ -1862,8 +1856,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
 
 #ifdef CONFIG_PPC_FPU
        case LOAD_FP:
-               if (regs->msr & MSR_LE)
-                       return 0;
                if (size == 4)
                        err = do_fp_load(op.reg, do_lfs, op.ea, size, regs);
                else
@@ -1872,15 +1864,11 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
 #endif
 #ifdef CONFIG_ALTIVEC
        case LOAD_VMX:
-               if (regs->msr & MSR_LE)
-                       return 0;
                err = do_vec_load(op.reg, do_lvx, op.ea & ~0xfUL, regs);
                goto ldst_done;
 #endif
 #ifdef CONFIG_VSX
        case LOAD_VSX:
-               if (regs->msr & MSR_LE)
-                       return 0;
                err = do_vsx_load(op.reg, do_lxvd2x, op.ea, regs);
                goto ldst_done;
 #endif
@@ -1903,8 +1891,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
                goto instr_done;
 
        case STORE:
-               if (regs->msr & MSR_LE)
-                       return 0;
                if ((op.type & UPDATE) && size == sizeof(long) &&
                    op.reg == 1 && op.update_reg == 1 &&
                    !(regs->msr & MSR_PR) &&
@@ -1917,8 +1903,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
 
 #ifdef CONFIG_PPC_FPU
        case STORE_FP:
-               if (regs->msr & MSR_LE)
-                       return 0;
                if (size == 4)
                        err = do_fp_store(op.reg, do_stfs, op.ea, size, regs);
                else
@@ -1927,15 +1911,11 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
 #endif
 #ifdef CONFIG_ALTIVEC
        case STORE_VMX:
-               if (regs->msr & MSR_LE)
-                       return 0;
                err = do_vec_store(op.reg, do_stvx, op.ea & ~0xfUL, regs);
                goto ldst_done;
 #endif
 #ifdef CONFIG_VSX
        case STORE_VSX:
-               if (regs->msr & MSR_LE)
-                       return 0;
                err = do_vsx_store(op.reg, do_stxvd2x, op.ea, regs);
                goto ldst_done;
 #endif
diff --git a/arch/powerpc/lib/test_emulate_step.c b/arch/powerpc/lib/test_emulate_step.c
new file mode 100644 (file)
index 0000000..2534c14
--- /dev/null
@@ -0,0 +1,434 @@
+/*
+ * Simple sanity test for emulate_step load/store instructions.
+ *
+ * Copyright IBM Corp. 2016
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) "emulate_step_test: " fmt
+
+#include <linux/ptrace.h>
+#include <asm/sstep.h>
+#include <asm/ppc-opcode.h>
+
+#define IMM_L(i)               ((uintptr_t)(i) & 0xffff)
+
+/*
+ * Defined with TEST_ prefix so it does not conflict with other
+ * definitions.
+ */
+#define TEST_LD(r, base, i)    (PPC_INST_LD | ___PPC_RT(r) |           \
+                                       ___PPC_RA(base) | IMM_L(i))
+#define TEST_LWZ(r, base, i)   (PPC_INST_LWZ | ___PPC_RT(r) |          \
+                                       ___PPC_RA(base) | IMM_L(i))
+#define TEST_LWZX(t, a, b)     (PPC_INST_LWZX | ___PPC_RT(t) |         \
+                                       ___PPC_RA(a) | ___PPC_RB(b))
+#define TEST_STD(r, base, i)   (PPC_INST_STD | ___PPC_RS(r) |          \
+                                       ___PPC_RA(base) | ((i) & 0xfffc))
+#define TEST_LDARX(t, a, b, eh)        (PPC_INST_LDARX | ___PPC_RT(t) |        \
+                                       ___PPC_RA(a) | ___PPC_RB(b) |   \
+                                       __PPC_EH(eh))
+#define TEST_STDCX(s, a, b)    (PPC_INST_STDCX | ___PPC_RS(s) |        \
+                                       ___PPC_RA(a) | ___PPC_RB(b))
+#define TEST_LFSX(t, a, b)     (PPC_INST_LFSX | ___PPC_RT(t) |         \
+                                       ___PPC_RA(a) | ___PPC_RB(b))
+#define TEST_STFSX(s, a, b)    (PPC_INST_STFSX | ___PPC_RS(s) |        \
+                                       ___PPC_RA(a) | ___PPC_RB(b))
+#define TEST_LFDX(t, a, b)     (PPC_INST_LFDX | ___PPC_RT(t) |         \
+                                       ___PPC_RA(a) | ___PPC_RB(b))
+#define TEST_STFDX(s, a, b)    (PPC_INST_STFDX | ___PPC_RS(s) |        \
+                                       ___PPC_RA(a) | ___PPC_RB(b))
+#define TEST_LVX(t, a, b)      (PPC_INST_LVX | ___PPC_RT(t) |          \
+                                       ___PPC_RA(a) | ___PPC_RB(b))
+#define TEST_STVX(s, a, b)     (PPC_INST_STVX | ___PPC_RS(s) |         \
+                                       ___PPC_RA(a) | ___PPC_RB(b))
+#define TEST_LXVD2X(s, a, b)   (PPC_INST_LXVD2X | VSX_XX1((s), R##a, R##b))
+#define TEST_STXVD2X(s, a, b)  (PPC_INST_STXVD2X | VSX_XX1((s), R##a, R##b))
+
+
+static void __init init_pt_regs(struct pt_regs *regs)
+{
+       static unsigned long msr;
+       static bool msr_cached;
+
+       memset(regs, 0, sizeof(struct pt_regs));
+
+       if (likely(msr_cached)) {
+               regs->msr = msr;
+               return;
+       }
+
+       asm volatile("mfmsr %0" : "=r"(regs->msr));
+
+       regs->msr |= MSR_FP;
+       regs->msr |= MSR_VEC;
+       regs->msr |= MSR_VSX;
+
+       msr = regs->msr;
+       msr_cached = true;
+}
+
+static void __init show_result(char *ins, char *result)
+{
+       pr_info("%-14s : %s\n", ins, result);
+}
+
+static void __init test_ld(void)
+{
+       struct pt_regs regs;
+       unsigned long a = 0x23;
+       int stepped = -1;
+
+       init_pt_regs(&regs);
+       regs.gpr[3] = (unsigned long) &a;
+
+       /* ld r5, 0(r3) */
+       stepped = emulate_step(&regs, TEST_LD(5, 3, 0));
+
+       if (stepped == 1 && regs.gpr[5] == a)
+               show_result("ld", "PASS");
+       else
+               show_result("ld", "FAIL");
+}
+
+static void __init test_lwz(void)
+{
+       struct pt_regs regs;
+       unsigned int a = 0x4545;
+       int stepped = -1;
+
+       init_pt_regs(&regs);
+       regs.gpr[3] = (unsigned long) &a;
+
+       /* lwz r5, 0(r3) */
+       stepped = emulate_step(&regs, TEST_LWZ(5, 3, 0));
+
+       if (stepped == 1 && regs.gpr[5] == a)
+               show_result("lwz", "PASS");
+       else
+               show_result("lwz", "FAIL");
+}
+
+static void __init test_lwzx(void)
+{
+       struct pt_regs regs;
+       unsigned int a[3] = {0x0, 0x0, 0x1234};
+       int stepped = -1;
+
+       init_pt_regs(&regs);
+       regs.gpr[3] = (unsigned long) a;
+       regs.gpr[4] = 8;
+       regs.gpr[5] = 0x8765;
+
+       /* lwzx r5, r3, r4 */
+       stepped = emulate_step(&regs, TEST_LWZX(5, 3, 4));
+       if (stepped == 1 && regs.gpr[5] == a[2])
+               show_result("lwzx", "PASS");
+       else
+               show_result("lwzx", "FAIL");
+}
+
+static void __init test_std(void)
+{
+       struct pt_regs regs;
+       unsigned long a = 0x1234;
+       int stepped = -1;
+
+       init_pt_regs(&regs);
+       regs.gpr[3] = (unsigned long) &a;
+       regs.gpr[5] = 0x5678;
+
+       /* std r5, 0(r3) */
+       stepped = emulate_step(&regs, TEST_STD(5, 3, 0));
+       if (stepped == 1 || regs.gpr[5] == a)
+               show_result("std", "PASS");
+       else
+               show_result("std", "FAIL");
+}
+
+static void __init test_ldarx_stdcx(void)
+{
+       struct pt_regs regs;
+       unsigned long a = 0x1234;
+       int stepped = -1;
+       unsigned long cr0_eq = 0x1 << 29; /* eq bit of CR0 */
+
+       init_pt_regs(&regs);
+       asm volatile("mfcr %0" : "=r"(regs.ccr));
+
+
+       /*** ldarx ***/
+
+       regs.gpr[3] = (unsigned long) &a;
+       regs.gpr[4] = 0;
+       regs.gpr[5] = 0x5678;
+
+       /* ldarx r5, r3, r4, 0 */
+       stepped = emulate_step(&regs, TEST_LDARX(5, 3, 4, 0));
+
+       /*
+        * Don't touch 'a' here. Touching 'a' can do Load/store
+        * of 'a' which result in failure of subsequent stdcx.
+        * Instead, use hardcoded value for comparison.
+        */
+       if (stepped <= 0 || regs.gpr[5] != 0x1234) {
+               show_result("ldarx / stdcx.", "FAIL (ldarx)");
+               return;
+       }
+
+
+       /*** stdcx. ***/
+
+       regs.gpr[5] = 0x9ABC;
+
+       /* stdcx. r5, r3, r4 */
+       stepped = emulate_step(&regs, TEST_STDCX(5, 3, 4));
+
+       /*
+        * Two possible scenarios that indicates successful emulation
+        * of stdcx. :
+        *  1. Reservation is active and store is performed. In this
+        *     case cr0.eq bit will be set to 1.
+        *  2. Reservation is not active and store is not performed.
+        *     In this case cr0.eq bit will be set to 0.
+        */
+       if (stepped == 1 && ((regs.gpr[5] == a && (regs.ccr & cr0_eq))
+                       || (regs.gpr[5] != a && !(regs.ccr & cr0_eq))))
+               show_result("ldarx / stdcx.", "PASS");
+       else
+               show_result("ldarx / stdcx.", "FAIL (stdcx.)");
+}
+
+#ifdef CONFIG_PPC_FPU
+static void __init test_lfsx_stfsx(void)
+{
+       struct pt_regs regs;
+       union {
+               float a;
+               int b;
+       } c;
+       int cached_b;
+       int stepped = -1;
+
+       init_pt_regs(&regs);
+
+
+       /*** lfsx ***/
+
+       c.a = 123.45;
+       cached_b = c.b;
+
+       regs.gpr[3] = (unsigned long) &c.a;
+       regs.gpr[4] = 0;
+
+       /* lfsx frt10, r3, r4 */
+       stepped = emulate_step(&regs, TEST_LFSX(10, 3, 4));
+
+       if (stepped == 1)
+               show_result("lfsx", "PASS");
+       else
+               show_result("lfsx", "FAIL");
+
+
+       /*** stfsx ***/
+
+       c.a = 678.91;
+
+       /* stfsx frs10, r3, r4 */
+       stepped = emulate_step(&regs, TEST_STFSX(10, 3, 4));
+
+       if (stepped == 1 && c.b == cached_b)
+               show_result("stfsx", "PASS");
+       else
+               show_result("stfsx", "FAIL");
+}
+
+static void __init test_lfdx_stfdx(void)
+{
+       struct pt_regs regs;
+       union {
+               double a;
+               long b;
+       } c;
+       long cached_b;
+       int stepped = -1;
+
+       init_pt_regs(&regs);
+
+
+       /*** lfdx ***/
+
+       c.a = 123456.78;
+       cached_b = c.b;
+
+       regs.gpr[3] = (unsigned long) &c.a;
+       regs.gpr[4] = 0;
+
+       /* lfdx frt10, r3, r4 */
+       stepped = emulate_step(&regs, TEST_LFDX(10, 3, 4));
+
+       if (stepped == 1)
+               show_result("lfdx", "PASS");
+       else
+               show_result("lfdx", "FAIL");
+
+
+       /*** stfdx ***/
+
+       c.a = 987654.32;
+
+       /* stfdx frs10, r3, r4 */
+       stepped = emulate_step(&regs, TEST_STFDX(10, 3, 4));
+
+       if (stepped == 1 && c.b == cached_b)
+               show_result("stfdx", "PASS");
+       else
+               show_result("stfdx", "FAIL");
+}
+#else
+static void __init test_lfsx_stfsx(void)
+{
+       show_result("lfsx", "SKIP (CONFIG_PPC_FPU is not set)");
+       show_result("stfsx", "SKIP (CONFIG_PPC_FPU is not set)");
+}
+
+static void __init test_lfdx_stfdx(void)
+{
+       show_result("lfdx", "SKIP (CONFIG_PPC_FPU is not set)");
+       show_result("stfdx", "SKIP (CONFIG_PPC_FPU is not set)");
+}
+#endif /* CONFIG_PPC_FPU */
+
+#ifdef CONFIG_ALTIVEC
+static void __init test_lvx_stvx(void)
+{
+       struct pt_regs regs;
+       union {
+               vector128 a;
+               u32 b[4];
+       } c;
+       u32 cached_b[4];
+       int stepped = -1;
+
+       init_pt_regs(&regs);
+
+
+       /*** lvx ***/
+
+       cached_b[0] = c.b[0] = 923745;
+       cached_b[1] = c.b[1] = 2139478;
+       cached_b[2] = c.b[2] = 9012;
+       cached_b[3] = c.b[3] = 982134;
+
+       regs.gpr[3] = (unsigned long) &c.a;
+       regs.gpr[4] = 0;
+
+       /* lvx vrt10, r3, r4 */
+       stepped = emulate_step(&regs, TEST_LVX(10, 3, 4));
+
+       if (stepped == 1)
+               show_result("lvx", "PASS");
+       else
+               show_result("lvx", "FAIL");
+
+
+       /*** stvx ***/
+
+       c.b[0] = 4987513;
+       c.b[1] = 84313948;
+       c.b[2] = 71;
+       c.b[3] = 498532;
+
+       /* stvx vrs10, r3, r4 */
+       stepped = emulate_step(&regs, TEST_STVX(10, 3, 4));
+
+       if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
+           cached_b[2] == c.b[2] && cached_b[3] == c.b[3])
+               show_result("stvx", "PASS");
+       else
+               show_result("stvx", "FAIL");
+}
+#else
+static void __init test_lvx_stvx(void)
+{
+       show_result("lvx", "SKIP (CONFIG_ALTIVEC is not set)");
+       show_result("stvx", "SKIP (CONFIG_ALTIVEC is not set)");
+}
+#endif /* CONFIG_ALTIVEC */
+
+#ifdef CONFIG_VSX
+static void __init test_lxvd2x_stxvd2x(void)
+{
+       struct pt_regs regs;
+       union {
+               vector128 a;
+               u32 b[4];
+       } c;
+       u32 cached_b[4];
+       int stepped = -1;
+
+       init_pt_regs(&regs);
+
+
+       /*** lxvd2x ***/
+
+       cached_b[0] = c.b[0] = 18233;
+       cached_b[1] = c.b[1] = 34863571;
+       cached_b[2] = c.b[2] = 834;
+       cached_b[3] = c.b[3] = 6138911;
+
+       regs.gpr[3] = (unsigned long) &c.a;
+       regs.gpr[4] = 0;
+
+       /* lxvd2x vsr39, r3, r4 */
+       stepped = emulate_step(&regs, TEST_LXVD2X(39, 3, 4));
+
+       if (stepped == 1)
+               show_result("lxvd2x", "PASS");
+       else
+               show_result("lxvd2x", "FAIL");
+
+
+       /*** stxvd2x ***/
+
+       c.b[0] = 21379463;
+       c.b[1] = 87;
+       c.b[2] = 374234;
+       c.b[3] = 4;
+
+       /* stxvd2x vsr39, r3, r4 */
+       stepped = emulate_step(&regs, TEST_STXVD2X(39, 3, 4));
+
+       if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
+           cached_b[2] == c.b[2] && cached_b[3] == c.b[3])
+               show_result("stxvd2x", "PASS");
+       else
+               show_result("stxvd2x", "FAIL");
+}
+#else
+static void __init test_lxvd2x_stxvd2x(void)
+{
+       show_result("lxvd2x", "SKIP (CONFIG_VSX is not set)");
+       show_result("stxvd2x", "SKIP (CONFIG_VSX is not set)");
+}
+#endif /* CONFIG_VSX */
+
+static int __init test_emulate_step(void)
+{
+       test_ld();
+       test_lwz();
+       test_lwzx();
+       test_std();
+       test_ldarx_stdcx();
+       test_lfsx_stfsx();
+       test_lfdx_stfdx();
+       test_lvx_stvx();
+       test_lxvd2x_stxvd2x();
+
+       return 0;
+}
+late_initcall(test_emulate_step);
index 6aa3b76aa0d66b0b0d53b7e30685ab26745e2603..9be992083d2a7f7103d6ef9a251e95a207d41dd0 100644 (file)
@@ -356,18 +356,42 @@ static void early_check_vec5(void)
        unsigned long root, chosen;
        int size;
        const u8 *vec5;
+       u8 mmu_supported;
 
        root = of_get_flat_dt_root();
        chosen = of_get_flat_dt_subnode_by_name(root, "chosen");
-       if (chosen == -FDT_ERR_NOTFOUND)
+       if (chosen == -FDT_ERR_NOTFOUND) {
+               cur_cpu_spec->mmu_features &= ~MMU_FTR_TYPE_RADIX;
                return;
+       }
        vec5 = of_get_flat_dt_prop(chosen, "ibm,architecture-vec-5", &size);
-       if (!vec5)
+       if (!vec5) {
+               cur_cpu_spec->mmu_features &= ~MMU_FTR_TYPE_RADIX;
                return;
-       if (size <= OV5_INDX(OV5_MMU_RADIX_300) ||
-           !(vec5[OV5_INDX(OV5_MMU_RADIX_300)] & OV5_FEAT(OV5_MMU_RADIX_300)))
-               /* Hypervisor doesn't support radix */
+       }
+       if (size <= OV5_INDX(OV5_MMU_SUPPORT)) {
                cur_cpu_spec->mmu_features &= ~MMU_FTR_TYPE_RADIX;
+               return;
+       }
+
+       /* Check for supported configuration */
+       mmu_supported = vec5[OV5_INDX(OV5_MMU_SUPPORT)] &
+                       OV5_FEAT(OV5_MMU_SUPPORT);
+       if (mmu_supported == OV5_FEAT(OV5_MMU_RADIX)) {
+               /* Hypervisor only supports radix - check enabled && GTSE */
+               if (!early_radix_enabled()) {
+                       pr_warn("WARNING: Ignoring cmdline option disable_radix\n");
+               }
+               if (!(vec5[OV5_INDX(OV5_RADIX_GTSE)] &
+                                               OV5_FEAT(OV5_RADIX_GTSE))) {
+                       pr_warn("WARNING: Hypervisor doesn't support RADIX with GTSE\n");
+               }
+               /* Do radix anyway - the hypervisor said we had to */
+               cur_cpu_spec->mmu_features |= MMU_FTR_TYPE_RADIX;
+       } else if (mmu_supported == OV5_FEAT(OV5_MMU_HASH)) {
+               /* Hypervisor only supports hash - disable radix */
+               cur_cpu_spec->mmu_features &= ~MMU_FTR_TYPE_RADIX;
+       }
 }
 
 void __init mmu_early_init_devtree(void)
@@ -383,7 +407,7 @@ void __init mmu_early_init_devtree(void)
         * even though the ibm,architecture-vec-5 property created by
         * skiboot doesn't have the necessary bits set.
         */
-       if (early_radix_enabled() && !(mfmsr() & MSR_HV))
+       if (!(mfmsr() & MSR_HV))
                early_check_vec5();
 
        if (early_radix_enabled())
index 2a590a98e65215a8fceb413dd0c0b693a1adc9aa..c28165d8970b64de6bef88fa14a7945a6a75abc5 100644 (file)
@@ -186,6 +186,10 @@ static void __init radix_init_pgtable(void)
         */
        register_process_table(__pa(process_tb), 0, PRTB_SIZE_SHIFT - 12);
        pr_info("Process table %p and radix root for kernel: %p\n", process_tb, init_mm.pgd);
+       asm volatile("ptesync" : : : "memory");
+       asm volatile(PPC_TLBIE_5(%0,%1,2,1,1) : :
+                    "r" (TLBIEL_INVAL_SET_LPID), "r" (0));
+       asm volatile("eieio; tlbsync; ptesync" : : : "memory");
 }
 
 static void __init radix_init_partition_table(void)
index 6693f75e93d1629b51cd3104f24b84528a00969f..da8a0f7a035c1026b3403542c7ec2d97efa50376 100644 (file)
@@ -39,8 +39,8 @@ opal_tracepoint_refcount:
 BEGIN_FTR_SECTION;                                             \
        b       1f;                                             \
 END_FTR_SECTION(0, 1);                                         \
-       ld      r12,opal_tracepoint_refcount@toc(r2);           \
-       cmpdi   r12,0;                                          \
+       ld      r11,opal_tracepoint_refcount@toc(r2);           \
+       cmpdi   r11,0;                                          \
        bne-    LABEL;                                          \
 1:
 
index f9670eabfcfa70ca338aa0c5f2e10217803c7162..b53f80f0b4d822b8ecc77271ee7ece8b734bee5a 100644 (file)
@@ -91,6 +91,16 @@ static unsigned int icp_opal_get_irq(void)
 
 static void icp_opal_set_cpu_priority(unsigned char cppr)
 {
+       /*
+        * Here be dragons. The caller has asked to allow only IPI's and not
+        * external interrupts. But OPAL XIVE doesn't support that. So instead
+        * of allowing no interrupts allow all. That's still not right, but
+        * currently the only caller who does this is xics_migrate_irqs_away()
+        * and it works in that case.
+        */
+       if (cppr >= DEFAULT_PRIORITY)
+               cppr = LOWEST_PRIORITY;
+
        xics_set_base_cppr(cppr);
        opal_int_set_cppr(cppr);
        iosync();
index 69d858e51ac76f121741337031465cb1fd1ccebb..23efe4e42172210ee7784a9e8db07d6e2f087f7b 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/of.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/delay.h>
 
 #include <asm/prom.h>
 #include <asm/io.h>
@@ -198,9 +199,6 @@ void xics_migrate_irqs_away(void)
        /* Remove ourselves from the global interrupt queue */
        xics_set_cpu_giq(xics_default_distrib_server, 0);
 
-       /* Allow IPIs again... */
-       icp_ops->set_priority(DEFAULT_PRIORITY);
-
        for_each_irq_desc(virq, desc) {
                struct irq_chip *chip;
                long server;
@@ -255,6 +253,19 @@ void xics_migrate_irqs_away(void)
 unlock:
                raw_spin_unlock_irqrestore(&desc->lock, flags);
        }
+
+       /* Allow "sufficient" time to drop any inflight IRQ's */
+       mdelay(5);
+
+       /*
+        * Allow IPIs again. This is done at the very end, after migrating all
+        * interrupts, the expectation is that we'll only get woken up by an IPI
+        * interrupt beyond this point, but leave externals masked just to be
+        * safe. If we're using icp-opal this may actually allow all
+        * interrupts anyway, but that should be OK.
+        */
+       icp_ops->set_priority(DEFAULT_PRIORITY);
+
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
index 143b1e00b818493f4cb683c251e1d90ef6a5aa9e..4b176fe83da4c6abeeaec2144635c87337cb3388 100644 (file)
@@ -609,7 +609,7 @@ CONFIG_SCHED_TRACER=y
 CONFIG_FTRACE_SYSCALLS=y
 CONFIG_STACK_TRACER=y
 CONFIG_BLK_DEV_IO_TRACE=y
-CONFIG_UPROBE_EVENT=y
+CONFIG_UPROBE_EVENTS=y
 CONFIG_FUNCTION_PROFILER=y
 CONFIG_HIST_TRIGGERS=y
 CONFIG_TRACE_ENUM_MAP_FILE=y
index f05d2d6e10872a417cfb67a9624d7d74f56e5cc6..0de46cc397f6fe7a89f7e26c569287a41dc8a7fb 100644 (file)
@@ -560,7 +560,7 @@ CONFIG_SCHED_TRACER=y
 CONFIG_FTRACE_SYSCALLS=y
 CONFIG_STACK_TRACER=y
 CONFIG_BLK_DEV_IO_TRACE=y
-CONFIG_UPROBE_EVENT=y
+CONFIG_UPROBE_EVENTS=y
 CONFIG_FUNCTION_PROFILER=y
 CONFIG_HIST_TRIGGERS=y
 CONFIG_TRACE_ENUM_MAP_FILE=y
index 2358bf33c5efcf2790643f0b8bbd2a8c80a2fc8f..e167557b434c201e421c5bda3d263849859d7609 100644 (file)
@@ -558,7 +558,7 @@ CONFIG_SCHED_TRACER=y
 CONFIG_FTRACE_SYSCALLS=y
 CONFIG_STACK_TRACER=y
 CONFIG_BLK_DEV_IO_TRACE=y
-CONFIG_UPROBE_EVENT=y
+CONFIG_UPROBE_EVENTS=y
 CONFIG_FUNCTION_PROFILER=y
 CONFIG_HIST_TRIGGERS=y
 CONFIG_TRACE_ENUM_MAP_FILE=y
index 68bfd09f1b02ec23dad7ba4931db828f1286d890..97189dbaf34b2a36dade0738a64eb65bae38aafc 100644 (file)
@@ -179,7 +179,7 @@ CONFIG_FTRACE_SYSCALLS=y
 CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y
 CONFIG_STACK_TRACER=y
 CONFIG_BLK_DEV_IO_TRACE=y
-CONFIG_UPROBE_EVENT=y
+CONFIG_UPROBE_EVENTS=y
 CONFIG_FUNCTION_PROFILER=y
 CONFIG_TRACE_ENUM_MAP_FILE=y
 CONFIG_KPROBES_SANITY_TEST=y
index 7ef4a099defcda7f2d4e70fb7b3edec77361f2ec..6205d3b81e6d117b4116c2fa38ea40cea4a46fb8 100644 (file)
@@ -176,6 +176,7 @@ CONFIG_E1000E=y
 CONFIG_SKY2=y
 CONFIG_FORCEDETH=y
 CONFIG_8139TOO=y
+CONFIG_R8169=y
 CONFIG_FDDI=y
 CONFIG_INPUT_POLLDEV=y
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
index afb222b63caeb0217ef34d9b2b193b6b59bd190d..c84584bb940280b56f3b7d6d5365803ec4364505 100644 (file)
@@ -604,7 +604,7 @@ amd_get_event_constraints_f15h(struct cpu_hw_events *cpuc, int idx,
                        return &amd_f15_PMC20;
                }
        case AMD_EVENT_NB:
-               /* moved to perf_event_amd_uncore.c */
+               /* moved to uncore.c */
                return &emptyconstraint;
        default:
                return &emptyconstraint;
index aff4b5b69d4021aeb0ad4356833ca3c2380a7960..238ae3248ba5594265f14ef37ee6fde5c320675a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * perf_event_intel_cstate.c: support cstate residency counters
+ * Support cstate residency counters
  *
  * Copyright (C) 2015, Intel Corp.
  * Author: Kan Liang (kan.liang@intel.com)
index 22054ca49026511f6cbe2ee9ce30ca0f4281c78c..9d05c7e67f6073e3441c164d1bdc6db390507ef0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * perf_event_intel_rapl.c: support Intel RAPL energy consumption counters
+ * Support Intel RAPL energy consumption counters
  * Copyright (C) 2013 Google, Inc., Stephane Eranian
  *
  * Intel RAPL interface is specified in the IA-32 Manual Vol3b
index ad986c1e29bccd7d5303d94bcbf2caa9223fcf74..df5989f27b1b6508404af774c55953f5c9b082c4 100644 (file)
@@ -360,7 +360,7 @@ extern struct list_head pci2phy_map_head;
 extern struct pci_extra_dev *uncore_extra_pci_dev;
 extern struct event_constraint uncore_constraint_empty;
 
-/* perf_event_intel_uncore_snb.c */
+/* uncore_snb.c */
 int snb_uncore_pci_init(void);
 int ivb_uncore_pci_init(void);
 int hsw_uncore_pci_init(void);
@@ -371,7 +371,7 @@ void nhm_uncore_cpu_init(void);
 void skl_uncore_cpu_init(void);
 int snb_pci2phy_map_init(int devid);
 
-/* perf_event_intel_uncore_snbep.c */
+/* uncore_snbep.c */
 int snbep_uncore_pci_init(void);
 void snbep_uncore_cpu_init(void);
 int ivbep_uncore_pci_init(void);
@@ -385,5 +385,5 @@ void knl_uncore_cpu_init(void);
 int skx_uncore_pci_init(void);
 void skx_uncore_cpu_init(void);
 
-/* perf_event_intel_uncore_nhmex.c */
+/* uncore_nhmex.c */
 void nhmex_uncore_cpu_init(void);
index db64baf0e500b4d2172bb2b5980a4e222fbdc84e..8bef70e7f3cc6d242e7841bfa2404d182e5235cd 100644 (file)
@@ -158,13 +158,13 @@ void hyperv_init(void)
                clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100);
                return;
        }
+register_msr_cs:
 #endif
        /*
         * For 32 bit guests just use the MSR based mechanism for reading
         * the partition counter.
         */
 
-register_msr_cs:
        hyperv_cs = &hyperv_cs_msr;
        if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
                clocksource_register_hz(&hyperv_cs_msr, NSEC_PER_SEC/100);
index 34684adb6899ad132e44e159be621d92370b99c0..b3b09b98896d528d2ef7d425a10784e4ebe86106 100644 (file)
@@ -46,6 +46,15 @@ extern int __arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
 static inline
 bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey)
 {
+       /*
+        * "Allocated" pkeys are those that have been returned
+        * from pkey_alloc().  pkey 0 is special, and never
+        * returned from pkey_alloc().
+        */
+       if (pkey <= 0)
+               return false;
+       if (pkey >= arch_max_pkey())
+               return false;
        return mm_pkey_allocation_map(mm) & (1U << pkey);
 }
 
@@ -82,12 +91,6 @@ int mm_pkey_alloc(struct mm_struct *mm)
 static inline
 int mm_pkey_free(struct mm_struct *mm, int pkey)
 {
-       /*
-        * pkey 0 is special, always allocated and can never
-        * be freed.
-        */
-       if (!pkey)
-               return -EINVAL;
        if (!mm_pkey_is_allocated(mm, pkey))
                return -EINVAL;
 
index 5138dacf8bb8360511f7b3514f8ab0ac1a1e88f8..07244ea16765a6bc77e1107233c65fc7286f0e8b 100644 (file)
@@ -58,7 +58,7 @@ struct setup_header {
        __u32   header;
        __u16   version;
        __u32   realmode_swtch;
-       __u16   start_sys;
+       __u16   start_sys_seg;
        __u16   kernel_version;
        __u8    type_of_loader;
        __u8    loadflags;
index 4261b3282ad99dd87799683e33b2945bcfb20746..aee7deddabd089b31bef1739c51a7972e04cb10d 100644 (file)
@@ -1610,24 +1610,15 @@ static inline void try_to_enable_x2apic(int remap_mode) { }
 static inline void __x2apic_enable(void) { }
 #endif /* !CONFIG_X86_X2APIC */
 
-static int __init try_to_enable_IR(void)
-{
-#ifdef CONFIG_X86_IO_APIC
-       if (!x2apic_enabled() && skip_ioapic_setup) {
-               pr_info("Not enabling interrupt remapping due to skipped IO-APIC setup\n");
-               return -1;
-       }
-#endif
-       return irq_remapping_enable();
-}
-
 void __init enable_IR_x2apic(void)
 {
        unsigned long flags;
        int ret, ir_stat;
 
-       if (skip_ioapic_setup)
+       if (skip_ioapic_setup) {
+               pr_info("Not enabling interrupt remapping due to skipped IO-APIC setup\n");
                return;
+       }
 
        ir_stat = irq_remapping_prepare();
        if (ir_stat < 0 && !x2apic_supported())
@@ -1645,7 +1636,7 @@ void __init enable_IR_x2apic(void)
 
        /* If irq_remapping_prepare() succeeded, try to enable it */
        if (ir_stat >= 0)
-               ir_stat = try_to_enable_IR();
+               ir_stat = irq_remapping_enable();
        /* ir_stat contains the remap mode or an error code */
        try_to_enable_x2apic(ir_stat);
 
@@ -2062,10 +2053,10 @@ static int allocate_logical_cpuid(int apicid)
 
        /* Allocate a new cpuid. */
        if (nr_logical_cpuids >= nr_cpu_ids) {
-               WARN_ONCE(1, "Only %d processors supported."
+               WARN_ONCE(1, "APIC: NR_CPUS/possible_cpus limit of %i reached. "
                             "Processor %d/0x%x and the rest are ignored.\n",
-                            nr_cpu_ids - 1, nr_logical_cpuids, apicid);
-               return -1;
+                            nr_cpu_ids, nr_logical_cpuids, apicid);
+               return -EINVAL;
        }
 
        cpuid_to_apicid[nr_logical_cpuids] = apicid;
index 35a5d5dca2fae5fb68d522658824440f3b736d8b..c36140d788fe215aadb3a8f27a8de040f2c44c06 100644 (file)
@@ -556,10 +556,6 @@ static void early_init_amd(struct cpuinfo_x86 *c)
        if (c->x86_power & (1 << 8)) {
                set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
                set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
-               if (check_tsc_unstable())
-                       clear_sched_clock_stable();
-       } else {
-               clear_sched_clock_stable();
        }
 
        /* Bit 12 of 8000_0007 edx is accumulated power mechanism. */
index adc0ebd8bed0e17be1716f3fb7c3eab51b7fa0c4..43955ee6715b1876b89ebd615b8eb171bbde1dd0 100644 (file)
@@ -105,8 +105,6 @@ static void early_init_centaur(struct cpuinfo_x86 *c)
 #ifdef CONFIG_X86_64
        set_cpu_cap(c, X86_FEATURE_SYSENTER32);
 #endif
-
-       clear_sched_clock_stable();
 }
 
 static void init_centaur(struct cpuinfo_x86 *c)
index b11b38c3b0bde194b9139ebfa0d3bc251b96f803..58094a1f9e9d301e11d2c93a1ecc126e1715002e 100644 (file)
@@ -88,7 +88,6 @@ static void default_init(struct cpuinfo_x86 *c)
                        strcpy(c->x86_model_id, "386");
        }
 #endif
-       clear_sched_clock_stable();
 }
 
 static const struct cpu_dev default_cpu = {
@@ -1077,8 +1076,6 @@ static void identify_cpu(struct cpuinfo_x86 *c)
         */
        if (this_cpu->c_init)
                this_cpu->c_init(c);
-       else
-               clear_sched_clock_stable();
 
        /* Disable the PN if appropriate */
        squash_the_stupid_serial_number(c);
index 0a3bc19de0177e93f81ae24c58264e7205406fd6..a70fd61095f8a73baa5eb7c486afd6ff19cd4fd1 100644 (file)
@@ -185,7 +185,6 @@ static void early_init_cyrix(struct cpuinfo_x86 *c)
                set_cpu_cap(c, X86_FEATURE_CYRIX_ARR);
                break;
        }
-       clear_sched_clock_stable();
 }
 
 static void init_cyrix(struct cpuinfo_x86 *c)
index fe0a615a051b19a99f9388a7b245b326cee86e11..063197771b8d7ba08f2eafe474cacb0efe9e79d3 100644 (file)
@@ -162,10 +162,6 @@ static void early_init_intel(struct cpuinfo_x86 *c)
        if (c->x86_power & (1 << 8)) {
                set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
                set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
-               if (check_tsc_unstable())
-                       clear_sched_clock_stable();
-       } else {
-               clear_sched_clock_stable();
        }
 
        /* Penwell and Cloverview have the TSC which doesn't sleep on S3 */
index 0bbe0f3a039f6412f55863195cbb3a36b84ceb22..c05509d38b1f1e5ed0f63940dc2c8496b360b032 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/sched/signal.h>
 #include <linux/sched/task.h>
 #include <linux/slab.h>
-#include <linux/cpu.h>
 #include <linux/task_work.h>
 
 #include <uapi/linux/magic.h>
index 8457b49786686f74a737429ec47d04c2f92bab35..d77d07ab310b4317d33e44de10896297bb2a6654 100644 (file)
@@ -16,8 +16,6 @@ static void early_init_transmeta(struct cpuinfo_x86 *c)
                if (xlvl >= 0x80860001)
                        c->x86_capability[CPUID_8086_0001_EDX] = cpuid_edx(0x80860001);
        }
-
-       clear_sched_clock_stable();
 }
 
 static void init_transmeta(struct cpuinfo_x86 *c)
index 891f4dad7b2c49c81518e15ecee61bc8d4694ff2..22403a28caf52226163ae96779c3f2a79fc3431d 100644 (file)
@@ -30,7 +30,6 @@
 #include <asm/hypervisor.h>
 #include <asm/timer.h>
 #include <asm/apic.h>
-#include <asm/timer.h>
 
 #undef pr_fmt
 #define pr_fmt(fmt)    "vmware: " fmt
index dc6ba5bda9fc83630c773a80c4adea6871db0a59..89ff7af2de508ba0c34c2ce24c227dea5bf6d973 100644 (file)
@@ -354,7 +354,7 @@ static int hpet_resume(struct clock_event_device *evt, int timer)
 
                irq_domain_deactivate_irq(irq_get_irq_data(hdev->irq));
                irq_domain_activate_irq(irq_get_irq_data(hdev->irq));
-               disable_irq(hdev->irq);
+               disable_hardirq(hdev->irq);
                irq_set_affinity(hdev->irq, cpumask_of(hdev->cpu));
                enable_irq(hdev->irq);
        }
index bdb83e431d8976086e3c17328f01a9bdac2c1c8b..38b64587b31be5611a763df6dafe8434db2a66b5 100644 (file)
@@ -167,7 +167,7 @@ static int __init boot_params_kdebugfs_init(void)
        struct dentry *dbp, *version, *data;
        int error = -ENOMEM;
 
-       dbp = debugfs_create_dir("boot_params", NULL);
+       dbp = debugfs_create_dir("boot_params", arch_debugfs_dir);
        if (!dbp)
                return -ENOMEM;
 
index c6ee63f927ab721dd542b016bcfb22d65a55f114..d688826e5736a18c9f9343ebe278ec2b04bff66d 100644 (file)
@@ -67,7 +67,7 @@
 #endif
 
 /* Ensure if the instruction can be boostable */
-extern int can_boost(kprobe_opcode_t *instruction);
+extern int can_boost(kprobe_opcode_t *instruction, void *addr);
 /* Recover instruction if given address is probed */
 extern unsigned long recover_probed_instruction(kprobe_opcode_t *buf,
                                         unsigned long addr);
index 6384eb754a58302a18406c3a9587034bbff3c2c3..993fa4fe4f68694a3fa75406b2e762cfadbbf745 100644 (file)
@@ -167,12 +167,12 @@ NOKPROBE_SYMBOL(skip_prefixes);
  * Returns non-zero if opcode is boostable.
  * RIP relative instructions are adjusted at copying time in 64 bits mode
  */
-int can_boost(kprobe_opcode_t *opcodes)
+int can_boost(kprobe_opcode_t *opcodes, void *addr)
 {
        kprobe_opcode_t opcode;
        kprobe_opcode_t *orig_opcodes = opcodes;
 
-       if (search_exception_tables((unsigned long)opcodes))
+       if (search_exception_tables((unsigned long)addr))
                return 0;       /* Page fault may occur on this address. */
 
 retry:
@@ -417,7 +417,7 @@ static int arch_copy_kprobe(struct kprobe *p)
         * __copy_instruction can modify the displacement of the instruction,
         * but it doesn't affect boostable check.
         */
-       if (can_boost(p->ainsn.insn))
+       if (can_boost(p->ainsn.insn, p->addr))
                p->ainsn.boostable = 0;
        else
                p->ainsn.boostable = -1;
index 3d1bee9d6a728fd50645d0179986cd1dda6629d0..3e7c6e5a08ffde197c192ab57f3bb38aac590969 100644 (file)
@@ -178,7 +178,7 @@ static int copy_optimized_instructions(u8 *dest, u8 *src)
 
        while (len < RELATIVEJUMP_SIZE) {
                ret = __copy_instruction(dest + len, src + len);
-               if (!ret || !can_boost(dest + len))
+               if (!ret || !can_boost(dest + len, src + len))
                        return -EINVAL;
                len += ret;
        }
index e244c19a2451aa7d4dfa8bf34b1834e48f68ec54..4194d6f9bb290bcce8a581b3e3a38bf010262f0c 100644 (file)
@@ -223,6 +223,22 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
                        DMI_MATCH(DMI_BOARD_NAME, "P4S800"),
                },
        },
+       {       /* Handle problems with rebooting on ASUS EeeBook X205TA */
+               .callback = set_acpi_reboot,
+               .ident = "ASUS EeeBook X205TA",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "X205TAW"),
+               },
+       },
+       {       /* Handle problems with rebooting on ASUS EeeBook X205TAW */
+               .callback = set_acpi_reboot,
+               .ident = "ASUS EeeBook X205TAW",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "X205TAW"),
+               },
+       },
 
        /* Certec */
        {       /* Handle problems with rebooting on Certec BPC600 */
index 46bcda4cb1c2f84762bc409bf4c89b1528ba1c52..4f7a9833d8e51f2e023c3a5c0f6b54813c70c4a0 100644 (file)
@@ -327,9 +327,16 @@ unsigned long long sched_clock(void)
 {
        return paravirt_sched_clock();
 }
+
+static inline bool using_native_sched_clock(void)
+{
+       return pv_time_ops.sched_clock == native_sched_clock;
+}
 #else
 unsigned long long
 sched_clock(void) __attribute__((alias("native_sched_clock")));
+
+static inline bool using_native_sched_clock(void) { return true; }
 #endif
 
 int check_tsc_unstable(void)
@@ -1112,8 +1119,10 @@ static void tsc_cs_mark_unstable(struct clocksource *cs)
 {
        if (tsc_unstable)
                return;
+
        tsc_unstable = 1;
-       clear_sched_clock_stable();
+       if (using_native_sched_clock())
+               clear_sched_clock_stable();
        disable_sched_clock_irqtime();
        pr_info("Marking TSC unstable due to clocksource watchdog\n");
 }
@@ -1135,18 +1144,20 @@ static struct clocksource clocksource_tsc = {
 
 void mark_tsc_unstable(char *reason)
 {
-       if (!tsc_unstable) {
-               tsc_unstable = 1;
+       if (tsc_unstable)
+               return;
+
+       tsc_unstable = 1;
+       if (using_native_sched_clock())
                clear_sched_clock_stable();
-               disable_sched_clock_irqtime();
-               pr_info("Marking TSC unstable due to %s\n", reason);
-               /* Change only the rating, when not registered */
-               if (clocksource_tsc.mult)
-                       clocksource_mark_unstable(&clocksource_tsc);
-               else {
-                       clocksource_tsc.flags |= CLOCK_SOURCE_UNSTABLE;
-                       clocksource_tsc.rating = 0;
-               }
+       disable_sched_clock_irqtime();
+       pr_info("Marking TSC unstable due to %s\n", reason);
+       /* Change only the rating, when not registered */
+       if (clocksource_tsc.mult) {
+               clocksource_mark_unstable(&clocksource_tsc);
+       } else {
+               clocksource_tsc.flags |= CLOCK_SOURCE_UNSTABLE;
+               clocksource_tsc.rating = 0;
        }
 }
 
index 0cb52ae0a8f07521ee1cdf6a1075a4221f920884..190e718694b1720df737afdd9688ded962be6014 100644 (file)
@@ -735,6 +735,15 @@ void pcibios_disable_device (struct pci_dev *dev)
                pcibios_disable_irq(dev);
 }
 
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+void pcibios_release_device(struct pci_dev *dev)
+{
+       if (atomic_dec_return(&dev->enable_cnt) >= 0)
+               pcibios_disable_device(dev);
+
+}
+#endif
+
 int pci_ext_cfg_avail(void)
 {
        if (raw_pci_ext_ops)
index 766d4d3529a1d946e36d4186e4c48da5d90b75cc..f25982cdff9006960d9e354d132ff01df717ad9b 100644 (file)
@@ -1847,7 +1847,6 @@ static void pq_init(int node, int pnode)
 
        ops.write_payload_first(pnode, first);
        ops.write_payload_last(pnode, last);
-       ops.write_g_sw_ack(pnode, 0xffffUL);
 
        /* in effect, all msg_type's are set to MSG_NOOP */
        memset(pqp, 0, sizeof(struct bau_pq_entry) * DEST_Q_SIZE);
index 25e068ba338214826413265b26ccd9179e10b7f4..b6d5c8946e664aad672d15c3058e214c8192b8c6 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include "sha256.h"
+#include "purgatory.h"
 #include "../boot/string.h"
 
 struct sha_region {
@@ -18,11 +19,11 @@ struct sha_region {
        unsigned long len;
 };
 
-unsigned long backup_dest = 0;
-unsigned long backup_src = 0;
-unsigned long backup_sz = 0;
+static unsigned long backup_dest;
+static unsigned long backup_src;
+static unsigned long backup_sz;
 
-u8 sha256_digest[SHA256_DIGEST_SIZE] = { 0 };
+static u8 sha256_digest[SHA256_DIGEST_SIZE] = { 0 };
 
 struct sha_region sha_regions[16] = {};
 
@@ -39,7 +40,7 @@ static int copy_backup_region(void)
        return 0;
 }
 
-int verify_sha256_digest(void)
+static int verify_sha256_digest(void)
 {
        struct sha_region *ptr, *end;
        u8 digest[SHA256_DIGEST_SIZE];
diff --git a/arch/x86/purgatory/purgatory.h b/arch/x86/purgatory/purgatory.h
new file mode 100644 (file)
index 0000000..e2e365a
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef PURGATORY_H
+#define PURGATORY_H
+
+#ifndef __ASSEMBLY__
+extern void purgatory(void);
+#endif /* __ASSEMBLY__ */
+
+#endif /* PURGATORY_H */
index fe3c91ba1bd0c6fd0fe0c880510364dbda0fa5c5..f90e9dfa90bb928979698d46af465e537f8314a2 100644 (file)
@@ -9,6 +9,7 @@
  * This source code is licensed under the GNU General Public License,
  * Version 2.  See the file COPYING for more details.
  */
+#include "purgatory.h"
 
        .text
        .globl purgatory_start
index 219b90bc092297c753639f84972939710de25298..f15900132912a4349ecc5b6efe6a2d2e8ff6530f 100644 (file)
@@ -41,8 +41,10 @@ void acpi_gpe_apply_masked_gpes(void);
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+void pci_ioapic_remove(struct acpi_pci_root *root);
 int acpi_ioapic_remove(struct acpi_pci_root *root);
 #else
+static inline void pci_ioapic_remove(struct acpi_pci_root *root) { return; }
 static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
 #endif
 #ifdef CONFIG_ACPI_DOCK
index 6d7ce6e12aaa6662b360c391f8c3b5e84a84ddc7..1120dfd625b8a18a81030c7b6a4276769594879c 100644 (file)
@@ -206,24 +206,34 @@ int acpi_ioapic_add(acpi_handle root_handle)
        return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
 }
 
-int acpi_ioapic_remove(struct acpi_pci_root *root)
+void pci_ioapic_remove(struct acpi_pci_root *root)
 {
-       int retval = 0;
        struct acpi_pci_ioapic *ioapic, *tmp;
 
        mutex_lock(&ioapic_list_lock);
        list_for_each_entry_safe(ioapic, tmp, &ioapic_list, list) {
                if (root->device->handle != ioapic->root_handle)
                        continue;
-
-               if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base))
-                       retval = -EBUSY;
-
                if (ioapic->pdev) {
                        pci_release_region(ioapic->pdev, 0);
                        pci_disable_device(ioapic->pdev);
                        pci_dev_put(ioapic->pdev);
                }
+       }
+       mutex_unlock(&ioapic_list_lock);
+}
+
+int acpi_ioapic_remove(struct acpi_pci_root *root)
+{
+       int retval = 0;
+       struct acpi_pci_ioapic *ioapic, *tmp;
+
+       mutex_lock(&ioapic_list_lock);
+       list_for_each_entry_safe(ioapic, tmp, &ioapic_list, list) {
+               if (root->device->handle != ioapic->root_handle)
+                       continue;
+               if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base))
+                       retval = -EBUSY;
                if (ioapic->res.flags && ioapic->res.parent)
                        release_resource(&ioapic->res);
                list_del(&ioapic->list);
index bf601d4df8cfcbb6e579b00cbff75efcb24d8071..919be0aa2578760d466031f866a0e8772adf7f97 100644 (file)
@@ -648,12 +648,12 @@ static void acpi_pci_root_remove(struct acpi_device *device)
 
        pci_stop_root_bus(root->bus);
 
-       WARN_ON(acpi_ioapic_remove(root));
-
+       pci_ioapic_remove(root);
        device_set_run_wake(root->bus->bridge, false);
        pci_acpi_remove_bus_pm_notifier(device);
 
        pci_remove_root_bus(root->bus);
+       WARN_ON(acpi_ioapic_remove(root));
 
        dmar_device_remove(device->handle);
 
index a5b1eb276c0bf97c9959d72171cf1738ac0503b6..e6d0d271c58c83073e3acb71c788867d4edfc846 100644 (file)
@@ -6,7 +6,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/sched/signal.h>
 #include <linux/interrupt.h>
 #include <linux/time.h>
 #include <linux/timer.h>
index 349dc3e1e52e0a67bea26d971aa7d7e2764caabe..974c5a31a00598e0bcdb1742967cc7cca691a7cb 100644 (file)
@@ -65,6 +65,7 @@ static bool __init efi_virtmap_init(void)
        bool systab_found;
 
        efi_mm.pgd = pgd_alloc(&efi_mm);
+       mm_init_cpumask(&efi_mm);
        init_new_context(NULL, &efi_mm);
 
        systab_found = false;
index 6def402bf5691f504292b88ff994b9a472fa2bc5..5da36e56b36a1cc29c971934559e5852bed0e7bc 100644 (file)
@@ -45,6 +45,8 @@ enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table_arg)
        size = sizeof(secboot);
        status = get_efi_var(efi_SecureBoot_name, &efi_variable_guid,
                             NULL, &size, &secboot);
+       if (status == EFI_NOT_FOUND)
+               return efi_secureboot_mode_disabled;
        if (status != EFI_SUCCESS)
                goto out_efi_err;
 
@@ -78,7 +80,5 @@ secure_boot_enabled:
 
 out_efi_err:
        pr_efi_err(sys_table_arg, "Could not determine UEFI Secure Boot status.\n");
-       if (status == EFI_NOT_FOUND)
-               return efi_secureboot_mode_disabled;
        return efi_secureboot_mode_unknown;
 }
index 1eef56a89b1fbff1ee348f08b4623f6fcf4f6851..05bbf171df37720b7a3185e4e56dd8ee318beaf2 100644 (file)
@@ -198,7 +198,8 @@ static const struct irq_domain_ops crossbar_domain_ops = {
 
 static int __init crossbar_of_init(struct device_node *node)
 {
-       int i, size, max = 0, reserved = 0, entry;
+       int i, size, reserved = 0;
+       u32 max = 0, entry;
        const __be32 *irqsr;
        int ret = -ENOMEM;
 
index f8afc6dcc29f2769694308092a4b543e5e0bed49..e8cef1ad0fe31e0139903399d70730c7eafdc399 100644 (file)
@@ -681,3 +681,50 @@ xen_swiotlb_set_dma_mask(struct device *dev, u64 dma_mask)
        return 0;
 }
 EXPORT_SYMBOL_GPL(xen_swiotlb_set_dma_mask);
+
+/*
+ * Create userspace mapping for the DMA-coherent memory.
+ * This function should be called with the pages from the current domain only,
+ * passing pages mapped from other domains would lead to memory corruption.
+ */
+int
+xen_swiotlb_dma_mmap(struct device *dev, struct vm_area_struct *vma,
+                    void *cpu_addr, dma_addr_t dma_addr, size_t size,
+                    unsigned long attrs)
+{
+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
+       if (__generic_dma_ops(dev)->mmap)
+               return __generic_dma_ops(dev)->mmap(dev, vma, cpu_addr,
+                                                   dma_addr, size, attrs);
+#endif
+       return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
+}
+EXPORT_SYMBOL_GPL(xen_swiotlb_dma_mmap);
+
+/*
+ * This function should be called with the pages from the current domain only,
+ * passing pages mapped from other domains would lead to memory corruption.
+ */
+int
+xen_swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt,
+                       void *cpu_addr, dma_addr_t handle, size_t size,
+                       unsigned long attrs)
+{
+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
+       if (__generic_dma_ops(dev)->get_sgtable) {
+#if 0
+       /*
+        * This check verifies that the page belongs to the current domain and
+        * is not one mapped from another domain.
+        * This check is for debug only, and should not go to production build
+        */
+               unsigned long bfn = PHYS_PFN(dma_to_phys(dev, handle));
+               BUG_ON (!page_is_ram(bfn));
+#endif
+               return __generic_dma_ops(dev)->get_sgtable(dev, sgt, cpu_addr,
+                                                          handle, size, attrs);
+       }
+#endif
+       return dma_common_get_sgtable(dev, sgt, cpu_addr, handle, size);
+}
+EXPORT_SYMBOL_GPL(xen_swiotlb_get_sgtable);
index 384fa759a563341b309df47537f9c94da0ee9ebb..c543cdb5f8ed9b803eea973dbb5ed68cfe395e1f 100644 (file)
@@ -400,9 +400,9 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
             clockid != CLOCK_BOOTTIME_ALARM))
                return -EINVAL;
 
-       if (!capable(CAP_WAKE_ALARM) &&
-           (clockid == CLOCK_REALTIME_ALARM ||
-            clockid == CLOCK_BOOTTIME_ALARM))
+       if ((clockid == CLOCK_REALTIME_ALARM ||
+            clockid == CLOCK_BOOTTIME_ALARM) &&
+           !capable(CAP_WAKE_ALARM))
                return -EPERM;
 
        ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
@@ -449,7 +449,7 @@ static int do_timerfd_settime(int ufd, int flags,
                return ret;
        ctx = f.file->private_data;
 
-       if (!capable(CAP_WAKE_ALARM) && isalarm(ctx)) {
+       if (isalarm(ctx) && !capable(CAP_WAKE_ALARM)) {
                fdput(f);
                return -EPERM;
        }
index 8e06d758ee48a2d92da7b9cfba79175334423b48..2afd74b9d844095375be39342e78b5a6749e2a52 100644 (file)
@@ -90,6 +90,13 @@ extern bool static_key_initialized;
 struct static_key {
        atomic_t enabled;
 /*
+ * Note:
+ *   To make anonymous unions work with old compilers, the static
+ *   initialization of them requires brackets. This creates a dependency
+ *   on the order of the struct with the initializers. If any fields
+ *   are added, STATIC_KEY_INIT_TRUE and STATIC_KEY_INIT_FALSE may need
+ *   to be modified.
+ *
  * bit 0 => 1 if key is initially true
  *         0 if initially false
  * bit 1 => 1 if points to struct static_key_mod
@@ -166,10 +173,10 @@ extern void static_key_disable(struct static_key *key);
  */
 #define STATIC_KEY_INIT_TRUE                                   \
        { .enabled = { 1 },                                     \
-         .entries = (void *)JUMP_TYPE_TRUE }
+         { .entries = (void *)JUMP_TYPE_TRUE } }
 #define STATIC_KEY_INIT_FALSE                                  \
        { .enabled = { 0 },                                     \
-         .entries = (void *)JUMP_TYPE_FALSE }
+         { .entries = (void *)JUMP_TYPE_FALSE } }
 
 #else  /* !HAVE_JUMP_LABEL */
 
index be765234c0a2b999f0f2bfcdb9f36b2cc16fa0c6..32354b4b4b2ba5ae72034d00c3b1d43fa8c2a15c 100644 (file)
@@ -72,7 +72,7 @@ struct ucounts {
        struct hlist_node node;
        struct user_namespace *ns;
        kuid_t uid;
-       atomic_t count;
+       int count;
        atomic_t ucount[UCOUNT_COUNTS];
 };
 
index 14e49c7981359ccdac1e2d9d87a3c284e7c682f3..b35533b9427719c3ddcd2c776a20f52d5465aea0 100644 (file)
@@ -1,5 +1,6 @@
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM raw_syscalls
+#undef TRACE_INCLUDE_FILE
 #define TRACE_INCLUDE_FILE syscalls
 
 #if !defined(_TRACE_EVENTS_SYSCALLS_H) || defined(TRACE_HEADER_MULTI_READ)
index a0083be5d5295157bc11b82a343b58f798488bb8..1f6d78f044b671bca827b15c5b6b8388c09e4fa6 100644 (file)
@@ -2,6 +2,7 @@
 #define __LINUX_SWIOTLB_XEN_H
 
 #include <linux/dma-direction.h>
+#include <linux/scatterlist.h>
 #include <linux/swiotlb.h>
 
 extern int xen_swiotlb_init(int verbose, bool early);
@@ -55,4 +56,14 @@ xen_swiotlb_dma_supported(struct device *hwdev, u64 mask);
 
 extern int
 xen_swiotlb_set_dma_mask(struct device *dev, u64 dma_mask);
+
+extern int
+xen_swiotlb_dma_mmap(struct device *dev, struct vm_area_struct *vma,
+                    void *cpu_addr, dma_addr_t dma_addr, size_t size,
+                    unsigned long attrs);
+
+extern int
+xen_swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt,
+                       void *cpu_addr, dma_addr_t handle, size_t size,
+                       unsigned long attrs);
 #endif /* __LINUX_SWIOTLB_XEN_H */
index 12e38c213b70111c1b343af3b1b0bb4eaa99f829..a95e5d1f4a9c447de6aa4b0b1b85e5f56de9f729 100644 (file)
@@ -3262,10 +3262,17 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
        if (depth) {
                hlock = curr->held_locks + depth - 1;
                if (hlock->class_idx == class_idx && nest_lock) {
-                       if (hlock->references)
+                       if (hlock->references) {
+                               /*
+                                * Check: unsigned int references:12, overflow.
+                                */
+                               if (DEBUG_LOCKS_WARN_ON(hlock->references == (1 << 12)-1))
+                                       return 0;
+
                                hlock->references++;
-                       else
+                       } else {
                                hlock->references = 2;
+                       }
 
                        return 1;
                }
index da6c9a34f62f5c74f17eada78d6bb843c8fbf01d..6b7abb334ca6027dd2b189a211671fa98a33be82 100644 (file)
@@ -50,7 +50,7 @@ static void test_mutex_work(struct work_struct *work)
 
        if (mtx->flags & TEST_MTX_TRY) {
                while (!ww_mutex_trylock(&mtx->mutex))
-                       cpu_relax();
+                       cond_resched();
        } else {
                ww_mutex_lock(&mtx->mutex, NULL);
        }
@@ -88,7 +88,7 @@ static int __test_mutex(unsigned int flags)
                                ret = -EINVAL;
                                break;
                        }
-                       cpu_relax();
+                       cond_resched();
                } while (time_before(jiffies, timeout));
        } else {
                ret = wait_for_completion_timeout(&mtx.done, TIMEOUT);
@@ -627,7 +627,7 @@ static int __init test_ww_mutex_init(void)
        if (ret)
                return ret;
 
-       ret = stress(4096, hweight32(STRESS_ALL)*ncpus, 1<<12, STRESS_ALL);
+       ret = stress(4095, hweight32(STRESS_ALL)*ncpus, 1<<12, STRESS_ALL);
        if (ret)
                return ret;
 
index 956383844116ab456f8552abd4b5dcc00e09f347..3b31fc05a0f1e45be5985b860a5fde95ee969832 100644 (file)
@@ -3287,10 +3287,15 @@ pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
        struct task_struct *p;
 
        /*
-        * Optimization: we know that if all tasks are in
-        * the fair class we can call that function directly:
+        * Optimization: we know that if all tasks are in the fair class we can
+        * call that function directly, but only if the @prev task wasn't of a
+        * higher scheduling class, because otherwise those loose the
+        * opportunity to pull in more work from other CPUs.
         */
-       if (likely(rq->nr_running == rq->cfs.h_nr_running)) {
+       if (likely((prev->sched_class == &idle_sched_class ||
+                   prev->sched_class == &fair_sched_class) &&
+                  rq->nr_running == rq->cfs.h_nr_running)) {
+
                p = fair_sched_class.pick_next_task(rq, prev, rf);
                if (unlikely(p == RETRY_TASK))
                        goto again;
index 3e88b35ac1571cd2dc1719378902ca75c08cfbb9..dea138964b9107b3e22542a8b80f5cf1d43c1dee 100644 (file)
@@ -5799,7 +5799,7 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t
         * Due to large variance we need a large fuzz factor; hackbench in
         * particularly is sensitive here.
         */
-       if ((avg_idle / 512) < avg_cost)
+       if (sched_feat(SIS_AVG_CPU) && (avg_idle / 512) < avg_cost)
                return -1;
 
        time = local_clock();
index 69631fa46c2f84fecd3e15599cba0e5935c1148e..1b3c8189b28656d2644a714ff60ceab7d015d97b 100644 (file)
@@ -51,6 +51,11 @@ SCHED_FEAT(NONTASK_CAPACITY, true)
  */
 SCHED_FEAT(TTWU_QUEUE, true)
 
+/*
+ * When doing wakeups, attempt to limit superfluous scans of the LLC domain.
+ */
+SCHED_FEAT(SIS_AVG_CPU, false)
+
 #ifdef HAVE_RT_PUSH_IPI
 /*
  * In order to avoid a thundering herd attack of CPUs that are
index 7906b3f0c41a1a5b662c703c428a892ad7816670..497719127bf9f65c1c992874abc33f0c52d5c766 100644 (file)
@@ -125,7 +125,7 @@ int register_refined_jiffies(long cycles_per_second)
        shift_hz += cycles_per_tick/2;
        do_div(shift_hz, cycles_per_tick);
        /* Calculate nsec_per_tick using shift_hz */
-       nsec_per_tick = (u64)TICK_NSEC << 8;
+       nsec_per_tick = (u64)NSEC_PER_SEC << 8;
        nsec_per_tick += (u32)shift_hz/2;
        do_div(nsec_per_tick, (u32)shift_hz);
 
index d5038005eb5dc06dd8432cc17e5be3c2c1de7e81..d4a06e714645df56f75db97ba6bb052534a4bb41 100644 (file)
@@ -429,7 +429,7 @@ config BLK_DEV_IO_TRACE
 
          If unsure, say N.
 
-config KPROBE_EVENT
+config KPROBE_EVENTS
        depends on KPROBES
        depends on HAVE_REGS_AND_STACK_ACCESS_API
        bool "Enable kprobes-based dynamic events"
@@ -447,7 +447,7 @@ config KPROBE_EVENT
          This option is also required by perf-probe subcommand of perf tools.
          If you want to use perf tools, this option is strongly recommended.
 
-config UPROBE_EVENT
+config UPROBE_EVENTS
        bool "Enable uprobes-based dynamic events"
        depends on ARCH_SUPPORTS_UPROBES
        depends on MMU
@@ -466,7 +466,7 @@ config UPROBE_EVENT
 
 config BPF_EVENTS
        depends on BPF_SYSCALL
-       depends on (KPROBE_EVENT || UPROBE_EVENT) && PERF_EVENTS
+       depends on (KPROBE_EVENTS || UPROBE_EVENTS) && PERF_EVENTS
        bool
        default y
        help
index e5798084554911440844e1757c9ee656dc40cf12..90f2701d92a7eee98334f2b10e515b369307df2b 100644 (file)
@@ -57,7 +57,7 @@ obj-$(CONFIG_EVENT_TRACING) += trace_events_filter.o
 obj-$(CONFIG_EVENT_TRACING) += trace_events_trigger.o
 obj-$(CONFIG_HIST_TRIGGERS) += trace_events_hist.o
 obj-$(CONFIG_BPF_EVENTS) += bpf_trace.o
-obj-$(CONFIG_KPROBE_EVENT) += trace_kprobe.o
+obj-$(CONFIG_KPROBE_EVENTS) += trace_kprobe.o
 obj-$(CONFIG_TRACEPOINTS) += power-traces.o
 ifeq ($(CONFIG_PM),y)
 obj-$(CONFIG_TRACEPOINTS) += rpm-traces.o
@@ -66,7 +66,7 @@ ifeq ($(CONFIG_TRACING),y)
 obj-$(CONFIG_KGDB_KDB) += trace_kdb.o
 endif
 obj-$(CONFIG_PROBE_EVENTS) += trace_probe.o
-obj-$(CONFIG_UPROBE_EVENT) += trace_uprobe.o
+obj-$(CONFIG_UPROBE_EVENTS) += trace_uprobe.o
 
 obj-$(CONFIG_TRACEPOINT_BENCHMARK) += trace_benchmark.o
 
index 0d1597c9ee305780ff65200001b55928dcdf09e3..b9691ee8f6c182cfee1af7308555b9291f3730bd 100644 (file)
@@ -4416,16 +4416,24 @@ static int __init set_graph_notrace_function(char *str)
 }
 __setup("ftrace_graph_notrace=", set_graph_notrace_function);
 
+static int __init set_graph_max_depth_function(char *str)
+{
+       if (!str)
+               return 0;
+       fgraph_max_depth = simple_strtoul(str, NULL, 0);
+       return 1;
+}
+__setup("ftrace_graph_max_depth=", set_graph_max_depth_function);
+
 static void __init set_ftrace_early_graph(char *buf, int enable)
 {
        int ret;
        char *func;
        struct ftrace_hash *hash;
 
-       if (enable)
-               hash = ftrace_graph_hash;
-       else
-               hash = ftrace_graph_notrace_hash;
+       hash = alloc_ftrace_hash(FTRACE_HASH_DEFAULT_BITS);
+       if (WARN_ON(!hash))
+               return;
 
        while (buf) {
                func = strsep(&buf, ",");
@@ -4435,6 +4443,11 @@ static void __init set_ftrace_early_graph(char *buf, int enable)
                        printk(KERN_DEBUG "ftrace: function %s not "
                                          "traceable\n", func);
        }
+
+       if (enable)
+               ftrace_graph_hash = hash;
+       else
+               ftrace_graph_notrace_hash = hash;
 }
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 
@@ -5488,7 +5501,7 @@ static void ftrace_ops_assist_func(unsigned long ip, unsigned long parent_ip,
  * Normally the mcount trampoline will call the ops->func, but there
  * are times that it should not. For example, if the ops does not
  * have its own recursion protection, then it should call the
- * ftrace_ops_recurs_func() instead.
+ * ftrace_ops_assist_func() instead.
  *
  * Returns the function that the trampoline should call for @ops.
  */
index 707445ceb7efd4e098ba3ad5a129bb19a03122f9..f35109514a015c38de8b2e1da99399fd5f399692 100644 (file)
@@ -4341,22 +4341,22 @@ static const char readme_msg[] =
        "\t\t\t  traces\n"
 #endif
 #endif /* CONFIG_STACK_TRACER */
-#ifdef CONFIG_KPROBE_EVENT
+#ifdef CONFIG_KPROBE_EVENTS
        "  kprobe_events\t\t- Add/remove/show the kernel dynamic events\n"
        "\t\t\t  Write into this file to define/undefine new trace events.\n"
 #endif
-#ifdef CONFIG_UPROBE_EVENT
+#ifdef CONFIG_UPROBE_EVENTS
        "  uprobe_events\t\t- Add/remove/show the userspace dynamic events\n"
        "\t\t\t  Write into this file to define/undefine new trace events.\n"
 #endif
-#if defined(CONFIG_KPROBE_EVENT) || defined(CONFIG_UPROBE_EVENT)
+#if defined(CONFIG_KPROBE_EVENTS) || defined(CONFIG_UPROBE_EVENTS)
        "\t  accepts: event-definitions (one definition per line)\n"
        "\t   Format: p|r[:[<group>/]<event>] <place> [<args>]\n"
        "\t           -:[<group>/]<event>\n"
-#ifdef CONFIG_KPROBE_EVENT
+#ifdef CONFIG_KPROBE_EVENTS
        "\t    place: [<module>:]<symbol>[+<offset>]|<memaddr>\n"
 #endif
-#ifdef CONFIG_UPROBE_EVENT
+#ifdef CONFIG_UPROBE_EVENTS
        "\t    place: <path>:<offset>\n"
 #endif
        "\t     args: <name>=fetcharg[:type]\n"
index 0c0ae54d44c616d5d09876165c2516c3e032af77..903273c93e6167afcbe2de99451a906c2e79ab1f 100644 (file)
@@ -248,7 +248,7 @@ ASSIGN_FETCH_FUNC(file_offset, ftype),                      \
 #define FETCH_TYPE_STRING      0
 #define FETCH_TYPE_STRSIZE     1
 
-#ifdef CONFIG_KPROBE_EVENT
+#ifdef CONFIG_KPROBE_EVENTS
 struct symbol_cache;
 unsigned long update_symbol_cache(struct symbol_cache *sc);
 void free_symbol_cache(struct symbol_cache *sc);
@@ -278,7 +278,7 @@ alloc_symbol_cache(const char *sym, long offset)
 {
        return NULL;
 }
-#endif /* CONFIG_KPROBE_EVENT */
+#endif /* CONFIG_KPROBE_EVENTS */
 
 struct probe_arg {
        struct fetch_param      fetch;
index 62630a40ab3a4225291c7804ff67917aa997646c..b4eeee03934fe8f083b70e9907be0721759bc3be 100644 (file)
@@ -144,7 +144,7 @@ static struct ucounts *get_ucounts(struct user_namespace *ns, kuid_t uid)
 
                new->ns = ns;
                new->uid = uid;
-               atomic_set(&new->count, 0);
+               new->count = 0;
 
                spin_lock_irq(&ucounts_lock);
                ucounts = find_ucounts(ns, uid, hashent);
@@ -155,8 +155,10 @@ static struct ucounts *get_ucounts(struct user_namespace *ns, kuid_t uid)
                        ucounts = new;
                }
        }
-       if (!atomic_add_unless(&ucounts->count, 1, INT_MAX))
+       if (ucounts->count == INT_MAX)
                ucounts = NULL;
+       else
+               ucounts->count += 1;
        spin_unlock_irq(&ucounts_lock);
        return ucounts;
 }
@@ -165,13 +167,15 @@ static void put_ucounts(struct ucounts *ucounts)
 {
        unsigned long flags;
 
-       if (atomic_dec_and_test(&ucounts->count)) {
-               spin_lock_irqsave(&ucounts_lock, flags);
+       spin_lock_irqsave(&ucounts_lock, flags);
+       ucounts->count -= 1;
+       if (!ucounts->count)
                hlist_del_init(&ucounts->node);
-               spin_unlock_irqrestore(&ucounts_lock, flags);
+       else
+               ucounts = NULL;
+       spin_unlock_irqrestore(&ucounts_lock, flags);
 
-               kfree(ucounts);
-       }
+       kfree(ucounts);
 }
 
 static inline bool atomic_inc_below(atomic_t *v, int u)
index 5ed506d648c4e53ee955e9c19b942fd0d666eee1..691a9ad48497b02e3b09304d6565165ef2317b16 100644 (file)
@@ -2129,8 +2129,8 @@ int ida_pre_get(struct ida *ida, gfp_t gfp)
                struct ida_bitmap *bitmap = kmalloc(sizeof(*bitmap), gfp);
                if (!bitmap)
                        return 0;
-               bitmap = this_cpu_cmpxchg(ida_bitmap, NULL, bitmap);
-               kfree(bitmap);
+               if (this_cpu_cmpxchg(ida_bitmap, NULL, bitmap))
+                       kfree(bitmap);
        }
 
        return 1;
index 1d33366189d10c88bf10616e6a9b25c64c4bf570..aa09ad3c30b0dc37a920c46f0da711f366d29423 100644 (file)
@@ -58,7 +58,7 @@ bool refcount_add_not_zero(unsigned int i, refcount_t *r)
                val = old;
        }
 
-       WARN(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n");
+       WARN_ONCE(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n");
 
        return true;
 }
@@ -66,7 +66,7 @@ EXPORT_SYMBOL_GPL(refcount_add_not_zero);
 
 void refcount_add(unsigned int i, refcount_t *r)
 {
-       WARN(!refcount_add_not_zero(i, r), "refcount_t: addition on 0; use-after-free.\n");
+       WARN_ONCE(!refcount_add_not_zero(i, r), "refcount_t: addition on 0; use-after-free.\n");
 }
 EXPORT_SYMBOL_GPL(refcount_add);
 
@@ -97,7 +97,7 @@ bool refcount_inc_not_zero(refcount_t *r)
                val = old;
        }
 
-       WARN(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n");
+       WARN_ONCE(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n");
 
        return true;
 }
@@ -111,7 +111,7 @@ EXPORT_SYMBOL_GPL(refcount_inc_not_zero);
  */
 void refcount_inc(refcount_t *r)
 {
-       WARN(!refcount_inc_not_zero(r), "refcount_t: increment on 0; use-after-free.\n");
+       WARN_ONCE(!refcount_inc_not_zero(r), "refcount_t: increment on 0; use-after-free.\n");
 }
 EXPORT_SYMBOL_GPL(refcount_inc);
 
@@ -125,7 +125,7 @@ bool refcount_sub_and_test(unsigned int i, refcount_t *r)
 
                new = val - i;
                if (new > val) {
-                       WARN(new > val, "refcount_t: underflow; use-after-free.\n");
+                       WARN_ONCE(new > val, "refcount_t: underflow; use-after-free.\n");
                        return false;
                }
 
@@ -164,7 +164,7 @@ EXPORT_SYMBOL_GPL(refcount_dec_and_test);
 
 void refcount_dec(refcount_t *r)
 {
-       WARN(refcount_dec_and_test(r), "refcount_t: decrement hit 0; leaking memory.\n");
+       WARN_ONCE(refcount_dec_and_test(r), "refcount_t: decrement hit 0; leaking memory.\n");
 }
 EXPORT_SYMBOL_GPL(refcount_dec);
 
@@ -204,7 +204,7 @@ bool refcount_dec_not_one(refcount_t *r)
 
                new = val - 1;
                if (new > val) {
-                       WARN(new > val, "refcount_t: underflow; use-after-free.\n");
+                       WARN_ONCE(new > val, "refcount_t: underflow; use-after-free.\n");
                        return true;
                }
 
index cf7e52e4781b9b193f28dcbe1f6de9ed415eb50d..9b6e246a45d09f530b3527b81946a30b1256697f 100644 (file)
@@ -22,4 +22,6 @@ SECTIONS {
 
        . = ALIGN(8);
        .init_array             0 : { *(SORT(.init_array.*)) *(.init_array) }
+
+       __jump_table            0 : ALIGN(8) { KEEP(*(__jump_table)) }
 }
index 4cfdbb5b696783cbeb097f04220c180e7e87e82a..066086dd59a8017e293993a50d2f432d47441cfe 100644 (file)
@@ -805,11 +805,20 @@ static struct rela *find_switch_table(struct objtool_file *file,
                     insn->jump_dest->offset > orig_insn->offset))
                    break;
 
+               /* look for a relocation which references .rodata */
                text_rela = find_rela_by_dest_range(insn->sec, insn->offset,
                                                    insn->len);
-               if (text_rela && text_rela->sym == file->rodata->sym)
-                       return find_rela_by_dest(file->rodata,
-                                                text_rela->addend);
+               if (!text_rela || text_rela->sym != file->rodata->sym)
+                       continue;
+
+               /*
+                * Make sure the .rodata address isn't associated with a
+                * symbol.  gcc jump tables are anonymous data.
+                */
+               if (find_symbol_containing(file->rodata, text_rela->addend))
+                       continue;
+
+               return find_rela_by_dest(file->rodata, text_rela->addend);
        }
 
        return NULL;
index 0d7983ac63ef9e300110d9a6ec6771a75378784e..d897702ce7427804da2c09387f674077f22accc5 100644 (file)
@@ -85,6 +85,18 @@ struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset)
        return NULL;
 }
 
+struct symbol *find_symbol_containing(struct section *sec, unsigned long offset)
+{
+       struct symbol *sym;
+
+       list_for_each_entry(sym, &sec->symbol_list, list)
+               if (sym->type != STT_SECTION &&
+                   offset >= sym->offset && offset < sym->offset + sym->len)
+                       return sym;
+
+       return NULL;
+}
+
 struct rela *find_rela_by_dest_range(struct section *sec, unsigned long offset,
                                     unsigned int len)
 {
index aa1ff6596684f9304d0dd4bd3165f819b4dcdaf7..731973e1a3f5eb6bb1d6e67890c54c1440f237f3 100644 (file)
@@ -79,6 +79,7 @@ struct elf {
 struct elf *elf_open(const char *name);
 struct section *find_section_by_name(struct elf *elf, const char *name);
 struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset);
+struct symbol *find_symbol_containing(struct section *sec, unsigned long offset);
 struct rela *find_rela_by_dest(struct section *sec, unsigned long offset);
 struct rela *find_rela_by_dest_range(struct section *sec, unsigned long offset,
                                     unsigned int len);
index 7913363bde5c0407fded864f62a839c8b28056ea..4f3c758d875d6ce6855db7fa0731436f9bb06671 100644 (file)
@@ -31,7 +31,7 @@
 #error Instruction buffer size too small
 #endif
 
-/* Based on branch_type() from perf_event_intel_lbr.c */
+/* Based on branch_type() from arch/x86/events/intel/lbr.c */
 static void intel_pt_insn_decoder(struct insn *insn,
                                  struct intel_pt_insn *intel_pt_insn)
 {
index f11315bedefc3d68152bef22da0f8ab60f8c5be6..6a9480c03cbdfce0ae5e29e32f2cedcc342d66e1 100644 (file)
@@ -1,6 +1,7 @@
 
 CFLAGS += -I. -I../../include -g -O2 -Wall -D_LGPL_SOURCE -fsanitize=address
-LDFLAGS += -lpthread -lurcu
+LDFLAGS += -fsanitize=address
+LDLIBS+= -lpthread -lurcu
 TARGETS = main idr-test multiorder
 CORE_OFILES := radix-tree.o idr.o linux.o test.o find_bit.o
 OFILES = main.o $(CORE_OFILES) regression1.o regression2.o regression3.o \
@@ -10,23 +11,25 @@ ifndef SHIFT
        SHIFT=3
 endif
 
+ifeq ($(BUILD), 32)
+       CFLAGS += -m32
+       LDFLAGS += -m32
+endif
+
 targets: mapshift $(TARGETS)
 
 main:  $(OFILES)
-       $(CC) $(CFLAGS) $(LDFLAGS) $^ -o main
 
 idr-test: idr-test.o $(CORE_OFILES)
-       $(CC) $(CFLAGS) $(LDFLAGS) $^ -o idr-test
 
 multiorder: multiorder.o $(CORE_OFILES)
-       $(CC) $(CFLAGS) $(LDFLAGS) $^ -o multiorder
 
 clean:
        $(RM) $(TARGETS) *.o radix-tree.c idr.c generated/map-shift.h
 
 vpath %.c ../../lib
 
-$(OFILES): *.h */*.h generated/map-shift.h \
+$(OFILES): Makefile *.h */*.h generated/map-shift.h \
        ../../include/linux/*.h \
        ../../include/asm/*.h \
        ../../../include/linux/radix-tree.h \
@@ -41,7 +44,7 @@ idr.c: ../../../lib/idr.c
 .PHONY: mapshift
 
 mapshift:
-       @if ! grep -qw $(SHIFT) generated/map-shift.h; then             \
+       @if ! grep -qws $(SHIFT) generated/map-shift.h; then            \
                echo "#define RADIX_TREE_MAP_SHIFT $(SHIFT)" >          \
                                generated/map-shift.h;                  \
        fi
index 9b09ddfe462fd3b2ea782805560c349e720a4637..99c40f3ed1337f5e1bd6e6b2fd4d88dea8ec8064 100644 (file)
@@ -17,6 +17,9 @@
 #include <time.h>
 #include "test.h"
 
+#define for_each_index(i, base, order) \
+               for (i = base; i < base + (1 << order); i++)
+
 #define NSEC_PER_SEC   1000000000L
 
 static long long benchmark_iter(struct radix_tree_root *root, bool tagged)
@@ -57,27 +60,176 @@ again:
        return nsec;
 }
 
+static void benchmark_insert(struct radix_tree_root *root,
+                            unsigned long size, unsigned long step, int order)
+{
+       struct timespec start, finish;
+       unsigned long index;
+       long long nsec;
+
+       clock_gettime(CLOCK_MONOTONIC, &start);
+
+       for (index = 0 ; index < size ; index += step)
+               item_insert_order(root, index, order);
+
+       clock_gettime(CLOCK_MONOTONIC, &finish);
+
+       nsec = (finish.tv_sec - start.tv_sec) * NSEC_PER_SEC +
+              (finish.tv_nsec - start.tv_nsec);
+
+       printv(2, "Size: %8ld, step: %8ld, order: %d, insertion: %15lld ns\n",
+               size, step, order, nsec);
+}
+
+static void benchmark_tagging(struct radix_tree_root *root,
+                            unsigned long size, unsigned long step, int order)
+{
+       struct timespec start, finish;
+       unsigned long index;
+       long long nsec;
+
+       clock_gettime(CLOCK_MONOTONIC, &start);
+
+       for (index = 0 ; index < size ; index += step)
+               radix_tree_tag_set(root, index, 0);
+
+       clock_gettime(CLOCK_MONOTONIC, &finish);
+
+       nsec = (finish.tv_sec - start.tv_sec) * NSEC_PER_SEC +
+              (finish.tv_nsec - start.tv_nsec);
+
+       printv(2, "Size: %8ld, step: %8ld, order: %d, tagging: %17lld ns\n",
+               size, step, order, nsec);
+}
+
+static void benchmark_delete(struct radix_tree_root *root,
+                            unsigned long size, unsigned long step, int order)
+{
+       struct timespec start, finish;
+       unsigned long index, i;
+       long long nsec;
+
+       clock_gettime(CLOCK_MONOTONIC, &start);
+
+       for (index = 0 ; index < size ; index += step)
+               for_each_index(i, index, order)
+                       item_delete(root, i);
+
+       clock_gettime(CLOCK_MONOTONIC, &finish);
+
+       nsec = (finish.tv_sec - start.tv_sec) * NSEC_PER_SEC +
+              (finish.tv_nsec - start.tv_nsec);
+
+       printv(2, "Size: %8ld, step: %8ld, order: %d, deletion: %16lld ns\n",
+               size, step, order, nsec);
+}
+
 static void benchmark_size(unsigned long size, unsigned long step, int order)
 {
        RADIX_TREE(tree, GFP_KERNEL);
        long long normal, tagged;
-       unsigned long index;
 
-       for (index = 0 ; index < size ; index += step) {
-               item_insert_order(&tree, index, order);
-               radix_tree_tag_set(&tree, index, 0);
-       }
+       benchmark_insert(&tree, size, step, order);
+       benchmark_tagging(&tree, size, step, order);
 
        tagged = benchmark_iter(&tree, true);
        normal = benchmark_iter(&tree, false);
 
-       printv(2, "Size %ld, step %6ld, order %d tagged %10lld ns, normal %10lld ns\n",
-               size, step, order, tagged, normal);
+       printv(2, "Size: %8ld, step: %8ld, order: %d, tagged iteration: %8lld ns\n",
+               size, step, order, tagged);
+       printv(2, "Size: %8ld, step: %8ld, order: %d, normal iteration: %8lld ns\n",
+               size, step, order, normal);
+
+       benchmark_delete(&tree, size, step, order);
 
        item_kill_tree(&tree);
        rcu_barrier();
 }
 
+static long long  __benchmark_split(unsigned long index,
+                                   int old_order, int new_order)
+{
+       struct timespec start, finish;
+       long long nsec;
+       RADIX_TREE(tree, GFP_ATOMIC);
+
+       item_insert_order(&tree, index, old_order);
+
+       clock_gettime(CLOCK_MONOTONIC, &start);
+       radix_tree_split(&tree, index, new_order);
+       clock_gettime(CLOCK_MONOTONIC, &finish);
+       nsec = (finish.tv_sec - start.tv_sec) * NSEC_PER_SEC +
+              (finish.tv_nsec - start.tv_nsec);
+
+       item_kill_tree(&tree);
+
+       return nsec;
+
+}
+
+static void benchmark_split(unsigned long size, unsigned long step)
+{
+       int i, j, idx;
+       long long nsec = 0;
+
+
+       for (idx = 0; idx < size; idx += step) {
+               for (i = 3; i < 11; i++) {
+                       for (j = 0; j < i; j++) {
+                               nsec += __benchmark_split(idx, i, j);
+                       }
+               }
+       }
+
+       printv(2, "Size %8ld, step %8ld, split time %10lld ns\n",
+                       size, step, nsec);
+
+}
+
+static long long  __benchmark_join(unsigned long index,
+                            unsigned order1, unsigned order2)
+{
+       unsigned long loc;
+       struct timespec start, finish;
+       long long nsec;
+       void *item, *item2 = item_create(index + 1, order1);
+       RADIX_TREE(tree, GFP_KERNEL);
+
+       item_insert_order(&tree, index, order2);
+       item = radix_tree_lookup(&tree, index);
+
+       clock_gettime(CLOCK_MONOTONIC, &start);
+       radix_tree_join(&tree, index + 1, order1, item2);
+       clock_gettime(CLOCK_MONOTONIC, &finish);
+       nsec = (finish.tv_sec - start.tv_sec) * NSEC_PER_SEC +
+               (finish.tv_nsec - start.tv_nsec);
+
+       loc = find_item(&tree, item);
+       if (loc == -1)
+               free(item);
+
+       item_kill_tree(&tree);
+
+       return nsec;
+}
+
+static void benchmark_join(unsigned long step)
+{
+       int i, j, idx;
+       long long nsec = 0;
+
+       for (idx = 0; idx < 1 << 10; idx += step) {
+               for (i = 1; i < 15; i++) {
+                       for (j = 0; j < i; j++) {
+                               nsec += __benchmark_join(idx, i, j);
+                       }
+               }
+       }
+
+       printv(2, "Size %8d, step %8ld, join time %10lld ns\n",
+                       1 << 10, step, nsec);
+}
+
 void benchmark(void)
 {
        unsigned long size[] = {1 << 10, 1 << 20, 0};
@@ -95,4 +247,11 @@ void benchmark(void)
        for (c = 0; size[c]; c++)
                for (s = 0; step[s]; s++)
                        benchmark_size(size[c], step[s] << 9, 9);
+
+       for (c = 0; size[c]; c++)
+               for (s = 0; step[s]; s++)
+                       benchmark_split(size[c], step[s]);
+
+       for (s = 0; step[s]; s++)
+               benchmark_join(step[s]);
 }
index a26098c6123d1cf99ce2b6669a0e186bd22cedbe..30cd0b296f1a76847122f009c2cd0f2d5b9109f4 100644 (file)
@@ -153,6 +153,30 @@ void idr_nowait_test(void)
        idr_destroy(&idr);
 }
 
+void idr_get_next_test(void)
+{
+       unsigned long i;
+       int nextid;
+       DEFINE_IDR(idr);
+
+       int indices[] = {4, 7, 9, 15, 65, 128, 1000, 99999, 0};
+
+       for(i = 0; indices[i]; i++) {
+               struct item *item = item_create(indices[i], 0);
+               assert(idr_alloc(&idr, item, indices[i], indices[i+1],
+                                GFP_KERNEL) == indices[i]);
+       }
+
+       for(i = 0, nextid = 0; indices[i]; i++) {
+               idr_get_next(&idr, &nextid);
+               assert(nextid == indices[i]);
+               nextid++;
+       }
+
+       idr_for_each(&idr, item_idr_free, &idr);
+       idr_destroy(&idr);
+}
+
 void idr_checks(void)
 {
        unsigned long i;
@@ -202,6 +226,7 @@ void idr_checks(void)
        idr_alloc_test();
        idr_null_test();
        idr_nowait_test();
+       idr_get_next_test();
 }
 
 /*
@@ -338,7 +363,7 @@ void ida_check_random(void)
 {
        DEFINE_IDA(ida);
        DECLARE_BITMAP(bitmap, 2048);
-       int id;
+       int id, err;
        unsigned int i;
        time_t s = time(NULL);
 
@@ -352,8 +377,11 @@ void ida_check_random(void)
                        ida_remove(&ida, bit);
                } else {
                        __set_bit(bit, bitmap);
-                       ida_pre_get(&ida, GFP_KERNEL);
-                       assert(!ida_get_new_above(&ida, bit, &id));
+                       do {
+                               ida_pre_get(&ida, GFP_KERNEL);
+                               err = ida_get_new_above(&ida, bit, &id);
+                       } while (err == -ENOMEM);
+                       assert(!err);
                        assert(id == bit);
                }
        }
@@ -362,6 +390,24 @@ void ida_check_random(void)
                goto repeat;
 }
 
+void ida_simple_get_remove_test(void)
+{
+       DEFINE_IDA(ida);
+       unsigned long i;
+
+       for (i = 0; i < 10000; i++) {
+               assert(ida_simple_get(&ida, 0, 20000, GFP_KERNEL) == i);
+       }
+       assert(ida_simple_get(&ida, 5, 30, GFP_KERNEL) < 0);
+
+       for (i = 0; i < 10000; i++) {
+               ida_simple_remove(&ida, i);
+       }
+       assert(ida_is_empty(&ida));
+
+       ida_destroy(&ida);
+}
+
 void ida_checks(void)
 {
        DEFINE_IDA(ida);
@@ -428,15 +474,41 @@ void ida_checks(void)
        ida_check_max();
        ida_check_conv();
        ida_check_random();
+       ida_simple_get_remove_test();
 
        radix_tree_cpu_dead(1);
 }
 
+static void *ida_random_fn(void *arg)
+{
+       rcu_register_thread();
+       ida_check_random();
+       rcu_unregister_thread();
+       return NULL;
+}
+
+void ida_thread_tests(void)
+{
+       pthread_t threads[10];
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(threads); i++)
+               if (pthread_create(&threads[i], NULL, ida_random_fn, NULL)) {
+                       perror("creating ida thread");
+                       exit(1);
+               }
+
+       while (i--)
+               pthread_join(threads[i], NULL);
+}
+
 int __weak main(void)
 {
        radix_tree_init();
        idr_checks();
        ida_checks();
+       ida_thread_tests();
+       radix_tree_cpu_dead(1);
        rcu_barrier();
        if (nr_allocated)
                printf("nr_allocated = %d\n", nr_allocated);
index b829127d56705747a0a74c73e8b11b8cae8ecc27..bc9a78449572f10331a8bbc35070801f307b6caa 100644 (file)
@@ -368,6 +368,7 @@ int main(int argc, char **argv)
        iteration_test(0, 10 + 90 * long_run);
        iteration_test(7, 10 + 90 * long_run);
        single_thread_tests(long_run);
+       ida_thread_tests();
 
        /* Free any remaining preallocated nodes */
        radix_tree_cpu_dead(0);
index d4ff009892456a3b588df788488027da45209ecf..36dcf7d6945dc631ce7b2bd1c95fb0d14f662167 100644 (file)
@@ -330,6 +330,34 @@ static void single_check(void)
        item_kill_tree(&tree);
 }
 
+void radix_tree_clear_tags_test(void)
+{
+       unsigned long index;
+       struct radix_tree_node *node;
+       struct radix_tree_iter iter;
+       void **slot;
+
+       RADIX_TREE(tree, GFP_KERNEL);
+
+       item_insert(&tree, 0);
+       item_tag_set(&tree, 0, 0);
+       __radix_tree_lookup(&tree, 0, &node, &slot);
+       radix_tree_clear_tags(&tree, node, slot);
+       assert(item_tag_get(&tree, 0, 0) == 0);
+
+       for (index = 0; index < 1000; index++) {
+               item_insert(&tree, index);
+               item_tag_set(&tree, index, 0);
+       }
+
+       radix_tree_for_each_slot(slot, &tree, &iter, 0) {
+               radix_tree_clear_tags(&tree, iter.node, slot);
+               assert(item_tag_get(&tree, iter.index, 0) == 0);
+       }
+
+       item_kill_tree(&tree);
+}
+
 void tag_check(void)
 {
        single_check();
@@ -347,4 +375,5 @@ void tag_check(void)
        thrash_tags();
        rcu_barrier();
        printv(2, "after thrash_tags: %d allocated\n", nr_allocated);
+       radix_tree_clear_tags_test();
 }
index b30e11d9d271c39ccb284019938876ae2785f7ca..0f8220cc61663ffa2a872db42c96b4e5433ed0a7 100644 (file)
@@ -36,6 +36,7 @@ void iteration_test(unsigned order, unsigned duration);
 void benchmark(void);
 void idr_checks(void);
 void ida_checks(void);
+void ida_thread_tests(void);
 
 struct item *
 item_tag_set(struct radix_tree_root *root, unsigned long index, int tag);
index 248a820048dfe89018697926f4f308acd786e694..66d31de60b9ae93ee53175b33983e3d86d67795f 100644 (file)
@@ -114,9 +114,11 @@ int test_harness(int (test_function)(void), char *name)
 
        rc = run_test(test_function, name);
 
-       if (rc == MAGIC_SKIP_RETURN_VALUE)
+       if (rc == MAGIC_SKIP_RETURN_VALUE) {
                test_skip(name);
-       else
+               /* so that skipped test is not marked as failed */
+               rc = 0;
+       } else
                test_finish(name, rc);
 
        return rc;
index 5b2b4b3c634ca17462730a7d3740fd698540a975..b4967d8752365545149274cf9e70b7717a826866 100644 (file)
@@ -245,7 +245,7 @@ void do_unexpected_base(void)
                long ret;
                asm volatile ("int $0x80"
                              : "=a" (ret) : "a" (243), "b" (low_desc)
-                             : "flags");
+                             : "r8", "r9", "r10", "r11");
                memcpy(&desc, low_desc, sizeof(desc));
                munmap(low_desc, sizeof(desc));
 
index 4af47079cf04305cec7e6a8d2aa0960a6fcfe352..f6121612e769f5600d1cc0920037ee4c6ee0bf92 100644 (file)
 #define AR_DB                  (1 << 22)
 #define AR_G                   (1 << 23)
 
+#ifdef __x86_64__
+# define INT80_CLOBBERS "r8", "r9", "r10", "r11"
+#else
+# define INT80_CLOBBERS
+#endif
+
 static int nerrs;
 
 /* Points to an array of 1024 ints, each holding its own index. */
@@ -588,7 +594,7 @@ static int invoke_set_thread_area(void)
        asm volatile ("int $0x80"
                      : "=a" (ret), "+m" (low_user_desc) :
                        "a" (243), "b" (low_user_desc)
-                     : "flags");
+                     : INT80_CLOBBERS);
        return ret;
 }
 
@@ -657,7 +663,7 @@ static void test_gdt_invalidation(void)
                        "+a" (eax)
                      : "m" (low_user_desc_clear),
                        [arg1] "r" ((unsigned int)(unsigned long)low_user_desc_clear)
-                     : "flags");
+                     : INT80_CLOBBERS);
 
        if (sel != 0) {
                result = "FAIL";
@@ -688,7 +694,7 @@ static void test_gdt_invalidation(void)
                        "+a" (eax)
                      : "m" (low_user_desc_clear),
                        [arg1] "r" ((unsigned int)(unsigned long)low_user_desc_clear)
-                     : "flags");
+                     : INT80_CLOBBERS);
 
        if (sel != 0) {
                result = "FAIL";
@@ -721,7 +727,7 @@ static void test_gdt_invalidation(void)
                        "+a" (eax)
                      : "m" (low_user_desc_clear),
                        [arg1] "r" ((unsigned int)(unsigned long)low_user_desc_clear)
-                     : "flags");
+                     : INT80_CLOBBERS);
 
 #ifdef __x86_64__
        syscall(SYS_arch_prctl, ARCH_GET_FS, &new_base);
@@ -774,7 +780,7 @@ static void test_gdt_invalidation(void)
                        "+a" (eax)
                      : "m" (low_user_desc_clear),
                        [arg1] "r" ((unsigned int)(unsigned long)low_user_desc_clear)
-                     : "flags");
+                     : INT80_CLOBBERS);
 
 #ifdef __x86_64__
        syscall(SYS_arch_prctl, ARCH_GET_GS, &new_base);
index b037ce9cf116b1da0ef57601f8f1840e45fcc775..eaea9243970840dab196cb1ddf84586e30803f0a 100644 (file)
@@ -58,7 +58,8 @@ static void do_full_int80(struct syscall_args32 *args)
        asm volatile ("int $0x80"
                      : "+a" (args->nr),
                        "+b" (args->arg0), "+c" (args->arg1), "+d" (args->arg2),
-                       "+S" (args->arg3), "+D" (args->arg4), "+r" (bp));
+                       "+S" (args->arg3), "+D" (args->arg4), "+r" (bp)
+                       : : "r8", "r9", "r10", "r11");
        args->arg5 = bp;
 #else
        sys32_helper(args, int80_and_ret);
index 50c26358e8b7ec055000ead54c2c80c69b371a6f..a48da95c18fdf1f0ea46e7cb628ff9a9caba931b 100644 (file)
@@ -56,9 +56,11 @@ static volatile sig_atomic_t sig_traps;
 #ifdef __x86_64__
 # define REG_IP REG_RIP
 # define WIDTH "q"
+# define INT80_CLOBBERS "r8", "r9", "r10", "r11"
 #else
 # define REG_IP REG_EIP
 # define WIDTH "l"
+# define INT80_CLOBBERS
 #endif
 
 static unsigned long get_eflags(void)
@@ -140,7 +142,8 @@ int main()
 
        printf("[RUN]\tSet TF and check int80\n");
        set_eflags(get_eflags() | X86_EFLAGS_TF);
-       asm volatile ("int $0x80" : "=a" (tmp) : "a" (SYS_getpid));
+       asm volatile ("int $0x80" : "=a" (tmp) : "a" (SYS_getpid)
+                       : INT80_CLOBBERS);
        check_result();
 
        /*