Commit 7246f600 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'powerpc-4.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux

Pull powerpc updates from Michael Ellerman:
 "Highlights include:

   - Larger virtual address space on 64-bit server CPUs. By default we
     use a 128TB virtual address space, but a process can request access
     to the full 512TB by passing a hint to mmap().

   - Support for the new Power9 "XIVE" interrupt controller.

   - TLB flushing optimisations for the radix MMU on Power9.

   - Support for CAPI cards on Power9, using the "Coherent Accelerator
     Interface Architecture 2.0".

   - The ability to configure the mmap randomisation limits at build and
     runtime.

   - Several small fixes and cleanups to the kprobes code, as well as
     support for KPROBES_ON_FTRACE.

   - Major improvements to handling of system reset interrupts,
     correctly treating them as NMIs, giving them a dedicated stack and
     using a new hypervisor call to trigger them, all of which should
     aid debugging and robustness.

   - Many fixes and other minor enhancements.

  Thanks to: Alastair D'Silva, Alexey Kardashevskiy, Alistair Popple,
  Andrew Donnellan, Aneesh Kumar K.V, Anshuman Khandual, Anton
  Blanchard, Balbir Singh, Ben Hutchings, Benjamin Herrenschmidt,
  Bhupesh Sharma, Chris Packham, Christian Zigotzky, Christophe Leroy,
  Christophe Lombard, Daniel Axtens, David Gibson, Gautham R. Shenoy,
  Gavin Shan, Geert Uytterhoeven, Guilherme G. Piccoli, Hamish Martin,
  Hari Bathini, Kees Cook, Laurent Dufour, Madhavan Srinivasan, Mahesh J
  Salgaonkar, Mahesh Salgaonkar, Masami Hiramatsu, Matt Brown, Matthew
  R. Ochs, Michael Neuling, Naveen N. Rao, Nicholas Piggin, Oliver
  O'Halloran, Pan Xinhui, Paul Mackerras, Rashmica Gupta, Russell
  Currey, Sukadev Bhattiprolu, Thadeu Lima de Souza Cascardo, Tobin C.
  Harding, Tyrel Datwyler, Uma Krishnan, Vaibhav Jain, Vipin K Parashar,
  Yang Shi"

* tag 'powerpc-4.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (214 commits)
  powerpc/64s: Power9 has no LPCR[VRMASD] field so don't set it
  powerpc/powernv: Fix TCE kill on NVLink2
  powerpc/mm/radix: Drop support for CPUs without lockless tlbie
  powerpc/book3s/mce: Move add_taint() later in virtual mode
  powerpc/sysfs: Move #ifdef CONFIG_HOTPLUG_CPU out of the function body
  powerpc/smp: Document irq enable/disable after migrating IRQs
  powerpc/mpc52xx: Don't select user-visible RTAS_PROC
  powerpc/powernv: Document cxl dependency on special case in pnv_eeh_reset()
  powerpc/eeh: Clean up and document event handling functions
  powerpc/eeh: Avoid use after free in eeh_handle_special_event()
  cxl: Mask slice error interrupts after first occurrence
  cxl: Route eeh events to all drivers in cxl_pci_error_detected()
  cxl: Force context lock during EEH flow
  powerpc/64: Allow CONFIG_RELOCATABLE if COMPILE_TEST
  powerpc/xmon: Teach xmon oops about radix vectors
  powerpc/mm/hash: Fix off-by-one in comment about kernel contexts ids
  powerpc/pseries: Enable VFIO
  powerpc/powernv: Fix iommu table size calculation hook for small tables
  powerpc/powernv: Check kzalloc() return value in pnv_pci_table_alloc
  powerpc: Add arch/powerpc/tools directory
  ...
