Commit 45824fc0 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull powerpc updates from Michael Ellerman:
 "This is a bit late, partly due to me travelling, and partly due to a
  power outage knocking out some of my test systems *while* I was
  travelling.

   - Initial support for running on a system with an Ultravisor, which
     is software that runs below the hypervisor and protects guests
     against some attacks by the hypervisor.

   - Support for building the kernel to run as a "Secure Virtual
     Machine", ie. as a guest capable of running on a system with an
     Ultravisor.

   - Some changes to our DMA code on bare metal, to allow devices with
     medium sized DMA masks (> 32 && < 59 bits) to use more than 2GB of
     DMA space.

   - Support for firmware assisted crash dumps on bare metal (powernv).

   - Two series fixing bugs in and refactoring our PCI EEH code.

   - A large series refactoring our exception entry code to use gas
     macros, both to make it more readable and also enable some future
     optimisations.

  As well as many cleanups and other minor features & fixups.

  Thanks to: Adam Zerella, Alexey Kardashevskiy, Alistair Popple, Andrew
  Donnellan, Aneesh Kumar K.V, Anju T Sudhakar, Anshuman Khandual,
  Balbir Singh, Benjamin Herrenschmidt, Cédric Le Goater, Christophe
  JAILLET, Christophe Leroy, Christopher M. Riedl, Christoph Hellwig,
  Claudio Carvalho, Daniel Axtens, David Gibson, David Hildenbrand,
  Desnes A. Nunes do Rosario, Ganesh Goudar, Gautham R. Shenoy, Greg
  Kurz, Guerney Hunt, Gustavo Romero, Halil Pasic, Hari Bathini, Joakim
  Tjernlund, Jonathan Neuschafer, Jordan Niethe, Leonardo Bras, Lianbo
  Jiang, Madhavan Srinivasan, Mahesh Salgaonkar, Mahesh Salgaonkar,
  Masahiro Yamada, Maxiwell S. Garcia, Michael Anderson, Nathan
  Chancellor, Nathan Lynch, Naveen N. Rao, Nicholas Piggin, Oliver
  O'Halloran, Qian Cai, Ram Pai, Ravi Bangoria, Reza Arbab, Ryan Grimm,
  Sam Bobroff, Santosh Sivaraj, Segher Boessenkool, Sukadev Bhattiprolu,
  Thiago Bauermann, Thiago Jung Bauermann, Thomas Gleixner, Tom
  Lendacky, Vasant Hegde"

* tag 'powerpc-5.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (264 commits)
  powerpc/mm/mce: Keep irqs disabled during lockless page table walk
  powerpc: Use ftrace_graph_ret_addr() when unwinding
  powerpc/ftrace: Enable HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
  ftrace: Look up the address of return_to_handler() using helpers
  powerpc: dump kernel log before carrying out fadump or kdump
  docs: powerpc: Add missing documentation reference
  powerpc/xmon: Fix output of XIVE IPI
  powerpc/xmon: Improve output of XIVE interrupts
  powerpc/mm/radix: remove useless kernel messages
  powerpc/fadump: support holes in kernel boot memory area
  powerpc/fadump: remove RMA_START and RMA_END macros
  powerpc/fadump: update documentation about option to release opalcore
  powerpc/fadump: consider f/w load area
  powerpc/opalcore: provide an option to invalidate /sys/firmware/opal/core file
  powerpc/opalcore: export /sys/firmware/opal/core for analysing opal crashes
  powerpc/fadump: update documentation about CONFIG_PRESERVE_FA_DUMP
  powerpc/fadump: add support to preserve crash data on FADUMP disabled kernel
  powerpc/fadump: improve how crashed kernel's memory is reserved
  powerpc/fadump: consider reserved ranges while releasing memory
  powerpc/fadump: make crash memory ranges array allocation generic
  ...
parents 8c2b418c d9101bfa
...@@ -562,3 +562,13 @@ Description: Umwait control ...@@ -562,3 +562,13 @@ Description: Umwait control
or C0.2 state. The time is an unsigned 32-bit number. or C0.2 state. The time is an unsigned 32-bit number.
Note that a value of zero means there is no limit. Note that a value of zero means there is no limit.
Low order two bits must be zero. Low order two bits must be zero.
What: /sys/devices/system/cpu/svm
Date: August 2019
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
Description: Secure Virtual Machine
If 1, it means the system is using the Protected Execution
Facility in POWER9 and newer processors. i.e., it is a Secure
Virtual Machine.
...@@ -860,6 +860,10 @@ ...@@ -860,6 +860,10 @@
disable_radix [PPC] disable_radix [PPC]
Disable RADIX MMU mode on POWER9 Disable RADIX MMU mode on POWER9
disable_tlbie [PPC]
Disable TLBIE instruction. Currently does not work
with KVM, with HASH MMU, or with coherent accelerators.
disable_cpu_apicid= [X86,APIC,SMP] disable_cpu_apicid= [X86,APIC,SMP]
Format: <int> Format: <int>
The number of initial APIC ID for the The number of initial APIC ID for the
...@@ -4641,6 +4645,11 @@ ...@@ -4641,6 +4645,11 @@
/sys/power/pm_test). Only available when CONFIG_PM_DEBUG /sys/power/pm_test). Only available when CONFIG_PM_DEBUG
is set. Default value is 5. is set. Default value is 5.
svm= [PPC]
Format: { on | off | y | n | 1 | 0 }
This parameter controls use of the Protected
Execution Facility on pSeries.
swapaccount=[0|1] swapaccount=[0|1]
[KNL] Enable accounting of swap in memory resource [KNL] Enable accounting of swap in memory resource
controller if no parameter or 1 is given or disable controller if no parameter or 1 is given or disable
...@@ -5326,3 +5335,22 @@ ...@@ -5326,3 +5335,22 @@
A hex value specifying bitmask with supplemental xhci A hex value specifying bitmask with supplemental xhci
host controller quirks. Meaning of each bit can be host controller quirks. Meaning of each bit can be
consulted in header drivers/usb/host/xhci.h. consulted in header drivers/usb/host/xhci.h.
xmon [PPC]
Format: { early | on | rw | ro | off }
Controls if xmon debugger is enabled. Default is off.
Passing only "xmon" is equivalent to "xmon=early".
early Call xmon as early as possible on boot; xmon
debugger is called from setup_arch().
on xmon debugger hooks will be installed so xmon
is only called on a kernel crash. Default mode,
i.e. either "ro" or "rw" mode, is controlled
with CONFIG_XMON_DEFAULT_RO_MODE.
rw xmon debugger hooks will be installed so xmon
is called only on a kernel crash, mode is write,
meaning SPR registers, memory and, other data
can be written using xmon commands.
ro same as "rw" option above but SPR registers,
memory, and other data can't be written using
xmon commands.
off xmon is disabled.
==========================
ELF Note PowerPC Namespace
==========================
The PowerPC namespace in an ELF Note of the kernel binary is used to store
capabilities and information which can be used by a bootloader or userland.
Types and Descriptors
---------------------
The types to be used with the "PowerPC" namesapce are defined in [#f1]_.
1) PPC_ELFNOTE_CAPABILITIES
Define the capabilities supported/required by the kernel. This type uses a
bitmap as "descriptor" field. Each bit is described below:
- Ultravisor-capable bit (PowerNV only).
.. code-block:: c
#define PPCCAP_ULTRAVISOR_BIT (1 << 0)
Indicate that the powerpc kernel binary knows how to run in an
ultravisor-enabled system.
In an ultravisor-enabled system, some machine resources are now controlled
by the ultravisor. If the kernel is not ultravisor-capable, but it ends up
being run on a machine with ultravisor, the kernel will probably crash
trying to access ultravisor resources. For instance, it may crash in early
boot trying to set the partition table entry 0.
In an ultravisor-enabled system, a bootloader could warn the user or prevent
the kernel from being run if the PowerPC ultravisor capability doesn't exist
or the Ultravisor-capable bit is not set.
References
----------
.. [#f1] arch/powerpc/include/asm/elfnote.h
...@@ -15,6 +15,7 @@ powerpc ...@@ -15,6 +15,7 @@ powerpc
dawr-power9 dawr-power9
dscr dscr
eeh-pci-error-recovery eeh-pci-error-recovery
elfnote
firmware-assisted-dump firmware-assisted-dump
hvcs hvcs
isa-versions isa-versions
...@@ -25,6 +26,7 @@ powerpc ...@@ -25,6 +26,7 @@ powerpc
qe_firmware qe_firmware
syscall64-abi syscall64-abi
transactional_memory transactional_memory
ultravisor
.. only:: subproject and html .. only:: subproject and html
......
This diff is collapsed.
...@@ -946,6 +946,9 @@ config RELR ...@@ -946,6 +946,9 @@ config RELR
well as compatible NM and OBJCOPY utilities (llvm-nm and llvm-objcopy well as compatible NM and OBJCOPY utilities (llvm-nm and llvm-objcopy
are compatible). are compatible).
config ARCH_HAS_MEM_ENCRYPT
bool
source "kernel/gcov/Kconfig" source "kernel/gcov/Kconfig"
source "scripts/gcc-plugins/Kconfig" source "scripts/gcc-plugins/Kconfig"
......
...@@ -128,14 +128,15 @@ config PPC ...@@ -128,14 +128,15 @@ config PPC
select ARCH_HAS_HUGEPD if HUGETLB_PAGE select ARCH_HAS_HUGEPD if HUGETLB_PAGE
select ARCH_HAS_MMIOWB if PPC64 select ARCH_HAS_MMIOWB if PPC64
select ARCH_HAS_PHYS_TO_DMA select ARCH_HAS_PHYS_TO_DMA
select ARCH_HAS_PMEM_API if PPC64 select ARCH_HAS_PMEM_API
select ARCH_HAS_PTE_DEVMAP if PPC_BOOK3S_64 select ARCH_HAS_PTE_DEVMAP if PPC_BOOK3S_64
select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_PTE_SPECIAL
select ARCH_HAS_MEMBARRIER_CALLBACKS select ARCH_HAS_MEMBARRIER_CALLBACKS
select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE && PPC64 select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE && PPC_BOOK3S_64
select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !RELOCATABLE && !HIBERNATION) select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !RELOCATABLE && !HIBERNATION)
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_HAS_UACCESS_FLUSHCACHE if PPC64 select ARCH_HAS_UACCESS_FLUSHCACHE
select ARCH_HAS_UACCESS_MCSAFE if PPC64
select ARCH_HAS_UBSAN_SANITIZE_ALL select ARCH_HAS_UBSAN_SANITIZE_ALL
select ARCH_HAVE_NMI_SAFE_CMPXCHG select ARCH_HAVE_NMI_SAFE_CMPXCHG
select ARCH_KEEP_MEMBLOCK select ARCH_KEEP_MEMBLOCK
...@@ -183,6 +184,7 @@ config PPC ...@@ -183,6 +184,7 @@ config PPC
select HAVE_STACKPROTECTOR if PPC64 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r13) select HAVE_STACKPROTECTOR if PPC64 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r13)
select HAVE_STACKPROTECTOR if PPC32 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r2) select HAVE_STACKPROTECTOR if PPC32 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r2)
select HAVE_CONTEXT_TRACKING if PPC64 select HAVE_CONTEXT_TRACKING if PPC64
select HAVE_COPY_THREAD_TLS
select HAVE_DEBUG_KMEMLEAK select HAVE_DEBUG_KMEMLEAK
select HAVE_DEBUG_STACKOVERFLOW select HAVE_DEBUG_STACKOVERFLOW
select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE
...@@ -568,7 +570,7 @@ config CRASH_DUMP ...@@ -568,7 +570,7 @@ config CRASH_DUMP
config FA_DUMP config FA_DUMP
bool "Firmware-assisted dump" bool "Firmware-assisted dump"
depends on PPC64 && PPC_RTAS depends on PPC64 && (PPC_RTAS || PPC_POWERNV)
select CRASH_CORE select CRASH_CORE
select CRASH_DUMP select CRASH_DUMP
help help
...@@ -579,7 +581,26 @@ config FA_DUMP ...@@ -579,7 +581,26 @@ config FA_DUMP
is meant to be a kdump replacement offering robustness and is meant to be a kdump replacement offering robustness and
speed not possible without system firmware assistance. speed not possible without system firmware assistance.
If unsure, say "N" If unsure, say "y". Only special kernels like petitboot may
need to say "N" here.
config PRESERVE_FA_DUMP
bool "Preserve Firmware-assisted dump"
depends on PPC64 && PPC_POWERNV && !FA_DUMP
help
On a kernel with FA_DUMP disabled, this option helps to preserve
crash data from a previously crash'ed kernel. Useful when the next
memory preserving kernel boot would process this crash data.
Petitboot kernel is the typical usecase for this option.
config OPAL_CORE
bool "Export OPAL memory as /sys/firmware/opal/core"
depends on PPC64 && PPC_POWERNV
help
This option uses the MPIPL support in firmware to provide an
ELF core of OPAL memory after a crash. The ELF core is exported
as /sys/firmware/opal/core file which is helpful in debugging
OPAL crashes using GDB.
config IRQ_ALL_CPUS config IRQ_ALL_CPUS
bool "Distribute interrupts on all CPUs by default" bool "Distribute interrupts on all CPUs by default"
...@@ -1140,18 +1161,6 @@ config TASK_SIZE ...@@ -1140,18 +1161,6 @@ config TASK_SIZE
default "0x80000000" if PPC_8xx default "0x80000000" if PPC_8xx
default "0xc0000000" default "0xc0000000"
config CONSISTENT_SIZE_BOOL
bool "Set custom consistent memory pool size"
depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
help
This option allows you to set the size of the
consistent memory pool. This pool of virtual memory
is used to make consistent memory allocations.
config CONSISTENT_SIZE
hex "Size of consistent memory pool" if CONSISTENT_SIZE_BOOL
default "0x00200000" if NOT_COHERENT_CACHE
config PIN_TLB config PIN_TLB
bool "Pinned Kernel TLBs (860 ONLY)" bool "Pinned Kernel TLBs (860 ONLY)"
depends on ADVANCED_OPTIONS && PPC_8xx && \ depends on ADVANCED_OPTIONS && PPC_8xx && \
......
...@@ -110,7 +110,6 @@ ifeq ($(HAS_BIARCH),y) ...@@ -110,7 +110,6 @@ ifeq ($(HAS_BIARCH),y)
KBUILD_CFLAGS += -m$(BITS) KBUILD_CFLAGS += -m$(BITS)
KBUILD_AFLAGS += -m$(BITS) -Wl,-a$(BITS) KBUILD_AFLAGS += -m$(BITS) -Wl,-a$(BITS)
KBUILD_LDFLAGS += -m elf$(BITS)$(LDEMULATION) KBUILD_LDFLAGS += -m elf$(BITS)$(LDEMULATION)
KBUILD_ARFLAGS += --target=elf$(BITS)-$(GNUTARGET)
endif endif
cflags-$(CONFIG_STACKPROTECTOR) += -mstack-protector-guard=tls cflags-$(CONFIG_STACKPROTECTOR) += -mstack-protector-guard=tls
......
...@@ -146,6 +146,46 @@ static struct addr_range prep_initrd(struct addr_range vmlinux, void *chosen, ...@@ -146,6 +146,46 @@ static struct addr_range prep_initrd(struct addr_range vmlinux, void *chosen,
return (struct addr_range){(void *)initrd_addr, initrd_size}; return (struct addr_range){(void *)initrd_addr, initrd_size};
} }
#ifdef __powerpc64__
static void prep_esm_blob(struct addr_range vmlinux, void *chosen)
{
unsigned long esm_blob_addr, esm_blob_size;
/* Do we have an ESM (Enter Secure Mode) blob? */
if (_esm_blob_end <= _esm_blob_start)
return;
printf("Attached ESM blob at 0x%p-0x%p\n\r",
_esm_blob_start, _esm_blob_end);
esm_blob_addr = (unsigned long)_esm_blob_start;
esm_blob_size = _esm_blob_end - _esm_blob_start;
/*
* If the ESM blob is too low it will be clobbered when the
* kernel relocates to its final location. In this case,
* allocate a safer place and move it.
*/
if (esm_blob_addr < vmlinux.size) {
void *old_addr = (void *)esm_blob_addr;
printf("Allocating 0x%lx bytes for esm_blob ...\n\r",
esm_blob_size);
esm_blob_addr = (unsigned long)malloc(esm_blob_size);
if (!esm_blob_addr)
fatal("Can't allocate memory for ESM blob !\n\r");
printf("Relocating ESM blob 0x%lx <- 0x%p (0x%lx bytes)\n\r",
esm_blob_addr, old_addr, esm_blob_size);
memmove((void *)esm_blob_addr, old_addr, esm_blob_size);
}
/* Tell the kernel ESM blob address via device tree. */
setprop_val(chosen, "linux,esm-blob-start", (u32)(esm_blob_addr));
setprop_val(chosen, "linux,esm-blob-end", (u32)(esm_blob_addr + esm_blob_size));
}
#else
static inline void prep_esm_blob(struct addr_range vmlinux, void *chosen) { }
#endif
/* A buffer that may be edited by tools operating on a zImage binary so as to /* A buffer that may be edited by tools operating on a zImage binary so as to
* edit the command line passed to vmlinux (by setting /chosen/bootargs). * edit the command line passed to vmlinux (by setting /chosen/bootargs).
* The buffer is put in it's own section so that tools may locate it easier. * The buffer is put in it's own section so that tools may locate it easier.
...@@ -214,6 +254,7 @@ void start(void) ...@@ -214,6 +254,7 @@ void start(void)
vmlinux = prep_kernel(); vmlinux = prep_kernel();
initrd = prep_initrd(vmlinux, chosen, initrd = prep_initrd(vmlinux, chosen,
loader_info.initrd_addr, loader_info.initrd_size); loader_info.initrd_addr, loader_info.initrd_size);
prep_esm_blob(vmlinux, chosen);
prep_cmdline(chosen); prep_cmdline(chosen);
printf("Finalizing device tree..."); printf("Finalizing device tree...");
......
...@@ -251,6 +251,8 @@ extern char _initrd_start[]; ...@@ -251,6 +251,8 @@ extern char _initrd_start[];
extern char _initrd_end[]; extern char _initrd_end[];
extern char _dtb_start[]; extern char _dtb_start[];
extern char _dtb_end[]; extern char _dtb_end[];
extern char _esm_blob_start[];
extern char _esm_blob_end[];
static inline __attribute__((const)) static inline __attribute__((const))
int __ilog2_u32(u32 n) int __ilog2_u32(u32 n)
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
# -i initrd specify initrd file # -i initrd specify initrd file
# -d devtree specify device-tree blob # -d devtree specify device-tree blob
# -s tree.dts specify device-tree source file (needs dtc installed) # -s tree.dts specify device-tree source file (needs dtc installed)
# -e esm_blob specify ESM blob for secure images
# -c cache $kernel.strip.gz (use if present & newer, else make) # -c cache $kernel.strip.gz (use if present & newer, else make)
# -C prefix specify command prefix for cross-building tools # -C prefix specify command prefix for cross-building tools
# (strip, objcopy, ld) # (strip, objcopy, ld)
...@@ -37,6 +38,7 @@ platform=of ...@@ -37,6 +38,7 @@ platform=of
initrd= initrd=
dtb= dtb=
dts= dts=
esm_blob=
cacheit= cacheit=
binary= binary=
compression=.gz compression=.gz
...@@ -60,9 +62,9 @@ tmpdir=. ...@@ -60,9 +62,9 @@ tmpdir=.
usage() { usage() {
echo 'Usage: wrapper [-o output] [-p platform] [-i initrd]' >&2 echo 'Usage: wrapper [-o output] [-p platform] [-i initrd]' >&2
echo ' [-d devtree] [-s tree.dts] [-c] [-C cross-prefix]' >&2 echo ' [-d devtree] [-s tree.dts] [-e esm_blob]' >&2
echo ' [-D datadir] [-W workingdir] [-Z (gz|xz|none)]' >&2 echo ' [-c] [-C cross-prefix] [-D datadir] [-W workingdir]' >&2
echo ' [--no-compression] [vmlinux]' >&2 echo ' [-Z (gz|xz|none)] [--no-compression] [vmlinux]' >&2
exit 1 exit 1
} }
...@@ -105,6 +107,11 @@ while [ "$#" -gt 0 ]; do ...@@ -105,6 +107,11 @@ while [ "$#" -gt 0 ]; do
[ "$#" -gt 0 ] || usage [ "$#" -gt 0 ] || usage
dtb="$1" dtb="$1"
;; ;;
-e)
shift
[ "$#" -gt 0 ] || usage
esm_blob="$1"
;;
-s) -s)
shift shift
[ "$#" -gt 0 ] || usage [ "$#" -gt 0 ] || usage
...@@ -218,9 +225,16 @@ objflags=-S ...@@ -218,9 +225,16 @@ objflags=-S
tmp=$tmpdir/zImage.$$.o tmp=$tmpdir/zImage.$$.o
ksection=.kernel:vmlinux.strip ksection=.kernel:vmlinux.strip
isection=.kernel:initrd isection=.kernel:initrd
esection=.kernel:esm_blob
link_address='0x400000' link_address='0x400000'
make_space=y make_space=y
if [ -n "$esm_blob" -a "$platform" != "pseries" ]; then
echo "ESM blob not support on non-pseries platforms" >&2
exit 1
fi
case "$platform" in case "$platform" in
of) of)
platformo="$object/of.o $object/epapr.o" platformo="$object/of.o $object/epapr.o"
...@@ -477,6 +491,10 @@ if [ -n "$dtb" ]; then ...@@ -477,6 +491,10 @@ if [ -n "$dtb" ]; then
fi fi
fi fi
if [ -n "$esm_blob" ]; then
addsec $tmp "$esm_blob" $esection
fi
if [ "$platform" != "miboot" ]; then if [ "$platform" != "miboot" ]; then
if [ -n "$link_address" ] ; then if [ -n "$link_address" ] ; then
text_start="-Ttext $link_address" text_start="-Ttext $link_address"
......
...@@ -68,6 +68,14 @@ SECTIONS ...@@ -68,6 +68,14 @@ SECTIONS
_initrd_end = .; _initrd_end = .;
} }
. = ALIGN(4096);
.kernel:esm_blob :
{
_esm_blob_start = .;
*(.kernel:esm_blob)
_esm_blob_end = .;
}
#ifdef CONFIG_PPC64_BOOT_WRAPPER #ifdef CONFIG_PPC64_BOOT_WRAPPER
. = ALIGN(256); . = ALIGN(256);
.got : .got :
......
...@@ -20,7 +20,6 @@ CONFIG_CPU_FREQ=y ...@@ -20,7 +20,6 @@ CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_PMAC=y CONFIG_CPU_FREQ_PMAC=y
CONFIG_PPC601_SYNC_FIX=y
CONFIG_GEN_RTC=y CONFIG_GEN_RTC=y
CONFIG_HIGHMEM=y CONFIG_HIGHMEM=y
CONFIG_BINFMT_MISC=m CONFIG_BINFMT_MISC=m
......
...@@ -38,7 +38,7 @@ CONFIG_MODULE_UNLOAD=y ...@@ -38,7 +38,7 @@ CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_PARTITION_ADVANCED=y CONFIG_PARTITION_ADVANCED=y
CONFIG_SCOM_DEBUGFS=y # CONFIG_SCOM_DEBUGFS is not set
CONFIG_OPAL_PRD=y CONFIG_OPAL_PRD=y
CONFIG_PPC_MEMTRACE=y CONFIG_PPC_MEMTRACE=y
# CONFIG_PPC_PSERIES is not set # CONFIG_PPC_PSERIES is not set
......
...@@ -84,4 +84,3 @@ CONFIG_CRYPTO_ECB=y ...@@ -84,4 +84,3 @@ CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_PCBC=y
CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_DES=y
CONFIG_PPC4xx_OCM=y
...@@ -29,6 +29,7 @@ CONFIG_DTL=y ...@@ -29,6 +29,7 @@ CONFIG_DTL=y
CONFIG_SCANLOG=m CONFIG_SCANLOG=m
CONFIG_PPC_SMLPAR=y CONFIG_PPC_SMLPAR=y
CONFIG_IBMEBUS=y CONFIG_IBMEBUS=y
CONFIG_PPC_SVM=y
CONFIG_PPC_MAPLE=y CONFIG_PPC_MAPLE=y
CONFIG_PPC_PASEMI=y CONFIG_PPC_PASEMI=y
CONFIG_PPC_PASEMI_IOMMU=y CONFIG_PPC_PASEMI_IOMMU=y
......
...@@ -42,6 +42,7 @@ CONFIG_DTL=y ...@@ -42,6 +42,7 @@ CONFIG_DTL=y
CONFIG_SCANLOG=m CONFIG_SCANLOG=m
CONFIG_PPC_SMLPAR=y CONFIG_PPC_SMLPAR=y
CONFIG_IBMEBUS=y CONFIG_IBMEBUS=y
CONFIG_PPC_SVM=y
# CONFIG_PPC_PMAC is not set # CONFIG_PPC_PMAC is not set
CONFIG_RTAS_FLASH=m CONFIG_RTAS_FLASH=m
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
......
...@@ -213,6 +213,7 @@ CONFIG_IPMI_WATCHDOG=y ...@@ -213,6 +213,7 @@ CONFIG_IPMI_WATCHDOG=y
CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM=y
CONFIG_TCG_TPM=y CONFIG_TCG_TPM=y
CONFIG_TCG_TIS_I2C_NUVOTON=y CONFIG_TCG_TIS_I2C_NUVOTON=y
# CONFIG_DEVPORT is not set
CONFIG_I2C=y CONFIG_I2C=y
# CONFIG_I2C_COMPAT is not set # CONFIG_I2C_COMPAT is not set
CONFIG_I2C_CHARDEV=y CONFIG_I2C_CHARDEV=y
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <asm/epapr_hcalls.h> #include <asm/epapr_hcalls.h>
#include <asm/dcr.h> #include <asm/dcr.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
#include <asm/ultravisor-api.h>
#include <uapi/asm/ucontext.h> #include <uapi/asm/ucontext.h>
...@@ -34,6 +35,16 @@ extern struct static_key hcall_tracepoint_key; ...@@ -34,6 +35,16 @@ extern struct static_key hcall_tracepoint_key;
void __trace_hcall_entry(unsigned long opcode, unsigned long *args); void __trace_hcall_entry(unsigned long opcode, unsigned long *args);
void __trace_hcall_exit(long opcode, long retval, unsigned long *retbuf); void __trace_hcall_exit(long opcode, long retval, unsigned long *retbuf);
/* Ultravisor */
#if defined(CONFIG_PPC_POWERNV) || defined(CONFIG_PPC_SVM)
long ucall_norets(unsigned long opcode, ...);
#else
static inline long ucall_norets(unsigned long opcode, ...)
{
return U_NOT_AVAILABLE;
}
#endif
/* OPAL */ /* OPAL */
int64_t __opal_call(int64_t a0, int64_t a1, int64_t a2, int64_t a3, int64_t __opal_call(int64_t a0, int64_t a1, int64_t a2, int64_t a3,
int64_t a4, int64_t a5, int64_t a6, int64_t a7, int64_t a4, int64_t a5, int64_t a6, int64_t a7,
...@@ -123,7 +134,8 @@ extern int __ucmpdi2(u64, u64); ...@@ -123,7 +134,8 @@ extern int __ucmpdi2(u64, u64);
/* tracing */ /* tracing */
void _mcount(void); void _mcount(void);
unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip); unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip,
unsigned long sp);
void pnv_power9_force_smt4_catch(void); void pnv_power9_force_smt4_catch(void);
void pnv_power9_force_smt4_release(void); void pnv_power9_force_smt4_release(void);
......
...@@ -148,23 +148,21 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot); ...@@ -148,23 +148,21 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
*/ */
#include <asm/fixmap.h> #include <asm/fixmap.h>
#ifdef CONFIG_HIGHMEM
#define KVIRT_TOP PKMAP_BASE
#else
#define KVIRT_TOP FIXADDR_START
#endif
/* /*
* ioremap_bot starts at that address. Early ioremaps move down from there, * ioremap_bot starts at that address. Early ioremaps move down from there,
* until mem_init() at which point this becomes the top of the vmalloc * until mem_init() at which point this becomes the top of the vmalloc
* and ioremap space * and ioremap space
*/ */
#ifdef CONFIG_NOT_COHERENT_CACHE #ifdef CONFIG_HIGHMEM
#define IOREMAP_TOP ((KVIRT_TOP - CONFIG_CONSISTENT_SIZE) & PAGE_MASK) #define IOREMAP_TOP PKMAP_BASE
#else #else
#define IOREMAP_TOP KVIRT_TOP #define IOREMAP_TOP FIXADDR_START
#endif #endif
/* PPC32 shares vmalloc area with ioremap */
#define IOREMAP_START VMALLOC_START
#define IOREMAP_END VMALLOC_END
/* /*
* Just any arbitrary offset to the start of the vmalloc VM area: the * Just any arbitrary offset to the start of the vmalloc VM area: the
* current 16MB value just means that there will be a 64MB "hole" after the * current 16MB value just means that there will be a 64MB "hole" after the
...@@ -201,8 +199,6 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot); ...@@ -201,8 +199,6 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/threads.h> #include <linux/threads.h>
extern unsigned long ioremap_bot;
/* Bits to mask out from a PGD to get to the PUD page */ /* Bits to mask out from a PGD to get to the PUD page */
#define PGD_MASKED_BITS 0 #define PGD_MASKED_BITS 0
......
...@@ -206,7 +206,6 @@ extern int mmu_io_psize; ...@@ -206,7 +206,6 @@ extern int mmu_io_psize;
void mmu_early_init_devtree(void); void mmu_early_init_devtree(void);
void hash__early_init_devtree(void); void hash__early_init_devtree(void);
void radix__early_init_devtree(void); void radix__early_init_devtree(void);
extern void radix_init_native(void);
extern void hash__early_init_mmu(void); extern void hash__early_init_mmu(void);
extern void radix__early_init_mmu(void); extern void radix__early_init_mmu(void);
static inline void early_init_mmu(void) static inline void early_init_mmu(void)
...@@ -238,9 +237,6 @@ static inline void setup_initial_memory_limit(phys_addr_t first_memblock_base, ...@@ -238,9 +237,6 @@ static inline void setup_initial_memory_limit(phys_addr_t first_memblock_base,
first_memblock_size); first_memblock_size);
} }
extern int (*register_process_table)(unsigned long base, unsigned long page_size,
unsigned long tbl_size);
#ifdef CONFIG_PPC_PSERIES #ifdef CONFIG_PPC_PSERIES
extern void radix_init_pseries(void); extern void radix_init_pseries(void);
#else #else
......
...@@ -289,7 +289,6 @@ extern unsigned long __kernel_io_end; ...@@ -289,7 +289,6 @@ extern unsigned long __kernel_io_end;
#define KERN_IO_END __kernel_io_end #define KERN_IO_END __kernel_io_end
extern struct page *vmemmap; extern struct page *vmemmap;
extern unsigned long ioremap_bot;
extern unsigned long pci_io_base; extern unsigned long pci_io_base;
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
...@@ -317,6 +316,7 @@ extern unsigned long pci_io_base; ...@@ -317,6 +316,7 @@ extern unsigned long pci_io_base;
#define PHB_IO_BASE (ISA_IO_END) #define PHB_IO_BASE (ISA_IO_END)
#define PHB_IO_END (KERN_IO_START + FULL_IO_SIZE) #define PHB_IO_END (KERN_IO_START + FULL_IO_SIZE)
#define IOREMAP_BASE (PHB_IO_END) #define IOREMAP_BASE (PHB_IO_END)
#define IOREMAP_START (ioremap_bot)
#define IOREMAP_END (KERN_IO_END) #define IOREMAP_END (KERN_IO_END)
/* Advertise special mapping type for AGP */ /* Advertise special mapping type for AGP */
...@@ -608,8 +608,10 @@ static inline bool pte_access_permitted(pte_t pte, bool write) ...@@ -608,8 +608,10 @@ static inline bool pte_access_permitted(pte_t pte, bool write)
*/ */
static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
{ {
return __pte((((pte_basic_t)(pfn) << PAGE_SHIFT) & PTE_RPN_MASK) | VM_BUG_ON(pfn >> (64 - PAGE_SHIFT));
pgprot_val(pgprot)); VM_BUG_ON((pfn << PAGE_SHIFT) & ~PTE_RPN_MASK);
return __pte(((pte_basic_t)pfn << PAGE_SHIFT) | pgprot_val(pgprot));
} }
static inline unsigned long pte_pfn(pte_t pte) static inline unsigned long pte_pfn(pte_t pte)
......
...@@ -266,9 +266,6 @@ extern void radix__vmemmap_remove_mapping(unsigned long start, ...@@ -266,9 +266,6 @@ extern void radix__vmemmap_remove_mapping(unsigned long start,
extern int radix__map_kernel_page(unsigned long ea, unsigned long pa, extern int radix__map_kernel_page(unsigned long ea, unsigned long pa,
pgprot_t flags, unsigned int psz); pgprot_t flags, unsigned int psz);
extern int radix__ioremap_range(unsigned long ea, phys_addr_t pa,
unsigned long size, pgprot_t prot, int nid);
static inline unsigned long radix__get_tree_size(void) static inline unsigned long radix__get_tree_size(void)
{ {
unsigned long rts_field; unsigned long rts_field;
......
...@@ -17,8 +17,8 @@ extern void radix__flush_tlb_lpid_page(unsigned int lpid, ...@@ -17,8 +17,8 @@ extern void radix__flush_tlb_lpid_page(unsigned int lpid,
unsigned long addr, unsigned long addr,
unsigned long page_size); unsigned long page_size);
extern void radix__flush_pwc_lpid(unsigned int lpid); extern void radix__flush_pwc_lpid(unsigned int lpid);
extern void radix__flush_tlb_lpid(unsigned int lpid); extern void radix__flush_all_lpid(unsigned int lpid);
extern void radix__local_flush_tlb_lpid_guest(unsigned int lpid); extern void radix__flush_all_lpid_guest(unsigned int lpid);
#else #else
static inline void radix__tlbiel_all(unsigned int action) { WARN_ON(1); }; static inline void radix__tlbiel_all(unsigned int action) { WARN_ON(1); };
static inline void radix__flush_tlb_lpid_page(unsigned int lpid, static inline void radix__flush_tlb_lpid_page(unsigned int lpid,
...@@ -31,11 +31,7 @@ static inline void radix__flush_pwc_lpid(unsigned int lpid) ...@@ -31,11 +31,7 @@ static inline void radix__flush_pwc_lpid(unsigned int lpid)
{ {
WARN_ON(1); WARN_ON(1);
} }
static inline void radix__flush_tlb_lpid(unsigned int lpid) static inline void radix__flush_all_lpid(unsigned int lpid)
{
WARN_ON(1);
}
static inline void radix__local_flush_tlb_lpid_guest(unsigned int lpid)
{ {
WARN_ON(1); WARN_ON(1);
} }
...@@ -73,6 +69,4 @@ extern void radix__flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr); ...@@ -73,6 +69,4 @@ extern void radix__flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr);
extern void radix__flush_tlb_collapsed_pmd(struct mm_struct *mm, unsigned long addr); extern void radix__flush_tlb_collapsed_pmd(struct mm_struct *mm, unsigned long addr);
extern void radix__flush_tlb_all(void); extern void radix__flush_tlb_all(void);
extern void radix__local_flush_tlb_lpid(unsigned int lpid);
#endif #endif
...@@ -162,4 +162,13 @@ static inline void flush_tlb_pgtable(struct mmu_gather *tlb, unsigned long addre ...@@ -162,4 +162,13 @@ static inline void flush_tlb_pgtable(struct mmu_gather *tlb, unsigned long addre
radix__flush_tlb_pwc(tlb, address); radix__flush_tlb_pwc(tlb, address);
} }
extern bool tlbie_capable;
extern bool tlbie_enabled;
static inline bool cputlb_use_tlbie(void)
{
return tlbie_enabled;
}
#endif /* _ASM_POWERPC_BOOK3S_64_TLBFLUSH_H */ #endif /* _ASM_POWERPC_BOOK3S_64_TLBFLUSH_H */
...@@ -26,5 +26,16 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, ...@@ -26,5 +26,16 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot); unsigned long size, pgprot_t vma_prot);
#define __HAVE_PHYS_MEM_ACCESS_PROT #define __HAVE_PHYS_MEM_ACCESS_PROT
/*
* This gets called at the end of handling a page fault, when
* the kernel has put a new PTE into the page table for the process.
* We use it to ensure coherency between the i-cache and d-cache
* for the page which has just been mapped in.
* On machines which use an MMU hash table, we use this to put a
* corresponding HPTE into the hash table ahead of time, instead of
* waiting for the inevitable extra hash-table miss exception.
*/
void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep);
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif #endif
...@@ -5,14 +5,6 @@ ...@@ -5,14 +5,6 @@
#include <asm/asm-compat.h> #include <asm/asm-compat.h>
/*
* Define an illegal instr to trap on the bug.
* We don't use 0 because that marks the end of a function
* in the ELF ABI. That's "Boo Boo" in case you wonder...
*/
#define BUG_OPCODE .long 0x00b00b00 /* For asm */
#define BUG_ILLEGAL_INSTR "0x00b00b00" /* For BUG macro */
#ifdef CONFIG_BUG #ifdef CONFIG_BUG
#ifdef __ASSEMBLY__ #ifdef __ASSEMBLY__
......
...@@ -145,12 +145,10 @@ static inline void cpu_feature_keys_init(void) { } ...@@ -145,12 +145,10 @@ static inline void cpu_feature_keys_init(void) { }
/* Definitions for features that only exist on 32-bit chips */ /* Definitions for features that only exist on 32-bit chips */
#ifdef CONFIG_PPC32 #ifdef CONFIG_PPC32
#define CPU_FTR_601 ASM_CONST(0x00001000)
#define CPU_FTR_L2CR ASM_CONST(0x00002000) #define CPU_FTR_L2CR ASM_CONST(0x00002000)
#define CPU_FTR_SPEC7450 ASM_CONST(0x00004000) #define CPU_FTR_SPEC7450 ASM_CONST(0x00004000)
#define CPU_FTR_TAU ASM_CONST(0x00008000) #define CPU_FTR_TAU ASM_CONST(0x00008000)
#define CPU_FTR_CAN_DOZE ASM_CONST(0x00010000) #define CPU_FTR_CAN_DOZE ASM_CONST(0x00010000)
#define CPU_FTR_USE_RTC ASM_CONST(0x00020000)
#define CPU_FTR_L3CR ASM_CONST(0x00040000) #define CPU_FTR_L3CR ASM_CONST(0x00040000)
#define CPU_FTR_L3_DISABLE_NAP ASM_CONST(0x00080000) #define CPU_FTR_L3_DISABLE_NAP ASM_CONST(0x00080000)
#define CPU_FTR_NAP_DISABLE_L2_PR ASM_CONST(0x00100000) #define CPU_FTR_NAP_DISABLE_L2_PR ASM_CONST(0x00100000)
...@@ -160,14 +158,12 @@ static inline void cpu_feature_keys_init(void) { } ...@@ -160,14 +158,12 @@ static inline void cpu_feature_keys_init(void) { }
#define CPU_FTR_NEED_COHERENT ASM_CONST(0x01000000) #define CPU_FTR_NEED_COHERENT ASM_CONST(0x01000000)
#define CPU_FTR_NO_BTIC ASM_CONST(0x02000000) #define CPU_FTR_NO_BTIC ASM_CONST(0x02000000)
#define CPU_FTR_PPC_LE ASM_CONST(0x04000000) #define CPU_FTR_PPC_LE ASM_CONST(0x04000000)
#define CPU_FTR_UNIFIED_ID_CACHE ASM_CONST(0x08000000)
#define CPU_FTR_SPE ASM_CONST(0x10000000) #define CPU_FTR_SPE ASM_CONST(0x10000000)
#define CPU_FTR_NEED_PAIRED_STWCX ASM_CONST(0x20000000) #define CPU_FTR_NEED_PAIRED_STWCX ASM_CONST(0x20000000)
#define CPU_FTR_INDEXED_DCR ASM_CONST(0x40000000) #define CPU_FTR_INDEXED_DCR ASM_CONST(0x40000000)
#else /* CONFIG_PPC32 */ #else /* CONFIG_PPC32 */
/* Define these to 0 for the sake of tests in common code */ /* Define these to 0 for the sake of tests in common code */
#define CPU_FTR_601 (0)
#define CPU_FTR_PPC_LE (0) #define CPU_FTR_PPC_LE (0)
#endif #endif
...@@ -294,8 +290,8 @@ static inline void cpu_feature_keys_init(void) { } ...@@ -294,8 +290,8 @@ static inline void cpu_feature_keys_init(void) { }
#define CPU_FTR_MAYBE_CAN_NAP 0 #define CPU_FTR_MAYBE_CAN_NAP 0
#endif #endif
#define CPU_FTRS_PPC601 (CPU_FTR_COMMON | CPU_FTR_601 | \ #define CPU_FTRS_PPC601 (CPU_FTR_COMMON | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_USE_RTC) CPU_FTR_COHERENT_ICACHE)
#define CPU_FTRS_603 (CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | \ #define CPU_FTRS_603 (CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | \
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE | CPU_FTR_NOEXECUTE) CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE | CPU_FTR_NOEXECUTE)
#define CPU_FTRS_604 (CPU_FTR_COMMON | CPU_FTR_PPC_LE) #define CPU_FTRS_604 (CPU_FTR_COMMON | CPU_FTR_PPC_LE)
...@@ -386,7 +382,7 @@ static inline void cpu_feature_keys_init(void) { } ...@@ -386,7 +382,7 @@ static inline void cpu_feature_keys_init(void) { }
#define CPU_FTRS_47X (CPU_FTRS_440x6) #define CPU_FTRS_47X (CPU_FTRS_440x6)
#define CPU_FTRS_E200 (CPU_FTR_SPE_COMP | \ #define CPU_FTRS_E200 (CPU_FTR_SPE_COMP | \
CPU_FTR_NODSISRALIGN | CPU_FTR_COHERENT_ICACHE | \ CPU_FTR_NODSISRALIGN | CPU_FTR_COHERENT_ICACHE | \
CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_NOEXECUTE | \ CPU_FTR_NOEXECUTE | \
CPU_FTR_DEBUG_LVL_EXC) CPU_FTR_DEBUG_LVL_EXC)
#define CPU_FTRS_E500 (CPU_FTR_MAYBE_CAN_DOZE | \ #define CPU_FTRS_E500 (CPU_FTR_MAYBE_CAN_DOZE | \
CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN | \ CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN | \
...@@ -498,7 +494,9 @@ static inline void cpu_feature_keys_init(void) { } ...@@ -498,7 +494,9 @@ static inline void cpu_feature_keys_init(void) { }
#else #else
enum { enum {
CPU_FTRS_POSSIBLE = CPU_FTRS_POSSIBLE =
#ifdef CONFIG_PPC_BOOK3S_32 #ifdef CONFIG_PPC_BOOK3S_601
CPU_FTRS_PPC601 |
#elif defined(CONFIG_PPC_BOOK3S_32)
CPU_FTRS_PPC601 | CPU_FTRS_603 | CPU_FTRS_604 | CPU_FTRS_740_NOTAU | CPU_FTRS_PPC601 | CPU_FTRS_603 | CPU_FTRS_604 | CPU_FTRS_740_NOTAU |
CPU_FTRS_740 | CPU_FTRS_750 | CPU_FTRS_750FX1 | CPU_FTRS_740 | CPU_FTRS_750 | CPU_FTRS_750FX1 |
CPU_FTRS_750FX2 | CPU_FTRS_750FX | CPU_FTRS_750GX | CPU_FTRS_750FX2 | CPU_FTRS_750FX | CPU_FTRS_750GX |
...@@ -574,8 +572,10 @@ enum { ...@@ -574,8 +572,10 @@ enum {
#else #else
enum { enum {
CPU_FTRS_ALWAYS = CPU_FTRS_ALWAYS =
#ifdef CONFIG_PPC_BOOK3S_32 #ifdef CONFIG_PPC_BOOK3S_601
CPU_FTRS_PPC601 & CPU_FTRS_603 & CPU_FTRS_604 & CPU_FTRS_740_NOTAU & CPU_FTRS_PPC601 &
#elif defined(CONFIG_PPC_BOOK3S_32)
CPU_FTRS_603 & CPU_FTRS_604 & CPU_FTRS_740_NOTAU &
CPU_FTRS_740 & CPU_FTRS_750 & CPU_FTRS_750FX1 & CPU_FTRS_740 & CPU_FTRS_750 & CPU_FTRS_750FX1 &
CPU_FTRS_750FX2 & CPU_FTRS_750FX & CPU_FTRS_750GX & CPU_FTRS_750FX2 & CPU_FTRS_750FX & CPU_FTRS_750GX &
CPU_FTRS_7400_NOTAU & CPU_FTRS_7400 & CPU_FTRS_7450_20 & CPU_FTRS_7400_NOTAU & CPU_FTRS_7400 & CPU_FTRS_7450_20 &
......
...@@ -16,7 +16,8 @@ static inline struct task_struct *get_current(void) ...@@ -16,7 +16,8 @@ static inline struct task_struct *get_current(void)
{ {
struct task_struct *task; struct task_struct *task;
__asm__ __volatile__("ld %0,%1(13)" /* get_current can be cached by the compiler, so no volatile */
asm ("ld %0,%1(13)"
: "=r" (task) : "=r" (task)
: "i" (offsetof(struct paca_struct, __current))); : "i" (offsetof(struct paca_struct, __current)));
......
...@@ -88,6 +88,19 @@ struct eeh_pe { ...@@ -88,6 +88,19 @@ struct eeh_pe {
struct list_head child_list; /* List of PEs below this PE */ struct list_head child_list; /* List of PEs below this PE */
struct list_head child; /* Memb. child_list/eeh_phb_pe */ struct list_head child; /* Memb. child_list/eeh_phb_pe */
struct list_head edevs; /* List of eeh_dev in this PE */ struct list_head edevs; /* List of eeh_dev in this PE */
#ifdef CONFIG_STACKTRACE
/*
* Saved stack trace. When we find a PE freeze in eeh_dev_check_failure
* the stack trace is saved here so we can print it in the recovery
* thread if it turns out to due to a real problem rather than
* a hot-remove.
*
* A max of 64 entries might be overkill, but it also might not be.
*/
unsigned long stack_trace[64];
int trace_entries;
#endif /* CONFIG_STACKTRACE */
}; };
#define eeh_pe_for_each_dev(pe, edev, tmp) \ #define eeh_pe_for_each_dev(pe, edev, tmp) \
...@@ -121,6 +134,8 @@ static inline bool eeh_pe_passed(struct eeh_pe *pe) ...@@ -121,6 +134,8 @@ static inline bool eeh_pe_passed(struct eeh_pe *pe)
struct eeh_dev { struct eeh_dev {
int mode; /* EEH mode */ int mode; /* EEH mode */
int class_code; /* Class code of the device */ int class_code; /* Class code of the device */
int bdfn; /* bdfn of device (for cfg ops) */
struct pci_controller *controller;
int pe_config_addr; /* PE config address */ int pe_config_addr; /* PE config address */
u32 config_space[16]; /* Saved PCI config space */ u32 config_space[16]; /* Saved PCI config space */
int pcix_cap; /* Saved PCIx capability */ int pcix_cap; /* Saved PCIx capability */
...@@ -136,6 +151,17 @@ struct eeh_dev { ...@@ -136,6 +151,17 @@ struct eeh_dev {
struct pci_dev *physfn; /* Associated SRIOV PF */ struct pci_dev *physfn; /* Associated SRIOV PF */
}; };
/* "fmt" must be a simple literal string */
#define EEH_EDEV_PRINT(level, edev, fmt, ...) \
pr_##level("PCI %04x:%02x:%02x.%x#%04x: EEH: " fmt, \
(edev)->controller->global_number, PCI_BUSNO((edev)->bdfn), \
PCI_SLOT((edev)->bdfn), PCI_FUNC((edev)->bdfn), \
((edev)->pe ? (edev)->pe_config_addr : 0xffff), ##__VA_ARGS__)
#define eeh_edev_dbg(edev, fmt, ...) EEH_EDEV_PRINT(debug, (edev), fmt, ##__VA_ARGS__)
#define eeh_edev_info(edev, fmt, ...) EEH_EDEV_PRINT(info, (edev), fmt, ##__VA_ARGS__)
#define eeh_edev_warn(edev, fmt, ...) EEH_EDEV_PRINT(warn, (edev), fmt, ##__VA_ARGS__)
#define eeh_edev_err(edev, fmt, ...) EEH_EDEV_PRINT(err, (edev), fmt, ##__VA_ARGS__)
static inline struct pci_dn *eeh_dev_to_pdn(struct eeh_dev *edev) static inline struct pci_dn *eeh_dev_to_pdn(struct eeh_dev *edev)
{ {
return edev ? edev->pdn : NULL; return edev ? edev->pdn : NULL;
...@@ -247,7 +273,7 @@ static inline bool eeh_state_active(int state) ...@@ -247,7 +273,7 @@ static inline bool eeh_state_active(int state)
== (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE); == (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE);
} }
typedef void *(*eeh_edev_traverse_func)(struct eeh_dev *edev, void *flag); typedef void (*eeh_edev_traverse_func)(struct eeh_dev *edev, void *flag);
typedef void *(*eeh_pe_traverse_func)(struct eeh_pe *pe, void *flag); typedef void *(*eeh_pe_traverse_func)(struct eeh_pe *pe, void *flag);
void eeh_set_pe_aux_size(int size); void eeh_set_pe_aux_size(int size);
int eeh_phb_pe_create(struct pci_controller *phb); int eeh_phb_pe_create(struct pci_controller *phb);
...@@ -261,20 +287,20 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev); ...@@ -261,20 +287,20 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev);
void eeh_pe_update_time_stamp(struct eeh_pe *pe); void eeh_pe_update_time_stamp(struct eeh_pe *pe);
void *eeh_pe_traverse(struct eeh_pe *root, void *eeh_pe_traverse(struct eeh_pe *root,
eeh_pe_traverse_func fn, void *flag); eeh_pe_traverse_func fn, void *flag);
void *eeh_pe_dev_traverse(struct eeh_pe *root, void eeh_pe_dev_traverse(struct eeh_pe *root,
eeh_edev_traverse_func fn, void *flag); eeh_edev_traverse_func fn, void *flag);
void eeh_pe_restore_bars(struct eeh_pe *pe); void eeh_pe_restore_bars(struct eeh_pe *pe);
const char *eeh_pe_loc_get(struct eeh_pe *pe); const char *eeh_pe_loc_get(struct eeh_pe *pe);
struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe); struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe);
struct eeh_dev *eeh_dev_init(struct pci_dn *pdn); struct eeh_dev *eeh_dev_init(struct pci_dn *pdn);
void eeh_dev_phb_init_dynamic(struct pci_controller *phb); void eeh_dev_phb_init_dynamic(struct pci_controller *phb);
void eeh_probe_devices(void); void eeh_show_enabled(void);
int __init eeh_ops_register(struct eeh_ops *ops); int __init eeh_ops_register(struct eeh_ops *ops);
int __exit eeh_ops_unregister(const char *name); int __exit eeh_ops_unregister(const char *name);
int eeh_check_failure(const volatile void __iomem *token); int eeh_check_failure(const volatile void __iomem *token);
int eeh_dev_check_failure(struct eeh_dev *edev); int eeh_dev_check_failure(struct eeh_dev *edev);
void eeh_addr_cache_build(void); void eeh_addr_cache_init(void);
void eeh_add_device_early(struct pci_dn *); void eeh_add_device_early(struct pci_dn *);
void eeh_add_device_tree_early(struct pci_dn *); void eeh_add_device_tree_early(struct pci_dn *);
void eeh_add_device_late(struct pci_dev *); void eeh_add_device_late(struct pci_dev *);
...@@ -316,7 +342,7 @@ static inline bool eeh_enabled(void) ...@@ -316,7 +342,7 @@ static inline bool eeh_enabled(void)
return false; return false;
} }
static inline void eeh_probe_devices(void) { } static inline void eeh_show_enabled(void) { }
static inline void *eeh_dev_init(struct pci_dn *pdn, void *data) static inline void *eeh_dev_init(struct pci_dn *pdn, void *data)
{ {
...@@ -332,7 +358,7 @@ static inline int eeh_check_failure(const volatile void __iomem *token) ...@@ -332,7 +358,7 @@ static inline int eeh_check_failure(const volatile void __iomem *token)
#define eeh_dev_check_failure(x) (0) #define eeh_dev_check_failure(x) (0)
static inline void eeh_addr_cache_build(void) { } static inline void eeh_addr_cache_init(void) { }
static inline void eeh_add_device_early(struct pci_dn *pdn) { } static inline void eeh_add_device_early(struct pci_dn *pdn) { }
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* PowerPC ELF notes.
*
* Copyright 2019, IBM Corporation
*/
#ifndef __ASM_POWERPC_ELFNOTE_H__
#define __ASM_POWERPC_ELFNOTE_H__
/*
* These note types should live in a SHT_NOTE segment and have
* "PowerPC" in the name field.
*/
/*
* The capabilities supported/required by this kernel (bitmap).
*
* This type uses a bitmap as "desc" field. Each bit is described
* in arch/powerpc/kernel/note.S
*/
#define PPC_ELFNOTE_CAPABILITIES 1
#endif /* __ASM_POWERPC_ELFNOTE_H__ */
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Firmware-Assisted Dump internal code.
*
* Copyright 2011, Mahesh Salgaonkar, IBM Corporation.
* Copyright 2019, Hari Bathini, IBM Corporation.
*/
#ifndef _ASM_POWERPC_FADUMP_INTERNAL_H
#define _ASM_POWERPC_FADUMP_INTERNAL_H
/* Maximum number of memory regions kernel supports */
#define FADUMP_MAX_MEM_REGS 128
#ifndef CONFIG_PRESERVE_FA_DUMP
/* The upper limit percentage for user specified boot memory size (25%) */
#define MAX_BOOT_MEM_RATIO 4
#define memblock_num_regions(memblock_type) (memblock.memblock_type.cnt)
/* Alignment per CMA requirement. */
#define FADUMP_CMA_ALIGNMENT (PAGE_SIZE << \
max_t(unsigned long, MAX_ORDER - 1, \
pageblock_order))
/* FAD commands */
#define FADUMP_REGISTER 1
#define FADUMP_UNREGISTER 2
#define FADUMP_INVALIDATE 3
/*
* Copy the ascii values for first 8 characters from a string into u64
* variable at their respective indexes.
* e.g.
* The string "FADMPINF" will be converted into 0x4641444d50494e46
*/
static inline u64 fadump_str_to_u64(const char *str)
{
u64 val = 0;
int i;
for (i = 0; i < sizeof(val); i++)
val = (*str) ? (val << 8) | *str++ : val << 8;
return val;
}
#define FADUMP_CPU_UNKNOWN (~((u32)0))
#define FADUMP_CRASH_INFO_MAGIC fadump_str_to_u64("FADMPINF")
/* fadump crash info structure */
struct fadump_crash_info_header {
u64 magic_number;
u64 elfcorehdr_addr;
u32 crashing_cpu;
struct pt_regs regs;
struct cpumask online_mask;
};
struct fadump_memory_range {
u64 base;
u64 size;
};
/* fadump memory ranges info */
struct fadump_mrange_info {
char name[16];
struct fadump_memory_range *mem_ranges;
u32 mem_ranges_sz;
u32 mem_range_cnt;
u32 max_mem_ranges;
};
/* Platform specific callback functions */
struct fadump_ops;
/* Firmware-assisted dump configuration details. */
struct fw_dump {
unsigned long reserve_dump_area_start;
unsigned long reserve_dump_area_size;
/* cmd line option during boot */
unsigned long reserve_bootvar;
unsigned long cpu_state_data_size;
u64 cpu_state_dest_vaddr;
u32 cpu_state_data_version;
u32 cpu_state_entry_size;
unsigned long hpte_region_size;
unsigned long boot_memory_size;
u64 boot_mem_dest_addr;
u64 boot_mem_addr[FADUMP_MAX_MEM_REGS];
u64 boot_mem_sz[FADUMP_MAX_MEM_REGS];
u64 boot_mem_top;
u64 boot_mem_regs_cnt;
unsigned long fadumphdr_addr;
unsigned long cpu_notes_buf_vaddr;
unsigned long cpu_notes_buf_size;
/*
* Maximum size supported by firmware to copy from source to
* destination address per entry.
*/
u64 max_copy_size;
u64 kernel_metadata;
int ibm_configure_kernel_dump;
unsigned long fadump_enabled:1;
unsigned long fadump_supported:1;
unsigned long dump_active:1;
unsigned long dump_registered:1;
unsigned long nocma:1;
struct fadump_ops *ops;
};
struct fadump_ops {
u64 (*fadump_init_mem_struct)(struct fw_dump *fadump_conf);
u64 (*fadump_get_metadata_size)(void);
int (*fadump_setup_metadata)(struct fw_dump *fadump_conf);
u64 (*fadump_get_bootmem_min)(void);
int (*fadump_register)(struct fw_dump *fadump_conf);
int (*fadump_unregister)(struct fw_dump *fadump_conf);
int (*fadump_invalidate)(struct fw_dump *fadump_conf);
void (*fadump_cleanup)(struct fw_dump *fadump_conf);
int (*fadump_process)(struct fw_dump *fadump_conf);
void (*fadump_region_show)(struct fw_dump *fadump_conf,
struct seq_file *m);
void (*fadump_trigger)(struct fadump_crash_info_header *fdh,
const char *msg);
};
/* Helper functions */
s32 fadump_setup_cpu_notes_buf(u32 num_cpus);
void fadump_free_cpu_notes_buf(void);
u32 *fadump_regs_to_elf_notes(u32 *buf, struct pt_regs *regs);
void fadump_update_elfcore_header(char *bufp);
bool is_fadump_boot_mem_contiguous(void);
bool is_fadump_reserved_mem_contiguous(void);
#else /* !CONFIG_PRESERVE_FA_DUMP */
/* Firmware-assisted dump configuration details. */
struct fw_dump {
u64 boot_mem_top;
u64 dump_active;
};
#endif /* CONFIG_PRESERVE_FA_DUMP */
#ifdef CONFIG_PPC_PSERIES
extern void rtas_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node);
#else
static inline void
rtas_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node) { }
#endif
#ifdef CONFIG_PPC_POWERNV
extern void opal_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node);
#else
static inline void
opal_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node) { }
#endif
#endif /* _ASM_POWERPC_FADUMP_INTERNAL_H */
...@@ -6,196 +6,14 @@ ...@@ -6,196 +6,14 @@
* Author: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> * Author: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
*/ */
#ifndef __PPC64_FA_DUMP_H__ #ifndef _ASM_POWERPC_FADUMP_H
#define __PPC64_FA_DUMP_H__ #define _ASM_POWERPC_FADUMP_H
#ifdef CONFIG_FA_DUMP #ifdef CONFIG_FA_DUMP
/*
* The RMA region will be saved for later dumping when kernel crashes.
* RMA is Real Mode Area, the first block of logical memory address owned
* by logical partition, containing the storage that may be accessed with
* translate off.
*/
#define RMA_START 0x0
#define RMA_END (ppc64_rma_size)
/*
* On some Power systems where RMO is 128MB, it still requires minimum of
* 256MB for kernel to boot successfully. When kdump infrastructure is
* configured to save vmcore over network, we run into OOM issue while
* loading modules related to network setup. Hence we need aditional 64M
* of memory to avoid OOM issue.
*/
#define MIN_BOOT_MEM (((RMA_END < (0x1UL << 28)) ? (0x1UL << 28) : RMA_END) \
+ (0x1UL << 26))
/* The upper limit percentage for user specified boot memory size (25%) */
#define MAX_BOOT_MEM_RATIO 4
#define memblock_num_regions(memblock_type) (memblock.memblock_type.cnt)
/* Alignement per CMA requirement. */
#define FADUMP_CMA_ALIGNMENT (PAGE_SIZE << \
max_t(unsigned long, MAX_ORDER - 1, pageblock_order))
/* Firmware provided dump sections */
#define FADUMP_CPU_STATE_DATA 0x0001
#define FADUMP_HPTE_REGION 0x0002
#define FADUMP_REAL_MODE_REGION 0x0011
/* Dump request flag */
#define FADUMP_REQUEST_FLAG 0x00000001
/* FAD commands */
#define FADUMP_REGISTER 1
#define FADUMP_UNREGISTER 2
#define FADUMP_INVALIDATE 3
/* Dump status flag */
#define FADUMP_ERROR_FLAG 0x2000
#define FADUMP_CPU_ID_MASK ((1UL << 32) - 1)
#define CPU_UNKNOWN (~((u32)0))
/* Utility macros */
#define SKIP_TO_NEXT_CPU(reg_entry) \
({ \
while (be64_to_cpu(reg_entry->reg_id) != REG_ID("CPUEND")) \
reg_entry++; \
reg_entry++; \
})
extern int crashing_cpu; extern int crashing_cpu;
/* Kernel Dump section info */
struct fadump_section {
__be32 request_flag;
__be16 source_data_type;
__be16 error_flags;
__be64 source_address;
__be64 source_len;
__be64 bytes_dumped;
__be64 destination_address;
};
/* ibm,configure-kernel-dump header. */
struct fadump_section_header {
__be32 dump_format_version;
__be16 dump_num_sections;
__be16 dump_status_flag;
__be32 offset_first_dump_section;
/* Fields for disk dump option. */
__be32 dd_block_size;
__be64 dd_block_offset;
__be64 dd_num_blocks;
__be32 dd_offset_disk_path;
/* Maximum time allowed to prevent an automatic dump-reboot. */
__be32 max_time_auto;
};
/*
* Firmware Assisted dump memory structure. This structure is required for
* registering future kernel dump with power firmware through rtas call.
*
* No disk dump option. Hence disk dump path string section is not included.
*/
struct fadump_mem_struct {
struct fadump_section_header header;
/* Kernel dump sections */
struct fadump_section cpu_state_data;
struct fadump_section hpte_region;
struct fadump_section rmr_region;
};
/* Firmware-assisted dump configuration details. */
struct fw_dump {
unsigned long cpu_state_data_size;
unsigned long hpte_region_size;
unsigned long boot_memory_size;
unsigned long reserve_dump_area_start;
unsigned long reserve_dump_area_size;
/* cmd line option during boot */
unsigned long reserve_bootvar;
unsigned long fadumphdr_addr;
unsigned long cpu_notes_buf;
unsigned long cpu_notes_buf_size;
int ibm_configure_kernel_dump;
unsigned long fadump_enabled:1;
unsigned long fadump_supported:1;
unsigned long dump_active:1;
unsigned long dump_registered:1;
unsigned long nocma:1;
};
/*
* Copy the ascii values for first 8 characters from a string into u64
* variable at their respective indexes.
* e.g.
* The string "FADMPINF" will be converted into 0x4641444d50494e46
*/
static inline u64 str_to_u64(const char *str)
{
u64 val = 0;
int i;
for (i = 0; i < sizeof(val); i++)
val = (*str) ? (val << 8) | *str++ : val << 8;
return val;
}
#define STR_TO_HEX(x) str_to_u64(x)
#define REG_ID(x) str_to_u64(x)
#define FADUMP_CRASH_INFO_MAGIC STR_TO_HEX("FADMPINF")
#define REGSAVE_AREA_MAGIC STR_TO_HEX("REGSAVE")
/* The firmware-assisted dump format.
*
* The register save area is an area in the partition's memory used to preserve
* the register contents (CPU state data) for the active CPUs during a firmware
* assisted dump. The dump format contains register save area header followed
* by register entries. Each list of registers for a CPU starts with
* "CPUSTRT" and ends with "CPUEND".
*/
/* Register save area header. */
struct fadump_reg_save_area_header {
__be64 magic_number;
__be32 version;
__be32 num_cpu_offset;
};
/* Register entry. */
struct fadump_reg_entry {
__be64 reg_id;
__be64 reg_value;
};
/* fadump crash info structure */
struct fadump_crash_info_header {
u64 magic_number;
u64 elfcorehdr_addr;
u32 crashing_cpu;
struct pt_regs regs;
struct cpumask online_mask;
};
struct fad_crash_memory_ranges {
unsigned long long base;
unsigned long long size;
};
extern int is_fadump_memory_area(u64 addr, ulong size); extern int is_fadump_memory_area(u64 addr, ulong size);
extern int early_init_dt_scan_fw_dump(unsigned long node,
const char *uname, int depth, void *data);
extern int fadump_reserve_mem(void);
extern int setup_fadump(void); extern int setup_fadump(void);
extern int is_fadump_active(void); extern int is_fadump_active(void);
extern int should_fadump_crash(void); extern int should_fadump_crash(void);
...@@ -207,5 +25,11 @@ static inline int is_fadump_active(void) { return 0; } ...@@ -207,5 +25,11 @@ static inline int is_fadump_active(void) { return 0; }
static inline int should_fadump_crash(void) { return 0; } static inline int should_fadump_crash(void) { return 0; }
static inline void crash_fadump(struct pt_regs *regs, const char *str) { } static inline void crash_fadump(struct pt_regs *regs, const char *str) { }
static inline void fadump_cleanup(void) { } static inline void fadump_cleanup(void) { }
#endif /* !CONFIG_FA_DUMP */
#if defined(CONFIG_FA_DUMP) || defined(CONFIG_PRESERVE_FA_DUMP)
extern int early_init_dt_scan_fw_dump(unsigned long node, const char *uname,
int depth, void *data);
extern int fadump_reserve_mem(void);
#endif #endif
#endif #endif /* _ASM_POWERPC_FADUMP_H */
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#define FW_FEATURE_DRC_INFO ASM_CONST(0x0000000800000000) #define FW_FEATURE_DRC_INFO ASM_CONST(0x0000000800000000)
#define FW_FEATURE_BLOCK_REMOVE ASM_CONST(0x0000001000000000) #define FW_FEATURE_BLOCK_REMOVE ASM_CONST(0x0000001000000000)
#define FW_FEATURE_PAPR_SCM ASM_CONST(0x0000002000000000) #define FW_FEATURE_PAPR_SCM ASM_CONST(0x0000002000000000)
#define FW_FEATURE_ULTRAVISOR ASM_CONST(0x0000004000000000)
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
...@@ -68,9 +69,9 @@ enum { ...@@ -68,9 +69,9 @@ enum {
FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN | FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN |
FW_FEATURE_HPT_RESIZE | FW_FEATURE_DRMEM_V2 | FW_FEATURE_HPT_RESIZE | FW_FEATURE_DRMEM_V2 |
FW_FEATURE_DRC_INFO | FW_FEATURE_BLOCK_REMOVE | FW_FEATURE_DRC_INFO | FW_FEATURE_BLOCK_REMOVE |
FW_FEATURE_PAPR_SCM, FW_FEATURE_PAPR_SCM | FW_FEATURE_ULTRAVISOR,
FW_FEATURE_PSERIES_ALWAYS = 0, FW_FEATURE_PSERIES_ALWAYS = 0,
FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL, FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_ULTRAVISOR,
FW_FEATURE_POWERNV_ALWAYS = 0, FW_FEATURE_POWERNV_ALWAYS = 0,
FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#define MCOUNT_ADDR ((unsigned long)(_mcount)) #define MCOUNT_ADDR ((unsigned long)(_mcount))
#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ #define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */
#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
#ifdef __ASSEMBLY__ #ifdef __ASSEMBLY__
/* Based off of objdump optput from glibc */ /* Based off of objdump optput from glibc */
......
...@@ -60,8 +60,7 @@ static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, ...@@ -60,8 +60,7 @@ static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
pagefault_enable(); pagefault_enable();
if (!ret) *oval = oldval;
*oval = oldval;
prevent_write_to_user(uaddr, sizeof(*uaddr)); prevent_write_to_user(uaddr, sizeof(*uaddr));
return ret; return ret;
......
...@@ -169,47 +169,6 @@ end_##sname: ...@@ -169,47 +169,6 @@ end_##sname:
#define ABS_ADDR(label) (label - fs_label + fs_start) #define ABS_ADDR(label) (label - fs_label + fs_start)
#define EXC_REAL_BEGIN(name, start, size) \
FIXED_SECTION_ENTRY_BEGIN_LOCATION(real_vectors, exc_real_##start##_##name, start, size)
#define EXC_REAL_END(name, start, size) \
FIXED_SECTION_ENTRY_END_LOCATION(real_vectors, exc_real_##start##_##name, start, size)
#define EXC_VIRT_BEGIN(name, start, size) \
FIXED_SECTION_ENTRY_BEGIN_LOCATION(virt_vectors, exc_virt_##start##_##name, start, size)
#define EXC_VIRT_END(name, start, size) \
FIXED_SECTION_ENTRY_END_LOCATION(virt_vectors, exc_virt_##start##_##name, start, size)
#define EXC_COMMON_BEGIN(name) \
USE_TEXT_SECTION(); \
.balign IFETCH_ALIGN_BYTES; \
.global name; \
_ASM_NOKPROBE_SYMBOL(name); \
DEFINE_FIXED_SYMBOL(name); \
name:
#define TRAMP_REAL_BEGIN(name) \
FIXED_SECTION_ENTRY_BEGIN(real_trampolines, name)
#define TRAMP_VIRT_BEGIN(name) \
FIXED_SECTION_ENTRY_BEGIN(virt_trampolines, name)
#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
#define TRAMP_KVM_BEGIN(name) \
TRAMP_VIRT_BEGIN(name)
#else
#define TRAMP_KVM_BEGIN(name)
#endif
#define EXC_REAL_NONE(start, size) \
FIXED_SECTION_ENTRY_BEGIN_LOCATION(real_vectors, exc_real_##start##_##unused, start, size); \
FIXED_SECTION_ENTRY_END_LOCATION(real_vectors, exc_real_##start##_##unused, start, size)
#define EXC_VIRT_NONE(start, size) \
FIXED_SECTION_ENTRY_BEGIN_LOCATION(virt_vectors, exc_virt_##start##_##unused, start, size); \
FIXED_SECTION_ENTRY_END_LOCATION(virt_vectors, exc_virt_##start##_##unused, start, size)
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* _ASM_POWERPC_HEAD_64_H */ #endif /* _ASM_POWERPC_HEAD_64_H */
...@@ -31,9 +31,6 @@ static inline int is_hugepage_only_range(struct mm_struct *mm, ...@@ -31,9 +31,6 @@ static inline int is_hugepage_only_range(struct mm_struct *mm,
return 0; return 0;
} }
void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea,
pte_t pte);
#define __HAVE_ARCH_HUGETLB_FREE_PGD_RANGE #define __HAVE_ARCH_HUGETLB_FREE_PGD_RANGE
void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr, void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr,
unsigned long end, unsigned long floor, unsigned long end, unsigned long floor,
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#ifndef _IO_WORKAROUNDS_H #ifndef _IO_WORKAROUNDS_H
#define _IO_WORKAROUNDS_H #define _IO_WORKAROUNDS_H
#ifdef CONFIG_PPC_IO_WORKAROUNDS
#include <linux/io.h> #include <linux/io.h>
#include <asm/pci-bridge.h> #include <asm/pci-bridge.h>
...@@ -32,4 +33,23 @@ extern int spiderpci_iowa_init(struct iowa_bus *, void *); ...@@ -32,4 +33,23 @@ extern int spiderpci_iowa_init(struct iowa_bus *, void *);
#define SPIDER_PCI_DUMMY_READ 0x0810 #define SPIDER_PCI_DUMMY_READ 0x0810
#define SPIDER_PCI_DUMMY_READ_BASE 0x0814 #define SPIDER_PCI_DUMMY_READ_BASE 0x0814
#endif
#if defined(CONFIG_PPC_IO_WORKAROUNDS) && defined(CONFIG_PPC_INDIRECT_MMIO)
extern bool io_workaround_inited;
static inline bool iowa_is_active(void)
{
return unlikely(io_workaround_inited);
}
#else
static inline bool iowa_is_active(void)
{
return false;
}
#endif
void __iomem *iowa_ioremap(phys_addr_t addr, unsigned long size,
pgprot_t prot, void *caller);
#endif /* _IO_WORKAROUNDS_H */ #endif /* _IO_WORKAROUNDS_H */
...@@ -705,16 +705,9 @@ static inline void iosync(void) ...@@ -705,16 +705,9 @@ static inline void iosync(void)
* create hand-made mappings for use only by the PCI code and cannot * create hand-made mappings for use only by the PCI code and cannot
* currently be hooked. Must be page aligned. * currently be hooked. Must be page aligned.
* *
* * __ioremap is the low level implementation used by ioremap and
* ioremap_prot and cannot be hooked (but can be used by a hook on one
* of the previous ones)
*
* * __ioremap_caller is the same as above but takes an explicit caller * * __ioremap_caller is the same as above but takes an explicit caller
* reference rather than using __builtin_return_address(0) * reference rather than using __builtin_return_address(0)
* *
* * __iounmap, is the low level implementation used by iounmap and cannot
* be hooked (but can be used by a hook on iounmap)
*
*/ */
extern void __iomem *ioremap(phys_addr_t address, unsigned long size); extern void __iomem *ioremap(phys_addr_t address, unsigned long size);
extern void __iomem *ioremap_prot(phys_addr_t address, unsigned long size, extern void __iomem *ioremap_prot(phys_addr_t address, unsigned long size,
...@@ -729,13 +722,14 @@ void __iomem *ioremap_coherent(phys_addr_t address, unsigned long size); ...@@ -729,13 +722,14 @@ void __iomem *ioremap_coherent(phys_addr_t address, unsigned long size);
extern void iounmap(volatile void __iomem *addr); extern void iounmap(volatile void __iomem *addr);
extern void __iomem *__ioremap(phys_addr_t, unsigned long size, int early_ioremap_range(unsigned long ea, phys_addr_t pa,
unsigned long flags); unsigned long size, pgprot_t prot);
void __iomem *do_ioremap(phys_addr_t pa, phys_addr_t offset, unsigned long size,
pgprot_t prot, void *caller);
extern void __iomem *__ioremap_caller(phys_addr_t, unsigned long size, extern void __iomem *__ioremap_caller(phys_addr_t, unsigned long size,
pgprot_t prot, void *caller); pgprot_t prot, void *caller);
extern void __iounmap(volatile void __iomem *addr);
extern void __iomem * __ioremap_at(phys_addr_t pa, void *ea, extern void __iomem * __ioremap_at(phys_addr_t pa, void *ea,
unsigned long size, pgprot_t prot); unsigned long size, pgprot_t prot);
extern void __iounmap_at(void *ea, unsigned long size); extern void __iounmap_at(void *ea, unsigned long size);
......
...@@ -48,15 +48,16 @@ struct iommu_table_ops { ...@@ -48,15 +48,16 @@ struct iommu_table_ops {
* returns old TCE and DMA direction mask. * returns old TCE and DMA direction mask.
* @tce is a physical address. * @tce is a physical address.
*/ */
int (*exchange)(struct iommu_table *tbl, int (*xchg_no_kill)(struct iommu_table *tbl,
long index, long index,
unsigned long *hpa, unsigned long *hpa,
enum dma_data_direction *direction); enum dma_data_direction *direction,
/* Real mode */ bool realmode);
int (*exchange_rm)(struct iommu_table *tbl,
long index, void (*tce_kill)(struct iommu_table *tbl,
unsigned long *hpa, unsigned long index,
enum dma_data_direction *direction); unsigned long pages,
bool realmode);
__be64 *(*useraddrptr)(struct iommu_table *tbl, long index, bool alloc); __be64 *(*useraddrptr)(struct iommu_table *tbl, long index, bool alloc);
#endif #endif
...@@ -111,6 +112,8 @@ struct iommu_table { ...@@ -111,6 +112,8 @@ struct iommu_table {
struct iommu_table_ops *it_ops; struct iommu_table_ops *it_ops;
struct kref it_kref; struct kref it_kref;
int it_nid; int it_nid;
unsigned long it_reserved_start; /* Start of not-DMA-able (MMIO) area */
unsigned long it_reserved_end;
}; };
#define IOMMU_TABLE_USERSPACE_ENTRY_RO(tbl, entry) \ #define IOMMU_TABLE_USERSPACE_ENTRY_RO(tbl, entry) \
...@@ -149,8 +152,9 @@ extern int iommu_tce_table_put(struct iommu_table *tbl); ...@@ -149,8 +152,9 @@ 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
*/ */
extern struct iommu_table *iommu_init_table(struct iommu_table * tbl, extern struct iommu_table *iommu_init_table(struct iommu_table *tbl,
int nid); int nid, unsigned long res_start, unsigned long res_end);
#define IOMMU_TABLE_GROUP_MAX_TABLES 2 #define IOMMU_TABLE_GROUP_MAX_TABLES 2
struct iommu_table_group; struct iommu_table_group;
...@@ -206,6 +210,12 @@ extern void iommu_del_device(struct device *dev); ...@@ -206,6 +210,12 @@ extern void iommu_del_device(struct device *dev);
extern long iommu_tce_xchg(struct mm_struct *mm, struct iommu_table *tbl, extern long iommu_tce_xchg(struct mm_struct *mm, struct iommu_table *tbl,
unsigned long entry, unsigned long *hpa, unsigned long entry, unsigned long *hpa,
enum dma_data_direction *direction); enum dma_data_direction *direction);
extern long iommu_tce_xchg_no_kill(struct mm_struct *mm,
struct iommu_table *tbl,
unsigned long entry, unsigned long *hpa,
enum dma_data_direction *direction);
extern void iommu_tce_kill(struct iommu_table *tbl,
unsigned long entry, unsigned long pages);
#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,
......
...@@ -297,6 +297,7 @@ struct kvm_arch { ...@@ -297,6 +297,7 @@ struct kvm_arch {
cpumask_t cpu_in_guest; cpumask_t cpu_in_guest;
u8 radix; u8 radix;
u8 fwnmi_enabled; u8 fwnmi_enabled;
u8 secure_guest;
bool threads_indep; bool threads_indep;
bool nested_enable; bool nested_enable;
pgd_t *pgtable; pgd_t *pgtable;
......
...@@ -3,9 +3,6 @@ ...@@ -3,9 +3,6 @@
#define _ASM_POWERPC_MACHDEP_H #define _ASM_POWERPC_MACHDEP_H
#ifdef __KERNEL__ #ifdef __KERNEL__
/*
*/
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
...@@ -31,10 +28,6 @@ struct pci_host_bridge; ...@@ -31,10 +28,6 @@ struct pci_host_bridge;
struct machdep_calls { struct machdep_calls {
char *name; char *name;
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
void __iomem * (*ioremap)(phys_addr_t addr, unsigned long size,
pgprot_t prot, void *caller);
void (*iounmap)(volatile void __iomem *token);
#ifdef CONFIG_PM #ifdef CONFIG_PM
void (*iommu_save)(void); void (*iommu_save)(void);
void (*iommu_restore)(void); void (*iommu_restore)(void);
......
...@@ -30,6 +30,10 @@ enum MCE_Disposition { ...@@ -30,6 +30,10 @@ enum MCE_Disposition {
enum MCE_Initiator { enum MCE_Initiator {
MCE_INITIATOR_UNKNOWN = 0, MCE_INITIATOR_UNKNOWN = 0,
MCE_INITIATOR_CPU = 1, MCE_INITIATOR_CPU = 1,
MCE_INITIATOR_PCI = 2,
MCE_INITIATOR_ISA = 3,
MCE_INITIATOR_MEMORY= 4,
MCE_INITIATOR_POWERMGM = 5,
}; };
enum MCE_ErrorType { enum MCE_ErrorType {
...@@ -41,6 +45,8 @@ enum MCE_ErrorType { ...@@ -41,6 +45,8 @@ enum MCE_ErrorType {
MCE_ERROR_TYPE_USER = 5, MCE_ERROR_TYPE_USER = 5,
MCE_ERROR_TYPE_RA = 6, MCE_ERROR_TYPE_RA = 6,
MCE_ERROR_TYPE_LINK = 7, MCE_ERROR_TYPE_LINK = 7,
MCE_ERROR_TYPE_DCACHE = 8,
MCE_ERROR_TYPE_ICACHE = 9,
}; };
enum MCE_ErrorClass { enum MCE_ErrorClass {
...@@ -122,7 +128,8 @@ struct machine_check_event { ...@@ -122,7 +128,8 @@ struct machine_check_event {
enum MCE_UeErrorType ue_error_type:8; enum MCE_UeErrorType ue_error_type:8;
u8 effective_address_provided; u8 effective_address_provided;
u8 physical_address_provided; u8 physical_address_provided;
u8 reserved_1[5]; u8 ignore_event;
u8 reserved_1[4];
u64 effective_address; u64 effective_address;
u64 physical_address; u64 physical_address;
u8 reserved_2[8]; u8 reserved_2[8];
...@@ -193,6 +200,7 @@ struct mce_error_info { ...@@ -193,6 +200,7 @@ struct mce_error_info {
enum MCE_Initiator initiator:8; enum MCE_Initiator initiator:8;
enum MCE_ErrorClass error_class:8; enum MCE_ErrorClass error_class:8;
bool sync_error; bool sync_error;
bool ignore_event;
}; };
#define MAX_MC_EVT 100 #define MAX_MC_EVT 100
......
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* SVM helper functions
*
* Copyright 2018 IBM Corporation
*/
#ifndef _ASM_POWERPC_MEM_ENCRYPT_H
#define _ASM_POWERPC_MEM_ENCRYPT_H
#include <asm/svm.h>
static inline bool mem_encrypt_active(void)
{
return is_secure_guest();
}
static inline bool force_dma_unencrypted(struct device *dev)
{
return is_secure_guest();
}
int set_memory_encrypted(unsigned long addr, int numpages);
int set_memory_decrypted(unsigned long addr, int numpages);
#endif /* _ASM_POWERPC_MEM_ENCRYPT_H */
...@@ -257,7 +257,7 @@ extern void radix__mmu_cleanup_all(void); ...@@ -257,7 +257,7 @@ extern void radix__mmu_cleanup_all(void);
/* Functions for creating and updating partition table on POWER9 */ /* Functions for creating and updating partition table on POWER9 */
extern void mmu_partition_table_init(void); extern void mmu_partition_table_init(void);
extern void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0, extern void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
unsigned long dw1); unsigned long dw1, bool flush);
#endif /* CONFIG_PPC64 */ #endif /* CONFIG_PPC64 */
struct mm_struct; struct mm_struct;
......
...@@ -11,8 +11,6 @@ ...@@ -11,8 +11,6 @@
#include <asm/mmu.h> /* For sub-arch specific PPC_PIN_SIZE */ #include <asm/mmu.h> /* For sub-arch specific PPC_PIN_SIZE */
#include <asm/asm-405.h> #include <asm/asm-405.h>
extern unsigned long ioremap_bot;
#ifdef CONFIG_44x #ifdef CONFIG_44x
extern int icache_44x_need_flush; extern int icache_44x_need_flush;
#endif #endif
...@@ -78,23 +76,21 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot); ...@@ -78,23 +76,21 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
*/ */
#include <asm/fixmap.h> #include <asm/fixmap.h>
#ifdef CONFIG_HIGHMEM
#define KVIRT_TOP PKMAP_BASE
#else
#define KVIRT_TOP FIXADDR_START
#endif
/* /*
* ioremap_bot starts at that address. Early ioremaps move down from there, * ioremap_bot starts at that address. Early ioremaps move down from there,
* until mem_init() at which point this becomes the top of the vmalloc * until mem_init() at which point this becomes the top of the vmalloc
* and ioremap space * and ioremap space
*/ */
#ifdef CONFIG_NOT_COHERENT_CACHE #ifdef CONFIG_HIGHMEM
#define IOREMAP_TOP ((KVIRT_TOP - CONFIG_CONSISTENT_SIZE) & PAGE_MASK) #define IOREMAP_TOP PKMAP_BASE
#else #else
#define IOREMAP_TOP KVIRT_TOP #define IOREMAP_TOP FIXADDR_START
#endif #endif
/* PPC32 shares vmalloc area with ioremap */
#define IOREMAP_START VMALLOC_START
#define IOREMAP_END VMALLOC_END
/* /*
* Just any arbitrary offset to the start of the vmalloc VM area: the * Just any arbitrary offset to the start of the vmalloc VM area: the
* current 16MB value just means that there will be a 64MB "hole" after the * current 16MB value just means that there will be a 64MB "hole" after the
......
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
#define PHB_IO_BASE (ISA_IO_END) #define PHB_IO_BASE (ISA_IO_END)
#define PHB_IO_END (KERN_IO_START + FULL_IO_SIZE) #define PHB_IO_END (KERN_IO_START + FULL_IO_SIZE)
#define IOREMAP_BASE (PHB_IO_END) #define IOREMAP_BASE (PHB_IO_END)
#define IOREMAP_START (ioremap_bot)
#define IOREMAP_END (KERN_VIRT_START + KERN_VIRT_SIZE) #define IOREMAP_END (KERN_VIRT_START + KERN_VIRT_SIZE)
......
...@@ -293,5 +293,18 @@ static inline int pgd_huge(pgd_t pgd) ...@@ -293,5 +293,18 @@ static inline int pgd_huge(pgd_t pgd)
#define is_hugepd(hpd) (hugepd_ok(hpd)) #define is_hugepd(hpd) (hugepd_ok(hpd))
#endif #endif
/*
* This gets called at the end of handling a page fault, when
* the kernel has put a new PTE into the page table for the process.
* We use it to ensure coherency between the i-cache and d-cache
* for the page which has just been mapped in.
*/
#if defined(CONFIG_PPC_FSL_BOOK3E) && defined(CONFIG_HUGETLB_PAGE)
void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep);
#else
static inline
void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) {}
#endif
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif #endif
...@@ -208,7 +208,10 @@ ...@@ -208,7 +208,10 @@
#define OPAL_HANDLE_HMI2 166 #define OPAL_HANDLE_HMI2 166
#define OPAL_NX_COPROC_INIT 167 #define OPAL_NX_COPROC_INIT 167
#define OPAL_XIVE_GET_VP_STATE 170 #define OPAL_XIVE_GET_VP_STATE 170
#define OPAL_LAST 170 #define OPAL_MPIPL_UPDATE 173
#define OPAL_MPIPL_REGISTER_TAG 174
#define OPAL_MPIPL_QUERY_TAG 175
#define OPAL_LAST 175
#define QUIESCE_HOLD 1 /* Spin all calls at entry */ #define QUIESCE_HOLD 1 /* Spin all calls at entry */
#define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */ #define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */
...@@ -453,6 +456,7 @@ enum opal_msg_type { ...@@ -453,6 +456,7 @@ enum opal_msg_type {
OPAL_MSG_DPO = 5, OPAL_MSG_DPO = 5,
OPAL_MSG_PRD = 6, OPAL_MSG_PRD = 6,
OPAL_MSG_OCC = 7, OPAL_MSG_OCC = 7,
OPAL_MSG_PRD2 = 8,
OPAL_MSG_TYPE_MAX, OPAL_MSG_TYPE_MAX,
}; };
...@@ -1059,6 +1063,7 @@ enum { ...@@ -1059,6 +1063,7 @@ enum {
OPAL_REBOOT_NORMAL = 0, OPAL_REBOOT_NORMAL = 0,
OPAL_REBOOT_PLATFORM_ERROR = 1, OPAL_REBOOT_PLATFORM_ERROR = 1,
OPAL_REBOOT_FULL_IPL = 2, OPAL_REBOOT_FULL_IPL = 2,
OPAL_REBOOT_MPIPL = 3,
}; };
/* Argument to OPAL_PCI_TCE_KILL */ /* Argument to OPAL_PCI_TCE_KILL */
...@@ -1135,6 +1140,44 @@ enum { ...@@ -1135,6 +1140,44 @@ enum {
#define OPAL_PCI_P2P_LOAD 0x2 #define OPAL_PCI_P2P_LOAD 0x2
#define OPAL_PCI_P2P_STORE 0x4 #define OPAL_PCI_P2P_STORE 0x4
/* MPIPL update operations */
enum opal_mpipl_ops {
OPAL_MPIPL_ADD_RANGE = 0,
OPAL_MPIPL_REMOVE_RANGE = 1,
OPAL_MPIPL_REMOVE_ALL = 2,
OPAL_MPIPL_FREE_PRESERVED_MEMORY = 3,
};
/* Tag will point to various metadata area. Kernel will
* use tag to get metadata value.
*/
enum opal_mpipl_tags {
OPAL_MPIPL_TAG_CPU = 0,
OPAL_MPIPL_TAG_OPAL = 1,
OPAL_MPIPL_TAG_KERNEL = 2,
OPAL_MPIPL_TAG_BOOT_MEM = 3,
};
/* Preserved memory details */
struct opal_mpipl_region {
__be64 src;
__be64 dest;
__be64 size;
};
/* Structure version */
#define OPAL_MPIPL_VERSION 0x01
struct opal_mpipl_fadump {
u8 version;
u8 reserved[7];
__be32 crashing_pir; /* OPAL crashing CPU PIR */
__be32 cpu_data_version;
__be32 cpu_data_size;
__be32 region_cnt;
struct opal_mpipl_region region[];
} __packed;
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* __OPAL_API_H */ #endif /* __OPAL_API_H */
...@@ -39,6 +39,7 @@ int64_t opal_npu_spa_clear_cache(uint64_t phb_id, uint32_t bdfn, ...@@ -39,6 +39,7 @@ int64_t opal_npu_spa_clear_cache(uint64_t phb_id, uint32_t bdfn,
uint64_t PE_handle); uint64_t PE_handle);
int64_t opal_npu_tl_set(uint64_t phb_id, uint32_t bdfn, long cap, int64_t opal_npu_tl_set(uint64_t phb_id, uint32_t bdfn, long cap,
uint64_t rate_phys, uint32_t size); uint64_t rate_phys, uint32_t size);
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,
...@@ -272,7 +273,7 @@ int64_t opal_xive_get_vp_info(uint64_t vp, ...@@ -272,7 +273,7 @@ int64_t opal_xive_get_vp_info(uint64_t vp,
int64_t opal_xive_set_vp_info(uint64_t vp, int64_t opal_xive_set_vp_info(uint64_t vp,
uint64_t flags, uint64_t flags,
uint64_t report_cl_pair); uint64_t report_cl_pair);
int64_t opal_xive_allocate_irq(uint32_t chip_id); int64_t opal_xive_allocate_irq_raw(uint32_t chip_id);
int64_t opal_xive_free_irq(uint32_t girq); int64_t opal_xive_free_irq(uint32_t girq);
int64_t opal_xive_sync(uint32_t type, uint32_t id); int64_t opal_xive_sync(uint32_t type, uint32_t id);
int64_t opal_xive_dump(uint32_t type, uint32_t id); int64_t opal_xive_dump(uint32_t type, uint32_t id);
...@@ -297,6 +298,10 @@ int opal_sensor_group_clear(u32 group_hndl, int token); ...@@ -297,6 +298,10 @@ int opal_sensor_group_clear(u32 group_hndl, int token);
int opal_sensor_group_enable(u32 group_hndl, int token, bool enable); int opal_sensor_group_enable(u32 group_hndl, int token, bool enable);
int opal_nx_coproc_init(uint32_t chip_id, uint32_t ct); int opal_nx_coproc_init(uint32_t chip_id, uint32_t ct);
s64 opal_mpipl_update(enum opal_mpipl_ops op, u64 src, u64 dest, u64 size);
s64 opal_mpipl_register_tag(enum opal_mpipl_tags tag, u64 addr);
s64 opal_mpipl_query_tag(enum opal_mpipl_tags tag, u64 *addr);
s64 opal_signal_system_reset(s32 cpu); s64 opal_signal_system_reset(s32 cpu);
s64 opal_quiesce(u64 shutdown_type, s32 cpu); s64 opal_quiesce(u64 shutdown_type, s32 cpu);
......
...@@ -215,9 +215,19 @@ static inline bool pfn_valid(unsigned long pfn) ...@@ -215,9 +215,19 @@ static inline bool pfn_valid(unsigned long pfn)
/* /*
* gcc miscompiles (unsigned long)(&static_var) - PAGE_OFFSET * gcc miscompiles (unsigned long)(&static_var) - PAGE_OFFSET
* with -mcmodel=medium, so we use & and | instead of - and + on 64-bit. * with -mcmodel=medium, so we use & and | instead of - and + on 64-bit.
* This also results in better code generation.
*/ */
#define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) | PAGE_OFFSET)) #define __va(x) \
#define __pa(x) ((unsigned long)(x) & 0x0fffffffffffffffUL) ({ \
VIRTUAL_BUG_ON((unsigned long)(x) >= PAGE_OFFSET); \
(void *)(unsigned long)((phys_addr_t)(x) | PAGE_OFFSET); \
})
#define __pa(x) \
({ \
VIRTUAL_BUG_ON((unsigned long)(x) < PAGE_OFFSET); \
(unsigned long)(x) & 0x0fffffffffffffffUL; \
})
#else /* 32-bit, non book E */ #else /* 32-bit, non book E */
#define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) + PAGE_OFFSET - MEMORY_START)) #define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) + PAGE_OFFSET - MEMORY_START))
......
...@@ -40,6 +40,8 @@ typedef unsigned long long pte_basic_t; ...@@ -40,6 +40,8 @@ typedef unsigned long long pte_basic_t;
typedef unsigned long pte_basic_t; typedef unsigned long pte_basic_t;
#endif #endif
#include <asm/bug.h>
/* /*
* Clear page using the dcbz instruction, which doesn't cause any * Clear page using the dcbz instruction, which doesn't cause any
* memory traffic (except to write out any cache lines which get * memory traffic (except to write out any cache lines which get
...@@ -49,6 +51,8 @@ static inline void clear_page(void *addr) ...@@ -49,6 +51,8 @@ static inline void clear_page(void *addr)
{ {
unsigned int i; unsigned int i;
WARN_ON((unsigned long)addr & (L1_CACHE_BYTES - 1));
for (i = 0; i < PAGE_SIZE / L1_CACHE_BYTES; i++, addr += L1_CACHE_BYTES) for (i = 0; i < PAGE_SIZE / L1_CACHE_BYTES; i++, addr += L1_CACHE_BYTES)
dcbz(addr); dcbz(addr);
} }
......
...@@ -183,6 +183,7 @@ struct iommu_table; ...@@ -183,6 +183,7 @@ struct iommu_table;
struct pci_dn { struct pci_dn {
int flags; int flags;
#define PCI_DN_FLAG_IOV_VF 0x01 #define PCI_DN_FLAG_IOV_VF 0x01
#define PCI_DN_FLAG_DEAD 0x02 /* Device has been hot-removed */
int busno; /* pci bus number */ int busno; /* pci bus number */
int devfn; /* pci device and function number */ int devfn; /* pci device and function number */
......
...@@ -68,6 +68,8 @@ extern pgd_t swapper_pg_dir[]; ...@@ -68,6 +68,8 @@ extern pgd_t swapper_pg_dir[];
extern void paging_init(void); extern void paging_init(void);
extern unsigned long ioremap_bot;
/* /*
* kern_addr_valid is intended to indicate whether an address is a valid * kern_addr_valid is intended to indicate whether an address is a valid
* kernel address. Most 32-bit archs define it as always true (like this) * kernel address. Most 32-bit archs define it as always true (like this)
...@@ -77,18 +79,6 @@ extern void paging_init(void); ...@@ -77,18 +79,6 @@ extern void paging_init(void);
#include <asm-generic/pgtable.h> #include <asm-generic/pgtable.h>
/*
* This gets called at the end of handling a page fault, when
* the kernel has put a new PTE into the page table for the process.
* We use it to ensure coherency between the i-cache and d-cache
* for the page which has just been mapped in.
* On machines which use an MMU hash table, we use this to put a
* corresponding HPTE into the hash table ahead of time, instead of
* waiting for the inevitable extra hash-table miss exception.
*/
extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);
#ifndef CONFIG_TRANSPARENT_HUGEPAGE #ifndef CONFIG_TRANSPARENT_HUGEPAGE
#define pmd_large(pmd) 0 #define pmd_large(pmd) 0
#endif #endif
......
...@@ -340,6 +340,12 @@ static inline long plpar_set_ciabr(unsigned long ciabr) ...@@ -340,6 +340,12 @@ static inline long plpar_set_ciabr(unsigned long ciabr)
{ {
return 0; return 0;
} }
static inline long plpar_pte_read_4(unsigned long flags, unsigned long ptex,
unsigned long *ptes)
{
return 0;
}
#endif /* CONFIG_PPC_PSERIES */ #endif /* CONFIG_PPC_PSERIES */
#endif /* _ASM_POWERPC_PLPAR_WRAPPERS_H */ #endif /* _ASM_POWERPC_PLPAR_WRAPPERS_H */
...@@ -62,11 +62,6 @@ void eeh_pe_dev_mode_mark(struct eeh_pe *pe, int mode); ...@@ -62,11 +62,6 @@ void eeh_pe_dev_mode_mark(struct eeh_pe *pe, int mode);
void eeh_sysfs_add_device(struct pci_dev *pdev); void eeh_sysfs_add_device(struct pci_dev *pdev);
void eeh_sysfs_remove_device(struct pci_dev *pdev); void eeh_sysfs_remove_device(struct pci_dev *pdev);
static inline const char *eeh_pci_name(struct pci_dev *pdev)
{
return pdev ? pci_name(pdev) : "<null>";
}
static inline const char *eeh_driver_name(struct pci_dev *pdev) static inline const char *eeh_driver_name(struct pci_dev *pdev)
{ {
return (pdev && pdev->driver) ? pdev->driver->name : "<null>"; return (pdev && pdev->driver) ? pdev->driver->name : "<null>";
...@@ -74,6 +69,8 @@ static inline const char *eeh_driver_name(struct pci_dev *pdev) ...@@ -74,6 +69,8 @@ static inline const char *eeh_driver_name(struct pci_dev *pdev)
#endif /* CONFIG_EEH */ #endif /* CONFIG_EEH */
#define PCI_BUSNO(bdfn) ((bdfn >> 8) & 0xff)
#else /* CONFIG_PCI */ #else /* CONFIG_PCI */
static inline void init_pci_config_tokens(void) { } static inline void init_pci_config_tokens(void) { }
#endif /* !CONFIG_PCI */ #endif /* !CONFIG_PCI */
......
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* PowerPC 4xx OCM memory allocation support
*
* (C) Copyright 2009, Applied Micro Circuits Corporation
* Victor Gallardo (vgallardo@amcc.com)
*
* See file CREDITS for list of people who contributed to this
* project.
*/
#ifndef __ASM_POWERPC_PPC4XX_OCM_H__
#define __ASM_POWERPC_PPC4XX_OCM_H__
#define PPC4XX_OCM_NON_CACHED 0
#define PPC4XX_OCM_CACHED 1
#if defined(CONFIG_PPC4xx_OCM)
void *ppc4xx_ocm_alloc(phys_addr_t *phys, int size, int align,
int flags, const char *owner);
void ppc4xx_ocm_free(const void *virt);
#else
#define ppc4xx_ocm_alloc(phys, size, align, flags, owner) NULL
#define ppc4xx_ocm_free(addr) ((void)0)
#endif /* CONFIG_PPC4xx_OCM */
#endif /* __ASM_POWERPC_PPC4XX_OCM_H__ */
...@@ -311,18 +311,48 @@ GLUE(.,name): ...@@ -311,18 +311,48 @@ GLUE(.,name):
addis reg,reg,(name - 0b)@ha; \ addis reg,reg,(name - 0b)@ha; \
addi reg,reg,(name - 0b)@l; addi reg,reg,(name - 0b)@l;
#ifdef __powerpc64__ #if defined(__powerpc64__) && defined(HAVE_AS_ATHIGH)
#ifdef HAVE_AS_ATHIGH
#define __AS_ATHIGH high #define __AS_ATHIGH high
#else #else
#define __AS_ATHIGH h #define __AS_ATHIGH h
#endif #endif
#define LOAD_REG_IMMEDIATE(reg,expr) \
lis reg,(expr)@highest; \ .macro __LOAD_REG_IMMEDIATE_32 r, x
ori reg,reg,(expr)@higher; \ .if (\x) >= 0x8000 || (\x) < -0x8000
rldicr reg,reg,32,31; \ lis \r, (\x)@__AS_ATHIGH
oris reg,reg,(expr)@__AS_ATHIGH; \ .if (\x) & 0xffff != 0
ori reg,reg,(expr)@l; ori \r, \r, (\x)@l
.endif
.else
li \r, (\x)@l
.endif
.endm
.macro __LOAD_REG_IMMEDIATE r, x
.if (\x) >= 0x80000000 || (\x) < -0x80000000
__LOAD_REG_IMMEDIATE_32 \r, (\x) >> 32
sldi \r, \r, 32
.if (\x) & 0xffff0000 != 0
oris \r, \r, (\x)@__AS_ATHIGH
.endif
.if (\x) & 0xffff != 0
ori \r, \r, (\x)@l
.endif
.else
__LOAD_REG_IMMEDIATE_32 \r, \x
.endif
.endm
#ifdef __powerpc64__
#define LOAD_REG_IMMEDIATE(reg, expr) __LOAD_REG_IMMEDIATE reg, expr
#define LOAD_REG_IMMEDIATE_SYM(reg, tmp, expr) \
lis tmp, (expr)@highest; \
lis reg, (expr)@__AS_ATHIGH; \
ori tmp, tmp, (expr)@higher; \
ori reg, reg, (expr)@l; \
rldimi reg, tmp, 32, 0
#define LOAD_REG_ADDR(reg,name) \ #define LOAD_REG_ADDR(reg,name) \
ld reg,name@got(r2) ld reg,name@got(r2)
...@@ -335,11 +365,13 @@ GLUE(.,name): ...@@ -335,11 +365,13 @@ GLUE(.,name):
#else /* 32-bit */ #else /* 32-bit */
#define LOAD_REG_IMMEDIATE(reg,expr) \ #define LOAD_REG_IMMEDIATE(reg, expr) __LOAD_REG_IMMEDIATE_32 reg, expr
#define LOAD_REG_IMMEDIATE_SYM(reg,expr) \
lis reg,(expr)@ha; \ lis reg,(expr)@ha; \
addi reg,reg,(expr)@l; addi reg,reg,(expr)@l;
#define LOAD_REG_ADDR(reg,name) LOAD_REG_IMMEDIATE(reg, name) #define LOAD_REG_ADDR(reg,name) LOAD_REG_IMMEDIATE_SYM(reg, name)
#define LOAD_REG_ADDRBASE(reg, name) lis reg,name@ha #define LOAD_REG_ADDRBASE(reg, name) lis reg,name@ha
#define ADDROFF(name) name@l #define ADDROFF(name) name@l
...@@ -351,19 +383,9 @@ GLUE(.,name): ...@@ -351,19 +383,9 @@ GLUE(.,name):
/* various errata or part fixups */ /* various errata or part fixups */
#ifdef CONFIG_PPC601_SYNC_FIX #ifdef CONFIG_PPC601_SYNC_FIX
#define SYNC \ #define SYNC sync; isync
BEGIN_FTR_SECTION \ #define SYNC_601 sync
sync; \ #define ISYNC_601 isync
isync; \
END_FTR_SECTION_IFSET(CPU_FTR_601)
#define SYNC_601 \
BEGIN_FTR_SECTION \
sync; \
END_FTR_SECTION_IFSET(CPU_FTR_601)
#define ISYNC_601 \
BEGIN_FTR_SECTION \
isync; \
END_FTR_SECTION_IFSET(CPU_FTR_601)
#else #else
#define SYNC #define SYNC
#define SYNC_601 #define SYNC_601
...@@ -389,15 +411,11 @@ END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96) ...@@ -389,15 +411,11 @@ END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96)
#define MFTBU(dest) mfspr dest, SPRN_TBRU #define MFTBU(dest) mfspr dest, SPRN_TBRU
#endif #endif
#ifndef CONFIG_SMP
#define TLBSYNC
#else /* CONFIG_SMP */
/* tlbsync is not implemented on 601 */ /* tlbsync is not implemented on 601 */
#define TLBSYNC \ #if !defined(CONFIG_SMP) || defined(CONFIG_PPC_BOOK3S_601)
BEGIN_FTR_SECTION \ #define TLBSYNC
tlbsync; \ #else
sync; \ #define TLBSYNC tlbsync; sync
END_FTR_SECTION_IFCLR(CPU_FTR_601)
#endif #endif
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
......
...@@ -203,7 +203,11 @@ do { \ ...@@ -203,7 +203,11 @@ do { \
#endif /* __powerpc64__ */ #endif /* __powerpc64__ */
#define arch_has_single_step() (1) #define arch_has_single_step() (1)
#define arch_has_block_step() (!cpu_has_feature(CPU_FTR_601)) #ifndef CONFIG_BOOK3S_601
#define arch_has_block_step() (true)
#else
#define arch_has_block_step() (false)
#endif
#define ARCH_HAS_USER_SINGLE_STEP_REPORT #define ARCH_HAS_USER_SINGLE_STEP_REPORT
/* /*
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#define MSR_TM_LG 32 /* Trans Mem Available */ #define MSR_TM_LG 32 /* Trans Mem Available */
#define MSR_VEC_LG 25 /* Enable AltiVec */ #define MSR_VEC_LG 25 /* Enable AltiVec */
#define MSR_VSX_LG 23 /* Enable VSX */ #define MSR_VSX_LG 23 /* Enable VSX */
#define MSR_S_LG 22 /* Secure state */
#define MSR_POW_LG 18 /* Enable Power Management */ #define MSR_POW_LG 18 /* Enable Power Management */
#define MSR_WE_LG 18 /* Wait State Enable */ #define MSR_WE_LG 18 /* Wait State Enable */
#define MSR_TGPR_LG 17 /* TLB Update registers in use */ #define MSR_TGPR_LG 17 /* TLB Update registers in use */
...@@ -71,11 +72,13 @@ ...@@ -71,11 +72,13 @@
#define MSR_SF __MASK(MSR_SF_LG) /* Enable 64 bit mode */ #define MSR_SF __MASK(MSR_SF_LG) /* Enable 64 bit mode */
#define MSR_ISF __MASK(MSR_ISF_LG) /* Interrupt 64b mode valid on 630 */ #define MSR_ISF __MASK(MSR_ISF_LG) /* Interrupt 64b mode valid on 630 */
#define MSR_HV __MASK(MSR_HV_LG) /* Hypervisor state */ #define MSR_HV __MASK(MSR_HV_LG) /* Hypervisor state */
#define MSR_S __MASK(MSR_S_LG) /* Secure state */
#else #else
/* so tests for these bits fail on 32-bit */ /* so tests for these bits fail on 32-bit */
#define MSR_SF 0 #define MSR_SF 0
#define MSR_ISF 0 #define MSR_ISF 0
#define MSR_HV 0 #define MSR_HV 0
#define MSR_S 0
#endif #endif
/* /*
......
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright 2010 Benjamin Herrenschmidt, IBM Corp
* <benh@kernel.crashing.org>
* and David Gibson, IBM Corporation.
*/
#ifndef _ASM_POWERPC_SCOM_H
#define _ASM_POWERPC_SCOM_H
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
#ifdef CONFIG_PPC_SCOM
/*
* The SCOM bus is a sideband bus used for accessing various internal
* registers of the processor or the chipset. The implementation details
* differ between processors and platforms, and the access method as
* well.
*
* This API allows to "map" ranges of SCOM register numbers associated
* with a given SCOM controller. The later must be represented by a
* device node, though some implementations might support NULL if there
* is no possible ambiguity
*
* Then, scom_read/scom_write can be used to accesses registers inside
* that range. The argument passed is a register number relative to
* the beginning of the range mapped.
*/
typedef void *scom_map_t;
/* Value for an invalid SCOM map */
#define SCOM_MAP_INVALID (NULL)
/* The scom_controller data structure is what the platform passes
* to the core code in scom_init, it provides the actual implementation
* of all the SCOM functions
*/
struct scom_controller {
scom_map_t (*map)(struct device_node *ctrl_dev, u64 reg, u64 count);
void (*unmap)(scom_map_t map);
int (*read)(scom_map_t map, u64 reg, u64 *value);
int (*write)(scom_map_t map, u64 reg, u64 value);
};
extern const struct scom_controller *scom_controller;
/**
* scom_init - Initialize the SCOM backend, called by the platform
* @controller: The platform SCOM controller
*/
static inline void scom_init(const struct scom_controller *controller)
{
scom_controller = controller;
}
/**
* scom_map_ok - Test is a SCOM mapping is successful
* @map: The result of scom_map to test
*/
static inline int scom_map_ok(scom_map_t map)
{
return map != SCOM_MAP_INVALID;
}
/**
* scom_map - Map a block of SCOM registers
* @ctrl_dev: Device node of the SCOM controller
* some implementations allow NULL here
* @reg: first SCOM register to map
* @count: Number of SCOM registers to map
*/
static inline scom_map_t scom_map(struct device_node *ctrl_dev,
u64 reg, u64 count)
{
return scom_controller->map(ctrl_dev, reg, count);
}
/**
* scom_find_parent - Find the SCOM controller for a device
* @dev: OF node of the device
*
* This is not meant for general usage, but in combination with
* scom_map() allows to map registers not represented by the
* device own scom-reg property. Useful for applying HW workarounds
* on things not properly represented in the device-tree for example.
*/
struct device_node *scom_find_parent(struct device_node *dev);
/**
* scom_map_device - Map a device's block of SCOM registers
* @dev: OF node of the device
* @index: Register bank index (index in "scom-reg" property)
*
* This function will use the device-tree binding for SCOM which
* is to follow "scom-parent" properties until it finds a node with
* a "scom-controller" property to find the controller. It will then
* use the "scom-reg" property which is made of reg/count pairs,
* each of them having a size defined by the controller's #scom-cells
* property
*/
extern scom_map_t scom_map_device(struct device_node *dev, int index);
/**
* scom_unmap - Unmap a block of SCOM registers
* @map: Result of scom_map is to be unmapped
*/
static inline void scom_unmap(scom_map_t map)
{
if (scom_map_ok(map))
scom_controller->unmap(map);
}
/**
* scom_read - Read a SCOM register
* @map: Result of scom_map
* @reg: Register index within that map
* @value: Updated with the value read
*
* Returns 0 (success) or a negative error code
*/
static inline int scom_read(scom_map_t map, u64 reg, u64 *value)
{
int rc;
rc = scom_controller->read(map, reg, value);
if (rc)
*value = 0xfffffffffffffffful;
return rc;
}
/**
* scom_write - Write to a SCOM register
* @map: Result of scom_map
* @reg: Register index within that map
* @value: Value to write
*
* Returns 0 (success) or a negative error code
*/
static inline int scom_write(scom_map_t map, u64 reg, u64 value)
{
return scom_controller->write(map, reg, value);
}
#endif /* CONFIG_PPC_SCOM */
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_SCOM_H */
...@@ -61,17 +61,6 @@ static inline int overlaps_kernel_text(unsigned long start, unsigned long end) ...@@ -61,17 +61,6 @@ static inline int overlaps_kernel_text(unsigned long start, unsigned long end)
(unsigned long)_stext < end; (unsigned long)_stext < end;
} }
static inline int overlaps_kvm_tmp(unsigned long start, unsigned long end)
{
#ifdef CONFIG_KVM_GUEST
extern char kvm_tmp[];
return start < (unsigned long)kvm_tmp &&
(unsigned long)&kvm_tmp[1024 * 1024] < end;
#else
return 0;
#endif
}
#ifdef PPC64_ELF_ABI_v1 #ifdef PPC64_ELF_ABI_v1
#define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1 #define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#define JMP_BUF_LEN 23 #define JMP_BUF_LEN 23
extern long setjmp(long *); extern long setjmp(long *) __attribute__((returns_twice));
extern void longjmp(long *, long); extern void longjmp(long *, long) __attribute__((noreturn));
#endif /* _ASM_POWERPC_SETJMP_H */ #endif /* _ASM_POWERPC_SETJMP_H */
...@@ -101,15 +101,43 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock) ...@@ -101,15 +101,43 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)
#if defined(CONFIG_PPC_SPLPAR) #if defined(CONFIG_PPC_SPLPAR)
/* We only yield to the hypervisor if we are in shared processor mode */ /* We only yield to the hypervisor if we are in shared processor mode */
#define SHARED_PROCESSOR (lppaca_shared_proc(local_paca->lppaca_ptr)) void splpar_spin_yield(arch_spinlock_t *lock);
extern void __spin_yield(arch_spinlock_t *lock); void splpar_rw_yield(arch_rwlock_t *lock);
extern void __rw_yield(arch_rwlock_t *lock);
#else /* SPLPAR */ #else /* SPLPAR */
#define __spin_yield(x) barrier() static inline void splpar_spin_yield(arch_spinlock_t *lock) {};
#define __rw_yield(x) barrier() static inline void splpar_rw_yield(arch_rwlock_t *lock) {};
#define SHARED_PROCESSOR 0
#endif #endif
static inline bool is_shared_processor(void)
{
/*
* LPPACA is only available on Pseries so guard anything LPPACA related to
* allow other platforms (which include this common header) to compile.
*/
#ifdef CONFIG_PPC_PSERIES
return (IS_ENABLED(CONFIG_PPC_SPLPAR) &&
lppaca_shared_proc(local_paca->lppaca_ptr));
#else
return false;
#endif
}
static inline void spin_yield(arch_spinlock_t *lock)
{
if (is_shared_processor())
splpar_spin_yield(lock);
else
barrier();
}
static inline void rw_yield(arch_rwlock_t *lock)
{
if (is_shared_processor())
splpar_rw_yield(lock);
else
barrier();
}
static inline void arch_spin_lock(arch_spinlock_t *lock) static inline void arch_spin_lock(arch_spinlock_t *lock)
{ {
while (1) { while (1) {
...@@ -117,8 +145,8 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) ...@@ -117,8 +145,8 @@ static inline void arch_spin_lock(arch_spinlock_t *lock)
break; break;
do { do {
HMT_low(); HMT_low();
if (SHARED_PROCESSOR) if (is_shared_processor())
__spin_yield(lock); splpar_spin_yield(lock);
} while (unlikely(lock->slock != 0)); } while (unlikely(lock->slock != 0));
HMT_medium(); HMT_medium();
} }
...@@ -136,8 +164,8 @@ void arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) ...@@ -136,8 +164,8 @@ void arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags)
local_irq_restore(flags); local_irq_restore(flags);
do { do {
HMT_low(); HMT_low();
if (SHARED_PROCESSOR) if (is_shared_processor())
__spin_yield(lock); splpar_spin_yield(lock);
} while (unlikely(lock->slock != 0)); } while (unlikely(lock->slock != 0));
HMT_medium(); HMT_medium();
local_irq_restore(flags_dis); local_irq_restore(flags_dis);
...@@ -226,8 +254,8 @@ static inline void arch_read_lock(arch_rwlock_t *rw) ...@@ -226,8 +254,8 @@ static inline void arch_read_lock(arch_rwlock_t *rw)
break; break;
do { do {
HMT_low(); HMT_low();
if (SHARED_PROCESSOR) if (is_shared_processor())
__rw_yield(rw); splpar_rw_yield(rw);
} while (unlikely(rw->lock < 0)); } while (unlikely(rw->lock < 0));
HMT_medium(); HMT_medium();
} }
...@@ -240,8 +268,8 @@ static inline void arch_write_lock(arch_rwlock_t *rw) ...@@ -240,8 +268,8 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
break; break;
do { do {
HMT_low(); HMT_low();
if (SHARED_PROCESSOR) if (is_shared_processor())
__rw_yield(rw); splpar_rw_yield(rw);
} while (unlikely(rw->lock != 0)); } while (unlikely(rw->lock != 0));
HMT_medium(); HMT_medium();
} }
...@@ -281,9 +309,9 @@ static inline void arch_write_unlock(arch_rwlock_t *rw) ...@@ -281,9 +309,9 @@ static inline void arch_write_unlock(arch_rwlock_t *rw)
rw->lock = 0; rw->lock = 0;
} }
#define arch_spin_relax(lock) __spin_yield(lock) #define arch_spin_relax(lock) spin_yield(lock)
#define arch_read_relax(lock) __rw_yield(lock) #define arch_read_relax(lock) rw_yield(lock)
#define arch_write_relax(lock) __rw_yield(lock) #define arch_write_relax(lock) rw_yield(lock)
/* See include/linux/spinlock.h */ /* See include/linux/spinlock.h */
#define smp_mb__after_spinlock() smp_mb() #define smp_mb__after_spinlock() smp_mb()
......
...@@ -53,7 +53,9 @@ void *__memmove(void *to, const void *from, __kernel_size_t n); ...@@ -53,7 +53,9 @@ void *__memmove(void *to, const void *from, __kernel_size_t n);
#ifndef CONFIG_KASAN #ifndef CONFIG_KASAN
#define __HAVE_ARCH_MEMSET32 #define __HAVE_ARCH_MEMSET32
#define __HAVE_ARCH_MEMSET64 #define __HAVE_ARCH_MEMSET64
#define __HAVE_ARCH_MEMCPY_MCSAFE
extern int memcpy_mcsafe(void *dst, const void *src, __kernel_size_t sz);
extern void *__memset16(uint16_t *, uint16_t v, __kernel_size_t); extern void *__memset16(uint16_t *, uint16_t v, __kernel_size_t);
extern void *__memset32(uint32_t *, uint32_t v, __kernel_size_t); extern void *__memset32(uint32_t *, uint32_t v, __kernel_size_t);
extern void *__memset64(uint64_t *, uint64_t v, __kernel_size_t); extern void *__memset64(uint64_t *, uint64_t v, __kernel_size_t);
......
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* SVM helper functions
*
* Copyright 2018 Anshuman Khandual, IBM Corporation.
*/
#ifndef _ASM_POWERPC_SVM_H
#define _ASM_POWERPC_SVM_H
#ifdef CONFIG_PPC_SVM
static inline bool is_secure_guest(void)
{
return mfmsr() & MSR_S;
}
void dtl_cache_ctor(void *addr);
#define get_dtl_cache_ctor() (is_secure_guest() ? dtl_cache_ctor : NULL)
#else /* CONFIG_PPC_SVM */
static inline bool is_secure_guest(void)
{
return false;
}
#define get_dtl_cache_ctor() NULL
#endif /* CONFIG_PPC_SVM */
#endif /* _ASM_POWERPC_SVM_H */
...@@ -41,11 +41,7 @@ struct div_result { ...@@ -41,11 +41,7 @@ struct div_result {
/* Accessor functions for the timebase (RTC on 601) registers. */ /* Accessor functions for the timebase (RTC on 601) registers. */
/* If one day CONFIG_POWER is added just define __USE_RTC as 1 */ /* If one day CONFIG_POWER is added just define __USE_RTC as 1 */
#ifdef CONFIG_PPC_BOOK3S_32 #define __USE_RTC() (IS_ENABLED(CONFIG_PPC_BOOK3S_601))
#define __USE_RTC() (cpu_has_feature(CPU_FTR_USE_RTC))
#else
#define __USE_RTC() 0
#endif
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
......
...@@ -17,38 +17,10 @@ typedef unsigned long cycles_t; ...@@ -17,38 +17,10 @@ typedef unsigned long cycles_t;
static inline cycles_t get_cycles(void) static inline cycles_t get_cycles(void)
{ {
#ifdef __powerpc64__ if (IS_ENABLED(CONFIG_BOOK3S_601))
return 0;
return mftb(); return mftb();
#else
cycles_t ret;
/*
* For the "cycle" counter we use the timebase lower half.
* Currently only used on SMP.
*/
ret = 0;
__asm__ __volatile__(
#ifdef CONFIG_PPC_8xx
"97: mftb %0\n"
#else
"97: mfspr %0, %2\n"
#endif
"99:\n"
".section __ftr_fixup,\"a\"\n"
".align 2\n"
"98:\n"
" .long %1\n"
" .long 0\n"
" .long 97b-98b\n"
" .long 99b-98b\n"
" .long 0\n"
" .long 0\n"
".previous"
: "=r" (ret) : "i" (CPU_FTR_601), "i" (SPRN_TBRL));
return ret;
#endif
} }
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -387,6 +387,20 @@ static inline unsigned long raw_copy_to_user(void __user *to, ...@@ -387,6 +387,20 @@ static inline unsigned long raw_copy_to_user(void __user *to,
return ret; return ret;
} }
static __always_inline unsigned long __must_check
copy_to_user_mcsafe(void __user *to, const void *from, unsigned long n)
{
if (likely(check_copy_size(from, n, true))) {
if (access_ok(to, n)) {
allow_write_to_user(to, n);
n = memcpy_mcsafe((void *)to, from, n);
prevent_write_to_user(to, n);
}
}
return n;
}
extern unsigned long __clear_user(void __user *addr, unsigned long size); extern unsigned long __clear_user(void __user *addr, unsigned long size);
static inline unsigned long clear_user(void __user *addr, unsigned long size) static inline unsigned long clear_user(void __user *addr, unsigned long size)
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Ultravisor API.
*
* Copyright 2019, IBM Corporation.
*
*/
#ifndef _ASM_POWERPC_ULTRAVISOR_API_H
#define _ASM_POWERPC_ULTRAVISOR_API_H
#include <asm/hvcall.h>
/* Return codes */
#define U_BUSY H_BUSY
#define U_FUNCTION H_FUNCTION
#define U_NOT_AVAILABLE H_NOT_AVAILABLE
#define U_P2 H_P2
#define U_P3 H_P3
#define U_P4 H_P4
#define U_P5 H_P5
#define U_PARAMETER H_PARAMETER
#define U_PERMISSION H_PERMISSION
#define U_SUCCESS H_SUCCESS
/* opcodes */
#define UV_WRITE_PATE 0xF104
#define UV_RETURN 0xF11C
#define UV_ESM 0xF110
#define UV_SHARE_PAGE 0xF130
#define UV_UNSHARE_PAGE 0xF134
#define UV_UNSHARE_ALL_PAGES 0xF140
#endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Ultravisor definitions
*
* Copyright 2019, IBM Corporation.
*
*/
#ifndef _ASM_POWERPC_ULTRAVISOR_H
#define _ASM_POWERPC_ULTRAVISOR_H
#include <asm/asm-prototypes.h>
#include <asm/ultravisor-api.h>
#include <asm/firmware.h>
int early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
int depth, void *data);
/*
* In ultravisor enabled systems, PTCR becomes ultravisor privileged only for
* writing and an attempt to write to it will cause a Hypervisor Emulation
* Assistance interrupt.
*/
static inline void set_ptcr_when_no_uv(u64 val)
{
if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
mtspr(SPRN_PTCR, val);
}
static inline int uv_register_pate(u64 lpid, u64 dw0, u64 dw1)
{
return ucall_norets(UV_WRITE_PATE, lpid, dw0, dw1);
}
static inline int uv_share_page(u64 pfn, u64 npages)
{
return ucall_norets(UV_SHARE_PAGE, pfn, npages);
}
static inline int uv_unshare_page(u64 pfn, u64 npages)
{
return ucall_norets(UV_UNSHARE_PAGE, pfn, npages);
}
static inline int uv_unshare_all_pages(void)
{
return ucall_norets(UV_UNSHARE_ALL_PAGES);
}
#endif /* _ASM_POWERPC_ULTRAVISOR_H */
...@@ -99,6 +99,7 @@ extern void xive_flush_interrupt(void); ...@@ -99,6 +99,7 @@ extern void xive_flush_interrupt(void);
/* xmon hook */ /* xmon hook */
extern void xmon_xive_do_dump(int cpu); extern void xmon_xive_do_dump(int cpu);
extern int xmon_xive_get_irq_config(u32 hw_irq, struct irq_data *d);
/* APIs used by KVM */ /* APIs used by KVM */
extern u32 xive_native_default_eq_shift(void); extern u32 xive_native_default_eq_shift(void);
......
prom_init_check
vmlinux.lds vmlinux.lds
...@@ -52,7 +52,7 @@ obj-y := cputable.o ptrace.o syscalls.o \ ...@@ -52,7 +52,7 @@ obj-y := cputable.o ptrace.o syscalls.o \
of_platform.o prom_parse.o of_platform.o prom_parse.o
obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \ obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \
signal_64.o ptrace32.o \ signal_64.o ptrace32.o \
paca.o nvram_64.o firmware.o paca.o nvram_64.o firmware.o note.o
obj-$(CONFIG_VDSO32) += vdso32/ obj-$(CONFIG_VDSO32) += vdso32/
obj-$(CONFIG_PPC_WATCHDOG) += watchdog.o obj-$(CONFIG_PPC_WATCHDOG) += watchdog.o
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
...@@ -78,7 +78,9 @@ obj-$(CONFIG_EEH) += eeh.o eeh_pe.o eeh_dev.o eeh_cache.o \ ...@@ -78,7 +78,9 @@ obj-$(CONFIG_EEH) += eeh.o eeh_pe.o eeh_dev.o eeh_cache.o \
eeh_driver.o eeh_event.o eeh_sysfs.o eeh_driver.o eeh_event.o eeh_sysfs.o
obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_FA_DUMP) += fadump.o ifneq ($(CONFIG_FA_DUMP)$(CONFIG_PRESERVE_FA_DUMP),)
obj-y += fadump.o
endif
ifdef CONFIG_PPC32 ifdef CONFIG_PPC32
obj-$(CONFIG_E500) += idle_e500.o obj-$(CONFIG_E500) += idle_e500.o
endif endif
...@@ -155,6 +157,9 @@ endif ...@@ -155,6 +157,9 @@ endif
obj-$(CONFIG_EPAPR_PARAVIRT) += epapr_paravirt.o epapr_hcalls.o obj-$(CONFIG_EPAPR_PARAVIRT) += epapr_paravirt.o epapr_hcalls.o
obj-$(CONFIG_KVM_GUEST) += kvm.o kvm_emul.o obj-$(CONFIG_KVM_GUEST) += kvm.o kvm_emul.o
ifneq ($(CONFIG_PPC_POWERNV)$(CONFIG_PPC_SVM),)
obj-y += ucall.o
endif
# Disable GCOV, KCOV & sanitizers in odd or sensitive code # Disable GCOV, KCOV & sanitizers in odd or sensitive code
GCOV_PROFILE_prom_init.o := n GCOV_PROFILE_prom_init.o := n
...@@ -184,15 +189,13 @@ extra-$(CONFIG_ALTIVEC) += vector.o ...@@ -184,15 +189,13 @@ extra-$(CONFIG_ALTIVEC) += vector.o
extra-$(CONFIG_PPC64) += entry_64.o extra-$(CONFIG_PPC64) += entry_64.o
extra-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init.o extra-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init.o
ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE extra-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init_check
$(obj)/built-in.a: prom_init_check
quiet_cmd_prom_init_check = CALL $< quiet_cmd_prom_init_check = PROMCHK $@
cmd_prom_init_check = $(CONFIG_SHELL) $< "$(NM)" "$(obj)/prom_init.o" cmd_prom_init_check = $(CONFIG_SHELL) $< "$(NM)" $(obj)/prom_init.o; touch $@
PHONY += prom_init_check $(obj)/prom_init_check: $(src)/prom_init_check.sh $(obj)/prom_init.o FORCE
prom_init_check: $(src)/prom_init_check.sh $(obj)/prom_init.o $(call if_changed,prom_init_check)
$(call cmd,prom_init_check) targets += prom_init_check
endif
clean-files := vmlinux.lds clean-files := vmlinux.lds
...@@ -506,6 +506,7 @@ int main(void) ...@@ -506,6 +506,7 @@ int main(void)
OFFSET(KVM_VRMA_SLB_V, kvm, arch.vrma_slb_v); OFFSET(KVM_VRMA_SLB_V, kvm, arch.vrma_slb_v);
OFFSET(KVM_RADIX, kvm, arch.radix); OFFSET(KVM_RADIX, kvm, arch.radix);
OFFSET(KVM_FWNMI, kvm, arch.fwnmi_enabled); OFFSET(KVM_FWNMI, kvm, arch.fwnmi_enabled);
OFFSET(KVM_SECURE_GUEST, kvm, arch.secure_guest);
OFFSET(VCPU_DSISR, kvm_vcpu, arch.shregs.dsisr); OFFSET(VCPU_DSISR, kvm_vcpu, arch.shregs.dsisr);
OFFSET(VCPU_DAR, kvm_vcpu, arch.shregs.dar); OFFSET(VCPU_DAR, kvm_vcpu, arch.shregs.dar);
OFFSET(VCPU_VPA, kvm_vcpu, arch.vpa.pinned_addr); OFFSET(VCPU_VPA, kvm_vcpu, arch.vpa.pinned_addr);
......
...@@ -569,7 +569,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -569,7 +569,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
#endif /* CONFIG_PPC_BOOK3S_64 */ #endif /* CONFIG_PPC_BOOK3S_64 */
#ifdef CONFIG_PPC32 #ifdef CONFIG_PPC32
#ifdef CONFIG_PPC_BOOK3S_32 #ifdef CONFIG_PPC_BOOK3S_601
{ /* 601 */ { /* 601 */
.pvr_mask = 0xffff0000, .pvr_mask = 0xffff0000,
.pvr_value = 0x00010000, .pvr_value = 0x00010000,
...@@ -583,6 +583,8 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -583,6 +583,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
.machine_check = machine_check_generic, .machine_check = machine_check_generic,
.platform = "ppc601", .platform = "ppc601",
}, },
#endif /* CONFIG_PPC_BOOK3S_601 */
#ifdef CONFIG_PPC_BOOK3S_6xx
{ /* 603 */ { /* 603 */
.pvr_mask = 0xffff0000, .pvr_mask = 0xffff0000,
.pvr_value = 0x00030000, .pvr_value = 0x00030000,
...@@ -1212,7 +1214,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1212,7 +1214,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.machine_check = machine_check_generic, .machine_check = machine_check_generic,
.platform = "ppc603", .platform = "ppc603",
}, },
#endif /* CONFIG_PPC_BOOK3S_32 */ #endif /* CONFIG_PPC_BOOK3S_6xx */
#ifdef CONFIG_PPC_8xx #ifdef CONFIG_PPC_8xx
{ /* 8xx */ { /* 8xx */
.pvr_mask = 0xffff0000, .pvr_mask = 0xffff0000,
......
...@@ -122,18 +122,17 @@ int dma_iommu_dma_supported(struct device *dev, u64 mask) ...@@ -122,18 +122,17 @@ int dma_iommu_dma_supported(struct device *dev, u64 mask)
{ {
struct iommu_table *tbl = get_iommu_table_base(dev); struct iommu_table *tbl = get_iommu_table_base(dev);
if (!tbl) {
dev_info(dev, "Warning: IOMMU dma not supported: mask 0x%08llx"
", table unavailable\n", mask);
return 0;
}
if (dev_is_pci(dev) && dma_iommu_bypass_supported(dev, mask)) { if (dev_is_pci(dev) && dma_iommu_bypass_supported(dev, mask)) {
dev->archdata.iommu_bypass = true; dev->archdata.iommu_bypass = true;
dev_dbg(dev, "iommu: 64-bit OK, using fixed ops\n"); dev_dbg(dev, "iommu: 64-bit OK, using fixed ops\n");
return 1; return 1;
} }
if (!tbl) {
dev_err(dev, "Warning: IOMMU dma not supported: mask 0x%08llx, table unavailable\n", mask);
return 0;
}
if (tbl->it_offset > (mask >> tbl->it_page_shift)) { if (tbl->it_offset > (mask >> tbl->it_page_shift)) {
dev_info(dev, "Warning: IOMMU offset too big for device mask\n"); dev_info(dev, "Warning: IOMMU offset too big for device mask\n");
dev_info(dev, "mask: 0x%08llx, table offset: 0x%08lx\n", dev_info(dev, "mask: 0x%08llx, table offset: 0x%08lx\n",
......
This diff is collapsed.
...@@ -148,8 +148,8 @@ eeh_addr_cache_insert(struct pci_dev *dev, resource_size_t alo, ...@@ -148,8 +148,8 @@ eeh_addr_cache_insert(struct pci_dev *dev, resource_size_t alo,
piar->pcidev = dev; piar->pcidev = dev;
piar->flags = flags; piar->flags = flags;
pr_debug("PIAR: insert range=[%pap:%pap] dev=%s\n", eeh_edev_dbg(piar->edev, "PIAR: insert range=[%pap:%pap]\n",
&alo, &ahi, pci_name(dev)); &alo, &ahi);
rb_link_node(&piar->rb_node, parent, p); rb_link_node(&piar->rb_node, parent, p);
rb_insert_color(&piar->rb_node, &pci_io_addr_cache_root.rb_root); rb_insert_color(&piar->rb_node, &pci_io_addr_cache_root.rb_root);
...@@ -229,8 +229,8 @@ static inline void __eeh_addr_cache_rmv_dev(struct pci_dev *dev) ...@@ -229,8 +229,8 @@ static inline void __eeh_addr_cache_rmv_dev(struct pci_dev *dev)
piar = rb_entry(n, struct pci_io_addr_range, rb_node); piar = rb_entry(n, struct pci_io_addr_range, rb_node);
if (piar->pcidev == dev) { if (piar->pcidev == dev) {
pr_debug("PIAR: remove range=[%pap:%pap] dev=%s\n", eeh_edev_dbg(piar->edev, "PIAR: remove range=[%pap:%pap]\n",
&piar->addr_lo, &piar->addr_hi, pci_name(dev)); &piar->addr_lo, &piar->addr_hi);
rb_erase(n, &pci_io_addr_cache_root.rb_root); rb_erase(n, &pci_io_addr_cache_root.rb_root);
kfree(piar); kfree(piar);
goto restart; goto restart;
...@@ -258,37 +258,14 @@ void eeh_addr_cache_rmv_dev(struct pci_dev *dev) ...@@ -258,37 +258,14 @@ void eeh_addr_cache_rmv_dev(struct pci_dev *dev)
} }
/** /**
* eeh_addr_cache_build - Build a cache of I/O addresses * eeh_addr_cache_init - Initialize a cache of I/O addresses
* *
* Build a cache of pci i/o addresses. This cache will be used to * Initialize a cache of pci i/o addresses. This cache will be used to
* find the pci device that corresponds to a given address. * find the pci device that corresponds to a given address.
* This routine scans all pci busses to build the cache.
* Must be run late in boot process, after the pci controllers
* have been scanned for devices (after all device resources are known).
*/ */
void eeh_addr_cache_build(void) void eeh_addr_cache_init(void)
{ {
struct pci_dn *pdn;
struct eeh_dev *edev;
struct pci_dev *dev = NULL;
spin_lock_init(&pci_io_addr_cache_root.piar_lock); spin_lock_init(&pci_io_addr_cache_root.piar_lock);
for_each_pci_dev(dev) {
pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
if (!pdn)
continue;
edev = pdn_to_eeh_dev(pdn);
if (!edev)
continue;
dev->dev.archdata.edev = edev;
edev->pdev = dev;
eeh_addr_cache_insert_dev(dev);
eeh_sysfs_add_device(dev);
}
} }
static int eeh_addr_cache_show(struct seq_file *s, void *v) static int eeh_addr_cache_show(struct seq_file *s, void *v)
......
...@@ -47,6 +47,8 @@ struct eeh_dev *eeh_dev_init(struct pci_dn *pdn) ...@@ -47,6 +47,8 @@ struct eeh_dev *eeh_dev_init(struct pci_dn *pdn)
/* Associate EEH device with OF node */ /* Associate EEH device with OF node */
pdn->edev = edev; pdn->edev = edev;
edev->pdn = pdn; edev->pdn = pdn;
edev->bdfn = (pdn->busno << 8) | pdn->devfn;
edev->controller = pdn->phb;
return edev; return edev;
} }
......
This diff is collapsed.
...@@ -40,7 +40,6 @@ static int eeh_event_handler(void * dummy) ...@@ -40,7 +40,6 @@ static int eeh_event_handler(void * dummy)
{ {
unsigned long flags; unsigned long flags;
struct eeh_event *event; struct eeh_event *event;
struct eeh_pe *pe;
while (!kthread_should_stop()) { while (!kthread_should_stop()) {
if (wait_for_completion_interruptible(&eeh_eventlist_event)) if (wait_for_completion_interruptible(&eeh_eventlist_event))
...@@ -59,19 +58,10 @@ static int eeh_event_handler(void * dummy) ...@@ -59,19 +58,10 @@ static int eeh_event_handler(void * dummy)
continue; continue;
/* We might have event without binding PE */ /* We might have event without binding PE */
pe = event->pe; if (event->pe)
if (pe) { eeh_handle_normal_event(event->pe);
if (pe->type & EEH_PE_PHB) else
pr_info("EEH: Detected error on PHB#%x\n",
pe->phb->global_number);
else
pr_info("EEH: Detected PCI bus error on "
"PHB#%x-PE#%x\n",
pe->phb->global_number, pe->addr);
eeh_handle_normal_event(pe);
} else {
eeh_handle_special_event(); eeh_handle_special_event();
}
kfree(event); kfree(event);
} }
...@@ -121,6 +111,24 @@ int __eeh_send_failure_event(struct eeh_pe *pe) ...@@ -121,6 +111,24 @@ int __eeh_send_failure_event(struct eeh_pe *pe)
} }
event->pe = pe; event->pe = pe;
/*
* Mark the PE as recovering before inserting it in the queue.
* This prevents the PE from being free()ed by a hotplug driver
* while the PE is sitting in the event queue.
*/
if (pe) {
#ifdef CONFIG_STACKTRACE
/*
* Save the current stack trace so we can dump it from the
* event handler thread.
*/
pe->trace_entries = stack_trace_save(pe->stack_trace,
ARRAY_SIZE(pe->stack_trace), 0);
#endif /* CONFIG_STACKTRACE */
eeh_pe_state_mark(pe, EEH_PE_RECOVERING);
}
/* We may or may not be called in an interrupt context */ /* We may or may not be called in an interrupt context */
spin_lock_irqsave(&eeh_eventlist_lock, flags); spin_lock_irqsave(&eeh_eventlist_lock, flags);
list_add(&event->list, &eeh_eventlist); list_add(&event->list, &eeh_eventlist);
......
This diff is collapsed.
This diff is collapsed.
...@@ -69,24 +69,20 @@ BEGIN_FTR_SECTION ...@@ -69,24 +69,20 @@ BEGIN_FTR_SECTION
bne .Ltabort_syscall bne .Ltabort_syscall
END_FTR_SECTION_IFSET(CPU_FTR_TM) END_FTR_SECTION_IFSET(CPU_FTR_TM)
#endif #endif
andi. r10,r12,MSR_PR
mr r10,r1 mr r10,r1
addi r1,r1,-INT_FRAME_SIZE
beq- 1f
ld r1,PACAKSAVE(r13) ld r1,PACAKSAVE(r13)
1: std r10,0(r1) std r10,0(r1)
std r11,_NIP(r1) std r11,_NIP(r1)
std r12,_MSR(r1) std r12,_MSR(r1)
std r0,GPR0(r1) std r0,GPR0(r1)
std r10,GPR1(r1) std r10,GPR1(r1)
beq 2f /* if from kernel mode */
#ifdef CONFIG_PPC_FSL_BOOK3E #ifdef CONFIG_PPC_FSL_BOOK3E
START_BTB_FLUSH_SECTION START_BTB_FLUSH_SECTION
BTB_FLUSH(r10) BTB_FLUSH(r10)
END_BTB_FLUSH_SECTION END_BTB_FLUSH_SECTION
#endif #endif
ACCOUNT_CPU_USER_ENTRY(r13, r10, r11) ACCOUNT_CPU_USER_ENTRY(r13, r10, r11)
2: std r2,GPR2(r1) std r2,GPR2(r1)
std r3,GPR3(r1) std r3,GPR3(r1)
mfcr r2 mfcr r2
std r4,GPR4(r1) std r4,GPR4(r1)
...@@ -122,14 +118,13 @@ END_BTB_FLUSH_SECTION ...@@ -122,14 +118,13 @@ END_BTB_FLUSH_SECTION
#if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) && defined(CONFIG_PPC_SPLPAR) #if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) && defined(CONFIG_PPC_SPLPAR)
BEGIN_FW_FTR_SECTION BEGIN_FW_FTR_SECTION
beq 33f /* see if there are any DTL entries to process */
/* if from user, see if there are any DTL entries to process */
ld r10,PACALPPACAPTR(r13) /* get ptr to VPA */ ld r10,PACALPPACAPTR(r13) /* get ptr to VPA */
ld r11,PACA_DTL_RIDX(r13) /* get log read index */ ld r11,PACA_DTL_RIDX(r13) /* get log read index */
addi r10,r10,LPPACA_DTLIDX addi r10,r10,LPPACA_DTLIDX
LDX_BE r10,0,r10 /* get log write index */ LDX_BE r10,0,r10 /* get log write index */
cmpd cr1,r11,r10 cmpd r11,r10
beq+ cr1,33f beq+ 33f
bl accumulate_stolen_time bl accumulate_stolen_time
REST_GPR(0,r1) REST_GPR(0,r1)
REST_4GPRS(3,r1) REST_4GPRS(3,r1)
...@@ -203,6 +198,7 @@ system_call: /* label this so stack traces look sane */ ...@@ -203,6 +198,7 @@ system_call: /* label this so stack traces look sane */
mtctr r12 mtctr r12
bctrl /* Call handler */ bctrl /* Call handler */
/* syscall_exit can exit to kernel mode, via ret_from_kernel_thread */
.Lsyscall_exit: .Lsyscall_exit:
std r3,RESULT(r1) std r3,RESULT(r1)
...@@ -216,11 +212,6 @@ system_call: /* label this so stack traces look sane */ ...@@ -216,11 +212,6 @@ system_call: /* label this so stack traces look sane */
ld r12, PACA_THREAD_INFO(r13) ld r12, PACA_THREAD_INFO(r13)
ld r8,_MSR(r1) ld r8,_MSR(r1)
#ifdef CONFIG_PPC_BOOK3S
/* No MSR:RI on BookE */
andi. r10,r8,MSR_RI
beq- .Lunrecov_restore
#endif
/* /*
* This is a few instructions into the actual syscall exit path (which actually * This is a few instructions into the actual syscall exit path (which actually
......
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.
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