parents e579dde6 700b7ead
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
| nios2: | TODO | | nios2: | TODO |
| openrisc: | TODO | | openrisc: | TODO |
| parisc: | TODO | | parisc: | TODO |
| powerpc: | TODO | | powerpc: | ok |
| s390: | TODO | | s390: | TODO |
| score: | TODO | | score: | TODO |
| sh: | TODO | | sh: | TODO |
......
...@@ -21,7 +21,7 @@ Introduction ...@@ -21,7 +21,7 @@ Introduction
Hardware overview Hardware overview
================= =================
POWER8 FPGA POWER8/9 FPGA
+----------+ +---------+ +----------+ +---------+
| | | | | | | |
| CPU | | AFU | | CPU | | AFU |
...@@ -34,7 +34,7 @@ Hardware overview ...@@ -34,7 +34,7 @@ Hardware overview
| | CAPP |<------>| | | | CAPP |<------>| |
+---+------+ PCIE +---------+ +---+------+ PCIE +---------+
The POWER8 chip has a Coherently Attached Processor Proxy (CAPP) The POWER8/9 chip has a Coherently Attached Processor Proxy (CAPP)
unit which is part of the PCIe Host Bridge (PHB). This is managed unit which is part of the PCIe Host Bridge (PHB). This is managed
by Linux by calls into OPAL. Linux doesn't directly program the by Linux by calls into OPAL. Linux doesn't directly program the
CAPP. CAPP.
...@@ -59,6 +59,17 @@ Hardware overview ...@@ -59,6 +59,17 @@ Hardware overview
the fault. The context to which this fault is serviced is based on the fault. The context to which this fault is serviced is based on
who owns that acceleration function. who owns that acceleration function.
POWER8 <-----> PSL Version 8 is compliant to the CAIA Version 1.0.
POWER9 <-----> PSL Version 9 is compliant to the CAIA Version 2.0.
This PSL Version 9 provides new features such as:
* Interaction with the nest MMU on the P9 chip.
* Native DMA support.
* Supports sending ASB_Notify messages for host thread wakeup.
* Supports Atomic operations.
* ....
Cards with a PSL9 won't work on a POWER8 system and cards with a
PSL8 won't work on a POWER9 system.
AFU Modes AFU Modes
========= =========
......
...@@ -105,21 +105,21 @@ memory is held. ...@@ -105,21 +105,21 @@ memory is held.
If there is no waiting dump data, then only the memory required If there is no waiting dump data, then only the memory required
to hold CPU state, HPTE region, boot memory dump and elfcore to hold CPU state, HPTE region, boot memory dump and elfcore
header, is reserved at the top of memory (see Fig. 1). This area header, is usually reserved at an offset greater than boot memory
is *not* released: this region will be kept permanently reserved, size (see Fig. 1). This area is *not* released: this region will
so that it can act as a receptacle for a copy of the boot memory be kept permanently reserved, so that it can act as a receptacle
content in addition to CPU state and HPTE region, in the case a for a copy of the boot memory content in addition to CPU state
crash does occur. and HPTE region, in the case a crash does occur.
o Memory Reservation during first kernel o Memory Reservation during first kernel
Low memory Top of memory Low memory Top of memory
0 boot memory size | 0 boot memory size |
| | |<--Reserved dump area -->| | | |<--Reserved dump area -->| |
V V | Permanent Reservation V V V | Permanent Reservation | V
+-----------+----------/ /----------+---+----+-----------+----+ +-----------+----------/ /---+---+----+-----------+----+------+
| | |CPU|HPTE| DUMP |ELF | | | |CPU|HPTE| DUMP |ELF | |
+-----------+----------/ /----------+---+----+-----------+----+ +-----------+----------/ /---+---+----+-----------+----+------+
| ^ | ^
| | | |
\ / \ /
...@@ -135,12 +135,12 @@ crash does occur. ...@@ -135,12 +135,12 @@ crash does occur.
0 boot memory size | 0 boot memory size |
| |<------------- Reserved dump area ----------- -->| | |<------------- Reserved dump area ----------- -->|
V V V V V V
+-----------+----------/ /----------+---+----+-----------+----+ +-----------+----------/ /---+---+----+-----------+----+------+
| | |CPU|HPTE| DUMP |ELF | | | |CPU|HPTE| DUMP |ELF | |
+-----------+----------/ /----------+---+----+-----------+----+ +-----------+----------/ /---+---+----+-----------+----+------+
| | | |
V V V V
Used by second /proc/vmcore Used by second /proc/vmcore
kernel to boot kernel to boot
Fig. 2 Fig. 2
......
...@@ -5310,6 +5310,7 @@ M: Scott Wood <oss@buserror.net> ...@@ -5310,6 +5310,7 @@ M: Scott Wood <oss@buserror.net>
L: linuxppc-dev@lists.ozlabs.org L: linuxppc-dev@lists.ozlabs.org
L: linux-arm-kernel@lists.infradead.org L: linux-arm-kernel@lists.infradead.org
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/powerpc/fsl/
F: drivers/soc/fsl/ F: drivers/soc/fsl/
F: include/linux/fsl/ F: include/linux/fsl/
...@@ -7568,7 +7569,7 @@ Q: http://patchwork.ozlabs.org/project/linuxppc-dev/list/ ...@@ -7568,7 +7569,7 @@ Q: http://patchwork.ozlabs.org/project/linuxppc-dev/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git
S: Supported S: Supported
F: Documentation/ABI/stable/sysfs-firmware-opal-* F: Documentation/ABI/stable/sysfs-firmware-opal-*
F: Documentation/devicetree/bindings/powerpc/opal/ F: Documentation/devicetree/bindings/powerpc/
F: Documentation/devicetree/bindings/rtc/rtc-opal.txt F: Documentation/devicetree/bindings/rtc/rtc-opal.txt
F: Documentation/devicetree/bindings/i2c/i2c-opal.txt F: Documentation/devicetree/bindings/i2c/i2c-opal.txt
F: Documentation/powerpc/ F: Documentation/powerpc/
......
...@@ -22,6 +22,48 @@ config MMU ...@@ -22,6 +22,48 @@ config MMU
bool bool
default y default y
config ARCH_MMAP_RND_BITS_MAX
# On Book3S 64, the default virtual address space for 64-bit processes
# is 2^47 (128TB). As a maximum, allow randomisation to consume up to
# 32T of address space (2^45), which should ensure a reasonable gap
# between bottom-up and top-down allocations for applications that
# consume "normal" amounts of address space. Book3S 64 only supports 64K
# and 4K page sizes.
default 29 if PPC_BOOK3S_64 && PPC_64K_PAGES # 29 = 45 (32T) - 16 (64K)
default 33 if PPC_BOOK3S_64 # 33 = 45 (32T) - 12 (4K)
#
# On all other 64-bit platforms (currently only Book3E), the virtual
# address space is 2^46 (64TB). Allow randomisation to consume up to 16T
# of address space (2^44). Only 4K page sizes are supported.
default 32 if 64BIT # 32 = 44 (16T) - 12 (4K)
#
# For 32-bit, use the compat values, as they're the same.
default ARCH_MMAP_RND_COMPAT_BITS_MAX
config ARCH_MMAP_RND_BITS_MIN
# Allow randomisation to consume up to 1GB of address space (2^30).
default 14 if 64BIT && PPC_64K_PAGES # 14 = 30 (1GB) - 16 (64K)
default 18 if 64BIT # 18 = 30 (1GB) - 12 (4K)
#
# For 32-bit, use the compat values, as they're the same.
default ARCH_MMAP_RND_COMPAT_BITS_MIN
config ARCH_MMAP_RND_COMPAT_BITS_MAX
# Total virtual address space for 32-bit processes is 2^31 (2GB).
# Allow randomisation to consume up to 512MB of address space (2^29).
default 11 if PPC_256K_PAGES # 11 = 29 (512MB) - 18 (256K)
default 13 if PPC_64K_PAGES # 13 = 29 (512MB) - 16 (64K)
default 15 if PPC_16K_PAGES # 15 = 29 (512MB) - 14 (16K)
default 17 # 17 = 29 (512MB) - 12 (4K)
config ARCH_MMAP_RND_COMPAT_BITS_MIN
# Total virtual address space for 32-bit processes is 2^31 (2GB).
# Allow randomisation to consume up to 8MB of address space (2^23).
default 5 if PPC_256K_PAGES # 5 = 23 (8MB) - 18 (256K)
default 7 if PPC_64K_PAGES # 7 = 23 (8MB) - 16 (64K)
default 9 if PPC_16K_PAGES # 9 = 23 (8MB) - 14 (16K)
default 11 # 11 = 23 (8MB) - 12 (4K)
config HAVE_SETUP_PER_CPU_AREA config HAVE_SETUP_PER_CPU_AREA
def_bool PPC64 def_bool PPC64
...@@ -38,6 +80,11 @@ config NR_IRQS ...@@ -38,6 +80,11 @@ config NR_IRQS
/proc/interrupts. If you configure your system to have too few, /proc/interrupts. If you configure your system to have too few,
drivers will fail to load or worse - handle with care. drivers will fail to load or worse - handle with care.
config NMI_IPI
bool
depends on SMP && (DEBUGGER || KEXEC_CORE)
default y
config STACKTRACE_SUPPORT config STACKTRACE_SUPPORT
bool bool
default y default y
...@@ -119,6 +166,8 @@ config PPC ...@@ -119,6 +166,8 @@ config PPC
select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_JUMP_LABEL select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_KGDB select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRACEHOOK
select HAVE_CBPF_JIT if !PPC64 select HAVE_CBPF_JIT if !PPC64
...@@ -141,6 +190,7 @@ config PPC ...@@ -141,6 +190,7 @@ config PPC
select HAVE_IRQ_EXIT_ON_IRQ_STACK select HAVE_IRQ_EXIT_ON_IRQ_STACK
select HAVE_KERNEL_GZIP select HAVE_KERNEL_GZIP
select HAVE_KPROBES select HAVE_KPROBES
select HAVE_KPROBES_ON_FTRACE
select HAVE_KRETPROBES select HAVE_KRETPROBES
select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS
select HAVE_MEMBLOCK select HAVE_MEMBLOCK
...@@ -489,7 +539,7 @@ config KEXEC_FILE ...@@ -489,7 +539,7 @@ config KEXEC_FILE
config RELOCATABLE config RELOCATABLE
bool "Build a relocatable kernel" bool "Build a relocatable kernel"
depends on (PPC64 && !COMPILE_TEST) || (FLATMEM && (44x || FSL_BOOKE)) depends on PPC64 || (FLATMEM && (44x || FSL_BOOKE))
select NONSTATIC_KERNEL select NONSTATIC_KERNEL
select MODULE_REL_CRCS if MODVERSIONS select MODULE_REL_CRCS if MODVERSIONS
help help
...@@ -523,7 +573,7 @@ config RELOCATABLE_TEST ...@@ -523,7 +573,7 @@ config RELOCATABLE_TEST
config CRASH_DUMP config CRASH_DUMP
bool "Build a kdump crash kernel" bool "Build a kdump crash kernel"
depends on PPC64 || 6xx || FSL_BOOKE || (44x && !SMP) depends on PPC64 || 6xx || FSL_BOOKE || (44x && !SMP)
select RELOCATABLE if (PPC64 && !COMPILE_TEST) || 44x || FSL_BOOKE select RELOCATABLE if PPC64 || 44x || FSL_BOOKE
help help
Build a kernel suitable for use as a kdump capture kernel. Build a kernel suitable for use as a kdump capture kernel.
The same kernel binary can be used as production kernel and dump The same kernel binary can be used as production kernel and dump
...@@ -585,7 +635,7 @@ config ARCH_SPARSEMEM_ENABLE ...@@ -585,7 +635,7 @@ config ARCH_SPARSEMEM_ENABLE
config ARCH_SPARSEMEM_DEFAULT config ARCH_SPARSEMEM_DEFAULT
def_bool y def_bool y
depends on (SMP && PPC_PSERIES) || PPC_PS3 depends on PPC_BOOK3S_64
config SYS_SUPPORTS_HUGETLBFS config SYS_SUPPORTS_HUGETLBFS
bool bool
...@@ -677,6 +727,16 @@ config PPC_256K_PAGES ...@@ -677,6 +727,16 @@ config PPC_256K_PAGES
endchoice endchoice
config THREAD_SHIFT
int "Thread shift" if EXPERT
range 13 15
default "15" if PPC_256K_PAGES
default "14" if PPC64
default "13"
help
Used to define the stack size. The default is almost always what you
want. Only change this if you know what you are doing.
config FORCE_MAX_ZONEORDER config FORCE_MAX_ZONEORDER
int "Maximum zone order" int "Maximum zone order"
range 8 9 if PPC64 && PPC_64K_PAGES range 8 9 if PPC64 && PPC_64K_PAGES
......
...@@ -136,7 +136,7 @@ CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64 ...@@ -136,7 +136,7 @@ CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64
endif endif
ifdef CONFIG_MPROFILE_KERNEL ifdef CONFIG_MPROFILE_KERNEL
ifeq ($(shell $(srctree)/arch/powerpc/scripts/gcc-check-mprofile-kernel.sh $(CC) -I$(srctree)/include -D__KERNEL__),OK) ifeq ($(shell $(srctree)/arch/powerpc/tools/gcc-check-mprofile-kernel.sh $(CC) -I$(srctree)/include -D__KERNEL__),OK)
CC_FLAGS_FTRACE := -pg -mprofile-kernel CC_FLAGS_FTRACE := -pg -mprofile-kernel
KBUILD_CPPFLAGS += -DCC_USING_MPROFILE_KERNEL KBUILD_CPPFLAGS += -DCC_USING_MPROFILE_KERNEL
else else
...@@ -274,17 +274,6 @@ PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2) ...@@ -274,17 +274,6 @@ PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2)
boot := arch/$(ARCH)/boot boot := arch/$(ARCH)/boot
ifeq ($(CONFIG_RELOCATABLE),y)
quiet_cmd_relocs_check = CALL $<
cmd_relocs_check = $(CONFIG_SHELL) $< "$(OBJDUMP)" "$(obj)/vmlinux"
PHONY += relocs_check
relocs_check: arch/powerpc/relocs_check.sh vmlinux
$(call cmd,relocs_check)
zImage: relocs_check
endif
$(BOOT_TARGETS1): vmlinux $(BOOT_TARGETS1): vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(patsubst %,$(boot)/%,$@) $(Q)$(MAKE) $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
$(BOOT_TARGETS2): vmlinux $(BOOT_TARGETS2): vmlinux
......
# ===========================================================================
# Post-link powerpc pass
# ===========================================================================
#
# 1. Check that vmlinux relocations look sane
PHONY := __archpost
__archpost:
include include/config/auto.conf
include scripts/Kbuild.include
quiet_cmd_relocs_check = CHKREL $@
cmd_relocs_check = $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$@"
# `@true` prevents complaint when there is nothing to be done
vmlinux: FORCE
@true
ifdef CONFIG_RELOCATABLE
$(call if_changed,relocs_check)
endif
%.ko: FORCE
@true
clean:
@true
PHONY += FORCE clean
FORCE:
.PHONY: $(PHONY)
...@@ -33,7 +33,7 @@ CONFIG_BLK_DEV_INITRD=y ...@@ -33,7 +33,7 @@ CONFIG_BLK_DEV_INITRD=y
CONFIG_BPF_SYSCALL=y CONFIG_BPF_SYSCALL=y
# CONFIG_COMPAT_BRK is not set # CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y CONFIG_PROFILING=y
CONFIG_OPROFILE=y CONFIG_OPROFILE=m
CONFIG_KPROBES=y CONFIG_KPROBES=y
CONFIG_JUMP_LABEL=y CONFIG_JUMP_LABEL=y
CONFIG_MODULES=y CONFIG_MODULES=y
...@@ -261,7 +261,7 @@ CONFIG_NILFS2_FS=m ...@@ -261,7 +261,7 @@ CONFIG_NILFS2_FS=m
CONFIG_AUTOFS4_FS=m CONFIG_AUTOFS4_FS=m
CONFIG_FUSE_FS=m CONFIG_FUSE_FS=m
CONFIG_OVERLAY_FS=m CONFIG_OVERLAY_FS=m
CONFIG_ISO9660_FS=m CONFIG_ISO9660_FS=y
CONFIG_UDF_FS=m CONFIG_UDF_FS=m
CONFIG_MSDOS_FS=y CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=m CONFIG_VFAT_FS=m
...@@ -306,7 +306,7 @@ CONFIG_CRYPTO_TEST=m ...@@ -306,7 +306,7 @@ CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_CCM=m CONFIG_CRYPTO_CCM=m
CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPT_CRC32C_VPMSUM=m CONFIG_CRYPTO_CRC32C_VPMSUM=m
CONFIG_CRYPTO_MD5_PPC=m CONFIG_CRYPTO_MD5_PPC=m
CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA256=y
......
...@@ -19,7 +19,7 @@ CONFIG_BLK_DEV_INITRD=y ...@@ -19,7 +19,7 @@ CONFIG_BLK_DEV_INITRD=y
CONFIG_BPF_SYSCALL=y CONFIG_BPF_SYSCALL=y
# CONFIG_COMPAT_BRK is not set # CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y CONFIG_PROFILING=y
CONFIG_OPROFILE=y CONFIG_OPROFILE=m
CONFIG_KPROBES=y CONFIG_KPROBES=y
CONFIG_JUMP_LABEL=y CONFIG_JUMP_LABEL=y
CONFIG_MODULES=y CONFIG_MODULES=y
...@@ -290,7 +290,7 @@ CONFIG_NILFS2_FS=m ...@@ -290,7 +290,7 @@ CONFIG_NILFS2_FS=m
CONFIG_AUTOFS4_FS=m CONFIG_AUTOFS4_FS=m
CONFIG_FUSE_FS=m CONFIG_FUSE_FS=m
CONFIG_OVERLAY_FS=m CONFIG_OVERLAY_FS=m
CONFIG_ISO9660_FS=m CONFIG_ISO9660_FS=y
CONFIG_UDF_FS=m CONFIG_UDF_FS=m
CONFIG_MSDOS_FS=y CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=m CONFIG_VFAT_FS=m
...@@ -339,7 +339,7 @@ CONFIG_PPC_EARLY_DEBUG=y ...@@ -339,7 +339,7 @@ CONFIG_PPC_EARLY_DEBUG=y
CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPT_CRC32C_VPMSUM=m CONFIG_CRYPTO_CRC32C_VPMSUM=m
CONFIG_CRYPTO_MD5_PPC=m CONFIG_CRYPTO_MD5_PPC=m
CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA256=y
......
...@@ -34,7 +34,7 @@ CONFIG_BLK_DEV_INITRD=y ...@@ -34,7 +34,7 @@ CONFIG_BLK_DEV_INITRD=y
CONFIG_BPF_SYSCALL=y CONFIG_BPF_SYSCALL=y
# CONFIG_COMPAT_BRK is not set # CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y CONFIG_PROFILING=y
CONFIG_OPROFILE=y CONFIG_OPROFILE=m
CONFIG_KPROBES=y CONFIG_KPROBES=y
CONFIG_JUMP_LABEL=y CONFIG_JUMP_LABEL=y
CONFIG_MODULES=y CONFIG_MODULES=y
...@@ -259,7 +259,7 @@ CONFIG_NILFS2_FS=m ...@@ -259,7 +259,7 @@ CONFIG_NILFS2_FS=m
CONFIG_AUTOFS4_FS=m CONFIG_AUTOFS4_FS=m
CONFIG_FUSE_FS=m CONFIG_FUSE_FS=m
CONFIG_OVERLAY_FS=m CONFIG_OVERLAY_FS=m
CONFIG_ISO9660_FS=m CONFIG_ISO9660_FS=y
CONFIG_UDF_FS=m CONFIG_UDF_FS=m
CONFIG_MSDOS_FS=y CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=m CONFIG_VFAT_FS=m
...@@ -303,7 +303,7 @@ CONFIG_XMON=y ...@@ -303,7 +303,7 @@ CONFIG_XMON=y
CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPT_CRC32C_VPMSUM=m CONFIG_CRYPTO_CRC32C_VPMSUM=m
CONFIG_CRYPTO_MD5_PPC=m CONFIG_CRYPTO_MD5_PPC=m
CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA256=y
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include <asm/checksum.h> #include <asm/checksum.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/epapr_hcalls.h> #include <asm/epapr_hcalls.h>
#include <asm/dcr.h>
#include <asm/mmu_context.h>
#include <uapi/asm/ucontext.h> #include <uapi/asm/ucontext.h>
...@@ -120,6 +122,8 @@ extern s64 __ashrdi3(s64, int); ...@@ -120,6 +122,8 @@ extern s64 __ashrdi3(s64, int);
extern int __cmpdi2(s64, s64); extern int __cmpdi2(s64, s64);
extern int __ucmpdi2(u64, u64); extern int __ucmpdi2(u64, u64);
/* tracing */
void _mcount(void); void _mcount(void);
unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip);
#endif /* _ASM_POWERPC_ASM_PROTOTYPES_H */ #endif /* _ASM_POWERPC_ASM_PROTOTYPES_H */
...@@ -55,6 +55,14 @@ ...@@ -55,6 +55,14 @@
#define PPC_BITEXTRACT(bits, ppc_bit, dst_bit) \ #define PPC_BITEXTRACT(bits, ppc_bit, dst_bit) \
((((bits) >> PPC_BITLSHIFT(ppc_bit)) & 1) << (dst_bit)) ((((bits) >> PPC_BITLSHIFT(ppc_bit)) & 1) << (dst_bit))
#define PPC_BITLSHIFT32(be) (32 - 1 - (be))
#define PPC_BIT32(bit) (1UL << PPC_BITLSHIFT32(bit))
#define PPC_BITMASK32(bs, be) ((PPC_BIT32(bs) - PPC_BIT32(be))|PPC_BIT32(bs))
#define PPC_BITLSHIFT8(be) (8 - 1 - (be))
#define PPC_BIT8(bit) (1UL << PPC_BITLSHIFT8(bit))
#define PPC_BITMASK8(bs, be) ((PPC_BIT8(bs) - PPC_BIT8(be))|PPC_BIT8(bs))
#include <asm/barrier.h> #include <asm/barrier.h>
/* Macro for generating the ***_bits() functions */ /* Macro for generating the ***_bits() functions */
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#define H_PTE_INDEX_SIZE 9 #define H_PTE_INDEX_SIZE 9
#define H_PMD_INDEX_SIZE 7 #define H_PMD_INDEX_SIZE 7
#define H_PUD_INDEX_SIZE 9 #define H_PUD_INDEX_SIZE 9
#define H_PGD_INDEX_SIZE 9 #define H_PGD_INDEX_SIZE 12
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#define H_PTE_TABLE_SIZE (sizeof(pte_t) << H_PTE_INDEX_SIZE) #define H_PTE_TABLE_SIZE (sizeof(pte_t) << H_PTE_INDEX_SIZE)
......
...@@ -4,10 +4,14 @@ ...@@ -4,10 +4,14 @@
#define H_PTE_INDEX_SIZE 8 #define H_PTE_INDEX_SIZE 8
#define H_PMD_INDEX_SIZE 5 #define H_PMD_INDEX_SIZE 5
#define H_PUD_INDEX_SIZE 5 #define H_PUD_INDEX_SIZE 5
#define H_PGD_INDEX_SIZE 12 #define H_PGD_INDEX_SIZE 15
#define H_PAGE_COMBO 0x00001000 /* this is a combo 4k page */ /*
#define H_PAGE_4K_PFN 0x00002000 /* PFN is for a single 4k page */ * 64k aligned address free up few of the lower bits of RPN for us
* We steal that here. For more deatils look at pte_pfn/pfn_pte()
*/
#define H_PAGE_COMBO _RPAGE_RPN0 /* this is a combo 4k page */
#define H_PAGE_4K_PFN _RPAGE_RPN1 /* PFN is for a single 4k page */
/* /*
* We need to differentiate between explicit huge page and THP huge * We need to differentiate between explicit huge page and THP huge
* page, since THP huge page also need to track real subpage details * page, since THP huge page also need to track real subpage details
......
...@@ -6,19 +6,13 @@ ...@@ -6,19 +6,13 @@
* Common bits between 4K and 64K pages in a linux-style PTE. * Common bits between 4K and 64K pages in a linux-style PTE.
* Additional bits may be defined in pgtable-hash64-*.h * Additional bits may be defined in pgtable-hash64-*.h
* *
* Note: We only support user read/write permissions. Supervisor always
* have full read/write to pages above PAGE_OFFSET (pages below that
* always use the user access permissions).
*
* We could create separate kernel read-only if we used the 3 PP bits
* combinations that newer processors provide but we currently don't.
*/ */
#define H_PAGE_BUSY 0x00800 /* software: PTE & hash are busy */
#define H_PTE_NONE_MASK _PAGE_HPTEFLAGS #define H_PTE_NONE_MASK _PAGE_HPTEFLAGS
#define H_PAGE_F_GIX_SHIFT 57 #define H_PAGE_F_GIX_SHIFT 56
#define H_PAGE_F_GIX (7ul << 57) /* HPTE index within HPTEG */ #define H_PAGE_BUSY _RPAGE_RSV1 /* software: PTE & hash are busy */
#define H_PAGE_F_SECOND (1ul << 60) /* HPTE is in 2ndary HPTEG */ #define H_PAGE_F_SECOND _RPAGE_RSV2 /* HPTE is in 2ndary HPTEG */
#define H_PAGE_HASHPTE (1ul << 61) /* PTE has associated HPTE */ #define H_PAGE_F_GIX (_RPAGE_RSV3 | _RPAGE_RSV4 | _RPAGE_RPN44)
#define H_PAGE_HASHPTE _RPAGE_RPN43 /* PTE has associated HPTE */
#ifdef CONFIG_PPC_64K_PAGES #ifdef CONFIG_PPC_64K_PAGES
#include <asm/book3s/64/hash-64k.h> #include <asm/book3s/64/hash-64k.h>
......
...@@ -46,7 +46,7 @@ static inline pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma, ...@@ -46,7 +46,7 @@ static inline pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
*/ */
VM_WARN_ON(page_shift == mmu_psize_defs[MMU_PAGE_1G].shift); VM_WARN_ON(page_shift == mmu_psize_defs[MMU_PAGE_1G].shift);
if (page_shift == mmu_psize_defs[MMU_PAGE_2M].shift) if (page_shift == mmu_psize_defs[MMU_PAGE_2M].shift)
return __pte(pte_val(entry) | _PAGE_LARGE); return __pte(pte_val(entry) | R_PAGE_LARGE);
else else
return entry; return entry;
} }
......
...@@ -65,6 +65,8 @@ extern struct patb_entry *partition_tb; ...@@ -65,6 +65,8 @@ extern struct patb_entry *partition_tb;
* MAX_USER_CONTEXT * 16 bytes of space. * MAX_USER_CONTEXT * 16 bytes of space.
*/ */
#define PRTB_SIZE_SHIFT (CONTEXT_BITS + 4) #define PRTB_SIZE_SHIFT (CONTEXT_BITS + 4)
#define PRTB_ENTRIES (1ul << CONTEXT_BITS)
/* /*
* Power9 currently only support 64K partition table size. * Power9 currently only support 64K partition table size.
*/ */
...@@ -73,13 +75,20 @@ extern struct patb_entry *partition_tb; ...@@ -73,13 +75,20 @@ extern struct patb_entry *partition_tb;
typedef unsigned long mm_context_id_t; typedef unsigned long mm_context_id_t;
struct spinlock; struct spinlock;
/* Maximum possible number of NPUs in a system. */
#define NV_MAX_NPUS 8
typedef struct { typedef struct {
mm_context_id_t id; mm_context_id_t id;
u16 user_psize; /* page size index */ u16 user_psize; /* page size index */
/* NPU NMMU context */
struct npu_context *npu_context;
#ifdef CONFIG_PPC_MM_SLICES #ifdef CONFIG_PPC_MM_SLICES
u64 low_slices_psize; /* SLB page size encodings */ u64 low_slices_psize; /* SLB page size encodings */
unsigned char high_slices_psize[SLICE_ARRAY_SIZE]; unsigned char high_slices_psize[SLICE_ARRAY_SIZE];
unsigned long addr_limit;
#else #else
u16 sllp; /* SLB page size encoding */ u16 sllp; /* SLB page size encoding */
#endif #endif
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#define _PAGE_BIT_SWAP_TYPE 0 #define _PAGE_BIT_SWAP_TYPE 0
#define _PAGE_RO 0 #define _PAGE_RO 0
#define _PAGE_SHARED 0
#define _PAGE_EXEC 0x00001 /* execute permission */ #define _PAGE_EXEC 0x00001 /* execute permission */
#define _PAGE_WRITE 0x00002 /* write access allowed */ #define _PAGE_WRITE 0x00002 /* write access allowed */
...@@ -37,21 +38,47 @@ ...@@ -37,21 +38,47 @@
#define _RPAGE_RSV3 0x0400000000000000UL #define _RPAGE_RSV3 0x0400000000000000UL
#define _RPAGE_RSV4 0x0200000000000000UL #define _RPAGE_RSV4 0x0200000000000000UL
#ifdef CONFIG_MEM_SOFT_DIRTY #define _PAGE_PTE 0x4000000000000000UL /* distinguishes PTEs from pointers */
#define _PAGE_SOFT_DIRTY _RPAGE_SW3 /* software: software dirty tracking */ #define _PAGE_PRESENT 0x8000000000000000UL /* pte contains a translation */
#else
#define _PAGE_SOFT_DIRTY 0x00000
#endif
#define _PAGE_SPECIAL _RPAGE_SW2 /* software: special page */
/* /*
* For P9 DD1 only, we need to track whether the pte's huge. * Top and bottom bits of RPN which can be used by hash
* translation mode, because we expect them to be zero
* otherwise.
*/ */
#define _PAGE_LARGE _RPAGE_RSV1 #define _RPAGE_RPN0 0x01000
#define _RPAGE_RPN1 0x02000
#define _RPAGE_RPN44 0x0100000000000000UL
#define _RPAGE_RPN43 0x0080000000000000UL
#define _RPAGE_RPN42 0x0040000000000000UL
#define _RPAGE_RPN41 0x0020000000000000UL
/* Max physical address bit as per radix table */
#define _RPAGE_PA_MAX 57
/*
* Max physical address bit we will use for now.
*
* This is mostly a hardware limitation and for now Power9 has
* a 51 bit limit.
*
* This is different from the number of physical bit required to address
* the last byte of memory. That is defined by MAX_PHYSMEM_BITS.
* MAX_PHYSMEM_BITS is a linux limitation imposed by the maximum
* number of sections we can support (SECTIONS_SHIFT).
*
* This is different from Radix page table limitation above and
* should always be less than that. The limit is done such that
* we can overload the bits between _RPAGE_PA_MAX and _PAGE_PA_MAX
* for hash linux page table specific bits.
*
* In order to be compatible with future hardware generations we keep
* some offsets and limit this for now to 53
*/
#define _PAGE_PA_MAX 53
#define _PAGE_PTE (1ul << 62) /* distinguishes PTEs from pointers */ #define _PAGE_SOFT_DIRTY _RPAGE_SW3 /* software: software dirty tracking */
#define _PAGE_PRESENT (1ul << 63) /* pte contains a translation */ #define _PAGE_SPECIAL _RPAGE_SW2 /* software: special page */
/* /*
* Drivers request for cache inhibited pte mapping using _PAGE_NO_CACHE * Drivers request for cache inhibited pte mapping using _PAGE_NO_CACHE
* Instead of fixing all of them, add an alternate define which * Instead of fixing all of them, add an alternate define which
...@@ -59,10 +86,11 @@ ...@@ -59,10 +86,11 @@
*/ */
#define _PAGE_NO_CACHE _PAGE_TOLERANT #define _PAGE_NO_CACHE _PAGE_TOLERANT
/* /*
* We support 57 bit real address in pte. Clear everything above 57, and * We support _RPAGE_PA_MAX bit real address in pte. On the linux side
* every thing below PAGE_SHIFT; * we are limited by _PAGE_PA_MAX. Clear everything above _PAGE_PA_MAX
* and every thing below PAGE_SHIFT;
*/ */
#define PTE_RPN_MASK (((1UL << 57) - 1) & (PAGE_MASK)) #define PTE_RPN_MASK (((1UL << _PAGE_PA_MAX) - 1) & (PAGE_MASK))
/* /*
* set of bits not changed in pmd_modify. Even though we have hash specific bits * set of bits not changed in pmd_modify. Even though we have hash specific bits
* in here, on radix we expect them to be zero. * in here, on radix we expect them to be zero.
...@@ -205,10 +233,6 @@ extern unsigned long __pte_frag_nr; ...@@ -205,10 +233,6 @@ extern unsigned long __pte_frag_nr;
extern unsigned long __pte_frag_size_shift; extern unsigned long __pte_frag_size_shift;
#define PTE_FRAG_SIZE_SHIFT __pte_frag_size_shift #define PTE_FRAG_SIZE_SHIFT __pte_frag_size_shift
#define PTE_FRAG_SIZE (1UL << PTE_FRAG_SIZE_SHIFT) #define PTE_FRAG_SIZE (1UL << PTE_FRAG_SIZE_SHIFT)
/*
* Pgtable size used by swapper, init in asm code
*/
#define MAX_PGD_TABLE_SIZE (sizeof(pgd_t) << RADIX_PGD_INDEX_SIZE)
#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE) #define PTRS_PER_PTE (1 << PTE_INDEX_SIZE)
#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE) #define PTRS_PER_PMD (1 << PMD_INDEX_SIZE)
......
...@@ -11,6 +11,12 @@ ...@@ -11,6 +11,12 @@
#include <asm/book3s/64/radix-4k.h> #include <asm/book3s/64/radix-4k.h>
#endif #endif
/*
* For P9 DD1 only, we need to track whether the pte's huge.
*/
#define R_PAGE_LARGE _RPAGE_RSV1
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <asm/book3s/64/tlbflush-radix.h> #include <asm/book3s/64/tlbflush-radix.h>
#include <asm/cpu_has_feature.h> #include <asm/cpu_has_feature.h>
...@@ -252,7 +258,7 @@ static inline int radix__pmd_trans_huge(pmd_t pmd) ...@@ -252,7 +258,7 @@ static inline int radix__pmd_trans_huge(pmd_t pmd)
static inline pmd_t radix__pmd_mkhuge(pmd_t pmd) static inline pmd_t radix__pmd_mkhuge(pmd_t pmd)
{ {
if (cpu_has_feature(CPU_FTR_POWER9_DD1)) if (cpu_has_feature(CPU_FTR_POWER9_DD1))
return __pmd(pmd_val(pmd) | _PAGE_PTE | _PAGE_LARGE); return __pmd(pmd_val(pmd) | _PAGE_PTE | R_PAGE_LARGE);
return __pmd(pmd_val(pmd) | _PAGE_PTE); return __pmd(pmd_val(pmd) | _PAGE_PTE);
} }
static inline void radix__pmdp_huge_split_prepare(struct vm_area_struct *vma, static inline void radix__pmdp_huge_split_prepare(struct vm_area_struct *vma,
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#include <asm/types.h> #include <asm/types.h>
#include <asm/ppc-opcode.h> #include <asm/ppc-opcode.h>
#include <linux/string.h>
#include <linux/kallsyms.h>
/* Flags for create_branch: /* Flags for create_branch:
* "b" == create_branch(addr, target, 0); * "b" == create_branch(addr, target, 0);
...@@ -99,6 +101,45 @@ static inline unsigned long ppc_global_function_entry(void *func) ...@@ -99,6 +101,45 @@ static inline unsigned long ppc_global_function_entry(void *func)
#endif #endif
} }
/*
* Wrapper around kallsyms_lookup() to return function entry address:
* - For ABIv1, we lookup the dot variant.
* - For ABIv2, we return the local entry point.
*/
static inline unsigned long ppc_kallsyms_lookup_name(const char *name)
{
unsigned long addr;
#ifdef PPC64_ELF_ABI_v1
/* check for dot variant */
char dot_name[1 + KSYM_NAME_LEN];
bool dot_appended = false;
if (strnlen(name, KSYM_NAME_LEN) >= KSYM_NAME_LEN)
return 0;
if (name[0] != '.') {
dot_name[0] = '.';
dot_name[1] = '\0';
strlcat(dot_name, name, sizeof(dot_name));
dot_appended = true;
} else {
dot_name[0] = '\0';
strlcat(dot_name, name, sizeof(dot_name));
}
addr = kallsyms_lookup_name(dot_name);
if (!addr && dot_appended)
/* Let's try the original non-dot symbol lookup */
addr = kallsyms_lookup_name(name);
#elif defined(PPC64_ELF_ABI_v2)
addr = kallsyms_lookup_name(name);
if (addr)
addr = ppc_function_entry((void *)addr);
#else
addr = kallsyms_lookup_name(name);
#endif
return addr;
}
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
/* /*
* Some instruction encodings commonly used in dynamic ftracing * Some instruction encodings commonly used in dynamic ftracing
......
...@@ -2,13 +2,39 @@ ...@@ -2,13 +2,39 @@
#define _ASM_POWERPC_CPUIDLE_H #define _ASM_POWERPC_CPUIDLE_H
#ifdef CONFIG_PPC_POWERNV #ifdef CONFIG_PPC_POWERNV
/* Used in powernv idle state management */ /* Thread state used in powernv idle state management */
#define PNV_THREAD_RUNNING 0 #define PNV_THREAD_RUNNING 0
#define PNV_THREAD_NAP 1 #define PNV_THREAD_NAP 1
#define PNV_THREAD_SLEEP 2 #define PNV_THREAD_SLEEP 2
#define PNV_THREAD_WINKLE 3 #define PNV_THREAD_WINKLE 3
#define PNV_CORE_IDLE_LOCK_BIT 0x100
#define PNV_CORE_IDLE_THREAD_BITS 0x0FF /*
* Core state used in powernv idle for POWER8.
*
* The lock bit synchronizes updates to the state, as well as parts of the
* sleep/wake code (see kernel/idle_book3s.S).
*
* Bottom 8 bits track the idle state of each thread. Bit is cleared before
* the thread executes an idle instruction (nap/sleep/winkle).
*
* Then there is winkle tracking. A core does not lose complete state
* until every thread is in winkle. So the winkle count field counts the
* number of threads in winkle (small window of false positives is okay
* around the sleep/wake, so long as there are no false negatives).
*
* When the winkle count reaches 8 (the COUNT_ALL_BIT becomes set), then
* the THREAD_WINKLE_BITS are set, which indicate which threads have not
* yet woken from the winkle state.
*/
#define PNV_CORE_IDLE_LOCK_BIT 0x10000000
#define PNV_CORE_IDLE_WINKLE_COUNT 0x00010000
#define PNV_CORE_IDLE_WINKLE_COUNT_ALL_BIT 0x00080000
#define PNV_CORE_IDLE_WINKLE_COUNT_BITS 0x000F0000
#define PNV_CORE_IDLE_THREAD_WINKLE_BITS_SHIFT 8
#define PNV_CORE_IDLE_THREAD_WINKLE_BITS 0x0000FF00
#define PNV_CORE_IDLE_THREAD_BITS 0x000000FF
/* /*
* ============================ NOTE ================================= * ============================ NOTE =================================
...@@ -46,6 +72,7 @@ extern u32 pnv_fastsleep_workaround_at_exit[]; ...@@ -46,6 +72,7 @@ extern u32 pnv_fastsleep_workaround_at_exit[];
extern u64 pnv_first_deep_stop_state; extern u64 pnv_first_deep_stop_state;
unsigned long pnv_cpu_offline(unsigned int cpu);
int validate_psscr_val_mask(u64 *psscr_val, u64 *psscr_mask, u32 flags); int validate_psscr_val_mask(u64 *psscr_val, u64 *psscr_mask, u32 flags);
static inline void report_invalid_psscr_val(u64 psscr_val, int err) static inline void report_invalid_psscr_val(u64 psscr_val, int err)
{ {
......
...@@ -471,10 +471,11 @@ enum { ...@@ -471,10 +471,11 @@ enum {
CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
CPU_FTR_DSCR | CPU_FTR_SAO | \ CPU_FTR_DSCR | CPU_FTR_SAO | \
CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \ CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \
CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_ARCH_300) CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_ARCH_300)
#define CPU_FTRS_POWER9_DD1 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD1) #define CPU_FTRS_POWER9_DD1 ((CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD1) & \
(~CPU_FTR_SAO))
#define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ #define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
......
...@@ -35,33 +35,53 @@ enum ppc_dbell { ...@@ -35,33 +35,53 @@ enum ppc_dbell {
#ifdef CONFIG_PPC_BOOK3S #ifdef CONFIG_PPC_BOOK3S
#define PPC_DBELL_MSGTYPE PPC_DBELL_SERVER #define PPC_DBELL_MSGTYPE PPC_DBELL_SERVER
#define SPRN_DOORBELL_CPUTAG SPRN_TIR
#define PPC_DBELL_TAG_MASK 0x7f
static inline void _ppc_msgsnd(u32 msg) static inline void _ppc_msgsnd(u32 msg)
{ {
if (cpu_has_feature(CPU_FTR_HVMODE)) __asm__ __volatile__ (ASM_FTR_IFSET(PPC_MSGSND(%1), PPC_MSGSNDP(%1), %0)
__asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg)); : : "i" (CPU_FTR_HVMODE), "r" (msg));
else }
__asm__ __volatile__ (PPC_MSGSNDP(%0) : : "r" (msg));
/* sync before sending message */
static inline void ppc_msgsnd_sync(void)
{
__asm__ __volatile__ ("sync" : : : "memory");
}
/* sync after taking message interrupt */
static inline void ppc_msgsync(void)
{
/* sync is not required when taking messages from the same core */
__asm__ __volatile__ (ASM_FTR_IFSET(PPC_MSGSYNC " ; lwsync", "", %0)
: : "i" (CPU_FTR_HVMODE|CPU_FTR_ARCH_300));
} }
#else /* CONFIG_PPC_BOOK3S */ #else /* CONFIG_PPC_BOOK3S */
#define PPC_DBELL_MSGTYPE PPC_DBELL #define PPC_DBELL_MSGTYPE PPC_DBELL
#define SPRN_DOORBELL_CPUTAG SPRN_PIR
#define PPC_DBELL_TAG_MASK 0x3fff
static inline void _ppc_msgsnd(u32 msg) static inline void _ppc_msgsnd(u32 msg)
{ {
__asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg)); __asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg));
} }
/* sync before sending message */
static inline void ppc_msgsnd_sync(void)
{
__asm__ __volatile__ ("sync" : : : "memory");
}
/* sync after taking message interrupt */
static inline void ppc_msgsync(void)
{
}
#endif /* CONFIG_PPC_BOOK3S */ #endif /* CONFIG_PPC_BOOK3S */
extern void doorbell_cause_ipi(int cpu, unsigned long data); extern void doorbell_global_ipi(int cpu);
extern void doorbell_core_ipi(int cpu);
extern int doorbell_try_core_ipi(int cpu);
extern void doorbell_exception(struct pt_regs *regs); extern void doorbell_exception(struct pt_regs *regs);
extern void doorbell_setup_this_cpu(void);
static inline void ppc_msgsnd(enum ppc_dbell type, u32 flags, u32 tag) static inline void ppc_msgsnd(enum ppc_dbell type, u32 flags, u32 tag)
{ {
......
...@@ -8,8 +8,6 @@ ...@@ -8,8 +8,6 @@
struct pt_regs; struct pt_regs;
extern struct dentry *powerpc_debugfs_root;
#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC_CORE) #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC_CORE)
extern int (*__debugger)(struct pt_regs *regs); extern int (*__debugger)(struct pt_regs *regs);
......
#ifndef _ASM_POWERPC_DEBUGFS_H
#define _ASM_POWERPC_DEBUGFS_H
/*
* Copyright 2017, Michael Ellerman, IBM Corporation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/debugfs.h>
extern struct dentry *powerpc_debugfs_root;
#endif /* _ASM_POWERPC_DEBUGFS_H */
...@@ -167,17 +167,14 @@ BEGIN_FTR_SECTION_NESTED(943) \ ...@@ -167,17 +167,14 @@ BEGIN_FTR_SECTION_NESTED(943) \
std ra,offset(r13); \ std ra,offset(r13); \
END_FTR_SECTION_NESTED(ftr,ftr,943) END_FTR_SECTION_NESTED(ftr,ftr,943)
#define EXCEPTION_PROLOG_0_PACA(area) \ #define EXCEPTION_PROLOG_0(area) \
GET_PACA(r13); \
std r9,area+EX_R9(r13); /* save r9 */ \ std r9,area+EX_R9(r13); /* save r9 */ \
OPT_GET_SPR(r9, SPRN_PPR, CPU_FTR_HAS_PPR); \ OPT_GET_SPR(r9, SPRN_PPR, CPU_FTR_HAS_PPR); \
HMT_MEDIUM; \ HMT_MEDIUM; \
std r10,area+EX_R10(r13); /* save r10 - r12 */ \ std r10,area+EX_R10(r13); /* save r10 - r12 */ \
OPT_GET_SPR(r10, SPRN_CFAR, CPU_FTR_CFAR) OPT_GET_SPR(r10, SPRN_CFAR, CPU_FTR_CFAR)
#define EXCEPTION_PROLOG_0(area) \
GET_PACA(r13); \
EXCEPTION_PROLOG_0_PACA(area)
#define __EXCEPTION_PROLOG_1(area, extra, vec) \ #define __EXCEPTION_PROLOG_1(area, extra, vec) \
OPT_SAVE_REG_TO_PACA(area+EX_PPR, r9, CPU_FTR_HAS_PPR); \ OPT_SAVE_REG_TO_PACA(area+EX_PPR, r9, CPU_FTR_HAS_PPR); \
OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR); \ OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR); \
...@@ -203,17 +200,26 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) ...@@ -203,17 +200,26 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
#define EXCEPTION_PROLOG_PSERIES_1(label, h) \ #define EXCEPTION_PROLOG_PSERIES_1(label, h) \
__EXCEPTION_PROLOG_PSERIES_1(label, h) __EXCEPTION_PROLOG_PSERIES_1(label, h)
/* _NORI variant keeps MSR_RI clear */
#define __EXCEPTION_PROLOG_PSERIES_1_NORI(label, h) \
ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \
xori r10,r10,MSR_RI; /* Clear MSR_RI */ \
mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \
LOAD_HANDLER(r12,label) \
mtspr SPRN_##h##SRR0,r12; \
mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
mtspr SPRN_##h##SRR1,r10; \
h##rfid; \
b . /* prevent speculative execution */
#define EXCEPTION_PROLOG_PSERIES_1_NORI(label, h) \
__EXCEPTION_PROLOG_PSERIES_1_NORI(label, h)
#define EXCEPTION_PROLOG_PSERIES(area, label, h, extra, vec) \ #define EXCEPTION_PROLOG_PSERIES(area, label, h, extra, vec) \
EXCEPTION_PROLOG_0(area); \ EXCEPTION_PROLOG_0(area); \
EXCEPTION_PROLOG_1(area, extra, vec); \ EXCEPTION_PROLOG_1(area, extra, vec); \
EXCEPTION_PROLOG_PSERIES_1(label, h); EXCEPTION_PROLOG_PSERIES_1(label, h);
/* Have the PACA in r13 already */
#define EXCEPTION_PROLOG_PSERIES_PACA(area, label, h, extra, vec) \
EXCEPTION_PROLOG_0_PACA(area); \
EXCEPTION_PROLOG_1(area, extra, vec); \
EXCEPTION_PROLOG_PSERIES_1(label, h);
#define __KVMTEST(h, n) \ #define __KVMTEST(h, n) \
lbz r10,HSTATE_IN_GUEST(r13); \ lbz r10,HSTATE_IN_GUEST(r13); \
cmpwi r10,0; \ cmpwi r10,0; \
...@@ -256,11 +262,6 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) ...@@ -256,11 +262,6 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
ld r9,area+EX_R9(r13); \ ld r9,area+EX_R9(r13); \
bctr bctr
#define BRANCH_TO_KVM(reg, label) \
__LOAD_FAR_HANDLER(reg, label); \
mtctr reg; \
bctr
#else #else
#define BRANCH_TO_COMMON(reg, label) \ #define BRANCH_TO_COMMON(reg, label) \
b label b label
...@@ -268,15 +269,18 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) ...@@ -268,15 +269,18 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
#define BRANCH_LINK_TO_FAR(label) \ #define BRANCH_LINK_TO_FAR(label) \
bl label bl label
#define BRANCH_TO_KVM(reg, label) \
b label
#define __BRANCH_TO_KVM_EXIT(area, label) \ #define __BRANCH_TO_KVM_EXIT(area, label) \
ld r9,area+EX_R9(r13); \ ld r9,area+EX_R9(r13); \
b label b label
#endif #endif
/* Do not enable RI */
#define EXCEPTION_PROLOG_PSERIES_NORI(area, label, h, extra, vec) \
EXCEPTION_PROLOG_0(area); \
EXCEPTION_PROLOG_1(area, extra, vec); \
EXCEPTION_PROLOG_PSERIES_1_NORI(label, h);
#define __KVM_HANDLER(area, h, n) \ #define __KVM_HANDLER(area, h, n) \
BEGIN_FTR_SECTION_NESTED(947) \ BEGIN_FTR_SECTION_NESTED(947) \
...@@ -325,6 +329,15 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) ...@@ -325,6 +329,15 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
#define NOTEST(n) #define NOTEST(n)
#define EXCEPTION_PROLOG_COMMON_1() \
std r9,_CCR(r1); /* save CR in stackframe */ \
std r11,_NIP(r1); /* save SRR0 in stackframe */ \
std r12,_MSR(r1); /* save SRR1 in stackframe */ \
std r10,0(r1); /* make stack chain pointer */ \
std r0,GPR0(r1); /* save r0 in stackframe */ \
std r10,GPR1(r1); /* save r1 in stackframe */ \
/* /*
* The common exception prolog is used for all except a few exceptions * The common exception prolog is used for all except a few exceptions
* such as a segment miss on a kernel address. We have to be prepared * such as a segment miss on a kernel address. We have to be prepared
...@@ -349,12 +362,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) ...@@ -349,12 +362,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
addi r3,r13,area; /* r3 -> where regs are saved*/ \ addi r3,r13,area; /* r3 -> where regs are saved*/ \
RESTORE_CTR(r1, area); \ RESTORE_CTR(r1, area); \
b bad_stack; \ b bad_stack; \
3: std r9,_CCR(r1); /* save CR in stackframe */ \ 3: EXCEPTION_PROLOG_COMMON_1(); \
std r11,_NIP(r1); /* save SRR0 in stackframe */ \
std r12,_MSR(r1); /* save SRR1 in stackframe */ \
std r10,0(r1); /* make stack chain pointer */ \
std r0,GPR0(r1); /* save r0 in stackframe */ \
std r10,GPR1(r1); /* save r1 in stackframe */ \
beq 4f; /* if from kernel mode */ \ beq 4f; /* if from kernel mode */ \
ACCOUNT_CPU_USER_ENTRY(r13, r9, r10); \ ACCOUNT_CPU_USER_ENTRY(r13, r9, r10); \
SAVE_PPR(area, r9, r10); \ SAVE_PPR(area, r9, r10); \
...@@ -522,7 +530,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) ...@@ -522,7 +530,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
#define MASKABLE_RELON_EXCEPTION_HV_OOL(vec, label) \ #define MASKABLE_RELON_EXCEPTION_HV_OOL(vec, label) \
EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV, vec); \ EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV, vec); \
EXCEPTION_PROLOG_PSERIES_1(label, EXC_HV) EXCEPTION_RELON_PROLOG_PSERIES_1(label, EXC_HV)
/* /*
* Our exception common code can be passed various "additions" * Our exception common code can be passed various "additions"
...@@ -547,26 +555,39 @@ BEGIN_FTR_SECTION \ ...@@ -547,26 +555,39 @@ BEGIN_FTR_SECTION \
beql ppc64_runlatch_on_trampoline; \ beql ppc64_runlatch_on_trampoline; \
END_FTR_SECTION_IFSET(CPU_FTR_CTRL) END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
#define EXCEPTION_COMMON(trap, label, hdlr, ret, additions) \ #define EXCEPTION_COMMON(area, trap, label, hdlr, ret, additions) \
EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ EXCEPTION_PROLOG_COMMON(trap, area); \
/* Volatile regs are potentially clobbered here */ \ /* Volatile regs are potentially clobbered here */ \
additions; \ additions; \
addi r3,r1,STACK_FRAME_OVERHEAD; \ addi r3,r1,STACK_FRAME_OVERHEAD; \
bl hdlr; \ bl hdlr; \
b ret b ret
/*
* Exception where stack is already set in r1, r1 is saved in r10, and it
* continues rather than returns.
*/
#define EXCEPTION_COMMON_NORET_STACK(area, trap, label, hdlr, additions) \
EXCEPTION_PROLOG_COMMON_1(); \
EXCEPTION_PROLOG_COMMON_2(area); \
EXCEPTION_PROLOG_COMMON_3(trap); \
/* Volatile regs are potentially clobbered here */ \
additions; \
addi r3,r1,STACK_FRAME_OVERHEAD; \
bl hdlr
#define STD_EXCEPTION_COMMON(trap, label, hdlr) \ #define STD_EXCEPTION_COMMON(trap, label, hdlr) \
EXCEPTION_COMMON(trap, label, hdlr, ret_from_except, \ EXCEPTION_COMMON(PACA_EXGEN, trap, label, hdlr, \
ADD_NVGPRS;ADD_RECONCILE) ret_from_except, ADD_NVGPRS;ADD_RECONCILE)
/* /*
* Like STD_EXCEPTION_COMMON, but for exceptions that can occur * Like STD_EXCEPTION_COMMON, but for exceptions that can occur
* in the idle task and therefore need the special idle handling * in the idle task and therefore need the special idle handling
* (finish nap and runlatch) * (finish nap and runlatch)
*/ */
#define STD_EXCEPTION_COMMON_ASYNC(trap, label, hdlr) \ #define STD_EXCEPTION_COMMON_ASYNC(trap, label, hdlr) \
EXCEPTION_COMMON(trap, label, hdlr, ret_from_except_lite, \ EXCEPTION_COMMON(PACA_EXGEN, trap, label, hdlr, \
FINISH_NAP;ADD_RECONCILE;RUNLATCH_ON) ret_from_except_lite, FINISH_NAP;ADD_RECONCILE;RUNLATCH_ON)
/* /*
* When the idle code in power4_idle puts the CPU into NAP mode, * When the idle code in power4_idle puts the CPU into NAP mode,
......
...@@ -66,6 +66,9 @@ label##5: \ ...@@ -66,6 +66,9 @@ label##5: \
#define END_FTR_SECTION(msk, val) \ #define END_FTR_SECTION(msk, val) \
END_FTR_SECTION_NESTED(msk, val, 97) END_FTR_SECTION_NESTED(msk, val, 97)
#define END_FTR_SECTION_NESTED_IFSET(msk, label) \
END_FTR_SECTION_NESTED((msk), (msk), label)
#define END_FTR_SECTION_IFSET(msk) END_FTR_SECTION((msk), (msk)) #define END_FTR_SECTION_IFSET(msk) END_FTR_SECTION((msk), (msk))
#define END_FTR_SECTION_IFCLR(msk) END_FTR_SECTION((msk), 0) #define END_FTR_SECTION_IFCLR(msk) END_FTR_SECTION((msk), 0)
......
...@@ -213,6 +213,7 @@ end_##sname: ...@@ -213,6 +213,7 @@ end_##sname:
USE_TEXT_SECTION(); \ USE_TEXT_SECTION(); \
.balign IFETCH_ALIGN_BYTES; \ .balign IFETCH_ALIGN_BYTES; \
.global name; \ .global name; \
_ASM_NOKPROBE_SYMBOL(name); \
DEFINE_FIXED_SYMBOL(name); \ DEFINE_FIXED_SYMBOL(name); \
name: name:
......
...@@ -377,16 +377,6 @@ long plpar_hcall_raw(unsigned long opcode, unsigned long *retbuf, ...); ...@@ -377,16 +377,6 @@ long plpar_hcall_raw(unsigned long opcode, unsigned long *retbuf, ...);
long plpar_hcall9(unsigned long opcode, unsigned long *retbuf, ...); long plpar_hcall9(unsigned long opcode, unsigned long *retbuf, ...);
long plpar_hcall9_raw(unsigned long opcode, unsigned long *retbuf, ...); long plpar_hcall9_raw(unsigned long opcode, unsigned long *retbuf, ...);
/* For hcall instrumentation. One structure per-hcall, per-CPU */
struct hcall_stats {
unsigned long num_calls; /* number of calls (on this CPU) */
unsigned long tb_total; /* total wall time (mftb) of calls. */
unsigned long purr_total; /* total cpu time (PURR) of calls. */
unsigned long tb_start;
unsigned long purr_start;
};
#define HCALL_STAT_ARRAY_SIZE ((MAX_HCALL_OPCODE >> 2) + 1)
struct hvcall_mpp_data { struct hvcall_mpp_data {
unsigned long entitled_mem; unsigned long entitled_mem;
unsigned long mapped_mem; unsigned long mapped_mem;
......
...@@ -25,8 +25,6 @@ extern struct pci_dev *isa_bridge_pcidev; ...@@ -25,8 +25,6 @@ extern struct pci_dev *isa_bridge_pcidev;
#endif #endif
#include <linux/device.h> #include <linux/device.h>
#include <linux/io.h>
#include <linux/compiler.h> #include <linux/compiler.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
...@@ -192,24 +190,8 @@ DEF_MMIO_OUT_D(out_le32, 32, stw); ...@@ -192,24 +190,8 @@ DEF_MMIO_OUT_D(out_le32, 32, stw);
#endif /* __BIG_ENDIAN */ #endif /* __BIG_ENDIAN */
/*
* Cache inhibitied accessors for use in real mode, you don't want to use these
* unless you know what you're doing.
*
* NB. These use the cpu byte ordering.
*/
DEF_MMIO_OUT_X(out_rm8, 8, stbcix);
DEF_MMIO_OUT_X(out_rm16, 16, sthcix);
DEF_MMIO_OUT_X(out_rm32, 32, stwcix);
DEF_MMIO_IN_X(in_rm8, 8, lbzcix);
DEF_MMIO_IN_X(in_rm16, 16, lhzcix);
DEF_MMIO_IN_X(in_rm32, 32, lwzcix);
#ifdef __powerpc64__ #ifdef __powerpc64__
DEF_MMIO_OUT_X(out_rm64, 64, stdcix);
DEF_MMIO_IN_X(in_rm64, 64, ldcix);
#ifdef __BIG_ENDIAN__ #ifdef __BIG_ENDIAN__
DEF_MMIO_OUT_D(out_be64, 64, std); DEF_MMIO_OUT_D(out_be64, 64, std);
DEF_MMIO_IN_D(in_be64, 64, ld); DEF_MMIO_IN_D(in_be64, 64, ld);
...@@ -242,35 +224,6 @@ static inline void out_be64(volatile u64 __iomem *addr, u64 val) ...@@ -242,35 +224,6 @@ static inline void out_be64(volatile u64 __iomem *addr, u64 val)
#endif #endif
#endif /* __powerpc64__ */ #endif /* __powerpc64__ */
/*
* Simple Cache inhibited accessors
* Unlike the DEF_MMIO_* macros, these don't include any h/w memory
* barriers, callers need to manage memory barriers on their own.
* These can only be used in hypervisor real mode.
*/
static inline u32 _lwzcix(unsigned long addr)
{
u32 ret;
__asm__ __volatile__("lwzcix %0,0, %1"
: "=r" (ret) : "r" (addr) : "memory");
return ret;
}
static inline void _stbcix(u64 addr, u8 val)
{
__asm__ __volatile__("stbcix %0,0,%1"
: : "r" (val), "r" (addr) : "memory");
}
static inline void _stwcix(u64 addr, u32 val)
{
__asm__ __volatile__("stwcix %0,0,%1"
: : "r" (val), "r" (addr) : "memory");
}
/* /*
* Low level IO stream instructions are defined out of line for now * Low level IO stream instructions are defined out of line for now
*/ */
...@@ -417,15 +370,64 @@ static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr) ...@@ -417,15 +370,64 @@ static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr)
} }
/* /*
* Real mode version of the above. stdcix is only supposed to be used * Real mode versions of the above. Those instructions are only supposed
* in hypervisor real mode as per the architecture spec. * to be used in hypervisor real mode as per the architecture spec.
*/ */
static inline void __raw_rm_writeb(u8 val, volatile void __iomem *paddr)
{
__asm__ __volatile__("stbcix %0,0,%1"
: : "r" (val), "r" (paddr) : "memory");
}
static inline void __raw_rm_writew(u16 val, volatile void __iomem *paddr)
{
__asm__ __volatile__("sthcix %0,0,%1"
: : "r" (val), "r" (paddr) : "memory");
}
static inline void __raw_rm_writel(u32 val, volatile void __iomem *paddr)
{
__asm__ __volatile__("stwcix %0,0,%1"
: : "r" (val), "r" (paddr) : "memory");
}
static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr) static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr)
{ {
__asm__ __volatile__("stdcix %0,0,%1" __asm__ __volatile__("stdcix %0,0,%1"
: : "r" (val), "r" (paddr) : "memory"); : : "r" (val), "r" (paddr) : "memory");
} }
static inline u8 __raw_rm_readb(volatile void __iomem *paddr)
{
u8 ret;
__asm__ __volatile__("lbzcix %0,0, %1"
: "=r" (ret) : "r" (paddr) : "memory");
return ret;
}
static inline u16 __raw_rm_readw(volatile void __iomem *paddr)
{
u16 ret;
__asm__ __volatile__("lhzcix %0,0, %1"
: "=r" (ret) : "r" (paddr) : "memory");
return ret;
}
static inline u32 __raw_rm_readl(volatile void __iomem *paddr)
{
u32 ret;
__asm__ __volatile__("lwzcix %0,0, %1"
: "=r" (ret) : "r" (paddr) : "memory");
return ret;
}
static inline u64 __raw_rm_readq(volatile void __iomem *paddr)
{
u64 ret;
__asm__ __volatile__("ldcix %0,0, %1"
: "=r" (ret) : "r" (paddr) : "memory");
return ret;
}
#endif /* __powerpc64__ */ #endif /* __powerpc64__ */
/* /*
...@@ -757,6 +759,8 @@ extern void __iomem *ioremap_prot(phys_addr_t address, unsigned long size, ...@@ -757,6 +759,8 @@ extern void __iomem *ioremap_prot(phys_addr_t address, unsigned long size,
extern void __iomem *ioremap_wc(phys_addr_t address, unsigned long size); extern void __iomem *ioremap_wc(phys_addr_t address, unsigned long size);
#define ioremap_nocache(addr, size) ioremap((addr), (size)) #define ioremap_nocache(addr, size) ioremap((addr), (size))
#define ioremap_uc(addr, size) ioremap((addr), (size)) #define ioremap_uc(addr, size) ioremap((addr), (size))
#define ioremap_cache(addr, size) \
ioremap_prot((addr), (size), pgprot_val(PAGE_KERNEL))
extern void iounmap(volatile void __iomem *addr); extern void iounmap(volatile void __iomem *addr);
......
...@@ -64,6 +64,11 @@ struct iommu_table_ops { ...@@ -64,6 +64,11 @@ struct iommu_table_ops {
long index, long index,
unsigned long *hpa, unsigned long *hpa,
enum dma_data_direction *direction); enum dma_data_direction *direction);
/* Real mode */
int (*exchange_rm)(struct iommu_table *tbl,
long index,
unsigned long *hpa,
enum dma_data_direction *direction);
#endif #endif
void (*clear)(struct iommu_table *tbl, void (*clear)(struct iommu_table *tbl,
long index, long npages); long index, long npages);
...@@ -114,6 +119,7 @@ struct iommu_table { ...@@ -114,6 +119,7 @@ struct iommu_table {
struct list_head it_group_list;/* List of iommu_table_group_link */ struct list_head it_group_list;/* List of iommu_table_group_link */
unsigned long *it_userspace; /* userspace view of the table */ unsigned long *it_userspace; /* userspace view of the table */
struct iommu_table_ops *it_ops; struct iommu_table_ops *it_ops;
struct kref it_kref;
}; };
#define IOMMU_TABLE_USERSPACE_ENTRY(tbl, entry) \ #define IOMMU_TABLE_USERSPACE_ENTRY(tbl, entry) \
...@@ -146,8 +152,8 @@ static inline void *get_iommu_table_base(struct device *dev) ...@@ -146,8 +152,8 @@ static inline void *get_iommu_table_base(struct device *dev)
extern int dma_iommu_dma_supported(struct device *dev, u64 mask); extern int dma_iommu_dma_supported(struct device *dev, u64 mask);
/* Frees table for an individual device node */ extern struct iommu_table *iommu_tce_table_get(struct iommu_table *tbl);
extern void iommu_free_table(struct iommu_table *tbl, const char *node_name); extern int iommu_tce_table_put(struct iommu_table *tbl);
/* Initializes an iommu_table based in values set in the passed-in /* Initializes an iommu_table based in values set in the passed-in
* structure * structure
...@@ -208,6 +214,8 @@ extern void iommu_del_device(struct device *dev); ...@@ -208,6 +214,8 @@ extern void iommu_del_device(struct device *dev);
extern int __init tce_iommu_bus_notifier_init(void); extern int __init tce_iommu_bus_notifier_init(void);
extern long iommu_tce_xchg(struct iommu_table *tbl, unsigned long entry, extern long iommu_tce_xchg(struct iommu_table *tbl, unsigned long entry,
unsigned long *hpa, enum dma_data_direction *direction); unsigned long *hpa, enum dma_data_direction *direction);
extern long iommu_tce_xchg_rm(struct iommu_table *tbl, unsigned long entry,
unsigned long *hpa, enum dma_data_direction *direction);
#else #else
static inline void iommu_register_group(struct iommu_table_group *table_group, static inline void iommu_register_group(struct iommu_table_group *table_group,
int pci_domain_number, int pci_domain_number,
......
...@@ -61,59 +61,6 @@ extern kprobe_opcode_t optprobe_template_end[]; ...@@ -61,59 +61,6 @@ extern kprobe_opcode_t optprobe_template_end[];
#define MAX_OPTINSN_SIZE (optprobe_template_end - optprobe_template_entry) #define MAX_OPTINSN_SIZE (optprobe_template_end - optprobe_template_entry)
#define RELATIVEJUMP_SIZE sizeof(kprobe_opcode_t) /* 4 bytes */ #define RELATIVEJUMP_SIZE sizeof(kprobe_opcode_t) /* 4 bytes */
#ifdef PPC64_ELF_ABI_v2
/* PPC64 ABIv2 needs local entry point */
#define kprobe_lookup_name(name, addr) \
{ \
addr = (kprobe_opcode_t *)kallsyms_lookup_name(name); \
if (addr) \
addr = (kprobe_opcode_t *)ppc_function_entry(addr); \
}
#elif defined(PPC64_ELF_ABI_v1)
/*
* 64bit powerpc ABIv1 uses function descriptors:
* - Check for the dot variant of the symbol first.
* - If that fails, try looking up the symbol provided.
*
* This ensures we always get to the actual symbol and not the descriptor.
* Also handle <module:symbol> format.
*/
#define kprobe_lookup_name(name, addr) \
{ \
char dot_name[MODULE_NAME_LEN + 1 + KSYM_NAME_LEN]; \
const char *modsym; \
bool dot_appended = false; \
if ((modsym = strchr(name, ':')) != NULL) { \
modsym++; \
if (*modsym != '\0' && *modsym != '.') { \
/* Convert to <module:.symbol> */ \
strncpy(dot_name, name, modsym - name); \
dot_name[modsym - name] = '.'; \
dot_name[modsym - name + 1] = '\0'; \
strncat(dot_name, modsym, \
sizeof(dot_name) - (modsym - name) - 2);\
dot_appended = true; \
} else { \
dot_name[0] = '\0'; \
strncat(dot_name, name, sizeof(dot_name) - 1); \
} \
} else if (name[0] != '.') { \
dot_name[0] = '.'; \
dot_name[1] = '\0'; \
strncat(dot_name, name, KSYM_NAME_LEN - 2); \
dot_appended = true; \
} else { \
dot_name[0] = '\0'; \
strncat(dot_name, name, KSYM_NAME_LEN - 1); \
} \
addr = (kprobe_opcode_t *)kallsyms_lookup_name(dot_name); \
if (!addr && dot_appended) { \
/* Let's try the original non-dot symbol lookup */ \
addr = (kprobe_opcode_t *)kallsyms_lookup_name(name); \
} \
}
#endif
#define flush_insn_slot(p) do { } while (0) #define flush_insn_slot(p) do { } while (0)
#define kretprobe_blacklist_size 0 #define kretprobe_blacklist_size 0
...@@ -156,6 +103,16 @@ extern int kprobe_exceptions_notify(struct notifier_block *self, ...@@ -156,6 +103,16 @@ extern int kprobe_exceptions_notify(struct notifier_block *self,
extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
extern int kprobe_handler(struct pt_regs *regs); extern int kprobe_handler(struct pt_regs *regs);
extern int kprobe_post_handler(struct pt_regs *regs); extern int kprobe_post_handler(struct pt_regs *regs);
#ifdef CONFIG_KPROBES_ON_FTRACE
extern int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
struct kprobe_ctlblk *kcb);
#else
static inline int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
struct kprobe_ctlblk *kcb)
{
return 0;
}
#endif
#else #else
static inline int kprobe_handler(struct pt_regs *regs) { return 0; } static inline int kprobe_handler(struct pt_regs *regs) { return 0; }
static inline int kprobe_post_handler(struct pt_regs *regs) { return 0; } static inline int kprobe_post_handler(struct pt_regs *regs) { return 0; }
......
...@@ -49,8 +49,6 @@ static inline bool kvm_is_radix(struct kvm *kvm) ...@@ -49,8 +49,6 @@ static inline bool kvm_is_radix(struct kvm *kvm)
#define KVM_DEFAULT_HPT_ORDER 24 /* 16MB HPT by default */ #define KVM_DEFAULT_HPT_ORDER 24 /* 16MB HPT by default */
#endif #endif
#define VRMA_VSID 0x1ffffffUL /* 1TB VSID reserved for VRMA */
/* /*
* We use a lock bit in HPTE dword 0 to synchronize updates and * We use a lock bit in HPTE dword 0 to synchronize updates and
* accesses to each HPTE, and another bit to indicate non-present * accesses to each HPTE, and another bit to indicate non-present
......
...@@ -110,7 +110,7 @@ struct kvmppc_host_state { ...@@ -110,7 +110,7 @@ struct kvmppc_host_state {
u8 ptid; u8 ptid;
struct kvm_vcpu *kvm_vcpu; struct kvm_vcpu *kvm_vcpu;
struct kvmppc_vcore *kvm_vcore; struct kvmppc_vcore *kvm_vcore;
unsigned long xics_phys; void __iomem *xics_phys;
u32 saved_xirr; u32 saved_xirr;
u64 dabr; u64 dabr;
u64 host_mmcr[7]; /* MMCR 0,1,A, SIAR, SDAR, MMCR2, SIER */ u64 host_mmcr[7]; /* MMCR 0,1,A, SIAR, SDAR, MMCR2, SIER */
......
...@@ -409,7 +409,7 @@ struct openpic; ...@@ -409,7 +409,7 @@ struct openpic;
extern void kvm_cma_reserve(void) __init; extern void kvm_cma_reserve(void) __init;
static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr)
{ {
paca[cpu].kvm_hstate.xics_phys = addr; paca[cpu].kvm_hstate.xics_phys = (void __iomem *)addr;
} }
static inline u32 kvmppc_get_xics_latch(void) static inline u32 kvmppc_get_xics_latch(void)
...@@ -478,8 +478,6 @@ extern void kvmppc_free_host_rm_ops(void); ...@@ -478,8 +478,6 @@ extern void kvmppc_free_host_rm_ops(void);
extern void kvmppc_free_pimap(struct kvm *kvm); extern void kvmppc_free_pimap(struct kvm *kvm);
extern int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall); extern int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall);
extern void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu); extern void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu);
extern int kvmppc_xics_create_icp(struct kvm_vcpu *vcpu, unsigned long server);
extern int kvm_vm_ioctl_xics_irq(struct kvm *kvm, struct kvm_irq_level *args);
extern int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd); extern int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd);
extern u64 kvmppc_xics_get_icp(struct kvm_vcpu *vcpu); extern u64 kvmppc_xics_get_icp(struct kvm_vcpu *vcpu);
extern int kvmppc_xics_set_icp(struct kvm_vcpu *vcpu, u64 icpval); extern int kvmppc_xics_set_icp(struct kvm_vcpu *vcpu, u64 icpval);
...@@ -507,12 +505,6 @@ static inline int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall) ...@@ -507,12 +505,6 @@ static inline int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall)
static inline int kvmppc_xics_enabled(struct kvm_vcpu *vcpu) static inline int kvmppc_xics_enabled(struct kvm_vcpu *vcpu)
{ return 0; } { return 0; }
static inline void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu) { } static inline void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu) { }
static inline int kvmppc_xics_create_icp(struct kvm_vcpu *vcpu,
unsigned long server)
{ return -EINVAL; }
static inline int kvm_vm_ioctl_xics_irq(struct kvm *kvm,
struct kvm_irq_level *args)
{ return -ENOTTY; }
static inline int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd) static inline int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd)
{ return 0; } { return 0; }
#endif #endif
......
...@@ -24,97 +24,6 @@ ...@@ -24,97 +24,6 @@
#include <linux/bitops.h> #include <linux/bitops.h>
/*
* Machine Check bits on power7 and power8
*/
#define P7_SRR1_MC_LOADSTORE(srr1) ((srr1) & PPC_BIT(42)) /* P8 too */
/* SRR1 bits for machine check (On Power7 and Power8) */
#define P7_SRR1_MC_IFETCH(srr1) ((srr1) & PPC_BITMASK(43, 45)) /* P8 too */
#define P7_SRR1_MC_IFETCH_UE (0x1 << PPC_BITLSHIFT(45)) /* P8 too */
#define P7_SRR1_MC_IFETCH_SLB_PARITY (0x2 << PPC_BITLSHIFT(45)) /* P8 too */
#define P7_SRR1_MC_IFETCH_SLB_MULTIHIT (0x3 << PPC_BITLSHIFT(45)) /* P8 too */
#define P7_SRR1_MC_IFETCH_SLB_BOTH (0x4 << PPC_BITLSHIFT(45))
#define P7_SRR1_MC_IFETCH_TLB_MULTIHIT (0x5 << PPC_BITLSHIFT(45)) /* P8 too */
#define P7_SRR1_MC_IFETCH_UE_TLB_RELOAD (0x6 << PPC_BITLSHIFT(45)) /* P8 too */
#define P7_SRR1_MC_IFETCH_UE_IFU_INTERNAL (0x7 << PPC_BITLSHIFT(45))
/* SRR1 bits for machine check (On Power8) */
#define P8_SRR1_MC_IFETCH_ERAT_MULTIHIT (0x4 << PPC_BITLSHIFT(45))
/* DSISR bits for machine check (On Power7 and Power8) */
#define P7_DSISR_MC_UE (PPC_BIT(48)) /* P8 too */
#define P7_DSISR_MC_UE_TABLEWALK (PPC_BIT(49)) /* P8 too */
#define P7_DSISR_MC_ERAT_MULTIHIT (PPC_BIT(52)) /* P8 too */
#define P7_DSISR_MC_TLB_MULTIHIT_MFTLB (PPC_BIT(53)) /* P8 too */
#define P7_DSISR_MC_SLB_PARITY_MFSLB (PPC_BIT(55)) /* P8 too */
#define P7_DSISR_MC_SLB_MULTIHIT (PPC_BIT(56)) /* P8 too */
#define P7_DSISR_MC_SLB_MULTIHIT_PARITY (PPC_BIT(57)) /* P8 too */
/*
* DSISR bits for machine check (Power8) in addition to above.
* Secondary DERAT Multihit
*/
#define P8_DSISR_MC_ERAT_MULTIHIT_SEC (PPC_BIT(54))
/* SLB error bits */
#define P7_DSISR_MC_SLB_ERRORS (P7_DSISR_MC_ERAT_MULTIHIT | \
P7_DSISR_MC_SLB_PARITY_MFSLB | \
P7_DSISR_MC_SLB_MULTIHIT | \
P7_DSISR_MC_SLB_MULTIHIT_PARITY)
#define P8_DSISR_MC_SLB_ERRORS (P7_DSISR_MC_SLB_ERRORS | \
P8_DSISR_MC_ERAT_MULTIHIT_SEC)
/*
* Machine Check bits on power9
*/
#define P9_SRR1_MC_LOADSTORE(srr1) (((srr1) >> PPC_BITLSHIFT(42)) & 1)
#define P9_SRR1_MC_IFETCH(srr1) ( \
PPC_BITEXTRACT(srr1, 45, 0) | \
PPC_BITEXTRACT(srr1, 44, 1) | \
PPC_BITEXTRACT(srr1, 43, 2) | \
PPC_BITEXTRACT(srr1, 36, 3) )
/* 0 is reserved */
#define P9_SRR1_MC_IFETCH_UE 1
#define P9_SRR1_MC_IFETCH_SLB_PARITY 2
#define P9_SRR1_MC_IFETCH_SLB_MULTIHIT 3
#define P9_SRR1_MC_IFETCH_ERAT_MULTIHIT 4
#define P9_SRR1_MC_IFETCH_TLB_MULTIHIT 5
#define P9_SRR1_MC_IFETCH_UE_TLB_RELOAD 6
/* 7 is reserved */
#define P9_SRR1_MC_IFETCH_LINK_TIMEOUT 8
#define P9_SRR1_MC_IFETCH_LINK_TABLEWALK_TIMEOUT 9
/* 10 ? */
#define P9_SRR1_MC_IFETCH_RA 11
#define P9_SRR1_MC_IFETCH_RA_TABLEWALK 12
#define P9_SRR1_MC_IFETCH_RA_ASYNC_STORE 13
#define P9_SRR1_MC_IFETCH_LINK_ASYNC_STORE_TIMEOUT 14
#define P9_SRR1_MC_IFETCH_RA_TABLEWALK_FOREIGN 15
/* DSISR bits for machine check (On Power9) */
#define P9_DSISR_MC_UE (PPC_BIT(48))
#define P9_DSISR_MC_UE_TABLEWALK (PPC_BIT(49))
#define P9_DSISR_MC_LINK_LOAD_TIMEOUT (PPC_BIT(50))
#define P9_DSISR_MC_LINK_TABLEWALK_TIMEOUT (PPC_BIT(51))
#define P9_DSISR_MC_ERAT_MULTIHIT (PPC_BIT(52))
#define P9_DSISR_MC_TLB_MULTIHIT_MFTLB (PPC_BIT(53))
#define P9_DSISR_MC_USER_TLBIE (PPC_BIT(54))
#define P9_DSISR_MC_SLB_PARITY_MFSLB (PPC_BIT(55))
#define P9_DSISR_MC_SLB_MULTIHIT_MFSLB (PPC_BIT(56))
#define P9_DSISR_MC_RA_LOAD (PPC_BIT(57))
#define P9_DSISR_MC_RA_TABLEWALK (PPC_BIT(58))
#define P9_DSISR_MC_RA_TABLEWALK_FOREIGN (PPC_BIT(59))
#define P9_DSISR_MC_RA_FOREIGN (PPC_BIT(60))
/* SLB error bits */
#define P9_DSISR_MC_SLB_ERRORS (P9_DSISR_MC_ERAT_MULTIHIT | \
P9_DSISR_MC_SLB_PARITY_MFSLB | \
P9_DSISR_MC_SLB_MULTIHIT_MFSLB)
enum MCE_Version { enum MCE_Version {
MCE_V1 = 1, MCE_V1 = 1,
}; };
...@@ -298,7 +207,8 @@ extern void save_mce_event(struct pt_regs *regs, long handled, ...@@ -298,7 +207,8 @@ extern void save_mce_event(struct pt_regs *regs, long handled,
extern int get_mce_event(struct machine_check_event *mce, bool release); extern int get_mce_event(struct machine_check_event *mce, bool release);
extern void release_mce_event(void); extern void release_mce_event(void);
extern void machine_check_queue_event(void); extern void machine_check_queue_event(void);
extern void machine_check_print_event_info(struct machine_check_event *evt); extern void machine_check_print_event_info(struct machine_check_event *evt,
bool user_mode);
extern uint64_t get_mce_fault_addr(struct machine_check_event *evt); extern uint64_t get_mce_fault_addr(struct machine_check_event *evt);
#endif /* __ASM_PPC64_MCE_H__ */ #endif /* __ASM_PPC64_MCE_H__ */
...@@ -229,11 +229,6 @@ typedef struct { ...@@ -229,11 +229,6 @@ typedef struct {
unsigned int id; unsigned int id;
unsigned int active; unsigned int active;
unsigned long vdso_base; unsigned long vdso_base;
#ifdef CONFIG_PPC_MM_SLICES
u64 low_slices_psize; /* SLB page size encodings */
u64 high_slices_psize; /* 4 bits per slice for now */
u16 user_psize; /* page size index */
#endif
#ifdef CONFIG_PPC_64K_PAGES #ifdef CONFIG_PPC_64K_PAGES
/* for 4K PTE fragment support */ /* for 4K PTE fragment support */
void *pte_frag; void *pte_frag;
......
...@@ -28,6 +28,10 @@ ...@@ -28,6 +28,10 @@
* Individual features below. * Individual features below.
*/ */
/*
* Support for 68 bit VA space. We added that from ISA 2.05
*/
#define MMU_FTR_68_BIT_VA ASM_CONST(0x00002000)
/* /*
* Kernel read only support. * Kernel read only support.
* We added the ppp value 0b110 in ISA 2.04. * We added the ppp value 0b110 in ISA 2.04.
...@@ -109,10 +113,10 @@ ...@@ -109,10 +113,10 @@
#define MMU_FTRS_POWER4 MMU_FTRS_DEFAULT_HPTE_ARCH_V2 #define MMU_FTRS_POWER4 MMU_FTRS_DEFAULT_HPTE_ARCH_V2
#define MMU_FTRS_PPC970 MMU_FTRS_POWER4 | MMU_FTR_TLBIE_CROP_VA #define MMU_FTRS_PPC970 MMU_FTRS_POWER4 | MMU_FTR_TLBIE_CROP_VA
#define MMU_FTRS_POWER5 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE #define MMU_FTRS_POWER5 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
#define MMU_FTRS_POWER6 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_KERNEL_RO #define MMU_FTRS_POWER6 MMU_FTRS_POWER5 | MMU_FTR_KERNEL_RO | MMU_FTR_68_BIT_VA
#define MMU_FTRS_POWER7 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_KERNEL_RO #define MMU_FTRS_POWER7 MMU_FTRS_POWER6
#define MMU_FTRS_POWER8 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_KERNEL_RO #define MMU_FTRS_POWER8 MMU_FTRS_POWER6
#define MMU_FTRS_POWER9 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_KERNEL_RO #define MMU_FTRS_POWER9 MMU_FTRS_POWER6
#define MMU_FTRS_CELL MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \ #define MMU_FTRS_CELL MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
MMU_FTR_CI_LARGE_PAGE MMU_FTR_CI_LARGE_PAGE
#define MMU_FTRS_PA6T MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \ #define MMU_FTRS_PA6T MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
...@@ -136,7 +140,7 @@ enum { ...@@ -136,7 +140,7 @@ enum {
MMU_FTR_NO_SLBIE_B | MMU_FTR_16M_PAGE | MMU_FTR_TLBIEL | MMU_FTR_NO_SLBIE_B | MMU_FTR_16M_PAGE | MMU_FTR_TLBIEL |
MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_CI_LARGE_PAGE | MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_CI_LARGE_PAGE |
MMU_FTR_1T_SEGMENT | MMU_FTR_TLBIE_CROP_VA | MMU_FTR_1T_SEGMENT | MMU_FTR_TLBIE_CROP_VA |
MMU_FTR_KERNEL_RO | MMU_FTR_KERNEL_RO | MMU_FTR_68_BIT_VA |
#ifdef CONFIG_PPC_RADIX_MMU #ifdef CONFIG_PPC_RADIX_MMU
MMU_FTR_TYPE_RADIX | MMU_FTR_TYPE_RADIX |
#endif #endif
...@@ -290,7 +294,10 @@ static inline bool early_radix_enabled(void) ...@@ -290,7 +294,10 @@ static inline bool early_radix_enabled(void)
#define MMU_PAGE_16G 14 #define MMU_PAGE_16G 14
#define MMU_PAGE_64G 15 #define MMU_PAGE_64G 15
/* N.B. we need to change the type of hpte_page_sizes if this gets to be > 16 */ /*
* N.B. we need to change the type of hpte_page_sizes if this gets to be > 16
* Also we need to change he type of mm_context.low/high_slices_psize.
*/
#define MMU_PAGE_COUNT 16 #define MMU_PAGE_COUNT 16
#ifdef CONFIG_PPC_BOOK3S_64 #ifdef CONFIG_PPC_BOOK3S_64
......
...@@ -29,10 +29,14 @@ extern void mm_iommu_init(struct mm_struct *mm); ...@@ -29,10 +29,14 @@ extern void mm_iommu_init(struct mm_struct *mm);
extern void mm_iommu_cleanup(struct mm_struct *mm); extern void mm_iommu_cleanup(struct mm_struct *mm);
extern struct mm_iommu_table_group_mem_t *mm_iommu_lookup(struct mm_struct *mm, extern struct mm_iommu_table_group_mem_t *mm_iommu_lookup(struct mm_struct *mm,
unsigned long ua, unsigned long size); unsigned long ua, unsigned long size);
extern struct mm_iommu_table_group_mem_t *mm_iommu_lookup_rm(
struct mm_struct *mm, unsigned long ua, unsigned long size);
extern struct mm_iommu_table_group_mem_t *mm_iommu_find(struct mm_struct *mm, extern struct mm_iommu_table_group_mem_t *mm_iommu_find(struct mm_struct *mm,
unsigned long ua, unsigned long entries); unsigned long ua, unsigned long entries);
extern long mm_iommu_ua_to_hpa(struct mm_iommu_table_group_mem_t *mem, extern long mm_iommu_ua_to_hpa(struct mm_iommu_table_group_mem_t *mem,
unsigned long ua, unsigned long *hpa); unsigned long ua, unsigned long *hpa);
extern long mm_iommu_ua_to_hpa_rm(struct mm_iommu_table_group_mem_t *mem,
unsigned long ua, unsigned long *hpa);
extern long mm_iommu_mapped_inc(struct mm_iommu_table_group_mem_t *mem); extern long mm_iommu_mapped_inc(struct mm_iommu_table_group_mem_t *mem);
extern void mm_iommu_mapped_dec(struct mm_iommu_table_group_mem_t *mem); extern void mm_iommu_mapped_dec(struct mm_iommu_table_group_mem_t *mem);
#endif #endif
...@@ -51,7 +55,8 @@ static inline void switch_mmu_context(struct mm_struct *prev, ...@@ -51,7 +55,8 @@ static inline void switch_mmu_context(struct mm_struct *prev,
return switch_slb(tsk, next); return switch_slb(tsk, next);
} }
extern int __init_new_context(void); extern int hash__alloc_context_id(void);
extern void hash__reserve_context_id(int id);
extern void __destroy_context(int context_id); extern void __destroy_context(int context_id);
static inline void mmu_context_init(void) { } static inline void mmu_context_init(void) { }
#else #else
...@@ -70,8 +75,9 @@ extern void drop_cop(unsigned long acop, struct mm_struct *mm); ...@@ -70,8 +75,9 @@ extern void drop_cop(unsigned long acop, struct mm_struct *mm);
* switch_mm is the entry point called from the architecture independent * switch_mm is the entry point called from the architecture independent
* code in kernel/sched/core.c * code in kernel/sched/core.c
*/ */
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, static inline void switch_mm_irqs_off(struct mm_struct *prev,
struct task_struct *tsk) struct mm_struct *next,
struct task_struct *tsk)
{ {
/* Mark this context has been used on the new CPU */ /* Mark this context has been used on the new CPU */
if (!cpumask_test_cpu(smp_processor_id(), mm_cpumask(next))) if (!cpumask_test_cpu(smp_processor_id(), mm_cpumask(next)))
...@@ -110,6 +116,18 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, ...@@ -110,6 +116,18 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
switch_mmu_context(prev, next, tsk); switch_mmu_context(prev, next, tsk);
} }
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk)
{
unsigned long flags;
local_irq_save(flags);
switch_mm_irqs_off(prev, next, tsk);
local_irq_restore(flags);
}
#define switch_mm_irqs_off switch_mm_irqs_off
#define deactivate_mm(tsk,mm) do { } while (0) #define deactivate_mm(tsk,mm) do { } while (0)
/* /*
......
...@@ -88,11 +88,6 @@ ...@@ -88,11 +88,6 @@
#include <asm/nohash/pte-book3e.h> #include <asm/nohash/pte-book3e.h>
#include <asm/pte-common.h> #include <asm/pte-common.h>
#ifdef CONFIG_PPC_MM_SLICES
#define HAVE_ARCH_UNMAPPED_AREA
#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
#endif /* CONFIG_PPC_MM_SLICES */
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
/* pte_clear moved to later in this file */ /* pte_clear moved to later in this file */
......
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
#define OPAL_I2C_ARBT_LOST -22 #define OPAL_I2C_ARBT_LOST -22
#define OPAL_I2C_NACK_RCVD -23 #define OPAL_I2C_NACK_RCVD -23
#define OPAL_I2C_STOP_ERR -24 #define OPAL_I2C_STOP_ERR -24
#define OPAL_XIVE_PROVISIONING -31
#define OPAL_XIVE_FREE_ACTIVE -32
/* API Tokens (in r0) */ /* API Tokens (in r0) */
#define OPAL_INVALID_CALL -1 #define OPAL_INVALID_CALL -1
...@@ -168,7 +170,27 @@ ...@@ -168,7 +170,27 @@
#define OPAL_INT_SET_MFRR 125 #define OPAL_INT_SET_MFRR 125
#define OPAL_PCI_TCE_KILL 126 #define OPAL_PCI_TCE_KILL 126
#define OPAL_NMMU_SET_PTCR 127 #define OPAL_NMMU_SET_PTCR 127
#define OPAL_LAST 127 #define OPAL_XIVE_RESET 128
#define OPAL_XIVE_GET_IRQ_INFO 129
#define OPAL_XIVE_GET_IRQ_CONFIG 130
#define OPAL_XIVE_SET_IRQ_CONFIG 131
#define OPAL_XIVE_GET_QUEUE_INFO 132
#define OPAL_XIVE_SET_QUEUE_INFO 133
#define OPAL_XIVE_DONATE_PAGE 134
#define OPAL_XIVE_ALLOCATE_VP_BLOCK 135
#define OPAL_XIVE_FREE_VP_BLOCK 136
#define OPAL_XIVE_GET_VP_INFO 137
#define OPAL_XIVE_SET_VP_INFO 138
#define OPAL_XIVE_ALLOCATE_IRQ 139
#define OPAL_XIVE_FREE_IRQ 140
#define OPAL_XIVE_SYNC 141
#define OPAL_XIVE_DUMP 142
#define OPAL_XIVE_RESERVED3 143
#define OPAL_XIVE_RESERVED4 144
#define OPAL_NPU_INIT_CONTEXT 146
#define OPAL_NPU_DESTROY_CONTEXT 147
#define OPAL_NPU_MAP_LPAR 148
#define OPAL_LAST 148
/* Device tree flags */ /* Device tree flags */
...@@ -928,6 +950,59 @@ enum { ...@@ -928,6 +950,59 @@ enum {
OPAL_PCI_TCE_KILL_ALL, OPAL_PCI_TCE_KILL_ALL,
}; };
/* The xive operation mode indicates the active "API" and
* corresponds to the "mode" parameter of the opal_xive_reset()
* call
*/
enum {
OPAL_XIVE_MODE_EMU = 0,
OPAL_XIVE_MODE_EXPL = 1,
};
/* Flags for OPAL_XIVE_GET_IRQ_INFO */
enum {
OPAL_XIVE_IRQ_TRIGGER_PAGE = 0x00000001,
OPAL_XIVE_IRQ_STORE_EOI = 0x00000002,
OPAL_XIVE_IRQ_LSI = 0x00000004,
OPAL_XIVE_IRQ_SHIFT_BUG = 0x00000008,
OPAL_XIVE_IRQ_MASK_VIA_FW = 0x00000010,
OPAL_XIVE_IRQ_EOI_VIA_FW = 0x00000020,
};
/* Flags for OPAL_XIVE_GET/SET_QUEUE_INFO */
enum {
OPAL_XIVE_EQ_ENABLED = 0x00000001,
OPAL_XIVE_EQ_ALWAYS_NOTIFY = 0x00000002,
OPAL_XIVE_EQ_ESCALATE = 0x00000004,
};
/* Flags for OPAL_XIVE_GET/SET_VP_INFO */
enum {
OPAL_XIVE_VP_ENABLED = 0x00000001,
};
/* "Any chip" replacement for chip ID for allocation functions */
enum {
OPAL_XIVE_ANY_CHIP = 0xffffffff,
};
/* Xive sync options */
enum {
/* This bits are cumulative, arg is a girq */
XIVE_SYNC_EAS = 0x00000001, /* Sync irq source */
XIVE_SYNC_QUEUE = 0x00000002, /* Sync irq target */
};
/* Dump options */
enum {
XIVE_DUMP_TM_HYP = 0,
XIVE_DUMP_TM_POOL = 1,
XIVE_DUMP_TM_OS = 2,
XIVE_DUMP_TM_USER = 3,
XIVE_DUMP_VP = 4,
XIVE_DUMP_EMU_STATE = 5,
};
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* __OPAL_API_H */ #endif /* __OPAL_API_H */
...@@ -29,6 +29,11 @@ extern struct device_node *opal_node; ...@@ -29,6 +29,11 @@ extern struct device_node *opal_node;
/* API functions */ /* API functions */
int64_t opal_invalid_call(void); int64_t opal_invalid_call(void);
int64_t opal_npu_destroy_context(uint64_t phb_id, uint64_t pid, uint64_t bdf);
int64_t opal_npu_init_context(uint64_t phb_id, int pasid, uint64_t msr,
uint64_t bdf);
int64_t opal_npu_map_lpar(uint64_t phb_id, uint64_t bdf, uint64_t lparid,
uint64_t lpcr);
int64_t opal_console_write(int64_t term_number, __be64 *length, int64_t opal_console_write(int64_t term_number, __be64 *length,
const uint8_t *buffer); const uint8_t *buffer);
int64_t opal_console_read(int64_t term_number, __be64 *length, int64_t opal_console_read(int64_t term_number, __be64 *length,
...@@ -226,6 +231,42 @@ int64_t opal_pci_tce_kill(uint64_t phb_id, uint32_t kill_type, ...@@ -226,6 +231,42 @@ int64_t opal_pci_tce_kill(uint64_t phb_id, uint32_t kill_type,
uint32_t pe_num, uint32_t tce_size, uint32_t pe_num, uint32_t tce_size,
uint64_t dma_addr, uint32_t npages); uint64_t dma_addr, uint32_t npages);
int64_t opal_nmmu_set_ptcr(uint64_t chip_id, uint64_t ptcr); int64_t opal_nmmu_set_ptcr(uint64_t chip_id, uint64_t ptcr);
int64_t opal_xive_reset(uint64_t version);
int64_t opal_xive_get_irq_info(uint32_t girq,
__be64 *out_flags,
__be64 *out_eoi_page,
__be64 *out_trig_page,
__be32 *out_esb_shift,
__be32 *out_src_chip);
int64_t opal_xive_get_irq_config(uint32_t girq, __be64 *out_vp,
uint8_t *out_prio, __be32 *out_lirq);
int64_t opal_xive_set_irq_config(uint32_t girq, uint64_t vp, uint8_t prio,
uint32_t lirq);
int64_t opal_xive_get_queue_info(uint64_t vp, uint32_t prio,
__be64 *out_qpage,
__be64 *out_qsize,
__be64 *out_qeoi_page,
__be32 *out_escalate_irq,
__be64 *out_qflags);
int64_t opal_xive_set_queue_info(uint64_t vp, uint32_t prio,
uint64_t qpage,
uint64_t qsize,
uint64_t qflags);
int64_t opal_xive_donate_page(uint32_t chip_id, uint64_t addr);
int64_t opal_xive_alloc_vp_block(uint32_t alloc_order);
int64_t opal_xive_free_vp_block(uint64_t vp);
int64_t opal_xive_get_vp_info(uint64_t vp,
__be64 *out_flags,
__be64 *out_cam_value,
__be64 *out_report_cl_pair,
__be32 *out_chip_id);
int64_t opal_xive_set_vp_info(uint64_t vp,
uint64_t flags,
uint64_t report_cl_pair);
int64_t opal_xive_allocate_irq(uint32_t chip_id);
int64_t opal_xive_free_irq(uint32_t girq);
int64_t opal_xive_sync(uint32_t type, uint32_t id);
int64_t opal_xive_dump(uint32_t type, uint32_t id);
/* Internal functions */ /* Internal functions */
extern int early_init_dt_scan_opal(unsigned long node, const char *uname, extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
......
...@@ -99,7 +99,6 @@ struct paca_struct { ...@@ -99,7 +99,6 @@ struct paca_struct {
*/ */
/* used for most interrupts/exceptions */ /* used for most interrupts/exceptions */
u64 exgen[13] __attribute__((aligned(0x80))); u64 exgen[13] __attribute__((aligned(0x80)));
u64 exmc[13]; /* used for machine checks */
u64 exslb[13]; /* used for SLB/segment table misses u64 exslb[13]; /* used for SLB/segment table misses
* on the linear mapping */ * on the linear mapping */
/* SLB related definitions */ /* SLB related definitions */
...@@ -139,6 +138,7 @@ struct paca_struct { ...@@ -139,6 +138,7 @@ struct paca_struct {
#ifdef CONFIG_PPC_MM_SLICES #ifdef CONFIG_PPC_MM_SLICES
u64 mm_ctx_low_slices_psize; u64 mm_ctx_low_slices_psize;
unsigned char mm_ctx_high_slices_psize[SLICE_ARRAY_SIZE]; unsigned char mm_ctx_high_slices_psize[SLICE_ARRAY_SIZE];
unsigned long addr_limit;
#else #else
u16 mm_ctx_user_psize; u16 mm_ctx_user_psize;
u16 mm_ctx_sllp; u16 mm_ctx_sllp;
...@@ -172,17 +172,31 @@ struct paca_struct { ...@@ -172,17 +172,31 @@ struct paca_struct {
u8 thread_mask; u8 thread_mask;
/* Mask to denote subcore sibling threads */ /* Mask to denote subcore sibling threads */
u8 subcore_sibling_mask; u8 subcore_sibling_mask;
/*
* Pointer to an array which contains pointer
* to the sibling threads' paca.
*/
struct paca_struct **thread_sibling_pacas;
#endif #endif
#ifdef CONFIG_PPC_STD_MMU_64
/* Non-maskable exceptions that are not performance critical */
u64 exnmi[13]; /* used for system reset (nmi) */
u64 exmc[13]; /* used for machine checks */
#endif
#ifdef CONFIG_PPC_BOOK3S_64 #ifdef CONFIG_PPC_BOOK3S_64
/* Exclusive emergency stack pointer for machine check exception. */ /* Exclusive stacks for system reset and machine check exception. */
void *nmi_emergency_sp;
void *mc_emergency_sp; void *mc_emergency_sp;
u16 in_nmi; /* In nmi handler */
/* /*
* Flag to check whether we are in machine check early handler * Flag to check whether we are in machine check early handler
* and already using emergency stack. * and already using emergency stack.
*/ */
u16 in_mce; u16 in_mce;
u8 hmi_event_available; /* HMI event is available */ u8 hmi_event_available; /* HMI event is available */
#endif #endif
/* Stuff for accurate time accounting */ /* Stuff for accurate time accounting */
...@@ -206,23 +220,7 @@ struct paca_struct { ...@@ -206,23 +220,7 @@ struct paca_struct {
#endif #endif
}; };
#ifdef CONFIG_PPC_BOOK3S extern void copy_mm_to_paca(struct mm_struct *mm);
static inline void copy_mm_to_paca(mm_context_t *context)
{
get_paca()->mm_ctx_id = context->id;
#ifdef CONFIG_PPC_MM_SLICES
get_paca()->mm_ctx_low_slices_psize = context->low_slices_psize;
memcpy(&get_paca()->mm_ctx_high_slices_psize,
&context->high_slices_psize, SLICE_ARRAY_SIZE);
#else
get_paca()->mm_ctx_user_psize = context->user_psize;
get_paca()->mm_ctx_sllp = context->sllp;
#endif
}
#else
static inline void copy_mm_to_paca(mm_context_t *context){}
#endif
extern struct paca_struct *paca; extern struct paca_struct *paca;
extern void initialise_paca(struct paca_struct *new_paca, int cpu); extern void initialise_paca(struct paca_struct *new_paca, int cpu);
extern void setup_paca(struct paca_struct *new_paca); extern void setup_paca(struct paca_struct *new_paca);
......
...@@ -98,21 +98,7 @@ extern u64 ppc64_pft_size; ...@@ -98,21 +98,7 @@ extern u64 ppc64_pft_size;
#define GET_LOW_SLICE_INDEX(addr) ((addr) >> SLICE_LOW_SHIFT) #define GET_LOW_SLICE_INDEX(addr) ((addr) >> SLICE_LOW_SHIFT)
#define GET_HIGH_SLICE_INDEX(addr) ((addr) >> SLICE_HIGH_SHIFT) #define GET_HIGH_SLICE_INDEX(addr) ((addr) >> SLICE_HIGH_SHIFT)
/*
* 1 bit per slice and we have one slice per 1TB
* Right now we support only 64TB.
* IF we change this we will have to change the type
* of high_slices
*/
#define SLICE_MASK_SIZE 8
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
struct slice_mask {
u16 low_slices;
u64 high_slices;
};
struct mm_struct; struct mm_struct;
extern unsigned long slice_get_unmapped_area(unsigned long addr, extern unsigned long slice_get_unmapped_area(unsigned long addr,
......
...@@ -38,6 +38,9 @@ struct power_pmu { ...@@ -38,6 +38,9 @@ struct power_pmu {
unsigned long *valp); unsigned long *valp);
int (*get_alternatives)(u64 event_id, unsigned int flags, int (*get_alternatives)(u64 event_id, unsigned int flags,
u64 alt[]); u64 alt[]);
void (*get_mem_data_src)(union perf_mem_data_src *dsrc,
u32 flags, struct pt_regs *regs);
void (*get_mem_weight)(u64 *weight);
u64 (*bhrb_filter_map)(u64 branch_sample_type); u64 (*bhrb_filter_map)(u64 branch_sample_type);
void (*config_bhrb)(u64 pmu_bhrb_filter); void (*config_bhrb)(u64 pmu_bhrb_filter);
void (*disable_pmc)(unsigned int pmc, unsigned long mmcr[]); void (*disable_pmc)(unsigned int pmc, unsigned long mmcr[]);
......
...@@ -11,9 +11,31 @@ ...@@ -11,9 +11,31 @@
#define _ASM_POWERNV_H #define _ASM_POWERNV_H
#ifdef CONFIG_PPC_POWERNV #ifdef CONFIG_PPC_POWERNV
#define NPU2_WRITE 1
extern void powernv_set_nmmu_ptcr(unsigned long ptcr); extern void powernv_set_nmmu_ptcr(unsigned long ptcr);
extern struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev,
unsigned long flags,
struct npu_context *(*cb)(struct npu_context *, void *),
void *priv);
extern void pnv_npu2_destroy_context(struct npu_context *context,
struct pci_dev *gpdev);
extern int pnv_npu2_handle_fault(struct npu_context *context, uintptr_t *ea,
unsigned long *flags, unsigned long *status,
int count);
#else #else
static inline void powernv_set_nmmu_ptcr(unsigned long ptcr) { } static inline void powernv_set_nmmu_ptcr(unsigned long ptcr) { }
static inline struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev,
unsigned long flags,
struct npu_context *(*cb)(struct npu_context *, void *),
void *priv) { return ERR_PTR(-ENODEV); }
static inline void pnv_npu2_destroy_context(struct npu_context *context,
struct pci_dev *gpdev) { }
static inline int pnv_npu2_handle_fault(struct npu_context *context,
uintptr_t *ea, unsigned long *flags,
unsigned long *status, int count) {
return -ENODEV;
}
#endif #endif
#endif /* _ASM_POWERNV_H */ #endif /* _ASM_POWERNV_H */
...@@ -161,6 +161,7 @@ ...@@ -161,6 +161,7 @@
#define PPC_INST_MFTMR 0x7c0002dc #define PPC_INST_MFTMR 0x7c0002dc
#define PPC_INST_MSGSND 0x7c00019c #define PPC_INST_MSGSND 0x7c00019c
#define PPC_INST_MSGCLR 0x7c0001dc #define PPC_INST_MSGCLR 0x7c0001dc
#define PPC_INST_MSGSYNC 0x7c0006ec
#define PPC_INST_MSGSNDP 0x7c00011c #define PPC_INST_MSGSNDP 0x7c00011c
#define PPC_INST_MTTMR 0x7c0003dc #define PPC_INST_MTTMR 0x7c0003dc
#define PPC_INST_NOP 0x60000000 #define PPC_INST_NOP 0x60000000
...@@ -345,6 +346,7 @@ ...@@ -345,6 +346,7 @@
___PPC_RB(b) | __PPC_EH(eh)) ___PPC_RB(b) | __PPC_EH(eh))
#define PPC_MSGSND(b) stringify_in_c(.long PPC_INST_MSGSND | \ #define PPC_MSGSND(b) stringify_in_c(.long PPC_INST_MSGSND | \
___PPC_RB(b)) ___PPC_RB(b))
#define PPC_MSGSYNC stringify_in_c(.long PPC_INST_MSGSYNC)
#define PPC_MSGCLR(b) stringify_in_c(.long PPC_INST_MSGCLR | \ #define PPC_MSGCLR(b) stringify_in_c(.long PPC_INST_MSGCLR | \
___PPC_RB(b)) ___PPC_RB(b))
#define PPC_MSGSNDP(b) stringify_in_c(.long PPC_INST_MSGSNDP | \ #define PPC_MSGSNDP(b) stringify_in_c(.long PPC_INST_MSGSNDP | \
......
...@@ -102,11 +102,25 @@ void release_thread(struct task_struct *); ...@@ -102,11 +102,25 @@ void release_thread(struct task_struct *);
#endif #endif
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
/* 64-bit user address space is 46-bits (64TB user VM) */ /*
#define TASK_SIZE_USER64 (0x0000400000000000UL) * 64-bit user address space can have multiple limits
* For now supported values are:
*/
#define TASK_SIZE_64TB (0x0000400000000000UL)
#define TASK_SIZE_128TB (0x0000800000000000UL)
#define TASK_SIZE_512TB (0x0002000000000000UL)
#ifdef CONFIG_PPC_BOOK3S_64
/*
* Max value currently used:
*/
#define TASK_SIZE_USER64 TASK_SIZE_512TB
#else
#define TASK_SIZE_USER64 TASK_SIZE_64TB
#endif
/* /*
* 32-bit user address space is 4GB - 1 page * 32-bit user address space is 4GB - 1 page
* (this 1 page is needed so referencing of 0xFFFFFFFF generates EFAULT * (this 1 page is needed so referencing of 0xFFFFFFFF generates EFAULT
*/ */
#define TASK_SIZE_USER32 (0x0000000100000000UL - (1*PAGE_SIZE)) #define TASK_SIZE_USER32 (0x0000000100000000UL - (1*PAGE_SIZE))
...@@ -114,26 +128,37 @@ void release_thread(struct task_struct *); ...@@ -114,26 +128,37 @@ void release_thread(struct task_struct *);
#define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk, TIF_32BIT) ? \ #define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk, TIF_32BIT) ? \
TASK_SIZE_USER32 : TASK_SIZE_USER64) TASK_SIZE_USER32 : TASK_SIZE_USER64)
#define TASK_SIZE TASK_SIZE_OF(current) #define TASK_SIZE TASK_SIZE_OF(current)
/* This decides where the kernel will search for a free chunk of vm /* This decides where the kernel will search for a free chunk of vm
* space during mmap's. * space during mmap's.
*/ */
#define TASK_UNMAPPED_BASE_USER32 (PAGE_ALIGN(TASK_SIZE_USER32 / 4)) #define TASK_UNMAPPED_BASE_USER32 (PAGE_ALIGN(TASK_SIZE_USER32 / 4))
#define TASK_UNMAPPED_BASE_USER64 (PAGE_ALIGN(TASK_SIZE_USER64 / 4)) #define TASK_UNMAPPED_BASE_USER64 (PAGE_ALIGN(TASK_SIZE_128TB / 4))
#define TASK_UNMAPPED_BASE ((is_32bit_task()) ? \ #define TASK_UNMAPPED_BASE ((is_32bit_task()) ? \
TASK_UNMAPPED_BASE_USER32 : TASK_UNMAPPED_BASE_USER64 ) TASK_UNMAPPED_BASE_USER32 : TASK_UNMAPPED_BASE_USER64 )
#endif #endif
/*
* Initial task size value for user applications. For book3s 64 we start
* with 128TB and conditionally enable upto 512TB
*/
#ifdef CONFIG_PPC_BOOK3S_64
#define DEFAULT_MAP_WINDOW ((is_32bit_task()) ? \
TASK_SIZE_USER32 : TASK_SIZE_128TB)
#else
#define DEFAULT_MAP_WINDOW TASK_SIZE
#endif
#ifdef __powerpc64__ #ifdef __powerpc64__
#define STACK_TOP_USER64 TASK_SIZE_USER64 /* Limit stack to 128TB */
#define STACK_TOP_USER64 TASK_SIZE_128TB
#define STACK_TOP_USER32 TASK_SIZE_USER32 #define STACK_TOP_USER32 TASK_SIZE_USER32
#define STACK_TOP (is_32bit_task() ? \ #define STACK_TOP (is_32bit_task() ? \
STACK_TOP_USER32 : STACK_TOP_USER64) STACK_TOP_USER32 : STACK_TOP_USER64)
#define STACK_TOP_MAX STACK_TOP_USER64 #define STACK_TOP_MAX TASK_SIZE_USER64
#else /* __powerpc64__ */ #else /* __powerpc64__ */
......
...@@ -310,6 +310,7 @@ ...@@ -310,6 +310,7 @@
#define SPRN_PMCR 0x374 /* Power Management Control Register */ #define SPRN_PMCR 0x374 /* Power Management Control Register */
/* HFSCR and FSCR bit numbers are the same */ /* HFSCR and FSCR bit numbers are the same */
#define FSCR_SCV_LG 12 /* Enable System Call Vectored */
#define FSCR_MSGP_LG 10 /* Enable MSGP */ #define FSCR_MSGP_LG 10 /* Enable MSGP */
#define FSCR_TAR_LG 8 /* Enable Target Address Register */ #define FSCR_TAR_LG 8 /* Enable Target Address Register */
#define FSCR_EBB_LG 7 /* Enable Event Based Branching */ #define FSCR_EBB_LG 7 /* Enable Event Based Branching */
...@@ -320,6 +321,7 @@ ...@@ -320,6 +321,7 @@
#define FSCR_VECVSX_LG 1 /* Enable VMX/VSX */ #define FSCR_VECVSX_LG 1 /* Enable VMX/VSX */
#define FSCR_FP_LG 0 /* Enable Floating Point */ #define FSCR_FP_LG 0 /* Enable Floating Point */
#define SPRN_FSCR 0x099 /* Facility Status & Control Register */ #define SPRN_FSCR 0x099 /* Facility Status & Control Register */
#define FSCR_SCV __MASK(FSCR_SCV_LG)
#define FSCR_TAR __MASK(FSCR_TAR_LG) #define FSCR_TAR __MASK(FSCR_TAR_LG)
#define FSCR_EBB __MASK(FSCR_EBB_LG) #define FSCR_EBB __MASK(FSCR_EBB_LG)
#define FSCR_DSCR __MASK(FSCR_DSCR_LG) #define FSCR_DSCR __MASK(FSCR_DSCR_LG)
...@@ -365,6 +367,7 @@ ...@@ -365,6 +367,7 @@
#define LPCR_MER_SH 11 #define LPCR_MER_SH 11
#define LPCR_GTSE ASM_CONST(0x0000000000000400) /* Guest Translation Shootdown Enable */ #define LPCR_GTSE ASM_CONST(0x0000000000000400) /* Guest Translation Shootdown Enable */
#define LPCR_TC ASM_CONST(0x0000000000000200) /* Translation control */ #define LPCR_TC ASM_CONST(0x0000000000000200) /* Translation control */
#define LPCR_HEIC ASM_CONST(0x0000000000000010) /* Hypervisor External Interrupt Control */
#define LPCR_LPES 0x0000000c #define LPCR_LPES 0x0000000c
#define LPCR_LPES0 ASM_CONST(0x0000000000000008) /* LPAR Env selector 0 */ #define LPCR_LPES0 ASM_CONST(0x0000000000000008) /* LPAR Env selector 0 */
#define LPCR_LPES1 ASM_CONST(0x0000000000000004) /* LPAR Env selector 1 */ #define LPCR_LPES1 ASM_CONST(0x0000000000000004) /* LPAR Env selector 1 */
...@@ -656,6 +659,7 @@ ...@@ -656,6 +659,7 @@
#define SRR1_ISI_PROT 0x08000000 /* ISI: Other protection fault */ #define SRR1_ISI_PROT 0x08000000 /* ISI: Other protection fault */
#define SRR1_WAKEMASK 0x00380000 /* reason for wakeup */ #define SRR1_WAKEMASK 0x00380000 /* reason for wakeup */
#define SRR1_WAKEMASK_P8 0x003c0000 /* reason for wakeup on POWER8 and 9 */ #define SRR1_WAKEMASK_P8 0x003c0000 /* reason for wakeup on POWER8 and 9 */
#define SRR1_WAKEMCE_RESVD 0x003c0000 /* Unused/reserved value used by MCE wakeup to indicate cause to idle wakeup handler */
#define SRR1_WAKESYSERR 0x00300000 /* System error */ #define SRR1_WAKESYSERR 0x00300000 /* System error */
#define SRR1_WAKEEE 0x00200000 /* External interrupt */ #define SRR1_WAKEEE 0x00200000 /* External interrupt */
#define SRR1_WAKEHVI 0x00240000 /* Hypervisor Virtualization Interrupt (P9) */ #define SRR1_WAKEHVI 0x00240000 /* Hypervisor Virtualization Interrupt (P9) */
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm-generic/sections.h> #include <asm-generic/sections.h>
extern char __head_end[];
#ifdef __powerpc64__ #ifdef __powerpc64__
extern char __start_interrupts[]; extern char __start_interrupts[];
......
...@@ -40,10 +40,12 @@ extern int cpu_to_chip_id(int cpu); ...@@ -40,10 +40,12 @@ extern int cpu_to_chip_id(int cpu);
struct smp_ops_t { struct smp_ops_t {
void (*message_pass)(int cpu, int msg); void (*message_pass)(int cpu, int msg);
#ifdef CONFIG_PPC_SMP_MUXED_IPI #ifdef CONFIG_PPC_SMP_MUXED_IPI
void (*cause_ipi)(int cpu, unsigned long data); void (*cause_ipi)(int cpu);
#endif #endif
int (*cause_nmi_ipi)(int cpu);
void (*probe)(void); void (*probe)(void);
int (*kick_cpu)(int nr); int (*kick_cpu)(int nr);
int (*prepare_cpu)(int nr);
void (*setup_cpu)(int nr); void (*setup_cpu)(int nr);
void (*bringup_done)(void); void (*bringup_done)(void);
void (*take_timebase)(void); void (*take_timebase)(void);
...@@ -61,7 +63,6 @@ extern void smp_generic_take_timebase(void); ...@@ -61,7 +63,6 @@ extern void smp_generic_take_timebase(void);
DECLARE_PER_CPU(unsigned int, cpu_pvr); DECLARE_PER_CPU(unsigned int, cpu_pvr);
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
extern void migrate_irqs(void);
int generic_cpu_disable(void); int generic_cpu_disable(void);
void generic_cpu_die(unsigned int cpu); void generic_cpu_die(unsigned int cpu);
void generic_set_cpu_dead(unsigned int cpu); void generic_set_cpu_dead(unsigned int cpu);
...@@ -112,23 +113,31 @@ extern int cpu_to_core_id(int cpu); ...@@ -112,23 +113,31 @@ extern int cpu_to_core_id(int cpu);
* *
* Make sure this matches openpic_request_IPIs in open_pic.c, or what shows up * Make sure this matches openpic_request_IPIs in open_pic.c, or what shows up
* in /proc/interrupts will be wrong!!! --Troy */ * in /proc/interrupts will be wrong!!! --Troy */
#define PPC_MSG_CALL_FUNCTION 0 #define PPC_MSG_CALL_FUNCTION 0
#define PPC_MSG_RESCHEDULE 1 #define PPC_MSG_RESCHEDULE 1
#define PPC_MSG_TICK_BROADCAST 2 #define PPC_MSG_TICK_BROADCAST 2
#define PPC_MSG_DEBUGGER_BREAK 3 #define PPC_MSG_NMI_IPI 3
/* This is only used by the powernv kernel */ /* This is only used by the powernv kernel */
#define PPC_MSG_RM_HOST_ACTION 4 #define PPC_MSG_RM_HOST_ACTION 4
#define NMI_IPI_ALL_OTHERS -2
#ifdef CONFIG_NMI_IPI
extern int smp_handle_nmi_ipi(struct pt_regs *regs);
#else
static inline int smp_handle_nmi_ipi(struct pt_regs *regs) { return 0; }
#endif
/* for irq controllers that have dedicated ipis per message (4) */ /* for irq controllers that have dedicated ipis per message (4) */
extern int smp_request_message_ipi(int virq, int message); extern int smp_request_message_ipi(int virq, int message);
extern const char *smp_ipi_name[]; extern const char *smp_ipi_name[];
/* for irq controllers with only a single ipi */ /* for irq controllers with only a single ipi */
extern void smp_muxed_ipi_set_data(int cpu, unsigned long data);
extern void smp_muxed_ipi_message_pass(int cpu, int msg); extern void smp_muxed_ipi_message_pass(int cpu, int msg);
extern void smp_muxed_ipi_set_message(int cpu, int msg); extern void smp_muxed_ipi_set_message(int cpu, int msg);
extern irqreturn_t smp_ipi_demux(void); extern irqreturn_t smp_ipi_demux(void);
extern irqreturn_t smp_ipi_demux_relaxed(void);
void smp_init_pSeries(void); void smp_init_pSeries(void);
void smp_init_cell(void); void smp_init_cell(void);
......
...@@ -8,10 +8,10 @@ ...@@ -8,10 +8,10 @@
struct rtas_args; struct rtas_args;
asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, asmlinkage long sys_mmap(unsigned long addr, size_t len,
unsigned long prot, unsigned long flags, unsigned long prot, unsigned long flags,
unsigned long fd, off_t offset); unsigned long fd, off_t offset);
asmlinkage unsigned long sys_mmap2(unsigned long addr, size_t len, asmlinkage long sys_mmap2(unsigned long addr, size_t len,
unsigned long prot, unsigned long flags, unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff); unsigned long fd, unsigned long pgoff);
asmlinkage long ppc64_personality(unsigned long personality); asmlinkage long ppc64_personality(unsigned long personality);
......
...@@ -10,15 +10,7 @@ ...@@ -10,15 +10,7 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
/* We have 8k stacks on ppc32 and 16k on ppc64 */ #define THREAD_SHIFT CONFIG_THREAD_SHIFT
#if defined(CONFIG_PPC64)
#define THREAD_SHIFT 14
#elif defined(CONFIG_PPC_256K_PAGES)
#define THREAD_SHIFT 15
#else
#define THREAD_SHIFT 13
#endif
#define THREAD_SIZE (1 << THREAD_SHIFT) #define THREAD_SIZE (1 << THREAD_SHIFT)
......
...@@ -57,7 +57,7 @@ struct icp_ops { ...@@ -57,7 +57,7 @@ struct icp_ops {
void (*teardown_cpu)(void); void (*teardown_cpu)(void);
void (*flush_ipi)(void); void (*flush_ipi)(void);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
void (*cause_ipi)(int cpu, unsigned long data); void (*cause_ipi)(int cpu);
irq_handler_t ipi_action; irq_handler_t ipi_action;
#endif #endif
}; };
......
/*
* Copyright 2016,2017 IBM Corporation.
*
* 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.
*/
#ifndef _ASM_POWERPC_XIVE_REGS_H
#define _ASM_POWERPC_XIVE_REGS_H
/*
* Thread Management (aka "TM") registers
*/
/* TM register offsets */
#define TM_QW0_USER 0x000 /* All rings */
#define TM_QW1_OS 0x010 /* Ring 0..2 */
#define TM_QW2_HV_POOL 0x020 /* Ring 0..1 */
#define TM_QW3_HV_PHYS 0x030 /* Ring 0..1 */
/* Byte offsets inside a QW QW0 QW1 QW2 QW3 */
#define TM_NSR 0x0 /* + + - + */
#define TM_CPPR 0x1 /* - + - + */
#define TM_IPB 0x2 /* - + + + */
#define TM_LSMFB 0x3 /* - + + + */
#define TM_ACK_CNT 0x4 /* - + - - */
#define TM_INC 0x5 /* - + - + */
#define TM_AGE 0x6 /* - + - + */
#define TM_PIPR 0x7 /* - + - + */
#define TM_WORD0 0x0
#define TM_WORD1 0x4
/*
* QW word 2 contains the valid bit at the top and other fields
* depending on the QW.
*/
#define TM_WORD2 0x8
#define TM_QW0W2_VU PPC_BIT32(0)
#define TM_QW0W2_LOGIC_SERV PPC_BITMASK32(1,31) // XX 2,31 ?
#define TM_QW1W2_VO PPC_BIT32(0)
#define TM_QW1W2_OS_CAM PPC_BITMASK32(8,31)
#define TM_QW2W2_VP PPC_BIT32(0)
#define TM_QW2W2_POOL_CAM PPC_BITMASK32(8,31)
#define TM_QW3W2_VT PPC_BIT32(0)
#define TM_QW3W2_LP PPC_BIT32(6)
#define TM_QW3W2_LE PPC_BIT32(7)
#define TM_QW3W2_T PPC_BIT32(31)
/*
* In addition to normal loads to "peek" and writes (only when invalid)
* using 4 and 8 bytes accesses, the above registers support these
* "special" byte operations:
*
* - Byte load from QW0[NSR] - User level NSR (EBB)
* - Byte store to QW0[NSR] - User level NSR (EBB)
* - Byte load/store to QW1[CPPR] and QW3[CPPR] - CPPR access
* - Byte load from QW3[TM_WORD2] - Read VT||00000||LP||LE on thrd 0
* otherwise VT||0000000
* - Byte store to QW3[TM_WORD2] - Set VT bit (and LP/LE if present)
*
* Then we have all these "special" CI ops at these offset that trigger
* all sorts of side effects:
*/
#define TM_SPC_ACK_EBB 0x800 /* Load8 ack EBB to reg*/
#define TM_SPC_ACK_OS_REG 0x810 /* Load16 ack OS irq to reg */
#define TM_SPC_PUSH_USR_CTX 0x808 /* Store32 Push/Validate user context */
#define TM_SPC_PULL_USR_CTX 0x808 /* Load32 Pull/Invalidate user context */
#define TM_SPC_SET_OS_PENDING 0x812 /* Store8 Set OS irq pending bit */
#define TM_SPC_PULL_OS_CTX 0x818 /* Load32/Load64 Pull/Invalidate OS context to reg */
#define TM_SPC_PULL_POOL_CTX 0x828 /* Load32/Load64 Pull/Invalidate Pool context to reg*/
#define TM_SPC_ACK_HV_REG 0x830 /* Load16 ack HV irq to reg */
#define TM_SPC_PULL_USR_CTX_OL 0xc08 /* Store8 Pull/Inval usr ctx to odd line */
#define TM_SPC_ACK_OS_EL 0xc10 /* Store8 ack OS irq to even line */
#define TM_SPC_ACK_HV_POOL_EL 0xc20 /* Store8 ack HV evt pool to even line */
#define TM_SPC_ACK_HV_EL 0xc30 /* Store8 ack HV irq to even line */
/* XXX more... */
/* NSR fields for the various QW ack types */
#define TM_QW0_NSR_EB PPC_BIT8(0)
#define TM_QW1_NSR_EO PPC_BIT8(0)
#define TM_QW3_NSR_HE PPC_BITMASK8(0,1)
#define TM_QW3_NSR_HE_NONE 0
#define TM_QW3_NSR_HE_POOL 1
#define TM_QW3_NSR_HE_PHYS 2
#define TM_QW3_NSR_HE_LSI 3
#define TM_QW3_NSR_I PPC_BIT8(2)
#define TM_QW3_NSR_GRP_LVL PPC_BIT8(3,7)
/* Utilities to manipulate these (originaly from OPAL) */
#define MASK_TO_LSH(m) (__builtin_ffsl(m) - 1)
#define GETFIELD(m, v) (((v) & (m)) >> MASK_TO_LSH(m))
#define SETFIELD(m, v, val) \
(((v) & ~(m)) | ((((typeof(v))(val)) << MASK_TO_LSH(m)) & (m)))
#endif /* _ASM_POWERPC_XIVE_REGS_H */
/*
* Copyright 2016,2017 IBM Corporation.
*
* 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.
*/
#ifndef _ASM_POWERPC_XIVE_H
#define _ASM_POWERPC_XIVE_H
#define XIVE_INVALID_VP 0xffffffff
#ifdef CONFIG_PPC_XIVE
/*
* Thread Interrupt Management Area (TIMA)
*
* This is a global MMIO region divided in 4 pages of varying access
* permissions, providing access to per-cpu interrupt management
* functions. It always identifies the CPU doing the access based
* on the PowerBus initiator ID, thus we always access via the
* same offset regardless of where the code is executing
*/
extern void __iomem *xive_tima;
/*
* Offset in the TM area of our current execution level (provided by
* the backend)
*/
extern u32 xive_tima_offset;
/*
* Per-irq data (irq_get_handler_data for normal IRQs), IPIs
* have it stored in the xive_cpu structure. We also cache
* for normal interrupts the current target CPU.
*
* This structure is setup by the backend for each interrupt.
*/
struct xive_irq_data {
u64 flags;
u64 eoi_page;
void __iomem *eoi_mmio;
u64 trig_page;
void __iomem *trig_mmio;
u32 esb_shift;
int src_chip;
/* Setup/used by frontend */
int target;
bool saved_p;
};
#define XIVE_IRQ_FLAG_STORE_EOI 0x01
#define XIVE_IRQ_FLAG_LSI 0x02
#define XIVE_IRQ_FLAG_SHIFT_BUG 0x04
#define XIVE_IRQ_FLAG_MASK_FW 0x08
#define XIVE_IRQ_FLAG_EOI_FW 0x10
#define XIVE_INVALID_CHIP_ID -1
/* A queue tracking structure in a CPU */
struct xive_q {
__be32 *qpage;
u32 msk;
u32 idx;
u32 toggle;
u64 eoi_phys;
u32 esc_irq;
atomic_t count;
atomic_t pending_count;
};
/*
* "magic" Event State Buffer (ESB) MMIO offsets.
*
* Each interrupt source has a 2-bit state machine called ESB
* which can be controlled by MMIO. It's made of 2 bits, P and
* Q. P indicates that an interrupt is pending (has been sent
* to a queue and is waiting for an EOI). Q indicates that the
* interrupt has been triggered while pending.
*
* This acts as a coalescing mechanism in order to guarantee
* that a given interrupt only occurs at most once in a queue.
*
* When doing an EOI, the Q bit will indicate if the interrupt
* needs to be re-triggered.
*
* The following offsets into the ESB MMIO allow to read or
* manipulate the PQ bits. They must be used with an 8-bytes
* load instruction. They all return the previous state of the
* interrupt (atomically).
*
* Additionally, some ESB pages support doing an EOI via a
* store at 0 and some ESBs support doing a trigger via a
* separate trigger page.
*/
#define XIVE_ESB_GET 0x800
#define XIVE_ESB_SET_PQ_00 0xc00
#define XIVE_ESB_SET_PQ_01 0xd00
#define XIVE_ESB_SET_PQ_10 0xe00
#define XIVE_ESB_SET_PQ_11 0xf00
#define XIVE_ESB_MASK XIVE_ESB_SET_PQ_01
#define XIVE_ESB_VAL_P 0x2
#define XIVE_ESB_VAL_Q 0x1
/* Global enable flags for the XIVE support */
extern bool __xive_enabled;
static inline bool xive_enabled(void) { return __xive_enabled; }
extern bool xive_native_init(void);
extern void xive_smp_probe(void);
extern int xive_smp_prepare_cpu(unsigned int cpu);
extern void xive_smp_setup_cpu(void);
extern void xive_smp_disable_cpu(void);
extern void xive_kexec_teardown_cpu(int secondary);
extern void xive_shutdown(void);
extern void xive_flush_interrupt(void);
/* xmon hook */
extern void xmon_xive_do_dump(int cpu);
/* APIs used by KVM */
extern u32 xive_native_default_eq_shift(void);
extern u32 xive_native_alloc_vp_block(u32 max_vcpus);
extern void xive_native_free_vp_block(u32 vp_base);
extern int xive_native_populate_irq_data(u32 hw_irq,
struct xive_irq_data *data);
extern void xive_cleanup_irq_data(struct xive_irq_data *xd);
extern u32 xive_native_alloc_irq(void);
extern void xive_native_free_irq(u32 irq);
extern int xive_native_configure_irq(u32 hw_irq, u32 target, u8 prio, u32 sw_irq);
extern int xive_native_configure_queue(u32 vp_id, struct xive_q *q, u8 prio,
__be32 *qpage, u32 order, bool can_escalate);
extern void xive_native_disable_queue(u32 vp_id, struct xive_q *q, u8 prio);
extern bool __xive_irq_trigger(struct xive_irq_data *xd);
extern bool __xive_irq_retrigger(struct xive_irq_data *xd);
extern void xive_do_source_eoi(u32 hw_irq, struct xive_irq_data *xd);
extern bool is_xive_irq(struct irq_chip *chip);
#else
static inline bool xive_enabled(void) { return false; }
static inline bool xive_native_init(void) { return false; }
static inline void xive_smp_probe(void) { }
extern inline int xive_smp_prepare_cpu(unsigned int cpu) { return -EINVAL; }
static inline void xive_smp_setup_cpu(void) { }
static inline void xive_smp_disable_cpu(void) { }
static inline void xive_kexec_teardown_cpu(int secondary) { }
static inline void xive_shutdown(void) { }
static inline void xive_flush_interrupt(void) { }
static inline u32 xive_native_alloc_vp_block(u32 max_vcpus) { return XIVE_INVALID_VP; }
static inline void xive_native_free_vp_block(u32 vp_base) { }
#endif
#endif /* _ASM_POWERPC_XIVE_H */
...@@ -29,5 +29,7 @@ static inline void xmon_register_spus(struct list_head *list) { }; ...@@ -29,5 +29,7 @@ static inline void xmon_register_spus(struct list_head *list) { };
extern int cpus_are_in_xmon(void); extern int cpus_are_in_xmon(void);
#endif #endif
extern void xmon_printf(const char *format, ...);
#endif /* __KERNEL __ */ #endif /* __KERNEL __ */
#endif /* __ASM_POWERPC_XMON_H */ #endif /* __ASM_POWERPC_XMON_H */
...@@ -29,4 +29,20 @@ ...@@ -29,4 +29,20 @@
#define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */ #define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */
#define MAP_HUGETLB 0x40000 /* create a huge page mapping */ #define MAP_HUGETLB 0x40000 /* create a huge page mapping */
/*
* When MAP_HUGETLB is set, bits [26:31] of the flags argument to mmap(2),
* encode the log2 of the huge page size. A value of zero indicates that the
* default huge page size should be used. To use a non-default huge page size,
* one of these defines can be used, or the size can be encoded by hand. Note
* that on most systems only a subset, or possibly none, of these sizes will be
* available.
*/
#define MAP_HUGE_512KB (19 << MAP_HUGE_SHIFT) /* 512KB HugeTLB Page */
#define MAP_HUGE_1MB (20 << MAP_HUGE_SHIFT) /* 1MB HugeTLB Page */
#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT) /* 2MB HugeTLB Page */
#define MAP_HUGE_8MB (23 << MAP_HUGE_SHIFT) /* 8MB HugeTLB Page */
#define MAP_HUGE_16MB (24 << MAP_HUGE_SHIFT) /* 16MB HugeTLB Page */
#define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT) /* 1GB HugeTLB Page */
#define MAP_HUGE_16GB (34 << MAP_HUGE_SHIFT) /* 16GB HugeTLB Page */
#endif /* _UAPI_ASM_POWERPC_MMAN_H */ #endif /* _UAPI_ASM_POWERPC_MMAN_H */
...@@ -25,8 +25,6 @@ CFLAGS_REMOVE_cputable.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) ...@@ -25,8 +25,6 @@ CFLAGS_REMOVE_cputable.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_prom_init.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_prom_init.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_btext.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_btext.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_prom.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_prom.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
# do not trace tracer code
CFLAGS_REMOVE_ftrace.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
# timers used by tracing # timers used by tracing
CFLAGS_REMOVE_time.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_time.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
endif endif
...@@ -97,6 +95,7 @@ obj-$(CONFIG_BOOTX_TEXT) += btext.o ...@@ -97,6 +95,7 @@ obj-$(CONFIG_BOOTX_TEXT) += btext.o
obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_OPTPROBES) += optprobes.o optprobes_head.o obj-$(CONFIG_OPTPROBES) += optprobes.o optprobes_head.o
obj-$(CONFIG_KPROBES_ON_FTRACE) += kprobes-ftrace.o
obj-$(CONFIG_UPROBES) += uprobes.o obj-$(CONFIG_UPROBES) += uprobes.o
obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_STACKTRACE) += stacktrace.o
...@@ -118,10 +117,7 @@ obj64-$(CONFIG_AUDIT) += compat_audit.o ...@@ -118,10 +117,7 @@ obj64-$(CONFIG_AUDIT) += compat_audit.o
obj-$(CONFIG_PPC_IO_WORKAROUNDS) += io-workarounds.o obj-$(CONFIG_PPC_IO_WORKAROUNDS) += io-workarounds.o
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o obj-y += trace/
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
obj-$(CONFIG_TRACING) += trace_clock.o
ifneq ($(CONFIG_PPC_INDIRECT_PIO),y) ifneq ($(CONFIG_PPC_INDIRECT_PIO),y)
obj-y += iomap.o obj-y += iomap.o
...@@ -142,14 +138,14 @@ obj-$(CONFIG_KVM_GUEST) += kvm.o kvm_emul.o ...@@ -142,14 +138,14 @@ obj-$(CONFIG_KVM_GUEST) += kvm.o kvm_emul.o
# Disable GCOV & sanitizers in odd or sensitive code # Disable GCOV & sanitizers in odd or sensitive code
GCOV_PROFILE_prom_init.o := n GCOV_PROFILE_prom_init.o := n
UBSAN_SANITIZE_prom_init.o := n UBSAN_SANITIZE_prom_init.o := n
GCOV_PROFILE_ftrace.o := n
UBSAN_SANITIZE_ftrace.o := n
GCOV_PROFILE_machine_kexec_64.o := n GCOV_PROFILE_machine_kexec_64.o := n
UBSAN_SANITIZE_machine_kexec_64.o := n UBSAN_SANITIZE_machine_kexec_64.o := n
GCOV_PROFILE_machine_kexec_32.o := n GCOV_PROFILE_machine_kexec_32.o := n
UBSAN_SANITIZE_machine_kexec_32.o := n UBSAN_SANITIZE_machine_kexec_32.o := n
GCOV_PROFILE_kprobes.o := n GCOV_PROFILE_kprobes.o := n
UBSAN_SANITIZE_kprobes.o := n UBSAN_SANITIZE_kprobes.o := n
GCOV_PROFILE_kprobes-ftrace.o := n
UBSAN_SANITIZE_kprobes-ftrace.o := n
UBSAN_SANITIZE_vdso.o := n UBSAN_SANITIZE_vdso.o := n
extra-$(CONFIG_PPC_FPU) += fpu.o extra-$(CONFIG_PPC_FPU) += fpu.o
......
...@@ -185,6 +185,7 @@ int main(void) ...@@ -185,6 +185,7 @@ int main(void)
#ifdef CONFIG_PPC_MM_SLICES #ifdef CONFIG_PPC_MM_SLICES
OFFSET(PACALOWSLICESPSIZE, paca_struct, mm_ctx_low_slices_psize); OFFSET(PACALOWSLICESPSIZE, paca_struct, mm_ctx_low_slices_psize);
OFFSET(PACAHIGHSLICEPSIZE, paca_struct, mm_ctx_high_slices_psize); OFFSET(PACAHIGHSLICEPSIZE, paca_struct, mm_ctx_high_slices_psize);
DEFINE(PACA_ADDR_LIMIT, offsetof(struct paca_struct, addr_limit));
DEFINE(MMUPSIZEDEFSIZE, sizeof(struct mmu_psize_def)); DEFINE(MMUPSIZEDEFSIZE, sizeof(struct mmu_psize_def));
#endif /* CONFIG_PPC_MM_SLICES */ #endif /* CONFIG_PPC_MM_SLICES */
#endif #endif
...@@ -219,6 +220,7 @@ int main(void) ...@@ -219,6 +220,7 @@ int main(void)
OFFSET(PACA_EXGEN, paca_struct, exgen); OFFSET(PACA_EXGEN, paca_struct, exgen);
OFFSET(PACA_EXMC, paca_struct, exmc); OFFSET(PACA_EXMC, paca_struct, exmc);
OFFSET(PACA_EXSLB, paca_struct, exslb); OFFSET(PACA_EXSLB, paca_struct, exslb);
OFFSET(PACA_EXNMI, paca_struct, exnmi);
OFFSET(PACALPPACAPTR, paca_struct, lppaca_ptr); OFFSET(PACALPPACAPTR, paca_struct, lppaca_ptr);
OFFSET(PACA_SLBSHADOWPTR, paca_struct, slb_shadow_ptr); OFFSET(PACA_SLBSHADOWPTR, paca_struct, slb_shadow_ptr);
OFFSET(SLBSHADOW_STACKVSID, slb_shadow, save_area[SLB_NUM_BOLTED - 1].vsid); OFFSET(SLBSHADOW_STACKVSID, slb_shadow, save_area[SLB_NUM_BOLTED - 1].vsid);
...@@ -232,7 +234,9 @@ int main(void) ...@@ -232,7 +234,9 @@ int main(void)
OFFSET(PACAEMERGSP, paca_struct, emergency_sp); OFFSET(PACAEMERGSP, paca_struct, emergency_sp);
#ifdef CONFIG_PPC_BOOK3S_64 #ifdef CONFIG_PPC_BOOK3S_64
OFFSET(PACAMCEMERGSP, paca_struct, mc_emergency_sp); OFFSET(PACAMCEMERGSP, paca_struct, mc_emergency_sp);
OFFSET(PACA_NMI_EMERG_SP, paca_struct, nmi_emergency_sp);
OFFSET(PACA_IN_MCE, paca_struct, in_mce); OFFSET(PACA_IN_MCE, paca_struct, in_mce);
OFFSET(PACA_IN_NMI, paca_struct, in_nmi);
#endif #endif
OFFSET(PACAHWCPUID, paca_struct, hw_cpu_id); OFFSET(PACAHWCPUID, paca_struct, hw_cpu_id);
OFFSET(PACAKEXECSTATE, paca_struct, kexec_state); OFFSET(PACAKEXECSTATE, paca_struct, kexec_state);
...@@ -399,8 +403,8 @@ int main(void) ...@@ -399,8 +403,8 @@ int main(void)
DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry)); DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry));
#endif #endif
#ifdef MAX_PGD_TABLE_SIZE #ifdef CONFIG_PPC_BOOK3S_64
DEFINE(PGD_TABLE_SIZE, MAX_PGD_TABLE_SIZE); DEFINE(PGD_TABLE_SIZE, (sizeof(pgd_t) << max(RADIX_PGD_INDEX_SIZE, H_PGD_INDEX_SIZE)));
#else #else
DEFINE(PGD_TABLE_SIZE, PGD_TABLE_SIZE); DEFINE(PGD_TABLE_SIZE, PGD_TABLE_SIZE);
#endif #endif
...@@ -727,6 +731,7 @@ int main(void) ...@@ -727,6 +731,7 @@ int main(void)
OFFSET(PACA_THREAD_IDLE_STATE, paca_struct, thread_idle_state); OFFSET(PACA_THREAD_IDLE_STATE, paca_struct, thread_idle_state);
OFFSET(PACA_THREAD_MASK, paca_struct, thread_mask); OFFSET(PACA_THREAD_MASK, paca_struct, thread_mask);
OFFSET(PACA_SUBCORE_SIBLING_MASK, paca_struct, subcore_sibling_mask); OFFSET(PACA_SUBCORE_SIBLING_MASK, paca_struct, subcore_sibling_mask);
OFFSET(PACA_SIBLING_PACA_PTRS, paca_struct, thread_sibling_pacas);
#endif #endif
DEFINE(PPC_DBELL_SERVER, PPC_DBELL_SERVER); DEFINE(PPC_DBELL_SERVER, PPC_DBELL_SERVER);
......
...@@ -29,7 +29,8 @@ _GLOBAL(__setup_cpu_power7) ...@@ -29,7 +29,8 @@ _GLOBAL(__setup_cpu_power7)
li r0,0 li r0,0
mtspr SPRN_LPID,r0 mtspr SPRN_LPID,r0
mfspr r3,SPRN_LPCR mfspr r3,SPRN_LPCR
bl __init_LPCR li r4,(LPCR_LPES1 >> LPCR_LPES_SH)
bl __init_LPCR_ISA206
bl __init_tlb_power7 bl __init_tlb_power7
mtlr r11 mtlr r11
blr blr
...@@ -42,7 +43,8 @@ _GLOBAL(__restore_cpu_power7) ...@@ -42,7 +43,8 @@ _GLOBAL(__restore_cpu_power7)
li r0,0 li r0,0
mtspr SPRN_LPID,r0 mtspr SPRN_LPID,r0
mfspr r3,SPRN_LPCR mfspr r3,SPRN_LPCR
bl __init_LPCR li r4,(LPCR_LPES1 >> LPCR_LPES_SH)
bl __init_LPCR_ISA206
bl __init_tlb_power7 bl __init_tlb_power7
mtlr r11 mtlr r11
blr blr
...@@ -59,7 +61,8 @@ _GLOBAL(__setup_cpu_power8) ...@@ -59,7 +61,8 @@ _GLOBAL(__setup_cpu_power8)
mtspr SPRN_LPID,r0 mtspr SPRN_LPID,r0
mfspr r3,SPRN_LPCR mfspr r3,SPRN_LPCR
ori r3, r3, LPCR_PECEDH ori r3, r3, LPCR_PECEDH
bl __init_LPCR li r4,0 /* LPES = 0 */
bl __init_LPCR_ISA206
bl __init_HFSCR bl __init_HFSCR
bl __init_tlb_power8 bl __init_tlb_power8
bl __init_PMU_HV bl __init_PMU_HV
...@@ -80,7 +83,8 @@ _GLOBAL(__restore_cpu_power8) ...@@ -80,7 +83,8 @@ _GLOBAL(__restore_cpu_power8)
mtspr SPRN_LPID,r0 mtspr SPRN_LPID,r0
mfspr r3,SPRN_LPCR mfspr r3,SPRN_LPCR
ori r3, r3, LPCR_PECEDH ori r3, r3, LPCR_PECEDH
bl __init_LPCR li r4,0 /* LPES = 0 */
bl __init_LPCR_ISA206
bl __init_HFSCR bl __init_HFSCR
bl __init_tlb_power8 bl __init_tlb_power8
bl __init_PMU_HV bl __init_PMU_HV
...@@ -99,11 +103,12 @@ _GLOBAL(__setup_cpu_power9) ...@@ -99,11 +103,12 @@ _GLOBAL(__setup_cpu_power9)
mtspr SPRN_PSSCR,r0 mtspr SPRN_PSSCR,r0
mtspr SPRN_LPID,r0 mtspr SPRN_LPID,r0
mfspr r3,SPRN_LPCR mfspr r3,SPRN_LPCR
LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE) LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE | LPCR_HEIC)
or r3, r3, r4 or r3, r3, r4
LOAD_REG_IMMEDIATE(r4, LPCR_UPRT | LPCR_HR) LOAD_REG_IMMEDIATE(r4, LPCR_UPRT | LPCR_HR)
andc r3, r3, r4 andc r3, r3, r4
bl __init_LPCR li r4,0 /* LPES = 0 */
bl __init_LPCR_ISA300
bl __init_HFSCR bl __init_HFSCR
bl __init_tlb_power9 bl __init_tlb_power9
bl __init_PMU_HV bl __init_PMU_HV
...@@ -122,11 +127,12 @@ _GLOBAL(__restore_cpu_power9) ...@@ -122,11 +127,12 @@ _GLOBAL(__restore_cpu_power9)
mtspr SPRN_PSSCR,r0 mtspr SPRN_PSSCR,r0
mtspr SPRN_LPID,r0 mtspr SPRN_LPID,r0
mfspr r3,SPRN_LPCR mfspr r3,SPRN_LPCR
LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE) LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE | LPCR_HEIC)
or r3, r3, r4 or r3, r3, r4
LOAD_REG_IMMEDIATE(r4, LPCR_UPRT | LPCR_HR) LOAD_REG_IMMEDIATE(r4, LPCR_UPRT | LPCR_HR)
andc r3, r3, r4 andc r3, r3, r4
bl __init_LPCR li r4,0 /* LPES = 0 */
bl __init_LPCR_ISA300
bl __init_HFSCR bl __init_HFSCR
bl __init_tlb_power9 bl __init_tlb_power9
bl __init_PMU_HV bl __init_PMU_HV
...@@ -144,9 +150,9 @@ __init_hvmode_206: ...@@ -144,9 +150,9 @@ __init_hvmode_206:
std r5,CPU_SPEC_FEATURES(r4) std r5,CPU_SPEC_FEATURES(r4)
blr blr
__init_LPCR: __init_LPCR_ISA206:
/* Setup a sane LPCR: /* Setup a sane LPCR:
* Called with initial LPCR in R3 * Called with initial LPCR in R3 and desired LPES 2-bit value in R4
* *
* LPES = 0b01 (HSRR0/1 used for 0x500) * LPES = 0b01 (HSRR0/1 used for 0x500)
* PECE = 0b111 * PECE = 0b111
...@@ -157,16 +163,18 @@ __init_LPCR: ...@@ -157,16 +163,18 @@ __init_LPCR:
* *
* Other bits untouched for now * Other bits untouched for now
*/ */
li r5,1 li r5,0x10
rldimi r3,r5, LPCR_LPES_SH, 64-LPCR_LPES_SH-2 rldimi r3,r5, LPCR_VRMASD_SH, 64-LPCR_VRMASD_SH-5
/* POWER9 has no VRMASD */
__init_LPCR_ISA300:
rldimi r3,r4, LPCR_LPES_SH, 64-LPCR_LPES_SH-2
ori r3,r3,(LPCR_PECE0|LPCR_PECE1|LPCR_PECE2) ori r3,r3,(LPCR_PECE0|LPCR_PECE1|LPCR_PECE2)
li r5,4 li r5,4
rldimi r3,r5, LPCR_DPFD_SH, 64-LPCR_DPFD_SH-3 rldimi r3,r5, LPCR_DPFD_SH, 64-LPCR_DPFD_SH-3
clrrdi r3,r3,1 /* clear HDICE */ clrrdi r3,r3,1 /* clear HDICE */
li r5,4 li r5,4
rldimi r3,r5, LPCR_VC_SH, 0 rldimi r3,r5, LPCR_VC_SH, 0
li r5,0x10
rldimi r3,r5, LPCR_VRMASD_SH, 64-LPCR_VRMASD_SH-5
mtspr SPRN_LPCR,r3 mtspr SPRN_LPCR,r3
isync isync
blr blr
......
...@@ -20,18 +20,60 @@ ...@@ -20,18 +20,60 @@
#include <asm/kvm_ppc.h> #include <asm/kvm_ppc.h>
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
void doorbell_setup_this_cpu(void)
/*
* Doorbells must only be used if CPU_FTR_DBELL is available.
* msgsnd is used in HV, and msgsndp is used in !HV.
*
* These should be used by platform code that is aware of restrictions.
* Other arch code should use ->cause_ipi.
*
* doorbell_global_ipi() sends a dbell to any target CPU.
* Must be used only by architectures that address msgsnd target
* by PIR/get_hard_smp_processor_id.
*/
void doorbell_global_ipi(int cpu)
{ {
unsigned long tag = mfspr(SPRN_DOORBELL_CPUTAG) & PPC_DBELL_TAG_MASK; u32 tag = get_hard_smp_processor_id(cpu);
smp_muxed_ipi_set_data(smp_processor_id(), tag); kvmppc_set_host_ipi(cpu, 1);
/* Order previous accesses vs. msgsnd, which is treated as a store */
ppc_msgsnd_sync();
ppc_msgsnd(PPC_DBELL_MSGTYPE, 0, tag);
} }
void doorbell_cause_ipi(int cpu, unsigned long data) /*
* doorbell_core_ipi() sends a dbell to a target CPU in the same core.
* Must be used only by architectures that address msgsnd target
* by TIR/cpu_thread_in_core.
*/
void doorbell_core_ipi(int cpu)
{ {
u32 tag = cpu_thread_in_core(cpu);
kvmppc_set_host_ipi(cpu, 1);
/* Order previous accesses vs. msgsnd, which is treated as a store */ /* Order previous accesses vs. msgsnd, which is treated as a store */
mb(); ppc_msgsnd_sync();
ppc_msgsnd(PPC_DBELL_MSGTYPE, 0, data); ppc_msgsnd(PPC_DBELL_MSGTYPE, 0, tag);
}
/*
* Attempt to cause a core doorbell if destination is on the same core.
* Returns 1 on success, 0 on failure.
*/
int doorbell_try_core_ipi(int cpu)
{
int this_cpu = get_cpu();
int ret = 0;
if (cpumask_test_cpu(cpu, cpu_sibling_mask(this_cpu))) {
doorbell_core_ipi(cpu);
ret = 1;
}
put_cpu();
return ret;
} }
void doorbell_exception(struct pt_regs *regs) void doorbell_exception(struct pt_regs *regs)
...@@ -40,12 +82,14 @@ void doorbell_exception(struct pt_regs *regs) ...@@ -40,12 +82,14 @@ void doorbell_exception(struct pt_regs *regs)
irq_enter(); irq_enter();
ppc_msgsync();
may_hard_irq_enable(); may_hard_irq_enable();
kvmppc_set_host_ipi(smp_processor_id(), 0); kvmppc_set_host_ipi(smp_processor_id(), 0);
__this_cpu_inc(irq_stat.doorbell_irqs); __this_cpu_inc(irq_stat.doorbell_irqs);
smp_ipi_demux(); smp_ipi_demux_relaxed(); /* already performed the barrier */
irq_exit(); irq_exit();
set_irq_regs(old_regs); set_irq_regs(old_regs);
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
*/ */
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/debugfs.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/list.h> #include <linux/list.h>
...@@ -37,7 +36,7 @@ ...@@ -37,7 +36,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/atomic.h> #include <linux/atomic.h>
#include <asm/debug.h> #include <asm/debugfs.h>
#include <asm/eeh.h> #include <asm/eeh.h>
#include <asm/eeh_event.h> #include <asm/eeh_event.h>
#include <asm/io.h> #include <asm/io.h>
......
...@@ -724,7 +724,16 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus, ...@@ -724,7 +724,16 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus,
*/ */
#define MAX_WAIT_FOR_RECOVERY 300 #define MAX_WAIT_FOR_RECOVERY 300
static void eeh_handle_normal_event(struct eeh_pe *pe) /**
* eeh_handle_normal_event - Handle EEH events on a specific PE
* @pe: EEH PE
*
* Attempts to recover the given PE. If recovery fails or the PE has failed
* too many times, remove the PE.
*
* Returns true if @pe should no longer be used, else false.
*/
static bool eeh_handle_normal_event(struct eeh_pe *pe)
{ {
struct pci_bus *frozen_bus; struct pci_bus *frozen_bus;
struct eeh_dev *edev, *tmp; struct eeh_dev *edev, *tmp;
...@@ -736,13 +745,18 @@ static void eeh_handle_normal_event(struct eeh_pe *pe) ...@@ -736,13 +745,18 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
if (!frozen_bus) { if (!frozen_bus) {
pr_err("%s: Cannot find PCI bus for PHB#%x-PE#%x\n", pr_err("%s: Cannot find PCI bus for PHB#%x-PE#%x\n",
__func__, pe->phb->global_number, pe->addr); __func__, pe->phb->global_number, pe->addr);
return; return false;
} }
eeh_pe_update_time_stamp(pe); eeh_pe_update_time_stamp(pe);
pe->freeze_count++; pe->freeze_count++;
if (pe->freeze_count > eeh_max_freezes) if (pe->freeze_count > eeh_max_freezes) {
goto excess_failures; pr_err("EEH: PHB#%x-PE#%x has failed %d times in the\n"
"last hour and has been permanently disabled.\n",
pe->phb->global_number, pe->addr,
pe->freeze_count);
goto hard_fail;
}
pr_warn("EEH: This PCI device has failed %d times in the last hour\n", pr_warn("EEH: This PCI device has failed %d times in the last hour\n",
pe->freeze_count); pe->freeze_count);
...@@ -870,27 +884,18 @@ static void eeh_handle_normal_event(struct eeh_pe *pe) ...@@ -870,27 +884,18 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
pr_info("EEH: Notify device driver to resume\n"); pr_info("EEH: Notify device driver to resume\n");
eeh_pe_dev_traverse(pe, eeh_report_resume, NULL); eeh_pe_dev_traverse(pe, eeh_report_resume, NULL);
return; return false;
excess_failures: hard_fail:
/* /*
* About 90% of all real-life EEH failures in the field * About 90% of all real-life EEH failures in the field
* are due to poorly seated PCI cards. Only 10% or so are * are due to poorly seated PCI cards. Only 10% or so are
* due to actual, failed cards. * due to actual, failed cards.
*/ */
pr_err("EEH: PHB#%x-PE#%x has failed %d times in the\n"
"last hour and has been permanently disabled.\n"
"Please try reseating or replacing it.\n",
pe->phb->global_number, pe->addr,
pe->freeze_count);
goto perm_error;
hard_fail:
pr_err("EEH: Unable to recover from failure from PHB#%x-PE#%x.\n" pr_err("EEH: Unable to recover from failure from PHB#%x-PE#%x.\n"
"Please try reseating or replacing it\n", "Please try reseating or replacing it\n",
pe->phb->global_number, pe->addr); pe->phb->global_number, pe->addr);
perm_error:
eeh_slot_error_detail(pe, EEH_LOG_PERM); eeh_slot_error_detail(pe, EEH_LOG_PERM);
/* Notify all devices that they're about to go down. */ /* Notify all devices that they're about to go down. */
...@@ -915,10 +920,21 @@ static void eeh_handle_normal_event(struct eeh_pe *pe) ...@@ -915,10 +920,21 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
pci_lock_rescan_remove(); pci_lock_rescan_remove();
pci_hp_remove_devices(frozen_bus); pci_hp_remove_devices(frozen_bus);
pci_unlock_rescan_remove(); pci_unlock_rescan_remove();
/* The passed PE should no longer be used */
return true;
} }
} }
return false;
} }
/**
* eeh_handle_special_event - Handle EEH events without a specific failing PE
*
* Called when an EEH event is detected but can't be narrowed down to a
* specific PE. Iterates through possible failures and handles them as
* necessary.
*/
static void eeh_handle_special_event(void) static void eeh_handle_special_event(void)
{ {
struct eeh_pe *pe, *phb_pe; struct eeh_pe *pe, *phb_pe;
...@@ -982,7 +998,14 @@ static void eeh_handle_special_event(void) ...@@ -982,7 +998,14 @@ static void eeh_handle_special_event(void)
*/ */
if (rc == EEH_NEXT_ERR_FROZEN_PE || if (rc == EEH_NEXT_ERR_FROZEN_PE ||
rc == EEH_NEXT_ERR_FENCED_PHB) { rc == EEH_NEXT_ERR_FENCED_PHB) {
eeh_handle_normal_event(pe); /*
* eeh_handle_normal_event() can make the PE stale if it
* determines that the PE cannot possibly be recovered.
* Don't modify the PE state if that's the case.
*/
if (eeh_handle_normal_event(pe))
continue;
eeh_pe_state_clear(pe, EEH_PE_RECOVERING); eeh_pe_state_clear(pe, EEH_PE_RECOVERING);
} else { } else {
pci_lock_rescan_remove(); pci_lock_rescan_remove();
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
#include <asm/ppc_asm.h> #include <asm/ppc_asm.h>
#include <asm/asm-offsets.h> #include <asm/asm-offsets.h>
#include <asm/unistd.h> #include <asm/unistd.h>
#include <asm/ftrace.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/export.h> #include <asm/export.h>
...@@ -1315,109 +1314,3 @@ machine_check_in_rtas: ...@@ -1315,109 +1314,3 @@ machine_check_in_rtas:
/* XXX load up BATs and panic */ /* XXX load up BATs and panic */
#endif /* CONFIG_PPC_RTAS */ #endif /* CONFIG_PPC_RTAS */
#ifdef CONFIG_FUNCTION_TRACER
#ifdef CONFIG_DYNAMIC_FTRACE
_GLOBAL(mcount)
_GLOBAL(_mcount)
/*
* It is required that _mcount on PPC32 must preserve the
* link register. But we have r0 to play with. We use r0
* to push the return address back to the caller of mcount
* into the ctr register, restore the link register and
* then jump back using the ctr register.
*/
mflr r0
mtctr r0
lwz r0, 4(r1)
mtlr r0
bctr
_GLOBAL(ftrace_caller)
MCOUNT_SAVE_FRAME
/* r3 ends up with link register */
subi r3, r3, MCOUNT_INSN_SIZE
.globl ftrace_call
ftrace_call:
bl ftrace_stub
nop
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
.globl ftrace_graph_call
ftrace_graph_call:
b ftrace_graph_stub
_GLOBAL(ftrace_graph_stub)
#endif
MCOUNT_RESTORE_FRAME
/* old link register ends up in ctr reg */
bctr
#else
_GLOBAL(mcount)
_GLOBAL(_mcount)
MCOUNT_SAVE_FRAME
subi r3, r3, MCOUNT_INSN_SIZE
LOAD_REG_ADDR(r5, ftrace_trace_function)
lwz r5,0(r5)
mtctr r5
bctrl
nop
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
b ftrace_graph_caller
#endif
MCOUNT_RESTORE_FRAME
bctr
#endif
EXPORT_SYMBOL(_mcount)
_GLOBAL(ftrace_stub)
blr
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
_GLOBAL(ftrace_graph_caller)
/* load r4 with local address */
lwz r4, 44(r1)
subi r4, r4, MCOUNT_INSN_SIZE
/* Grab the LR out of the caller stack frame */
lwz r3,52(r1)
bl prepare_ftrace_return
nop
/*
* prepare_ftrace_return gives us the address we divert to.
* Change the LR in the callers stack frame to this.
*/
stw r3,52(r1)
MCOUNT_RESTORE_FRAME
/* old link register ends up in ctr reg */
bctr
_GLOBAL(return_to_handler)
/* need to save return values */
stwu r1, -32(r1)
stw r3, 20(r1)
stw r4, 16(r1)
stw r31, 12(r1)
mr r31, r1
bl ftrace_return_to_handler
nop
/* return value has real return address */
mtlr r3
lwz r3, 20(r1)
lwz r4, 16(r1)
lwz r31,12(r1)
lwz r1, 0(r1)
/* Jump back to real return address */
blr
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
#endif /* CONFIG_FUNCTION_TRACER */
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/magic.h>
#include <asm/unistd.h> #include <asm/unistd.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/page.h> #include <asm/page.h>
...@@ -33,7 +32,6 @@ ...@@ -33,7 +32,6 @@
#include <asm/bug.h> #include <asm/bug.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/irqflags.h> #include <asm/irqflags.h>
#include <asm/ftrace.h>
#include <asm/hw_irq.h> #include <asm/hw_irq.h>
#include <asm/context_tracking.h> #include <asm/context_tracking.h>
#include <asm/tm.h> #include <asm/tm.h>
...@@ -1173,381 +1171,3 @@ _GLOBAL(enter_prom) ...@@ -1173,381 +1171,3 @@ _GLOBAL(enter_prom)
ld r0,16(r1) ld r0,16(r1)
mtlr r0 mtlr r0
blr blr
#ifdef CONFIG_FUNCTION_TRACER
#ifdef CONFIG_DYNAMIC_FTRACE
_GLOBAL(mcount)
_GLOBAL(_mcount)
EXPORT_SYMBOL(_mcount)
mflr r12
mtctr r12
mtlr r0
bctr
#ifndef CC_USING_MPROFILE_KERNEL
_GLOBAL_TOC(ftrace_caller)
/* Taken from output of objdump from lib64/glibc */
mflr r3
ld r11, 0(r1)
stdu r1, -112(r1)
std r3, 128(r1)
ld r4, 16(r11)
subi r3, r3, MCOUNT_INSN_SIZE
.globl ftrace_call
ftrace_call:
bl ftrace_stub
nop
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
.globl ftrace_graph_call
ftrace_graph_call:
b ftrace_graph_stub
_GLOBAL(ftrace_graph_stub)
#endif
ld r0, 128(r1)
mtlr r0
addi r1, r1, 112
#else /* CC_USING_MPROFILE_KERNEL */
/*
*
* ftrace_caller() is the function that replaces _mcount() when ftrace is
* active.
*
* We arrive here after a function A calls function B, and we are the trace
* function for B. When we enter r1 points to A's stack frame, B has not yet
* had a chance to allocate one yet.
*
* Additionally r2 may point either to the TOC for A, or B, depending on
* whether B did a TOC setup sequence before calling us.
*
* On entry the LR points back to the _mcount() call site, and r0 holds the
* saved LR as it was on entry to B, ie. the original return address at the
* call site in A.
*
* Our job is to save the register state into a struct pt_regs (on the stack)
* and then arrange for the ftrace function to be called.
*/
_GLOBAL(ftrace_caller)
/* Save the original return address in A's stack frame */
std r0,LRSAVE(r1)
/* Create our stack frame + pt_regs */
stdu r1,-SWITCH_FRAME_SIZE(r1)
/* Save all gprs to pt_regs */
SAVE_8GPRS(0,r1)
SAVE_8GPRS(8,r1)
SAVE_8GPRS(16,r1)
SAVE_8GPRS(24,r1)
/* Load special regs for save below */
mfmsr r8
mfctr r9
mfxer r10
mfcr r11
/* Get the _mcount() call site out of LR */
mflr r7
/* Save it as pt_regs->nip & pt_regs->link */
std r7, _NIP(r1)
std r7, _LINK(r1)
/* Save callee's TOC in the ABI compliant location */
std r2, 24(r1)
ld r2,PACATOC(r13) /* get kernel TOC in r2 */
addis r3,r2,function_trace_op@toc@ha
addi r3,r3,function_trace_op@toc@l
ld r5,0(r3)
#ifdef CONFIG_LIVEPATCH
mr r14,r7 /* remember old NIP */
#endif
/* Calculate ip from nip-4 into r3 for call below */
subi r3, r7, MCOUNT_INSN_SIZE
/* Put the original return address in r4 as parent_ip */
mr r4, r0
/* Save special regs */
std r8, _MSR(r1)
std r9, _CTR(r1)
std r10, _XER(r1)
std r11, _CCR(r1)
/* Load &pt_regs in r6 for call below */
addi r6, r1 ,STACK_FRAME_OVERHEAD
/* ftrace_call(r3, r4, r5, r6) */
.globl ftrace_call
ftrace_call:
bl ftrace_stub
nop
/* Load ctr with the possibly modified NIP */
ld r3, _NIP(r1)
mtctr r3
#ifdef CONFIG_LIVEPATCH
cmpd r14,r3 /* has NIP been altered? */
#endif
/* Restore gprs */
REST_8GPRS(0,r1)
REST_8GPRS(8,r1)
REST_8GPRS(16,r1)
REST_8GPRS(24,r1)
/* Restore callee's TOC */
ld r2, 24(r1)
/* Pop our stack frame */
addi r1, r1, SWITCH_FRAME_SIZE
/* Restore original LR for return to B */
ld r0, LRSAVE(r1)
mtlr r0
#ifdef CONFIG_LIVEPATCH
/* Based on the cmpd above, if the NIP was altered handle livepatch */
bne- livepatch_handler
#endif
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
stdu r1, -112(r1)
.globl ftrace_graph_call
ftrace_graph_call:
b ftrace_graph_stub
_GLOBAL(ftrace_graph_stub)
addi r1, r1, 112
#endif
ld r0,LRSAVE(r1) /* restore callee's lr at _mcount site */
mtlr r0
bctr /* jump after _mcount site */
#endif /* CC_USING_MPROFILE_KERNEL */
_GLOBAL(ftrace_stub)
blr
#ifdef CONFIG_LIVEPATCH
/*
* This function runs in the mcount context, between two functions. As
* such it can only clobber registers which are volatile and used in
* function linkage.
*
* We get here when a function A, calls another function B, but B has
* been live patched with a new function C.
*
* On entry:
* - we have no stack frame and can not allocate one
* - LR points back to the original caller (in A)
* - CTR holds the new NIP in C
* - r0 & r12 are free
*
* r0 can't be used as the base register for a DS-form load or store, so
* we temporarily shuffle r1 (stack pointer) into r0 and then put it back.
*/
livepatch_handler:
CURRENT_THREAD_INFO(r12, r1)
/* Save stack pointer into r0 */
mr r0, r1
/* Allocate 3 x 8 bytes */
ld r1, TI_livepatch_sp(r12)
addi r1, r1, 24
std r1, TI_livepatch_sp(r12)
/* Save toc & real LR on livepatch stack */
std r2, -24(r1)
mflr r12
std r12, -16(r1)
/* Store stack end marker */
lis r12, STACK_END_MAGIC@h
ori r12, r12, STACK_END_MAGIC@l
std r12, -8(r1)
/* Restore real stack pointer */
mr r1, r0
/* Put ctr in r12 for global entry and branch there */
mfctr r12
bctrl
/*
* Now we are returning from the patched function to the original
* caller A. We are free to use r0 and r12, and we can use r2 until we
* restore it.
*/
CURRENT_THREAD_INFO(r12, r1)
/* Save stack pointer into r0 */
mr r0, r1
ld r1, TI_livepatch_sp(r12)
/* Check stack marker hasn't been trashed */
lis r2, STACK_END_MAGIC@h
ori r2, r2, STACK_END_MAGIC@l
ld r12, -8(r1)
1: tdne r12, r2
EMIT_BUG_ENTRY 1b, __FILE__, __LINE__ - 1, 0
/* Restore LR & toc from livepatch stack */
ld r12, -16(r1)
mtlr r12
ld r2, -24(r1)
/* Pop livepatch stack frame */
CURRENT_THREAD_INFO(r12, r0)
subi r1, r1, 24
std r1, TI_livepatch_sp(r12)
/* Restore real stack pointer */
mr r1, r0
/* Return to original caller of live patched function */
blr
#endif
#else
_GLOBAL_TOC(_mcount)
EXPORT_SYMBOL(_mcount)
/* Taken from output of objdump from lib64/glibc */
mflr r3
ld r11, 0(r1)
stdu r1, -112(r1)
std r3, 128(r1)
ld r4, 16(r11)
subi r3, r3, MCOUNT_INSN_SIZE
LOAD_REG_ADDR(r5,ftrace_trace_function)
ld r5,0(r5)
ld r5,0(r5)
mtctr r5
bctrl
nop
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
b ftrace_graph_caller
#endif
ld r0, 128(r1)
mtlr r0
addi r1, r1, 112
_GLOBAL(ftrace_stub)
blr
#endif /* CONFIG_DYNAMIC_FTRACE */
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
#ifndef CC_USING_MPROFILE_KERNEL
_GLOBAL(ftrace_graph_caller)
/* load r4 with local address */
ld r4, 128(r1)
subi r4, r4, MCOUNT_INSN_SIZE
/* Grab the LR out of the caller stack frame */
ld r11, 112(r1)
ld r3, 16(r11)
bl prepare_ftrace_return
nop
/*
* prepare_ftrace_return gives us the address we divert to.
* Change the LR in the callers stack frame to this.
*/
ld r11, 112(r1)
std r3, 16(r11)
ld r0, 128(r1)
mtlr r0
addi r1, r1, 112
blr
#else /* CC_USING_MPROFILE_KERNEL */
_GLOBAL(ftrace_graph_caller)
/* with -mprofile-kernel, parameter regs are still alive at _mcount */
std r10, 104(r1)
std r9, 96(r1)
std r8, 88(r1)
std r7, 80(r1)
std r6, 72(r1)
std r5, 64(r1)
std r4, 56(r1)
std r3, 48(r1)
/* Save callee's TOC in the ABI compliant location */
std r2, 24(r1)
ld r2, PACATOC(r13) /* get kernel TOC in r2 */
mfctr r4 /* ftrace_caller has moved local addr here */
std r4, 40(r1)
mflr r3 /* ftrace_caller has restored LR from stack */
subi r4, r4, MCOUNT_INSN_SIZE
bl prepare_ftrace_return
nop
/*
* prepare_ftrace_return gives us the address we divert to.
* Change the LR to this.
*/
mtlr r3
ld r0, 40(r1)
mtctr r0
ld r10, 104(r1)
ld r9, 96(r1)
ld r8, 88(r1)
ld r7, 80(r1)
ld r6, 72(r1)
ld r5, 64(r1)
ld r4, 56(r1)
ld r3, 48(r1)
/* Restore callee's TOC */
ld r2, 24(r1)
addi r1, r1, 112
mflr r0
std r0, LRSAVE(r1)
bctr
#endif /* CC_USING_MPROFILE_KERNEL */
_GLOBAL(return_to_handler)
/* need to save return values */
std r4, -32(r1)
std r3, -24(r1)
/* save TOC */
std r2, -16(r1)
std r31, -8(r1)
mr r31, r1
stdu r1, -112(r1)
/*
* We might be called from a module.
* Switch to our TOC to run inside the core kernel.
*/
ld r2, PACATOC(r13)
bl ftrace_return_to_handler
nop
/* return value has real return address */
mtlr r3
ld r1, 0(r1)
ld r4, -32(r1)
ld r3, -24(r1)
ld r2, -16(r1)
ld r31, -8(r1)
/* Jump back to real return address */
blr
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
#endif /* CONFIG_FUNCTION_TRACER */
...@@ -116,9 +116,11 @@ EXC_VIRT_NONE(0x4000, 0x100) ...@@ -116,9 +116,11 @@ EXC_VIRT_NONE(0x4000, 0x100)
EXC_REAL_BEGIN(system_reset, 0x100, 0x100) EXC_REAL_BEGIN(system_reset, 0x100, 0x100)
SET_SCRATCH0(r13) SET_SCRATCH0(r13)
GET_PACA(r13) /*
clrrdi r13,r13,1 /* Last bit of HSPRG0 is set if waking from winkle */ * MSR_RI is not enabled, because PACA_EXNMI and nmi stack is
EXCEPTION_PROLOG_PSERIES_PACA(PACA_EXGEN, system_reset_common, EXC_STD, * being used, so a nested NMI exception would corrupt it.
*/
EXCEPTION_PROLOG_PSERIES_NORI(PACA_EXNMI, system_reset_common, EXC_STD,
IDLETEST, 0x100) IDLETEST, 0x100)
EXC_REAL_END(system_reset, 0x100, 0x100) EXC_REAL_END(system_reset, 0x100, 0x100)
...@@ -126,34 +128,37 @@ EXC_VIRT_NONE(0x4100, 0x100) ...@@ -126,34 +128,37 @@ EXC_VIRT_NONE(0x4100, 0x100)
#ifdef CONFIG_PPC_P7_NAP #ifdef CONFIG_PPC_P7_NAP
EXC_COMMON_BEGIN(system_reset_idle_common) EXC_COMMON_BEGIN(system_reset_idle_common)
BEGIN_FTR_SECTION b pnv_powersave_wakeup
GET_PACA(r13) /* Restore HSPRG0 to get the winkle bit in r13 */ #endif
END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300)
bl pnv_restore_hyp_resource
li r0,PNV_THREAD_RUNNING EXC_COMMON_BEGIN(system_reset_common)
stb r0,PACA_THREAD_IDLE_STATE(r13) /* Clear thread state */ /*
* Increment paca->in_nmi then enable MSR_RI. SLB or MCE will be able
* to recover, but nested NMI will notice in_nmi and not recover
* because of the use of the NMI stack. in_nmi reentrancy is tested in
* system_reset_exception.
*/
lhz r10,PACA_IN_NMI(r13)
addi r10,r10,1
sth r10,PACA_IN_NMI(r13)
li r10,MSR_RI
mtmsrd r10,1
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE mr r10,r1
li r0,KVM_HWTHREAD_IN_KERNEL ld r1,PACA_NMI_EMERG_SP(r13)
stb r0,HSTATE_HWTHREAD_STATE(r13) subi r1,r1,INT_FRAME_SIZE
/* Order setting hwthread_state vs. testing hwthread_req */ EXCEPTION_COMMON_NORET_STACK(PACA_EXNMI, 0x100,
sync system_reset, system_reset_exception,
lbz r0,HSTATE_HWTHREAD_REQ(r13) ADD_NVGPRS;ADD_RECONCILE)
cmpwi r0,0
beq 1f
BRANCH_TO_KVM(r10, kvm_start_guest)
1:
#endif
/* Return SRR1 from power7_nap() */ /*
mfspr r3,SPRN_SRR1 * The stack is no longer in use, decrement in_nmi.
blt cr3,2f */
b pnv_wakeup_loss lhz r10,PACA_IN_NMI(r13)
2: b pnv_wakeup_noloss subi r10,r10,1
#endif sth r10,PACA_IN_NMI(r13)
EXC_COMMON(system_reset_common, 0x100, system_reset_exception) b ret_from_except
#ifdef CONFIG_PPC_PSERIES #ifdef CONFIG_PPC_PSERIES
/* /*
...@@ -161,8 +166,9 @@ EXC_COMMON(system_reset_common, 0x100, system_reset_exception) ...@@ -161,8 +166,9 @@ EXC_COMMON(system_reset_common, 0x100, system_reset_exception)
*/ */
TRAMP_REAL_BEGIN(system_reset_fwnmi) TRAMP_REAL_BEGIN(system_reset_fwnmi)
SET_SCRATCH0(r13) /* save r13 */ SET_SCRATCH0(r13) /* save r13 */
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD, /* See comment at system_reset exception */
NOTEST, 0x100) EXCEPTION_PROLOG_PSERIES_NORI(PACA_EXNMI, system_reset_common,
EXC_STD, NOTEST, 0x100)
#endif /* CONFIG_PPC_PSERIES */ #endif /* CONFIG_PPC_PSERIES */
...@@ -172,14 +178,6 @@ EXC_REAL_BEGIN(machine_check, 0x200, 0x100) ...@@ -172,14 +178,6 @@ EXC_REAL_BEGIN(machine_check, 0x200, 0x100)
* vector * vector
*/ */
SET_SCRATCH0(r13) /* save r13 */ SET_SCRATCH0(r13) /* save r13 */
/*
* Running native on arch 2.06 or later, we may wakeup from winkle
* inside machine check. If yes, then last bit of HSPRG0 would be set
* to 1. Hence clear it unconditionally.
*/
GET_PACA(r13)
clrrdi r13,r13,1
SET_PACA(r13)
EXCEPTION_PROLOG_0(PACA_EXMC) EXCEPTION_PROLOG_0(PACA_EXMC)
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
b machine_check_powernv_early b machine_check_powernv_early
...@@ -212,6 +210,12 @@ BEGIN_FTR_SECTION ...@@ -212,6 +210,12 @@ BEGIN_FTR_SECTION
* NOTE: We are here with MSR_ME=0 (off), which means we risk a * NOTE: We are here with MSR_ME=0 (off), which means we risk a
* checkstop if we get another machine check exception before we do * checkstop if we get another machine check exception before we do
* rfid with MSR_ME=1. * rfid with MSR_ME=1.
*
* This interrupt can wake directly from idle. If that is the case,
* the machine check is handled then the idle wakeup code is called
* to restore state. In that case, the POWER9 DD1 idle PACA workaround
* is not applied in the early machine check code, which will cause
* bugs.
*/ */
mr r11,r1 /* Save r1 */ mr r11,r1 /* Save r1 */
lhz r10,PACA_IN_MCE(r13) lhz r10,PACA_IN_MCE(r13)
...@@ -268,20 +272,11 @@ machine_check_fwnmi: ...@@ -268,20 +272,11 @@ machine_check_fwnmi:
machine_check_pSeries_0: machine_check_pSeries_0:
EXCEPTION_PROLOG_1(PACA_EXMC, KVMTEST_PR, 0x200) EXCEPTION_PROLOG_1(PACA_EXMC, KVMTEST_PR, 0x200)
/* /*
* The following is essentially EXCEPTION_PROLOG_PSERIES_1 with the * MSR_RI is not enabled, because PACA_EXMC is being used, so a
* difference that MSR_RI is not enabled, because PACA_EXMC is being * nested machine check corrupts it. machine_check_common enables
* used, so nested machine check corrupts it. machine_check_common * MSR_RI.
* enables MSR_RI.
*/ */
ld r10,PACAKMSR(r13) EXCEPTION_PROLOG_PSERIES_1_NORI(machine_check_common, EXC_STD)
xori r10,r10,MSR_RI
mfspr r11,SPRN_SRR0
LOAD_HANDLER(r12, machine_check_common)
mtspr SPRN_SRR0,r12
mfspr r12,SPRN_SRR1
mtspr SPRN_SRR1,r10
rfid
b . /* prevent speculative execution */
TRAMP_KVM_SKIP(PACA_EXMC, 0x200) TRAMP_KVM_SKIP(PACA_EXMC, 0x200)
...@@ -340,6 +335,37 @@ EXC_COMMON_BEGIN(machine_check_common) ...@@ -340,6 +335,37 @@ EXC_COMMON_BEGIN(machine_check_common)
/* restore original r1. */ \ /* restore original r1. */ \
ld r1,GPR1(r1) ld r1,GPR1(r1)
#ifdef CONFIG_PPC_P7_NAP
/*
* This is an idle wakeup. Low level machine check has already been
* done. Queue the event then call the idle code to do the wake up.
*/
EXC_COMMON_BEGIN(machine_check_idle_common)
bl machine_check_queue_event
/*
* We have not used any non-volatile GPRs here, and as a rule
* most exception code including machine check does not.
* Therefore PACA_NAPSTATELOST does not need to be set. Idle
* wakeup will restore volatile registers.
*
* Load the original SRR1 into r3 for pnv_powersave_wakeup_mce.
*
* Then decrement MCE nesting after finishing with the stack.
*/
ld r3,_MSR(r1)
lhz r11,PACA_IN_MCE(r13)
subi r11,r11,1
sth r11,PACA_IN_MCE(r13)
/* Turn off the RI bit because SRR1 is used by idle wakeup code. */
/* Recoverability could be improved by reducing the use of SRR1. */
li r11,0
mtmsrd r11,1
b pnv_powersave_wakeup_mce
#endif
/* /*
* Handle machine check early in real mode. We come here with * Handle machine check early in real mode. We come here with
* ME=1, MMU (IR=0 and DR=0) off and using MC emergency stack. * ME=1, MMU (IR=0 and DR=0) off and using MC emergency stack.
...@@ -352,6 +378,7 @@ EXC_COMMON_BEGIN(machine_check_handle_early) ...@@ -352,6 +378,7 @@ EXC_COMMON_BEGIN(machine_check_handle_early)
bl machine_check_early bl machine_check_early
std r3,RESULT(r1) /* Save result */ std r3,RESULT(r1) /* Save result */
ld r12,_MSR(r1) ld r12,_MSR(r1)
#ifdef CONFIG_PPC_P7_NAP #ifdef CONFIG_PPC_P7_NAP
/* /*
* Check if thread was in power saving mode. We come here when any * Check if thread was in power saving mode. We come here when any
...@@ -362,48 +389,14 @@ EXC_COMMON_BEGIN(machine_check_handle_early) ...@@ -362,48 +389,14 @@ EXC_COMMON_BEGIN(machine_check_handle_early)
* *
* Go back to nap/sleep/winkle mode again if (b) is true. * Go back to nap/sleep/winkle mode again if (b) is true.
*/ */
rlwinm. r11,r12,47-31,30,31 /* Was it in power saving mode? */ BEGIN_FTR_SECTION
beq 4f /* No, it wasn;t */ rlwinm. r11,r12,47-31,30,31
/* Thread was in power saving mode. Go back to nap again. */ beq- 4f
cmpwi r11,2 BRANCH_TO_COMMON(r10, machine_check_idle_common)
blt 3f
/* Supervisor/Hypervisor state loss */
li r0,1
stb r0,PACA_NAPSTATELOST(r13)
3: bl machine_check_queue_event
MACHINE_CHECK_HANDLER_WINDUP
GET_PACA(r13)
ld r1,PACAR1(r13)
/*
* Check what idle state this CPU was in and go back to same mode
* again.
*/
lbz r3,PACA_THREAD_IDLE_STATE(r13)
cmpwi r3,PNV_THREAD_NAP
bgt 10f
IDLE_STATE_ENTER_SEQ_NORET(PPC_NAP)
/* No return */
10:
cmpwi r3,PNV_THREAD_SLEEP
bgt 2f
IDLE_STATE_ENTER_SEQ_NORET(PPC_SLEEP)
/* No return */
2:
/*
* Go back to winkle. Please note that this thread was woken up in
* machine check from winkle and have not restored the per-subcore
* state. Hence before going back to winkle, set last bit of HSPRG0
* to 1. This will make sure that if this thread gets woken up
* again at reset vector 0x100 then it will get chance to restore
* the subcore state.
*/
ori r13,r13,1
SET_PACA(r13)
IDLE_STATE_ENTER_SEQ_NORET(PPC_WINKLE)
/* No return */
4: 4:
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
#endif #endif
/* /*
* Check if we are coming from hypervisor userspace. If yes then we * Check if we are coming from hypervisor userspace. If yes then we
* continue in host kernel in V mode to deliver the MC event. * continue in host kernel in V mode to deliver the MC event.
...@@ -968,17 +961,12 @@ EXC_VIRT_NONE(0x4e60, 0x20) ...@@ -968,17 +961,12 @@ EXC_VIRT_NONE(0x4e60, 0x20)
TRAMP_KVM_HV(PACA_EXGEN, 0xe60) TRAMP_KVM_HV(PACA_EXGEN, 0xe60)
TRAMP_REAL_BEGIN(hmi_exception_early) TRAMP_REAL_BEGIN(hmi_exception_early)
EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV, 0xe60) EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV, 0xe60)
mr r10,r1 /* Save r1 */ mr r10,r1 /* Save r1 */
ld r1,PACAEMERGSP(r13) /* Use emergency stack */ ld r1,PACAEMERGSP(r13) /* Use emergency stack for realmode */
subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */ subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */
std r9,_CCR(r1) /* save CR in stackframe */
mfspr r11,SPRN_HSRR0 /* Save HSRR0 */ mfspr r11,SPRN_HSRR0 /* Save HSRR0 */
std r11,_NIP(r1) /* save HSRR0 in stackframe */ mfspr r12,SPRN_HSRR1 /* Save HSRR1 */
mfspr r12,SPRN_HSRR1 /* Save SRR1 */ EXCEPTION_PROLOG_COMMON_1()
std r12,_MSR(r1) /* save SRR1 in stackframe */
std r10,0(r1) /* make stack chain pointer */
std r0,GPR0(r1) /* save r0 in stackframe */
std r10,GPR1(r1) /* save r1 in stackframe */
EXCEPTION_PROLOG_COMMON_2(PACA_EXGEN) EXCEPTION_PROLOG_COMMON_2(PACA_EXGEN)
EXCEPTION_PROLOG_COMMON_3(0xe60) EXCEPTION_PROLOG_COMMON_3(0xe60)
addi r3,r1,STACK_FRAME_OVERHEAD addi r3,r1,STACK_FRAME_OVERHEAD
......
...@@ -30,17 +30,16 @@ ...@@ -30,17 +30,16 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/crash_dump.h> #include <linux/crash_dump.h>
#include <linux/kobject.h> #include <linux/kobject.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
#include <asm/debugfs.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/prom.h> #include <asm/prom.h>
#include <asm/rtas.h> #include <asm/rtas.h>
#include <asm/fadump.h> #include <asm/fadump.h>
#include <asm/debug.h>
#include <asm/setup.h> #include <asm/setup.h>
static struct fw_dump fw_dump; static struct fw_dump fw_dump;
...@@ -319,15 +318,34 @@ int __init fadump_reserve_mem(void) ...@@ -319,15 +318,34 @@ int __init fadump_reserve_mem(void)
pr_debug("fadumphdr_addr = %p\n", pr_debug("fadumphdr_addr = %p\n",
(void *) fw_dump.fadumphdr_addr); (void *) fw_dump.fadumphdr_addr);
} else { } else {
/* Reserve the memory at the top of memory. */
size = get_fadump_area_size(); size = get_fadump_area_size();
base = memory_boundary - size;
memblock_reserve(base, size); /*
printk(KERN_INFO "Reserved %ldMB of memory at %ldMB " * Reserve memory at an offset closer to bottom of the RAM to
"for firmware-assisted dump\n", * minimize the impact of memory hot-remove operation. We can't
(unsigned long)(size >> 20), * use memblock_find_in_range() here since it doesn't allocate
(unsigned long)(base >> 20)); * from bottom to top.
*/
for (base = fw_dump.boot_memory_size;
base <= (memory_boundary - size);
base += size) {
if (memblock_is_region_memory(base, size) &&
!memblock_is_region_reserved(base, size))
break;
}
if ((base > (memory_boundary - size)) ||
memblock_reserve(base, size)) {
pr_err("Failed to reserve memory\n");
return 0;
}
pr_info("Reserved %ldMB of memory at %ldMB for firmware-"
"assisted dump (System RAM: %ldMB)\n",
(unsigned long)(size >> 20),
(unsigned long)(base >> 20),
(unsigned long)(memblock_phys_mem_size() >> 20));
} }
fw_dump.reserve_dump_area_start = base; fw_dump.reserve_dump_area_start = base;
fw_dump.reserve_dump_area_size = size; fw_dump.reserve_dump_area_size = size;
return 1; return 1;
......
...@@ -735,11 +735,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU) ...@@ -735,11 +735,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
EXCEPTION(0x2c00, Trap_2c, unknown_exception, EXC_XFER_EE) EXCEPTION(0x2c00, Trap_2c, unknown_exception, EXC_XFER_EE)
EXCEPTION(0x2d00, Trap_2d, unknown_exception, EXC_XFER_EE) EXCEPTION(0x2d00, Trap_2d, unknown_exception, EXC_XFER_EE)
EXCEPTION(0x2e00, Trap_2e, unknown_exception, EXC_XFER_EE) EXCEPTION(0x2e00, Trap_2e, unknown_exception, EXC_XFER_EE)
EXCEPTION(0x2f00, MOLTrampoline, unknown_exception, EXC_XFER_EE_LITE) EXCEPTION(0x2f00, Trap_2f, unknown_exception, EXC_XFER_EE)
.globl mol_trampoline
.set mol_trampoline, i0x2f00
EXPORT_SYMBOL(mol_trampoline)
. = 0x3000 . = 0x3000
...@@ -1278,16 +1274,6 @@ EXPORT_SYMBOL(empty_zero_page) ...@@ -1278,16 +1274,6 @@ EXPORT_SYMBOL(empty_zero_page)
swapper_pg_dir: swapper_pg_dir:
.space PGD_TABLE_SIZE .space PGD_TABLE_SIZE
.globl intercept_table
intercept_table:
.long 0, 0, i0x200, i0x300, i0x400, 0, i0x600, i0x700
.long i0x800, 0, 0, 0, 0, i0xd00, 0, 0
.long 0, 0, 0, i0x1300, 0, 0, 0, 0
.long 0, 0, 0, 0, 0, 0, 0, 0
.long 0, 0, 0, 0, 0, 0, 0, 0
.long 0, 0, 0, 0, 0, 0, 0, 0
EXPORT_SYMBOL(intercept_table)
/* Room for two PTE pointers, usually the kernel and current user pointers /* Room for two PTE pointers, usually the kernel and current user pointers
* to their respective root page table. * to their respective root page table.
*/ */
......
...@@ -949,7 +949,8 @@ start_here_multiplatform: ...@@ -949,7 +949,8 @@ start_here_multiplatform:
LOAD_REG_ADDR(r3,init_thread_union) LOAD_REG_ADDR(r3,init_thread_union)
/* set up a stack pointer */ /* set up a stack pointer */
addi r1,r3,THREAD_SIZE LOAD_REG_IMMEDIATE(r1,THREAD_SIZE)
add r1,r3,r1
li r0,0 li r0,0
stdu r0,-STACK_FRAME_OVERHEAD(r1) stdu r0,-STACK_FRAME_OVERHEAD(r1)
......
This diff is collapsed.
...@@ -711,13 +711,16 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) ...@@ -711,13 +711,16 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
return tbl; return tbl;
} }
void iommu_free_table(struct iommu_table *tbl, const char *node_name) static void iommu_table_free(struct kref *kref)
{ {
unsigned long bitmap_sz; unsigned long bitmap_sz;
unsigned int order; unsigned int order;
struct iommu_table *tbl;
if (!tbl) tbl = container_of(kref, struct iommu_table, it_kref);
return;
if (tbl->it_ops->free)
tbl->it_ops->free(tbl);
if (!tbl->it_map) { if (!tbl->it_map) {
kfree(tbl); kfree(tbl);
...@@ -733,7 +736,7 @@ void iommu_free_table(struct iommu_table *tbl, const char *node_name) ...@@ -733,7 +736,7 @@ void iommu_free_table(struct iommu_table *tbl, const char *node_name)
/* verify that table contains no entries */ /* verify that table contains no entries */
if (!bitmap_empty(tbl->it_map, tbl->it_size)) if (!bitmap_empty(tbl->it_map, tbl->it_size))
pr_warn("%s: Unexpected TCEs for %s\n", __func__, node_name); pr_warn("%s: Unexpected TCEs\n", __func__);
/* calculate bitmap size in bytes */ /* calculate bitmap size in bytes */
bitmap_sz = BITS_TO_LONGS(tbl->it_size) * sizeof(unsigned long); bitmap_sz = BITS_TO_LONGS(tbl->it_size) * sizeof(unsigned long);
...@@ -746,6 +749,24 @@ void iommu_free_table(struct iommu_table *tbl, const char *node_name) ...@@ -746,6 +749,24 @@ void iommu_free_table(struct iommu_table *tbl, const char *node_name)
kfree(tbl); kfree(tbl);
} }
struct iommu_table *iommu_tce_table_get(struct iommu_table *tbl)
{
if (kref_get_unless_zero(&tbl->it_kref))
return tbl;
return NULL;
}
EXPORT_SYMBOL_GPL(iommu_tce_table_get);
int iommu_tce_table_put(struct iommu_table *tbl)
{
if (WARN_ON(!tbl))
return 0;
return kref_put(&tbl->it_kref, iommu_table_free);
}
EXPORT_SYMBOL_GPL(iommu_tce_table_put);
/* Creates TCEs for a user provided buffer. The user buffer must be /* Creates TCEs for a user provided buffer. The user buffer must be
* contiguous real kernel storage (not vmalloc). The address passed here * contiguous real kernel storage (not vmalloc). The address passed here
* comprises a page address and offset into that page. The dma_addr_t * comprises a page address and offset into that page. The dma_addr_t
...@@ -1004,6 +1025,31 @@ long iommu_tce_xchg(struct iommu_table *tbl, unsigned long entry, ...@@ -1004,6 +1025,31 @@ long iommu_tce_xchg(struct iommu_table *tbl, unsigned long entry,
} }
EXPORT_SYMBOL_GPL(iommu_tce_xchg); EXPORT_SYMBOL_GPL(iommu_tce_xchg);
#ifdef CONFIG_PPC_BOOK3S_64
long iommu_tce_xchg_rm(struct iommu_table *tbl, unsigned long entry,
unsigned long *hpa, enum dma_data_direction *direction)
{
long ret;
ret = tbl->it_ops->exchange_rm(tbl, entry, hpa, direction);
if (!ret && ((*direction == DMA_FROM_DEVICE) ||
(*direction == DMA_BIDIRECTIONAL))) {
struct page *pg = realmode_pfn_to_page(*hpa >> PAGE_SHIFT);
if (likely(pg)) {
SetPageDirty(pg);
} else {
tbl->it_ops->exchange_rm(tbl, entry, hpa, direction);
ret = -EFAULT;
}
}
return ret;
}
EXPORT_SYMBOL_GPL(iommu_tce_xchg_rm);
#endif
int iommu_take_ownership(struct iommu_table *tbl) int iommu_take_ownership(struct iommu_table *tbl)
{ {
unsigned long flags, i, sz = (tbl->it_size + 7) >> 3; unsigned long flags, i, sz = (tbl->it_size + 7) >> 3;
......
...@@ -65,7 +65,6 @@ ...@@ -65,7 +65,6 @@
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/udbg.h> #include <asm/udbg.h>
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/debug.h>
#include <asm/livepatch.h> #include <asm/livepatch.h>
#include <asm/asm-prototypes.h> #include <asm/asm-prototypes.h>
...@@ -442,46 +441,6 @@ u64 arch_irq_stat_cpu(unsigned int cpu) ...@@ -442,46 +441,6 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
return sum; return sum;
} }
#ifdef CONFIG_HOTPLUG_CPU
void migrate_irqs(void)
{
struct irq_desc *desc;
unsigned int irq;
static int warned;
cpumask_var_t mask;
const struct cpumask *map = cpu_online_mask;
alloc_cpumask_var(&mask, GFP_KERNEL);
for_each_irq_desc(irq, desc) {
struct irq_data *data;
struct irq_chip *chip;
data = irq_desc_get_irq_data(desc);
if (irqd_is_per_cpu(data))
continue;
chip = irq_data_get_irq_chip(data);
cpumask_and(mask, irq_data_get_affinity_mask(data), map);
if (cpumask_any(mask) >= nr_cpu_ids) {
pr_warn("Breaking affinity for irq %i\n", irq);
cpumask_copy(mask, map);
}
if (chip->irq_set_affinity)
chip->irq_set_affinity(data, mask, true);
else if (desc->action && !(warned++))
pr_err("Cannot set affinity for irq %i\n", irq);
}
free_cpumask_var(mask);
local_irq_enable();
mdelay(1);
local_irq_disable();
}
#endif
static inline void check_stack_overflow(void) static inline void check_stack_overflow(void)
{ {
#ifdef CONFIG_DEBUG_STACKOVERFLOW #ifdef CONFIG_DEBUG_STACKOVERFLOW
......
/*
* Dynamic Ftrace based Kprobes Optimization
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Copyright (C) Hitachi Ltd., 2012
* Copyright 2016 Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
* IBM Corporation
*/
#include <linux/kprobes.h>
#include <linux/ptrace.h>
#include <linux/hardirq.h>
#include <linux/preempt.h>
#include <linux/ftrace.h>
static nokprobe_inline
int __skip_singlestep(struct kprobe *p, struct pt_regs *regs,
struct kprobe_ctlblk *kcb, unsigned long orig_nip)
{
/*
* Emulate singlestep (and also recover regs->nip)
* as if there is a nop
*/
regs->nip = (unsigned long)p->addr + MCOUNT_INSN_SIZE;
if (unlikely(p->post_handler)) {
kcb->kprobe_status = KPROBE_HIT_SSDONE;
p->post_handler(p, regs, 0);
}
__this_cpu_write(current_kprobe, NULL);
if (orig_nip)
regs->nip = orig_nip;
return 1;
}
int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
struct kprobe_ctlblk *kcb)
{
if (kprobe_ftrace(p))
return __skip_singlestep(p, regs, kcb, 0);
else
return 0;
}
NOKPROBE_SYMBOL(skip_singlestep);
/* Ftrace callback handler for kprobes */
void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,
struct ftrace_ops *ops, struct pt_regs *regs)
{
struct kprobe *p;
struct kprobe_ctlblk *kcb;
unsigned long flags;
/* Disable irq for emulating a breakpoint and avoiding preempt */
local_irq_save(flags);
hard_irq_disable();
p = get_kprobe((kprobe_opcode_t *)nip);
if (unlikely(!p) || kprobe_disabled(p))
goto end;
kcb = get_kprobe_ctlblk();
if (kprobe_running()) {
kprobes_inc_nmissed_count(p);
} else {
unsigned long orig_nip = regs->nip;
/*
* On powerpc, NIP is *before* this instruction for the
* pre handler
*/
regs->nip -= MCOUNT_INSN_SIZE;
__this_cpu_write(current_kprobe, p);
kcb->kprobe_status = KPROBE_HIT_ACTIVE;
if (!p->pre_handler || !p->pre_handler(p, regs))
__skip_singlestep(p, regs, kcb, orig_nip);
/*
* If pre_handler returns !0, it sets regs->nip and
* resets current kprobe.
*/
}
end:
local_irq_restore(flags);
}
NOKPROBE_SYMBOL(kprobe_ftrace_handler);
int arch_prepare_kprobe_ftrace(struct kprobe *p)
{
p->ainsn.insn = NULL;
p->ainsn.boostable = -1;
return 0;
}
This diff is collapsed.
...@@ -221,6 +221,8 @@ static void machine_check_process_queued_event(struct irq_work *work) ...@@ -221,6 +221,8 @@ static void machine_check_process_queued_event(struct irq_work *work)
{ {
int index; int index;
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
/* /*
* For now just print it to console. * For now just print it to console.
* TODO: log this error event to FSP or nvram. * TODO: log this error event to FSP or nvram.
...@@ -228,12 +230,13 @@ static void machine_check_process_queued_event(struct irq_work *work) ...@@ -228,12 +230,13 @@ static void machine_check_process_queued_event(struct irq_work *work)
while (__this_cpu_read(mce_queue_count) > 0) { while (__this_cpu_read(mce_queue_count) > 0) {
index = __this_cpu_read(mce_queue_count) - 1; index = __this_cpu_read(mce_queue_count) - 1;
machine_check_print_event_info( machine_check_print_event_info(
this_cpu_ptr(&mce_event_queue[index])); this_cpu_ptr(&mce_event_queue[index]), false);
__this_cpu_dec(mce_queue_count); __this_cpu_dec(mce_queue_count);
} }
} }
void machine_check_print_event_info(struct machine_check_event *evt) void machine_check_print_event_info(struct machine_check_event *evt,
bool user_mode)
{ {
const char *level, *sevstr, *subtype; const char *level, *sevstr, *subtype;
static const char *mc_ue_types[] = { static const char *mc_ue_types[] = {
...@@ -310,7 +313,16 @@ void machine_check_print_event_info(struct machine_check_event *evt) ...@@ -310,7 +313,16 @@ void machine_check_print_event_info(struct machine_check_event *evt)
printk("%s%s Machine check interrupt [%s]\n", level, sevstr, printk("%s%s Machine check interrupt [%s]\n", level, sevstr,
evt->disposition == MCE_DISPOSITION_RECOVERED ? evt->disposition == MCE_DISPOSITION_RECOVERED ?
"Recovered" : "[Not recovered"); "Recovered" : "Not recovered");
if (user_mode) {
printk("%s NIP: [%016llx] PID: %d Comm: %s\n", level,
evt->srr0, current->pid, current->comm);
} else {
printk("%s NIP [%016llx]: %pS\n", level, evt->srr0,
(void *)evt->srr0);
}
printk("%s Initiator: %s\n", level, printk("%s Initiator: %s\n", level,
evt->initiator == MCE_INITIATOR_CPU ? "CPU" : "Unknown"); evt->initiator == MCE_INITIATOR_CPU ? "CPU" : "Unknown");
switch (evt->error_type) { switch (evt->error_type) {
......
This diff is collapsed.
...@@ -243,10 +243,10 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) ...@@ -243,10 +243,10 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
/* /*
* 2. branch to optimized_callback() and emulate_step() * 2. branch to optimized_callback() and emulate_step()
*/ */
kprobe_lookup_name("optimized_callback", op_callback_addr); op_callback_addr = (kprobe_opcode_t *)ppc_kallsyms_lookup_name("optimized_callback");
kprobe_lookup_name("emulate_step", emulate_step_addr); emulate_step_addr = (kprobe_opcode_t *)ppc_kallsyms_lookup_name("emulate_step");
if (!op_callback_addr || !emulate_step_addr) { if (!op_callback_addr || !emulate_step_addr) {
WARN(1, "kprobe_lookup_name() failed\n"); WARN(1, "Unable to lookup optimized_callback()/emulate_step()\n");
goto error; goto error;
} }
......
...@@ -245,3 +245,24 @@ void __init free_unused_pacas(void) ...@@ -245,3 +245,24 @@ void __init free_unused_pacas(void)
free_lppacas(); free_lppacas();
} }
void copy_mm_to_paca(struct mm_struct *mm)
{
#ifdef CONFIG_PPC_BOOK3S
mm_context_t *context = &mm->context;
get_paca()->mm_ctx_id = context->id;
#ifdef CONFIG_PPC_MM_SLICES
VM_BUG_ON(!mm->context.addr_limit);
get_paca()->addr_limit = mm->context.addr_limit;
get_paca()->mm_ctx_low_slices_psize = context->low_slices_psize;
memcpy(&get_paca()->mm_ctx_high_slices_psize,
&context->high_slices_psize, TASK_SLICE_ARRAY_SZ(mm));
#else /* CONFIG_PPC_MM_SLICES */
get_paca()->mm_ctx_user_psize = context->user_psize;
get_paca()->mm_ctx_sllp = context->sllp;
#endif
#else /* CONFIG_PPC_BOOK3S */
return;
#endif
}
...@@ -55,7 +55,6 @@ ...@@ -55,7 +55,6 @@
#include <asm/kexec.h> #include <asm/kexec.h>
#include <asm/opal.h> #include <asm/opal.h>
#include <asm/fadump.h> #include <asm/fadump.h>
#include <asm/debug.h>
#include <asm/epapr_hcalls.h> #include <asm/epapr_hcalls.h>
#include <asm/firmware.h> #include <asm/firmware.h>
......
...@@ -815,7 +815,7 @@ struct ibm_arch_vec __cacheline_aligned ibm_architecture_vec = { ...@@ -815,7 +815,7 @@ struct ibm_arch_vec __cacheline_aligned ibm_architecture_vec = {
.virt_base = cpu_to_be32(0xffffffff), .virt_base = cpu_to_be32(0xffffffff),
.virt_size = cpu_to_be32(0xffffffff), .virt_size = cpu_to_be32(0xffffffff),
.load_base = cpu_to_be32(0xffffffff), .load_base = cpu_to_be32(0xffffffff),
.min_rma = cpu_to_be32(256), /* 256MB min RMA */ .min_rma = cpu_to_be32(512), /* 512MB min RMA */
.min_load = cpu_to_be32(0xffffffff), /* full client load */ .min_load = cpu_to_be32(0xffffffff), /* full client load */
.min_rma_percent = 0, /* min RMA percentage of total RAM */ .min_rma_percent = 0, /* min RMA percentage of total RAM */
.max_pft_size = 48, /* max log_2(hash table size) */ .max_pft_size = 48, /* max log_2(hash table size) */
......
...@@ -31,11 +31,11 @@ ...@@ -31,11 +31,11 @@
#include <linux/unistd.h> #include <linux/unistd.h>
#include <linux/serial.h> #include <linux/serial.h>
#include <linux/serial_8250.h> #include <linux/serial_8250.h>
#include <linux/debugfs.h>
#include <linux/percpu.h> #include <linux/percpu.h>
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/hugetlb.h> #include <linux/hugetlb.h>
#include <asm/debugfs.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/paca.h> #include <asm/paca.h>
#include <asm/prom.h> #include <asm/prom.h>
...@@ -920,6 +920,15 @@ void __init setup_arch(char **cmdline_p) ...@@ -920,6 +920,15 @@ void __init setup_arch(char **cmdline_p)
init_mm.end_code = (unsigned long) _etext; init_mm.end_code = (unsigned long) _etext;
init_mm.end_data = (unsigned long) _edata; init_mm.end_data = (unsigned long) _edata;
init_mm.brk = klimit; init_mm.brk = klimit;
#ifdef CONFIG_PPC_MM_SLICES
#ifdef CONFIG_PPC64
init_mm.context.addr_limit = TASK_SIZE_128TB;
#else
#error "context.addr_limit not initialized."
#endif
#endif
#ifdef CONFIG_PPC_64K_PAGES #ifdef CONFIG_PPC_64K_PAGES
init_mm.context.pte_frag = NULL; init_mm.context.pte_frag = NULL;
#endif #endif
......
...@@ -230,8 +230,8 @@ static void cpu_ready_for_interrupts(void) ...@@ -230,8 +230,8 @@ static void cpu_ready_for_interrupts(void)
* If we are not in hypervisor mode the job is done once for * If we are not in hypervisor mode the job is done once for
* the whole partition in configure_exceptions(). * the whole partition in configure_exceptions().
*/ */
if (early_cpu_has_feature(CPU_FTR_HVMODE) && if (cpu_has_feature(CPU_FTR_HVMODE) &&
early_cpu_has_feature(CPU_FTR_ARCH_207S)) { cpu_has_feature(CPU_FTR_ARCH_207S)) {
unsigned long lpcr = mfspr(SPRN_LPCR); unsigned long lpcr = mfspr(SPRN_LPCR);
mtspr(SPRN_LPCR, lpcr | LPCR_AIL_3); mtspr(SPRN_LPCR, lpcr | LPCR_AIL_3);
} }
...@@ -637,6 +637,11 @@ void __init emergency_stack_init(void) ...@@ -637,6 +637,11 @@ void __init emergency_stack_init(void)
paca[i].emergency_sp = (void *)ti + THREAD_SIZE; paca[i].emergency_sp = (void *)ti + THREAD_SIZE;
#ifdef CONFIG_PPC_BOOK3S_64 #ifdef CONFIG_PPC_BOOK3S_64
/* emergency stack for NMI exception handling. */
ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit));
klp_init_thread_info(ti);
paca[i].nmi_emergency_sp = (void *)ti + THREAD_SIZE;
/* emergency stack for machine check exception handling. */ /* emergency stack for machine check exception handling. */
ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit)); ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit));
klp_init_thread_info(ti); klp_init_thread_info(ti);
......
This diff is collapsed.
This diff is collapsed.
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
*/ */
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/suspend.h>
#include <asm/current.h> #include <asm/current.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
#include <asm/switch_to.h> #include <asm/switch_to.h>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment