aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-02-02 13:01:04 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2018-02-02 13:01:04 -0500
commit03f51d4efa2287cc628bb20b0c032036d2a9e66a (patch)
treeec7fb3b6624d53092e2768578f3ef887c8d77f22
parent367b0df173b0ebea5d18b6971c244e260b5feb17 (diff)
parent015eb1b89e959c9349f0a01803fb8ed1ced36f09 (diff)
Merge tag 'powerpc-4.16-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc updates from Michael Ellerman: "Highlights: - Enable support for memory protection keys aka "pkeys" on Power7/8/9 when using the hash table MMU. - Extend our interrupt soft masking to support masking PMU interrupts as well as "normal" interrupts, and then use that to implement local_t for a ~4x speedup vs the current atomics-based implementation. - A new driver "ocxl" for "Open Coherent Accelerator Processor Interface (OpenCAPI)" devices. - Support for new device tree properties on PowerVM to describe hotpluggable memory and devices. - Add support for CLOCK_{REALTIME/MONOTONIC}_COARSE to the 64-bit VDSO. - Freescale updates from Scott: fixes for CPM GPIO and an FSL PCI erratum workaround, plus a minor cleanup patch. As well as quite a lot of other changes all over the place, and small fixes and cleanups as always. Thanks to: Alan Modra, Alastair D'Silva, Alexey Kardashevskiy, Alistair Popple, Andreas Schwab, Andrew Donnellan, Aneesh Kumar K.V, Anju T Sudhakar, Anshuman Khandual, Anton Blanchard, Arnd Bergmann, Balbir Singh, Benjamin Herrenschmidt, Bhaktipriya Shridhar, Bryant G. Ly, Cédric Le Goater, Christophe Leroy, Christophe Lombard, Cyril Bur, David Gibson, Desnes A. Nunes do Rosario, Dmitry Torokhov, Frederic Barrat, Geert Uytterhoeven, Guilherme G. Piccoli, Gustavo A. R. Silva, Gustavo Romero, Ivan Mikhaylov, Joakim Tjernlund, Joe Perches, Josh Poimboeuf, Juan J. Alvarez, Julia Cartwright, Kamalesh Babulal, Madhavan Srinivasan, Mahesh Salgaonkar, Mathieu Malaterre, Michael Bringmann, Michael Hanselmann, Michael Neuling, Nathan Fontenot, Naveen N. Rao, Nicholas Piggin, Paul Mackerras, Philippe Bergheaud, Ram Pai, Russell Currey, Santosh Sivaraj, Scott Wood, Seth Forshee, Simon Guo, Stewart Smith, Sukadev Bhattiprolu, Thiago Jung Bauermann, Vaibhav Jain, Vasyl Gomonovych" * tag 'powerpc-4.16-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (199 commits) powerpc/mm/radix: Fix build error when RADIX_MMU=n macintosh/ams-input: Use true and false for boolean values macintosh: change some data types from int to bool powerpc/watchdog: Print the NIP in soft_nmi_interrupt() powerpc/watchdog: regs can't be null in soft_nmi_interrupt() powerpc/watchdog: Tweak watchdog printks powerpc/cell: Remove axonram driver rtc-opal: Fix handling of firmware error codes, prevent busy loops powerpc/mpc52xx_gpt: make use of raw_spinlock variants macintosh/adb: Properly mark continued kernel messages powerpc/pseries: Fix cpu hotplug crash with memoryless nodes powerpc/numa: Ensure nodes initialized for hotplug powerpc/numa: Use ibm,max-associativity-domains to discover possible nodes powerpc/kernel: Block interrupts when updating TIDR powerpc/powernv/idoa: Remove unnecessary pcidev from pci_dn powerpc/mm/nohash: do not flush the entire mm when range is a single page powerpc/pseries: Add Initialization of VF Bars powerpc/pseries/pci: Associate PEs to VFs in configure SR-IOV powerpc/eeh: Add EEH notify resume sysfs powerpc/eeh: Add EEH operations to notify resume ...
-rw-r--r--Documentation/ABI/testing/sysfs-class-ocxl35
-rw-r--r--Documentation/accelerators/ocxl.rst160
-rw-r--r--Documentation/devicetree/booting-without-of.txt2
-rw-r--r--Documentation/filesystems/dax.txt1
-rw-r--r--Documentation/ioctl/ioctl-number.txt1
-rw-r--r--MAINTAINERS12
-rw-r--r--arch/powerpc/Kconfig19
-rw-r--r--arch/powerpc/Kconfig.debug6
-rw-r--r--arch/powerpc/Makefile1
-rw-r--r--arch/powerpc/boot/Makefile8
-rw-r--r--arch/powerpc/boot/dts/a3m071.dts10
-rw-r--r--arch/powerpc/boot/dts/akebono.dts4
-rw-r--r--arch/powerpc/boot/dts/c2k.dts6
-rw-r--r--arch/powerpc/boot/dts/currituck.dts2
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8568mds.dts12
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8569mds.dts20
-rw-r--r--arch/powerpc/boot/dts/fsl/p1021mds.dts6
-rw-r--r--arch/powerpc/boot/dts/fsl/p1025rdb.dtsi8
-rw-r--r--arch/powerpc/boot/dts/fsl/p1025rdb_32b.dts2
-rw-r--r--arch/powerpc/boot/dts/fsl/p1025twr.dtsi8
-rw-r--r--arch/powerpc/boot/dts/fsl/t1040rdb.dts2
-rw-r--r--arch/powerpc/boot/dts/fsl/t1042d4rdb.dts10
-rw-r--r--arch/powerpc/boot/dts/fsl/t1042rdb.dts2
-rw-r--r--arch/powerpc/boot/dts/fsl/t104xrdb.dtsi6
-rw-r--r--arch/powerpc/boot/dts/fsp2.dts6
-rw-r--r--arch/powerpc/boot/dts/gamecube.dts14
-rw-r--r--arch/powerpc/boot/dts/haleakala.dts2
-rw-r--r--arch/powerpc/boot/dts/kilauea.dts4
-rw-r--r--arch/powerpc/boot/dts/kmeter1.dts10
-rw-r--r--arch/powerpc/boot/dts/makalu.dts4
-rw-r--r--arch/powerpc/boot/dts/mpc832x_mds.dts10
-rw-r--r--arch/powerpc/boot/dts/mpc832x_rdb.dts8
-rw-r--r--arch/powerpc/boot/dts/mpc836x_mds.dts8
-rw-r--r--arch/powerpc/boot/dts/sbc8548-altflash.dts8
-rw-r--r--arch/powerpc/boot/dts/sbc8548.dts8
-rw-r--r--arch/powerpc/boot/dts/wii.dts32
-rw-r--r--arch/powerpc/boot/serial.c6
-rw-r--r--arch/powerpc/configs/mpc866_ads_defconfig1
-rw-r--r--arch/powerpc/configs/powernv_defconfig2
-rw-r--r--arch/powerpc/include/asm/book3s/32/pgtable.h23
-rw-r--r--arch/powerpc/include/asm/book3s/64/hash-4k.h20
-rw-r--r--arch/powerpc/include/asm/book3s/64/hash-64k.h71
-rw-r--r--arch/powerpc/include/asm/book3s/64/hash.h8
-rw-r--r--arch/powerpc/include/asm/book3s/64/mmu-hash.h5
-rw-r--r--arch/powerpc/include/asm/book3s/64/mmu.h10
-rw-r--r--arch/powerpc/include/asm/book3s/64/pgtable.h79
-rw-r--r--arch/powerpc/include/asm/book3s/64/tlbflush-hash.h1
-rw-r--r--arch/powerpc/include/asm/book3s/64/tlbflush-radix.h7
-rw-r--r--arch/powerpc/include/asm/book3s/64/tlbflush.h38
-rw-r--r--arch/powerpc/include/asm/bug.h4
-rw-r--r--arch/powerpc/include/asm/code-patching.h2
-rw-r--r--arch/powerpc/include/asm/cpm.h2
-rw-r--r--arch/powerpc/include/asm/cpm1.h2
-rw-r--r--arch/powerpc/include/asm/cputable.h21
-rw-r--r--arch/powerpc/include/asm/drmem.h102
-rw-r--r--arch/powerpc/include/asm/eeh.h2
-rw-r--r--arch/powerpc/include/asm/exception-64s.h103
-rw-r--r--arch/powerpc/include/asm/firmware.h5
-rw-r--r--arch/powerpc/include/asm/hardirq.h1
-rw-r--r--arch/powerpc/include/asm/head-64.h47
-rw-r--r--arch/powerpc/include/asm/hmi.h4
-rw-r--r--arch/powerpc/include/asm/hugetlb.h3
-rw-r--r--arch/powerpc/include/asm/hw_irq.h161
-rw-r--r--arch/powerpc/include/asm/imc-pmu.h9
-rw-r--r--arch/powerpc/include/asm/irqflags.h14
-rw-r--r--arch/powerpc/include/asm/kexec.h2
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h2
-rw-r--r--arch/powerpc/include/asm/local.h200
-rw-r--r--arch/powerpc/include/asm/machdep.h8
-rw-r--r--arch/powerpc/include/asm/mman.h13
-rw-r--r--arch/powerpc/include/asm/mmu-8xx.h60
-rw-r--r--arch/powerpc/include/asm/mmu.h9
-rw-r--r--arch/powerpc/include/asm/mmu_context.h22
-rw-r--r--arch/powerpc/include/asm/mpic_timer.h8
-rw-r--r--arch/powerpc/include/asm/nmi.h4
-rw-r--r--arch/powerpc/include/asm/nohash/32/pgalloc.h3
-rw-r--r--arch/powerpc/include/asm/nohash/32/pgtable.h2
-rw-r--r--arch/powerpc/include/asm/nohash/32/pte-8xx.h25
-rw-r--r--arch/powerpc/include/asm/nohash/pgtable.h27
-rw-r--r--arch/powerpc/include/asm/nohash/pte-book3e.h1
-rw-r--r--arch/powerpc/include/asm/opal-api.h5
-rw-r--r--arch/powerpc/include/asm/opal.h6
-rw-r--r--arch/powerpc/include/asm/paca.h5
-rw-r--r--arch/powerpc/include/asm/pci-bridge.h9
-rw-r--r--arch/powerpc/include/asm/pci.h2
-rw-r--r--arch/powerpc/include/asm/pkeys.h218
-rw-r--r--arch/powerpc/include/asm/pnv-ocxl.h36
-rw-r--r--arch/powerpc/include/asm/ppc-opcode.h2
-rw-r--r--arch/powerpc/include/asm/processor.h5
-rw-r--r--arch/powerpc/include/asm/prom.h27
-rw-r--r--arch/powerpc/include/asm/pte-common.h37
-rw-r--r--arch/powerpc/include/asm/reg.h6
-rw-r--r--arch/powerpc/include/asm/reg_8xx.h82
-rw-r--r--arch/powerpc/include/asm/systbl.h3
-rw-r--r--arch/powerpc/include/asm/unistd.h6
-rw-r--r--arch/powerpc/include/asm/xive-regs.h35
-rw-r--r--arch/powerpc/include/asm/xive.h40
-rw-r--r--arch/powerpc/include/uapi/asm/elf.h1
-rw-r--r--arch/powerpc/include/uapi/asm/mman.h6
-rw-r--r--arch/powerpc/include/uapi/asm/unistd.h3
-rw-r--r--arch/powerpc/kernel/asm-offsets.c7
-rw-r--r--arch/powerpc/kernel/cpu_setup_power.S50
-rw-r--r--arch/powerpc/kernel/cputable.c15
-rw-r--r--arch/powerpc/kernel/crash.c16
-rw-r--r--arch/powerpc/kernel/dt_cpu_ftrs.c30
-rw-r--r--arch/powerpc/kernel/eeh.c59
-rw-r--r--arch/powerpc/kernel/eeh_driver.c10
-rw-r--r--arch/powerpc/kernel/eeh_sysfs.c64
-rw-r--r--arch/powerpc/kernel/entry_32.S10
-rw-r--r--arch/powerpc/kernel/entry_64.S67
-rw-r--r--arch/powerpc/kernel/exceptions-64e.S20
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S118
-rw-r--r--arch/powerpc/kernel/head_64.S11
-rw-r--r--arch/powerpc/kernel/head_8xx.S275
-rw-r--r--arch/powerpc/kernel/idle_book3e.S5
-rw-r--r--arch/powerpc/kernel/idle_power4.S5
-rw-r--r--arch/powerpc/kernel/irq.c29
-rw-r--r--arch/powerpc/kernel/mce.c142
-rw-r--r--arch/powerpc/kernel/mce_power.c115
-rw-r--r--arch/powerpc/kernel/module.lds8
-rw-r--r--arch/powerpc/kernel/module_64.c35
-rw-r--r--arch/powerpc/kernel/optprobes_head.S2
-rw-r--r--arch/powerpc/kernel/paca.c13
-rw-r--r--arch/powerpc/kernel/pci-common.c27
-rw-r--r--arch/powerpc/kernel/pci_dn.c6
-rw-r--r--arch/powerpc/kernel/pci_of_scan.c2
-rw-r--r--arch/powerpc/kernel/proc_powerpc.c2
-rw-r--r--arch/powerpc/kernel/process.c28
-rw-r--r--arch/powerpc/kernel/prom.c115
-rw-r--r--arch/powerpc/kernel/prom_init.c2
-rw-r--r--arch/powerpc/kernel/ptrace.c78
-rw-r--r--arch/powerpc/kernel/rtas-proc.c14
-rw-r--r--arch/powerpc/kernel/rtas_flash.c2
-rw-r--r--arch/powerpc/kernel/rtasd.c2
-rw-r--r--arch/powerpc/kernel/setup-common.c21
-rw-r--r--arch/powerpc/kernel/setup.h4
-rw-r--r--arch/powerpc/kernel/setup_64.c48
-rw-r--r--arch/powerpc/kernel/signal_32.c8
-rw-r--r--arch/powerpc/kernel/signal_64.c11
-rw-r--r--arch/powerpc/kernel/smp.c18
-rw-r--r--arch/powerpc/kernel/sysfs.c8
-rw-r--r--arch/powerpc/kernel/time.c6
-rw-r--r--arch/powerpc/kernel/traps.c51
-rw-r--r--arch/powerpc/kernel/vdso64/gettimeofday.S67
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S1
-rw-r--r--arch/powerpc/kernel/watchdog.c100
-rw-r--r--arch/powerpc/kvm/book3s_hv.c10
-rw-r--r--arch/powerpc/kvm/book3s_hv_ras.c14
-rw-r--r--arch/powerpc/kvm/book3s_hv_rm_mmu.c9
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S11
-rw-r--r--arch/powerpc/kvm/book3s_xics.c2
-rw-r--r--arch/powerpc/lib/code-patching.c37
-rw-r--r--arch/powerpc/lib/feature-fixups.c8
-rw-r--r--arch/powerpc/mm/8xx_mmu.c4
-rw-r--r--arch/powerpc/mm/Makefile3
-rw-r--r--arch/powerpc/mm/drmem.c439
-rw-r--r--arch/powerpc/mm/dump_linuxpagetables.c32
-rw-r--r--arch/powerpc/mm/fault.c53
-rw-r--r--arch/powerpc/mm/hash64_4k.c14
-rw-r--r--arch/powerpc/mm/hash64_64k.c123
-rw-r--r--arch/powerpc/mm/hash_native_64.c97
-rw-r--r--arch/powerpc/mm/hash_utils_64.c97
-rw-r--r--arch/powerpc/mm/hugetlbpage-hash64.c16
-rw-r--r--arch/powerpc/mm/hugetlbpage.c8
-rw-r--r--arch/powerpc/mm/init_64.c5
-rw-r--r--arch/powerpc/mm/mem.c3
-rw-r--r--arch/powerpc/mm/mmu_context_book3s64.c2
-rw-r--r--arch/powerpc/mm/numa.c333
-rw-r--r--arch/powerpc/mm/pgtable-radix.c23
-rw-r--r--arch/powerpc/mm/pgtable.c3
-rw-r--r--arch/powerpc/mm/pgtable_32.c9
-rw-r--r--arch/powerpc/mm/pgtable_64.c14
-rw-r--r--arch/powerpc/mm/pkeys.c468
-rw-r--r--arch/powerpc/mm/subpage-prot.c3
-rw-r--r--arch/powerpc/mm/tlb-radix.c68
-rw-r--r--arch/powerpc/mm/tlb_nohash.c5
-rw-r--r--arch/powerpc/perf/8xx-pmu.c52
-rw-r--r--arch/powerpc/perf/Makefile2
-rw-r--r--arch/powerpc/perf/core-book3s.c2
-rw-r--r--arch/powerpc/perf/imc-pmu.c102
-rw-r--r--arch/powerpc/platforms/44x/fsp2.c259
-rw-r--r--arch/powerpc/platforms/44x/fsp2.h272
-rw-r--r--arch/powerpc/platforms/512x/mpc512x_shared.c4
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_gpt.c52
-rw-r--r--arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c2
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_mds.c2
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_rdb.c2
-rw-r--r--arch/powerpc/platforms/83xx/mpc836x_mds.c2
-rw-r--r--arch/powerpc/platforms/85xx/socrates_fpga_pic.c7
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c2
-rw-r--r--arch/powerpc/platforms/8xx/Kconfig12
-rw-r--r--arch/powerpc/platforms/Kconfig11
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype8
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c3
-rw-r--r--arch/powerpc/platforms/cell/setup.c3
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c3
-rw-r--r--arch/powerpc/platforms/cell/spu_manage.c4
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c6
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c4
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h2
-rw-r--r--arch/powerpc/platforms/pasemi/dma_lib.c4
-rw-r--r--arch/powerpc/platforms/powermac/backlight.c6
-rw-r--r--arch/powerpc/platforms/powermac/feature.c3
-rw-r--r--arch/powerpc/platforms/powermac/pic.c8
-rw-r--r--arch/powerpc/platforms/powermac/smp.c4
-rw-r--r--arch/powerpc/platforms/powernv/Makefile1
-rw-r--r--arch/powerpc/platforms/powernv/eeh-powernv.c101
-rw-r--r--arch/powerpc/platforms/powernv/npu-dma.c7
-rw-r--r--arch/powerpc/platforms/powernv/ocxl.c515
-rw-r--r--arch/powerpc/platforms/powernv/opal-dump.c4
-rw-r--r--arch/powerpc/platforms/powernv/opal-elog.c4
-rw-r--r--arch/powerpc/platforms/powernv/opal-imc.c77
-rw-r--r--arch/powerpc/platforms/powernv/opal-sysparam.c6
-rw-r--r--arch/powerpc/platforms/powernv/opal-wrappers.S3
-rw-r--r--arch/powerpc/platforms/powernv/opal.c28
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c88
-rw-r--r--arch/powerpc/platforms/powernv/pci.c4
-rw-r--r--arch/powerpc/platforms/powernv/pci.h8
-rw-r--r--arch/powerpc/platforms/powernv/smp.c28
-rw-r--r--arch/powerpc/platforms/ps3/device-init.c12
-rw-r--r--arch/powerpc/platforms/ps3/mm.c4
-rw-r--r--arch/powerpc/platforms/ps3/os-area.c2
-rw-r--r--arch/powerpc/platforms/ps3/setup.c1
-rw-r--r--arch/powerpc/platforms/pseries/cmm.c16
-rw-r--r--arch/powerpc/platforms/pseries/eeh_pseries.c162
-rw-r--r--arch/powerpc/platforms/pseries/firmware.c2
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-cpu.c3
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-memory.c522
-rw-r--r--arch/powerpc/platforms/pseries/hvCall_inst.c2
-rw-r--r--arch/powerpc/platforms/pseries/ibmebus.c4
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c8
-rw-r--r--arch/powerpc/platforms/pseries/lparcfg.c8
-rw-r--r--arch/powerpc/platforms/pseries/mobility.c2
-rw-r--r--arch/powerpc/platforms/pseries/of_helpers.c60
-rw-r--r--arch/powerpc/platforms/pseries/pci.c177
-rw-r--r--arch/powerpc/platforms/pseries/pseries_energy.c126
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c2
-rw-r--r--arch/powerpc/platforms/pseries/scanlog.c2
-rw-r--r--arch/powerpc/platforms/pseries/setup.c176
-rw-r--r--arch/powerpc/platforms/pseries/suspend.c3
-rw-r--r--arch/powerpc/sysdev/Makefile4
-rw-r--r--arch/powerpc/sysdev/axonram.c383
-rw-r--r--arch/powerpc/sysdev/cpm1.c33
-rw-r--r--arch/powerpc/sysdev/cpm2.c11
-rw-r--r--arch/powerpc/sysdev/cpm_common.c5
-rw-r--r--arch/powerpc/sysdev/cpm_gpio.c80
-rw-r--r--arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c16
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c14
-rw-r--r--arch/powerpc/sysdev/mpic.c10
-rw-r--r--arch/powerpc/sysdev/mpic_timer.c55
-rw-r--r--arch/powerpc/sysdev/mv64x60_pci.c2
-rw-r--r--arch/powerpc/sysdev/xics/icp-native.c10
-rw-r--r--arch/powerpc/sysdev/xics/ics-opal.c4
-rw-r--r--arch/powerpc/sysdev/xics/ics-rtas.c4
-rw-r--r--arch/powerpc/sysdev/xics/xics-common.c8
-rw-r--r--arch/powerpc/sysdev/xive/common.c8
-rw-r--r--arch/powerpc/xmon/ppc-dis.c4
-rw-r--r--arch/powerpc/xmon/xmon.c6
-rw-r--r--drivers/cpuidle/cpuidle-powernv.c2
-rw-r--r--drivers/cpuidle/cpuidle-pseries.c16
-rw-r--r--drivers/macintosh/adb.c24
-rw-r--r--drivers/macintosh/adbhid.c55
-rw-r--r--drivers/macintosh/ams/ams-input.c4
-rw-r--r--drivers/macintosh/therm_adt746x.c4
-rw-r--r--drivers/macintosh/via-pmu-backlight.c2
-rw-r--r--drivers/macintosh/windfarm_pm112.c8
-rw-r--r--drivers/macintosh/windfarm_pm121.c5
-rw-r--r--drivers/macintosh/windfarm_pm72.c2
-rw-r--r--drivers/macintosh/windfarm_pm81.c5
-rw-r--r--drivers/macintosh/windfarm_pm91.c5
-rw-r--r--drivers/macintosh/windfarm_rm31.c2
-rw-r--r--drivers/misc/Kconfig1
-rw-r--r--drivers/misc/Makefile3
-rw-r--r--drivers/misc/cxl/context.c2
-rw-r--r--drivers/misc/cxl/cxl.h3
-rw-r--r--drivers/misc/cxl/cxllib.c3
-rw-r--r--drivers/misc/cxl/file.c15
-rw-r--r--drivers/misc/cxl/native.c13
-rw-r--r--drivers/misc/cxl/pci.c2
-rw-r--r--drivers/misc/ocxl/Kconfig31
-rw-r--r--drivers/misc/ocxl/Makefile11
-rw-r--r--drivers/misc/ocxl/afu_irq.c202
-rw-r--r--drivers/misc/ocxl/config.c723
-rw-r--r--drivers/misc/ocxl/context.c279
-rw-r--r--drivers/misc/ocxl/file.c432
-rw-r--r--drivers/misc/ocxl/link.c647
-rw-r--r--drivers/misc/ocxl/main.c33
-rw-r--r--drivers/misc/ocxl/ocxl_internal.h131
-rw-r--r--drivers/misc/ocxl/pasid.c107
-rw-r--r--drivers/misc/ocxl/pci.c585
-rw-r--r--drivers/misc/ocxl/sysfs.c142
-rw-r--r--drivers/misc/ocxl/trace.c6
-rw-r--r--drivers/misc/ocxl/trace.h182
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c13
-rw-r--r--drivers/pci/hotplug/rpadlpar_sysfs.c3
-rw-r--r--drivers/pci/hotplug/rpaphp.h8
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c107
-rw-r--r--drivers/pci/iov.c11
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c3
-rw-r--r--drivers/ps3/ps3av.c11
-rw-r--r--drivers/rtc/rtc-opal.c12
-rw-r--r--include/linux/pci.h38
-rw-r--r--include/misc/ocxl-config.h45
-rw-r--r--include/misc/ocxl.h214
-rw-r--r--include/uapi/linux/elf.h1
-rw-r--r--include/uapi/misc/cxl.h10
-rw-r--r--include/uapi/misc/ocxl.h49
-rw-r--r--tools/testing/selftests/powerpc/alignment/Makefile3
-rw-r--r--tools/testing/selftests/powerpc/alignment/alignment_handler.c491
-rw-r--r--tools/testing/selftests/powerpc/benchmarks/mmap_bench.c53
-rw-r--r--tools/testing/selftests/powerpc/mm/.gitignore3
-rw-r--r--tools/testing/selftests/powerpc/mm/Makefile2
-rw-r--r--tools/testing/selftests/powerpc/mm/segv_errors.c78
-rw-r--r--tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-vsx.c4
-rw-r--r--tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c3
-rw-r--r--tools/testing/selftests/powerpc/ptrace/ptrace-tm-vsx.c2
-rw-r--r--tools/testing/selftests/powerpc/tm/.gitignore1
-rw-r--r--tools/testing/selftests/powerpc/tm/Makefile3
-rw-r--r--tools/testing/selftests/powerpc/tm/tm-trap.c329
-rw-r--r--tools/testing/selftests/powerpc/tm/tm-unavailable.c43
320 files changed, 11609 insertions, 3056 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-ocxl b/Documentation/ABI/testing/sysfs-class-ocxl
new file mode 100644
index 000000000000..b5b1fa197592
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-ocxl
@@ -0,0 +1,35 @@
1What: /sys/class/ocxl/<afu name>/afu_version
2Date: January 2018
3Contact: linuxppc-dev@lists.ozlabs.org
4Description: read only
5 Version of the AFU, in the format <major>:<minor>
6 Reflects what is read in the configuration space of the AFU
7
8What: /sys/class/ocxl/<afu name>/contexts
9Date: January 2018
10Contact: linuxppc-dev@lists.ozlabs.org
11Description: read only
12 Number of contexts for the AFU, in the format <n>/<max>
13 where:
14 n: number of currently active contexts, for debug
15 max: maximum number of contexts supported by the AFU
16
17What: /sys/class/ocxl/<afu name>/pp_mmio_size
18Date: January 2018
19Contact: linuxppc-dev@lists.ozlabs.org
20Description: read only
21 Size of the per-process mmio area, as defined in the
22 configuration space of the AFU
23
24What: /sys/class/ocxl/<afu name>/global_mmio_size
25Date: January 2018
26Contact: linuxppc-dev@lists.ozlabs.org
27Description: read only
28 Size of the global mmio area, as defined in the
29 configuration space of the AFU
30
31What: /sys/class/ocxl/<afu name>/global_mmio_area
32Date: January 2018
33Contact: linuxppc-dev@lists.ozlabs.org
34Description: read/write
35 Give access the global mmio area for the AFU
diff --git a/Documentation/accelerators/ocxl.rst b/Documentation/accelerators/ocxl.rst
new file mode 100644
index 000000000000..4f7af841d935
--- /dev/null
+++ b/Documentation/accelerators/ocxl.rst
@@ -0,0 +1,160 @@
1========================================================
2OpenCAPI (Open Coherent Accelerator Processor Interface)
3========================================================
4
5OpenCAPI is an interface between processors and accelerators. It aims
6at being low-latency and high-bandwidth. The specification is
7developed by the `OpenCAPI Consortium <http://opencapi.org/>`_.
8
9It allows an accelerator (which could be a FPGA, ASICs, ...) to access
10the host memory coherently, using virtual addresses. An OpenCAPI
11device can also host its own memory, that can be accessed from the
12host.
13
14OpenCAPI is known in linux as 'ocxl', as the open, processor-agnostic
15evolution of 'cxl' (the driver for the IBM CAPI interface for
16powerpc), which was named that way to avoid confusion with the ISDN
17CAPI subsystem.
18
19
20High-level view
21===============
22
23OpenCAPI defines a Data Link Layer (DL) and Transaction Layer (TL), to
24be implemented on top of a physical link. Any processor or device
25implementing the DL and TL can start sharing memory.
26
27::
28
29 +-----------+ +-------------+
30 | | | |
31 | | | Accelerated |
32 | Processor | | Function |
33 | | +--------+ | Unit | +--------+
34 | |--| Memory | | (AFU) |--| Memory |
35 | | +--------+ | | +--------+
36 +-----------+ +-------------+
37 | |
38 +-----------+ +-------------+
39 | TL | | TLX |
40 +-----------+ +-------------+
41 | |
42 +-----------+ +-------------+
43 | DL | | DLX |
44 +-----------+ +-------------+
45 | |
46 | PHY |
47 +---------------------------------------+
48
49
50
51Device discovery
52================
53
54OpenCAPI relies on a PCI-like configuration space, implemented on the
55device. So the host can discover AFUs by querying the config space.
56
57OpenCAPI devices in Linux are treated like PCI devices (with a few
58caveats). The firmware is expected to abstract the hardware as if it
59was a PCI link. A lot of the existing PCI infrastructure is reused:
60devices are scanned and BARs are assigned during the standard PCI
61enumeration. Commands like 'lspci' can therefore be used to see what
62devices are available.
63
64The configuration space defines the AFU(s) that can be found on the
65physical adapter, such as its name, how many memory contexts it can
66work with, the size of its MMIO areas, ...
67
68
69
70MMIO
71====
72
73OpenCAPI defines two MMIO areas for each AFU:
74
75* the global MMIO area, with registers pertinent to the whole AFU.
76* a per-process MMIO area, which has a fixed size for each context.
77
78
79
80AFU interrupts
81==============
82
83OpenCAPI includes the possibility for an AFU to send an interrupt to a
84host process. It is done through a 'intrp_req' defined in the
85Transaction Layer, specifying a 64-bit object handle which defines the
86interrupt.
87
88The driver allows a process to allocate an interrupt and obtain its
8964-bit object handle, that can be passed to the AFU.
90
91
92
93char devices
94============
95
96The driver creates one char device per AFU found on the physical
97device. A physical device may have multiple functions and each
98function can have multiple AFUs. At the time of this writing though,
99it has only been tested with devices exporting only one AFU.
100
101Char devices can be found in /dev/ocxl/ and are named as:
102/dev/ocxl/<AFU name>.<location>.<index>
103
104where <AFU name> is a max 20-character long name, as found in the
105config space of the AFU.
106<location> is added by the driver and can help distinguish devices
107when a system has more than one instance of the same OpenCAPI device.
108<index> is also to help distinguish AFUs in the unlikely case where a
109device carries multiple copies of the same AFU.
110
111
112
113Sysfs class
114===========
115
116An ocxl class is added for the devices representing the AFUs. See
117/sys/class/ocxl. The layout is described in
118Documentation/ABI/testing/sysfs-class-ocxl
119
120
121
122User API
123========
124
125open
126----
127
128Based on the AFU definition found in the config space, an AFU may
129support working with more than one memory context, in which case the
130associated char device may be opened multiple times by different
131processes.
132
133
134ioctl
135-----
136
137OCXL_IOCTL_ATTACH:
138
139 Attach the memory context of the calling process to the AFU so that
140 the AFU can access its memory.
141
142OCXL_IOCTL_IRQ_ALLOC:
143
144 Allocate an AFU interrupt and return an identifier.
145
146OCXL_IOCTL_IRQ_FREE:
147
148 Free a previously allocated AFU interrupt.
149
150OCXL_IOCTL_IRQ_SET_FD:
151
152 Associate an event fd to an AFU interrupt so that the user process
153 can be notified when the AFU sends an interrupt.
154
155
156mmap
157----
158
159A process can mmap the per-process MMIO area for interactions with the
160AFU.
diff --git a/Documentation/devicetree/booting-without-of.txt b/Documentation/devicetree/booting-without-of.txt
index 417f91110010..e86bd2f64117 100644
--- a/Documentation/devicetree/booting-without-of.txt
+++ b/Documentation/devicetree/booting-without-of.txt
@@ -1309,7 +1309,7 @@ number and level/sense information. All interrupt children in an
1309OpenPIC interrupt domain use 2 cells per interrupt in their interrupts 1309OpenPIC interrupt domain use 2 cells per interrupt in their interrupts
1310property. 1310property.
1311 1311
1312The PCI bus binding specifies a #interrupt-cell value of 1 to encode 1312The PCI bus binding specifies a #interrupt-cells value of 1 to encode
1313which interrupt pin (INTA,INTB,INTC,INTD) is used. 1313which interrupt pin (INTA,INTB,INTC,INTD) is used.
1314 1314
13152) interrupt-parent property 13152) interrupt-parent property
diff --git a/Documentation/filesystems/dax.txt b/Documentation/filesystems/dax.txt
index 3be3b266be41..70cb68bed2e8 100644
--- a/Documentation/filesystems/dax.txt
+++ b/Documentation/filesystems/dax.txt
@@ -46,7 +46,6 @@ stall the CPU for an extended period, you should also not attempt to
46implement direct_access. 46implement direct_access.
47 47
48These block devices may be used for inspiration: 48These block devices may be used for inspiration:
49- axonram: Axon DDR2 device driver
50- brd: RAM backed block device driver 49- brd: RAM backed block device driver
51- dcssblk: s390 dcss block device driver 50- dcssblk: s390 dcss block device driver
52- pmem: NVDIMM persistent memory driver 51- pmem: NVDIMM persistent memory driver
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index 3e3fdae5f3ed..6501389d55b9 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -326,6 +326,7 @@ Code Seq#(hex) Include File Comments
3260xB5 00-0F uapi/linux/rpmsg.h <mailto:linux-remoteproc@vger.kernel.org> 3260xB5 00-0F uapi/linux/rpmsg.h <mailto:linux-remoteproc@vger.kernel.org>
3270xC0 00-0F linux/usb/iowarrior.h 3270xC0 00-0F linux/usb/iowarrior.h
3280xCA 00-0F uapi/misc/cxl.h 3280xCA 00-0F uapi/misc/cxl.h
3290xCA 10-2F uapi/misc/ocxl.h
3290xCA 80-BF uapi/scsi/cxlflash_ioctl.h 3300xCA 80-BF uapi/scsi/cxlflash_ioctl.h
3300xCB 00-1F CBM serial IEC bus in development: 3310xCB 00-1F CBM serial IEC bus in development:
331 <mailto:michael.klein@puffin.lb.shuttle.de> 332 <mailto:michael.klein@puffin.lb.shuttle.de>
diff --git a/MAINTAINERS b/MAINTAINERS
index f981c5678eeb..1dc846d0add6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9909,6 +9909,18 @@ M: Josh Poimboeuf <jpoimboe@redhat.com>
9909S: Supported 9909S: Supported
9910F: tools/objtool/ 9910F: tools/objtool/
9911 9911
9912OCXL (Open Coherent Accelerator Processor Interface OpenCAPI) DRIVER
9913M: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
9914M: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
9915L: linuxppc-dev@lists.ozlabs.org
9916S: Supported
9917F: arch/powerpc/platforms/powernv/ocxl.c
9918F: arch/powerpc/include/asm/pnv-ocxl.h
9919F: drivers/misc/ocxl/
9920F: include/misc/ocxl*
9921F: include/uapi/misc/ocxl.h
9922F: Documentation/accelerators/ocxl.txt
9923
9912OMAP AUDIO SUPPORT 9924OMAP AUDIO SUPPORT
9913M: Peter Ujfalusi <peter.ujfalusi@ti.com> 9925M: Peter Ujfalusi <peter.ujfalusi@ti.com>
9914M: Jarkko Nikula <jarkko.nikula@bitmer.com> 9926M: Jarkko Nikula <jarkko.nikula@bitmer.com>
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 73fcf592ee91..9d3329811cc1 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -143,6 +143,7 @@ config PPC
143 select ARCH_HAS_PMEM_API if PPC64 143 select ARCH_HAS_PMEM_API if PPC64
144 select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE 144 select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE
145 select ARCH_HAS_SG_CHAIN 145 select ARCH_HAS_SG_CHAIN
146 select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !RELOCATABLE && !HIBERNATION)
146 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST 147 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
147 select ARCH_HAS_UACCESS_FLUSHCACHE if PPC64 148 select ARCH_HAS_UACCESS_FLUSHCACHE if PPC64
148 select ARCH_HAS_UBSAN_SANITIZE_ALL 149 select ARCH_HAS_UBSAN_SANITIZE_ALL
@@ -150,6 +151,7 @@ config PPC
150 select ARCH_HAVE_NMI_SAFE_CMPXCHG 151 select ARCH_HAVE_NMI_SAFE_CMPXCHG
151 select ARCH_MIGHT_HAVE_PC_PARPORT 152 select ARCH_MIGHT_HAVE_PC_PARPORT
152 select ARCH_MIGHT_HAVE_PC_SERIO 153 select ARCH_MIGHT_HAVE_PC_SERIO
154 select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX
153 select ARCH_SUPPORTS_ATOMIC_RMW 155 select ARCH_SUPPORTS_ATOMIC_RMW
154 select ARCH_USE_BUILTIN_BSWAP 156 select ARCH_USE_BUILTIN_BSWAP
155 select ARCH_USE_CMPXCHG_LOCKREF if PPC64 157 select ARCH_USE_CMPXCHG_LOCKREF if PPC64
@@ -180,8 +182,6 @@ config PPC
180 select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT 182 select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
181 select HAVE_ARCH_SECCOMP_FILTER 183 select HAVE_ARCH_SECCOMP_FILTER
182 select HAVE_ARCH_TRACEHOOK 184 select HAVE_ARCH_TRACEHOOK
183 select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !RELOCATABLE && !HIBERNATION)
184 select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX
185 select HAVE_CBPF_JIT if !PPC64 185 select HAVE_CBPF_JIT if !PPC64
186 select HAVE_CONTEXT_TRACKING if PPC64 186 select HAVE_CONTEXT_TRACKING if PPC64
187 select HAVE_DEBUG_KMEMLEAK 187 select HAVE_DEBUG_KMEMLEAK
@@ -868,6 +868,21 @@ config SECCOMP
868 868
869 If unsure, say Y. Only embedded should say N here. 869 If unsure, say Y. Only embedded should say N here.
870 870
871config PPC_MEM_KEYS
872 prompt "PowerPC Memory Protection Keys"
873 def_bool y
874 depends on PPC_BOOK3S_64
875 select ARCH_USES_HIGH_VMA_FLAGS
876 select ARCH_HAS_PKEYS
877 help
878 Memory Protection Keys provides a mechanism for enforcing
879 page-based protections, but without requiring modification of the
880 page tables when an application changes protection domains.
881
882 For details, see Documentation/vm/protection-keys.txt
883
884 If unsure, say y.
885
871endmenu 886endmenu
872 887
873config ISA_DMA_API 888config ISA_DMA_API
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 657c33cd4eee..c45424c64e19 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -90,6 +90,10 @@ config MSI_BITMAP_SELFTEST
90 depends on DEBUG_KERNEL 90 depends on DEBUG_KERNEL
91 default n 91 default n
92 92
93config PPC_IRQ_SOFT_MASK_DEBUG
94 bool "Include extra checks for powerpc irq soft masking"
95 default n
96
93config XMON 97config XMON
94 bool "Include xmon kernel debugger" 98 bool "Include xmon kernel debugger"
95 depends on DEBUG_KERNEL 99 depends on DEBUG_KERNEL
@@ -368,7 +372,7 @@ config PPC_PTDUMP
368 372
369config PPC_HTDUMP 373config PPC_HTDUMP
370 def_bool y 374 def_bool y
371 depends on PPC_PTDUMP && PPC_BOOK3S 375 depends on PPC_PTDUMP && PPC_BOOK3S_64
372 376
373config PPC_FAST_ENDIAN_SWITCH 377config PPC_FAST_ENDIAN_SWITCH
374 bool "Deprecated fast endian-switch syscall" 378 bool "Deprecated fast endian-switch syscall"
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 1381693a4a51..ccd2556bdb53 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -63,6 +63,7 @@ UTS_MACHINE := $(subst $(space),,$(machine-y))
63ifdef CONFIG_PPC32 63ifdef CONFIG_PPC32
64KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o 64KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
65else 65else
66KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/powerpc/kernel/module.lds
66ifeq ($(call ld-ifversion, -ge, 225000000, y),y) 67ifeq ($(call ld-ifversion, -ge, 225000000, y),y)
67# Have the linker provide sfpr if possible. 68# Have the linker provide sfpr if possible.
68# There is a corresponding test in arch/powerpc/lib/Makefile 69# There is a corresponding test in arch/powerpc/lib/Makefile
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 08782f55b89f..ef6549e57157 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -108,10 +108,10 @@ src-wlib-y := string.S crt0.S stdio.c decompress.c main.c \
108 $(libfdt) libfdt-wrapper.c \ 108 $(libfdt) libfdt-wrapper.c \
109 ns16550.c serial.c simple_alloc.c div64.S util.S \ 109 ns16550.c serial.c simple_alloc.c div64.S util.S \
110 elf_util.c $(zlib-y) devtree.c stdlib.c \ 110 elf_util.c $(zlib-y) devtree.c stdlib.c \
111 oflib.c ofconsole.c cuboot.c cpm-serial.c \ 111 oflib.c ofconsole.c cuboot.c
112 uartlite.c opal.c 112
113src-wlib-$(CONFIG_PPC_MPC52XX) += mpc52xx-psc.c 113src-wlib-$(CONFIG_PPC_MPC52XX) += mpc52xx-psc.c
114src-wlib-$(CONFIG_PPC64_BOOT_WRAPPER) += opal-calls.S 114src-wlib-$(CONFIG_PPC64_BOOT_WRAPPER) += opal-calls.S opal.c
115ifndef CONFIG_PPC64_BOOT_WRAPPER 115ifndef CONFIG_PPC64_BOOT_WRAPPER
116src-wlib-y += crtsavres.S 116src-wlib-y += crtsavres.S
117endif 117endif
@@ -120,6 +120,8 @@ src-wlib-$(CONFIG_44x) += 4xx.c ebony.c bamboo.c
120src-wlib-$(CONFIG_PPC_8xx) += mpc8xx.c planetcore.c fsl-soc.c 120src-wlib-$(CONFIG_PPC_8xx) += mpc8xx.c planetcore.c fsl-soc.c
121src-wlib-$(CONFIG_PPC_82xx) += pq2.c fsl-soc.c planetcore.c 121src-wlib-$(CONFIG_PPC_82xx) += pq2.c fsl-soc.c planetcore.c
122src-wlib-$(CONFIG_EMBEDDED6xx) += mpsc.c mv64x60.c mv64x60_i2c.c ugecon.c fsl-soc.c 122src-wlib-$(CONFIG_EMBEDDED6xx) += mpsc.c mv64x60.c mv64x60_i2c.c ugecon.c fsl-soc.c
123src-wlib-$(CONFIG_XILINX_VIRTEX) += uartlite.c
124src-wlib-$(CONFIG_CPM) += cpm-serial.c
123 125
124src-plat-y := of.c epapr.c 126src-plat-y := of.c epapr.c
125src-plat-$(CONFIG_40x) += fixed-head.S ep405.c cuboot-hotfoot.c \ 127src-plat-$(CONFIG_40x) += fixed-head.S ep405.c cuboot-hotfoot.c \
diff --git a/arch/powerpc/boot/dts/a3m071.dts b/arch/powerpc/boot/dts/a3m071.dts
index bf81b8f9704c..187ce458d03a 100644
--- a/arch/powerpc/boot/dts/a3m071.dts
+++ b/arch/powerpc/boot/dts/a3m071.dts
@@ -105,24 +105,24 @@
105 reg = <0 0x0 0x02000000>; 105 reg = <0 0x0 0x02000000>;
106 compatible = "cfi-flash"; 106 compatible = "cfi-flash";
107 bank-width = <2>; 107 bank-width = <2>;
108 partition@0x0 { 108 partition@0 {
109 label = "u-boot"; 109 label = "u-boot";
110 reg = <0x00000000 0x00040000>; 110 reg = <0x00000000 0x00040000>;
111 read-only; 111 read-only;
112 }; 112 };
113 partition@0x00040000 { 113 partition@40000 {
114 label = "env"; 114 label = "env";
115 reg = <0x00040000 0x00020000>; 115 reg = <0x00040000 0x00020000>;
116 }; 116 };
117 partition@0x00060000 { 117 partition@60000 {
118 label = "dtb"; 118 label = "dtb";
119 reg = <0x00060000 0x00020000>; 119 reg = <0x00060000 0x00020000>;
120 }; 120 };
121 partition@0x00080000 { 121 partition@80000 {
122 label = "kernel"; 122 label = "kernel";
123 reg = <0x00080000 0x00500000>; 123 reg = <0x00080000 0x00500000>;
124 }; 124 };
125 partition@0x00580000 { 125 partition@580000 {
126 label = "root"; 126 label = "root";
127 reg = <0x00580000 0x00A80000>; 127 reg = <0x00580000 0x00A80000>;
128 }; 128 };
diff --git a/arch/powerpc/boot/dts/akebono.dts b/arch/powerpc/boot/dts/akebono.dts
index e61d5dc598c1..746779202a12 100644
--- a/arch/powerpc/boot/dts/akebono.dts
+++ b/arch/powerpc/boot/dts/akebono.dts
@@ -216,7 +216,7 @@
216 interrupts = <39 2>; 216 interrupts = <39 2>;
217 }; 217 };
218 218
219 IIC0: i2c@00000000 { 219 IIC0: i2c@0 {
220 compatible = "ibm,iic-476gtr", "ibm,iic"; 220 compatible = "ibm,iic-476gtr", "ibm,iic";
221 reg = <0x0 0x00000020>; 221 reg = <0x0 0x00000020>;
222 interrupt-parent = <&MPIC>; 222 interrupt-parent = <&MPIC>;
@@ -229,7 +229,7 @@
229 }; 229 };
230 }; 230 };
231 231
232 IIC1: i2c@00000100 { 232 IIC1: i2c@100 {
233 compatible = "ibm,iic-476gtr", "ibm,iic"; 233 compatible = "ibm,iic-476gtr", "ibm,iic";
234 reg = <0x100 0x00000020>; 234 reg = <0x100 0x00000020>;
235 interrupt-parent = <&MPIC>; 235 interrupt-parent = <&MPIC>;
diff --git a/arch/powerpc/boot/dts/c2k.dts b/arch/powerpc/boot/dts/c2k.dts
index 1e32903cb0a8..27f169e3ade9 100644
--- a/arch/powerpc/boot/dts/c2k.dts
+++ b/arch/powerpc/boot/dts/c2k.dts
@@ -276,14 +276,14 @@
276 >; 276 >;
277 }; 277 };
278 278
279 cpu-error@0070 { 279 cpu-error@70 {
280 compatible = "marvell,mv64360-cpu-error"; 280 compatible = "marvell,mv64360-cpu-error";
281 reg = <0x0070 0x10 0x0128 0x28>; 281 reg = <0x0070 0x10 0x0128 0x28>;
282 interrupts = <3>; 282 interrupts = <3>;
283 interrupt-parent = <&PIC>; 283 interrupt-parent = <&PIC>;
284 }; 284 };
285 285
286 sram-ctrl@0380 { 286 sram-ctrl@380 {
287 compatible = "marvell,mv64360-sram-ctrl"; 287 compatible = "marvell,mv64360-sram-ctrl";
288 reg = <0x0380 0x80>; 288 reg = <0x0380 0x80>;
289 interrupts = <13>; 289 interrupts = <13>;
@@ -311,7 +311,7 @@
311 interrupt-parent = <&PIC>; 311 interrupt-parent = <&PIC>;
312 }; 312 };
313 /* Devices attached to the device controller */ 313 /* Devices attached to the device controller */
314 devicebus@045c { 314 devicebus@45c {
315 #address-cells = <2>; 315 #address-cells = <2>;
316 #size-cells = <1>; 316 #size-cells = <1>;
317 compatible = "marvell,mv64306-devctrl"; 317 compatible = "marvell,mv64306-devctrl";
diff --git a/arch/powerpc/boot/dts/currituck.dts b/arch/powerpc/boot/dts/currituck.dts
index 4191e1850ea1..f2ad5815f08d 100644
--- a/arch/powerpc/boot/dts/currituck.dts
+++ b/arch/powerpc/boot/dts/currituck.dts
@@ -108,7 +108,7 @@
108 reg = <0x50000000 0x4>; 108 reg = <0x50000000 0x4>;
109 }; 109 };
110 110
111 IIC0: i2c@00000000 { 111 IIC0: i2c@0 {
112 compatible = "ibm,iic-currituck", "ibm,iic"; 112 compatible = "ibm,iic-currituck", "ibm,iic";
113 reg = <0x0 0x00000014>; 113 reg = <0x0 0x00000014>;
114 interrupt-parent = <&MPIC>; 114 interrupt-parent = <&MPIC>;
diff --git a/arch/powerpc/boot/dts/fsl/mpc8568mds.dts b/arch/powerpc/boot/dts/fsl/mpc8568mds.dts
index 01706a339603..bc3e8039bdc7 100644
--- a/arch/powerpc/boot/dts/fsl/mpc8568mds.dts
+++ b/arch/powerpc/boot/dts/fsl/mpc8568mds.dts
@@ -126,7 +126,7 @@
126 par_io@e0100 { 126 par_io@e0100 {
127 num-ports = <7>; 127 num-ports = <7>;
128 128
129 pio1: ucc_pin@01 { 129 pio1: ucc_pin@1 {
130 pio-map = < 130 pio-map = <
131 /* port pin dir open_drain assignment has_irq */ 131 /* port pin dir open_drain assignment has_irq */
132 0x4 0xa 0x1 0x0 0x2 0x0 /* TxD0 */ 132 0x4 0xa 0x1 0x0 0x2 0x0 /* TxD0 */
@@ -154,7 +154,7 @@
154 0x1 0x1f 0x2 0x0 0x3 0x0>; /* GTX125 */ 154 0x1 0x1f 0x2 0x0 0x3 0x0>; /* GTX125 */
155 }; 155 };
156 156
157 pio2: ucc_pin@02 { 157 pio2: ucc_pin@2 {
158 pio-map = < 158 pio-map = <
159 /* port pin dir open_drain assignment has_irq */ 159 /* port pin dir open_drain assignment has_irq */
160 0x5 0xa 0x1 0x0 0x2 0x0 /* TxD0 */ 160 0x5 0xa 0x1 0x0 0x2 0x0 /* TxD0 */
@@ -228,22 +228,22 @@
228 228
229 /* These are the same PHYs as on 229 /* These are the same PHYs as on
230 * gianfar's MDIO bus */ 230 * gianfar's MDIO bus */
231 qe_phy0: ethernet-phy@07 { 231 qe_phy0: ethernet-phy@7 {
232 interrupt-parent = <&mpic>; 232 interrupt-parent = <&mpic>;
233 interrupts = <1 1 0 0>; 233 interrupts = <1 1 0 0>;
234 reg = <0x7>; 234 reg = <0x7>;
235 }; 235 };
236 qe_phy1: ethernet-phy@01 { 236 qe_phy1: ethernet-phy@1 {
237 interrupt-parent = <&mpic>; 237 interrupt-parent = <&mpic>;
238 interrupts = <2 1 0 0>; 238 interrupts = <2 1 0 0>;
239 reg = <0x1>; 239 reg = <0x1>;
240 }; 240 };
241 qe_phy2: ethernet-phy@02 { 241 qe_phy2: ethernet-phy@2 {
242 interrupt-parent = <&mpic>; 242 interrupt-parent = <&mpic>;
243 interrupts = <1 1 0 0>; 243 interrupts = <1 1 0 0>;
244 reg = <0x2>; 244 reg = <0x2>;
245 }; 245 };
246 qe_phy3: ethernet-phy@03 { 246 qe_phy3: ethernet-phy@3 {
247 interrupt-parent = <&mpic>; 247 interrupt-parent = <&mpic>;
248 interrupts = <2 1 0 0>; 248 interrupts = <2 1 0 0>;
249 reg = <0x3>; 249 reg = <0x3>;
diff --git a/arch/powerpc/boot/dts/fsl/mpc8569mds.dts b/arch/powerpc/boot/dts/fsl/mpc8569mds.dts
index 76b2bd6f7742..d8367ceddea6 100644
--- a/arch/powerpc/boot/dts/fsl/mpc8569mds.dts
+++ b/arch/powerpc/boot/dts/fsl/mpc8569mds.dts
@@ -141,7 +141,7 @@
141 gpio-controller; 141 gpio-controller;
142 }; 142 };
143 143
144 pio1: ucc_pin@01 { 144 pio1: ucc_pin@1 {
145 pio-map = < 145 pio-map = <
146 /* port pin dir open_drain assignment has_irq */ 146 /* port pin dir open_drain assignment has_irq */
147 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */ 147 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
@@ -161,7 +161,7 @@
161 0x2 0x14 0x1 0x0 0x2 0x0>; /* ENET1_GTXCLK */ 161 0x2 0x14 0x1 0x0 0x2 0x0>; /* ENET1_GTXCLK */
162 }; 162 };
163 163
164 pio2: ucc_pin@02 { 164 pio2: ucc_pin@2 {
165 pio-map = < 165 pio-map = <
166 /* port pin dir open_drain assignment has_irq */ 166 /* port pin dir open_drain assignment has_irq */
167 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */ 167 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
@@ -181,7 +181,7 @@
181 0x2 0x2 0x1 0x0 0x2 0x0>; /* ENET2_GTXCLK */ 181 0x2 0x2 0x1 0x0 0x2 0x0>; /* ENET2_GTXCLK */
182 }; 182 };
183 183
184 pio3: ucc_pin@03 { 184 pio3: ucc_pin@3 {
185 pio-map = < 185 pio-map = <
186 /* port pin dir open_drain assignment has_irq */ 186 /* port pin dir open_drain assignment has_irq */
187 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */ 187 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
@@ -201,7 +201,7 @@
201 0x2 0x19 0x1 0x0 0x2 0x0>; /* ENET3_GTXCLK */ 201 0x2 0x19 0x1 0x0 0x2 0x0>; /* ENET3_GTXCLK */
202 }; 202 };
203 203
204 pio4: ucc_pin@04 { 204 pio4: ucc_pin@4 {
205 pio-map = < 205 pio-map = <
206 /* port pin dir open_drain assignment has_irq */ 206 /* port pin dir open_drain assignment has_irq */
207 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */ 207 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
@@ -272,30 +272,30 @@
272 reg = <0x2120 0x18>; 272 reg = <0x2120 0x18>;
273 compatible = "fsl,ucc-mdio"; 273 compatible = "fsl,ucc-mdio";
274 274
275 qe_phy0: ethernet-phy@07 { 275 qe_phy0: ethernet-phy@7 {
276 interrupt-parent = <&mpic>; 276 interrupt-parent = <&mpic>;
277 interrupts = <1 1 0 0>; 277 interrupts = <1 1 0 0>;
278 reg = <0x7>; 278 reg = <0x7>;
279 }; 279 };
280 qe_phy1: ethernet-phy@01 { 280 qe_phy1: ethernet-phy@1 {
281 interrupt-parent = <&mpic>; 281 interrupt-parent = <&mpic>;
282 interrupts = <2 1 0 0>; 282 interrupts = <2 1 0 0>;
283 reg = <0x1>; 283 reg = <0x1>;
284 }; 284 };
285 qe_phy2: ethernet-phy@02 { 285 qe_phy2: ethernet-phy@2 {
286 interrupt-parent = <&mpic>; 286 interrupt-parent = <&mpic>;
287 interrupts = <3 1 0 0>; 287 interrupts = <3 1 0 0>;
288 reg = <0x2>; 288 reg = <0x2>;
289 }; 289 };
290 qe_phy3: ethernet-phy@03 { 290 qe_phy3: ethernet-phy@3 {
291 interrupt-parent = <&mpic>; 291 interrupt-parent = <&mpic>;
292 interrupts = <4 1 0 0>; 292 interrupts = <4 1 0 0>;
293 reg = <0x3>; 293 reg = <0x3>;
294 }; 294 };
295 qe_phy5: ethernet-phy@04 { 295 qe_phy5: ethernet-phy@4 {
296 reg = <0x04>; 296 reg = <0x04>;
297 }; 297 };
298 qe_phy7: ethernet-phy@06 { 298 qe_phy7: ethernet-phy@6 {
299 reg = <0x6>; 299 reg = <0x6>;
300 }; 300 };
301 tbi1: tbi-phy@11 { 301 tbi1: tbi-phy@11 {
diff --git a/arch/powerpc/boot/dts/fsl/p1021mds.dts b/arch/powerpc/boot/dts/fsl/p1021mds.dts
index 291454c75dda..1047802f4d2a 100644
--- a/arch/powerpc/boot/dts/fsl/p1021mds.dts
+++ b/arch/powerpc/boot/dts/fsl/p1021mds.dts
@@ -202,7 +202,7 @@
202 ranges = <0x0 0xe0100 0x60>; 202 ranges = <0x0 0xe0100 0x60>;
203 device_type = "par_io"; 203 device_type = "par_io";
204 num-ports = <3>; 204 num-ports = <3>;
205 pio1: ucc_pin@01 { 205 pio1: ucc_pin@1 {
206 pio-map = < 206 pio-map = <
207 /* port pin dir open_drain assignment has_irq */ 207 /* port pin dir open_drain assignment has_irq */
208 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */ 208 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
@@ -225,7 +225,7 @@
225 0x0 0x10 0x2 0x0 0x2 0x0>; /* ENET1_COL */ 225 0x0 0x10 0x2 0x0 0x2 0x0>; /* ENET1_COL */
226 }; 226 };
227 227
228 pio2: ucc_pin@02 { 228 pio2: ucc_pin@2 {
229 pio-map = < 229 pio-map = <
230 /* port pin dir open_drain assignment has_irq */ 230 /* port pin dir open_drain assignment has_irq */
231 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */ 231 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
@@ -296,7 +296,7 @@
296 interrupts = <4 1 0 0>; 296 interrupts = <4 1 0 0>;
297 reg = <0x0>; 297 reg = <0x0>;
298 }; 298 };
299 qe_phy1: ethernet-phy@03 { 299 qe_phy1: ethernet-phy@3 {
300 interrupt-parent = <&mpic>; 300 interrupt-parent = <&mpic>;
301 interrupts = <5 1 0 0>; 301 interrupts = <5 1 0 0>;
302 reg = <0x3>; 302 reg = <0x3>;
diff --git a/arch/powerpc/boot/dts/fsl/p1025rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1025rdb.dtsi
index d44bb12debb0..0a5434a631c3 100644
--- a/arch/powerpc/boot/dts/fsl/p1025rdb.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1025rdb.dtsi
@@ -245,7 +245,7 @@
245 ranges = <0x0 0xe0100 0x60>; 245 ranges = <0x0 0xe0100 0x60>;
246 device_type = "par_io"; 246 device_type = "par_io";
247 num-ports = <3>; 247 num-ports = <3>;
248 pio1: ucc_pin@01 { 248 pio1: ucc_pin@1 {
249 pio-map = < 249 pio-map = <
250 /* port pin dir open_drain assignment has_irq */ 250 /* port pin dir open_drain assignment has_irq */
251 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */ 251 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
@@ -268,7 +268,7 @@
268 0x0 0x10 0x2 0x0 0x2 0x0>; /* ENET1_COL */ 268 0x0 0x10 0x2 0x0 0x2 0x0>; /* ENET1_COL */
269 }; 269 };
270 270
271 pio2: ucc_pin@02 { 271 pio2: ucc_pin@2 {
272 pio-map = < 272 pio-map = <
273 /* port pin dir open_drain assignment has_irq */ 273 /* port pin dir open_drain assignment has_irq */
274 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */ 274 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
@@ -283,7 +283,7 @@
283 0x1 0x8 0x2 0x0 0x2 0x0>; /* ENET5_RX_ER_SER5_CD_B */ 283 0x1 0x8 0x2 0x0 0x2 0x0>; /* ENET5_RX_ER_SER5_CD_B */
284 }; 284 };
285 285
286 pio3: ucc_pin@03 { 286 pio3: ucc_pin@3 {
287 pio-map = < 287 pio-map = <
288 /* port pin dir open_drain assignment has_irq */ 288 /* port pin dir open_drain assignment has_irq */
289 0x0 0x16 0x2 0x0 0x2 0x0 /* SER7_CD_B*/ 289 0x0 0x16 0x2 0x0 0x2 0x0 /* SER7_CD_B*/
@@ -293,7 +293,7 @@
293 0x0 0x15 0x1 0x0 0x2 0x0>; /* SER7_TXD0*/ 293 0x0 0x15 0x1 0x0 0x2 0x0>; /* SER7_TXD0*/
294 }; 294 };
295 295
296 pio4: ucc_pin@04 { 296 pio4: ucc_pin@4 {
297 pio-map = < 297 pio-map = <
298 /* port pin dir open_drain assignment has_irq */ 298 /* port pin dir open_drain assignment has_irq */
299 0x1 0x0 0x2 0x0 0x2 0x0 /* SER3_CD_B*/ 299 0x1 0x0 0x2 0x0 0x2 0x0 /* SER3_CD_B*/
diff --git a/arch/powerpc/boot/dts/fsl/p1025rdb_32b.dts b/arch/powerpc/boot/dts/fsl/p1025rdb_32b.dts
index b15acbaea34b..ea33b57f8774 100644
--- a/arch/powerpc/boot/dts/fsl/p1025rdb_32b.dts
+++ b/arch/powerpc/boot/dts/fsl/p1025rdb_32b.dts
@@ -106,7 +106,7 @@
106 interrupts = <4 1 0 0>; 106 interrupts = <4 1 0 0>;
107 reg = <0x6>; 107 reg = <0x6>;
108 }; 108 };
109 qe_phy1: ethernet-phy@03 { 109 qe_phy1: ethernet-phy@3 {
110 interrupt-parent = <&mpic>; 110 interrupt-parent = <&mpic>;
111 interrupts = <5 1 0 0>; 111 interrupts = <5 1 0 0>;
112 reg = <0x3>; 112 reg = <0x3>;
diff --git a/arch/powerpc/boot/dts/fsl/p1025twr.dtsi b/arch/powerpc/boot/dts/fsl/p1025twr.dtsi
index 08816fb474f5..ab75b8f29ae2 100644
--- a/arch/powerpc/boot/dts/fsl/p1025twr.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1025twr.dtsi
@@ -172,7 +172,7 @@
172 ranges = <0x0 0xe0100 0x60>; 172 ranges = <0x0 0xe0100 0x60>;
173 device_type = "par_io"; 173 device_type = "par_io";
174 num-ports = <3>; 174 num-ports = <3>;
175 pio1: ucc_pin@01 { 175 pio1: ucc_pin@1 {
176 pio-map = < 176 pio-map = <
177 /* port pin dir open_drain assignment has_irq */ 177 /* port pin dir open_drain assignment has_irq */
178 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */ 178 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
@@ -195,7 +195,7 @@
195 0x0 0x10 0x2 0x0 0x2 0x0>; /* ENET1_COL */ 195 0x0 0x10 0x2 0x0 0x2 0x0>; /* ENET1_COL */
196 }; 196 };
197 197
198 pio2: ucc_pin@02 { 198 pio2: ucc_pin@2 {
199 pio-map = < 199 pio-map = <
200 /* port pin dir open_drain assignment has_irq */ 200 /* port pin dir open_drain assignment has_irq */
201 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */ 201 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
@@ -210,7 +210,7 @@
210 0x1 0x8 0x2 0x0 0x2 0x0>; /* ENET5_RX_ER_SER5_CD_B */ 210 0x1 0x8 0x2 0x0 0x2 0x0>; /* ENET5_RX_ER_SER5_CD_B */
211 }; 211 };
212 212
213 pio3: ucc_pin@03 { 213 pio3: ucc_pin@3 {
214 pio-map = < 214 pio-map = <
215 /* port pin dir open_drain assignment has_irq */ 215 /* port pin dir open_drain assignment has_irq */
216 0x0 0x16 0x2 0x0 0x2 0x0 /* SER7_CD_B*/ 216 0x0 0x16 0x2 0x0 0x2 0x0 /* SER7_CD_B*/
@@ -220,7 +220,7 @@
220 0x0 0x15 0x1 0x0 0x2 0x0>; /* SER7_TXD0*/ 220 0x0 0x15 0x1 0x0 0x2 0x0>; /* SER7_TXD0*/
221 }; 221 };
222 222
223 pio4: ucc_pin@04 { 223 pio4: ucc_pin@4 {
224 pio-map = < 224 pio-map = <
225 /* port pin dir open_drain assignment has_irq */ 225 /* port pin dir open_drain assignment has_irq */
226 0x1 0x0 0x2 0x0 0x2 0x0 /* SER3_CD_B*/ 226 0x1 0x0 0x2 0x0 0x2 0x0 /* SER3_CD_B*/
diff --git a/arch/powerpc/boot/dts/fsl/t1040rdb.dts b/arch/powerpc/boot/dts/fsl/t1040rdb.dts
index 621f2c6ee6ad..65ff34c49025 100644
--- a/arch/powerpc/boot/dts/fsl/t1040rdb.dts
+++ b/arch/powerpc/boot/dts/fsl/t1040rdb.dts
@@ -61,7 +61,7 @@
61 }; 61 };
62 62
63 mdio@fc000 { 63 mdio@fc000 {
64 phy_sgmii_2: ethernet-phy@03 { 64 phy_sgmii_2: ethernet-phy@3 {
65 reg = <0x03>; 65 reg = <0x03>;
66 }; 66 };
67 }; 67 };
diff --git a/arch/powerpc/boot/dts/fsl/t1042d4rdb.dts b/arch/powerpc/boot/dts/fsl/t1042d4rdb.dts
index fcd2aeb5b8ac..4fa15f48a4c3 100644
--- a/arch/powerpc/boot/dts/fsl/t1042d4rdb.dts
+++ b/arch/powerpc/boot/dts/fsl/t1042d4rdb.dts
@@ -77,23 +77,23 @@
77 }; 77 };
78 78
79 mdio0: mdio@fc000 { 79 mdio0: mdio@fc000 {
80 phy_sgmii_0: ethernet-phy@02 { 80 phy_sgmii_0: ethernet-phy@2 {
81 reg = <0x02>; 81 reg = <0x02>;
82 }; 82 };
83 83
84 phy_sgmii_1: ethernet-phy@03 { 84 phy_sgmii_1: ethernet-phy@3 {
85 reg = <0x03>; 85 reg = <0x03>;
86 }; 86 };
87 87
88 phy_sgmii_2: ethernet-phy@01 { 88 phy_sgmii_2: ethernet-phy@1 {
89 reg = <0x01>; 89 reg = <0x01>;
90 }; 90 };
91 91
92 phy_rgmii_0: ethernet-phy@04 { 92 phy_rgmii_0: ethernet-phy@4 {
93 reg = <0x04>; 93 reg = <0x04>;
94 }; 94 };
95 95
96 phy_rgmii_1: ethernet-phy@05 { 96 phy_rgmii_1: ethernet-phy@5 {
97 reg = <0x05>; 97 reg = <0x05>;
98 }; 98 };
99 }; 99 };
diff --git a/arch/powerpc/boot/dts/fsl/t1042rdb.dts b/arch/powerpc/boot/dts/fsl/t1042rdb.dts
index 2c138627b1b4..3ebb712224cb 100644
--- a/arch/powerpc/boot/dts/fsl/t1042rdb.dts
+++ b/arch/powerpc/boot/dts/fsl/t1042rdb.dts
@@ -59,7 +59,7 @@
59 }; 59 };
60 60
61 mdio@fc000 { 61 mdio@fc000 {
62 phy_sgmii_2: ethernet-phy@03 { 62 phy_sgmii_2: ethernet-phy@3 {
63 reg = <0x03>; 63 reg = <0x03>;
64 }; 64 };
65 }; 65 };
diff --git a/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi b/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi
index 5fdddbd2a62b..099a598c74c0 100644
--- a/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi
@@ -148,15 +148,15 @@
148 }; 148 };
149 149
150 mdio0: mdio@fc000 { 150 mdio0: mdio@fc000 {
151 phy_sgmii_2: ethernet-phy@03 { 151 phy_sgmii_2: ethernet-phy@3 {
152 reg = <0x03>; 152 reg = <0x03>;
153 }; 153 };
154 154
155 phy_rgmii_0: ethernet-phy@01 { 155 phy_rgmii_0: ethernet-phy@1 {
156 reg = <0x01>; 156 reg = <0x01>;
157 }; 157 };
158 158
159 phy_rgmii_1: ethernet-phy@02 { 159 phy_rgmii_1: ethernet-phy@2 {
160 reg = <0x02>; 160 reg = <0x02>;
161 }; 161 };
162 }; 162 };
diff --git a/arch/powerpc/boot/dts/fsp2.dts b/arch/powerpc/boot/dts/fsp2.dts
index f10a64aeb83b..6560283c5aec 100644
--- a/arch/powerpc/boot/dts/fsp2.dts
+++ b/arch/powerpc/boot/dts/fsp2.dts
@@ -583,21 +583,21 @@
583 }; 583 };
584 }; 584 };
585 585
586 OHCI1: ohci@02040000 { 586 OHCI1: ohci@2040000 {
587 compatible = "ohci-le"; 587 compatible = "ohci-le";
588 reg = <0x02040000 0xa0>; 588 reg = <0x02040000 0xa0>;
589 interrupt-parent = <&UIC1_3>; 589 interrupt-parent = <&UIC1_3>;
590 interrupts = <28 0x8 29 0x8>; 590 interrupts = <28 0x8 29 0x8>;
591 }; 591 };
592 592
593 OHCI2: ohci@02080000 { 593 OHCI2: ohci@2080000 {
594 compatible = "ohci-le"; 594 compatible = "ohci-le";
595 reg = <0x02080000 0xa0>; 595 reg = <0x02080000 0xa0>;
596 interrupt-parent = <&UIC1_3>; 596 interrupt-parent = <&UIC1_3>;
597 interrupts = <30 0x8 31 0x8>; 597 interrupts = <30 0x8 31 0x8>;
598 }; 598 };
599 599
600 EHCI: ehci@02000000 { 600 EHCI: ehci@2000000 {
601 compatible = "usb-ehci"; 601 compatible = "usb-ehci";
602 reg = <0x02000000 0xa4>; 602 reg = <0x02000000 0xa4>;
603 interrupt-parent = <&UIC1_3>; 603 interrupt-parent = <&UIC1_3>;
diff --git a/arch/powerpc/boot/dts/gamecube.dts b/arch/powerpc/boot/dts/gamecube.dts
index ef3be0e58b02..58d06c9ee08b 100644
--- a/arch/powerpc/boot/dts/gamecube.dts
+++ b/arch/powerpc/boot/dts/gamecube.dts
@@ -54,13 +54,13 @@
54 ranges = <0x0c000000 0x0c000000 0x00010000>; 54 ranges = <0x0c000000 0x0c000000 0x00010000>;
55 interrupt-parent = <&PIC>; 55 interrupt-parent = <&PIC>;
56 56
57 video@0c002000 { 57 video@c002000 {
58 compatible = "nintendo,flipper-vi"; 58 compatible = "nintendo,flipper-vi";
59 reg = <0x0c002000 0x100>; 59 reg = <0x0c002000 0x100>;
60 interrupts = <8>; 60 interrupts = <8>;
61 }; 61 };
62 62
63 processor-interface@0c003000 { 63 processor-interface@c003000 {
64 compatible = "nintendo,flipper-pi"; 64 compatible = "nintendo,flipper-pi";
65 reg = <0x0c003000 0x100>; 65 reg = <0x0c003000 0x100>;
66 66
@@ -71,7 +71,7 @@
71 }; 71 };
72 }; 72 };
73 73
74 dsp@0c005000 { 74 dsp@c005000 {
75 #address-cells = <1>; 75 #address-cells = <1>;
76 #size-cells = <1>; 76 #size-cells = <1>;
77 compatible = "nintendo,flipper-dsp"; 77 compatible = "nintendo,flipper-dsp";
@@ -84,26 +84,26 @@
84 }; 84 };
85 }; 85 };
86 86
87 disk@0c006000 { 87 disk@c006000 {
88 compatible = "nintendo,flipper-di"; 88 compatible = "nintendo,flipper-di";
89 reg = <0x0c006000 0x40>; 89 reg = <0x0c006000 0x40>;
90 interrupts = <2>; 90 interrupts = <2>;
91 }; 91 };
92 92
93 audio@0c006c00 { 93 audio@c006c00 {
94 compatible = "nintendo,flipper-ai"; 94 compatible = "nintendo,flipper-ai";
95 reg = <0x0c006c00 0x20>; 95 reg = <0x0c006c00 0x20>;
96 interrupts = <6>; 96 interrupts = <6>;
97 }; 97 };
98 98
99 gamepad-controller@0c006400 { 99 gamepad-controller@c006400 {
100 compatible = "nintendo,flipper-si"; 100 compatible = "nintendo,flipper-si";
101 reg = <0x0c006400 0x100>; 101 reg = <0x0c006400 0x100>;
102 interrupts = <3>; 102 interrupts = <3>;
103 }; 103 };
104 104
105 /* External Interface bus */ 105 /* External Interface bus */
106 exi@0c006800 { 106 exi@c006800 {
107 compatible = "nintendo,flipper-exi"; 107 compatible = "nintendo,flipper-exi";
108 reg = <0x0c006800 0x40>; 108 reg = <0x0c006800 0x40>;
109 virtual-reg = <0x0c006800>; 109 virtual-reg = <0x0c006800>;
diff --git a/arch/powerpc/boot/dts/haleakala.dts b/arch/powerpc/boot/dts/haleakala.dts
index 2b256694eca6..cb16dad43c92 100644
--- a/arch/powerpc/boot/dts/haleakala.dts
+++ b/arch/powerpc/boot/dts/haleakala.dts
@@ -237,7 +237,7 @@
237 }; 237 };
238 }; 238 };
239 239
240 PCIE0: pciex@0a0000000 { 240 PCIE0: pciex@a0000000 {
241 device_type = "pci"; 241 device_type = "pci";
242 #interrupt-cells = <1>; 242 #interrupt-cells = <1>;
243 #size-cells = <2>; 243 #size-cells = <2>;
diff --git a/arch/powerpc/boot/dts/kilauea.dts b/arch/powerpc/boot/dts/kilauea.dts
index 5ba7f01e2a29..2a3413221cc1 100644
--- a/arch/powerpc/boot/dts/kilauea.dts
+++ b/arch/powerpc/boot/dts/kilauea.dts
@@ -322,7 +322,7 @@
322 }; 322 };
323 }; 323 };
324 324
325 PCIE0: pciex@0a0000000 { 325 PCIE0: pciex@a0000000 {
326 device_type = "pci"; 326 device_type = "pci";
327 #interrupt-cells = <1>; 327 #interrupt-cells = <1>;
328 #size-cells = <2>; 328 #size-cells = <2>;
@@ -363,7 +363,7 @@
363 0x0 0x0 0x0 0x4 &UIC2 0x3 0x4 /* swizzled int D */>; 363 0x0 0x0 0x0 0x4 &UIC2 0x3 0x4 /* swizzled int D */>;
364 }; 364 };
365 365
366 PCIE1: pciex@0c0000000 { 366 PCIE1: pciex@c0000000 {
367 device_type = "pci"; 367 device_type = "pci";
368 #interrupt-cells = <1>; 368 #interrupt-cells = <1>;
369 #size-cells = <2>; 369 #size-cells = <2>;
diff --git a/arch/powerpc/boot/dts/kmeter1.dts b/arch/powerpc/boot/dts/kmeter1.dts
index 983aee185793..9fa33d9ba966 100644
--- a/arch/powerpc/boot/dts/kmeter1.dts
+++ b/arch/powerpc/boot/dts/kmeter1.dts
@@ -434,27 +434,27 @@
434 compatible = "fsl,ucc-mdio"; 434 compatible = "fsl,ucc-mdio";
435 435
436 /* Piggy2 (UCC4, MDIO 0x00, RMII) */ 436 /* Piggy2 (UCC4, MDIO 0x00, RMII) */
437 phy_piggy2: ethernet-phy@00 { 437 phy_piggy2: ethernet-phy@0 {
438 reg = <0x0>; 438 reg = <0x0>;
439 }; 439 };
440 440
441 /* Eth-1 (UCC5, MDIO 0x08, RMII) */ 441 /* Eth-1 (UCC5, MDIO 0x08, RMII) */
442 phy_eth1: ethernet-phy@08 { 442 phy_eth1: ethernet-phy@8 {
443 reg = <0x08>; 443 reg = <0x08>;
444 }; 444 };
445 445
446 /* Eth-2 (UCC6, MDIO 0x09, RMII) */ 446 /* Eth-2 (UCC6, MDIO 0x09, RMII) */
447 phy_eth2: ethernet-phy@09 { 447 phy_eth2: ethernet-phy@9 {
448 reg = <0x09>; 448 reg = <0x09>;
449 }; 449 };
450 450
451 /* Eth-3 (UCC7, MDIO 0x0a, RMII) */ 451 /* Eth-3 (UCC7, MDIO 0x0a, RMII) */
452 phy_eth3: ethernet-phy@0a { 452 phy_eth3: ethernet-phy@a {
453 reg = <0x0a>; 453 reg = <0x0a>;
454 }; 454 };
455 455
456 /* Eth-4 (UCC8, MDIO 0x0b, RMII) */ 456 /* Eth-4 (UCC8, MDIO 0x0b, RMII) */
457 phy_eth4: ethernet-phy@0b { 457 phy_eth4: ethernet-phy@b {
458 reg = <0x0b>; 458 reg = <0x0b>;
459 }; 459 };
460 460
diff --git a/arch/powerpc/boot/dts/makalu.dts b/arch/powerpc/boot/dts/makalu.dts
index 63d48b632c84..bf8fe1629392 100644
--- a/arch/powerpc/boot/dts/makalu.dts
+++ b/arch/powerpc/boot/dts/makalu.dts
@@ -268,7 +268,7 @@
268 }; 268 };
269 }; 269 };
270 270
271 PCIE0: pciex@0a0000000 { 271 PCIE0: pciex@a0000000 {
272 device_type = "pci"; 272 device_type = "pci";
273 #interrupt-cells = <1>; 273 #interrupt-cells = <1>;
274 #size-cells = <2>; 274 #size-cells = <2>;
@@ -309,7 +309,7 @@
309 0x0 0x0 0x0 0x4 &UIC2 0x3 0x4 /* swizzled int D */>; 309 0x0 0x0 0x0 0x4 &UIC2 0x3 0x4 /* swizzled int D */>;
310 }; 310 };
311 311
312 PCIE1: pciex@0c0000000 { 312 PCIE1: pciex@c0000000 {
313 device_type = "pci"; 313 device_type = "pci";
314 #interrupt-cells = <1>; 314 #interrupt-cells = <1>;
315 #size-cells = <2>; 315 #size-cells = <2>;
diff --git a/arch/powerpc/boot/dts/mpc832x_mds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts
index 0793cdf0d46e..49c7d657118a 100644
--- a/arch/powerpc/boot/dts/mpc832x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc832x_mds.dts
@@ -186,7 +186,7 @@
186 device_type = "par_io"; 186 device_type = "par_io";
187 num-ports = <7>; 187 num-ports = <7>;
188 188
189 pio3: ucc_pin@03 { 189 pio3: ucc_pin@3 {
190 pio-map = < 190 pio-map = <
191 /* port pin dir open_drain assignment has_irq */ 191 /* port pin dir open_drain assignment has_irq */
192 3 4 3 0 2 0 /* MDIO */ 192 3 4 3 0 2 0 /* MDIO */
@@ -208,7 +208,7 @@
208 1 12 1 0 1 0 /* TX_EN */ 208 1 12 1 0 1 0 /* TX_EN */
209 1 13 2 0 1 0>; /* CRS */ 209 1 13 2 0 1 0>; /* CRS */
210 }; 210 };
211 pio4: ucc_pin@04 { 211 pio4: ucc_pin@4 {
212 pio-map = < 212 pio-map = <
213 /* port pin dir open_drain assignment has_irq */ 213 /* port pin dir open_drain assignment has_irq */
214 3 31 2 0 1 0 /* RX_CLK (CLK7) */ 214 3 31 2 0 1 0 /* RX_CLK (CLK7) */
@@ -228,7 +228,7 @@
228 1 30 1 0 1 0 /* TX_EN */ 228 1 30 1 0 1 0 /* TX_EN */
229 1 31 2 0 1 0>; /* CRS */ 229 1 31 2 0 1 0>; /* CRS */
230 }; 230 };
231 pio5: ucc_pin@05 { 231 pio5: ucc_pin@5 {
232 pio-map = < 232 pio-map = <
233 /* 233 /*
234 * open has 234 * open has
@@ -352,12 +352,12 @@
352 reg = <0x2320 0x18>; 352 reg = <0x2320 0x18>;
353 compatible = "fsl,ucc-mdio"; 353 compatible = "fsl,ucc-mdio";
354 354
355 phy3: ethernet-phy@03 { 355 phy3: ethernet-phy@3 {
356 interrupt-parent = <&ipic>; 356 interrupt-parent = <&ipic>;
357 interrupts = <17 0x8>; 357 interrupts = <17 0x8>;
358 reg = <0x3>; 358 reg = <0x3>;
359 }; 359 };
360 phy4: ethernet-phy@04 { 360 phy4: ethernet-phy@4 {
361 interrupt-parent = <&ipic>; 361 interrupt-parent = <&ipic>;
362 interrupts = <18 0x8>; 362 interrupts = <18 0x8>;
363 reg = <0x4>; 363 reg = <0x4>;
diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts
index 91df1eb16667..647cae14c16d 100644
--- a/arch/powerpc/boot/dts/mpc832x_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts
@@ -175,7 +175,7 @@
175 gpio-controller; 175 gpio-controller;
176 }; 176 };
177 177
178 ucc2pio:ucc_pin@02 { 178 ucc2pio:ucc_pin@2 {
179 pio-map = < 179 pio-map = <
180 /* port pin dir open_drain assignment has_irq */ 180 /* port pin dir open_drain assignment has_irq */
181 3 4 3 0 2 0 /* MDIO */ 181 3 4 3 0 2 0 /* MDIO */
@@ -197,7 +197,7 @@
197 0 30 1 0 1 0 /* TX_EN */ 197 0 30 1 0 1 0 /* TX_EN */
198 0 31 2 0 1 0>; /* CRS */ 198 0 31 2 0 1 0>; /* CRS */
199 }; 199 };
200 ucc3pio:ucc_pin@03 { 200 ucc3pio:ucc_pin@3 {
201 pio-map = < 201 pio-map = <
202 /* port pin dir open_drain assignment has_irq */ 202 /* port pin dir open_drain assignment has_irq */
203 0 13 2 0 1 0 /* RX_CLK (CLK9) */ 203 0 13 2 0 1 0 /* RX_CLK (CLK9) */
@@ -310,12 +310,12 @@
310 reg = <0x3120 0x18>; 310 reg = <0x3120 0x18>;
311 compatible = "fsl,ucc-mdio"; 311 compatible = "fsl,ucc-mdio";
312 312
313 phy00:ethernet-phy@00 { 313 phy00:ethernet-phy@0 {
314 interrupt-parent = <&ipic>; 314 interrupt-parent = <&ipic>;
315 interrupts = <0>; 315 interrupts = <0>;
316 reg = <0x0>; 316 reg = <0x0>;
317 }; 317 };
318 phy04:ethernet-phy@04 { 318 phy04:ethernet-phy@4 {
319 interrupt-parent = <&ipic>; 319 interrupt-parent = <&ipic>;
320 interrupts = <0>; 320 interrupts = <0>;
321 reg = <0x4>; 321 reg = <0x4>;
diff --git a/arch/powerpc/boot/dts/mpc836x_mds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts
index ecb6ccd3a6aa..539fd9f72eda 100644
--- a/arch/powerpc/boot/dts/mpc836x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc836x_mds.dts
@@ -228,7 +228,7 @@
228 gpio-controller; 228 gpio-controller;
229 }; 229 };
230 230
231 pio1: ucc_pin@01 { 231 pio1: ucc_pin@1 {
232 pio-map = < 232 pio-map = <
233 /* port pin dir open_drain assignment has_irq */ 233 /* port pin dir open_drain assignment has_irq */
234 0 3 1 0 1 0 /* TxD0 */ 234 0 3 1 0 1 0 /* TxD0 */
@@ -255,7 +255,7 @@
255 2 9 1 0 3 0 /* GTX_CLK - CLK10 */ 255 2 9 1 0 3 0 /* GTX_CLK - CLK10 */
256 2 8 2 0 1 0>; /* GTX125 - CLK9 */ 256 2 8 2 0 1 0>; /* GTX125 - CLK9 */
257 }; 257 };
258 pio2: ucc_pin@02 { 258 pio2: ucc_pin@2 {
259 pio-map = < 259 pio-map = <
260 /* port pin dir open_drain assignment has_irq */ 260 /* port pin dir open_drain assignment has_irq */
261 0 17 1 0 1 0 /* TxD0 */ 261 0 17 1 0 1 0 /* TxD0 */
@@ -393,12 +393,12 @@
393 reg = <0x2120 0x18>; 393 reg = <0x2120 0x18>;
394 compatible = "fsl,ucc-mdio"; 394 compatible = "fsl,ucc-mdio";
395 395
396 phy0: ethernet-phy@00 { 396 phy0: ethernet-phy@0 {
397 interrupt-parent = <&ipic>; 397 interrupt-parent = <&ipic>;
398 interrupts = <17 0x8>; 398 interrupts = <17 0x8>;
399 reg = <0x0>; 399 reg = <0x0>;
400 }; 400 };
401 phy1: ethernet-phy@01 { 401 phy1: ethernet-phy@1 {
402 interrupt-parent = <&ipic>; 402 interrupt-parent = <&ipic>;
403 interrupts = <18 0x8>; 403 interrupts = <18 0x8>;
404 reg = <0x1>; 404 reg = <0x1>;
diff --git a/arch/powerpc/boot/dts/sbc8548-altflash.dts b/arch/powerpc/boot/dts/sbc8548-altflash.dts
index 0b38a0defd2c..8967a56adad4 100644
--- a/arch/powerpc/boot/dts/sbc8548-altflash.dts
+++ b/arch/powerpc/boot/dts/sbc8548-altflash.dts
@@ -40,12 +40,12 @@
40 compatible = "intel,JS28F128", "cfi-flash"; 40 compatible = "intel,JS28F128", "cfi-flash";
41 bank-width = <4>; 41 bank-width = <4>;
42 device-width = <1>; 42 device-width = <1>;
43 partition@0x0 { 43 partition@0 {
44 label = "space"; 44 label = "space";
45 /* FC000000 -> FFEFFFFF */ 45 /* FC000000 -> FFEFFFFF */
46 reg = <0x00000000 0x03f00000>; 46 reg = <0x00000000 0x03f00000>;
47 }; 47 };
48 partition@0x03f00000 { 48 partition@3f00000 {
49 label = "bootloader"; 49 label = "bootloader";
50 /* FFF00000 -> FFFFFFFF */ 50 /* FFF00000 -> FFFFFFFF */
51 reg = <0x03f00000 0x00100000>; 51 reg = <0x03f00000 0x00100000>;
@@ -95,12 +95,12 @@
95 reg = <0x6 0x0 0x800000>; 95 reg = <0x6 0x0 0x800000>;
96 bank-width = <1>; 96 bank-width = <1>;
97 device-width = <1>; 97 device-width = <1>;
98 partition@0x0 { 98 partition@0 {
99 label = "space"; 99 label = "space";
100 /* EF800000 -> EFF9FFFF */ 100 /* EF800000 -> EFF9FFFF */
101 reg = <0x00000000 0x007a0000>; 101 reg = <0x00000000 0x007a0000>;
102 }; 102 };
103 partition@0x7a0000 { 103 partition@7a0000 {
104 label = "bootloader"; 104 label = "bootloader";
105 /* EFFA0000 -> EFFFFFFF */ 105 /* EFFA0000 -> EFFFFFFF */
106 reg = <0x007a0000 0x00060000>; 106 reg = <0x007a0000 0x00060000>;
diff --git a/arch/powerpc/boot/dts/sbc8548.dts b/arch/powerpc/boot/dts/sbc8548.dts
index 1df2a0955668..9bdb828a504e 100644
--- a/arch/powerpc/boot/dts/sbc8548.dts
+++ b/arch/powerpc/boot/dts/sbc8548.dts
@@ -38,12 +38,12 @@
38 reg = <0x0 0x0 0x800000>; 38 reg = <0x0 0x0 0x800000>;
39 bank-width = <1>; 39 bank-width = <1>;
40 device-width = <1>; 40 device-width = <1>;
41 partition@0x0 { 41 partition@0 {
42 label = "space"; 42 label = "space";
43 /* FF800000 -> FFF9FFFF */ 43 /* FF800000 -> FFF9FFFF */
44 reg = <0x00000000 0x007a0000>; 44 reg = <0x00000000 0x007a0000>;
45 }; 45 };
46 partition@0x7a0000 { 46 partition@7a0000 {
47 label = "bootloader"; 47 label = "bootloader";
48 /* FFFA0000 -> FFFFFFFF */ 48 /* FFFA0000 -> FFFFFFFF */
49 reg = <0x007a0000 0x00060000>; 49 reg = <0x007a0000 0x00060000>;
@@ -92,12 +92,12 @@
92 compatible = "intel,JS28F128", "cfi-flash"; 92 compatible = "intel,JS28F128", "cfi-flash";
93 bank-width = <4>; 93 bank-width = <4>;
94 device-width = <1>; 94 device-width = <1>;
95 partition@0x0 { 95 partition@0 {
96 label = "space"; 96 label = "space";
97 /* EC000000 -> EFEFFFFF */ 97 /* EC000000 -> EFEFFFFF */
98 reg = <0x00000000 0x03f00000>; 98 reg = <0x00000000 0x03f00000>;
99 }; 99 };
100 partition@0x03f00000 { 100 partition@3f00000 {
101 label = "bootloader"; 101 label = "bootloader";
102 /* EFF00000 -> EFFFFFFF */ 102 /* EFF00000 -> EFFFFFFF */
103 reg = <0x03f00000 0x00100000>; 103 reg = <0x03f00000 0x00100000>;
diff --git a/arch/powerpc/boot/dts/wii.dts b/arch/powerpc/boot/dts/wii.dts
index 77528c9a8dbd..17a5babb098d 100644
--- a/arch/powerpc/boot/dts/wii.dts
+++ b/arch/powerpc/boot/dts/wii.dts
@@ -65,14 +65,14 @@
65 0x0d800000 0x0d800000 0x00800000>; 65 0x0d800000 0x0d800000 0x00800000>;
66 interrupt-parent = <&PIC0>; 66 interrupt-parent = <&PIC0>;
67 67
68 video@0c002000 { 68 video@c002000 {
69 compatible = "nintendo,hollywood-vi", 69 compatible = "nintendo,hollywood-vi",
70 "nintendo,flipper-vi"; 70 "nintendo,flipper-vi";
71 reg = <0x0c002000 0x100>; 71 reg = <0x0c002000 0x100>;
72 interrupts = <8>; 72 interrupts = <8>;
73 }; 73 };
74 74
75 processor-interface@0c003000 { 75 processor-interface@c003000 {
76 compatible = "nintendo,hollywood-pi", 76 compatible = "nintendo,hollywood-pi",
77 "nintendo,flipper-pi"; 77 "nintendo,flipper-pi";
78 reg = <0x0c003000 0x100>; 78 reg = <0x0c003000 0x100>;
@@ -84,7 +84,7 @@
84 }; 84 };
85 }; 85 };
86 86
87 dsp@0c005000 { 87 dsp@c005000 {
88 #address-cells = <1>; 88 #address-cells = <1>;
89 #size-cells = <1>; 89 #size-cells = <1>;
90 compatible = "nintendo,hollywood-dsp", 90 compatible = "nintendo,hollywood-dsp",
@@ -93,14 +93,14 @@
93 interrupts = <6>; 93 interrupts = <6>;
94 }; 94 };
95 95
96 gamepad-controller@0d006400 { 96 gamepad-controller@d006400 {
97 compatible = "nintendo,hollywood-si", 97 compatible = "nintendo,hollywood-si",
98 "nintendo,flipper-si"; 98 "nintendo,flipper-si";
99 reg = <0x0d006400 0x100>; 99 reg = <0x0d006400 0x100>;
100 interrupts = <3>; 100 interrupts = <3>;
101 }; 101 };
102 102
103 audio@0c006c00 { 103 audio@c006c00 {
104 compatible = "nintendo,hollywood-ai", 104 compatible = "nintendo,hollywood-ai",
105 "nintendo,flipper-ai"; 105 "nintendo,flipper-ai";
106 reg = <0x0d006c00 0x20>; 106 reg = <0x0d006c00 0x20>;
@@ -108,7 +108,7 @@
108 }; 108 };
109 109
110 /* External Interface bus */ 110 /* External Interface bus */
111 exi@0d006800 { 111 exi@d006800 {
112 compatible = "nintendo,hollywood-exi", 112 compatible = "nintendo,hollywood-exi",
113 "nintendo,flipper-exi"; 113 "nintendo,flipper-exi";
114 reg = <0x0d006800 0x40>; 114 reg = <0x0d006800 0x40>;
@@ -116,7 +116,7 @@
116 interrupts = <4>; 116 interrupts = <4>;
117 }; 117 };
118 118
119 usb@0d040000 { 119 usb@d040000 {
120 compatible = "nintendo,hollywood-usb-ehci", 120 compatible = "nintendo,hollywood-usb-ehci",
121 "usb-ehci"; 121 "usb-ehci";
122 reg = <0x0d040000 0x100>; 122 reg = <0x0d040000 0x100>;
@@ -124,7 +124,7 @@
124 interrupt-parent = <&PIC1>; 124 interrupt-parent = <&PIC1>;
125 }; 125 };
126 126
127 usb@0d050000 { 127 usb@d050000 {
128 compatible = "nintendo,hollywood-usb-ohci", 128 compatible = "nintendo,hollywood-usb-ohci",
129 "usb-ohci"; 129 "usb-ohci";
130 reg = <0x0d050000 0x100>; 130 reg = <0x0d050000 0x100>;
@@ -132,7 +132,7 @@
132 interrupt-parent = <&PIC1>; 132 interrupt-parent = <&PIC1>;
133 }; 133 };
134 134
135 usb@0d060000 { 135 usb@d060000 {
136 compatible = "nintendo,hollywood-usb-ohci", 136 compatible = "nintendo,hollywood-usb-ohci",
137 "usb-ohci"; 137 "usb-ohci";
138 reg = <0x0d060000 0x100>; 138 reg = <0x0d060000 0x100>;
@@ -140,7 +140,7 @@
140 interrupt-parent = <&PIC1>; 140 interrupt-parent = <&PIC1>;
141 }; 141 };
142 142
143 sd@0d070000 { 143 sd@d070000 {
144 compatible = "nintendo,hollywood-sdhci", 144 compatible = "nintendo,hollywood-sdhci",
145 "sdhci"; 145 "sdhci";
146 reg = <0x0d070000 0x200>; 146 reg = <0x0d070000 0x200>;
@@ -148,7 +148,7 @@
148 interrupt-parent = <&PIC1>; 148 interrupt-parent = <&PIC1>;
149 }; 149 };
150 150
151 sdio@0d080000 { 151 sdio@d080000 {
152 compatible = "nintendo,hollywood-sdhci", 152 compatible = "nintendo,hollywood-sdhci",
153 "sdhci"; 153 "sdhci";
154 reg = <0x0d080000 0x200>; 154 reg = <0x0d080000 0x200>;
@@ -156,14 +156,14 @@
156 interrupt-parent = <&PIC1>; 156 interrupt-parent = <&PIC1>;
157 }; 157 };
158 158
159 ipc@0d000000 { 159 ipc@d000000 {
160 compatible = "nintendo,hollywood-ipc"; 160 compatible = "nintendo,hollywood-ipc";
161 reg = <0x0d000000 0x10>; 161 reg = <0x0d000000 0x10>;
162 interrupts = <30>; 162 interrupts = <30>;
163 interrupt-parent = <&PIC1>; 163 interrupt-parent = <&PIC1>;
164 }; 164 };
165 165
166 PIC1: pic1@0d800030 { 166 PIC1: pic1@d800030 {
167 #interrupt-cells = <1>; 167 #interrupt-cells = <1>;
168 compatible = "nintendo,hollywood-pic"; 168 compatible = "nintendo,hollywood-pic";
169 reg = <0x0d800030 0x10>; 169 reg = <0x0d800030 0x10>;
@@ -171,7 +171,7 @@
171 interrupts = <14>; 171 interrupts = <14>;
172 }; 172 };
173 173
174 GPIO: gpio@0d8000c0 { 174 GPIO: gpio@d8000c0 {
175 #gpio-cells = <2>; 175 #gpio-cells = <2>;
176 compatible = "nintendo,hollywood-gpio"; 176 compatible = "nintendo,hollywood-gpio";
177 reg = <0x0d8000c0 0x40>; 177 reg = <0x0d8000c0 0x40>;
@@ -203,12 +203,12 @@
203 */ 203 */
204 }; 204 };
205 205
206 control@0d800100 { 206 control@d800100 {
207 compatible = "nintendo,hollywood-control"; 207 compatible = "nintendo,hollywood-control";
208 reg = <0x0d800100 0x300>; 208 reg = <0x0d800100 0x300>;
209 }; 209 };
210 210
211 disk@0d806000 { 211 disk@d806000 {
212 compatible = "nintendo,hollywood-di"; 212 compatible = "nintendo,hollywood-di";
213 reg = <0x0d806000 0x40>; 213 reg = <0x0d806000 0x40>;
214 interrupts = <2>; 214 interrupts = <2>;
diff --git a/arch/powerpc/boot/serial.c b/arch/powerpc/boot/serial.c
index 7b5c02b1afd0..88955095ec07 100644
--- a/arch/powerpc/boot/serial.c
+++ b/arch/powerpc/boot/serial.c
@@ -124,20 +124,26 @@ int serial_console_init(void)
124 else if (dt_is_compatible(devp, "marvell,mv64360-mpsc")) 124 else if (dt_is_compatible(devp, "marvell,mv64360-mpsc"))
125 rc = mpsc_console_init(devp, &serial_cd); 125 rc = mpsc_console_init(devp, &serial_cd);
126#endif 126#endif
127#ifdef CONFIG_CPM
127 else if (dt_is_compatible(devp, "fsl,cpm1-scc-uart") || 128 else if (dt_is_compatible(devp, "fsl,cpm1-scc-uart") ||
128 dt_is_compatible(devp, "fsl,cpm1-smc-uart") || 129 dt_is_compatible(devp, "fsl,cpm1-smc-uart") ||
129 dt_is_compatible(devp, "fsl,cpm2-scc-uart") || 130 dt_is_compatible(devp, "fsl,cpm2-scc-uart") ||
130 dt_is_compatible(devp, "fsl,cpm2-smc-uart")) 131 dt_is_compatible(devp, "fsl,cpm2-smc-uart"))
131 rc = cpm_console_init(devp, &serial_cd); 132 rc = cpm_console_init(devp, &serial_cd);
133#endif
132#ifdef CONFIG_PPC_MPC52XX 134#ifdef CONFIG_PPC_MPC52XX
133 else if (dt_is_compatible(devp, "fsl,mpc5200-psc-uart")) 135 else if (dt_is_compatible(devp, "fsl,mpc5200-psc-uart"))
134 rc = mpc5200_psc_console_init(devp, &serial_cd); 136 rc = mpc5200_psc_console_init(devp, &serial_cd);
135#endif 137#endif
138#ifdef CONFIG_XILINX_VIRTEX
136 else if (dt_is_compatible(devp, "xlnx,opb-uartlite-1.00.b") || 139 else if (dt_is_compatible(devp, "xlnx,opb-uartlite-1.00.b") ||
137 dt_is_compatible(devp, "xlnx,xps-uartlite-1.00.a")) 140 dt_is_compatible(devp, "xlnx,xps-uartlite-1.00.a"))
138 rc = uartlite_console_init(devp, &serial_cd); 141 rc = uartlite_console_init(devp, &serial_cd);
142#endif
143#ifdef CONFIG_PPC64_BOOT_WRAPPER
139 else if (dt_is_compatible(devp, "ibm,opal-console-raw")) 144 else if (dt_is_compatible(devp, "ibm,opal-console-raw"))
140 rc = opal_console_init(devp, &serial_cd); 145 rc = opal_console_init(devp, &serial_cd);
146#endif
141 147
142 /* Add other serial console driver calls here */ 148 /* Add other serial console driver calls here */
143 149
diff --git a/arch/powerpc/configs/mpc866_ads_defconfig b/arch/powerpc/configs/mpc866_ads_defconfig
index f1f176c29fa3..5320735395e7 100644
--- a/arch/powerpc/configs/mpc866_ads_defconfig
+++ b/arch/powerpc/configs/mpc866_ads_defconfig
@@ -13,7 +13,6 @@ CONFIG_EXPERT=y
13CONFIG_PARTITION_ADVANCED=y 13CONFIG_PARTITION_ADVANCED=y
14CONFIG_MPC86XADS=y 14CONFIG_MPC86XADS=y
15CONFIG_8xx_COPYBACK=y 15CONFIG_8xx_COPYBACK=y
16CONFIG_8xx_CPU6=y
17CONFIG_GEN_RTC=y 16CONFIG_GEN_RTC=y
18CONFIG_HZ_1000=y 17CONFIG_HZ_1000=y
19CONFIG_MATH_EMULATION=y 18CONFIG_MATH_EMULATION=y
diff --git a/arch/powerpc/configs/powernv_defconfig b/arch/powerpc/configs/powernv_defconfig
index 73dab7a37386..9e92aa6a52ba 100644
--- a/arch/powerpc/configs/powernv_defconfig
+++ b/arch/powerpc/configs/powernv_defconfig
@@ -96,6 +96,7 @@ CONFIG_BLK_DEV_NBD=m
96CONFIG_BLK_DEV_RAM=y 96CONFIG_BLK_DEV_RAM=y
97CONFIG_BLK_DEV_RAM_SIZE=65536 97CONFIG_BLK_DEV_RAM_SIZE=65536
98CONFIG_VIRTIO_BLK=m 98CONFIG_VIRTIO_BLK=m
99CONFIG_BLK_DEV_NVME=y
99CONFIG_IDE=y 100CONFIG_IDE=y
100CONFIG_BLK_DEV_IDECD=y 101CONFIG_BLK_DEV_IDECD=y
101CONFIG_BLK_DEV_GENERIC=y 102CONFIG_BLK_DEV_GENERIC=y
@@ -112,6 +113,7 @@ CONFIG_SCSI_CXGB3_ISCSI=m
112CONFIG_SCSI_CXGB4_ISCSI=m 113CONFIG_SCSI_CXGB4_ISCSI=m
113CONFIG_SCSI_BNX2_ISCSI=m 114CONFIG_SCSI_BNX2_ISCSI=m
114CONFIG_BE2ISCSI=m 115CONFIG_BE2ISCSI=m
116CONFIG_SCSI_AACRAID=y
115CONFIG_SCSI_MPT2SAS=m 117CONFIG_SCSI_MPT2SAS=m
116CONFIG_SCSI_SYM53C8XX_2=m 118CONFIG_SCSI_SYM53C8XX_2=m
117CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 119CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 016579ef16d3..30a155c0a6b0 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -311,6 +311,29 @@ static inline int pte_present(pte_t pte)
311 return pte_val(pte) & _PAGE_PRESENT; 311 return pte_val(pte) & _PAGE_PRESENT;
312} 312}
313 313
314/*
315 * We only find page table entry in the last level
316 * Hence no need for other accessors
317 */
318#define pte_access_permitted pte_access_permitted
319static inline bool pte_access_permitted(pte_t pte, bool write)
320{
321 unsigned long pteval = pte_val(pte);
322 /*
323 * A read-only access is controlled by _PAGE_USER bit.
324 * We have _PAGE_READ set for WRITE and EXECUTE
325 */
326 unsigned long need_pte_bits = _PAGE_PRESENT | _PAGE_USER;
327
328 if (write)
329 need_pte_bits |= _PAGE_WRITE;
330
331 if ((pteval & need_pte_bits) != need_pte_bits)
332 return false;
333
334 return true;
335}
336
314/* Conversion functions: convert a page and protection to a page entry, 337/* Conversion functions: convert a page and protection to a page entry,
315 * and a page entry and page directory to the page they refer to. 338 * and a page entry and page directory to the page they refer to.
316 * 339 *
diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h
index 2d9df40446f6..949d691094a4 100644
--- a/arch/powerpc/include/asm/book3s/64/hash-4k.h
+++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h
@@ -17,6 +17,12 @@
17#define H_PUD_TABLE_SIZE (sizeof(pud_t) << H_PUD_INDEX_SIZE) 17#define H_PUD_TABLE_SIZE (sizeof(pud_t) << H_PUD_INDEX_SIZE)
18#define H_PGD_TABLE_SIZE (sizeof(pgd_t) << H_PGD_INDEX_SIZE) 18#define H_PGD_TABLE_SIZE (sizeof(pgd_t) << H_PGD_INDEX_SIZE)
19 19
20#define H_PAGE_F_GIX_SHIFT 53
21#define H_PAGE_F_SECOND _RPAGE_RPN44 /* HPTE is in 2ndary HPTEG */
22#define H_PAGE_F_GIX (_RPAGE_RPN43 | _RPAGE_RPN42 | _RPAGE_RPN41)
23#define H_PAGE_BUSY _RPAGE_RSV1 /* software: PTE & hash are busy */
24#define H_PAGE_HASHPTE _RPAGE_RSV2 /* software: PTE & hash are busy */
25
20/* PTE flags to conserve for HPTE identification */ 26/* PTE flags to conserve for HPTE identification */
21#define _PAGE_HPTEFLAGS (H_PAGE_BUSY | H_PAGE_HASHPTE | \ 27#define _PAGE_HPTEFLAGS (H_PAGE_BUSY | H_PAGE_HASHPTE | \
22 H_PAGE_F_SECOND | H_PAGE_F_GIX) 28 H_PAGE_F_SECOND | H_PAGE_F_GIX)
@@ -49,6 +55,20 @@ static inline int hash__hugepd_ok(hugepd_t hpd)
49} 55}
50#endif 56#endif
51 57
58/*
59 * 4K PTE format is different from 64K PTE format. Saving the hash_slot is just
60 * a matter of returning the PTE bits that need to be modified. On 64K PTE,
61 * things are a little more involved and hence needs many more parameters to
62 * accomplish the same. However we want to abstract this out from the caller by
63 * keeping the prototype consistent across the two formats.
64 */
65static inline unsigned long pte_set_hidx(pte_t *ptep, real_pte_t rpte,
66 unsigned int subpg_index, unsigned long hidx)
67{
68 return (hidx << H_PAGE_F_GIX_SHIFT) &
69 (H_PAGE_F_SECOND | H_PAGE_F_GIX);
70}
71
52#ifdef CONFIG_TRANSPARENT_HUGEPAGE 72#ifdef CONFIG_TRANSPARENT_HUGEPAGE
53 73
54static inline char *get_hpte_slot_array(pmd_t *pmdp) 74static inline char *get_hpte_slot_array(pmd_t *pmdp)
diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h
index cb46d1034f33..338b7da468ce 100644
--- a/arch/powerpc/include/asm/book3s/64/hash-64k.h
+++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h
@@ -13,21 +13,17 @@
13 */ 13 */
14#define H_PAGE_COMBO _RPAGE_RPN0 /* this is a combo 4k page */ 14#define H_PAGE_COMBO _RPAGE_RPN0 /* this is a combo 4k page */
15#define H_PAGE_4K_PFN _RPAGE_RPN1 /* PFN is for a single 4k page */ 15#define H_PAGE_4K_PFN _RPAGE_RPN1 /* PFN is for a single 4k page */
16#define H_PAGE_BUSY _RPAGE_RPN44 /* software: PTE & hash are busy */
17#define H_PAGE_HASHPTE _RPAGE_RPN43 /* PTE has associated HPTE */
18
16/* 19/*
17 * We need to differentiate between explicit huge page and THP huge 20 * We need to differentiate between explicit huge page and THP huge
18 * page, since THP huge page also need to track real subpage details 21 * page, since THP huge page also need to track real subpage details
19 */ 22 */
20#define H_PAGE_THP_HUGE H_PAGE_4K_PFN 23#define H_PAGE_THP_HUGE H_PAGE_4K_PFN
21 24
22/*
23 * Used to track subpage group valid if H_PAGE_COMBO is set
24 * This overloads H_PAGE_F_GIX and H_PAGE_F_SECOND
25 */
26#define H_PAGE_COMBO_VALID (H_PAGE_F_GIX | H_PAGE_F_SECOND)
27
28/* PTE flags to conserve for HPTE identification */ 25/* PTE flags to conserve for HPTE identification */
29#define _PAGE_HPTEFLAGS (H_PAGE_BUSY | H_PAGE_F_SECOND | \ 26#define _PAGE_HPTEFLAGS (H_PAGE_BUSY | H_PAGE_HASHPTE | H_PAGE_COMBO)
30 H_PAGE_F_GIX | H_PAGE_HASHPTE | H_PAGE_COMBO)
31/* 27/*
32 * we support 16 fragments per PTE page of 64K size. 28 * we support 16 fragments per PTE page of 64K size.
33 */ 29 */
@@ -55,24 +51,57 @@ static inline real_pte_t __real_pte(pte_t pte, pte_t *ptep)
55 unsigned long *hidxp; 51 unsigned long *hidxp;
56 52
57 rpte.pte = pte; 53 rpte.pte = pte;
58 rpte.hidx = 0; 54
59 if (pte_val(pte) & H_PAGE_COMBO) { 55 /*
60 /* 56 * Ensure that we do not read the hidx before we read the PTE. Because
61 * Make sure we order the hidx load against the H_PAGE_COMBO 57 * the writer side is expected to finish writing the hidx first followed
62 * check. The store side ordering is done in __hash_page_4K 58 * by the PTE, by using smp_wmb(). pte_set_hash_slot() ensures that.
63 */ 59 */
64 smp_rmb(); 60 smp_rmb();
65 hidxp = (unsigned long *)(ptep + PTRS_PER_PTE); 61
66 rpte.hidx = *hidxp; 62 hidxp = (unsigned long *)(ptep + PTRS_PER_PTE);
67 } 63 rpte.hidx = *hidxp;
68 return rpte; 64 return rpte;
69} 65}
70 66
67/*
68 * shift the hidx representation by one-modulo-0xf; i.e hidx 0 is respresented
69 * as 1, 1 as 2,... , and 0xf as 0. This convention lets us represent a
70 * invalid hidx 0xf with a 0x0 bit value. PTEs are anyway zero'd when
71 * allocated. We dont have to zero them gain; thus save on the initialization.
72 */
73#define HIDX_UNSHIFT_BY_ONE(x) ((x + 0xfUL) & 0xfUL) /* shift backward by one */
74#define HIDX_SHIFT_BY_ONE(x) ((x + 0x1UL) & 0xfUL) /* shift forward by one */
75#define HIDX_BITS(x, index) (x << (index << 2))
76#define BITS_TO_HIDX(x, index) ((x >> (index << 2)) & 0xfUL)
77#define INVALID_RPTE_HIDX 0x0UL
78
71static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index) 79static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index)
72{ 80{
73 if ((pte_val(rpte.pte) & H_PAGE_COMBO)) 81 return HIDX_UNSHIFT_BY_ONE(BITS_TO_HIDX(rpte.hidx, index));
74 return (rpte.hidx >> (index<<2)) & 0xf; 82}
75 return (pte_val(rpte.pte) >> H_PAGE_F_GIX_SHIFT) & 0xf; 83
84/*
85 * Commit the hidx and return PTE bits that needs to be modified. The caller is
86 * expected to modify the PTE bits accordingly and commit the PTE to memory.
87 */
88static inline unsigned long pte_set_hidx(pte_t *ptep, real_pte_t rpte,
89 unsigned int subpg_index, unsigned long hidx)
90{
91 unsigned long *hidxp = (unsigned long *)(ptep + PTRS_PER_PTE);
92
93 rpte.hidx &= ~HIDX_BITS(0xfUL, subpg_index);
94 *hidxp = rpte.hidx | HIDX_BITS(HIDX_SHIFT_BY_ONE(hidx), subpg_index);
95
96 /*
97 * Anyone reading PTE must ensure hidx bits are read after reading the
98 * PTE by using the read-side barrier smp_rmb(). __real_pte() can be
99 * used for that.
100 */
101 smp_wmb();
102
103 /* No PTE bits to be modified, return 0x0UL */
104 return 0x0UL;
76} 105}
77 106
78#define __rpte_to_pte(r) ((r).pte) 107#define __rpte_to_pte(r) ((r).pte)
diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h
index ecb1239d74f4..0920eff731b3 100644
--- a/arch/powerpc/include/asm/book3s/64/hash.h
+++ b/arch/powerpc/include/asm/book3s/64/hash.h
@@ -9,11 +9,6 @@
9 * 9 *
10 */ 10 */
11#define H_PTE_NONE_MASK _PAGE_HPTEFLAGS 11#define H_PTE_NONE_MASK _PAGE_HPTEFLAGS
12#define H_PAGE_F_GIX_SHIFT 56
13#define H_PAGE_BUSY _RPAGE_RSV1 /* software: PTE & hash are busy */
14#define H_PAGE_F_SECOND _RPAGE_RSV2 /* HPTE is in 2ndary HPTEG */
15#define H_PAGE_F_GIX (_RPAGE_RSV3 | _RPAGE_RSV4 | _RPAGE_RPN44)
16#define H_PAGE_HASHPTE _RPAGE_RPN43 /* PTE has associated HPTE */
17 12
18#ifdef CONFIG_PPC_64K_PAGES 13#ifdef CONFIG_PPC_64K_PAGES
19#include <asm/book3s/64/hash-64k.h> 14#include <asm/book3s/64/hash-64k.h>
@@ -167,6 +162,9 @@ static inline int hash__pte_none(pte_t pte)
167 return (pte_val(pte) & ~H_PTE_NONE_MASK) == 0; 162 return (pte_val(pte) & ~H_PTE_NONE_MASK) == 0;
168} 163}
169 164
165unsigned long pte_get_hash_gslot(unsigned long vpn, unsigned long shift,
166 int ssize, real_pte_t rpte, unsigned int subpg_index);
167
170/* This low level function performs the actual PTE insertion 168/* This low level function performs the actual PTE insertion
171 * Setting the PTE depends on the MMU type and other factors. It's 169 * Setting the PTE depends on the MMU type and other factors. It's
172 * an horrible mess that I'm not going to try to clean up now but 170 * an horrible mess that I'm not going to try to clean up now but
diff --git a/arch/powerpc/include/asm/book3s/64/mmu-hash.h b/arch/powerpc/include/asm/book3s/64/mmu-hash.h
index e91e115a816f..50ed64fba4ae 100644
--- a/arch/powerpc/include/asm/book3s/64/mmu-hash.h
+++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h
@@ -90,6 +90,8 @@
90#define HPTE_R_PP0 ASM_CONST(0x8000000000000000) 90#define HPTE_R_PP0 ASM_CONST(0x8000000000000000)
91#define HPTE_R_TS ASM_CONST(0x4000000000000000) 91#define HPTE_R_TS ASM_CONST(0x4000000000000000)
92#define HPTE_R_KEY_HI ASM_CONST(0x3000000000000000) 92#define HPTE_R_KEY_HI ASM_CONST(0x3000000000000000)
93#define HPTE_R_KEY_BIT0 ASM_CONST(0x2000000000000000)
94#define HPTE_R_KEY_BIT1 ASM_CONST(0x1000000000000000)
93#define HPTE_R_RPN_SHIFT 12 95#define HPTE_R_RPN_SHIFT 12
94#define HPTE_R_RPN ASM_CONST(0x0ffffffffffff000) 96#define HPTE_R_RPN ASM_CONST(0x0ffffffffffff000)
95#define HPTE_R_RPN_3_0 ASM_CONST(0x01fffffffffff000) 97#define HPTE_R_RPN_3_0 ASM_CONST(0x01fffffffffff000)
@@ -104,6 +106,9 @@
104#define HPTE_R_C ASM_CONST(0x0000000000000080) 106#define HPTE_R_C ASM_CONST(0x0000000000000080)
105#define HPTE_R_R ASM_CONST(0x0000000000000100) 107#define HPTE_R_R ASM_CONST(0x0000000000000100)
106#define HPTE_R_KEY_LO ASM_CONST(0x0000000000000e00) 108#define HPTE_R_KEY_LO ASM_CONST(0x0000000000000e00)
109#define HPTE_R_KEY_BIT2 ASM_CONST(0x0000000000000800)
110#define HPTE_R_KEY_BIT3 ASM_CONST(0x0000000000000400)
111#define HPTE_R_KEY_BIT4 ASM_CONST(0x0000000000000200)
107#define HPTE_R_KEY (HPTE_R_KEY_LO | HPTE_R_KEY_HI) 112#define HPTE_R_KEY (HPTE_R_KEY_LO | HPTE_R_KEY_HI)
108 113
109#define HPTE_V_1TB_SEG ASM_CONST(0x4000000000000000) 114#define HPTE_V_1TB_SEG ASM_CONST(0x4000000000000000)
diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h
index c9448e19847a..0abeb0e2d616 100644
--- a/arch/powerpc/include/asm/book3s/64/mmu.h
+++ b/arch/powerpc/include/asm/book3s/64/mmu.h
@@ -108,6 +108,16 @@ typedef struct {
108#ifdef CONFIG_SPAPR_TCE_IOMMU 108#ifdef CONFIG_SPAPR_TCE_IOMMU
109 struct list_head iommu_group_mem_list; 109 struct list_head iommu_group_mem_list;
110#endif 110#endif
111
112#ifdef CONFIG_PPC_MEM_KEYS
113 /*
114 * Each bit represents one protection key.
115 * bit set -> key allocated
116 * bit unset -> key available for allocation
117 */
118 u32 pkey_allocation_map;
119 s16 execute_only_pkey; /* key holding execute-only protection */
120#endif
111} mm_context_t; 121} mm_context_t;
112 122
113/* 123/*
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index 6ca1208cedcb..51017726d495 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -14,8 +14,9 @@
14 */ 14 */
15#define _PAGE_BIT_SWAP_TYPE 0 15#define _PAGE_BIT_SWAP_TYPE 0
16 16
17#define _PAGE_NA 0
17#define _PAGE_RO 0 18#define _PAGE_RO 0
18#define _PAGE_SHARED 0 19#define _PAGE_USER 0
19 20
20#define _PAGE_EXEC 0x00001 /* execute permission */ 21#define _PAGE_EXEC 0x00001 /* execute permission */
21#define _PAGE_WRITE 0x00002 /* write access allowed */ 22#define _PAGE_WRITE 0x00002 /* write access allowed */
@@ -39,6 +40,7 @@
39#define _RPAGE_RSV2 0x0800000000000000UL 40#define _RPAGE_RSV2 0x0800000000000000UL
40#define _RPAGE_RSV3 0x0400000000000000UL 41#define _RPAGE_RSV3 0x0400000000000000UL
41#define _RPAGE_RSV4 0x0200000000000000UL 42#define _RPAGE_RSV4 0x0200000000000000UL
43#define _RPAGE_RSV5 0x00040UL
42 44
43#define _PAGE_PTE 0x4000000000000000UL /* distinguishes PTEs from pointers */ 45#define _PAGE_PTE 0x4000000000000000UL /* distinguishes PTEs from pointers */
44#define _PAGE_PRESENT 0x8000000000000000UL /* pte contains a translation */ 46#define _PAGE_PRESENT 0x8000000000000000UL /* pte contains a translation */
@@ -58,6 +60,25 @@
58/* Max physical address bit as per radix table */ 60/* Max physical address bit as per radix table */
59#define _RPAGE_PA_MAX 57 61#define _RPAGE_PA_MAX 57
60 62
63#ifdef CONFIG_PPC_MEM_KEYS
64#ifdef CONFIG_PPC_64K_PAGES
65#define H_PTE_PKEY_BIT0 _RPAGE_RSV1
66#define H_PTE_PKEY_BIT1 _RPAGE_RSV2
67#else /* CONFIG_PPC_64K_PAGES */
68#define H_PTE_PKEY_BIT0 0 /* _RPAGE_RSV1 is not available */
69#define H_PTE_PKEY_BIT1 0 /* _RPAGE_RSV2 is not available */
70#endif /* CONFIG_PPC_64K_PAGES */
71#define H_PTE_PKEY_BIT2 _RPAGE_RSV3
72#define H_PTE_PKEY_BIT3 _RPAGE_RSV4
73#define H_PTE_PKEY_BIT4 _RPAGE_RSV5
74#else /* CONFIG_PPC_MEM_KEYS */
75#define H_PTE_PKEY_BIT0 0
76#define H_PTE_PKEY_BIT1 0
77#define H_PTE_PKEY_BIT2 0
78#define H_PTE_PKEY_BIT3 0
79#define H_PTE_PKEY_BIT4 0
80#endif /* CONFIG_PPC_MEM_KEYS */
81
61/* 82/*
62 * Max physical address bit we will use for now. 83 * Max physical address bit we will use for now.
63 * 84 *
@@ -121,13 +142,16 @@
121#define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \ 142#define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \
122 _PAGE_ACCESSED | _PAGE_SPECIAL | _PAGE_PTE | \ 143 _PAGE_ACCESSED | _PAGE_SPECIAL | _PAGE_PTE | \
123 _PAGE_SOFT_DIRTY) 144 _PAGE_SOFT_DIRTY)
145
146#define H_PTE_PKEY (H_PTE_PKEY_BIT0 | H_PTE_PKEY_BIT1 | H_PTE_PKEY_BIT2 | \
147 H_PTE_PKEY_BIT3 | H_PTE_PKEY_BIT4)
124/* 148/*
125 * Mask of bits returned by pte_pgprot() 149 * Mask of bits returned by pte_pgprot()
126 */ 150 */
127#define PAGE_PROT_BITS (_PAGE_SAO | _PAGE_NON_IDEMPOTENT | _PAGE_TOLERANT | \ 151#define PAGE_PROT_BITS (_PAGE_SAO | _PAGE_NON_IDEMPOTENT | _PAGE_TOLERANT | \
128 H_PAGE_4K_PFN | _PAGE_PRIVILEGED | _PAGE_ACCESSED | \ 152 H_PAGE_4K_PFN | _PAGE_PRIVILEGED | _PAGE_ACCESSED | \
129 _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_EXEC | \ 153 _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_EXEC | \
130 _PAGE_SOFT_DIRTY) 154 _PAGE_SOFT_DIRTY | H_PTE_PKEY)
131/* 155/*
132 * We define 2 sets of base prot bits, one for basic pages (ie, 156 * We define 2 sets of base prot bits, one for basic pages (ie,
133 * cacheable kernel and user pages) and one for non cacheable 157 * cacheable kernel and user pages) and one for non cacheable
@@ -546,6 +570,40 @@ static inline int pte_present(pte_t pte)
546{ 570{
547 return !!(pte_raw(pte) & cpu_to_be64(_PAGE_PRESENT)); 571 return !!(pte_raw(pte) & cpu_to_be64(_PAGE_PRESENT));
548} 572}
573
574#ifdef CONFIG_PPC_MEM_KEYS
575extern bool arch_pte_access_permitted(u64 pte, bool write, bool execute);
576#else
577static inline bool arch_pte_access_permitted(u64 pte, bool write, bool execute)
578{
579 return true;
580}
581#endif /* CONFIG_PPC_MEM_KEYS */
582
583#define pte_access_permitted pte_access_permitted
584static inline bool pte_access_permitted(pte_t pte, bool write)
585{
586 unsigned long pteval = pte_val(pte);
587 /* Also check for pte_user */
588 unsigned long clear_pte_bits = _PAGE_PRIVILEGED;
589 /*
590 * _PAGE_READ is needed for any access and will be
591 * cleared for PROT_NONE
592 */
593 unsigned long need_pte_bits = _PAGE_PRESENT | _PAGE_READ;
594
595 if (write)
596 need_pte_bits |= _PAGE_WRITE;
597
598 if ((pteval & need_pte_bits) != need_pte_bits)
599 return false;
600
601 if ((pteval & clear_pte_bits) == clear_pte_bits)
602 return false;
603
604 return arch_pte_access_permitted(pte_val(pte), write, 0);
605}
606
549/* 607/*
550 * Conversion functions: convert a page and protection to a page entry, 608 * Conversion functions: convert a page and protection to a page entry,
551 * and a page entry and page directory to the page they refer to. 609 * and a page entry and page directory to the page they refer to.
@@ -850,6 +908,11 @@ static inline int pud_bad(pud_t pud)
850 return hash__pud_bad(pud); 908 return hash__pud_bad(pud);
851} 909}
852 910
911#define pud_access_permitted pud_access_permitted
912static inline bool pud_access_permitted(pud_t pud, bool write)
913{
914 return pte_access_permitted(pud_pte(pud), write);
915}
853 916
854#define pgd_write(pgd) pte_write(pgd_pte(pgd)) 917#define pgd_write(pgd) pte_write(pgd_pte(pgd))
855static inline void pgd_set(pgd_t *pgdp, unsigned long val) 918static inline void pgd_set(pgd_t *pgdp, unsigned long val)
@@ -889,6 +952,12 @@ static inline int pgd_bad(pgd_t pgd)
889 return hash__pgd_bad(pgd); 952 return hash__pgd_bad(pgd);
890} 953}
891 954
955#define pgd_access_permitted pgd_access_permitted
956static inline bool pgd_access_permitted(pgd_t pgd, bool write)
957{
958 return pte_access_permitted(pgd_pte(pgd), write);
959}
960
892extern struct page *pgd_page(pgd_t pgd); 961extern struct page *pgd_page(pgd_t pgd);
893 962
894/* Pointers in the page table tree are physical addresses */ 963/* Pointers in the page table tree are physical addresses */
@@ -1009,6 +1078,12 @@ static inline int pmd_protnone(pmd_t pmd)
1009#define __pmd_write(pmd) __pte_write(pmd_pte(pmd)) 1078#define __pmd_write(pmd) __pte_write(pmd_pte(pmd))
1010#define pmd_savedwrite(pmd) pte_savedwrite(pmd_pte(pmd)) 1079#define pmd_savedwrite(pmd) pte_savedwrite(pmd_pte(pmd))
1011 1080
1081#define pmd_access_permitted pmd_access_permitted
1082static inline bool pmd_access_permitted(pmd_t pmd, bool write)
1083{
1084 return pte_access_permitted(pmd_pte(pmd), write);
1085}
1086
1012#ifdef CONFIG_TRANSPARENT_HUGEPAGE 1087#ifdef CONFIG_TRANSPARENT_HUGEPAGE
1013extern pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot); 1088extern pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot);
1014extern pmd_t mk_pmd(struct page *page, pgprot_t pgprot); 1089extern pmd_t mk_pmd(struct page *page, pgprot_t pgprot);
diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h
index 849ecaae9e79..64d02a704bcb 100644
--- a/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h
+++ b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h
@@ -51,6 +51,7 @@ static inline void arch_leave_lazy_mmu_mode(void)
51 51
52#define arch_flush_lazy_mmu_mode() do {} while (0) 52#define arch_flush_lazy_mmu_mode() do {} while (0)
53 53
54extern void hash__tlbiel_all(unsigned int action);
54 55
55extern void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize, 56extern void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize,
56 int ssize, unsigned long flags); 57 int ssize, unsigned long flags);
diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h b/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h
index 6a9e68003387..8eea90f80e45 100644
--- a/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h
+++ b/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h
@@ -11,6 +11,12 @@ static inline int mmu_get_ap(int psize)
11 return mmu_psize_defs[psize].ap; 11 return mmu_psize_defs[psize].ap;
12} 12}
13 13
14#ifdef CONFIG_PPC_RADIX_MMU
15extern void radix__tlbiel_all(unsigned int action);
16#else
17static inline void radix__tlbiel_all(unsigned int action) { WARN_ON(1); };
18#endif
19
14extern void radix__flush_hugetlb_tlb_range(struct vm_area_struct *vma, 20extern void radix__flush_hugetlb_tlb_range(struct vm_area_struct *vma,
15 unsigned long start, unsigned long end); 21 unsigned long start, unsigned long end);
16extern void radix__flush_tlb_range_psize(struct mm_struct *mm, unsigned long start, 22extern void radix__flush_tlb_range_psize(struct mm_struct *mm, unsigned long start,
@@ -47,4 +53,5 @@ extern void radix__flush_tlb_lpid(unsigned long lpid);
47extern void radix__flush_tlb_all(void); 53extern void radix__flush_tlb_all(void);
48extern void radix__flush_tlb_pte_p9_dd1(unsigned long old_pte, struct mm_struct *mm, 54extern void radix__flush_tlb_pte_p9_dd1(unsigned long old_pte, struct mm_struct *mm,
49 unsigned long address); 55 unsigned long address);
56
50#endif 57#endif
diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush.h b/arch/powerpc/include/asm/book3s/64/tlbflush.h
index 58b576f654b3..0cac17253513 100644
--- a/arch/powerpc/include/asm/book3s/64/tlbflush.h
+++ b/arch/powerpc/include/asm/book3s/64/tlbflush.h
@@ -8,6 +8,44 @@
8#include <asm/book3s/64/tlbflush-hash.h> 8#include <asm/book3s/64/tlbflush-hash.h>
9#include <asm/book3s/64/tlbflush-radix.h> 9#include <asm/book3s/64/tlbflush-radix.h>
10 10
11/* TLB flush actions. Used as argument to tlbiel_all() */
12enum {
13 TLB_INVAL_SCOPE_GLOBAL = 0, /* invalidate all TLBs */
14 TLB_INVAL_SCOPE_LPID = 1, /* invalidate TLBs for current LPID */
15};
16
17#ifdef CONFIG_PPC_NATIVE
18static inline void tlbiel_all(void)
19{
20 /*
21 * This is used for host machine check and bootup.
22 *
23 * This uses early_radix_enabled and implementations use
24 * early_cpu_has_feature etc because that works early in boot
25 * and this is the machine check path which is not performance
26 * critical.
27 */
28 if (early_radix_enabled())
29 radix__tlbiel_all(TLB_INVAL_SCOPE_GLOBAL);
30 else
31 hash__tlbiel_all(TLB_INVAL_SCOPE_GLOBAL);
32}
33#else
34static inline void tlbiel_all(void) { BUG(); };
35#endif
36
37static inline void tlbiel_all_lpid(bool radix)
38{
39 /*
40 * This is used for guest machine check.
41 */
42 if (radix)
43 radix__tlbiel_all(TLB_INVAL_SCOPE_LPID);
44 else
45 hash__tlbiel_all(TLB_INVAL_SCOPE_LPID);
46}
47
48
11#define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE 49#define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE
12static inline void flush_pmd_tlb_range(struct vm_area_struct *vma, 50static inline void flush_pmd_tlb_range(struct vm_area_struct *vma,
13 unsigned long start, unsigned long end) 51 unsigned long start, unsigned long end)
diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
index 3c04249bcf39..fd06dbe7d7d3 100644
--- a/arch/powerpc/include/asm/bug.h
+++ b/arch/powerpc/include/asm/bug.h
@@ -133,9 +133,11 @@ struct pt_regs;
133extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long); 133extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long);
134extern void bad_page_fault(struct pt_regs *, unsigned long, int); 134extern void bad_page_fault(struct pt_regs *, unsigned long, int);
135extern void _exception(int, struct pt_regs *, int, unsigned long); 135extern void _exception(int, struct pt_regs *, int, unsigned long);
136extern void _exception_pkey(int, struct pt_regs *, int, unsigned long, int);
136extern void die(const char *, struct pt_regs *, long); 137extern void die(const char *, struct pt_regs *, long);
137extern bool die_will_crash(void); 138extern bool die_will_crash(void);
138 139extern void panic_flush_kmsg_start(void);
140extern void panic_flush_kmsg_end(void);
139#endif /* !__ASSEMBLY__ */ 141#endif /* !__ASSEMBLY__ */
140 142
141#endif /* __KERNEL__ */ 143#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
index abef812de7f8..812535f40124 100644
--- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -31,8 +31,10 @@ unsigned int create_cond_branch(const unsigned int *addr,
31 unsigned long target, int flags); 31 unsigned long target, int flags);
32int patch_branch(unsigned int *addr, unsigned long target, int flags); 32int patch_branch(unsigned int *addr, unsigned long target, int flags);
33int patch_instruction(unsigned int *addr, unsigned int instr); 33int patch_instruction(unsigned int *addr, unsigned int instr);
34int raw_patch_instruction(unsigned int *addr, unsigned int instr);
34 35
35int instr_is_relative_branch(unsigned int instr); 36int instr_is_relative_branch(unsigned int instr);
37int instr_is_relative_link_branch(unsigned int instr);
36int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr); 38int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr);
37unsigned long branch_target(const unsigned int *instr); 39unsigned long branch_target(const unsigned int *instr);
38unsigned int translate_branch(const unsigned int *dest, 40unsigned int translate_branch(const unsigned int *dest,
diff --git a/arch/powerpc/include/asm/cpm.h b/arch/powerpc/include/asm/cpm.h
index b925df1b87d0..4c24ea8209bb 100644
--- a/arch/powerpc/include/asm/cpm.h
+++ b/arch/powerpc/include/asm/cpm.h
@@ -166,6 +166,6 @@ static inline int cpm_command(u32 command, u8 opcode)
166} 166}
167#endif /* CONFIG_CPM */ 167#endif /* CONFIG_CPM */
168 168
169int cpm2_gpiochip_add32(struct device_node *np); 169int cpm2_gpiochip_add32(struct device *dev);
170 170
171#endif 171#endif
diff --git a/arch/powerpc/include/asm/cpm1.h b/arch/powerpc/include/asm/cpm1.h
index 3db821876d48..a116fe931789 100644
--- a/arch/powerpc/include/asm/cpm1.h
+++ b/arch/powerpc/include/asm/cpm1.h
@@ -605,5 +605,7 @@ enum cpm_clk {
605}; 605};
606 606
607int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode); 607int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode);
608int cpm1_gpiochip_add16(struct device *dev);
609int cpm1_gpiochip_add32(struct device *dev);
608 610
609#endif /* __CPM1__ */ 611#endif /* __CPM1__ */
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 0546663a98db..a2c5c95882cf 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -107,12 +107,6 @@ struct cpu_spec {
107 * called in real mode to handle SLB and TLB errors. 107 * called in real mode to handle SLB and TLB errors.
108 */ 108 */
109 long (*machine_check_early)(struct pt_regs *regs); 109 long (*machine_check_early)(struct pt_regs *regs);
110
111 /*
112 * Processor specific routine to flush tlbs.
113 */
114 void (*flush_tlb)(unsigned int action);
115
116}; 110};
117 111
118extern struct cpu_spec *cur_cpu_spec; 112extern struct cpu_spec *cur_cpu_spec;
@@ -133,12 +127,6 @@ extern void cpu_feature_keys_init(void);
133static inline void cpu_feature_keys_init(void) { } 127static inline void cpu_feature_keys_init(void) { }
134#endif 128#endif
135 129
136/* TLB flush actions. Used as argument to cpu_spec.flush_tlb() hook */
137enum {
138 TLB_INVAL_SCOPE_GLOBAL = 0, /* invalidate all TLBs */
139 TLB_INVAL_SCOPE_LPID = 1, /* invalidate TLBs for current LPID */
140};
141
142#endif /* __ASSEMBLY__ */ 130#endif /* __ASSEMBLY__ */
143 131
144/* CPU kernel features */ 132/* CPU kernel features */
@@ -207,7 +195,7 @@ enum {
207#define CPU_FTR_STCX_CHECKS_ADDRESS LONG_ASM_CONST(0x0004000000000000) 195#define CPU_FTR_STCX_CHECKS_ADDRESS LONG_ASM_CONST(0x0004000000000000)
208#define CPU_FTR_POPCNTB LONG_ASM_CONST(0x0008000000000000) 196#define CPU_FTR_POPCNTB LONG_ASM_CONST(0x0008000000000000)
209#define CPU_FTR_POPCNTD LONG_ASM_CONST(0x0010000000000000) 197#define CPU_FTR_POPCNTD LONG_ASM_CONST(0x0010000000000000)
210/* Free LONG_ASM_CONST(0x0020000000000000) */ 198#define CPU_FTR_PKEY LONG_ASM_CONST(0x0020000000000000)
211#define CPU_FTR_VMX_COPY LONG_ASM_CONST(0x0040000000000000) 199#define CPU_FTR_VMX_COPY LONG_ASM_CONST(0x0040000000000000)
212#define CPU_FTR_TM LONG_ASM_CONST(0x0080000000000000) 200#define CPU_FTR_TM LONG_ASM_CONST(0x0080000000000000)
213#define CPU_FTR_CFAR LONG_ASM_CONST(0x0100000000000000) 201#define CPU_FTR_CFAR LONG_ASM_CONST(0x0100000000000000)
@@ -454,7 +442,7 @@ enum {
454 CPU_FTR_DSCR | CPU_FTR_SAO | CPU_FTR_ASYM_SMT | \ 442 CPU_FTR_DSCR | CPU_FTR_SAO | CPU_FTR_ASYM_SMT | \
455 CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ 443 CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
456 CPU_FTR_CFAR | CPU_FTR_HVMODE | \ 444 CPU_FTR_CFAR | CPU_FTR_HVMODE | \
457 CPU_FTR_VMX_COPY | CPU_FTR_HAS_PPR | CPU_FTR_DABRX) 445 CPU_FTR_VMX_COPY | CPU_FTR_HAS_PPR | CPU_FTR_DABRX | CPU_FTR_PKEY)
458#define CPU_FTRS_POWER8 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ 446#define CPU_FTRS_POWER8 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
459 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\ 447 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\
460 CPU_FTR_MMCRA | CPU_FTR_SMT | \ 448 CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -464,7 +452,7 @@ enum {
464 CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ 452 CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
465 CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ 453 CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
466 CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \ 454 CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \
467 CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP) 455 CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_PKEY)
468#define CPU_FTRS_POWER8E (CPU_FTRS_POWER8 | CPU_FTR_PMAO_BUG) 456#define CPU_FTRS_POWER8E (CPU_FTRS_POWER8 | CPU_FTR_PMAO_BUG)
469#define CPU_FTRS_POWER8_DD1 (CPU_FTRS_POWER8 & ~CPU_FTR_DBELL) 457#define CPU_FTRS_POWER8_DD1 (CPU_FTRS_POWER8 & ~CPU_FTR_DBELL)
470#define CPU_FTRS_POWER9 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ 458#define CPU_FTRS_POWER9 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
@@ -476,7 +464,8 @@ enum {
476 CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ 464 CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
477 CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ 465 CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
478 CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \ 466 CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \
479 CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_ARCH_300) 467 CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | \
468 CPU_FTR_PKEY)
480#define CPU_FTRS_POWER9_DD1 ((CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD1) & \ 469#define CPU_FTRS_POWER9_DD1 ((CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD1) & \
481 (~CPU_FTR_SAO)) 470 (~CPU_FTR_SAO))
482#define CPU_FTRS_POWER9_DD2_0 CPU_FTRS_POWER9 471#define CPU_FTRS_POWER9_DD2_0 CPU_FTRS_POWER9
diff --git a/arch/powerpc/include/asm/drmem.h b/arch/powerpc/include/asm/drmem.h
new file mode 100644
index 000000000000..ce242b9ea8c6
--- /dev/null
+++ b/arch/powerpc/include/asm/drmem.h
@@ -0,0 +1,102 @@
1/*
2 * drmem.h: Power specific logical memory block representation
3 *
4 * Copyright 2017 IBM Corporation
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#ifndef _ASM_POWERPC_LMB_H
13#define _ASM_POWERPC_LMB_H
14
15struct drmem_lmb {
16 u64 base_addr;
17 u32 drc_index;
18 u32 aa_index;
19 u32 flags;
20};
21
22struct drmem_lmb_info {
23 struct drmem_lmb *lmbs;
24 int n_lmbs;
25 u32 lmb_size;
26};
27
28extern struct drmem_lmb_info *drmem_info;
29
30#define for_each_drmem_lmb_in_range(lmb, start, end) \
31 for ((lmb) = (start); (lmb) <= (end); (lmb)++)
32
33#define for_each_drmem_lmb(lmb) \
34 for_each_drmem_lmb_in_range((lmb), \
35 &drmem_info->lmbs[0], \
36 &drmem_info->lmbs[drmem_info->n_lmbs - 1])
37
38/*
39 * The of_drconf_cell_v1 struct defines the layout of the LMB data
40 * specified in the ibm,dynamic-memory device tree property.
41 * The property itself is a 32-bit value specifying the number of
42 * LMBs followed by an array of of_drconf_cell_v1 entries, one
43 * per LMB.
44 */
45struct of_drconf_cell_v1 {
46 __be64 base_addr;
47 __be32 drc_index;
48 __be32 reserved;
49 __be32 aa_index;
50 __be32 flags;
51};
52
53/*
54 * Version 2 of the ibm,dynamic-memory property is defined as a
55 * 32-bit value specifying the number of LMB sets followed by an
56 * array of of_drconf_cell_v2 entries, one per LMB set.
57 */
58struct of_drconf_cell_v2 {
59 u32 seq_lmbs;
60 u64 base_addr;
61 u32 drc_index;
62 u32 aa_index;
63 u32 flags;
64} __packed;
65
66#define DRCONF_MEM_ASSIGNED 0x00000008
67#define DRCONF_MEM_AI_INVALID 0x00000040
68#define DRCONF_MEM_RESERVED 0x00000080
69
70static inline u32 drmem_lmb_size(void)
71{
72 return drmem_info->lmb_size;
73}
74
75#define DRMEM_LMB_RESERVED 0x80000000
76
77static inline void drmem_mark_lmb_reserved(struct drmem_lmb *lmb)
78{
79 lmb->flags |= DRMEM_LMB_RESERVED;
80}
81
82static inline void drmem_remove_lmb_reservation(struct drmem_lmb *lmb)
83{
84 lmb->flags &= ~DRMEM_LMB_RESERVED;
85}
86
87static inline bool drmem_lmb_reserved(struct drmem_lmb *lmb)
88{
89 return lmb->flags & DRMEM_LMB_RESERVED;
90}
91
92u64 drmem_lmb_memory_max(void);
93void __init walk_drmem_lmbs(struct device_node *dn,
94 void (*func)(struct drmem_lmb *, const __be32 **));
95int drmem_update_dt(void);
96
97#ifdef CONFIG_PPC_PSERIES
98void __init walk_drmem_lmbs_early(unsigned long node,
99 void (*func)(struct drmem_lmb *, const __be32 **));
100#endif
101
102#endif /* _ASM_POWERPC_LMB_H */
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index 5161c37dd039..fd37cc101f4f 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -214,6 +214,7 @@ struct eeh_ops {
214 int (*write_config)(struct pci_dn *pdn, int where, int size, u32 val); 214 int (*write_config)(struct pci_dn *pdn, int where, int size, u32 val);
215 int (*next_error)(struct eeh_pe **pe); 215 int (*next_error)(struct eeh_pe **pe);
216 int (*restore_config)(struct pci_dn *pdn); 216 int (*restore_config)(struct pci_dn *pdn);
217 int (*notify_resume)(struct pci_dn *pdn);
217}; 218};
218 219
219extern int eeh_subsystem_flags; 220extern int eeh_subsystem_flags;
@@ -297,6 +298,7 @@ int eeh_pe_reset(struct eeh_pe *pe, int option);
297int eeh_pe_configure(struct eeh_pe *pe); 298int eeh_pe_configure(struct eeh_pe *pe);
298int eeh_pe_inject_err(struct eeh_pe *pe, int type, int func, 299int eeh_pe_inject_err(struct eeh_pe *pe, int type, int func,
299 unsigned long addr, unsigned long mask); 300 unsigned long addr, unsigned long mask);
301int eeh_restore_vf_config(struct pci_dn *pdn);
300 302
301/** 303/**
302 * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure. 304 * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure.
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 7197b179c1b1..176dfb73d42c 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -251,18 +251,40 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
251 std r10,area+EX_R10(r13); /* save r10 - r12 */ \ 251 std r10,area+EX_R10(r13); /* save r10 - r12 */ \
252 OPT_GET_SPR(r10, SPRN_CFAR, CPU_FTR_CFAR) 252 OPT_GET_SPR(r10, SPRN_CFAR, CPU_FTR_CFAR)
253 253
254#define __EXCEPTION_PROLOG_1(area, extra, vec) \ 254#define __EXCEPTION_PROLOG_1_PRE(area) \
255 OPT_SAVE_REG_TO_PACA(area+EX_PPR, r9, CPU_FTR_HAS_PPR); \ 255 OPT_SAVE_REG_TO_PACA(area+EX_PPR, r9, CPU_FTR_HAS_PPR); \
256 OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR); \ 256 OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR); \
257 SAVE_CTR(r10, area); \ 257 SAVE_CTR(r10, area); \
258 mfcr r9; \ 258 mfcr r9;
259 extra(vec); \ 259
260#define __EXCEPTION_PROLOG_1_POST(area) \
260 std r11,area+EX_R11(r13); \ 261 std r11,area+EX_R11(r13); \
261 std r12,area+EX_R12(r13); \ 262 std r12,area+EX_R12(r13); \
262 GET_SCRATCH0(r10); \ 263 GET_SCRATCH0(r10); \
263 std r10,area+EX_R13(r13) 264 std r10,area+EX_R13(r13)
265
266/*
267 * This version of the EXCEPTION_PROLOG_1 will carry
268 * addition parameter called "bitmask" to support
269 * checking of the interrupt maskable level in the SOFTEN_TEST.
270 * Intended to be used in MASKABLE_EXCPETION_* macros.
271 */
272#define MASKABLE_EXCEPTION_PROLOG_1(area, extra, vec, bitmask) \
273 __EXCEPTION_PROLOG_1_PRE(area); \
274 extra(vec, bitmask); \
275 __EXCEPTION_PROLOG_1_POST(area);
276
277/*
278 * This version of the EXCEPTION_PROLOG_1 is intended
279 * to be used in STD_EXCEPTION* macros
280 */
281#define _EXCEPTION_PROLOG_1(area, extra, vec) \
282 __EXCEPTION_PROLOG_1_PRE(area); \
283 extra(vec); \
284 __EXCEPTION_PROLOG_1_POST(area);
285
264#define EXCEPTION_PROLOG_1(area, extra, vec) \ 286#define EXCEPTION_PROLOG_1(area, extra, vec) \
265 __EXCEPTION_PROLOG_1(area, extra, vec) 287 _EXCEPTION_PROLOG_1(area, extra, vec)
266 288
267#define __EXCEPTION_PROLOG_PSERIES_1(label, h) \ 289#define __EXCEPTION_PROLOG_PSERIES_1(label, h) \
268 ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \ 290 ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \
@@ -485,7 +507,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
485 mflr r9; /* Get LR, later save to stack */ \ 507 mflr r9; /* Get LR, later save to stack */ \
486 ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \ 508 ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \
487 std r9,_LINK(r1); \ 509 std r9,_LINK(r1); \
488 lbz r10,PACASOFTIRQEN(r13); \ 510 lbz r10,PACAIRQSOFTMASK(r13); \
489 mfspr r11,SPRN_XER; /* save XER in stackframe */ \ 511 mfspr r11,SPRN_XER; /* save XER in stackframe */ \
490 std r10,SOFTE(r1); \ 512 std r10,SOFTE(r1); \
491 std r11,_XER(r1); \ 513 std r11,_XER(r1); \
@@ -549,22 +571,23 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
549#define SOFTEN_VALUE_0xe80 PACA_IRQ_DBELL 571#define SOFTEN_VALUE_0xe80 PACA_IRQ_DBELL
550#define SOFTEN_VALUE_0xe60 PACA_IRQ_HMI 572#define SOFTEN_VALUE_0xe60 PACA_IRQ_HMI
551#define SOFTEN_VALUE_0xea0 PACA_IRQ_EE 573#define SOFTEN_VALUE_0xea0 PACA_IRQ_EE
574#define SOFTEN_VALUE_0xf00 PACA_IRQ_PMI
552 575
553#define __SOFTEN_TEST(h, vec) \ 576#define __SOFTEN_TEST(h, vec, bitmask) \
554 lbz r10,PACASOFTIRQEN(r13); \ 577 lbz r10,PACAIRQSOFTMASK(r13); \
555 cmpwi r10,0; \ 578 andi. r10,r10,bitmask; \
556 li r10,SOFTEN_VALUE_##vec; \ 579 li r10,SOFTEN_VALUE_##vec; \
557 beq masked_##h##interrupt 580 bne masked_##h##interrupt
558 581
559#define _SOFTEN_TEST(h, vec) __SOFTEN_TEST(h, vec) 582#define _SOFTEN_TEST(h, vec, bitmask) __SOFTEN_TEST(h, vec, bitmask)
560 583
561#define SOFTEN_TEST_PR(vec) \ 584#define SOFTEN_TEST_PR(vec, bitmask) \
562 KVMTEST(EXC_STD, vec); \ 585 KVMTEST(EXC_STD, vec); \
563 _SOFTEN_TEST(EXC_STD, vec) 586 _SOFTEN_TEST(EXC_STD, vec, bitmask)
564 587
565#define SOFTEN_TEST_HV(vec) \ 588#define SOFTEN_TEST_HV(vec, bitmask) \
566 KVMTEST(EXC_HV, vec); \ 589 KVMTEST(EXC_HV, vec); \
567 _SOFTEN_TEST(EXC_HV, vec) 590 _SOFTEN_TEST(EXC_HV, vec, bitmask)
568 591
569#define KVMTEST_PR(vec) \ 592#define KVMTEST_PR(vec) \
570 KVMTEST(EXC_STD, vec) 593 KVMTEST(EXC_STD, vec)
@@ -572,53 +595,57 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
572#define KVMTEST_HV(vec) \ 595#define KVMTEST_HV(vec) \
573 KVMTEST(EXC_HV, vec) 596 KVMTEST(EXC_HV, vec)
574 597
575#define SOFTEN_NOTEST_PR(vec) _SOFTEN_TEST(EXC_STD, vec) 598#define SOFTEN_NOTEST_PR(vec, bitmask) _SOFTEN_TEST(EXC_STD, vec, bitmask)
576#define SOFTEN_NOTEST_HV(vec) _SOFTEN_TEST(EXC_HV, vec) 599#define SOFTEN_NOTEST_HV(vec, bitmask) _SOFTEN_TEST(EXC_HV, vec, bitmask)
577 600
578#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra) \ 601#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra, bitmask) \
579 SET_SCRATCH0(r13); /* save r13 */ \ 602 SET_SCRATCH0(r13); /* save r13 */ \
580 EXCEPTION_PROLOG_0(PACA_EXGEN); \ 603 EXCEPTION_PROLOG_0(PACA_EXGEN); \
581 __EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec); \ 604 MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec, bitmask); \
582 EXCEPTION_PROLOG_PSERIES_1(label, h); 605 EXCEPTION_PROLOG_PSERIES_1(label, h);
583 606
584#define _MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra) \ 607#define _MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra, bitmask) \
585 __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra) 608 __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra, bitmask)
586 609
587#define MASKABLE_EXCEPTION_PSERIES(loc, vec, label) \ 610#define MASKABLE_EXCEPTION_PSERIES(loc, vec, label, bitmask) \
588 _MASKABLE_EXCEPTION_PSERIES(vec, label, \ 611 _MASKABLE_EXCEPTION_PSERIES(vec, label, \
589 EXC_STD, SOFTEN_TEST_PR) 612 EXC_STD, SOFTEN_TEST_PR, bitmask)
590 613
591#define MASKABLE_EXCEPTION_PSERIES_OOL(vec, label) \ 614#define MASKABLE_EXCEPTION_PSERIES_OOL(vec, label, bitmask) \
592 EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_PR, vec); \ 615 MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_PR, vec, bitmask);\
593 EXCEPTION_PROLOG_PSERIES_1(label, EXC_STD) 616 EXCEPTION_PROLOG_PSERIES_1(label, EXC_STD)
594 617
595#define MASKABLE_EXCEPTION_HV(loc, vec, label) \ 618#define MASKABLE_EXCEPTION_HV(loc, vec, label, bitmask) \
596 _MASKABLE_EXCEPTION_PSERIES(vec, label, \ 619 _MASKABLE_EXCEPTION_PSERIES(vec, label, \
597 EXC_HV, SOFTEN_TEST_HV) 620 EXC_HV, SOFTEN_TEST_HV, bitmask)
598 621
599#define MASKABLE_EXCEPTION_HV_OOL(vec, label) \ 622#define MASKABLE_EXCEPTION_HV_OOL(vec, label, bitmask) \
600 EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV, vec); \ 623 MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV, vec, bitmask);\
601 EXCEPTION_PROLOG_PSERIES_1(label, EXC_HV) 624 EXCEPTION_PROLOG_PSERIES_1(label, EXC_HV)
602 625
603#define __MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra) \ 626#define __MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra, bitmask) \
604 SET_SCRATCH0(r13); /* save r13 */ \ 627 SET_SCRATCH0(r13); /* save r13 */ \
605 EXCEPTION_PROLOG_0(PACA_EXGEN); \ 628 EXCEPTION_PROLOG_0(PACA_EXGEN); \
606 __EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec); \ 629 MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec, bitmask); \
607 EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) 630 EXCEPTION_RELON_PROLOG_PSERIES_1(label, h)
608 631
609#define _MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra) \ 632#define _MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra, bitmask)\
610 __MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra) 633 __MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra, bitmask)
611 634
612#define MASKABLE_RELON_EXCEPTION_PSERIES(loc, vec, label) \ 635#define MASKABLE_RELON_EXCEPTION_PSERIES(loc, vec, label, bitmask) \
613 _MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, \ 636 _MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, \
614 EXC_STD, SOFTEN_NOTEST_PR) 637 EXC_STD, SOFTEN_NOTEST_PR, bitmask)
638
639#define MASKABLE_RELON_EXCEPTION_PSERIES_OOL(vec, label, bitmask) \
640 MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_NOTEST_PR, vec, bitmask);\
641 EXCEPTION_PROLOG_PSERIES_1(label, EXC_STD);
615 642
616#define MASKABLE_RELON_EXCEPTION_HV(loc, vec, label) \ 643#define MASKABLE_RELON_EXCEPTION_HV(loc, vec, label, bitmask) \
617 _MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, \ 644 _MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, \
618 EXC_HV, SOFTEN_TEST_HV) 645 EXC_HV, SOFTEN_TEST_HV, bitmask)
619 646
620#define MASKABLE_RELON_EXCEPTION_HV_OOL(vec, label) \ 647#define MASKABLE_RELON_EXCEPTION_HV_OOL(vec, label, bitmask) \
621 EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV, vec); \ 648 MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_NOTEST_HV, vec, bitmask);\
622 EXCEPTION_RELON_PROLOG_PSERIES_1(label, EXC_HV) 649 EXCEPTION_RELON_PROLOG_PSERIES_1(label, EXC_HV)
623 650
624/* 651/*
diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h
index 8645897472b1..511acfd7ab0d 100644
--- a/arch/powerpc/include/asm/firmware.h
+++ b/arch/powerpc/include/asm/firmware.h
@@ -51,6 +51,8 @@
51#define FW_FEATURE_BEST_ENERGY ASM_CONST(0x0000000080000000) 51#define FW_FEATURE_BEST_ENERGY ASM_CONST(0x0000000080000000)
52#define FW_FEATURE_TYPE1_AFFINITY ASM_CONST(0x0000000100000000) 52#define FW_FEATURE_TYPE1_AFFINITY ASM_CONST(0x0000000100000000)
53#define FW_FEATURE_PRRN ASM_CONST(0x0000000200000000) 53#define FW_FEATURE_PRRN ASM_CONST(0x0000000200000000)
54#define FW_FEATURE_DRMEM_V2 ASM_CONST(0x0000000400000000)
55#define FW_FEATURE_DRC_INFO ASM_CONST(0x0000000400000000)
54 56
55#ifndef __ASSEMBLY__ 57#ifndef __ASSEMBLY__
56 58
@@ -67,7 +69,8 @@ enum {
67 FW_FEATURE_CMO | FW_FEATURE_VPHN | FW_FEATURE_XCMO | 69 FW_FEATURE_CMO | FW_FEATURE_VPHN | FW_FEATURE_XCMO |
68 FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY | 70 FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY |
69 FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN | 71 FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN |
70 FW_FEATURE_HPT_RESIZE, 72 FW_FEATURE_HPT_RESIZE | FW_FEATURE_DRMEM_V2 |
73 FW_FEATURE_DRC_INFO,
71 FW_FEATURE_PSERIES_ALWAYS = 0, 74 FW_FEATURE_PSERIES_ALWAYS = 0,
72 FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL, 75 FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL,
73 FW_FEATURE_POWERNV_ALWAYS = 0, 76 FW_FEATURE_POWERNV_ALWAYS = 0,
diff --git a/arch/powerpc/include/asm/hardirq.h b/arch/powerpc/include/asm/hardirq.h
index 456f9e7b8d83..5986d473722b 100644
--- a/arch/powerpc/include/asm/hardirq.h
+++ b/arch/powerpc/include/asm/hardirq.h
@@ -29,6 +29,7 @@ DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
29#define local_softirq_pending() __this_cpu_read(irq_stat.__softirq_pending) 29#define local_softirq_pending() __this_cpu_read(irq_stat.__softirq_pending)
30 30
31#define __ARCH_SET_SOFTIRQ_PENDING 31#define __ARCH_SET_SOFTIRQ_PENDING
32#define __ARCH_IRQ_EXIT_IRQS_DISABLED
32 33
33#define set_softirq_pending(x) __this_cpu_write(irq_stat.__softirq_pending, (x)) 34#define set_softirq_pending(x) __this_cpu_write(irq_stat.__softirq_pending, (x))
34#define or_softirq_pending(x) __this_cpu_or(irq_stat.__softirq_pending, (x)) 35#define or_softirq_pending(x) __this_cpu_or(irq_stat.__softirq_pending, (x))
diff --git a/arch/powerpc/include/asm/head-64.h b/arch/powerpc/include/asm/head-64.h
index fdcff76e9a25..7e0e93f24cb7 100644
--- a/arch/powerpc/include/asm/head-64.h
+++ b/arch/powerpc/include/asm/head-64.h
@@ -178,7 +178,7 @@ name:
178 * TRAMP_REAL_* - real, unrelocated helpers (virt can call these) 178 * TRAMP_REAL_* - real, unrelocated helpers (virt can call these)
179 * TRAMP_VIRT_* - virt, unreloc helpers (in practice, real can use) 179 * TRAMP_VIRT_* - virt, unreloc helpers (in practice, real can use)
180 * TRAMP_KVM - KVM handlers that get put into real, unrelocated 180 * TRAMP_KVM - KVM handlers that get put into real, unrelocated
181 * EXC_COMMON_* - virt, relocated common handlers 181 * EXC_COMMON - virt, relocated common handlers
182 * 182 *
183 * The EXC handlers are given a name, and branch to name_common, or the 183 * The EXC handlers are given a name, and branch to name_common, or the
184 * appropriate KVM or masking function. Vector handler verieties are as 184 * appropriate KVM or masking function. Vector handler verieties are as
@@ -211,7 +211,6 @@ name:
211 * EXC_COMMON_BEGIN/END - used to open-code the handler 211 * EXC_COMMON_BEGIN/END - used to open-code the handler
212 * EXC_COMMON 212 * EXC_COMMON
213 * EXC_COMMON_ASYNC 213 * EXC_COMMON_ASYNC
214 * EXC_COMMON_HV
215 * 214 *
216 * TRAMP_REAL and TRAMP_VIRT can be used with BEGIN/END. KVM 215 * TRAMP_REAL and TRAMP_VIRT can be used with BEGIN/END. KVM
217 * and OOL handlers are implemented as types of TRAMP and TRAMP_VIRT handlers. 216 * and OOL handlers are implemented as types of TRAMP and TRAMP_VIRT handlers.
@@ -269,14 +268,14 @@ name:
269 STD_RELON_EXCEPTION_PSERIES(start, realvec, name##_common); \ 268 STD_RELON_EXCEPTION_PSERIES(start, realvec, name##_common); \
270 EXC_VIRT_END(name, start, size); 269 EXC_VIRT_END(name, start, size);
271 270
272#define EXC_REAL_MASKABLE(name, start, size) \ 271#define EXC_REAL_MASKABLE(name, start, size, bitmask) \
273 EXC_REAL_BEGIN(name, start, size); \ 272 EXC_REAL_BEGIN(name, start, size); \
274 MASKABLE_EXCEPTION_PSERIES(start, start, name##_common); \ 273 MASKABLE_EXCEPTION_PSERIES(start, start, name##_common, bitmask);\
275 EXC_REAL_END(name, start, size); 274 EXC_REAL_END(name, start, size);
276 275
277#define EXC_VIRT_MASKABLE(name, start, size, realvec) \ 276#define EXC_VIRT_MASKABLE(name, start, size, realvec, bitmask) \
278 EXC_VIRT_BEGIN(name, start, size); \ 277 EXC_VIRT_BEGIN(name, start, size); \
279 MASKABLE_RELON_EXCEPTION_PSERIES(start, realvec, name##_common); \ 278 MASKABLE_RELON_EXCEPTION_PSERIES(start, realvec, name##_common, bitmask);\
280 EXC_VIRT_END(name, start, size); 279 EXC_VIRT_END(name, start, size);
281 280
282#define EXC_REAL_HV(name, start, size) \ 281#define EXC_REAL_HV(name, start, size) \
@@ -305,13 +304,13 @@ name:
305#define __EXC_REAL_OOL_MASKABLE(name, start, size) \ 304#define __EXC_REAL_OOL_MASKABLE(name, start, size) \
306 __EXC_REAL_OOL(name, start, size); 305 __EXC_REAL_OOL(name, start, size);
307 306
308#define __TRAMP_REAL_OOL_MASKABLE(name, vec) \ 307#define __TRAMP_REAL_OOL_MASKABLE(name, vec, bitmask) \
309 TRAMP_REAL_BEGIN(tramp_real_##name); \ 308 TRAMP_REAL_BEGIN(tramp_real_##name); \
310 MASKABLE_EXCEPTION_PSERIES_OOL(vec, name##_common); \ 309 MASKABLE_EXCEPTION_PSERIES_OOL(vec, name##_common, bitmask); \
311 310
312#define EXC_REAL_OOL_MASKABLE(name, start, size) \ 311#define EXC_REAL_OOL_MASKABLE(name, start, size, bitmask) \
313 __EXC_REAL_OOL_MASKABLE(name, start, size); \ 312 __EXC_REAL_OOL_MASKABLE(name, start, size); \
314 __TRAMP_REAL_OOL_MASKABLE(name, start); 313 __TRAMP_REAL_OOL_MASKABLE(name, start, bitmask);
315 314
316#define __EXC_REAL_OOL_HV_DIRECT(name, start, size, handler) \ 315#define __EXC_REAL_OOL_HV_DIRECT(name, start, size, handler) \
317 EXC_REAL_BEGIN(name, start, size); \ 316 EXC_REAL_BEGIN(name, start, size); \
@@ -332,13 +331,13 @@ name:
332#define __EXC_REAL_OOL_MASKABLE_HV(name, start, size) \ 331#define __EXC_REAL_OOL_MASKABLE_HV(name, start, size) \
333 __EXC_REAL_OOL(name, start, size); 332 __EXC_REAL_OOL(name, start, size);
334 333
335#define __TRAMP_REAL_OOL_MASKABLE_HV(name, vec) \ 334#define __TRAMP_REAL_OOL_MASKABLE_HV(name, vec, bitmask) \
336 TRAMP_REAL_BEGIN(tramp_real_##name); \ 335 TRAMP_REAL_BEGIN(tramp_real_##name); \
337 MASKABLE_EXCEPTION_HV_OOL(vec, name##_common); \ 336 MASKABLE_EXCEPTION_HV_OOL(vec, name##_common, bitmask); \
338 337
339#define EXC_REAL_OOL_MASKABLE_HV(name, start, size) \ 338#define EXC_REAL_OOL_MASKABLE_HV(name, start, size, bitmask) \
340 __EXC_REAL_OOL_MASKABLE_HV(name, start, size); \ 339 __EXC_REAL_OOL_MASKABLE_HV(name, start, size); \
341 __TRAMP_REAL_OOL_MASKABLE_HV(name, start); 340 __TRAMP_REAL_OOL_MASKABLE_HV(name, start, bitmask);
342 341
343#define __EXC_VIRT_OOL(name, start, size) \ 342#define __EXC_VIRT_OOL(name, start, size) \
344 EXC_VIRT_BEGIN(name, start, size); \ 343 EXC_VIRT_BEGIN(name, start, size); \
@@ -356,13 +355,13 @@ name:
356#define __EXC_VIRT_OOL_MASKABLE(name, start, size) \ 355#define __EXC_VIRT_OOL_MASKABLE(name, start, size) \
357 __EXC_VIRT_OOL(name, start, size); 356 __EXC_VIRT_OOL(name, start, size);
358 357
359#define __TRAMP_VIRT_OOL_MASKABLE(name, realvec) \ 358#define __TRAMP_VIRT_OOL_MASKABLE(name, realvec, bitmask) \
360 TRAMP_VIRT_BEGIN(tramp_virt_##name); \ 359 TRAMP_VIRT_BEGIN(tramp_virt_##name); \
361 MASKABLE_RELON_EXCEPTION_PSERIES_OOL(realvec, name##_common); \ 360 MASKABLE_RELON_EXCEPTION_PSERIES_OOL(realvec, name##_common, bitmask);\
362 361
363#define EXC_VIRT_OOL_MASKABLE(name, start, size, realvec) \ 362#define EXC_VIRT_OOL_MASKABLE(name, start, size, realvec, bitmask) \
364 __EXC_VIRT_OOL_MASKABLE(name, start, size); \ 363 __EXC_VIRT_OOL_MASKABLE(name, start, size); \
365 __TRAMP_VIRT_OOL_MASKABLE(name, realvec); 364 __TRAMP_VIRT_OOL_MASKABLE(name, realvec, bitmask);
366 365
367#define __EXC_VIRT_OOL_HV(name, start, size) \ 366#define __EXC_VIRT_OOL_HV(name, start, size) \
368 __EXC_VIRT_OOL(name, start, size); 367 __EXC_VIRT_OOL(name, start, size);
@@ -378,13 +377,13 @@ name:
378#define __EXC_VIRT_OOL_MASKABLE_HV(name, start, size) \ 377#define __EXC_VIRT_OOL_MASKABLE_HV(name, start, size) \
379 __EXC_VIRT_OOL(name, start, size); 378 __EXC_VIRT_OOL(name, start, size);
380 379
381#define __TRAMP_VIRT_OOL_MASKABLE_HV(name, realvec) \ 380#define __TRAMP_VIRT_OOL_MASKABLE_HV(name, realvec, bitmask) \
382 TRAMP_VIRT_BEGIN(tramp_virt_##name); \ 381 TRAMP_VIRT_BEGIN(tramp_virt_##name); \
383 MASKABLE_RELON_EXCEPTION_HV_OOL(realvec, name##_common); \ 382 MASKABLE_RELON_EXCEPTION_HV_OOL(realvec, name##_common, bitmask);\
384 383
385#define EXC_VIRT_OOL_MASKABLE_HV(name, start, size, realvec) \ 384#define EXC_VIRT_OOL_MASKABLE_HV(name, start, size, realvec, bitmask) \
386 __EXC_VIRT_OOL_MASKABLE_HV(name, start, size); \ 385 __EXC_VIRT_OOL_MASKABLE_HV(name, start, size); \
387 __TRAMP_VIRT_OOL_MASKABLE_HV(name, realvec); 386 __TRAMP_VIRT_OOL_MASKABLE_HV(name, realvec, bitmask);
388 387
389#define TRAMP_KVM(area, n) \ 388#define TRAMP_KVM(area, n) \
390 TRAMP_KVM_BEGIN(do_kvm_##n); \ 389 TRAMP_KVM_BEGIN(do_kvm_##n); \
@@ -413,10 +412,6 @@ name:
413 EXC_COMMON_BEGIN(name); \ 412 EXC_COMMON_BEGIN(name); \
414 STD_EXCEPTION_COMMON_ASYNC(realvec, name, hdlr); \ 413 STD_EXCEPTION_COMMON_ASYNC(realvec, name, hdlr); \
415 414
416#define EXC_COMMON_HV(name, realvec, hdlr) \
417 EXC_COMMON_BEGIN(name); \
418 STD_EXCEPTION_COMMON(realvec + 0x2, name, hdlr); \
419
420#endif /* __ASSEMBLY__ */ 415#endif /* __ASSEMBLY__ */
421 416
422#endif /* _ASM_POWERPC_HEAD_64_H */ 417#endif /* _ASM_POWERPC_HEAD_64_H */
diff --git a/arch/powerpc/include/asm/hmi.h b/arch/powerpc/include/asm/hmi.h
index 85b7a1a21e22..9c14f7b5c46c 100644
--- a/arch/powerpc/include/asm/hmi.h
+++ b/arch/powerpc/include/asm/hmi.h
@@ -42,4 +42,8 @@ extern void wait_for_tb_resync(void);
42static inline void wait_for_subcore_guest_exit(void) { } 42static inline void wait_for_subcore_guest_exit(void) { }
43static inline void wait_for_tb_resync(void) { } 43static inline void wait_for_tb_resync(void) { }
44#endif 44#endif
45
46struct pt_regs;
47extern long hmi_handle_debugtrig(struct pt_regs *regs);
48
45#endif /* __ASM_PPC64_HMI_H__ */ 49#endif /* __ASM_PPC64_HMI_H__ */
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index 14c9d44f355b..1a4847f67ea8 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -47,8 +47,7 @@ static inline pte_t *hugepd_page(hugepd_t hpd)
47{ 47{
48 BUG_ON(!hugepd_ok(hpd)); 48 BUG_ON(!hugepd_ok(hpd));
49#ifdef CONFIG_PPC_8xx 49#ifdef CONFIG_PPC_8xx
50 return (pte_t *)__va(hpd_val(hpd) & 50 return (pte_t *)__va(hpd_val(hpd) & ~HUGEPD_SHIFT_MASK);
51 ~(_PMD_PAGE_MASK | _PMD_PRESENT_MASK));
52#else 51#else
53 return (pte_t *)((hpd_val(hpd) & 52 return (pte_t *)((hpd_val(hpd) &
54 ~HUGEPD_SHIFT_MASK) | PD_HUGE); 53 ~HUGEPD_SHIFT_MASK) | PD_HUGE);
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index 3818fa0164f0..88e5e8f17e98 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -27,6 +27,15 @@
27#define PACA_IRQ_DEC 0x08 /* Or FIT */ 27#define PACA_IRQ_DEC 0x08 /* Or FIT */
28#define PACA_IRQ_EE_EDGE 0x10 /* BookE only */ 28#define PACA_IRQ_EE_EDGE 0x10 /* BookE only */
29#define PACA_IRQ_HMI 0x20 29#define PACA_IRQ_HMI 0x20
30#define PACA_IRQ_PMI 0x40
31
32/*
33 * flags for paca->irq_soft_mask
34 */
35#define IRQS_ENABLED 0
36#define IRQS_DISABLED 1 /* local_irq_disable() interrupts */
37#define IRQS_PMI_DISABLED 2
38#define IRQS_ALL_DISABLED (IRQS_DISABLED | IRQS_PMI_DISABLED)
30 39
31#endif /* CONFIG_PPC64 */ 40#endif /* CONFIG_PPC64 */
32 41
@@ -43,46 +52,112 @@ extern void unknown_exception(struct pt_regs *regs);
43#ifdef CONFIG_PPC64 52#ifdef CONFIG_PPC64
44#include <asm/paca.h> 53#include <asm/paca.h>
45 54
46static inline unsigned long arch_local_save_flags(void) 55static inline notrace unsigned long irq_soft_mask_return(void)
47{ 56{
48 unsigned long flags; 57 unsigned long flags;
49 58
50 asm volatile( 59 asm volatile(
51 "lbz %0,%1(13)" 60 "lbz %0,%1(13)"
52 : "=r" (flags) 61 : "=r" (flags)
53 : "i" (offsetof(struct paca_struct, soft_enabled))); 62 : "i" (offsetof(struct paca_struct, irq_soft_mask)));
63
64 return flags;
65}
66
67/*
68 * The "memory" clobber acts as both a compiler barrier
69 * for the critical section and as a clobber because
70 * we changed paca->irq_soft_mask
71 */
72static inline notrace void irq_soft_mask_set(unsigned long mask)
73{
74#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
75 /*
76 * The irq mask must always include the STD bit if any are set.
77 *
78 * and interrupts don't get replayed until the standard
79 * interrupt (local_irq_disable()) is unmasked.
80 *
81 * Other masks must only provide additional masking beyond
82 * the standard, and they are also not replayed until the
83 * standard interrupt becomes unmasked.
84 *
85 * This could be changed, but it will require partial
86 * unmasks to be replayed, among other things. For now, take
87 * the simple approach.
88 */
89 WARN_ON(mask && !(mask & IRQS_DISABLED));
90#endif
91
92 asm volatile(
93 "stb %0,%1(13)"
94 :
95 : "r" (mask),
96 "i" (offsetof(struct paca_struct, irq_soft_mask))
97 : "memory");
98}
99
100static inline notrace unsigned long irq_soft_mask_set_return(unsigned long mask)
101{
102 unsigned long flags;
103
104#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
105 WARN_ON(mask && !(mask & IRQS_DISABLED));
106#endif
107
108 asm volatile(
109 "lbz %0,%1(13); stb %2,%1(13)"
110 : "=&r" (flags)
111 : "i" (offsetof(struct paca_struct, irq_soft_mask)),
112 "r" (mask)
113 : "memory");
54 114
55 return flags; 115 return flags;
56} 116}
57 117
58static inline unsigned long arch_local_irq_disable(void) 118static inline notrace unsigned long irq_soft_mask_or_return(unsigned long mask)
59{ 119{
60 unsigned long flags, zero; 120 unsigned long flags, tmp;
61 121
62 asm volatile( 122 asm volatile(
63 "li %1,0; lbz %0,%2(13); stb %1,%2(13)" 123 "lbz %0,%2(13); or %1,%0,%3; stb %1,%2(13)"
64 : "=r" (flags), "=&r" (zero) 124 : "=&r" (flags), "=r" (tmp)
65 : "i" (offsetof(struct paca_struct, soft_enabled)) 125 : "i" (offsetof(struct paca_struct, irq_soft_mask)),
126 "r" (mask)
66 : "memory"); 127 : "memory");
67 128
129#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
130 WARN_ON((mask | flags) && !((mask | flags) & IRQS_DISABLED));
131#endif
132
68 return flags; 133 return flags;
69} 134}
70 135
136static inline unsigned long arch_local_save_flags(void)
137{
138 return irq_soft_mask_return();
139}
140
141static inline void arch_local_irq_disable(void)
142{
143 irq_soft_mask_set(IRQS_DISABLED);
144}
145
71extern void arch_local_irq_restore(unsigned long); 146extern void arch_local_irq_restore(unsigned long);
72 147
73static inline void arch_local_irq_enable(void) 148static inline void arch_local_irq_enable(void)
74{ 149{
75 arch_local_irq_restore(1); 150 arch_local_irq_restore(IRQS_ENABLED);
76} 151}
77 152
78static inline unsigned long arch_local_irq_save(void) 153static inline unsigned long arch_local_irq_save(void)
79{ 154{
80 return arch_local_irq_disable(); 155 return irq_soft_mask_set_return(IRQS_DISABLED);
81} 156}
82 157
83static inline bool arch_irqs_disabled_flags(unsigned long flags) 158static inline bool arch_irqs_disabled_flags(unsigned long flags)
84{ 159{
85 return flags == 0; 160 return flags & IRQS_DISABLED;
86} 161}
87 162
88static inline bool arch_irqs_disabled(void) 163static inline bool arch_irqs_disabled(void)
@@ -90,6 +165,55 @@ static inline bool arch_irqs_disabled(void)
90 return arch_irqs_disabled_flags(arch_local_save_flags()); 165 return arch_irqs_disabled_flags(arch_local_save_flags());
91} 166}
92 167
168#ifdef CONFIG_PPC_BOOK3S
169/*
170 * To support disabling and enabling of irq with PMI, set of
171 * new powerpc_local_irq_pmu_save() and powerpc_local_irq_restore()
172 * functions are added. These macros are implemented using generic
173 * linux local_irq_* code from include/linux/irqflags.h.
174 */
175#define raw_local_irq_pmu_save(flags) \
176 do { \
177 typecheck(unsigned long, flags); \
178 flags = irq_soft_mask_or_return(IRQS_DISABLED | \
179 IRQS_PMI_DISABLED); \
180 } while(0)
181
182#define raw_local_irq_pmu_restore(flags) \
183 do { \
184 typecheck(unsigned long, flags); \
185 arch_local_irq_restore(flags); \
186 } while(0)
187
188#ifdef CONFIG_TRACE_IRQFLAGS
189#define powerpc_local_irq_pmu_save(flags) \
190 do { \
191 raw_local_irq_pmu_save(flags); \
192 trace_hardirqs_off(); \
193 } while(0)
194#define powerpc_local_irq_pmu_restore(flags) \
195 do { \
196 if (raw_irqs_disabled_flags(flags)) { \
197 raw_local_irq_pmu_restore(flags); \
198 trace_hardirqs_off(); \
199 } else { \
200 trace_hardirqs_on(); \
201 raw_local_irq_pmu_restore(flags); \
202 } \
203 } while(0)
204#else
205#define powerpc_local_irq_pmu_save(flags) \
206 do { \
207 raw_local_irq_pmu_save(flags); \
208 } while(0)
209#define powerpc_local_irq_pmu_restore(flags) \
210 do { \
211 raw_local_irq_pmu_restore(flags); \
212 } while (0)
213#endif /* CONFIG_TRACE_IRQFLAGS */
214
215#endif /* CONFIG_PPC_BOOK3S */
216
93#ifdef CONFIG_PPC_BOOK3E 217#ifdef CONFIG_PPC_BOOK3E
94#define __hard_irq_enable() asm volatile("wrteei 1" : : : "memory") 218#define __hard_irq_enable() asm volatile("wrteei 1" : : : "memory")
95#define __hard_irq_disable() asm volatile("wrteei 0" : : : "memory") 219#define __hard_irq_disable() asm volatile("wrteei 0" : : : "memory")
@@ -98,14 +222,13 @@ static inline bool arch_irqs_disabled(void)
98#define __hard_irq_disable() __mtmsrd(local_paca->kernel_msr, 1) 222#define __hard_irq_disable() __mtmsrd(local_paca->kernel_msr, 1)
99#endif 223#endif
100 224
101#define hard_irq_disable() do { \ 225#define hard_irq_disable() do { \
102 u8 _was_enabled; \ 226 unsigned long flags; \
103 __hard_irq_disable(); \ 227 __hard_irq_disable(); \
104 _was_enabled = local_paca->soft_enabled; \ 228 flags = irq_soft_mask_set_return(IRQS_ALL_DISABLED); \
105 local_paca->soft_enabled = 0; \ 229 local_paca->irq_happened |= PACA_IRQ_HARD_DIS; \
106 local_paca->irq_happened |= PACA_IRQ_HARD_DIS; \ 230 if (!arch_irqs_disabled_flags(flags)) \
107 if (_was_enabled) \ 231 trace_hardirqs_off(); \
108 trace_hardirqs_off(); \
109} while(0) 232} while(0)
110 233
111static inline bool lazy_irq_pending(void) 234static inline bool lazy_irq_pending(void)
@@ -127,7 +250,7 @@ static inline void may_hard_irq_enable(void)
127 250
128static inline bool arch_irq_disabled_regs(struct pt_regs *regs) 251static inline bool arch_irq_disabled_regs(struct pt_regs *regs)
129{ 252{
130 return !regs->softe; 253 return (regs->softe & IRQS_DISABLED);
131} 254}
132 255
133extern bool prep_irq_for_idle(void); 256extern bool prep_irq_for_idle(void);
diff --git a/arch/powerpc/include/asm/imc-pmu.h b/arch/powerpc/include/asm/imc-pmu.h
index fad0e6ff460f..d76cb11be3e3 100644
--- a/arch/powerpc/include/asm/imc-pmu.h
+++ b/arch/powerpc/include/asm/imc-pmu.h
@@ -35,6 +35,13 @@
35#define THREAD_IMC_ENABLE 0x8000000000000000ULL 35#define THREAD_IMC_ENABLE 0x8000000000000000ULL
36 36
37/* 37/*
38 * For debugfs interface for imc-mode and imc-command
39 */
40#define IMC_CNTL_BLK_OFFSET 0x3FC00
41#define IMC_CNTL_BLK_CMD_OFFSET 8
42#define IMC_CNTL_BLK_MODE_OFFSET 32
43
44/*
38 * Structure to hold memory address information for imc units. 45 * Structure to hold memory address information for imc units.
39 */ 46 */
40struct imc_mem_info { 47struct imc_mem_info {
@@ -71,7 +78,7 @@ struct imc_events {
71struct imc_pmu { 78struct imc_pmu {
72 struct pmu pmu; 79 struct pmu pmu;
73 struct imc_mem_info *mem_info; 80 struct imc_mem_info *mem_info;
74 struct imc_events **events; 81 struct imc_events *events;
75 /* 82 /*
76 * Attribute groups for the PMU. Slot 0 used for 83 * Attribute groups for the PMU. Slot 0 used for
77 * format attribute, slot 1 used for cpusmask attribute, 84 * format attribute, slot 1 used for cpusmask attribute,
diff --git a/arch/powerpc/include/asm/irqflags.h b/arch/powerpc/include/asm/irqflags.h
index 1aeb5f13b8c4..1a6c1ce17735 100644
--- a/arch/powerpc/include/asm/irqflags.h
+++ b/arch/powerpc/include/asm/irqflags.h
@@ -47,14 +47,14 @@
47 * be clobbered. 47 * be clobbered.
48 */ 48 */
49#define RECONCILE_IRQ_STATE(__rA, __rB) \ 49#define RECONCILE_IRQ_STATE(__rA, __rB) \
50 lbz __rA,PACASOFTIRQEN(r13); \ 50 lbz __rA,PACAIRQSOFTMASK(r13); \
51 lbz __rB,PACAIRQHAPPENED(r13); \ 51 lbz __rB,PACAIRQHAPPENED(r13); \
52 cmpwi cr0,__rA,0; \ 52 andi. __rA,__rA,IRQS_DISABLED; \
53 li __rA,0; \ 53 li __rA,IRQS_DISABLED; \
54 ori __rB,__rB,PACA_IRQ_HARD_DIS; \ 54 ori __rB,__rB,PACA_IRQ_HARD_DIS; \
55 stb __rB,PACAIRQHAPPENED(r13); \ 55 stb __rB,PACAIRQHAPPENED(r13); \
56 beq 44f; \ 56 bne 44f; \
57 stb __rA,PACASOFTIRQEN(r13); \ 57 stb __rA,PACAIRQSOFTMASK(r13); \
58 TRACE_DISABLE_INTS; \ 58 TRACE_DISABLE_INTS; \
5944: 5944:
60 60
@@ -64,9 +64,9 @@
64 64
65#define RECONCILE_IRQ_STATE(__rA, __rB) \ 65#define RECONCILE_IRQ_STATE(__rA, __rB) \
66 lbz __rA,PACAIRQHAPPENED(r13); \ 66 lbz __rA,PACAIRQHAPPENED(r13); \
67 li __rB,0; \ 67 li __rB,IRQS_DISABLED; \
68 ori __rA,__rA,PACA_IRQ_HARD_DIS; \ 68 ori __rA,__rA,PACA_IRQ_HARD_DIS; \
69 stb __rB,PACASOFTIRQEN(r13); \ 69 stb __rB,PACAIRQSOFTMASK(r13); \
70 stb __rA,PACAIRQHAPPENED(r13) 70 stb __rA,PACAIRQHAPPENED(r13)
71#endif 71#endif
72#endif 72#endif
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index 4419d435639a..9dcbfa6bbb91 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -73,6 +73,8 @@ extern void kexec_smp_wait(void); /* get and clear naca physid, wait for
73 master to copy new code to 0 */ 73 master to copy new code to 0 */
74extern int crashing_cpu; 74extern int crashing_cpu;
75extern void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *)); 75extern void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *));
76extern void crash_ipi_callback(struct pt_regs *);
77extern int crash_wake_offline;
76 78
77struct kimage; 79struct kimage;
78struct pt_regs; 80struct pt_regs;
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 941c2a3f231b..9db18287b5f4 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -873,7 +873,7 @@ static inline void kvmppc_fix_ee_before_entry(void)
873 873
874 /* Only need to enable IRQs by hard enabling them after this */ 874 /* Only need to enable IRQs by hard enabling them after this */
875 local_paca->irq_happened = 0; 875 local_paca->irq_happened = 0;
876 local_paca->soft_enabled = 1; 876 irq_soft_mask_set(IRQS_ENABLED);
877#endif 877#endif
878} 878}
879 879
diff --git a/arch/powerpc/include/asm/local.h b/arch/powerpc/include/asm/local.h
index 600a68bd77f5..fdd00939270b 100644
--- a/arch/powerpc/include/asm/local.h
+++ b/arch/powerpc/include/asm/local.h
@@ -2,76 +2,64 @@
2#ifndef _ARCH_POWERPC_LOCAL_H 2#ifndef _ARCH_POWERPC_LOCAL_H
3#define _ARCH_POWERPC_LOCAL_H 3#define _ARCH_POWERPC_LOCAL_H
4 4
5#ifdef CONFIG_PPC_BOOK3S_64
6
5#include <linux/percpu.h> 7#include <linux/percpu.h>
6#include <linux/atomic.h> 8#include <linux/atomic.h>
9#include <linux/irqflags.h>
10
11#include <asm/hw_irq.h>
7 12
8typedef struct 13typedef struct
9{ 14{
10 atomic_long_t a; 15 long v;
11} local_t; 16} local_t;
12 17
13#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) } 18#define LOCAL_INIT(i) { (i) }
14
15#define local_read(l) atomic_long_read(&(l)->a)
16#define local_set(l,i) atomic_long_set(&(l)->a, (i))
17 19
18#define local_add(i,l) atomic_long_add((i),(&(l)->a)) 20static __inline__ long local_read(local_t *l)
19#define local_sub(i,l) atomic_long_sub((i),(&(l)->a))
20#define local_inc(l) atomic_long_inc(&(l)->a)
21#define local_dec(l) atomic_long_dec(&(l)->a)
22
23static __inline__ long local_add_return(long a, local_t *l)
24{ 21{
25 long t; 22 return READ_ONCE(l->v);
26
27 __asm__ __volatile__(
28"1:" PPC_LLARX(%0,0,%2,0) " # local_add_return\n\
29 add %0,%1,%0\n"
30 PPC405_ERR77(0,%2)
31 PPC_STLCX "%0,0,%2 \n\
32 bne- 1b"
33 : "=&r" (t)
34 : "r" (a), "r" (&(l->a.counter))
35 : "cc", "memory");
36
37 return t;
38} 23}
39 24
40#define local_add_negative(a, l) (local_add_return((a), (l)) < 0) 25static __inline__ void local_set(local_t *l, long i)
41
42static __inline__ long local_sub_return(long a, local_t *l)
43{ 26{
44 long t; 27 WRITE_ONCE(l->v, i);
28}
45 29
46 __asm__ __volatile__( 30#define LOCAL_OP(op, c_op) \
47"1:" PPC_LLARX(%0,0,%2,0) " # local_sub_return\n\ 31static __inline__ void local_##op(long i, local_t *l) \
48 subf %0,%1,%0\n" 32{ \
49 PPC405_ERR77(0,%2) 33 unsigned long flags; \
50 PPC_STLCX "%0,0,%2 \n\ 34 \
51 bne- 1b" 35 powerpc_local_irq_pmu_save(flags); \
52 : "=&r" (t) 36 l->v c_op i; \
53 : "r" (a), "r" (&(l->a.counter)) 37 powerpc_local_irq_pmu_restore(flags); \
54 : "cc", "memory"); 38}
55 39
56 return t; 40#define LOCAL_OP_RETURN(op, c_op) \
41static __inline__ long local_##op##_return(long a, local_t *l) \
42{ \
43 long t; \
44 unsigned long flags; \
45 \
46 powerpc_local_irq_pmu_save(flags); \
47 t = (l->v c_op a); \
48 powerpc_local_irq_pmu_restore(flags); \
49 \
50 return t; \
57} 51}
58 52
59static __inline__ long local_inc_return(local_t *l) 53#define LOCAL_OPS(op, c_op) \
60{ 54 LOCAL_OP(op, c_op) \
61 long t; 55 LOCAL_OP_RETURN(op, c_op)
62 56
63 __asm__ __volatile__( 57LOCAL_OPS(add, +=)
64"1:" PPC_LLARX(%0,0,%1,0) " # local_inc_return\n\ 58LOCAL_OPS(sub, -=)
65 addic %0,%0,1\n"
66 PPC405_ERR77(0,%1)
67 PPC_STLCX "%0,0,%1 \n\
68 bne- 1b"
69 : "=&r" (t)
70 : "r" (&(l->a.counter))
71 : "cc", "xer", "memory");
72 59
73 return t; 60#define local_add_negative(a, l) (local_add_return((a), (l)) < 0)
74} 61#define local_inc_return(l) local_add_return(1LL, l)
62#define local_inc(l) local_inc_return(l)
75 63
76/* 64/*
77 * local_inc_and_test - increment and test 65 * local_inc_and_test - increment and test
@@ -81,28 +69,39 @@ static __inline__ long local_inc_return(local_t *l)
81 * and returns true if the result is zero, or false for all 69 * and returns true if the result is zero, or false for all
82 * other cases. 70 * other cases.
83 */ 71 */
84#define local_inc_and_test(l) (local_inc_return(l) == 0) 72#define local_inc_and_test(l) (local_inc_return(l) == 0)
85 73
86static __inline__ long local_dec_return(local_t *l) 74#define local_dec_return(l) local_sub_return(1LL, l)
75#define local_dec(l) local_dec_return(l)
76#define local_sub_and_test(a, l) (local_sub_return((a), (l)) == 0)
77#define local_dec_and_test(l) (local_dec_return((l)) == 0)
78
79static __inline__ long local_cmpxchg(local_t *l, long o, long n)
87{ 80{
88 long t; 81 long t;
82 unsigned long flags;
89 83
90 __asm__ __volatile__( 84 powerpc_local_irq_pmu_save(flags);
91"1:" PPC_LLARX(%0,0,%1,0) " # local_dec_return\n\ 85 t = l->v;
92 addic %0,%0,-1\n" 86 if (t == o)
93 PPC405_ERR77(0,%1) 87 l->v = n;
94 PPC_STLCX "%0,0,%1\n\ 88 powerpc_local_irq_pmu_restore(flags);
95 bne- 1b"
96 : "=&r" (t)
97 : "r" (&(l->a.counter))
98 : "cc", "xer", "memory");
99 89
100 return t; 90 return t;
101} 91}
102 92
103#define local_cmpxchg(l, o, n) \ 93static __inline__ long local_xchg(local_t *l, long n)
104 (cmpxchg_local(&((l)->a.counter), (o), (n))) 94{
105#define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n))) 95 long t;
96 unsigned long flags;
97
98 powerpc_local_irq_pmu_save(flags);
99 t = l->v;
100 l->v = n;
101 powerpc_local_irq_pmu_restore(flags);
102
103 return t;
104}
106 105
107/** 106/**
108 * local_add_unless - add unless the number is a given value 107 * local_add_unless - add unless the number is a given value
@@ -115,62 +114,35 @@ static __inline__ long local_dec_return(local_t *l)
115 */ 114 */
116static __inline__ int local_add_unless(local_t *l, long a, long u) 115static __inline__ int local_add_unless(local_t *l, long a, long u)
117{ 116{
118 long t; 117 unsigned long flags;
119 118 int ret = 0;
120 __asm__ __volatile__ (
121"1:" PPC_LLARX(%0,0,%1,0) " # local_add_unless\n\
122 cmpw 0,%0,%3 \n\
123 beq- 2f \n\
124 add %0,%2,%0 \n"
125 PPC405_ERR77(0,%2)
126 PPC_STLCX "%0,0,%1 \n\
127 bne- 1b \n"
128" subf %0,%2,%0 \n\
1292:"
130 : "=&r" (t)
131 : "r" (&(l->a.counter)), "r" (a), "r" (u)
132 : "cc", "memory");
133
134 return t != u;
135}
136
137#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
138
139#define local_sub_and_test(a, l) (local_sub_return((a), (l)) == 0)
140#define local_dec_and_test(l) (local_dec_return((l)) == 0)
141
142/*
143 * Atomically test *l and decrement if it is greater than 0.
144 * The function returns the old value of *l minus 1.
145 */
146static __inline__ long local_dec_if_positive(local_t *l)
147{
148 long t;
149 119
150 __asm__ __volatile__( 120 powerpc_local_irq_pmu_save(flags);
151"1:" PPC_LLARX(%0,0,%1,0) " # local_dec_if_positive\n\ 121 if (l->v != u) {
152 cmpwi %0,1\n\ 122 l->v += a;
153 addi %0,%0,-1\n\ 123 ret = 1;
154 blt- 2f\n" 124 }
155 PPC405_ERR77(0,%1) 125 powerpc_local_irq_pmu_restore(flags);
156 PPC_STLCX "%0,0,%1\n\
157 bne- 1b"
158 "\n\
1592:" : "=&b" (t)
160 : "r" (&(l->a.counter))
161 : "cc", "memory");
162 126
163 return t; 127 return ret;
164} 128}
165 129
130#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
131
166/* Use these for per-cpu local_t variables: on some archs they are 132/* Use these for per-cpu local_t variables: on some archs they are
167 * much more efficient than these naive implementations. Note they take 133 * much more efficient than these naive implementations. Note they take
168 * a variable, not an address. 134 * a variable, not an address.
169 */ 135 */
170 136
171#define __local_inc(l) ((l)->a.counter++) 137#define __local_inc(l) ((l)->v++)
172#define __local_dec(l) ((l)->a.counter++) 138#define __local_dec(l) ((l)->v++)
173#define __local_add(i,l) ((l)->a.counter+=(i)) 139#define __local_add(i,l) ((l)->v+=(i))
174#define __local_sub(i,l) ((l)->a.counter-=(i)) 140#define __local_sub(i,l) ((l)->v-=(i))
141
142#else /* CONFIG_PPC64 */
143
144#include <asm-generic/local.h>
145
146#endif /* CONFIG_PPC64 */
175 147
176#endif /* _ARCH_POWERPC_LOCAL_H */ 148#endif /* _ARCH_POWERPC_LOCAL_H */
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index cd2fc1cc1cc7..ffe7c71e1132 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -173,11 +173,19 @@ struct machdep_calls {
173 /* Called after scan and before resource survey */ 173 /* Called after scan and before resource survey */
174 void (*pcibios_fixup_phb)(struct pci_controller *hose); 174 void (*pcibios_fixup_phb)(struct pci_controller *hose);
175 175
176 /*
177 * Called after device has been added to bus and
178 * before sysfs has been created.
179 */
180 void (*pcibios_bus_add_device)(struct pci_dev *pdev);
181
176 resource_size_t (*pcibios_default_alignment)(void); 182 resource_size_t (*pcibios_default_alignment)(void);
177 183
178#ifdef CONFIG_PCI_IOV 184#ifdef CONFIG_PCI_IOV
179 void (*pcibios_fixup_sriov)(struct pci_dev *pdev); 185 void (*pcibios_fixup_sriov)(struct pci_dev *pdev);
180 resource_size_t (*pcibios_iov_resource_alignment)(struct pci_dev *, int resno); 186 resource_size_t (*pcibios_iov_resource_alignment)(struct pci_dev *, int resno);
187 int (*pcibios_sriov_enable)(struct pci_dev *pdev, u16 num_vfs);
188 int (*pcibios_sriov_disable)(struct pci_dev *pdev);
181#endif /* CONFIG_PCI_IOV */ 189#endif /* CONFIG_PCI_IOV */
182 190
183 /* Called to shutdown machine specific hardware not already controlled 191 /* Called to shutdown machine specific hardware not already controlled
diff --git a/arch/powerpc/include/asm/mman.h b/arch/powerpc/include/asm/mman.h
index 30922f699341..07e3f54de9e3 100644
--- a/arch/powerpc/include/asm/mman.h
+++ b/arch/powerpc/include/asm/mman.h
@@ -13,6 +13,7 @@
13 13
14#include <asm/cputable.h> 14#include <asm/cputable.h>
15#include <linux/mm.h> 15#include <linux/mm.h>
16#include <linux/pkeys.h>
16#include <asm/cpu_has_feature.h> 17#include <asm/cpu_has_feature.h>
17 18
18/* 19/*
@@ -22,13 +23,23 @@
22static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot, 23static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot,
23 unsigned long pkey) 24 unsigned long pkey)
24{ 25{
25 return (prot & PROT_SAO) ? VM_SAO : 0; 26#ifdef CONFIG_PPC_MEM_KEYS
27 return (((prot & PROT_SAO) ? VM_SAO : 0) | pkey_to_vmflag_bits(pkey));
28#else
29 return ((prot & PROT_SAO) ? VM_SAO : 0);
30#endif
26} 31}
27#define arch_calc_vm_prot_bits(prot, pkey) arch_calc_vm_prot_bits(prot, pkey) 32#define arch_calc_vm_prot_bits(prot, pkey) arch_calc_vm_prot_bits(prot, pkey)
28 33
29static inline pgprot_t arch_vm_get_page_prot(unsigned long vm_flags) 34static inline pgprot_t arch_vm_get_page_prot(unsigned long vm_flags)
30{ 35{
36#ifdef CONFIG_PPC_MEM_KEYS
37 return (vm_flags & VM_SAO) ?
38 __pgprot(_PAGE_SAO | vmflag_to_pte_pkey_bits(vm_flags)) :
39 __pgprot(0 | vmflag_to_pte_pkey_bits(vm_flags));
40#else
31 return (vm_flags & VM_SAO) ? __pgprot(_PAGE_SAO) : __pgprot(0); 41 return (vm_flags & VM_SAO) ? __pgprot(_PAGE_SAO) : __pgprot(0);
42#endif
32} 43}
33#define arch_vm_get_page_prot(vm_flags) arch_vm_get_page_prot(vm_flags) 44#define arch_vm_get_page_prot(vm_flags) arch_vm_get_page_prot(vm_flags)
34 45
diff --git a/arch/powerpc/include/asm/mmu-8xx.h b/arch/powerpc/include/asm/mmu-8xx.h
index 5bb3dbede41a..2f806e329648 100644
--- a/arch/powerpc/include/asm/mmu-8xx.h
+++ b/arch/powerpc/include/asm/mmu-8xx.h
@@ -29,17 +29,25 @@
29#define MI_Kp 0x40000000 /* Should always be set */ 29#define MI_Kp 0x40000000 /* Should always be set */
30 30
31/* 31/*
32 * All pages' PP exec bits are set to 000, which means Execute for Supervisor 32 * All pages' PP data bits are set to either 001 or 011 by copying _PAGE_EXEC
33 * and no Execute for User. 33 * into bit 21 in the ITLBmiss handler (bit 21 is the middle bit), which means
34 * Then we use the APG to say whether accesses are according to Page rules, 34 * respectively NA for All or X for Supervisor and no access for User.
35 * "all Supervisor" rules (Exec for all) and "all User" rules (Exec for noone) 35 * Then we use the APG to say whether accesses are according to Page rules or
36 * Therefore, we define 4 APG groups. msb is _PAGE_EXEC, lsb is _PAGE_USER 36 * "all Supervisor" rules (Access to all)
37 * 0 (00) => Not User, no exec => 11 (all accesses performed as user) 37 * We also use the 2nd APG bit for _PAGE_ACCESSED when having SWAP:
38 * 1 (01) => User but no exec => 11 (all accesses performed as user) 38 * When that bit is not set access is done iaw "all user"
39 * 2 (10) => Not User, exec => 01 (rights according to page definition) 39 * which means no access iaw page rules.
40 * 3 (11) => User, exec => 00 (all accesses performed as supervisor) 40 * Therefore, we define 4 APG groups. lsb is _PMD_USER, 2nd is _PAGE_ACCESSED
41 */ 41 * 0x => No access => 11 (all accesses performed as user iaw page definition)
42#define MI_APG_INIT 0xf4ffffff 42 * 10 => No user => 01 (all accesses performed according to page definition)
43 * 11 => User => 00 (all accesses performed as supervisor iaw page definition)
44 * We define all 16 groups so that all other bits of APG can take any value
45 */
46#ifdef CONFIG_SWAP
47#define MI_APG_INIT 0xf4f4f4f4
48#else
49#define MI_APG_INIT 0x44444444
50#endif
43 51
44/* The effective page number register. When read, contains the information 52/* The effective page number register. When read, contains the information
45 * about the last instruction TLB miss. When MI_RPN is written, bits in 53 * about the last instruction TLB miss. When MI_RPN is written, bits in
@@ -102,17 +110,25 @@
102#define MD_Kp 0x40000000 /* Should always be set */ 110#define MD_Kp 0x40000000 /* Should always be set */
103 111
104/* 112/*
105 * All pages' PP data bits are set to either 000 or 011, which means 113 * All pages' PP data bits are set to either 000 or 011 or 001, which means
106 * respectively RW for Supervisor and no access for User, or RO for 114 * respectively RW for Supervisor and no access for User, or RO for
107 * Supervisor and no access for user. 115 * Supervisor and no access for user and NA for ALL.
108 * Then we use the APG to say whether accesses are according to Page rules or 116 * Then we use the APG to say whether accesses are according to Page rules or
109 * "all Supervisor" rules (Access to all) 117 * "all Supervisor" rules (Access to all)
110 * Therefore, we define 2 APG groups. lsb is _PAGE_USER 118 * We also use the 2nd APG bit for _PAGE_ACCESSED when having SWAP:
111 * 0 => No user => 01 (all accesses performed according to page definition) 119 * When that bit is not set access is done iaw "all user"
112 * 1 => User => 00 (all accesses performed as supervisor 120 * which means no access iaw page rules.
113 * according to page definition) 121 * Therefore, we define 4 APG groups. lsb is _PMD_USER, 2nd is _PAGE_ACCESSED
114 */ 122 * 0x => No access => 11 (all accesses performed as user iaw page definition)
115#define MD_APG_INIT 0x4fffffff 123 * 10 => No user => 01 (all accesses performed according to page definition)
124 * 11 => User => 00 (all accesses performed as supervisor iaw page definition)
125 * We define all 16 groups so that all other bits of APG can take any value
126 */
127#ifdef CONFIG_SWAP
128#define MD_APG_INIT 0xf4f4f4f4
129#else
130#define MD_APG_INIT 0x44444444
131#endif
116 132
117/* The effective page number register. When read, contains the information 133/* The effective page number register. When read, contains the information
118 * about the last instruction TLB miss. When MD_RPN is written, bits in 134 * about the last instruction TLB miss. When MD_RPN is written, bits in
@@ -164,6 +180,12 @@
164 */ 180 */
165#define SPRN_M_TW 799 181#define SPRN_M_TW 799
166 182
183/* APGs */
184#define M_APG0 0x00000000
185#define M_APG1 0x00000020
186#define M_APG2 0x00000040
187#define M_APG3 0x00000060
188
167#ifndef __ASSEMBLY__ 189#ifndef __ASSEMBLY__
168typedef struct { 190typedef struct {
169 unsigned int id; 191 unsigned int id;
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index 6364f5c2cc3e..bb38312cff28 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -260,6 +260,15 @@ static inline bool early_radix_enabled(void)
260} 260}
261#endif 261#endif
262 262
263#ifdef CONFIG_PPC_MEM_KEYS
264extern u16 get_mm_addr_key(struct mm_struct *mm, unsigned long address);
265#else
266static inline u16 get_mm_addr_key(struct mm_struct *mm, unsigned long address)
267{
268 return 0;
269}
270#endif /* CONFIG_PPC_MEM_KEYS */
271
263#endif /* !__ASSEMBLY__ */ 272#endif /* !__ASSEMBLY__ */
264 273
265/* The kernel use the constants below to index in the page sizes array. 274/* The kernel use the constants below to index in the page sizes array.
diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h
index e2a2b8400490..051b3d63afe3 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -187,11 +187,33 @@ static inline void arch_bprm_mm_init(struct mm_struct *mm,
187{ 187{
188} 188}
189 189
190#ifdef CONFIG_PPC_MEM_KEYS
191bool arch_vma_access_permitted(struct vm_area_struct *vma, bool write,
192 bool execute, bool foreign);
193#else /* CONFIG_PPC_MEM_KEYS */
190static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, 194static inline bool arch_vma_access_permitted(struct vm_area_struct *vma,
191 bool write, bool execute, bool foreign) 195 bool write, bool execute, bool foreign)
192{ 196{
193 /* by default, allow everything */ 197 /* by default, allow everything */
194 return true; 198 return true;
195} 199}
200
201#define pkey_mm_init(mm)
202#define thread_pkey_regs_save(thread)
203#define thread_pkey_regs_restore(new_thread, old_thread)
204#define thread_pkey_regs_init(thread)
205
206static inline int vma_pkey(struct vm_area_struct *vma)
207{
208 return 0;
209}
210
211static inline u64 pte_to_hpte_pkey_bits(u64 pteflags)
212{
213 return 0x0UL;
214}
215
216#endif /* CONFIG_PPC_MEM_KEYS */
217
196#endif /* __KERNEL__ */ 218#endif /* __KERNEL__ */
197#endif /* __ASM_POWERPC_MMU_CONTEXT_H */ 219#endif /* __ASM_POWERPC_MMU_CONTEXT_H */
diff --git a/arch/powerpc/include/asm/mpic_timer.h b/arch/powerpc/include/asm/mpic_timer.h
index 0e23cd4ac8aa..13e6702ec458 100644
--- a/arch/powerpc/include/asm/mpic_timer.h
+++ b/arch/powerpc/include/asm/mpic_timer.h
@@ -29,17 +29,17 @@ struct mpic_timer {
29 29
30#ifdef CONFIG_MPIC_TIMER 30#ifdef CONFIG_MPIC_TIMER
31struct mpic_timer *mpic_request_timer(irq_handler_t fn, void *dev, 31struct mpic_timer *mpic_request_timer(irq_handler_t fn, void *dev,
32 const struct timeval *time); 32 time64_t time);
33void mpic_start_timer(struct mpic_timer *handle); 33void mpic_start_timer(struct mpic_timer *handle);
34void mpic_stop_timer(struct mpic_timer *handle); 34void mpic_stop_timer(struct mpic_timer *handle);
35void mpic_get_remain_time(struct mpic_timer *handle, struct timeval *time); 35void mpic_get_remain_time(struct mpic_timer *handle, time64_t *time);
36void mpic_free_timer(struct mpic_timer *handle); 36void mpic_free_timer(struct mpic_timer *handle);
37#else 37#else
38struct mpic_timer *mpic_request_timer(irq_handler_t fn, void *dev, 38struct mpic_timer *mpic_request_timer(irq_handler_t fn, void *dev,
39 const struct timeval *time) { return NULL; } 39 time64_t time) { return NULL; }
40void mpic_start_timer(struct mpic_timer *handle) { } 40void mpic_start_timer(struct mpic_timer *handle) { }
41void mpic_stop_timer(struct mpic_timer *handle) { } 41void mpic_stop_timer(struct mpic_timer *handle) { }
42void mpic_get_remain_time(struct mpic_timer *handle, struct timeval *time) { } 42void mpic_get_remain_time(struct mpic_timer *handle, time64_t *time) { }
43void mpic_free_timer(struct mpic_timer *handle) { } 43void mpic_free_timer(struct mpic_timer *handle) { }
44#endif 44#endif
45 45
diff --git a/arch/powerpc/include/asm/nmi.h b/arch/powerpc/include/asm/nmi.h
index e97f58689ca7..9c80939b4d14 100644
--- a/arch/powerpc/include/asm/nmi.h
+++ b/arch/powerpc/include/asm/nmi.h
@@ -4,10 +4,6 @@
4 4
5#ifdef CONFIG_PPC_WATCHDOG 5#ifdef CONFIG_PPC_WATCHDOG
6extern void arch_touch_nmi_watchdog(void); 6extern void arch_touch_nmi_watchdog(void);
7extern void arch_trigger_cpumask_backtrace(const cpumask_t *mask,
8 bool exclude_self);
9#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
10
11#else 7#else
12static inline void arch_touch_nmi_watchdog(void) {} 8static inline void arch_touch_nmi_watchdog(void) {}
13#endif 9#endif
diff --git a/arch/powerpc/include/asm/nohash/32/pgalloc.h b/arch/powerpc/include/asm/nohash/32/pgalloc.h
index d072139ff2e5..29d37bd1f3b3 100644
--- a/arch/powerpc/include/asm/nohash/32/pgalloc.h
+++ b/arch/powerpc/include/asm/nohash/32/pgalloc.h
@@ -61,7 +61,8 @@ static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp,
61static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmdp, 61static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmdp,
62 pgtable_t pte_page) 62 pgtable_t pte_page)
63{ 63{
64 *pmdp = __pmd((page_to_pfn(pte_page) << PAGE_SHIFT) | _PMD_PRESENT); 64 *pmdp = __pmd((page_to_pfn(pte_page) << PAGE_SHIFT) | _PMD_USER |
65 _PMD_PRESENT);
65} 66}
66 67
67#define pmd_pgtable(pmd) pmd_page(pmd) 68#define pmd_pgtable(pmd) pmd_page(pmd)
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
index cc2bfec3aa3b..504a3c36ce5c 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -282,7 +282,7 @@ static inline void __ptep_set_access_flags(struct mm_struct *mm,
282{ 282{
283 unsigned long set = pte_val(entry) & 283 unsigned long set = pte_val(entry) &
284 (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC); 284 (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
285 unsigned long clr = ~pte_val(entry) & _PAGE_RO; 285 unsigned long clr = ~pte_val(entry) & (_PAGE_RO | _PAGE_NA);
286 286
287 pte_update(ptep, clr, set); 287 pte_update(ptep, clr, set);
288} 288}
diff --git a/arch/powerpc/include/asm/nohash/32/pte-8xx.h b/arch/powerpc/include/asm/nohash/32/pte-8xx.h
index 6dc0180fd5c7..f04cb46ae8a1 100644
--- a/arch/powerpc/include/asm/nohash/32/pte-8xx.h
+++ b/arch/powerpc/include/asm/nohash/32/pte-8xx.h
@@ -31,37 +31,34 @@
31/* Definitions for 8xx embedded chips. */ 31/* Definitions for 8xx embedded chips. */
32#define _PAGE_PRESENT 0x0001 /* Page is valid */ 32#define _PAGE_PRESENT 0x0001 /* Page is valid */
33#define _PAGE_NO_CACHE 0x0002 /* I: cache inhibit */ 33#define _PAGE_NO_CACHE 0x0002 /* I: cache inhibit */
34#define _PAGE_SHARED 0x0004 /* No ASID (context) compare */ 34#define _PAGE_PRIVILEGED 0x0004 /* No ASID (context) compare */
35#define _PAGE_SPECIAL 0x0008 /* SW entry, forced to 0 by the TLB miss */ 35#define _PAGE_HUGE 0x0008 /* SPS: Small Page Size (1 if 16k, 512k or 8M)*/
36#define _PAGE_DIRTY 0x0100 /* C: page changed */ 36#define _PAGE_DIRTY 0x0100 /* C: page changed */
37 37
38/* These 4 software bits must be masked out when the L2 entry is loaded 38/* These 4 software bits must be masked out when the L2 entry is loaded
39 * into the TLB. 39 * into the TLB.
40 */ 40 */
41#define _PAGE_GUARDED 0x0010 /* Copied to L1 G entry in DTLB */ 41#define _PAGE_GUARDED 0x0010 /* Copied to L1 G entry in DTLB */
42#define _PAGE_USER 0x0020 /* Copied to L1 APG lsb */ 42#define _PAGE_SPECIAL 0x0020 /* SW entry */
43#define _PAGE_EXEC 0x0040 /* Copied to L1 APG */ 43#define _PAGE_EXEC 0x0040 /* Copied to PP (bit 21) in ITLB */
44#define _PAGE_WRITETHRU 0x0080 /* software: caching is write through */ 44#define _PAGE_ACCESSED 0x0080 /* software: page referenced */
45#define _PAGE_ACCESSED 0x0800 /* software: page referenced */
46 45
46#define _PAGE_NA 0x0200 /* Supervisor NA, User no access */
47#define _PAGE_RO 0x0600 /* Supervisor RO, User no access */ 47#define _PAGE_RO 0x0600 /* Supervisor RO, User no access */
48 48
49#define _PMD_PRESENT 0x0001 49#define _PMD_PRESENT 0x0001
50#define _PMD_BAD 0x0ff0 50#define _PMD_BAD 0x0fd0
51#define _PMD_PAGE_MASK 0x000c 51#define _PMD_PAGE_MASK 0x000c
52#define _PMD_PAGE_8M 0x000c 52#define _PMD_PAGE_8M 0x000c
53#define _PMD_PAGE_512K 0x0004 53#define _PMD_PAGE_512K 0x0004
54#define _PMD_USER 0x0020 /* APG 1 */
54 55
55/* Until my rework is finished, 8xx still needs atomic PTE updates */ 56/* Until my rework is finished, 8xx still needs atomic PTE updates */
56#define PTE_ATOMIC_UPDATES 1 57#define PTE_ATOMIC_UPDATES 1
57 58
58/* We need to add _PAGE_SHARED to kernel pages */ 59#ifdef CONFIG_PPC_16K_PAGES
59#define _PAGE_KERNEL_RO (_PAGE_SHARED | _PAGE_RO) 60#define _PAGE_PSIZE _PAGE_HUGE
60#define _PAGE_KERNEL_ROX (_PAGE_SHARED | _PAGE_RO | _PAGE_EXEC) 61#endif
61#define _PAGE_KERNEL_RW (_PAGE_SHARED | _PAGE_DIRTY | _PAGE_RW | \
62 _PAGE_HWWRITE)
63#define _PAGE_KERNEL_RWX (_PAGE_SHARED | _PAGE_DIRTY | _PAGE_RW | \
64 _PAGE_HWWRITE | _PAGE_EXEC)
65 62
66#endif /* __KERNEL__ */ 63#endif /* __KERNEL__ */
67#endif /* _ASM_POWERPC_NOHASH_32_PTE_8xx_H */ 64#endif /* _ASM_POWERPC_NOHASH_32_PTE_8xx_H */
diff --git a/arch/powerpc/include/asm/nohash/pgtable.h b/arch/powerpc/include/asm/nohash/pgtable.h
index 5c68f4a59f75..c56de1e8026f 100644
--- a/arch/powerpc/include/asm/nohash/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/pgtable.h
@@ -45,6 +45,29 @@ static inline int pte_present(pte_t pte)
45 return pte_val(pte) & _PAGE_PRESENT; 45 return pte_val(pte) & _PAGE_PRESENT;
46} 46}
47 47
48/*
49 * We only find page table entry in the last level
50 * Hence no need for other accessors
51 */
52#define pte_access_permitted pte_access_permitted
53static inline bool pte_access_permitted(pte_t pte, bool write)
54{
55 unsigned long pteval = pte_val(pte);
56 /*
57 * A read-only access is controlled by _PAGE_USER bit.
58 * We have _PAGE_READ set for WRITE and EXECUTE
59 */
60 unsigned long need_pte_bits = _PAGE_PRESENT | _PAGE_USER;
61
62 if (write)
63 need_pte_bits |= _PAGE_WRITE;
64
65 if ((pteval & need_pte_bits) != need_pte_bits)
66 return false;
67
68 return true;
69}
70
48/* Conversion functions: convert a page and protection to a page entry, 71/* Conversion functions: convert a page and protection to a page entry,
49 * and a page entry and page directory to the page they refer to. 72 * and a page entry and page directory to the page they refer to.
50 * 73 *
@@ -103,7 +126,7 @@ static inline pte_t pte_mkspecial(pte_t pte)
103 126
104static inline pte_t pte_mkhuge(pte_t pte) 127static inline pte_t pte_mkhuge(pte_t pte)
105{ 128{
106 return pte; 129 return __pte(pte_val(pte) | _PAGE_HUGE);
107} 130}
108 131
109static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 132static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
@@ -212,8 +235,10 @@ extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long addre
212#define pgprot_cached(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ 235#define pgprot_cached(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
213 _PAGE_COHERENT)) 236 _PAGE_COHERENT))
214 237
238#if _PAGE_WRITETHRU != 0
215#define pgprot_cached_wthru(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ 239#define pgprot_cached_wthru(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
216 _PAGE_COHERENT | _PAGE_WRITETHRU)) 240 _PAGE_COHERENT | _PAGE_WRITETHRU))
241#endif
217 242
218#define pgprot_cached_noncoherent(prot) \ 243#define pgprot_cached_noncoherent(prot) \
219 (__pgprot(pgprot_val(prot) & ~_PAGE_CACHE_CTL)) 244 (__pgprot(pgprot_val(prot) & ~_PAGE_CACHE_CTL))
diff --git a/arch/powerpc/include/asm/nohash/pte-book3e.h b/arch/powerpc/include/asm/nohash/pte-book3e.h
index 2da4532ca377..ccee8eb509bb 100644
--- a/arch/powerpc/include/asm/nohash/pte-book3e.h
+++ b/arch/powerpc/include/asm/nohash/pte-book3e.h
@@ -55,6 +55,7 @@
55#define _PAGE_KERNEL_RWX (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY | _PAGE_BAP_SX) 55#define _PAGE_KERNEL_RWX (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY | _PAGE_BAP_SX)
56#define _PAGE_KERNEL_ROX (_PAGE_BAP_SR | _PAGE_BAP_SX) 56#define _PAGE_KERNEL_ROX (_PAGE_BAP_SR | _PAGE_BAP_SX)
57#define _PAGE_USER (_PAGE_BAP_UR | _PAGE_BAP_SR) /* Can be read */ 57#define _PAGE_USER (_PAGE_BAP_UR | _PAGE_BAP_SR) /* Can be read */
58#define _PAGE_PRIVILEGED (_PAGE_BAP_SR)
58 59
59#define _PAGE_HASHPTE 0 60#define _PAGE_HASHPTE 0
60#define _PAGE_BUSY 0 61#define _PAGE_BUSY 0
diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h
index 233c7504b1f2..24c73f5575ee 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -201,7 +201,10 @@
201#define OPAL_SET_POWER_SHIFT_RATIO 155 201#define OPAL_SET_POWER_SHIFT_RATIO 155
202#define OPAL_SENSOR_GROUP_CLEAR 156 202#define OPAL_SENSOR_GROUP_CLEAR 156
203#define OPAL_PCI_SET_P2P 157 203#define OPAL_PCI_SET_P2P 157
204#define OPAL_LAST 157 204#define OPAL_NPU_SPA_SETUP 159
205#define OPAL_NPU_SPA_CLEAR_CACHE 160
206#define OPAL_NPU_TL_SET 161
207#define OPAL_LAST 161
205 208
206/* Device tree flags */ 209/* Device tree flags */
207 210
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 0c545f7fc77b..12e70fb58700 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -34,6 +34,12 @@ int64_t opal_npu_init_context(uint64_t phb_id, int pasid, uint64_t msr,
34 uint64_t bdf); 34 uint64_t bdf);
35int64_t opal_npu_map_lpar(uint64_t phb_id, uint64_t bdf, uint64_t lparid, 35int64_t opal_npu_map_lpar(uint64_t phb_id, uint64_t bdf, uint64_t lparid,
36 uint64_t lpcr); 36 uint64_t lpcr);
37int64_t opal_npu_spa_setup(uint64_t phb_id, uint32_t bdfn,
38 uint64_t addr, uint64_t PE_mask);
39int64_t opal_npu_spa_clear_cache(uint64_t phb_id, uint32_t bdfn,
40 uint64_t PE_handle);
41int64_t opal_npu_tl_set(uint64_t phb_id, uint32_t bdfn, long cap,
42 uint64_t rate_phys, uint32_t size);
37int64_t opal_console_write(int64_t term_number, __be64 *length, 43int64_t opal_console_write(int64_t term_number, __be64 *length,
38 const uint8_t *buffer); 44 const uint8_t *buffer);
39int64_t opal_console_read(int64_t term_number, __be64 *length, 45int64_t opal_console_read(int64_t term_number, __be64 *length,
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index 23ac7fc0af23..b62c31037cad 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -159,7 +159,7 @@ struct paca_struct {
159 u64 saved_r1; /* r1 save for RTAS calls or PM */ 159 u64 saved_r1; /* r1 save for RTAS calls or PM */
160 u64 saved_msr; /* MSR saved here by enter_rtas */ 160 u64 saved_msr; /* MSR saved here by enter_rtas */
161 u16 trap_save; /* Used when bad stack is encountered */ 161 u16 trap_save; /* Used when bad stack is encountered */
162 u8 soft_enabled; /* irq soft-enable flag */ 162 u8 irq_soft_mask; /* mask for irq soft masking */
163 u8 irq_happened; /* irq happened while soft-disabled */ 163 u8 irq_happened; /* irq happened while soft-disabled */
164 u8 io_sync; /* writel() needs spin_unlock sync */ 164 u8 io_sync; /* writel() needs spin_unlock sync */
165 u8 irq_work_pending; /* IRQ_WORK interrupt while soft-disable */ 165 u8 irq_work_pending; /* IRQ_WORK interrupt while soft-disable */
@@ -239,8 +239,7 @@ struct paca_struct {
239 */ 239 */
240 u64 exrfi[EX_SIZE] __aligned(0x80); 240 u64 exrfi[EX_SIZE] __aligned(0x80);
241 void *rfi_flush_fallback_area; 241 void *rfi_flush_fallback_area;
242 u64 l1d_flush_congruence; 242 u64 l1d_flush_size;
243 u64 l1d_flush_sets;
244#endif 243#endif
245}; 244};
246 245
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 62ed83db04ae..94d449031b18 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -197,25 +197,22 @@ struct pci_dn {
197 struct iommu_table_group *table_group; /* for phb's or bridges */ 197 struct iommu_table_group *table_group; /* for phb's or bridges */
198 198
199 int pci_ext_config_space; /* for pci devices */ 199 int pci_ext_config_space; /* for pci devices */
200
201 struct pci_dev *pcidev; /* back-pointer to the pci device */
202#ifdef CONFIG_EEH 200#ifdef CONFIG_EEH
203 struct eeh_dev *edev; /* eeh device */ 201 struct eeh_dev *edev; /* eeh device */
204#endif 202#endif
205#define IODA_INVALID_PE 0xFFFFFFFF 203#define IODA_INVALID_PE 0xFFFFFFFF
206#ifdef CONFIG_PPC_POWERNV
207 unsigned int pe_number; 204 unsigned int pe_number;
208 int vf_index; /* VF index in the PF */
209#ifdef CONFIG_PCI_IOV 205#ifdef CONFIG_PCI_IOV
206 int vf_index; /* VF index in the PF */
210 u16 vfs_expanded; /* number of VFs IOV BAR expanded */ 207 u16 vfs_expanded; /* number of VFs IOV BAR expanded */
211 u16 num_vfs; /* number of VFs enabled*/ 208 u16 num_vfs; /* number of VFs enabled*/
212 unsigned int *pe_num_map; /* PE# for the first VF PE or array */ 209 unsigned int *pe_num_map; /* PE# for the first VF PE or array */
213 bool m64_single_mode; /* Use M64 BAR in Single Mode */ 210 bool m64_single_mode; /* Use M64 BAR in Single Mode */
214#define IODA_INVALID_M64 (-1) 211#define IODA_INVALID_M64 (-1)
215 int (*m64_map)[PCI_SRIOV_NUM_BARS]; 212 int (*m64_map)[PCI_SRIOV_NUM_BARS]; /* Only used on powernv */
213 int last_allow_rc; /* Only used on pseries */
216#endif /* CONFIG_PCI_IOV */ 214#endif /* CONFIG_PCI_IOV */
217 int mps; /* Maximum Payload Size */ 215 int mps; /* Maximum Payload Size */
218#endif
219 struct list_head child_list; 216 struct list_head child_list;
220 struct list_head list; 217 struct list_head list;
221 struct resource holes[PCI_SRIOV_NUM_BARS]; 218 struct resource holes[PCI_SRIOV_NUM_BARS];
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index 8dc32eacc97c..d82802ff5088 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -121,6 +121,8 @@ extern int remove_phb_dynamic(struct pci_controller *phb);
121extern struct pci_dev *of_create_pci_dev(struct device_node *node, 121extern struct pci_dev *of_create_pci_dev(struct device_node *node,
122 struct pci_bus *bus, int devfn); 122 struct pci_bus *bus, int devfn);
123 123
124extern unsigned int pci_parse_of_flags(u32 addr0, int bridge);
125
124extern void of_scan_pci_bridge(struct pci_dev *dev); 126extern void of_scan_pci_bridge(struct pci_dev *dev);
125 127
126extern void of_scan_bus(struct device_node *node, struct pci_bus *bus); 128extern void of_scan_bus(struct device_node *node, struct pci_bus *bus);
diff --git a/arch/powerpc/include/asm/pkeys.h b/arch/powerpc/include/asm/pkeys.h
new file mode 100644
index 000000000000..0409c80c32c0
--- /dev/null
+++ b/arch/powerpc/include/asm/pkeys.h
@@ -0,0 +1,218 @@
1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * PowerPC Memory Protection Keys management
4 *
5 * Copyright 2017, Ram Pai, IBM Corporation.
6 */
7
8#ifndef _ASM_POWERPC_KEYS_H
9#define _ASM_POWERPC_KEYS_H
10
11#include <linux/jump_label.h>
12#include <asm/firmware.h>
13
14DECLARE_STATIC_KEY_TRUE(pkey_disabled);
15extern int pkeys_total; /* total pkeys as per device tree */
16extern u32 initial_allocation_mask; /* bits set for reserved keys */
17
18/*
19 * Define these here temporarily so we're not dependent on patching linux/mm.h.
20 * Once it's updated we can drop these.
21 */
22#ifndef VM_PKEY_BIT0
23# define VM_PKEY_SHIFT VM_HIGH_ARCH_BIT_0
24# define VM_PKEY_BIT0 VM_HIGH_ARCH_0
25# define VM_PKEY_BIT1 VM_HIGH_ARCH_1
26# define VM_PKEY_BIT2 VM_HIGH_ARCH_2
27# define VM_PKEY_BIT3 VM_HIGH_ARCH_3
28# define VM_PKEY_BIT4 VM_HIGH_ARCH_4
29#endif
30
31#define ARCH_VM_PKEY_FLAGS (VM_PKEY_BIT0 | VM_PKEY_BIT1 | VM_PKEY_BIT2 | \
32 VM_PKEY_BIT3 | VM_PKEY_BIT4)
33
34/* Override any generic PKEY permission defines */
35#define PKEY_DISABLE_EXECUTE 0x4
36#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS | \
37 PKEY_DISABLE_WRITE | \
38 PKEY_DISABLE_EXECUTE)
39
40static inline u64 pkey_to_vmflag_bits(u16 pkey)
41{
42 return (((u64)pkey << VM_PKEY_SHIFT) & ARCH_VM_PKEY_FLAGS);
43}
44
45static inline u64 vmflag_to_pte_pkey_bits(u64 vm_flags)
46{
47 if (static_branch_likely(&pkey_disabled))
48 return 0x0UL;
49
50 return (((vm_flags & VM_PKEY_BIT0) ? H_PTE_PKEY_BIT4 : 0x0UL) |
51 ((vm_flags & VM_PKEY_BIT1) ? H_PTE_PKEY_BIT3 : 0x0UL) |
52 ((vm_flags & VM_PKEY_BIT2) ? H_PTE_PKEY_BIT2 : 0x0UL) |
53 ((vm_flags & VM_PKEY_BIT3) ? H_PTE_PKEY_BIT1 : 0x0UL) |
54 ((vm_flags & VM_PKEY_BIT4) ? H_PTE_PKEY_BIT0 : 0x0UL));
55}
56
57static inline int vma_pkey(struct vm_area_struct *vma)
58{
59 if (static_branch_likely(&pkey_disabled))
60 return 0;
61 return (vma->vm_flags & ARCH_VM_PKEY_FLAGS) >> VM_PKEY_SHIFT;
62}
63
64#define arch_max_pkey() pkeys_total
65
66static inline u64 pte_to_hpte_pkey_bits(u64 pteflags)
67{
68 return (((pteflags & H_PTE_PKEY_BIT0) ? HPTE_R_KEY_BIT0 : 0x0UL) |
69 ((pteflags & H_PTE_PKEY_BIT1) ? HPTE_R_KEY_BIT1 : 0x0UL) |
70 ((pteflags & H_PTE_PKEY_BIT2) ? HPTE_R_KEY_BIT2 : 0x0UL) |
71 ((pteflags & H_PTE_PKEY_BIT3) ? HPTE_R_KEY_BIT3 : 0x0UL) |
72 ((pteflags & H_PTE_PKEY_BIT4) ? HPTE_R_KEY_BIT4 : 0x0UL));
73}
74
75static inline u16 pte_to_pkey_bits(u64 pteflags)
76{
77 return (((pteflags & H_PTE_PKEY_BIT0) ? 0x10 : 0x0UL) |
78 ((pteflags & H_PTE_PKEY_BIT1) ? 0x8 : 0x0UL) |
79 ((pteflags & H_PTE_PKEY_BIT2) ? 0x4 : 0x0UL) |
80 ((pteflags & H_PTE_PKEY_BIT3) ? 0x2 : 0x0UL) |
81 ((pteflags & H_PTE_PKEY_BIT4) ? 0x1 : 0x0UL));
82}
83
84#define pkey_alloc_mask(pkey) (0x1 << pkey)
85
86#define mm_pkey_allocation_map(mm) (mm->context.pkey_allocation_map)
87
88#define __mm_pkey_allocated(mm, pkey) { \
89 mm_pkey_allocation_map(mm) |= pkey_alloc_mask(pkey); \
90}
91
92#define __mm_pkey_free(mm, pkey) { \
93 mm_pkey_allocation_map(mm) &= ~pkey_alloc_mask(pkey); \
94}
95
96#define __mm_pkey_is_allocated(mm, pkey) \
97 (mm_pkey_allocation_map(mm) & pkey_alloc_mask(pkey))
98
99#define __mm_pkey_is_reserved(pkey) (initial_allocation_mask & \
100 pkey_alloc_mask(pkey))
101
102static inline bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey)
103{
104 /* A reserved key is never considered as 'explicitly allocated' */
105 return ((pkey < arch_max_pkey()) &&
106 !__mm_pkey_is_reserved(pkey) &&
107 __mm_pkey_is_allocated(mm, pkey));
108}
109
110extern void __arch_activate_pkey(int pkey);
111extern void __arch_deactivate_pkey(int pkey);
112/*
113 * Returns a positive, 5-bit key on success, or -1 on failure.
114 * Relies on the mmap_sem to protect against concurrency in mm_pkey_alloc() and
115 * mm_pkey_free().
116 */
117static inline int mm_pkey_alloc(struct mm_struct *mm)
118{
119 /*
120 * Note: this is the one and only place we make sure that the pkey is
121 * valid as far as the hardware is concerned. The rest of the kernel
122 * trusts that only good, valid pkeys come out of here.
123 */
124 u32 all_pkeys_mask = (u32)(~(0x0));
125 int ret;
126
127 if (static_branch_likely(&pkey_disabled))
128 return -1;
129
130 /*
131 * Are we out of pkeys? We must handle this specially because ffz()
132 * behavior is undefined if there are no zeros.
133 */
134 if (mm_pkey_allocation_map(mm) == all_pkeys_mask)
135 return -1;
136
137 ret = ffz((u32)mm_pkey_allocation_map(mm));
138 __mm_pkey_allocated(mm, ret);
139
140 /*
141 * Enable the key in the hardware
142 */
143 if (ret > 0)
144 __arch_activate_pkey(ret);
145 return ret;
146}
147
148static inline int mm_pkey_free(struct mm_struct *mm, int pkey)
149{
150 if (static_branch_likely(&pkey_disabled))
151 return -1;
152
153 if (!mm_pkey_is_allocated(mm, pkey))
154 return -EINVAL;
155
156 /*
157 * Disable the key in the hardware
158 */
159 __arch_deactivate_pkey(pkey);
160 __mm_pkey_free(mm, pkey);
161
162 return 0;
163}
164
165/*
166 * Try to dedicate one of the protection keys to be used as an
167 * execute-only protection key.
168 */
169extern int __execute_only_pkey(struct mm_struct *mm);
170static inline int execute_only_pkey(struct mm_struct *mm)
171{
172 if (static_branch_likely(&pkey_disabled))
173 return -1;
174
175 return __execute_only_pkey(mm);
176}
177
178extern int __arch_override_mprotect_pkey(struct vm_area_struct *vma,
179 int prot, int pkey);
180static inline int arch_override_mprotect_pkey(struct vm_area_struct *vma,
181 int prot, int pkey)
182{
183 if (static_branch_likely(&pkey_disabled))
184 return 0;
185
186 /*
187 * Is this an mprotect_pkey() call? If so, never override the value that
188 * came from the user.
189 */
190 if (pkey != -1)
191 return pkey;
192
193 return __arch_override_mprotect_pkey(vma, prot, pkey);
194}
195
196extern int __arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
197 unsigned long init_val);
198static inline int arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
199 unsigned long init_val)
200{
201 if (static_branch_likely(&pkey_disabled))
202 return -EINVAL;
203 return __arch_set_user_pkey_access(tsk, pkey, init_val);
204}
205
206static inline bool arch_pkeys_enabled(void)
207{
208 return !static_branch_likely(&pkey_disabled);
209}
210
211extern void pkey_mm_init(struct mm_struct *mm);
212extern bool arch_supports_pkeys(int cap);
213extern unsigned int arch_usable_pkeys(void);
214extern void thread_pkey_regs_save(struct thread_struct *thread);
215extern void thread_pkey_regs_restore(struct thread_struct *new_thread,
216 struct thread_struct *old_thread);
217extern void thread_pkey_regs_init(struct thread_struct *thread);
218#endif /*_ASM_POWERPC_KEYS_H */
diff --git a/arch/powerpc/include/asm/pnv-ocxl.h b/arch/powerpc/include/asm/pnv-ocxl.h
new file mode 100644
index 000000000000..f6945d3bc971
--- /dev/null
+++ b/arch/powerpc/include/asm/pnv-ocxl.h
@@ -0,0 +1,36 @@
1// SPDX-License-Identifier: GPL-2.0+
2// Copyright 2017 IBM Corp.
3#ifndef _ASM_PNV_OCXL_H
4#define _ASM_PNV_OCXL_H
5
6#include <linux/pci.h>
7
8#define PNV_OCXL_TL_MAX_TEMPLATE 63
9#define PNV_OCXL_TL_BITS_PER_RATE 4
10#define PNV_OCXL_TL_RATE_BUF_SIZE ((PNV_OCXL_TL_MAX_TEMPLATE+1) * PNV_OCXL_TL_BITS_PER_RATE / 8)
11
12extern int pnv_ocxl_get_actag(struct pci_dev *dev, u16 *base, u16 *enabled,
13 u16 *supported);
14extern int pnv_ocxl_get_pasid_count(struct pci_dev *dev, int *count);
15
16extern int pnv_ocxl_get_tl_cap(struct pci_dev *dev, long *cap,
17 char *rate_buf, int rate_buf_size);
18extern int pnv_ocxl_set_tl_conf(struct pci_dev *dev, long cap,
19 uint64_t rate_buf_phys, int rate_buf_size);
20
21extern int pnv_ocxl_get_xsl_irq(struct pci_dev *dev, int *hwirq);
22extern void pnv_ocxl_unmap_xsl_regs(void __iomem *dsisr, void __iomem *dar,
23 void __iomem *tfc, void __iomem *pe_handle);
24extern int pnv_ocxl_map_xsl_regs(struct pci_dev *dev, void __iomem **dsisr,
25 void __iomem **dar, void __iomem **tfc,
26 void __iomem **pe_handle);
27
28extern int pnv_ocxl_spa_setup(struct pci_dev *dev, void *spa_mem, int PE_mask,
29 void **platform_data);
30extern void pnv_ocxl_spa_release(void *platform_data);
31extern int pnv_ocxl_spa_remove_pe(void *platform_data, int pe_handle);
32
33extern int pnv_ocxl_alloc_xive_irq(u32 *irq, u64 *trigger_addr);
34extern void pnv_ocxl_free_xive_irq(u32 irq);
35
36#endif /* _ASM_PNV_OCXL_H */
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index ce0930d68857..ab5c1588b487 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -236,6 +236,7 @@
236#define PPC_INST_RFCI 0x4c000066 236#define PPC_INST_RFCI 0x4c000066
237#define PPC_INST_RFDI 0x4c00004e 237#define PPC_INST_RFDI 0x4c00004e
238#define PPC_INST_RFMCI 0x4c00004c 238#define PPC_INST_RFMCI 0x4c00004c
239#define PPC_INST_MFSPR 0x7c0002a6
239#define PPC_INST_MFSPR_DSCR 0x7c1102a6 240#define PPC_INST_MFSPR_DSCR 0x7c1102a6
240#define PPC_INST_MFSPR_DSCR_MASK 0xfc1ffffe 241#define PPC_INST_MFSPR_DSCR_MASK 0xfc1ffffe
241#define PPC_INST_MTSPR_DSCR 0x7c1103a6 242#define PPC_INST_MTSPR_DSCR 0x7c1103a6
@@ -383,6 +384,7 @@
383#define __PPC_ME64(s) __PPC_MB64(s) 384#define __PPC_ME64(s) __PPC_MB64(s)
384#define __PPC_BI(s) (((s) & 0x1f) << 16) 385#define __PPC_BI(s) (((s) & 0x1f) << 16)
385#define __PPC_CT(t) (((t) & 0x0f) << 21) 386#define __PPC_CT(t) (((t) & 0x0f) << 21)
387#define __PPC_SPR(r) ((((r) & 0x1f) << 16) | ((((r) >> 5) & 0x1f) << 11))
386 388
387/* 389/*
388 * Only use the larx hint bit on 64bit CPUs. e500v1/v2 based CPUs will treat a 390 * Only use the larx hint bit on 64bit CPUs. e500v1/v2 based CPUs will treat a
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index bdab3b74eb98..01299cdc9806 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -309,6 +309,11 @@ struct thread_struct {
309 struct thread_vr_state ckvr_state; /* Checkpointed VR state */ 309 struct thread_vr_state ckvr_state; /* Checkpointed VR state */
310 unsigned long ckvrsave; /* Checkpointed VRSAVE */ 310 unsigned long ckvrsave; /* Checkpointed VRSAVE */
311#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ 311#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
312#ifdef CONFIG_PPC_MEM_KEYS
313 unsigned long amr;
314 unsigned long iamr;
315 unsigned long uamor;
316#endif
312#ifdef CONFIG_KVM_BOOK3S_32_HANDLER 317#ifdef CONFIG_KVM_BOOK3S_32_HANDLER
313 void* kvm_shadow_vcpu; /* KVM internal data */ 318 void* kvm_shadow_vcpu; /* KVM internal data */
314#endif /* CONFIG_KVM_BOOK3S_32_HANDLER */ 319#endif /* CONFIG_KVM_BOOK3S_32_HANDLER */
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index 825bd5998701..b04c5ce8191b 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -80,21 +80,20 @@ extern void of_instantiate_rtc(void);
80 80
81extern int of_get_ibm_chip_id(struct device_node *np); 81extern int of_get_ibm_chip_id(struct device_node *np);
82 82
83/* The of_drconf_cell struct defines the layout of the LMB array 83struct of_drc_info {
84 * specified in the device tree property 84 char *drc_type;
85 * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory 85 char *drc_name_prefix;
86 */ 86 u32 drc_index_start;
87struct of_drconf_cell { 87 u32 drc_name_suffix_start;
88 u64 base_addr; 88 u32 num_sequential_elems;
89 u32 drc_index; 89 u32 sequential_inc;
90 u32 reserved; 90 u32 drc_power_domain;
91 u32 aa_index; 91 u32 last_drc_index;
92 u32 flags;
93}; 92};
94 93
95#define DRCONF_MEM_ASSIGNED 0x00000008 94extern int of_read_drc_info_cell(struct property **prop,
96#define DRCONF_MEM_AI_INVALID 0x00000040 95 const __be32 **curval, struct of_drc_info *data);
97#define DRCONF_MEM_RESERVED 0x00000080 96
98 97
99/* 98/*
100 * There are two methods for telling firmware what our capabilities are. 99 * There are two methods for telling firmware what our capabilities are.
@@ -159,6 +158,7 @@ struct of_drconf_cell {
159#define OV5_PFO_HW_842 0x1140 /* PFO Compression Accelerator */ 158#define OV5_PFO_HW_842 0x1140 /* PFO Compression Accelerator */
160#define OV5_PFO_HW_ENCR 0x1120 /* PFO Encryption Accelerator */ 159#define OV5_PFO_HW_ENCR 0x1120 /* PFO Encryption Accelerator */
161#define OV5_SUB_PROCESSORS 0x1501 /* 1,2,or 4 Sub-Processors supported */ 160#define OV5_SUB_PROCESSORS 0x1501 /* 1,2,or 4 Sub-Processors supported */
161#define OV5_DRMEM_V2 0x1680 /* ibm,dynamic-reconfiguration-v2 */
162#define OV5_XIVE_SUPPORT 0x17C0 /* XIVE Exploitation Support Mask */ 162#define OV5_XIVE_SUPPORT 0x17C0 /* XIVE Exploitation Support Mask */
163#define OV5_XIVE_LEGACY 0x1700 /* XIVE legacy mode Only */ 163#define OV5_XIVE_LEGACY 0x1700 /* XIVE legacy mode Only */
164#define OV5_XIVE_EXPLOIT 0x1740 /* XIVE exploitation mode Only */ 164#define OV5_XIVE_EXPLOIT 0x1740 /* XIVE exploitation mode Only */
@@ -175,6 +175,7 @@ struct of_drconf_cell {
175#define OV5_HASH_GTSE 0x1940 /* Guest Translation Shoot Down Avail */ 175#define OV5_HASH_GTSE 0x1940 /* Guest Translation Shoot Down Avail */
176/* Radix Table Extensions */ 176/* Radix Table Extensions */
177#define OV5_RADIX_GTSE 0x1A40 /* Guest Translation Shoot Down Avail */ 177#define OV5_RADIX_GTSE 0x1A40 /* Guest Translation Shoot Down Avail */
178#define OV5_DRC_INFO 0x1640 /* Redef Prop Structures: drc-info */
178 179
179/* Option Vector 6: IBM PAPR hints */ 180/* Option Vector 6: IBM PAPR hints */
180#define OV6_LINUX 0x02 /* Linux is our OS */ 181#define OV6_LINUX 0x02 /* Linux is our OS */
diff --git a/arch/powerpc/include/asm/pte-common.h b/arch/powerpc/include/asm/pte-common.h
index ce142ef99ba7..c4a72c7a8c83 100644
--- a/arch/powerpc/include/asm/pte-common.h
+++ b/arch/powerpc/include/asm/pte-common.h
@@ -8,9 +8,6 @@
8#ifndef _PAGE_HASHPTE 8#ifndef _PAGE_HASHPTE
9#define _PAGE_HASHPTE 0 9#define _PAGE_HASHPTE 0
10#endif 10#endif
11#ifndef _PAGE_SHARED
12#define _PAGE_SHARED 0
13#endif
14#ifndef _PAGE_HWWRITE 11#ifndef _PAGE_HWWRITE
15#define _PAGE_HWWRITE 0 12#define _PAGE_HWWRITE 0
16#endif 13#endif
@@ -45,6 +42,20 @@
45#ifndef _PAGE_PTE 42#ifndef _PAGE_PTE
46#define _PAGE_PTE 0 43#define _PAGE_PTE 0
47#endif 44#endif
45/* At least one of _PAGE_PRIVILEGED or _PAGE_USER must be defined */
46#ifndef _PAGE_PRIVILEGED
47#define _PAGE_PRIVILEGED 0
48#else
49#ifndef _PAGE_USER
50#define _PAGE_USER 0
51#endif
52#endif
53#ifndef _PAGE_NA
54#define _PAGE_NA 0
55#endif
56#ifndef _PAGE_HUGE
57#define _PAGE_HUGE 0
58#endif
48 59
49#ifndef _PMD_PRESENT_MASK 60#ifndef _PMD_PRESENT_MASK
50#define _PMD_PRESENT_MASK _PMD_PRESENT 61#define _PMD_PRESENT_MASK _PMD_PRESENT
@@ -53,17 +64,22 @@
53#define _PMD_SIZE 0 64#define _PMD_SIZE 0
54#define PMD_PAGE_SIZE(pmd) bad_call_to_PMD_PAGE_SIZE() 65#define PMD_PAGE_SIZE(pmd) bad_call_to_PMD_PAGE_SIZE()
55#endif 66#endif
67#ifndef _PMD_USER
68#define _PMD_USER 0
69#endif
56#ifndef _PAGE_KERNEL_RO 70#ifndef _PAGE_KERNEL_RO
57#define _PAGE_KERNEL_RO (_PAGE_RO) 71#define _PAGE_KERNEL_RO (_PAGE_PRIVILEGED | _PAGE_RO)
58#endif 72#endif
59#ifndef _PAGE_KERNEL_ROX 73#ifndef _PAGE_KERNEL_ROX
60#define _PAGE_KERNEL_ROX (_PAGE_EXEC | _PAGE_RO) 74#define _PAGE_KERNEL_ROX (_PAGE_PRIVILEGED | _PAGE_RO | _PAGE_EXEC)
61#endif 75#endif
62#ifndef _PAGE_KERNEL_RW 76#ifndef _PAGE_KERNEL_RW
63#define _PAGE_KERNEL_RW (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE) 77#define _PAGE_KERNEL_RW (_PAGE_PRIVILEGED | _PAGE_DIRTY | _PAGE_RW | \
78 _PAGE_HWWRITE)
64#endif 79#endif
65#ifndef _PAGE_KERNEL_RWX 80#ifndef _PAGE_KERNEL_RWX
66#define _PAGE_KERNEL_RWX (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE | _PAGE_EXEC) 81#define _PAGE_KERNEL_RWX (_PAGE_PRIVILEGED | _PAGE_DIRTY | _PAGE_RW | \
82 _PAGE_HWWRITE | _PAGE_EXEC)
67#endif 83#endif
68#ifndef _PAGE_HPTEFLAGS 84#ifndef _PAGE_HPTEFLAGS
69#define _PAGE_HPTEFLAGS _PAGE_HASHPTE 85#define _PAGE_HPTEFLAGS _PAGE_HASHPTE
@@ -85,7 +101,7 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
85 */ 101 */
86static inline bool pte_user(pte_t pte) 102static inline bool pte_user(pte_t pte)
87{ 103{
88 return (pte_val(pte) & _PAGE_USER) == _PAGE_USER; 104 return (pte_val(pte) & (_PAGE_USER | _PAGE_PRIVILEGED)) == _PAGE_USER;
89} 105}
90#endif /* __ASSEMBLY__ */ 106#endif /* __ASSEMBLY__ */
91 107
@@ -115,7 +131,8 @@ static inline bool pte_user(pte_t pte)
115/* Mask of bits returned by pte_pgprot() */ 131/* Mask of bits returned by pte_pgprot() */
116#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \ 132#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \
117 _PAGE_WRITETHRU | _PAGE_ENDIAN | _PAGE_4K_PFN | \ 133 _PAGE_WRITETHRU | _PAGE_ENDIAN | _PAGE_4K_PFN | \
118 _PAGE_USER | _PAGE_ACCESSED | _PAGE_RO | \ 134 _PAGE_USER | _PAGE_ACCESSED | _PAGE_RO | _PAGE_NA | \
135 _PAGE_PRIVILEGED | \
119 _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | _PAGE_EXEC) 136 _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | _PAGE_EXEC)
120 137
121/* 138/*
@@ -142,7 +159,7 @@ static inline bool pte_user(pte_t pte)
142 * 159 *
143 * Note due to the way vm flags are laid out, the bits are XWR 160 * Note due to the way vm flags are laid out, the bits are XWR
144 */ 161 */
145#define PAGE_NONE __pgprot(_PAGE_BASE) 162#define PAGE_NONE __pgprot(_PAGE_BASE | _PAGE_NA)
146#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW) 163#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
147#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | \ 164#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | \
148 _PAGE_EXEC) 165 _PAGE_EXEC)
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index b779f3ccd412..e6c7eadf6bce 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -312,7 +312,6 @@
312 DSISR_BAD_EXT_CTRL) 312 DSISR_BAD_EXT_CTRL)
313#define DSISR_BAD_FAULT_64S (DSISR_BAD_FAULT_32S | \ 313#define DSISR_BAD_FAULT_64S (DSISR_BAD_FAULT_32S | \
314 DSISR_ATTR_CONFLICT | \ 314 DSISR_ATTR_CONFLICT | \
315 DSISR_KEYFAULT | \
316 DSISR_UNSUPP_MMU | \ 315 DSISR_UNSUPP_MMU | \
317 DSISR_PRTABLE_FAULT | \ 316 DSISR_PRTABLE_FAULT | \
318 DSISR_ICSWX_NO_CT | \ 317 DSISR_ICSWX_NO_CT | \
@@ -432,8 +431,9 @@
432#define SPRN_LPID 0x13F /* Logical Partition Identifier */ 431#define SPRN_LPID 0x13F /* Logical Partition Identifier */
433#endif 432#endif
434#define LPID_RSVD 0x3ff /* Reserved LPID for partn switching */ 433#define LPID_RSVD 0x3ff /* Reserved LPID for partn switching */
435#define SPRN_HMER 0x150 /* Hardware m? error recovery */ 434#define SPRN_HMER 0x150 /* Hypervisor maintenance exception reg */
436#define SPRN_HMEER 0x151 /* Hardware m? enable error recovery */ 435#define HMER_DEBUG_TRIG (1ul << (63 - 17)) /* Debug trigger */
436#define SPRN_HMEER 0x151 /* Hyp maintenance exception enable reg */
437#define SPRN_PCR 0x152 /* Processor compatibility register */ 437#define SPRN_PCR 0x152 /* Processor compatibility register */
438#define PCR_VEC_DIS (1ul << (63-0)) /* Vec. disable (bit NA since POWER8) */ 438#define PCR_VEC_DIS (1ul << (63-0)) /* Vec. disable (bit NA since POWER8) */
439#define PCR_VSX_DIS (1ul << (63-1)) /* VSX disable (bit NA since POWER8) */ 439#define PCR_VSX_DIS (1ul << (63-1)) /* VSX disable (bit NA since POWER8) */
diff --git a/arch/powerpc/include/asm/reg_8xx.h b/arch/powerpc/include/asm/reg_8xx.h
index 53a7e2955d3e..7192eece6c3e 100644
--- a/arch/powerpc/include/asm/reg_8xx.h
+++ b/arch/powerpc/include/asm/reg_8xx.h
@@ -66,86 +66,4 @@
66#define DC_DFWT 0x40000000 /* Data cache is forced write through */ 66#define DC_DFWT 0x40000000 /* Data cache is forced write through */
67#define DC_LES 0x20000000 /* Caches are little endian mode */ 67#define DC_LES 0x20000000 /* Caches are little endian mode */
68 68
69#ifdef CONFIG_8xx_CPU6
70#define do_mtspr_cpu6(rn, rn_addr, v) \
71 do { \
72 int _reg_cpu6 = rn_addr, _tmp_cpu6; \
73 asm volatile("stw %0, %1;" \
74 "lwz %0, %1;" \
75 "mtspr " __stringify(rn) ",%2" : \
76 : "r" (_reg_cpu6), "m"(_tmp_cpu6), \
77 "r" ((unsigned long)(v)) \
78 : "memory"); \
79 } while (0)
80
81#define do_mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : \
82 : "r" ((unsigned long)(v)) \
83 : "memory")
84#define mtspr(rn, v) \
85 do { \
86 if (rn == SPRN_IMMR) \
87 do_mtspr_cpu6(rn, 0x3d30, v); \
88 else if (rn == SPRN_IC_CST) \
89 do_mtspr_cpu6(rn, 0x2110, v); \
90 else if (rn == SPRN_IC_ADR) \
91 do_mtspr_cpu6(rn, 0x2310, v); \
92 else if (rn == SPRN_IC_DAT) \
93 do_mtspr_cpu6(rn, 0x2510, v); \
94 else if (rn == SPRN_DC_CST) \
95 do_mtspr_cpu6(rn, 0x3110, v); \
96 else if (rn == SPRN_DC_ADR) \
97 do_mtspr_cpu6(rn, 0x3310, v); \
98 else if (rn == SPRN_DC_DAT) \
99 do_mtspr_cpu6(rn, 0x3510, v); \
100 else if (rn == SPRN_MI_CTR) \
101 do_mtspr_cpu6(rn, 0x2180, v); \
102 else if (rn == SPRN_MI_AP) \
103 do_mtspr_cpu6(rn, 0x2580, v); \
104 else if (rn == SPRN_MI_EPN) \
105 do_mtspr_cpu6(rn, 0x2780, v); \
106 else if (rn == SPRN_MI_TWC) \
107 do_mtspr_cpu6(rn, 0x2b80, v); \
108 else if (rn == SPRN_MI_RPN) \
109 do_mtspr_cpu6(rn, 0x2d80, v); \
110 else if (rn == SPRN_MI_CAM) \
111 do_mtspr_cpu6(rn, 0x2190, v); \
112 else if (rn == SPRN_MI_RAM0) \
113 do_mtspr_cpu6(rn, 0x2390, v); \
114 else if (rn == SPRN_MI_RAM1) \
115 do_mtspr_cpu6(rn, 0x2590, v); \
116 else if (rn == SPRN_MD_CTR) \
117 do_mtspr_cpu6(rn, 0x3180, v); \
118 else if (rn == SPRN_M_CASID) \
119 do_mtspr_cpu6(rn, 0x3380, v); \
120 else if (rn == SPRN_MD_AP) \
121 do_mtspr_cpu6(rn, 0x3580, v); \
122 else if (rn == SPRN_MD_EPN) \
123 do_mtspr_cpu6(rn, 0x3780, v); \
124 else if (rn == SPRN_M_TWB) \
125 do_mtspr_cpu6(rn, 0x3980, v); \
126 else if (rn == SPRN_MD_TWC) \
127 do_mtspr_cpu6(rn, 0x3b80, v); \
128 else if (rn == SPRN_MD_RPN) \
129 do_mtspr_cpu6(rn, 0x3d80, v); \
130 else if (rn == SPRN_M_TW) \
131 do_mtspr_cpu6(rn, 0x3f80, v); \
132 else if (rn == SPRN_MD_CAM) \
133 do_mtspr_cpu6(rn, 0x3190, v); \
134 else if (rn == SPRN_MD_RAM0) \
135 do_mtspr_cpu6(rn, 0x3390, v); \
136 else if (rn == SPRN_MD_RAM1) \
137 do_mtspr_cpu6(rn, 0x3590, v); \
138 else if (rn == SPRN_DEC) \
139 do_mtspr_cpu6(rn, 0x2c00, v); \
140 else if (rn == SPRN_TBWL) \
141 do_mtspr_cpu6(rn, 0x3880, v); \
142 else if (rn == SPRN_TBWU) \
143 do_mtspr_cpu6(rn, 0x3a80, v); \
144 else if (rn == SPRN_DPDR) \
145 do_mtspr_cpu6(rn, 0x2d30, v); \
146 else \
147 do_mtspr(rn, v); \
148 } while (0)
149#endif
150
151#endif /* _ASM_POWERPC_REG_8xx_H */ 69#endif /* _ASM_POWERPC_REG_8xx_H */
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index 449912f057f6..d61f9c96d916 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -389,3 +389,6 @@ COMPAT_SYS_SPU(preadv2)
389COMPAT_SYS_SPU(pwritev2) 389COMPAT_SYS_SPU(pwritev2)
390SYSCALL(kexec_file_load) 390SYSCALL(kexec_file_load)
391SYSCALL(statx) 391SYSCALL(statx)
392SYSCALL(pkey_alloc)
393SYSCALL(pkey_free)
394SYSCALL(pkey_mprotect)
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index 9ba11dbcaca9..daf1ba97a00c 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -12,14 +12,10 @@
12#include <uapi/asm/unistd.h> 12#include <uapi/asm/unistd.h>
13 13
14 14
15#define NR_syscalls 384 15#define NR_syscalls 387
16 16
17#define __NR__exit __NR_exit 17#define __NR__exit __NR_exit
18 18
19#define __IGNORE_pkey_mprotect
20#define __IGNORE_pkey_alloc
21#define __IGNORE_pkey_free
22
23#ifndef __ASSEMBLY__ 19#ifndef __ASSEMBLY__
24 20
25#include <linux/types.h> 21#include <linux/types.h>
diff --git a/arch/powerpc/include/asm/xive-regs.h b/arch/powerpc/include/asm/xive-regs.h
index 1d3f2be5ae39..fa4288822b68 100644
--- a/arch/powerpc/include/asm/xive-regs.h
+++ b/arch/powerpc/include/asm/xive-regs.h
@@ -10,6 +10,41 @@
10#define _ASM_POWERPC_XIVE_REGS_H 10#define _ASM_POWERPC_XIVE_REGS_H
11 11
12/* 12/*
13 * "magic" Event State Buffer (ESB) MMIO offsets.
14 *
15 * Each interrupt source has a 2-bit state machine called ESB
16 * which can be controlled by MMIO. It's made of 2 bits, P and
17 * Q. P indicates that an interrupt is pending (has been sent
18 * to a queue and is waiting for an EOI). Q indicates that the
19 * interrupt has been triggered while pending.
20 *
21 * This acts as a coalescing mechanism in order to guarantee
22 * that a given interrupt only occurs at most once in a queue.
23 *
24 * When doing an EOI, the Q bit will indicate if the interrupt
25 * needs to be re-triggered.
26 *
27 * The following offsets into the ESB MMIO allow to read or
28 * manipulate the PQ bits. They must be used with an 8-bytes
29 * load instruction. They all return the previous state of the
30 * interrupt (atomically).
31 *
32 * Additionally, some ESB pages support doing an EOI via a
33 * store at 0 and some ESBs support doing a trigger via a
34 * separate trigger page.
35 */
36#define XIVE_ESB_STORE_EOI 0x400 /* Store */
37#define XIVE_ESB_LOAD_EOI 0x000 /* Load */
38#define XIVE_ESB_GET 0x800 /* Load */
39#define XIVE_ESB_SET_PQ_00 0xc00 /* Load */
40#define XIVE_ESB_SET_PQ_01 0xd00 /* Load */
41#define XIVE_ESB_SET_PQ_10 0xe00 /* Load */
42#define XIVE_ESB_SET_PQ_11 0xf00 /* Load */
43
44#define XIVE_ESB_VAL_P 0x2
45#define XIVE_ESB_VAL_Q 0x1
46
47/*
13 * Thread Management (aka "TM") registers 48 * Thread Management (aka "TM") registers
14 */ 49 */
15 50
diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h
index 371fbebf1ec9..7624e22f5045 100644
--- a/arch/powerpc/include/asm/xive.h
+++ b/arch/powerpc/include/asm/xive.h
@@ -58,6 +58,9 @@ struct xive_irq_data {
58#define XIVE_IRQ_FLAG_EOI_FW 0x10 58#define XIVE_IRQ_FLAG_EOI_FW 0x10
59#define XIVE_IRQ_FLAG_H_INT_ESB 0x20 59#define XIVE_IRQ_FLAG_H_INT_ESB 0x20
60 60
61/* Special flag set by KVM for excalation interrupts */
62#define XIVE_IRQ_NO_EOI 0x80
63
61#define XIVE_INVALID_CHIP_ID -1 64#define XIVE_INVALID_CHIP_ID -1
62 65
63/* A queue tracking structure in a CPU */ 66/* A queue tracking structure in a CPU */
@@ -72,41 +75,6 @@ struct xive_q {
72 atomic_t pending_count; 75 atomic_t pending_count;
73}; 76};
74 77
75/*
76 * "magic" Event State Buffer (ESB) MMIO offsets.
77 *
78 * Each interrupt source has a 2-bit state machine called ESB
79 * which can be controlled by MMIO. It's made of 2 bits, P and
80 * Q. P indicates that an interrupt is pending (has been sent
81 * to a queue and is waiting for an EOI). Q indicates that the
82 * interrupt has been triggered while pending.
83 *
84 * This acts as a coalescing mechanism in order to guarantee
85 * that a given interrupt only occurs at most once in a queue.
86 *
87 * When doing an EOI, the Q bit will indicate if the interrupt
88 * needs to be re-triggered.
89 *
90 * The following offsets into the ESB MMIO allow to read or
91 * manipulate the PQ bits. They must be used with an 8-bytes
92 * load instruction. They all return the previous state of the
93 * interrupt (atomically).
94 *
95 * Additionally, some ESB pages support doing an EOI via a
96 * store at 0 and some ESBs support doing a trigger via a
97 * separate trigger page.
98 */
99#define XIVE_ESB_STORE_EOI 0x400 /* Store */
100#define XIVE_ESB_LOAD_EOI 0x000 /* Load */
101#define XIVE_ESB_GET 0x800 /* Load */
102#define XIVE_ESB_SET_PQ_00 0xc00 /* Load */
103#define XIVE_ESB_SET_PQ_01 0xd00 /* Load */
104#define XIVE_ESB_SET_PQ_10 0xe00 /* Load */
105#define XIVE_ESB_SET_PQ_11 0xf00 /* Load */
106
107#define XIVE_ESB_VAL_P 0x2
108#define XIVE_ESB_VAL_Q 0x1
109
110/* Global enable flags for the XIVE support */ 78/* Global enable flags for the XIVE support */
111extern bool __xive_enabled; 79extern bool __xive_enabled;
112 80
@@ -154,7 +122,7 @@ static inline bool xive_enabled(void) { return false; }
154static inline bool xive_spapr_init(void) { return false; } 122static inline bool xive_spapr_init(void) { return false; }
155static inline bool xive_native_init(void) { return false; } 123static inline bool xive_native_init(void) { return false; }
156static inline void xive_smp_probe(void) { } 124static inline void xive_smp_probe(void) { }
157extern inline int xive_smp_prepare_cpu(unsigned int cpu) { return -EINVAL; } 125static inline int xive_smp_prepare_cpu(unsigned int cpu) { return -EINVAL; }
158static inline void xive_smp_setup_cpu(void) { } 126static inline void xive_smp_setup_cpu(void) { }
159static inline void xive_smp_disable_cpu(void) { } 127static inline void xive_smp_disable_cpu(void) { }
160static inline void xive_kexec_teardown_cpu(int secondary) { } 128static inline void xive_kexec_teardown_cpu(int secondary) { }
diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h
index 5f201d40bcca..860c59291bfc 100644
--- a/arch/powerpc/include/uapi/asm/elf.h
+++ b/arch/powerpc/include/uapi/asm/elf.h
@@ -97,6 +97,7 @@
97#define ELF_NTMSPRREG 3 /* include tfhar, tfiar, texasr */ 97#define ELF_NTMSPRREG 3 /* include tfhar, tfiar, texasr */
98#define ELF_NEBB 3 /* includes ebbrr, ebbhr, bescr */ 98#define ELF_NEBB 3 /* includes ebbrr, ebbhr, bescr */
99#define ELF_NPMU 5 /* includes siar, sdar, sier, mmcr2, mmcr0 */ 99#define ELF_NPMU 5 /* includes siar, sdar, sier, mmcr2, mmcr0 */
100#define ELF_NPKEY 3 /* includes amr, iamr, uamor */
100 101
101typedef unsigned long elf_greg_t64; 102typedef unsigned long elf_greg_t64;
102typedef elf_greg_t64 elf_gregset_t64[ELF_NGREG]; 103typedef elf_greg_t64 elf_gregset_t64[ELF_NGREG];
diff --git a/arch/powerpc/include/uapi/asm/mman.h b/arch/powerpc/include/uapi/asm/mman.h
index e63bc37e33af..65065ce32814 100644
--- a/arch/powerpc/include/uapi/asm/mman.h
+++ b/arch/powerpc/include/uapi/asm/mman.h
@@ -30,4 +30,10 @@
30#define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */ 30#define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */
31#define MAP_HUGETLB 0x40000 /* create a huge page mapping */ 31#define MAP_HUGETLB 0x40000 /* create a huge page mapping */
32 32
33/* Override any generic PKEY permission defines */
34#define PKEY_DISABLE_EXECUTE 0x4
35#undef PKEY_ACCESS_MASK
36#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\
37 PKEY_DISABLE_WRITE |\
38 PKEY_DISABLE_EXECUTE)
33#endif /* _UAPI_ASM_POWERPC_MMAN_H */ 39#endif /* _UAPI_ASM_POWERPC_MMAN_H */
diff --git a/arch/powerpc/include/uapi/asm/unistd.h b/arch/powerpc/include/uapi/asm/unistd.h
index df8684f31919..389c36fd8299 100644
--- a/arch/powerpc/include/uapi/asm/unistd.h
+++ b/arch/powerpc/include/uapi/asm/unistd.h
@@ -395,5 +395,8 @@
395#define __NR_pwritev2 381 395#define __NR_pwritev2 381
396#define __NR_kexec_file_load 382 396#define __NR_kexec_file_load 382
397#define __NR_statx 383 397#define __NR_statx 383
398#define __NR_pkey_alloc 384
399#define __NR_pkey_free 385
400#define __NR_pkey_mprotect 386
398 401
399#endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ 402#endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index f390d57cf2e1..88b84ac76b53 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -178,7 +178,7 @@ int main(void)
178 OFFSET(PACATOC, paca_struct, kernel_toc); 178 OFFSET(PACATOC, paca_struct, kernel_toc);
179 OFFSET(PACAKBASE, paca_struct, kernelbase); 179 OFFSET(PACAKBASE, paca_struct, kernelbase);
180 OFFSET(PACAKMSR, paca_struct, kernel_msr); 180 OFFSET(PACAKMSR, paca_struct, kernel_msr);
181 OFFSET(PACASOFTIRQEN, paca_struct, soft_enabled); 181 OFFSET(PACAIRQSOFTMASK, paca_struct, irq_soft_mask);
182 OFFSET(PACAIRQHAPPENED, paca_struct, irq_happened); 182 OFFSET(PACAIRQHAPPENED, paca_struct, irq_happened);
183#ifdef CONFIG_PPC_BOOK3S 183#ifdef CONFIG_PPC_BOOK3S
184 OFFSET(PACACONTEXTID, paca_struct, mm_ctx_id); 184 OFFSET(PACACONTEXTID, paca_struct, mm_ctx_id);
@@ -239,8 +239,7 @@ int main(void)
239 OFFSET(PACA_IN_NMI, paca_struct, in_nmi); 239 OFFSET(PACA_IN_NMI, paca_struct, in_nmi);
240 OFFSET(PACA_RFI_FLUSH_FALLBACK_AREA, paca_struct, rfi_flush_fallback_area); 240 OFFSET(PACA_RFI_FLUSH_FALLBACK_AREA, paca_struct, rfi_flush_fallback_area);
241 OFFSET(PACA_EXRFI, paca_struct, exrfi); 241 OFFSET(PACA_EXRFI, paca_struct, exrfi);
242 OFFSET(PACA_L1D_FLUSH_CONGRUENCE, paca_struct, l1d_flush_congruence); 242 OFFSET(PACA_L1D_FLUSH_SIZE, paca_struct, l1d_flush_size);
243 OFFSET(PACA_L1D_FLUSH_SETS, paca_struct, l1d_flush_sets);
244 243
245#endif 244#endif
246 OFFSET(PACAHWCPUID, paca_struct, hw_cpu_id); 245 OFFSET(PACAHWCPUID, paca_struct, hw_cpu_id);
@@ -401,6 +400,8 @@ int main(void)
401 /* Other bits used by the vdso */ 400 /* Other bits used by the vdso */
402 DEFINE(CLOCK_REALTIME, CLOCK_REALTIME); 401 DEFINE(CLOCK_REALTIME, CLOCK_REALTIME);
403 DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC); 402 DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
403 DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE);
404 DEFINE(CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE);
404 DEFINE(NSEC_PER_SEC, NSEC_PER_SEC); 405 DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
405 DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC); 406 DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
406 407
diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S
index 679bbe714e85..3f30c994e931 100644
--- a/arch/powerpc/kernel/cpu_setup_power.S
+++ b/arch/powerpc/kernel/cpu_setup_power.S
@@ -31,7 +31,6 @@ _GLOBAL(__setup_cpu_power7)
31 mfspr r3,SPRN_LPCR 31 mfspr r3,SPRN_LPCR
32 li r4,(LPCR_LPES1 >> LPCR_LPES_SH) 32 li r4,(LPCR_LPES1 >> LPCR_LPES_SH)
33 bl __init_LPCR_ISA206 33 bl __init_LPCR_ISA206
34 bl __init_tlb_power7
35 mtlr r11 34 mtlr r11
36 blr 35 blr
37 36
@@ -45,7 +44,6 @@ _GLOBAL(__restore_cpu_power7)
45 mfspr r3,SPRN_LPCR 44 mfspr r3,SPRN_LPCR
46 li r4,(LPCR_LPES1 >> LPCR_LPES_SH) 45 li r4,(LPCR_LPES1 >> LPCR_LPES_SH)
47 bl __init_LPCR_ISA206 46 bl __init_LPCR_ISA206
48 bl __init_tlb_power7
49 mtlr r11 47 mtlr r11
50 blr 48 blr
51 49
@@ -64,7 +62,6 @@ _GLOBAL(__setup_cpu_power8)
64 li r4,0 /* LPES = 0 */ 62 li r4,0 /* LPES = 0 */
65 bl __init_LPCR_ISA206 63 bl __init_LPCR_ISA206
66 bl __init_HFSCR 64 bl __init_HFSCR
67 bl __init_tlb_power8
68 bl __init_PMU_HV 65 bl __init_PMU_HV
69 bl __init_PMU_HV_ISA207 66 bl __init_PMU_HV_ISA207
70 mtlr r11 67 mtlr r11
@@ -86,7 +83,6 @@ _GLOBAL(__restore_cpu_power8)
86 li r4,0 /* LPES = 0 */ 83 li r4,0 /* LPES = 0 */
87 bl __init_LPCR_ISA206 84 bl __init_LPCR_ISA206
88 bl __init_HFSCR 85 bl __init_HFSCR
89 bl __init_tlb_power8
90 bl __init_PMU_HV 86 bl __init_PMU_HV
91 bl __init_PMU_HV_ISA207 87 bl __init_PMU_HV_ISA207
92 mtlr r11 88 mtlr r11
@@ -111,7 +107,6 @@ _GLOBAL(__setup_cpu_power9)
111 li r4,0 /* LPES = 0 */ 107 li r4,0 /* LPES = 0 */
112 bl __init_LPCR_ISA300 108 bl __init_LPCR_ISA300
113 bl __init_HFSCR 109 bl __init_HFSCR
114 bl __init_tlb_power9
115 bl __init_PMU_HV 110 bl __init_PMU_HV
116 mtlr r11 111 mtlr r11
117 blr 112 blr
@@ -136,7 +131,6 @@ _GLOBAL(__restore_cpu_power9)
136 li r4,0 /* LPES = 0 */ 131 li r4,0 /* LPES = 0 */
137 bl __init_LPCR_ISA300 132 bl __init_LPCR_ISA300
138 bl __init_HFSCR 133 bl __init_HFSCR
139 bl __init_tlb_power9
140 bl __init_PMU_HV 134 bl __init_PMU_HV
141 mtlr r11 135 mtlr r11
142 blr 136 blr
@@ -194,50 +188,6 @@ __init_HFSCR:
194 mtspr SPRN_HFSCR,r3 188 mtspr SPRN_HFSCR,r3
195 blr 189 blr
196 190
197/*
198 * Clear the TLB using the specified IS form of tlbiel instruction
199 * (invalidate by congruence class). P7 has 128 CCs., P8 has 512.
200 */
201__init_tlb_power7:
202 li r6,POWER7_TLB_SETS
203 mtctr r6
204 li r7,0xc00 /* IS field = 0b11 */
205 ptesync
2062: tlbiel r7
207 addi r7,r7,0x1000
208 bdnz 2b
209 ptesync
2101: blr
211
212__init_tlb_power8:
213 li r6,POWER8_TLB_SETS
214 mtctr r6
215 li r7,0xc00 /* IS field = 0b11 */
216 ptesync
2172: tlbiel r7
218 addi r7,r7,0x1000
219 bdnz 2b
220 ptesync
2211: blr
222
223/*
224 * Flush the TLB in hash mode. Hash must flush with RIC=2 once for process
225 * and one for partition scope to clear process and partition table entries.
226 */
227__init_tlb_power9:
228 li r6,POWER9_TLB_SETS_HASH - 1
229 mtctr r6
230 li r7,0xc00 /* IS field = 0b11 */
231 li r8,0
232 ptesync
233 PPC_TLBIEL(7, 8, 2, 1, 0)
234 PPC_TLBIEL(7, 8, 2, 0, 0)
2352: addi r7,r7,0x1000
236 PPC_TLBIEL(7, 8, 0, 0, 0)
237 bdnz 2b
238 ptesync
2391: blr
240
241__init_PMU_HV: 191__init_PMU_HV:
242 li r5,0 192 li r5,0
243 mtspr SPRN_MMCRC,r5 193 mtspr SPRN_MMCRC,r5
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 1350f49d81a8..c40a9fc1e5d1 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -74,9 +74,6 @@ extern void __setup_cpu_power8(unsigned long offset, struct cpu_spec* spec);
74extern void __restore_cpu_power8(void); 74extern void __restore_cpu_power8(void);
75extern void __setup_cpu_power9(unsigned long offset, struct cpu_spec* spec); 75extern void __setup_cpu_power9(unsigned long offset, struct cpu_spec* spec);
76extern void __restore_cpu_power9(void); 76extern void __restore_cpu_power9(void);
77extern void __flush_tlb_power7(unsigned int action);
78extern void __flush_tlb_power8(unsigned int action);
79extern void __flush_tlb_power9(unsigned int action);
80extern long __machine_check_early_realmode_p7(struct pt_regs *regs); 77extern long __machine_check_early_realmode_p7(struct pt_regs *regs);
81extern long __machine_check_early_realmode_p8(struct pt_regs *regs); 78extern long __machine_check_early_realmode_p8(struct pt_regs *regs);
82extern long __machine_check_early_realmode_p9(struct pt_regs *regs); 79extern long __machine_check_early_realmode_p9(struct pt_regs *regs);
@@ -368,7 +365,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
368 .oprofile_cpu_type = "ppc64/ibm-compat-v1", 365 .oprofile_cpu_type = "ppc64/ibm-compat-v1",
369 .cpu_setup = __setup_cpu_power7, 366 .cpu_setup = __setup_cpu_power7,
370 .cpu_restore = __restore_cpu_power7, 367 .cpu_restore = __restore_cpu_power7,
371 .flush_tlb = __flush_tlb_power7,
372 .machine_check_early = __machine_check_early_realmode_p7, 368 .machine_check_early = __machine_check_early_realmode_p7,
373 .platform = "power7", 369 .platform = "power7",
374 }, 370 },
@@ -386,7 +382,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
386 .oprofile_cpu_type = "ppc64/ibm-compat-v1", 382 .oprofile_cpu_type = "ppc64/ibm-compat-v1",
387 .cpu_setup = __setup_cpu_power8, 383 .cpu_setup = __setup_cpu_power8,
388 .cpu_restore = __restore_cpu_power8, 384 .cpu_restore = __restore_cpu_power8,
389 .flush_tlb = __flush_tlb_power8,
390 .machine_check_early = __machine_check_early_realmode_p8, 385 .machine_check_early = __machine_check_early_realmode_p8,
391 .platform = "power8", 386 .platform = "power8",
392 }, 387 },
@@ -404,7 +399,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
404 .oprofile_cpu_type = "ppc64/ibm-compat-v1", 399 .oprofile_cpu_type = "ppc64/ibm-compat-v1",
405 .cpu_setup = __setup_cpu_power9, 400 .cpu_setup = __setup_cpu_power9,
406 .cpu_restore = __restore_cpu_power9, 401 .cpu_restore = __restore_cpu_power9,
407 .flush_tlb = __flush_tlb_power9,
408 .platform = "power9", 402 .platform = "power9",
409 }, 403 },
410 { /* Power7 */ 404 { /* Power7 */
@@ -423,7 +417,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
423 .oprofile_type = PPC_OPROFILE_POWER4, 417 .oprofile_type = PPC_OPROFILE_POWER4,
424 .cpu_setup = __setup_cpu_power7, 418 .cpu_setup = __setup_cpu_power7,
425 .cpu_restore = __restore_cpu_power7, 419 .cpu_restore = __restore_cpu_power7,
426 .flush_tlb = __flush_tlb_power7,
427 .machine_check_early = __machine_check_early_realmode_p7, 420 .machine_check_early = __machine_check_early_realmode_p7,
428 .platform = "power7", 421 .platform = "power7",
429 }, 422 },
@@ -443,7 +436,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
443 .oprofile_type = PPC_OPROFILE_POWER4, 436 .oprofile_type = PPC_OPROFILE_POWER4,
444 .cpu_setup = __setup_cpu_power7, 437 .cpu_setup = __setup_cpu_power7,
445 .cpu_restore = __restore_cpu_power7, 438 .cpu_restore = __restore_cpu_power7,
446 .flush_tlb = __flush_tlb_power7,
447 .machine_check_early = __machine_check_early_realmode_p7, 439 .machine_check_early = __machine_check_early_realmode_p7,
448 .platform = "power7+", 440 .platform = "power7+",
449 }, 441 },
@@ -463,7 +455,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
463 .oprofile_type = PPC_OPROFILE_INVALID, 455 .oprofile_type = PPC_OPROFILE_INVALID,
464 .cpu_setup = __setup_cpu_power8, 456 .cpu_setup = __setup_cpu_power8,
465 .cpu_restore = __restore_cpu_power8, 457 .cpu_restore = __restore_cpu_power8,
466 .flush_tlb = __flush_tlb_power8,
467 .machine_check_early = __machine_check_early_realmode_p8, 458 .machine_check_early = __machine_check_early_realmode_p8,
468 .platform = "power8", 459 .platform = "power8",
469 }, 460 },
@@ -483,7 +474,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
483 .oprofile_type = PPC_OPROFILE_INVALID, 474 .oprofile_type = PPC_OPROFILE_INVALID,
484 .cpu_setup = __setup_cpu_power8, 475 .cpu_setup = __setup_cpu_power8,
485 .cpu_restore = __restore_cpu_power8, 476 .cpu_restore = __restore_cpu_power8,
486 .flush_tlb = __flush_tlb_power8,
487 .machine_check_early = __machine_check_early_realmode_p8, 477 .machine_check_early = __machine_check_early_realmode_p8,
488 .platform = "power8", 478 .platform = "power8",
489 }, 479 },
@@ -503,7 +493,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
503 .oprofile_type = PPC_OPROFILE_INVALID, 493 .oprofile_type = PPC_OPROFILE_INVALID,
504 .cpu_setup = __setup_cpu_power8, 494 .cpu_setup = __setup_cpu_power8,
505 .cpu_restore = __restore_cpu_power8, 495 .cpu_restore = __restore_cpu_power8,
506 .flush_tlb = __flush_tlb_power8,
507 .machine_check_early = __machine_check_early_realmode_p8, 496 .machine_check_early = __machine_check_early_realmode_p8,
508 .platform = "power8", 497 .platform = "power8",
509 }, 498 },
@@ -523,7 +512,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
523 .oprofile_type = PPC_OPROFILE_INVALID, 512 .oprofile_type = PPC_OPROFILE_INVALID,
524 .cpu_setup = __setup_cpu_power8, 513 .cpu_setup = __setup_cpu_power8,
525 .cpu_restore = __restore_cpu_power8, 514 .cpu_restore = __restore_cpu_power8,
526 .flush_tlb = __flush_tlb_power8,
527 .machine_check_early = __machine_check_early_realmode_p8, 515 .machine_check_early = __machine_check_early_realmode_p8,
528 .platform = "power8", 516 .platform = "power8",
529 }, 517 },
@@ -543,7 +531,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
543 .oprofile_type = PPC_OPROFILE_INVALID, 531 .oprofile_type = PPC_OPROFILE_INVALID,
544 .cpu_setup = __setup_cpu_power9, 532 .cpu_setup = __setup_cpu_power9,
545 .cpu_restore = __restore_cpu_power9, 533 .cpu_restore = __restore_cpu_power9,
546 .flush_tlb = __flush_tlb_power9,
547 .machine_check_early = __machine_check_early_realmode_p9, 534 .machine_check_early = __machine_check_early_realmode_p9,
548 .platform = "power9", 535 .platform = "power9",
549 }, 536 },
@@ -563,7 +550,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
563 .oprofile_type = PPC_OPROFILE_INVALID, 550 .oprofile_type = PPC_OPROFILE_INVALID,
564 .cpu_setup = __setup_cpu_power9, 551 .cpu_setup = __setup_cpu_power9,
565 .cpu_restore = __restore_cpu_power9, 552 .cpu_restore = __restore_cpu_power9,
566 .flush_tlb = __flush_tlb_power9,
567 .machine_check_early = __machine_check_early_realmode_p9, 553 .machine_check_early = __machine_check_early_realmode_p9,
568 .platform = "power9", 554 .platform = "power9",
569 }, 555 },
@@ -583,7 +569,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
583 .oprofile_type = PPC_OPROFILE_INVALID, 569 .oprofile_type = PPC_OPROFILE_INVALID,
584 .cpu_setup = __setup_cpu_power9, 570 .cpu_setup = __setup_cpu_power9,
585 .cpu_restore = __restore_cpu_power9, 571 .cpu_restore = __restore_cpu_power9,
586 .flush_tlb = __flush_tlb_power9,
587 .machine_check_early = __machine_check_early_realmode_p9, 572 .machine_check_early = __machine_check_early_realmode_p9,
588 .platform = "power9", 573 .platform = "power9",
589 }, 574 },
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
index cbabb5adccd9..00b215125d3e 100644
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -44,6 +44,14 @@
44#define REAL_MODE_TIMEOUT 10000 44#define REAL_MODE_TIMEOUT 10000
45 45
46static int time_to_dump; 46static int time_to_dump;
47/*
48 * crash_wake_offline should be set to 1 by platforms that intend to wake
49 * up offline cpus prior to jumping to a kdump kernel. Currently powernv
50 * sets it to 1, since we want to avoid things from happening when an
51 * offline CPU wakes up due to something like an HMI (malfunction error),
52 * which propagates to all threads.
53 */
54int crash_wake_offline;
47 55
48#define CRASH_HANDLER_MAX 3 56#define CRASH_HANDLER_MAX 3
49/* List of shutdown handles */ 57/* List of shutdown handles */
@@ -63,15 +71,12 @@ static int handle_fault(struct pt_regs *regs)
63#ifdef CONFIG_SMP 71#ifdef CONFIG_SMP
64 72
65static atomic_t cpus_in_crash; 73static atomic_t cpus_in_crash;
66static void crash_ipi_callback(struct pt_regs *regs) 74void crash_ipi_callback(struct pt_regs *regs)
67{ 75{
68 static cpumask_t cpus_state_saved = CPU_MASK_NONE; 76 static cpumask_t cpus_state_saved = CPU_MASK_NONE;
69 77
70 int cpu = smp_processor_id(); 78 int cpu = smp_processor_id();
71 79
72 if (!cpu_online(cpu))
73 return;
74
75 hard_irq_disable(); 80 hard_irq_disable();
76 if (!cpumask_test_cpu(cpu, &cpus_state_saved)) { 81 if (!cpumask_test_cpu(cpu, &cpus_state_saved)) {
77 crash_save_cpu(regs, cpu); 82 crash_save_cpu(regs, cpu);
@@ -109,6 +114,9 @@ static void crash_kexec_prepare_cpus(int cpu)
109 114
110 printk(KERN_EMERG "Sending IPI to other CPUs\n"); 115 printk(KERN_EMERG "Sending IPI to other CPUs\n");
111 116
117 if (crash_wake_offline)
118 ncpus = num_present_cpus() - 1;
119
112 crash_send_ipi(crash_ipi_callback); 120 crash_send_ipi(crash_ipi_callback);
113 smp_wmb(); 121 smp_wmb();
114 122
diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c
index 8bdc2f96c5d6..945e2c29ad2d 100644
--- a/arch/powerpc/kernel/dt_cpu_ftrs.c
+++ b/arch/powerpc/kernel/dt_cpu_ftrs.c
@@ -77,8 +77,6 @@ struct dt_cpu_feature {
77 * Set up the base CPU 77 * Set up the base CPU
78 */ 78 */
79 79
80extern void __flush_tlb_power8(unsigned int action);
81extern void __flush_tlb_power9(unsigned int action);
82extern long __machine_check_early_realmode_p8(struct pt_regs *regs); 80extern long __machine_check_early_realmode_p8(struct pt_regs *regs);
83extern long __machine_check_early_realmode_p9(struct pt_regs *regs); 81extern long __machine_check_early_realmode_p9(struct pt_regs *regs);
84 82
@@ -92,27 +90,6 @@ static struct {
92 90
93static void (*init_pmu_registers)(void); 91static void (*init_pmu_registers)(void);
94 92
95static void cpufeatures_flush_tlb(void)
96{
97 /*
98 * This is a temporary measure to keep equivalent TLB flush as the
99 * cputable based setup code.
100 */
101 switch (PVR_VER(mfspr(SPRN_PVR))) {
102 case PVR_POWER8:
103 case PVR_POWER8E:
104 case PVR_POWER8NVL:
105 __flush_tlb_power8(TLB_INVAL_SCOPE_GLOBAL);
106 break;
107 case PVR_POWER9:
108 __flush_tlb_power9(TLB_INVAL_SCOPE_GLOBAL);
109 break;
110 default:
111 pr_err("unknown CPU version for boot TLB flush\n");
112 break;
113 }
114}
115
116static void __restore_cpu_cpufeatures(void) 93static void __restore_cpu_cpufeatures(void)
117{ 94{
118 /* 95 /*
@@ -137,8 +114,6 @@ static void __restore_cpu_cpufeatures(void)
137 114
138 if (init_pmu_registers) 115 if (init_pmu_registers)
139 init_pmu_registers(); 116 init_pmu_registers();
140
141 cpufeatures_flush_tlb();
142} 117}
143 118
144static char dt_cpu_name[64]; 119static char dt_cpu_name[64];
@@ -157,7 +132,6 @@ static struct cpu_spec __initdata base_cpu_spec = {
157 .oprofile_type = PPC_OPROFILE_INVALID, 132 .oprofile_type = PPC_OPROFILE_INVALID,
158 .cpu_setup = NULL, 133 .cpu_setup = NULL,
159 .cpu_restore = __restore_cpu_cpufeatures, 134 .cpu_restore = __restore_cpu_cpufeatures,
160 .flush_tlb = NULL,
161 .machine_check_early = NULL, 135 .machine_check_early = NULL,
162 .platform = NULL, 136 .platform = NULL,
163}; 137};
@@ -412,7 +386,6 @@ static void init_pmu_power8(void)
412static int __init feat_enable_mce_power8(struct dt_cpu_feature *f) 386static int __init feat_enable_mce_power8(struct dt_cpu_feature *f)
413{ 387{
414 cur_cpu_spec->platform = "power8"; 388 cur_cpu_spec->platform = "power8";
415 cur_cpu_spec->flush_tlb = __flush_tlb_power8;
416 cur_cpu_spec->machine_check_early = __machine_check_early_realmode_p8; 389 cur_cpu_spec->machine_check_early = __machine_check_early_realmode_p8;
417 390
418 return 1; 391 return 1;
@@ -451,7 +424,6 @@ static void init_pmu_power9(void)
451static int __init feat_enable_mce_power9(struct dt_cpu_feature *f) 424static int __init feat_enable_mce_power9(struct dt_cpu_feature *f)
452{ 425{
453 cur_cpu_spec->platform = "power9"; 426 cur_cpu_spec->platform = "power9";
454 cur_cpu_spec->flush_tlb = __flush_tlb_power9;
455 cur_cpu_spec->machine_check_early = __machine_check_early_realmode_p9; 427 cur_cpu_spec->machine_check_early = __machine_check_early_realmode_p9;
456 428
457 return 1; 429 return 1;
@@ -752,8 +724,6 @@ static void __init cpufeatures_setup_finished(void)
752 system_registers.hfscr = mfspr(SPRN_HFSCR); 724 system_registers.hfscr = mfspr(SPRN_HFSCR);
753 system_registers.fscr = mfspr(SPRN_FSCR); 725 system_registers.fscr = mfspr(SPRN_FSCR);
754 726
755 cpufeatures_flush_tlb();
756
757 pr_info("final cpu/mmu features = 0x%016lx 0x%08x\n", 727 pr_info("final cpu/mmu features = 0x%016lx 0x%08x\n",
758 cur_cpu_spec->cpu_features, cur_cpu_spec->mmu_features); 728 cur_cpu_spec->cpu_features, cur_cpu_spec->mmu_features);
759} 729}
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index cbca0a667682..cc649809885e 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -740,6 +740,65 @@ static void *eeh_restore_dev_state(void *data, void *userdata)
740 return NULL; 740 return NULL;
741} 741}
742 742
743int eeh_restore_vf_config(struct pci_dn *pdn)
744{
745 struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
746 u32 devctl, cmd, cap2, aer_capctl;
747 int old_mps;
748
749 if (edev->pcie_cap) {
750 /* Restore MPS */
751 old_mps = (ffs(pdn->mps) - 8) << 5;
752 eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
753 2, &devctl);
754 devctl &= ~PCI_EXP_DEVCTL_PAYLOAD;
755 devctl |= old_mps;
756 eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
757 2, devctl);
758
759 /* Disable Completion Timeout */
760 eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCAP2,
761 4, &cap2);
762 if (cap2 & 0x10) {
763 eeh_ops->read_config(pdn,
764 edev->pcie_cap + PCI_EXP_DEVCTL2,
765 4, &cap2);
766 cap2 |= 0x10;
767 eeh_ops->write_config(pdn,
768 edev->pcie_cap + PCI_EXP_DEVCTL2,
769 4, cap2);
770 }
771 }
772
773 /* Enable SERR and parity checking */
774 eeh_ops->read_config(pdn, PCI_COMMAND, 2, &cmd);
775 cmd |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
776 eeh_ops->write_config(pdn, PCI_COMMAND, 2, cmd);
777
778 /* Enable report various errors */
779 if (edev->pcie_cap) {
780 eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
781 2, &devctl);
782 devctl &= ~PCI_EXP_DEVCTL_CERE;
783 devctl |= (PCI_EXP_DEVCTL_NFERE |
784 PCI_EXP_DEVCTL_FERE |
785 PCI_EXP_DEVCTL_URRE);
786 eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
787 2, devctl);
788 }
789
790 /* Enable ECRC generation and check */
791 if (edev->pcie_cap && edev->aer_cap) {
792 eeh_ops->read_config(pdn, edev->aer_cap + PCI_ERR_CAP,
793 4, &aer_capctl);
794 aer_capctl |= (PCI_ERR_CAP_ECRC_GENE | PCI_ERR_CAP_ECRC_CHKE);
795 eeh_ops->write_config(pdn, edev->aer_cap + PCI_ERR_CAP,
796 4, aer_capctl);
797 }
798
799 return 0;
800}
801
743/** 802/**
744 * pcibios_set_pcie_reset_state - Set PCI-E reset state 803 * pcibios_set_pcie_reset_state - Set PCI-E reset state
745 * @dev: pci device struct 804 * @dev: pci device struct
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 4f71e4c9beb7..beea2182d754 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -228,6 +228,7 @@ static void *eeh_report_error(void *data, void *userdata)
228 228
229 edev->in_error = true; 229 edev->in_error = true;
230 eeh_pcid_put(dev); 230 eeh_pcid_put(dev);
231 pci_uevent_ers(dev, PCI_ERS_RESULT_NONE);
231 return NULL; 232 return NULL;
232} 233}
233 234
@@ -381,6 +382,10 @@ static void *eeh_report_resume(void *data, void *userdata)
381 driver->err_handler->resume(dev); 382 driver->err_handler->resume(dev);
382 383
383 eeh_pcid_put(dev); 384 eeh_pcid_put(dev);
385 pci_uevent_ers(dev, PCI_ERS_RESULT_RECOVERED);
386#ifdef CONFIG_PCI_IOV
387 eeh_ops->notify_resume(eeh_dev_to_pdn(edev));
388#endif
384 return NULL; 389 return NULL;
385} 390}
386 391
@@ -416,6 +421,7 @@ static void *eeh_report_failure(void *data, void *userdata)
416 driver->err_handler->error_detected(dev, pci_channel_io_perm_failure); 421 driver->err_handler->error_detected(dev, pci_channel_io_perm_failure);
417 422
418 eeh_pcid_put(dev); 423 eeh_pcid_put(dev);
424 pci_uevent_ers(dev, PCI_ERS_RESULT_DISCONNECT);
419 return NULL; 425 return NULL;
420} 426}
421 427
@@ -440,7 +446,7 @@ static void *eeh_add_virt_device(void *data, void *userdata)
440 return NULL; 446 return NULL;
441 } 447 }
442 448
443#ifdef CONFIG_PPC_POWERNV 449#ifdef CONFIG_PCI_IOV
444 pci_iov_add_virtfn(edev->physfn, pdn->vf_index); 450 pci_iov_add_virtfn(edev->physfn, pdn->vf_index);
445#endif 451#endif
446 return NULL; 452 return NULL;
@@ -496,7 +502,7 @@ static void *eeh_rmv_device(void *data, void *userdata)
496 (*removed)++; 502 (*removed)++;
497 503
498 if (edev->physfn) { 504 if (edev->physfn) {
499#ifdef CONFIG_PPC_POWERNV 505#ifdef CONFIG_PCI_IOV
500 struct pci_dn *pdn = eeh_dev_to_pdn(edev); 506 struct pci_dn *pdn = eeh_dev_to_pdn(edev);
501 507
502 pci_iov_remove_virtfn(edev->physfn, pdn->vf_index); 508 pci_iov_remove_virtfn(edev->physfn, pdn->vf_index);
diff --git a/arch/powerpc/kernel/eeh_sysfs.c b/arch/powerpc/kernel/eeh_sysfs.c
index 797549289798..deed906dd8f1 100644
--- a/arch/powerpc/kernel/eeh_sysfs.c
+++ b/arch/powerpc/kernel/eeh_sysfs.c
@@ -48,7 +48,7 @@ static ssize_t eeh_show_##_name(struct device *dev, \
48 \ 48 \
49 return sprintf(buf, _format "\n", edev->_memb); \ 49 return sprintf(buf, _format "\n", edev->_memb); \
50} \ 50} \
51static DEVICE_ATTR(_name, S_IRUGO, eeh_show_##_name, NULL); 51static DEVICE_ATTR(_name, 0444, eeh_show_##_name, NULL);
52 52
53EEH_SHOW_ATTR(eeh_mode, mode, "0x%x"); 53EEH_SHOW_ATTR(eeh_mode, mode, "0x%x");
54EEH_SHOW_ATTR(eeh_pe_config_addr, pe_config_addr, "0x%x"); 54EEH_SHOW_ATTR(eeh_pe_config_addr, pe_config_addr, "0x%x");
@@ -90,6 +90,65 @@ static ssize_t eeh_pe_state_store(struct device *dev,
90 90
91static DEVICE_ATTR_RW(eeh_pe_state); 91static DEVICE_ATTR_RW(eeh_pe_state);
92 92
93#ifdef CONFIG_PCI_IOV
94static ssize_t eeh_notify_resume_show(struct device *dev,
95 struct device_attribute *attr, char *buf)
96{
97 struct pci_dev *pdev = to_pci_dev(dev);
98 struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev);
99 struct pci_dn *pdn = pci_get_pdn(pdev);
100
101 if (!edev || !edev->pe)
102 return -ENODEV;
103
104 pdn = pci_get_pdn(pdev);
105 return sprintf(buf, "%d\n", pdn->last_allow_rc);
106}
107
108static ssize_t eeh_notify_resume_store(struct device *dev,
109 struct device_attribute *attr,
110 const char *buf, size_t count)
111{
112 struct pci_dev *pdev = to_pci_dev(dev);
113 struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev);
114
115 if (!edev || !edev->pe || !eeh_ops->notify_resume)
116 return -ENODEV;
117
118 if (eeh_ops->notify_resume(pci_get_pdn(pdev)))
119 return -EIO;
120
121 return count;
122}
123static DEVICE_ATTR_RW(eeh_notify_resume);
124
125static int eeh_notify_resume_add(struct pci_dev *pdev)
126{
127 struct device_node *np;
128 int rc = 0;
129
130 np = pci_device_to_OF_node(pdev->is_physfn ? pdev : pdev->physfn);
131
132 if (of_property_read_bool(np, "ibm,is-open-sriov-pf"))
133 rc = device_create_file(&pdev->dev, &dev_attr_eeh_notify_resume);
134
135 return rc;
136}
137
138static void eeh_notify_resume_remove(struct pci_dev *pdev)
139{
140 struct device_node *np;
141
142 np = pci_device_to_OF_node(pdev->is_physfn ? pdev : pdev->physfn);
143
144 if (of_property_read_bool(np, "ibm,is-open-sriov-pf"))
145 device_remove_file(&pdev->dev, &dev_attr_eeh_notify_resume);
146}
147#else
148static inline int eeh_notify_resume_add(struct pci_dev *pdev) { return 0; }
149static inline void eeh_notify_resume_remove(struct pci_dev *pdev) { }
150#endif /* CONFIG_PCI_IOV */
151
93void eeh_sysfs_add_device(struct pci_dev *pdev) 152void eeh_sysfs_add_device(struct pci_dev *pdev)
94{ 153{
95 struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev); 154 struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev);
@@ -104,6 +163,7 @@ void eeh_sysfs_add_device(struct pci_dev *pdev)
104 rc += device_create_file(&pdev->dev, &dev_attr_eeh_mode); 163 rc += device_create_file(&pdev->dev, &dev_attr_eeh_mode);
105 rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_config_addr); 164 rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_config_addr);
106 rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_state); 165 rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_state);
166 rc += eeh_notify_resume_add(pdev);
107 167
108 if (rc) 168 if (rc)
109 pr_warn("EEH: Unable to create sysfs entries\n"); 169 pr_warn("EEH: Unable to create sysfs entries\n");
@@ -129,6 +189,8 @@ void eeh_sysfs_remove_device(struct pci_dev *pdev)
129 device_remove_file(&pdev->dev, &dev_attr_eeh_pe_config_addr); 189 device_remove_file(&pdev->dev, &dev_attr_eeh_pe_config_addr);
130 device_remove_file(&pdev->dev, &dev_attr_eeh_pe_state); 190 device_remove_file(&pdev->dev, &dev_attr_eeh_pe_state);
131 191
192 eeh_notify_resume_remove(pdev);
193
132 if (edev) 194 if (edev)
133 edev->mode &= ~EEH_DEV_SYSFS; 195 edev->mode &= ~EEH_DEV_SYSFS;
134} 196}
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index e780e1fbf6c2..eb8d01bae8c6 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -211,7 +211,7 @@ transfer_to_handler_cont:
211 mflr r9 211 mflr r9
212 lwz r11,0(r9) /* virtual address of handler */ 212 lwz r11,0(r9) /* virtual address of handler */
213 lwz r9,4(r9) /* where to go when done */ 213 lwz r9,4(r9) /* where to go when done */
214#ifdef CONFIG_PPC_8xx_PERF_EVENT 214#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
215 mtspr SPRN_NRI, r0 215 mtspr SPRN_NRI, r0
216#endif 216#endif
217#ifdef CONFIG_TRACE_IRQFLAGS 217#ifdef CONFIG_TRACE_IRQFLAGS
@@ -301,7 +301,7 @@ stack_ovf:
301 lis r9,StackOverflow@ha 301 lis r9,StackOverflow@ha
302 addi r9,r9,StackOverflow@l 302 addi r9,r9,StackOverflow@l
303 LOAD_MSR_KERNEL(r10,MSR_KERNEL) 303 LOAD_MSR_KERNEL(r10,MSR_KERNEL)
304#ifdef CONFIG_PPC_8xx_PERF_EVENT 304#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
305 mtspr SPRN_NRI, r0 305 mtspr SPRN_NRI, r0
306#endif 306#endif
307 mtspr SPRN_SRR0,r9 307 mtspr SPRN_SRR0,r9
@@ -430,7 +430,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
430 lwz r7,_NIP(r1) 430 lwz r7,_NIP(r1)
431 lwz r2,GPR2(r1) 431 lwz r2,GPR2(r1)
432 lwz r1,GPR1(r1) 432 lwz r1,GPR1(r1)
433#ifdef CONFIG_PPC_8xx_PERF_EVENT 433#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
434 mtspr SPRN_NRI, r0 434 mtspr SPRN_NRI, r0
435#endif 435#endif
436 mtspr SPRN_SRR0,r7 436 mtspr SPRN_SRR0,r7
@@ -727,7 +727,7 @@ fast_exception_return:
727 lwz r10,_LINK(r11) 727 lwz r10,_LINK(r11)
728 mtlr r10 728 mtlr r10
729 REST_GPR(10, r11) 729 REST_GPR(10, r11)
730#ifdef CONFIG_PPC_8xx_PERF_EVENT 730#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
731 mtspr SPRN_NRI, r0 731 mtspr SPRN_NRI, r0
732#endif 732#endif
733 mtspr SPRN_SRR1,r9 733 mtspr SPRN_SRR1,r9
@@ -978,7 +978,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
978 .globl exc_exit_restart 978 .globl exc_exit_restart
979exc_exit_restart: 979exc_exit_restart:
980 lwz r12,_NIP(r1) 980 lwz r12,_NIP(r1)
981#ifdef CONFIG_PPC_8xx_PERF_EVENT 981#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
982 mtspr SPRN_NRI, r0 982 mtspr SPRN_NRI, r0
983#endif 983#endif
984 mtspr SPRN_SRR0,r12 984 mtspr SPRN_SRR0,r12
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 2748584b767d..2cb5109a7ea3 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -133,10 +133,9 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
133 * of irq tracing is used, we additionally check that condition 133 * of irq tracing is used, we additionally check that condition
134 * is correct 134 * is correct
135 */ 135 */
136#if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_BUG) 136#if defined(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG) && defined(CONFIG_BUG)
137 lbz r10,PACASOFTIRQEN(r13) 137 lbz r10,PACAIRQSOFTMASK(r13)
138 xori r10,r10,1 1381: tdnei r10,IRQS_ENABLED
1391: tdnei r10,0
140 EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,BUGFLAG_WARNING 139 EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,BUGFLAG_WARNING
141#endif 140#endif
142 141
@@ -152,7 +151,7 @@ system_call: /* label this so stack traces look sane */
152 /* We do need to set SOFTE in the stack frame or the return 151 /* We do need to set SOFTE in the stack frame or the return
153 * from interrupt will be painful 152 * from interrupt will be painful
154 */ 153 */
155 li r10,1 154 li r10,IRQS_ENABLED
156 std r10,SOFTE(r1) 155 std r10,SOFTE(r1)
157 156
158 CURRENT_THREAD_INFO(r11, r1) 157 CURRENT_THREAD_INFO(r11, r1)
@@ -755,10 +754,10 @@ resume_kernel:
755 beq+ restore 754 beq+ restore
756 /* Check that preempt_count() == 0 and interrupts are enabled */ 755 /* Check that preempt_count() == 0 and interrupts are enabled */
757 lwz r8,TI_PREEMPT(r9) 756 lwz r8,TI_PREEMPT(r9)
758 cmpwi cr1,r8,0 757 cmpwi cr0,r8,0
758 bne restore
759 ld r0,SOFTE(r1) 759 ld r0,SOFTE(r1)
760 cmpdi r0,0 760 andi. r0,r0,IRQS_DISABLED
761 crandc eq,cr1*4+eq,eq
762 bne restore 761 bne restore
763 762
764 /* 763 /*
@@ -796,12 +795,12 @@ restore:
796 * are about to re-enable interrupts 795 * are about to re-enable interrupts
797 */ 796 */
798 ld r5,SOFTE(r1) 797 ld r5,SOFTE(r1)
799 lbz r6,PACASOFTIRQEN(r13) 798 lbz r6,PACAIRQSOFTMASK(r13)
800 cmpwi cr0,r5,0 799 andi. r5,r5,IRQS_DISABLED
801 beq .Lrestore_irq_off 800 bne .Lrestore_irq_off
802 801
803 /* We are enabling, were we already enabled ? Yes, just return */ 802 /* We are enabling, were we already enabled ? Yes, just return */
804 cmpwi cr0,r6,1 803 andi. r6,r6,IRQS_DISABLED
805 beq cr0,.Ldo_restore 804 beq cr0,.Ldo_restore
806 805
807 /* 806 /*
@@ -820,8 +819,8 @@ restore:
820 */ 819 */
821.Lrestore_no_replay: 820.Lrestore_no_replay:
822 TRACE_ENABLE_INTS 821 TRACE_ENABLE_INTS
823 li r0,1 822 li r0,IRQS_ENABLED
824 stb r0,PACASOFTIRQEN(r13); 823 stb r0,PACAIRQSOFTMASK(r13);
825 824
826 /* 825 /*
827 * Final return path. BookE is handled in a different file 826 * Final return path. BookE is handled in a different file
@@ -939,9 +938,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
939 beq 1f 938 beq 1f
940 rlwinm r7,r7,0,~PACA_IRQ_HARD_DIS 939 rlwinm r7,r7,0,~PACA_IRQ_HARD_DIS
941 stb r7,PACAIRQHAPPENED(r13) 940 stb r7,PACAIRQHAPPENED(r13)
9421: li r0,0 9411:
943 stb r0,PACASOFTIRQEN(r13); 942#if defined(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG) && defined(CONFIG_BUG)
944 TRACE_DISABLE_INTS 943 /* The interrupt should not have soft enabled. */
944 lbz r7,PACAIRQSOFTMASK(r13)
9451: tdeqi r7,IRQS_ENABLED
946 EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,BUGFLAG_WARNING
947#endif
945 b .Ldo_restore 948 b .Ldo_restore
946 949
947 /* 950 /*
@@ -979,6 +982,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
979 addi r3,r1,STACK_FRAME_OVERHEAD; 982 addi r3,r1,STACK_FRAME_OVERHEAD;
980 bl do_IRQ 983 bl do_IRQ
981 b ret_from_except 984 b ret_from_except
9851: cmpwi cr0,r3,0xf00
986 bne 1f
987 addi r3,r1,STACK_FRAME_OVERHEAD;
988 bl performance_monitor_exception
989 b ret_from_except
9821: cmpwi cr0,r3,0xe60 9901: cmpwi cr0,r3,0xe60
983 bne 1f 991 bne 1f
984 addi r3,r1,STACK_FRAME_OVERHEAD; 992 addi r3,r1,STACK_FRAME_OVERHEAD;
@@ -1055,15 +1063,15 @@ _GLOBAL(enter_rtas)
1055 li r0,0 1063 li r0,0
1056 mtcr r0 1064 mtcr r0
1057 1065
1058#ifdef CONFIG_BUG 1066#ifdef CONFIG_BUG
1059 /* There is no way it is acceptable to get here with interrupts enabled, 1067 /* There is no way it is acceptable to get here with interrupts enabled,
1060 * check it with the asm equivalent of WARN_ON 1068 * check it with the asm equivalent of WARN_ON
1061 */ 1069 */
1062 lbz r0,PACASOFTIRQEN(r13) 1070 lbz r0,PACAIRQSOFTMASK(r13)
10631: tdnei r0,0 10711: tdeqi r0,IRQS_ENABLED
1064 EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,BUGFLAG_WARNING 1072 EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,BUGFLAG_WARNING
1065#endif 1073#endif
1066 1074
1067 /* Hard-disable interrupts */ 1075 /* Hard-disable interrupts */
1068 mfmsr r6 1076 mfmsr r6
1069 rldicl r7,r6,48,1 1077 rldicl r7,r6,48,1
@@ -1107,6 +1115,17 @@ __enter_rtas:
1107rtas_return_loc: 1115rtas_return_loc:
1108 FIXUP_ENDIAN 1116 FIXUP_ENDIAN
1109 1117
1118 /*
1119 * Clear RI and set SF before anything.
1120 */
1121 mfmsr r6
1122 li r0,MSR_RI
1123 andc r6,r6,r0
1124 sldi r0,r0,(MSR_SF_LG - MSR_RI_LG)
1125 or r6,r6,r0
1126 sync
1127 mtmsrd r6
1128
1110 /* relocation is off at this point */ 1129 /* relocation is off at this point */
1111 GET_PACA(r4) 1130 GET_PACA(r4)
1112 clrldi r4,r4,2 /* convert to realmode address */ 1131 clrldi r4,r4,2 /* convert to realmode address */
@@ -1115,12 +1134,6 @@ rtas_return_loc:
11150: mflr r3 11340: mflr r3
1116 ld r3,(1f-0b)(r3) /* get &rtas_restore_regs */ 1135 ld r3,(1f-0b)(r3) /* get &rtas_restore_regs */
1117 1136
1118 mfmsr r6
1119 li r0,MSR_RI
1120 andc r6,r6,r0
1121 sync
1122 mtmsrd r6
1123
1124 ld r1,PACAR1(r4) /* Restore our SP */ 1137 ld r1,PACAR1(r4) /* Restore our SP */
1125 ld r4,PACASAVEDMSR(r4) /* Restore our MSR */ 1138 ld r4,PACASAVEDMSR(r4) /* Restore our MSR */
1126 1139
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index acd8ca76233e..ee832d344a5a 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -139,7 +139,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
139 mfspr r10,SPRN_ESR 139 mfspr r10,SPRN_ESR
140 SPECIAL_EXC_STORE(r10,ESR) 140 SPECIAL_EXC_STORE(r10,ESR)
141 141
142 lbz r10,PACASOFTIRQEN(r13) 142 lbz r10,PACAIRQSOFTMASK(r13)
143 SPECIAL_EXC_STORE(r10,SOFTE) 143 SPECIAL_EXC_STORE(r10,SOFTE)
144 ld r10,_NIP(r1) 144 ld r10,_NIP(r1)
145 SPECIAL_EXC_STORE(r10,CSRR0) 145 SPECIAL_EXC_STORE(r10,CSRR0)
@@ -206,17 +206,17 @@ BEGIN_FTR_SECTION
206 mtspr SPRN_MAS8,r10 206 mtspr SPRN_MAS8,r10
207END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV) 207END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
208 208
209 lbz r6,PACASOFTIRQEN(r13) 209 lbz r6,PACAIRQSOFTMASK(r13)
210 ld r5,SOFTE(r1) 210 ld r5,SOFTE(r1)
211 211
212 /* Interrupts had better not already be enabled... */ 212 /* Interrupts had better not already be enabled... */
213 twnei r6,0 213 tweqi r6,IRQS_ENABLED
214 214
215 cmpwi cr0,r5,0 215 andi. r6,r5,IRQS_DISABLED
216 beq 1f 216 bne 1f
217 217
218 TRACE_ENABLE_INTS 218 TRACE_ENABLE_INTS
219 stb r5,PACASOFTIRQEN(r13) 219 stb r5,PACAIRQSOFTMASK(r13)
2201: 2201:
221 /* 221 /*
222 * Restore PACAIRQHAPPENED rather than setting it based on 222 * Restore PACAIRQHAPPENED rather than setting it based on
@@ -351,9 +351,9 @@ ret_from_mc_except:
351#define PROLOG_ADDITION_NONE_MC(n) 351#define PROLOG_ADDITION_NONE_MC(n)
352 352
353#define PROLOG_ADDITION_MASKABLE_GEN(n) \ 353#define PROLOG_ADDITION_MASKABLE_GEN(n) \
354 lbz r10,PACASOFTIRQEN(r13); /* are irqs soft-disabled ? */ \ 354 lbz r10,PACAIRQSOFTMASK(r13); /* are irqs soft-masked? */ \
355 cmpwi cr0,r10,0; /* yes -> go out of line */ \ 355 andi. r10,r10,IRQS_DISABLED; /* yes -> go out of line */ \
356 beq masked_interrupt_book3e_##n 356 bne masked_interrupt_book3e_##n
357 357
358#define PROLOG_ADDITION_2REGS_GEN(n) \ 358#define PROLOG_ADDITION_2REGS_GEN(n) \
359 std r14,PACA_EXGEN+EX_R14(r13); \ 359 std r14,PACA_EXGEN+EX_R14(r13); \
@@ -397,7 +397,7 @@ exc_##n##_common: \
397 mfspr r8,SPRN_XER; /* save XER in stackframe */ \ 397 mfspr r8,SPRN_XER; /* save XER in stackframe */ \
398 ld r9,excf+EX_R1(r13); /* load orig r1 back from PACA */ \ 398 ld r9,excf+EX_R1(r13); /* load orig r1 back from PACA */ \
399 lwz r10,excf+EX_CR(r13); /* load orig CR back from PACA */ \ 399 lwz r10,excf+EX_CR(r13); /* load orig CR back from PACA */ \
400 lbz r11,PACASOFTIRQEN(r13); /* get current IRQ softe */ \ 400 lbz r11,PACAIRQSOFTMASK(r13); /* get current IRQ softe */ \
401 ld r12,exception_marker@toc(r2); \ 401 ld r12,exception_marker@toc(r2); \
402 li r0,0; \ 402 li r0,0; \
403 std r3,GPR10(r1); /* save r10 to stackframe */ \ 403 std r3,GPR10(r1); /* save r10 to stackframe */ \
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 2dc10bf646b8..243d072a225a 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -718,10 +718,12 @@ EXC_REAL_BEGIN(hardware_interrupt, 0x500, 0x100)
718hardware_interrupt_hv: 718hardware_interrupt_hv:
719 BEGIN_FTR_SECTION 719 BEGIN_FTR_SECTION
720 _MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt_common, 720 _MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt_common,
721 EXC_HV, SOFTEN_TEST_HV) 721 EXC_HV, SOFTEN_TEST_HV,
722 IRQS_DISABLED)
722 FTR_SECTION_ELSE 723 FTR_SECTION_ELSE
723 _MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt_common, 724 _MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt_common,
724 EXC_STD, SOFTEN_TEST_PR) 725 EXC_STD, SOFTEN_TEST_PR,
726 IRQS_DISABLED)
725 ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) 727 ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
726EXC_REAL_END(hardware_interrupt, 0x500, 0x100) 728EXC_REAL_END(hardware_interrupt, 0x500, 0x100)
727 729
@@ -729,9 +731,13 @@ EXC_VIRT_BEGIN(hardware_interrupt, 0x4500, 0x100)
729 .globl hardware_interrupt_relon_hv; 731 .globl hardware_interrupt_relon_hv;
730hardware_interrupt_relon_hv: 732hardware_interrupt_relon_hv:
731 BEGIN_FTR_SECTION 733 BEGIN_FTR_SECTION
732 _MASKABLE_RELON_EXCEPTION_PSERIES(0x500, hardware_interrupt_common, EXC_HV, SOFTEN_TEST_HV) 734 _MASKABLE_RELON_EXCEPTION_PSERIES(0x500, hardware_interrupt_common,
735 EXC_HV, SOFTEN_TEST_HV,
736 IRQS_DISABLED)
733 FTR_SECTION_ELSE 737 FTR_SECTION_ELSE
734 _MASKABLE_RELON_EXCEPTION_PSERIES(0x500, hardware_interrupt_common, EXC_STD, SOFTEN_TEST_PR) 738 _MASKABLE_RELON_EXCEPTION_PSERIES(0x500, hardware_interrupt_common,
739 EXC_STD, SOFTEN_TEST_PR,
740 IRQS_DISABLED)
735 ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) 741 ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
736EXC_VIRT_END(hardware_interrupt, 0x4500, 0x100) 742EXC_VIRT_END(hardware_interrupt, 0x4500, 0x100)
737 743
@@ -827,8 +833,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
827#endif 833#endif
828 834
829 835
830EXC_REAL_MASKABLE(decrementer, 0x900, 0x80) 836EXC_REAL_MASKABLE(decrementer, 0x900, 0x80, IRQS_DISABLED)
831EXC_VIRT_MASKABLE(decrementer, 0x4900, 0x80, 0x900) 837EXC_VIRT_MASKABLE(decrementer, 0x4900, 0x80, 0x900, IRQS_DISABLED)
832TRAMP_KVM(PACA_EXGEN, 0x900) 838TRAMP_KVM(PACA_EXGEN, 0x900)
833EXC_COMMON_ASYNC(decrementer_common, 0x900, timer_interrupt) 839EXC_COMMON_ASYNC(decrementer_common, 0x900, timer_interrupt)
834 840
@@ -839,8 +845,8 @@ TRAMP_KVM_HV(PACA_EXGEN, 0x980)
839EXC_COMMON(hdecrementer_common, 0x980, hdec_interrupt) 845EXC_COMMON(hdecrementer_common, 0x980, hdec_interrupt)
840 846
841 847
842EXC_REAL_MASKABLE(doorbell_super, 0xa00, 0x100) 848EXC_REAL_MASKABLE(doorbell_super, 0xa00, 0x100, IRQS_DISABLED)
843EXC_VIRT_MASKABLE(doorbell_super, 0x4a00, 0x100, 0xa00) 849EXC_VIRT_MASKABLE(doorbell_super, 0x4a00, 0x100, 0xa00, IRQS_DISABLED)
844TRAMP_KVM(PACA_EXGEN, 0xa00) 850TRAMP_KVM(PACA_EXGEN, 0xa00)
845#ifdef CONFIG_PPC_DOORBELL 851#ifdef CONFIG_PPC_DOORBELL
846EXC_COMMON_ASYNC(doorbell_super_common, 0xa00, doorbell_exception) 852EXC_COMMON_ASYNC(doorbell_super_common, 0xa00, doorbell_exception)
@@ -1052,7 +1058,7 @@ EXC_COMMON(emulation_assist_common, 0xe40, emulation_assist_interrupt)
1052 * mode. 1058 * mode.
1053 */ 1059 */
1054__EXC_REAL_OOL_HV_DIRECT(hmi_exception, 0xe60, 0x20, hmi_exception_early) 1060__EXC_REAL_OOL_HV_DIRECT(hmi_exception, 0xe60, 0x20, hmi_exception_early)
1055__TRAMP_REAL_OOL_MASKABLE_HV(hmi_exception, 0xe60) 1061__TRAMP_REAL_OOL_MASKABLE_HV(hmi_exception, 0xe60, IRQS_DISABLED)
1056EXC_VIRT_NONE(0x4e60, 0x20) 1062EXC_VIRT_NONE(0x4e60, 0x20)
1057TRAMP_KVM_HV(PACA_EXGEN, 0xe60) 1063TRAMP_KVM_HV(PACA_EXGEN, 0xe60)
1058TRAMP_REAL_BEGIN(hmi_exception_early) 1064TRAMP_REAL_BEGIN(hmi_exception_early)
@@ -1110,8 +1116,8 @@ EXC_COMMON_BEGIN(hmi_exception_common)
1110EXCEPTION_COMMON(PACA_EXGEN, 0xe60, hmi_exception_common, handle_hmi_exception, 1116EXCEPTION_COMMON(PACA_EXGEN, 0xe60, hmi_exception_common, handle_hmi_exception,
1111 ret_from_except, FINISH_NAP;ADD_NVGPRS;ADD_RECONCILE;RUNLATCH_ON) 1117 ret_from_except, FINISH_NAP;ADD_NVGPRS;ADD_RECONCILE;RUNLATCH_ON)
1112 1118
1113EXC_REAL_OOL_MASKABLE_HV(h_doorbell, 0xe80, 0x20) 1119EXC_REAL_OOL_MASKABLE_HV(h_doorbell, 0xe80, 0x20, IRQS_DISABLED)
1114EXC_VIRT_OOL_MASKABLE_HV(h_doorbell, 0x4e80, 0x20, 0xe80) 1120EXC_VIRT_OOL_MASKABLE_HV(h_doorbell, 0x4e80, 0x20, 0xe80, IRQS_DISABLED)
1115TRAMP_KVM_HV(PACA_EXGEN, 0xe80) 1121TRAMP_KVM_HV(PACA_EXGEN, 0xe80)
1116#ifdef CONFIG_PPC_DOORBELL 1122#ifdef CONFIG_PPC_DOORBELL
1117EXC_COMMON_ASYNC(h_doorbell_common, 0xe80, doorbell_exception) 1123EXC_COMMON_ASYNC(h_doorbell_common, 0xe80, doorbell_exception)
@@ -1120,8 +1126,8 @@ EXC_COMMON_ASYNC(h_doorbell_common, 0xe80, unknown_exception)
1120#endif 1126#endif
1121 1127
1122 1128
1123EXC_REAL_OOL_MASKABLE_HV(h_virt_irq, 0xea0, 0x20) 1129EXC_REAL_OOL_MASKABLE_HV(h_virt_irq, 0xea0, 0x20, IRQS_DISABLED)
1124EXC_VIRT_OOL_MASKABLE_HV(h_virt_irq, 0x4ea0, 0x20, 0xea0) 1130EXC_VIRT_OOL_MASKABLE_HV(h_virt_irq, 0x4ea0, 0x20, 0xea0, IRQS_DISABLED)
1125TRAMP_KVM_HV(PACA_EXGEN, 0xea0) 1131TRAMP_KVM_HV(PACA_EXGEN, 0xea0)
1126EXC_COMMON_ASYNC(h_virt_irq_common, 0xea0, do_IRQ) 1132EXC_COMMON_ASYNC(h_virt_irq_common, 0xea0, do_IRQ)
1127 1133
@@ -1132,8 +1138,8 @@ EXC_REAL_NONE(0xee0, 0x20)
1132EXC_VIRT_NONE(0x4ee0, 0x20) 1138EXC_VIRT_NONE(0x4ee0, 0x20)
1133 1139
1134 1140
1135EXC_REAL_OOL(performance_monitor, 0xf00, 0x20) 1141EXC_REAL_OOL_MASKABLE(performance_monitor, 0xf00, 0x20, IRQS_PMI_DISABLED)
1136EXC_VIRT_OOL(performance_monitor, 0x4f00, 0x20, 0xf00) 1142EXC_VIRT_OOL_MASKABLE(performance_monitor, 0x4f00, 0x20, 0xf00, IRQS_PMI_DISABLED)
1137TRAMP_KVM(PACA_EXGEN, 0xf00) 1143TRAMP_KVM(PACA_EXGEN, 0xf00)
1138EXC_COMMON_ASYNC(performance_monitor_common, 0xf00, performance_monitor_exception) 1144EXC_COMMON_ASYNC(performance_monitor_common, 0xf00, performance_monitor_exception)
1139 1145
@@ -1345,7 +1351,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
1345 b . 1351 b .
1346#endif 1352#endif
1347 1353
1348EXC_COMMON_HV(denorm_common, 0x1500, unknown_exception) 1354EXC_COMMON(denorm_common, 0x1500, unknown_exception)
1349 1355
1350 1356
1351#ifdef CONFIG_CBE_RAS 1357#ifdef CONFIG_CBE_RAS
@@ -1455,39 +1461,37 @@ TRAMP_REAL_BEGIN(rfi_flush_fallback)
1455 std r9,PACA_EXRFI+EX_R9(r13) 1461 std r9,PACA_EXRFI+EX_R9(r13)
1456 std r10,PACA_EXRFI+EX_R10(r13) 1462 std r10,PACA_EXRFI+EX_R10(r13)
1457 std r11,PACA_EXRFI+EX_R11(r13) 1463 std r11,PACA_EXRFI+EX_R11(r13)
1458 std r12,PACA_EXRFI+EX_R12(r13)
1459 std r8,PACA_EXRFI+EX_R13(r13)
1460 mfctr r9 1464 mfctr r9
1461 ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13) 1465 ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13)
1462 ld r11,PACA_L1D_FLUSH_SETS(r13) 1466 ld r11,PACA_L1D_FLUSH_SIZE(r13)
1463 ld r12,PACA_L1D_FLUSH_CONGRUENCE(r13) 1467 srdi r11,r11,(7 + 3) /* 128 byte lines, unrolled 8x */
1464 /*
1465 * The load adresses are at staggered offsets within cachelines,
1466 * which suits some pipelines better (on others it should not
1467 * hurt).
1468 */
1469 addi r12,r12,8
1470 mtctr r11 1468 mtctr r11
1471 DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */ 1469 DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */
1472 1470
1473 /* order ld/st prior to dcbt stop all streams with flushing */ 1471 /* order ld/st prior to dcbt stop all streams with flushing */
1474 sync 1472 sync
14751: li r8,0 1473
1476 .rept 8 /* 8-way set associative */ 1474 /*
1477 ldx r11,r10,r8 1475 * The load adresses are at staggered offsets within cachelines,
1478 add r8,r8,r12 1476 * which suits some pipelines better (on others it should not
1479 xor r11,r11,r11 // Ensure r11 is 0 even if fallback area is not 1477 * hurt).
1480 add r8,r8,r11 // Add 0, this creates a dependency on the ldx 1478 */
1481 .endr 14791:
1482 addi r10,r10,128 /* 128 byte cache line */ 1480 ld r11,(0x80 + 8)*0(r10)
1481 ld r11,(0x80 + 8)*1(r10)
1482 ld r11,(0x80 + 8)*2(r10)
1483 ld r11,(0x80 + 8)*3(r10)
1484 ld r11,(0x80 + 8)*4(r10)
1485 ld r11,(0x80 + 8)*5(r10)
1486 ld r11,(0x80 + 8)*6(r10)
1487 ld r11,(0x80 + 8)*7(r10)
1488 addi r10,r10,0x80*8
1483 bdnz 1b 1489 bdnz 1b
1484 1490
1485 mtctr r9 1491 mtctr r9
1486 ld r9,PACA_EXRFI+EX_R9(r13) 1492 ld r9,PACA_EXRFI+EX_R9(r13)
1487 ld r10,PACA_EXRFI+EX_R10(r13) 1493 ld r10,PACA_EXRFI+EX_R10(r13)
1488 ld r11,PACA_EXRFI+EX_R11(r13) 1494 ld r11,PACA_EXRFI+EX_R11(r13)
1489 ld r12,PACA_EXRFI+EX_R12(r13)
1490 ld r8,PACA_EXRFI+EX_R13(r13)
1491 GET_SCRATCH0(r13); 1495 GET_SCRATCH0(r13);
1492 rfid 1496 rfid
1493 1497
@@ -1497,39 +1501,37 @@ TRAMP_REAL_BEGIN(hrfi_flush_fallback)
1497 std r9,PACA_EXRFI+EX_R9(r13) 1501 std r9,PACA_EXRFI+EX_R9(r13)
1498 std r10,PACA_EXRFI+EX_R10(r13) 1502 std r10,PACA_EXRFI+EX_R10(r13)
1499 std r11,PACA_EXRFI+EX_R11(r13) 1503 std r11,PACA_EXRFI+EX_R11(r13)
1500 std r12,PACA_EXRFI+EX_R12(r13)
1501 std r8,PACA_EXRFI+EX_R13(r13)
1502 mfctr r9 1504 mfctr r9
1503 ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13) 1505 ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13)
1504 ld r11,PACA_L1D_FLUSH_SETS(r13) 1506 ld r11,PACA_L1D_FLUSH_SIZE(r13)
1505 ld r12,PACA_L1D_FLUSH_CONGRUENCE(r13) 1507 srdi r11,r11,(7 + 3) /* 128 byte lines, unrolled 8x */
1506 /*
1507 * The load adresses are at staggered offsets within cachelines,
1508 * which suits some pipelines better (on others it should not
1509 * hurt).
1510 */
1511 addi r12,r12,8
1512 mtctr r11 1508 mtctr r11
1513 DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */ 1509 DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */
1514 1510
1515 /* order ld/st prior to dcbt stop all streams with flushing */ 1511 /* order ld/st prior to dcbt stop all streams with flushing */
1516 sync 1512 sync
15171: li r8,0 1513
1518 .rept 8 /* 8-way set associative */ 1514 /*
1519 ldx r11,r10,r8 1515 * The load adresses are at staggered offsets within cachelines,
1520 add r8,r8,r12 1516 * which suits some pipelines better (on others it should not
1521 xor r11,r11,r11 // Ensure r11 is 0 even if fallback area is not 1517 * hurt).
1522 add r8,r8,r11 // Add 0, this creates a dependency on the ldx 1518 */
1523 .endr 15191:
1524 addi r10,r10,128 /* 128 byte cache line */ 1520 ld r11,(0x80 + 8)*0(r10)
1521 ld r11,(0x80 + 8)*1(r10)
1522 ld r11,(0x80 + 8)*2(r10)
1523 ld r11,(0x80 + 8)*3(r10)
1524 ld r11,(0x80 + 8)*4(r10)
1525 ld r11,(0x80 + 8)*5(r10)
1526 ld r11,(0x80 + 8)*6(r10)
1527 ld r11,(0x80 + 8)*7(r10)
1528 addi r10,r10,0x80*8
1525 bdnz 1b 1529 bdnz 1b
1526 1530
1527 mtctr r9 1531 mtctr r9
1528 ld r9,PACA_EXRFI+EX_R9(r13) 1532 ld r9,PACA_EXRFI+EX_R9(r13)
1529 ld r10,PACA_EXRFI+EX_R10(r13) 1533 ld r10,PACA_EXRFI+EX_R10(r13)
1530 ld r11,PACA_EXRFI+EX_R11(r13) 1534 ld r11,PACA_EXRFI+EX_R11(r13)
1531 ld r12,PACA_EXRFI+EX_R12(r13)
1532 ld r8,PACA_EXRFI+EX_R13(r13)
1533 GET_SCRATCH0(r13); 1535 GET_SCRATCH0(r13);
1534 hrfid 1536 hrfid
1535 1537
@@ -1632,7 +1634,7 @@ USE_TEXT_SECTION()
1632 .balign IFETCH_ALIGN_BYTES 1634 .balign IFETCH_ALIGN_BYTES
1633do_hash_page: 1635do_hash_page:
1634#ifdef CONFIG_PPC_BOOK3S_64 1636#ifdef CONFIG_PPC_BOOK3S_64
1635 lis r0,(DSISR_BAD_FAULT_64S|DSISR_DABRMATCH)@h 1637 lis r0,(DSISR_BAD_FAULT_64S | DSISR_DABRMATCH | DSISR_KEYFAULT)@h
1636 ori r0,r0,DSISR_BAD_FAULT_64S@l 1638 ori r0,r0,DSISR_BAD_FAULT_64S@l
1637 and. r0,r4,r0 /* weird error? */ 1639 and. r0,r4,r0 /* weird error? */
1638 bne- handle_page_fault /* if not, try to insert a HPTE */ 1640 bne- handle_page_fault /* if not, try to insert a HPTE */
@@ -1828,6 +1830,8 @@ BEGIN_FTR_SECTION
1828FTR_SECTION_ELSE 1830FTR_SECTION_ELSE
1829 beq hardware_interrupt_common 1831 beq hardware_interrupt_common
1830ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_300) 1832ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_300)
1833 cmpwi r3,0xf00
1834 beq performance_monitor_common
1831BEGIN_FTR_SECTION 1835BEGIN_FTR_SECTION
1832 cmpwi r3,0xa00 1836 cmpwi r3,0xa00
1833 beq h_doorbell_common_msgclr 1837 beq h_doorbell_common_msgclr
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index aa71a90f5222..a61151a6ea5e 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -765,8 +765,8 @@ _GLOBAL(pmac_secondary_start)
765 /* Mark interrupts soft and hard disabled (they might be enabled 765 /* Mark interrupts soft and hard disabled (they might be enabled
766 * in the PACA when doing hotplug) 766 * in the PACA when doing hotplug)
767 */ 767 */
768 li r0,0 768 li r0,IRQS_DISABLED
769 stb r0,PACASOFTIRQEN(r13) 769 stb r0,PACAIRQSOFTMASK(r13)
770 li r0,PACA_IRQ_HARD_DIS 770 li r0,PACA_IRQ_HARD_DIS
771 stb r0,PACAIRQHAPPENED(r13) 771 stb r0,PACAIRQHAPPENED(r13)
772 772
@@ -822,7 +822,8 @@ __secondary_start:
822 /* Mark interrupts soft and hard disabled (they might be enabled 822 /* Mark interrupts soft and hard disabled (they might be enabled
823 * in the PACA when doing hotplug) 823 * in the PACA when doing hotplug)
824 */ 824 */
825 stb r7,PACASOFTIRQEN(r13) 825 li r7,IRQS_DISABLED
826 stb r7,PACAIRQSOFTMASK(r13)
826 li r0,PACA_IRQ_HARD_DIS 827 li r0,PACA_IRQ_HARD_DIS
827 stb r0,PACAIRQHAPPENED(r13) 828 stb r0,PACAIRQHAPPENED(r13)
828 829
@@ -988,8 +989,8 @@ start_here_common:
988 /* Mark interrupts soft and hard disabled (they might be enabled 989 /* Mark interrupts soft and hard disabled (they might be enabled
989 * in the PACA when doing hotplug) 990 * in the PACA when doing hotplug)
990 */ 991 */
991 li r0,0 992 li r0,IRQS_DISABLED
992 stb r0,PACASOFTIRQEN(r13) 993 stb r0,PACAIRQSOFTMASK(r13)
993 li r0,PACA_IRQ_HARD_DIS 994 li r0,PACA_IRQ_HARD_DIS
994 stb r0,PACAIRQHAPPENED(r13) 995 stb r0,PACAIRQHAPPENED(r13)
995 996
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 4fee00d414e8..d8670a37d70c 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -33,23 +33,6 @@
33#include <asm/fixmap.h> 33#include <asm/fixmap.h>
34#include <asm/export.h> 34#include <asm/export.h>
35 35
36/* Macro to make the code more readable. */
37#ifdef CONFIG_8xx_CPU6
38#define SPRN_MI_TWC_ADDR 0x2b80
39#define SPRN_MI_RPN_ADDR 0x2d80
40#define SPRN_MD_TWC_ADDR 0x3b80
41#define SPRN_MD_RPN_ADDR 0x3d80
42
43#define MTSPR_CPU6(spr, reg, treg) \
44 li treg, spr##_ADDR; \
45 stw treg, 12(r0); \
46 lwz treg, 12(r0); \
47 mtspr spr, reg
48#else
49#define MTSPR_CPU6(spr, reg, treg) \
50 mtspr spr, reg
51#endif
52
53#if CONFIG_TASK_SIZE <= 0x80000000 && CONFIG_PAGE_OFFSET >= 0x80000000 36#if CONFIG_TASK_SIZE <= 0x80000000 && CONFIG_PAGE_OFFSET >= 0x80000000
54/* By simply checking Address >= 0x80000000, we know if its a kernel address */ 37/* By simply checking Address >= 0x80000000, we know if its a kernel address */
55#define SIMPLE_KERNEL_ADDRESS 1 38#define SIMPLE_KERNEL_ADDRESS 1
@@ -69,11 +52,7 @@
69 * Value for the bits that have fixed value in RPN entries. 52 * Value for the bits that have fixed value in RPN entries.
70 * Also used for tagging DAR for DTLBerror. 53 * Also used for tagging DAR for DTLBerror.
71 */ 54 */
72#ifdef CONFIG_PPC_16K_PAGES
73#define RPN_PATTERN (0x00f0 | MD_SPS16K)
74#else
75#define RPN_PATTERN 0x00f0 55#define RPN_PATTERN 0x00f0
76#endif
77 56
78#define PAGE_SHIFT_512K 19 57#define PAGE_SHIFT_512K 19
79#define PAGE_SHIFT_8M 23 58#define PAGE_SHIFT_8M 23
@@ -134,15 +113,12 @@ turn_on_mmu:
134 * task's thread_struct. 113 * task's thread_struct.
135 */ 114 */
136#define EXCEPTION_PROLOG \ 115#define EXCEPTION_PROLOG \
137 EXCEPTION_PROLOG_0; \ 116 mtspr SPRN_SPRG_SCRATCH0, r10; \
117 mtspr SPRN_SPRG_SCRATCH1, r11; \
138 mfcr r10; \ 118 mfcr r10; \
139 EXCEPTION_PROLOG_1; \ 119 EXCEPTION_PROLOG_1; \
140 EXCEPTION_PROLOG_2 120 EXCEPTION_PROLOG_2
141 121
142#define EXCEPTION_PROLOG_0 \
143 mtspr SPRN_SPRG_SCRATCH0,r10; \
144 mtspr SPRN_SPRG_SCRATCH1,r11
145
146#define EXCEPTION_PROLOG_1 \ 122#define EXCEPTION_PROLOG_1 \
147 mfspr r11,SPRN_SRR1; /* check whether user or kernel */ \ 123 mfspr r11,SPRN_SRR1; /* check whether user or kernel */ \
148 andi. r11,r11,MSR_PR; \ 124 andi. r11,r11,MSR_PR; \
@@ -177,13 +153,6 @@ turn_on_mmu:
177 SAVE_2GPRS(7, r11) 153 SAVE_2GPRS(7, r11)
178 154
179/* 155/*
180 * Exception exit code.
181 */
182#define EXCEPTION_EPILOG_0 \
183 mfspr r10,SPRN_SPRG_SCRATCH0; \
184 mfspr r11,SPRN_SPRG_SCRATCH1
185
186/*
187 * Note: code which follows this uses cr0.eq (set if from kernel), 156 * Note: code which follows this uses cr0.eq (set if from kernel),
188 * r11, r12 (SRR0), and r9 (SRR1). 157 * r11, r12 (SRR0), and r9 (SRR1).
189 * 158 *
@@ -326,15 +295,10 @@ SystemCall:
326#endif 295#endif
327 296
328InstructionTLBMiss: 297InstructionTLBMiss:
329#if defined(CONFIG_8xx_CPU6) || defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE) 298 mtspr SPRN_SPRG_SCRATCH0, r10
330 mtspr SPRN_SPRG_SCRATCH2, r3 299 mtspr SPRN_SPRG_SCRATCH1, r11
331#endif 300#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE)
332 EXCEPTION_PROLOG_0 301 mtspr SPRN_SPRG_SCRATCH2, r12
333#ifdef CONFIG_PPC_8xx_PERF_EVENT
334 lis r10, (itlb_miss_counter - PAGE_OFFSET)@ha
335 lwz r11, (itlb_miss_counter - PAGE_OFFSET)@l(r10)
336 addi r11, r11, 1
337 stw r11, (itlb_miss_counter - PAGE_OFFSET)@l(r10)
338#endif 302#endif
339 303
340 /* If we are faulting a kernel address, we have to use the 304 /* If we are faulting a kernel address, we have to use the
@@ -345,7 +309,7 @@ InstructionTLBMiss:
345 /* Only modules will cause ITLB Misses as we always 309 /* Only modules will cause ITLB Misses as we always
346 * pin the first 8MB of kernel memory */ 310 * pin the first 8MB of kernel memory */
347#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE) 311#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE)
348 mfcr r3 312 mfcr r12
349#endif 313#endif
350#ifdef ITLB_MISS_KERNEL 314#ifdef ITLB_MISS_KERNEL
351#if defined(SIMPLE_KERNEL_ADDRESS) && defined(CONFIG_PIN_TLB_TEXT) 315#if defined(SIMPLE_KERNEL_ADDRESS) && defined(CONFIG_PIN_TLB_TEXT)
@@ -388,40 +352,46 @@ _ENTRY(ITLBMiss_cmp)
388 lwz r10, 0(r10) /* Get the pte */ 352 lwz r10, 0(r10) /* Get the pte */
3894: 3534:
390#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE) 354#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE)
391 mtcr r3 355 mtcr r12
392#endif 356#endif
393 /* Insert the APG into the TWC from the Linux PTE. */
394 rlwimi r11, r10, 0, 25, 26
395 /* Load the MI_TWC with the attributes for this "segment." */
396 MTSPR_CPU6(SPRN_MI_TWC, r11, r3) /* Set segment attributes */
397 357
398#if defined (CONFIG_HUGETLB_PAGE) && defined (CONFIG_PPC_4K_PAGES)
399 rlwimi r10, r11, 1, MI_SPS16K
400#endif
401#ifdef CONFIG_SWAP 358#ifdef CONFIG_SWAP
402 rlwinm r11, r10, 32-5, _PAGE_PRESENT 359 rlwinm r11, r10, 31, _PAGE_ACCESSED >> 1
403 and r11, r11, r10
404 rlwimi r10, r11, 0, _PAGE_PRESENT
405#endif 360#endif
406 li r11, RPN_PATTERN 361 /* Load the MI_TWC with the attributes for this "segment." */
362 mtspr SPRN_MI_TWC, r11 /* Set segment attributes */
363
364 li r11, RPN_PATTERN | 0x200
407 /* The Linux PTE won't go exactly into the MMU TLB. 365 /* The Linux PTE won't go exactly into the MMU TLB.
408 * Software indicator bits 20-23 and 28 must be clear. 366 * Software indicator bits 20 and 23 must be clear.
409 * Software indicator bits 24, 25, 26, and 27 must be 367 * Software indicator bits 22, 24, 25, 26, and 27 must be
410 * set. All other Linux PTE bits control the behavior 368 * set. All other Linux PTE bits control the behavior
411 * of the MMU. 369 * of the MMU.
412 */ 370 */
413#if defined (CONFIG_HUGETLB_PAGE) && defined (CONFIG_PPC_4K_PAGES) 371 rlwimi r11, r10, 4, 0x0400 /* Copy _PAGE_EXEC into bit 21 */
414 rlwimi r10, r11, 0, 0x0ff0 /* Set 24-27, clear 20-23 */ 372 rlwimi r10, r11, 0, 0x0ff0 /* Set 22, 24-27, clear 20,23 */
415#else 373 mtspr SPRN_MI_RPN, r10 /* Update TLB entry */
416 rlwimi r10, r11, 0, 0x0ff8 /* Set 24-27, clear 20-23,28 */
417#endif
418 MTSPR_CPU6(SPRN_MI_RPN, r10, r3) /* Update TLB entry */
419 374
420 /* Restore registers */ 375 /* Restore registers */
421#if defined(CONFIG_8xx_CPU6) || defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE) 376_ENTRY(itlb_miss_exit_1)
422 mfspr r3, SPRN_SPRG_SCRATCH2 377 mfspr r10, SPRN_SPRG_SCRATCH0
378 mfspr r11, SPRN_SPRG_SCRATCH1
379#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE)
380 mfspr r12, SPRN_SPRG_SCRATCH2
381#endif
382 rfi
383#ifdef CONFIG_PERF_EVENTS
384_ENTRY(itlb_miss_perf)
385 lis r10, (itlb_miss_counter - PAGE_OFFSET)@ha
386 lwz r11, (itlb_miss_counter - PAGE_OFFSET)@l(r10)
387 addi r11, r11, 1
388 stw r11, (itlb_miss_counter - PAGE_OFFSET)@l(r10)
389#endif
390 mfspr r10, SPRN_SPRG_SCRATCH0
391 mfspr r11, SPRN_SPRG_SCRATCH1
392#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE)
393 mfspr r12, SPRN_SPRG_SCRATCH2
423#endif 394#endif
424 EXCEPTION_EPILOG_0
425 rfi 395 rfi
426 396
427#ifdef CONFIG_HUGETLB_PAGE 397#ifdef CONFIG_HUGETLB_PAGE
@@ -436,7 +406,6 @@ _ENTRY(ITLBMiss_cmp)
436 rlwinm r10, r11, 0, ~HUGEPD_SHIFT_MASK 406 rlwinm r10, r11, 0, ~HUGEPD_SHIFT_MASK
437#endif 407#endif
438 lwz r10, 0(r10) /* Get the pte */ 408 lwz r10, 0(r10) /* Get the pte */
439 rlwinm r11, r11, 0, 0xf
440 b 4b 409 b 4b
441 410
44220: /* 512k pages */ 41120: /* 512k pages */
@@ -445,21 +414,15 @@ _ENTRY(ITLBMiss_cmp)
445 /* Add level 2 base */ 414 /* Add level 2 base */
446 rlwimi r10, r11, 0, 0, 32 + PAGE_SHIFT_512K - (PAGE_SHIFT << 1) - 1 415 rlwimi r10, r11, 0, 0, 32 + PAGE_SHIFT_512K - (PAGE_SHIFT << 1) - 1
447 lwz r10, 0(r10) /* Get the pte */ 416 lwz r10, 0(r10) /* Get the pte */
448 rlwinm r11, r11, 0, 0xf
449 b 4b 417 b 4b
450#endif 418#endif
451 419
452 . = 0x1200 420 . = 0x1200
453DataStoreTLBMiss: 421DataStoreTLBMiss:
454 mtspr SPRN_SPRG_SCRATCH2, r3 422 mtspr SPRN_SPRG_SCRATCH0, r10
455 EXCEPTION_PROLOG_0 423 mtspr SPRN_SPRG_SCRATCH1, r11
456#ifdef CONFIG_PPC_8xx_PERF_EVENT 424 mtspr SPRN_SPRG_SCRATCH2, r12
457 lis r10, (dtlb_miss_counter - PAGE_OFFSET)@ha 425 mfcr r12
458 lwz r11, (dtlb_miss_counter - PAGE_OFFSET)@l(r10)
459 addi r11, r11, 1
460 stw r11, (dtlb_miss_counter - PAGE_OFFSET)@l(r10)
461#endif
462 mfcr r3
463 426
464 /* If we are faulting a kernel address, we have to use the 427 /* If we are faulting a kernel address, we have to use the
465 * kernel page tables. 428 * kernel page tables.
@@ -499,59 +462,49 @@ _ENTRY(DTLBMiss_jmp)
499 rlwimi r10, r11, 0, 0, 32 - PAGE_SHIFT - 1 /* Add level 2 base */ 462 rlwimi r10, r11, 0, 0, 32 - PAGE_SHIFT - 1 /* Add level 2 base */
500 lwz r10, 0(r10) /* Get the pte */ 463 lwz r10, 0(r10) /* Get the pte */
5014: 4644:
502 mtcr r3 465 mtcr r12
503 466
504 /* Insert the Guarded flag and APG into the TWC from the Linux PTE. 467 /* Insert the Guarded flag into the TWC from the Linux PTE.
505 * It is bit 26-27 of both the Linux PTE and the TWC (at least 468 * It is bit 27 of both the Linux PTE and the TWC (at least
506 * I got that right :-). It will be better when we can put 469 * I got that right :-). It will be better when we can put
507 * this into the Linux pgd/pmd and load it in the operation 470 * this into the Linux pgd/pmd and load it in the operation
508 * above. 471 * above.
509 */ 472 */
510 rlwimi r11, r10, 0, 26, 27 473 rlwimi r11, r10, 0, _PAGE_GUARDED
511 /* Insert the WriteThru flag into the TWC from the Linux PTE.
512 * It is bit 25 in the Linux PTE and bit 30 in the TWC
513 */
514 rlwimi r11, r10, 32-5, 30, 30
515 MTSPR_CPU6(SPRN_MD_TWC, r11, r3)
516
517 /* In 4k pages mode, SPS (bit 28) in RPN must match PS[1] (bit 29)
518 * In 16k pages mode, SPS is always 1 */
519#if defined (CONFIG_HUGETLB_PAGE) && defined (CONFIG_PPC_4K_PAGES)
520 rlwimi r10, r11, 1, MD_SPS16K
521#endif
522 /* Both _PAGE_ACCESSED and _PAGE_PRESENT has to be set.
523 * We also need to know if the insn is a load/store, so:
524 * Clear _PAGE_PRESENT and load that which will
525 * trap into DTLB Error with store bit set accordinly.
526 */
527 /* PRESENT=0x1, ACCESSED=0x20
528 * r11 = ((r10 & PRESENT) & ((r10 & ACCESSED) >> 5));
529 * r10 = (r10 & ~PRESENT) | r11;
530 */
531#ifdef CONFIG_SWAP 474#ifdef CONFIG_SWAP
532 rlwinm r11, r10, 32-5, _PAGE_PRESENT 475 /* _PAGE_ACCESSED has to be set. We use second APG bit for that, 0
533 and r11, r11, r10 476 * on that bit will represent a Non Access group
534 rlwimi r10, r11, 0, _PAGE_PRESENT 477 */
478 rlwinm r11, r10, 31, _PAGE_ACCESSED >> 1
535#endif 479#endif
480 mtspr SPRN_MD_TWC, r11
481
536 /* The Linux PTE won't go exactly into the MMU TLB. 482 /* The Linux PTE won't go exactly into the MMU TLB.
537 * Software indicator bits 22 and 28 must be clear.
538 * Software indicator bits 24, 25, 26, and 27 must be 483 * Software indicator bits 24, 25, 26, and 27 must be
539 * set. All other Linux PTE bits control the behavior 484 * set. All other Linux PTE bits control the behavior
540 * of the MMU. 485 * of the MMU.
541 */ 486 */
542 li r11, RPN_PATTERN 487 li r11, RPN_PATTERN
543#if defined (CONFIG_HUGETLB_PAGE) && defined (CONFIG_PPC_4K_PAGES)
544 rlwimi r10, r11, 0, 24, 27 /* Set 24-27 */ 488 rlwimi r10, r11, 0, 24, 27 /* Set 24-27 */
545#else 489 mtspr SPRN_MD_RPN, r10 /* Update TLB entry */
546 rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */
547#endif
548 rlwimi r10, r11, 0, 20, 20 /* clear 20 */
549 MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */
550 490
551 /* Restore registers */ 491 /* Restore registers */
552 mfspr r3, SPRN_SPRG_SCRATCH2
553 mtspr SPRN_DAR, r11 /* Tag DAR */ 492 mtspr SPRN_DAR, r11 /* Tag DAR */
554 EXCEPTION_EPILOG_0 493_ENTRY(dtlb_miss_exit_1)
494 mfspr r10, SPRN_SPRG_SCRATCH0
495 mfspr r11, SPRN_SPRG_SCRATCH1
496 mfspr r12, SPRN_SPRG_SCRATCH2
497 rfi
498#ifdef CONFIG_PERF_EVENTS
499_ENTRY(dtlb_miss_perf)
500 lis r10, (dtlb_miss_counter - PAGE_OFFSET)@ha
501 lwz r11, (dtlb_miss_counter - PAGE_OFFSET)@l(r10)
502 addi r11, r11, 1
503 stw r11, (dtlb_miss_counter - PAGE_OFFSET)@l(r10)
504#endif
505 mfspr r10, SPRN_SPRG_SCRATCH0
506 mfspr r11, SPRN_SPRG_SCRATCH1
507 mfspr r12, SPRN_SPRG_SCRATCH2
555 rfi 508 rfi
556 509
557#ifdef CONFIG_HUGETLB_PAGE 510#ifdef CONFIG_HUGETLB_PAGE
@@ -566,7 +519,6 @@ _ENTRY(DTLBMiss_jmp)
566 rlwinm r10, r11, 0, ~HUGEPD_SHIFT_MASK 519 rlwinm r10, r11, 0, ~HUGEPD_SHIFT_MASK
567#endif 520#endif
568 lwz r10, 0(r10) /* Get the pte */ 521 lwz r10, 0(r10) /* Get the pte */
569 rlwinm r11, r11, 0, 0xf
570 b 4b 522 b 4b
571 523
57220: /* 512k pages */ 52420: /* 512k pages */
@@ -575,7 +527,6 @@ _ENTRY(DTLBMiss_jmp)
575 /* Add level 2 base */ 527 /* Add level 2 base */
576 rlwimi r10, r11, 0, 0, 32 + PAGE_SHIFT_512K - (PAGE_SHIFT << 1) - 1 528 rlwimi r10, r11, 0, 0, 32 + PAGE_SHIFT_512K - (PAGE_SHIFT << 1) - 1
577 lwz r10, 0(r10) /* Get the pte */ 529 lwz r10, 0(r10) /* Get the pte */
578 rlwinm r11, r11, 0, 0xf
579 b 4b 530 b 4b
580#endif 531#endif
581 532
@@ -601,7 +552,8 @@ itlbie:
601 */ 552 */
602 . = 0x1400 553 . = 0x1400
603DataTLBError: 554DataTLBError:
604 EXCEPTION_PROLOG_0 555 mtspr SPRN_SPRG_SCRATCH0, r10
556 mtspr SPRN_SPRG_SCRATCH1, r11
605 mfcr r10 557 mfcr r10
606 558
607 mfspr r11, SPRN_DAR 559 mfspr r11, SPRN_DAR
@@ -636,7 +588,8 @@ dtlbie:
636 */ 588 */
637 . = 0x1c00 589 . = 0x1c00
638DataBreakpoint: 590DataBreakpoint:
639 EXCEPTION_PROLOG_0 591 mtspr SPRN_SPRG_SCRATCH0, r10
592 mtspr SPRN_SPRG_SCRATCH1, r11
640 mfcr r10 593 mfcr r10
641 mfspr r11, SPRN_SRR0 594 mfspr r11, SPRN_SRR0
642 cmplwi cr0, r11, (dtlbie - PAGE_OFFSET)@l 595 cmplwi cr0, r11, (dtlbie - PAGE_OFFSET)@l
@@ -652,13 +605,15 @@ DataBreakpoint:
652 EXC_XFER_EE(0x1c00, do_break) 605 EXC_XFER_EE(0x1c00, do_break)
65311: 60611:
654 mtcr r10 607 mtcr r10
655 EXCEPTION_EPILOG_0 608 mfspr r10, SPRN_SPRG_SCRATCH0
609 mfspr r11, SPRN_SPRG_SCRATCH1
656 rfi 610 rfi
657 611
658#ifdef CONFIG_PPC_8xx_PERF_EVENT 612#ifdef CONFIG_PERF_EVENTS
659 . = 0x1d00 613 . = 0x1d00
660InstructionBreakpoint: 614InstructionBreakpoint:
661 EXCEPTION_PROLOG_0 615 mtspr SPRN_SPRG_SCRATCH0, r10
616 mtspr SPRN_SPRG_SCRATCH1, r11
662 lis r10, (instruction_counter - PAGE_OFFSET)@ha 617 lis r10, (instruction_counter - PAGE_OFFSET)@ha
663 lwz r11, (instruction_counter - PAGE_OFFSET)@l(r10) 618 lwz r11, (instruction_counter - PAGE_OFFSET)@l(r10)
664 addi r11, r11, -1 619 addi r11, r11, -1
@@ -666,7 +621,8 @@ InstructionBreakpoint:
666 lis r10, 0xffff 621 lis r10, 0xffff
667 ori r10, r10, 0x01 622 ori r10, r10, 0x01
668 mtspr SPRN_COUNTA, r10 623 mtspr SPRN_COUNTA, r10
669 EXCEPTION_EPILOG_0 624 mfspr r10, SPRN_SPRG_SCRATCH0
625 mfspr r11, SPRN_SPRG_SCRATCH1
670 rfi 626 rfi
671#else 627#else
672 EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE) 628 EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE)
@@ -681,51 +637,57 @@ InstructionBreakpoint:
681 * not enough space in the DataStoreTLBMiss area. 637 * not enough space in the DataStoreTLBMiss area.
682 */ 638 */
683DTLBMissIMMR: 639DTLBMissIMMR:
684 mtcr r3 640 mtcr r12
685 /* Set 512k byte guarded page and mark it valid */ 641 /* Set 512k byte guarded page and mark it valid and accessed */
686 li r10, MD_PS512K | MD_GUARDED | MD_SVALID 642 li r10, MD_PS512K | MD_GUARDED | MD_SVALID | M_APG2
687 MTSPR_CPU6(SPRN_MD_TWC, r10, r11) 643 mtspr SPRN_MD_TWC, r10
688 mfspr r10, SPRN_IMMR /* Get current IMMR */ 644 mfspr r10, SPRN_IMMR /* Get current IMMR */
689 rlwinm r10, r10, 0, 0xfff80000 /* Get 512 kbytes boundary */ 645 rlwinm r10, r10, 0, 0xfff80000 /* Get 512 kbytes boundary */
690 ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \ 646 ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_PRIVILEGED | _PAGE_DIRTY | \
691 _PAGE_PRESENT | _PAGE_NO_CACHE 647 _PAGE_PRESENT | _PAGE_NO_CACHE
692 MTSPR_CPU6(SPRN_MD_RPN, r10, r11) /* Update TLB entry */ 648 mtspr SPRN_MD_RPN, r10 /* Update TLB entry */
693 649
694 li r11, RPN_PATTERN 650 li r11, RPN_PATTERN
695 mtspr SPRN_DAR, r11 /* Tag DAR */ 651 mtspr SPRN_DAR, r11 /* Tag DAR */
696 mfspr r3, SPRN_SPRG_SCRATCH2 652_ENTRY(dtlb_miss_exit_2)
697 EXCEPTION_EPILOG_0 653 mfspr r10, SPRN_SPRG_SCRATCH0
654 mfspr r11, SPRN_SPRG_SCRATCH1
655 mfspr r12, SPRN_SPRG_SCRATCH2
698 rfi 656 rfi
699 657
700DTLBMissLinear: 658DTLBMissLinear:
701 mtcr r3 659 mtcr r12
702 /* Set 8M byte page and mark it valid */ 660 /* Set 8M byte page and mark it valid and accessed */
703 li r11, MD_PS8MEG | MD_SVALID 661 li r11, MD_PS8MEG | MD_SVALID | M_APG2
704 MTSPR_CPU6(SPRN_MD_TWC, r11, r3) 662 mtspr SPRN_MD_TWC, r11
705 rlwinm r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */ 663 rlwinm r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */
706 ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \ 664 ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_PRIVILEGED | _PAGE_DIRTY | \
707 _PAGE_PRESENT 665 _PAGE_PRESENT
708 MTSPR_CPU6(SPRN_MD_RPN, r10, r11) /* Update TLB entry */ 666 mtspr SPRN_MD_RPN, r10 /* Update TLB entry */
709 667
710 li r11, RPN_PATTERN 668 li r11, RPN_PATTERN
711 mtspr SPRN_DAR, r11 /* Tag DAR */ 669 mtspr SPRN_DAR, r11 /* Tag DAR */
712 mfspr r3, SPRN_SPRG_SCRATCH2 670_ENTRY(dtlb_miss_exit_3)
713 EXCEPTION_EPILOG_0 671 mfspr r10, SPRN_SPRG_SCRATCH0
672 mfspr r11, SPRN_SPRG_SCRATCH1
673 mfspr r12, SPRN_SPRG_SCRATCH2
714 rfi 674 rfi
715 675
716#ifndef CONFIG_PIN_TLB_TEXT 676#ifndef CONFIG_PIN_TLB_TEXT
717ITLBMissLinear: 677ITLBMissLinear:
718 mtcr r3 678 mtcr r12
719 /* Set 8M byte page and mark it valid */ 679 /* Set 8M byte page and mark it valid,accessed */
720 li r11, MI_PS8MEG | MI_SVALID | _PAGE_EXEC 680 li r11, MI_PS8MEG | MI_SVALID | M_APG2
721 MTSPR_CPU6(SPRN_MI_TWC, r11, r3) 681 mtspr SPRN_MI_TWC, r11
722 rlwinm r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */ 682 rlwinm r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */
723 ori r10, r10, 0xf0 | MI_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \ 683 ori r10, r10, 0xf0 | MI_SPS16K | _PAGE_PRIVILEGED | _PAGE_DIRTY | \
724 _PAGE_PRESENT 684 _PAGE_PRESENT
725 MTSPR_CPU6(SPRN_MI_RPN, r10, r11) /* Update TLB entry */ 685 mtspr SPRN_MI_RPN, r10 /* Update TLB entry */
726 686
727 mfspr r3, SPRN_SPRG_SCRATCH2 687_ENTRY(itlb_miss_exit_2)
728 EXCEPTION_EPILOG_0 688 mfspr r10, SPRN_SPRG_SCRATCH0
689 mfspr r11, SPRN_SPRG_SCRATCH1
690 mfspr r12, SPRN_SPRG_SCRATCH2
729 rfi 691 rfi
730#endif 692#endif
731 693
@@ -933,13 +895,6 @@ start_here:
933 */ 895 */
934 lis r6, swapper_pg_dir@ha 896 lis r6, swapper_pg_dir@ha
935 tophys(r6,r6) 897 tophys(r6,r6)
936#ifdef CONFIG_8xx_CPU6
937 lis r4, cpu6_errata_word@h
938 ori r4, r4, cpu6_errata_word@l
939 li r3, 0x3f80
940 stw r3, 12(r4)
941 lwz r3, 12(r4)
942#endif
943 mtspr SPRN_M_TW, r6 898 mtspr SPRN_M_TW, r6
944 lis r4,2f@h 899 lis r4,2f@h
945 ori r4,r4,2f@l 900 ori r4,r4,2f@l
@@ -1004,8 +959,8 @@ initial_mmu:
1004 lis r8, KERNELBASE@h /* Create vaddr for TLB */ 959 lis r8, KERNELBASE@h /* Create vaddr for TLB */
1005 ori r8, r8, MI_EVALID /* Mark it valid */ 960 ori r8, r8, MI_EVALID /* Mark it valid */
1006 mtspr SPRN_MI_EPN, r8 961 mtspr SPRN_MI_EPN, r8
1007 li r8, MI_PS8MEG | (2 << 5) /* Set 8M byte page, APG 2 */ 962 li r8, MI_PS8MEG /* Set 8M byte page */
1008 ori r8, r8, MI_SVALID /* Make it valid */ 963 ori r8, r8, MI_SVALID | M_APG2 /* Make it valid, APG 2 */
1009 mtspr SPRN_MI_TWC, r8 964 mtspr SPRN_MI_TWC, r8
1010 li r8, MI_BOOTINIT /* Create RPN for address 0 */ 965 li r8, MI_BOOTINIT /* Create RPN for address 0 */
1011 mtspr SPRN_MI_RPN, r8 /* Store TLB entry */ 966 mtspr SPRN_MI_RPN, r8 /* Store TLB entry */
@@ -1032,7 +987,7 @@ initial_mmu:
1032 ori r8, r8, MD_EVALID /* Mark it valid */ 987 ori r8, r8, MD_EVALID /* Mark it valid */
1033 mtspr SPRN_MD_EPN, r8 988 mtspr SPRN_MD_EPN, r8
1034 li r8, MD_PS512K | MD_GUARDED /* Set 512k byte page */ 989 li r8, MD_PS512K | MD_GUARDED /* Set 512k byte page */
1035 ori r8, r8, MD_SVALID /* Make it valid */ 990 ori r8, r8, MD_SVALID | M_APG2 /* Make it valid and accessed */
1036 mtspr SPRN_MD_TWC, r8 991 mtspr SPRN_MD_TWC, r8
1037 mr r8, r9 /* Create paddr for TLB */ 992 mr r8, r9 /* Create paddr for TLB */
1038 ori r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */ 993 ori r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
@@ -1061,7 +1016,7 @@ initial_mmu:
1061#endif 1016#endif
1062 /* Disable debug mode entry on breakpoints */ 1017 /* Disable debug mode entry on breakpoints */
1063 mfspr r8, SPRN_DER 1018 mfspr r8, SPRN_DER
1064#ifdef CONFIG_PPC_8xx_PERF_EVENT 1019#ifdef CONFIG_PERF_EVENTS
1065 rlwinm r8, r8, 0, ~0xc 1020 rlwinm r8, r8, 0, ~0xc
1066#else 1021#else
1067 rlwinm r8, r8, 0, ~0x8 1022 rlwinm r8, r8, 0, ~0x8
@@ -1094,13 +1049,7 @@ swapper_pg_dir:
1094abatron_pteptrs: 1049abatron_pteptrs:
1095 .space 8 1050 .space 8
1096 1051
1097#ifdef CONFIG_8xx_CPU6 1052#ifdef CONFIG_PERF_EVENTS
1098 .globl cpu6_errata_word
1099cpu6_errata_word:
1100 .space 16
1101#endif
1102
1103#ifdef CONFIG_PPC_8xx_PERF_EVENT
1104 .globl itlb_miss_counter 1053 .globl itlb_miss_counter
1105itlb_miss_counter: 1054itlb_miss_counter:
1106 .space 4 1055 .space 4
diff --git a/arch/powerpc/kernel/idle_book3e.S b/arch/powerpc/kernel/idle_book3e.S
index 48c21acef915..2b269315d377 100644
--- a/arch/powerpc/kernel/idle_book3e.S
+++ b/arch/powerpc/kernel/idle_book3e.S
@@ -17,6 +17,7 @@
17#include <asm/processor.h> 17#include <asm/processor.h>
18#include <asm/thread_info.h> 18#include <asm/thread_info.h>
19#include <asm/epapr_hcalls.h> 19#include <asm/epapr_hcalls.h>
20#include <asm/hw_irq.h>
20 21
21/* 64-bit version only for now */ 22/* 64-bit version only for now */
22#ifdef CONFIG_PPC64 23#ifdef CONFIG_PPC64
@@ -46,8 +47,8 @@ _GLOBAL(\name)
46 bl trace_hardirqs_on 47 bl trace_hardirqs_on
47 addi r1,r1,128 48 addi r1,r1,128
48#endif 49#endif
49 li r0,1 50 li r0,IRQS_ENABLED
50 stb r0,PACASOFTIRQEN(r13) 51 stb r0,PACAIRQSOFTMASK(r13)
51 52
52 /* Interrupts will make use return to LR, so get something we want 53 /* Interrupts will make use return to LR, so get something we want
53 * in there 54 * in there
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
index f57a19348bdd..08faa93755f9 100644
--- a/arch/powerpc/kernel/idle_power4.S
+++ b/arch/powerpc/kernel/idle_power4.S
@@ -15,6 +15,7 @@
15#include <asm/ppc_asm.h> 15#include <asm/ppc_asm.h>
16#include <asm/asm-offsets.h> 16#include <asm/asm-offsets.h>
17#include <asm/irqflags.h> 17#include <asm/irqflags.h>
18#include <asm/hw_irq.h>
18 19
19#undef DEBUG 20#undef DEBUG
20 21
@@ -53,8 +54,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
53 mfmsr r7 54 mfmsr r7
54#endif /* CONFIG_TRACE_IRQFLAGS */ 55#endif /* CONFIG_TRACE_IRQFLAGS */
55 56
56 li r0,1 57 li r0,IRQS_ENABLED
57 stb r0,PACASOFTIRQEN(r13) /* we'll hard-enable shortly */ 58 stb r0,PACAIRQSOFTMASK(r13) /* we'll hard-enable shortly */
58BEGIN_FTR_SECTION 59BEGIN_FTR_SECTION
59 DSSALL 60 DSSALL
60 sync 61 sync
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index b7a84522e652..f88038847790 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -67,6 +67,7 @@
67#include <asm/smp.h> 67#include <asm/smp.h>
68#include <asm/livepatch.h> 68#include <asm/livepatch.h>
69#include <asm/asm-prototypes.h> 69#include <asm/asm-prototypes.h>
70#include <asm/hw_irq.h>
70 71
71#ifdef CONFIG_PPC64 72#ifdef CONFIG_PPC64
72#include <asm/paca.h> 73#include <asm/paca.h>
@@ -106,12 +107,6 @@ static inline notrace unsigned long get_irq_happened(void)
106 return happened; 107 return happened;
107} 108}
108 109
109static inline notrace void set_soft_enabled(unsigned long enable)
110{
111 __asm__ __volatile__("stb %0,%1(13)"
112 : : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled)));
113}
114
115static inline notrace int decrementer_check_overflow(void) 110static inline notrace int decrementer_check_overflow(void)
116{ 111{
117 u64 now = get_tb_or_rtc(); 112 u64 now = get_tb_or_rtc();
@@ -191,6 +186,11 @@ notrace unsigned int __check_irq_replay(void)
191 return 0x900; 186 return 0x900;
192 } 187 }
193 188
189 if (happened & PACA_IRQ_PMI) {
190 local_paca->irq_happened &= ~PACA_IRQ_PMI;
191 return 0xf00;
192 }
193
194 if (happened & PACA_IRQ_EE) { 194 if (happened & PACA_IRQ_EE) {
195 local_paca->irq_happened &= ~PACA_IRQ_EE; 195 local_paca->irq_happened &= ~PACA_IRQ_EE;
196 return 0x500; 196 return 0x500;
@@ -224,15 +224,16 @@ notrace unsigned int __check_irq_replay(void)
224 return 0; 224 return 0;
225} 225}
226 226
227notrace void arch_local_irq_restore(unsigned long en) 227notrace void arch_local_irq_restore(unsigned long mask)
228{ 228{
229 unsigned char irq_happened; 229 unsigned char irq_happened;
230 unsigned int replay; 230 unsigned int replay;
231 231
232 /* Write the new soft-enabled value */ 232 /* Write the new soft-enabled value */
233 set_soft_enabled(en); 233 irq_soft_mask_set(mask);
234 if (!en) 234 if (mask)
235 return; 235 return;
236
236 /* 237 /*
237 * From this point onward, we can take interrupts, preempt, 238 * From this point onward, we can take interrupts, preempt,
238 * etc... unless we got hard-disabled. We check if an event 239 * etc... unless we got hard-disabled. We check if an event
@@ -263,7 +264,7 @@ notrace void arch_local_irq_restore(unsigned long en)
263 */ 264 */
264 if (unlikely(irq_happened != PACA_IRQ_HARD_DIS)) 265 if (unlikely(irq_happened != PACA_IRQ_HARD_DIS))
265 __hard_irq_disable(); 266 __hard_irq_disable();
266#ifdef CONFIG_TRACE_IRQFLAGS 267#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
267 else { 268 else {
268 /* 269 /*
269 * We should already be hard disabled here. We had bugs 270 * We should already be hard disabled here. We had bugs
@@ -274,9 +275,9 @@ notrace void arch_local_irq_restore(unsigned long en)
274 if (WARN_ON(mfmsr() & MSR_EE)) 275 if (WARN_ON(mfmsr() & MSR_EE))
275 __hard_irq_disable(); 276 __hard_irq_disable();
276 } 277 }
277#endif /* CONFIG_TRACE_IRQFLAGS */ 278#endif
278 279
279 set_soft_enabled(0); 280 irq_soft_mask_set(IRQS_ALL_DISABLED);
280 trace_hardirqs_off(); 281 trace_hardirqs_off();
281 282
282 /* 283 /*
@@ -288,7 +289,7 @@ notrace void arch_local_irq_restore(unsigned long en)
288 289
289 /* We can soft-enable now */ 290 /* We can soft-enable now */
290 trace_hardirqs_on(); 291 trace_hardirqs_on();
291 set_soft_enabled(1); 292 irq_soft_mask_set(IRQS_ENABLED);
292 293
293 /* 294 /*
294 * And replay if we have to. This will return with interrupts 295 * And replay if we have to. This will return with interrupts
@@ -363,7 +364,7 @@ bool prep_irq_for_idle(void)
363 * of entering the low power state. 364 * of entering the low power state.
364 */ 365 */
365 local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS; 366 local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS;
366 local_paca->soft_enabled = 1; 367 irq_soft_mask_set(IRQS_ENABLED);
367 368
368 /* Tell the caller to enter the low power state */ 369 /* Tell the caller to enter the low power state */
369 return true; 370 return true;
diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c
index 71e8a1b8c86e..efdd16a79075 100644
--- a/arch/powerpc/kernel/mce.c
+++ b/arch/powerpc/kernel/mce.c
@@ -495,37 +495,123 @@ long machine_check_early(struct pt_regs *regs)
495 return handled; 495 return handled;
496} 496}
497 497
498long hmi_exception_realmode(struct pt_regs *regs) 498/* Possible meanings for HMER_DEBUG_TRIG bit being set on POWER9 */
499static enum {
500 DTRIG_UNKNOWN,
501 DTRIG_VECTOR_CI, /* need to emulate vector CI load instr */
502 DTRIG_SUSPEND_ESCAPE, /* need to escape from TM suspend mode */
503} hmer_debug_trig_function;
504
505static int init_debug_trig_function(void)
499{ 506{
500 __this_cpu_inc(irq_stat.hmi_exceptions); 507 int pvr;
501 508 struct device_node *cpun;
502#ifdef CONFIG_PPC_BOOK3S_64 509 struct property *prop = NULL;
503 /* Workaround for P9 vector CI loads (see p9_hmi_special_emu) */ 510 const char *str;
504 if (pvr_version_is(PVR_POWER9)) { 511
505 unsigned long hmer = mfspr(SPRN_HMER); 512 /* First look in the device tree */
506 513 preempt_disable();
507 /* Do we have the debug bit set */ 514 cpun = of_get_cpu_node(smp_processor_id(), NULL);
508 if (hmer & PPC_BIT(17)) { 515 if (cpun) {
509 hmer &= ~PPC_BIT(17); 516 of_property_for_each_string(cpun, "ibm,hmi-special-triggers",
510 mtspr(SPRN_HMER, hmer); 517 prop, str) {
511 518 if (strcmp(str, "bit17-vector-ci-load") == 0)
512 /* 519 hmer_debug_trig_function = DTRIG_VECTOR_CI;
513 * Now to avoid problems with soft-disable we 520 else if (strcmp(str, "bit17-tm-suspend-escape") == 0)
514 * only do the emulation if we are coming from 521 hmer_debug_trig_function = DTRIG_SUSPEND_ESCAPE;
515 * user space
516 */
517 if (user_mode(regs))
518 local_paca->hmi_p9_special_emu = 1;
519
520 /*
521 * Don't bother going to OPAL if that's the
522 * only relevant bit.
523 */
524 if (!(hmer & mfspr(SPRN_HMEER)))
525 return local_paca->hmi_p9_special_emu;
526 } 522 }
523 of_node_put(cpun);
524 }
525 preempt_enable();
526
527 /* If we found the property, don't look at PVR */
528 if (prop)
529 goto out;
530
531 pvr = mfspr(SPRN_PVR);
532 /* Check for POWER9 Nimbus (scale-out) */
533 if ((PVR_VER(pvr) == PVR_POWER9) && (pvr & 0xe000) == 0) {
534 /* DD2.2 and later */
535 if ((pvr & 0xfff) >= 0x202)
536 hmer_debug_trig_function = DTRIG_SUSPEND_ESCAPE;
537 /* DD2.0 and DD2.1 - used for vector CI load emulation */
538 else if ((pvr & 0xfff) >= 0x200)
539 hmer_debug_trig_function = DTRIG_VECTOR_CI;
540 }
541
542 out:
543 switch (hmer_debug_trig_function) {
544 case DTRIG_VECTOR_CI:
545 pr_debug("HMI debug trigger used for vector CI load\n");
546 break;
547 case DTRIG_SUSPEND_ESCAPE:
548 pr_debug("HMI debug trigger used for TM suspend escape\n");
549 break;
550 default:
551 break;
527 } 552 }
528#endif /* CONFIG_PPC_BOOK3S_64 */ 553 return 0;
554}
555__initcall(init_debug_trig_function);
556
557/*
558 * Handle HMIs that occur as a result of a debug trigger.
559 * Return values:
560 * -1 means this is not a HMI cause that we know about
561 * 0 means no further handling is required
562 * 1 means further handling is required
563 */
564long hmi_handle_debugtrig(struct pt_regs *regs)
565{
566 unsigned long hmer = mfspr(SPRN_HMER);
567 long ret = 0;
568
569 /* HMER_DEBUG_TRIG bit is used for various workarounds on P9 */
570 if (!((hmer & HMER_DEBUG_TRIG)
571 && hmer_debug_trig_function != DTRIG_UNKNOWN))
572 return -1;
573
574 hmer &= ~HMER_DEBUG_TRIG;
575 /* HMER is a write-AND register */
576 mtspr(SPRN_HMER, ~HMER_DEBUG_TRIG);
577
578 switch (hmer_debug_trig_function) {
579 case DTRIG_VECTOR_CI:
580 /*
581 * Now to avoid problems with soft-disable we
582 * only do the emulation if we are coming from
583 * host user space
584 */
585 if (regs && user_mode(regs))
586 ret = local_paca->hmi_p9_special_emu = 1;
587
588 break;
589
590 default:
591 break;
592 }
593
594 /*
595 * See if any other HMI causes remain to be handled
596 */
597 if (hmer & mfspr(SPRN_HMEER))
598 return -1;
599
600 return ret;
601}
602
603/*
604 * Return values:
605 */
606long hmi_exception_realmode(struct pt_regs *regs)
607{
608 int ret;
609
610 __this_cpu_inc(irq_stat.hmi_exceptions);
611
612 ret = hmi_handle_debugtrig(regs);
613 if (ret >= 0)
614 return ret;
529 615
530 wait_for_subcore_guest_exit(); 616 wait_for_subcore_guest_exit();
531 617
diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c
index 644f7040b91c..fe6fc63251fe 100644
--- a/arch/powerpc/kernel/mce_power.c
+++ b/arch/powerpc/kernel/mce_power.c
@@ -58,115 +58,6 @@ static unsigned long addr_to_pfn(struct pt_regs *regs, unsigned long addr)
58 return pte_pfn(*ptep); 58 return pte_pfn(*ptep);
59} 59}
60 60
61static void flush_tlb_206(unsigned int num_sets, unsigned int action)
62{
63 unsigned long rb;
64 unsigned int i;
65
66 switch (action) {
67 case TLB_INVAL_SCOPE_GLOBAL:
68 rb = TLBIEL_INVAL_SET;
69 break;
70 case TLB_INVAL_SCOPE_LPID:
71 rb = TLBIEL_INVAL_SET_LPID;
72 break;
73 default:
74 BUG();
75 break;
76 }
77
78 asm volatile("ptesync" : : : "memory");
79 for (i = 0; i < num_sets; i++) {
80 asm volatile("tlbiel %0" : : "r" (rb));
81 rb += 1 << TLBIEL_INVAL_SET_SHIFT;
82 }
83 asm volatile("ptesync" : : : "memory");
84}
85
86static void flush_tlb_300(unsigned int num_sets, unsigned int action)
87{
88 unsigned long rb;
89 unsigned int i;
90 unsigned int r;
91
92 switch (action) {
93 case TLB_INVAL_SCOPE_GLOBAL:
94 rb = TLBIEL_INVAL_SET;
95 break;
96 case TLB_INVAL_SCOPE_LPID:
97 rb = TLBIEL_INVAL_SET_LPID;
98 break;
99 default:
100 BUG();
101 break;
102 }
103
104 asm volatile("ptesync" : : : "memory");
105
106 if (early_radix_enabled())
107 r = 1;
108 else
109 r = 0;
110
111 /*
112 * First flush table/PWC caches with set 0, then flush the
113 * rest of the sets, partition scope. Radix must then do it
114 * all again with process scope. Hash just has to flush
115 * process table.
116 */
117 asm volatile(PPC_TLBIEL(%0, %1, %2, %3, %4) : :
118 "r"(rb), "r"(0), "i"(2), "i"(0), "r"(r));
119 for (i = 1; i < num_sets; i++) {
120 unsigned long set = i * (1<<TLBIEL_INVAL_SET_SHIFT);
121
122 asm volatile(PPC_TLBIEL(%0, %1, %2, %3, %4) : :
123 "r"(rb+set), "r"(0), "i"(2), "i"(0), "r"(r));
124 }
125
126 asm volatile(PPC_TLBIEL(%0, %1, %2, %3, %4) : :
127 "r"(rb), "r"(0), "i"(2), "i"(1), "r"(r));
128 if (early_radix_enabled()) {
129 for (i = 1; i < num_sets; i++) {
130 unsigned long set = i * (1<<TLBIEL_INVAL_SET_SHIFT);
131
132 asm volatile(PPC_TLBIEL(%0, %1, %2, %3, %4) : :
133 "r"(rb+set), "r"(0), "i"(2), "i"(1), "r"(r));
134 }
135 }
136
137 asm volatile("ptesync" : : : "memory");
138}
139
140/*
141 * Generic routines to flush TLB on POWER processors. These routines
142 * are used as flush_tlb hook in the cpu_spec.
143 *
144 * action => TLB_INVAL_SCOPE_GLOBAL: Invalidate all TLBs.
145 * TLB_INVAL_SCOPE_LPID: Invalidate TLB for current LPID.
146 */
147void __flush_tlb_power7(unsigned int action)
148{
149 flush_tlb_206(POWER7_TLB_SETS, action);
150}
151
152void __flush_tlb_power8(unsigned int action)
153{
154 flush_tlb_206(POWER8_TLB_SETS, action);
155}
156
157void __flush_tlb_power9(unsigned int action)
158{
159 unsigned int num_sets;
160
161 if (early_radix_enabled())
162 num_sets = POWER9_TLB_SETS_RADIX;
163 else
164 num_sets = POWER9_TLB_SETS_HASH;
165
166 flush_tlb_300(num_sets, action);
167}
168
169
170/* flush SLBs and reload */ 61/* flush SLBs and reload */
171#ifdef CONFIG_PPC_BOOK3S_64 62#ifdef CONFIG_PPC_BOOK3S_64
172static void flush_and_reload_slb(void) 63static void flush_and_reload_slb(void)
@@ -226,10 +117,8 @@ static int mce_flush(int what)
226 return 1; 117 return 1;
227 } 118 }
228 if (what == MCE_FLUSH_TLB) { 119 if (what == MCE_FLUSH_TLB) {
229 if (cur_cpu_spec && cur_cpu_spec->flush_tlb) { 120 tlbiel_all();
230 cur_cpu_spec->flush_tlb(TLB_INVAL_SCOPE_GLOBAL); 121 return 1;
231 return 1;
232 }
233 } 122 }
234 123
235 return 0; 124 return 0;
diff --git a/arch/powerpc/kernel/module.lds b/arch/powerpc/kernel/module.lds
new file mode 100644
index 000000000000..cea5dc124be4
--- /dev/null
+++ b/arch/powerpc/kernel/module.lds
@@ -0,0 +1,8 @@
1/* Force alignment of .toc section. */
2SECTIONS
3{
4 .toc 0 : ALIGN(256)
5 {
6 *(.got .toc)
7 }
8}
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 218971ac7e04..a2636c250b7b 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -348,8 +348,11 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr,
348 char *p; 348 char *p;
349 if (strcmp(secstrings + sechdrs[i].sh_name, ".stubs") == 0) 349 if (strcmp(secstrings + sechdrs[i].sh_name, ".stubs") == 0)
350 me->arch.stubs_section = i; 350 me->arch.stubs_section = i;
351 else if (strcmp(secstrings + sechdrs[i].sh_name, ".toc") == 0) 351 else if (strcmp(secstrings + sechdrs[i].sh_name, ".toc") == 0) {
352 me->arch.toc_section = i; 352 me->arch.toc_section = i;
353 if (sechdrs[i].sh_addralign < 8)
354 sechdrs[i].sh_addralign = 8;
355 }
353 else if (strcmp(secstrings+sechdrs[i].sh_name,"__versions")==0) 356 else if (strcmp(secstrings+sechdrs[i].sh_name,"__versions")==0)
354 dedotify_versions((void *)hdr + sechdrs[i].sh_offset, 357 dedotify_versions((void *)hdr + sechdrs[i].sh_offset,
355 sechdrs[i].sh_size); 358 sechdrs[i].sh_size);
@@ -387,12 +390,15 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr,
387 return 0; 390 return 0;
388} 391}
389 392
390/* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this 393/*
391 gives the value maximum span in an instruction which uses a signed 394 * r2 is the TOC pointer: it actually points 0x8000 into the TOC (this gives the
392 offset) */ 395 * value maximum span in an instruction which uses a signed offset). Round down
396 * to a 256 byte boundary for the odd case where we are setting up r2 without a
397 * .toc section.
398 */
393static inline unsigned long my_r2(const Elf64_Shdr *sechdrs, struct module *me) 399static inline unsigned long my_r2(const Elf64_Shdr *sechdrs, struct module *me)
394{ 400{
395 return sechdrs[me->arch.toc_section].sh_addr + 0x8000; 401 return (sechdrs[me->arch.toc_section].sh_addr & ~0xfful) + 0x8000;
396} 402}
397 403
398/* Both low and high 16 bits are added as SIGNED additions, so if low 404/* Both low and high 16 bits are added as SIGNED additions, so if low
@@ -501,12 +507,22 @@ static bool is_early_mcount_callsite(u32 *instruction)
501 restore r2. */ 507 restore r2. */
502static int restore_r2(u32 *instruction, struct module *me) 508static int restore_r2(u32 *instruction, struct module *me)
503{ 509{
504 if (is_early_mcount_callsite(instruction - 1)) 510 u32 *prev_insn = instruction - 1;
511
512 if (is_early_mcount_callsite(prev_insn))
513 return 1;
514
515 /*
516 * Make sure the branch isn't a sibling call. Sibling calls aren't
517 * "link" branches and they don't return, so they don't need the r2
518 * restore afterwards.
519 */
520 if (!instr_is_relative_link_branch(*prev_insn))
505 return 1; 521 return 1;
506 522
507 if (*instruction != PPC_INST_NOP) { 523 if (*instruction != PPC_INST_NOP) {
508 pr_err("%s: Expect noop after relocate, got %08x\n", 524 pr_err("%s: Expected nop after call, got %08x at %pS\n",
509 me->name, *instruction); 525 me->name, *instruction, instruction);
510 return 0; 526 return 0;
511 } 527 }
512 /* ld r2,R2_STACK_OFFSET(r1) */ 528 /* ld r2,R2_STACK_OFFSET(r1) */
@@ -628,7 +644,8 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
628 644
629 case R_PPC_REL24: 645 case R_PPC_REL24:
630 /* FIXME: Handle weak symbols here --RR */ 646 /* FIXME: Handle weak symbols here --RR */
631 if (sym->st_shndx == SHN_UNDEF) { 647 if (sym->st_shndx == SHN_UNDEF ||
648 sym->st_shndx == SHN_LIVEPATCH) {
632 /* External: go via stub */ 649 /* External: go via stub */
633 value = stub_for_addr(sechdrs, value, me); 650 value = stub_for_addr(sechdrs, value, me);
634 if (!value) 651 if (!value)
diff --git a/arch/powerpc/kernel/optprobes_head.S b/arch/powerpc/kernel/optprobes_head.S
index 52fc864cdec4..98a3aeeb3c8c 100644
--- a/arch/powerpc/kernel/optprobes_head.S
+++ b/arch/powerpc/kernel/optprobes_head.S
@@ -58,7 +58,7 @@ optprobe_template_entry:
58 std r5,_XER(r1) 58 std r5,_XER(r1)
59 mfcr r5 59 mfcr r5
60 std r5,_CCR(r1) 60 std r5,_CCR(r1)
61 lbz r5,PACASOFTIRQEN(r13) 61 lbz r5,PACAIRQSOFTMASK(r13)
62 std r5,SOFTE(r1) 62 std r5,SOFTE(r1)
63 63
64 /* 64 /*
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index d6597038931d..95ffedf14885 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -18,6 +18,8 @@
18#include <asm/pgtable.h> 18#include <asm/pgtable.h>
19#include <asm/kexec.h> 19#include <asm/kexec.h>
20 20
21#include "setup.h"
22
21#ifdef CONFIG_PPC_BOOK3S 23#ifdef CONFIG_PPC_BOOK3S
22 24
23/* 25/*
@@ -208,15 +210,14 @@ void __init allocate_pacas(void)
208 u64 limit; 210 u64 limit;
209 int cpu; 211 int cpu;
210 212
211 limit = ppc64_rma_size;
212
213#ifdef CONFIG_PPC_BOOK3S_64 213#ifdef CONFIG_PPC_BOOK3S_64
214 /* 214 /*
215 * We can't take SLB misses on the paca, and we want to access them 215 * We access pacas in real mode, and cannot take SLB faults
216 * in real mode, so allocate them within the RMA and also within 216 * on them when in virtual mode, so allocate them accordingly.
217 * the first segment.
218 */ 217 */
219 limit = min(0x10000000ULL, limit); 218 limit = min(ppc64_bolted_size(), ppc64_rma_size);
219#else
220 limit = ppc64_rma_size;
220#endif 221#endif
221 222
222 paca_size = PAGE_ALIGN(sizeof(struct paca_struct) * nr_cpu_ids); 223 paca_size = PAGE_ALIGN(sizeof(struct paca_struct) * nr_cpu_ids);
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 590f4d0a6cb1..208e623b2557 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -249,8 +249,31 @@ resource_size_t pcibios_iov_resource_alignment(struct pci_dev *pdev, int resno)
249 249
250 return pci_iov_resource_size(pdev, resno); 250 return pci_iov_resource_size(pdev, resno);
251} 251}
252
253int pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
254{
255 if (ppc_md.pcibios_sriov_enable)
256 return ppc_md.pcibios_sriov_enable(pdev, num_vfs);
257
258 return 0;
259}
260
261int pcibios_sriov_disable(struct pci_dev *pdev)
262{
263 if (ppc_md.pcibios_sriov_disable)
264 return ppc_md.pcibios_sriov_disable(pdev);
265
266 return 0;
267}
268
252#endif /* CONFIG_PCI_IOV */ 269#endif /* CONFIG_PCI_IOV */
253 270
271void pcibios_bus_add_device(struct pci_dev *pdev)
272{
273 if (ppc_md.pcibios_bus_add_device)
274 ppc_md.pcibios_bus_add_device(pdev);
275}
276
254static resource_size_t pcibios_io_size(const struct pci_controller *hose) 277static resource_size_t pcibios_io_size(const struct pci_controller *hose)
255{ 278{
256#ifdef CONFIG_PPC64 279#ifdef CONFIG_PPC64
@@ -1276,8 +1299,8 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
1276 i + PCI_BRIDGE_RESOURCES) == 0) 1299 i + PCI_BRIDGE_RESOURCES) == 0)
1277 continue; 1300 continue;
1278 } 1301 }
1279 pr_warning("PCI: Cannot allocate resource region " 1302 pr_warn("PCI: Cannot allocate resource region %d of PCI bridge %d, will remap\n",
1280 "%d of PCI bridge %d, will remap\n", i, bus->number); 1303 i, bus->number);
1281 clear_resource: 1304 clear_resource:
1282 /* The resource might be figured out when doing 1305 /* The resource might be figured out when doing
1283 * reassignment based on the resources required 1306 * reassignment based on the resources required
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index 0e395afbf0f4..ab147a1909c8 100644
--- a/arch/powerpc/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -156,10 +156,8 @@ static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent,
156 pdn->parent = parent; 156 pdn->parent = parent;
157 pdn->busno = busno; 157 pdn->busno = busno;
158 pdn->devfn = devfn; 158 pdn->devfn = devfn;
159#ifdef CONFIG_PPC_POWERNV
160 pdn->vf_index = vf_index; 159 pdn->vf_index = vf_index;
161 pdn->pe_number = IODA_INVALID_PE; 160 pdn->pe_number = IODA_INVALID_PE;
162#endif
163 INIT_LIST_HEAD(&pdn->child_list); 161 INIT_LIST_HEAD(&pdn->child_list);
164 INIT_LIST_HEAD(&pdn->list); 162 INIT_LIST_HEAD(&pdn->list);
165 list_add_tail(&pdn->list, &parent->child_list); 163 list_add_tail(&pdn->list, &parent->child_list);
@@ -226,9 +224,7 @@ void remove_dev_pci_data(struct pci_dev *pdev)
226 */ 224 */
227 if (pdev->is_virtfn) { 225 if (pdev->is_virtfn) {
228 pdn = pci_get_pdn(pdev); 226 pdn = pci_get_pdn(pdev);
229#ifdef CONFIG_PPC_POWERNV
230 pdn->pe_number = IODA_INVALID_PE; 227 pdn->pe_number = IODA_INVALID_PE;
231#endif
232 return; 228 return;
233 } 229 }
234 230
@@ -294,9 +290,7 @@ struct pci_dn *pci_add_device_node_info(struct pci_controller *hose,
294 return NULL; 290 return NULL;
295 dn->data = pdn; 291 dn->data = pdn;
296 pdn->phb = hose; 292 pdn->phb = hose;
297#ifdef CONFIG_PPC_POWERNV
298 pdn->pe_number = IODA_INVALID_PE; 293 pdn->pe_number = IODA_INVALID_PE;
299#endif
300 regs = of_get_property(dn, "reg", NULL); 294 regs = of_get_property(dn, "reg", NULL);
301 if (regs) { 295 if (regs) {
302 u32 addr = of_read_number(regs, 1); 296 u32 addr = of_read_number(regs, 1);
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
index 0d790f8432d2..20ceec4a5f5e 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -38,7 +38,7 @@ static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
38 * @addr0: value of 1st cell of a device tree PCI address. 38 * @addr0: value of 1st cell of a device tree PCI address.
39 * @bridge: Set this flag if the address is from a bridge 'ranges' property 39 * @bridge: Set this flag if the address is from a bridge 'ranges' property
40 */ 40 */
41static unsigned int pci_parse_of_flags(u32 addr0, int bridge) 41unsigned int pci_parse_of_flags(u32 addr0, int bridge)
42{ 42{
43 unsigned int flags = 0; 43 unsigned int flags = 0;
44 44
diff --git a/arch/powerpc/kernel/proc_powerpc.c b/arch/powerpc/kernel/proc_powerpc.c
index 56548bf6231f..9bfbd800d32f 100644
--- a/arch/powerpc/kernel/proc_powerpc.c
+++ b/arch/powerpc/kernel/proc_powerpc.c
@@ -63,7 +63,7 @@ static int __init proc_ppc64_init(void)
63{ 63{
64 struct proc_dir_entry *pde; 64 struct proc_dir_entry *pde;
65 65
66 pde = proc_create_data("powerpc/systemcfg", S_IFREG|S_IRUGO, NULL, 66 pde = proc_create_data("powerpc/systemcfg", S_IFREG | 0444, NULL,
67 &page_map_fops, vdso_data); 67 &page_map_fops, vdso_data);
68 if (!pde) 68 if (!pde)
69 return 1; 69 return 1;
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 4208cbe2fb7f..1738c4127b32 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -42,6 +42,7 @@
42#include <linux/hw_breakpoint.h> 42#include <linux/hw_breakpoint.h>
43#include <linux/uaccess.h> 43#include <linux/uaccess.h>
44#include <linux/elf-randomize.h> 44#include <linux/elf-randomize.h>
45#include <linux/pkeys.h>
45 46
46#include <asm/pgtable.h> 47#include <asm/pgtable.h>
47#include <asm/io.h> 48#include <asm/io.h>
@@ -57,6 +58,7 @@
57#include <asm/debug.h> 58#include <asm/debug.h>
58#ifdef CONFIG_PPC64 59#ifdef CONFIG_PPC64
59#include <asm/firmware.h> 60#include <asm/firmware.h>
61#include <asm/hw_irq.h>
60#endif 62#endif
61#include <asm/code-patching.h> 63#include <asm/code-patching.h>
62#include <asm/exec.h> 64#include <asm/exec.h>
@@ -1097,6 +1099,8 @@ static inline void save_sprs(struct thread_struct *t)
1097 t->tar = mfspr(SPRN_TAR); 1099 t->tar = mfspr(SPRN_TAR);
1098 } 1100 }
1099#endif 1101#endif
1102
1103 thread_pkey_regs_save(t);
1100} 1104}
1101 1105
1102static inline void restore_sprs(struct thread_struct *old_thread, 1106static inline void restore_sprs(struct thread_struct *old_thread,
@@ -1136,6 +1140,8 @@ static inline void restore_sprs(struct thread_struct *old_thread,
1136 old_thread->tidr != new_thread->tidr) 1140 old_thread->tidr != new_thread->tidr)
1137 mtspr(SPRN_TIDR, new_thread->tidr); 1141 mtspr(SPRN_TIDR, new_thread->tidr);
1138#endif 1142#endif
1143
1144 thread_pkey_regs_restore(new_thread, old_thread);
1139} 1145}
1140 1146
1141#ifdef CONFIG_PPC_BOOK3S_64 1147#ifdef CONFIG_PPC_BOOK3S_64
@@ -1404,7 +1410,7 @@ void show_regs(struct pt_regs * regs)
1404 print_msr_bits(regs->msr); 1410 print_msr_bits(regs->msr);
1405 pr_cont(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer); 1411 pr_cont(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer);
1406 trap = TRAP(regs); 1412 trap = TRAP(regs);
1407 if ((regs->trap != 0xc00) && cpu_has_feature(CPU_FTR_CFAR)) 1413 if ((TRAP(regs) != 0xc00) && cpu_has_feature(CPU_FTR_CFAR))
1408 pr_cont("CFAR: "REG" ", regs->orig_gpr3); 1414 pr_cont("CFAR: "REG" ", regs->orig_gpr3);
1409 if (trap == 0x200 || trap == 0x300 || trap == 0x600) 1415 if (trap == 0x200 || trap == 0x300 || trap == 0x600)
1410#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) 1416#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
@@ -1504,14 +1510,15 @@ static int assign_thread_tidr(void)
1504{ 1510{
1505 int index; 1511 int index;
1506 int err; 1512 int err;
1513 unsigned long flags;
1507 1514
1508again: 1515again:
1509 if (!ida_pre_get(&vas_thread_ida, GFP_KERNEL)) 1516 if (!ida_pre_get(&vas_thread_ida, GFP_KERNEL))
1510 return -ENOMEM; 1517 return -ENOMEM;
1511 1518
1512 spin_lock(&vas_thread_id_lock); 1519 spin_lock_irqsave(&vas_thread_id_lock, flags);
1513 err = ida_get_new_above(&vas_thread_ida, 1, &index); 1520 err = ida_get_new_above(&vas_thread_ida, 1, &index);
1514 spin_unlock(&vas_thread_id_lock); 1521 spin_unlock_irqrestore(&vas_thread_id_lock, flags);
1515 1522
1516 if (err == -EAGAIN) 1523 if (err == -EAGAIN)
1517 goto again; 1524 goto again;
@@ -1519,9 +1526,9 @@ again:
1519 return err; 1526 return err;
1520 1527
1521 if (index > MAX_THREAD_CONTEXT) { 1528 if (index > MAX_THREAD_CONTEXT) {
1522 spin_lock(&vas_thread_id_lock); 1529 spin_lock_irqsave(&vas_thread_id_lock, flags);
1523 ida_remove(&vas_thread_ida, index); 1530 ida_remove(&vas_thread_ida, index);
1524 spin_unlock(&vas_thread_id_lock); 1531 spin_unlock_irqrestore(&vas_thread_id_lock, flags);
1525 return -ENOMEM; 1532 return -ENOMEM;
1526 } 1533 }
1527 1534
@@ -1530,9 +1537,11 @@ again:
1530 1537
1531static void free_thread_tidr(int id) 1538static void free_thread_tidr(int id)
1532{ 1539{
1533 spin_lock(&vas_thread_id_lock); 1540 unsigned long flags;
1541
1542 spin_lock_irqsave(&vas_thread_id_lock, flags);
1534 ida_remove(&vas_thread_ida, id); 1543 ida_remove(&vas_thread_ida, id);
1535 spin_unlock(&vas_thread_id_lock); 1544 spin_unlock_irqrestore(&vas_thread_id_lock, flags);
1536} 1545}
1537 1546
1538/* 1547/*
@@ -1584,6 +1593,7 @@ int set_thread_tidr(struct task_struct *t)
1584 1593
1585 return 0; 1594 return 0;
1586} 1595}
1596EXPORT_SYMBOL_GPL(set_thread_tidr);
1587 1597
1588#endif /* CONFIG_PPC64 */ 1598#endif /* CONFIG_PPC64 */
1589 1599
@@ -1669,7 +1679,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
1669 childregs->gpr[14] = ppc_function_entry((void *)usp); 1679 childregs->gpr[14] = ppc_function_entry((void *)usp);
1670#ifdef CONFIG_PPC64 1680#ifdef CONFIG_PPC64
1671 clear_tsk_thread_flag(p, TIF_32BIT); 1681 clear_tsk_thread_flag(p, TIF_32BIT);
1672 childregs->softe = 1; 1682 childregs->softe = IRQS_ENABLED;
1673#endif 1683#endif
1674 childregs->gpr[15] = kthread_arg; 1684 childregs->gpr[15] = kthread_arg;
1675 p->thread.regs = NULL; /* no user register state */ 1685 p->thread.regs = NULL; /* no user register state */
@@ -1860,6 +1870,8 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
1860 current->thread.tm_tfiar = 0; 1870 current->thread.tm_tfiar = 0;
1861 current->thread.load_tm = 0; 1871 current->thread.load_tm = 0;
1862#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ 1872#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
1873
1874 thread_pkey_regs_init(&current->thread);
1863} 1875}
1864EXPORT_SYMBOL(start_thread); 1876EXPORT_SYMBOL(start_thread);
1865 1877
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index b15bae265c90..4dffef947b8a 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -59,6 +59,7 @@
59#include <asm/epapr_hcalls.h> 59#include <asm/epapr_hcalls.h>
60#include <asm/firmware.h> 60#include <asm/firmware.h>
61#include <asm/dt_cpu_ftrs.h> 61#include <asm/dt_cpu_ftrs.h>
62#include <asm/drmem.h>
62 63
63#include <mm/mmu_decl.h> 64#include <mm/mmu_decl.h>
64 65
@@ -455,92 +456,74 @@ static int __init early_init_dt_scan_chosen_ppc(unsigned long node,
455 456
456#ifdef CONFIG_PPC_PSERIES 457#ifdef CONFIG_PPC_PSERIES
457/* 458/*
458 * Interpret the ibm,dynamic-memory property in the 459 * Interpret the ibm dynamic reconfiguration memory LMBs.
459 * /ibm,dynamic-reconfiguration-memory node.
460 * This contains a list of memory blocks along with NUMA affinity 460 * This contains a list of memory blocks along with NUMA affinity
461 * information. 461 * information.
462 */ 462 */
463static int __init early_init_dt_scan_drconf_memory(unsigned long node) 463static void __init early_init_drmem_lmb(struct drmem_lmb *lmb,
464 const __be32 **usm)
464{ 465{
465 const __be32 *dm, *ls, *usm; 466 u64 base, size;
466 int l; 467 int is_kexec_kdump = 0, rngs;
467 unsigned long n, flags;
468 u64 base, size, memblock_size;
469 unsigned int is_kexec_kdump = 0, rngs;
470
471 ls = of_get_flat_dt_prop(node, "ibm,lmb-size", &l);
472 if (ls == NULL || l < dt_root_size_cells * sizeof(__be32))
473 return 0;
474 memblock_size = dt_mem_next_cell(dt_root_size_cells, &ls);
475 468
476 dm = of_get_flat_dt_prop(node, "ibm,dynamic-memory", &l); 469 base = lmb->base_addr;
477 if (dm == NULL || l < sizeof(__be32)) 470 size = drmem_lmb_size();
478 return 0; 471 rngs = 1;
479 472
480 n = of_read_number(dm++, 1); /* number of entries */ 473 /*
481 if (l < (n * (dt_root_addr_cells + 4) + 1) * sizeof(__be32)) 474 * Skip this block if the reserved bit is set in flags
482 return 0; 475 * or if the block is not assigned to this partition.
476 */
477 if ((lmb->flags & DRCONF_MEM_RESERVED) ||
478 !(lmb->flags & DRCONF_MEM_ASSIGNED))
479 return;
483 480
484 /* check if this is a kexec/kdump kernel. */ 481 if (*usm)
485 usm = of_get_flat_dt_prop(node, "linux,drconf-usable-memory",
486 &l);
487 if (usm != NULL)
488 is_kexec_kdump = 1; 482 is_kexec_kdump = 1;
489 483
490 for (; n != 0; --n) { 484 if (is_kexec_kdump) {
491 base = dt_mem_next_cell(dt_root_addr_cells, &dm); 485 /*
492 flags = of_read_number(&dm[3], 1); 486 * For each memblock in ibm,dynamic-memory, a
493 /* skip DRC index, pad, assoc. list index, flags */ 487 * corresponding entry in linux,drconf-usable-memory
494 dm += 4; 488 * property contains a counter 'p' followed by 'p'
495 /* skip this block if the reserved bit is set in flags 489 * (base, size) duple. Now read the counter from
496 or if the block is not assigned to this partition */ 490 * linux,drconf-usable-memory property
497 if ((flags & DRCONF_MEM_RESERVED) || 491 */
498 !(flags & DRCONF_MEM_ASSIGNED)) 492 rngs = dt_mem_next_cell(dt_root_size_cells, usm);
499 continue; 493 if (!rngs) /* there are no (base, size) duple */
500 size = memblock_size; 494 return;
501 rngs = 1; 495 }
496
497 do {
502 if (is_kexec_kdump) { 498 if (is_kexec_kdump) {
503 /* 499 base = dt_mem_next_cell(dt_root_addr_cells, usm);
504 * For each memblock in ibm,dynamic-memory, a corresponding 500 size = dt_mem_next_cell(dt_root_size_cells, usm);
505 * entry in linux,drconf-usable-memory property contains 501 }
506 * a counter 'p' followed by 'p' (base, size) duple. 502
507 * Now read the counter from 503 if (iommu_is_off) {
508 * linux,drconf-usable-memory property 504 if (base >= 0x80000000ul)
509 */
510 rngs = dt_mem_next_cell(dt_root_size_cells, &usm);
511 if (!rngs) /* there are no (base, size) duple */
512 continue; 505 continue;
506 if ((base + size) > 0x80000000ul)
507 size = 0x80000000ul - base;
513 } 508 }
514 do { 509
515 if (is_kexec_kdump) { 510 DBG("Adding: %llx -> %llx\n", base, size);
516 base = dt_mem_next_cell(dt_root_addr_cells, 511 memblock_add(base, size);
517 &usm); 512 } while (--rngs);
518 size = dt_mem_next_cell(dt_root_size_cells,
519 &usm);
520 }
521 if (iommu_is_off) {
522 if (base >= 0x80000000ul)
523 continue;
524 if ((base + size) > 0x80000000ul)
525 size = 0x80000000ul - base;
526 }
527 memblock_add(base, size);
528 } while (--rngs);
529 }
530 memblock_dump_all();
531 return 0;
532} 513}
533#else
534#define early_init_dt_scan_drconf_memory(node) 0
535#endif /* CONFIG_PPC_PSERIES */ 514#endif /* CONFIG_PPC_PSERIES */
536 515
537static int __init early_init_dt_scan_memory_ppc(unsigned long node, 516static int __init early_init_dt_scan_memory_ppc(unsigned long node,
538 const char *uname, 517 const char *uname,
539 int depth, void *data) 518 int depth, void *data)
540{ 519{
520#ifdef CONFIG_PPC_PSERIES
541 if (depth == 1 && 521 if (depth == 1 &&
542 strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0) 522 strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0) {
543 return early_init_dt_scan_drconf_memory(node); 523 walk_drmem_lmbs_early(node, early_init_drmem_lmb);
524 return 0;
525 }
526#endif
544 527
545 return early_init_dt_scan_memory(node, uname, depth, data); 528 return early_init_dt_scan_memory(node, uname, depth, data);
546} 529}
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 02190e90c7ae..adf044daafd7 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -869,10 +869,12 @@ struct ibm_arch_vec __cacheline_aligned ibm_architecture_vec = {
869 .reserved2 = 0, 869 .reserved2 = 0,
870 .reserved3 = 0, 870 .reserved3 = 0,
871 .subprocessors = 1, 871 .subprocessors = 1,
872 .byte22 = OV5_FEAT(OV5_DRMEM_V2),
872 .intarch = 0, 873 .intarch = 0,
873 .mmu = 0, 874 .mmu = 0,
874 .hash_ext = 0, 875 .hash_ext = 0,
875 .radix_ext = 0, 876 .radix_ext = 0,
877 .byte22 = OV5_FEAT(OV5_DRC_INFO),
876 }, 878 },
877 879
878 /* option vector 6: IBM PAPR hints */ 880 /* option vector 6: IBM PAPR hints */
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index f52ad5bb7109..ca72d7391d40 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -35,6 +35,7 @@
35#include <linux/context_tracking.h> 35#include <linux/context_tracking.h>
36 36
37#include <linux/uaccess.h> 37#include <linux/uaccess.h>
38#include <linux/pkeys.h>
38#include <asm/page.h> 39#include <asm/page.h>
39#include <asm/pgtable.h> 40#include <asm/pgtable.h>
40#include <asm/switch_to.h> 41#include <asm/switch_to.h>
@@ -283,6 +284,18 @@ int ptrace_get_reg(struct task_struct *task, int regno, unsigned long *data)
283 if (regno == PT_DSCR) 284 if (regno == PT_DSCR)
284 return get_user_dscr(task, data); 285 return get_user_dscr(task, data);
285 286
287#ifdef CONFIG_PPC64
288 /*
289 * softe copies paca->irq_soft_mask variable state. Since irq_soft_mask is
290 * no more used as a flag, lets force usr to alway see the softe value as 1
291 * which means interrupts are not soft disabled.
292 */
293 if (regno == PT_SOFTE) {
294 *data = 1;
295 return 0;
296 }
297#endif
298
286 if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long))) { 299 if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long))) {
287 *data = ((unsigned long *)task->thread.regs)[regno]; 300 *data = ((unsigned long *)task->thread.regs)[regno];
288 return 0; 301 return 0;
@@ -1775,6 +1788,61 @@ static int pmu_set(struct task_struct *target,
1775 return ret; 1788 return ret;
1776} 1789}
1777#endif 1790#endif
1791
1792#ifdef CONFIG_PPC_MEM_KEYS
1793static int pkey_active(struct task_struct *target,
1794 const struct user_regset *regset)
1795{
1796 if (!arch_pkeys_enabled())
1797 return -ENODEV;
1798
1799 return regset->n;
1800}
1801
1802static int pkey_get(struct task_struct *target,
1803 const struct user_regset *regset,
1804 unsigned int pos, unsigned int count,
1805 void *kbuf, void __user *ubuf)
1806{
1807 BUILD_BUG_ON(TSO(amr) + sizeof(unsigned long) != TSO(iamr));
1808 BUILD_BUG_ON(TSO(iamr) + sizeof(unsigned long) != TSO(uamor));
1809
1810 if (!arch_pkeys_enabled())
1811 return -ENODEV;
1812
1813 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
1814 &target->thread.amr, 0,
1815 ELF_NPKEY * sizeof(unsigned long));
1816}
1817
1818static int pkey_set(struct task_struct *target,
1819 const struct user_regset *regset,
1820 unsigned int pos, unsigned int count,
1821 const void *kbuf, const void __user *ubuf)
1822{
1823 u64 new_amr;
1824 int ret;
1825
1826 if (!arch_pkeys_enabled())
1827 return -ENODEV;
1828
1829 /* Only the AMR can be set from userspace */
1830 if (pos != 0 || count != sizeof(new_amr))
1831 return -EINVAL;
1832
1833 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
1834 &new_amr, 0, sizeof(new_amr));
1835 if (ret)
1836 return ret;
1837
1838 /* UAMOR determines which bits of the AMR can be set from userspace. */
1839 target->thread.amr = (new_amr & target->thread.uamor) |
1840 (target->thread.amr & ~target->thread.uamor);
1841
1842 return 0;
1843}
1844#endif /* CONFIG_PPC_MEM_KEYS */
1845
1778/* 1846/*
1779 * These are our native regset flavors. 1847 * These are our native regset flavors.
1780 */ 1848 */
@@ -1809,6 +1877,9 @@ enum powerpc_regset {
1809 REGSET_EBB, /* EBB registers */ 1877 REGSET_EBB, /* EBB registers */
1810 REGSET_PMR, /* Performance Monitor Registers */ 1878 REGSET_PMR, /* Performance Monitor Registers */
1811#endif 1879#endif
1880#ifdef CONFIG_PPC_MEM_KEYS
1881 REGSET_PKEY, /* AMR register */
1882#endif
1812}; 1883};
1813 1884
1814static const struct user_regset native_regsets[] = { 1885static const struct user_regset native_regsets[] = {
@@ -1914,6 +1985,13 @@ static const struct user_regset native_regsets[] = {
1914 .active = pmu_active, .get = pmu_get, .set = pmu_set 1985 .active = pmu_active, .get = pmu_get, .set = pmu_set
1915 }, 1986 },
1916#endif 1987#endif
1988#ifdef CONFIG_PPC_MEM_KEYS
1989 [REGSET_PKEY] = {
1990 .core_note_type = NT_PPC_PKEY, .n = ELF_NPKEY,
1991 .size = sizeof(u64), .align = sizeof(u64),
1992 .active = pkey_active, .get = pkey_get, .set = pkey_set
1993 },
1994#endif
1917}; 1995};
1918 1996
1919static const struct user_regset_view user_ppc_native_view = { 1997static const struct user_regset_view user_ppc_native_view = {
diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c
index c8c5f3a550c2..fb070d8cad07 100644
--- a/arch/powerpc/kernel/rtas-proc.c
+++ b/arch/powerpc/kernel/rtas-proc.c
@@ -261,19 +261,19 @@ static int __init proc_rtas_init(void)
261 if (rtas_node == NULL) 261 if (rtas_node == NULL)
262 return -ENODEV; 262 return -ENODEV;
263 263
264 proc_create("powerpc/rtas/progress", S_IRUGO|S_IWUSR, NULL, 264 proc_create("powerpc/rtas/progress", 0644, NULL,
265 &ppc_rtas_progress_operations); 265 &ppc_rtas_progress_operations);
266 proc_create("powerpc/rtas/clock", S_IRUGO|S_IWUSR, NULL, 266 proc_create("powerpc/rtas/clock", 0644, NULL,
267 &ppc_rtas_clock_operations); 267 &ppc_rtas_clock_operations);
268 proc_create("powerpc/rtas/poweron", S_IWUSR|S_IRUGO, NULL, 268 proc_create("powerpc/rtas/poweron", 0644, NULL,
269 &ppc_rtas_poweron_operations); 269 &ppc_rtas_poweron_operations);
270 proc_create("powerpc/rtas/sensors", S_IRUGO, NULL, 270 proc_create("powerpc/rtas/sensors", 0444, NULL,
271 &ppc_rtas_sensors_operations); 271 &ppc_rtas_sensors_operations);
272 proc_create("powerpc/rtas/frequency", S_IWUSR|S_IRUGO, NULL, 272 proc_create("powerpc/rtas/frequency", 0644, NULL,
273 &ppc_rtas_tone_freq_operations); 273 &ppc_rtas_tone_freq_operations);
274 proc_create("powerpc/rtas/volume", S_IWUSR|S_IRUGO, NULL, 274 proc_create("powerpc/rtas/volume", 0644, NULL,
275 &ppc_rtas_tone_volume_operations); 275 &ppc_rtas_tone_volume_operations);
276 proc_create("powerpc/rtas/rmo_buffer", S_IRUSR, NULL, 276 proc_create("powerpc/rtas/rmo_buffer", 0400, NULL,
277 &ppc_rtas_rmo_buf_ops); 277 &ppc_rtas_rmo_buf_ops);
278 return 0; 278 return 0;
279} 279}
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c
index f6f6a8a5103a..10fabae2574d 100644
--- a/arch/powerpc/kernel/rtas_flash.c
+++ b/arch/powerpc/kernel/rtas_flash.c
@@ -727,7 +727,7 @@ static int __init rtas_flash_init(void)
727 const struct rtas_flash_file *f = &rtas_flash_files[i]; 727 const struct rtas_flash_file *f = &rtas_flash_files[i];
728 int token; 728 int token;
729 729
730 if (!proc_create(f->filename, S_IRUSR | S_IWUSR, NULL, &f->fops)) 730 if (!proc_create(f->filename, 0600, NULL, &f->fops))
731 goto enomem; 731 goto enomem;
732 732
733 /* 733 /*
diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
index 1da8b7d8c6ca..fc600a8b1e77 100644
--- a/arch/powerpc/kernel/rtasd.c
+++ b/arch/powerpc/kernel/rtasd.c
@@ -581,7 +581,7 @@ static int __init rtas_init(void)
581 if (!rtas_log_buf) 581 if (!rtas_log_buf)
582 return -ENODEV; 582 return -ENODEV;
583 583
584 entry = proc_create("powerpc/rtas/error_log", S_IRUSR, NULL, 584 entry = proc_create("powerpc/rtas/error_log", 0400, NULL,
585 &proc_rtas_log_operations); 585 &proc_rtas_log_operations);
586 if (!entry) 586 if (!entry)
587 printk(KERN_ERR "Failed to create error_log proc entry\n"); 587 printk(KERN_ERR "Failed to create error_log proc entry\n");
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 3f33869c6486..d73ec518ef80 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -346,10 +346,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
346 loops_per_jiffy / (500000/HZ), 346 loops_per_jiffy / (500000/HZ),
347 (loops_per_jiffy / (5000/HZ)) % 100); 347 (loops_per_jiffy / (5000/HZ)) % 100);
348#endif 348#endif
349
350#ifdef CONFIG_SMP
351 seq_printf(m, "\n"); 349 seq_printf(m, "\n");
352#endif 350
353 /* If this is the last cpu, print the summary */ 351 /* If this is the last cpu, print the summary */
354 if (cpumask_next(cpu_id, cpu_online_mask) >= nr_cpu_ids) 352 if (cpumask_next(cpu_id, cpu_online_mask) >= nr_cpu_ids)
355 show_cpuinfo_summary(m); 353 show_cpuinfo_summary(m);
@@ -379,10 +377,10 @@ static void c_stop(struct seq_file *m, void *v)
379} 377}
380 378
381const struct seq_operations cpuinfo_op = { 379const struct seq_operations cpuinfo_op = {
382 .start =c_start, 380 .start = c_start,
383 .next = c_next, 381 .next = c_next,
384 .stop = c_stop, 382 .stop = c_stop,
385 .show = show_cpuinfo, 383 .show = show_cpuinfo,
386}; 384};
387 385
388void __init check_for_initrd(void) 386void __init check_for_initrd(void)
@@ -459,13 +457,13 @@ static void __init cpu_init_thread_core_maps(int tpc)
459 */ 457 */
460void __init smp_setup_cpu_maps(void) 458void __init smp_setup_cpu_maps(void)
461{ 459{
462 struct device_node *dn = NULL; 460 struct device_node *dn;
463 int cpu = 0; 461 int cpu = 0;
464 int nthreads = 1; 462 int nthreads = 1;
465 463
466 DBG("smp_setup_cpu_maps()\n"); 464 DBG("smp_setup_cpu_maps()\n");
467 465
468 while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < nr_cpu_ids) { 466 for_each_node_by_type(dn, "cpu") {
469 const __be32 *intserv; 467 const __be32 *intserv;
470 __be32 cpu_be; 468 __be32 cpu_be;
471 int j, len; 469 int j, len;
@@ -505,6 +503,11 @@ void __init smp_setup_cpu_maps(void)
505 set_cpu_possible(cpu, true); 503 set_cpu_possible(cpu, true);
506 cpu++; 504 cpu++;
507 } 505 }
506
507 if (cpu >= nr_cpu_ids) {
508 of_node_put(dn);
509 break;
510 }
508 } 511 }
509 512
510 /* If no SMT supported, nthreads is forced to 1 */ 513 /* If no SMT supported, nthreads is forced to 1 */
diff --git a/arch/powerpc/kernel/setup.h b/arch/powerpc/kernel/setup.h
index 21c18071d9d5..3fc11e30308f 100644
--- a/arch/powerpc/kernel/setup.h
+++ b/arch/powerpc/kernel/setup.h
@@ -51,6 +51,10 @@ void record_spr_defaults(void);
51static inline void record_spr_defaults(void) { }; 51static inline void record_spr_defaults(void) { };
52#endif 52#endif
53 53
54#ifdef CONFIG_PPC64
55u64 ppc64_bolted_size(void);
56#endif
57
54/* 58/*
55 * Having this in kvm_ppc.h makes include dependencies too 59 * Having this in kvm_ppc.h makes include dependencies too
56 * tricky to solve for setup-common.c so have it here. 60 * tricky to solve for setup-common.c so have it here.
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index e67413f4a8f0..c388cc3357fa 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -10,8 +10,6 @@
10 * 2 of the License, or (at your option) any later version. 10 * 2 of the License, or (at your option) any later version.
11 */ 11 */
12 12
13#define DEBUG
14
15#include <linux/export.h> 13#include <linux/export.h>
16#include <linux/string.h> 14#include <linux/string.h>
17#include <linux/sched.h> 15#include <linux/sched.h>
@@ -69,6 +67,7 @@
69#include <asm/livepatch.h> 67#include <asm/livepatch.h>
70#include <asm/opal.h> 68#include <asm/opal.h>
71#include <asm/cputhreads.h> 69#include <asm/cputhreads.h>
70#include <asm/hw_irq.h>
72 71
73#include "setup.h" 72#include "setup.h"
74 73
@@ -190,6 +189,8 @@ static void __init fixup_boot_paca(void)
190 get_paca()->cpu_start = 1; 189 get_paca()->cpu_start = 1;
191 /* Allow percpu accesses to work until we setup percpu data */ 190 /* Allow percpu accesses to work until we setup percpu data */
192 get_paca()->data_offset = 0; 191 get_paca()->data_offset = 0;
192 /* Mark interrupts disabled in PACA */
193 irq_soft_mask_set(IRQS_DISABLED);
193} 194}
194 195
195static void __init configure_exceptions(void) 196static void __init configure_exceptions(void)
@@ -352,7 +353,7 @@ void __init early_setup(unsigned long dt_ptr)
352void early_setup_secondary(void) 353void early_setup_secondary(void)
353{ 354{
354 /* Mark interrupts disabled in PACA */ 355 /* Mark interrupts disabled in PACA */
355 get_paca()->soft_enabled = 0; 356 irq_soft_mask_set(IRQS_DISABLED);
356 357
357 /* Initialize the hash table or TLB handling */ 358 /* Initialize the hash table or TLB handling */
358 early_init_mmu_secondary(); 359 early_init_mmu_secondary();
@@ -568,25 +569,31 @@ void __init initialize_cache_info(void)
568 DBG(" <- initialize_cache_info()\n"); 569 DBG(" <- initialize_cache_info()\n");
569} 570}
570 571
571/* This returns the limit below which memory accesses to the linear 572/*
572 * mapping are guarnateed not to cause a TLB or SLB miss. This is 573 * This returns the limit below which memory accesses to the linear
573 * used to allocate interrupt or emergency stacks for which our 574 * mapping are guarnateed not to cause an architectural exception (e.g.,
574 * exception entry path doesn't deal with being interrupted. 575 * TLB or SLB miss fault).
576 *
577 * This is used to allocate PACAs and various interrupt stacks that
578 * that are accessed early in interrupt handlers that must not cause
579 * re-entrant interrupts.
575 */ 580 */
576static __init u64 safe_stack_limit(void) 581__init u64 ppc64_bolted_size(void)
577{ 582{
578#ifdef CONFIG_PPC_BOOK3E 583#ifdef CONFIG_PPC_BOOK3E
579 /* Freescale BookE bolts the entire linear mapping */ 584 /* Freescale BookE bolts the entire linear mapping */
580 if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) 585 /* XXX: BookE ppc64_rma_limit setup seems to disagree? */
586 if (early_mmu_has_feature(MMU_FTR_TYPE_FSL_E))
581 return linear_map_top; 587 return linear_map_top;
582 /* Other BookE, we assume the first GB is bolted */ 588 /* Other BookE, we assume the first GB is bolted */
583 return 1ul << 30; 589 return 1ul << 30;
584#else 590#else
591 /* BookS radix, does not take faults on linear mapping */
585 if (early_radix_enabled()) 592 if (early_radix_enabled())
586 return ULONG_MAX; 593 return ULONG_MAX;
587 594
588 /* BookS, the first segment is bolted */ 595 /* BookS hash, the first segment is bolted */
589 if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) 596 if (early_mmu_has_feature(MMU_FTR_1T_SEGMENT))
590 return 1UL << SID_SHIFT_1T; 597 return 1UL << SID_SHIFT_1T;
591 return 1UL << SID_SHIFT; 598 return 1UL << SID_SHIFT;
592#endif 599#endif
@@ -594,7 +601,7 @@ static __init u64 safe_stack_limit(void)
594 601
595void __init irqstack_early_init(void) 602void __init irqstack_early_init(void)
596{ 603{
597 u64 limit = safe_stack_limit(); 604 u64 limit = ppc64_bolted_size();
598 unsigned int i; 605 unsigned int i;
599 606
600 /* 607 /*
@@ -679,7 +686,7 @@ void __init emergency_stack_init(void)
679 * initialized in kernel/irq.c. These are initialized here in order 686 * initialized in kernel/irq.c. These are initialized here in order
680 * to have emergency stacks available as early as possible. 687 * to have emergency stacks available as early as possible.
681 */ 688 */
682 limit = min(safe_stack_limit(), ppc64_rma_size); 689 limit = min(ppc64_bolted_size(), ppc64_rma_size);
683 690
684 for_each_possible_cpu(i) { 691 for_each_possible_cpu(i) {
685 struct thread_info *ti; 692 struct thread_info *ti;
@@ -857,7 +864,7 @@ static void init_fallback_flush(void)
857 int cpu; 864 int cpu;
858 865
859 l1d_size = ppc64_caches.l1d.size; 866 l1d_size = ppc64_caches.l1d.size;
860 limit = min(safe_stack_limit(), ppc64_rma_size); 867 limit = min(ppc64_bolted_size(), ppc64_rma_size);
861 868
862 /* 869 /*
863 * Align to L1d size, and size it at 2x L1d size, to catch possible 870 * Align to L1d size, and size it at 2x L1d size, to catch possible
@@ -868,19 +875,8 @@ static void init_fallback_flush(void)
868 memset(l1d_flush_fallback_area, 0, l1d_size * 2); 875 memset(l1d_flush_fallback_area, 0, l1d_size * 2);
869 876
870 for_each_possible_cpu(cpu) { 877 for_each_possible_cpu(cpu) {
871 /*
872 * The fallback flush is currently coded for 8-way
873 * associativity. Different associativity is possible, but it
874 * will be treated as 8-way and may not evict the lines as
875 * effectively.
876 *
877 * 128 byte lines are mandatory.
878 */
879 u64 c = l1d_size / 8;
880
881 paca[cpu].rfi_flush_fallback_area = l1d_flush_fallback_area; 878 paca[cpu].rfi_flush_fallback_area = l1d_flush_fallback_area;
882 paca[cpu].l1d_flush_congruence = c; 879 paca[cpu].l1d_flush_size = l1d_size;
883 paca[cpu].l1d_flush_sets = c / 128;
884 } 880 }
885} 881}
886 882
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index aded81169648..a46de0035214 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -111,12 +111,20 @@ static inline int save_general_regs(struct pt_regs *regs,
111{ 111{
112 elf_greg_t64 *gregs = (elf_greg_t64 *)regs; 112 elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
113 int i; 113 int i;
114 /* Force usr to alway see softe as 1 (interrupts enabled) */
115 elf_greg_t64 softe = 0x1;
114 116
115 WARN_ON(!FULL_REGS(regs)); 117 WARN_ON(!FULL_REGS(regs));
116 118
117 for (i = 0; i <= PT_RESULT; i ++) { 119 for (i = 0; i <= PT_RESULT; i ++) {
118 if (i == 14 && !FULL_REGS(regs)) 120 if (i == 14 && !FULL_REGS(regs))
119 i = 32; 121 i = 32;
122 if ( i == PT_SOFTE) {
123 if(__put_user((unsigned int)softe, &frame->mc_gregs[i]))
124 return -EFAULT;
125 else
126 continue;
127 }
120 if (__put_user((unsigned int)gregs[i], &frame->mc_gregs[i])) 128 if (__put_user((unsigned int)gregs[i], &frame->mc_gregs[i]))
121 return -EFAULT; 129 return -EFAULT;
122 } 130 }
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 4b9ca3570344..720117690822 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -110,6 +110,8 @@ static long setup_sigcontext(struct sigcontext __user *sc,
110 struct pt_regs *regs = tsk->thread.regs; 110 struct pt_regs *regs = tsk->thread.regs;
111 unsigned long msr = regs->msr; 111 unsigned long msr = regs->msr;
112 long err = 0; 112 long err = 0;
113 /* Force usr to alway see softe as 1 (interrupts enabled) */
114 unsigned long softe = 0x1;
113 115
114 BUG_ON(tsk != current); 116 BUG_ON(tsk != current);
115 117
@@ -169,6 +171,7 @@ static long setup_sigcontext(struct sigcontext __user *sc,
169 WARN_ON(!FULL_REGS(regs)); 171 WARN_ON(!FULL_REGS(regs));
170 err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE); 172 err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE);
171 err |= __put_user(msr, &sc->gp_regs[PT_MSR]); 173 err |= __put_user(msr, &sc->gp_regs[PT_MSR]);
174 err |= __put_user(softe, &sc->gp_regs[PT_SOFTE]);
172 err |= __put_user(signr, &sc->signal); 175 err |= __put_user(signr, &sc->signal);
173 err |= __put_user(handler, &sc->handler); 176 err |= __put_user(handler, &sc->handler);
174 if (set != NULL) 177 if (set != NULL)
@@ -207,7 +210,7 @@ static long setup_tm_sigcontexts(struct sigcontext __user *sc,
207 elf_vrreg_t __user *tm_v_regs = sigcontext_vmx_regs(tm_sc); 210 elf_vrreg_t __user *tm_v_regs = sigcontext_vmx_regs(tm_sc);
208#endif 211#endif
209 struct pt_regs *regs = tsk->thread.regs; 212 struct pt_regs *regs = tsk->thread.regs;
210 unsigned long msr = tsk->thread.ckpt_regs.msr; 213 unsigned long msr = tsk->thread.regs->msr;
211 long err = 0; 214 long err = 0;
212 215
213 BUG_ON(tsk != current); 216 BUG_ON(tsk != current);
@@ -216,6 +219,12 @@ static long setup_tm_sigcontexts(struct sigcontext __user *sc,
216 219
217 WARN_ON(tm_suspend_disabled); 220 WARN_ON(tm_suspend_disabled);
218 221
222 /* Restore checkpointed FP, VEC, and VSX bits from ckpt_regs as
223 * it contains the correct FP, VEC, VSX state after we treclaimed
224 * the transaction and giveup_all() was called on reclaiming.
225 */
226 msr |= tsk->thread.ckpt_regs.msr & (MSR_FP | MSR_VEC | MSR_VSX);
227
219 /* Remove TM bits from thread's MSR. The MSR in the sigcontext 228 /* Remove TM bits from thread's MSR. The MSR in the sigcontext
220 * just indicates to userland that we were doing a transaction, but we 229 * just indicates to userland that we were doing a transaction, but we
221 * don't want to return in transactional state. This also ensures 230 * don't want to return in transactional state. This also ensures
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index e0a4c1f82e25..bbe7634b3a43 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -543,7 +543,25 @@ void smp_send_debugger_break(void)
543#ifdef CONFIG_KEXEC_CORE 543#ifdef CONFIG_KEXEC_CORE
544void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *)) 544void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
545{ 545{
546 int cpu;
547
546 smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, crash_ipi_callback, 1000000); 548 smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, crash_ipi_callback, 1000000);
549 if (kdump_in_progress() && crash_wake_offline) {
550 for_each_present_cpu(cpu) {
551 if (cpu_online(cpu))
552 continue;
553 /*
554 * crash_ipi_callback will wait for
555 * all cpus, including offline CPUs.
556 * We don't care about nmi_ipi_function.
557 * Offline cpus will jump straight into
558 * crash_ipi_callback, we can skip the
559 * entire NMI dance and waiting for
560 * cpus to clear pending mask, etc.
561 */
562 do_smp_send_nmi_ipi(cpu);
563 }
564 }
547} 565}
548#endif 566#endif
549 567
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index b8d4a1dac39f..5a8bfee6e187 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -485,6 +485,7 @@ SYSFS_PMCSETUP(mmcra, SPRN_MMCRA);
485SYSFS_SPRSETUP(purr, SPRN_PURR); 485SYSFS_SPRSETUP(purr, SPRN_PURR);
486SYSFS_SPRSETUP(spurr, SPRN_SPURR); 486SYSFS_SPRSETUP(spurr, SPRN_SPURR);
487SYSFS_SPRSETUP(pir, SPRN_PIR); 487SYSFS_SPRSETUP(pir, SPRN_PIR);
488SYSFS_SPRSETUP(tscr, SPRN_TSCR);
488 489
489/* 490/*
490 Lets only enable read for phyp resources and 491 Lets only enable read for phyp resources and
@@ -495,6 +496,7 @@ static DEVICE_ATTR(mmcra, 0600, show_mmcra, store_mmcra);
495static DEVICE_ATTR(spurr, 0400, show_spurr, NULL); 496static DEVICE_ATTR(spurr, 0400, show_spurr, NULL);
496static DEVICE_ATTR(purr, 0400, show_purr, store_purr); 497static DEVICE_ATTR(purr, 0400, show_purr, store_purr);
497static DEVICE_ATTR(pir, 0400, show_pir, NULL); 498static DEVICE_ATTR(pir, 0400, show_pir, NULL);
499static DEVICE_ATTR(tscr, 0600, show_tscr, store_tscr);
498 500
499/* 501/*
500 * This is the system wide DSCR register default value. Any 502 * This is the system wide DSCR register default value. Any
@@ -785,6 +787,9 @@ static int register_cpu_online(unsigned int cpu)
785 787
786 if (cpu_has_feature(CPU_FTR_PPCAS_ARCH_V2)) 788 if (cpu_has_feature(CPU_FTR_PPCAS_ARCH_V2))
787 device_create_file(s, &dev_attr_pir); 789 device_create_file(s, &dev_attr_pir);
790
791 if (cpu_has_feature(CPU_FTR_ARCH_206))
792 device_create_file(s, &dev_attr_tscr);
788#endif /* CONFIG_PPC64 */ 793#endif /* CONFIG_PPC64 */
789 794
790#ifdef CONFIG_PPC_FSL_BOOK3E 795#ifdef CONFIG_PPC_FSL_BOOK3E
@@ -867,6 +872,9 @@ static int unregister_cpu_online(unsigned int cpu)
867 872
868 if (cpu_has_feature(CPU_FTR_PPCAS_ARCH_V2)) 873 if (cpu_has_feature(CPU_FTR_PPCAS_ARCH_V2))
869 device_remove_file(s, &dev_attr_pir); 874 device_remove_file(s, &dev_attr_pir);
875
876 if (cpu_has_feature(CPU_FTR_ARCH_206))
877 device_remove_file(s, &dev_attr_tscr);
870#endif /* CONFIG_PPC64 */ 878#endif /* CONFIG_PPC64 */
871 879
872#ifdef CONFIG_PPC_FSL_BOOK3E 880#ifdef CONFIG_PPC_FSL_BOOK3E
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index fe6f3a285455..a32823dcd9a4 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -244,7 +244,7 @@ static u64 scan_dispatch_log(u64 stop_tb)
244void accumulate_stolen_time(void) 244void accumulate_stolen_time(void)
245{ 245{
246 u64 sst, ust; 246 u64 sst, ust;
247 u8 save_soft_enabled = local_paca->soft_enabled; 247 unsigned long save_irq_soft_mask = irq_soft_mask_return();
248 struct cpu_accounting_data *acct = &local_paca->accounting; 248 struct cpu_accounting_data *acct = &local_paca->accounting;
249 249
250 /* We are called early in the exception entry, before 250 /* We are called early in the exception entry, before
@@ -253,7 +253,7 @@ void accumulate_stolen_time(void)
253 * needs to reflect that so various debug stuff doesn't 253 * needs to reflect that so various debug stuff doesn't
254 * complain 254 * complain
255 */ 255 */
256 local_paca->soft_enabled = 0; 256 irq_soft_mask_set(IRQS_DISABLED);
257 257
258 sst = scan_dispatch_log(acct->starttime_user); 258 sst = scan_dispatch_log(acct->starttime_user);
259 ust = scan_dispatch_log(acct->starttime); 259 ust = scan_dispatch_log(acct->starttime);
@@ -261,7 +261,7 @@ void accumulate_stolen_time(void)
261 acct->utime -= ust; 261 acct->utime -= ust;
262 acct->steal_time += ust + sst; 262 acct->steal_time += ust + sst;
263 263
264 local_paca->soft_enabled = save_soft_enabled; 264 irq_soft_mask_set(save_irq_soft_mask);
265} 265}
266 266
267static inline u64 calculate_stolen_time(u64 stop_tb) 267static inline u64 calculate_stolen_time(u64 stop_tb)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index c93f1e6a9fff..1e48d157196a 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -20,6 +20,7 @@
20#include <linux/sched/debug.h> 20#include <linux/sched/debug.h>
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/mm.h> 22#include <linux/mm.h>
23#include <linux/pkeys.h>
23#include <linux/stddef.h> 24#include <linux/stddef.h>
24#include <linux/unistd.h> 25#include <linux/unistd.h>
25#include <linux/ptrace.h> 26#include <linux/ptrace.h>
@@ -38,6 +39,8 @@
38#include <linux/ratelimit.h> 39#include <linux/ratelimit.h>
39#include <linux/context_tracking.h> 40#include <linux/context_tracking.h>
40#include <linux/smp.h> 41#include <linux/smp.h>
42#include <linux/console.h>
43#include <linux/kmsg_dump.h>
41 44
42#include <asm/emulated_ops.h> 45#include <asm/emulated_ops.h>
43#include <asm/pgtable.h> 46#include <asm/pgtable.h>
@@ -142,6 +145,28 @@ static int die_owner = -1;
142static unsigned int die_nest_count; 145static unsigned int die_nest_count;
143static int die_counter; 146static int die_counter;
144 147
148extern void panic_flush_kmsg_start(void)
149{
150 /*
151 * These are mostly taken from kernel/panic.c, but tries to do
152 * relatively minimal work. Don't use delay functions (TB may
153 * be broken), don't crash dump (need to set a firmware log),
154 * don't run notifiers. We do want to get some information to
155 * Linux console.
156 */
157 console_verbose();
158 bust_spinlocks(1);
159}
160
161extern void panic_flush_kmsg_end(void)
162{
163 printk_safe_flush_on_panic();
164 kmsg_dump(KMSG_DUMP_PANIC);
165 bust_spinlocks(0);
166 debug_locks_off();
167 console_flush_on_panic();
168}
169
145static unsigned long oops_begin(struct pt_regs *regs) 170static unsigned long oops_begin(struct pt_regs *regs)
146{ 171{
147 int cpu; 172 int cpu;
@@ -266,7 +291,9 @@ void user_single_step_siginfo(struct task_struct *tsk,
266 info->si_addr = (void __user *)regs->nip; 291 info->si_addr = (void __user *)regs->nip;
267} 292}
268 293
269void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) 294
295void _exception_pkey(int signr, struct pt_regs *regs, int code,
296 unsigned long addr, int key)
270{ 297{
271 siginfo_t info; 298 siginfo_t info;
272 const char fmt32[] = KERN_INFO "%s[%d]: unhandled signal %d " \ 299 const char fmt32[] = KERN_INFO "%s[%d]: unhandled signal %d " \
@@ -289,13 +316,27 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
289 local_irq_enable(); 316 local_irq_enable();
290 317
291 current->thread.trap_nr = code; 318 current->thread.trap_nr = code;
319
320 /*
321 * Save all the pkey registers AMR/IAMR/UAMOR. Eg: Core dumps need
322 * to capture the content, if the task gets killed.
323 */
324 thread_pkey_regs_save(&current->thread);
325
292 memset(&info, 0, sizeof(info)); 326 memset(&info, 0, sizeof(info));
293 info.si_signo = signr; 327 info.si_signo = signr;
294 info.si_code = code; 328 info.si_code = code;
295 info.si_addr = (void __user *) addr; 329 info.si_addr = (void __user *) addr;
330 info.si_pkey = key;
331
296 force_sig_info(signr, &info, current); 332 force_sig_info(signr, &info, current);
297} 333}
298 334
335void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
336{
337 _exception_pkey(signr, regs, code, addr, 0);
338}
339
299void system_reset_exception(struct pt_regs *regs) 340void system_reset_exception(struct pt_regs *regs)
300{ 341{
301 /* 342 /*
@@ -337,7 +378,7 @@ void system_reset_exception(struct pt_regs *regs)
337 * No debugger or crash dump registered, print logs then 378 * No debugger or crash dump registered, print logs then
338 * panic. 379 * panic.
339 */ 380 */
340 __die("System Reset", regs, SIGABRT); 381 die("System Reset", regs, SIGABRT);
341 382
342 mdelay(2*MSEC_PER_SEC); /* Wait a little while for others to print */ 383 mdelay(2*MSEC_PER_SEC); /* Wait a little while for others to print */
343 add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); 384 add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
@@ -1564,7 +1605,7 @@ void facility_unavailable_exception(struct pt_regs *regs)
1564 u8 status; 1605 u8 status;
1565 bool hv; 1606 bool hv;
1566 1607
1567 hv = (regs->trap == 0xf80); 1608 hv = (TRAP(regs) == 0xf80);
1568 if (hv) 1609 if (hv)
1569 value = mfspr(SPRN_HFSCR); 1610 value = mfspr(SPRN_HFSCR);
1570 else 1611 else
@@ -2113,13 +2154,13 @@ static int __init ppc_warn_emulated_init(void)
2113 if (!dir) 2154 if (!dir)
2114 return -ENOMEM; 2155 return -ENOMEM;
2115 2156
2116 d = debugfs_create_u32("do_warn", S_IRUGO | S_IWUSR, dir, 2157 d = debugfs_create_u32("do_warn", 0644, dir,
2117 &ppc_warn_emulated); 2158 &ppc_warn_emulated);
2118 if (!d) 2159 if (!d)
2119 goto fail; 2160 goto fail;
2120 2161
2121 for (i = 0; i < sizeof(ppc_emulated)/sizeof(*entries); i++) { 2162 for (i = 0; i < sizeof(ppc_emulated)/sizeof(*entries); i++) {
2122 d = debugfs_create_u32(entries[i].name, S_IRUGO | S_IWUSR, dir, 2163 d = debugfs_create_u32(entries[i].name, 0644, dir,
2123 (u32 *)&entries[i].val.counter); 2164 (u32 *)&entries[i].val.counter);
2124 if (!d) 2165 if (!d)
2125 goto fail; 2166 goto fail;
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S
index 382021324883..c002adcc694c 100644
--- a/arch/powerpc/kernel/vdso64/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso64/gettimeofday.S
@@ -64,6 +64,12 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
64 cmpwi cr0,r3,CLOCK_REALTIME 64 cmpwi cr0,r3,CLOCK_REALTIME
65 cmpwi cr1,r3,CLOCK_MONOTONIC 65 cmpwi cr1,r3,CLOCK_MONOTONIC
66 cror cr0*4+eq,cr0*4+eq,cr1*4+eq 66 cror cr0*4+eq,cr0*4+eq,cr1*4+eq
67
68 cmpwi cr5,r3,CLOCK_REALTIME_COARSE
69 cmpwi cr6,r3,CLOCK_MONOTONIC_COARSE
70 cror cr5*4+eq,cr5*4+eq,cr6*4+eq
71
72 cror cr0*4+eq,cr0*4+eq,cr5*4+eq
67 bne cr0,99f 73 bne cr0,99f
68 74
69 mflr r12 /* r12 saves lr */ 75 mflr r12 /* r12 saves lr */
@@ -72,6 +78,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
72 bl V_LOCAL_FUNC(__get_datapage) /* get data page */ 78 bl V_LOCAL_FUNC(__get_datapage) /* get data page */
73 lis r7,NSEC_PER_SEC@h /* want nanoseconds */ 79 lis r7,NSEC_PER_SEC@h /* want nanoseconds */
74 ori r7,r7,NSEC_PER_SEC@l 80 ori r7,r7,NSEC_PER_SEC@l
81 beq cr5,70f
7550: bl V_LOCAL_FUNC(__do_get_tspec) /* get time from tb & kernel */ 8250: bl V_LOCAL_FUNC(__do_get_tspec) /* get time from tb & kernel */
76 bne cr1,80f /* if not monotonic, all done */ 83 bne cr1,80f /* if not monotonic, all done */
77 84
@@ -97,19 +104,57 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
97 ld r0,CFG_TB_UPDATE_COUNT(r3) 104 ld r0,CFG_TB_UPDATE_COUNT(r3)
98 cmpld cr0,r0,r8 /* check if updated */ 105 cmpld cr0,r0,r8 /* check if updated */
99 bne- 50b 106 bne- 50b
107 b 78f
100 108
101 /* Add wall->monotonic offset and check for overflow or underflow. 109 /*
110 * For coarse clocks we get data directly from the vdso data page, so
111 * we don't need to call __do_get_tspec, but we still need to do the
112 * counter trick.
102 */ 113 */
103 add r4,r4,r6 11470: ld r8,CFG_TB_UPDATE_COUNT(r3)
104 add r5,r5,r9 115 andi. r0,r8,1 /* pending update ? loop */
105 cmpd cr0,r5,r7 116 bne- 70b
106 cmpdi cr1,r5,0 117 add r3,r3,r0 /* r0 is already 0 */
107 blt 1f 118
108 subf r5,r7,r5 119 /*
109 addi r4,r4,1 120 * CLOCK_REALTIME_COARSE, below values are needed for MONOTONIC_COARSE
1101: bge cr1,80f 121 * too
111 addi r4,r4,-1 122 */
112 add r5,r5,r7 123 ld r4,STAMP_XTIME+TSPC64_TV_SEC(r3)
124 ld r5,STAMP_XTIME+TSPC64_TV_NSEC(r3)
125 bne cr6,75f
126
127 /* CLOCK_MONOTONIC_COARSE */
128 lwa r6,WTOM_CLOCK_SEC(r3)
129 lwa r9,WTOM_CLOCK_NSEC(r3)
130
131 /* check if counter has updated */
132 or r0,r6,r9
13375: or r0,r0,r4
134 or r0,r0,r5
135 xor r0,r0,r0
136 add r3,r3,r0
137 ld r0,CFG_TB_UPDATE_COUNT(r3)
138 cmpld cr0,r0,r8 /* check if updated */
139 bne- 70b
140
141 /* Counter has not updated, so continue calculating proper values for
142 * sec and nsec if monotonic coarse, or just return with the proper
143 * values for realtime.
144 */
145 bne cr6,80f
146
147 /* Add wall->monotonic offset and check for overflow or underflow */
14878: add r4,r4,r6
149 add r5,r5,r9
150 cmpd cr0,r5,r7
151 cmpdi cr1,r5,0
152 blt 79f
153 subf r5,r7,r5
154 addi r4,r4,1
15579: bge cr1,80f
156 addi r4,r4,-1
157 add r5,r5,r7
113 158
11480: std r4,TSPC64_TV_SEC(r11) 15980: std r4,TSPC64_TV_SEC(r11)
115 std r5,TSPC64_TV_NSEC(r11) 160 std r5,TSPC64_TV_NSEC(r11)
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 74901a87bf7a..c8af90ff49f0 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -273,6 +273,7 @@ SECTIONS
273#ifdef CONFIG_PPC32 273#ifdef CONFIG_PPC32
274 .data : AT(ADDR(.data) - LOAD_OFFSET) { 274 .data : AT(ADDR(.data) - LOAD_OFFSET) {
275 DATA_DATA 275 DATA_DATA
276 *(.data.rel*)
276 *(.sdata) 277 *(.sdata)
277 *(.sdata2) 278 *(.sdata2)
278 *(.got.plt) *(.got) 279 *(.got.plt) *(.got)
diff --git a/arch/powerpc/kernel/watchdog.c b/arch/powerpc/kernel/watchdog.c
index 87da80ccced1..6256dc3b0087 100644
--- a/arch/powerpc/kernel/watchdog.c
+++ b/arch/powerpc/kernel/watchdog.c
@@ -6,6 +6,9 @@
6 * 6 *
7 * This uses code from arch/sparc/kernel/nmi.c and kernel/watchdog.c 7 * This uses code from arch/sparc/kernel/nmi.c and kernel/watchdog.c
8 */ 8 */
9
10#define pr_fmt(fmt) "watchdog: " fmt
11
9#include <linux/kernel.h> 12#include <linux/kernel.h>
10#include <linux/param.h> 13#include <linux/param.h>
11#include <linux/init.h> 14#include <linux/init.h>
@@ -26,15 +29,45 @@
26#include <asm/paca.h> 29#include <asm/paca.h>
27 30
28/* 31/*
29 * The watchdog has a simple timer that runs on each CPU, once per timer 32 * The powerpc watchdog ensures that each CPU is able to service timers.
30 * period. This is the heartbeat. 33 * The watchdog sets up a simple timer on each CPU to run once per timer
34 * period, and updates a per-cpu timestamp and a "pending" cpumask. This is
35 * the heartbeat.
36 *
37 * Then there are two systems to check that the heartbeat is still running.
38 * The local soft-NMI, and the SMP checker.
39 *
40 * The soft-NMI checker can detect lockups on the local CPU. When interrupts
41 * are disabled with local_irq_disable(), platforms that use soft-masking
42 * can leave hardware interrupts enabled and handle them with a masked
43 * interrupt handler. The masked handler can send the timer interrupt to the
44 * watchdog's soft_nmi_interrupt(), which appears to Linux as an NMI
45 * interrupt, and can be used to detect CPUs stuck with IRQs disabled.
46 *
47 * The soft-NMI checker will compare the heartbeat timestamp for this CPU
48 * with the current time, and take action if the difference exceeds the
49 * watchdog threshold.
50 *
51 * The limitation of the soft-NMI watchdog is that it does not work when
52 * interrupts are hard disabled or otherwise not being serviced. This is
53 * solved by also having a SMP watchdog where all CPUs check all other
54 * CPUs heartbeat.
31 * 55 *
32 * Then there are checks to see if the heartbeat has not triggered on a CPU 56 * The SMP checker can detect lockups on other CPUs. A gobal "pending"
33 * for the panic timeout period. Currently the watchdog only supports an 57 * cpumask is kept, containing all CPUs which enable the watchdog. Each
34 * SMP check, so the heartbeat only turns on when we have 2 or more CPUs. 58 * CPU clears their pending bit in their heartbeat timer. When the bitmask
59 * becomes empty, the last CPU to clear its pending bit updates a global
60 * timestamp and refills the pending bitmask.
35 * 61 *
36 * This is not an NMI watchdog, but Linux uses that name for a generic 62 * In the heartbeat timer, if any CPU notices that the global timestamp has
37 * watchdog in some cases, so NMI gets used in some places. 63 * not been updated for a period exceeding the watchdog threshold, then it
64 * means the CPU(s) with their bit still set in the pending mask have had
65 * their heartbeat stop, and action is taken.
66 *
67 * Some platforms implement true NMI IPIs, which can by used by the SMP
68 * watchdog to detect an unresponsive CPU and pull it out of its stuck
69 * state with the NMI IPI, to get crash/debug data from it. This way the
70 * SMP watchdog can detect hardware interrupts off lockups.
38 */ 71 */
39 72
40static cpumask_t wd_cpus_enabled __read_mostly; 73static cpumask_t wd_cpus_enabled __read_mostly;
@@ -47,19 +80,7 @@ static u64 wd_timer_period_ms __read_mostly; /* interval between heartbeat */
47static DEFINE_PER_CPU(struct timer_list, wd_timer); 80static DEFINE_PER_CPU(struct timer_list, wd_timer);
48static DEFINE_PER_CPU(u64, wd_timer_tb); 81static DEFINE_PER_CPU(u64, wd_timer_tb);
49 82
50/* 83/* SMP checker bits */
51 * These are for the SMP checker. CPUs clear their pending bit in their
52 * heartbeat. If the bitmask becomes empty, the time is noted and the
53 * bitmask is refilled.
54 *
55 * All CPUs clear their bit in the pending mask every timer period.
56 * Once all have cleared, the time is noted and the bits are reset.
57 * If the time since all clear was greater than the panic timeout,
58 * we can panic with the list of stuck CPUs.
59 *
60 * This will work best with NMI IPIs for crash code so the stuck CPUs
61 * can be pulled out to get their backtraces.
62 */
63static unsigned long __wd_smp_lock; 84static unsigned long __wd_smp_lock;
64static cpumask_t wd_smp_cpus_pending; 85static cpumask_t wd_smp_cpus_pending;
65static cpumask_t wd_smp_cpus_stuck; 86static cpumask_t wd_smp_cpus_stuck;
@@ -90,7 +111,7 @@ static inline void wd_smp_unlock(unsigned long *flags)
90 111
91static void wd_lockup_ipi(struct pt_regs *regs) 112static void wd_lockup_ipi(struct pt_regs *regs)
92{ 113{
93 pr_emerg("Watchdog CPU:%d Hard LOCKUP\n", raw_smp_processor_id()); 114 pr_emerg("CPU %d Hard LOCKUP\n", raw_smp_processor_id());
94 print_modules(); 115 print_modules();
95 print_irqtrace_events(current); 116 print_irqtrace_events(current);
96 if (regs) 117 if (regs)
@@ -131,8 +152,8 @@ static void watchdog_smp_panic(int cpu, u64 tb)
131 if (cpumask_weight(&wd_smp_cpus_pending) == 0) 152 if (cpumask_weight(&wd_smp_cpus_pending) == 0)
132 goto out; 153 goto out;
133 154
134 pr_emerg("Watchdog CPU:%d detected Hard LOCKUP other CPUS:%*pbl\n", 155 pr_emerg("CPU %d detected hard LOCKUP on other CPUs %*pbl\n",
135 cpu, cpumask_pr_args(&wd_smp_cpus_pending)); 156 cpu, cpumask_pr_args(&wd_smp_cpus_pending));
136 157
137 if (!sysctl_hardlockup_all_cpu_backtrace) { 158 if (!sysctl_hardlockup_all_cpu_backtrace) {
138 /* 159 /*
@@ -175,7 +196,7 @@ static void wd_smp_clear_cpu_pending(int cpu, u64 tb)
175 if (unlikely(cpumask_test_cpu(cpu, &wd_smp_cpus_stuck))) { 196 if (unlikely(cpumask_test_cpu(cpu, &wd_smp_cpus_stuck))) {
176 unsigned long flags; 197 unsigned long flags;
177 198
178 pr_emerg("Watchdog CPU:%d became unstuck\n", cpu); 199 pr_emerg("CPU %d became unstuck\n", cpu);
179 wd_smp_lock(&flags); 200 wd_smp_lock(&flags);
180 cpumask_clear_cpu(cpu, &wd_smp_cpus_stuck); 201 cpumask_clear_cpu(cpu, &wd_smp_cpus_stuck);
181 wd_smp_unlock(&flags); 202 wd_smp_unlock(&flags);
@@ -233,13 +254,10 @@ void soft_nmi_interrupt(struct pt_regs *regs)
233 } 254 }
234 set_cpu_stuck(cpu, tb); 255 set_cpu_stuck(cpu, tb);
235 256
236 pr_emerg("Watchdog CPU:%d Hard LOCKUP\n", cpu); 257 pr_emerg("CPU %d self-detected hard LOCKUP @ %pS\n", cpu, (void *)regs->nip);
237 print_modules(); 258 print_modules();
238 print_irqtrace_events(current); 259 print_irqtrace_events(current);
239 if (regs) 260 show_regs(regs);
240 show_regs(regs);
241 else
242 dump_stack();
243 261
244 wd_smp_unlock(&flags); 262 wd_smp_unlock(&flags);
245 263
@@ -388,30 +406,8 @@ int __init watchdog_nmi_probe(void)
388 "powerpc/watchdog:online", 406 "powerpc/watchdog:online",
389 start_wd_on_cpu, stop_wd_on_cpu); 407 start_wd_on_cpu, stop_wd_on_cpu);
390 if (err < 0) { 408 if (err < 0) {
391 pr_warn("Watchdog could not be initialized"); 409 pr_warn("could not be initialized");
392 return err; 410 return err;
393 } 411 }
394 return 0; 412 return 0;
395} 413}
396
397static void handle_backtrace_ipi(struct pt_regs *regs)
398{
399 nmi_cpu_backtrace(regs);
400}
401
402static void raise_backtrace_ipi(cpumask_t *mask)
403{
404 unsigned int cpu;
405
406 for_each_cpu(cpu, mask) {
407 if (cpu == smp_processor_id())
408 handle_backtrace_ipi(NULL);
409 else
410 smp_send_nmi_ipi(cpu, handle_backtrace_ipi, 1000000);
411 }
412}
413
414void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self)
415{
416 nmi_trigger_cpumask_backtrace(mask, exclude_self, raise_backtrace_ipi);
417}
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 2d46037ce936..e4f70c33fbc7 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -93,10 +93,10 @@
93static DECLARE_BITMAP(default_enabled_hcalls, MAX_HCALL_OPCODE/4 + 1); 93static DECLARE_BITMAP(default_enabled_hcalls, MAX_HCALL_OPCODE/4 + 1);
94 94
95static int dynamic_mt_modes = 6; 95static int dynamic_mt_modes = 6;
96module_param(dynamic_mt_modes, int, S_IRUGO | S_IWUSR); 96module_param(dynamic_mt_modes, int, 0644);
97MODULE_PARM_DESC(dynamic_mt_modes, "Set of allowed dynamic micro-threading modes: 0 (= none), 2, 4, or 6 (= 2 or 4)"); 97MODULE_PARM_DESC(dynamic_mt_modes, "Set of allowed dynamic micro-threading modes: 0 (= none), 2, 4, or 6 (= 2 or 4)");
98static int target_smt_mode; 98static int target_smt_mode;
99module_param(target_smt_mode, int, S_IRUGO | S_IWUSR); 99module_param(target_smt_mode, int, 0644);
100MODULE_PARM_DESC(target_smt_mode, "Target threads per core (0 = max)"); 100MODULE_PARM_DESC(target_smt_mode, "Target threads per core (0 = max)");
101 101
102static bool indep_threads_mode = true; 102static bool indep_threads_mode = true;
@@ -109,12 +109,10 @@ static struct kernel_param_ops module_param_ops = {
109 .get = param_get_int, 109 .get = param_get_int,
110}; 110};
111 111
112module_param_cb(kvm_irq_bypass, &module_param_ops, &kvm_irq_bypass, 112module_param_cb(kvm_irq_bypass, &module_param_ops, &kvm_irq_bypass, 0644);
113 S_IRUGO | S_IWUSR);
114MODULE_PARM_DESC(kvm_irq_bypass, "Bypass passthrough interrupt optimization"); 113MODULE_PARM_DESC(kvm_irq_bypass, "Bypass passthrough interrupt optimization");
115 114
116module_param_cb(h_ipi_redirect, &module_param_ops, &h_ipi_redirect, 115module_param_cb(h_ipi_redirect, &module_param_ops, &h_ipi_redirect, 0644);
117 S_IRUGO | S_IWUSR);
118MODULE_PARM_DESC(h_ipi_redirect, "Redirect H_IPI wakeup to a free host core"); 116MODULE_PARM_DESC(h_ipi_redirect, "Redirect H_IPI wakeup to a free host core");
119#endif 117#endif
120 118
diff --git a/arch/powerpc/kvm/book3s_hv_ras.c b/arch/powerpc/kvm/book3s_hv_ras.c
index c356f9a40b24..b11043b23c18 100644
--- a/arch/powerpc/kvm/book3s_hv_ras.c
+++ b/arch/powerpc/kvm/book3s_hv_ras.c
@@ -87,8 +87,7 @@ static long kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu)
87 DSISR_MC_SLB_PARITY | DSISR_MC_DERAT_MULTI); 87 DSISR_MC_SLB_PARITY | DSISR_MC_DERAT_MULTI);
88 } 88 }
89 if (dsisr & DSISR_MC_TLB_MULTI) { 89 if (dsisr & DSISR_MC_TLB_MULTI) {
90 if (cur_cpu_spec && cur_cpu_spec->flush_tlb) 90 tlbiel_all_lpid(vcpu->kvm->arch.radix);
91 cur_cpu_spec->flush_tlb(TLB_INVAL_SCOPE_LPID);
92 dsisr &= ~DSISR_MC_TLB_MULTI; 91 dsisr &= ~DSISR_MC_TLB_MULTI;
93 } 92 }
94 /* Any other errors we don't understand? */ 93 /* Any other errors we don't understand? */
@@ -105,8 +104,7 @@ static long kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu)
105 reload_slb(vcpu); 104 reload_slb(vcpu);
106 break; 105 break;
107 case SRR1_MC_IFETCH_TLBMULTI: 106 case SRR1_MC_IFETCH_TLBMULTI:
108 if (cur_cpu_spec && cur_cpu_spec->flush_tlb) 107 tlbiel_all_lpid(vcpu->kvm->arch.radix);
109 cur_cpu_spec->flush_tlb(TLB_INVAL_SCOPE_LPID);
110 break; 108 break;
111 default: 109 default:
112 handled = 0; 110 handled = 0;
@@ -268,17 +266,19 @@ static void kvmppc_tb_resync_done(void)
268 * secondary threads to proceed. 266 * secondary threads to proceed.
269 * - All secondary threads will eventually call opal hmi handler on 267 * - All secondary threads will eventually call opal hmi handler on
270 * their exit path. 268 * their exit path.
269 *
270 * Returns 1 if the timebase offset should be applied, 0 if not.
271 */ 271 */
272 272
273long kvmppc_realmode_hmi_handler(void) 273long kvmppc_realmode_hmi_handler(void)
274{ 274{
275 int ptid = local_paca->kvm_hstate.ptid;
276 bool resync_req; 275 bool resync_req;
277 276
278 /* This is only called on primary thread. */
279 BUG_ON(ptid != 0);
280 __this_cpu_inc(irq_stat.hmi_exceptions); 277 __this_cpu_inc(irq_stat.hmi_exceptions);
281 278
279 if (hmi_handle_debugtrig(NULL) >= 0)
280 return 1;
281
282 /* 282 /*
283 * By now primary thread has already completed guest->host 283 * By now primary thread has already completed guest->host
284 * partition switch but haven't signaled secondaries yet. 284 * partition switch but haven't signaled secondaries yet.
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
index 26c11f678fbf..8888e625a999 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
@@ -42,7 +42,7 @@ static void *real_vmalloc_addr(void *x)
42} 42}
43 43
44/* Return 1 if we need to do a global tlbie, 0 if we can use tlbiel */ 44/* Return 1 if we need to do a global tlbie, 0 if we can use tlbiel */
45static int global_invalidates(struct kvm *kvm, unsigned long flags) 45static int global_invalidates(struct kvm *kvm)
46{ 46{
47 int global; 47 int global;
48 int cpu; 48 int cpu;
@@ -522,7 +522,7 @@ long kvmppc_do_h_remove(struct kvm *kvm, unsigned long flags,
522 if (v & HPTE_V_VALID) { 522 if (v & HPTE_V_VALID) {
523 hpte[0] &= ~cpu_to_be64(HPTE_V_VALID); 523 hpte[0] &= ~cpu_to_be64(HPTE_V_VALID);
524 rb = compute_tlbie_rb(v, pte_r, pte_index); 524 rb = compute_tlbie_rb(v, pte_r, pte_index);
525 do_tlbies(kvm, &rb, 1, global_invalidates(kvm, flags), true); 525 do_tlbies(kvm, &rb, 1, global_invalidates(kvm), true);
526 /* 526 /*
527 * The reference (R) and change (C) bits in a HPT 527 * The reference (R) and change (C) bits in a HPT
528 * entry can be set by hardware at any time up until 528 * entry can be set by hardware at any time up until
@@ -572,7 +572,7 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu)
572 572
573 if (kvm_is_radix(kvm)) 573 if (kvm_is_radix(kvm))
574 return H_FUNCTION; 574 return H_FUNCTION;
575 global = global_invalidates(kvm, 0); 575 global = global_invalidates(kvm);
576 for (i = 0; i < 4 && ret == H_SUCCESS; ) { 576 for (i = 0; i < 4 && ret == H_SUCCESS; ) {
577 n = 0; 577 n = 0;
578 for (; i < 4; ++i) { 578 for (; i < 4; ++i) {
@@ -732,8 +732,7 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags,
732 rb = compute_tlbie_rb(v, r, pte_index); 732 rb = compute_tlbie_rb(v, r, pte_index);
733 hpte[0] = cpu_to_be64((pte_v & ~HPTE_V_VALID) | 733 hpte[0] = cpu_to_be64((pte_v & ~HPTE_V_VALID) |
734 HPTE_V_ABSENT); 734 HPTE_V_ABSENT);
735 do_tlbies(kvm, &rb, 1, global_invalidates(kvm, flags), 735 do_tlbies(kvm, &rb, 1, global_invalidates(kvm), true);
736 true);
737 /* Don't lose R/C bit updates done by hardware */ 736 /* Don't lose R/C bit updates done by hardware */
738 r |= be64_to_cpu(hpte[1]) & (HPTE_R_R | HPTE_R_C); 737 r |= be64_to_cpu(hpte[1]) & (HPTE_R_R | HPTE_R_C);
739 hpte[1] = cpu_to_be64(r); 738 hpte[1] = cpu_to_be64(r);
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 9c61f736c75b..7886b313d135 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -1908,16 +1908,17 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
1908 bne 27f 1908 bne 27f
1909 bl kvmppc_realmode_hmi_handler 1909 bl kvmppc_realmode_hmi_handler
1910 nop 1910 nop
1911 cmpdi r3, 0
1911 li r12, BOOK3S_INTERRUPT_HMI 1912 li r12, BOOK3S_INTERRUPT_HMI
1912 /* 1913 /*
1913 * At this point kvmppc_realmode_hmi_handler would have resync-ed 1914 * At this point kvmppc_realmode_hmi_handler may have resync-ed
1914 * the TB. Hence it is not required to subtract guest timebase 1915 * the TB, and if it has, we must not subtract the guest timebase
1915 * offset from timebase. So, skip it. 1916 * offset from the timebase. So, skip it.
1916 * 1917 *
1917 * Also, do not call kvmppc_subcore_exit_guest() because it has 1918 * Also, do not call kvmppc_subcore_exit_guest() because it has
1918 * been invoked as part of kvmppc_realmode_hmi_handler(). 1919 * been invoked as part of kvmppc_realmode_hmi_handler().
1919 */ 1920 */
1920 b 30f 1921 beq 30f
1921 1922
192227: 192327:
1923 /* Subtract timebase offset from timebase */ 1924 /* Subtract timebase offset from timebase */
@@ -3248,7 +3249,7 @@ kvmppc_bad_host_intr:
3248 mfctr r4 3249 mfctr r4
3249#endif 3250#endif
3250 mfxer r5 3251 mfxer r5
3251 lbz r6, PACASOFTIRQEN(r13) 3252 lbz r6, PACAIRQSOFTMASK(r13)
3252 std r3, _LINK(r1) 3253 std r3, _LINK(r1)
3253 std r4, _CTR(r1) 3254 std r4, _CTR(r1)
3254 std r5, _XER(r1) 3255 std r5, _XER(r1)
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c
index d329b2add7e2..b8356cdc0c04 100644
--- a/arch/powerpc/kvm/book3s_xics.c
+++ b/arch/powerpc/kvm/book3s_xics.c
@@ -1039,7 +1039,7 @@ static void xics_debugfs_init(struct kvmppc_xics *xics)
1039 return; 1039 return;
1040 } 1040 }
1041 1041
1042 xics->dentry = debugfs_create_file(name, S_IRUGO, powerpc_debugfs_root, 1042 xics->dentry = debugfs_create_file(name, 0444, powerpc_debugfs_root,
1043 xics, &xics_debug_fops); 1043 xics, &xics_debug_fops);
1044 1044
1045 pr_debug("%s: created %s\n", __func__, name); 1045 pr_debug("%s: created %s\n", __func__, name);
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index d469224c4ada..e0d881ab304e 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -23,19 +23,26 @@
23#include <asm/code-patching.h> 23#include <asm/code-patching.h>
24#include <asm/setup.h> 24#include <asm/setup.h>
25 25
26static int __patch_instruction(unsigned int *addr, unsigned int instr) 26static int __patch_instruction(unsigned int *exec_addr, unsigned int instr,
27 unsigned int *patch_addr)
27{ 28{
28 int err; 29 int err;
29 30
30 __put_user_size(instr, addr, 4, err); 31 __put_user_size(instr, patch_addr, 4, err);
31 if (err) 32 if (err)
32 return err; 33 return err;
33 34
34 asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" :: "r" (addr)); 35 asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr),
36 "r" (exec_addr));
35 37
36 return 0; 38 return 0;
37} 39}
38 40
41int raw_patch_instruction(unsigned int *addr, unsigned int instr)
42{
43 return __patch_instruction(addr, instr, addr);
44}
45
39#ifdef CONFIG_STRICT_KERNEL_RWX 46#ifdef CONFIG_STRICT_KERNEL_RWX
40static DEFINE_PER_CPU(struct vm_struct *, text_poke_area); 47static DEFINE_PER_CPU(struct vm_struct *, text_poke_area);
41 48
@@ -138,7 +145,7 @@ static inline int unmap_patch_area(unsigned long addr)
138int patch_instruction(unsigned int *addr, unsigned int instr) 145int patch_instruction(unsigned int *addr, unsigned int instr)
139{ 146{
140 int err; 147 int err;
141 unsigned int *dest = NULL; 148 unsigned int *patch_addr = NULL;
142 unsigned long flags; 149 unsigned long flags;
143 unsigned long text_poke_addr; 150 unsigned long text_poke_addr;
144 unsigned long kaddr = (unsigned long)addr; 151 unsigned long kaddr = (unsigned long)addr;
@@ -148,8 +155,8 @@ int patch_instruction(unsigned int *addr, unsigned int instr)
148 * when text_poke_area is not ready, but we still need 155 * when text_poke_area is not ready, but we still need
149 * to allow patching. We just do the plain old patching 156 * to allow patching. We just do the plain old patching
150 */ 157 */
151 if (!this_cpu_read(*PTRRELOC(&text_poke_area))) 158 if (!this_cpu_read(text_poke_area))
152 return __patch_instruction(addr, instr); 159 return raw_patch_instruction(addr, instr);
153 160
154 local_irq_save(flags); 161 local_irq_save(flags);
155 162
@@ -159,17 +166,10 @@ int patch_instruction(unsigned int *addr, unsigned int instr)
159 goto out; 166 goto out;
160 } 167 }
161 168
162 dest = (unsigned int *)(text_poke_addr) + 169 patch_addr = (unsigned int *)(text_poke_addr) +
163 ((kaddr & ~PAGE_MASK) / sizeof(unsigned int)); 170 ((kaddr & ~PAGE_MASK) / sizeof(unsigned int));
164 171
165 /* 172 __patch_instruction(addr, instr, patch_addr);
166 * We use __put_user_size so that we can handle faults while
167 * writing to dest and return err to handle faults gracefully
168 */
169 __put_user_size(instr, dest, 4, err);
170 if (!err)
171 asm ("dcbst 0, %0; sync; icbi 0,%0; icbi 0,%1; sync; isync"
172 ::"r" (dest), "r"(addr));
173 173
174 err = unmap_patch_area(text_poke_addr); 174 err = unmap_patch_area(text_poke_addr);
175 if (err) 175 if (err)
@@ -184,7 +184,7 @@ out:
184 184
185int patch_instruction(unsigned int *addr, unsigned int instr) 185int patch_instruction(unsigned int *addr, unsigned int instr)
186{ 186{
187 return __patch_instruction(addr, instr); 187 return raw_patch_instruction(addr, instr);
188} 188}
189 189
190#endif /* CONFIG_STRICT_KERNEL_RWX */ 190#endif /* CONFIG_STRICT_KERNEL_RWX */
@@ -302,6 +302,11 @@ int instr_is_relative_branch(unsigned int instr)
302 return instr_is_branch_iform(instr) || instr_is_branch_bform(instr); 302 return instr_is_branch_iform(instr) || instr_is_branch_bform(instr);
303} 303}
304 304
305int instr_is_relative_link_branch(unsigned int instr)
306{
307 return instr_is_relative_branch(instr) && (instr & BRANCH_SET_LINK);
308}
309
305static unsigned long branch_iform_target(const unsigned int *instr) 310static unsigned long branch_iform_target(const unsigned int *instr)
306{ 311{
307 signed long imm; 312 signed long imm;
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
index a95ea007d654..73697c4e3468 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -62,7 +62,7 @@ static int patch_alt_instruction(unsigned int *src, unsigned int *dest,
62 } 62 }
63 } 63 }
64 64
65 patch_instruction(dest, instr); 65 raw_patch_instruction(dest, instr);
66 66
67 return 0; 67 return 0;
68} 68}
@@ -91,7 +91,7 @@ static int patch_feature_section(unsigned long value, struct fixup_entry *fcur)
91 } 91 }
92 92
93 for (; dest < end; dest++) 93 for (; dest < end; dest++)
94 patch_instruction(dest, PPC_INST_NOP); 94 raw_patch_instruction(dest, PPC_INST_NOP);
95 95
96 return 0; 96 return 0;
97} 97}
@@ -170,7 +170,7 @@ void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
170 170
171 for (; start < end; start++) { 171 for (; start < end; start++) {
172 dest = (void *)start + *start; 172 dest = (void *)start + *start;
173 patch_instruction(dest, PPC_INST_LWSYNC); 173 raw_patch_instruction(dest, PPC_INST_LWSYNC);
174 } 174 }
175} 175}
176 176
@@ -188,7 +188,7 @@ static void do_final_fixups(void)
188 length = (__end_interrupts - _stext) / sizeof(int); 188 length = (__end_interrupts - _stext) / sizeof(int);
189 189
190 while (length--) { 190 while (length--) {
191 patch_instruction(dest, *src); 191 raw_patch_instruction(dest, *src);
192 src++; 192 src++;
193 dest++; 193 dest++;
194 } 194 }
diff --git a/arch/powerpc/mm/8xx_mmu.c b/arch/powerpc/mm/8xx_mmu.c
index f29212e40f40..849f50cd62f2 100644
--- a/arch/powerpc/mm/8xx_mmu.c
+++ b/arch/powerpc/mm/8xx_mmu.c
@@ -67,7 +67,7 @@ void __init MMU_init_hw(void)
67 /* PIN up to the 3 first 8Mb after IMMR in DTLB table */ 67 /* PIN up to the 3 first 8Mb after IMMR in DTLB table */
68#ifdef CONFIG_PIN_TLB_DATA 68#ifdef CONFIG_PIN_TLB_DATA
69 unsigned long ctr = mfspr(SPRN_MD_CTR) & 0xfe000000; 69 unsigned long ctr = mfspr(SPRN_MD_CTR) & 0xfe000000;
70 unsigned long flags = 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY; 70 unsigned long flags = 0xf0 | MD_SPS16K | _PAGE_PRIVILEGED | _PAGE_DIRTY;
71#ifdef CONFIG_PIN_TLB_IMMR 71#ifdef CONFIG_PIN_TLB_IMMR
72 int i = 29; 72 int i = 29;
73#else 73#else
@@ -79,7 +79,7 @@ void __init MMU_init_hw(void)
79 for (; i < 32 && mem >= LARGE_PAGE_SIZE_8M; i++) { 79 for (; i < 32 && mem >= LARGE_PAGE_SIZE_8M; i++) {
80 mtspr(SPRN_MD_CTR, ctr | (i << 8)); 80 mtspr(SPRN_MD_CTR, ctr | (i << 8));
81 mtspr(SPRN_MD_EPN, (unsigned long)__va(addr) | MD_EVALID); 81 mtspr(SPRN_MD_EPN, (unsigned long)__va(addr) | MD_EVALID);
82 mtspr(SPRN_MD_TWC, MD_PS8MEG | MD_SVALID); 82 mtspr(SPRN_MD_TWC, MD_PS8MEG | MD_SVALID | M_APG2);
83 mtspr(SPRN_MD_RPN, addr | flags | _PAGE_PRESENT); 83 mtspr(SPRN_MD_RPN, addr | flags | _PAGE_PRESENT);
84 addr += LARGE_PAGE_SIZE_8M; 84 addr += LARGE_PAGE_SIZE_8M;
85 mem -= LARGE_PAGE_SIZE_8M; 85 mem -= LARGE_PAGE_SIZE_8M;
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index 76a6b057d454..f06f3577d8d1 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -9,7 +9,7 @@ ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
9 9
10obj-y := fault.o mem.o pgtable.o mmap.o \ 10obj-y := fault.o mem.o pgtable.o mmap.o \
11 init_$(BITS).o pgtable_$(BITS).o \ 11 init_$(BITS).o pgtable_$(BITS).o \
12 init-common.o mmu_context.o 12 init-common.o mmu_context.o drmem.o
13obj-$(CONFIG_PPC_MMU_NOHASH) += mmu_context_nohash.o tlb_nohash.o \ 13obj-$(CONFIG_PPC_MMU_NOHASH) += mmu_context_nohash.o tlb_nohash.o \
14 tlb_nohash_low.o 14 tlb_nohash_low.o
15obj-$(CONFIG_PPC_BOOK3E) += tlb_low_$(BITS)e.o 15obj-$(CONFIG_PPC_BOOK3E) += tlb_low_$(BITS)e.o
@@ -44,3 +44,4 @@ obj-$(CONFIG_PPC_COPRO_BASE) += copro_fault.o
44obj-$(CONFIG_SPAPR_TCE_IOMMU) += mmu_context_iommu.o 44obj-$(CONFIG_SPAPR_TCE_IOMMU) += mmu_context_iommu.o
45obj-$(CONFIG_PPC_PTDUMP) += dump_linuxpagetables.o 45obj-$(CONFIG_PPC_PTDUMP) += dump_linuxpagetables.o
46obj-$(CONFIG_PPC_HTDUMP) += dump_hashpagetable.o 46obj-$(CONFIG_PPC_HTDUMP) += dump_hashpagetable.o
47obj-$(CONFIG_PPC_MEM_KEYS) += pkeys.o
diff --git a/arch/powerpc/mm/drmem.c b/arch/powerpc/mm/drmem.c
new file mode 100644
index 000000000000..1604110c4238
--- /dev/null
+++ b/arch/powerpc/mm/drmem.c
@@ -0,0 +1,439 @@
1/*
2 * Dynamic reconfiguration memory support
3 *
4 * Copyright 2017 IBM Corporation
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#define pr_fmt(fmt) "drmem: " fmt
13
14#include <linux/kernel.h>
15#include <linux/of.h>
16#include <linux/of_fdt.h>
17#include <linux/memblock.h>
18#include <asm/prom.h>
19#include <asm/drmem.h>
20
21static struct drmem_lmb_info __drmem_info;
22struct drmem_lmb_info *drmem_info = &__drmem_info;
23
24u64 drmem_lmb_memory_max(void)
25{
26 struct drmem_lmb *last_lmb;
27
28 last_lmb = &drmem_info->lmbs[drmem_info->n_lmbs - 1];
29 return last_lmb->base_addr + drmem_lmb_size();
30}
31
32static u32 drmem_lmb_flags(struct drmem_lmb *lmb)
33{
34 /*
35 * Return the value of the lmb flags field minus the reserved
36 * bit used internally for hotplug processing.
37 */
38 return lmb->flags & ~DRMEM_LMB_RESERVED;
39}
40
41static struct property *clone_property(struct property *prop, u32 prop_sz)
42{
43 struct property *new_prop;
44
45 new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL);
46 if (!new_prop)
47 return NULL;
48
49 new_prop->name = kstrdup(prop->name, GFP_KERNEL);
50 new_prop->value = kzalloc(prop_sz, GFP_KERNEL);
51 if (!new_prop->name || !new_prop->value) {
52 kfree(new_prop->name);
53 kfree(new_prop->value);
54 kfree(new_prop);
55 return NULL;
56 }
57
58 new_prop->length = prop_sz;
59#if defined(CONFIG_OF_DYNAMIC)
60 of_property_set_flag(new_prop, OF_DYNAMIC);
61#endif
62 return new_prop;
63}
64
65static int drmem_update_dt_v1(struct device_node *memory,
66 struct property *prop)
67{
68 struct property *new_prop;
69 struct of_drconf_cell_v1 *dr_cell;
70 struct drmem_lmb *lmb;
71 u32 *p;
72
73 new_prop = clone_property(prop, prop->length);
74 if (!new_prop)
75 return -1;
76
77 p = new_prop->value;
78 *p++ = cpu_to_be32(drmem_info->n_lmbs);
79
80 dr_cell = (struct of_drconf_cell_v1 *)p;
81
82 for_each_drmem_lmb(lmb) {
83 dr_cell->base_addr = cpu_to_be64(lmb->base_addr);
84 dr_cell->drc_index = cpu_to_be32(lmb->drc_index);
85 dr_cell->aa_index = cpu_to_be32(lmb->aa_index);
86 dr_cell->flags = cpu_to_be32(drmem_lmb_flags(lmb));
87
88 dr_cell++;
89 }
90
91 of_update_property(memory, new_prop);
92 return 0;
93}
94
95static void init_drconf_v2_cell(struct of_drconf_cell_v2 *dr_cell,
96 struct drmem_lmb *lmb)
97{
98 dr_cell->base_addr = cpu_to_be64(lmb->base_addr);
99 dr_cell->drc_index = cpu_to_be32(lmb->drc_index);
100 dr_cell->aa_index = cpu_to_be32(lmb->aa_index);
101 dr_cell->flags = cpu_to_be32(lmb->flags);
102}
103
104static int drmem_update_dt_v2(struct device_node *memory,
105 struct property *prop)
106{
107 struct property *new_prop;
108 struct of_drconf_cell_v2 *dr_cell;
109 struct drmem_lmb *lmb, *prev_lmb;
110 u32 lmb_sets, prop_sz, seq_lmbs;
111 u32 *p;
112
113 /* First pass, determine how many LMB sets are needed. */
114 lmb_sets = 0;
115 prev_lmb = NULL;
116 for_each_drmem_lmb(lmb) {
117 if (!prev_lmb) {
118 prev_lmb = lmb;
119 lmb_sets++;
120 continue;
121 }
122
123 if (prev_lmb->aa_index != lmb->aa_index ||
124 prev_lmb->flags != lmb->flags)
125 lmb_sets++;
126
127 prev_lmb = lmb;
128 }
129
130 prop_sz = lmb_sets * sizeof(*dr_cell) + sizeof(__be32);
131 new_prop = clone_property(prop, prop_sz);
132 if (!new_prop)
133 return -1;
134
135 p = new_prop->value;
136 *p++ = cpu_to_be32(lmb_sets);
137
138 dr_cell = (struct of_drconf_cell_v2 *)p;
139
140 /* Second pass, populate the LMB set data */
141 prev_lmb = NULL;
142 seq_lmbs = 0;
143 for_each_drmem_lmb(lmb) {
144 if (prev_lmb == NULL) {
145 /* Start of first LMB set */
146 prev_lmb = lmb;
147 init_drconf_v2_cell(dr_cell, lmb);
148 seq_lmbs++;
149 continue;
150 }
151
152 if (prev_lmb->aa_index != lmb->aa_index ||
153 prev_lmb->flags != lmb->flags) {
154 /* end of one set, start of another */
155 dr_cell->seq_lmbs = cpu_to_be32(seq_lmbs);
156 dr_cell++;
157
158 init_drconf_v2_cell(dr_cell, lmb);
159 seq_lmbs = 1;
160 } else {
161 seq_lmbs++;
162 }
163
164 prev_lmb = lmb;
165 }
166
167 /* close out last LMB set */
168 dr_cell->seq_lmbs = cpu_to_be32(seq_lmbs);
169 of_update_property(memory, new_prop);
170 return 0;
171}
172
173int drmem_update_dt(void)
174{
175 struct device_node *memory;
176 struct property *prop;
177 int rc = -1;
178
179 memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
180 if (!memory)
181 return -1;
182
183 prop = of_find_property(memory, "ibm,dynamic-memory", NULL);
184 if (prop) {
185 rc = drmem_update_dt_v1(memory, prop);
186 } else {
187 prop = of_find_property(memory, "ibm,dynamic-memory-v2", NULL);
188 if (prop)
189 rc = drmem_update_dt_v2(memory, prop);
190 }
191
192 of_node_put(memory);
193 return rc;
194}
195
196static void __init read_drconf_v1_cell(struct drmem_lmb *lmb,
197 const __be32 **prop)
198{
199 const __be32 *p = *prop;
200
201 lmb->base_addr = dt_mem_next_cell(dt_root_addr_cells, &p);
202 lmb->drc_index = of_read_number(p++, 1);
203
204 p++; /* skip reserved field */
205
206 lmb->aa_index = of_read_number(p++, 1);
207 lmb->flags = of_read_number(p++, 1);
208
209 *prop = p;
210}
211
212static void __init __walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm,
213 void (*func)(struct drmem_lmb *, const __be32 **))
214{
215 struct drmem_lmb lmb;
216 u32 i, n_lmbs;
217
218 n_lmbs = of_read_number(prop++, 1);
219
220 for (i = 0; i < n_lmbs; i++) {
221 read_drconf_v1_cell(&lmb, &prop);
222 func(&lmb, &usm);
223 }
224}
225
226static void __init read_drconf_v2_cell(struct of_drconf_cell_v2 *dr_cell,
227 const __be32 **prop)
228{
229 const __be32 *p = *prop;
230
231 dr_cell->seq_lmbs = of_read_number(p++, 1);
232 dr_cell->base_addr = dt_mem_next_cell(dt_root_addr_cells, &p);
233 dr_cell->drc_index = of_read_number(p++, 1);
234 dr_cell->aa_index = of_read_number(p++, 1);
235 dr_cell->flags = of_read_number(p++, 1);
236
237 *prop = p;
238}
239
240static void __init __walk_drmem_v2_lmbs(const __be32 *prop, const __be32 *usm,
241 void (*func)(struct drmem_lmb *, const __be32 **))
242{
243 struct of_drconf_cell_v2 dr_cell;
244 struct drmem_lmb lmb;
245 u32 i, j, lmb_sets;
246
247 lmb_sets = of_read_number(prop++, 1);
248
249 for (i = 0; i < lmb_sets; i++) {
250 read_drconf_v2_cell(&dr_cell, &prop);
251
252 for (j = 0; j < dr_cell.seq_lmbs; j++) {
253 lmb.base_addr = dr_cell.base_addr;
254 dr_cell.base_addr += drmem_lmb_size();
255
256 lmb.drc_index = dr_cell.drc_index;
257 dr_cell.drc_index++;
258
259 lmb.aa_index = dr_cell.aa_index;
260 lmb.flags = dr_cell.flags;
261
262 func(&lmb, &usm);
263 }
264 }
265}
266
267#ifdef CONFIG_PPC_PSERIES
268void __init walk_drmem_lmbs_early(unsigned long node,
269 void (*func)(struct drmem_lmb *, const __be32 **))
270{
271 const __be32 *prop, *usm;
272 int len;
273
274 prop = of_get_flat_dt_prop(node, "ibm,lmb-size", &len);
275 if (!prop || len < dt_root_size_cells * sizeof(__be32))
276 return;
277
278 drmem_info->lmb_size = dt_mem_next_cell(dt_root_size_cells, &prop);
279
280 usm = of_get_flat_dt_prop(node, "linux,drconf-usable-memory", &len);
281
282 prop = of_get_flat_dt_prop(node, "ibm,dynamic-memory", &len);
283 if (prop) {
284 __walk_drmem_v1_lmbs(prop, usm, func);
285 } else {
286 prop = of_get_flat_dt_prop(node, "ibm,dynamic-memory-v2",
287 &len);
288 if (prop)
289 __walk_drmem_v2_lmbs(prop, usm, func);
290 }
291
292 memblock_dump_all();
293}
294
295#endif
296
297static int __init init_drmem_lmb_size(struct device_node *dn)
298{
299 const __be32 *prop;
300 int len;
301
302 if (drmem_info->lmb_size)
303 return 0;
304
305 prop = of_get_property(dn, "ibm,lmb-size", &len);
306 if (!prop || len < dt_root_size_cells * sizeof(__be32)) {
307 pr_info("Could not determine LMB size\n");
308 return -1;
309 }
310
311 drmem_info->lmb_size = dt_mem_next_cell(dt_root_size_cells, &prop);
312 return 0;
313}
314
315/*
316 * Returns the property linux,drconf-usable-memory if
317 * it exists (the property exists only in kexec/kdump kernels,
318 * added by kexec-tools)
319 */
320static const __be32 *of_get_usable_memory(struct device_node *dn)
321{
322 const __be32 *prop;
323 u32 len;
324
325 prop = of_get_property(dn, "linux,drconf-usable-memory", &len);
326 if (!prop || len < sizeof(unsigned int))
327 return NULL;
328
329 return prop;
330}
331
332void __init walk_drmem_lmbs(struct device_node *dn,
333 void (*func)(struct drmem_lmb *, const __be32 **))
334{
335 const __be32 *prop, *usm;
336
337 if (init_drmem_lmb_size(dn))
338 return;
339
340 usm = of_get_usable_memory(dn);
341
342 prop = of_get_property(dn, "ibm,dynamic-memory", NULL);
343 if (prop) {
344 __walk_drmem_v1_lmbs(prop, usm, func);
345 } else {
346 prop = of_get_property(dn, "ibm,dynamic-memory-v2", NULL);
347 if (prop)
348 __walk_drmem_v2_lmbs(prop, usm, func);
349 }
350}
351
352static void __init init_drmem_v1_lmbs(const __be32 *prop)
353{
354 struct drmem_lmb *lmb;
355
356 drmem_info->n_lmbs = of_read_number(prop++, 1);
357
358 drmem_info->lmbs = kcalloc(drmem_info->n_lmbs, sizeof(*lmb),
359 GFP_KERNEL);
360 if (!drmem_info->lmbs)
361 return;
362
363 for_each_drmem_lmb(lmb)
364 read_drconf_v1_cell(lmb, &prop);
365}
366
367static void __init init_drmem_v2_lmbs(const __be32 *prop)
368{
369 struct drmem_lmb *lmb;
370 struct of_drconf_cell_v2 dr_cell;
371 const __be32 *p;
372 u32 i, j, lmb_sets;
373 int lmb_index;
374
375 lmb_sets = of_read_number(prop++, 1);
376
377 /* first pass, calculate the number of LMBs */
378 p = prop;
379 for (i = 0; i < lmb_sets; i++) {
380 read_drconf_v2_cell(&dr_cell, &p);
381 drmem_info->n_lmbs += dr_cell.seq_lmbs;
382 }
383
384 drmem_info->lmbs = kcalloc(drmem_info->n_lmbs, sizeof(*lmb),
385 GFP_KERNEL);
386 if (!drmem_info->lmbs)
387 return;
388
389 /* second pass, read in the LMB information */
390 lmb_index = 0;
391 p = prop;
392
393 for (i = 0; i < lmb_sets; i++) {
394 read_drconf_v2_cell(&dr_cell, &p);
395
396 for (j = 0; j < dr_cell.seq_lmbs; j++) {
397 lmb = &drmem_info->lmbs[lmb_index++];
398
399 lmb->base_addr = dr_cell.base_addr;
400 dr_cell.base_addr += drmem_info->lmb_size;
401
402 lmb->drc_index = dr_cell.drc_index;
403 dr_cell.drc_index++;
404
405 lmb->aa_index = dr_cell.aa_index;
406 lmb->flags = dr_cell.flags;
407 }
408 }
409}
410
411static int __init drmem_init(void)
412{
413 struct device_node *dn;
414 const __be32 *prop;
415
416 dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
417 if (!dn) {
418 pr_info("No dynamic reconfiguration memory found\n");
419 return 0;
420 }
421
422 if (init_drmem_lmb_size(dn)) {
423 of_node_put(dn);
424 return 0;
425 }
426
427 prop = of_get_property(dn, "ibm,dynamic-memory", NULL);
428 if (prop) {
429 init_drmem_v1_lmbs(prop);
430 } else {
431 prop = of_get_property(dn, "ibm,dynamic-memory-v2", NULL);
432 if (prop)
433 init_drmem_v2_lmbs(prop);
434 }
435
436 of_node_put(dn);
437 return 0;
438}
439late_initcall(drmem_init);
diff --git a/arch/powerpc/mm/dump_linuxpagetables.c b/arch/powerpc/mm/dump_linuxpagetables.c
index c2e7dea59490..876e2a3c79f2 100644
--- a/arch/powerpc/mm/dump_linuxpagetables.c
+++ b/arch/powerpc/mm/dump_linuxpagetables.c
@@ -112,26 +112,25 @@ struct flag_info {
112 112
113static const struct flag_info flag_array[] = { 113static const struct flag_info flag_array[] = {
114 { 114 {
115#ifdef CONFIG_PPC_BOOK3S_64 115 .mask = _PAGE_USER | _PAGE_PRIVILEGED,
116 .mask = _PAGE_PRIVILEGED,
117 .val = 0,
118#else
119 .mask = _PAGE_USER,
120 .val = _PAGE_USER, 116 .val = _PAGE_USER,
121#endif
122 .set = "user", 117 .set = "user",
123 .clear = " ", 118 .clear = " ",
124 }, { 119 }, {
125#if _PAGE_RO == 0 120 .mask = _PAGE_RW | _PAGE_RO | _PAGE_NA,
126 .mask = _PAGE_RW,
127 .val = _PAGE_RW, 121 .val = _PAGE_RW,
128#else
129 .mask = _PAGE_RO,
130 .val = 0,
131#endif
132 .set = "rw", 122 .set = "rw",
133 .clear = "ro",
134 }, { 123 }, {
124 .mask = _PAGE_RW | _PAGE_RO | _PAGE_NA,
125 .val = _PAGE_RO,
126 .set = "ro",
127 }, {
128#if _PAGE_NA != 0
129 .mask = _PAGE_RW | _PAGE_RO | _PAGE_NA,
130 .val = _PAGE_RO,
131 .set = "na",
132 }, {
133#endif
135 .mask = _PAGE_EXEC, 134 .mask = _PAGE_EXEC,
136 .val = _PAGE_EXEC, 135 .val = _PAGE_EXEC,
137 .set = " X ", 136 .set = " X ",
@@ -213,7 +212,7 @@ static const struct flag_info flag_array[] = {
213 .val = H_PAGE_4K_PFN, 212 .val = H_PAGE_4K_PFN,
214 .set = "4K_pfn", 213 .set = "4K_pfn",
215 }, { 214 }, {
216#endif 215#else /* CONFIG_PPC_64K_PAGES */
217 .mask = H_PAGE_F_GIX, 216 .mask = H_PAGE_F_GIX,
218 .val = H_PAGE_F_GIX, 217 .val = H_PAGE_F_GIX,
219 .set = "f_gix", 218 .set = "f_gix",
@@ -224,14 +223,11 @@ static const struct flag_info flag_array[] = {
224 .val = H_PAGE_F_SECOND, 223 .val = H_PAGE_F_SECOND,
225 .set = "f_second", 224 .set = "f_second",
226 }, { 225 }, {
226#endif /* CONFIG_PPC_64K_PAGES */
227#endif 227#endif
228 .mask = _PAGE_SPECIAL, 228 .mask = _PAGE_SPECIAL,
229 .val = _PAGE_SPECIAL, 229 .val = _PAGE_SPECIAL,
230 .set = "special", 230 .set = "special",
231 }, {
232 .mask = _PAGE_SHARED,
233 .val = _PAGE_SHARED,
234 .set = "shared",
235 } 231 }
236}; 232};
237 233
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 6e1e39035380..866446cf2d9a 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -107,7 +107,8 @@ static bool store_updates_sp(struct pt_regs *regs)
107 */ 107 */
108 108
109static int 109static int
110__bad_area_nosemaphore(struct pt_regs *regs, unsigned long address, int si_code) 110__bad_area_nosemaphore(struct pt_regs *regs, unsigned long address, int si_code,
111 int pkey)
111{ 112{
112 /* 113 /*
113 * If we are in kernel mode, bail out with a SEGV, this will 114 * If we are in kernel mode, bail out with a SEGV, this will
@@ -117,17 +118,18 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long address, int si_code)
117 if (!user_mode(regs)) 118 if (!user_mode(regs))
118 return SIGSEGV; 119 return SIGSEGV;
119 120
120 _exception(SIGSEGV, regs, si_code, address); 121 _exception_pkey(SIGSEGV, regs, si_code, address, pkey);
121 122
122 return 0; 123 return 0;
123} 124}
124 125
125static noinline int bad_area_nosemaphore(struct pt_regs *regs, unsigned long address) 126static noinline int bad_area_nosemaphore(struct pt_regs *regs, unsigned long address)
126{ 127{
127 return __bad_area_nosemaphore(regs, address, SEGV_MAPERR); 128 return __bad_area_nosemaphore(regs, address, SEGV_MAPERR, 0);
128} 129}
129 130
130static int __bad_area(struct pt_regs *regs, unsigned long address, int si_code) 131static int __bad_area(struct pt_regs *regs, unsigned long address, int si_code,
132 int pkey)
131{ 133{
132 struct mm_struct *mm = current->mm; 134 struct mm_struct *mm = current->mm;
133 135
@@ -137,17 +139,23 @@ static int __bad_area(struct pt_regs *regs, unsigned long address, int si_code)
137 */ 139 */
138 up_read(&mm->mmap_sem); 140 up_read(&mm->mmap_sem);
139 141
140 return __bad_area_nosemaphore(regs, address, si_code); 142 return __bad_area_nosemaphore(regs, address, si_code, pkey);
141} 143}
142 144
143static noinline int bad_area(struct pt_regs *regs, unsigned long address) 145static noinline int bad_area(struct pt_regs *regs, unsigned long address)
144{ 146{
145 return __bad_area(regs, address, SEGV_MAPERR); 147 return __bad_area(regs, address, SEGV_MAPERR, 0);
148}
149
150static int bad_key_fault_exception(struct pt_regs *regs, unsigned long address,
151 int pkey)
152{
153 return __bad_area_nosemaphore(regs, address, SEGV_PKUERR, pkey);
146} 154}
147 155
148static noinline int bad_access(struct pt_regs *regs, unsigned long address) 156static noinline int bad_access(struct pt_regs *regs, unsigned long address)
149{ 157{
150 return __bad_area(regs, address, SEGV_ACCERR); 158 return __bad_area(regs, address, SEGV_ACCERR, 0);
151} 159}
152 160
153static int do_sigbus(struct pt_regs *regs, unsigned long address, 161static int do_sigbus(struct pt_regs *regs, unsigned long address,
@@ -432,6 +440,10 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
432 440
433 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); 441 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
434 442
443 if (error_code & DSISR_KEYFAULT)
444 return bad_key_fault_exception(regs, address,
445 get_mm_addr_key(mm, address));
446
435 /* 447 /*
436 * We want to do this outside mmap_sem, because reading code around nip 448 * We want to do this outside mmap_sem, because reading code around nip
437 * can result in fault, which will cause a deadlock when called with 449 * can result in fault, which will cause a deadlock when called with
@@ -503,6 +515,31 @@ good_area:
503 * the fault. 515 * the fault.
504 */ 516 */
505 fault = handle_mm_fault(vma, address, flags); 517 fault = handle_mm_fault(vma, address, flags);
518
519#ifdef CONFIG_PPC_MEM_KEYS
520 /*
521 * if the HPTE is not hashed, hardware will not detect
522 * a key fault. Lets check if we failed because of a
523 * software detected key fault.
524 */
525 if (unlikely(fault & VM_FAULT_SIGSEGV) &&
526 !arch_vma_access_permitted(vma, flags & FAULT_FLAG_WRITE,
527 is_exec, 0)) {
528 /*
529 * The PGD-PDT...PMD-PTE tree may not have been fully setup.
530 * Hence we cannot walk the tree to locate the PTE, to locate
531 * the key. Hence let's use vma_pkey() to get the key; instead
532 * of get_mm_addr_key().
533 */
534 int pkey = vma_pkey(vma);
535
536 if (likely(pkey)) {
537 up_read(&mm->mmap_sem);
538 return bad_key_fault_exception(regs, address, pkey);
539 }
540 }
541#endif /* CONFIG_PPC_MEM_KEYS */
542
506 major |= fault & VM_FAULT_MAJOR; 543 major |= fault & VM_FAULT_MAJOR;
507 544
508 /* 545 /*
@@ -576,7 +613,7 @@ void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
576 613
577 /* kernel has accessed a bad area */ 614 /* kernel has accessed a bad area */
578 615
579 switch (regs->trap) { 616 switch (TRAP(regs)) {
580 case 0x300: 617 case 0x300:
581 case 0x380: 618 case 0x380:
582 printk(KERN_ALERT "Unable to handle kernel paging request for " 619 printk(KERN_ALERT "Unable to handle kernel paging request for "
diff --git a/arch/powerpc/mm/hash64_4k.c b/arch/powerpc/mm/hash64_4k.c
index 6fa450c12d6d..5a69b51d08a3 100644
--- a/arch/powerpc/mm/hash64_4k.c
+++ b/arch/powerpc/mm/hash64_4k.c
@@ -20,6 +20,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
20 pte_t *ptep, unsigned long trap, unsigned long flags, 20 pte_t *ptep, unsigned long trap, unsigned long flags,
21 int ssize, int subpg_prot) 21 int ssize, int subpg_prot)
22{ 22{
23 real_pte_t rpte;
23 unsigned long hpte_group; 24 unsigned long hpte_group;
24 unsigned long rflags, pa; 25 unsigned long rflags, pa;
25 unsigned long old_pte, new_pte; 26 unsigned long old_pte, new_pte;
@@ -54,6 +55,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
54 * need to add in 0x1 if it's a read-only user page 55 * need to add in 0x1 if it's a read-only user page
55 */ 56 */
56 rflags = htab_convert_pte_flags(new_pte); 57 rflags = htab_convert_pte_flags(new_pte);
58 rpte = __real_pte(__pte(old_pte), ptep);
57 59
58 if (cpu_has_feature(CPU_FTR_NOEXECUTE) && 60 if (cpu_has_feature(CPU_FTR_NOEXECUTE) &&
59 !cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) 61 !cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
@@ -64,13 +66,10 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
64 /* 66 /*
65 * There MIGHT be an HPTE for this pte 67 * There MIGHT be an HPTE for this pte
66 */ 68 */
67 hash = hpt_hash(vpn, shift, ssize); 69 unsigned long gslot = pte_get_hash_gslot(vpn, shift, ssize,
68 if (old_pte & H_PAGE_F_SECOND) 70 rpte, 0);
69 hash = ~hash;
70 slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
71 slot += (old_pte & H_PAGE_F_GIX) >> H_PAGE_F_GIX_SHIFT;
72 71
73 if (mmu_hash_ops.hpte_updatepp(slot, rflags, vpn, MMU_PAGE_4K, 72 if (mmu_hash_ops.hpte_updatepp(gslot, rflags, vpn, MMU_PAGE_4K,
74 MMU_PAGE_4K, ssize, flags) == -1) 73 MMU_PAGE_4K, ssize, flags) == -1)
75 old_pte &= ~_PAGE_HPTEFLAGS; 74 old_pte &= ~_PAGE_HPTEFLAGS;
76 } 75 }
@@ -118,8 +117,7 @@ repeat:
118 return -1; 117 return -1;
119 } 118 }
120 new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | H_PAGE_HASHPTE; 119 new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | H_PAGE_HASHPTE;
121 new_pte |= (slot << H_PAGE_F_GIX_SHIFT) & 120 new_pte |= pte_set_hidx(ptep, rpte, 0, slot);
122 (H_PAGE_F_SECOND | H_PAGE_F_GIX);
123 } 121 }
124 *ptep = __pte(new_pte & ~H_PAGE_BUSY); 122 *ptep = __pte(new_pte & ~H_PAGE_BUSY);
125 return 0; 123 return 0;
diff --git a/arch/powerpc/mm/hash64_64k.c b/arch/powerpc/mm/hash64_64k.c
index 1a68cb19b0e3..2253bbc6a599 100644
--- a/arch/powerpc/mm/hash64_64k.c
+++ b/arch/powerpc/mm/hash64_64k.c
@@ -15,34 +15,22 @@
15#include <linux/mm.h> 15#include <linux/mm.h>
16#include <asm/machdep.h> 16#include <asm/machdep.h>
17#include <asm/mmu.h> 17#include <asm/mmu.h>
18
18/* 19/*
19 * index from 0 - 15 20 * Return true, if the entry has a slot value which
21 * the software considers as invalid.
20 */ 22 */
21bool __rpte_sub_valid(real_pte_t rpte, unsigned long index) 23static inline bool hpte_soft_invalid(unsigned long hidx)
22{ 24{
23 unsigned long g_idx; 25 return ((hidx & 0xfUL) == 0xfUL);
24 unsigned long ptev = pte_val(rpte.pte);
25
26 g_idx = (ptev & H_PAGE_COMBO_VALID) >> H_PAGE_F_GIX_SHIFT;
27 index = index >> 2;
28 if (g_idx & (0x1 << index))
29 return true;
30 else
31 return false;
32} 26}
27
33/* 28/*
34 * index from 0 - 15 29 * index from 0 - 15
35 */ 30 */
36static unsigned long mark_subptegroup_valid(unsigned long ptev, unsigned long index) 31bool __rpte_sub_valid(real_pte_t rpte, unsigned long index)
37{ 32{
38 unsigned long g_idx; 33 return !(hpte_soft_invalid(__rpte_to_hidx(rpte, index)));
39
40 if (!(ptev & H_PAGE_COMBO))
41 return ptev;
42 index = index >> 2;
43 g_idx = 0x1 << index;
44
45 return ptev | (g_idx << H_PAGE_F_GIX_SHIFT);
46} 34}
47 35
48int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, 36int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
@@ -50,12 +38,11 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
50 int ssize, int subpg_prot) 38 int ssize, int subpg_prot)
51{ 39{
52 real_pte_t rpte; 40 real_pte_t rpte;
53 unsigned long *hidxp;
54 unsigned long hpte_group; 41 unsigned long hpte_group;
55 unsigned int subpg_index; 42 unsigned int subpg_index;
56 unsigned long rflags, pa, hidx; 43 unsigned long rflags, pa;
57 unsigned long old_pte, new_pte, subpg_pte; 44 unsigned long old_pte, new_pte, subpg_pte;
58 unsigned long vpn, hash, slot; 45 unsigned long vpn, hash, slot, gslot;
59 unsigned long shift = mmu_psize_defs[MMU_PAGE_4K].shift; 46 unsigned long shift = mmu_psize_defs[MMU_PAGE_4K].shift;
60 47
61 /* 48 /*
@@ -116,8 +103,8 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
116 * On hash insert failure we use old pte value and we don't 103 * On hash insert failure we use old pte value and we don't
117 * want slot information there if we have a insert failure. 104 * want slot information there if we have a insert failure.
118 */ 105 */
119 old_pte &= ~(H_PAGE_HASHPTE | H_PAGE_F_GIX | H_PAGE_F_SECOND); 106 old_pte &= ~H_PAGE_HASHPTE;
120 new_pte &= ~(H_PAGE_HASHPTE | H_PAGE_F_GIX | H_PAGE_F_SECOND); 107 new_pte &= ~H_PAGE_HASHPTE;
121 goto htab_insert_hpte; 108 goto htab_insert_hpte;
122 } 109 }
123 /* 110 /*
@@ -126,18 +113,14 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
126 if (__rpte_sub_valid(rpte, subpg_index)) { 113 if (__rpte_sub_valid(rpte, subpg_index)) {
127 int ret; 114 int ret;
128 115
129 hash = hpt_hash(vpn, shift, ssize); 116 gslot = pte_get_hash_gslot(vpn, shift, ssize, rpte,
130 hidx = __rpte_to_hidx(rpte, subpg_index); 117 subpg_index);
131 if (hidx & _PTEIDX_SECONDARY) 118 ret = mmu_hash_ops.hpte_updatepp(gslot, rflags, vpn,
132 hash = ~hash;
133 slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
134 slot += hidx & _PTEIDX_GROUP_IX;
135
136 ret = mmu_hash_ops.hpte_updatepp(slot, rflags, vpn,
137 MMU_PAGE_4K, MMU_PAGE_4K, 119 MMU_PAGE_4K, MMU_PAGE_4K,
138 ssize, flags); 120 ssize, flags);
121
139 /* 122 /*
140 *if we failed because typically the HPTE wasn't really here 123 * If we failed because typically the HPTE wasn't really here
141 * we try an insertion. 124 * we try an insertion.
142 */ 125 */
143 if (ret == -1) 126 if (ret == -1)
@@ -148,6 +131,14 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
148 } 131 }
149 132
150htab_insert_hpte: 133htab_insert_hpte:
134
135 /*
136 * Initialize all hidx entries to invalid value, the first time
137 * the PTE is about to allocate a 4K HPTE.
138 */
139 if (!(old_pte & H_PAGE_COMBO))
140 rpte.hidx = INVALID_RPTE_HIDX;
141
151 /* 142 /*
152 * handle H_PAGE_4K_PFN case 143 * handle H_PAGE_4K_PFN case
153 */ 144 */
@@ -172,15 +163,39 @@ repeat:
172 * Primary is full, try the secondary 163 * Primary is full, try the secondary
173 */ 164 */
174 if (unlikely(slot == -1)) { 165 if (unlikely(slot == -1)) {
166 bool soft_invalid;
167
175 hpte_group = ((~hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL; 168 hpte_group = ((~hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL;
176 slot = mmu_hash_ops.hpte_insert(hpte_group, vpn, pa, 169 slot = mmu_hash_ops.hpte_insert(hpte_group, vpn, pa,
177 rflags, HPTE_V_SECONDARY, 170 rflags, HPTE_V_SECONDARY,
178 MMU_PAGE_4K, MMU_PAGE_4K, 171 MMU_PAGE_4K, MMU_PAGE_4K,
179 ssize); 172 ssize);
180 if (slot == -1) { 173
181 if (mftb() & 0x1) 174 soft_invalid = hpte_soft_invalid(slot);
175 if (unlikely(soft_invalid)) {
176 /*
177 * We got a valid slot from a hardware point of view.
178 * but we cannot use it, because we use this special
179 * value; as defined by hpte_soft_invalid(), to track
180 * invalid slots. We cannot use it. So invalidate it.
181 */
182 gslot = slot & _PTEIDX_GROUP_IX;
183 mmu_hash_ops.hpte_invalidate(hpte_group + gslot, vpn,
184 MMU_PAGE_4K, MMU_PAGE_4K,
185 ssize, 0);
186 }
187
188 if (unlikely(slot == -1 || soft_invalid)) {
189 /*
190 * For soft invalid slot, let's ensure that we release a
191 * slot from the primary, with the hope that we will
192 * acquire that slot next time we try. This will ensure
193 * that we do not get the same soft-invalid slot.
194 */
195 if (soft_invalid || (mftb() & 0x1))
182 hpte_group = ((hash & htab_hash_mask) * 196 hpte_group = ((hash & htab_hash_mask) *
183 HPTES_PER_GROUP) & ~0x7UL; 197 HPTES_PER_GROUP) & ~0x7UL;
198
184 mmu_hash_ops.hpte_remove(hpte_group); 199 mmu_hash_ops.hpte_remove(hpte_group);
185 /* 200 /*
186 * FIXME!! Should be try the group from which we removed ? 201 * FIXME!! Should be try the group from which we removed ?
@@ -198,21 +213,10 @@ repeat:
198 MMU_PAGE_4K, MMU_PAGE_4K, old_pte); 213 MMU_PAGE_4K, MMU_PAGE_4K, old_pte);
199 return -1; 214 return -1;
200 } 215 }
201 /* 216
202 * Insert slot number & secondary bit in PTE second half, 217 new_pte |= pte_set_hidx(ptep, rpte, subpg_index, slot);
203 * clear H_PAGE_BUSY and set appropriate HPTE slot bit 218 new_pte |= H_PAGE_HASHPTE;
204 * Since we have H_PAGE_BUSY set on ptep, we can be sure 219
205 * nobody is undating hidx.
206 */
207 hidxp = (unsigned long *)(ptep + PTRS_PER_PTE);
208 rpte.hidx &= ~(0xfUL << (subpg_index << 2));
209 *hidxp = rpte.hidx | (slot << (subpg_index << 2));
210 new_pte = mark_subptegroup_valid(new_pte, subpg_index);
211 new_pte |= H_PAGE_HASHPTE;
212 /*
213 * check __real_pte for details on matching smp_rmb()
214 */
215 smp_wmb();
216 *ptep = __pte(new_pte & ~H_PAGE_BUSY); 220 *ptep = __pte(new_pte & ~H_PAGE_BUSY);
217 return 0; 221 return 0;
218} 222}
@@ -221,6 +225,7 @@ int __hash_page_64K(unsigned long ea, unsigned long access,
221 unsigned long vsid, pte_t *ptep, unsigned long trap, 225 unsigned long vsid, pte_t *ptep, unsigned long trap,
222 unsigned long flags, int ssize) 226 unsigned long flags, int ssize)
223{ 227{
228 real_pte_t rpte;
224 unsigned long hpte_group; 229 unsigned long hpte_group;
225 unsigned long rflags, pa; 230 unsigned long rflags, pa;
226 unsigned long old_pte, new_pte; 231 unsigned long old_pte, new_pte;
@@ -257,6 +262,7 @@ int __hash_page_64K(unsigned long ea, unsigned long access,
257 } while (!pte_xchg(ptep, __pte(old_pte), __pte(new_pte))); 262 } while (!pte_xchg(ptep, __pte(old_pte), __pte(new_pte)));
258 263
259 rflags = htab_convert_pte_flags(new_pte); 264 rflags = htab_convert_pte_flags(new_pte);
265 rpte = __real_pte(__pte(old_pte), ptep);
260 266
261 if (cpu_has_feature(CPU_FTR_NOEXECUTE) && 267 if (cpu_has_feature(CPU_FTR_NOEXECUTE) &&
262 !cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) 268 !cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
@@ -264,16 +270,13 @@ int __hash_page_64K(unsigned long ea, unsigned long access,
264 270
265 vpn = hpt_vpn(ea, vsid, ssize); 271 vpn = hpt_vpn(ea, vsid, ssize);
266 if (unlikely(old_pte & H_PAGE_HASHPTE)) { 272 if (unlikely(old_pte & H_PAGE_HASHPTE)) {
273 unsigned long gslot;
274
267 /* 275 /*
268 * There MIGHT be an HPTE for this pte 276 * There MIGHT be an HPTE for this pte
269 */ 277 */
270 hash = hpt_hash(vpn, shift, ssize); 278 gslot = pte_get_hash_gslot(vpn, shift, ssize, rpte, 0);
271 if (old_pte & H_PAGE_F_SECOND) 279 if (mmu_hash_ops.hpte_updatepp(gslot, rflags, vpn, MMU_PAGE_64K,
272 hash = ~hash;
273 slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
274 slot += (old_pte & H_PAGE_F_GIX) >> H_PAGE_F_GIX_SHIFT;
275
276 if (mmu_hash_ops.hpte_updatepp(slot, rflags, vpn, MMU_PAGE_64K,
277 MMU_PAGE_64K, ssize, 280 MMU_PAGE_64K, ssize,
278 flags) == -1) 281 flags) == -1)
279 old_pte &= ~_PAGE_HPTEFLAGS; 282 old_pte &= ~_PAGE_HPTEFLAGS;
@@ -322,9 +325,9 @@ repeat:
322 MMU_PAGE_64K, MMU_PAGE_64K, old_pte); 325 MMU_PAGE_64K, MMU_PAGE_64K, old_pte);
323 return -1; 326 return -1;
324 } 327 }
328
325 new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | H_PAGE_HASHPTE; 329 new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | H_PAGE_HASHPTE;
326 new_pte |= (slot << H_PAGE_F_GIX_SHIFT) & 330 new_pte |= pte_set_hidx(ptep, rpte, 0, slot);
327 (H_PAGE_F_SECOND | H_PAGE_F_GIX);
328 } 331 }
329 *ptep = __pte(new_pte & ~H_PAGE_BUSY); 332 *ptep = __pte(new_pte & ~H_PAGE_BUSY);
330 return 0; 333 return 0;
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index 640cf566e986..a0675e91ad7d 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -47,6 +47,103 @@
47 47
48DEFINE_RAW_SPINLOCK(native_tlbie_lock); 48DEFINE_RAW_SPINLOCK(native_tlbie_lock);
49 49
50static inline void tlbiel_hash_set_isa206(unsigned int set, unsigned int is)
51{
52 unsigned long rb;
53
54 rb = (set << PPC_BITLSHIFT(51)) | (is << PPC_BITLSHIFT(53));
55
56 asm volatile("tlbiel %0" : : "r" (rb));
57}
58
59/*
60 * tlbiel instruction for hash, set invalidation
61 * i.e., r=1 and is=01 or is=10 or is=11
62 */
63static inline void tlbiel_hash_set_isa300(unsigned int set, unsigned int is,
64 unsigned int pid,
65 unsigned int ric, unsigned int prs)
66{
67 unsigned long rb;
68 unsigned long rs;
69 unsigned int r = 0; /* hash format */
70
71 rb = (set << PPC_BITLSHIFT(51)) | (is << PPC_BITLSHIFT(53));
72 rs = ((unsigned long)pid << PPC_BITLSHIFT(31));
73
74 asm volatile(PPC_TLBIEL(%0, %1, %2, %3, %4)
75 : : "r"(rb), "r"(rs), "i"(ric), "i"(prs), "r"(r)
76 : "memory");
77}
78
79
80static void tlbiel_all_isa206(unsigned int num_sets, unsigned int is)
81{
82 unsigned int set;
83
84 asm volatile("ptesync": : :"memory");
85
86 for (set = 0; set < num_sets; set++)
87 tlbiel_hash_set_isa206(set, is);
88
89 asm volatile("ptesync": : :"memory");
90}
91
92static void tlbiel_all_isa300(unsigned int num_sets, unsigned int is)
93{
94 unsigned int set;
95
96 asm volatile("ptesync": : :"memory");
97
98 /*
99 * Flush the first set of the TLB, and any caching of partition table
100 * entries. Then flush the remaining sets of the TLB. Hash mode uses
101 * partition scoped TLB translations.
102 */
103 tlbiel_hash_set_isa300(0, is, 0, 2, 0);
104 for (set = 1; set < num_sets; set++)
105 tlbiel_hash_set_isa300(set, is, 0, 0, 0);
106
107 /*
108 * Now invalidate the process table cache.
109 *
110 * From ISA v3.0B p. 1078:
111 * The following forms are invalid.
112 * * PRS=1, R=0, and RIC!=2 (The only process-scoped
113 * HPT caching is of the Process Table.)
114 */
115 tlbiel_hash_set_isa300(0, is, 0, 2, 1);
116
117 asm volatile("ptesync": : :"memory");
118}
119
120void hash__tlbiel_all(unsigned int action)
121{
122 unsigned int is;
123
124 switch (action) {
125 case TLB_INVAL_SCOPE_GLOBAL:
126 is = 3;
127 break;
128 case TLB_INVAL_SCOPE_LPID:
129 is = 2;
130 break;
131 default:
132 BUG();
133 }
134
135 if (early_cpu_has_feature(CPU_FTR_ARCH_300))
136 tlbiel_all_isa300(POWER9_TLB_SETS_HASH, is);
137 else if (early_cpu_has_feature(CPU_FTR_ARCH_207S))
138 tlbiel_all_isa206(POWER8_TLB_SETS, is);
139 else if (early_cpu_has_feature(CPU_FTR_ARCH_206))
140 tlbiel_all_isa206(POWER7_TLB_SETS, is);
141 else
142 WARN(1, "%s called on pre-POWER7 CPU\n", __func__);
143
144 asm volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory");
145}
146
50static inline unsigned long ___tlbie(unsigned long vpn, int psize, 147static inline unsigned long ___tlbie(unsigned long vpn, int psize,
51 int apsize, int ssize) 148 int apsize, int ssize)
52{ 149{
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 655a5a9a183d..7d07c7e17db6 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -36,6 +36,7 @@
36#include <linux/memblock.h> 36#include <linux/memblock.h>
37#include <linux/context_tracking.h> 37#include <linux/context_tracking.h>
38#include <linux/libfdt.h> 38#include <linux/libfdt.h>
39#include <linux/pkeys.h>
39 40
40#include <asm/debugfs.h> 41#include <asm/debugfs.h>
41#include <asm/processor.h> 42#include <asm/processor.h>
@@ -232,6 +233,7 @@ unsigned long htab_convert_pte_flags(unsigned long pteflags)
232 */ 233 */
233 rflags |= HPTE_R_M; 234 rflags |= HPTE_R_M;
234 235
236 rflags |= pte_to_hpte_pkey_bits(pteflags);
235 return rflags; 237 return rflags;
236} 238}
237 239
@@ -606,7 +608,7 @@ static void init_hpte_page_sizes(void)
606 continue; /* not a supported page size */ 608 continue; /* not a supported page size */
607 for (ap = bp; ap < MMU_PAGE_COUNT; ++ap) { 609 for (ap = bp; ap < MMU_PAGE_COUNT; ++ap) {
608 penc = mmu_psize_defs[bp].penc[ap]; 610 penc = mmu_psize_defs[bp].penc[ap];
609 if (penc == -1) 611 if (penc == -1 || !mmu_psize_defs[ap].shift)
610 continue; 612 continue;
611 shift = mmu_psize_defs[ap].shift - LP_SHIFT; 613 shift = mmu_psize_defs[ap].shift - LP_SHIFT;
612 if (shift <= 0) 614 if (shift <= 0)
@@ -772,7 +774,7 @@ void resize_hpt_for_hotplug(unsigned long new_mem_size)
772 int rc; 774 int rc;
773 775
774 rc = mmu_hash_ops.resize_hpt(target_hpt_shift); 776 rc = mmu_hash_ops.resize_hpt(target_hpt_shift);
775 if (rc) 777 if (rc && (rc != -ENODEV))
776 printk(KERN_WARNING 778 printk(KERN_WARNING
777 "Unable to resize hash page table to target order %d: %d\n", 779 "Unable to resize hash page table to target order %d: %d\n",
778 target_hpt_shift, rc); 780 target_hpt_shift, rc);
@@ -979,8 +981,9 @@ void __init hash__early_init_devtree(void)
979 981
980void __init hash__early_init_mmu(void) 982void __init hash__early_init_mmu(void)
981{ 983{
984#ifndef CONFIG_PPC_64K_PAGES
982 /* 985 /*
983 * We have code in __hash_page_64K() and elsewhere, which assumes it can 986 * We have code in __hash_page_4K() and elsewhere, which assumes it can
984 * do the following: 987 * do the following:
985 * new_pte |= (slot << H_PAGE_F_GIX_SHIFT) & (H_PAGE_F_SECOND | H_PAGE_F_GIX); 988 * new_pte |= (slot << H_PAGE_F_GIX_SHIFT) & (H_PAGE_F_SECOND | H_PAGE_F_GIX);
986 * 989 *
@@ -991,6 +994,7 @@ void __init hash__early_init_mmu(void)
991 * with a BUILD_BUG_ON(). 994 * with a BUILD_BUG_ON().
992 */ 995 */
993 BUILD_BUG_ON(H_PAGE_F_SECOND != (1ul << (H_PAGE_F_GIX_SHIFT + 3))); 996 BUILD_BUG_ON(H_PAGE_F_SECOND != (1ul << (H_PAGE_F_GIX_SHIFT + 3)));
997#endif /* CONFIG_PPC_64K_PAGES */
994 998
995 htab_init_page_sizes(); 999 htab_init_page_sizes();
996 1000
@@ -1049,6 +1053,10 @@ void __init hash__early_init_mmu(void)
1049 pr_info("Initializing hash mmu with SLB\n"); 1053 pr_info("Initializing hash mmu with SLB\n");
1050 /* Initialize SLB management */ 1054 /* Initialize SLB management */
1051 slb_initialize(); 1055 slb_initialize();
1056
1057 if (cpu_has_feature(CPU_FTR_ARCH_206)
1058 && cpu_has_feature(CPU_FTR_HVMODE))
1059 tlbiel_all();
1052} 1060}
1053 1061
1054#ifdef CONFIG_SMP 1062#ifdef CONFIG_SMP
@@ -1068,6 +1076,10 @@ void hash__early_init_mmu_secondary(void)
1068 } 1076 }
1069 /* Initialize SLB */ 1077 /* Initialize SLB */
1070 slb_initialize(); 1078 slb_initialize();
1079
1080 if (cpu_has_feature(CPU_FTR_ARCH_206)
1081 && cpu_has_feature(CPU_FTR_HVMODE))
1082 tlbiel_all();
1071} 1083}
1072#endif /* CONFIG_SMP */ 1084#endif /* CONFIG_SMP */
1073 1085
@@ -1569,6 +1581,30 @@ out_exit:
1569 local_irq_restore(flags); 1581 local_irq_restore(flags);
1570} 1582}
1571 1583
1584#ifdef CONFIG_PPC_MEM_KEYS
1585/*
1586 * Return the protection key associated with the given address and the
1587 * mm_struct.
1588 */
1589u16 get_mm_addr_key(struct mm_struct *mm, unsigned long address)
1590{
1591 pte_t *ptep;
1592 u16 pkey = 0;
1593 unsigned long flags;
1594
1595 if (!mm || !mm->pgd)
1596 return 0;
1597
1598 local_irq_save(flags);
1599 ptep = find_linux_pte(mm->pgd, address, NULL, NULL);
1600 if (ptep)
1601 pkey = pte_to_pkey_bits(pte_val(READ_ONCE(*ptep)));
1602 local_irq_restore(flags);
1603
1604 return pkey;
1605}
1606#endif /* CONFIG_PPC_MEM_KEYS */
1607
1572#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 1608#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1573static inline void tm_flush_hash_page(int local) 1609static inline void tm_flush_hash_page(int local)
1574{ 1610{
@@ -1592,29 +1628,42 @@ static inline void tm_flush_hash_page(int local)
1592} 1628}
1593#endif 1629#endif
1594 1630
1631/*
1632 * Return the global hash slot, corresponding to the given PTE, which contains
1633 * the HPTE.
1634 */
1635unsigned long pte_get_hash_gslot(unsigned long vpn, unsigned long shift,
1636 int ssize, real_pte_t rpte, unsigned int subpg_index)
1637{
1638 unsigned long hash, gslot, hidx;
1639
1640 hash = hpt_hash(vpn, shift, ssize);
1641 hidx = __rpte_to_hidx(rpte, subpg_index);
1642 if (hidx & _PTEIDX_SECONDARY)
1643 hash = ~hash;
1644 gslot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
1645 gslot += hidx & _PTEIDX_GROUP_IX;
1646 return gslot;
1647}
1648
1595/* WARNING: This is called from hash_low_64.S, if you change this prototype, 1649/* WARNING: This is called from hash_low_64.S, if you change this prototype,
1596 * do not forget to update the assembly call site ! 1650 * do not forget to update the assembly call site !
1597 */ 1651 */
1598void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize, int ssize, 1652void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize, int ssize,
1599 unsigned long flags) 1653 unsigned long flags)
1600{ 1654{
1601 unsigned long hash, index, shift, hidx, slot; 1655 unsigned long index, shift, gslot;
1602 int local = flags & HPTE_LOCAL_UPDATE; 1656 int local = flags & HPTE_LOCAL_UPDATE;
1603 1657
1604 DBG_LOW("flush_hash_page(vpn=%016lx)\n", vpn); 1658 DBG_LOW("flush_hash_page(vpn=%016lx)\n", vpn);
1605 pte_iterate_hashed_subpages(pte, psize, vpn, index, shift) { 1659 pte_iterate_hashed_subpages(pte, psize, vpn, index, shift) {
1606 hash = hpt_hash(vpn, shift, ssize); 1660 gslot = pte_get_hash_gslot(vpn, shift, ssize, pte, index);
1607 hidx = __rpte_to_hidx(pte, index); 1661 DBG_LOW(" sub %ld: gslot=%lx\n", index, gslot);
1608 if (hidx & _PTEIDX_SECONDARY)
1609 hash = ~hash;
1610 slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
1611 slot += hidx & _PTEIDX_GROUP_IX;
1612 DBG_LOW(" sub %ld: hash=%lx, hidx=%lx\n", index, slot, hidx);
1613 /* 1662 /*
1614 * We use same base page size and actual psize, because we don't 1663 * We use same base page size and actual psize, because we don't
1615 * use these functions for hugepage 1664 * use these functions for hugepage
1616 */ 1665 */
1617 mmu_hash_ops.hpte_invalidate(slot, vpn, psize, psize, 1666 mmu_hash_ops.hpte_invalidate(gslot, vpn, psize, psize,
1618 ssize, local); 1667 ssize, local);
1619 } pte_iterate_hashed_end(); 1668 } pte_iterate_hashed_end();
1620 1669
@@ -1825,16 +1874,24 @@ void hash__setup_initial_memory_limit(phys_addr_t first_memblock_base,
1825 */ 1874 */
1826 BUG_ON(first_memblock_base != 0); 1875 BUG_ON(first_memblock_base != 0);
1827 1876
1828 /* On LPAR systems, the first entry is our RMA region, 1877 /*
1829 * non-LPAR 64-bit hash MMU systems don't have a limitation 1878 * On virtualized systems the first entry is our RMA region aka VRMA,
1830 * on real mode access, but using the first entry works well 1879 * non-virtualized 64-bit hash MMU systems don't have a limitation
1831 * enough. We also clamp it to 1G to avoid some funky things 1880 * on real mode access.
1832 * such as RTAS bugs etc... 1881 *
1882 * For guests on platforms before POWER9, we clamp the it limit to 1G
1883 * to avoid some funky things such as RTAS bugs etc...
1833 */ 1884 */
1834 ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000); 1885 if (!early_cpu_has_feature(CPU_FTR_HVMODE)) {
1886 ppc64_rma_size = first_memblock_size;
1887 if (!early_cpu_has_feature(CPU_FTR_ARCH_300))
1888 ppc64_rma_size = min_t(u64, ppc64_rma_size, 0x40000000);
1835 1889
1836 /* Finally limit subsequent allocations */ 1890 /* Finally limit subsequent allocations */
1837 memblock_set_current_limit(ppc64_rma_size); 1891 memblock_set_current_limit(ppc64_rma_size);
1892 } else {
1893 ppc64_rma_size = ULONG_MAX;
1894 }
1838} 1895}
1839 1896
1840#ifdef CONFIG_DEBUG_FS 1897#ifdef CONFIG_DEBUG_FS
diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c
index 0c2a91df3210..12511f5a015f 100644
--- a/arch/powerpc/mm/hugetlbpage-hash64.c
+++ b/arch/powerpc/mm/hugetlbpage-hash64.c
@@ -23,6 +23,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
23 pte_t *ptep, unsigned long trap, unsigned long flags, 23 pte_t *ptep, unsigned long trap, unsigned long flags,
24 int ssize, unsigned int shift, unsigned int mmu_psize) 24 int ssize, unsigned int shift, unsigned int mmu_psize)
25{ 25{
26 real_pte_t rpte;
26 unsigned long vpn; 27 unsigned long vpn;
27 unsigned long old_pte, new_pte; 28 unsigned long old_pte, new_pte;
28 unsigned long rflags, pa, sz; 29 unsigned long rflags, pa, sz;
@@ -62,6 +63,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
62 } while(!pte_xchg(ptep, __pte(old_pte), __pte(new_pte))); 63 } while(!pte_xchg(ptep, __pte(old_pte), __pte(new_pte)));
63 64
64 rflags = htab_convert_pte_flags(new_pte); 65 rflags = htab_convert_pte_flags(new_pte);
66 rpte = __real_pte(__pte(old_pte), ptep);
65 67
66 sz = ((1UL) << shift); 68 sz = ((1UL) << shift);
67 if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) 69 if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
@@ -72,15 +74,10 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
72 /* Check if pte already has an hpte (case 2) */ 74 /* Check if pte already has an hpte (case 2) */
73 if (unlikely(old_pte & H_PAGE_HASHPTE)) { 75 if (unlikely(old_pte & H_PAGE_HASHPTE)) {
74 /* There MIGHT be an HPTE for this pte */ 76 /* There MIGHT be an HPTE for this pte */
75 unsigned long hash, slot; 77 unsigned long gslot;
76 78
77 hash = hpt_hash(vpn, shift, ssize); 79 gslot = pte_get_hash_gslot(vpn, shift, ssize, rpte, 0);
78 if (old_pte & H_PAGE_F_SECOND) 80 if (mmu_hash_ops.hpte_updatepp(gslot, rflags, vpn, mmu_psize,
79 hash = ~hash;
80 slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
81 slot += (old_pte & H_PAGE_F_GIX) >> H_PAGE_F_GIX_SHIFT;
82
83 if (mmu_hash_ops.hpte_updatepp(slot, rflags, vpn, mmu_psize,
84 mmu_psize, ssize, flags) == -1) 81 mmu_psize, ssize, flags) == -1)
85 old_pte &= ~_PAGE_HPTEFLAGS; 82 old_pte &= ~_PAGE_HPTEFLAGS;
86 } 83 }
@@ -107,8 +104,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
107 return -1; 104 return -1;
108 } 105 }
109 106
110 new_pte |= (slot << H_PAGE_F_GIX_SHIFT) & 107 new_pte |= pte_set_hidx(ptep, rpte, 0, slot);
111 (H_PAGE_F_SECOND | H_PAGE_F_GIX);
112 } 108 }
113 109
114 /* 110 /*
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index a9b9083c5e49..876da2bc1796 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -96,7 +96,7 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp,
96 *hpdp = __hugepd(__pa(new) | 96 *hpdp = __hugepd(__pa(new) |
97 (shift_to_mmu_psize(pshift) << 2)); 97 (shift_to_mmu_psize(pshift) << 2));
98#elif defined(CONFIG_PPC_8xx) 98#elif defined(CONFIG_PPC_8xx)
99 *hpdp = __hugepd(__pa(new) | 99 *hpdp = __hugepd(__pa(new) | _PMD_USER |
100 (pshift == PAGE_SHIFT_8M ? _PMD_PAGE_8M : 100 (pshift == PAGE_SHIFT_8M ? _PMD_PAGE_8M :
101 _PMD_PAGE_512K) | _PMD_PRESENT); 101 _PMD_PAGE_512K) | _PMD_PRESENT);
102#else 102#else
@@ -752,7 +752,7 @@ void flush_dcache_icache_hugepage(struct page *page)
752 * So long as we atomically load page table pointers we are safe against teardown, 752 * So long as we atomically load page table pointers we are safe against teardown,
753 * we can follow the address down to the the page and take a ref on it. 753 * we can follow the address down to the the page and take a ref on it.
754 * This function need to be called with interrupts disabled. We use this variant 754 * This function need to be called with interrupts disabled. We use this variant
755 * when we have MSR[EE] = 0 but the paca->soft_enabled = 1 755 * when we have MSR[EE] = 0 but the paca->irq_soft_mask = IRQS_ENABLED
756 */ 756 */
757pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea, 757pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea,
758 bool *is_thp, unsigned *hpage_shift) 758 bool *is_thp, unsigned *hpage_shift)
@@ -855,9 +855,7 @@ int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
855 855
856 pte = READ_ONCE(*ptep); 856 pte = READ_ONCE(*ptep);
857 857
858 if (!pte_present(pte) || !pte_read(pte)) 858 if (!pte_access_permitted(pte, write))
859 return 0;
860 if (write && !pte_write(pte))
861 return 0; 859 return 0;
862 860
863 /* hugepages are never "special" */ 861 /* hugepages are never "special" */
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index a07722531b32..f6eb7e8f4c93 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -214,9 +214,8 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
214 214
215 rc = vmemmap_create_mapping(start, page_size, __pa(p)); 215 rc = vmemmap_create_mapping(start, page_size, __pa(p));
216 if (rc < 0) { 216 if (rc < 0) {
217 pr_warning( 217 pr_warn("%s: Unable to create vmemmap mapping: %d\n",
218 "vmemmap_populate: Unable to create vmemmap mapping: %d\n", 218 __func__, rc);
219 rc);
220 return -EFAULT; 219 return -EFAULT;
221 } 220 }
222 } 221 }
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 4362b86ef84c..1281c6eb3a85 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -138,8 +138,7 @@ int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
138 start = (unsigned long)__va(start); 138 start = (unsigned long)__va(start);
139 rc = create_section_mapping(start, start + size); 139 rc = create_section_mapping(start, start + size);
140 if (rc) { 140 if (rc) {
141 pr_warning( 141 pr_warn("Unable to create mapping for hot added memory 0x%llx..0x%llx: %d\n",
142 "Unable to create mapping for hot added memory 0x%llx..0x%llx: %d\n",
143 start, start + size, rc); 142 start, start + size, rc);
144 return -EFAULT; 143 return -EFAULT;
145 } 144 }
diff --git a/arch/powerpc/mm/mmu_context_book3s64.c b/arch/powerpc/mm/mmu_context_book3s64.c
index 59c0766ae4e0..929d9ef7083f 100644
--- a/arch/powerpc/mm/mmu_context_book3s64.c
+++ b/arch/powerpc/mm/mmu_context_book3s64.c
@@ -16,6 +16,7 @@
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/types.h> 17#include <linux/types.h>
18#include <linux/mm.h> 18#include <linux/mm.h>
19#include <linux/pkeys.h>
19#include <linux/spinlock.h> 20#include <linux/spinlock.h>
20#include <linux/idr.h> 21#include <linux/idr.h>
21#include <linux/export.h> 22#include <linux/export.h>
@@ -118,6 +119,7 @@ static int hash__init_new_context(struct mm_struct *mm)
118 119
119 subpage_prot_init_new_context(mm); 120 subpage_prot_init_new_context(mm);
120 121
122 pkey_mm_init(mm);
121 return index; 123 return index;
122} 124}
123 125
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index adb6364f4091..314d19ab9385 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -40,6 +40,7 @@
40#include <asm/hvcall.h> 40#include <asm/hvcall.h>
41#include <asm/setup.h> 41#include <asm/setup.h>
42#include <asm/vdso.h> 42#include <asm/vdso.h>
43#include <asm/drmem.h>
43 44
44static int numa_enabled = 1; 45static int numa_enabled = 1;
45 46
@@ -179,21 +180,6 @@ static const __be32 *of_get_associativity(struct device_node *dev)
179 return of_get_property(dev, "ibm,associativity", NULL); 180 return of_get_property(dev, "ibm,associativity", NULL);
180} 181}
181 182
182/*
183 * Returns the property linux,drconf-usable-memory if
184 * it exists (the property exists only in kexec/kdump kernels,
185 * added by kexec-tools)
186 */
187static const __be32 *of_get_usable_memory(struct device_node *memory)
188{
189 const __be32 *prop;
190 u32 len;
191 prop = of_get_property(memory, "linux,drconf-usable-memory", &len);
192 if (!prop || len < sizeof(unsigned int))
193 return NULL;
194 return prop;
195}
196
197int __node_distance(int a, int b) 183int __node_distance(int a, int b)
198{ 184{
199 int i; 185 int i;
@@ -387,69 +373,6 @@ static unsigned long read_n_cells(int n, const __be32 **buf)
387 return result; 373 return result;
388} 374}
389 375
390/*
391 * Read the next memblock list entry from the ibm,dynamic-memory property
392 * and return the information in the provided of_drconf_cell structure.
393 */
394static void read_drconf_cell(struct of_drconf_cell *drmem, const __be32 **cellp)
395{
396 const __be32 *cp;
397
398 drmem->base_addr = read_n_cells(n_mem_addr_cells, cellp);
399
400 cp = *cellp;
401 drmem->drc_index = of_read_number(cp, 1);
402 drmem->reserved = of_read_number(&cp[1], 1);
403 drmem->aa_index = of_read_number(&cp[2], 1);
404 drmem->flags = of_read_number(&cp[3], 1);
405
406 *cellp = cp + 4;
407}
408
409/*
410 * Retrieve and validate the ibm,dynamic-memory property of the device tree.
411 *
412 * The layout of the ibm,dynamic-memory property is a number N of memblock
413 * list entries followed by N memblock list entries. Each memblock list entry
414 * contains information as laid out in the of_drconf_cell struct above.
415 */
416static int of_get_drconf_memory(struct device_node *memory, const __be32 **dm)
417{
418 const __be32 *prop;
419 u32 len, entries;
420
421 prop = of_get_property(memory, "ibm,dynamic-memory", &len);
422 if (!prop || len < sizeof(unsigned int))
423 return 0;
424
425 entries = of_read_number(prop++, 1);
426
427 /* Now that we know the number of entries, revalidate the size
428 * of the property read in to ensure we have everything
429 */
430 if (len < (entries * (n_mem_addr_cells + 4) + 1) * sizeof(unsigned int))
431 return 0;
432
433 *dm = prop;
434 return entries;
435}
436
437/*
438 * Retrieve and validate the ibm,lmb-size property for drconf memory
439 * from the device tree.
440 */
441static u64 of_get_lmb_size(struct device_node *memory)
442{
443 const __be32 *prop;
444 u32 len;
445
446 prop = of_get_property(memory, "ibm,lmb-size", &len);
447 if (!prop || len < sizeof(unsigned int))
448 return 0;
449
450 return read_n_cells(n_mem_size_cells, &prop);
451}
452
453struct assoc_arrays { 376struct assoc_arrays {
454 u32 n_arrays; 377 u32 n_arrays;
455 u32 array_sz; 378 u32 array_sz;
@@ -466,19 +389,27 @@ struct assoc_arrays {
466 * indicating the size of each associativity array, followed by a list 389 * indicating the size of each associativity array, followed by a list
467 * of N associativity arrays. 390 * of N associativity arrays.
468 */ 391 */
469static int of_get_assoc_arrays(struct device_node *memory, 392static int of_get_assoc_arrays(struct assoc_arrays *aa)
470 struct assoc_arrays *aa)
471{ 393{
394 struct device_node *memory;
472 const __be32 *prop; 395 const __be32 *prop;
473 u32 len; 396 u32 len;
474 397
398 memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
399 if (!memory)
400 return -1;
401
475 prop = of_get_property(memory, "ibm,associativity-lookup-arrays", &len); 402 prop = of_get_property(memory, "ibm,associativity-lookup-arrays", &len);
476 if (!prop || len < 2 * sizeof(unsigned int)) 403 if (!prop || len < 2 * sizeof(unsigned int)) {
404 of_node_put(memory);
477 return -1; 405 return -1;
406 }
478 407
479 aa->n_arrays = of_read_number(prop++, 1); 408 aa->n_arrays = of_read_number(prop++, 1);
480 aa->array_sz = of_read_number(prop++, 1); 409 aa->array_sz = of_read_number(prop++, 1);
481 410
411 of_node_put(memory);
412
482 /* Now that we know the number of arrays and size of each array, 413 /* Now that we know the number of arrays and size of each array,
483 * revalidate the size of the property read in. 414 * revalidate the size of the property read in.
484 */ 415 */
@@ -493,26 +424,30 @@ static int of_get_assoc_arrays(struct device_node *memory,
493 * This is like of_node_to_nid_single() for memory represented in the 424 * This is like of_node_to_nid_single() for memory represented in the
494 * ibm,dynamic-reconfiguration-memory node. 425 * ibm,dynamic-reconfiguration-memory node.
495 */ 426 */
496static int of_drconf_to_nid_single(struct of_drconf_cell *drmem, 427static int of_drconf_to_nid_single(struct drmem_lmb *lmb)
497 struct assoc_arrays *aa)
498{ 428{
429 struct assoc_arrays aa = { .arrays = NULL };
499 int default_nid = 0; 430 int default_nid = 0;
500 int nid = default_nid; 431 int nid = default_nid;
501 int index; 432 int rc, index;
433
434 rc = of_get_assoc_arrays(&aa);
435 if (rc)
436 return default_nid;
502 437
503 if (min_common_depth > 0 && min_common_depth <= aa->array_sz && 438 if (min_common_depth > 0 && min_common_depth <= aa.array_sz &&
504 !(drmem->flags & DRCONF_MEM_AI_INVALID) && 439 !(lmb->flags & DRCONF_MEM_AI_INVALID) &&
505 drmem->aa_index < aa->n_arrays) { 440 lmb->aa_index < aa.n_arrays) {
506 index = drmem->aa_index * aa->array_sz + min_common_depth - 1; 441 index = lmb->aa_index * aa.array_sz + min_common_depth - 1;
507 nid = of_read_number(&aa->arrays[index], 1); 442 nid = of_read_number(&aa.arrays[index], 1);
508 443
509 if (nid == 0xffff || nid >= MAX_NUMNODES) 444 if (nid == 0xffff || nid >= MAX_NUMNODES)
510 nid = default_nid; 445 nid = default_nid;
511 446
512 if (nid > 0) { 447 if (nid > 0) {
513 index = drmem->aa_index * aa->array_sz; 448 index = lmb->aa_index * aa.array_sz;
514 initialize_distance_lookup_table(nid, 449 initialize_distance_lookup_table(nid,
515 &aa->arrays[index]); 450 &aa.arrays[index]);
516 } 451 }
517 } 452 }
518 453
@@ -551,7 +486,7 @@ static int numa_setup_cpu(unsigned long lcpu)
551 nid = of_node_to_nid_single(cpu); 486 nid = of_node_to_nid_single(cpu);
552 487
553out_present: 488out_present:
554 if (nid < 0 || !node_online(nid)) 489 if (nid < 0 || !node_possible(nid))
555 nid = first_online_node; 490 nid = first_online_node;
556 491
557 map_cpu_to_node(lcpu, nid); 492 map_cpu_to_node(lcpu, nid);
@@ -645,67 +580,48 @@ static inline int __init read_usm_ranges(const __be32 **usm)
645 * Extract NUMA information from the ibm,dynamic-reconfiguration-memory 580 * Extract NUMA information from the ibm,dynamic-reconfiguration-memory
646 * node. This assumes n_mem_{addr,size}_cells have been set. 581 * node. This assumes n_mem_{addr,size}_cells have been set.
647 */ 582 */
648static void __init parse_drconf_memory(struct device_node *memory) 583static void __init numa_setup_drmem_lmb(struct drmem_lmb *lmb,
584 const __be32 **usm)
649{ 585{
650 const __be32 *uninitialized_var(dm), *usm; 586 unsigned int ranges, is_kexec_kdump = 0;
651 unsigned int n, rc, ranges, is_kexec_kdump = 0; 587 unsigned long base, size, sz;
652 unsigned long lmb_size, base, size, sz;
653 int nid; 588 int nid;
654 struct assoc_arrays aa = { .arrays = NULL };
655
656 n = of_get_drconf_memory(memory, &dm);
657 if (!n)
658 return;
659
660 lmb_size = of_get_lmb_size(memory);
661 if (!lmb_size)
662 return;
663 589
664 rc = of_get_assoc_arrays(memory, &aa); 590 /*
665 if (rc) 591 * Skip this block if the reserved bit is set in flags (0x80)
592 * or if the block is not assigned to this partition (0x8)
593 */
594 if ((lmb->flags & DRCONF_MEM_RESERVED)
595 || !(lmb->flags & DRCONF_MEM_ASSIGNED))
666 return; 596 return;
667 597
668 /* check if this is a kexec/kdump kernel */ 598 if (*usm)
669 usm = of_get_usable_memory(memory);
670 if (usm != NULL)
671 is_kexec_kdump = 1; 599 is_kexec_kdump = 1;
672 600
673 for (; n != 0; --n) { 601 base = lmb->base_addr;
674 struct of_drconf_cell drmem; 602 size = drmem_lmb_size();
675 603 ranges = 1;
676 read_drconf_cell(&drmem, &dm);
677 604
678 /* skip this block if the reserved bit is set in flags (0x80) 605 if (is_kexec_kdump) {
679 or if the block is not assigned to this partition (0x8) */ 606 ranges = read_usm_ranges(usm);
680 if ((drmem.flags & DRCONF_MEM_RESERVED) 607 if (!ranges) /* there are no (base, size) duple */
681 || !(drmem.flags & DRCONF_MEM_ASSIGNED)) 608 return;
682 continue; 609 }
683
684 base = drmem.base_addr;
685 size = lmb_size;
686 ranges = 1;
687 610
611 do {
688 if (is_kexec_kdump) { 612 if (is_kexec_kdump) {
689 ranges = read_usm_ranges(&usm); 613 base = read_n_cells(n_mem_addr_cells, usm);
690 if (!ranges) /* there are no (base, size) duple */ 614 size = read_n_cells(n_mem_size_cells, usm);
691 continue;
692 } 615 }
693 do { 616
694 if (is_kexec_kdump) { 617 nid = of_drconf_to_nid_single(lmb);
695 base = read_n_cells(n_mem_addr_cells, &usm); 618 fake_numa_create_new_node(((base + size) >> PAGE_SHIFT),
696 size = read_n_cells(n_mem_size_cells, &usm); 619 &nid);
697 } 620 node_set_online(nid);
698 nid = of_drconf_to_nid_single(&drmem, &aa); 621 sz = numa_enforce_memory_limit(base, size);
699 fake_numa_create_new_node( 622 if (sz)
700 ((base + size) >> PAGE_SHIFT), 623 memblock_set_node(base, sz, &memblock.memory, nid);
701 &nid); 624 } while (--ranges);
702 node_set_online(nid);
703 sz = numa_enforce_memory_limit(base, size);
704 if (sz)
705 memblock_set_node(base, sz,
706 &memblock.memory, nid);
707 } while (--ranges);
708 }
709} 625}
710 626
711static int __init parse_numa_properties(void) 627static int __init parse_numa_properties(void)
@@ -800,8 +716,10 @@ new_range:
800 * ibm,dynamic-reconfiguration-memory node. 716 * ibm,dynamic-reconfiguration-memory node.
801 */ 717 */
802 memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); 718 memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
803 if (memory) 719 if (memory) {
804 parse_drconf_memory(memory); 720 walk_drmem_lmbs(memory, numa_setup_drmem_lmb);
721 of_node_put(memory);
722 }
805 723
806 return 0; 724 return 0;
807} 725}
@@ -892,6 +810,32 @@ static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn)
892 NODE_DATA(nid)->node_spanned_pages = spanned_pages; 810 NODE_DATA(nid)->node_spanned_pages = spanned_pages;
893} 811}
894 812
813static void __init find_possible_nodes(void)
814{
815 struct device_node *rtas;
816 u32 numnodes, i;
817
818 if (min_common_depth <= 0)
819 return;
820
821 rtas = of_find_node_by_path("/rtas");
822 if (!rtas)
823 return;
824
825 if (of_property_read_u32_index(rtas,
826 "ibm,max-associativity-domains",
827 min_common_depth, &numnodes))
828 goto out;
829
830 for (i = 0; i < numnodes; i++) {
831 if (!node_possible(i))
832 node_set(i, node_possible_map);
833 }
834
835out:
836 of_node_put(rtas);
837}
838
895void __init initmem_init(void) 839void __init initmem_init(void)
896{ 840{
897 int nid, cpu; 841 int nid, cpu;
@@ -905,12 +849,15 @@ void __init initmem_init(void)
905 memblock_dump_all(); 849 memblock_dump_all();
906 850
907 /* 851 /*
908 * Reduce the possible NUMA nodes to the online NUMA nodes, 852 * Modify the set of possible NUMA nodes to reflect information
909 * since we do not support node hotplug. This ensures that we 853 * available about the set of online nodes, and the set of nodes
910 * lower the maximum NUMA node ID to what is actually present. 854 * that we expect to make use of for this platform's affinity
855 * calculations.
911 */ 856 */
912 nodes_and(node_possible_map, node_possible_map, node_online_map); 857 nodes_and(node_possible_map, node_possible_map, node_online_map);
913 858
859 find_possible_nodes();
860
914 for_each_online_node(nid) { 861 for_each_online_node(nid) {
915 unsigned long start_pfn, end_pfn; 862 unsigned long start_pfn, end_pfn;
916 863
@@ -979,43 +926,26 @@ early_param("topology_updates", early_topology_updates);
979 * memory represented in the device tree by the property 926 * memory represented in the device tree by the property
980 * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory. 927 * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory.
981 */ 928 */
982static int hot_add_drconf_scn_to_nid(struct device_node *memory, 929static int hot_add_drconf_scn_to_nid(unsigned long scn_addr)
983 unsigned long scn_addr)
984{ 930{
985 const __be32 *dm; 931 struct drmem_lmb *lmb;
986 unsigned int drconf_cell_cnt, rc;
987 unsigned long lmb_size; 932 unsigned long lmb_size;
988 struct assoc_arrays aa;
989 int nid = -1; 933 int nid = -1;
990 934
991 drconf_cell_cnt = of_get_drconf_memory(memory, &dm); 935 lmb_size = drmem_lmb_size();
992 if (!drconf_cell_cnt)
993 return -1;
994
995 lmb_size = of_get_lmb_size(memory);
996 if (!lmb_size)
997 return -1;
998
999 rc = of_get_assoc_arrays(memory, &aa);
1000 if (rc)
1001 return -1;
1002
1003 for (; drconf_cell_cnt != 0; --drconf_cell_cnt) {
1004 struct of_drconf_cell drmem;
1005
1006 read_drconf_cell(&drmem, &dm);
1007 936
937 for_each_drmem_lmb(lmb) {
1008 /* skip this block if it is reserved or not assigned to 938 /* skip this block if it is reserved or not assigned to
1009 * this partition */ 939 * this partition */
1010 if ((drmem.flags & DRCONF_MEM_RESERVED) 940 if ((lmb->flags & DRCONF_MEM_RESERVED)
1011 || !(drmem.flags & DRCONF_MEM_ASSIGNED)) 941 || !(lmb->flags & DRCONF_MEM_ASSIGNED))
1012 continue; 942 continue;
1013 943
1014 if ((scn_addr < drmem.base_addr) 944 if ((scn_addr < lmb->base_addr)
1015 || (scn_addr >= (drmem.base_addr + lmb_size))) 945 || (scn_addr >= (lmb->base_addr + lmb_size)))
1016 continue; 946 continue;
1017 947
1018 nid = of_drconf_to_nid_single(&drmem, &aa); 948 nid = of_drconf_to_nid_single(lmb);
1019 break; 949 break;
1020 } 950 }
1021 951
@@ -1080,7 +1010,7 @@ int hot_add_scn_to_nid(unsigned long scn_addr)
1080 1010
1081 memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); 1011 memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
1082 if (memory) { 1012 if (memory) {
1083 nid = hot_add_drconf_scn_to_nid(memory, scn_addr); 1013 nid = hot_add_drconf_scn_to_nid(scn_addr);
1084 of_node_put(memory); 1014 of_node_put(memory);
1085 } else { 1015 } else {
1086 nid = hot_add_node_scn_to_nid(scn_addr); 1016 nid = hot_add_node_scn_to_nid(scn_addr);
@@ -1096,11 +1026,7 @@ static u64 hot_add_drconf_memory_max(void)
1096{ 1026{
1097 struct device_node *memory = NULL; 1027 struct device_node *memory = NULL;
1098 struct device_node *dn = NULL; 1028 struct device_node *dn = NULL;
1099 unsigned int drconf_cell_cnt = 0;
1100 u64 lmb_size = 0;
1101 const __be32 *dm = NULL;
1102 const __be64 *lrdr = NULL; 1029 const __be64 *lrdr = NULL;
1103 struct of_drconf_cell drmem;
1104 1030
1105 dn = of_find_node_by_path("/rtas"); 1031 dn = of_find_node_by_path("/rtas");
1106 if (dn) { 1032 if (dn) {
@@ -1112,14 +1038,8 @@ static u64 hot_add_drconf_memory_max(void)
1112 1038
1113 memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); 1039 memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
1114 if (memory) { 1040 if (memory) {
1115 drconf_cell_cnt = of_get_drconf_memory(memory, &dm);
1116 lmb_size = of_get_lmb_size(memory);
1117
1118 /* Advance to the last cell, each cell has 6 32 bit integers */
1119 dm += (drconf_cell_cnt - 1) * 6;
1120 read_drconf_cell(&drmem, &dm);
1121 of_node_put(memory); 1041 of_node_put(memory);
1122 return drmem.base_addr + lmb_size; 1042 return drmem_lmb_memory_max();
1123 } 1043 }
1124 return 0; 1044 return 0;
1125} 1045}
@@ -1278,6 +1198,42 @@ static long vphn_get_associativity(unsigned long cpu,
1278 return rc; 1198 return rc;
1279} 1199}
1280 1200
1201int find_and_online_cpu_nid(int cpu)
1202{
1203 __be32 associativity[VPHN_ASSOC_BUFSIZE] = {0};
1204 int new_nid;
1205
1206 /* Use associativity from first thread for all siblings */
1207 vphn_get_associativity(cpu, associativity);
1208 new_nid = associativity_to_nid(associativity);
1209 if (new_nid < 0 || !node_possible(new_nid))
1210 new_nid = first_online_node;
1211
1212 if (NODE_DATA(new_nid) == NULL) {
1213#ifdef CONFIG_MEMORY_HOTPLUG
1214 /*
1215 * Need to ensure that NODE_DATA is initialized for a node from
1216 * available memory (see memblock_alloc_try_nid). If unable to
1217 * init the node, then default to nearest node that has memory
1218 * installed.
1219 */
1220 if (try_online_node(new_nid))
1221 new_nid = first_online_node;
1222#else
1223 /*
1224 * Default to using the nearest node that has memory installed.
1225 * Otherwise, it would be necessary to patch the kernel MM code
1226 * to deal with more memoryless-node error conditions.
1227 */
1228 new_nid = first_online_node;
1229#endif
1230 }
1231
1232 pr_debug("%s:%d cpu %d nid %d\n", __FUNCTION__, __LINE__,
1233 cpu, new_nid);
1234 return new_nid;
1235}
1236
1281/* 1237/*
1282 * Update the CPU maps and sysfs entries for a single CPU when its NUMA 1238 * Update the CPU maps and sysfs entries for a single CPU when its NUMA
1283 * characteristics change. This function doesn't perform any locking and is 1239 * characteristics change. This function doesn't perform any locking and is
@@ -1345,7 +1301,6 @@ int numa_update_cpu_topology(bool cpus_locked)
1345{ 1301{
1346 unsigned int cpu, sibling, changed = 0; 1302 unsigned int cpu, sibling, changed = 0;
1347 struct topology_update_data *updates, *ud; 1303 struct topology_update_data *updates, *ud;
1348 __be32 associativity[VPHN_ASSOC_BUFSIZE] = {0};
1349 cpumask_t updated_cpus; 1304 cpumask_t updated_cpus;
1350 struct device *dev; 1305 struct device *dev;
1351 int weight, new_nid, i = 0; 1306 int weight, new_nid, i = 0;
@@ -1383,11 +1338,7 @@ int numa_update_cpu_topology(bool cpus_locked)
1383 continue; 1338 continue;
1384 } 1339 }
1385 1340
1386 /* Use associativity from first thread for all siblings */ 1341 new_nid = find_and_online_cpu_nid(cpu);
1387 vphn_get_associativity(cpu, associativity);
1388 new_nid = associativity_to_nid(associativity);
1389 if (new_nid < 0 || !node_online(new_nid))
1390 new_nid = first_online_node;
1391 1342
1392 if (new_nid == numa_cpu_lookup_table[cpu]) { 1343 if (new_nid == numa_cpu_lookup_table[cpu]) {
1393 cpumask_andnot(&cpu_associativity_changes_mask, 1344 cpumask_andnot(&cpu_associativity_changes_mask,
diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c
index cfbbee941a76..573a9a2ee455 100644
--- a/arch/powerpc/mm/pgtable-radix.c
+++ b/arch/powerpc/mm/pgtable-radix.c
@@ -579,6 +579,9 @@ void __init radix__early_init_mmu(void)
579 579
580 radix_init_iamr(); 580 radix_init_iamr();
581 radix_init_pgtable(); 581 radix_init_pgtable();
582
583 if (cpu_has_feature(CPU_FTR_HVMODE))
584 tlbiel_all();
582} 585}
583 586
584void radix__early_init_mmu_secondary(void) 587void radix__early_init_mmu_secondary(void)
@@ -600,6 +603,9 @@ void radix__early_init_mmu_secondary(void)
600 radix_init_amor(); 603 radix_init_amor();
601 } 604 }
602 radix_init_iamr(); 605 radix_init_iamr();
606
607 if (cpu_has_feature(CPU_FTR_HVMODE))
608 tlbiel_all();
603} 609}
604 610
605void radix__mmu_cleanup_all(void) 611void radix__mmu_cleanup_all(void)
@@ -622,22 +628,11 @@ void radix__setup_initial_memory_limit(phys_addr_t first_memblock_base,
622 * physical on those processors 628 * physical on those processors
623 */ 629 */
624 BUG_ON(first_memblock_base != 0); 630 BUG_ON(first_memblock_base != 0);
631
625 /* 632 /*
626 * We limit the allocation that depend on ppc64_rma_size 633 * Radix mode is not limited by RMA / VRMA addressing.
627 * to first_memblock_size. We also clamp it to 1GB to
628 * avoid some funky things such as RTAS bugs.
629 *
630 * On radix config we really don't have a limitation
631 * on real mode access. But keeping it as above works
632 * well enough.
633 */
634 ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000);
635 /*
636 * Finally limit subsequent allocations. We really don't want
637 * to limit the memblock allocations to rma_size. FIXME!! should
638 * we even limit at all ?
639 */ 634 */
640 memblock_set_current_limit(first_memblock_base + first_memblock_size); 635 ppc64_rma_size = ULONG_MAX;
641} 636}
642 637
643#ifdef CONFIG_MEMORY_HOTPLUG 638#ifdef CONFIG_MEMORY_HOTPLUG
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index a03ff3d99e0c..9f361ae571e9 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -54,7 +54,8 @@ static inline int pte_looks_normal(pte_t pte)
54 return 0; 54 return 0;
55#else 55#else
56 return (pte_val(pte) & 56 return (pte_val(pte) &
57 (_PAGE_PRESENT | _PAGE_SPECIAL | _PAGE_NO_CACHE | _PAGE_USER)) == 57 (_PAGE_PRESENT | _PAGE_SPECIAL | _PAGE_NO_CACHE | _PAGE_USER |
58 _PAGE_PRIVILEGED)) ==
58 (_PAGE_PRESENT | _PAGE_USER); 59 (_PAGE_PRESENT | _PAGE_USER);
59#endif 60#endif
60} 61}
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index f6c7f54c0515..d35d9ad3c1cd 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -98,14 +98,7 @@ ioremap_prot(phys_addr_t addr, unsigned long size, unsigned long flags)
98 98
99 /* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */ 99 /* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */
100 flags &= ~(_PAGE_USER | _PAGE_EXEC); 100 flags &= ~(_PAGE_USER | _PAGE_EXEC);
101 101 flags |= _PAGE_PRIVILEGED;
102#ifdef _PAGE_BAP_SR
103 /* _PAGE_USER contains _PAGE_BAP_SR on BookE using the new PTE format
104 * which means that we just cleared supervisor access... oops ;-) This
105 * restores it
106 */
107 flags |= _PAGE_BAP_SR;
108#endif
109 102
110 return __ioremap_caller(addr, size, flags, __builtin_return_address(0)); 103 return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
111} 104}
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 813ea22c3e00..c9a623c2d8a2 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -244,20 +244,8 @@ void __iomem * ioremap_prot(phys_addr_t addr, unsigned long size,
244 /* 244 /*
245 * Force kernel mapping. 245 * Force kernel mapping.
246 */ 246 */
247#if defined(CONFIG_PPC_BOOK3S_64)
248 flags |= _PAGE_PRIVILEGED;
249#else
250 flags &= ~_PAGE_USER; 247 flags &= ~_PAGE_USER;
251#endif 248 flags |= _PAGE_PRIVILEGED;
252
253
254#ifdef _PAGE_BAP_SR
255 /* _PAGE_USER contains _PAGE_BAP_SR on BookE using the new PTE format
256 * which means that we just cleared supervisor access... oops ;-) This
257 * restores it
258 */
259 flags |= _PAGE_BAP_SR;
260#endif
261 249
262 if (ppc_md.ioremap) 250 if (ppc_md.ioremap)
263 return ppc_md.ioremap(addr, size, flags, caller); 251 return ppc_md.ioremap(addr, size, flags, caller);
diff --git a/arch/powerpc/mm/pkeys.c b/arch/powerpc/mm/pkeys.c
new file mode 100644
index 000000000000..ba71c5481f42
--- /dev/null
+++ b/arch/powerpc/mm/pkeys.c
@@ -0,0 +1,468 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * PowerPC Memory Protection Keys management
4 *
5 * Copyright 2017, Ram Pai, IBM Corporation.
6 */
7
8#include <asm/mman.h>
9#include <asm/setup.h>
10#include <linux/pkeys.h>
11#include <linux/of_device.h>
12
13DEFINE_STATIC_KEY_TRUE(pkey_disabled);
14bool pkey_execute_disable_supported;
15int pkeys_total; /* Total pkeys as per device tree */
16bool pkeys_devtree_defined; /* pkey property exported by device tree */
17u32 initial_allocation_mask; /* Bits set for reserved keys */
18u64 pkey_amr_uamor_mask; /* Bits in AMR/UMOR not to be touched */
19u64 pkey_iamr_mask; /* Bits in AMR not to be touched */
20
21#define AMR_BITS_PER_PKEY 2
22#define AMR_RD_BIT 0x1UL
23#define AMR_WR_BIT 0x2UL
24#define IAMR_EX_BIT 0x1UL
25#define PKEY_REG_BITS (sizeof(u64)*8)
26#define pkeyshift(pkey) (PKEY_REG_BITS - ((pkey+1) * AMR_BITS_PER_PKEY))
27
28static void scan_pkey_feature(void)
29{
30 u32 vals[2];
31 struct device_node *cpu;
32
33 cpu = of_find_node_by_type(NULL, "cpu");
34 if (!cpu)
35 return;
36
37 if (of_property_read_u32_array(cpu,
38 "ibm,processor-storage-keys", vals, 2))
39 return;
40
41 /*
42 * Since any pkey can be used for data or execute, we will just treat
43 * all keys as equal and track them as one entity.
44 */
45 pkeys_total = be32_to_cpu(vals[0]);
46 pkeys_devtree_defined = true;
47}
48
49static inline bool pkey_mmu_enabled(void)
50{
51 if (firmware_has_feature(FW_FEATURE_LPAR))
52 return pkeys_total;
53 else
54 return cpu_has_feature(CPU_FTR_PKEY);
55}
56
57int pkey_initialize(void)
58{
59 int os_reserved, i;
60
61 /*
62 * We define PKEY_DISABLE_EXECUTE in addition to the arch-neutral
63 * generic defines for PKEY_DISABLE_ACCESS and PKEY_DISABLE_WRITE.
64 * Ensure that the bits a distinct.
65 */
66 BUILD_BUG_ON(PKEY_DISABLE_EXECUTE &
67 (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE));
68
69 /*
70 * pkey_to_vmflag_bits() assumes that the pkey bits are contiguous
71 * in the vmaflag. Make sure that is really the case.
72 */
73 BUILD_BUG_ON(__builtin_clzl(ARCH_VM_PKEY_FLAGS >> VM_PKEY_SHIFT) +
74 __builtin_popcountl(ARCH_VM_PKEY_FLAGS >> VM_PKEY_SHIFT)
75 != (sizeof(u64) * BITS_PER_BYTE));
76
77 /* scan the device tree for pkey feature */
78 scan_pkey_feature();
79
80 /*
81 * Let's assume 32 pkeys on P8 bare metal, if its not defined by device
82 * tree. We make this exception since skiboot forgot to expose this
83 * property on power8.
84 */
85 if (!pkeys_devtree_defined && !firmware_has_feature(FW_FEATURE_LPAR) &&
86 cpu_has_feature(CPU_FTRS_POWER8))
87 pkeys_total = 32;
88
89 /*
90 * Adjust the upper limit, based on the number of bits supported by
91 * arch-neutral code.
92 */
93 pkeys_total = min_t(int, pkeys_total,
94 (ARCH_VM_PKEY_FLAGS >> VM_PKEY_SHIFT));
95
96 if (!pkey_mmu_enabled() || radix_enabled() || !pkeys_total)
97 static_branch_enable(&pkey_disabled);
98 else
99 static_branch_disable(&pkey_disabled);
100
101 if (static_branch_likely(&pkey_disabled))
102 return 0;
103
104 /*
105 * The device tree cannot be relied to indicate support for
106 * execute_disable support. Instead we use a PVR check.
107 */
108 if (pvr_version_is(PVR_POWER7) || pvr_version_is(PVR_POWER7p))
109 pkey_execute_disable_supported = false;
110 else
111 pkey_execute_disable_supported = true;
112
113#ifdef CONFIG_PPC_4K_PAGES
114 /*
115 * The OS can manage only 8 pkeys due to its inability to represent them
116 * in the Linux 4K PTE.
117 */
118 os_reserved = pkeys_total - 8;
119#else
120 os_reserved = 0;
121#endif
122 /*
123 * Bits are in LE format. NOTE: 1, 0 are reserved.
124 * key 0 is the default key, which allows read/write/execute.
125 * key 1 is recommended not to be used. PowerISA(3.0) page 1015,
126 * programming note.
127 */
128 initial_allocation_mask = ~0x0;
129
130 /* register mask is in BE format */
131 pkey_amr_uamor_mask = ~0x0ul;
132 pkey_iamr_mask = ~0x0ul;
133
134 for (i = 2; i < (pkeys_total - os_reserved); i++) {
135 initial_allocation_mask &= ~(0x1 << i);
136 pkey_amr_uamor_mask &= ~(0x3ul << pkeyshift(i));
137 pkey_iamr_mask &= ~(0x1ul << pkeyshift(i));
138 }
139 return 0;
140}
141
142arch_initcall(pkey_initialize);
143
144void pkey_mm_init(struct mm_struct *mm)
145{
146 if (static_branch_likely(&pkey_disabled))
147 return;
148 mm_pkey_allocation_map(mm) = initial_allocation_mask;
149 /* -1 means unallocated or invalid */
150 mm->context.execute_only_pkey = -1;
151}
152
153static inline u64 read_amr(void)
154{
155 return mfspr(SPRN_AMR);
156}
157
158static inline void write_amr(u64 value)
159{
160 mtspr(SPRN_AMR, value);
161}
162
163static inline u64 read_iamr(void)
164{
165 if (!likely(pkey_execute_disable_supported))
166 return 0x0UL;
167
168 return mfspr(SPRN_IAMR);
169}
170
171static inline void write_iamr(u64 value)
172{
173 if (!likely(pkey_execute_disable_supported))
174 return;
175
176 mtspr(SPRN_IAMR, value);
177}
178
179static inline u64 read_uamor(void)
180{
181 return mfspr(SPRN_UAMOR);
182}
183
184static inline void write_uamor(u64 value)
185{
186 mtspr(SPRN_UAMOR, value);
187}
188
189static bool is_pkey_enabled(int pkey)
190{
191 u64 uamor = read_uamor();
192 u64 pkey_bits = 0x3ul << pkeyshift(pkey);
193 u64 uamor_pkey_bits = (uamor & pkey_bits);
194
195 /*
196 * Both the bits in UAMOR corresponding to the key should be set or
197 * reset.
198 */
199 WARN_ON(uamor_pkey_bits && (uamor_pkey_bits != pkey_bits));
200 return !!(uamor_pkey_bits);
201}
202
203static inline void init_amr(int pkey, u8 init_bits)
204{
205 u64 new_amr_bits = (((u64)init_bits & 0x3UL) << pkeyshift(pkey));
206 u64 old_amr = read_amr() & ~((u64)(0x3ul) << pkeyshift(pkey));
207
208 write_amr(old_amr | new_amr_bits);
209}
210
211static inline void init_iamr(int pkey, u8 init_bits)
212{
213 u64 new_iamr_bits = (((u64)init_bits & 0x1UL) << pkeyshift(pkey));
214 u64 old_iamr = read_iamr() & ~((u64)(0x1ul) << pkeyshift(pkey));
215
216 write_iamr(old_iamr | new_iamr_bits);
217}
218
219static void pkey_status_change(int pkey, bool enable)
220{
221 u64 old_uamor;
222
223 /* Reset the AMR and IAMR bits for this key */
224 init_amr(pkey, 0x0);
225 init_iamr(pkey, 0x0);
226
227 /* Enable/disable key */
228 old_uamor = read_uamor();
229 if (enable)
230 old_uamor |= (0x3ul << pkeyshift(pkey));
231 else
232 old_uamor &= ~(0x3ul << pkeyshift(pkey));
233 write_uamor(old_uamor);
234}
235
236void __arch_activate_pkey(int pkey)
237{
238 pkey_status_change(pkey, true);
239}
240
241void __arch_deactivate_pkey(int pkey)
242{
243 pkey_status_change(pkey, false);
244}
245
246/*
247 * Set the access rights in AMR IAMR and UAMOR registers for @pkey to that
248 * specified in @init_val.
249 */
250int __arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
251 unsigned long init_val)
252{
253 u64 new_amr_bits = 0x0ul;
254 u64 new_iamr_bits = 0x0ul;
255
256 if (!is_pkey_enabled(pkey))
257 return -EINVAL;
258
259 if (init_val & PKEY_DISABLE_EXECUTE) {
260 if (!pkey_execute_disable_supported)
261 return -EINVAL;
262 new_iamr_bits |= IAMR_EX_BIT;
263 }
264 init_iamr(pkey, new_iamr_bits);
265
266 /* Set the bits we need in AMR: */
267 if (init_val & PKEY_DISABLE_ACCESS)
268 new_amr_bits |= AMR_RD_BIT | AMR_WR_BIT;
269 else if (init_val & PKEY_DISABLE_WRITE)
270 new_amr_bits |= AMR_WR_BIT;
271
272 init_amr(pkey, new_amr_bits);
273 return 0;
274}
275
276void thread_pkey_regs_save(struct thread_struct *thread)
277{
278 if (static_branch_likely(&pkey_disabled))
279 return;
280
281 /*
282 * TODO: Skip saving registers if @thread hasn't used any keys yet.
283 */
284 thread->amr = read_amr();
285 thread->iamr = read_iamr();
286 thread->uamor = read_uamor();
287}
288
289void thread_pkey_regs_restore(struct thread_struct *new_thread,
290 struct thread_struct *old_thread)
291{
292 if (static_branch_likely(&pkey_disabled))
293 return;
294
295 /*
296 * TODO: Just set UAMOR to zero if @new_thread hasn't used any keys yet.
297 */
298 if (old_thread->amr != new_thread->amr)
299 write_amr(new_thread->amr);
300 if (old_thread->iamr != new_thread->iamr)
301 write_iamr(new_thread->iamr);
302 if (old_thread->uamor != new_thread->uamor)
303 write_uamor(new_thread->uamor);
304}
305
306void thread_pkey_regs_init(struct thread_struct *thread)
307{
308 if (static_branch_likely(&pkey_disabled))
309 return;
310
311 write_amr(read_amr() & pkey_amr_uamor_mask);
312 write_iamr(read_iamr() & pkey_iamr_mask);
313 write_uamor(read_uamor() & pkey_amr_uamor_mask);
314}
315
316static inline bool pkey_allows_readwrite(int pkey)
317{
318 int pkey_shift = pkeyshift(pkey);
319
320 if (!is_pkey_enabled(pkey))
321 return true;
322
323 return !(read_amr() & ((AMR_RD_BIT|AMR_WR_BIT) << pkey_shift));
324}
325
326int __execute_only_pkey(struct mm_struct *mm)
327{
328 bool need_to_set_mm_pkey = false;
329 int execute_only_pkey = mm->context.execute_only_pkey;
330 int ret;
331
332 /* Do we need to assign a pkey for mm's execute-only maps? */
333 if (execute_only_pkey == -1) {
334 /* Go allocate one to use, which might fail */
335 execute_only_pkey = mm_pkey_alloc(mm);
336 if (execute_only_pkey < 0)
337 return -1;
338 need_to_set_mm_pkey = true;
339 }
340
341 /*
342 * We do not want to go through the relatively costly dance to set AMR
343 * if we do not need to. Check it first and assume that if the
344 * execute-only pkey is readwrite-disabled than we do not have to set it
345 * ourselves.
346 */
347 if (!need_to_set_mm_pkey && !pkey_allows_readwrite(execute_only_pkey))
348 return execute_only_pkey;
349
350 /*
351 * Set up AMR so that it denies access for everything other than
352 * execution.
353 */
354 ret = __arch_set_user_pkey_access(current, execute_only_pkey,
355 PKEY_DISABLE_ACCESS |
356 PKEY_DISABLE_WRITE);
357 /*
358 * If the AMR-set operation failed somehow, just return 0 and
359 * effectively disable execute-only support.
360 */
361 if (ret) {
362 mm_pkey_free(mm, execute_only_pkey);
363 return -1;
364 }
365
366 /* We got one, store it and use it from here on out */
367 if (need_to_set_mm_pkey)
368 mm->context.execute_only_pkey = execute_only_pkey;
369 return execute_only_pkey;
370}
371
372static inline bool vma_is_pkey_exec_only(struct vm_area_struct *vma)
373{
374 /* Do this check first since the vm_flags should be hot */
375 if ((vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)) != VM_EXEC)
376 return false;
377
378 return (vma_pkey(vma) == vma->vm_mm->context.execute_only_pkey);
379}
380
381/*
382 * This should only be called for *plain* mprotect calls.
383 */
384int __arch_override_mprotect_pkey(struct vm_area_struct *vma, int prot,
385 int pkey)
386{
387 /*
388 * If the currently associated pkey is execute-only, but the requested
389 * protection requires read or write, move it back to the default pkey.
390 */
391 if (vma_is_pkey_exec_only(vma) && (prot & (PROT_READ | PROT_WRITE)))
392 return 0;
393
394 /*
395 * The requested protection is execute-only. Hence let's use an
396 * execute-only pkey.
397 */
398 if (prot == PROT_EXEC) {
399 pkey = execute_only_pkey(vma->vm_mm);
400 if (pkey > 0)
401 return pkey;
402 }
403
404 /* Nothing to override. */
405 return vma_pkey(vma);
406}
407
408static bool pkey_access_permitted(int pkey, bool write, bool execute)
409{
410 int pkey_shift;
411 u64 amr;
412
413 if (!pkey)
414 return true;
415
416 if (!is_pkey_enabled(pkey))
417 return true;
418
419 pkey_shift = pkeyshift(pkey);
420 if (execute && !(read_iamr() & (IAMR_EX_BIT << pkey_shift)))
421 return true;
422
423 amr = read_amr(); /* Delay reading amr until absolutely needed */
424 return ((!write && !(amr & (AMR_RD_BIT << pkey_shift))) ||
425 (write && !(amr & (AMR_WR_BIT << pkey_shift))));
426}
427
428bool arch_pte_access_permitted(u64 pte, bool write, bool execute)
429{
430 if (static_branch_likely(&pkey_disabled))
431 return true;
432
433 return pkey_access_permitted(pte_to_pkey_bits(pte), write, execute);
434}
435
436/*
437 * We only want to enforce protection keys on the current thread because we
438 * effectively have no access to AMR/IAMR for other threads or any way to tell
439 * which AMR/IAMR in a threaded process we could use.
440 *
441 * So do not enforce things if the VMA is not from the current mm, or if we are
442 * in a kernel thread.
443 */
444static inline bool vma_is_foreign(struct vm_area_struct *vma)
445{
446 if (!current->mm)
447 return true;
448
449 /* if it is not our ->mm, it has to be foreign */
450 if (current->mm != vma->vm_mm)
451 return true;
452
453 return false;
454}
455
456bool arch_vma_access_permitted(struct vm_area_struct *vma, bool write,
457 bool execute, bool foreign)
458{
459 if (static_branch_likely(&pkey_disabled))
460 return true;
461 /*
462 * Do not enforce our key-permissions on a foreign vma.
463 */
464 if (foreign || vma_is_foreign(vma))
465 return true;
466
467 return pkey_access_permitted(vma_pkey(vma), write, execute);
468}
diff --git a/arch/powerpc/mm/subpage-prot.c b/arch/powerpc/mm/subpage-prot.c
index 781532d7bc4d..f14a07c2fb90 100644
--- a/arch/powerpc/mm/subpage-prot.c
+++ b/arch/powerpc/mm/subpage-prot.c
@@ -195,6 +195,9 @@ long sys_subpage_prot(unsigned long addr, unsigned long len, u32 __user *map)
195 unsigned long next, limit; 195 unsigned long next, limit;
196 int err; 196 int err;
197 197
198 if (radix_enabled())
199 return -ENOENT;
200
198 /* Check parameters */ 201 /* Check parameters */
199 if ((addr & ~PAGE_MASK) || (len & ~PAGE_MASK) || 202 if ((addr & ~PAGE_MASK) || (len & ~PAGE_MASK) ||
200 addr >= mm->task_size || len >= mm->task_size || 203 addr >= mm->task_size || len >= mm->task_size ||
diff --git a/arch/powerpc/mm/tlb-radix.c b/arch/powerpc/mm/tlb-radix.c
index 884f4b705b57..71d1b19ad1c0 100644
--- a/arch/powerpc/mm/tlb-radix.c
+++ b/arch/powerpc/mm/tlb-radix.c
@@ -23,6 +23,72 @@
23#define RIC_FLUSH_PWC 1 23#define RIC_FLUSH_PWC 1
24#define RIC_FLUSH_ALL 2 24#define RIC_FLUSH_ALL 2
25 25
26/*
27 * tlbiel instruction for radix, set invalidation
28 * i.e., r=1 and is=01 or is=10 or is=11
29 */
30static inline void tlbiel_radix_set_isa300(unsigned int set, unsigned int is,
31 unsigned int pid,
32 unsigned int ric, unsigned int prs)
33{
34 unsigned long rb;
35 unsigned long rs;
36 unsigned int r = 1; /* radix format */
37
38 rb = (set << PPC_BITLSHIFT(51)) | (is << PPC_BITLSHIFT(53));
39 rs = ((unsigned long)pid << PPC_BITLSHIFT(31));
40
41 asm volatile(PPC_TLBIEL(%0, %1, %2, %3, %4)
42 : : "r"(rb), "r"(rs), "i"(ric), "i"(prs), "r"(r)
43 : "memory");
44}
45
46static void tlbiel_all_isa300(unsigned int num_sets, unsigned int is)
47{
48 unsigned int set;
49
50 asm volatile("ptesync": : :"memory");
51
52 /*
53 * Flush the first set of the TLB, and the entire Page Walk Cache
54 * and partition table entries. Then flush the remaining sets of the
55 * TLB.
56 */
57 tlbiel_radix_set_isa300(0, is, 0, RIC_FLUSH_ALL, 0);
58 for (set = 1; set < num_sets; set++)
59 tlbiel_radix_set_isa300(set, is, 0, RIC_FLUSH_TLB, 0);
60
61 /* Do the same for process scoped entries. */
62 tlbiel_radix_set_isa300(0, is, 0, RIC_FLUSH_ALL, 1);
63 for (set = 1; set < num_sets; set++)
64 tlbiel_radix_set_isa300(set, is, 0, RIC_FLUSH_TLB, 1);
65
66 asm volatile("ptesync": : :"memory");
67}
68
69void radix__tlbiel_all(unsigned int action)
70{
71 unsigned int is;
72
73 switch (action) {
74 case TLB_INVAL_SCOPE_GLOBAL:
75 is = 3;
76 break;
77 case TLB_INVAL_SCOPE_LPID:
78 is = 2;
79 break;
80 default:
81 BUG();
82 }
83
84 if (early_cpu_has_feature(CPU_FTR_ARCH_300))
85 tlbiel_all_isa300(POWER9_TLB_SETS_RADIX, is);
86 else
87 WARN(1, "%s called on pre-POWER9 CPU\n", __func__);
88
89 asm volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory");
90}
91
26static inline void __tlbiel_pid(unsigned long pid, int set, 92static inline void __tlbiel_pid(unsigned long pid, int set,
27 unsigned long ric) 93 unsigned long ric)
28{ 94{
@@ -600,14 +666,12 @@ void radix__flush_tlb_all(void)
600 */ 666 */
601 asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1) 667 asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
602 : : "r"(rb), "i"(r), "i"(1), "i"(ric), "r"(rs) : "memory"); 668 : : "r"(rb), "i"(r), "i"(1), "i"(ric), "r"(rs) : "memory");
603 trace_tlbie(0, 0, rb, rs, ric, prs, r);
604 /* 669 /*
605 * now flush host entires by passing PRS = 0 and LPID == 0 670 * now flush host entires by passing PRS = 0 and LPID == 0
606 */ 671 */
607 asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1) 672 asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
608 : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(0) : "memory"); 673 : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(0) : "memory");
609 asm volatile("eieio; tlbsync; ptesync": : :"memory"); 674 asm volatile("eieio; tlbsync; ptesync": : :"memory");
610 trace_tlbie(0, 0, rb, 0, ric, prs, r);
611} 675}
612 676
613void radix__flush_tlb_pte_p9_dd1(unsigned long old_pte, struct mm_struct *mm, 677void radix__flush_tlb_pte_p9_dd1(unsigned long old_pte, struct mm_struct *mm,
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index bfc4a0869609..15fe5f0c8665 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -388,7 +388,10 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
388 unsigned long end) 388 unsigned long end)
389 389
390{ 390{
391 flush_tlb_mm(vma->vm_mm); 391 if (end - start == PAGE_SIZE && !(start & ~PAGE_MASK))
392 flush_tlb_page(vma, start);
393 else
394 flush_tlb_mm(vma->vm_mm);
392} 395}
393EXPORT_SYMBOL(flush_tlb_range); 396EXPORT_SYMBOL(flush_tlb_range);
394 397
diff --git a/arch/powerpc/perf/8xx-pmu.c b/arch/powerpc/perf/8xx-pmu.c
index 3c39f05f0af3..6c0020d1c561 100644
--- a/arch/powerpc/perf/8xx-pmu.c
+++ b/arch/powerpc/perf/8xx-pmu.c
@@ -18,6 +18,7 @@
18#include <asm/machdep.h> 18#include <asm/machdep.h>
19#include <asm/firmware.h> 19#include <asm/firmware.h>
20#include <asm/ptrace.h> 20#include <asm/ptrace.h>
21#include <asm/code-patching.h>
21 22
22#define PERF_8xx_ID_CPU_CYCLES 1 23#define PERF_8xx_ID_CPU_CYCLES 1
23#define PERF_8xx_ID_HW_INSTRUCTIONS 2 24#define PERF_8xx_ID_HW_INSTRUCTIONS 2
@@ -30,8 +31,13 @@
30 31
31extern unsigned long itlb_miss_counter, dtlb_miss_counter; 32extern unsigned long itlb_miss_counter, dtlb_miss_counter;
32extern atomic_t instruction_counter; 33extern atomic_t instruction_counter;
34extern unsigned int itlb_miss_perf, dtlb_miss_perf;
35extern unsigned int itlb_miss_exit_1, itlb_miss_exit_2;
36extern unsigned int dtlb_miss_exit_1, dtlb_miss_exit_2, dtlb_miss_exit_3;
33 37
34static atomic_t insn_ctr_ref; 38static atomic_t insn_ctr_ref;
39static atomic_t itlb_miss_ref;
40static atomic_t dtlb_miss_ref;
35 41
36static s64 get_insn_ctr(void) 42static s64 get_insn_ctr(void)
37{ 43{
@@ -96,9 +102,24 @@ static int mpc8xx_pmu_add(struct perf_event *event, int flags)
96 val = get_insn_ctr(); 102 val = get_insn_ctr();
97 break; 103 break;
98 case PERF_8xx_ID_ITLB_LOAD_MISS: 104 case PERF_8xx_ID_ITLB_LOAD_MISS:
105 if (atomic_inc_return(&itlb_miss_ref) == 1) {
106 unsigned long target = (unsigned long)&itlb_miss_perf;
107
108 patch_branch(&itlb_miss_exit_1, target, 0);
109#ifndef CONFIG_PIN_TLB_TEXT
110 patch_branch(&itlb_miss_exit_2, target, 0);
111#endif
112 }
99 val = itlb_miss_counter; 113 val = itlb_miss_counter;
100 break; 114 break;
101 case PERF_8xx_ID_DTLB_LOAD_MISS: 115 case PERF_8xx_ID_DTLB_LOAD_MISS:
116 if (atomic_inc_return(&dtlb_miss_ref) == 1) {
117 unsigned long target = (unsigned long)&dtlb_miss_perf;
118
119 patch_branch(&dtlb_miss_exit_1, target, 0);
120 patch_branch(&dtlb_miss_exit_2, target, 0);
121 patch_branch(&dtlb_miss_exit_3, target, 0);
122 }
102 val = dtlb_miss_counter; 123 val = dtlb_miss_counter;
103 break; 124 break;
104 } 125 }
@@ -143,13 +164,36 @@ static void mpc8xx_pmu_read(struct perf_event *event)
143 164
144static void mpc8xx_pmu_del(struct perf_event *event, int flags) 165static void mpc8xx_pmu_del(struct perf_event *event, int flags)
145{ 166{
167 /* mfspr r10, SPRN_SPRG_SCRATCH0 */
168 unsigned int insn = PPC_INST_MFSPR | __PPC_RS(R10) |
169 __PPC_SPR(SPRN_SPRG_SCRATCH0);
170
146 mpc8xx_pmu_read(event); 171 mpc8xx_pmu_read(event);
147 if (event_type(event) != PERF_8xx_ID_HW_INSTRUCTIONS)
148 return;
149 172
150 /* If it was the last user, stop counting to avoid useles overhead */ 173 /* If it was the last user, stop counting to avoid useles overhead */
151 if (atomic_dec_return(&insn_ctr_ref) == 0) 174 switch (event_type(event)) {
152 mtspr(SPRN_ICTRL, 7); 175 case PERF_8xx_ID_CPU_CYCLES:
176 break;
177 case PERF_8xx_ID_HW_INSTRUCTIONS:
178 if (atomic_dec_return(&insn_ctr_ref) == 0)
179 mtspr(SPRN_ICTRL, 7);
180 break;
181 case PERF_8xx_ID_ITLB_LOAD_MISS:
182 if (atomic_dec_return(&itlb_miss_ref) == 0) {
183 patch_instruction(&itlb_miss_exit_1, insn);
184#ifndef CONFIG_PIN_TLB_TEXT
185 patch_instruction(&itlb_miss_exit_2, insn);
186#endif
187 }
188 break;
189 case PERF_8xx_ID_DTLB_LOAD_MISS:
190 if (atomic_dec_return(&dtlb_miss_ref) == 0) {
191 patch_instruction(&dtlb_miss_exit_1, insn);
192 patch_instruction(&dtlb_miss_exit_2, insn);
193 patch_instruction(&dtlb_miss_exit_3, insn);
194 }
195 break;
196 }
153} 197}
154 198
155static struct pmu mpc8xx_pmu = { 199static struct pmu mpc8xx_pmu = {
diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
index 225c9c86d7c0..57ebc655d2ac 100644
--- a/arch/powerpc/perf/Makefile
+++ b/arch/powerpc/perf/Makefile
@@ -15,7 +15,7 @@ obj-$(CONFIG_FSL_EMB_PERF_EVENT_E500) += e500-pmu.o e6500-pmu.o
15 15
16obj-$(CONFIG_HV_PERF_CTRS) += hv-24x7.o hv-gpci.o hv-common.o 16obj-$(CONFIG_HV_PERF_CTRS) += hv-24x7.o hv-gpci.o hv-common.o
17 17
18obj-$(CONFIG_PPC_8xx_PERF_EVENT) += 8xx-pmu.o 18obj-$(CONFIG_PPC_8xx) += 8xx-pmu.o
19 19
20obj-$(CONFIG_PPC64) += $(obj64-y) 20obj-$(CONFIG_PPC64) += $(obj64-y)
21obj-$(CONFIG_PPC32) += $(obj32-y) 21obj-$(CONFIG_PPC32) += $(obj32-y)
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index fce545774d50..f89bbd54ecec 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -322,7 +322,7 @@ static inline void perf_read_regs(struct pt_regs *regs)
322 */ 322 */
323static inline int perf_intr_is_nmi(struct pt_regs *regs) 323static inline int perf_intr_is_nmi(struct pt_regs *regs)
324{ 324{
325 return !regs->softe; 325 return (regs->softe & IRQS_DISABLED);
326} 326}
327 327
328/* 328/*
diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
index be4e7f84f70a..d7532e7b9ab5 100644
--- a/arch/powerpc/perf/imc-pmu.c
+++ b/arch/powerpc/perf/imc-pmu.c
@@ -40,7 +40,6 @@ static struct imc_pmu *core_imc_pmu;
40/* Thread IMC data structures and variables */ 40/* Thread IMC data structures and variables */
41 41
42static DEFINE_PER_CPU(u64 *, thread_imc_mem); 42static DEFINE_PER_CPU(u64 *, thread_imc_mem);
43static struct imc_pmu *thread_imc_pmu;
44static int thread_imc_mem_size; 43static int thread_imc_mem_size;
45 44
46struct imc_pmu *imc_event_to_pmu(struct perf_event *event) 45struct imc_pmu *imc_event_to_pmu(struct perf_event *event)
@@ -117,17 +116,13 @@ static struct attribute *device_str_attr_create(const char *name, const char *st
117 return &attr->attr.attr; 116 return &attr->attr.attr;
118} 117}
119 118
120struct imc_events *imc_parse_event(struct device_node *np, const char *scale, 119static int imc_parse_event(struct device_node *np, const char *scale,
121 const char *unit, const char *prefix, u32 base) 120 const char *unit, const char *prefix,
121 u32 base, struct imc_events *event)
122{ 122{
123 struct imc_events *event;
124 const char *s; 123 const char *s;
125 u32 reg; 124 u32 reg;
126 125
127 event = kzalloc(sizeof(struct imc_events), GFP_KERNEL);
128 if (!event)
129 return NULL;
130
131 if (of_property_read_u32(np, "reg", &reg)) 126 if (of_property_read_u32(np, "reg", &reg))
132 goto error; 127 goto error;
133 /* Add the base_reg value to the "reg" */ 128 /* Add the base_reg value to the "reg" */
@@ -158,14 +153,32 @@ struct imc_events *imc_parse_event(struct device_node *np, const char *scale,
158 goto error; 153 goto error;
159 } 154 }
160 155
161 return event; 156 return 0;
162error: 157error:
163 kfree(event->unit); 158 kfree(event->unit);
164 kfree(event->scale); 159 kfree(event->scale);
165 kfree(event->name); 160 kfree(event->name);
166 kfree(event); 161 return -EINVAL;
162}
163
164/*
165 * imc_free_events: Function to cleanup the events list, having
166 * "nr_entries".
167 */
168static void imc_free_events(struct imc_events *events, int nr_entries)
169{
170 int i;
167 171
168 return NULL; 172 /* Nothing to clean, return */
173 if (!events)
174 return;
175 for (i = 0; i < nr_entries; i++) {
176 kfree(events[i].unit);
177 kfree(events[i].scale);
178 kfree(events[i].name);
179 }
180
181 kfree(events);
169} 182}
170 183
171/* 184/*
@@ -177,9 +190,8 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu)
177 struct attribute_group *attr_group; 190 struct attribute_group *attr_group;
178 struct attribute **attrs, *dev_str; 191 struct attribute **attrs, *dev_str;
179 struct device_node *np, *pmu_events; 192 struct device_node *np, *pmu_events;
180 struct imc_events *ev;
181 u32 handle, base_reg; 193 u32 handle, base_reg;
182 int i=0, j=0, ct; 194 int i = 0, j = 0, ct, ret;
183 const char *prefix, *g_scale, *g_unit; 195 const char *prefix, *g_scale, *g_unit;
184 const char *ev_val_str, *ev_scale_str, *ev_unit_str; 196 const char *ev_val_str, *ev_scale_str, *ev_unit_str;
185 197
@@ -217,15 +229,17 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu)
217 ct = 0; 229 ct = 0;
218 /* Parse the events and update the struct */ 230 /* Parse the events and update the struct */
219 for_each_child_of_node(pmu_events, np) { 231 for_each_child_of_node(pmu_events, np) {
220 ev = imc_parse_event(np, g_scale, g_unit, prefix, base_reg); 232 ret = imc_parse_event(np, g_scale, g_unit, prefix, base_reg, &pmu->events[ct]);
221 if (ev) 233 if (!ret)
222 pmu->events[ct++] = ev; 234 ct++;
223 } 235 }
224 236
225 /* Allocate memory for attribute group */ 237 /* Allocate memory for attribute group */
226 attr_group = kzalloc(sizeof(*attr_group), GFP_KERNEL); 238 attr_group = kzalloc(sizeof(*attr_group), GFP_KERNEL);
227 if (!attr_group) 239 if (!attr_group) {
240 imc_free_events(pmu->events, ct);
228 return -ENOMEM; 241 return -ENOMEM;
242 }
229 243
230 /* 244 /*
231 * Allocate memory for attributes. 245 * Allocate memory for attributes.
@@ -238,31 +252,31 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu)
238 attrs = kcalloc(((ct * 3) + 1), sizeof(struct attribute *), GFP_KERNEL); 252 attrs = kcalloc(((ct * 3) + 1), sizeof(struct attribute *), GFP_KERNEL);
239 if (!attrs) { 253 if (!attrs) {
240 kfree(attr_group); 254 kfree(attr_group);
241 kfree(pmu->events); 255 imc_free_events(pmu->events, ct);
242 return -ENOMEM; 256 return -ENOMEM;
243 } 257 }
244 258
245 attr_group->name = "events"; 259 attr_group->name = "events";
246 attr_group->attrs = attrs; 260 attr_group->attrs = attrs;
247 do { 261 do {
248 ev_val_str = kasprintf(GFP_KERNEL, "event=0x%x", pmu->events[i]->value); 262 ev_val_str = kasprintf(GFP_KERNEL, "event=0x%x", pmu->events[i].value);
249 dev_str = device_str_attr_create(pmu->events[i]->name, ev_val_str); 263 dev_str = device_str_attr_create(pmu->events[i].name, ev_val_str);
250 if (!dev_str) 264 if (!dev_str)
251 continue; 265 continue;
252 266
253 attrs[j++] = dev_str; 267 attrs[j++] = dev_str;
254 if (pmu->events[i]->scale) { 268 if (pmu->events[i].scale) {
255 ev_scale_str = kasprintf(GFP_KERNEL, "%s.scale",pmu->events[i]->name); 269 ev_scale_str = kasprintf(GFP_KERNEL, "%s.scale", pmu->events[i].name);
256 dev_str = device_str_attr_create(ev_scale_str, pmu->events[i]->scale); 270 dev_str = device_str_attr_create(ev_scale_str, pmu->events[i].scale);
257 if (!dev_str) 271 if (!dev_str)
258 continue; 272 continue;
259 273
260 attrs[j++] = dev_str; 274 attrs[j++] = dev_str;
261 } 275 }
262 276
263 if (pmu->events[i]->unit) { 277 if (pmu->events[i].unit) {
264 ev_unit_str = kasprintf(GFP_KERNEL, "%s.unit",pmu->events[i]->name); 278 ev_unit_str = kasprintf(GFP_KERNEL, "%s.unit", pmu->events[i].name);
265 dev_str = device_str_attr_create(ev_unit_str, pmu->events[i]->unit); 279 dev_str = device_str_attr_create(ev_unit_str, pmu->events[i].unit);
266 if (!dev_str) 280 if (!dev_str)
267 continue; 281 continue;
268 282
@@ -273,7 +287,6 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu)
273 /* Save the event attribute */ 287 /* Save the event attribute */
274 pmu->attr_groups[IMC_EVENT_ATTR] = attr_group; 288 pmu->attr_groups[IMC_EVENT_ATTR] = attr_group;
275 289
276 kfree(pmu->events);
277 return 0; 290 return 0;
278} 291}
279 292
@@ -611,7 +624,8 @@ static int ppc_core_imc_cpu_online(unsigned int cpu)
611 624
612static int ppc_core_imc_cpu_offline(unsigned int cpu) 625static int ppc_core_imc_cpu_offline(unsigned int cpu)
613{ 626{
614 unsigned int ncpu, core_id; 627 unsigned int core_id;
628 int ncpu;
615 struct imc_pmu_ref *ref; 629 struct imc_pmu_ref *ref;
616 630
617 /* 631 /*
@@ -1171,6 +1185,15 @@ static void cleanup_all_thread_imc_memory(void)
1171 } 1185 }
1172} 1186}
1173 1187
1188/* Function to free the attr_groups which are dynamically allocated */
1189static void imc_common_mem_free(struct imc_pmu *pmu_ptr)
1190{
1191 if (pmu_ptr->attr_groups[IMC_EVENT_ATTR])
1192 kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]->attrs);
1193 kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]);
1194 kfree(pmu_ptr);
1195}
1196
1174/* 1197/*
1175 * Common function to unregister cpu hotplug callback and 1198 * Common function to unregister cpu hotplug callback and
1176 * free the memory. 1199 * free the memory.
@@ -1203,13 +1226,6 @@ static void imc_common_cpuhp_mem_free(struct imc_pmu *pmu_ptr)
1203 cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE); 1226 cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE);
1204 cleanup_all_thread_imc_memory(); 1227 cleanup_all_thread_imc_memory();
1205 } 1228 }
1206
1207 /* Only free the attr_groups which are dynamically allocated */
1208 if (pmu_ptr->attr_groups[IMC_EVENT_ATTR])
1209 kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]->attrs);
1210 kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]);
1211 kfree(pmu_ptr);
1212 return;
1213} 1229}
1214 1230
1215 1231
@@ -1258,8 +1274,10 @@ static int imc_mem_init(struct imc_pmu *pmu_ptr, struct device_node *parent,
1258 core_imc_refc = kcalloc(nr_cores, sizeof(struct imc_pmu_ref), 1274 core_imc_refc = kcalloc(nr_cores, sizeof(struct imc_pmu_ref),
1259 GFP_KERNEL); 1275 GFP_KERNEL);
1260 1276
1261 if (!core_imc_refc) 1277 if (!core_imc_refc) {
1278 kfree(pmu_ptr->mem_info);
1262 return -ENOMEM; 1279 return -ENOMEM;
1280 }
1263 1281
1264 core_imc_pmu = pmu_ptr; 1282 core_imc_pmu = pmu_ptr;
1265 break; 1283 break;
@@ -1272,11 +1290,12 @@ static int imc_mem_init(struct imc_pmu *pmu_ptr, struct device_node *parent,
1272 thread_imc_mem_size = pmu_ptr->counter_mem_size; 1290 thread_imc_mem_size = pmu_ptr->counter_mem_size;
1273 for_each_online_cpu(cpu) { 1291 for_each_online_cpu(cpu) {
1274 res = thread_imc_mem_alloc(cpu, pmu_ptr->counter_mem_size); 1292 res = thread_imc_mem_alloc(cpu, pmu_ptr->counter_mem_size);
1275 if (res) 1293 if (res) {
1294 cleanup_all_thread_imc_memory();
1276 return res; 1295 return res;
1296 }
1277 } 1297 }
1278 1298
1279 thread_imc_pmu = pmu_ptr;
1280 break; 1299 break;
1281 default: 1300 default:
1282 return -EINVAL; 1301 return -EINVAL;
@@ -1300,8 +1319,10 @@ int init_imc_pmu(struct device_node *parent, struct imc_pmu *pmu_ptr, int pmu_id
1300 int ret; 1319 int ret;
1301 1320
1302 ret = imc_mem_init(pmu_ptr, parent, pmu_idx); 1321 ret = imc_mem_init(pmu_ptr, parent, pmu_idx);
1303 if (ret) 1322 if (ret) {
1304 goto err_free; 1323 imc_common_mem_free(pmu_ptr);
1324 return ret;
1325 }
1305 1326
1306 switch (pmu_ptr->domain) { 1327 switch (pmu_ptr->domain) {
1307 case IMC_DOMAIN_NEST: 1328 case IMC_DOMAIN_NEST:
@@ -1368,6 +1389,7 @@ int init_imc_pmu(struct device_node *parent, struct imc_pmu *pmu_ptr, int pmu_id
1368 return 0; 1389 return 0;
1369 1390
1370err_free: 1391err_free:
1392 imc_common_mem_free(pmu_ptr);
1371 imc_common_cpuhp_mem_free(pmu_ptr); 1393 imc_common_cpuhp_mem_free(pmu_ptr);
1372 return ret; 1394 return ret;
1373} 1395}
diff --git a/arch/powerpc/platforms/44x/fsp2.c b/arch/powerpc/platforms/44x/fsp2.c
index 92e98048404f..04f0c73a9b4f 100644
--- a/arch/powerpc/platforms/44x/fsp2.c
+++ b/arch/powerpc/platforms/44x/fsp2.c
@@ -27,6 +27,17 @@
27#include <asm/time.h> 27#include <asm/time.h>
28#include <asm/uic.h> 28#include <asm/uic.h>
29#include <asm/ppc4xx.h> 29#include <asm/ppc4xx.h>
30#include <asm/dcr.h>
31#include <linux/interrupt.h>
32#include <linux/of_irq.h>
33#include "fsp2.h"
34
35#define FSP2_BUS_ERR "ibm,bus-error-irq"
36#define FSP2_CMU_ERR "ibm,cmu-error-irq"
37#define FSP2_CONF_ERR "ibm,conf-error-irq"
38#define FSP2_OPBD_ERR "ibm,opbd-error-irq"
39#define FSP2_MCUE "ibm,mc-ue-irq"
40#define FSP2_RST_WRN "ibm,reset-warning-irq"
30 41
31static __initdata struct of_device_id fsp2_of_bus[] = { 42static __initdata struct of_device_id fsp2_of_bus[] = {
32 { .compatible = "ibm,plb4", }, 43 { .compatible = "ibm,plb4", },
@@ -35,6 +46,194 @@ static __initdata struct of_device_id fsp2_of_bus[] = {
35 {}, 46 {},
36}; 47};
37 48
49static void l2regs(void)
50{
51 pr_err("L2 Controller:\n");
52 pr_err("MCK: 0x%08x\n", mfl2(L2MCK));
53 pr_err("INT: 0x%08x\n", mfl2(L2INT));
54 pr_err("PLBSTAT0: 0x%08x\n", mfl2(L2PLBSTAT0));
55 pr_err("PLBSTAT1: 0x%08x\n", mfl2(L2PLBSTAT1));
56 pr_err("ARRSTAT0: 0x%08x\n", mfl2(L2ARRSTAT0));
57 pr_err("ARRSTAT1: 0x%08x\n", mfl2(L2ARRSTAT1));
58 pr_err("ARRSTAT2: 0x%08x\n", mfl2(L2ARRSTAT2));
59 pr_err("CPUSTAT: 0x%08x\n", mfl2(L2CPUSTAT));
60 pr_err("RACSTAT0: 0x%08x\n", mfl2(L2RACSTAT0));
61 pr_err("WACSTAT0: 0x%08x\n", mfl2(L2WACSTAT0));
62 pr_err("WACSTAT1: 0x%08x\n", mfl2(L2WACSTAT1));
63 pr_err("WACSTAT2: 0x%08x\n", mfl2(L2WACSTAT2));
64 pr_err("WDFSTAT: 0x%08x\n", mfl2(L2WDFSTAT));
65 pr_err("LOG0: 0x%08x\n", mfl2(L2LOG0));
66 pr_err("LOG1: 0x%08x\n", mfl2(L2LOG1));
67 pr_err("LOG2: 0x%08x\n", mfl2(L2LOG2));
68 pr_err("LOG3: 0x%08x\n", mfl2(L2LOG3));
69 pr_err("LOG4: 0x%08x\n", mfl2(L2LOG4));
70 pr_err("LOG5: 0x%08x\n", mfl2(L2LOG5));
71}
72
73static void show_plbopb_regs(u32 base, int num)
74{
75 pr_err("\nPLBOPB Bridge %d:\n", num);
76 pr_err("GESR0: 0x%08x\n", mfdcr(base + PLB4OPB_GESR0));
77 pr_err("GESR1: 0x%08x\n", mfdcr(base + PLB4OPB_GESR1));
78 pr_err("GESR2: 0x%08x\n", mfdcr(base + PLB4OPB_GESR2));
79 pr_err("GEARU: 0x%08x\n", mfdcr(base + PLB4OPB_GEARU));
80 pr_err("GEAR: 0x%08x\n", mfdcr(base + PLB4OPB_GEAR));
81}
82
83static irqreturn_t bus_err_handler(int irq, void *data)
84{
85 pr_err("Bus Error\n");
86
87 l2regs();
88
89 pr_err("\nPLB6 Controller:\n");
90 pr_err("BC_SHD: 0x%08x\n", mfdcr(DCRN_PLB6_SHD));
91 pr_err("BC_ERR: 0x%08x\n", mfdcr(DCRN_PLB6_ERR));
92
93 pr_err("\nPLB6-to-PLB4 Bridge:\n");
94 pr_err("ESR: 0x%08x\n", mfdcr(DCRN_PLB6PLB4_ESR));
95 pr_err("EARH: 0x%08x\n", mfdcr(DCRN_PLB6PLB4_EARH));
96 pr_err("EARL: 0x%08x\n", mfdcr(DCRN_PLB6PLB4_EARL));
97
98 pr_err("\nPLB4-to-PLB6 Bridge:\n");
99 pr_err("ESR: 0x%08x\n", mfdcr(DCRN_PLB4PLB6_ESR));
100 pr_err("EARH: 0x%08x\n", mfdcr(DCRN_PLB4PLB6_EARH));
101 pr_err("EARL: 0x%08x\n", mfdcr(DCRN_PLB4PLB6_EARL));
102
103 pr_err("\nPLB6-to-MCIF Bridge:\n");
104 pr_err("BESR0: 0x%08x\n", mfdcr(DCRN_PLB6MCIF_BESR0));
105 pr_err("BESR1: 0x%08x\n", mfdcr(DCRN_PLB6MCIF_BESR1));
106 pr_err("BEARH: 0x%08x\n", mfdcr(DCRN_PLB6MCIF_BEARH));
107 pr_err("BEARL: 0x%08x\n", mfdcr(DCRN_PLB6MCIF_BEARL));
108
109 pr_err("\nPLB4 Arbiter:\n");
110 pr_err("P0ESRH 0x%08x\n", mfdcr(DCRN_PLB4_P0ESRH));
111 pr_err("P0ESRL 0x%08x\n", mfdcr(DCRN_PLB4_P0ESRL));
112 pr_err("P0EARH 0x%08x\n", mfdcr(DCRN_PLB4_P0EARH));
113 pr_err("P0EARH 0x%08x\n", mfdcr(DCRN_PLB4_P0EARH));
114 pr_err("P1ESRH 0x%08x\n", mfdcr(DCRN_PLB4_P1ESRH));
115 pr_err("P1ESRL 0x%08x\n", mfdcr(DCRN_PLB4_P1ESRL));
116 pr_err("P1EARH 0x%08x\n", mfdcr(DCRN_PLB4_P1EARH));
117 pr_err("P1EARH 0x%08x\n", mfdcr(DCRN_PLB4_P1EARH));
118
119 show_plbopb_regs(DCRN_PLB4OPB0_BASE, 0);
120 show_plbopb_regs(DCRN_PLB4OPB1_BASE, 1);
121 show_plbopb_regs(DCRN_PLB4OPB2_BASE, 2);
122 show_plbopb_regs(DCRN_PLB4OPB3_BASE, 3);
123
124 pr_err("\nPLB4-to-AHB Bridge:\n");
125 pr_err("ESR: 0x%08x\n", mfdcr(DCRN_PLB4AHB_ESR));
126 pr_err("SEUAR: 0x%08x\n", mfdcr(DCRN_PLB4AHB_SEUAR));
127 pr_err("SELAR: 0x%08x\n", mfdcr(DCRN_PLB4AHB_SELAR));
128
129 pr_err("\nAHB-to-PLB4 Bridge:\n");
130 pr_err("\nESR: 0x%08x\n", mfdcr(DCRN_AHBPLB4_ESR));
131 pr_err("\nEAR: 0x%08x\n", mfdcr(DCRN_AHBPLB4_EAR));
132 panic("Bus Error\n");
133}
134
135static irqreturn_t cmu_err_handler(int irq, void *data) {
136 pr_err("CMU Error\n");
137 pr_err("FIR0: 0x%08x\n", mfcmu(CMUN_FIR0));
138 panic("CMU Error\n");
139}
140
141static irqreturn_t conf_err_handler(int irq, void *data) {
142 pr_err("Configuration Logic Error\n");
143 pr_err("CONF_FIR: 0x%08x\n", mfdcr(DCRN_CONF_FIR_RWC));
144 pr_err("RPERR0: 0x%08x\n", mfdcr(DCRN_CONF_RPERR0));
145 pr_err("RPERR1: 0x%08x\n", mfdcr(DCRN_CONF_RPERR1));
146 panic("Configuration Logic Error\n");
147}
148
149static irqreturn_t opbd_err_handler(int irq, void *data) {
150 panic("OPBD Error\n");
151}
152
153static irqreturn_t mcue_handler(int irq, void *data) {
154 pr_err("DDR: Uncorrectable Error\n");
155 pr_err("MCSTAT: 0x%08x\n",
156 mfdcr(DCRN_DDR34_BASE + DCRN_DDR34_MCSTAT));
157 pr_err("MCOPT1: 0x%08x\n",
158 mfdcr(DCRN_DDR34_BASE + DCRN_DDR34_MCOPT1));
159 pr_err("MCOPT2: 0x%08x\n",
160 mfdcr(DCRN_DDR34_BASE + DCRN_DDR34_MCOPT2));
161 pr_err("PHYSTAT: 0x%08x\n",
162 mfdcr(DCRN_DDR34_BASE + DCRN_DDR34_PHYSTAT));
163 pr_err("CFGR0: 0x%08x\n",
164 mfdcr(DCRN_DDR34_BASE + DCRN_DDR34_CFGR0));
165 pr_err("CFGR1: 0x%08x\n",
166 mfdcr(DCRN_DDR34_BASE + DCRN_DDR34_CFGR1));
167 pr_err("CFGR2: 0x%08x\n",
168 mfdcr(DCRN_DDR34_BASE + DCRN_DDR34_CFGR2));
169 pr_err("CFGR3: 0x%08x\n",
170 mfdcr(DCRN_DDR34_BASE + DCRN_DDR34_CFGR3));
171 pr_err("SCRUB_CNTL: 0x%08x\n",
172 mfdcr(DCRN_DDR34_BASE + DCRN_DDR34_SCRUB_CNTL));
173 pr_err("ECCERR_PORT0: 0x%08x\n",
174 mfdcr(DCRN_DDR34_BASE + DCRN_DDR34_ECCERR_PORT0));
175 pr_err("ECCERR_ADDR_PORT0: 0x%08x\n",
176 mfdcr(DCRN_DDR34_BASE + DCRN_DDR34_ECCERR_ADDR_PORT0));
177 pr_err("ECCERR_CNT_PORT0: 0x%08x\n",
178 mfdcr(DCRN_DDR34_BASE + DCRN_DDR34_ECCERR_COUNT_PORT0));
179 pr_err("ECC_CHECK_PORT0: 0x%08x\n",
180 mfdcr(DCRN_DDR34_BASE + DCRN_DDR34_ECC_CHECK_PORT0));
181 pr_err("MCER0: 0x%08x\n",
182 mfdcr(DCRN_CW_BASE + DCRN_CW_MCER0));
183 pr_err("MCER1: 0x%08x\n",
184 mfdcr(DCRN_CW_BASE + DCRN_CW_MCER1));
185 pr_err("BESR: 0x%08x\n",
186 mfdcr(DCRN_PLB6MCIF_BESR0));
187 pr_err("BEARL: 0x%08x\n",
188 mfdcr(DCRN_PLB6MCIF_BEARL));
189 pr_err("BEARH: 0x%08x\n",
190 mfdcr(DCRN_PLB6MCIF_BEARH));
191 panic("DDR: Uncorrectable Error\n");
192}
193
194static irqreturn_t rst_wrn_handler(int irq, void *data) {
195 u32 crcs = mfcmu(CMUN_CRCS);
196 switch (crcs & CRCS_STAT_MASK) {
197 case CRCS_STAT_CHIP_RST_B:
198 panic("Received chassis-initiated reset request");
199 default:
200 panic("Unknown external reset: CRCS=0x%x", crcs);
201 }
202}
203
204static void node_irq_request(const char *compat, irq_handler_t errirq_handler)
205{
206 struct device_node *np;
207 unsigned int irq;
208 int32_t rc;
209
210 for_each_compatible_node(np, NULL, compat) {
211 irq = irq_of_parse_and_map(np, 0);
212 if (irq == NO_IRQ) {
213 pr_err("device tree node %s is missing a interrupt",
214 np->name);
215 return;
216 }
217
218 rc = request_irq(irq, errirq_handler, 0, np->name, np);
219 if (rc) {
220 pr_err("fsp_of_probe: request_irq failed: np=%s rc=%d",
221 np->full_name, rc);
222 return;
223 }
224 }
225}
226
227static void critical_irq_setup(void)
228{
229 node_irq_request(FSP2_CMU_ERR, cmu_err_handler);
230 node_irq_request(FSP2_BUS_ERR, bus_err_handler);
231 node_irq_request(FSP2_CONF_ERR, conf_err_handler);
232 node_irq_request(FSP2_OPBD_ERR, opbd_err_handler);
233 node_irq_request(FSP2_MCUE, mcue_handler);
234 node_irq_request(FSP2_RST_WRN, rst_wrn_handler);
235}
236
38static int __init fsp2_device_probe(void) 237static int __init fsp2_device_probe(void)
39{ 238{
40 of_platform_bus_probe(NULL, fsp2_of_bus, NULL); 239 of_platform_bus_probe(NULL, fsp2_of_bus, NULL);
@@ -44,18 +243,76 @@ machine_device_initcall(fsp2, fsp2_device_probe);
44 243
45static int __init fsp2_probe(void) 244static int __init fsp2_probe(void)
46{ 245{
246 u32 val;
47 unsigned long root = of_get_flat_dt_root(); 247 unsigned long root = of_get_flat_dt_root();
48 248
49 if (!of_flat_dt_is_compatible(root, "ibm,fsp2")) 249 if (!of_flat_dt_is_compatible(root, "ibm,fsp2"))
50 return 0; 250 return 0;
251
252 /* Clear BC_ERR and mask snoopable request plb errors. */
253 val = mfdcr(DCRN_PLB6_CR0);
254 val |= 0x20000000;
255 mtdcr(DCRN_PLB6_BASE, val);
256 mtdcr(DCRN_PLB6_HD, 0xffff0000);
257 mtdcr(DCRN_PLB6_SHD, 0xffff0000);
258
259 /* TVSENSE reset is blocked (clock gated) by the POR default of the TVS
260 * sleep config bit. As a consequence, TVSENSE will provide erratic
261 * sensor values, which may result in spurious (parity) errors
262 * recorded in the CMU FIR and leading to erroneous interrupt requests
263 * once the CMU interrupt is unmasked.
264 */
265
266 /* 1. set TVS1[UNDOZE] */
267 val = mfcmu(CMUN_TVS1);
268 val |= 0x4;
269 mtcmu(CMUN_TVS1, val);
270
271 /* 2. clear FIR[TVS] and FIR[TVSPAR] */
272 val = mfcmu(CMUN_FIR0);
273 val |= 0x30000000;
274 mtcmu(CMUN_FIR0, val);
275
276 /* L2 machine checks */
277 mtl2(L2PLBMCKEN0, 0xffffffff);
278 mtl2(L2PLBMCKEN1, 0x0000ffff);
279 mtl2(L2ARRMCKEN0, 0xffffffff);
280 mtl2(L2ARRMCKEN1, 0xffffffff);
281 mtl2(L2ARRMCKEN2, 0xfffff000);
282 mtl2(L2CPUMCKEN, 0xffffffff);
283 mtl2(L2RACMCKEN0, 0xffffffff);
284 mtl2(L2WACMCKEN0, 0xffffffff);
285 mtl2(L2WACMCKEN1, 0xffffffff);
286 mtl2(L2WACMCKEN2, 0xffffffff);
287 mtl2(L2WDFMCKEN, 0xffffffff);
288
289 /* L2 interrupts */
290 mtl2(L2PLBINTEN1, 0xffff0000);
291
292 /*
293 * At a global level, enable all L2 machine checks and interrupts
294 * reported by the L2 subsystems, except for the external machine check
295 * input (UIC0.1).
296 */
297 mtl2(L2MCKEN, 0x000007ff);
298 mtl2(L2INTEN, 0x000004ff);
299
300 /* Enable FSP-2 configuration logic parity errors */
301 mtdcr(DCRN_CONF_EIR_RS, 0x80000000);
51 return 1; 302 return 1;
52} 303}
53 304
305static void __init fsp2_irq_init(void)
306{
307 uic_init_tree();
308 critical_irq_setup();
309}
310
54define_machine(fsp2) { 311define_machine(fsp2) {
55 .name = "FSP-2", 312 .name = "FSP-2",
56 .probe = fsp2_probe, 313 .probe = fsp2_probe,
57 .progress = udbg_progress, 314 .progress = udbg_progress,
58 .init_IRQ = uic_init_tree, 315 .init_IRQ = fsp2_irq_init,
59 .get_irq = uic_get_irq, 316 .get_irq = uic_get_irq,
60 .restart = ppc4xx_reset_system, 317 .restart = ppc4xx_reset_system,
61 .calibrate_decr = generic_calibrate_decr, 318 .calibrate_decr = generic_calibrate_decr,
diff --git a/arch/powerpc/platforms/44x/fsp2.h b/arch/powerpc/platforms/44x/fsp2.h
new file mode 100644
index 000000000000..9e1d52754c8b
--- /dev/null
+++ b/arch/powerpc/platforms/44x/fsp2.h
@@ -0,0 +1,272 @@
1#ifndef _ASM_POWERPC_FSP_DCR_H_
2#define _ASM_POWERPC_FSP_DCR_H_
3#ifdef __KERNEL__
4#include <asm/dcr.h>
5
6#define DCRN_CMU_ADDR 0x00C /* Chip management unic addr */
7#define DCRN_CMU_DATA 0x00D /* Chip management unic data */
8
9/* PLB4 Arbiter */
10#define DCRN_PLB4_PCBI 0x010 /* PLB Crossbar ID/Rev Register */
11#define DCRN_PLB4_P0ACR 0x011 /* PLB0 Arbiter Control Register */
12#define DCRN_PLB4_P0ESRL 0x012 /* PLB0 Error Status Register Low */
13#define DCRN_PLB4_P0ESRH 0x013 /* PLB0 Error Status Register High */
14#define DCRN_PLB4_P0EARL 0x014 /* PLB0 Error Address Register Low */
15#define DCRN_PLB4_P0EARH 0x015 /* PLB0 Error Address Register High */
16#define DCRN_PLB4_P0ESRLS 0x016 /* PLB0 Error Status Register Low Set*/
17#define DCRN_PLB4_P0ESRHS 0x017 /* PLB0 Error Status Register High */
18#define DCRN_PLB4_PCBC 0x018 /* PLB Crossbar Control Register */
19#define DCRN_PLB4_P1ACR 0x019 /* PLB1 Arbiter Control Register */
20#define DCRN_PLB4_P1ESRL 0x01A /* PLB1 Error Status Register Low */
21#define DCRN_PLB4_P1ESRH 0x01B /* PLB1 Error Status Register High */
22#define DCRN_PLB4_P1EARL 0x01C /* PLB1 Error Address Register Low */
23#define DCRN_PLB4_P1EARH 0x01D /* PLB1 Error Address Register High */
24#define DCRN_PLB4_P1ESRLS 0x01E /* PLB1 Error Status Register Low Set*/
25#define DCRN_PLB4_P1ESRHS 0x01F /*PLB1 Error Status Register High Set*/
26
27/* PLB4/OPB bridge 0, 1, 2, 3 */
28#define DCRN_PLB4OPB0_BASE 0x020
29#define DCRN_PLB4OPB1_BASE 0x030
30#define DCRN_PLB4OPB2_BASE 0x040
31#define DCRN_PLB4OPB3_BASE 0x050
32
33#define PLB4OPB_GESR0 0x0 /* Error status 0: Master Dev 0-3 */
34#define PLB4OPB_GEAR 0x2 /* Error Address Register */
35#define PLB4OPB_GEARU 0x3 /* Error Upper Address Register */
36#define PLB4OPB_GESR1 0x4 /* Error Status 1: Master Dev 4-7 */
37#define PLB4OPB_GESR2 0xC /* Error Status 2: Master Dev 8-11 */
38
39/* PLB4-to-AHB Bridge */
40#define DCRN_PLB4AHB_BASE 0x400
41#define DCRN_PLB4AHB_SEUAR (DCRN_PLB4AHB_BASE + 1)
42#define DCRN_PLB4AHB_SELAR (DCRN_PLB4AHB_BASE + 2)
43#define DCRN_PLB4AHB_ESR (DCRN_PLB4AHB_BASE + 3)
44#define DCRN_AHBPLB4_ESR (DCRN_PLB4AHB_BASE + 8)
45#define DCRN_AHBPLB4_EAR (DCRN_PLB4AHB_BASE + 9)
46
47/* PLB6 Controller */
48#define DCRN_PLB6_BASE 0x11111300
49#define DCRN_PLB6_CR0 (DCRN_PLB6_BASE)
50#define DCRN_PLB6_ERR (DCRN_PLB6_BASE + 0x0B)
51#define DCRN_PLB6_HD (DCRN_PLB6_BASE + 0x0E)
52#define DCRN_PLB6_SHD (DCRN_PLB6_BASE + 0x10)
53
54/* PLB4-to-PLB6 Bridge */
55#define DCRN_PLB4PLB6_BASE 0x11111320
56#define DCRN_PLB4PLB6_ESR (DCRN_PLB4PLB6_BASE + 1)
57#define DCRN_PLB4PLB6_EARH (DCRN_PLB4PLB6_BASE + 3)
58#define DCRN_PLB4PLB6_EARL (DCRN_PLB4PLB6_BASE + 4)
59
60/* PLB6-to-PLB4 Bridge */
61#define DCRN_PLB6PLB4_BASE 0x11111350
62#define DCRN_PLB6PLB4_ESR (DCRN_PLB6PLB4_BASE + 1)
63#define DCRN_PLB6PLB4_EARH (DCRN_PLB6PLB4_BASE + 3)
64#define DCRN_PLB6PLB4_EARL (DCRN_PLB6PLB4_BASE + 4)
65
66/* PLB6-to-MCIF Bridge */
67#define DCRN_PLB6MCIF_BASE 0x11111380
68#define DCRN_PLB6MCIF_BESR0 (DCRN_PLB6MCIF_BASE + 0)
69#define DCRN_PLB6MCIF_BESR1 (DCRN_PLB6MCIF_BASE + 1)
70#define DCRN_PLB6MCIF_BEARL (DCRN_PLB6MCIF_BASE + 2)
71#define DCRN_PLB6MCIF_BEARH (DCRN_PLB6MCIF_BASE + 3)
72
73/* Configuration Logic Registers */
74#define DCRN_CONF_BASE 0x11111400
75#define DCRN_CONF_FIR_RWC (DCRN_CONF_BASE + 0x3A)
76#define DCRN_CONF_EIR_RS (DCRN_CONF_BASE + 0x3E)
77#define DCRN_CONF_RPERR0 (DCRN_CONF_BASE + 0x4D)
78#define DCRN_CONF_RPERR1 (DCRN_CONF_BASE + 0x4E)
79
80#define DCRN_L2CDCRAI 0x11111100
81#define DCRN_L2CDCRDI 0x11111104
82/* L2 indirect addresses */
83#define L2MCK 0x120
84#define L2MCKEN 0x130
85#define L2INT 0x150
86#define L2INTEN 0x160
87#define L2LOG0 0x180
88#define L2LOG1 0x184
89#define L2LOG2 0x188
90#define L2LOG3 0x18C
91#define L2LOG4 0x190
92#define L2LOG5 0x194
93#define L2PLBSTAT0 0x300
94#define L2PLBSTAT1 0x304
95#define L2PLBMCKEN0 0x330
96#define L2PLBMCKEN1 0x334
97#define L2PLBINTEN0 0x360
98#define L2PLBINTEN1 0x364
99#define L2ARRSTAT0 0x500
100#define L2ARRSTAT1 0x504
101#define L2ARRSTAT2 0x508
102#define L2ARRMCKEN0 0x530
103#define L2ARRMCKEN1 0x534
104#define L2ARRMCKEN2 0x538
105#define L2ARRINTEN0 0x560
106#define L2ARRINTEN1 0x564
107#define L2ARRINTEN2 0x568
108#define L2CPUSTAT 0x700
109#define L2CPUMCKEN 0x730
110#define L2CPUINTEN 0x760
111#define L2RACSTAT0 0x900
112#define L2RACMCKEN0 0x930
113#define L2RACINTEN0 0x960
114#define L2WACSTAT0 0xD00
115#define L2WACSTAT1 0xD04
116#define L2WACSTAT2 0xD08
117#define L2WACMCKEN0 0xD30
118#define L2WACMCKEN1 0xD34
119#define L2WACMCKEN2 0xD38
120#define L2WACINTEN0 0xD60
121#define L2WACINTEN1 0xD64
122#define L2WACINTEN2 0xD68
123#define L2WDFSTAT 0xF00
124#define L2WDFMCKEN 0xF30
125#define L2WDFINTEN 0xF60
126
127/* DDR3/4 Memory Controller */
128#define DCRN_DDR34_BASE 0x11120000
129#define DCRN_DDR34_MCSTAT 0x10
130#define DCRN_DDR34_MCOPT1 0x20
131#define DCRN_DDR34_MCOPT2 0x21
132#define DCRN_DDR34_PHYSTAT 0x32
133#define DCRN_DDR34_CFGR0 0x40
134#define DCRN_DDR34_CFGR1 0x41
135#define DCRN_DDR34_CFGR2 0x42
136#define DCRN_DDR34_CFGR3 0x43
137#define DCRN_DDR34_SCRUB_CNTL 0xAA
138#define DCRN_DDR34_SCRUB_INT 0xAB
139#define DCRN_DDR34_SCRUB_START_ADDR 0xB0
140#define DCRN_DDR34_SCRUB_END_ADDR 0xD0
141#define DCRN_DDR34_ECCERR_ADDR_PORT0 0xE0
142#define DCRN_DDR34_ECCERR_ADDR_PORT1 0xE1
143#define DCRN_DDR34_ECCERR_ADDR_PORT2 0xE2
144#define DCRN_DDR34_ECCERR_ADDR_PORT3 0xE3
145#define DCRN_DDR34_ECCERR_COUNT_PORT0 0xE4
146#define DCRN_DDR34_ECCERR_COUNT_PORT1 0xE5
147#define DCRN_DDR34_ECCERR_COUNT_PORT2 0xE6
148#define DCRN_DDR34_ECCERR_COUNT_PORT3 0xE7
149#define DCRN_DDR34_ECCERR_PORT0 0xF0
150#define DCRN_DDR34_ECCERR_PORT1 0xF2
151#define DCRN_DDR34_ECCERR_PORT2 0xF4
152#define DCRN_DDR34_ECCERR_PORT3 0xF6
153#define DCRN_DDR34_ECC_CHECK_PORT0 0xF8
154#define DCRN_DDR34_ECC_CHECK_PORT1 0xF9
155#define DCRN_DDR34_ECC_CHECK_PORT2 0xF9
156#define DCRN_DDR34_ECC_CHECK_PORT3 0xFB
157
158#define DDR34_SCRUB_CNTL_STOP 0x00000000
159#define DDR34_SCRUB_CNTL_SCRUB 0x80000000
160#define DDR34_SCRUB_CNTL_UE_STOP 0x20000000
161#define DDR34_SCRUB_CNTL_CE_STOP 0x10000000
162#define DDR34_SCRUB_CNTL_RANK_EN 0x00008000
163
164/* PLB-Attached DDR3/4 Core Wrapper */
165#define DCRN_CW_BASE 0x11111800
166#define DCRN_CW_MCER0 0x00
167#define DCRN_CW_MCER1 0x01
168#define DCRN_CW_MCER_AND0 0x02
169#define DCRN_CW_MCER_AND1 0x03
170#define DCRN_CW_MCER_OR0 0x04
171#define DCRN_CW_MCER_OR1 0x05
172#define DCRN_CW_MCER_MASK0 0x06
173#define DCRN_CW_MCER_MASK1 0x07
174#define DCRN_CW_MCER_MASK_AND0 0x08
175#define DCRN_CW_MCER_MASK_AND1 0x09
176#define DCRN_CW_MCER_MASK_OR0 0x0A
177#define DCRN_CW_MCER_MASK_OR1 0x0B
178#define DCRN_CW_MCER_ACTION0 0x0C
179#define DCRN_CW_MCER_ACTION1 0x0D
180#define DCRN_CW_MCER_WOF0 0x0E
181#define DCRN_CW_MCER_WOF1 0x0F
182#define DCRN_CW_LFIR 0x10
183#define DCRN_CW_LFIR_AND 0x11
184#define DCRN_CW_LFIR_OR 0x12
185#define DCRN_CW_LFIR_MASK 0x13
186#define DCRN_CW_LFIR_MASK_AND 0x14
187#define DCRN_CW_LFIR_MASK_OR 0x15
188
189#define CW_MCER0_MEM_CE 0x00020000
190/* CMU addresses */
191#define CMUN_CRCS 0x00 /* Chip Reset Control/Status */
192#define CMUN_CONFFIR0 0x20 /* Config Reg Parity FIR 0 */
193#define CMUN_CONFFIR1 0x21 /* Config Reg Parity FIR 1 */
194#define CMUN_CONFFIR2 0x22 /* Config Reg Parity FIR 2 */
195#define CMUN_CONFFIR3 0x23 /* Config Reg Parity FIR 3 */
196#define CMUN_URCR3_RS 0x24 /* Unit Reset Control Reg 3 Set */
197#define CMUN_URCR3_C 0x25 /* Unit Reset Control Reg 3 Clear */
198#define CMUN_URCR3_P 0x26 /* Unit Reset Control Reg 3 Pulse */
199#define CMUN_PW0 0x2C /* Pulse Width Register */
200#define CMUN_URCR0_P 0x2D /* Unit Reset Control Reg 0 Pulse */
201#define CMUN_URCR1_P 0x2E /* Unit Reset Control Reg 1 Pulse */
202#define CMUN_URCR2_P 0x2F /* Unit Reset Control Reg 2 Pulse */
203#define CMUN_CLS_RW 0x30 /* Code Load Status (Read/Write) */
204#define CMUN_CLS_S 0x31 /* Code Load Status (Set) */
205#define CMUN_CLS_C 0x32 /* Code Load Status (Clear */
206#define CMUN_URCR2_RS 0x33 /* Unit Reset Control Reg 2 Set */
207#define CMUN_URCR2_C 0x34 /* Unit Reset Control Reg 2 Clear */
208#define CMUN_CLKEN0 0x35 /* Clock Enable 0 */
209#define CMUN_CLKEN1 0x36 /* Clock Enable 1 */
210#define CMUN_PCD0 0x37 /* PSI clock divider 0 */
211#define CMUN_PCD1 0x38 /* PSI clock divider 1 */
212#define CMUN_TMR0 0x39 /* Reset Timer */
213#define CMUN_TVS0 0x3A /* TV Sense Reg 0 */
214#define CMUN_TVS1 0x3B /* TV Sense Reg 1 */
215#define CMUN_MCCR 0x3C /* DRAM Configuration Reg */
216#define CMUN_FIR0 0x3D /* Fault Isolation Reg 0 */
217#define CMUN_FMR0 0x3E /* FIR Mask Reg 0 */
218#define CMUN_ETDRB 0x3F /* ETDR Backdoor */
219
220/* CRCS bit fields */
221#define CRCS_STAT_MASK 0xF0000000
222#define CRCS_STAT_POR 0x10000000
223#define CRCS_STAT_PHR 0x20000000
224#define CRCS_STAT_PCIE 0x30000000
225#define CRCS_STAT_CRCS_SYS 0x40000000
226#define CRCS_STAT_DBCR_SYS 0x50000000
227#define CRCS_STAT_HOST_SYS 0x60000000
228#define CRCS_STAT_CHIP_RST_B 0x70000000
229#define CRCS_STAT_CRCS_CHIP 0x80000000
230#define CRCS_STAT_DBCR_CHIP 0x90000000
231#define CRCS_STAT_HOST_CHIP 0xA0000000
232#define CRCS_STAT_PSI_CHIP 0xB0000000
233#define CRCS_STAT_CRCS_CORE 0xC0000000
234#define CRCS_STAT_DBCR_CORE 0xD0000000
235#define CRCS_STAT_HOST_CORE 0xE0000000
236#define CRCS_STAT_PCIE_HOT 0xF0000000
237#define CRCS_STAT_SELF_CORE 0x40000000
238#define CRCS_STAT_SELF_CHIP 0x50000000
239#define CRCS_WATCHE 0x08000000
240#define CRCS_CORE 0x04000000 /* Reset PPC440 core */
241#define CRCS_CHIP 0x02000000 /* Chip Reset */
242#define CRCS_SYS 0x01000000 /* System Reset */
243#define CRCS_WRCR 0x00800000 /* Watchdog reset on core reset */
244#define CRCS_EXTCR 0x00080000 /* CHIP_RST_B triggers chip reset */
245#define CRCS_PLOCK 0x00000002 /* PLL Locked */
246
247#define mtcmu(reg, data) \
248do { \
249 mtdcr(DCRN_CMU_ADDR, reg); \
250 mtdcr(DCRN_CMU_DATA, data); \
251} while (0)
252
253#define mfcmu(reg)\
254 ({u32 data; \
255 mtdcr(DCRN_CMU_ADDR, reg); \
256 data = mfdcr(DCRN_CMU_DATA); \
257 data; })
258
259#define mtl2(reg, data) \
260do { \
261 mtdcr(DCRN_L2CDCRAI, reg); \
262 mtdcr(DCRN_L2CDCRDI, data); \
263} while (0)
264
265#define mfl2(reg) \
266 ({u32 data; \
267 mtdcr(DCRN_L2CDCRAI, reg); \
268 data = mfdcr(DCRN_L2CDCRDI); \
269 data; })
270
271#endif /* __KERNEL__ */
272#endif /* _ASM_POWERPC_FSP2_DCR_H_ */
diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c
index f99e79ee060e..48abb4cb304c 100644
--- a/arch/powerpc/platforms/512x/mpc512x_shared.c
+++ b/arch/powerpc/platforms/512x/mpc512x_shared.c
@@ -387,8 +387,8 @@ static unsigned int __init get_fifo_size(struct device_node *np,
387 if (fp) 387 if (fp)
388 return *fp; 388 return *fp;
389 389
390 pr_warning("no %s property in %pOF node, defaulting to %d\n", 390 pr_warn("no %s property in %pOF node, defaulting to %d\n",
391 prop_name, np, DEFAULT_FIFO_SIZE); 391 prop_name, np, DEFAULT_FIFO_SIZE);
392 392
393 return DEFAULT_FIFO_SIZE; 393 return DEFAULT_FIFO_SIZE;
394} 394}
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index 9e974b1e1697..17cf249b18ee 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -90,7 +90,7 @@ struct mpc52xx_gpt_priv {
90 struct list_head list; /* List of all GPT devices */ 90 struct list_head list; /* List of all GPT devices */
91 struct device *dev; 91 struct device *dev;
92 struct mpc52xx_gpt __iomem *regs; 92 struct mpc52xx_gpt __iomem *regs;
93 spinlock_t lock; 93 raw_spinlock_t lock;
94 struct irq_domain *irqhost; 94 struct irq_domain *irqhost;
95 u32 ipb_freq; 95 u32 ipb_freq;
96 u8 wdt_mode; 96 u8 wdt_mode;
@@ -141,9 +141,9 @@ static void mpc52xx_gpt_irq_unmask(struct irq_data *d)
141 struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d); 141 struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d);
142 unsigned long flags; 142 unsigned long flags;
143 143
144 spin_lock_irqsave(&gpt->lock, flags); 144 raw_spin_lock_irqsave(&gpt->lock, flags);
145 setbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN); 145 setbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
146 spin_unlock_irqrestore(&gpt->lock, flags); 146 raw_spin_unlock_irqrestore(&gpt->lock, flags);
147} 147}
148 148
149static void mpc52xx_gpt_irq_mask(struct irq_data *d) 149static void mpc52xx_gpt_irq_mask(struct irq_data *d)
@@ -151,9 +151,9 @@ static void mpc52xx_gpt_irq_mask(struct irq_data *d)
151 struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d); 151 struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d);
152 unsigned long flags; 152 unsigned long flags;
153 153
154 spin_lock_irqsave(&gpt->lock, flags); 154 raw_spin_lock_irqsave(&gpt->lock, flags);
155 clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN); 155 clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
156 spin_unlock_irqrestore(&gpt->lock, flags); 156 raw_spin_unlock_irqrestore(&gpt->lock, flags);
157} 157}
158 158
159static void mpc52xx_gpt_irq_ack(struct irq_data *d) 159static void mpc52xx_gpt_irq_ack(struct irq_data *d)
@@ -171,14 +171,14 @@ static int mpc52xx_gpt_irq_set_type(struct irq_data *d, unsigned int flow_type)
171 171
172 dev_dbg(gpt->dev, "%s: virq=%i type=%x\n", __func__, d->irq, flow_type); 172 dev_dbg(gpt->dev, "%s: virq=%i type=%x\n", __func__, d->irq, flow_type);
173 173
174 spin_lock_irqsave(&gpt->lock, flags); 174 raw_spin_lock_irqsave(&gpt->lock, flags);
175 reg = in_be32(&gpt->regs->mode) & ~MPC52xx_GPT_MODE_ICT_MASK; 175 reg = in_be32(&gpt->regs->mode) & ~MPC52xx_GPT_MODE_ICT_MASK;
176 if (flow_type & IRQF_TRIGGER_RISING) 176 if (flow_type & IRQF_TRIGGER_RISING)
177 reg |= MPC52xx_GPT_MODE_ICT_RISING; 177 reg |= MPC52xx_GPT_MODE_ICT_RISING;
178 if (flow_type & IRQF_TRIGGER_FALLING) 178 if (flow_type & IRQF_TRIGGER_FALLING)
179 reg |= MPC52xx_GPT_MODE_ICT_FALLING; 179 reg |= MPC52xx_GPT_MODE_ICT_FALLING;
180 out_be32(&gpt->regs->mode, reg); 180 out_be32(&gpt->regs->mode, reg);
181 spin_unlock_irqrestore(&gpt->lock, flags); 181 raw_spin_unlock_irqrestore(&gpt->lock, flags);
182 182
183 return 0; 183 return 0;
184} 184}
@@ -264,11 +264,11 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
264 /* If the GPT is currently disabled, then change it to be in Input 264 /* If the GPT is currently disabled, then change it to be in Input
265 * Capture mode. If the mode is non-zero, then the pin could be 265 * Capture mode. If the mode is non-zero, then the pin could be
266 * already in use for something. */ 266 * already in use for something. */
267 spin_lock_irqsave(&gpt->lock, flags); 267 raw_spin_lock_irqsave(&gpt->lock, flags);
268 mode = in_be32(&gpt->regs->mode); 268 mode = in_be32(&gpt->regs->mode);
269 if ((mode & MPC52xx_GPT_MODE_MS_MASK) == 0) 269 if ((mode & MPC52xx_GPT_MODE_MS_MASK) == 0)
270 out_be32(&gpt->regs->mode, mode | MPC52xx_GPT_MODE_MS_IC); 270 out_be32(&gpt->regs->mode, mode | MPC52xx_GPT_MODE_MS_IC);
271 spin_unlock_irqrestore(&gpt->lock, flags); 271 raw_spin_unlock_irqrestore(&gpt->lock, flags);
272 272
273 dev_dbg(gpt->dev, "%s() complete. virq=%i\n", __func__, cascade_virq); 273 dev_dbg(gpt->dev, "%s() complete. virq=%i\n", __func__, cascade_virq);
274} 274}
@@ -295,9 +295,9 @@ mpc52xx_gpt_gpio_set(struct gpio_chip *gc, unsigned int gpio, int v)
295 dev_dbg(gpt->dev, "%s: gpio:%d v:%d\n", __func__, gpio, v); 295 dev_dbg(gpt->dev, "%s: gpio:%d v:%d\n", __func__, gpio, v);
296 r = v ? MPC52xx_GPT_MODE_GPIO_OUT_HIGH : MPC52xx_GPT_MODE_GPIO_OUT_LOW; 296 r = v ? MPC52xx_GPT_MODE_GPIO_OUT_HIGH : MPC52xx_GPT_MODE_GPIO_OUT_LOW;
297 297
298 spin_lock_irqsave(&gpt->lock, flags); 298 raw_spin_lock_irqsave(&gpt->lock, flags);
299 clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK, r); 299 clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK, r);
300 spin_unlock_irqrestore(&gpt->lock, flags); 300 raw_spin_unlock_irqrestore(&gpt->lock, flags);
301} 301}
302 302
303static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) 303static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
@@ -307,9 +307,9 @@ static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
307 307
308 dev_dbg(gpt->dev, "%s: gpio:%d\n", __func__, gpio); 308 dev_dbg(gpt->dev, "%s: gpio:%d\n", __func__, gpio);
309 309
310 spin_lock_irqsave(&gpt->lock, flags); 310 raw_spin_lock_irqsave(&gpt->lock, flags);
311 clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK); 311 clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK);
312 spin_unlock_irqrestore(&gpt->lock, flags); 312 raw_spin_unlock_irqrestore(&gpt->lock, flags);
313 313
314 return 0; 314 return 0;
315} 315}
@@ -436,16 +436,16 @@ static int mpc52xx_gpt_do_start(struct mpc52xx_gpt_priv *gpt, u64 period,
436 } 436 }
437 437
438 /* Set and enable the timer, reject an attempt to use a wdt as gpt */ 438 /* Set and enable the timer, reject an attempt to use a wdt as gpt */
439 spin_lock_irqsave(&gpt->lock, flags); 439 raw_spin_lock_irqsave(&gpt->lock, flags);
440 if (as_wdt) 440 if (as_wdt)
441 gpt->wdt_mode |= MPC52xx_GPT_IS_WDT; 441 gpt->wdt_mode |= MPC52xx_GPT_IS_WDT;
442 else if ((gpt->wdt_mode & MPC52xx_GPT_IS_WDT) != 0) { 442 else if ((gpt->wdt_mode & MPC52xx_GPT_IS_WDT) != 0) {
443 spin_unlock_irqrestore(&gpt->lock, flags); 443 raw_spin_unlock_irqrestore(&gpt->lock, flags);
444 return -EBUSY; 444 return -EBUSY;
445 } 445 }
446 out_be32(&gpt->regs->count, prescale << 16 | clocks); 446 out_be32(&gpt->regs->count, prescale << 16 | clocks);
447 clrsetbits_be32(&gpt->regs->mode, clear, set); 447 clrsetbits_be32(&gpt->regs->mode, clear, set);
448 spin_unlock_irqrestore(&gpt->lock, flags); 448 raw_spin_unlock_irqrestore(&gpt->lock, flags);
449 449
450 return 0; 450 return 0;
451} 451}
@@ -476,14 +476,14 @@ int mpc52xx_gpt_stop_timer(struct mpc52xx_gpt_priv *gpt)
476 unsigned long flags; 476 unsigned long flags;
477 477
478 /* reject the operation if the timer is used as watchdog (gpt 0 only) */ 478 /* reject the operation if the timer is used as watchdog (gpt 0 only) */
479 spin_lock_irqsave(&gpt->lock, flags); 479 raw_spin_lock_irqsave(&gpt->lock, flags);
480 if ((gpt->wdt_mode & MPC52xx_GPT_IS_WDT) != 0) { 480 if ((gpt->wdt_mode & MPC52xx_GPT_IS_WDT) != 0) {
481 spin_unlock_irqrestore(&gpt->lock, flags); 481 raw_spin_unlock_irqrestore(&gpt->lock, flags);
482 return -EBUSY; 482 return -EBUSY;
483 } 483 }
484 484
485 clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_COUNTER_ENABLE); 485 clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_COUNTER_ENABLE);
486 spin_unlock_irqrestore(&gpt->lock, flags); 486 raw_spin_unlock_irqrestore(&gpt->lock, flags);
487 return 0; 487 return 0;
488} 488}
489EXPORT_SYMBOL(mpc52xx_gpt_stop_timer); 489EXPORT_SYMBOL(mpc52xx_gpt_stop_timer);
@@ -500,9 +500,9 @@ u64 mpc52xx_gpt_timer_period(struct mpc52xx_gpt_priv *gpt)
500 u64 prescale; 500 u64 prescale;
501 unsigned long flags; 501 unsigned long flags;
502 502
503 spin_lock_irqsave(&gpt->lock, flags); 503 raw_spin_lock_irqsave(&gpt->lock, flags);
504 period = in_be32(&gpt->regs->count); 504 period = in_be32(&gpt->regs->count);
505 spin_unlock_irqrestore(&gpt->lock, flags); 505 raw_spin_unlock_irqrestore(&gpt->lock, flags);
506 506
507 prescale = period >> 16; 507 prescale = period >> 16;
508 period &= 0xffff; 508 period &= 0xffff;
@@ -532,9 +532,9 @@ static inline void mpc52xx_gpt_wdt_ping(struct mpc52xx_gpt_priv *gpt_wdt)
532{ 532{
533 unsigned long flags; 533 unsigned long flags;
534 534
535 spin_lock_irqsave(&gpt_wdt->lock, flags); 535 raw_spin_lock_irqsave(&gpt_wdt->lock, flags);
536 out_8((u8 *) &gpt_wdt->regs->mode, MPC52xx_GPT_MODE_WDT_PING); 536 out_8((u8 *) &gpt_wdt->regs->mode, MPC52xx_GPT_MODE_WDT_PING);
537 spin_unlock_irqrestore(&gpt_wdt->lock, flags); 537 raw_spin_unlock_irqrestore(&gpt_wdt->lock, flags);
538} 538}
539 539
540/* wdt misc device api */ 540/* wdt misc device api */
@@ -638,11 +638,11 @@ static int mpc52xx_wdt_release(struct inode *inode, struct file *file)
638 struct mpc52xx_gpt_priv *gpt_wdt = file->private_data; 638 struct mpc52xx_gpt_priv *gpt_wdt = file->private_data;
639 unsigned long flags; 639 unsigned long flags;
640 640
641 spin_lock_irqsave(&gpt_wdt->lock, flags); 641 raw_spin_lock_irqsave(&gpt_wdt->lock, flags);
642 clrbits32(&gpt_wdt->regs->mode, 642 clrbits32(&gpt_wdt->regs->mode,
643 MPC52xx_GPT_MODE_COUNTER_ENABLE | MPC52xx_GPT_MODE_WDT_EN); 643 MPC52xx_GPT_MODE_COUNTER_ENABLE | MPC52xx_GPT_MODE_WDT_EN);
644 gpt_wdt->wdt_mode &= ~MPC52xx_GPT_IS_WDT; 644 gpt_wdt->wdt_mode &= ~MPC52xx_GPT_IS_WDT;
645 spin_unlock_irqrestore(&gpt_wdt->lock, flags); 645 raw_spin_unlock_irqrestore(&gpt_wdt->lock, flags);
646#endif 646#endif
647 clear_bit(0, &wdt_is_active); 647 clear_bit(0, &wdt_is_active);
648 return 0; 648 return 0;
@@ -723,7 +723,7 @@ static int mpc52xx_gpt_probe(struct platform_device *ofdev)
723 if (!gpt) 723 if (!gpt)
724 return -ENOMEM; 724 return -ENOMEM;
725 725
726 spin_lock_init(&gpt->lock); 726 raw_spin_lock_init(&gpt->lock);
727 gpt->dev = &ofdev->dev; 727 gpt->dev = &ofdev->dev;
728 gpt->ipb_freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node); 728 gpt->ipb_freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node);
729 gpt->regs = of_iomap(ofdev->dev.of_node, 0); 729 gpt->regs = of_iomap(ofdev->dev.of_node, 0);
diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
index 96bb55ca61d3..d2ef39f0edc8 100644
--- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
+++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
@@ -84,7 +84,7 @@ static ssize_t show_status(struct device *d,
84 84
85 return sprintf(buf, "%02x\n", ret); 85 return sprintf(buf, "%02x\n", ret);
86} 86}
87static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); 87static DEVICE_ATTR(status, 0444, show_status, NULL);
88 88
89static void mcu_power_off(void) 89static void mcu_power_off(void)
90{ 90{
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index bb7b25acf26f..74c154e67c8b 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -75,7 +75,7 @@ static void __init mpc832x_sys_setup_arch(void)
75 par_io_init(np); 75 par_io_init(np);
76 of_node_put(np); 76 of_node_put(np);
77 77
78 for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;) 78 for_each_node_by_name(np, "ucc")
79 par_io_of_config(np); 79 par_io_of_config(np);
80 } 80 }
81 81
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index a4539c5accb0..438986593873 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -204,7 +204,7 @@ static void __init mpc832x_rdb_setup_arch(void)
204 par_io_init(np); 204 par_io_init(np);
205 of_node_put(np); 205 of_node_put(np);
206 206
207 for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;) 207 for_each_node_by_name(np, "ucc")
208 par_io_of_config(np); 208 par_io_of_config(np);
209 } 209 }
210#endif /* CONFIG_QUICC_ENGINE */ 210#endif /* CONFIG_QUICC_ENGINE */
diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c
index 4fc3051c2b2e..fd44dd03e1f3 100644
--- a/arch/powerpc/platforms/83xx/mpc836x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c
@@ -83,7 +83,7 @@ static void __init mpc836x_mds_setup_arch(void)
83 par_io_init(np); 83 par_io_init(np);
84 of_node_put(np); 84 of_node_put(np);
85 85
86 for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;) 86 for_each_node_by_name(np, "ucc")
87 par_io_of_config(np); 87 par_io_of_config(np);
88#ifdef CONFIG_QE_USB 88#ifdef CONFIG_QE_USB
89 /* Must fixup Par IO before QE GPIO chips are registered. */ 89 /* Must fixup Par IO before QE GPIO chips are registered. */
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
index 82f8490b5aa7..38d4ba9f37b5 100644
--- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
+++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
@@ -252,8 +252,7 @@ static int socrates_fpga_pic_host_xlate(struct irq_domain *h,
252 /* type is configurable */ 252 /* type is configurable */
253 if (intspec[1] != IRQ_TYPE_LEVEL_LOW && 253 if (intspec[1] != IRQ_TYPE_LEVEL_LOW &&
254 intspec[1] != IRQ_TYPE_LEVEL_HIGH) { 254 intspec[1] != IRQ_TYPE_LEVEL_HIGH) {
255 pr_warning("FPGA PIC: invalid irq type, " 255 pr_warn("FPGA PIC: invalid irq type, setting default active low\n");
256 "setting default active low\n");
257 *out_flags = IRQ_TYPE_LEVEL_LOW; 256 *out_flags = IRQ_TYPE_LEVEL_LOW;
258 } else { 257 } else {
259 *out_flags = intspec[1]; 258 *out_flags = intspec[1];
@@ -267,7 +266,7 @@ static int socrates_fpga_pic_host_xlate(struct irq_domain *h,
267 if (intspec[2] <= 2) 266 if (intspec[2] <= 2)
268 fpga_irq->irq_line = intspec[2]; 267 fpga_irq->irq_line = intspec[2];
269 else 268 else
270 pr_warning("FPGA PIC: invalid irq routing\n"); 269 pr_warn("FPGA PIC: invalid irq routing\n");
271 270
272 return 0; 271 return 0;
273} 272}
@@ -293,7 +292,7 @@ void socrates_fpga_pic_init(struct device_node *pic)
293 for (i = 0; i < 3; i++) { 292 for (i = 0; i < 3; i++) {
294 socrates_fpga_irqs[i] = irq_of_parse_and_map(pic, i); 293 socrates_fpga_irqs[i] = irq_of_parse_and_map(pic, i);
295 if (!socrates_fpga_irqs[i]) { 294 if (!socrates_fpga_irqs[i]) {
296 pr_warning("FPGA PIC: can't get irq%d.\n", i); 295 pr_warn("FPGA PIC: can't get irq%d\n", i);
297 continue; 296 continue;
298 } 297 }
299 irq_set_chained_handler(socrates_fpga_irqs[i], 298 irq_set_chained_handler(socrates_fpga_irqs[i],
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index a0e989ed4b6f..17c6cd3d02e6 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -101,7 +101,7 @@ static int __init mpc86xx_hpcn_probe(void)
101 101
102 /* Be nice and don't give silent boot death. Delete this in 2.6.27 */ 102 /* Be nice and don't give silent boot death. Delete this in 2.6.27 */
103 if (of_machine_is_compatible("mpc86xx")) { 103 if (of_machine_is_compatible("mpc86xx")) {
104 pr_warning("WARNING: your dts/dtb is old. You must update before the next kernel release\n"); 104 pr_warn("WARNING: your dts/dtb is old. You must update before the next kernel release.\n");
105 return 1; 105 return 1;
106 } 106 }
107 107
diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig
index e2089d3de00c..d408162d5af4 100644
--- a/arch/powerpc/platforms/8xx/Kconfig
+++ b/arch/powerpc/platforms/8xx/Kconfig
@@ -116,18 +116,6 @@ config 8xx_GPIO
116 116
117 If in doubt, say Y here. 117 If in doubt, say Y here.
118 118
119config 8xx_CPU6
120 bool "CPU6 Silicon Errata (860 Pre Rev. C)"
121 help
122 MPC860 CPUs, prior to Rev C have some bugs in the silicon, which
123 require workarounds for Linux (and most other OSes to work). If you
124 get a BUG() very early in boot, this might fix the problem. For
125 more details read the document entitled "MPC860 Family Device Errata
126 Reference" on Freescale's website. This option also incurs a
127 performance hit.
128
129 If in doubt, say N here.
130
131config 8xx_CPU15 119config 8xx_CPU15
132 bool "CPU15 Silicon Errata" 120 bool "CPU15 Silicon Errata"
133 depends on !HUGETLB_PAGE 121 depends on !HUGETLB_PAGE
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 5a96a2763e4a..14ef17e10ec9 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -293,17 +293,6 @@ config CPM2
293 you wish to build a kernel for a machine with a CPM2 coprocessor 293 you wish to build a kernel for a machine with a CPM2 coprocessor
294 on it (826x, 827x, 8560). 294 on it (826x, 827x, 8560).
295 295
296config AXON_RAM
297 tristate "Axon DDR2 memory device driver"
298 depends on PPC_IBM_CELL_BLADE && BLOCK
299 select DAX
300 default m
301 help
302 It registers one block device per Axon's DDR2 memory bank found
303 on a system. Block devices are called axonram?, their major and
304 minor numbers are available in /proc/devices, /proc/partitions or
305 in /sys/block/axonram?/dev.
306
307config FSL_ULI1575 296config FSL_ULI1575
308 bool 297 bool
309 default n 298 default n
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index ae07470fde3c..a429d859f15d 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -33,7 +33,6 @@ config PPC_85xx
33config PPC_8xx 33config PPC_8xx
34 bool "Freescale 8xx" 34 bool "Freescale 8xx"
35 select FSL_SOC 35 select FSL_SOC
36 select PPC_LIB_RHEAP
37 select SYS_SUPPORTS_HUGETLBFS 36 select SYS_SUPPORTS_HUGETLBFS
38 37
39config 40x 38config 40x
@@ -168,13 +167,6 @@ config PPC_FPU
168 bool 167 bool
169 default y if PPC64 168 default y if PPC64
170 169
171config PPC_8xx_PERF_EVENT
172 bool "PPC 8xx perf events"
173 depends on PPC_8xx && PERF_EVENTS
174 help
175 This is Performance Events support for PPC 8xx. The 8xx doesn't
176 have a PMU but some events are emulated using 8xx features.
177
178config FSL_EMB_PERFMON 170config FSL_EMB_PERFMON
179 bool "Freescale Embedded Perfmon" 171 bool "Freescale Embedded Perfmon"
180 depends on E500 || PPC_83xx 172 depends on E500 || PPC_83xx
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 6fc85e29dc08..5d4bf9aed51a 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -315,8 +315,7 @@ static int __init setup_iic(void)
315 struct cbe_iic_regs __iomem *node_iic; 315 struct cbe_iic_regs __iomem *node_iic;
316 const u32 *np; 316 const u32 *np;
317 317
318 for (dn = NULL; 318 for_each_node_by_name(dn, "interrupt-controller") {
319 (dn = of_find_node_by_name(dn,"interrupt-controller")) != NULL;) {
320 if (!of_device_is_compatible(dn, 319 if (!of_device_is_compatible(dn,
321 "IBM,CBEA-Internal-Interrupt-Controller")) 320 "IBM,CBEA-Internal-Interrupt-Controller"))
322 continue; 321 continue;
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index d3543e68efe8..7d31b8d14661 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -192,8 +192,7 @@ static void __init mpic_init_IRQ(void)
192 struct device_node *dn; 192 struct device_node *dn;
193 struct mpic *mpic; 193 struct mpic *mpic;
194 194
195 for (dn = NULL; 195 for_each_node_by_name(dn, "interrupt-controller") {
196 (dn = of_find_node_by_name(dn, "interrupt-controller"));) {
197 if (!of_device_is_compatible(dn, "CBEA,platform-open-pic")) 196 if (!of_device_is_compatible(dn, "CBEA,platform-open-pic"))
198 continue; 197 continue;
199 198
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index aa44bfc46467..c137f0cb4151 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -343,8 +343,7 @@ void __init spider_init_IRQ(void)
343 * device-tree is bogus anyway) so all we can do is pray or maybe test 343 * device-tree is bogus anyway) so all we can do is pray or maybe test
344 * the address and deduce the node-id 344 * the address and deduce the node-id
345 */ 345 */
346 for (dn = NULL; 346 for_each_node_by_name(dn, "interrupt-controller") {
347 (dn = of_find_node_by_name(dn, "interrupt-controller"));) {
348 if (of_device_is_compatible(dn, "CBEA,platform-spider-pic")) { 347 if (of_device_is_compatible(dn, "CBEA,platform-spider-pic")) {
349 if (of_address_to_resource(dn, 0, &r)) { 348 if (of_address_to_resource(dn, 0, &r)) {
350 printk(KERN_WARNING "spider-pic: Failed\n"); 349 printk(KERN_WARNING "spider-pic: Failed\n");
diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c
index f636ee22b203..5c409c98cca8 100644
--- a/arch/powerpc/platforms/cell/spu_manage.c
+++ b/arch/powerpc/platforms/cell/spu_manage.c
@@ -292,12 +292,12 @@ static int __init of_enumerate_spus(int (*fn)(void *data))
292 unsigned int n = 0; 292 unsigned int n = 0;
293 293
294 ret = -ENODEV; 294 ret = -ENODEV;
295 for (node = of_find_node_by_type(NULL, "spe"); 295 for_each_node_by_type(node, "spe") {
296 node; node = of_find_node_by_type(node, "spe")) {
297 ret = fn(node); 296 ret = fn(node);
298 if (ret) { 297 if (ret) {
299 printk(KERN_WARNING "%s: Error initializing %s\n", 298 printk(KERN_WARNING "%s: Error initializing %s\n",
300 __func__, node->name); 299 __func__, node->name);
300 of_node_put(node);
301 break; 301 break;
302 } 302 }
303 n++; 303 n++;
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index fc7772c3d068..c1be486da899 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -2375,8 +2375,8 @@ static int switch_log_sprint(struct spu_context *ctx, char *tbuf, int n)
2375 2375
2376 p = ctx->switch_log->log + ctx->switch_log->tail % SWITCH_LOG_BUFSIZE; 2376 p = ctx->switch_log->log + ctx->switch_log->tail % SWITCH_LOG_BUFSIZE;
2377 2377
2378 return snprintf(tbuf, n, "%u.%09u %d %u %u %llu\n", 2378 return snprintf(tbuf, n, "%llu.%09u %d %u %u %llu\n",
2379 (unsigned int) p->tstamp.tv_sec, 2379 (unsigned long long) p->tstamp.tv_sec,
2380 (unsigned int) p->tstamp.tv_nsec, 2380 (unsigned int) p->tstamp.tv_nsec,
2381 p->spu_id, 2381 p->spu_id,
2382 (unsigned int) p->type, 2382 (unsigned int) p->type,
@@ -2499,7 +2499,7 @@ void spu_switch_log_notify(struct spu *spu, struct spu_context *ctx,
2499 struct switch_log_entry *p; 2499 struct switch_log_entry *p;
2500 2500
2501 p = ctx->switch_log->log + ctx->switch_log->head; 2501 p = ctx->switch_log->log + ctx->switch_log->head;
2502 ktime_get_ts(&p->tstamp); 2502 ktime_get_ts64(&p->tstamp);
2503 p->timebase = get_tb(); 2503 p->timebase = get_tb();
2504 p->spu_id = spu ? spu->number : -1; 2504 p->spu_id = spu ? spu->number : -1;
2505 p->type = type; 2505 p->type = type;
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 9558d725a99b..db329d4bf1c3 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -455,7 +455,7 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
455 } 455 }
456 } 456 }
457 457
458 ret = spufs_mkdir(inode, dentry, flags, mode & S_IRWXUGO); 458 ret = spufs_mkdir(inode, dentry, flags, mode & 0777);
459 if (ret) 459 if (ret)
460 goto out_aff_unlock; 460 goto out_aff_unlock;
461 461
@@ -546,7 +546,7 @@ static int spufs_create_gang(struct inode *inode,
546 struct path path = {.mnt = mnt, .dentry = dentry}; 546 struct path path = {.mnt = mnt, .dentry = dentry};
547 int ret; 547 int ret;
548 548
549 ret = spufs_mkgang(inode, dentry, mode & S_IRWXUGO); 549 ret = spufs_mkgang(inode, dentry, mode & 0777);
550 if (!ret) { 550 if (!ret) {
551 ret = spufs_gang_open(&path); 551 ret = spufs_gang_open(&path);
552 if (ret < 0) { 552 if (ret < 0) {
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 2d0479ad3af4..b5fc1b3fe538 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -69,7 +69,7 @@ struct switch_log {
69 unsigned long head; 69 unsigned long head;
70 unsigned long tail; 70 unsigned long tail;
71 struct switch_log_entry { 71 struct switch_log_entry {
72 struct timespec tstamp; 72 struct timespec64 tstamp;
73 s32 spu_id; 73 s32 spu_id;
74 u32 type; 74 u32 type;
75 u32 val; 75 u32 val;
diff --git a/arch/powerpc/platforms/pasemi/dma_lib.c b/arch/powerpc/platforms/pasemi/dma_lib.c
index aafa01ba062f..2c72263ad6ab 100644
--- a/arch/powerpc/platforms/pasemi/dma_lib.c
+++ b/arch/powerpc/platforms/pasemi/dma_lib.c
@@ -589,7 +589,7 @@ int pasemi_dma_init(void)
589 pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, 0); 589 pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, 0);
590 while (pasemi_read_dma_reg(PAS_DMA_COM_RXSTA) & 1) { 590 while (pasemi_read_dma_reg(PAS_DMA_COM_RXSTA) & 1) {
591 if (time_after(jiffies, timeout)) { 591 if (time_after(jiffies, timeout)) {
592 pr_warning("Warning: Could not disable RX section\n"); 592 pr_warn("Warning: Could not disable RX section\n");
593 break; 593 break;
594 } 594 }
595 } 595 }
@@ -598,7 +598,7 @@ int pasemi_dma_init(void)
598 pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, 0); 598 pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, 0);
599 while (pasemi_read_dma_reg(PAS_DMA_COM_TXSTA) & 1) { 599 while (pasemi_read_dma_reg(PAS_DMA_COM_TXSTA) & 1) {
600 if (time_after(jiffies, timeout)) { 600 if (time_after(jiffies, timeout)) {
601 pr_warning("Warning: Could not disable TX section\n"); 601 pr_warn("Warning: Could not disable TX section\n");
602 break; 602 break;
603 } 603 }
604 } 604 }
diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c
index a00096b1c713..6b5dcccae1d3 100644
--- a/arch/powerpc/platforms/powermac/backlight.c
+++ b/arch/powerpc/platforms/powermac/backlight.c
@@ -186,7 +186,7 @@ int pmac_backlight_set_legacy_brightness(int brightness)
186 return __pmac_backlight_set_legacy_brightness(brightness); 186 return __pmac_backlight_set_legacy_brightness(brightness);
187} 187}
188 188
189int pmac_backlight_get_legacy_brightness() 189int pmac_backlight_get_legacy_brightness(void)
190{ 190{
191 int result = -ENXIO; 191 int result = -ENXIO;
192 192
@@ -205,12 +205,12 @@ int pmac_backlight_get_legacy_brightness()
205 return result; 205 return result;
206} 206}
207 207
208void pmac_backlight_disable() 208void pmac_backlight_disable(void)
209{ 209{
210 atomic_inc(&kernel_backlight_disabled); 210 atomic_inc(&kernel_backlight_disabled);
211} 211}
212 212
213void pmac_backlight_enable() 213void pmac_backlight_enable(void)
214{ 214{
215 atomic_dec(&kernel_backlight_disabled); 215 atomic_dec(&kernel_backlight_disabled);
216} 216}
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index 9e3f39d36e88..466b84234683 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -2641,7 +2641,7 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ
2641 phys_addr_t addr; 2641 phys_addr_t addr;
2642 u64 size; 2642 u64 size;
2643 2643
2644 for (node = NULL; (node = of_find_node_by_name(node, name)) != NULL;) { 2644 for_each_node_by_name(node, name) {
2645 if (!compat) 2645 if (!compat)
2646 break; 2646 break;
2647 if (of_device_is_compatible(node, compat)) 2647 if (of_device_is_compatible(node, compat))
@@ -2853,7 +2853,6 @@ set_initial_features(void)
2853 } 2853 }
2854 2854
2855 /* Enable ATA-100 before PCI probe. */ 2855 /* Enable ATA-100 before PCI probe. */
2856 np = of_find_node_by_name(NULL, "ata-6");
2857 for_each_node_by_name(np, "ata-6") { 2856 for_each_node_by_name(np, "ata-6") {
2858 if (np->parent 2857 if (np->parent
2859 && of_device_is_compatible(np->parent, "uni-north") 2858 && of_device_is_compatible(np->parent, "uni-north")
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 5e0719b27294..57bbff465964 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -486,15 +486,16 @@ static int __init pmac_pic_probe_mpic(void)
486 struct device_node *np, *master = NULL, *slave = NULL; 486 struct device_node *np, *master = NULL, *slave = NULL;
487 487
488 /* We can have up to 2 MPICs cascaded */ 488 /* We can have up to 2 MPICs cascaded */
489 for (np = NULL; (np = of_find_node_by_type(np, "open-pic")) 489 for_each_node_by_type(np, "open-pic") {
490 != NULL;) {
491 if (master == NULL && 490 if (master == NULL &&
492 of_get_property(np, "interrupts", NULL) == NULL) 491 of_get_property(np, "interrupts", NULL) == NULL)
493 master = of_node_get(np); 492 master = of_node_get(np);
494 else if (slave == NULL) 493 else if (slave == NULL)
495 slave = of_node_get(np); 494 slave = of_node_get(np);
496 if (master && slave) 495 if (master && slave) {
496 of_node_put(np);
497 break; 497 break;
498 }
498 } 499 }
499 500
500 /* Check for bogus setups */ 501 /* Check for bogus setups */
@@ -604,6 +605,7 @@ static int pmacpic_find_viaint(void)
604 if (np == NULL) 605 if (np == NULL)
605 goto not_found; 606 goto not_found;
606 viaint = irq_of_parse_and_map(np, 0); 607 viaint = irq_of_parse_and_map(np, 0);
608 of_node_put(np);
607 609
608not_found: 610not_found:
609#endif /* CONFIG_ADB_PMU */ 611#endif /* CONFIG_ADB_PMU */
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 2cd99eb30762..95275e0e2efa 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -774,8 +774,8 @@ static void __init smp_core99_probe(void)
774 if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345); 774 if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
775 775
776 /* Count CPUs in the device-tree */ 776 /* Count CPUs in the device-tree */
777 for (cpus = NULL; (cpus = of_find_node_by_type(cpus, "cpu")) != NULL;) 777 for_each_node_by_type(cpus, "cpu")
778 ++ncpus; 778 ++ncpus;
779 779
780 printk(KERN_INFO "PowerMac SMP probe found %d cpus\n", ncpus); 780 printk(KERN_INFO "PowerMac SMP probe found %d cpus\n", ncpus);
781 781
diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile
index 3732118a0482..6c9d5199a7e2 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_PERF_EVENTS) += opal-imc.o
17obj-$(CONFIG_PPC_MEMTRACE) += memtrace.o 17obj-$(CONFIG_PPC_MEMTRACE) += memtrace.o
18obj-$(CONFIG_PPC_VAS) += vas.o vas-window.o vas-debug.o 18obj-$(CONFIG_PPC_VAS) += vas.o vas-window.o vas-debug.o
19obj-$(CONFIG_PPC_FTW) += nx-ftw.o 19obj-$(CONFIG_PPC_FTW) += nx-ftw.o
20obj-$(CONFIG_OCXL_BASE) += ocxl.o
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c
index 4650fb294e7a..33c86c1a1720 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -43,6 +43,22 @@
43 43
44static int eeh_event_irq = -EINVAL; 44static int eeh_event_irq = -EINVAL;
45 45
46void pnv_pcibios_bus_add_device(struct pci_dev *pdev)
47{
48 struct pci_dn *pdn = pci_get_pdn(pdev);
49
50 if (!pdev->is_virtfn)
51 return;
52
53 /*
54 * The following operations will fail if VF's sysfs files
55 * aren't created or its resources aren't finalized.
56 */
57 eeh_add_device_early(pdn);
58 eeh_add_device_late(pdev);
59 eeh_sysfs_add_device(pdev);
60}
61
46static int pnv_eeh_init(void) 62static int pnv_eeh_init(void)
47{ 63{
48 struct pci_controller *hose; 64 struct pci_controller *hose;
@@ -86,6 +102,7 @@ static int pnv_eeh_init(void)
86 } 102 }
87 103
88 eeh_set_pe_aux_size(max_diag_size); 104 eeh_set_pe_aux_size(max_diag_size);
105 ppc_md.pcibios_bus_add_device = pnv_pcibios_bus_add_device;
89 106
90 return 0; 107 return 0;
91} 108}
@@ -1638,70 +1655,11 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)
1638 return ret; 1655 return ret;
1639} 1656}
1640 1657
1641static int pnv_eeh_restore_vf_config(struct pci_dn *pdn)
1642{
1643 struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
1644 u32 devctl, cmd, cap2, aer_capctl;
1645 int old_mps;
1646
1647 if (edev->pcie_cap) {
1648 /* Restore MPS */
1649 old_mps = (ffs(pdn->mps) - 8) << 5;
1650 eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
1651 2, &devctl);
1652 devctl &= ~PCI_EXP_DEVCTL_PAYLOAD;
1653 devctl |= old_mps;
1654 eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
1655 2, devctl);
1656
1657 /* Disable Completion Timeout */
1658 eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCAP2,
1659 4, &cap2);
1660 if (cap2 & 0x10) {
1661 eeh_ops->read_config(pdn,
1662 edev->pcie_cap + PCI_EXP_DEVCTL2,
1663 4, &cap2);
1664 cap2 |= 0x10;
1665 eeh_ops->write_config(pdn,
1666 edev->pcie_cap + PCI_EXP_DEVCTL2,
1667 4, cap2);
1668 }
1669 }
1670
1671 /* Enable SERR and parity checking */
1672 eeh_ops->read_config(pdn, PCI_COMMAND, 2, &cmd);
1673 cmd |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1674 eeh_ops->write_config(pdn, PCI_COMMAND, 2, cmd);
1675
1676 /* Enable report various errors */
1677 if (edev->pcie_cap) {
1678 eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
1679 2, &devctl);
1680 devctl &= ~PCI_EXP_DEVCTL_CERE;
1681 devctl |= (PCI_EXP_DEVCTL_NFERE |
1682 PCI_EXP_DEVCTL_FERE |
1683 PCI_EXP_DEVCTL_URRE);
1684 eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
1685 2, devctl);
1686 }
1687
1688 /* Enable ECRC generation and check */
1689 if (edev->pcie_cap && edev->aer_cap) {
1690 eeh_ops->read_config(pdn, edev->aer_cap + PCI_ERR_CAP,
1691 4, &aer_capctl);
1692 aer_capctl |= (PCI_ERR_CAP_ECRC_GENE | PCI_ERR_CAP_ECRC_CHKE);
1693 eeh_ops->write_config(pdn, edev->aer_cap + PCI_ERR_CAP,
1694 4, aer_capctl);
1695 }
1696
1697 return 0;
1698}
1699
1700static int pnv_eeh_restore_config(struct pci_dn *pdn) 1658static int pnv_eeh_restore_config(struct pci_dn *pdn)
1701{ 1659{
1702 struct eeh_dev *edev = pdn_to_eeh_dev(pdn); 1660 struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
1703 struct pnv_phb *phb; 1661 struct pnv_phb *phb;
1704 s64 ret; 1662 s64 ret = 0;
1705 int config_addr = (pdn->busno << 8) | (pdn->devfn); 1663 int config_addr = (pdn->busno << 8) | (pdn->devfn);
1706 1664
1707 if (!edev) 1665 if (!edev)
@@ -1715,7 +1673,7 @@ static int pnv_eeh_restore_config(struct pci_dn *pdn)
1715 * to be exported by firmware in extendible way. 1673 * to be exported by firmware in extendible way.
1716 */ 1674 */
1717 if (edev->physfn) { 1675 if (edev->physfn) {
1718 ret = pnv_eeh_restore_vf_config(pdn); 1676 ret = eeh_restore_vf_config(pdn);
1719 } else { 1677 } else {
1720 phb = pdn->phb->private_data; 1678 phb = pdn->phb->private_data;
1721 ret = opal_pci_reinit(phb->opal_id, 1679 ret = opal_pci_reinit(phb->opal_id,
@@ -1728,7 +1686,7 @@ static int pnv_eeh_restore_config(struct pci_dn *pdn)
1728 return -EIO; 1686 return -EIO;
1729 } 1687 }
1730 1688
1731 return 0; 1689 return ret;
1732} 1690}
1733 1691
1734static struct eeh_ops pnv_eeh_ops = { 1692static struct eeh_ops pnv_eeh_ops = {
@@ -1746,25 +1704,10 @@ static struct eeh_ops pnv_eeh_ops = {
1746 .read_config = pnv_eeh_read_config, 1704 .read_config = pnv_eeh_read_config,
1747 .write_config = pnv_eeh_write_config, 1705 .write_config = pnv_eeh_write_config,
1748 .next_error = pnv_eeh_next_error, 1706 .next_error = pnv_eeh_next_error,
1749 .restore_config = pnv_eeh_restore_config 1707 .restore_config = pnv_eeh_restore_config,
1708 .notify_resume = NULL
1750}; 1709};
1751 1710
1752void pcibios_bus_add_device(struct pci_dev *pdev)
1753{
1754 struct pci_dn *pdn = pci_get_pdn(pdev);
1755
1756 if (!pdev->is_virtfn)
1757 return;
1758
1759 /*
1760 * The following operations will fail if VF's sysfs files
1761 * aren't created or its resources aren't finalized.
1762 */
1763 eeh_add_device_early(pdn);
1764 eeh_add_device_late(pdev);
1765 eeh_sysfs_add_device(pdev);
1766}
1767
1768#ifdef CONFIG_PCI_IOV 1711#ifdef CONFIG_PCI_IOV
1769static void pnv_pci_fixup_vf_mps(struct pci_dev *pdev) 1712static void pnv_pci_fixup_vf_mps(struct pci_dev *pdev)
1770{ 1713{
diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c
index f6cbc1a71472..0a253b64ac5f 100644
--- a/arch/powerpc/platforms/powernv/npu-dma.c
+++ b/arch/powerpc/platforms/powernv/npu-dma.c
@@ -39,7 +39,10 @@
39 */ 39 */
40static struct pci_dev *get_pci_dev(struct device_node *dn) 40static struct pci_dev *get_pci_dev(struct device_node *dn)
41{ 41{
42 return PCI_DN(dn)->pcidev; 42 struct pci_dn *pdn = PCI_DN(dn);
43
44 return pci_get_domain_bus_and_slot(pci_domain_nr(pdn->phb->bus),
45 pdn->busno, pdn->devfn);
43} 46}
44 47
45/* Given a NPU device get the associated PCI device. */ 48/* Given a NPU device get the associated PCI device. */
@@ -277,7 +280,7 @@ static int pnv_npu_dma_set_bypass(struct pnv_ioda_pe *npe)
277 int64_t rc = 0; 280 int64_t rc = 0;
278 phys_addr_t top = memblock_end_of_DRAM(); 281 phys_addr_t top = memblock_end_of_DRAM();
279 282
280 if (phb->type != PNV_PHB_NPU || !npe->pdev) 283 if (phb->type != PNV_PHB_NPU_NVLINK || !npe->pdev)
281 return -EINVAL; 284 return -EINVAL;
282 285
283 rc = pnv_npu_unset_window(npe, 0); 286 rc = pnv_npu_unset_window(npe, 0);
diff --git a/arch/powerpc/platforms/powernv/ocxl.c b/arch/powerpc/platforms/powernv/ocxl.c
new file mode 100644
index 000000000000..fa9b53af3c7b
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/ocxl.c
@@ -0,0 +1,515 @@
1// SPDX-License-Identifier: GPL-2.0+
2// Copyright 2017 IBM Corp.
3#include <asm/pnv-ocxl.h>
4#include <asm/opal.h>
5#include <asm/xive.h>
6#include <misc/ocxl-config.h>
7#include "pci.h"
8
9#define PNV_OCXL_TL_P9_RECV_CAP 0x000000000000000Full
10#define PNV_OCXL_ACTAG_MAX 64
11/* PASIDs are 20-bit, but on P9, NPU can only handle 15 bits */
12#define PNV_OCXL_PASID_BITS 15
13#define PNV_OCXL_PASID_MAX ((1 << PNV_OCXL_PASID_BITS) - 1)
14
15#define AFU_PRESENT (1 << 31)
16#define AFU_INDEX_MASK 0x3F000000
17#define AFU_INDEX_SHIFT 24
18#define ACTAG_MASK 0xFFF
19
20
21struct actag_range {
22 u16 start;
23 u16 count;
24};
25
26struct npu_link {
27 struct list_head list;
28 int domain;
29 int bus;
30 int dev;
31 u16 fn_desired_actags[8];
32 struct actag_range fn_actags[8];
33 bool assignment_done;
34};
35static struct list_head links_list = LIST_HEAD_INIT(links_list);
36static DEFINE_MUTEX(links_list_lock);
37
38
39/*
40 * opencapi actags handling:
41 *
42 * When sending commands, the opencapi device references the memory
43 * context it's targeting with an 'actag', which is really an alias
44 * for a (BDF, pasid) combination. When it receives a command, the NPU
45 * must do a lookup of the actag to identify the memory context. The
46 * hardware supports a finite number of actags per link (64 for
47 * POWER9).
48 *
49 * The device can carry multiple functions, and each function can have
50 * multiple AFUs. Each AFU advertises in its config space the number
51 * of desired actags. The host must configure in the config space of
52 * the AFU how many actags the AFU is really allowed to use (which can
53 * be less than what the AFU desires).
54 *
55 * When a PCI function is probed by the driver, it has no visibility
56 * about the other PCI functions and how many actags they'd like,
57 * which makes it impossible to distribute actags fairly among AFUs.
58 *
59 * Unfortunately, the only way to know how many actags a function
60 * desires is by looking at the data for each AFU in the config space
61 * and add them up. Similarly, the only way to know how many actags
62 * all the functions of the physical device desire is by adding the
63 * previously computed function counts. Then we can match that against
64 * what the hardware supports.
65 *
66 * To get a comprehensive view, we use a 'pci fixup': at the end of
67 * PCI enumeration, each function counts how many actags its AFUs
68 * desire and we save it in a 'npu_link' structure, shared between all
69 * the PCI functions of a same device. Therefore, when the first
70 * function is probed by the driver, we can get an idea of the total
71 * count of desired actags for the device, and assign the actags to
72 * the AFUs, by pro-rating if needed.
73 */
74
75static int find_dvsec_from_pos(struct pci_dev *dev, int dvsec_id, int pos)
76{
77 int vsec = pos;
78 u16 vendor, id;
79
80 while ((vsec = pci_find_next_ext_capability(dev, vsec,
81 OCXL_EXT_CAP_ID_DVSEC))) {
82 pci_read_config_word(dev, vsec + OCXL_DVSEC_VENDOR_OFFSET,
83 &vendor);
84 pci_read_config_word(dev, vsec + OCXL_DVSEC_ID_OFFSET, &id);
85 if (vendor == PCI_VENDOR_ID_IBM && id == dvsec_id)
86 return vsec;
87 }
88 return 0;
89}
90
91static int find_dvsec_afu_ctrl(struct pci_dev *dev, u8 afu_idx)
92{
93 int vsec = 0;
94 u8 idx;
95
96 while ((vsec = find_dvsec_from_pos(dev, OCXL_DVSEC_AFU_CTRL_ID,
97 vsec))) {
98 pci_read_config_byte(dev, vsec + OCXL_DVSEC_AFU_CTRL_AFU_IDX,
99 &idx);
100 if (idx == afu_idx)
101 return vsec;
102 }
103 return 0;
104}
105
106static int get_max_afu_index(struct pci_dev *dev, int *afu_idx)
107{
108 int pos;
109 u32 val;
110
111 pos = find_dvsec_from_pos(dev, OCXL_DVSEC_FUNC_ID, 0);
112 if (!pos)
113 return -ESRCH;
114
115 pci_read_config_dword(dev, pos + OCXL_DVSEC_FUNC_OFF_INDEX, &val);
116 if (val & AFU_PRESENT)
117 *afu_idx = (val & AFU_INDEX_MASK) >> AFU_INDEX_SHIFT;
118 else
119 *afu_idx = -1;
120 return 0;
121}
122
123static int get_actag_count(struct pci_dev *dev, int afu_idx, int *actag)
124{
125 int pos;
126 u16 actag_sup;
127
128 pos = find_dvsec_afu_ctrl(dev, afu_idx);
129 if (!pos)
130 return -ESRCH;
131
132 pci_read_config_word(dev, pos + OCXL_DVSEC_AFU_CTRL_ACTAG_SUP,
133 &actag_sup);
134 *actag = actag_sup & ACTAG_MASK;
135 return 0;
136}
137
138static struct npu_link *find_link(struct pci_dev *dev)
139{
140 struct npu_link *link;
141
142 list_for_each_entry(link, &links_list, list) {
143 /* The functions of a device all share the same link */
144 if (link->domain == pci_domain_nr(dev->bus) &&
145 link->bus == dev->bus->number &&
146 link->dev == PCI_SLOT(dev->devfn)) {
147 return link;
148 }
149 }
150
151 /* link doesn't exist yet. Allocate one */
152 link = kzalloc(sizeof(struct npu_link), GFP_KERNEL);
153 if (!link)
154 return NULL;
155 link->domain = pci_domain_nr(dev->bus);
156 link->bus = dev->bus->number;
157 link->dev = PCI_SLOT(dev->devfn);
158 list_add(&link->list, &links_list);
159 return link;
160}
161
162static void pnv_ocxl_fixup_actag(struct pci_dev *dev)
163{
164 struct pci_controller *hose = pci_bus_to_host(dev->bus);
165 struct pnv_phb *phb = hose->private_data;
166 struct npu_link *link;
167 int rc, afu_idx = -1, i, actag;
168
169 if (!machine_is(powernv))
170 return;
171
172 if (phb->type != PNV_PHB_NPU_OCAPI)
173 return;
174
175 mutex_lock(&links_list_lock);
176
177 link = find_link(dev);
178 if (!link) {
179 dev_warn(&dev->dev, "couldn't update actag information\n");
180 mutex_unlock(&links_list_lock);
181 return;
182 }
183
184 /*
185 * Check how many actags are desired for the AFUs under that
186 * function and add it to the count for the link
187 */
188 rc = get_max_afu_index(dev, &afu_idx);
189 if (rc) {
190 /* Most likely an invalid config space */
191 dev_dbg(&dev->dev, "couldn't find AFU information\n");
192 afu_idx = -1;
193 }
194
195 link->fn_desired_actags[PCI_FUNC(dev->devfn)] = 0;
196 for (i = 0; i <= afu_idx; i++) {
197 /*
198 * AFU index 'holes' are allowed. So don't fail if we
199 * can't read the actag info for an index
200 */
201 rc = get_actag_count(dev, i, &actag);
202 if (rc)
203 continue;
204 link->fn_desired_actags[PCI_FUNC(dev->devfn)] += actag;
205 }
206 dev_dbg(&dev->dev, "total actags for function: %d\n",
207 link->fn_desired_actags[PCI_FUNC(dev->devfn)]);
208
209 mutex_unlock(&links_list_lock);
210}
211DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pnv_ocxl_fixup_actag);
212
213static u16 assign_fn_actags(u16 desired, u16 total)
214{
215 u16 count;
216
217 if (total <= PNV_OCXL_ACTAG_MAX)
218 count = desired;
219 else
220 count = PNV_OCXL_ACTAG_MAX * desired / total;
221
222 return count;
223}
224
225static void assign_actags(struct npu_link *link)
226{
227 u16 actag_count, range_start = 0, total_desired = 0;
228 int i;
229
230 for (i = 0; i < 8; i++)
231 total_desired += link->fn_desired_actags[i];
232
233 for (i = 0; i < 8; i++) {
234 if (link->fn_desired_actags[i]) {
235 actag_count = assign_fn_actags(
236 link->fn_desired_actags[i],
237 total_desired);
238 link->fn_actags[i].start = range_start;
239 link->fn_actags[i].count = actag_count;
240 range_start += actag_count;
241 WARN_ON(range_start >= PNV_OCXL_ACTAG_MAX);
242 }
243 pr_debug("link %x:%x:%x fct %d actags: start=%d count=%d (desired=%d)\n",
244 link->domain, link->bus, link->dev, i,
245 link->fn_actags[i].start, link->fn_actags[i].count,
246 link->fn_desired_actags[i]);
247 }
248 link->assignment_done = true;
249}
250
251int pnv_ocxl_get_actag(struct pci_dev *dev, u16 *base, u16 *enabled,
252 u16 *supported)
253{
254 struct npu_link *link;
255
256 mutex_lock(&links_list_lock);
257
258 link = find_link(dev);
259 if (!link) {
260 dev_err(&dev->dev, "actag information not found\n");
261 mutex_unlock(&links_list_lock);
262 return -ENODEV;
263 }
264 /*
265 * On p9, we only have 64 actags per link, so they must be
266 * shared by all the functions of the same adapter. We counted
267 * the desired actag counts during PCI enumeration, so that we
268 * can allocate a pro-rated number of actags to each function.
269 */
270 if (!link->assignment_done)
271 assign_actags(link);
272
273 *base = link->fn_actags[PCI_FUNC(dev->devfn)].start;
274 *enabled = link->fn_actags[PCI_FUNC(dev->devfn)].count;
275 *supported = link->fn_desired_actags[PCI_FUNC(dev->devfn)];
276
277 mutex_unlock(&links_list_lock);
278 return 0;
279}
280EXPORT_SYMBOL_GPL(pnv_ocxl_get_actag);
281
282int pnv_ocxl_get_pasid_count(struct pci_dev *dev, int *count)
283{
284 struct npu_link *link;
285 int i, rc = -EINVAL;
286
287 /*
288 * The number of PASIDs (process address space ID) which can
289 * be used by a function depends on how many functions exist
290 * on the device. The NPU needs to be configured to know how
291 * many bits are available to PASIDs and how many are to be
292 * used by the function BDF indentifier.
293 *
294 * We only support one AFU-carrying function for now.
295 */
296 mutex_lock(&links_list_lock);
297
298 link = find_link(dev);
299 if (!link) {
300 dev_err(&dev->dev, "actag information not found\n");
301 mutex_unlock(&links_list_lock);
302 return -ENODEV;
303 }
304
305 for (i = 0; i < 8; i++)
306 if (link->fn_desired_actags[i] && (i == PCI_FUNC(dev->devfn))) {
307 *count = PNV_OCXL_PASID_MAX;
308 rc = 0;
309 break;
310 }
311
312 mutex_unlock(&links_list_lock);
313 dev_dbg(&dev->dev, "%d PASIDs available for function\n",
314 rc ? 0 : *count);
315 return rc;
316}
317EXPORT_SYMBOL_GPL(pnv_ocxl_get_pasid_count);
318
319static void set_templ_rate(unsigned int templ, unsigned int rate, char *buf)
320{
321 int shift, idx;
322
323 WARN_ON(templ > PNV_OCXL_TL_MAX_TEMPLATE);
324 idx = (PNV_OCXL_TL_MAX_TEMPLATE - templ) / 2;
325 shift = 4 * (1 - ((PNV_OCXL_TL_MAX_TEMPLATE - templ) % 2));
326 buf[idx] |= rate << shift;
327}
328
329int pnv_ocxl_get_tl_cap(struct pci_dev *dev, long *cap,
330 char *rate_buf, int rate_buf_size)
331{
332 if (rate_buf_size != PNV_OCXL_TL_RATE_BUF_SIZE)
333 return -EINVAL;
334 /*
335 * The TL capabilities are a characteristic of the NPU, so
336 * we go with hard-coded values.
337 *
338 * The receiving rate of each template is encoded on 4 bits.
339 *
340 * On P9:
341 * - templates 0 -> 3 are supported
342 * - templates 0, 1 and 3 have a 0 receiving rate
343 * - template 2 has receiving rate of 1 (extra cycle)
344 */
345 memset(rate_buf, 0, rate_buf_size);
346 set_templ_rate(2, 1, rate_buf);
347 *cap = PNV_OCXL_TL_P9_RECV_CAP;
348 return 0;
349}
350EXPORT_SYMBOL_GPL(pnv_ocxl_get_tl_cap);
351
352int pnv_ocxl_set_tl_conf(struct pci_dev *dev, long cap,
353 uint64_t rate_buf_phys, int rate_buf_size)
354{
355 struct pci_controller *hose = pci_bus_to_host(dev->bus);
356 struct pnv_phb *phb = hose->private_data;
357 int rc;
358
359 if (rate_buf_size != PNV_OCXL_TL_RATE_BUF_SIZE)
360 return -EINVAL;
361
362 rc = opal_npu_tl_set(phb->opal_id, dev->devfn, cap,
363 rate_buf_phys, rate_buf_size);
364 if (rc) {
365 dev_err(&dev->dev, "Can't configure host TL: %d\n", rc);
366 return -EINVAL;
367 }
368 return 0;
369}
370EXPORT_SYMBOL_GPL(pnv_ocxl_set_tl_conf);
371
372int pnv_ocxl_get_xsl_irq(struct pci_dev *dev, int *hwirq)
373{
374 int rc;
375
376 rc = of_property_read_u32(dev->dev.of_node, "ibm,opal-xsl-irq", hwirq);
377 if (rc) {
378 dev_err(&dev->dev,
379 "Can't get translation interrupt for device\n");
380 return rc;
381 }
382 return 0;
383}
384EXPORT_SYMBOL_GPL(pnv_ocxl_get_xsl_irq);
385
386void pnv_ocxl_unmap_xsl_regs(void __iomem *dsisr, void __iomem *dar,
387 void __iomem *tfc, void __iomem *pe_handle)
388{
389 iounmap(dsisr);
390 iounmap(dar);
391 iounmap(tfc);
392 iounmap(pe_handle);
393}
394EXPORT_SYMBOL_GPL(pnv_ocxl_unmap_xsl_regs);
395
396int pnv_ocxl_map_xsl_regs(struct pci_dev *dev, void __iomem **dsisr,
397 void __iomem **dar, void __iomem **tfc,
398 void __iomem **pe_handle)
399{
400 u64 reg;
401 int i, j, rc = 0;
402 void __iomem *regs[4];
403
404 /*
405 * opal stores the mmio addresses of the DSISR, DAR, TFC and
406 * PE_HANDLE registers in a device tree property, in that
407 * order
408 */
409 for (i = 0; i < 4; i++) {
410 rc = of_property_read_u64_index(dev->dev.of_node,
411 "ibm,opal-xsl-mmio", i, &reg);
412 if (rc)
413 break;
414 regs[i] = ioremap(reg, 8);
415 if (!regs[i]) {
416 rc = -EINVAL;
417 break;
418 }
419 }
420 if (rc) {
421 dev_err(&dev->dev, "Can't map translation mmio registers\n");
422 for (j = i - 1; j >= 0; j--)
423 iounmap(regs[j]);
424 } else {
425 *dsisr = regs[0];
426 *dar = regs[1];
427 *tfc = regs[2];
428 *pe_handle = regs[3];
429 }
430 return rc;
431}
432EXPORT_SYMBOL_GPL(pnv_ocxl_map_xsl_regs);
433
434struct spa_data {
435 u64 phb_opal_id;
436 u32 bdfn;
437};
438
439int pnv_ocxl_spa_setup(struct pci_dev *dev, void *spa_mem, int PE_mask,
440 void **platform_data)
441{
442 struct pci_controller *hose = pci_bus_to_host(dev->bus);
443 struct pnv_phb *phb = hose->private_data;
444 struct spa_data *data;
445 u32 bdfn;
446 int rc;
447
448 data = kzalloc(sizeof(*data), GFP_KERNEL);
449 if (!data)
450 return -ENOMEM;
451
452 bdfn = (dev->bus->number << 8) | dev->devfn;
453 rc = opal_npu_spa_setup(phb->opal_id, bdfn, virt_to_phys(spa_mem),
454 PE_mask);
455 if (rc) {
456 dev_err(&dev->dev, "Can't setup Shared Process Area: %d\n", rc);
457 kfree(data);
458 return rc;
459 }
460 data->phb_opal_id = phb->opal_id;
461 data->bdfn = bdfn;
462 *platform_data = (void *) data;
463 return 0;
464}
465EXPORT_SYMBOL_GPL(pnv_ocxl_spa_setup);
466
467void pnv_ocxl_spa_release(void *platform_data)
468{
469 struct spa_data *data = (struct spa_data *) platform_data;
470 int rc;
471
472 rc = opal_npu_spa_setup(data->phb_opal_id, data->bdfn, 0, 0);
473 WARN_ON(rc);
474 kfree(data);
475}
476EXPORT_SYMBOL_GPL(pnv_ocxl_spa_release);
477
478int pnv_ocxl_spa_remove_pe(void *platform_data, int pe_handle)
479{
480 struct spa_data *data = (struct spa_data *) platform_data;
481 int rc;
482
483 rc = opal_npu_spa_clear_cache(data->phb_opal_id, data->bdfn, pe_handle);
484 return rc;
485}
486EXPORT_SYMBOL_GPL(pnv_ocxl_spa_remove_pe);
487
488int pnv_ocxl_alloc_xive_irq(u32 *irq, u64 *trigger_addr)
489{
490 __be64 flags, trigger_page;
491 s64 rc;
492 u32 hwirq;
493
494 hwirq = xive_native_alloc_irq();
495 if (!hwirq)
496 return -ENOENT;
497
498 rc = opal_xive_get_irq_info(hwirq, &flags, NULL, &trigger_page, NULL,
499 NULL);
500 if (rc || !trigger_page) {
501 xive_native_free_irq(hwirq);
502 return -ENOENT;
503 }
504 *irq = hwirq;
505 *trigger_addr = be64_to_cpu(trigger_page);
506 return 0;
507
508}
509EXPORT_SYMBOL_GPL(pnv_ocxl_alloc_xive_irq);
510
511void pnv_ocxl_free_xive_irq(u32 irq)
512{
513 xive_native_free_irq(irq);
514}
515EXPORT_SYMBOL_GPL(pnv_ocxl_free_xive_irq);
diff --git a/arch/powerpc/platforms/powernv/opal-dump.c b/arch/powerpc/platforms/powernv/opal-dump.c
index 4c827826c05e..0dc8fa4e0af2 100644
--- a/arch/powerpc/platforms/powernv/opal-dump.c
+++ b/arch/powerpc/platforms/powernv/opal-dump.c
@@ -103,9 +103,9 @@ static ssize_t dump_ack_store(struct dump_obj *dump_obj,
103 * due to the dynamic size of the dump 103 * due to the dynamic size of the dump
104 */ 104 */
105static struct dump_attribute id_attribute = 105static struct dump_attribute id_attribute =
106 __ATTR(id, S_IRUGO, dump_id_show, NULL); 106 __ATTR(id, 0444, dump_id_show, NULL);
107static struct dump_attribute type_attribute = 107static struct dump_attribute type_attribute =
108 __ATTR(type, S_IRUGO, dump_type_show, NULL); 108 __ATTR(type, 0444, dump_type_show, NULL);
109static struct dump_attribute ack_attribute = 109static struct dump_attribute ack_attribute =
110 __ATTR(acknowledge, 0660, dump_ack_show, dump_ack_store); 110 __ATTR(acknowledge, 0660, dump_ack_show, dump_ack_store);
111 111
diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c
index ecd6d9177d13..ba6e437abb4b 100644
--- a/arch/powerpc/platforms/powernv/opal-elog.c
+++ b/arch/powerpc/platforms/powernv/opal-elog.c
@@ -83,9 +83,9 @@ static ssize_t elog_ack_store(struct elog_obj *elog_obj,
83} 83}
84 84
85static struct elog_attribute id_attribute = 85static struct elog_attribute id_attribute =
86 __ATTR(id, S_IRUGO, elog_id_show, NULL); 86 __ATTR(id, 0444, elog_id_show, NULL);
87static struct elog_attribute type_attribute = 87static struct elog_attribute type_attribute =
88 __ATTR(type, S_IRUGO, elog_type_show, NULL); 88 __ATTR(type, 0444, elog_type_show, NULL);
89static struct elog_attribute ack_attribute = 89static struct elog_attribute ack_attribute =
90 __ATTR(acknowledge, 0660, elog_ack_show, elog_ack_store); 90 __ATTR(acknowledge, 0660, elog_ack_show, elog_ack_store);
91 91
diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c
index 465ea105b771..dd4c9b8b8a81 100644
--- a/arch/powerpc/platforms/powernv/opal-imc.c
+++ b/arch/powerpc/platforms/powernv/opal-imc.c
@@ -21,6 +21,78 @@
21#include <asm/io.h> 21#include <asm/io.h>
22#include <asm/imc-pmu.h> 22#include <asm/imc-pmu.h>
23#include <asm/cputhreads.h> 23#include <asm/cputhreads.h>
24#include <asm/debugfs.h>
25
26static struct dentry *imc_debugfs_parent;
27
28/* Helpers to export imc command and mode via debugfs */
29static int imc_mem_get(void *data, u64 *val)
30{
31 *val = cpu_to_be64(*(u64 *)data);
32 return 0;
33}
34
35static int imc_mem_set(void *data, u64 val)
36{
37 *(u64 *)data = cpu_to_be64(val);
38 return 0;
39}
40DEFINE_DEBUGFS_ATTRIBUTE(fops_imc_x64, imc_mem_get, imc_mem_set, "0x%016llx\n");
41
42static struct dentry *imc_debugfs_create_x64(const char *name, umode_t mode,
43 struct dentry *parent, u64 *value)
44{
45 return debugfs_create_file_unsafe(name, mode, parent,
46 value, &fops_imc_x64);
47}
48
49/*
50 * export_imc_mode_and_cmd: Create a debugfs interface
51 * for imc_cmd and imc_mode
52 * for each node in the system.
53 * imc_mode and imc_cmd can be changed by echo into
54 * this interface.
55 */
56static void export_imc_mode_and_cmd(struct device_node *node,
57 struct imc_pmu *pmu_ptr)
58{
59 static u64 loc, *imc_mode_addr, *imc_cmd_addr;
60 int chip = 0, nid;
61 char mode[16], cmd[16];
62 u32 cb_offset;
63
64 imc_debugfs_parent = debugfs_create_dir("imc", powerpc_debugfs_root);
65
66 /*
67 * Return here, either because 'imc' directory already exists,
68 * Or failed to create a new one.
69 */
70 if (!imc_debugfs_parent)
71 return;
72
73 if (of_property_read_u32(node, "cb_offset", &cb_offset))
74 cb_offset = IMC_CNTL_BLK_OFFSET;
75
76 for_each_node(nid) {
77 loc = (u64)(pmu_ptr->mem_info[chip].vbase) + cb_offset;
78 imc_mode_addr = (u64 *)(loc + IMC_CNTL_BLK_MODE_OFFSET);
79 sprintf(mode, "imc_mode_%d", nid);
80 if (!imc_debugfs_create_x64(mode, 0600, imc_debugfs_parent,
81 imc_mode_addr))
82 goto err;
83
84 imc_cmd_addr = (u64 *)(loc + IMC_CNTL_BLK_CMD_OFFSET);
85 sprintf(cmd, "imc_cmd_%d", nid);
86 if (!imc_debugfs_create_x64(cmd, 0600, imc_debugfs_parent,
87 imc_cmd_addr))
88 goto err;
89 chip++;
90 }
91 return;
92
93err:
94 debugfs_remove_recursive(imc_debugfs_parent);
95}
24 96
25/* 97/*
26 * imc_get_mem_addr_nest: Function to get nest counter memory region 98 * imc_get_mem_addr_nest: Function to get nest counter memory region
@@ -65,6 +137,7 @@ static int imc_get_mem_addr_nest(struct device_node *node,
65 } 137 }
66 138
67 pmu_ptr->imc_counter_mmaped = true; 139 pmu_ptr->imc_counter_mmaped = true;
140 export_imc_mode_and_cmd(node, pmu_ptr);
68 kfree(base_addr_arr); 141 kfree(base_addr_arr);
69 kfree(chipid_arr); 142 kfree(chipid_arr);
70 return 0; 143 return 0;
@@ -213,6 +286,10 @@ static int opal_imc_counters_probe(struct platform_device *pdev)
213 } 286 }
214 } 287 }
215 288
289 /* If none of the nest units are registered, remove debugfs interface */
290 if (pmu_count == 0)
291 debugfs_remove_recursive(imc_debugfs_parent);
292
216 return 0; 293 return 0;
217} 294}
218 295
diff --git a/arch/powerpc/platforms/powernv/opal-sysparam.c b/arch/powerpc/platforms/powernv/opal-sysparam.c
index 23fb6647dced..6fd4092798d5 100644
--- a/arch/powerpc/platforms/powernv/opal-sysparam.c
+++ b/arch/powerpc/platforms/powernv/opal-sysparam.c
@@ -260,13 +260,13 @@ void __init opal_sys_param_init(void)
260 /* If the parameter is read-only or read-write */ 260 /* If the parameter is read-only or read-write */
261 switch (perm[i] & 3) { 261 switch (perm[i] & 3) {
262 case OPAL_SYSPARAM_READ: 262 case OPAL_SYSPARAM_READ:
263 attr[i].kobj_attr.attr.mode = S_IRUGO; 263 attr[i].kobj_attr.attr.mode = 0444;
264 break; 264 break;
265 case OPAL_SYSPARAM_WRITE: 265 case OPAL_SYSPARAM_WRITE:
266 attr[i].kobj_attr.attr.mode = S_IWUSR; 266 attr[i].kobj_attr.attr.mode = 0200;
267 break; 267 break;
268 case OPAL_SYSPARAM_RW: 268 case OPAL_SYSPARAM_RW:
269 attr[i].kobj_attr.attr.mode = S_IRUGO | S_IWUSR; 269 attr[i].kobj_attr.attr.mode = 0644;
270 break; 270 break;
271 default: 271 default:
272 break; 272 break;
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
index 6f4b00a2ac46..1b2936ba6040 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -320,3 +320,6 @@ OPAL_CALL(opal_set_powercap, OPAL_SET_POWERCAP);
320OPAL_CALL(opal_get_power_shift_ratio, OPAL_GET_POWER_SHIFT_RATIO); 320OPAL_CALL(opal_get_power_shift_ratio, OPAL_GET_POWER_SHIFT_RATIO);
321OPAL_CALL(opal_set_power_shift_ratio, OPAL_SET_POWER_SHIFT_RATIO); 321OPAL_CALL(opal_set_power_shift_ratio, OPAL_SET_POWER_SHIFT_RATIO);
322OPAL_CALL(opal_sensor_group_clear, OPAL_SENSOR_GROUP_CLEAR); 322OPAL_CALL(opal_sensor_group_clear, OPAL_SENSOR_GROUP_CLEAR);
323OPAL_CALL(opal_npu_spa_setup, OPAL_NPU_SPA_SETUP);
324OPAL_CALL(opal_npu_spa_clear_cache, OPAL_NPU_SPA_CLEAR_CACHE);
325OPAL_CALL(opal_npu_tl_set, OPAL_NPU_TL_SET);
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 041ddbd1fc57..c15182765ff5 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -127,7 +127,7 @@ int __init early_init_dt_scan_opal(unsigned long node,
127 127
128 if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) { 128 if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) {
129 powerpc_firmware_features |= FW_FEATURE_OPAL; 129 powerpc_firmware_features |= FW_FEATURE_OPAL;
130 pr_info("OPAL detected !\n"); 130 pr_debug("OPAL detected !\n");
131 } else { 131 } else {
132 panic("OPAL != V3 detected, no longer supported.\n"); 132 panic("OPAL != V3 detected, no longer supported.\n");
133 } 133 }
@@ -239,8 +239,8 @@ int opal_message_notifier_register(enum opal_msg_type msg_type,
239 struct notifier_block *nb) 239 struct notifier_block *nb)
240{ 240{
241 if (!nb || msg_type >= OPAL_MSG_TYPE_MAX) { 241 if (!nb || msg_type >= OPAL_MSG_TYPE_MAX) {
242 pr_warning("%s: Invalid arguments, msg_type:%d\n", 242 pr_warn("%s: Invalid arguments, msg_type:%d\n",
243 __func__, msg_type); 243 __func__, msg_type);
244 return -EINVAL; 244 return -EINVAL;
245 } 245 }
246 246
@@ -281,8 +281,8 @@ static void opal_handle_message(void)
281 281
282 /* check for errors. */ 282 /* check for errors. */
283 if (ret) { 283 if (ret) {
284 pr_warning("%s: Failed to retrieve opal message, err=%lld\n", 284 pr_warn("%s: Failed to retrieve opal message, err=%lld\n",
285 __func__, ret); 285 __func__, ret);
286 return; 286 return;
287 } 287 }
288 288
@@ -461,24 +461,14 @@ static int opal_recover_mce(struct pt_regs *regs,
461 461
462void pnv_platform_error_reboot(struct pt_regs *regs, const char *msg) 462void pnv_platform_error_reboot(struct pt_regs *regs, const char *msg)
463{ 463{
464 /* 464 panic_flush_kmsg_start();
465 * This is mostly taken from kernel/panic.c, but tries to do 465
466 * relatively minimal work. Don't use delay functions (TB may
467 * be broken), don't crash dump (need to set a firmware log),
468 * don't run notifiers. We do want to get some information to
469 * Linux console.
470 */
471 console_verbose();
472 bust_spinlocks(1);
473 pr_emerg("Hardware platform error: %s\n", msg); 466 pr_emerg("Hardware platform error: %s\n", msg);
474 if (regs) 467 if (regs)
475 show_regs(regs); 468 show_regs(regs);
476 smp_send_stop(); 469 smp_send_stop();
477 printk_safe_flush_on_panic(); 470
478 kmsg_dump(KMSG_DUMP_PANIC); 471 panic_flush_kmsg_end();
479 bust_spinlocks(0);
480 debug_locks_off();
481 console_flush_on_panic();
482 472
483 /* 473 /*
484 * Don't bother to shut things down because this will 474 * Don't bother to shut things down because this will
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 9582aeb1fe4c..496e47696ed0 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -54,7 +54,8 @@
54#define POWERNV_IOMMU_DEFAULT_LEVELS 1 54#define POWERNV_IOMMU_DEFAULT_LEVELS 1
55#define POWERNV_IOMMU_MAX_LEVELS 5 55#define POWERNV_IOMMU_MAX_LEVELS 5
56 56
57static const char * const pnv_phb_names[] = { "IODA1", "IODA2", "NPU" }; 57static const char * const pnv_phb_names[] = { "IODA1", "IODA2", "NPU_NVLINK",
58 "NPU_OCAPI" };
58static void pnv_pci_ioda2_table_free_pages(struct iommu_table *tbl); 59static void pnv_pci_ioda2_table_free_pages(struct iommu_table *tbl);
59 60
60void pe_level_printk(const struct pnv_ioda_pe *pe, const char *level, 61void pe_level_printk(const struct pnv_ioda_pe *pe, const char *level,
@@ -89,6 +90,7 @@ void pe_level_printk(const struct pnv_ioda_pe *pe, const char *level,
89} 90}
90 91
91static bool pnv_iommu_bypass_disabled __read_mostly; 92static bool pnv_iommu_bypass_disabled __read_mostly;
93static bool pci_reset_phbs __read_mostly;
92 94
93static int __init iommu_setup(char *str) 95static int __init iommu_setup(char *str)
94{ 96{
@@ -110,6 +112,14 @@ static int __init iommu_setup(char *str)
110} 112}
111early_param("iommu", iommu_setup); 113early_param("iommu", iommu_setup);
112 114
115static int __init pci_reset_phbs_setup(char *str)
116{
117 pci_reset_phbs = true;
118 return 0;
119}
120
121early_param("ppc_pci_reset_phbs", pci_reset_phbs_setup);
122
113static inline bool pnv_pci_is_m64(struct pnv_phb *phb, struct resource *r) 123static inline bool pnv_pci_is_m64(struct pnv_phb *phb, struct resource *r)
114{ 124{
115 /* 125 /*
@@ -924,7 +934,7 @@ static int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe)
924 * Configure PELTV. NPUs don't have a PELTV table so skip 934 * Configure PELTV. NPUs don't have a PELTV table so skip
925 * configuration on them. 935 * configuration on them.
926 */ 936 */
927 if (phb->type != PNV_PHB_NPU) 937 if (phb->type != PNV_PHB_NPU_NVLINK && phb->type != PNV_PHB_NPU_OCAPI)
928 pnv_ioda_set_peltv(phb, pe, true); 938 pnv_ioda_set_peltv(phb, pe, true);
929 939
930 /* Setup reverse map */ 940 /* Setup reverse map */
@@ -1059,8 +1069,8 @@ static struct pnv_ioda_pe *pnv_ioda_setup_dev_PE(struct pci_dev *dev)
1059 1069
1060 pe = pnv_ioda_alloc_pe(phb); 1070 pe = pnv_ioda_alloc_pe(phb);
1061 if (!pe) { 1071 if (!pe) {
1062 pr_warning("%s: Not enough PE# available, disabling device\n", 1072 pr_warn("%s: Not enough PE# available, disabling device\n",
1063 pci_name(dev)); 1073 pci_name(dev));
1064 return NULL; 1074 return NULL;
1065 } 1075 }
1066 1076
@@ -1072,7 +1082,6 @@ static struct pnv_ioda_pe *pnv_ioda_setup_dev_PE(struct pci_dev *dev)
1072 * At some point we want to remove the PDN completely anyways 1082 * At some point we want to remove the PDN completely anyways
1073 */ 1083 */
1074 pci_dev_get(dev); 1084 pci_dev_get(dev);
1075 pdn->pcidev = dev;
1076 pdn->pe_number = pe->pe_number; 1085 pdn->pe_number = pe->pe_number;
1077 pe->flags = PNV_IODA_PE_DEV; 1086 pe->flags = PNV_IODA_PE_DEV;
1078 pe->pdev = dev; 1087 pe->pdev = dev;
@@ -1119,7 +1128,6 @@ static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe)
1119 continue; 1128 continue;
1120 1129
1121 pe->device_count++; 1130 pe->device_count++;
1122 pdn->pcidev = dev;
1123 pdn->pe_number = pe->pe_number; 1131 pdn->pe_number = pe->pe_number;
1124 if ((pe->flags & PNV_IODA_PE_BUS_ALL) && dev->subordinate) 1132 if ((pe->flags & PNV_IODA_PE_BUS_ALL) && dev->subordinate)
1125 pnv_ioda_setup_same_PE(dev->subordinate, pe); 1133 pnv_ioda_setup_same_PE(dev->subordinate, pe);
@@ -1164,7 +1172,7 @@ static struct pnv_ioda_pe *pnv_ioda_setup_bus_PE(struct pci_bus *bus, bool all)
1164 pe = pnv_ioda_alloc_pe(phb); 1172 pe = pnv_ioda_alloc_pe(phb);
1165 1173
1166 if (!pe) { 1174 if (!pe) {
1167 pr_warning("%s: Not enough PE# available for PCI bus %04x:%02x\n", 1175 pr_warn("%s: Not enough PE# available for PCI bus %04x:%02x\n",
1168 __func__, pci_domain_nr(bus), bus->number); 1176 __func__, pci_domain_nr(bus), bus->number);
1169 return NULL; 1177 return NULL;
1170 } 1178 }
@@ -1234,7 +1242,6 @@ static struct pnv_ioda_pe *pnv_ioda_setup_npu_PE(struct pci_dev *npu_pdev)
1234 pci_dev_get(npu_pdev); 1242 pci_dev_get(npu_pdev);
1235 npu_pdn = pci_get_pdn(npu_pdev); 1243 npu_pdn = pci_get_pdn(npu_pdev);
1236 rid = npu_pdev->bus->number << 8 | npu_pdn->devfn; 1244 rid = npu_pdev->bus->number << 8 | npu_pdn->devfn;
1237 npu_pdn->pcidev = npu_pdev;
1238 npu_pdn->pe_number = pe_num; 1245 npu_pdn->pe_number = pe_num;
1239 phb->ioda.pe_rmap[rid] = pe->pe_number; 1246 phb->ioda.pe_rmap[rid] = pe->pe_number;
1240 1247
@@ -1272,16 +1279,23 @@ static void pnv_pci_ioda_setup_PEs(void)
1272{ 1279{
1273 struct pci_controller *hose, *tmp; 1280 struct pci_controller *hose, *tmp;
1274 struct pnv_phb *phb; 1281 struct pnv_phb *phb;
1282 struct pci_bus *bus;
1283 struct pci_dev *pdev;
1275 1284
1276 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { 1285 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
1277 phb = hose->private_data; 1286 phb = hose->private_data;
1278 if (phb->type == PNV_PHB_NPU) { 1287 if (phb->type == PNV_PHB_NPU_NVLINK) {
1279 /* PE#0 is needed for error reporting */ 1288 /* PE#0 is needed for error reporting */
1280 pnv_ioda_reserve_pe(phb, 0); 1289 pnv_ioda_reserve_pe(phb, 0);
1281 pnv_ioda_setup_npu_PEs(hose->bus); 1290 pnv_ioda_setup_npu_PEs(hose->bus);
1282 if (phb->model == PNV_PHB_MODEL_NPU2) 1291 if (phb->model == PNV_PHB_MODEL_NPU2)
1283 pnv_npu2_init(phb); 1292 pnv_npu2_init(phb);
1284 } 1293 }
1294 if (phb->type == PNV_PHB_NPU_OCAPI) {
1295 bus = hose->bus;
1296 list_for_each_entry(pdev, &bus->devices, bus_list)
1297 pnv_ioda_setup_dev_PE(pdev);
1298 }
1285 } 1299 }
1286} 1300}
1287 1301
@@ -1692,7 +1706,7 @@ m64_failed:
1692 return ret; 1706 return ret;
1693} 1707}
1694 1708
1695int pcibios_sriov_disable(struct pci_dev *pdev) 1709int pnv_pcibios_sriov_disable(struct pci_dev *pdev)
1696{ 1710{
1697 pnv_pci_sriov_disable(pdev); 1711 pnv_pci_sriov_disable(pdev);
1698 1712
@@ -1701,7 +1715,7 @@ int pcibios_sriov_disable(struct pci_dev *pdev)
1701 return 0; 1715 return 0;
1702} 1716}
1703 1717
1704int pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs) 1718int pnv_pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
1705{ 1719{
1706 /* Allocate PCI data */ 1720 /* Allocate PCI data */
1707 add_dev_pci_data(pdev); 1721 add_dev_pci_data(pdev);
@@ -2572,7 +2586,6 @@ static unsigned long pnv_pci_ioda2_get_table_size(__u32 page_shift,
2572 unsigned long direct_table_size; 2586 unsigned long direct_table_size;
2573 2587
2574 if (!levels || (levels > POWERNV_IOMMU_MAX_LEVELS) || 2588 if (!levels || (levels > POWERNV_IOMMU_MAX_LEVELS) ||
2575 (window_size > memory_hotplug_max()) ||
2576 !is_power_of_2(window_size)) 2589 !is_power_of_2(window_size))
2577 return 0; 2590 return 0;
2578 2591
@@ -2640,7 +2653,7 @@ static int gpe_table_group_to_npe_cb(struct device *dev, void *opaque)
2640 2653
2641 hose = pci_bus_to_host(pdev->bus); 2654 hose = pci_bus_to_host(pdev->bus);
2642 phb = hose->private_data; 2655 phb = hose->private_data;
2643 if (phb->type != PNV_PHB_NPU) 2656 if (phb->type != PNV_PHB_NPU_NVLINK)
2644 return 0; 2657 return 0;
2645 2658
2646 *ptmppe = &phb->ioda.pe_array[pdn->pe_number]; 2659 *ptmppe = &phb->ioda.pe_array[pdn->pe_number];
@@ -2724,7 +2737,7 @@ static void pnv_pci_ioda_setup_iommu_api(void)
2724 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { 2737 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
2725 phb = hose->private_data; 2738 phb = hose->private_data;
2726 2739
2727 if (phb->type != PNV_PHB_NPU) 2740 if (phb->type != PNV_PHB_NPU_NVLINK)
2728 continue; 2741 continue;
2729 2742
2730 list_for_each_entry(pe, &phb->ioda.pe_list, list) { 2743 list_for_each_entry(pe, &phb->ioda.pe_list, list) {
@@ -3293,7 +3306,7 @@ static void pnv_pci_ioda_create_dbgfs(void)
3293 sprintf(name, "PCI%04x", hose->global_number); 3306 sprintf(name, "PCI%04x", hose->global_number);
3294 phb->dbgfs = debugfs_create_dir(name, powerpc_debugfs_root); 3307 phb->dbgfs = debugfs_create_dir(name, powerpc_debugfs_root);
3295 if (!phb->dbgfs) { 3308 if (!phb->dbgfs) {
3296 pr_warning("%s: Error on creating debugfs on PHB#%x\n", 3309 pr_warn("%s: Error on creating debugfs on PHB#%x\n",
3297 __func__, hose->global_number); 3310 __func__, hose->global_number);
3298 continue; 3311 continue;
3299 } 3312 }
@@ -3774,6 +3787,13 @@ static const struct pci_controller_ops pnv_npu_ioda_controller_ops = {
3774 .shutdown = pnv_pci_ioda_shutdown, 3787 .shutdown = pnv_pci_ioda_shutdown,
3775}; 3788};
3776 3789
3790static const struct pci_controller_ops pnv_npu_ocapi_ioda_controller_ops = {
3791 .enable_device_hook = pnv_pci_enable_device_hook,
3792 .window_alignment = pnv_pci_window_alignment,
3793 .reset_secondary_bus = pnv_pci_reset_secondary_bus,
3794 .shutdown = pnv_pci_ioda_shutdown,
3795};
3796
3777#ifdef CONFIG_CXL_BASE 3797#ifdef CONFIG_CXL_BASE
3778const struct pci_controller_ops pnv_cxl_cx4_ioda_controller_ops = { 3798const struct pci_controller_ops pnv_cxl_cx4_ioda_controller_ops = {
3779 .dma_dev_setup = pnv_pci_dma_dev_setup, 3799 .dma_dev_setup = pnv_pci_dma_dev_setup,
@@ -4007,9 +4027,14 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
4007 */ 4027 */
4008 ppc_md.pcibios_fixup = pnv_pci_ioda_fixup; 4028 ppc_md.pcibios_fixup = pnv_pci_ioda_fixup;
4009 4029
4010 if (phb->type == PNV_PHB_NPU) { 4030 switch (phb->type) {
4031 case PNV_PHB_NPU_NVLINK:
4011 hose->controller_ops = pnv_npu_ioda_controller_ops; 4032 hose->controller_ops = pnv_npu_ioda_controller_ops;
4012 } else { 4033 break;
4034 case PNV_PHB_NPU_OCAPI:
4035 hose->controller_ops = pnv_npu_ocapi_ioda_controller_ops;
4036 break;
4037 default:
4013 phb->dma_dev_setup = pnv_pci_ioda_dma_dev_setup; 4038 phb->dma_dev_setup = pnv_pci_ioda_dma_dev_setup;
4014 hose->controller_ops = pnv_pci_ioda_controller_ops; 4039 hose->controller_ops = pnv_pci_ioda_controller_ops;
4015 } 4040 }
@@ -4019,6 +4044,8 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
4019#ifdef CONFIG_PCI_IOV 4044#ifdef CONFIG_PCI_IOV
4020 ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov_resources; 4045 ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov_resources;
4021 ppc_md.pcibios_iov_resource_alignment = pnv_pci_iov_resource_alignment; 4046 ppc_md.pcibios_iov_resource_alignment = pnv_pci_iov_resource_alignment;
4047 ppc_md.pcibios_sriov_enable = pnv_pcibios_sriov_enable;
4048 ppc_md.pcibios_sriov_disable = pnv_pcibios_sriov_disable;
4022#endif 4049#endif
4023 4050
4024 pci_add_flags(PCI_REASSIGN_ALL_RSRC); 4051 pci_add_flags(PCI_REASSIGN_ALL_RSRC);
@@ -4026,15 +4053,16 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
4026 /* Reset IODA tables to a clean state */ 4053 /* Reset IODA tables to a clean state */
4027 rc = opal_pci_reset(phb_id, OPAL_RESET_PCI_IODA_TABLE, OPAL_ASSERT_RESET); 4054 rc = opal_pci_reset(phb_id, OPAL_RESET_PCI_IODA_TABLE, OPAL_ASSERT_RESET);
4028 if (rc) 4055 if (rc)
4029 pr_warning(" OPAL Error %ld performing IODA table reset !\n", rc); 4056 pr_warn(" OPAL Error %ld performing IODA table reset !\n", rc);
4030 4057
4031 /* 4058 /*
4032 * If we're running in kdump kernel, the previous kernel never 4059 * If we're running in kdump kernel, the previous kernel never
4033 * shutdown PCI devices correctly. We already got IODA table 4060 * shutdown PCI devices correctly. We already got IODA table
4034 * cleaned out. So we have to issue PHB reset to stop all PCI 4061 * cleaned out. So we have to issue PHB reset to stop all PCI
4035 * transactions from previous kernel. 4062 * transactions from previous kernel. The ppc_pci_reset_phbs
4063 * kernel parameter will force this reset too.
4036 */ 4064 */
4037 if (is_kdump_kernel()) { 4065 if (is_kdump_kernel() || pci_reset_phbs) {
4038 pr_info(" Issue PHB reset ...\n"); 4066 pr_info(" Issue PHB reset ...\n");
4039 pnv_eeh_phb_reset(hose, EEH_RESET_FUNDAMENTAL); 4067 pnv_eeh_phb_reset(hose, EEH_RESET_FUNDAMENTAL);
4040 pnv_eeh_phb_reset(hose, EEH_RESET_DEACTIVATE); 4068 pnv_eeh_phb_reset(hose, EEH_RESET_DEACTIVATE);
@@ -4052,8 +4080,26 @@ void __init pnv_pci_init_ioda2_phb(struct device_node *np)
4052 4080
4053void __init pnv_pci_init_npu_phb(struct device_node *np) 4081void __init pnv_pci_init_npu_phb(struct device_node *np)
4054{ 4082{
4055 pnv_pci_init_ioda_phb(np, 0, PNV_PHB_NPU); 4083 pnv_pci_init_ioda_phb(np, 0, PNV_PHB_NPU_NVLINK);
4084}
4085
4086void __init pnv_pci_init_npu2_opencapi_phb(struct device_node *np)
4087{
4088 pnv_pci_init_ioda_phb(np, 0, PNV_PHB_NPU_OCAPI);
4089}
4090
4091static void pnv_npu2_opencapi_cfg_size_fixup(struct pci_dev *dev)
4092{
4093 struct pci_controller *hose = pci_bus_to_host(dev->bus);
4094 struct pnv_phb *phb = hose->private_data;
4095
4096 if (!machine_is(powernv))
4097 return;
4098
4099 if (phb->type == PNV_PHB_NPU_OCAPI)
4100 dev->cfg_size = PCI_CFG_SPACE_EXP_SIZE;
4056} 4101}
4102DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, pnv_npu2_opencapi_cfg_size_fixup);
4057 4103
4058void __init pnv_pci_init_ioda_hub(struct device_node *np) 4104void __init pnv_pci_init_ioda_hub(struct device_node *np)
4059{ 4105{
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index 5422f4a6317c..69d102cbf48f 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -1142,6 +1142,10 @@ void __init pnv_pci_init(void)
1142 for_each_compatible_node(np, NULL, "ibm,ioda2-npu2-phb") 1142 for_each_compatible_node(np, NULL, "ibm,ioda2-npu2-phb")
1143 pnv_pci_init_npu_phb(np); 1143 pnv_pci_init_npu_phb(np);
1144 1144
1145 /* Look for NPU2 OpenCAPI PHBs */
1146 for_each_compatible_node(np, NULL, "ibm,ioda2-npu2-opencapi-phb")
1147 pnv_pci_init_npu2_opencapi_phb(np);
1148
1145 /* Configure IOMMU DMA hooks */ 1149 /* Configure IOMMU DMA hooks */
1146 set_pci_dma_ops(&dma_iommu_ops); 1150 set_pci_dma_ops(&dma_iommu_ops);
1147} 1151}
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
index b772d7473896..eada4b6068cb 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -12,9 +12,10 @@ struct pci_dn;
12#define NV_NMMU_ATSD_REGS 8 12#define NV_NMMU_ATSD_REGS 8
13 13
14enum pnv_phb_type { 14enum pnv_phb_type {
15 PNV_PHB_IODA1 = 0, 15 PNV_PHB_IODA1 = 0,
16 PNV_PHB_IODA2 = 1, 16 PNV_PHB_IODA2 = 1,
17 PNV_PHB_NPU = 2, 17 PNV_PHB_NPU_NVLINK = 2,
18 PNV_PHB_NPU_OCAPI = 3,
18}; 19};
19 20
20/* Precise PHB model for error management */ 21/* Precise PHB model for error management */
@@ -227,6 +228,7 @@ extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
227extern void pnv_pci_init_ioda_hub(struct device_node *np); 228extern void pnv_pci_init_ioda_hub(struct device_node *np);
228extern void pnv_pci_init_ioda2_phb(struct device_node *np); 229extern void pnv_pci_init_ioda2_phb(struct device_node *np);
229extern void pnv_pci_init_npu_phb(struct device_node *np); 230extern void pnv_pci_init_npu_phb(struct device_node *np);
231extern void pnv_pci_init_npu2_opencapi_phb(struct device_node *np);
230extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev); 232extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev);
231extern int pnv_eeh_phb_reset(struct pci_controller *hose, int option); 233extern int pnv_eeh_phb_reset(struct pci_controller *hose, int option);
232 234
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c
index ba030669eca1..9664c8461f03 100644
--- a/arch/powerpc/platforms/powernv/smp.c
+++ b/arch/powerpc/platforms/powernv/smp.c
@@ -37,6 +37,8 @@
37#include <asm/kvm_ppc.h> 37#include <asm/kvm_ppc.h>
38#include <asm/ppc-opcode.h> 38#include <asm/ppc-opcode.h>
39#include <asm/cpuidle.h> 39#include <asm/cpuidle.h>
40#include <asm/kexec.h>
41#include <asm/reg.h>
40 42
41#include "powernv.h" 43#include "powernv.h"
42 44
@@ -209,9 +211,32 @@ static void pnv_smp_cpu_kill_self(void)
209 } else if ((srr1 & wmask) == SRR1_WAKEHDBELL) { 211 } else if ((srr1 & wmask) == SRR1_WAKEHDBELL) {
210 unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER); 212 unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);
211 asm volatile(PPC_MSGCLR(%0) : : "r" (msg)); 213 asm volatile(PPC_MSGCLR(%0) : : "r" (msg));
214 } else if ((srr1 & wmask) == SRR1_WAKERESET) {
215 irq_set_pending_from_srr1(srr1);
216 /* Does not return */
212 } 217 }
218
213 smp_mb(); 219 smp_mb();
214 220
221 /*
222 * For kdump kernels, we process the ipi and jump to
223 * crash_ipi_callback
224 */
225 if (kdump_in_progress()) {
226 /*
227 * If we got to this point, we've not used
228 * NMI's, otherwise we would have gone
229 * via the SRR1_WAKERESET path. We are
230 * using regular IPI's for waking up offline
231 * threads.
232 */
233 struct pt_regs regs;
234
235 ppc_save_regs(&regs);
236 crash_ipi_callback(&regs);
237 /* Does not return */
238 }
239
215 if (cpu_core_split_required()) 240 if (cpu_core_split_required())
216 continue; 241 continue;
217 242
@@ -371,5 +396,8 @@ void __init pnv_smp_init(void)
371 396
372#ifdef CONFIG_HOTPLUG_CPU 397#ifdef CONFIG_HOTPLUG_CPU
373 ppc_md.cpu_die = pnv_smp_cpu_kill_self; 398 ppc_md.cpu_die = pnv_smp_cpu_kill_self;
399#ifdef CONFIG_KEXEC_CORE
400 crash_wake_offline = 1;
401#endif
374#endif 402#endif
375} 403}
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c
index e48462447ff0..e7075aaff1bb 100644
--- a/arch/powerpc/platforms/ps3/device-init.c
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -663,8 +663,8 @@ static void ps3_find_and_add_device(u64 bus_id, u64 dev_id)
663 if (rem) 663 if (rem)
664 break; 664 break;
665 } 665 }
666 pr_warning("%s:%u: device %llu:%llu not found\n", __func__, __LINE__, 666 pr_warn("%s:%u: device %llu:%llu not found\n",
667 bus_id, dev_id); 667 __func__, __LINE__, bus_id, dev_id);
668 return; 668 return;
669 669
670found: 670found:
@@ -859,11 +859,9 @@ static int ps3_probe_thread(void *data)
859 859
860 if (notify_event->event_type != notify_region_probe || 860 if (notify_event->event_type != notify_region_probe ||
861 notify_event->bus_id != dev.sbd.bus_id) { 861 notify_event->bus_id != dev.sbd.bus_id) {
862 pr_warning("%s:%u: bad notify_event: event %llu, " 862 pr_warn("%s:%u: bad notify_event: event %llu, dev_id %llu, dev_type %llu\n",
863 "dev_id %llu, dev_type %llu\n", 863 __func__, __LINE__, notify_event->event_type,
864 __func__, __LINE__, notify_event->event_type, 864 notify_event->dev_id, notify_event->dev_type);
865 notify_event->dev_id,
866 notify_event->dev_type);
867 continue; 865 continue;
868 } 866 }
869 867
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index b0f34663b1ae..7f870ec29daf 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -607,8 +607,8 @@ static int dma_ioc0_map_pages(struct ps3_dma_region *r, unsigned long phys_addr,
607 r->ioid, 607 r->ioid,
608 iopte_flag); 608 iopte_flag);
609 if (result) { 609 if (result) {
610 pr_warning("%s:%d: lv1_put_iopte failed: %s\n", 610 pr_warn("%s:%d: lv1_put_iopte failed: %s\n",
611 __func__, __LINE__, ps3_result(result)); 611 __func__, __LINE__, ps3_result(result));
612 goto fail_map; 612 goto fail_map;
613 } 613 }
614 DBG("%s: pg=%d bus=%#lx, lpar=%#lx, ioid=%#x\n", __func__, 614 DBG("%s: pg=%d bus=%#lx, lpar=%#lx, ioid=%#x\n", __func__,
diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c
index 3db53e8aff92..cdbfc5cfd6f3 100644
--- a/arch/powerpc/platforms/ps3/os-area.c
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -699,7 +699,7 @@ static void os_area_queue_work_handler(struct work_struct *work)
699 699
700 error = update_flash_db(); 700 error = update_flash_db();
701 if (error) 701 if (error)
702 pr_warning("%s: Could not update FLASH ROM\n", __func__); 702 pr_warn("%s: Could not update FLASH ROM\n", __func__);
703 703
704 pr_debug(" <- %s:%d\n", __func__, __LINE__); 704 pr_debug(" <- %s:%d\n", __func__, __LINE__);
705} 705}
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 6244bc849469..77a37520068d 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -113,6 +113,7 @@ static void ps3_panic(char *str)
113 printk(" System does not reboot automatically.\n"); 113 printk(" System does not reboot automatically.\n");
114 printk(" Please press POWER button.\n"); 114 printk(" Please press POWER button.\n");
115 printk("\n"); 115 printk("\n");
116 panic_flush_kmsg_end();
116 117
117 while(1) 118 while(1)
118 lv1_pause(1); 119 lv1_pause(1);
diff --git a/arch/powerpc/platforms/pseries/cmm.c b/arch/powerpc/platforms/pseries/cmm.c
index 560aefde06c0..25427a48feae 100644
--- a/arch/powerpc/platforms/pseries/cmm.c
+++ b/arch/powerpc/platforms/pseries/cmm.c
@@ -72,20 +72,20 @@ MODULE_DESCRIPTION("IBM System p Collaborative Memory Manager");
72MODULE_LICENSE("GPL"); 72MODULE_LICENSE("GPL");
73MODULE_VERSION(CMM_DRIVER_VERSION); 73MODULE_VERSION(CMM_DRIVER_VERSION);
74 74
75module_param_named(delay, delay, uint, S_IRUGO | S_IWUSR); 75module_param_named(delay, delay, uint, 0644);
76MODULE_PARM_DESC(delay, "Delay (in seconds) between polls to query hypervisor paging requests. " 76MODULE_PARM_DESC(delay, "Delay (in seconds) between polls to query hypervisor paging requests. "
77 "[Default=" __stringify(CMM_DEFAULT_DELAY) "]"); 77 "[Default=" __stringify(CMM_DEFAULT_DELAY) "]");
78module_param_named(hotplug_delay, hotplug_delay, uint, S_IRUGO | S_IWUSR); 78module_param_named(hotplug_delay, hotplug_delay, uint, 0644);
79MODULE_PARM_DESC(hotplug_delay, "Delay (in seconds) after memory hotplug remove " 79MODULE_PARM_DESC(hotplug_delay, "Delay (in seconds) after memory hotplug remove "
80 "before loaning resumes. " 80 "before loaning resumes. "
81 "[Default=" __stringify(CMM_HOTPLUG_DELAY) "]"); 81 "[Default=" __stringify(CMM_HOTPLUG_DELAY) "]");
82module_param_named(oom_kb, oom_kb, uint, S_IRUGO | S_IWUSR); 82module_param_named(oom_kb, oom_kb, uint, 0644);
83MODULE_PARM_DESC(oom_kb, "Amount of memory in kb to free on OOM. " 83MODULE_PARM_DESC(oom_kb, "Amount of memory in kb to free on OOM. "
84 "[Default=" __stringify(CMM_OOM_KB) "]"); 84 "[Default=" __stringify(CMM_OOM_KB) "]");
85module_param_named(min_mem_mb, min_mem_mb, ulong, S_IRUGO | S_IWUSR); 85module_param_named(min_mem_mb, min_mem_mb, ulong, 0644);
86MODULE_PARM_DESC(min_mem_mb, "Minimum amount of memory (in MB) to not balloon. " 86MODULE_PARM_DESC(min_mem_mb, "Minimum amount of memory (in MB) to not balloon. "
87 "[Default=" __stringify(CMM_MIN_MEM_MB) "]"); 87 "[Default=" __stringify(CMM_MIN_MEM_MB) "]");
88module_param_named(debug, cmm_debug, uint, S_IRUGO | S_IWUSR); 88module_param_named(debug, cmm_debug, uint, 0644);
89MODULE_PARM_DESC(debug, "Enable module debugging logging. Set to 1 to enable. " 89MODULE_PARM_DESC(debug, "Enable module debugging logging. Set to 1 to enable. "
90 "[Default=" __stringify(CMM_DEBUG) "]"); 90 "[Default=" __stringify(CMM_DEBUG) "]");
91 91
@@ -385,7 +385,7 @@ static int cmm_thread(void *dummy)
385 { \ 385 { \
386 return sprintf(buf, format, ##args); \ 386 return sprintf(buf, format, ##args); \
387 } \ 387 } \
388 static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) 388 static DEVICE_ATTR(name, 0444, show_##name, NULL)
389 389
390CMM_SHOW(loaned_kb, "%lu\n", PAGES2KB(loaned_pages)); 390CMM_SHOW(loaned_kb, "%lu\n", PAGES2KB(loaned_pages));
391CMM_SHOW(loaned_target_kb, "%lu\n", PAGES2KB(loaned_pages_target)); 391CMM_SHOW(loaned_target_kb, "%lu\n", PAGES2KB(loaned_pages_target));
@@ -411,7 +411,7 @@ static ssize_t store_oom_pages(struct device *dev,
411 return count; 411 return count;
412} 412}
413 413
414static DEVICE_ATTR(oom_freed_kb, S_IWUSR | S_IRUGO, 414static DEVICE_ATTR(oom_freed_kb, 0644,
415 show_oom_pages, store_oom_pages); 415 show_oom_pages, store_oom_pages);
416 416
417static struct device_attribute *cmm_attrs[] = { 417static struct device_attribute *cmm_attrs[] = {
@@ -765,7 +765,7 @@ static int cmm_set_disable(const char *val, const struct kernel_param *kp)
765} 765}
766 766
767module_param_call(disable, cmm_set_disable, param_get_uint, 767module_param_call(disable, cmm_set_disable, param_get_uint,
768 &cmm_disabled, S_IRUGO | S_IWUSR); 768 &cmm_disabled, 0644);
769MODULE_PARM_DESC(disable, "Disable CMM. Set to 1 to disable. " 769MODULE_PARM_DESC(disable, "Disable CMM. Set to 1 to disable. "
770 "[Default=" __stringify(CMM_DISABLE) "]"); 770 "[Default=" __stringify(CMM_DISABLE) "]");
771 771
diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
index 6b812ad990e4..823cb27efa8b 100644
--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
@@ -55,6 +55,43 @@ static int ibm_get_config_addr_info;
55static int ibm_get_config_addr_info2; 55static int ibm_get_config_addr_info2;
56static int ibm_configure_pe; 56static int ibm_configure_pe;
57 57
58#ifdef CONFIG_PCI_IOV
59void pseries_pcibios_bus_add_device(struct pci_dev *pdev)
60{
61 struct pci_dn *pdn = pci_get_pdn(pdev);
62 struct pci_dn *physfn_pdn;
63 struct eeh_dev *edev;
64
65 if (!pdev->is_virtfn)
66 return;
67
68 pdn->device_id = pdev->device;
69 pdn->vendor_id = pdev->vendor;
70 pdn->class_code = pdev->class;
71 /*
72 * Last allow unfreeze return code used for retrieval
73 * by user space in eeh-sysfs to show the last command
74 * completion from platform.
75 */
76 pdn->last_allow_rc = 0;
77 physfn_pdn = pci_get_pdn(pdev->physfn);
78 pdn->pe_number = physfn_pdn->pe_num_map[pdn->vf_index];
79 edev = pdn_to_eeh_dev(pdn);
80
81 /*
82 * The following operations will fail if VF's sysfs files
83 * aren't created or its resources aren't finalized.
84 */
85 eeh_add_device_early(pdn);
86 eeh_add_device_late(pdev);
87 edev->pe_config_addr = (pdn->busno << 16) | (pdn->devfn << 8);
88 eeh_rmv_from_parent_pe(edev); /* Remove as it is adding to bus pe */
89 eeh_add_to_parent_pe(edev); /* Add as VF PE type */
90 eeh_sysfs_add_device(pdev);
91
92}
93#endif
94
58/* 95/*
59 * Buffer for reporting slot-error-detail rtas calls. Its here 96 * Buffer for reporting slot-error-detail rtas calls. Its here
60 * in BSS, and not dynamically alloced, so that it ends up in 97 * in BSS, and not dynamically alloced, so that it ends up in
@@ -120,6 +157,11 @@ static int pseries_eeh_init(void)
120 /* Set EEH probe mode */ 157 /* Set EEH probe mode */
121 eeh_add_flag(EEH_PROBE_MODE_DEVTREE | EEH_ENABLE_IO_FOR_LOG); 158 eeh_add_flag(EEH_PROBE_MODE_DEVTREE | EEH_ENABLE_IO_FOR_LOG);
122 159
160#ifdef CONFIG_PCI_IOV
161 /* Set EEH machine dependent code */
162 ppc_md.pcibios_bus_add_device = pseries_pcibios_bus_add_device;
163#endif
164
123 return 0; 165 return 0;
124} 166}
125 167
@@ -684,6 +726,121 @@ static int pseries_eeh_write_config(struct pci_dn *pdn, int where, int size, u32
684 return rtas_write_config(pdn, where, size, val); 726 return rtas_write_config(pdn, where, size, val);
685} 727}
686 728
729static int pseries_eeh_restore_config(struct pci_dn *pdn)
730{
731 struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
732 s64 ret = 0;
733
734 if (!edev)
735 return -EEXIST;
736
737 /*
738 * FIXME: The MPS, error routing rules, timeout setting are worthy
739 * to be exported by firmware in extendible way.
740 */
741 if (edev->physfn)
742 ret = eeh_restore_vf_config(pdn);
743
744 if (ret) {
745 pr_warn("%s: Can't reinit PCI dev 0x%x (%lld)\n",
746 __func__, edev->pe_config_addr, ret);
747 return -EIO;
748 }
749
750 return ret;
751}
752
753#ifdef CONFIG_PCI_IOV
754int pseries_send_allow_unfreeze(struct pci_dn *pdn,
755 u16 *vf_pe_array, int cur_vfs)
756{
757 int rc;
758 int ibm_allow_unfreeze = rtas_token("ibm,open-sriov-allow-unfreeze");
759 unsigned long buid, addr;
760
761 addr = rtas_config_addr(pdn->busno, pdn->devfn, 0);
762 buid = pdn->phb->buid;
763 spin_lock(&rtas_data_buf_lock);
764 memcpy(rtas_data_buf, vf_pe_array, RTAS_DATA_BUF_SIZE);
765 rc = rtas_call(ibm_allow_unfreeze, 5, 1, NULL,
766 addr,
767 BUID_HI(buid),
768 BUID_LO(buid),
769 rtas_data_buf, cur_vfs * sizeof(u16));
770 spin_unlock(&rtas_data_buf_lock);
771 if (rc)
772 pr_warn("%s: Failed to allow unfreeze for PHB#%x-PE#%lx, rc=%x\n",
773 __func__,
774 pdn->phb->global_number, addr, rc);
775 return rc;
776}
777
778static int pseries_call_allow_unfreeze(struct eeh_dev *edev)
779{
780 struct pci_dn *pdn, *tmp, *parent, *physfn_pdn;
781 int cur_vfs = 0, rc = 0, vf_index, bus, devfn;
782 u16 *vf_pe_array;
783
784 vf_pe_array = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
785 if (!vf_pe_array)
786 return -ENOMEM;
787 if (pci_num_vf(edev->physfn ? edev->physfn : edev->pdev)) {
788 if (edev->pdev->is_physfn) {
789 cur_vfs = pci_num_vf(edev->pdev);
790 pdn = eeh_dev_to_pdn(edev);
791 parent = pdn->parent;
792 for (vf_index = 0; vf_index < cur_vfs; vf_index++)
793 vf_pe_array[vf_index] =
794 cpu_to_be16(pdn->pe_num_map[vf_index]);
795 rc = pseries_send_allow_unfreeze(pdn, vf_pe_array,
796 cur_vfs);
797 pdn->last_allow_rc = rc;
798 for (vf_index = 0; vf_index < cur_vfs; vf_index++) {
799 list_for_each_entry_safe(pdn, tmp,
800 &parent->child_list,
801 list) {
802 bus = pci_iov_virtfn_bus(edev->pdev,
803 vf_index);
804 devfn = pci_iov_virtfn_devfn(edev->pdev,
805 vf_index);
806 if (pdn->busno != bus ||
807 pdn->devfn != devfn)
808 continue;
809 pdn->last_allow_rc = rc;
810 }
811 }
812 } else {
813 pdn = pci_get_pdn(edev->pdev);
814 vf_pe_array[0] = cpu_to_be16(pdn->pe_number);
815 physfn_pdn = pci_get_pdn(edev->physfn);
816 rc = pseries_send_allow_unfreeze(physfn_pdn,
817 vf_pe_array, 1);
818 pdn->last_allow_rc = rc;
819 }
820 }
821
822 kfree(vf_pe_array);
823 return rc;
824}
825
826static int pseries_notify_resume(struct pci_dn *pdn)
827{
828 struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
829
830 if (!edev)
831 return -EEXIST;
832
833 if (rtas_token("ibm,open-sriov-allow-unfreeze")
834 == RTAS_UNKNOWN_SERVICE)
835 return -EINVAL;
836
837 if (edev->pdev->is_physfn || edev->pdev->is_virtfn)
838 return pseries_call_allow_unfreeze(edev);
839
840 return 0;
841}
842#endif
843
687static struct eeh_ops pseries_eeh_ops = { 844static struct eeh_ops pseries_eeh_ops = {
688 .name = "pseries", 845 .name = "pseries",
689 .init = pseries_eeh_init, 846 .init = pseries_eeh_init,
@@ -699,7 +856,10 @@ static struct eeh_ops pseries_eeh_ops = {
699 .read_config = pseries_eeh_read_config, 856 .read_config = pseries_eeh_read_config,
700 .write_config = pseries_eeh_write_config, 857 .write_config = pseries_eeh_write_config,
701 .next_error = NULL, 858 .next_error = NULL,
702 .restore_config = NULL 859 .restore_config = pseries_eeh_restore_config,
860#ifdef CONFIG_PCI_IOV
861 .notify_resume = pseries_notify_resume
862#endif
703}; 863};
704 864
705/** 865/**
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
index 63cc82ad58ac..a3bbeb43689e 100644
--- a/arch/powerpc/platforms/pseries/firmware.c
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -114,6 +114,8 @@ static __initdata struct vec5_fw_feature
114vec5_fw_features_table[] = { 114vec5_fw_features_table[] = {
115 {FW_FEATURE_TYPE1_AFFINITY, OV5_TYPE1_AFFINITY}, 115 {FW_FEATURE_TYPE1_AFFINITY, OV5_TYPE1_AFFINITY},
116 {FW_FEATURE_PRRN, OV5_PRRN}, 116 {FW_FEATURE_PRRN, OV5_PRRN},
117 {FW_FEATURE_DRMEM_V2, OV5_DRMEM_V2},
118 {FW_FEATURE_DRC_INFO, OV5_DRC_INFO},
117}; 119};
118 120
119static void __init fw_vec5_feature_init(const char *vec5, unsigned long len) 121static void __init fw_vec5_feature_init(const char *vec5, unsigned long len)
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index a7d14aa7bb7c..dceb51454d8d 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -340,6 +340,8 @@ static void pseries_remove_processor(struct device_node *np)
340 cpu_maps_update_done(); 340 cpu_maps_update_done();
341} 341}
342 342
343extern int find_and_online_cpu_nid(int cpu);
344
343static int dlpar_online_cpu(struct device_node *dn) 345static int dlpar_online_cpu(struct device_node *dn)
344{ 346{
345 int rc = 0; 347 int rc = 0;
@@ -364,6 +366,7 @@ static int dlpar_online_cpu(struct device_node *dn)
364 != CPU_STATE_OFFLINE); 366 != CPU_STATE_OFFLINE);
365 cpu_maps_update_done(); 367 cpu_maps_update_done();
366 timed_topology_update(1); 368 timed_topology_update(1);
369 find_and_online_cpu_nid(cpu);
367 rc = device_online(get_cpu_device(cpu)); 370 rc = device_online(get_cpu_device(cpu));
368 if (rc) 371 if (rc)
369 goto out; 372 goto out;
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 1d48ab424bd9..c1578f54c626 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -23,6 +23,7 @@
23#include <asm/prom.h> 23#include <asm/prom.h>
24#include <asm/sparsemem.h> 24#include <asm/sparsemem.h>
25#include <asm/fadump.h> 25#include <asm/fadump.h>
26#include <asm/drmem.h>
26#include "pseries.h" 27#include "pseries.h"
27 28
28static bool rtas_hp_event; 29static bool rtas_hp_event;
@@ -100,100 +101,6 @@ static struct property *dlpar_clone_property(struct property *prop,
100 return new_prop; 101 return new_prop;
101} 102}
102 103
103static struct property *dlpar_clone_drconf_property(struct device_node *dn)
104{
105 struct property *prop, *new_prop;
106 struct of_drconf_cell *lmbs;
107 u32 num_lmbs, *p;
108 int i;
109
110 prop = of_find_property(dn, "ibm,dynamic-memory", NULL);
111 if (!prop)
112 return NULL;
113
114 new_prop = dlpar_clone_property(prop, prop->length);
115 if (!new_prop)
116 return NULL;
117
118 /* Convert the property to cpu endian-ness */
119 p = new_prop->value;
120 *p = be32_to_cpu(*p);
121
122 num_lmbs = *p++;
123 lmbs = (struct of_drconf_cell *)p;
124
125 for (i = 0; i < num_lmbs; i++) {
126 lmbs[i].base_addr = be64_to_cpu(lmbs[i].base_addr);
127 lmbs[i].drc_index = be32_to_cpu(lmbs[i].drc_index);
128 lmbs[i].aa_index = be32_to_cpu(lmbs[i].aa_index);
129 lmbs[i].flags = be32_to_cpu(lmbs[i].flags);
130 }
131
132 return new_prop;
133}
134
135static void dlpar_update_drconf_property(struct device_node *dn,
136 struct property *prop)
137{
138 struct of_drconf_cell *lmbs;
139 u32 num_lmbs, *p;
140 int i;
141
142 /* Convert the property back to BE */
143 p = prop->value;
144 num_lmbs = *p;
145 *p = cpu_to_be32(*p);
146 p++;
147
148 lmbs = (struct of_drconf_cell *)p;
149 for (i = 0; i < num_lmbs; i++) {
150 lmbs[i].base_addr = cpu_to_be64(lmbs[i].base_addr);
151 lmbs[i].drc_index = cpu_to_be32(lmbs[i].drc_index);
152 lmbs[i].aa_index = cpu_to_be32(lmbs[i].aa_index);
153 lmbs[i].flags = cpu_to_be32(lmbs[i].flags);
154 }
155
156 rtas_hp_event = true;
157 of_update_property(dn, prop);
158 rtas_hp_event = false;
159}
160
161static int dlpar_update_device_tree_lmb(struct of_drconf_cell *lmb)
162{
163 struct device_node *dn;
164 struct property *prop;
165 struct of_drconf_cell *lmbs;
166 u32 *p, num_lmbs;
167 int i;
168
169 dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
170 if (!dn)
171 return -ENODEV;
172
173 prop = dlpar_clone_drconf_property(dn);
174 if (!prop) {
175 of_node_put(dn);
176 return -ENODEV;
177 }
178
179 p = prop->value;
180 num_lmbs = *p++;
181 lmbs = (struct of_drconf_cell *)p;
182
183 for (i = 0; i < num_lmbs; i++) {
184 if (lmbs[i].drc_index == lmb->drc_index) {
185 lmbs[i].flags = lmb->flags;
186 lmbs[i].aa_index = lmb->aa_index;
187
188 dlpar_update_drconf_property(dn, prop);
189 break;
190 }
191 }
192
193 of_node_put(dn);
194 return 0;
195}
196
197static u32 find_aa_index(struct device_node *dr_node, 104static u32 find_aa_index(struct device_node *dr_node,
198 struct property *ala_prop, const u32 *lmb_assoc) 105 struct property *ala_prop, const u32 *lmb_assoc)
199{ 106{
@@ -256,7 +163,7 @@ static u32 find_aa_index(struct device_node *dr_node,
256 return aa_index; 163 return aa_index;
257} 164}
258 165
259static u32 lookup_lmb_associativity_index(struct of_drconf_cell *lmb) 166static u32 lookup_lmb_associativity_index(struct drmem_lmb *lmb)
260{ 167{
261 struct device_node *parent, *lmb_node, *dr_node; 168 struct device_node *parent, *lmb_node, *dr_node;
262 struct property *ala_prop; 169 struct property *ala_prop;
@@ -299,9 +206,9 @@ static u32 lookup_lmb_associativity_index(struct of_drconf_cell *lmb)
299 return aa_index; 206 return aa_index;
300} 207}
301 208
302static int dlpar_add_device_tree_lmb(struct of_drconf_cell *lmb) 209static int dlpar_add_device_tree_lmb(struct drmem_lmb *lmb)
303{ 210{
304 int aa_index; 211 int rc, aa_index;
305 212
306 lmb->flags |= DRCONF_MEM_ASSIGNED; 213 lmb->flags |= DRCONF_MEM_ASSIGNED;
307 214
@@ -313,17 +220,29 @@ static int dlpar_add_device_tree_lmb(struct of_drconf_cell *lmb)
313 } 220 }
314 221
315 lmb->aa_index = aa_index; 222 lmb->aa_index = aa_index;
316 return dlpar_update_device_tree_lmb(lmb); 223
224 rtas_hp_event = true;
225 rc = drmem_update_dt();
226 rtas_hp_event = false;
227
228 return rc;
317} 229}
318 230
319static int dlpar_remove_device_tree_lmb(struct of_drconf_cell *lmb) 231static int dlpar_remove_device_tree_lmb(struct drmem_lmb *lmb)
320{ 232{
233 int rc;
234
321 lmb->flags &= ~DRCONF_MEM_ASSIGNED; 235 lmb->flags &= ~DRCONF_MEM_ASSIGNED;
322 lmb->aa_index = 0xffffffff; 236 lmb->aa_index = 0xffffffff;
323 return dlpar_update_device_tree_lmb(lmb); 237
238 rtas_hp_event = true;
239 rc = drmem_update_dt();
240 rtas_hp_event = false;
241
242 return rc;
324} 243}
325 244
326static struct memory_block *lmb_to_memblock(struct of_drconf_cell *lmb) 245static struct memory_block *lmb_to_memblock(struct drmem_lmb *lmb)
327{ 246{
328 unsigned long section_nr; 247 unsigned long section_nr;
329 struct mem_section *mem_sect; 248 struct mem_section *mem_sect;
@@ -336,7 +255,36 @@ static struct memory_block *lmb_to_memblock(struct of_drconf_cell *lmb)
336 return mem_block; 255 return mem_block;
337} 256}
338 257
339static int dlpar_change_lmb_state(struct of_drconf_cell *lmb, bool online) 258static int get_lmb_range(u32 drc_index, int n_lmbs,
259 struct drmem_lmb **start_lmb,
260 struct drmem_lmb **end_lmb)
261{
262 struct drmem_lmb *lmb, *start, *end;
263 struct drmem_lmb *last_lmb;
264
265 start = NULL;
266 for_each_drmem_lmb(lmb) {
267 if (lmb->drc_index == drc_index) {
268 start = lmb;
269 break;
270 }
271 }
272
273 if (!start)
274 return -EINVAL;
275
276 end = &start[n_lmbs - 1];
277
278 last_lmb = &drmem_info->lmbs[drmem_info->n_lmbs - 1];
279 if (end > last_lmb)
280 return -EINVAL;
281
282 *start_lmb = start;
283 *end_lmb = end;
284 return 0;
285}
286
287static int dlpar_change_lmb_state(struct drmem_lmb *lmb, bool online)
340{ 288{
341 struct memory_block *mem_block; 289 struct memory_block *mem_block;
342 int rc; 290 int rc;
@@ -357,13 +305,13 @@ static int dlpar_change_lmb_state(struct of_drconf_cell *lmb, bool online)
357 return rc; 305 return rc;
358} 306}
359 307
360static int dlpar_online_lmb(struct of_drconf_cell *lmb) 308static int dlpar_online_lmb(struct drmem_lmb *lmb)
361{ 309{
362 return dlpar_change_lmb_state(lmb, true); 310 return dlpar_change_lmb_state(lmb, true);
363} 311}
364 312
365#ifdef CONFIG_MEMORY_HOTREMOVE 313#ifdef CONFIG_MEMORY_HOTREMOVE
366static int dlpar_offline_lmb(struct of_drconf_cell *lmb) 314static int dlpar_offline_lmb(struct drmem_lmb *lmb)
367{ 315{
368 return dlpar_change_lmb_state(lmb, false); 316 return dlpar_change_lmb_state(lmb, false);
369} 317}
@@ -426,7 +374,7 @@ static int pseries_remove_mem_node(struct device_node *np)
426 return 0; 374 return 0;
427} 375}
428 376
429static bool lmb_is_removable(struct of_drconf_cell *lmb) 377static bool lmb_is_removable(struct drmem_lmb *lmb)
430{ 378{
431 int i, scns_per_block; 379 int i, scns_per_block;
432 int rc = 1; 380 int rc = 1;
@@ -458,9 +406,9 @@ static bool lmb_is_removable(struct of_drconf_cell *lmb)
458 return rc ? true : false; 406 return rc ? true : false;
459} 407}
460 408
461static int dlpar_add_lmb(struct of_drconf_cell *); 409static int dlpar_add_lmb(struct drmem_lmb *);
462 410
463static int dlpar_remove_lmb(struct of_drconf_cell *lmb) 411static int dlpar_remove_lmb(struct drmem_lmb *lmb)
464{ 412{
465 unsigned long block_sz; 413 unsigned long block_sz;
466 int nid, rc; 414 int nid, rc;
@@ -484,28 +432,25 @@ static int dlpar_remove_lmb(struct of_drconf_cell *lmb)
484 return 0; 432 return 0;
485} 433}
486 434
487static int dlpar_memory_remove_by_count(u32 lmbs_to_remove, 435static int dlpar_memory_remove_by_count(u32 lmbs_to_remove)
488 struct property *prop)
489{ 436{
490 struct of_drconf_cell *lmbs; 437 struct drmem_lmb *lmb;
491 int lmbs_removed = 0; 438 int lmbs_removed = 0;
492 int lmbs_available = 0; 439 int lmbs_available = 0;
493 u32 num_lmbs, *p; 440 int rc;
494 int i, rc;
495 441
496 pr_info("Attempting to hot-remove %d LMB(s)\n", lmbs_to_remove); 442 pr_info("Attempting to hot-remove %d LMB(s)\n", lmbs_to_remove);
497 443
498 if (lmbs_to_remove == 0) 444 if (lmbs_to_remove == 0)
499 return -EINVAL; 445 return -EINVAL;
500 446
501 p = prop->value;
502 num_lmbs = *p++;
503 lmbs = (struct of_drconf_cell *)p;
504
505 /* Validate that there are enough LMBs to satisfy the request */ 447 /* Validate that there are enough LMBs to satisfy the request */
506 for (i = 0; i < num_lmbs; i++) { 448 for_each_drmem_lmb(lmb) {
507 if (lmb_is_removable(&lmbs[i])) 449 if (lmb_is_removable(lmb))
508 lmbs_available++; 450 lmbs_available++;
451
452 if (lmbs_available == lmbs_to_remove)
453 break;
509 } 454 }
510 455
511 if (lmbs_available < lmbs_to_remove) { 456 if (lmbs_available < lmbs_to_remove) {
@@ -514,45 +459,47 @@ static int dlpar_memory_remove_by_count(u32 lmbs_to_remove,
514 return -EINVAL; 459 return -EINVAL;
515 } 460 }
516 461
517 for (i = 0; i < num_lmbs && lmbs_removed < lmbs_to_remove; i++) { 462 for_each_drmem_lmb(lmb) {
518 rc = dlpar_remove_lmb(&lmbs[i]); 463 rc = dlpar_remove_lmb(lmb);
519 if (rc) 464 if (rc)
520 continue; 465 continue;
521 466
522 lmbs_removed++;
523
524 /* Mark this lmb so we can add it later if all of the 467 /* Mark this lmb so we can add it later if all of the
525 * requested LMBs cannot be removed. 468 * requested LMBs cannot be removed.
526 */ 469 */
527 lmbs[i].reserved = 1; 470 drmem_mark_lmb_reserved(lmb);
471
472 lmbs_removed++;
473 if (lmbs_removed == lmbs_to_remove)
474 break;
528 } 475 }
529 476
530 if (lmbs_removed != lmbs_to_remove) { 477 if (lmbs_removed != lmbs_to_remove) {
531 pr_err("Memory hot-remove failed, adding LMB's back\n"); 478 pr_err("Memory hot-remove failed, adding LMB's back\n");
532 479
533 for (i = 0; i < num_lmbs; i++) { 480 for_each_drmem_lmb(lmb) {
534 if (!lmbs[i].reserved) 481 if (!drmem_lmb_reserved(lmb))
535 continue; 482 continue;
536 483
537 rc = dlpar_add_lmb(&lmbs[i]); 484 rc = dlpar_add_lmb(lmb);
538 if (rc) 485 if (rc)
539 pr_err("Failed to add LMB back, drc index %x\n", 486 pr_err("Failed to add LMB back, drc index %x\n",
540 lmbs[i].drc_index); 487 lmb->drc_index);
541 488
542 lmbs[i].reserved = 0; 489 drmem_remove_lmb_reservation(lmb);
543 } 490 }
544 491
545 rc = -EINVAL; 492 rc = -EINVAL;
546 } else { 493 } else {
547 for (i = 0; i < num_lmbs; i++) { 494 for_each_drmem_lmb(lmb) {
548 if (!lmbs[i].reserved) 495 if (!drmem_lmb_reserved(lmb))
549 continue; 496 continue;
550 497
551 dlpar_release_drc(lmbs[i].drc_index); 498 dlpar_release_drc(lmb->drc_index);
552 pr_info("Memory at %llx was hot-removed\n", 499 pr_info("Memory at %llx was hot-removed\n",
553 lmbs[i].base_addr); 500 lmb->base_addr);
554 501
555 lmbs[i].reserved = 0; 502 drmem_remove_lmb_reservation(lmb);
556 } 503 }
557 rc = 0; 504 rc = 0;
558 } 505 }
@@ -560,26 +507,21 @@ static int dlpar_memory_remove_by_count(u32 lmbs_to_remove,
560 return rc; 507 return rc;
561} 508}
562 509
563static int dlpar_memory_remove_by_index(u32 drc_index, struct property *prop) 510static int dlpar_memory_remove_by_index(u32 drc_index)
564{ 511{
565 struct of_drconf_cell *lmbs; 512 struct drmem_lmb *lmb;
566 u32 num_lmbs, *p;
567 int lmb_found; 513 int lmb_found;
568 int i, rc; 514 int rc;
569 515
570 pr_info("Attempting to hot-remove LMB, drc index %x\n", drc_index); 516 pr_info("Attempting to hot-remove LMB, drc index %x\n", drc_index);
571 517
572 p = prop->value;
573 num_lmbs = *p++;
574 lmbs = (struct of_drconf_cell *)p;
575
576 lmb_found = 0; 518 lmb_found = 0;
577 for (i = 0; i < num_lmbs; i++) { 519 for_each_drmem_lmb(lmb) {
578 if (lmbs[i].drc_index == drc_index) { 520 if (lmb->drc_index == drc_index) {
579 lmb_found = 1; 521 lmb_found = 1;
580 rc = dlpar_remove_lmb(&lmbs[i]); 522 rc = dlpar_remove_lmb(lmb);
581 if (!rc) 523 if (!rc)
582 dlpar_release_drc(lmbs[i].drc_index); 524 dlpar_release_drc(lmb->drc_index);
583 525
584 break; 526 break;
585 } 527 }
@@ -590,35 +532,30 @@ static int dlpar_memory_remove_by_index(u32 drc_index, struct property *prop)
590 532
591 if (rc) 533 if (rc)
592 pr_info("Failed to hot-remove memory at %llx\n", 534 pr_info("Failed to hot-remove memory at %llx\n",
593 lmbs[i].base_addr); 535 lmb->base_addr);
594 else 536 else
595 pr_info("Memory at %llx was hot-removed\n", lmbs[i].base_addr); 537 pr_info("Memory at %llx was hot-removed\n", lmb->base_addr);
596 538
597 return rc; 539 return rc;
598} 540}
599 541
600static int dlpar_memory_readd_by_index(u32 drc_index, struct property *prop) 542static int dlpar_memory_readd_by_index(u32 drc_index)
601{ 543{
602 struct of_drconf_cell *lmbs; 544 struct drmem_lmb *lmb;
603 u32 num_lmbs, *p;
604 int lmb_found; 545 int lmb_found;
605 int i, rc; 546 int rc;
606 547
607 pr_info("Attempting to update LMB, drc index %x\n", drc_index); 548 pr_info("Attempting to update LMB, drc index %x\n", drc_index);
608 549
609 p = prop->value;
610 num_lmbs = *p++;
611 lmbs = (struct of_drconf_cell *)p;
612
613 lmb_found = 0; 550 lmb_found = 0;
614 for (i = 0; i < num_lmbs; i++) { 551 for_each_drmem_lmb(lmb) {
615 if (lmbs[i].drc_index == drc_index) { 552 if (lmb->drc_index == drc_index) {
616 lmb_found = 1; 553 lmb_found = 1;
617 rc = dlpar_remove_lmb(&lmbs[i]); 554 rc = dlpar_remove_lmb(lmb);
618 if (!rc) { 555 if (!rc) {
619 rc = dlpar_add_lmb(&lmbs[i]); 556 rc = dlpar_add_lmb(lmb);
620 if (rc) 557 if (rc)
621 dlpar_release_drc(lmbs[i].drc_index); 558 dlpar_release_drc(lmb->drc_index);
622 } 559 }
623 break; 560 break;
624 } 561 }
@@ -629,20 +566,18 @@ static int dlpar_memory_readd_by_index(u32 drc_index, struct property *prop)
629 566
630 if (rc) 567 if (rc)
631 pr_info("Failed to update memory at %llx\n", 568 pr_info("Failed to update memory at %llx\n",
632 lmbs[i].base_addr); 569 lmb->base_addr);
633 else 570 else
634 pr_info("Memory at %llx was updated\n", lmbs[i].base_addr); 571 pr_info("Memory at %llx was updated\n", lmb->base_addr);
635 572
636 return rc; 573 return rc;
637} 574}
638 575
639static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index, 576static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index)
640 struct property *prop)
641{ 577{
642 struct of_drconf_cell *lmbs; 578 struct drmem_lmb *lmb, *start_lmb, *end_lmb;
643 u32 num_lmbs, *p; 579 int lmbs_available = 0;
644 int i, rc, start_lmb_found; 580 int rc;
645 int lmbs_available = 0, start_index = 0, end_index;
646 581
647 pr_info("Attempting to hot-remove %u LMB(s) at %x\n", 582 pr_info("Attempting to hot-remove %u LMB(s) at %x\n",
648 lmbs_to_remove, drc_index); 583 lmbs_to_remove, drc_index);
@@ -650,29 +585,13 @@ static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index,
650 if (lmbs_to_remove == 0) 585 if (lmbs_to_remove == 0)
651 return -EINVAL; 586 return -EINVAL;
652 587
653 p = prop->value; 588 rc = get_lmb_range(drc_index, lmbs_to_remove, &start_lmb, &end_lmb);
654 num_lmbs = *p++; 589 if (rc)
655 lmbs = (struct of_drconf_cell *)p;
656 start_lmb_found = 0;
657
658 /* Navigate to drc_index */
659 while (start_index < num_lmbs) {
660 if (lmbs[start_index].drc_index == drc_index) {
661 start_lmb_found = 1;
662 break;
663 }
664
665 start_index++;
666 }
667
668 if (!start_lmb_found)
669 return -EINVAL; 590 return -EINVAL;
670 591
671 end_index = start_index + lmbs_to_remove;
672
673 /* Validate that there are enough LMBs to satisfy the request */ 592 /* Validate that there are enough LMBs to satisfy the request */
674 for (i = start_index; i < end_index; i++) { 593 for_each_drmem_lmb_in_range(lmb, start_lmb, end_lmb) {
675 if (lmbs[i].flags & DRCONF_MEM_RESERVED) 594 if (lmb->flags & DRCONF_MEM_RESERVED)
676 break; 595 break;
677 596
678 lmbs_available++; 597 lmbs_available++;
@@ -681,42 +600,43 @@ static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index,
681 if (lmbs_available < lmbs_to_remove) 600 if (lmbs_available < lmbs_to_remove)
682 return -EINVAL; 601 return -EINVAL;
683 602
684 for (i = start_index; i < end_index; i++) { 603 for_each_drmem_lmb_in_range(lmb, start_lmb, end_lmb) {
685 if (!(lmbs[i].flags & DRCONF_MEM_ASSIGNED)) 604 if (!(lmb->flags & DRCONF_MEM_ASSIGNED))
686 continue; 605 continue;
687 606
688 rc = dlpar_remove_lmb(&lmbs[i]); 607 rc = dlpar_remove_lmb(lmb);
689 if (rc) 608 if (rc)
690 break; 609 break;
691 610
692 lmbs[i].reserved = 1; 611 drmem_mark_lmb_reserved(lmb);
693 } 612 }
694 613
695 if (rc) { 614 if (rc) {
696 pr_err("Memory indexed-count-remove failed, adding any removed LMBs\n"); 615 pr_err("Memory indexed-count-remove failed, adding any removed LMBs\n");
697 616
698 for (i = start_index; i < end_index; i++) { 617
699 if (!lmbs[i].reserved) 618 for_each_drmem_lmb_in_range(lmb, start_lmb, end_lmb) {
619 if (!drmem_lmb_reserved(lmb))
700 continue; 620 continue;
701 621
702 rc = dlpar_add_lmb(&lmbs[i]); 622 rc = dlpar_add_lmb(lmb);
703 if (rc) 623 if (rc)
704 pr_err("Failed to add LMB, drc index %x\n", 624 pr_err("Failed to add LMB, drc index %x\n",
705 be32_to_cpu(lmbs[i].drc_index)); 625 lmb->drc_index);
706 626
707 lmbs[i].reserved = 0; 627 drmem_remove_lmb_reservation(lmb);
708 } 628 }
709 rc = -EINVAL; 629 rc = -EINVAL;
710 } else { 630 } else {
711 for (i = start_index; i < end_index; i++) { 631 for_each_drmem_lmb_in_range(lmb, start_lmb, end_lmb) {
712 if (!lmbs[i].reserved) 632 if (!drmem_lmb_reserved(lmb))
713 continue; 633 continue;
714 634
715 dlpar_release_drc(lmbs[i].drc_index); 635 dlpar_release_drc(lmb->drc_index);
716 pr_info("Memory at %llx (drc index %x) was hot-removed\n", 636 pr_info("Memory at %llx (drc index %x) was hot-removed\n",
717 lmbs[i].base_addr, lmbs[i].drc_index); 637 lmb->base_addr, lmb->drc_index);
718 638
719 lmbs[i].reserved = 0; 639 drmem_remove_lmb_reservation(lmb);
720 } 640 }
721 } 641 }
722 642
@@ -737,32 +657,30 @@ static inline int dlpar_memory_remove(struct pseries_hp_errorlog *hp_elog)
737{ 657{
738 return -EOPNOTSUPP; 658 return -EOPNOTSUPP;
739} 659}
740static int dlpar_remove_lmb(struct of_drconf_cell *lmb) 660static int dlpar_remove_lmb(struct drmem_lmb *lmb)
741{ 661{
742 return -EOPNOTSUPP; 662 return -EOPNOTSUPP;
743} 663}
744static int dlpar_memory_remove_by_count(u32 lmbs_to_remove, 664static int dlpar_memory_remove_by_count(u32 lmbs_to_remove)
745 struct property *prop)
746{ 665{
747 return -EOPNOTSUPP; 666 return -EOPNOTSUPP;
748} 667}
749static int dlpar_memory_remove_by_index(u32 drc_index, struct property *prop) 668static int dlpar_memory_remove_by_index(u32 drc_index)
750{ 669{
751 return -EOPNOTSUPP; 670 return -EOPNOTSUPP;
752} 671}
753static int dlpar_memory_readd_by_index(u32 drc_index, struct property *prop) 672static int dlpar_memory_readd_by_index(u32 drc_index)
754{ 673{
755 return -EOPNOTSUPP; 674 return -EOPNOTSUPP;
756} 675}
757 676
758static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index, 677static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index)
759 struct property *prop)
760{ 678{
761 return -EOPNOTSUPP; 679 return -EOPNOTSUPP;
762} 680}
763#endif /* CONFIG_MEMORY_HOTREMOVE */ 681#endif /* CONFIG_MEMORY_HOTREMOVE */
764 682
765static int dlpar_add_lmb(struct of_drconf_cell *lmb) 683static int dlpar_add_lmb(struct drmem_lmb *lmb)
766{ 684{
767 unsigned long block_sz; 685 unsigned long block_sz;
768 int nid, rc; 686 int nid, rc;
@@ -801,77 +719,79 @@ static int dlpar_add_lmb(struct of_drconf_cell *lmb)
801 return rc; 719 return rc;
802} 720}
803 721
804static int dlpar_memory_add_by_count(u32 lmbs_to_add, struct property *prop) 722static int dlpar_memory_add_by_count(u32 lmbs_to_add)
805{ 723{
806 struct of_drconf_cell *lmbs; 724 struct drmem_lmb *lmb;
807 u32 num_lmbs, *p;
808 int lmbs_available = 0; 725 int lmbs_available = 0;
809 int lmbs_added = 0; 726 int lmbs_added = 0;
810 int i, rc; 727 int rc;
811 728
812 pr_info("Attempting to hot-add %d LMB(s)\n", lmbs_to_add); 729 pr_info("Attempting to hot-add %d LMB(s)\n", lmbs_to_add);
813 730
814 if (lmbs_to_add == 0) 731 if (lmbs_to_add == 0)
815 return -EINVAL; 732 return -EINVAL;
816 733
817 p = prop->value;
818 num_lmbs = *p++;
819 lmbs = (struct of_drconf_cell *)p;
820
821 /* Validate that there are enough LMBs to satisfy the request */ 734 /* Validate that there are enough LMBs to satisfy the request */
822 for (i = 0; i < num_lmbs; i++) { 735 for_each_drmem_lmb(lmb) {
823 if (!(lmbs[i].flags & DRCONF_MEM_ASSIGNED)) 736 if (!(lmb->flags & DRCONF_MEM_ASSIGNED))
824 lmbs_available++; 737 lmbs_available++;
738
739 if (lmbs_available == lmbs_to_add)
740 break;
825 } 741 }
826 742
827 if (lmbs_available < lmbs_to_add) 743 if (lmbs_available < lmbs_to_add)
828 return -EINVAL; 744 return -EINVAL;
829 745
830 for (i = 0; i < num_lmbs && lmbs_to_add != lmbs_added; i++) { 746 for_each_drmem_lmb(lmb) {
831 if (lmbs[i].flags & DRCONF_MEM_ASSIGNED) 747 if (lmb->flags & DRCONF_MEM_ASSIGNED)
832 continue; 748 continue;
833 749
834 rc = dlpar_acquire_drc(lmbs[i].drc_index); 750 rc = dlpar_acquire_drc(lmb->drc_index);
835 if (rc) 751 if (rc)
836 continue; 752 continue;
837 753
838 rc = dlpar_add_lmb(&lmbs[i]); 754 rc = dlpar_add_lmb(lmb);
839 if (rc) { 755 if (rc) {
840 dlpar_release_drc(lmbs[i].drc_index); 756 dlpar_release_drc(lmb->drc_index);
841 continue; 757 continue;
842 } 758 }
843 759
844 lmbs_added++;
845
846 /* Mark this lmb so we can remove it later if all of the 760 /* Mark this lmb so we can remove it later if all of the
847 * requested LMBs cannot be added. 761 * requested LMBs cannot be added.
848 */ 762 */
849 lmbs[i].reserved = 1; 763 drmem_mark_lmb_reserved(lmb);
764
765 lmbs_added++;
766 if (lmbs_added == lmbs_to_add)
767 break;
850 } 768 }
851 769
852 if (lmbs_added != lmbs_to_add) { 770 if (lmbs_added != lmbs_to_add) {
853 pr_err("Memory hot-add failed, removing any added LMBs\n"); 771 pr_err("Memory hot-add failed, removing any added LMBs\n");
854 772
855 for (i = 0; i < num_lmbs; i++) { 773 for_each_drmem_lmb(lmb) {
856 if (!lmbs[i].reserved) 774 if (!drmem_lmb_reserved(lmb))
857 continue; 775 continue;
858 776
859 rc = dlpar_remove_lmb(&lmbs[i]); 777 rc = dlpar_remove_lmb(lmb);
860 if (rc) 778 if (rc)
861 pr_err("Failed to remove LMB, drc index %x\n", 779 pr_err("Failed to remove LMB, drc index %x\n",
862 be32_to_cpu(lmbs[i].drc_index)); 780 lmb->drc_index);
863 else 781 else
864 dlpar_release_drc(lmbs[i].drc_index); 782 dlpar_release_drc(lmb->drc_index);
783
784 drmem_remove_lmb_reservation(lmb);
865 } 785 }
866 rc = -EINVAL; 786 rc = -EINVAL;
867 } else { 787 } else {
868 for (i = 0; i < num_lmbs; i++) { 788 for_each_drmem_lmb(lmb) {
869 if (!lmbs[i].reserved) 789 if (!drmem_lmb_reserved(lmb))
870 continue; 790 continue;
871 791
872 pr_info("Memory at %llx (drc index %x) was hot-added\n", 792 pr_info("Memory at %llx (drc index %x) was hot-added\n",
873 lmbs[i].base_addr, lmbs[i].drc_index); 793 lmb->base_addr, lmb->drc_index);
874 lmbs[i].reserved = 0; 794 drmem_remove_lmb_reservation(lmb);
875 } 795 }
876 rc = 0; 796 rc = 0;
877 } 797 }
@@ -879,28 +799,22 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add, struct property *prop)
879 return rc; 799 return rc;
880} 800}
881 801
882static int dlpar_memory_add_by_index(u32 drc_index, struct property *prop) 802static int dlpar_memory_add_by_index(u32 drc_index)
883{ 803{
884 struct of_drconf_cell *lmbs; 804 struct drmem_lmb *lmb;
885 u32 num_lmbs, *p; 805 int rc, lmb_found;
886 int i, lmb_found;
887 int rc;
888 806
889 pr_info("Attempting to hot-add LMB, drc index %x\n", drc_index); 807 pr_info("Attempting to hot-add LMB, drc index %x\n", drc_index);
890 808
891 p = prop->value;
892 num_lmbs = *p++;
893 lmbs = (struct of_drconf_cell *)p;
894
895 lmb_found = 0; 809 lmb_found = 0;
896 for (i = 0; i < num_lmbs; i++) { 810 for_each_drmem_lmb(lmb) {
897 if (lmbs[i].drc_index == drc_index) { 811 if (lmb->drc_index == drc_index) {
898 lmb_found = 1; 812 lmb_found = 1;
899 rc = dlpar_acquire_drc(lmbs[i].drc_index); 813 rc = dlpar_acquire_drc(lmb->drc_index);
900 if (!rc) { 814 if (!rc) {
901 rc = dlpar_add_lmb(&lmbs[i]); 815 rc = dlpar_add_lmb(lmb);
902 if (rc) 816 if (rc)
903 dlpar_release_drc(lmbs[i].drc_index); 817 dlpar_release_drc(lmb->drc_index);
904 } 818 }
905 819
906 break; 820 break;
@@ -914,18 +828,16 @@ static int dlpar_memory_add_by_index(u32 drc_index, struct property *prop)
914 pr_info("Failed to hot-add memory, drc index %x\n", drc_index); 828 pr_info("Failed to hot-add memory, drc index %x\n", drc_index);
915 else 829 else
916 pr_info("Memory at %llx (drc index %x) was hot-added\n", 830 pr_info("Memory at %llx (drc index %x) was hot-added\n",
917 lmbs[i].base_addr, drc_index); 831 lmb->base_addr, drc_index);
918 832
919 return rc; 833 return rc;
920} 834}
921 835
922static int dlpar_memory_add_by_ic(u32 lmbs_to_add, u32 drc_index, 836static int dlpar_memory_add_by_ic(u32 lmbs_to_add, u32 drc_index)
923 struct property *prop)
924{ 837{
925 struct of_drconf_cell *lmbs; 838 struct drmem_lmb *lmb, *start_lmb, *end_lmb;
926 u32 num_lmbs, *p; 839 int lmbs_available = 0;
927 int i, rc, start_lmb_found; 840 int rc;
928 int lmbs_available = 0, start_index = 0, end_index;
929 841
930 pr_info("Attempting to hot-add %u LMB(s) at index %x\n", 842 pr_info("Attempting to hot-add %u LMB(s) at index %x\n",
931 lmbs_to_add, drc_index); 843 lmbs_to_add, drc_index);
@@ -933,29 +845,13 @@ static int dlpar_memory_add_by_ic(u32 lmbs_to_add, u32 drc_index,
933 if (lmbs_to_add == 0) 845 if (lmbs_to_add == 0)
934 return -EINVAL; 846 return -EINVAL;
935 847
936 p = prop->value; 848 rc = get_lmb_range(drc_index, lmbs_to_add, &start_lmb, &end_lmb);
937 num_lmbs = *p++; 849 if (rc)
938 lmbs = (struct of_drconf_cell *)p;
939 start_lmb_found = 0;
940
941 /* Navigate to drc_index */
942 while (start_index < num_lmbs) {
943 if (lmbs[start_index].drc_index == drc_index) {
944 start_lmb_found = 1;
945 break;
946 }
947
948 start_index++;
949 }
950
951 if (!start_lmb_found)
952 return -EINVAL; 850 return -EINVAL;
953 851
954 end_index = start_index + lmbs_to_add;
955
956 /* Validate that the LMBs in this range are not reserved */ 852 /* Validate that the LMBs in this range are not reserved */
957 for (i = start_index; i < end_index; i++) { 853 for_each_drmem_lmb_in_range(lmb, start_lmb, end_lmb) {
958 if (lmbs[i].flags & DRCONF_MEM_RESERVED) 854 if (lmb->flags & DRCONF_MEM_RESERVED)
959 break; 855 break;
960 856
961 lmbs_available++; 857 lmbs_available++;
@@ -964,46 +860,48 @@ static int dlpar_memory_add_by_ic(u32 lmbs_to_add, u32 drc_index,
964 if (lmbs_available < lmbs_to_add) 860 if (lmbs_available < lmbs_to_add)
965 return -EINVAL; 861 return -EINVAL;
966 862
967 for (i = start_index; i < end_index; i++) { 863 for_each_drmem_lmb_in_range(lmb, start_lmb, end_lmb) {
968 if (lmbs[i].flags & DRCONF_MEM_ASSIGNED) 864 if (lmb->flags & DRCONF_MEM_ASSIGNED)
969 continue; 865 continue;
970 866
971 rc = dlpar_acquire_drc(lmbs[i].drc_index); 867 rc = dlpar_acquire_drc(lmb->drc_index);
972 if (rc) 868 if (rc)
973 break; 869 break;
974 870
975 rc = dlpar_add_lmb(&lmbs[i]); 871 rc = dlpar_add_lmb(lmb);
976 if (rc) { 872 if (rc) {
977 dlpar_release_drc(lmbs[i].drc_index); 873 dlpar_release_drc(lmb->drc_index);
978 break; 874 break;
979 } 875 }
980 876
981 lmbs[i].reserved = 1; 877 drmem_mark_lmb_reserved(lmb);
982 } 878 }
983 879
984 if (rc) { 880 if (rc) {
985 pr_err("Memory indexed-count-add failed, removing any added LMBs\n"); 881 pr_err("Memory indexed-count-add failed, removing any added LMBs\n");
986 882
987 for (i = start_index; i < end_index; i++) { 883 for_each_drmem_lmb_in_range(lmb, start_lmb, end_lmb) {
988 if (!lmbs[i].reserved) 884 if (!drmem_lmb_reserved(lmb))
989 continue; 885 continue;
990 886
991 rc = dlpar_remove_lmb(&lmbs[i]); 887 rc = dlpar_remove_lmb(lmb);
992 if (rc) 888 if (rc)
993 pr_err("Failed to remove LMB, drc index %x\n", 889 pr_err("Failed to remove LMB, drc index %x\n",
994 be32_to_cpu(lmbs[i].drc_index)); 890 lmb->drc_index);
995 else 891 else
996 dlpar_release_drc(lmbs[i].drc_index); 892 dlpar_release_drc(lmb->drc_index);
893
894 drmem_remove_lmb_reservation(lmb);
997 } 895 }
998 rc = -EINVAL; 896 rc = -EINVAL;
999 } else { 897 } else {
1000 for (i = start_index; i < end_index; i++) { 898 for_each_drmem_lmb_in_range(lmb, start_lmb, end_lmb) {
1001 if (!lmbs[i].reserved) 899 if (!drmem_lmb_reserved(lmb))
1002 continue; 900 continue;
1003 901
1004 pr_info("Memory at %llx (drc index %x) was hot-added\n", 902 pr_info("Memory at %llx (drc index %x) was hot-added\n",
1005 lmbs[i].base_addr, lmbs[i].drc_index); 903 lmb->base_addr, lmb->drc_index);
1006 lmbs[i].reserved = 0; 904 drmem_remove_lmb_reservation(lmb);
1007 } 905 }
1008 } 906 }
1009 907
@@ -1012,37 +910,23 @@ static int dlpar_memory_add_by_ic(u32 lmbs_to_add, u32 drc_index,
1012 910
1013int dlpar_memory(struct pseries_hp_errorlog *hp_elog) 911int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
1014{ 912{
1015 struct device_node *dn;
1016 struct property *prop;
1017 u32 count, drc_index; 913 u32 count, drc_index;
1018 int rc; 914 int rc;
1019 915
1020 lock_device_hotplug(); 916 lock_device_hotplug();
1021 917
1022 dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
1023 if (!dn) {
1024 rc = -EINVAL;
1025 goto dlpar_memory_out;
1026 }
1027
1028 prop = dlpar_clone_drconf_property(dn);
1029 if (!prop) {
1030 rc = -EINVAL;
1031 goto dlpar_memory_out;
1032 }
1033
1034 switch (hp_elog->action) { 918 switch (hp_elog->action) {
1035 case PSERIES_HP_ELOG_ACTION_ADD: 919 case PSERIES_HP_ELOG_ACTION_ADD:
1036 if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT) { 920 if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT) {
1037 count = hp_elog->_drc_u.drc_count; 921 count = hp_elog->_drc_u.drc_count;
1038 rc = dlpar_memory_add_by_count(count, prop); 922 rc = dlpar_memory_add_by_count(count);
1039 } else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX) { 923 } else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX) {
1040 drc_index = hp_elog->_drc_u.drc_index; 924 drc_index = hp_elog->_drc_u.drc_index;
1041 rc = dlpar_memory_add_by_index(drc_index, prop); 925 rc = dlpar_memory_add_by_index(drc_index);
1042 } else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_IC) { 926 } else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_IC) {
1043 count = hp_elog->_drc_u.ic.count; 927 count = hp_elog->_drc_u.ic.count;
1044 drc_index = hp_elog->_drc_u.ic.index; 928 drc_index = hp_elog->_drc_u.ic.index;
1045 rc = dlpar_memory_add_by_ic(count, drc_index, prop); 929 rc = dlpar_memory_add_by_ic(count, drc_index);
1046 } else { 930 } else {
1047 rc = -EINVAL; 931 rc = -EINVAL;
1048 } 932 }
@@ -1051,14 +935,14 @@ int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
1051 case PSERIES_HP_ELOG_ACTION_REMOVE: 935 case PSERIES_HP_ELOG_ACTION_REMOVE:
1052 if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT) { 936 if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT) {
1053 count = hp_elog->_drc_u.drc_count; 937 count = hp_elog->_drc_u.drc_count;
1054 rc = dlpar_memory_remove_by_count(count, prop); 938 rc = dlpar_memory_remove_by_count(count);
1055 } else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX) { 939 } else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX) {
1056 drc_index = hp_elog->_drc_u.drc_index; 940 drc_index = hp_elog->_drc_u.drc_index;
1057 rc = dlpar_memory_remove_by_index(drc_index, prop); 941 rc = dlpar_memory_remove_by_index(drc_index);
1058 } else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_IC) { 942 } else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_IC) {
1059 count = hp_elog->_drc_u.ic.count; 943 count = hp_elog->_drc_u.ic.count;
1060 drc_index = hp_elog->_drc_u.ic.index; 944 drc_index = hp_elog->_drc_u.ic.index;
1061 rc = dlpar_memory_remove_by_ic(count, drc_index, prop); 945 rc = dlpar_memory_remove_by_ic(count, drc_index);
1062 } else { 946 } else {
1063 rc = -EINVAL; 947 rc = -EINVAL;
1064 } 948 }
@@ -1066,7 +950,7 @@ int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
1066 break; 950 break;
1067 case PSERIES_HP_ELOG_ACTION_READD: 951 case PSERIES_HP_ELOG_ACTION_READD:
1068 drc_index = hp_elog->_drc_u.drc_index; 952 drc_index = hp_elog->_drc_u.drc_index;
1069 rc = dlpar_memory_readd_by_index(drc_index, prop); 953 rc = dlpar_memory_readd_by_index(drc_index);
1070 break; 954 break;
1071 default: 955 default:
1072 pr_err("Invalid action (%d) specified\n", hp_elog->action); 956 pr_err("Invalid action (%d) specified\n", hp_elog->action);
@@ -1074,10 +958,6 @@ int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
1074 break; 958 break;
1075 } 959 }
1076 960
1077 dlpar_free_property(prop);
1078
1079dlpar_memory_out:
1080 of_node_put(dn);
1081 unlock_device_hotplug(); 961 unlock_device_hotplug();
1082 return rc; 962 return rc;
1083} 963}
@@ -1116,7 +996,7 @@ static int pseries_add_mem_node(struct device_node *np)
1116 996
1117static int pseries_update_drconf_memory(struct of_reconfig_data *pr) 997static int pseries_update_drconf_memory(struct of_reconfig_data *pr)
1118{ 998{
1119 struct of_drconf_cell *new_drmem, *old_drmem; 999 struct of_drconf_cell_v1 *new_drmem, *old_drmem;
1120 unsigned long memblock_size; 1000 unsigned long memblock_size;
1121 u32 entries; 1001 u32 entries;
1122 __be32 *p; 1002 __be32 *p;
@@ -1139,11 +1019,11 @@ static int pseries_update_drconf_memory(struct of_reconfig_data *pr)
1139 * of_drconf_cell's. 1019 * of_drconf_cell's.
1140 */ 1020 */
1141 entries = be32_to_cpu(*p++); 1021 entries = be32_to_cpu(*p++);
1142 old_drmem = (struct of_drconf_cell *)p; 1022 old_drmem = (struct of_drconf_cell_v1 *)p;
1143 1023
1144 p = (__be32 *)pr->prop->value; 1024 p = (__be32 *)pr->prop->value;
1145 p++; 1025 p++;
1146 new_drmem = (struct of_drconf_cell *)p; 1026 new_drmem = (struct of_drconf_cell_v1 *)p;
1147 1027
1148 for (i = 0; i < entries; i++) { 1028 for (i = 0; i < entries; i++) {
1149 if ((be32_to_cpu(old_drmem[i].flags) & DRCONF_MEM_ASSIGNED) && 1029 if ((be32_to_cpu(old_drmem[i].flags) & DRCONF_MEM_ASSIGNED) &&
diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c
index 957ae347b0b3..89b7ce807e70 100644
--- a/arch/powerpc/platforms/pseries/hvCall_inst.c
+++ b/arch/powerpc/platforms/pseries/hvCall_inst.c
@@ -163,7 +163,7 @@ static int __init hcall_inst_init(void)
163 163
164 for_each_possible_cpu(cpu) { 164 for_each_possible_cpu(cpu) {
165 snprintf(cpu_name_buf, CPU_NAME_BUF_SIZE, "cpu%d", cpu); 165 snprintf(cpu_name_buf, CPU_NAME_BUF_SIZE, "cpu%d", cpu);
166 hcall_file = debugfs_create_file(cpu_name_buf, S_IRUGO, 166 hcall_file = debugfs_create_file(cpu_name_buf, 0444,
167 hcall_root, 167 hcall_root,
168 per_cpu(hcall_stats, cpu), 168 per_cpu(hcall_stats, cpu),
169 &hcall_inst_seq_fops); 169 &hcall_inst_seq_fops);
diff --git a/arch/powerpc/platforms/pseries/ibmebus.c b/arch/powerpc/platforms/pseries/ibmebus.c
index 408a86044133..c7c1140c13b6 100644
--- a/arch/powerpc/platforms/pseries/ibmebus.c
+++ b/arch/powerpc/platforms/pseries/ibmebus.c
@@ -298,7 +298,7 @@ out:
298 return rc; 298 return rc;
299 return count; 299 return count;
300} 300}
301static BUS_ATTR(probe, S_IWUSR, NULL, ibmebus_store_probe); 301static BUS_ATTR(probe, 0200, NULL, ibmebus_store_probe);
302 302
303static ssize_t ibmebus_store_remove(struct bus_type *bus, 303static ssize_t ibmebus_store_remove(struct bus_type *bus,
304 const char *buf, size_t count) 304 const char *buf, size_t count)
@@ -325,7 +325,7 @@ static ssize_t ibmebus_store_remove(struct bus_type *bus,
325 return -ENODEV; 325 return -ENODEV;
326 } 326 }
327} 327}
328static BUS_ATTR(remove, S_IWUSR, NULL, ibmebus_store_remove); 328static BUS_ATTR(remove, 0200, NULL, ibmebus_store_remove);
329 329
330static struct attribute *ibmbus_bus_attrs[] = { 330static struct attribute *ibmbus_bus_attrs[] = {
331 &bus_attr_probe.attr, 331 &bus_attr_probe.attr,
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index eaa11334fc8c..06f02960b439 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -816,15 +816,15 @@ static void remove_ddw(struct device_node *np, bool remove_prop)
816 ret = tce_clearrange_multi_pSeriesLP(0, 816 ret = tce_clearrange_multi_pSeriesLP(0,
817 1ULL << (be32_to_cpu(dwp->window_shift) - PAGE_SHIFT), dwp); 817 1ULL << (be32_to_cpu(dwp->window_shift) - PAGE_SHIFT), dwp);
818 if (ret) 818 if (ret)
819 pr_warning("%pOF failed to clear tces in window.\n", 819 pr_warn("%pOF failed to clear tces in window.\n",
820 np); 820 np);
821 else 821 else
822 pr_debug("%pOF successfully cleared tces in window.\n", 822 pr_debug("%pOF successfully cleared tces in window.\n",
823 np); 823 np);
824 824
825 ret = rtas_call(ddw_avail[2], 1, 1, NULL, liobn); 825 ret = rtas_call(ddw_avail[2], 1, 1, NULL, liobn);
826 if (ret) 826 if (ret)
827 pr_warning("%pOF: failed to remove direct window: rtas returned " 827 pr_warn("%pOF: failed to remove direct window: rtas returned "
828 "%d to ibm,remove-pe-dma-window(%x) %llx\n", 828 "%d to ibm,remove-pe-dma-window(%x) %llx\n",
829 np, ret, ddw_avail[2], liobn); 829 np, ret, ddw_avail[2], liobn);
830 else 830 else
@@ -836,7 +836,7 @@ delprop:
836 if (remove_prop) 836 if (remove_prop)
837 ret = of_remove_property(np, win64); 837 ret = of_remove_property(np, win64);
838 if (ret) 838 if (ret)
839 pr_warning("%pOF: failed to remove direct window property: %d\n", 839 pr_warn("%pOF: failed to remove direct window property: %d\n",
840 np, ret); 840 np, ret);
841} 841}
842 842
diff --git a/arch/powerpc/platforms/pseries/lparcfg.c b/arch/powerpc/platforms/pseries/lparcfg.c
index b2706c483067..c508c938dc71 100644
--- a/arch/powerpc/platforms/pseries/lparcfg.c
+++ b/arch/powerpc/platforms/pseries/lparcfg.c
@@ -370,10 +370,10 @@ static void parse_system_parameter_string(struct seq_file *m)
370 */ 370 */
371static int lparcfg_count_active_processors(void) 371static int lparcfg_count_active_processors(void)
372{ 372{
373 struct device_node *cpus_dn = NULL; 373 struct device_node *cpus_dn;
374 int count = 0; 374 int count = 0;
375 375
376 while ((cpus_dn = of_find_node_by_type(cpus_dn, "cpu"))) { 376 for_each_node_by_type(cpus_dn, "cpu") {
377#ifdef LPARCFG_DEBUG 377#ifdef LPARCFG_DEBUG
378 printk(KERN_ERR "cpus_dn %p\n", cpus_dn); 378 printk(KERN_ERR "cpus_dn %p\n", cpus_dn);
379#endif 379#endif
@@ -697,11 +697,11 @@ static const struct file_operations lparcfg_fops = {
697 697
698static int __init lparcfg_init(void) 698static int __init lparcfg_init(void)
699{ 699{
700 umode_t mode = S_IRUSR | S_IRGRP | S_IROTH; 700 umode_t mode = 0444;
701 701
702 /* Allow writing if we have FW_FEATURE_SPLPAR */ 702 /* Allow writing if we have FW_FEATURE_SPLPAR */
703 if (firmware_has_feature(FW_FEATURE_SPLPAR)) 703 if (firmware_has_feature(FW_FEATURE_SPLPAR))
704 mode |= S_IWUSR; 704 mode |= 0200;
705 705
706 if (!proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_fops)) { 706 if (!proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_fops)) {
707 printk(KERN_ERR "Failed to create powerpc/lparcfg\n"); 707 printk(KERN_ERR "Failed to create powerpc/lparcfg\n");
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index f7042ad492ba..0f7fb7170b03 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -384,7 +384,7 @@ static ssize_t migration_store(struct class *class,
384#define MIGRATION_API_VERSION 1 384#define MIGRATION_API_VERSION 1
385 385
386static CLASS_ATTR_WO(migration); 386static CLASS_ATTR_WO(migration);
387static CLASS_ATTR_STRING(api_version, S_IRUGO, __stringify(MIGRATION_API_VERSION)); 387static CLASS_ATTR_STRING(api_version, 0444, __stringify(MIGRATION_API_VERSION));
388 388
389static int __init mobility_sysfs_init(void) 389static int __init mobility_sysfs_init(void)
390{ 390{
diff --git a/arch/powerpc/platforms/pseries/of_helpers.c b/arch/powerpc/platforms/pseries/of_helpers.c
index 7e75101fa522..6df192f38f80 100644
--- a/arch/powerpc/platforms/pseries/of_helpers.c
+++ b/arch/powerpc/platforms/pseries/of_helpers.c
@@ -3,6 +3,7 @@
3#include <linux/err.h> 3#include <linux/err.h>
4#include <linux/slab.h> 4#include <linux/slab.h>
5#include <linux/of.h> 5#include <linux/of.h>
6#include <asm/prom.h>
6 7
7#include "of_helpers.h" 8#include "of_helpers.h"
8 9
@@ -37,3 +38,62 @@ struct device_node *pseries_of_derive_parent(const char *path)
37 kfree(parent_path); 38 kfree(parent_path);
38 return parent ? parent : ERR_PTR(-EINVAL); 39 return parent ? parent : ERR_PTR(-EINVAL);
39} 40}
41
42
43/* Helper Routines to convert between drc_index to cpu numbers */
44
45int of_read_drc_info_cell(struct property **prop, const __be32 **curval,
46 struct of_drc_info *data)
47{
48 const char *p;
49 const __be32 *p2;
50
51 if (!data)
52 return -EINVAL;
53
54 /* Get drc-type:encode-string */
55 p = data->drc_type = (char*) (*curval);
56 p = of_prop_next_string(*prop, p);
57 if (!p)
58 return -EINVAL;
59
60 /* Get drc-name-prefix:encode-string */
61 data->drc_name_prefix = (char *)p;
62 p = of_prop_next_string(*prop, p);
63 if (!p)
64 return -EINVAL;
65
66 /* Get drc-index-start:encode-int */
67 p2 = (const __be32 *)p;
68 p2 = of_prop_next_u32(*prop, p2, &data->drc_index_start);
69 if (!p2)
70 return -EINVAL;
71
72 /* Get drc-name-suffix-start:encode-int */
73 p2 = of_prop_next_u32(*prop, p2, &data->drc_name_suffix_start);
74 if (!p2)
75 return -EINVAL;
76
77 /* Get number-sequential-elements:encode-int */
78 p2 = of_prop_next_u32(*prop, p2, &data->num_sequential_elems);
79 if (!p2)
80 return -EINVAL;
81
82 /* Get sequential-increment:encode-int */
83 p2 = of_prop_next_u32(*prop, p2, &data->sequential_inc);
84 if (!p2)
85 return -EINVAL;
86
87 /* Get drc-power-domain:encode-int */
88 p2 = of_prop_next_u32(*prop, p2, &data->drc_power_domain);
89 if (!p2)
90 return -EINVAL;
91
92 /* Should now know end of current entry */
93 (*curval) = (void *)p2;
94 data->last_drc_index = data->drc_index_start +
95 ((data->num_sequential_elems - 1) * data->sequential_inc);
96
97 return 0;
98}
99EXPORT_SYMBOL(of_read_drc_info_cell);
diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c
index 09eba5a9929a..eab96637d6cf 100644
--- a/arch/powerpc/platforms/pseries/pci.c
+++ b/arch/powerpc/platforms/pseries/pci.c
@@ -3,17 +3,17 @@
3 * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM 3 * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
4 * 4 *
5 * pSeries specific routines for PCI. 5 * pSeries specific routines for PCI.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or 9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version. 10 * (at your option) any later version.
11 * 11 *
12 * This program is distributed in the hope that it will be useful, 12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -54,10 +54,174 @@ void pcibios_name_device(struct pci_dev *dev)
54 } 54 }
55 } 55 }
56 } 56 }
57} 57}
58DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device); 58DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device);
59#endif 59#endif
60 60
61#ifdef CONFIG_PCI_IOV
62#define MAX_VFS_FOR_MAP_PE 256
63struct pe_map_bar_entry {
64 __be64 bar; /* Input: Virtual Function BAR */
65 __be16 rid; /* Input: Virtual Function Router ID */
66 __be16 pe_num; /* Output: Virtual Function PE Number */
67 __be32 reserved; /* Reserved Space */
68};
69
70int pseries_send_map_pe(struct pci_dev *pdev,
71 u16 num_vfs,
72 struct pe_map_bar_entry *vf_pe_array)
73{
74 struct pci_dn *pdn;
75 int rc;
76 unsigned long buid, addr;
77 int ibm_map_pes = rtas_token("ibm,open-sriov-map-pe-number");
78
79 if (ibm_map_pes == RTAS_UNKNOWN_SERVICE)
80 return -EINVAL;
81
82 pdn = pci_get_pdn(pdev);
83 addr = rtas_config_addr(pdn->busno, pdn->devfn, 0);
84 buid = pdn->phb->buid;
85 spin_lock(&rtas_data_buf_lock);
86 memcpy(rtas_data_buf, vf_pe_array,
87 RTAS_DATA_BUF_SIZE);
88 rc = rtas_call(ibm_map_pes, 5, 1, NULL, addr,
89 BUID_HI(buid), BUID_LO(buid),
90 rtas_data_buf,
91 num_vfs * sizeof(struct pe_map_bar_entry));
92 memcpy(vf_pe_array, rtas_data_buf, RTAS_DATA_BUF_SIZE);
93 spin_unlock(&rtas_data_buf_lock);
94
95 if (rc)
96 dev_err(&pdev->dev,
97 "%s: Failed to associate pes PE#%lx, rc=%x\n",
98 __func__, addr, rc);
99
100 return rc;
101}
102
103void pseries_set_pe_num(struct pci_dev *pdev, u16 vf_index, __be16 pe_num)
104{
105 struct pci_dn *pdn;
106
107 pdn = pci_get_pdn(pdev);
108 pdn->pe_num_map[vf_index] = be16_to_cpu(pe_num);
109 dev_dbg(&pdev->dev, "VF %04x:%02x:%02x.%x associated with PE#%x\n",
110 pci_domain_nr(pdev->bus),
111 pdev->bus->number,
112 PCI_SLOT(pci_iov_virtfn_devfn(pdev, vf_index)),
113 PCI_FUNC(pci_iov_virtfn_devfn(pdev, vf_index)),
114 pdn->pe_num_map[vf_index]);
115}
116
117int pseries_associate_pes(struct pci_dev *pdev, u16 num_vfs)
118{
119 struct pci_dn *pdn;
120 int i, rc, vf_index;
121 struct pe_map_bar_entry *vf_pe_array;
122 struct resource *res;
123 u64 size;
124
125 vf_pe_array = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
126 if (!vf_pe_array)
127 return -ENOMEM;
128
129 pdn = pci_get_pdn(pdev);
130 /* create firmware structure to associate pes */
131 for (vf_index = 0; vf_index < num_vfs; vf_index++) {
132 pdn->pe_num_map[vf_index] = IODA_INVALID_PE;
133 for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
134 res = &pdev->resource[i + PCI_IOV_RESOURCES];
135 if (!res->parent)
136 continue;
137 size = pcibios_iov_resource_alignment(pdev, i +
138 PCI_IOV_RESOURCES);
139 vf_pe_array[vf_index].bar =
140 cpu_to_be64(res->start + size * vf_index);
141 vf_pe_array[vf_index].rid =
142 cpu_to_be16((pci_iov_virtfn_bus(pdev, vf_index)
143 << 8) | pci_iov_virtfn_devfn(pdev,
144 vf_index));
145 vf_pe_array[vf_index].pe_num =
146 cpu_to_be16(IODA_INVALID_PE);
147 }
148 }
149
150 rc = pseries_send_map_pe(pdev, num_vfs, vf_pe_array);
151 /* Only zero is success */
152 if (!rc)
153 for (vf_index = 0; vf_index < num_vfs; vf_index++)
154 pseries_set_pe_num(pdev, vf_index,
155 vf_pe_array[vf_index].pe_num);
156
157 kfree(vf_pe_array);
158 return rc;
159}
160
161int pseries_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
162{
163 struct pci_dn *pdn;
164 int rc;
165 const int *max_vfs;
166 int max_config_vfs;
167 struct device_node *dn = pci_device_to_OF_node(pdev);
168
169 max_vfs = of_get_property(dn, "ibm,number-of-configurable-vfs", NULL);
170
171 if (!max_vfs)
172 return -EINVAL;
173
174 /* First integer stores max config */
175 max_config_vfs = of_read_number(&max_vfs[0], 1);
176 if (max_config_vfs < num_vfs && num_vfs > MAX_VFS_FOR_MAP_PE) {
177 dev_err(&pdev->dev,
178 "Num VFs %x > %x Configurable VFs\n",
179 num_vfs, (num_vfs > MAX_VFS_FOR_MAP_PE) ?
180 MAX_VFS_FOR_MAP_PE : max_config_vfs);
181 return -EINVAL;
182 }
183
184 pdn = pci_get_pdn(pdev);
185 pdn->pe_num_map = kmalloc_array(num_vfs,
186 sizeof(*pdn->pe_num_map),
187 GFP_KERNEL);
188 if (!pdn->pe_num_map)
189 return -ENOMEM;
190
191 rc = pseries_associate_pes(pdev, num_vfs);
192
193 /* Anything other than zero is failure */
194 if (rc) {
195 dev_err(&pdev->dev, "Failure to enable sriov: %x\n", rc);
196 kfree(pdn->pe_num_map);
197 } else {
198 pci_vf_drivers_autoprobe(pdev, false);
199 }
200
201 return rc;
202}
203
204int pseries_pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
205{
206 /* Allocate PCI data */
207 add_dev_pci_data(pdev);
208 return pseries_pci_sriov_enable(pdev, num_vfs);
209}
210
211int pseries_pcibios_sriov_disable(struct pci_dev *pdev)
212{
213 struct pci_dn *pdn;
214
215 pdn = pci_get_pdn(pdev);
216 /* Releasing pe_num_map */
217 kfree(pdn->pe_num_map);
218 /* Release PCI data */
219 remove_dev_pci_data(pdev);
220 pci_vf_drivers_autoprobe(pdev, true);
221 return 0;
222}
223#endif
224
61static void __init pSeries_request_regions(void) 225static void __init pSeries_request_regions(void)
62{ 226{
63 if (!isa_io_base) 227 if (!isa_io_base)
@@ -76,6 +240,11 @@ void __init pSeries_final_fixup(void)
76 pSeries_request_regions(); 240 pSeries_request_regions();
77 241
78 eeh_addr_cache_build(); 242 eeh_addr_cache_build();
243
244#ifdef CONFIG_PCI_IOV
245 ppc_md.pcibios_sriov_enable = pseries_pcibios_sriov_enable;
246 ppc_md.pcibios_sriov_disable = pseries_pcibios_sriov_disable;
247#endif
79} 248}
80 249
81/* 250/*
diff --git a/arch/powerpc/platforms/pseries/pseries_energy.c b/arch/powerpc/platforms/pseries/pseries_energy.c
index 35c891aabef0..6ed22127391b 100644
--- a/arch/powerpc/platforms/pseries/pseries_energy.c
+++ b/arch/powerpc/platforms/pseries/pseries_energy.c
@@ -22,6 +22,7 @@
22#include <asm/page.h> 22#include <asm/page.h>
23#include <asm/hvcall.h> 23#include <asm/hvcall.h>
24#include <asm/firmware.h> 24#include <asm/firmware.h>
25#include <asm/prom.h>
25 26
26 27
27#define MODULE_VERS "1.0" 28#define MODULE_VERS "1.0"
@@ -38,26 +39,58 @@ static int sysfs_entries;
38static u32 cpu_to_drc_index(int cpu) 39static u32 cpu_to_drc_index(int cpu)
39{ 40{
40 struct device_node *dn = NULL; 41 struct device_node *dn = NULL;
41 const int *indexes; 42 int thread_index;
42 int i;
43 int rc = 1; 43 int rc = 1;
44 u32 ret = 0; 44 u32 ret = 0;
45 45
46 dn = of_find_node_by_path("/cpus"); 46 dn = of_find_node_by_path("/cpus");
47 if (dn == NULL) 47 if (dn == NULL)
48 goto err; 48 goto err;
49 indexes = of_get_property(dn, "ibm,drc-indexes", NULL); 49
50 if (indexes == NULL)
51 goto err_of_node_put;
52 /* Convert logical cpu number to core number */ 50 /* Convert logical cpu number to core number */
53 i = cpu_core_index_of_thread(cpu); 51 thread_index = cpu_core_index_of_thread(cpu);
54 /* 52
55 * The first element indexes[0] is the number of drc_indexes 53 if (firmware_has_feature(FW_FEATURE_DRC_INFO)) {
56 * returned in the list. Hence i+1 will get the drc_index 54 struct property *info = NULL;
57 * corresponding to core number i. 55 struct of_drc_info drc;
58 */ 56 int j;
59 WARN_ON(i > indexes[0]); 57 u32 num_set_entries;
60 ret = indexes[i + 1]; 58 const __be32 *value;
59
60 info = of_find_property(dn, "ibm,drc-info", NULL);
61 if (info == NULL)
62 goto err_of_node_put;
63
64 value = of_prop_next_u32(info, NULL, &num_set_entries);
65 if (!value)
66 goto err_of_node_put;
67
68 for (j = 0; j < num_set_entries; j++) {
69
70 of_read_drc_info_cell(&info, &value, &drc);
71 if (strncmp(drc.drc_type, "CPU", 3))
72 goto err;
73
74 if (thread_index < drc.last_drc_index)
75 break;
76 }
77
78 ret = drc.drc_index_start + (thread_index * drc.sequential_inc);
79 } else {
80 const __be32 *indexes;
81
82 indexes = of_get_property(dn, "ibm,drc-indexes", NULL);
83 if (indexes == NULL)
84 goto err_of_node_put;
85
86 /*
87 * The first element indexes[0] is the number of drc_indexes
88 * returned in the list. Hence thread_index+1 will get the
89 * drc_index corresponding to core number thread_index.
90 */
91 ret = indexes[thread_index + 1];
92 }
93
61 rc = 0; 94 rc = 0;
62 95
63err_of_node_put: 96err_of_node_put:
@@ -72,34 +105,71 @@ static int drc_index_to_cpu(u32 drc_index)
72{ 105{
73 struct device_node *dn = NULL; 106 struct device_node *dn = NULL;
74 const int *indexes; 107 const int *indexes;
75 int i, cpu = 0; 108 int thread_index = 0, cpu = 0;
76 int rc = 1; 109 int rc = 1;
77 110
78 dn = of_find_node_by_path("/cpus"); 111 dn = of_find_node_by_path("/cpus");
79 if (dn == NULL) 112 if (dn == NULL)
80 goto err; 113 goto err;
81 indexes = of_get_property(dn, "ibm,drc-indexes", NULL); 114
82 if (indexes == NULL) 115 if (firmware_has_feature(FW_FEATURE_DRC_INFO)) {
83 goto err_of_node_put; 116 struct property *info = NULL;
84 /* 117 struct of_drc_info drc;
85 * First element in the array is the number of drc_indexes 118 int j;
86 * returned. Search through the list to find the matching 119 u32 num_set_entries;
87 * drc_index and get the core number 120 const __be32 *value;
88 */ 121
89 for (i = 0; i < indexes[0]; i++) { 122 info = of_find_property(dn, "ibm,drc-info", NULL);
90 if (indexes[i + 1] == drc_index) 123 if (info == NULL)
124 goto err_of_node_put;
125
126 value = of_prop_next_u32(info, NULL, &num_set_entries);
127 if (!value)
128 goto err_of_node_put;
129
130 for (j = 0; j < num_set_entries; j++) {
131
132 of_read_drc_info_cell(&info, &value, &drc);
133 if (strncmp(drc.drc_type, "CPU", 3))
134 goto err;
135
136 if (drc_index > drc.last_drc_index) {
137 cpu += drc.num_sequential_elems;
138 continue;
139 }
140 cpu += ((drc_index - drc.drc_index_start) /
141 drc.sequential_inc);
142
143 thread_index = cpu_first_thread_of_core(cpu);
144 rc = 0;
91 break; 145 break;
146 }
147 } else {
148 unsigned long int i;
149
150 indexes = of_get_property(dn, "ibm,drc-indexes", NULL);
151 if (indexes == NULL)
152 goto err_of_node_put;
153 /*
154 * First element in the array is the number of drc_indexes
155 * returned. Search through the list to find the matching
156 * drc_index and get the core number
157 */
158 for (i = 0; i < indexes[0]; i++) {
159 if (indexes[i + 1] == drc_index)
160 break;
161 }
162 /* Convert core number to logical cpu number */
163 thread_index = cpu_first_thread_of_core(i);
164 rc = 0;
92 } 165 }
93 /* Convert core number to logical cpu number */
94 cpu = cpu_first_thread_of_core(i);
95 rc = 0;
96 166
97err_of_node_put: 167err_of_node_put:
98 of_node_put(dn); 168 of_node_put(dn);
99err: 169err:
100 if (rc) 170 if (rc)
101 printk(KERN_WARNING "drc_index_to_cpu(%d) failed", drc_index); 171 printk(KERN_WARNING "drc_index_to_cpu(%d) failed", drc_index);
102 return cpu; 172 return thread_index;
103} 173}
104 174
105/* 175/*
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index f24d8159c9e1..0e0208117e77 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -405,7 +405,7 @@ static int proc_ppc64_create_ofdt(void)
405{ 405{
406 struct proc_dir_entry *ent; 406 struct proc_dir_entry *ent;
407 407
408 ent = proc_create("powerpc/ofdt", S_IWUSR, NULL, &ofdt_fops); 408 ent = proc_create("powerpc/ofdt", 0200, NULL, &ofdt_fops);
409 if (ent) 409 if (ent)
410 proc_set_size(ent, 0); 410 proc_set_size(ent, 0);
411 411
diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c
index c47585a78b69..054ce7a16fc3 100644
--- a/arch/powerpc/platforms/pseries/scanlog.c
+++ b/arch/powerpc/platforms/pseries/scanlog.c
@@ -179,7 +179,7 @@ static int __init scanlog_init(void)
179 if (!scanlog_buffer) 179 if (!scanlog_buffer)
180 goto err; 180 goto err;
181 181
182 ent = proc_create("powerpc/rtas/scan-log-dump", S_IRUSR, NULL, 182 ent = proc_create("powerpc/rtas/scan-log-dump", 0400, NULL,
183 &scanlog_fops); 183 &scanlog_fops);
184 if (!ent) 184 if (!ent)
185 goto err; 185 goto err;
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index ae4f596273b5..372d7ada1a0c 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -371,8 +371,8 @@ void pseries_disable_reloc_on_exc(void)
371 mdelay(get_longbusy_msecs(rc)); 371 mdelay(get_longbusy_msecs(rc));
372 } 372 }
373 if (rc != H_SUCCESS) 373 if (rc != H_SUCCESS)
374 pr_warning("Warning: Failed to disable relocation on " 374 pr_warn("Warning: Failed to disable relocation on exceptions: %ld\n",
375 "exceptions: %ld\n", rc); 375 rc);
376} 376}
377EXPORT_SYMBOL(pseries_disable_reloc_on_exc); 377EXPORT_SYMBOL(pseries_disable_reloc_on_exc);
378 378
@@ -492,6 +492,162 @@ static void pseries_setup_rfi_flush(void)
492 setup_rfi_flush(types, enable); 492 setup_rfi_flush(types, enable);
493} 493}
494 494
495#ifdef CONFIG_PCI_IOV
496enum rtas_iov_fw_value_map {
497 NUM_RES_PROPERTY = 0, /* Number of Resources */
498 LOW_INT = 1, /* Lowest 32 bits of Address */
499 START_OF_ENTRIES = 2, /* Always start of entry */
500 APERTURE_PROPERTY = 2, /* Start of entry+ to Aperture Size */
501 WDW_SIZE_PROPERTY = 4, /* Start of entry+ to Window Size */
502 NEXT_ENTRY = 7 /* Go to next entry on array */
503};
504
505enum get_iov_fw_value_index {
506 BAR_ADDRS = 1, /* Get Bar Address */
507 APERTURE_SIZE = 2, /* Get Aperture Size */
508 WDW_SIZE = 3 /* Get Window Size */
509};
510
511resource_size_t pseries_get_iov_fw_value(struct pci_dev *dev, int resno,
512 enum get_iov_fw_value_index value)
513{
514 const int *indexes;
515 struct device_node *dn = pci_device_to_OF_node(dev);
516 int i, num_res, ret = 0;
517
518 indexes = of_get_property(dn, "ibm,open-sriov-vf-bar-info", NULL);
519 if (!indexes)
520 return 0;
521
522 /*
523 * First element in the array is the number of Bars
524 * returned. Search through the list to find the matching
525 * bar
526 */
527 num_res = of_read_number(&indexes[NUM_RES_PROPERTY], 1);
528 if (resno >= num_res)
529 return 0; /* or an errror */
530
531 i = START_OF_ENTRIES + NEXT_ENTRY * resno;
532 switch (value) {
533 case BAR_ADDRS:
534 ret = of_read_number(&indexes[i], 2);
535 break;
536 case APERTURE_SIZE:
537 ret = of_read_number(&indexes[i + APERTURE_PROPERTY], 2);
538 break;
539 case WDW_SIZE:
540 ret = of_read_number(&indexes[i + WDW_SIZE_PROPERTY], 2);
541 break;
542 }
543
544 return ret;
545}
546
547void of_pci_set_vf_bar_size(struct pci_dev *dev, const int *indexes)
548{
549 struct resource *res;
550 resource_size_t base, size;
551 int i, r, num_res;
552
553 num_res = of_read_number(&indexes[NUM_RES_PROPERTY], 1);
554 num_res = min_t(int, num_res, PCI_SRIOV_NUM_BARS);
555 for (i = START_OF_ENTRIES, r = 0; r < num_res && r < PCI_SRIOV_NUM_BARS;
556 i += NEXT_ENTRY, r++) {
557 res = &dev->resource[r + PCI_IOV_RESOURCES];
558 base = of_read_number(&indexes[i], 2);
559 size = of_read_number(&indexes[i + APERTURE_PROPERTY], 2);
560 res->flags = pci_parse_of_flags(of_read_number
561 (&indexes[i + LOW_INT], 1), 0);
562 res->flags |= (IORESOURCE_MEM_64 | IORESOURCE_PCI_FIXED);
563 res->name = pci_name(dev);
564 res->start = base;
565 res->end = base + size - 1;
566 }
567}
568
569void of_pci_parse_iov_addrs(struct pci_dev *dev, const int *indexes)
570{
571 struct resource *res, *root, *conflict;
572 resource_size_t base, size;
573 int i, r, num_res;
574
575 /*
576 * First element in the array is the number of Bars
577 * returned. Search through the list to find the matching
578 * bars assign them from firmware into resources structure.
579 */
580 num_res = of_read_number(&indexes[NUM_RES_PROPERTY], 1);
581 for (i = START_OF_ENTRIES, r = 0; r < num_res && r < PCI_SRIOV_NUM_BARS;
582 i += NEXT_ENTRY, r++) {
583 res = &dev->resource[r + PCI_IOV_RESOURCES];
584 base = of_read_number(&indexes[i], 2);
585 size = of_read_number(&indexes[i + WDW_SIZE_PROPERTY], 2);
586 res->name = pci_name(dev);
587 res->start = base;
588 res->end = base + size - 1;
589 root = &iomem_resource;
590 dev_dbg(&dev->dev,
591 "pSeries IOV BAR %d: trying firmware assignment %pR\n",
592 r + PCI_IOV_RESOURCES, res);
593 conflict = request_resource_conflict(root, res);
594 if (conflict) {
595 dev_info(&dev->dev,
596 "BAR %d: %pR conflicts with %s %pR\n",
597 r + PCI_IOV_RESOURCES, res,
598 conflict->name, conflict);
599 res->flags |= IORESOURCE_UNSET;
600 }
601 }
602}
603
604static void pseries_pci_fixup_resources(struct pci_dev *pdev)
605{
606 const int *indexes;
607 struct device_node *dn = pci_device_to_OF_node(pdev);
608
609 /*Firmware must support open sriov otherwise dont configure*/
610 indexes = of_get_property(dn, "ibm,open-sriov-vf-bar-info", NULL);
611 if (!indexes)
612 return;
613 /* Assign the addresses from device tree*/
614 of_pci_set_vf_bar_size(pdev, indexes);
615}
616
617static void pseries_pci_fixup_iov_resources(struct pci_dev *pdev)
618{
619 const int *indexes;
620 struct device_node *dn = pci_device_to_OF_node(pdev);
621
622 if (!pdev->is_physfn || pdev->is_added)
623 return;
624 /*Firmware must support open sriov otherwise dont configure*/
625 indexes = of_get_property(dn, "ibm,open-sriov-vf-bar-info", NULL);
626 if (!indexes)
627 return;
628 /* Assign the addresses from device tree*/
629 of_pci_parse_iov_addrs(pdev, indexes);
630}
631
632static resource_size_t pseries_pci_iov_resource_alignment(struct pci_dev *pdev,
633 int resno)
634{
635 const __be32 *reg;
636 struct device_node *dn = pci_device_to_OF_node(pdev);
637
638 /*Firmware must support open sriov otherwise report regular alignment*/
639 reg = of_get_property(dn, "ibm,is-open-sriov-pf", NULL);
640 if (!reg)
641 return pci_iov_resource_size(pdev, resno);
642
643 if (!pdev->is_physfn)
644 return 0;
645 return pseries_get_iov_fw_value(pdev,
646 resno - PCI_IOV_RESOURCES,
647 APERTURE_SIZE);
648}
649#endif
650
495static void __init pSeries_setup_arch(void) 651static void __init pSeries_setup_arch(void)
496{ 652{
497 set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT); 653 set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
@@ -525,6 +681,14 @@ static void __init pSeries_setup_arch(void)
525 vpa_init(boot_cpuid); 681 vpa_init(boot_cpuid);
526 ppc_md.power_save = pseries_lpar_idle; 682 ppc_md.power_save = pseries_lpar_idle;
527 ppc_md.enable_pmcs = pseries_lpar_enable_pmcs; 683 ppc_md.enable_pmcs = pseries_lpar_enable_pmcs;
684#ifdef CONFIG_PCI_IOV
685 ppc_md.pcibios_fixup_resources =
686 pseries_pci_fixup_resources;
687 ppc_md.pcibios_fixup_sriov =
688 pseries_pci_fixup_iov_resources;
689 ppc_md.pcibios_iov_resource_alignment =
690 pseries_pci_iov_resource_alignment;
691#endif
528 } else { 692 } else {
529 /* No special idle routine */ 693 /* No special idle routine */
530 ppc_md.enable_pmcs = power4_enable_pmcs; 694 ppc_md.enable_pmcs = power4_enable_pmcs;
@@ -533,6 +697,12 @@ static void __init pSeries_setup_arch(void)
533 ppc_md.pcibios_root_bridge_prepare = pseries_root_bridge_prepare; 697 ppc_md.pcibios_root_bridge_prepare = pseries_root_bridge_prepare;
534} 698}
535 699
700static void pseries_panic(char *str)
701{
702 panic_flush_kmsg_end();
703 rtas_os_term(str);
704}
705
536static int __init pSeries_init_panel(void) 706static int __init pSeries_init_panel(void)
537{ 707{
538 /* Manually leave the kernel version on the panel. */ 708 /* Manually leave the kernel version on the panel. */
@@ -761,7 +931,7 @@ define_machine(pseries) {
761 .pcibios_fixup = pSeries_final_fixup, 931 .pcibios_fixup = pSeries_final_fixup,
762 .restart = rtas_restart, 932 .restart = rtas_restart,
763 .halt = rtas_halt, 933 .halt = rtas_halt,
764 .panic = rtas_os_term, 934 .panic = pseries_panic,
765 .get_boot_time = rtas_get_boot_time, 935 .get_boot_time = rtas_get_boot_time,
766 .get_rtc_time = rtas_get_rtc_time, 936 .get_rtc_time = rtas_get_rtc_time,
767 .set_rtc_time = rtas_set_rtc_time, 937 .set_rtc_time = rtas_set_rtc_time,
diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c
index 89726f07d249..52a021e1f86b 100644
--- a/arch/powerpc/platforms/pseries/suspend.c
+++ b/arch/powerpc/platforms/pseries/suspend.c
@@ -214,8 +214,7 @@ static ssize_t show_hibernate(struct device *dev,
214 return sprintf(buf, "%d\n", KERN_DT_UPDATE); 214 return sprintf(buf, "%d\n", KERN_DT_UPDATE);
215} 215}
216 216
217static DEVICE_ATTR(hibernate, S_IWUSR | S_IRUGO, 217static DEVICE_ATTR(hibernate, 0644, show_hibernate, store_hibernate);
218 show_hibernate, store_hibernate);
219 218
220static struct bus_type suspend_subsys = { 219static struct bus_type suspend_subsys = {
221 .name = "power", 220 .name = "power",
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 0baba21404dc..9861407d644a 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -32,7 +32,6 @@ mv64x60-$(CONFIG_PCI) += mv64x60_pci.o
32obj-$(CONFIG_MV64X60) += $(mv64x60-y) mv64x60_pic.o mv64x60_dev.o \ 32obj-$(CONFIG_MV64X60) += $(mv64x60-y) mv64x60_pic.o mv64x60_dev.o \
33 mv64x60_udbg.o 33 mv64x60_udbg.o
34obj-$(CONFIG_RTC_DRV_CMOS) += rtc_cmos_setup.o 34obj-$(CONFIG_RTC_DRV_CMOS) += rtc_cmos_setup.o
35obj-$(CONFIG_AXON_RAM) += axonram.o
36 35
37obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o 36obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
38obj-$(CONFIG_PPC_I8259) += i8259.o 37obj-$(CONFIG_PPC_I8259) += i8259.o
@@ -43,7 +42,8 @@ obj-$(CONFIG_OF_RTC) += of_rtc.o
43 42
44obj-$(CONFIG_CPM) += cpm_common.o 43obj-$(CONFIG_CPM) += cpm_common.o
45obj-$(CONFIG_CPM1) += cpm1.o 44obj-$(CONFIG_CPM1) += cpm1.o
46obj-$(CONFIG_CPM2) += cpm2.o cpm2_pic.o 45obj-$(CONFIG_CPM2) += cpm2.o cpm2_pic.o cpm_gpio.o
46obj-$(CONFIG_8xx_GPIO) += cpm_gpio.o
47obj-$(CONFIG_QUICC_ENGINE) += cpm_common.o 47obj-$(CONFIG_QUICC_ENGINE) += cpm_common.o
48obj-$(CONFIG_PPC_DCR) += dcr.o 48obj-$(CONFIG_PPC_DCR) += dcr.o
49obj-$(CONFIG_UCODE_PATCH) += micropatch.o 49obj-$(CONFIG_UCODE_PATCH) += micropatch.o
diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c
deleted file mode 100644
index 1b307c80b401..000000000000
--- a/arch/powerpc/sysdev/axonram.c
+++ /dev/null
@@ -1,383 +0,0 @@
1/*
2 * (C) Copyright IBM Deutschland Entwicklung GmbH 2006
3 *
4 * Author: Maxim Shchetynin <maxim@de.ibm.com>
5 *
6 * Axon DDR2 device driver.
7 * It registers one block device per Axon's DDR2 memory bank found on a system.
8 * Block devices are called axonram?, their major and minor numbers are
9 * available in /proc/devices, /proc/partitions or in /sys/block/axonram?/dev.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/bio.h>
27#include <linux/blkdev.h>
28#include <linux/dax.h>
29#include <linux/device.h>
30#include <linux/errno.h>
31#include <linux/fs.h>
32#include <linux/genhd.h>
33#include <linux/interrupt.h>
34#include <linux/io.h>
35#include <linux/ioport.h>
36#include <linux/irq.h>
37#include <linux/irqreturn.h>
38#include <linux/kernel.h>
39#include <linux/mm.h>
40#include <linux/mod_devicetable.h>
41#include <linux/module.h>
42#include <linux/slab.h>
43#include <linux/string.h>
44#include <linux/types.h>
45#include <linux/of_device.h>
46#include <linux/of_platform.h>
47#include <linux/pfn_t.h>
48#include <linux/uio.h>
49
50#include <asm/page.h>
51#include <asm/prom.h>
52
53#define AXON_RAM_MODULE_NAME "axonram"
54#define AXON_RAM_DEVICE_NAME "axonram"
55#define AXON_RAM_MINORS_PER_DISK 16
56#define AXON_RAM_BLOCK_SHIFT PAGE_SHIFT
57#define AXON_RAM_BLOCK_SIZE 1 << AXON_RAM_BLOCK_SHIFT
58#define AXON_RAM_SECTOR_SHIFT 9
59#define AXON_RAM_SECTOR_SIZE 1 << AXON_RAM_SECTOR_SHIFT
60#define AXON_RAM_IRQ_FLAGS IRQF_SHARED | IRQF_TRIGGER_RISING
61
62static int azfs_major, azfs_minor;
63
64struct axon_ram_bank {
65 struct platform_device *device;
66 struct gendisk *disk;
67 struct dax_device *dax_dev;
68 unsigned int irq_id;
69 unsigned long ph_addr;
70 unsigned long io_addr;
71 unsigned long size;
72 unsigned long ecc_counter;
73};
74
75static ssize_t
76axon_ram_sysfs_ecc(struct device *dev, struct device_attribute *attr, char *buf)
77{
78 struct platform_device *device = to_platform_device(dev);
79 struct axon_ram_bank *bank = device->dev.platform_data;
80
81 BUG_ON(!bank);
82
83 return sprintf(buf, "%ld\n", bank->ecc_counter);
84}
85
86static DEVICE_ATTR(ecc, S_IRUGO, axon_ram_sysfs_ecc, NULL);
87
88/**
89 * axon_ram_irq_handler - interrupt handler for Axon RAM ECC
90 * @irq: interrupt ID
91 * @dev: pointer to of_device
92 */
93static irqreturn_t
94axon_ram_irq_handler(int irq, void *dev)
95{
96 struct platform_device *device = dev;
97 struct axon_ram_bank *bank = device->dev.platform_data;
98
99 BUG_ON(!bank);
100
101 dev_err(&device->dev, "Correctable memory error occurred\n");
102 bank->ecc_counter++;
103 return IRQ_HANDLED;
104}
105
106/**
107 * axon_ram_make_request - make_request() method for block device
108 * @queue, @bio: see blk_queue_make_request()
109 */
110static blk_qc_t
111axon_ram_make_request(struct request_queue *queue, struct bio *bio)
112{
113 struct axon_ram_bank *bank = bio->bi_disk->private_data;
114 unsigned long phys_mem, phys_end;
115 void *user_mem;
116 struct bio_vec vec;
117 unsigned int transfered;
118 struct bvec_iter iter;
119
120 phys_mem = bank->io_addr + (bio->bi_iter.bi_sector <<
121 AXON_RAM_SECTOR_SHIFT);
122 phys_end = bank->io_addr + bank->size;
123 transfered = 0;
124 bio_for_each_segment(vec, bio, iter) {
125 if (unlikely(phys_mem + vec.bv_len > phys_end)) {
126 bio_io_error(bio);
127 return BLK_QC_T_NONE;
128 }
129
130 user_mem = page_address(vec.bv_page) + vec.bv_offset;
131 if (bio_data_dir(bio) == READ)
132 memcpy(user_mem, (void *) phys_mem, vec.bv_len);
133 else
134 memcpy((void *) phys_mem, user_mem, vec.bv_len);
135
136 phys_mem += vec.bv_len;
137 transfered += vec.bv_len;
138 }
139 bio_endio(bio);
140 return BLK_QC_T_NONE;
141}
142
143static const struct block_device_operations axon_ram_devops = {
144 .owner = THIS_MODULE,
145};
146
147static long
148__axon_ram_direct_access(struct axon_ram_bank *bank, pgoff_t pgoff, long nr_pages,
149 void **kaddr, pfn_t *pfn)
150{
151 resource_size_t offset = pgoff * PAGE_SIZE;
152
153 *kaddr = (void *) bank->io_addr + offset;
154 *pfn = phys_to_pfn_t(bank->ph_addr + offset, PFN_DEV);
155 return (bank->size - offset) / PAGE_SIZE;
156}
157
158static long
159axon_ram_dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, long nr_pages,
160 void **kaddr, pfn_t *pfn)
161{
162 struct axon_ram_bank *bank = dax_get_private(dax_dev);
163
164 return __axon_ram_direct_access(bank, pgoff, nr_pages, kaddr, pfn);
165}
166
167static size_t axon_ram_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff,
168 void *addr, size_t bytes, struct iov_iter *i)
169{
170 return copy_from_iter(addr, bytes, i);
171}
172
173static const struct dax_operations axon_ram_dax_ops = {
174 .direct_access = axon_ram_dax_direct_access,
175 .copy_from_iter = axon_ram_copy_from_iter,
176};
177
178/**
179 * axon_ram_probe - probe() method for platform driver
180 * @device: see platform_driver method
181 */
182static int axon_ram_probe(struct platform_device *device)
183{
184 static int axon_ram_bank_id = -1;
185 struct axon_ram_bank *bank;
186 struct resource resource;
187 int rc;
188
189 axon_ram_bank_id++;
190
191 dev_info(&device->dev, "Found memory controller on %pOF\n",
192 device->dev.of_node);
193
194 bank = kzalloc(sizeof(*bank), GFP_KERNEL);
195 if (!bank)
196 return -ENOMEM;
197
198 device->dev.platform_data = bank;
199
200 bank->device = device;
201
202 if (of_address_to_resource(device->dev.of_node, 0, &resource) != 0) {
203 dev_err(&device->dev, "Cannot access device tree\n");
204 rc = -EFAULT;
205 goto failed;
206 }
207
208 bank->size = resource_size(&resource);
209
210 if (bank->size == 0) {
211 dev_err(&device->dev, "No DDR2 memory found for %s%d\n",
212 AXON_RAM_DEVICE_NAME, axon_ram_bank_id);
213 rc = -ENODEV;
214 goto failed;
215 }
216
217 dev_info(&device->dev, "Register DDR2 memory device %s%d with %luMB\n",
218 AXON_RAM_DEVICE_NAME, axon_ram_bank_id, bank->size >> 20);
219
220 bank->ph_addr = resource.start;
221 bank->io_addr = (unsigned long) ioremap_prot(
222 bank->ph_addr, bank->size, _PAGE_NO_CACHE);
223 if (bank->io_addr == 0) {
224 dev_err(&device->dev, "ioremap() failed\n");
225 rc = -EFAULT;
226 goto failed;
227 }
228
229 bank->disk = alloc_disk(AXON_RAM_MINORS_PER_DISK);
230 if (bank->disk == NULL) {
231 dev_err(&device->dev, "Cannot register disk\n");
232 rc = -EFAULT;
233 goto failed;
234 }
235
236
237 bank->disk->major = azfs_major;
238 bank->disk->first_minor = azfs_minor;
239 bank->disk->fops = &axon_ram_devops;
240 bank->disk->private_data = bank;
241
242 sprintf(bank->disk->disk_name, "%s%d",
243 AXON_RAM_DEVICE_NAME, axon_ram_bank_id);
244
245 bank->dax_dev = alloc_dax(bank, bank->disk->disk_name,
246 &axon_ram_dax_ops);
247 if (!bank->dax_dev) {
248 rc = -ENOMEM;
249 goto failed;
250 }
251
252 bank->disk->queue = blk_alloc_queue(GFP_KERNEL);
253 if (bank->disk->queue == NULL) {
254 dev_err(&device->dev, "Cannot register disk queue\n");
255 rc = -EFAULT;
256 goto failed;
257 }
258
259 set_capacity(bank->disk, bank->size >> AXON_RAM_SECTOR_SHIFT);
260 blk_queue_make_request(bank->disk->queue, axon_ram_make_request);
261 blk_queue_logical_block_size(bank->disk->queue, AXON_RAM_SECTOR_SIZE);
262 device_add_disk(&device->dev, bank->disk);
263
264 bank->irq_id = irq_of_parse_and_map(device->dev.of_node, 0);
265 if (!bank->irq_id) {
266 dev_err(&device->dev, "Cannot access ECC interrupt ID\n");
267 rc = -EFAULT;
268 goto failed;
269 }
270
271 rc = request_irq(bank->irq_id, axon_ram_irq_handler,
272 AXON_RAM_IRQ_FLAGS, bank->disk->disk_name, device);
273 if (rc != 0) {
274 dev_err(&device->dev, "Cannot register ECC interrupt handler\n");
275 bank->irq_id = 0;
276 rc = -EFAULT;
277 goto failed;
278 }
279
280 rc = device_create_file(&device->dev, &dev_attr_ecc);
281 if (rc != 0) {
282 dev_err(&device->dev, "Cannot create sysfs file\n");
283 rc = -EFAULT;
284 goto failed;
285 }
286
287 azfs_minor += bank->disk->minors;
288
289 return 0;
290
291failed:
292 if (bank->irq_id)
293 free_irq(bank->irq_id, device);
294 if (bank->disk != NULL) {
295 if (bank->disk->major > 0)
296 unregister_blkdev(bank->disk->major,
297 bank->disk->disk_name);
298 if (bank->disk->flags & GENHD_FL_UP)
299 del_gendisk(bank->disk);
300 put_disk(bank->disk);
301 }
302 kill_dax(bank->dax_dev);
303 put_dax(bank->dax_dev);
304 device->dev.platform_data = NULL;
305 if (bank->io_addr != 0)
306 iounmap((void __iomem *) bank->io_addr);
307 kfree(bank);
308 return rc;
309}
310
311/**
312 * axon_ram_remove - remove() method for platform driver
313 * @device: see of_platform_driver method
314 */
315static int
316axon_ram_remove(struct platform_device *device)
317{
318 struct axon_ram_bank *bank = device->dev.platform_data;
319
320 BUG_ON(!bank || !bank->disk);
321
322 device_remove_file(&device->dev, &dev_attr_ecc);
323 free_irq(bank->irq_id, device);
324 kill_dax(bank->dax_dev);
325 put_dax(bank->dax_dev);
326 del_gendisk(bank->disk);
327 put_disk(bank->disk);
328 iounmap((void __iomem *) bank->io_addr);
329 kfree(bank);
330
331 return 0;
332}
333
334static const struct of_device_id axon_ram_device_id[] = {
335 {
336 .type = "dma-memory"
337 },
338 {}
339};
340MODULE_DEVICE_TABLE(of, axon_ram_device_id);
341
342static struct platform_driver axon_ram_driver = {
343 .probe = axon_ram_probe,
344 .remove = axon_ram_remove,
345 .driver = {
346 .name = AXON_RAM_MODULE_NAME,
347 .of_match_table = axon_ram_device_id,
348 },
349};
350
351/**
352 * axon_ram_init
353 */
354static int __init
355axon_ram_init(void)
356{
357 azfs_major = register_blkdev(azfs_major, AXON_RAM_DEVICE_NAME);
358 if (azfs_major < 0) {
359 printk(KERN_ERR "%s cannot become block device major number\n",
360 AXON_RAM_MODULE_NAME);
361 return -EFAULT;
362 }
363 azfs_minor = 0;
364
365 return platform_driver_register(&axon_ram_driver);
366}
367
368/**
369 * axon_ram_exit
370 */
371static void __exit
372axon_ram_exit(void)
373{
374 platform_driver_unregister(&axon_ram_driver);
375 unregister_blkdev(azfs_major, AXON_RAM_DEVICE_NAME);
376}
377
378module_init(axon_ram_init);
379module_exit(axon_ram_exit);
380
381MODULE_LICENSE("GPL");
382MODULE_AUTHOR("Maxim Shchetynin <maxim@de.ibm.com>");
383MODULE_DESCRIPTION("Axon DDR2 RAM device driver for IBM Cell BE");
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index c6f154b602fb..5240d3a74a10 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -629,8 +629,9 @@ static int cpm1_gpio16_dir_in(struct gpio_chip *gc, unsigned int gpio)
629 return 0; 629 return 0;
630} 630}
631 631
632int cpm1_gpiochip_add16(struct device_node *np) 632int cpm1_gpiochip_add16(struct device *dev)
633{ 633{
634 struct device_node *np = dev->of_node;
634 struct cpm1_gpio16_chip *cpm1_gc; 635 struct cpm1_gpio16_chip *cpm1_gc;
635 struct of_mm_gpio_chip *mm_gc; 636 struct of_mm_gpio_chip *mm_gc;
636 struct gpio_chip *gc; 637 struct gpio_chip *gc;
@@ -660,6 +661,8 @@ int cpm1_gpiochip_add16(struct device_node *np)
660 gc->get = cpm1_gpio16_get; 661 gc->get = cpm1_gpio16_get;
661 gc->set = cpm1_gpio16_set; 662 gc->set = cpm1_gpio16_set;
662 gc->to_irq = cpm1_gpio16_to_irq; 663 gc->to_irq = cpm1_gpio16_to_irq;
664 gc->parent = dev;
665 gc->owner = THIS_MODULE;
663 666
664 return of_mm_gpiochip_add_data(np, mm_gc, cpm1_gc); 667 return of_mm_gpiochip_add_data(np, mm_gc, cpm1_gc);
665} 668}
@@ -755,8 +758,9 @@ static int cpm1_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio)
755 return 0; 758 return 0;
756} 759}
757 760
758int cpm1_gpiochip_add32(struct device_node *np) 761int cpm1_gpiochip_add32(struct device *dev)
759{ 762{
763 struct device_node *np = dev->of_node;
760 struct cpm1_gpio32_chip *cpm1_gc; 764 struct cpm1_gpio32_chip *cpm1_gc;
761 struct of_mm_gpio_chip *mm_gc; 765 struct of_mm_gpio_chip *mm_gc;
762 struct gpio_chip *gc; 766 struct gpio_chip *gc;
@@ -776,31 +780,10 @@ int cpm1_gpiochip_add32(struct device_node *np)
776 gc->direction_output = cpm1_gpio32_dir_out; 780 gc->direction_output = cpm1_gpio32_dir_out;
777 gc->get = cpm1_gpio32_get; 781 gc->get = cpm1_gpio32_get;
778 gc->set = cpm1_gpio32_set; 782 gc->set = cpm1_gpio32_set;
783 gc->parent = dev;
784 gc->owner = THIS_MODULE;
779 785
780 return of_mm_gpiochip_add_data(np, mm_gc, cpm1_gc); 786 return of_mm_gpiochip_add_data(np, mm_gc, cpm1_gc);
781} 787}
782 788
783static int cpm_init_par_io(void)
784{
785 struct device_node *np;
786
787 for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank-a")
788 cpm1_gpiochip_add16(np);
789
790 for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank-b")
791 cpm1_gpiochip_add32(np);
792
793 for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank-c")
794 cpm1_gpiochip_add16(np);
795
796 for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank-d")
797 cpm1_gpiochip_add16(np);
798
799 /* Port E uses CPM2 layout */
800 for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank-e")
801 cpm2_gpiochip_add32(np);
802 return 0;
803}
804arch_initcall(cpm_init_par_io);
805
806#endif /* CONFIG_8xx_GPIO */ 789#endif /* CONFIG_8xx_GPIO */
diff --git a/arch/powerpc/sysdev/cpm2.c b/arch/powerpc/sysdev/cpm2.c
index f78ff841652c..07718b9a2c99 100644
--- a/arch/powerpc/sysdev/cpm2.c
+++ b/arch/powerpc/sysdev/cpm2.c
@@ -354,14 +354,3 @@ void cpm2_set_pin(int port, int pin, int flags)
354 else 354 else
355 clrbits32(&iop[port].odr, pin); 355 clrbits32(&iop[port].odr, pin);
356} 356}
357
358static int cpm_init_par_io(void)
359{
360 struct device_node *np;
361
362 for_each_compatible_node(np, NULL, "fsl,cpm2-pario-bank")
363 cpm2_gpiochip_add32(np);
364 return 0;
365}
366arch_initcall(cpm_init_par_io);
367
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c
index 51bf749a4f3a..b74508175b67 100644
--- a/arch/powerpc/sysdev/cpm_common.c
+++ b/arch/powerpc/sysdev/cpm_common.c
@@ -190,8 +190,9 @@ static int cpm2_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio)
190 return 0; 190 return 0;
191} 191}
192 192
193int cpm2_gpiochip_add32(struct device_node *np) 193int cpm2_gpiochip_add32(struct device *dev)
194{ 194{
195 struct device_node *np = dev->of_node;
195 struct cpm2_gpio32_chip *cpm2_gc; 196 struct cpm2_gpio32_chip *cpm2_gc;
196 struct of_mm_gpio_chip *mm_gc; 197 struct of_mm_gpio_chip *mm_gc;
197 struct gpio_chip *gc; 198 struct gpio_chip *gc;
@@ -211,6 +212,8 @@ int cpm2_gpiochip_add32(struct device_node *np)
211 gc->direction_output = cpm2_gpio32_dir_out; 212 gc->direction_output = cpm2_gpio32_dir_out;
212 gc->get = cpm2_gpio32_get; 213 gc->get = cpm2_gpio32_get;
213 gc->set = cpm2_gpio32_set; 214 gc->set = cpm2_gpio32_set;
215 gc->parent = dev;
216 gc->owner = THIS_MODULE;
214 217
215 return of_mm_gpiochip_add_data(np, mm_gc, cpm2_gc); 218 return of_mm_gpiochip_add_data(np, mm_gc, cpm2_gc);
216} 219}
diff --git a/arch/powerpc/sysdev/cpm_gpio.c b/arch/powerpc/sysdev/cpm_gpio.c
new file mode 100644
index 000000000000..0badc90be666
--- /dev/null
+++ b/arch/powerpc/sysdev/cpm_gpio.c
@@ -0,0 +1,80 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Common CPM GPIO wrapper for the CPM GPIO ports
4 *
5 * Author: Christophe Leroy <christophe.leroy@c-s.fr>
6 *
7 * Copyright 2017 CS Systemes d'Information.
8 *
9 */
10
11#include <linux/module.h>
12#include <linux/of_device.h>
13
14#include <asm/cpm.h>
15#ifdef CONFIG_8xx_GPIO
16#include <asm/cpm1.h>
17#endif
18
19static int cpm_gpio_probe(struct platform_device *ofdev)
20{
21 struct device *dev = &ofdev->dev;
22 int (*gp_add)(struct device *dev) = of_device_get_match_data(dev);
23
24 if (!gp_add)
25 return -ENODEV;
26
27 return gp_add(dev);
28}
29
30static const struct of_device_id cpm_gpio_match[] = {
31#ifdef CONFIG_8xx_GPIO
32 {
33 .compatible = "fsl,cpm1-pario-bank-a",
34 .data = cpm1_gpiochip_add16,
35 },
36 {
37 .compatible = "fsl,cpm1-pario-bank-b",
38 .data = cpm1_gpiochip_add32,
39 },
40 {
41 .compatible = "fsl,cpm1-pario-bank-c",
42 .data = cpm1_gpiochip_add16,
43 },
44 {
45 .compatible = "fsl,cpm1-pario-bank-d",
46 .data = cpm1_gpiochip_add16,
47 },
48 /* Port E uses CPM2 layout */
49 {
50 .compatible = "fsl,cpm1-pario-bank-e",
51 .data = cpm2_gpiochip_add32,
52 },
53#endif
54 {
55 .compatible = "fsl,cpm2-pario-bank",
56 .data = cpm2_gpiochip_add32,
57 },
58 {},
59};
60MODULE_DEVICE_TABLE(of, cpm_gpio_match);
61
62static struct platform_driver cpm_gpio_driver = {
63 .probe = cpm_gpio_probe,
64 .driver = {
65 .name = "cpm-gpio",
66 .owner = THIS_MODULE,
67 .of_match_table = cpm_gpio_match,
68 },
69};
70
71static int __init cpm_gpio_init(void)
72{
73 return platform_driver_register(&cpm_gpio_driver);
74}
75arch_initcall(cpm_gpio_init);
76
77MODULE_AUTHOR("Christophe Leroy <christophe.leroy@c-s.fr>");
78MODULE_DESCRIPTION("Driver for CPM GPIO");
79MODULE_LICENSE("GPL");
80MODULE_ALIAS("platform:cpm-gpio");
diff --git a/arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c b/arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c
index 1707bf04dec6..94278e8af192 100644
--- a/arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c
+++ b/arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c
@@ -56,17 +56,16 @@ static ssize_t fsl_timer_wakeup_show(struct device *dev,
56 struct device_attribute *attr, 56 struct device_attribute *attr,
57 char *buf) 57 char *buf)
58{ 58{
59 struct timeval interval; 59 time64_t interval = 0;
60 int val = 0;
61 60
62 mutex_lock(&sysfs_lock); 61 mutex_lock(&sysfs_lock);
63 if (fsl_wakeup->timer) { 62 if (fsl_wakeup->timer) {
64 mpic_get_remain_time(fsl_wakeup->timer, &interval); 63 mpic_get_remain_time(fsl_wakeup->timer, &interval);
65 val = interval.tv_sec + 1; 64 interval++;
66 } 65 }
67 mutex_unlock(&sysfs_lock); 66 mutex_unlock(&sysfs_lock);
68 67
69 return sprintf(buf, "%d\n", val); 68 return sprintf(buf, "%lld\n", interval);
70} 69}
71 70
72static ssize_t fsl_timer_wakeup_store(struct device *dev, 71static ssize_t fsl_timer_wakeup_store(struct device *dev,
@@ -74,11 +73,10 @@ static ssize_t fsl_timer_wakeup_store(struct device *dev,
74 const char *buf, 73 const char *buf,
75 size_t count) 74 size_t count)
76{ 75{
77 struct timeval interval; 76 time64_t interval;
78 int ret; 77 int ret;
79 78
80 interval.tv_usec = 0; 79 if (kstrtoll(buf, 0, &interval))
81 if (kstrtol(buf, 0, &interval.tv_sec))
82 return -EINVAL; 80 return -EINVAL;
83 81
84 mutex_lock(&sysfs_lock); 82 mutex_lock(&sysfs_lock);
@@ -89,13 +87,13 @@ static ssize_t fsl_timer_wakeup_store(struct device *dev,
89 fsl_wakeup->timer = NULL; 87 fsl_wakeup->timer = NULL;
90 } 88 }
91 89
92 if (!interval.tv_sec) { 90 if (!interval) {
93 mutex_unlock(&sysfs_lock); 91 mutex_unlock(&sysfs_lock);
94 return count; 92 return count;
95 } 93 }
96 94
97 fsl_wakeup->timer = mpic_request_timer(fsl_mpic_timer_irq, 95 fsl_wakeup->timer = mpic_request_timer(fsl_mpic_timer_irq,
98 fsl_wakeup, &interval); 96 fsl_wakeup, interval);
99 if (!fsl_wakeup->timer) { 97 if (!fsl_wakeup->timer) {
100 mutex_unlock(&sysfs_lock); 98 mutex_unlock(&sysfs_lock);
101 return -EINVAL; 99 return -EINVAL;
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 61e07c78d64f..918be816b097 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -448,7 +448,7 @@ static void setup_pci_atmu(struct pci_controller *hose)
448#endif 448#endif
449 /* adjusting outbound windows could reclaim space in mem map */ 449 /* adjusting outbound windows could reclaim space in mem map */
450 if (paddr_hi < 0xffffffffull) 450 if (paddr_hi < 0xffffffffull)
451 pr_warning("%pOF: WARNING: Outbound window cfg leaves " 451 pr_warn("%pOF: WARNING: Outbound window cfg leaves "
452 "gaps in memory map. Adjusting the memory map " 452 "gaps in memory map. Adjusting the memory map "
453 "could reduce unnecessary bounce buffering.\n", 453 "could reduce unnecessary bounce buffering.\n",
454 hose->dn); 454 hose->dn);
@@ -531,7 +531,7 @@ int fsl_add_bridge(struct platform_device *pdev, int is_primary)
531 dev = pdev->dev.of_node; 531 dev = pdev->dev.of_node;
532 532
533 if (!of_device_is_available(dev)) { 533 if (!of_device_is_available(dev)) {
534 pr_warning("%pOF: disabled\n", dev); 534 pr_warn("%pOF: disabled\n", dev);
535 return -ENODEV; 535 return -ENODEV;
536 } 536 }
537 537
@@ -808,8 +808,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
808 is_mpc83xx_pci = 1; 808 is_mpc83xx_pci = 1;
809 809
810 if (!of_device_is_available(dev)) { 810 if (!of_device_is_available(dev)) {
811 pr_warning("%pOF: disabled by the firmware.\n", 811 pr_warn("%pOF: disabled by the firmware.\n",
812 dev); 812 dev);
813 return -ENODEV; 813 return -ENODEV;
814 } 814 }
815 pr_debug("Adding PCI host bridge %pOF\n", dev); 815 pr_debug("Adding PCI host bridge %pOF\n", dev);
@@ -1070,7 +1070,7 @@ int fsl_pci_mcheck_exception(struct pt_regs *regs)
1070 if (is_in_pci_mem_space(addr)) { 1070 if (is_in_pci_mem_space(addr)) {
1071 if (user_mode(regs)) { 1071 if (user_mode(regs)) {
1072 pagefault_disable(); 1072 pagefault_disable();
1073 ret = get_user(regs->nip, &inst); 1073 ret = get_user(inst, (__u32 __user *)regs->nip);
1074 pagefault_enable(); 1074 pagefault_enable();
1075 } else { 1075 } else {
1076 ret = probe_kernel_address((void *)regs->nip, inst); 1076 ret = probe_kernel_address((void *)regs->nip, inst);
@@ -1304,10 +1304,8 @@ static int add_err_dev(struct platform_device *pdev)
1304 pdev->resource, 1304 pdev->resource,
1305 pdev->num_resources, 1305 pdev->num_resources,
1306 &pd, sizeof(pd)); 1306 &pd, sizeof(pd));
1307 if (IS_ERR(errdev))
1308 return PTR_ERR(errdev);
1309 1307
1310 return 0; 1308 return PTR_ERR_OR_ZERO(errdev);
1311} 1309}
1312 1310
1313static int fsl_pci_probe(struct platform_device *pdev) 1311static int fsl_pci_probe(struct platform_device *pdev)
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index ead3e2549ebf..73067805300a 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -1008,9 +1008,8 @@ static int mpic_host_map(struct irq_domain *h, unsigned int virq,
1008 if (hw == mpic->spurious_vec) 1008 if (hw == mpic->spurious_vec)
1009 return -EINVAL; 1009 return -EINVAL;
1010 if (mpic->protected && test_bit(hw, mpic->protected)) { 1010 if (mpic->protected && test_bit(hw, mpic->protected)) {
1011 pr_warning("mpic: Mapping of source 0x%x failed, " 1011 pr_warn("mpic: Mapping of source 0x%x failed, source protected by firmware !\n",
1012 "source protected by firmware !\n",\ 1012 (unsigned int)hw);
1013 (unsigned int)hw);
1014 return -EPERM; 1013 return -EPERM;
1015 } 1014 }
1016 1015
@@ -1040,9 +1039,8 @@ static int mpic_host_map(struct irq_domain *h, unsigned int virq,
1040 return 0; 1039 return 0;
1041 1040
1042 if (hw >= mpic->num_sources) { 1041 if (hw >= mpic->num_sources) {
1043 pr_warning("mpic: Mapping of source 0x%x failed, " 1042 pr_warn("mpic: Mapping of source 0x%x failed, source out of range !\n",
1044 "source out of range !\n",\ 1043 (unsigned int)hw);
1045 (unsigned int)hw);
1046 return -EINVAL; 1044 return -EINVAL;
1047 } 1045 }
1048 1046
diff --git a/arch/powerpc/sysdev/mpic_timer.c b/arch/powerpc/sysdev/mpic_timer.c
index a418579591be..87e7c42777a8 100644
--- a/arch/powerpc/sysdev/mpic_timer.c
+++ b/arch/powerpc/sysdev/mpic_timer.c
@@ -47,9 +47,6 @@
47#define MAX_TICKS_CASCADE (~0U) 47#define MAX_TICKS_CASCADE (~0U)
48#define TIMER_OFFSET(num) (1 << (TIMERS_PER_GROUP - 1 - num)) 48#define TIMER_OFFSET(num) (1 << (TIMERS_PER_GROUP - 1 - num))
49 49
50/* tv_usec should be less than ONE_SECOND, otherwise use tv_sec */
51#define ONE_SECOND 1000000
52
53struct timer_regs { 50struct timer_regs {
54 u32 gtccr; 51 u32 gtccr;
55 u32 res0[3]; 52 u32 res0[3];
@@ -90,51 +87,23 @@ static struct cascade_priv cascade_timer[] = {
90static LIST_HEAD(timer_group_list); 87static LIST_HEAD(timer_group_list);
91 88
92static void convert_ticks_to_time(struct timer_group_priv *priv, 89static void convert_ticks_to_time(struct timer_group_priv *priv,
93 const u64 ticks, struct timeval *time) 90 const u64 ticks, time64_t *time)
94{ 91{
95 u64 tmp_sec; 92 *time = (u64)div_u64(ticks, priv->timerfreq);
96
97 time->tv_sec = (__kernel_time_t)div_u64(ticks, priv->timerfreq);
98 tmp_sec = (u64)time->tv_sec * (u64)priv->timerfreq;
99
100 time->tv_usec = 0;
101
102 if (tmp_sec <= ticks)
103 time->tv_usec = (__kernel_suseconds_t)
104 div_u64((ticks - tmp_sec) * 1000000, priv->timerfreq);
105
106 return;
107} 93}
108 94
109/* the time set by the user is converted to "ticks" */ 95/* the time set by the user is converted to "ticks" */
110static int convert_time_to_ticks(struct timer_group_priv *priv, 96static int convert_time_to_ticks(struct timer_group_priv *priv,
111 const struct timeval *time, u64 *ticks) 97 time64_t time, u64 *ticks)
112{ 98{
113 u64 max_value; /* prevent u64 overflow */ 99 u64 max_value; /* prevent u64 overflow */
114 u64 tmp = 0;
115
116 u64 tmp_sec;
117 u64 tmp_ms;
118 u64 tmp_us;
119 100
120 max_value = div_u64(ULLONG_MAX, priv->timerfreq); 101 max_value = div_u64(ULLONG_MAX, priv->timerfreq);
121 102
122 if (time->tv_sec > max_value || 103 if (time > max_value)
123 (time->tv_sec == max_value && time->tv_usec > 0))
124 return -EINVAL; 104 return -EINVAL;
125 105
126 tmp_sec = (u64)time->tv_sec * (u64)priv->timerfreq; 106 *ticks = (u64)time * (u64)priv->timerfreq;
127 tmp += tmp_sec;
128
129 tmp_ms = time->tv_usec / 1000;
130 tmp_ms = div_u64((u64)tmp_ms * (u64)priv->timerfreq, 1000);
131 tmp += tmp_ms;
132
133 tmp_us = time->tv_usec % 1000;
134 tmp_us = div_u64((u64)tmp_us * (u64)priv->timerfreq, 1000000);
135 tmp += tmp_us;
136
137 *ticks = tmp;
138 107
139 return 0; 108 return 0;
140} 109}
@@ -223,7 +192,7 @@ static struct mpic_timer *get_cascade_timer(struct timer_group_priv *priv,
223 return allocated_timer; 192 return allocated_timer;
224} 193}
225 194
226static struct mpic_timer *get_timer(const struct timeval *time) 195static struct mpic_timer *get_timer(time64_t time)
227{ 196{
228 struct timer_group_priv *priv; 197 struct timer_group_priv *priv;
229 struct mpic_timer *timer; 198 struct mpic_timer *timer;
@@ -277,7 +246,7 @@ static struct mpic_timer *get_timer(const struct timeval *time)
277 * @handle: the timer to be started. 246 * @handle: the timer to be started.
278 * 247 *
279 * It will do ->fn(->dev) callback from the hardware interrupt at 248 * It will do ->fn(->dev) callback from the hardware interrupt at
280 * the ->timeval point in the future. 249 * the 'time64_t' point in the future.
281 */ 250 */
282void mpic_start_timer(struct mpic_timer *handle) 251void mpic_start_timer(struct mpic_timer *handle)
283{ 252{
@@ -319,7 +288,7 @@ EXPORT_SYMBOL(mpic_stop_timer);
319 * 288 *
320 * Query timer remaining time. 289 * Query timer remaining time.
321 */ 290 */
322void mpic_get_remain_time(struct mpic_timer *handle, struct timeval *time) 291void mpic_get_remain_time(struct mpic_timer *handle, time64_t *time)
323{ 292{
324 struct timer_group_priv *priv = container_of(handle, 293 struct timer_group_priv *priv = container_of(handle,
325 struct timer_group_priv, timer[handle->num]); 294 struct timer_group_priv, timer[handle->num]);
@@ -391,7 +360,7 @@ EXPORT_SYMBOL(mpic_free_timer);
391 * else "handle" on success. 360 * else "handle" on success.
392 */ 361 */
393struct mpic_timer *mpic_request_timer(irq_handler_t fn, void *dev, 362struct mpic_timer *mpic_request_timer(irq_handler_t fn, void *dev,
394 const struct timeval *time) 363 time64_t time)
395{ 364{
396 struct mpic_timer *allocated_timer; 365 struct mpic_timer *allocated_timer;
397 int ret; 366 int ret;
@@ -399,11 +368,7 @@ struct mpic_timer *mpic_request_timer(irq_handler_t fn, void *dev,
399 if (list_empty(&timer_group_list)) 368 if (list_empty(&timer_group_list))
400 return NULL; 369 return NULL;
401 370
402 if (!(time->tv_sec + time->tv_usec) || 371 if (time < 0)
403 time->tv_sec < 0 || time->tv_usec < 0)
404 return NULL;
405
406 if (time->tv_usec > ONE_SECOND)
407 return NULL; 372 return NULL;
408 373
409 allocated_timer = get_timer(time); 374 allocated_timer = get_timer(time);
diff --git a/arch/powerpc/sysdev/mv64x60_pci.c b/arch/powerpc/sysdev/mv64x60_pci.c
index d52b3b81e05f..50c411b1761e 100644
--- a/arch/powerpc/sysdev/mv64x60_pci.c
+++ b/arch/powerpc/sysdev/mv64x60_pci.c
@@ -73,7 +73,7 @@ static ssize_t mv64x60_hs_reg_write(struct file *filp, struct kobject *kobj,
73static const struct bin_attribute mv64x60_hs_reg_attr = { /* Hotswap register */ 73static const struct bin_attribute mv64x60_hs_reg_attr = { /* Hotswap register */
74 .attr = { 74 .attr = {
75 .name = "hs_reg", 75 .name = "hs_reg",
76 .mode = S_IRUGO | S_IWUSR, 76 .mode = 0644,
77 }, 77 },
78 .size = MV64X60_VAL_LEN_MAX, 78 .size = MV64X60_VAL_LEN_MAX,
79 .read = mv64x60_hs_reg_read, 79 .read = mv64x60_hs_reg_read,
diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c
index 2bfb9968d562..1459f4e8b698 100644
--- a/arch/powerpc/sysdev/xics/icp-native.c
+++ b/arch/powerpc/sysdev/xics/icp-native.c
@@ -241,18 +241,16 @@ static int __init icp_native_map_one_cpu(int hw_id, unsigned long addr,
241 cpu, hw_id); 241 cpu, hw_id);
242 242
243 if (!request_mem_region(addr, size, rname)) { 243 if (!request_mem_region(addr, size, rname)) {
244 pr_warning("icp_native: Could not reserve ICP MMIO" 244 pr_warn("icp_native: Could not reserve ICP MMIO for CPU %d, interrupt server #0x%x\n",
245 " for CPU %d, interrupt server #0x%x\n", 245 cpu, hw_id);
246 cpu, hw_id);
247 return -EBUSY; 246 return -EBUSY;
248 } 247 }
249 248
250 icp_native_regs[cpu] = ioremap(addr, size); 249 icp_native_regs[cpu] = ioremap(addr, size);
251 kvmppc_set_xics_phys(cpu, addr); 250 kvmppc_set_xics_phys(cpu, addr);
252 if (!icp_native_regs[cpu]) { 251 if (!icp_native_regs[cpu]) {
253 pr_warning("icp_native: Failed ioremap for CPU %d, " 252 pr_warn("icp_native: Failed ioremap for CPU %d, interrupt server #0x%x, addr %#lx\n",
254 "interrupt server #0x%x, addr %#lx\n", 253 cpu, hw_id, addr);
255 cpu, hw_id, addr);
256 release_mem_region(addr, size); 254 release_mem_region(addr, size);
257 return -ENOMEM; 255 return -ENOMEM;
258 } 256 }
diff --git a/arch/powerpc/sysdev/xics/ics-opal.c b/arch/powerpc/sysdev/xics/ics-opal.c
index 1c6bf4b66f56..f85f916ba432 100644
--- a/arch/powerpc/sysdev/xics/ics-opal.c
+++ b/arch/powerpc/sysdev/xics/ics-opal.c
@@ -131,8 +131,8 @@ static int ics_opal_set_affinity(struct irq_data *d,
131 131
132 wanted_server = xics_get_irq_server(d->irq, cpumask, 1); 132 wanted_server = xics_get_irq_server(d->irq, cpumask, 1);
133 if (wanted_server < 0) { 133 if (wanted_server < 0) {
134 pr_warning("%s: No online cpus in the mask %*pb for irq %d\n", 134 pr_warn("%s: No online cpus in the mask %*pb for irq %d\n",
135 __func__, cpumask_pr_args(cpumask), d->irq); 135 __func__, cpumask_pr_args(cpumask), d->irq);
136 return -1; 136 return -1;
137 } 137 }
138 server = ics_opal_mangle_server(wanted_server); 138 server = ics_opal_mangle_server(wanted_server);
diff --git a/arch/powerpc/sysdev/xics/ics-rtas.c b/arch/powerpc/sysdev/xics/ics-rtas.c
index 42e0c56ff81c..6aabc74688a6 100644
--- a/arch/powerpc/sysdev/xics/ics-rtas.c
+++ b/arch/powerpc/sysdev/xics/ics-rtas.c
@@ -141,8 +141,8 @@ static int ics_rtas_set_affinity(struct irq_data *d,
141 141
142 irq_server = xics_get_irq_server(d->irq, cpumask, 1); 142 irq_server = xics_get_irq_server(d->irq, cpumask, 1);
143 if (irq_server == -1) { 143 if (irq_server == -1) {
144 pr_warning("%s: No online cpus in the mask %*pb for irq %d\n", 144 pr_warn("%s: No online cpus in the mask %*pb for irq %d\n",
145 __func__, cpumask_pr_args(cpumask), d->irq); 145 __func__, cpumask_pr_args(cpumask), d->irq);
146 return -1; 146 return -1;
147 } 147 }
148 148
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index ffe138b8b9dc..77e864d5506d 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -243,8 +243,8 @@ void xics_migrate_irqs_away(void)
243 243
244 /* This is expected during cpu offline. */ 244 /* This is expected during cpu offline. */
245 if (cpu_online(cpu)) 245 if (cpu_online(cpu))
246 pr_warning("IRQ %u affinity broken off cpu %u\n", 246 pr_warn("IRQ %u affinity broken off cpu %u\n",
247 virq, cpu); 247 virq, cpu);
248 248
249 /* Reset affinity to all cpus */ 249 /* Reset affinity to all cpus */
250 raw_spin_unlock_irqrestore(&desc->lock, flags); 250 raw_spin_unlock_irqrestore(&desc->lock, flags);
@@ -466,7 +466,7 @@ void __init xics_init(void)
466 rc = icp_opal_init(); 466 rc = icp_opal_init();
467 } 467 }
468 if (rc < 0) { 468 if (rc < 0) {
469 pr_warning("XICS: Cannot find a Presentation Controller !\n"); 469 pr_warn("XICS: Cannot find a Presentation Controller !\n");
470 return; 470 return;
471 } 471 }
472 472
@@ -481,7 +481,7 @@ void __init xics_init(void)
481 if (rc < 0) 481 if (rc < 0)
482 rc = ics_opal_init(); 482 rc = ics_opal_init();
483 if (rc < 0) 483 if (rc < 0)
484 pr_warning("XICS: Cannot find a Source Controller !\n"); 484 pr_warn("XICS: Cannot find a Source Controller !\n");
485 485
486 /* Initialize common bits */ 486 /* Initialize common bits */
487 xics_get_server_size(); 487 xics_get_server_size();
diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c
index a3b8d7d1316e..40c06110821c 100644
--- a/arch/powerpc/sysdev/xive/common.c
+++ b/arch/powerpc/sysdev/xive/common.c
@@ -367,7 +367,8 @@ static void xive_irq_eoi(struct irq_data *d)
367 * EOI the source if it hasn't been disabled and hasn't 367 * EOI the source if it hasn't been disabled and hasn't
368 * been passed-through to a KVM guest 368 * been passed-through to a KVM guest
369 */ 369 */
370 if (!irqd_irq_disabled(d) && !irqd_is_forwarded_to_vcpu(d)) 370 if (!irqd_irq_disabled(d) && !irqd_is_forwarded_to_vcpu(d) &&
371 !(xd->flags & XIVE_IRQ_NO_EOI))
371 xive_do_source_eoi(irqd_to_hwirq(d), xd); 372 xive_do_source_eoi(irqd_to_hwirq(d), xd);
372 373
373 /* 374 /*
@@ -1269,11 +1270,6 @@ static void xive_setup_cpu(void)
1269{ 1270{
1270 struct xive_cpu *xc = __this_cpu_read(xive_cpu); 1271 struct xive_cpu *xc = __this_cpu_read(xive_cpu);
1271 1272
1272 /* Debug: Dump the TM state */
1273 pr_devel("CPU %d [HW 0x%02x] VT=%02x\n",
1274 smp_processor_id(), hard_smp_processor_id(),
1275 in_8(xive_tima + xive_tima_offset + TM_WORD2));
1276
1277 /* The backend might have additional things to do */ 1273 /* The backend might have additional things to do */
1278 if (xive_ops->setup_cpu) 1274 if (xive_ops->setup_cpu)
1279 xive_ops->setup_cpu(smp_processor_id(), xc); 1275 xive_ops->setup_cpu(smp_processor_id(), xc);
diff --git a/arch/powerpc/xmon/ppc-dis.c b/arch/powerpc/xmon/ppc-dis.c
index 31db8c072acd..9deea5ee13f6 100644
--- a/arch/powerpc/xmon/ppc-dis.c
+++ b/arch/powerpc/xmon/ppc-dis.c
@@ -93,10 +93,6 @@ lookup_powerpc (unsigned long insn, ppc_cpu_t dialect)
93{ 93{
94 const struct powerpc_opcode *opcode; 94 const struct powerpc_opcode *opcode;
95 const struct powerpc_opcode *opcode_end; 95 const struct powerpc_opcode *opcode_end;
96 unsigned long op;
97
98 /* Get the major opcode of the instruction. */
99 op = PPC_OP (insn);
100 96
101 opcode_end = powerpc_opcodes + powerpc_num_opcodes; 97 opcode_end = powerpc_opcodes + powerpc_num_opcodes;
102 /* Find the first match in the opcode table for this major opcode. */ 98 /* Find the first match in the opcode table for this major opcode. */
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 0ddc7ac6c5f1..82e1a3ee6e0f 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -1623,7 +1623,7 @@ static void excprint(struct pt_regs *fp)
1623 printf(" current = 0x%lx\n", current); 1623 printf(" current = 0x%lx\n", current);
1624#ifdef CONFIG_PPC64 1624#ifdef CONFIG_PPC64
1625 printf(" paca = 0x%lx\t softe: %d\t irq_happened: 0x%02x\n", 1625 printf(" paca = 0x%lx\t softe: %d\t irq_happened: 0x%02x\n",
1626 local_paca, local_paca->soft_enabled, local_paca->irq_happened); 1626 local_paca, local_paca->irq_soft_mask, local_paca->irq_happened);
1627#endif 1627#endif
1628 if (current) { 1628 if (current) {
1629 printf(" pid = %ld, comm = %s\n", 1629 printf(" pid = %ld, comm = %s\n",
@@ -2377,8 +2377,6 @@ static void dump_one_paca(int cpu)
2377 printf(" slb_cache[%d]: = 0x%016lx\n", i, p->slb_cache[i]); 2377 printf(" slb_cache[%d]: = 0x%016lx\n", i, p->slb_cache[i]);
2378 2378
2379 DUMP(p, rfi_flush_fallback_area, "px"); 2379 DUMP(p, rfi_flush_fallback_area, "px");
2380 DUMP(p, l1d_flush_congruence, "llx");
2381 DUMP(p, l1d_flush_sets, "llx");
2382#endif 2380#endif
2383 DUMP(p, dscr_default, "llx"); 2381 DUMP(p, dscr_default, "llx");
2384#ifdef CONFIG_PPC_BOOK3E 2382#ifdef CONFIG_PPC_BOOK3E
@@ -2395,7 +2393,7 @@ static void dump_one_paca(int cpu)
2395 DUMP(p, stab_rr, "lx"); 2393 DUMP(p, stab_rr, "lx");
2396 DUMP(p, saved_r1, "lx"); 2394 DUMP(p, saved_r1, "lx");
2397 DUMP(p, trap_save, "x"); 2395 DUMP(p, trap_save, "x");
2398 DUMP(p, soft_enabled, "x"); 2396 DUMP(p, irq_soft_mask, "x");
2399 DUMP(p, irq_happened, "x"); 2397 DUMP(p, irq_happened, "x");
2400 DUMP(p, io_sync, "x"); 2398 DUMP(p, io_sync, "x");
2401 DUMP(p, irq_work_pending, "x"); 2399 DUMP(p, irq_work_pending, "x");
diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c
index e06605b21841..1a8234e706bc 100644
--- a/drivers/cpuidle/cpuidle-powernv.c
+++ b/drivers/cpuidle/cpuidle-powernv.c
@@ -76,6 +76,8 @@ static int snooze_loop(struct cpuidle_device *dev,
76 ppc64_runlatch_on(); 76 ppc64_runlatch_on();
77 clear_thread_flag(TIF_POLLING_NRFLAG); 77 clear_thread_flag(TIF_POLLING_NRFLAG);
78 78
79 local_irq_disable();
80
79 return index; 81 return index;
80} 82}
81 83
diff --git a/drivers/cpuidle/cpuidle-pseries.c b/drivers/cpuidle/cpuidle-pseries.c
index a187a39fb866..9e56bc411061 100644
--- a/drivers/cpuidle/cpuidle-pseries.c
+++ b/drivers/cpuidle/cpuidle-pseries.c
@@ -51,8 +51,6 @@ static inline void idle_loop_epilog(unsigned long in_purr)
51 get_lppaca()->wait_state_cycles = cpu_to_be64(wait_cycles); 51 get_lppaca()->wait_state_cycles = cpu_to_be64(wait_cycles);
52 get_lppaca()->idle = 0; 52 get_lppaca()->idle = 0;
53 53
54 if (irqs_disabled())
55 local_irq_enable();
56 ppc64_runlatch_on(); 54 ppc64_runlatch_on();
57} 55}
58 56
@@ -87,6 +85,8 @@ static int snooze_loop(struct cpuidle_device *dev,
87 HMT_medium(); 85 HMT_medium();
88 clear_thread_flag(TIF_POLLING_NRFLAG); 86 clear_thread_flag(TIF_POLLING_NRFLAG);
89 87
88 local_irq_disable();
89
90 idle_loop_epilog(in_purr); 90 idle_loop_epilog(in_purr);
91 91
92 return index; 92 return index;
@@ -121,6 +121,7 @@ static int dedicated_cede_loop(struct cpuidle_device *dev,
121 HMT_medium(); 121 HMT_medium();
122 check_and_cede_processor(); 122 check_and_cede_processor();
123 123
124 local_irq_disable();
124 get_lppaca()->donate_dedicated_cpu = 0; 125 get_lppaca()->donate_dedicated_cpu = 0;
125 126
126 idle_loop_epilog(in_purr); 127 idle_loop_epilog(in_purr);
@@ -145,6 +146,7 @@ static int shared_cede_loop(struct cpuidle_device *dev,
145 */ 146 */
146 check_and_cede_processor(); 147 check_and_cede_processor();
147 148
149 local_irq_disable();
148 idle_loop_epilog(in_purr); 150 idle_loop_epilog(in_purr);
149 151
150 return index; 152 return index;
@@ -172,11 +174,17 @@ static struct cpuidle_state dedicated_states[] = {
172 * States for shared partition case. 174 * States for shared partition case.
173 */ 175 */
174static struct cpuidle_state shared_states[] = { 176static struct cpuidle_state shared_states[] = {
177 { /* Snooze */
178 .name = "snooze",
179 .desc = "snooze",
180 .exit_latency = 0,
181 .target_residency = 0,
182 .enter = &snooze_loop },
175 { /* Shared Cede */ 183 { /* Shared Cede */
176 .name = "Shared Cede", 184 .name = "Shared Cede",
177 .desc = "Shared Cede", 185 .desc = "Shared Cede",
178 .exit_latency = 0, 186 .exit_latency = 10,
179 .target_residency = 0, 187 .target_residency = 100,
180 .enter = &shared_cede_loop }, 188 .enter = &shared_cede_loop },
181}; 189};
182 190
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index 289800b5235d..4c8097e0e6fe 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -203,18 +203,17 @@ static int adb_scan_bus(void)
203 } 203 }
204 204
205 /* Now fill in the handler_id field of the adb_handler entries. */ 205 /* Now fill in the handler_id field of the adb_handler entries. */
206 printk(KERN_DEBUG "adb devices:"); 206 pr_debug("adb devices:\n");
207 for (i = 1; i < 16; i++) { 207 for (i = 1; i < 16; i++) {
208 if (adb_handler[i].original_address == 0) 208 if (adb_handler[i].original_address == 0)
209 continue; 209 continue;
210 adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1, 210 adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
211 (i << 4) | 0xf); 211 (i << 4) | 0xf);
212 adb_handler[i].handler_id = req.reply[2]; 212 adb_handler[i].handler_id = req.reply[2];
213 printk(" [%d]: %d %x", i, adb_handler[i].original_address, 213 pr_debug(" [%d]: %d %x\n", i, adb_handler[i].original_address,
214 adb_handler[i].handler_id); 214 adb_handler[i].handler_id);
215 devmask |= 1 << i; 215 devmask |= 1 << i;
216 } 216 }
217 printk("\n");
218 return devmask; 217 return devmask;
219} 218}
220 219
@@ -225,9 +224,9 @@ static int adb_scan_bus(void)
225static int 224static int
226adb_probe_task(void *x) 225adb_probe_task(void *x)
227{ 226{
228 printk(KERN_INFO "adb: starting probe task...\n"); 227 pr_debug("adb: starting probe task...\n");
229 do_adb_reset_bus(); 228 do_adb_reset_bus();
230 printk(KERN_INFO "adb: finished probe task...\n"); 229 pr_debug("adb: finished probe task...\n");
231 230
232 up(&adb_probe_mutex); 231 up(&adb_probe_mutex);
233 232
@@ -337,7 +336,7 @@ static int __init adb_init(void)
337 adb_controller->init()) 336 adb_controller->init())
338 adb_controller = NULL; 337 adb_controller = NULL;
339 if (adb_controller == NULL) { 338 if (adb_controller == NULL) {
340 printk(KERN_WARNING "Warning: no ADB interface detected\n"); 339 pr_warn("Warning: no ADB interface detected\n");
341 } else { 340 } else {
342#ifdef CONFIG_PPC 341#ifdef CONFIG_PPC
343 if (of_machine_is_compatible("AAPL,PowerBook1998") || 342 if (of_machine_is_compatible("AAPL,PowerBook1998") ||
@@ -480,8 +479,7 @@ adb_register(int default_id, int handler_id, struct adb_ids *ids,
480 (!handler_id || (handler_id == adb_handler[i].handler_id) || 479 (!handler_id || (handler_id == adb_handler[i].handler_id) ||
481 try_handler_change(i, handler_id))) { 480 try_handler_change(i, handler_id))) {
482 if (adb_handler[i].handler != 0) { 481 if (adb_handler[i].handler != 0) {
483 printk(KERN_ERR 482 pr_err("Two handlers for ADB device %d\n",
484 "Two handlers for ADB device %d\n",
485 default_id); 483 default_id);
486 continue; 484 continue;
487 } 485 }
@@ -535,10 +533,10 @@ adb_input(unsigned char *buf, int nb, int autopoll)
535 533
536 id = buf[0] >> 4; 534 id = buf[0] >> 4;
537 if (dump_adb_input) { 535 if (dump_adb_input) {
538 printk(KERN_INFO "adb packet: "); 536 pr_info("adb packet: ");
539 for (i = 0; i < nb; ++i) 537 for (i = 0; i < nb; ++i)
540 printk(" %x", buf[i]); 538 pr_cont(" %x", buf[i]);
541 printk(", id = %d\n", id); 539 pr_cont(", id = %d\n", id);
542 } 540 }
543 write_lock_irqsave(&adb_handler_lock, flags); 541 write_lock_irqsave(&adb_handler_lock, flags);
544 handler = adb_handler[id].handler; 542 handler = adb_handler[id].handler;
@@ -884,7 +882,7 @@ static void __init
884adbdev_init(void) 882adbdev_init(void)
885{ 883{
886 if (register_chrdev(ADB_MAJOR, "adb", &adb_fops)) { 884 if (register_chrdev(ADB_MAJOR, "adb", &adb_fops)) {
887 printk(KERN_ERR "adb: unable to get major %d\n", ADB_MAJOR); 885 pr_err("adb: unable to get major %d\n", ADB_MAJOR);
888 return; 886 return;
889 } 887 }
890 888
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index e091193104f7..a261892c03b3 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -268,7 +268,7 @@ adbhid_keyboard_input(unsigned char *data, int nb, int apoll)
268 int id = (data[0] >> 4) & 0x0f; 268 int id = (data[0] >> 4) & 0x0f;
269 269
270 if (!adbhid[id]) { 270 if (!adbhid[id]) {
271 printk(KERN_ERR "ADB HID on ID %d not yet registered, packet %#02x, %#02x, %#02x, %#02x\n", 271 pr_err("ADB HID on ID %d not yet registered, packet %#02x, %#02x, %#02x, %#02x\n",
272 id, data[0], data[1], data[2], data[3]); 272 id, data[0], data[1], data[2], data[3]);
273 return; 273 return;
274 } 274 }
@@ -320,8 +320,7 @@ adbhid_input_keycode(int id, int scancode, int repeat)
320 ahid->flags &= ~FLAG_CAPSLOCK_TRANSLATE; 320 ahid->flags &= ~FLAG_CAPSLOCK_TRANSLATE;
321 } 321 }
322 } else { 322 } else {
323 printk(KERN_INFO "Spurious caps lock event " 323 pr_info("Spurious caps lock event (scancode 0xff).\n");
324 "(scancode 0xff).\n");
325 } 324 }
326 } 325 }
327 } 326 }
@@ -397,8 +396,8 @@ adbhid_input_keycode(int id, int scancode, int repeat)
397 input_report_key(adbhid[id]->input, key, !up_flag); 396 input_report_key(adbhid[id]->input, key, !up_flag);
398 input_sync(adbhid[id]->input); 397 input_sync(adbhid[id]->input);
399 } else 398 } else
400 printk(KERN_INFO "Unhandled ADB key (scancode %#02x) %s.\n", keycode, 399 pr_info("Unhandled ADB key (scancode %#02x) %s.\n", keycode,
401 up_flag ? "released" : "pressed"); 400 up_flag ? "released" : "pressed");
402 401
403} 402}
404 403
@@ -408,7 +407,7 @@ adbhid_mouse_input(unsigned char *data, int nb, int autopoll)
408 int id = (data[0] >> 4) & 0x0f; 407 int id = (data[0] >> 4) & 0x0f;
409 408
410 if (!adbhid[id]) { 409 if (!adbhid[id]) {
411 printk(KERN_ERR "ADB HID on ID %d not yet registered\n", id); 410 pr_err("ADB HID on ID %d not yet registered\n", id);
412 return; 411 return;
413 } 412 }
414 413
@@ -506,7 +505,7 @@ adbhid_buttons_input(unsigned char *data, int nb, int autopoll)
506 int id = (data[0] >> 4) & 0x0f; 505 int id = (data[0] >> 4) & 0x0f;
507 506
508 if (!adbhid[id]) { 507 if (!adbhid[id]) {
509 printk(KERN_ERR "ADB HID on ID %d not yet registered\n", id); 508 pr_err("ADB HID on ID %d not yet registered\n", id);
510 return; 509 return;
511 } 510 }
512 511
@@ -534,8 +533,8 @@ adbhid_buttons_input(unsigned char *data, int nb, int autopoll)
534 break; 533 break;
535 534
536 default: 535 default:
537 printk(KERN_INFO "Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n", 536 pr_info("Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n",
538 data[0], data[1], data[2], data[3]); 537 data[0], data[1], data[2], data[3]);
539 break; 538 break;
540 } 539 }
541 } 540 }
@@ -609,14 +608,14 @@ adbhid_buttons_input(unsigned char *data, int nb, int autopoll)
609 break; 608 break;
610 609
611 default: 610 default:
612 printk(KERN_INFO "Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n", 611 pr_info("Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n",
613 data[0], data[1], data[2], data[3]); 612 data[0], data[1], data[2], data[3]);
614 break; 613 break;
615 } 614 }
616 break; 615 break;
617 default: 616 default:
618 printk(KERN_INFO "Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n", 617 pr_info("Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n",
619 data[0], data[1], data[2], data[3]); 618 data[0], data[1], data[2], data[3]);
620 break; 619 break;
621 } 620 }
622 } 621 }
@@ -760,7 +759,7 @@ adbhid_input_register(int id, int default_id, int original_handler_id,
760 int i; 759 int i;
761 760
762 if (adbhid[id]) { 761 if (adbhid[id]) {
763 printk(KERN_ERR "Trying to reregister ADB HID on ID %d\n", id); 762 pr_err("Trying to reregister ADB HID on ID %d\n", id);
764 return -EEXIST; 763 return -EEXIST;
765 } 764 }
766 765
@@ -799,24 +798,24 @@ adbhid_input_register(int id, int default_id, int original_handler_id,
799 798
800 memcpy(hid->keycode, adb_to_linux_keycodes, sizeof(adb_to_linux_keycodes)); 799 memcpy(hid->keycode, adb_to_linux_keycodes, sizeof(adb_to_linux_keycodes));
801 800
802 printk(KERN_INFO "Detected ADB keyboard, type "); 801 pr_info("Detected ADB keyboard, type ");
803 switch (original_handler_id) { 802 switch (original_handler_id) {
804 default: 803 default:
805 printk("<unknown>.\n"); 804 pr_cont("<unknown>.\n");
806 input_dev->id.version = ADB_KEYBOARD_UNKNOWN; 805 input_dev->id.version = ADB_KEYBOARD_UNKNOWN;
807 break; 806 break;
808 807
809 case 0x01: case 0x02: case 0x03: case 0x06: case 0x08: 808 case 0x01: case 0x02: case 0x03: case 0x06: case 0x08:
810 case 0x0C: case 0x10: case 0x18: case 0x1B: case 0x1C: 809 case 0x0C: case 0x10: case 0x18: case 0x1B: case 0x1C:
811 case 0xC0: case 0xC3: case 0xC6: 810 case 0xC0: case 0xC3: case 0xC6:
812 printk("ANSI.\n"); 811 pr_cont("ANSI.\n");
813 input_dev->id.version = ADB_KEYBOARD_ANSI; 812 input_dev->id.version = ADB_KEYBOARD_ANSI;
814 break; 813 break;
815 814
816 case 0x04: case 0x05: case 0x07: case 0x09: case 0x0D: 815 case 0x04: case 0x05: case 0x07: case 0x09: case 0x0D:
817 case 0x11: case 0x14: case 0x19: case 0x1D: case 0xC1: 816 case 0x11: case 0x14: case 0x19: case 0x1D: case 0xC1:
818 case 0xC4: case 0xC7: 817 case 0xC4: case 0xC7:
819 printk("ISO, swapping keys.\n"); 818 pr_cont("ISO, swapping keys.\n");
820 input_dev->id.version = ADB_KEYBOARD_ISO; 819 input_dev->id.version = ADB_KEYBOARD_ISO;
821 i = hid->keycode[10]; 820 i = hid->keycode[10];
822 hid->keycode[10] = hid->keycode[50]; 821 hid->keycode[10] = hid->keycode[50];
@@ -825,7 +824,7 @@ adbhid_input_register(int id, int default_id, int original_handler_id,
825 824
826 case 0x12: case 0x15: case 0x16: case 0x17: case 0x1A: 825 case 0x12: case 0x15: case 0x16: case 0x17: case 0x1A:
827 case 0x1E: case 0xC2: case 0xC5: case 0xC8: case 0xC9: 826 case 0x1E: case 0xC2: case 0xC5: case 0xC8: case 0xC9:
828 printk("JIS.\n"); 827 pr_cont("JIS.\n");
829 input_dev->id.version = ADB_KEYBOARD_JIS; 828 input_dev->id.version = ADB_KEYBOARD_JIS;
830 break; 829 break;
831 } 830 }
@@ -884,7 +883,7 @@ adbhid_input_register(int id, int default_id, int original_handler_id,
884 /* else fall through */ 883 /* else fall through */
885 884
886 default: 885 default:
887 printk(KERN_INFO "Trying to register unknown ADB device to input layer.\n"); 886 pr_info("Trying to register unknown ADB device to input layer.\n");
888 err = -ENODEV; 887 err = -ENODEV;
889 goto fail; 888 goto fail;
890 } 889 }
@@ -1073,12 +1072,12 @@ adbhid_probe(void)
1073 (req.reply[1] == 0x4b) && (req.reply[2] == 0x4f) && 1072 (req.reply[1] == 0x4b) && (req.reply[2] == 0x4f) &&
1074 (req.reply[3] == 0x49) && (req.reply[4] == 0x54)) { 1073 (req.reply[3] == 0x49) && (req.reply[4] == 0x54)) {
1075 if (adb_try_handler_change(id, 0x42)) { 1074 if (adb_try_handler_change(id, 0x42)) {
1076 printk("\nADB MacAlly 2-button mouse at %d, handler set to 0x42", id); 1075 pr_cont("\nADB MacAlly 2-button mouse at %d, handler set to 0x42", id);
1077 mouse_kind = ADBMOUSE_MACALLY2; 1076 mouse_kind = ADBMOUSE_MACALLY2;
1078 } 1077 }
1079 } 1078 }
1080 } 1079 }
1081 printk("\n"); 1080 pr_cont("\n");
1082 1081
1083 adb_get_infos(id, &default_id, &cur_handler_id); 1082 adb_get_infos(id, &default_id, &cur_handler_id);
1084 reg |= adbhid_input_reregister(id, default_id, org_handler_id, 1083 reg |= adbhid_input_reregister(id, default_id, org_handler_id,
@@ -1093,12 +1092,12 @@ init_trackpad(int id)
1093 struct adb_request req; 1092 struct adb_request req;
1094 unsigned char r1_buffer[8]; 1093 unsigned char r1_buffer[8];
1095 1094
1096 printk(" (trackpad)"); 1095 pr_cont(" (trackpad)");
1097 1096
1098 adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1, 1097 adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
1099 ADB_READREG(id,1)); 1098 ADB_READREG(id,1));
1100 if (req.reply_len < 8) 1099 if (req.reply_len < 8)
1101 printk("bad length for reg. 1\n"); 1100 pr_cont("bad length for reg. 1\n");
1102 else 1101 else
1103 { 1102 {
1104 memcpy(r1_buffer, &req.reply[1], 8); 1103 memcpy(r1_buffer, &req.reply[1], 8);
@@ -1146,7 +1145,7 @@ init_trackball(int id)
1146{ 1145{
1147 struct adb_request req; 1146 struct adb_request req;
1148 1147
1149 printk(" (trackman/mouseman)"); 1148 pr_cont(" (trackman/mouseman)");
1150 1149
1151 adb_request(&req, NULL, ADBREQ_SYNC, 3, 1150 adb_request(&req, NULL, ADBREQ_SYNC, 3,
1152 ADB_WRITEREG(id,1), 00,0x81); 1151 ADB_WRITEREG(id,1), 00,0x81);
@@ -1178,7 +1177,7 @@ init_turbomouse(int id)
1178{ 1177{
1179 struct adb_request req; 1178 struct adb_request req;
1180 1179
1181 printk(" (TurboMouse 5)"); 1180 pr_cont(" (TurboMouse 5)");
1182 1181
1183 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id)); 1182 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
1184 1183
@@ -1214,7 +1213,7 @@ init_microspeed(int id)
1214{ 1213{
1215 struct adb_request req; 1214 struct adb_request req;
1216 1215
1217 printk(" (Microspeed/MacPoint or compatible)"); 1216 pr_cont(" (Microspeed/MacPoint or compatible)");
1218 1217
1219 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id)); 1218 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
1220 1219
@@ -1254,7 +1253,7 @@ init_ms_a3(int id)
1254{ 1253{
1255 struct adb_request req; 1254 struct adb_request req;
1256 1255
1257 printk(" (Mouse Systems A3 Mouse, or compatible)"); 1256 pr_cont(" (Mouse Systems A3 Mouse, or compatible)");
1258 adb_request(&req, NULL, ADBREQ_SYNC, 3, 1257 adb_request(&req, NULL, ADBREQ_SYNC, 3,
1259 ADB_WRITEREG(id, 0x2), 1258 ADB_WRITEREG(id, 0x2),
1260 0x00, 1259 0x00,
diff --git a/drivers/macintosh/ams/ams-input.c b/drivers/macintosh/ams/ams-input.c
index 2edae7dfcab2..fe248f6a30c1 100644
--- a/drivers/macintosh/ams/ams-input.c
+++ b/drivers/macintosh/ams/ams-input.c
@@ -91,7 +91,7 @@ static int ams_input_enable(void)
91 return error; 91 return error;
92 } 92 }
93 93
94 joystick = 1; 94 joystick = true;
95 95
96 return 0; 96 return 0;
97} 97}
@@ -104,7 +104,7 @@ static void ams_input_disable(void)
104 ams_info.idev = NULL; 104 ams_info.idev = NULL;
105 } 105 }
106 106
107 joystick = 0; 107 joystick = false;
108} 108}
109 109
110static ssize_t ams_input_show_joystick(struct device *dev, 110static ssize_t ams_input_show_joystick(struct device *dev,
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index f433521a6f9d..d7cd5afa38cd 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -230,7 +230,7 @@ static void update_fans_speed (struct thermostat *th)
230 230
231 /* we don't care about local sensor, so we start at sensor 1 */ 231 /* we don't care about local sensor, so we start at sensor 1 */
232 for (i = 1; i < 3; i++) { 232 for (i = 1; i < 3; i++) {
233 int started = 0; 233 bool started = false;
234 int fan_number = (th->type == ADT7460 && i == 2); 234 int fan_number = (th->type == ADT7460 && i == 2);
235 int var = th->temps[i] - th->limits[i]; 235 int var = th->temps[i] - th->limits[i];
236 236
@@ -243,7 +243,7 @@ static void update_fans_speed (struct thermostat *th)
243 if (abs(var - th->last_var[fan_number]) < 2) 243 if (abs(var - th->last_var[fan_number]) < 2)
244 continue; 244 continue;
245 245
246 started = 1; 246 started = true;
247 new_speed = fan_speed + ((var-1)*step); 247 new_speed = fan_speed + ((var-1)*step);
248 248
249 if (new_speed < fan_speed) 249 if (new_speed < fan_speed)
diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c
index 89ed51571b62..50ada02ae75d 100644
--- a/drivers/macintosh/via-pmu-backlight.c
+++ b/drivers/macintosh/via-pmu-backlight.c
@@ -137,7 +137,7 @@ void pmu_backlight_set_sleep(int sleep)
137} 137}
138#endif /* CONFIG_PM */ 138#endif /* CONFIG_PM */
139 139
140void __init pmu_backlight_init() 140void __init pmu_backlight_init(void)
141{ 141{
142 struct backlight_properties props; 142 struct backlight_properties props;
143 struct backlight_device *bd; 143 struct backlight_device *bd;
diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c
index 96d16fca68b2..fec91db1142e 100644
--- a/drivers/macintosh/windfarm_pm112.c
+++ b/drivers/macintosh/windfarm_pm112.c
@@ -96,14 +96,14 @@ static int cpu_last_target;
96static struct wf_pid_state backside_pid; 96static struct wf_pid_state backside_pid;
97static int backside_tick; 97static int backside_tick;
98static struct wf_pid_state slots_pid; 98static struct wf_pid_state slots_pid;
99static int slots_started; 99static bool slots_started;
100static struct wf_pid_state drive_bay_pid; 100static struct wf_pid_state drive_bay_pid;
101static int drive_bay_tick; 101static int drive_bay_tick;
102 102
103static int nr_cores; 103static int nr_cores;
104static int have_all_controls; 104static int have_all_controls;
105static int have_all_sensors; 105static int have_all_sensors;
106static int started; 106static bool started;
107 107
108static int failure_state; 108static int failure_state;
109#define FAILURE_SENSOR 1 109#define FAILURE_SENSOR 1
@@ -462,7 +462,7 @@ static void slots_fan_tick(void)
462 /* first time; initialize things */ 462 /* first time; initialize things */
463 printk(KERN_INFO "windfarm: Slots control loop started.\n"); 463 printk(KERN_INFO "windfarm: Slots control loop started.\n");
464 wf_pid_init(&slots_pid, &slots_param); 464 wf_pid_init(&slots_pid, &slots_param);
465 slots_started = 1; 465 slots_started = true;
466 } 466 }
467 467
468 err = slots_power->ops->get_value(slots_power, &power); 468 err = slots_power->ops->get_value(slots_power, &power);
@@ -506,7 +506,7 @@ static void pm112_tick(void)
506 int i, last_failure; 506 int i, last_failure;
507 507
508 if (!started) { 508 if (!started) {
509 started = 1; 509 started = true;
510 printk(KERN_INFO "windfarm: CPUs control loops started.\n"); 510 printk(KERN_INFO "windfarm: CPUs control loops started.\n");
511 for (i = 0; i < nr_cores; ++i) { 511 for (i = 0; i < nr_cores; ++i) {
512 if (create_cpu_loop(i) < 0) { 512 if (create_cpu_loop(i) < 0) {
diff --git a/drivers/macintosh/windfarm_pm121.c b/drivers/macintosh/windfarm_pm121.c
index b350fb86ff08..4d72d8f58cb6 100644
--- a/drivers/macintosh/windfarm_pm121.c
+++ b/drivers/macintosh/windfarm_pm121.c
@@ -246,7 +246,8 @@ enum {
246static struct wf_control *controls[N_CONTROLS] = {}; 246static struct wf_control *controls[N_CONTROLS] = {};
247 247
248/* Set to kick the control loop into life */ 248/* Set to kick the control loop into life */
249static int pm121_all_controls_ok, pm121_all_sensors_ok, pm121_started; 249static int pm121_all_controls_ok, pm121_all_sensors_ok;
250static bool pm121_started;
250 251
251enum { 252enum {
252 FAILURE_FAN = 1 << 0, 253 FAILURE_FAN = 1 << 0,
@@ -806,7 +807,7 @@ static void pm121_tick(void)
806 pm121_create_sys_fans(i); 807 pm121_create_sys_fans(i);
807 808
808 pm121_create_cpu_fans(); 809 pm121_create_cpu_fans();
809 pm121_started = 1; 810 pm121_started = true;
810 } 811 }
811 812
812 /* skipping ticks */ 813 /* skipping ticks */
diff --git a/drivers/macintosh/windfarm_pm72.c b/drivers/macintosh/windfarm_pm72.c
index e88cfb36a74d..833021508c05 100644
--- a/drivers/macintosh/windfarm_pm72.c
+++ b/drivers/macintosh/windfarm_pm72.c
@@ -611,7 +611,7 @@ static void pm72_tick(void)
611 int i, last_failure; 611 int i, last_failure;
612 612
613 if (!started) { 613 if (!started) {
614 started = 1; 614 started = true;
615 printk(KERN_INFO "windfarm: CPUs control loops started.\n"); 615 printk(KERN_INFO "windfarm: CPUs control loops started.\n");
616 for (i = 0; i < nr_chips; ++i) { 616 for (i = 0; i < nr_chips; ++i) {
617 if (cpu_setup_pid(i) < 0) { 617 if (cpu_setup_pid(i) < 0) {
diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c
index 93faf298a3c5..d9ea45581b9e 100644
--- a/drivers/macintosh/windfarm_pm81.c
+++ b/drivers/macintosh/windfarm_pm81.c
@@ -140,7 +140,8 @@ static struct wf_control *fan_system;
140static struct wf_control *cpufreq_clamp; 140static struct wf_control *cpufreq_clamp;
141 141
142/* Set to kick the control loop into life */ 142/* Set to kick the control loop into life */
143static int wf_smu_all_controls_ok, wf_smu_all_sensors_ok, wf_smu_started; 143static int wf_smu_all_controls_ok, wf_smu_all_sensors_ok;
144static bool wf_smu_started;
144 145
145/* Failure handling.. could be nicer */ 146/* Failure handling.. could be nicer */
146#define FAILURE_FAN 0x01 147#define FAILURE_FAN 0x01
@@ -549,7 +550,7 @@ static void wf_smu_tick(void)
549 DBG("wf: creating control loops !\n"); 550 DBG("wf: creating control loops !\n");
550 wf_smu_create_sys_fans(); 551 wf_smu_create_sys_fans();
551 wf_smu_create_cpu_fans(); 552 wf_smu_create_cpu_fans();
552 wf_smu_started = 1; 553 wf_smu_started = true;
553 } 554 }
554 555
555 /* Skipping ticks */ 556 /* Skipping ticks */
diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c
index 81fdf40c5b82..7fd73dcb2b0a 100644
--- a/drivers/macintosh/windfarm_pm91.c
+++ b/drivers/macintosh/windfarm_pm91.c
@@ -75,7 +75,8 @@ static struct wf_control *fan_slots;
75static struct wf_control *cpufreq_clamp; 75static struct wf_control *cpufreq_clamp;
76 76
77/* Set to kick the control loop into life */ 77/* Set to kick the control loop into life */
78static int wf_smu_all_controls_ok, wf_smu_all_sensors_ok, wf_smu_started; 78static int wf_smu_all_controls_ok, wf_smu_all_sensors_ok;
79static bool wf_smu_started;
79static bool wf_smu_overtemp; 80static bool wf_smu_overtemp;
80 81
81/* Failure handling.. could be nicer */ 82/* Failure handling.. could be nicer */
@@ -467,7 +468,7 @@ static void wf_smu_tick(void)
467 wf_smu_create_drive_fans(); 468 wf_smu_create_drive_fans();
468 wf_smu_create_slots_fans(); 469 wf_smu_create_slots_fans();
469 wf_smu_create_cpu_fans(); 470 wf_smu_create_cpu_fans();
470 wf_smu_started = 1; 471 wf_smu_started = true;
471 } 472 }
472 473
473 /* Skipping ticks */ 474 /* Skipping ticks */
diff --git a/drivers/macintosh/windfarm_rm31.c b/drivers/macintosh/windfarm_rm31.c
index a0cd9c7f9835..9ce87cc0597f 100644
--- a/drivers/macintosh/windfarm_rm31.c
+++ b/drivers/macintosh/windfarm_rm31.c
@@ -514,7 +514,7 @@ static void rm31_tick(void)
514 int i, last_failure; 514 int i, last_failure;
515 515
516 if (!started) { 516 if (!started) {
517 started = 1; 517 started = true;
518 printk(KERN_INFO "windfarm: CPUs control loops started.\n"); 518 printk(KERN_INFO "windfarm: CPUs control loops started.\n");
519 for (i = 0; i < nr_chips; ++i) { 519 for (i = 0; i < nr_chips; ++i) {
520 if (cpu_setup_pid(i) < 0) { 520 if (cpu_setup_pid(i) < 0) {
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 6722073e339b..03605f8fc0dc 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -512,5 +512,6 @@ source "drivers/misc/mic/Kconfig"
512source "drivers/misc/genwqe/Kconfig" 512source "drivers/misc/genwqe/Kconfig"
513source "drivers/misc/echo/Kconfig" 513source "drivers/misc/echo/Kconfig"
514source "drivers/misc/cxl/Kconfig" 514source "drivers/misc/cxl/Kconfig"
515source "drivers/misc/ocxl/Kconfig"
515source "drivers/misc/cardreader/Kconfig" 516source "drivers/misc/cardreader/Kconfig"
516endmenu 517endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 8d8cc096063b..c3c8624f4d95 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -55,7 +55,8 @@ obj-$(CONFIG_CXL_BASE) += cxl/
55obj-$(CONFIG_ASPEED_LPC_CTRL) += aspeed-lpc-ctrl.o 55obj-$(CONFIG_ASPEED_LPC_CTRL) += aspeed-lpc-ctrl.o
56obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o 56obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o
57obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o 57obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o
58obj-$(CONFIG_MISC_RTSX) += cardreader/ 58obj-$(CONFIG_OCXL) += ocxl/
59obj-$(CONFIG_MISC_RTSX) += cardreader/
59 60
60lkdtm-$(CONFIG_LKDTM) += lkdtm_core.o 61lkdtm-$(CONFIG_LKDTM) += lkdtm_core.o
61lkdtm-$(CONFIG_LKDTM) += lkdtm_bugs.o 62lkdtm-$(CONFIG_LKDTM) += lkdtm_bugs.o
diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c
index 12a41b2753f0..7ff315ad3692 100644
--- a/drivers/misc/cxl/context.c
+++ b/drivers/misc/cxl/context.c
@@ -45,6 +45,8 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master)
45 ctx->pid = NULL; /* Set in start work ioctl */ 45 ctx->pid = NULL; /* Set in start work ioctl */
46 mutex_init(&ctx->mapping_lock); 46 mutex_init(&ctx->mapping_lock);
47 ctx->mapping = NULL; 47 ctx->mapping = NULL;
48 ctx->tidr = 0;
49 ctx->assign_tidr = false;
48 50
49 if (cxl_is_power8()) { 51 if (cxl_is_power8()) {
50 spin_lock_init(&ctx->sste_lock); 52 spin_lock_init(&ctx->sste_lock);
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index a798c2ccd67d..4f015da78f28 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -630,6 +630,9 @@ struct cxl_context {
630 struct list_head extra_irq_contexts; 630 struct list_head extra_irq_contexts;
631 631
632 struct mm_struct *mm; 632 struct mm_struct *mm;
633
634 u16 tidr;
635 bool assign_tidr;
633}; 636};
634 637
635struct cxl_irq_info; 638struct cxl_irq_info;
diff --git a/drivers/misc/cxl/cxllib.c b/drivers/misc/cxl/cxllib.c
index dc9bc1807fdf..30ccba436b3b 100644
--- a/drivers/misc/cxl/cxllib.c
+++ b/drivers/misc/cxl/cxllib.c
@@ -199,10 +199,11 @@ int cxllib_get_PE_attributes(struct task_struct *task,
199 */ 199 */
200 attr->pid = mm->context.id; 200 attr->pid = mm->context.id;
201 mmput(mm); 201 mmput(mm);
202 attr->tid = task->thread.tidr;
202 } else { 203 } else {
203 attr->pid = 0; 204 attr->pid = 0;
205 attr->tid = 0;
204 } 206 }
205 attr->tid = 0;
206 return 0; 207 return 0;
207} 208}
208EXPORT_SYMBOL_GPL(cxllib_get_PE_attributes); 209EXPORT_SYMBOL_GPL(cxllib_get_PE_attributes);
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c
index 90341ccda9bd..0162516f5e57 100644
--- a/drivers/misc/cxl/file.c
+++ b/drivers/misc/cxl/file.c
@@ -173,7 +173,7 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
173 * flags are set it's invalid 173 * flags are set it's invalid
174 */ 174 */
175 if (work.reserved1 || work.reserved2 || work.reserved3 || 175 if (work.reserved1 || work.reserved2 || work.reserved3 ||
176 work.reserved4 || work.reserved5 || work.reserved6 || 176 work.reserved4 || work.reserved5 ||
177 (work.flags & ~CXL_START_WORK_ALL)) { 177 (work.flags & ~CXL_START_WORK_ALL)) {
178 rc = -EINVAL; 178 rc = -EINVAL;
179 goto out; 179 goto out;
@@ -186,12 +186,16 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
186 rc = -EINVAL; 186 rc = -EINVAL;
187 goto out; 187 goto out;
188 } 188 }
189
189 if ((rc = afu_register_irqs(ctx, work.num_interrupts))) 190 if ((rc = afu_register_irqs(ctx, work.num_interrupts)))
190 goto out; 191 goto out;
191 192
192 if (work.flags & CXL_START_WORK_AMR) 193 if (work.flags & CXL_START_WORK_AMR)
193 amr = work.amr & mfspr(SPRN_UAMOR); 194 amr = work.amr & mfspr(SPRN_UAMOR);
194 195
196 if (work.flags & CXL_START_WORK_TID)
197 ctx->assign_tidr = true;
198
195 ctx->mmio_err_ff = !!(work.flags & CXL_START_WORK_ERR_FF); 199 ctx->mmio_err_ff = !!(work.flags & CXL_START_WORK_ERR_FF);
196 200
197 /* 201 /*
@@ -263,8 +267,15 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
263 goto out; 267 goto out;
264 } 268 }
265 269
266 ctx->status = STARTED;
267 rc = 0; 270 rc = 0;
271 if (work.flags & CXL_START_WORK_TID) {
272 work.tid = ctx->tidr;
273 if (copy_to_user(uwork, &work, sizeof(work)))
274 rc = -EFAULT;
275 }
276
277 ctx->status = STARTED;
278
268out: 279out:
269 mutex_unlock(&ctx->status_mutex); 280 mutex_unlock(&ctx->status_mutex);
270 return rc; 281 return rc;
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
index 02b6b45b4c20..1b3d7c65ea3f 100644
--- a/drivers/misc/cxl/native.c
+++ b/drivers/misc/cxl/native.c
@@ -16,6 +16,7 @@
16#include <linux/uaccess.h> 16#include <linux/uaccess.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <asm/synch.h> 18#include <asm/synch.h>
19#include <asm/switch_to.h>
19#include <misc/cxl-base.h> 20#include <misc/cxl-base.h>
20 21
21#include "cxl.h" 22#include "cxl.h"
@@ -655,6 +656,7 @@ static void update_ivtes_directed(struct cxl_context *ctx)
655static int process_element_entry_psl9(struct cxl_context *ctx, u64 wed, u64 amr) 656static int process_element_entry_psl9(struct cxl_context *ctx, u64 wed, u64 amr)
656{ 657{
657 u32 pid; 658 u32 pid;
659 int rc;
658 660
659 cxl_assign_psn_space(ctx); 661 cxl_assign_psn_space(ctx);
660 662
@@ -673,7 +675,16 @@ static int process_element_entry_psl9(struct cxl_context *ctx, u64 wed, u64 amr)
673 pid = ctx->mm->context.id; 675 pid = ctx->mm->context.id;
674 } 676 }
675 677
676 ctx->elem->common.tid = 0; 678 /* Assign a unique TIDR (thread id) for the current thread */
679 if (!(ctx->tidr) && (ctx->assign_tidr)) {
680 rc = set_thread_tidr(current);
681 if (rc)
682 return -ENODEV;
683 ctx->tidr = current->thread.tidr;
684 pr_devel("%s: current tidr: %d\n", __func__, ctx->tidr);
685 }
686
687 ctx->elem->common.tid = cpu_to_be32(ctx->tidr);
677 ctx->elem->common.pid = cpu_to_be32(pid); 688 ctx->elem->common.pid = cpu_to_be32(pid);
678 689
679 ctx->elem->sr = cpu_to_be64(calculate_sr(ctx)); 690 ctx->elem->sr = cpu_to_be64(calculate_sr(ctx));
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index 19969ee86d6f..758842f65a1b 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -125,8 +125,6 @@ static const struct pci_device_id cxl_pci_tbl[] = {
125 { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0601), }, 125 { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0601), },
126 { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0623), }, 126 { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0623), },
127 { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0628), }, 127 { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0628), },
128 { PCI_DEVICE_CLASS(0x120000, ~0), },
129
130 { } 128 { }
131}; 129};
132MODULE_DEVICE_TABLE(pci, cxl_pci_tbl); 130MODULE_DEVICE_TABLE(pci, cxl_pci_tbl);
diff --git a/drivers/misc/ocxl/Kconfig b/drivers/misc/ocxl/Kconfig
new file mode 100644
index 000000000000..4bbdb0d3c8ee
--- /dev/null
+++ b/drivers/misc/ocxl/Kconfig
@@ -0,0 +1,31 @@
1#
2# Open Coherent Accelerator (OCXL) compatible devices
3#
4
5config OCXL_BASE
6 bool
7 default n
8 select PPC_COPRO_BASE
9
10config OCXL
11 tristate "OpenCAPI coherent accelerator support"
12 depends on PPC_POWERNV && PCI && EEH
13 select OCXL_BASE
14 default m
15 help
16 Select this option to enable the ocxl driver for Open
17 Coherent Accelerator Processor Interface (OpenCAPI) devices.
18
19 OpenCAPI allows FPGA and ASIC accelerators to be coherently
20 attached to a CPU over an OpenCAPI link.
21
22 The ocxl driver enables userspace programs to access these
23 accelerators through devices in /dev/ocxl/.
24
25 For more information, see http://opencapi.org.
26
27 This is not to be confused with the support for IBM CAPI
28 accelerators (CONFIG_CXL), which are PCI-based instead of a
29 dedicated OpenCAPI link, and don't follow the same protocol.
30
31 If unsure, say N.
diff --git a/drivers/misc/ocxl/Makefile b/drivers/misc/ocxl/Makefile
new file mode 100644
index 000000000000..5229dcda8297
--- /dev/null
+++ b/drivers/misc/ocxl/Makefile
@@ -0,0 +1,11 @@
1# SPDX-License-Identifier: GPL-2.0+
2ccflags-$(CONFIG_PPC_WERROR) += -Werror
3
4ocxl-y += main.o pci.o config.o file.o pasid.o
5ocxl-y += link.o context.o afu_irq.o sysfs.o trace.o
6obj-$(CONFIG_OCXL) += ocxl.o
7
8# For tracepoints to include our trace.h from tracepoint infrastructure:
9CFLAGS_trace.o := -I$(src)
10
11# ccflags-y += -DDEBUG
diff --git a/drivers/misc/ocxl/afu_irq.c b/drivers/misc/ocxl/afu_irq.c
new file mode 100644
index 000000000000..e70cfa24577f
--- /dev/null
+++ b/drivers/misc/ocxl/afu_irq.c
@@ -0,0 +1,202 @@
1// SPDX-License-Identifier: GPL-2.0+
2// Copyright 2017 IBM Corp.
3#include <linux/interrupt.h>
4#include <linux/eventfd.h>
5#include <asm/pnv-ocxl.h>
6#include "ocxl_internal.h"
7#include "trace.h"
8
9struct afu_irq {
10 int id;
11 int hw_irq;
12 unsigned int virq;
13 char *name;
14 u64 trigger_page;
15 struct eventfd_ctx *ev_ctx;
16};
17
18static int irq_offset_to_id(struct ocxl_context *ctx, u64 offset)
19{
20 return (offset - ctx->afu->irq_base_offset) >> PAGE_SHIFT;
21}
22
23static u64 irq_id_to_offset(struct ocxl_context *ctx, int id)
24{
25 return ctx->afu->irq_base_offset + (id << PAGE_SHIFT);
26}
27
28static irqreturn_t afu_irq_handler(int virq, void *data)
29{
30 struct afu_irq *irq = (struct afu_irq *) data;
31
32 trace_ocxl_afu_irq_receive(virq);
33 if (irq->ev_ctx)
34 eventfd_signal(irq->ev_ctx, 1);
35 return IRQ_HANDLED;
36}
37
38static int setup_afu_irq(struct ocxl_context *ctx, struct afu_irq *irq)
39{
40 int rc;
41
42 irq->virq = irq_create_mapping(NULL, irq->hw_irq);
43 if (!irq->virq) {
44 pr_err("irq_create_mapping failed\n");
45 return -ENOMEM;
46 }
47 pr_debug("hw_irq %d mapped to virq %u\n", irq->hw_irq, irq->virq);
48
49 irq->name = kasprintf(GFP_KERNEL, "ocxl-afu-%u", irq->virq);
50 if (!irq->name) {
51 irq_dispose_mapping(irq->virq);
52 return -ENOMEM;
53 }
54
55 rc = request_irq(irq->virq, afu_irq_handler, 0, irq->name, irq);
56 if (rc) {
57 kfree(irq->name);
58 irq->name = NULL;
59 irq_dispose_mapping(irq->virq);
60 pr_err("request_irq failed: %d\n", rc);
61 return rc;
62 }
63 return 0;
64}
65
66static void release_afu_irq(struct afu_irq *irq)
67{
68 free_irq(irq->virq, irq);
69 irq_dispose_mapping(irq->virq);
70 kfree(irq->name);
71}
72
73int ocxl_afu_irq_alloc(struct ocxl_context *ctx, u64 *irq_offset)
74{
75 struct afu_irq *irq;
76 int rc;
77
78 irq = kzalloc(sizeof(struct afu_irq), GFP_KERNEL);
79 if (!irq)
80 return -ENOMEM;
81
82 /*
83 * We limit the number of afu irqs per context and per link to
84 * avoid a single process or user depleting the pool of IPIs
85 */
86
87 mutex_lock(&ctx->irq_lock);
88
89 irq->id = idr_alloc(&ctx->irq_idr, irq, 0, MAX_IRQ_PER_CONTEXT,
90 GFP_KERNEL);
91 if (irq->id < 0) {
92 rc = -ENOSPC;
93 goto err_unlock;
94 }
95
96 rc = ocxl_link_irq_alloc(ctx->afu->fn->link, &irq->hw_irq,
97 &irq->trigger_page);
98 if (rc)
99 goto err_idr;
100
101 rc = setup_afu_irq(ctx, irq);
102 if (rc)
103 goto err_alloc;
104
105 *irq_offset = irq_id_to_offset(ctx, irq->id);
106
107 trace_ocxl_afu_irq_alloc(ctx->pasid, irq->id, irq->virq, irq->hw_irq,
108 *irq_offset);
109 mutex_unlock(&ctx->irq_lock);
110 return 0;
111
112err_alloc:
113 ocxl_link_free_irq(ctx->afu->fn->link, irq->hw_irq);
114err_idr:
115 idr_remove(&ctx->irq_idr, irq->id);
116err_unlock:
117 mutex_unlock(&ctx->irq_lock);
118 kfree(irq);
119 return rc;
120}
121
122static void afu_irq_free(struct afu_irq *irq, struct ocxl_context *ctx)
123{
124 trace_ocxl_afu_irq_free(ctx->pasid, irq->id);
125 if (ctx->mapping)
126 unmap_mapping_range(ctx->mapping,
127 irq_id_to_offset(ctx, irq->id),
128 1 << PAGE_SHIFT, 1);
129 release_afu_irq(irq);
130 if (irq->ev_ctx)
131 eventfd_ctx_put(irq->ev_ctx);
132 ocxl_link_free_irq(ctx->afu->fn->link, irq->hw_irq);
133 kfree(irq);
134}
135
136int ocxl_afu_irq_free(struct ocxl_context *ctx, u64 irq_offset)
137{
138 struct afu_irq *irq;
139 int id = irq_offset_to_id(ctx, irq_offset);
140
141 mutex_lock(&ctx->irq_lock);
142
143 irq = idr_find(&ctx->irq_idr, id);
144 if (!irq) {
145 mutex_unlock(&ctx->irq_lock);
146 return -EINVAL;
147 }
148 idr_remove(&ctx->irq_idr, irq->id);
149 afu_irq_free(irq, ctx);
150 mutex_unlock(&ctx->irq_lock);
151 return 0;
152}
153
154void ocxl_afu_irq_free_all(struct ocxl_context *ctx)
155{
156 struct afu_irq *irq;
157 int id;
158
159 mutex_lock(&ctx->irq_lock);
160 idr_for_each_entry(&ctx->irq_idr, irq, id)
161 afu_irq_free(irq, ctx);
162 mutex_unlock(&ctx->irq_lock);
163}
164
165int ocxl_afu_irq_set_fd(struct ocxl_context *ctx, u64 irq_offset, int eventfd)
166{
167 struct afu_irq *irq;
168 struct eventfd_ctx *ev_ctx;
169 int rc = 0, id = irq_offset_to_id(ctx, irq_offset);
170
171 mutex_lock(&ctx->irq_lock);
172 irq = idr_find(&ctx->irq_idr, id);
173 if (!irq) {
174 rc = -EINVAL;
175 goto unlock;
176 }
177
178 ev_ctx = eventfd_ctx_fdget(eventfd);
179 if (IS_ERR(ev_ctx)) {
180 rc = -EINVAL;
181 goto unlock;
182 }
183
184 irq->ev_ctx = ev_ctx;
185unlock:
186 mutex_unlock(&ctx->irq_lock);
187 return rc;
188}
189
190u64 ocxl_afu_irq_get_addr(struct ocxl_context *ctx, u64 irq_offset)
191{
192 struct afu_irq *irq;
193 int id = irq_offset_to_id(ctx, irq_offset);
194 u64 addr = 0;
195
196 mutex_lock(&ctx->irq_lock);
197 irq = idr_find(&ctx->irq_idr, id);
198 if (irq)
199 addr = irq->trigger_page;
200 mutex_unlock(&ctx->irq_lock);
201 return addr;
202}
diff --git a/drivers/misc/ocxl/config.c b/drivers/misc/ocxl/config.c
new file mode 100644
index 000000000000..2e30de9c694a
--- /dev/null
+++ b/drivers/misc/ocxl/config.c
@@ -0,0 +1,723 @@
1// SPDX-License-Identifier: GPL-2.0+
2// Copyright 2017 IBM Corp.
3#include <linux/pci.h>
4#include <asm/pnv-ocxl.h>
5#include <misc/ocxl.h>
6#include <misc/ocxl-config.h>
7
8#define EXTRACT_BIT(val, bit) (!!(val & BIT(bit)))
9#define EXTRACT_BITS(val, s, e) ((val & GENMASK(e, s)) >> s)
10
11#define OCXL_DVSEC_AFU_IDX_MASK GENMASK(5, 0)
12#define OCXL_DVSEC_ACTAG_MASK GENMASK(11, 0)
13#define OCXL_DVSEC_PASID_MASK GENMASK(19, 0)
14#define OCXL_DVSEC_PASID_LOG_MASK GENMASK(4, 0)
15
16#define OCXL_DVSEC_TEMPL_VERSION 0x0
17#define OCXL_DVSEC_TEMPL_NAME 0x4
18#define OCXL_DVSEC_TEMPL_AFU_VERSION 0x1C
19#define OCXL_DVSEC_TEMPL_MMIO_GLOBAL 0x20
20#define OCXL_DVSEC_TEMPL_MMIO_GLOBAL_SZ 0x28
21#define OCXL_DVSEC_TEMPL_MMIO_PP 0x30
22#define OCXL_DVSEC_TEMPL_MMIO_PP_SZ 0x38
23#define OCXL_DVSEC_TEMPL_MEM_SZ 0x3C
24#define OCXL_DVSEC_TEMPL_WWID 0x40
25
26#define OCXL_MAX_AFU_PER_FUNCTION 64
27#define OCXL_TEMPL_LEN 0x58
28#define OCXL_TEMPL_NAME_LEN 24
29#define OCXL_CFG_TIMEOUT 3
30
31static int find_dvsec(struct pci_dev *dev, int dvsec_id)
32{
33 int vsec = 0;
34 u16 vendor, id;
35
36 while ((vsec = pci_find_next_ext_capability(dev, vsec,
37 OCXL_EXT_CAP_ID_DVSEC))) {
38 pci_read_config_word(dev, vsec + OCXL_DVSEC_VENDOR_OFFSET,
39 &vendor);
40 pci_read_config_word(dev, vsec + OCXL_DVSEC_ID_OFFSET, &id);
41 if (vendor == PCI_VENDOR_ID_IBM && id == dvsec_id)
42 return vsec;
43 }
44 return 0;
45}
46
47static int find_dvsec_afu_ctrl(struct pci_dev *dev, u8 afu_idx)
48{
49 int vsec = 0;
50 u16 vendor, id;
51 u8 idx;
52
53 while ((vsec = pci_find_next_ext_capability(dev, vsec,
54 OCXL_EXT_CAP_ID_DVSEC))) {
55 pci_read_config_word(dev, vsec + OCXL_DVSEC_VENDOR_OFFSET,
56 &vendor);
57 pci_read_config_word(dev, vsec + OCXL_DVSEC_ID_OFFSET, &id);
58
59 if (vendor == PCI_VENDOR_ID_IBM &&
60 id == OCXL_DVSEC_AFU_CTRL_ID) {
61 pci_read_config_byte(dev,
62 vsec + OCXL_DVSEC_AFU_CTRL_AFU_IDX,
63 &idx);
64 if (idx == afu_idx)
65 return vsec;
66 }
67 }
68 return 0;
69}
70
71static int read_pasid(struct pci_dev *dev, struct ocxl_fn_config *fn)
72{
73 u16 val;
74 int pos;
75
76 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PASID);
77 if (!pos) {
78 /*
79 * PASID capability is not mandatory, but there
80 * shouldn't be any AFU
81 */
82 dev_dbg(&dev->dev, "Function doesn't require any PASID\n");
83 fn->max_pasid_log = -1;
84 goto out;
85 }
86 pci_read_config_word(dev, pos + PCI_PASID_CAP, &val);
87 fn->max_pasid_log = EXTRACT_BITS(val, 8, 12);
88
89out:
90 dev_dbg(&dev->dev, "PASID capability:\n");
91 dev_dbg(&dev->dev, " Max PASID log = %d\n", fn->max_pasid_log);
92 return 0;
93}
94
95static int read_dvsec_tl(struct pci_dev *dev, struct ocxl_fn_config *fn)
96{
97 int pos;
98
99 pos = find_dvsec(dev, OCXL_DVSEC_TL_ID);
100 if (!pos && PCI_FUNC(dev->devfn) == 0) {
101 dev_err(&dev->dev, "Can't find TL DVSEC\n");
102 return -ENODEV;
103 }
104 if (pos && PCI_FUNC(dev->devfn) != 0) {
105 dev_err(&dev->dev, "TL DVSEC is only allowed on function 0\n");
106 return -ENODEV;
107 }
108 fn->dvsec_tl_pos = pos;
109 return 0;
110}
111
112static int read_dvsec_function(struct pci_dev *dev, struct ocxl_fn_config *fn)
113{
114 int pos, afu_present;
115 u32 val;
116
117 pos = find_dvsec(dev, OCXL_DVSEC_FUNC_ID);
118 if (!pos) {
119 dev_err(&dev->dev, "Can't find function DVSEC\n");
120 return -ENODEV;
121 }
122 fn->dvsec_function_pos = pos;
123
124 pci_read_config_dword(dev, pos + OCXL_DVSEC_FUNC_OFF_INDEX, &val);
125 afu_present = EXTRACT_BIT(val, 31);
126 if (!afu_present) {
127 fn->max_afu_index = -1;
128 dev_dbg(&dev->dev, "Function doesn't define any AFU\n");
129 goto out;
130 }
131 fn->max_afu_index = EXTRACT_BITS(val, 24, 29);
132
133out:
134 dev_dbg(&dev->dev, "Function DVSEC:\n");
135 dev_dbg(&dev->dev, " Max AFU index = %d\n", fn->max_afu_index);
136 return 0;
137}
138
139static int read_dvsec_afu_info(struct pci_dev *dev, struct ocxl_fn_config *fn)
140{
141 int pos;
142
143 if (fn->max_afu_index < 0) {
144 fn->dvsec_afu_info_pos = -1;
145 return 0;
146 }
147
148 pos = find_dvsec(dev, OCXL_DVSEC_AFU_INFO_ID);
149 if (!pos) {
150 dev_err(&dev->dev, "Can't find AFU information DVSEC\n");
151 return -ENODEV;
152 }
153 fn->dvsec_afu_info_pos = pos;
154 return 0;
155}
156
157static int read_dvsec_vendor(struct pci_dev *dev)
158{
159 int pos;
160 u32 cfg, tlx, dlx;
161
162 /*
163 * vendor specific DVSEC is optional
164 *
165 * It's currently only used on function 0 to specify the
166 * version of some logic blocks. Some older images may not
167 * even have it so we ignore any errors
168 */
169 if (PCI_FUNC(dev->devfn) != 0)
170 return 0;
171
172 pos = find_dvsec(dev, OCXL_DVSEC_VENDOR_ID);
173 if (!pos)
174 return 0;
175
176 pci_read_config_dword(dev, pos + OCXL_DVSEC_VENDOR_CFG_VERS, &cfg);
177 pci_read_config_dword(dev, pos + OCXL_DVSEC_VENDOR_TLX_VERS, &tlx);
178 pci_read_config_dword(dev, pos + OCXL_DVSEC_VENDOR_DLX_VERS, &dlx);
179
180 dev_dbg(&dev->dev, "Vendor specific DVSEC:\n");
181 dev_dbg(&dev->dev, " CFG version = 0x%x\n", cfg);
182 dev_dbg(&dev->dev, " TLX version = 0x%x\n", tlx);
183 dev_dbg(&dev->dev, " DLX version = 0x%x\n", dlx);
184 return 0;
185}
186
187static int validate_function(struct pci_dev *dev, struct ocxl_fn_config *fn)
188{
189 if (fn->max_pasid_log == -1 && fn->max_afu_index >= 0) {
190 dev_err(&dev->dev,
191 "AFUs are defined but no PASIDs are requested\n");
192 return -EINVAL;
193 }
194
195 if (fn->max_afu_index > OCXL_MAX_AFU_PER_FUNCTION) {
196 dev_err(&dev->dev,
197 "Max AFU index out of architectural limit (%d vs %d)\n",
198 fn->max_afu_index, OCXL_MAX_AFU_PER_FUNCTION);
199 return -EINVAL;
200 }
201 return 0;
202}
203
204int ocxl_config_read_function(struct pci_dev *dev, struct ocxl_fn_config *fn)
205{
206 int rc;
207
208 rc = read_pasid(dev, fn);
209 if (rc) {
210 dev_err(&dev->dev, "Invalid PASID configuration: %d\n", rc);
211 return -ENODEV;
212 }
213
214 rc = read_dvsec_tl(dev, fn);
215 if (rc) {
216 dev_err(&dev->dev,
217 "Invalid Transaction Layer DVSEC configuration: %d\n",
218 rc);
219 return -ENODEV;
220 }
221
222 rc = read_dvsec_function(dev, fn);
223 if (rc) {
224 dev_err(&dev->dev,
225 "Invalid Function DVSEC configuration: %d\n", rc);
226 return -ENODEV;
227 }
228
229 rc = read_dvsec_afu_info(dev, fn);
230 if (rc) {
231 dev_err(&dev->dev, "Invalid AFU configuration: %d\n", rc);
232 return -ENODEV;
233 }
234
235 rc = read_dvsec_vendor(dev);
236 if (rc) {
237 dev_err(&dev->dev,
238 "Invalid vendor specific DVSEC configuration: %d\n",
239 rc);
240 return -ENODEV;
241 }
242
243 rc = validate_function(dev, fn);
244 return rc;
245}
246EXPORT_SYMBOL_GPL(ocxl_config_read_function);
247
248static int read_afu_info(struct pci_dev *dev, struct ocxl_fn_config *fn,
249 int offset, u32 *data)
250{
251 u32 val;
252 unsigned long timeout = jiffies + (HZ * OCXL_CFG_TIMEOUT);
253 int pos = fn->dvsec_afu_info_pos;
254
255 /* Protect 'data valid' bit */
256 if (EXTRACT_BIT(offset, 31)) {
257 dev_err(&dev->dev, "Invalid offset in AFU info DVSEC\n");
258 return -EINVAL;
259 }
260
261 pci_write_config_dword(dev, pos + OCXL_DVSEC_AFU_INFO_OFF, offset);
262 pci_read_config_dword(dev, pos + OCXL_DVSEC_AFU_INFO_OFF, &val);
263 while (!EXTRACT_BIT(val, 31)) {
264 if (time_after_eq(jiffies, timeout)) {
265 dev_err(&dev->dev,
266 "Timeout while reading AFU info DVSEC (offset=%d)\n",
267 offset);
268 return -EBUSY;
269 }
270 cpu_relax();
271 pci_read_config_dword(dev, pos + OCXL_DVSEC_AFU_INFO_OFF, &val);
272 }
273 pci_read_config_dword(dev, pos + OCXL_DVSEC_AFU_INFO_DATA, data);
274 return 0;
275}
276
277int ocxl_config_check_afu_index(struct pci_dev *dev,
278 struct ocxl_fn_config *fn, int afu_idx)
279{
280 u32 val;
281 int rc, templ_major, templ_minor, len;
282
283 pci_write_config_word(dev, fn->dvsec_afu_info_pos, afu_idx);
284 rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_VERSION, &val);
285 if (rc)
286 return rc;
287
288 /* AFU index map can have holes */
289 if (!val)
290 return 0;
291
292 templ_major = EXTRACT_BITS(val, 8, 15);
293 templ_minor = EXTRACT_BITS(val, 0, 7);
294 dev_dbg(&dev->dev, "AFU descriptor template version %d.%d\n",
295 templ_major, templ_minor);
296
297 len = EXTRACT_BITS(val, 16, 31);
298 if (len != OCXL_TEMPL_LEN) {
299 dev_warn(&dev->dev,
300 "Unexpected template length in AFU information (%#x)\n",
301 len);
302 }
303 return 1;
304}
305EXPORT_SYMBOL_GPL(ocxl_config_check_afu_index);
306
307static int read_afu_name(struct pci_dev *dev, struct ocxl_fn_config *fn,
308 struct ocxl_afu_config *afu)
309{
310 int i, rc;
311 u32 val, *ptr;
312
313 BUILD_BUG_ON(OCXL_AFU_NAME_SZ < OCXL_TEMPL_NAME_LEN);
314 for (i = 0; i < OCXL_TEMPL_NAME_LEN; i += 4) {
315 rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_NAME + i, &val);
316 if (rc)
317 return rc;
318 ptr = (u32 *) &afu->name[i];
319 *ptr = val;
320 }
321 afu->name[OCXL_AFU_NAME_SZ - 1] = '\0'; /* play safe */
322 return 0;
323}
324
325static int read_afu_mmio(struct pci_dev *dev, struct ocxl_fn_config *fn,
326 struct ocxl_afu_config *afu)
327{
328 int rc;
329 u32 val;
330
331 /*
332 * Global MMIO
333 */
334 rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_GLOBAL, &val);
335 if (rc)
336 return rc;
337 afu->global_mmio_bar = EXTRACT_BITS(val, 0, 2);
338 afu->global_mmio_offset = EXTRACT_BITS(val, 16, 31) << 16;
339
340 rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_GLOBAL + 4, &val);
341 if (rc)
342 return rc;
343 afu->global_mmio_offset += (u64) val << 32;
344
345 rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_GLOBAL_SZ, &val);
346 if (rc)
347 return rc;
348 afu->global_mmio_size = val;
349
350 /*
351 * Per-process MMIO
352 */
353 rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_PP, &val);
354 if (rc)
355 return rc;
356 afu->pp_mmio_bar = EXTRACT_BITS(val, 0, 2);
357 afu->pp_mmio_offset = EXTRACT_BITS(val, 16, 31) << 16;
358
359 rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_PP + 4, &val);
360 if (rc)
361 return rc;
362 afu->pp_mmio_offset += (u64) val << 32;
363
364 rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_PP_SZ, &val);
365 if (rc)
366 return rc;
367 afu->pp_mmio_stride = val;
368
369 return 0;
370}
371
372static int read_afu_control(struct pci_dev *dev, struct ocxl_afu_config *afu)
373{
374 int pos;
375 u8 val8;
376 u16 val16;
377
378 pos = find_dvsec_afu_ctrl(dev, afu->idx);
379 if (!pos) {
380 dev_err(&dev->dev, "Can't find AFU control DVSEC for AFU %d\n",
381 afu->idx);
382 return -ENODEV;
383 }
384 afu->dvsec_afu_control_pos = pos;
385
386 pci_read_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_PASID_SUP, &val8);
387 afu->pasid_supported_log = EXTRACT_BITS(val8, 0, 4);
388
389 pci_read_config_word(dev, pos + OCXL_DVSEC_AFU_CTRL_ACTAG_SUP, &val16);
390 afu->actag_supported = EXTRACT_BITS(val16, 0, 11);
391 return 0;
392}
393
394static bool char_allowed(int c)
395{
396 /*
397 * Permitted Characters : Alphanumeric, hyphen, underscore, comma
398 */
399 if ((c >= 0x30 && c <= 0x39) /* digits */ ||
400 (c >= 0x41 && c <= 0x5A) /* upper case */ ||
401 (c >= 0x61 && c <= 0x7A) /* lower case */ ||
402 c == 0 /* NULL */ ||
403 c == 0x2D /* - */ ||
404 c == 0x5F /* _ */ ||
405 c == 0x2C /* , */)
406 return true;
407 return false;
408}
409
410static int validate_afu(struct pci_dev *dev, struct ocxl_afu_config *afu)
411{
412 int i;
413
414 if (!afu->name[0]) {
415 dev_err(&dev->dev, "Empty AFU name\n");
416 return -EINVAL;
417 }
418 for (i = 0; i < OCXL_TEMPL_NAME_LEN; i++) {
419 if (!char_allowed(afu->name[i])) {
420 dev_err(&dev->dev,
421 "Invalid character in AFU name\n");
422 return -EINVAL;
423 }
424 }
425
426 if (afu->global_mmio_bar != 0 &&
427 afu->global_mmio_bar != 2 &&
428 afu->global_mmio_bar != 4) {
429 dev_err(&dev->dev, "Invalid global MMIO bar number\n");
430 return -EINVAL;
431 }
432 if (afu->pp_mmio_bar != 0 &&
433 afu->pp_mmio_bar != 2 &&
434 afu->pp_mmio_bar != 4) {
435 dev_err(&dev->dev, "Invalid per-process MMIO bar number\n");
436 return -EINVAL;
437 }
438 return 0;
439}
440
441int ocxl_config_read_afu(struct pci_dev *dev, struct ocxl_fn_config *fn,
442 struct ocxl_afu_config *afu, u8 afu_idx)
443{
444 int rc;
445 u32 val32;
446
447 /*
448 * First, we need to write the AFU idx for the AFU we want to
449 * access.
450 */
451 WARN_ON((afu_idx & OCXL_DVSEC_AFU_IDX_MASK) != afu_idx);
452 afu->idx = afu_idx;
453 pci_write_config_byte(dev,
454 fn->dvsec_afu_info_pos + OCXL_DVSEC_AFU_INFO_AFU_IDX,
455 afu->idx);
456
457 rc = read_afu_name(dev, fn, afu);
458 if (rc)
459 return rc;
460
461 rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_AFU_VERSION, &val32);
462 if (rc)
463 return rc;
464 afu->version_major = EXTRACT_BITS(val32, 24, 31);
465 afu->version_minor = EXTRACT_BITS(val32, 16, 23);
466 afu->afuc_type = EXTRACT_BITS(val32, 14, 15);
467 afu->afum_type = EXTRACT_BITS(val32, 12, 13);
468 afu->profile = EXTRACT_BITS(val32, 0, 7);
469
470 rc = read_afu_mmio(dev, fn, afu);
471 if (rc)
472 return rc;
473
474 rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MEM_SZ, &val32);
475 if (rc)
476 return rc;
477 afu->log_mem_size = EXTRACT_BITS(val32, 0, 7);
478
479 rc = read_afu_control(dev, afu);
480 if (rc)
481 return rc;
482
483 dev_dbg(&dev->dev, "AFU configuration:\n");
484 dev_dbg(&dev->dev, " name = %s\n", afu->name);
485 dev_dbg(&dev->dev, " version = %d.%d\n", afu->version_major,
486 afu->version_minor);
487 dev_dbg(&dev->dev, " global mmio bar = %hhu\n", afu->global_mmio_bar);
488 dev_dbg(&dev->dev, " global mmio offset = %#llx\n",
489 afu->global_mmio_offset);
490 dev_dbg(&dev->dev, " global mmio size = %#x\n", afu->global_mmio_size);
491 dev_dbg(&dev->dev, " pp mmio bar = %hhu\n", afu->pp_mmio_bar);
492 dev_dbg(&dev->dev, " pp mmio offset = %#llx\n", afu->pp_mmio_offset);
493 dev_dbg(&dev->dev, " pp mmio stride = %#x\n", afu->pp_mmio_stride);
494 dev_dbg(&dev->dev, " mem size (log) = %hhu\n", afu->log_mem_size);
495 dev_dbg(&dev->dev, " pasid supported (log) = %u\n",
496 afu->pasid_supported_log);
497 dev_dbg(&dev->dev, " actag supported = %u\n",
498 afu->actag_supported);
499
500 rc = validate_afu(dev, afu);
501 return rc;
502}
503EXPORT_SYMBOL_GPL(ocxl_config_read_afu);
504
505int ocxl_config_get_actag_info(struct pci_dev *dev, u16 *base, u16 *enabled,
506 u16 *supported)
507{
508 int rc;
509
510 /*
511 * This is really a simple wrapper for the kernel API, to
512 * avoid an external driver using ocxl as a library to call
513 * platform-dependent code
514 */
515 rc = pnv_ocxl_get_actag(dev, base, enabled, supported);
516 if (rc) {
517 dev_err(&dev->dev, "Can't get actag for device: %d\n", rc);
518 return rc;
519 }
520 return 0;
521}
522EXPORT_SYMBOL_GPL(ocxl_config_get_actag_info);
523
524void ocxl_config_set_afu_actag(struct pci_dev *dev, int pos, int actag_base,
525 int actag_count)
526{
527 u16 val;
528
529 val = actag_count & OCXL_DVSEC_ACTAG_MASK;
530 pci_write_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_ACTAG_EN, val);
531
532 val = actag_base & OCXL_DVSEC_ACTAG_MASK;
533 pci_write_config_dword(dev, pos + OCXL_DVSEC_AFU_CTRL_ACTAG_BASE, val);
534}
535EXPORT_SYMBOL_GPL(ocxl_config_set_afu_actag);
536
537int ocxl_config_get_pasid_info(struct pci_dev *dev, int *count)
538{
539 return pnv_ocxl_get_pasid_count(dev, count);
540}
541EXPORT_SYMBOL_GPL(ocxl_config_get_pasid_info);
542
543void ocxl_config_set_afu_pasid(struct pci_dev *dev, int pos, int pasid_base,
544 u32 pasid_count_log)
545{
546 u8 val8;
547 u32 val32;
548
549 val8 = pasid_count_log & OCXL_DVSEC_PASID_LOG_MASK;
550 pci_write_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_PASID_EN, val8);
551
552 pci_read_config_dword(dev, pos + OCXL_DVSEC_AFU_CTRL_PASID_BASE,
553 &val32);
554 val32 &= ~OCXL_DVSEC_PASID_MASK;
555 val32 |= pasid_base & OCXL_DVSEC_PASID_MASK;
556 pci_write_config_dword(dev, pos + OCXL_DVSEC_AFU_CTRL_PASID_BASE,
557 val32);
558}
559EXPORT_SYMBOL_GPL(ocxl_config_set_afu_pasid);
560
561void ocxl_config_set_afu_state(struct pci_dev *dev, int pos, int enable)
562{
563 u8 val;
564
565 pci_read_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_ENABLE, &val);
566 if (enable)
567 val |= 1;
568 else
569 val &= 0xFE;
570 pci_write_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_ENABLE, val);
571}
572EXPORT_SYMBOL_GPL(ocxl_config_set_afu_state);
573
574int ocxl_config_set_TL(struct pci_dev *dev, int tl_dvsec)
575{
576 u32 val;
577 __be32 *be32ptr;
578 u8 timers;
579 int i, rc;
580 long recv_cap;
581 char *recv_rate;
582
583 /*
584 * Skip on function != 0, as the TL can only be defined on 0
585 */
586 if (PCI_FUNC(dev->devfn) != 0)
587 return 0;
588
589 recv_rate = kzalloc(PNV_OCXL_TL_RATE_BUF_SIZE, GFP_KERNEL);
590 if (!recv_rate)
591 return -ENOMEM;
592 /*
593 * The spec defines 64 templates for messages in the
594 * Transaction Layer (TL).
595 *
596 * The host and device each support a subset, so we need to
597 * configure the transmitters on each side to send only
598 * templates the receiver understands, at a rate the receiver
599 * can process. Per the spec, template 0 must be supported by
600 * everybody. That's the template which has been used by the
601 * host and device so far.
602 *
603 * The sending rate limit must be set before the template is
604 * enabled.
605 */
606
607 /*
608 * Device -> host
609 */
610 rc = pnv_ocxl_get_tl_cap(dev, &recv_cap, recv_rate,
611 PNV_OCXL_TL_RATE_BUF_SIZE);
612 if (rc)
613 goto out;
614
615 for (i = 0; i < PNV_OCXL_TL_RATE_BUF_SIZE; i += 4) {
616 be32ptr = (__be32 *) &recv_rate[i];
617 pci_write_config_dword(dev,
618 tl_dvsec + OCXL_DVSEC_TL_SEND_RATE + i,
619 be32_to_cpu(*be32ptr));
620 }
621 val = recv_cap >> 32;
622 pci_write_config_dword(dev, tl_dvsec + OCXL_DVSEC_TL_SEND_CAP, val);
623 val = recv_cap & GENMASK(31, 0);
624 pci_write_config_dword(dev, tl_dvsec + OCXL_DVSEC_TL_SEND_CAP + 4, val);
625
626 /*
627 * Host -> device
628 */
629 for (i = 0; i < PNV_OCXL_TL_RATE_BUF_SIZE; i += 4) {
630 pci_read_config_dword(dev,
631 tl_dvsec + OCXL_DVSEC_TL_RECV_RATE + i,
632 &val);
633 be32ptr = (__be32 *) &recv_rate[i];
634 *be32ptr = cpu_to_be32(val);
635 }
636 pci_read_config_dword(dev, tl_dvsec + OCXL_DVSEC_TL_RECV_CAP, &val);
637 recv_cap = (long) val << 32;
638 pci_read_config_dword(dev, tl_dvsec + OCXL_DVSEC_TL_RECV_CAP + 4, &val);
639 recv_cap |= val;
640
641 rc = pnv_ocxl_set_tl_conf(dev, recv_cap, __pa(recv_rate),
642 PNV_OCXL_TL_RATE_BUF_SIZE);
643 if (rc)
644 goto out;
645
646 /*
647 * Opencapi commands needing to be retried are classified per
648 * the TL in 2 groups: short and long commands.
649 *
650 * The short back off timer it not used for now. It will be
651 * for opencapi 4.0.
652 *
653 * The long back off timer is typically used when an AFU hits
654 * a page fault but the NPU is already processing one. So the
655 * AFU needs to wait before it can resubmit. Having a value
656 * too low doesn't break anything, but can generate extra
657 * traffic on the link.
658 * We set it to 1.6 us for now. It's shorter than, but in the
659 * same order of magnitude as the time spent to process a page
660 * fault.
661 */
662 timers = 0x2 << 4; /* long timer = 1.6 us */
663 pci_write_config_byte(dev, tl_dvsec + OCXL_DVSEC_TL_BACKOFF_TIMERS,
664 timers);
665
666 rc = 0;
667out:
668 kfree(recv_rate);
669 return rc;
670}
671EXPORT_SYMBOL_GPL(ocxl_config_set_TL);
672
673int ocxl_config_terminate_pasid(struct pci_dev *dev, int afu_control, int pasid)
674{
675 u32 val;
676 unsigned long timeout;
677
678 pci_read_config_dword(dev, afu_control + OCXL_DVSEC_AFU_CTRL_TERM_PASID,
679 &val);
680 if (EXTRACT_BIT(val, 20)) {
681 dev_err(&dev->dev,
682 "Can't terminate PASID %#x, previous termination didn't complete\n",
683 pasid);
684 return -EBUSY;
685 }
686
687 val &= ~OCXL_DVSEC_PASID_MASK;
688 val |= pasid & OCXL_DVSEC_PASID_MASK;
689 val |= BIT(20);
690 pci_write_config_dword(dev,
691 afu_control + OCXL_DVSEC_AFU_CTRL_TERM_PASID,
692 val);
693
694 timeout = jiffies + (HZ * OCXL_CFG_TIMEOUT);
695 pci_read_config_dword(dev, afu_control + OCXL_DVSEC_AFU_CTRL_TERM_PASID,
696 &val);
697 while (EXTRACT_BIT(val, 20)) {
698 if (time_after_eq(jiffies, timeout)) {
699 dev_err(&dev->dev,
700 "Timeout while waiting for AFU to terminate PASID %#x\n",
701 pasid);
702 return -EBUSY;
703 }
704 cpu_relax();
705 pci_read_config_dword(dev,
706 afu_control + OCXL_DVSEC_AFU_CTRL_TERM_PASID,
707 &val);
708 }
709 return 0;
710}
711EXPORT_SYMBOL_GPL(ocxl_config_terminate_pasid);
712
713void ocxl_config_set_actag(struct pci_dev *dev, int func_dvsec, u32 tag_first,
714 u32 tag_count)
715{
716 u32 val;
717
718 val = (tag_first & OCXL_DVSEC_ACTAG_MASK) << 16;
719 val |= tag_count & OCXL_DVSEC_ACTAG_MASK;
720 pci_write_config_dword(dev, func_dvsec + OCXL_DVSEC_FUNC_OFF_ACTAG,
721 val);
722}
723EXPORT_SYMBOL_GPL(ocxl_config_set_actag);
diff --git a/drivers/misc/ocxl/context.c b/drivers/misc/ocxl/context.c
new file mode 100644
index 000000000000..909e8807824a
--- /dev/null
+++ b/drivers/misc/ocxl/context.c
@@ -0,0 +1,279 @@
1// SPDX-License-Identifier: GPL-2.0+
2// Copyright 2017 IBM Corp.
3#include <linux/sched/mm.h>
4#include "trace.h"
5#include "ocxl_internal.h"
6
7struct ocxl_context *ocxl_context_alloc(void)
8{
9 return kzalloc(sizeof(struct ocxl_context), GFP_KERNEL);
10}
11
12int ocxl_context_init(struct ocxl_context *ctx, struct ocxl_afu *afu,
13 struct address_space *mapping)
14{
15 int pasid;
16
17 ctx->afu = afu;
18 mutex_lock(&afu->contexts_lock);
19 pasid = idr_alloc(&afu->contexts_idr, ctx, afu->pasid_base,
20 afu->pasid_base + afu->pasid_max, GFP_KERNEL);
21 if (pasid < 0) {
22 mutex_unlock(&afu->contexts_lock);
23 return pasid;
24 }
25 afu->pasid_count++;
26 mutex_unlock(&afu->contexts_lock);
27
28 ctx->pasid = pasid;
29 ctx->status = OPENED;
30 mutex_init(&ctx->status_mutex);
31 ctx->mapping = mapping;
32 mutex_init(&ctx->mapping_lock);
33 init_waitqueue_head(&ctx->events_wq);
34 mutex_init(&ctx->xsl_error_lock);
35 mutex_init(&ctx->irq_lock);
36 idr_init(&ctx->irq_idr);
37 /*
38 * Keep a reference on the AFU to make sure it's valid for the
39 * duration of the life of the context
40 */
41 ocxl_afu_get(afu);
42 return 0;
43}
44
45/*
46 * Callback for when a translation fault triggers an error
47 * data: a pointer to the context which triggered the fault
48 * addr: the address that triggered the error
49 * dsisr: the value of the PPC64 dsisr register
50 */
51static void xsl_fault_error(void *data, u64 addr, u64 dsisr)
52{
53 struct ocxl_context *ctx = (struct ocxl_context *) data;
54
55 mutex_lock(&ctx->xsl_error_lock);
56 ctx->xsl_error.addr = addr;
57 ctx->xsl_error.dsisr = dsisr;
58 ctx->xsl_error.count++;
59 mutex_unlock(&ctx->xsl_error_lock);
60
61 wake_up_all(&ctx->events_wq);
62}
63
64int ocxl_context_attach(struct ocxl_context *ctx, u64 amr)
65{
66 int rc;
67
68 mutex_lock(&ctx->status_mutex);
69 if (ctx->status != OPENED) {
70 rc = -EIO;
71 goto out;
72 }
73
74 rc = ocxl_link_add_pe(ctx->afu->fn->link, ctx->pasid,
75 current->mm->context.id, 0, amr, current->mm,
76 xsl_fault_error, ctx);
77 if (rc)
78 goto out;
79
80 ctx->status = ATTACHED;
81out:
82 mutex_unlock(&ctx->status_mutex);
83 return rc;
84}
85
86static int map_afu_irq(struct vm_area_struct *vma, unsigned long address,
87 u64 offset, struct ocxl_context *ctx)
88{
89 u64 trigger_addr;
90
91 trigger_addr = ocxl_afu_irq_get_addr(ctx, offset);
92 if (!trigger_addr)
93 return VM_FAULT_SIGBUS;
94
95 vm_insert_pfn(vma, address, trigger_addr >> PAGE_SHIFT);
96 return VM_FAULT_NOPAGE;
97}
98
99static int map_pp_mmio(struct vm_area_struct *vma, unsigned long address,
100 u64 offset, struct ocxl_context *ctx)
101{
102 u64 pp_mmio_addr;
103 int pasid_off;
104
105 if (offset >= ctx->afu->config.pp_mmio_stride)
106 return VM_FAULT_SIGBUS;
107
108 mutex_lock(&ctx->status_mutex);
109 if (ctx->status != ATTACHED) {
110 mutex_unlock(&ctx->status_mutex);
111 pr_debug("%s: Context not attached, failing mmio mmap\n",
112 __func__);
113 return VM_FAULT_SIGBUS;
114 }
115
116 pasid_off = ctx->pasid - ctx->afu->pasid_base;
117 pp_mmio_addr = ctx->afu->pp_mmio_start +
118 pasid_off * ctx->afu->config.pp_mmio_stride +
119 offset;
120
121 vm_insert_pfn(vma, address, pp_mmio_addr >> PAGE_SHIFT);
122 mutex_unlock(&ctx->status_mutex);
123 return VM_FAULT_NOPAGE;
124}
125
126static int ocxl_mmap_fault(struct vm_fault *vmf)
127{
128 struct vm_area_struct *vma = vmf->vma;
129 struct ocxl_context *ctx = vma->vm_file->private_data;
130 u64 offset;
131 int rc;
132
133 offset = vmf->pgoff << PAGE_SHIFT;
134 pr_debug("%s: pasid %d address 0x%lx offset 0x%llx\n", __func__,
135 ctx->pasid, vmf->address, offset);
136
137 if (offset < ctx->afu->irq_base_offset)
138 rc = map_pp_mmio(vma, vmf->address, offset, ctx);
139 else
140 rc = map_afu_irq(vma, vmf->address, offset, ctx);
141 return rc;
142}
143
144static const struct vm_operations_struct ocxl_vmops = {
145 .fault = ocxl_mmap_fault,
146};
147
148static int check_mmap_afu_irq(struct ocxl_context *ctx,
149 struct vm_area_struct *vma)
150{
151 /* only one page */
152 if (vma_pages(vma) != 1)
153 return -EINVAL;
154
155 /* check offset validty */
156 if (!ocxl_afu_irq_get_addr(ctx, vma->vm_pgoff << PAGE_SHIFT))
157 return -EINVAL;
158
159 /*
160 * trigger page should only be accessible in write mode.
161 *
162 * It's a bit theoretical, as a page mmaped with only
163 * PROT_WRITE is currently readable, but it doesn't hurt.
164 */
165 if ((vma->vm_flags & VM_READ) || (vma->vm_flags & VM_EXEC) ||
166 !(vma->vm_flags & VM_WRITE))
167 return -EINVAL;
168 vma->vm_flags &= ~(VM_MAYREAD | VM_MAYEXEC);
169 return 0;
170}
171
172static int check_mmap_mmio(struct ocxl_context *ctx,
173 struct vm_area_struct *vma)
174{
175 if ((vma_pages(vma) + vma->vm_pgoff) >
176 (ctx->afu->config.pp_mmio_stride >> PAGE_SHIFT))
177 return -EINVAL;
178 return 0;
179}
180
181int ocxl_context_mmap(struct ocxl_context *ctx, struct vm_area_struct *vma)
182{
183 int rc;
184
185 if ((vma->vm_pgoff << PAGE_SHIFT) < ctx->afu->irq_base_offset)
186 rc = check_mmap_mmio(ctx, vma);
187 else
188 rc = check_mmap_afu_irq(ctx, vma);
189 if (rc)
190 return rc;
191
192 vma->vm_flags |= VM_IO | VM_PFNMAP;
193 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
194 vma->vm_ops = &ocxl_vmops;
195 return 0;
196}
197
198int ocxl_context_detach(struct ocxl_context *ctx)
199{
200 struct pci_dev *dev;
201 int afu_control_pos;
202 enum ocxl_context_status status;
203 int rc;
204
205 mutex_lock(&ctx->status_mutex);
206 status = ctx->status;
207 ctx->status = CLOSED;
208 mutex_unlock(&ctx->status_mutex);
209 if (status != ATTACHED)
210 return 0;
211
212 dev = to_pci_dev(ctx->afu->fn->dev.parent);
213 afu_control_pos = ctx->afu->config.dvsec_afu_control_pos;
214
215 mutex_lock(&ctx->afu->afu_control_lock);
216 rc = ocxl_config_terminate_pasid(dev, afu_control_pos, ctx->pasid);
217 mutex_unlock(&ctx->afu->afu_control_lock);
218 trace_ocxl_terminate_pasid(ctx->pasid, rc);
219 if (rc) {
220 /*
221 * If we timeout waiting for the AFU to terminate the
222 * pasid, then it's dangerous to clean up the Process
223 * Element entry in the SPA, as it may be referenced
224 * in the future by the AFU. In which case, we would
225 * checkstop because of an invalid PE access (FIR
226 * register 2, bit 42). So leave the PE
227 * defined. Caller shouldn't free the context so that
228 * PASID remains allocated.
229 *
230 * A link reset will be required to cleanup the AFU
231 * and the SPA.
232 */
233 if (rc == -EBUSY)
234 return rc;
235 }
236 rc = ocxl_link_remove_pe(ctx->afu->fn->link, ctx->pasid);
237 if (rc) {
238 dev_warn(&ctx->afu->dev,
239 "Couldn't remove PE entry cleanly: %d\n", rc);
240 }
241 return 0;
242}
243
244void ocxl_context_detach_all(struct ocxl_afu *afu)
245{
246 struct ocxl_context *ctx;
247 int tmp;
248
249 mutex_lock(&afu->contexts_lock);
250 idr_for_each_entry(&afu->contexts_idr, ctx, tmp) {
251 ocxl_context_detach(ctx);
252 /*
253 * We are force detaching - remove any active mmio
254 * mappings so userspace cannot interfere with the
255 * card if it comes back. Easiest way to exercise
256 * this is to unbind and rebind the driver via sysfs
257 * while it is in use.
258 */
259 mutex_lock(&ctx->mapping_lock);
260 if (ctx->mapping)
261 unmap_mapping_range(ctx->mapping, 0, 0, 1);
262 mutex_unlock(&ctx->mapping_lock);
263 }
264 mutex_unlock(&afu->contexts_lock);
265}
266
267void ocxl_context_free(struct ocxl_context *ctx)
268{
269 mutex_lock(&ctx->afu->contexts_lock);
270 ctx->afu->pasid_count--;
271 idr_remove(&ctx->afu->contexts_idr, ctx->pasid);
272 mutex_unlock(&ctx->afu->contexts_lock);
273
274 ocxl_afu_irq_free_all(ctx);
275 idr_destroy(&ctx->irq_idr);
276 /* reference to the AFU taken in ocxl_context_init */
277 ocxl_afu_put(ctx->afu);
278 kfree(ctx);
279}
diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c
new file mode 100644
index 000000000000..c90c1a578d2f
--- /dev/null
+++ b/drivers/misc/ocxl/file.c
@@ -0,0 +1,432 @@
1// SPDX-License-Identifier: GPL-2.0+
2// Copyright 2017 IBM Corp.
3#include <linux/fs.h>
4#include <linux/poll.h>
5#include <linux/sched/signal.h>
6#include <linux/uaccess.h>
7#include <uapi/misc/ocxl.h>
8#include "ocxl_internal.h"
9
10
11#define OCXL_NUM_MINORS 256 /* Total to reserve */
12
13static dev_t ocxl_dev;
14static struct class *ocxl_class;
15static struct mutex minors_idr_lock;
16static struct idr minors_idr;
17
18static struct ocxl_afu *find_and_get_afu(dev_t devno)
19{
20 struct ocxl_afu *afu;
21 int afu_minor;
22
23 afu_minor = MINOR(devno);
24 /*
25 * We don't declare an RCU critical section here, as our AFU
26 * is protected by a reference counter on the device. By the time the
27 * minor number of a device is removed from the idr, the ref count of
28 * the device is already at 0, so no user API will access that AFU and
29 * this function can't return it.
30 */
31 afu = idr_find(&minors_idr, afu_minor);
32 if (afu)
33 ocxl_afu_get(afu);
34 return afu;
35}
36
37static int allocate_afu_minor(struct ocxl_afu *afu)
38{
39 int minor;
40
41 mutex_lock(&minors_idr_lock);
42 minor = idr_alloc(&minors_idr, afu, 0, OCXL_NUM_MINORS, GFP_KERNEL);
43 mutex_unlock(&minors_idr_lock);
44 return minor;
45}
46
47static void free_afu_minor(struct ocxl_afu *afu)
48{
49 mutex_lock(&minors_idr_lock);
50 idr_remove(&minors_idr, MINOR(afu->dev.devt));
51 mutex_unlock(&minors_idr_lock);
52}
53
54static int afu_open(struct inode *inode, struct file *file)
55{
56 struct ocxl_afu *afu;
57 struct ocxl_context *ctx;
58 int rc;
59
60 pr_debug("%s for device %x\n", __func__, inode->i_rdev);
61
62 afu = find_and_get_afu(inode->i_rdev);
63 if (!afu)
64 return -ENODEV;
65
66 ctx = ocxl_context_alloc();
67 if (!ctx) {
68 rc = -ENOMEM;
69 goto put_afu;
70 }
71
72 rc = ocxl_context_init(ctx, afu, inode->i_mapping);
73 if (rc)
74 goto put_afu;
75 file->private_data = ctx;
76 ocxl_afu_put(afu);
77 return 0;
78
79put_afu:
80 ocxl_afu_put(afu);
81 return rc;
82}
83
84static long afu_ioctl_attach(struct ocxl_context *ctx,
85 struct ocxl_ioctl_attach __user *uarg)
86{
87 struct ocxl_ioctl_attach arg;
88 u64 amr = 0;
89 int rc;
90
91 pr_debug("%s for context %d\n", __func__, ctx->pasid);
92
93 if (copy_from_user(&arg, uarg, sizeof(arg)))
94 return -EFAULT;
95
96 /* Make sure reserved fields are not set for forward compatibility */
97 if (arg.reserved1 || arg.reserved2 || arg.reserved3)
98 return -EINVAL;
99
100 amr = arg.amr & mfspr(SPRN_UAMOR);
101 rc = ocxl_context_attach(ctx, amr);
102 return rc;
103}
104
105#define CMD_STR(x) (x == OCXL_IOCTL_ATTACH ? "ATTACH" : \
106 x == OCXL_IOCTL_IRQ_ALLOC ? "IRQ_ALLOC" : \
107 x == OCXL_IOCTL_IRQ_FREE ? "IRQ_FREE" : \
108 x == OCXL_IOCTL_IRQ_SET_FD ? "IRQ_SET_FD" : \
109 "UNKNOWN")
110
111static long afu_ioctl(struct file *file, unsigned int cmd,
112 unsigned long args)
113{
114 struct ocxl_context *ctx = file->private_data;
115 struct ocxl_ioctl_irq_fd irq_fd;
116 u64 irq_offset;
117 long rc;
118
119 pr_debug("%s for context %d, command %s\n", __func__, ctx->pasid,
120 CMD_STR(cmd));
121
122 if (ctx->status == CLOSED)
123 return -EIO;
124
125 switch (cmd) {
126 case OCXL_IOCTL_ATTACH:
127 rc = afu_ioctl_attach(ctx,
128 (struct ocxl_ioctl_attach __user *) args);
129 break;
130
131 case OCXL_IOCTL_IRQ_ALLOC:
132 rc = ocxl_afu_irq_alloc(ctx, &irq_offset);
133 if (!rc) {
134 rc = copy_to_user((u64 __user *) args, &irq_offset,
135 sizeof(irq_offset));
136 if (rc)
137 ocxl_afu_irq_free(ctx, irq_offset);
138 }
139 break;
140
141 case OCXL_IOCTL_IRQ_FREE:
142 rc = copy_from_user(&irq_offset, (u64 __user *) args,
143 sizeof(irq_offset));
144 if (rc)
145 return -EFAULT;
146 rc = ocxl_afu_irq_free(ctx, irq_offset);
147 break;
148
149 case OCXL_IOCTL_IRQ_SET_FD:
150 rc = copy_from_user(&irq_fd, (u64 __user *) args,
151 sizeof(irq_fd));
152 if (rc)
153 return -EFAULT;
154 if (irq_fd.reserved)
155 return -EINVAL;
156 rc = ocxl_afu_irq_set_fd(ctx, irq_fd.irq_offset,
157 irq_fd.eventfd);
158 break;
159
160 default:
161 rc = -EINVAL;
162 }
163 return rc;
164}
165
166static long afu_compat_ioctl(struct file *file, unsigned int cmd,
167 unsigned long args)
168{
169 return afu_ioctl(file, cmd, args);
170}
171
172static int afu_mmap(struct file *file, struct vm_area_struct *vma)
173{
174 struct ocxl_context *ctx = file->private_data;
175
176 pr_debug("%s for context %d\n", __func__, ctx->pasid);
177 return ocxl_context_mmap(ctx, vma);
178}
179
180static bool has_xsl_error(struct ocxl_context *ctx)
181{
182 bool ret;
183
184 mutex_lock(&ctx->xsl_error_lock);
185 ret = !!ctx->xsl_error.addr;
186 mutex_unlock(&ctx->xsl_error_lock);
187
188 return ret;
189}
190
191/*
192 * Are there any events pending on the AFU
193 * ctx: The AFU context
194 * Returns: true if there are events pending
195 */
196static bool afu_events_pending(struct ocxl_context *ctx)
197{
198 if (has_xsl_error(ctx))
199 return true;
200 return false;
201}
202
203static unsigned int afu_poll(struct file *file, struct poll_table_struct *wait)
204{
205 struct ocxl_context *ctx = file->private_data;
206 unsigned int mask = 0;
207 bool closed;
208
209 pr_debug("%s for context %d\n", __func__, ctx->pasid);
210
211 poll_wait(file, &ctx->events_wq, wait);
212
213 mutex_lock(&ctx->status_mutex);
214 closed = (ctx->status == CLOSED);
215 mutex_unlock(&ctx->status_mutex);
216
217 if (afu_events_pending(ctx))
218 mask = POLLIN | POLLRDNORM;
219 else if (closed)
220 mask = POLLERR;
221
222 return mask;
223}
224
225/*
226 * Populate the supplied buffer with a single XSL error
227 * ctx: The AFU context to report the error from
228 * header: the event header to populate
229 * buf: The buffer to write the body into (should be at least
230 * AFU_EVENT_BODY_XSL_ERROR_SIZE)
231 * Return: the amount of buffer that was populated
232 */
233static ssize_t append_xsl_error(struct ocxl_context *ctx,
234 struct ocxl_kernel_event_header *header,
235 char __user *buf)
236{
237 struct ocxl_kernel_event_xsl_fault_error body;
238
239 memset(&body, 0, sizeof(body));
240
241 mutex_lock(&ctx->xsl_error_lock);
242 if (!ctx->xsl_error.addr) {
243 mutex_unlock(&ctx->xsl_error_lock);
244 return 0;
245 }
246
247 body.addr = ctx->xsl_error.addr;
248 body.dsisr = ctx->xsl_error.dsisr;
249 body.count = ctx->xsl_error.count;
250
251 ctx->xsl_error.addr = 0;
252 ctx->xsl_error.dsisr = 0;
253 ctx->xsl_error.count = 0;
254
255 mutex_unlock(&ctx->xsl_error_lock);
256
257 header->type = OCXL_AFU_EVENT_XSL_FAULT_ERROR;
258
259 if (copy_to_user(buf, &body, sizeof(body)))
260 return -EFAULT;
261
262 return sizeof(body);
263}
264
265#define AFU_EVENT_BODY_MAX_SIZE sizeof(struct ocxl_kernel_event_xsl_fault_error)
266
267/*
268 * Reports events on the AFU
269 * Format:
270 * Header (struct ocxl_kernel_event_header)
271 * Body (struct ocxl_kernel_event_*)
272 * Header...
273 */
274static ssize_t afu_read(struct file *file, char __user *buf, size_t count,
275 loff_t *off)
276{
277 struct ocxl_context *ctx = file->private_data;
278 struct ocxl_kernel_event_header header;
279 ssize_t rc;
280 size_t used = 0;
281 DEFINE_WAIT(event_wait);
282
283 memset(&header, 0, sizeof(header));
284
285 /* Require offset to be 0 */
286 if (*off != 0)
287 return -EINVAL;
288
289 if (count < (sizeof(struct ocxl_kernel_event_header) +
290 AFU_EVENT_BODY_MAX_SIZE))
291 return -EINVAL;
292
293 for (;;) {
294 prepare_to_wait(&ctx->events_wq, &event_wait,
295 TASK_INTERRUPTIBLE);
296
297 if (afu_events_pending(ctx))
298 break;
299
300 if (ctx->status == CLOSED)
301 break;
302
303 if (file->f_flags & O_NONBLOCK) {
304 finish_wait(&ctx->events_wq, &event_wait);
305 return -EAGAIN;
306 }
307
308 if (signal_pending(current)) {
309 finish_wait(&ctx->events_wq, &event_wait);
310 return -ERESTARTSYS;
311 }
312
313 schedule();
314 }
315
316 finish_wait(&ctx->events_wq, &event_wait);
317
318 if (has_xsl_error(ctx)) {
319 used = append_xsl_error(ctx, &header, buf + sizeof(header));
320 if (used < 0)
321 return used;
322 }
323
324 if (!afu_events_pending(ctx))
325 header.flags |= OCXL_KERNEL_EVENT_FLAG_LAST;
326
327 if (copy_to_user(buf, &header, sizeof(header)))
328 return -EFAULT;
329
330 used += sizeof(header);
331
332 rc = (ssize_t) used;
333 return rc;
334}
335
336static int afu_release(struct inode *inode, struct file *file)
337{
338 struct ocxl_context *ctx = file->private_data;
339 int rc;
340
341 pr_debug("%s for device %x\n", __func__, inode->i_rdev);
342 rc = ocxl_context_detach(ctx);
343 mutex_lock(&ctx->mapping_lock);
344 ctx->mapping = NULL;
345 mutex_unlock(&ctx->mapping_lock);
346 wake_up_all(&ctx->events_wq);
347 if (rc != -EBUSY)
348 ocxl_context_free(ctx);
349 return 0;
350}
351
352static const struct file_operations ocxl_afu_fops = {
353 .owner = THIS_MODULE,
354 .open = afu_open,
355 .unlocked_ioctl = afu_ioctl,
356 .compat_ioctl = afu_compat_ioctl,
357 .mmap = afu_mmap,
358 .poll = afu_poll,
359 .read = afu_read,
360 .release = afu_release,
361};
362
363int ocxl_create_cdev(struct ocxl_afu *afu)
364{
365 int rc;
366
367 cdev_init(&afu->cdev, &ocxl_afu_fops);
368 rc = cdev_add(&afu->cdev, afu->dev.devt, 1);
369 if (rc) {
370 dev_err(&afu->dev, "Unable to add afu char device: %d\n", rc);
371 return rc;
372 }
373 return 0;
374}
375
376void ocxl_destroy_cdev(struct ocxl_afu *afu)
377{
378 cdev_del(&afu->cdev);
379}
380
381int ocxl_register_afu(struct ocxl_afu *afu)
382{
383 int minor;
384
385 minor = allocate_afu_minor(afu);
386 if (minor < 0)
387 return minor;
388 afu->dev.devt = MKDEV(MAJOR(ocxl_dev), minor);
389 afu->dev.class = ocxl_class;
390 return device_register(&afu->dev);
391}
392
393void ocxl_unregister_afu(struct ocxl_afu *afu)
394{
395 free_afu_minor(afu);
396}
397
398static char *ocxl_devnode(struct device *dev, umode_t *mode)
399{
400 return kasprintf(GFP_KERNEL, "ocxl/%s", dev_name(dev));
401}
402
403int ocxl_file_init(void)
404{
405 int rc;
406
407 mutex_init(&minors_idr_lock);
408 idr_init(&minors_idr);
409
410 rc = alloc_chrdev_region(&ocxl_dev, 0, OCXL_NUM_MINORS, "ocxl");
411 if (rc) {
412 pr_err("Unable to allocate ocxl major number: %d\n", rc);
413 return rc;
414 }
415
416 ocxl_class = class_create(THIS_MODULE, "ocxl");
417 if (IS_ERR(ocxl_class)) {
418 pr_err("Unable to create ocxl class\n");
419 unregister_chrdev_region(ocxl_dev, OCXL_NUM_MINORS);
420 return PTR_ERR(ocxl_class);
421 }
422
423 ocxl_class->devnode = ocxl_devnode;
424 return 0;
425}
426
427void ocxl_file_exit(void)
428{
429 class_destroy(ocxl_class);
430 unregister_chrdev_region(ocxl_dev, OCXL_NUM_MINORS);
431 idr_destroy(&minors_idr);
432}
diff --git a/drivers/misc/ocxl/link.c b/drivers/misc/ocxl/link.c
new file mode 100644
index 000000000000..f30790582dc0
--- /dev/null
+++ b/drivers/misc/ocxl/link.c
@@ -0,0 +1,647 @@
1// SPDX-License-Identifier: GPL-2.0+
2// Copyright 2017 IBM Corp.
3#include <linux/sched/mm.h>
4#include <linux/mutex.h>
5#include <linux/mmu_context.h>
6#include <asm/copro.h>
7#include <asm/pnv-ocxl.h>
8#include <misc/ocxl.h>
9#include "ocxl_internal.h"
10#include "trace.h"
11
12
13#define SPA_PASID_BITS 15
14#define SPA_PASID_MAX ((1 << SPA_PASID_BITS) - 1)
15#define SPA_PE_MASK SPA_PASID_MAX
16#define SPA_SPA_SIZE_LOG 22 /* Each SPA is 4 Mb */
17
18#define SPA_CFG_SF (1ull << (63-0))
19#define SPA_CFG_TA (1ull << (63-1))
20#define SPA_CFG_HV (1ull << (63-3))
21#define SPA_CFG_UV (1ull << (63-4))
22#define SPA_CFG_XLAT_hpt (0ull << (63-6)) /* Hashed page table (HPT) mode */
23#define SPA_CFG_XLAT_roh (2ull << (63-6)) /* Radix on HPT mode */
24#define SPA_CFG_XLAT_ror (3ull << (63-6)) /* Radix on Radix mode */
25#define SPA_CFG_PR (1ull << (63-49))
26#define SPA_CFG_TC (1ull << (63-54))
27#define SPA_CFG_DR (1ull << (63-59))
28
29#define SPA_XSL_TF (1ull << (63-3)) /* Translation fault */
30#define SPA_XSL_S (1ull << (63-38)) /* Store operation */
31
32#define SPA_PE_VALID 0x80000000
33
34
35struct pe_data {
36 struct mm_struct *mm;
37 /* callback to trigger when a translation fault occurs */
38 void (*xsl_err_cb)(void *data, u64 addr, u64 dsisr);
39 /* opaque pointer to be passed to the above callback */
40 void *xsl_err_data;
41 struct rcu_head rcu;
42};
43
44struct spa {
45 struct ocxl_process_element *spa_mem;
46 int spa_order;
47 struct mutex spa_lock;
48 struct radix_tree_root pe_tree; /* Maps PE handles to pe_data */
49 char *irq_name;
50 int virq;
51 void __iomem *reg_dsisr;
52 void __iomem *reg_dar;
53 void __iomem *reg_tfc;
54 void __iomem *reg_pe_handle;
55 /*
56 * The following field are used by the memory fault
57 * interrupt handler. We can only have one interrupt at a
58 * time. The NPU won't raise another interrupt until the
59 * previous one has been ack'd by writing to the TFC register
60 */
61 struct xsl_fault {
62 struct work_struct fault_work;
63 u64 pe;
64 u64 dsisr;
65 u64 dar;
66 struct pe_data pe_data;
67 } xsl_fault;
68};
69
70/*
71 * A opencapi link can be used be by several PCI functions. We have
72 * one link per device slot.
73 *
74 * A linked list of opencapi links should suffice, as there's a
75 * limited number of opencapi slots on a system and lookup is only
76 * done when the device is probed
77 */
78struct link {
79 struct list_head list;
80 struct kref ref;
81 int domain;
82 int bus;
83 int dev;
84 atomic_t irq_available;
85 struct spa *spa;
86 void *platform_data;
87};
88static struct list_head links_list = LIST_HEAD_INIT(links_list);
89static DEFINE_MUTEX(links_list_lock);
90
91enum xsl_response {
92 CONTINUE,
93 ADDRESS_ERROR,
94 RESTART,
95};
96
97
98static void read_irq(struct spa *spa, u64 *dsisr, u64 *dar, u64 *pe)
99{
100 u64 reg;
101
102 *dsisr = in_be64(spa->reg_dsisr);
103 *dar = in_be64(spa->reg_dar);
104 reg = in_be64(spa->reg_pe_handle);
105 *pe = reg & SPA_PE_MASK;
106}
107
108static void ack_irq(struct spa *spa, enum xsl_response r)
109{
110 u64 reg = 0;
111
112 /* continue is not supported */
113 if (r == RESTART)
114 reg = PPC_BIT(31);
115 else if (r == ADDRESS_ERROR)
116 reg = PPC_BIT(30);
117 else
118 WARN(1, "Invalid irq response %d\n", r);
119
120 if (reg) {
121 trace_ocxl_fault_ack(spa->spa_mem, spa->xsl_fault.pe,
122 spa->xsl_fault.dsisr, spa->xsl_fault.dar, reg);
123 out_be64(spa->reg_tfc, reg);
124 }
125}
126
127static void xsl_fault_handler_bh(struct work_struct *fault_work)
128{
129 unsigned int flt = 0;
130 unsigned long access, flags, inv_flags = 0;
131 enum xsl_response r;
132 struct xsl_fault *fault = container_of(fault_work, struct xsl_fault,
133 fault_work);
134 struct spa *spa = container_of(fault, struct spa, xsl_fault);
135
136 int rc;
137
138 /*
139 * We need to release a reference on the mm whenever exiting this
140 * function (taken in the memory fault interrupt handler)
141 */
142 rc = copro_handle_mm_fault(fault->pe_data.mm, fault->dar, fault->dsisr,
143 &flt);
144 if (rc) {
145 pr_debug("copro_handle_mm_fault failed: %d\n", rc);
146 if (fault->pe_data.xsl_err_cb) {
147 fault->pe_data.xsl_err_cb(
148 fault->pe_data.xsl_err_data,
149 fault->dar, fault->dsisr);
150 }
151 r = ADDRESS_ERROR;
152 goto ack;
153 }
154
155 if (!radix_enabled()) {
156 /*
157 * update_mmu_cache() will not have loaded the hash
158 * since current->trap is not a 0x400 or 0x300, so
159 * just call hash_page_mm() here.
160 */
161 access = _PAGE_PRESENT | _PAGE_READ;
162 if (fault->dsisr & SPA_XSL_S)
163 access |= _PAGE_WRITE;
164
165 if (REGION_ID(fault->dar) != USER_REGION_ID)
166 access |= _PAGE_PRIVILEGED;
167
168 local_irq_save(flags);
169 hash_page_mm(fault->pe_data.mm, fault->dar, access, 0x300,
170 inv_flags);
171 local_irq_restore(flags);
172 }
173 r = RESTART;
174ack:
175 mmdrop(fault->pe_data.mm);
176 ack_irq(spa, r);
177}
178
179static irqreturn_t xsl_fault_handler(int irq, void *data)
180{
181 struct link *link = (struct link *) data;
182 struct spa *spa = link->spa;
183 u64 dsisr, dar, pe_handle;
184 struct pe_data *pe_data;
185 struct ocxl_process_element *pe;
186 int lpid, pid, tid;
187
188 read_irq(spa, &dsisr, &dar, &pe_handle);
189 trace_ocxl_fault(spa->spa_mem, pe_handle, dsisr, dar, -1);
190
191 WARN_ON(pe_handle > SPA_PE_MASK);
192 pe = spa->spa_mem + pe_handle;
193 lpid = be32_to_cpu(pe->lpid);
194 pid = be32_to_cpu(pe->pid);
195 tid = be32_to_cpu(pe->tid);
196 /* We could be reading all null values here if the PE is being
197 * removed while an interrupt kicks in. It's not supposed to
198 * happen if the driver notified the AFU to terminate the
199 * PASID, and the AFU waited for pending operations before
200 * acknowledging. But even if it happens, we won't find a
201 * memory context below and fail silently, so it should be ok.
202 */
203 if (!(dsisr & SPA_XSL_TF)) {
204 WARN(1, "Invalid xsl interrupt fault register %#llx\n", dsisr);
205 ack_irq(spa, ADDRESS_ERROR);
206 return IRQ_HANDLED;
207 }
208
209 rcu_read_lock();
210 pe_data = radix_tree_lookup(&spa->pe_tree, pe_handle);
211 if (!pe_data) {
212 /*
213 * Could only happen if the driver didn't notify the
214 * AFU about PASID termination before removing the PE,
215 * or the AFU didn't wait for all memory access to
216 * have completed.
217 *
218 * Either way, we fail early, but we shouldn't log an
219 * error message, as it is a valid (if unexpected)
220 * scenario
221 */
222 rcu_read_unlock();
223 pr_debug("Unknown mm context for xsl interrupt\n");
224 ack_irq(spa, ADDRESS_ERROR);
225 return IRQ_HANDLED;
226 }
227 WARN_ON(pe_data->mm->context.id != pid);
228
229 spa->xsl_fault.pe = pe_handle;
230 spa->xsl_fault.dar = dar;
231 spa->xsl_fault.dsisr = dsisr;
232 spa->xsl_fault.pe_data = *pe_data;
233 mmgrab(pe_data->mm); /* mm count is released by bottom half */
234
235 rcu_read_unlock();
236 schedule_work(&spa->xsl_fault.fault_work);
237 return IRQ_HANDLED;
238}
239
240static void unmap_irq_registers(struct spa *spa)
241{
242 pnv_ocxl_unmap_xsl_regs(spa->reg_dsisr, spa->reg_dar, spa->reg_tfc,
243 spa->reg_pe_handle);
244}
245
246static int map_irq_registers(struct pci_dev *dev, struct spa *spa)
247{
248 return pnv_ocxl_map_xsl_regs(dev, &spa->reg_dsisr, &spa->reg_dar,
249 &spa->reg_tfc, &spa->reg_pe_handle);
250}
251
252static int setup_xsl_irq(struct pci_dev *dev, struct link *link)
253{
254 struct spa *spa = link->spa;
255 int rc;
256 int hwirq;
257
258 rc = pnv_ocxl_get_xsl_irq(dev, &hwirq);
259 if (rc)
260 return rc;
261
262 rc = map_irq_registers(dev, spa);
263 if (rc)
264 return rc;
265
266 spa->irq_name = kasprintf(GFP_KERNEL, "ocxl-xsl-%x-%x-%x",
267 link->domain, link->bus, link->dev);
268 if (!spa->irq_name) {
269 unmap_irq_registers(spa);
270 dev_err(&dev->dev, "Can't allocate name for xsl interrupt\n");
271 return -ENOMEM;
272 }
273 /*
274 * At some point, we'll need to look into allowing a higher
275 * number of interrupts. Could we have an IRQ domain per link?
276 */
277 spa->virq = irq_create_mapping(NULL, hwirq);
278 if (!spa->virq) {
279 kfree(spa->irq_name);
280 unmap_irq_registers(spa);
281 dev_err(&dev->dev,
282 "irq_create_mapping failed for translation interrupt\n");
283 return -EINVAL;
284 }
285
286 dev_dbg(&dev->dev, "hwirq %d mapped to virq %d\n", hwirq, spa->virq);
287
288 rc = request_irq(spa->virq, xsl_fault_handler, 0, spa->irq_name,
289 link);
290 if (rc) {
291 irq_dispose_mapping(spa->virq);
292 kfree(spa->irq_name);
293 unmap_irq_registers(spa);
294 dev_err(&dev->dev,
295 "request_irq failed for translation interrupt: %d\n",
296 rc);
297 return -EINVAL;
298 }
299 return 0;
300}
301
302static void release_xsl_irq(struct link *link)
303{
304 struct spa *spa = link->spa;
305
306 if (spa->virq) {
307 free_irq(spa->virq, link);
308 irq_dispose_mapping(spa->virq);
309 }
310 kfree(spa->irq_name);
311 unmap_irq_registers(spa);
312}
313
314static int alloc_spa(struct pci_dev *dev, struct link *link)
315{
316 struct spa *spa;
317
318 spa = kzalloc(sizeof(struct spa), GFP_KERNEL);
319 if (!spa)
320 return -ENOMEM;
321
322 mutex_init(&spa->spa_lock);
323 INIT_RADIX_TREE(&spa->pe_tree, GFP_KERNEL);
324 INIT_WORK(&spa->xsl_fault.fault_work, xsl_fault_handler_bh);
325
326 spa->spa_order = SPA_SPA_SIZE_LOG - PAGE_SHIFT;
327 spa->spa_mem = (struct ocxl_process_element *)
328 __get_free_pages(GFP_KERNEL | __GFP_ZERO, spa->spa_order);
329 if (!spa->spa_mem) {
330 dev_err(&dev->dev, "Can't allocate Shared Process Area\n");
331 kfree(spa);
332 return -ENOMEM;
333 }
334 pr_debug("Allocated SPA for %x:%x:%x at %p\n", link->domain, link->bus,
335 link->dev, spa->spa_mem);
336
337 link->spa = spa;
338 return 0;
339}
340
341static void free_spa(struct link *link)
342{
343 struct spa *spa = link->spa;
344
345 pr_debug("Freeing SPA for %x:%x:%x\n", link->domain, link->bus,
346 link->dev);
347
348 if (spa && spa->spa_mem) {
349 free_pages((unsigned long) spa->spa_mem, spa->spa_order);
350 kfree(spa);
351 link->spa = NULL;
352 }
353}
354
355static int alloc_link(struct pci_dev *dev, int PE_mask, struct link **out_link)
356{
357 struct link *link;
358 int rc;
359
360 link = kzalloc(sizeof(struct link), GFP_KERNEL);
361 if (!link)
362 return -ENOMEM;
363
364 kref_init(&link->ref);
365 link->domain = pci_domain_nr(dev->bus);
366 link->bus = dev->bus->number;
367 link->dev = PCI_SLOT(dev->devfn);
368 atomic_set(&link->irq_available, MAX_IRQ_PER_LINK);
369
370 rc = alloc_spa(dev, link);
371 if (rc)
372 goto err_free;
373
374 rc = setup_xsl_irq(dev, link);
375 if (rc)
376 goto err_spa;
377
378 /* platform specific hook */
379 rc = pnv_ocxl_spa_setup(dev, link->spa->spa_mem, PE_mask,
380 &link->platform_data);
381 if (rc)
382 goto err_xsl_irq;
383
384 *out_link = link;
385 return 0;
386
387err_xsl_irq:
388 release_xsl_irq(link);
389err_spa:
390 free_spa(link);
391err_free:
392 kfree(link);
393 return rc;
394}
395
396static void free_link(struct link *link)
397{
398 release_xsl_irq(link);
399 free_spa(link);
400 kfree(link);
401}
402
403int ocxl_link_setup(struct pci_dev *dev, int PE_mask, void **link_handle)
404{
405 int rc = 0;
406 struct link *link;
407
408 mutex_lock(&links_list_lock);
409 list_for_each_entry(link, &links_list, list) {
410 /* The functions of a device all share the same link */
411 if (link->domain == pci_domain_nr(dev->bus) &&
412 link->bus == dev->bus->number &&
413 link->dev == PCI_SLOT(dev->devfn)) {
414 kref_get(&link->ref);
415 *link_handle = link;
416 goto unlock;
417 }
418 }
419 rc = alloc_link(dev, PE_mask, &link);
420 if (rc)
421 goto unlock;
422
423 list_add(&link->list, &links_list);
424 *link_handle = link;
425unlock:
426 mutex_unlock(&links_list_lock);
427 return rc;
428}
429EXPORT_SYMBOL_GPL(ocxl_link_setup);
430
431static void release_xsl(struct kref *ref)
432{
433 struct link *link = container_of(ref, struct link, ref);
434
435 list_del(&link->list);
436 /* call platform code before releasing data */
437 pnv_ocxl_spa_release(link->platform_data);
438 free_link(link);
439}
440
441void ocxl_link_release(struct pci_dev *dev, void *link_handle)
442{
443 struct link *link = (struct link *) link_handle;
444
445 mutex_lock(&links_list_lock);
446 kref_put(&link->ref, release_xsl);
447 mutex_unlock(&links_list_lock);
448}
449EXPORT_SYMBOL_GPL(ocxl_link_release);
450
451static u64 calculate_cfg_state(bool kernel)
452{
453 u64 state;
454
455 state = SPA_CFG_DR;
456 if (mfspr(SPRN_LPCR) & LPCR_TC)
457 state |= SPA_CFG_TC;
458 if (radix_enabled())
459 state |= SPA_CFG_XLAT_ror;
460 else
461 state |= SPA_CFG_XLAT_hpt;
462 state |= SPA_CFG_HV;
463 if (kernel) {
464 if (mfmsr() & MSR_SF)
465 state |= SPA_CFG_SF;
466 } else {
467 state |= SPA_CFG_PR;
468 if (!test_tsk_thread_flag(current, TIF_32BIT))
469 state |= SPA_CFG_SF;
470 }
471 return state;
472}
473
474int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr,
475 u64 amr, struct mm_struct *mm,
476 void (*xsl_err_cb)(void *data, u64 addr, u64 dsisr),
477 void *xsl_err_data)
478{
479 struct link *link = (struct link *) link_handle;
480 struct spa *spa = link->spa;
481 struct ocxl_process_element *pe;
482 int pe_handle, rc = 0;
483 struct pe_data *pe_data;
484
485 BUILD_BUG_ON(sizeof(struct ocxl_process_element) != 128);
486 if (pasid > SPA_PASID_MAX)
487 return -EINVAL;
488
489 mutex_lock(&spa->spa_lock);
490 pe_handle = pasid & SPA_PE_MASK;
491 pe = spa->spa_mem + pe_handle;
492
493 if (pe->software_state) {
494 rc = -EBUSY;
495 goto unlock;
496 }
497
498 pe_data = kmalloc(sizeof(*pe_data), GFP_KERNEL);
499 if (!pe_data) {
500 rc = -ENOMEM;
501 goto unlock;
502 }
503
504 pe_data->mm = mm;
505 pe_data->xsl_err_cb = xsl_err_cb;
506 pe_data->xsl_err_data = xsl_err_data;
507
508 memset(pe, 0, sizeof(struct ocxl_process_element));
509 pe->config_state = cpu_to_be64(calculate_cfg_state(pidr == 0));
510 pe->lpid = cpu_to_be32(mfspr(SPRN_LPID));
511 pe->pid = cpu_to_be32(pidr);
512 pe->tid = cpu_to_be32(tidr);
513 pe->amr = cpu_to_be64(amr);
514 pe->software_state = cpu_to_be32(SPA_PE_VALID);
515
516 mm_context_add_copro(mm);
517 /*
518 * Barrier is to make sure PE is visible in the SPA before it
519 * is used by the device. It also helps with the global TLBI
520 * invalidation
521 */
522 mb();
523 radix_tree_insert(&spa->pe_tree, pe_handle, pe_data);
524
525 /*
526 * The mm must stay valid for as long as the device uses it. We
527 * lower the count when the context is removed from the SPA.
528 *
529 * We grab mm_count (and not mm_users), as we don't want to
530 * end up in a circular dependency if a process mmaps its
531 * mmio, therefore incrementing the file ref count when
532 * calling mmap(), and forgets to unmap before exiting. In
533 * that scenario, when the kernel handles the death of the
534 * process, the file is not cleaned because unmap was not
535 * called, and the mm wouldn't be freed because we would still
536 * have a reference on mm_users. Incrementing mm_count solves
537 * the problem.
538 */
539 mmgrab(mm);
540 trace_ocxl_context_add(current->pid, spa->spa_mem, pasid, pidr, tidr);
541unlock:
542 mutex_unlock(&spa->spa_lock);
543 return rc;
544}
545EXPORT_SYMBOL_GPL(ocxl_link_add_pe);
546
547int ocxl_link_remove_pe(void *link_handle, int pasid)
548{
549 struct link *link = (struct link *) link_handle;
550 struct spa *spa = link->spa;
551 struct ocxl_process_element *pe;
552 struct pe_data *pe_data;
553 int pe_handle, rc;
554
555 if (pasid > SPA_PASID_MAX)
556 return -EINVAL;
557
558 /*
559 * About synchronization with our memory fault handler:
560 *
561 * Before removing the PE, the driver is supposed to have
562 * notified the AFU, which should have cleaned up and make
563 * sure the PASID is no longer in use, including pending
564 * interrupts. However, there's no way to be sure...
565 *
566 * We clear the PE and remove the context from our radix
567 * tree. From that point on, any new interrupt for that
568 * context will fail silently, which is ok. As mentioned
569 * above, that's not expected, but it could happen if the
570 * driver or AFU didn't do the right thing.
571 *
572 * There could still be a bottom half running, but we don't
573 * need to wait/flush, as it is managing a reference count on
574 * the mm it reads from the radix tree.
575 */
576 pe_handle = pasid & SPA_PE_MASK;
577 pe = spa->spa_mem + pe_handle;
578
579 mutex_lock(&spa->spa_lock);
580
581 if (!(be32_to_cpu(pe->software_state) & SPA_PE_VALID)) {
582 rc = -EINVAL;
583 goto unlock;
584 }
585
586 trace_ocxl_context_remove(current->pid, spa->spa_mem, pasid,
587 be32_to_cpu(pe->pid), be32_to_cpu(pe->tid));
588
589 memset(pe, 0, sizeof(struct ocxl_process_element));
590 /*
591 * The barrier makes sure the PE is removed from the SPA
592 * before we clear the NPU context cache below, so that the
593 * old PE cannot be reloaded erroneously.
594 */
595 mb();
596
597 /*
598 * hook to platform code
599 * On powerpc, the entry needs to be cleared from the context
600 * cache of the NPU.
601 */
602 rc = pnv_ocxl_spa_remove_pe(link->platform_data, pe_handle);
603 WARN_ON(rc);
604
605 pe_data = radix_tree_delete(&spa->pe_tree, pe_handle);
606 if (!pe_data) {
607 WARN(1, "Couldn't find pe data when removing PE\n");
608 } else {
609 mm_context_remove_copro(pe_data->mm);
610 mmdrop(pe_data->mm);
611 kfree_rcu(pe_data, rcu);
612 }
613unlock:
614 mutex_unlock(&spa->spa_lock);
615 return rc;
616}
617EXPORT_SYMBOL_GPL(ocxl_link_remove_pe);
618
619int ocxl_link_irq_alloc(void *link_handle, int *hw_irq, u64 *trigger_addr)
620{
621 struct link *link = (struct link *) link_handle;
622 int rc, irq;
623 u64 addr;
624
625 if (atomic_dec_if_positive(&link->irq_available) < 0)
626 return -ENOSPC;
627
628 rc = pnv_ocxl_alloc_xive_irq(&irq, &addr);
629 if (rc) {
630 atomic_inc(&link->irq_available);
631 return rc;
632 }
633
634 *hw_irq = irq;
635 *trigger_addr = addr;
636 return 0;
637}
638EXPORT_SYMBOL_GPL(ocxl_link_irq_alloc);
639
640void ocxl_link_free_irq(void *link_handle, int hw_irq)
641{
642 struct link *link = (struct link *) link_handle;
643
644 pnv_ocxl_free_xive_irq(hw_irq);
645 atomic_inc(&link->irq_available);
646}
647EXPORT_SYMBOL_GPL(ocxl_link_free_irq);
diff --git a/drivers/misc/ocxl/main.c b/drivers/misc/ocxl/main.c
new file mode 100644
index 000000000000..7210d9e059be
--- /dev/null
+++ b/drivers/misc/ocxl/main.c
@@ -0,0 +1,33 @@
1// SPDX-License-Identifier: GPL-2.0+
2// Copyright 2017 IBM Corp.
3#include <linux/module.h>
4#include <linux/pci.h>
5#include "ocxl_internal.h"
6
7static int __init init_ocxl(void)
8{
9 int rc = 0;
10
11 rc = ocxl_file_init();
12 if (rc)
13 return rc;
14
15 rc = pci_register_driver(&ocxl_pci_driver);
16 if (rc) {
17 ocxl_file_exit();
18 return rc;
19 }
20 return 0;
21}
22
23static void exit_ocxl(void)
24{
25 pci_unregister_driver(&ocxl_pci_driver);
26 ocxl_file_exit();
27}
28
29module_init(init_ocxl);
30module_exit(exit_ocxl);
31
32MODULE_DESCRIPTION("Open Coherent Accelerator");
33MODULE_LICENSE("GPL");
diff --git a/drivers/misc/ocxl/ocxl_internal.h b/drivers/misc/ocxl/ocxl_internal.h
new file mode 100644
index 000000000000..5d421824afd9
--- /dev/null
+++ b/drivers/misc/ocxl/ocxl_internal.h
@@ -0,0 +1,131 @@
1// SPDX-License-Identifier: GPL-2.0+
2// Copyright 2017 IBM Corp.
3#ifndef _OCXL_INTERNAL_H_
4#define _OCXL_INTERNAL_H_
5
6#include <linux/pci.h>
7#include <linux/cdev.h>
8#include <linux/list.h>
9#include <misc/ocxl.h>
10
11#define MAX_IRQ_PER_LINK 2000
12#define MAX_IRQ_PER_CONTEXT MAX_IRQ_PER_LINK
13
14#define to_ocxl_function(d) container_of(d, struct ocxl_fn, dev)
15#define to_ocxl_afu(d) container_of(d, struct ocxl_afu, dev)
16
17extern struct pci_driver ocxl_pci_driver;
18
19
20struct ocxl_fn {
21 struct device dev;
22 int bar_used[3];
23 struct ocxl_fn_config config;
24 struct list_head afu_list;
25 int pasid_base;
26 int actag_base;
27 int actag_enabled;
28 int actag_supported;
29 struct list_head pasid_list;
30 struct list_head actag_list;
31 void *link;
32};
33
34struct ocxl_afu {
35 struct ocxl_fn *fn;
36 struct list_head list;
37 struct device dev;
38 struct cdev cdev;
39 struct ocxl_afu_config config;
40 int pasid_base;
41 int pasid_count; /* opened contexts */
42 int pasid_max; /* maximum number of contexts */
43 int actag_base;
44 int actag_enabled;
45 struct mutex contexts_lock;
46 struct idr contexts_idr;
47 struct mutex afu_control_lock;
48 u64 global_mmio_start;
49 u64 irq_base_offset;
50 void __iomem *global_mmio_ptr;
51 u64 pp_mmio_start;
52 struct bin_attribute attr_global_mmio;
53};
54
55enum ocxl_context_status {
56 CLOSED,
57 OPENED,
58 ATTACHED,
59};
60
61// Contains metadata about a translation fault
62struct ocxl_xsl_error {
63 u64 addr; // The address that triggered the fault
64 u64 dsisr; // the value of the dsisr register
65 u64 count; // The number of times this fault has been triggered
66};
67
68struct ocxl_context {
69 struct ocxl_afu *afu;
70 int pasid;
71 struct mutex status_mutex;
72 enum ocxl_context_status status;
73 struct address_space *mapping;
74 struct mutex mapping_lock;
75 wait_queue_head_t events_wq;
76 struct mutex xsl_error_lock;
77 struct ocxl_xsl_error xsl_error;
78 struct mutex irq_lock;
79 struct idr irq_idr;
80};
81
82struct ocxl_process_element {
83 __be64 config_state;
84 __be32 reserved1[11];
85 __be32 lpid;
86 __be32 tid;
87 __be32 pid;
88 __be32 reserved2[10];
89 __be64 amr;
90 __be32 reserved3[3];
91 __be32 software_state;
92};
93
94
95extern struct ocxl_afu *ocxl_afu_get(struct ocxl_afu *afu);
96extern void ocxl_afu_put(struct ocxl_afu *afu);
97
98extern int ocxl_create_cdev(struct ocxl_afu *afu);
99extern void ocxl_destroy_cdev(struct ocxl_afu *afu);
100extern int ocxl_register_afu(struct ocxl_afu *afu);
101extern void ocxl_unregister_afu(struct ocxl_afu *afu);
102
103extern int ocxl_file_init(void);
104extern void ocxl_file_exit(void);
105
106extern int ocxl_pasid_afu_alloc(struct ocxl_fn *fn, u32 size);
107extern void ocxl_pasid_afu_free(struct ocxl_fn *fn, u32 start, u32 size);
108extern int ocxl_actag_afu_alloc(struct ocxl_fn *fn, u32 size);
109extern void ocxl_actag_afu_free(struct ocxl_fn *fn, u32 start, u32 size);
110
111extern struct ocxl_context *ocxl_context_alloc(void);
112extern int ocxl_context_init(struct ocxl_context *ctx, struct ocxl_afu *afu,
113 struct address_space *mapping);
114extern int ocxl_context_attach(struct ocxl_context *ctx, u64 amr);
115extern int ocxl_context_mmap(struct ocxl_context *ctx,
116 struct vm_area_struct *vma);
117extern int ocxl_context_detach(struct ocxl_context *ctx);
118extern void ocxl_context_detach_all(struct ocxl_afu *afu);
119extern void ocxl_context_free(struct ocxl_context *ctx);
120
121extern int ocxl_sysfs_add_afu(struct ocxl_afu *afu);
122extern void ocxl_sysfs_remove_afu(struct ocxl_afu *afu);
123
124extern int ocxl_afu_irq_alloc(struct ocxl_context *ctx, u64 *irq_offset);
125extern int ocxl_afu_irq_free(struct ocxl_context *ctx, u64 irq_offset);
126extern void ocxl_afu_irq_free_all(struct ocxl_context *ctx);
127extern int ocxl_afu_irq_set_fd(struct ocxl_context *ctx, u64 irq_offset,
128 int eventfd);
129extern u64 ocxl_afu_irq_get_addr(struct ocxl_context *ctx, u64 irq_offset);
130
131#endif /* _OCXL_INTERNAL_H_ */
diff --git a/drivers/misc/ocxl/pasid.c b/drivers/misc/ocxl/pasid.c
new file mode 100644
index 000000000000..d14cb56e6920
--- /dev/null
+++ b/drivers/misc/ocxl/pasid.c
@@ -0,0 +1,107 @@
1// SPDX-License-Identifier: GPL-2.0+
2// Copyright 2017 IBM Corp.
3#include "ocxl_internal.h"
4
5
6struct id_range {
7 struct list_head list;
8 u32 start;
9 u32 end;
10};
11
12#ifdef DEBUG
13static void dump_list(struct list_head *head, char *type_str)
14{
15 struct id_range *cur;
16
17 pr_debug("%s ranges allocated:\n", type_str);
18 list_for_each_entry(cur, head, list) {
19 pr_debug("Range %d->%d\n", cur->start, cur->end);
20 }
21}
22#endif
23
24static int range_alloc(struct list_head *head, u32 size, int max_id,
25 char *type_str)
26{
27 struct list_head *pos;
28 struct id_range *cur, *new;
29 int rc, last_end;
30
31 new = kmalloc(sizeof(struct id_range), GFP_KERNEL);
32 if (!new)
33 return -ENOMEM;
34
35 pos = head;
36 last_end = -1;
37 list_for_each_entry(cur, head, list) {
38 if ((cur->start - last_end) > size)
39 break;
40 last_end = cur->end;
41 pos = &cur->list;
42 }
43
44 new->start = last_end + 1;
45 new->end = new->start + size - 1;
46
47 if (new->end > max_id) {
48 kfree(new);
49 rc = -ENOSPC;
50 } else {
51 list_add(&new->list, pos);
52 rc = new->start;
53 }
54
55#ifdef DEBUG
56 dump_list(head, type_str);
57#endif
58 return rc;
59}
60
61static void range_free(struct list_head *head, u32 start, u32 size,
62 char *type_str)
63{
64 bool found = false;
65 struct id_range *cur, *tmp;
66
67 list_for_each_entry_safe(cur, tmp, head, list) {
68 if (cur->start == start && cur->end == (start + size - 1)) {
69 found = true;
70 list_del(&cur->list);
71 kfree(cur);
72 break;
73 }
74 }
75 WARN_ON(!found);
76#ifdef DEBUG
77 dump_list(head, type_str);
78#endif
79}
80
81int ocxl_pasid_afu_alloc(struct ocxl_fn *fn, u32 size)
82{
83 int max_pasid;
84
85 if (fn->config.max_pasid_log < 0)
86 return -ENOSPC;
87 max_pasid = 1 << fn->config.max_pasid_log;
88 return range_alloc(&fn->pasid_list, size, max_pasid, "afu pasid");
89}
90
91void ocxl_pasid_afu_free(struct ocxl_fn *fn, u32 start, u32 size)
92{
93 return range_free(&fn->pasid_list, start, size, "afu pasid");
94}
95
96int ocxl_actag_afu_alloc(struct ocxl_fn *fn, u32 size)
97{
98 int max_actag;
99
100 max_actag = fn->actag_enabled;
101 return range_alloc(&fn->actag_list, size, max_actag, "afu actag");
102}
103
104void ocxl_actag_afu_free(struct ocxl_fn *fn, u32 start, u32 size)
105{
106 return range_free(&fn->actag_list, start, size, "afu actag");
107}
diff --git a/drivers/misc/ocxl/pci.c b/drivers/misc/ocxl/pci.c
new file mode 100644
index 000000000000..0051d9ec76cc
--- /dev/null
+++ b/drivers/misc/ocxl/pci.c
@@ -0,0 +1,585 @@
1// SPDX-License-Identifier: GPL-2.0+
2// Copyright 2017 IBM Corp.
3#include <linux/module.h>
4#include <linux/pci.h>
5#include <linux/idr.h>
6#include <asm/pnv-ocxl.h>
7#include "ocxl_internal.h"
8
9/*
10 * Any opencapi device which wants to use this 'generic' driver should
11 * use the 0x062B device ID. Vendors should define the subsystem
12 * vendor/device ID to help differentiate devices.
13 */
14static const struct pci_device_id ocxl_pci_tbl[] = {
15 { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x062B), },
16 { }
17};
18MODULE_DEVICE_TABLE(pci, ocxl_pci_tbl);
19
20
21static struct ocxl_fn *ocxl_fn_get(struct ocxl_fn *fn)
22{
23 return (get_device(&fn->dev) == NULL) ? NULL : fn;
24}
25
26static void ocxl_fn_put(struct ocxl_fn *fn)
27{
28 put_device(&fn->dev);
29}
30
31struct ocxl_afu *ocxl_afu_get(struct ocxl_afu *afu)
32{
33 return (get_device(&afu->dev) == NULL) ? NULL : afu;
34}
35
36void ocxl_afu_put(struct ocxl_afu *afu)
37{
38 put_device(&afu->dev);
39}
40
41static struct ocxl_afu *alloc_afu(struct ocxl_fn *fn)
42{
43 struct ocxl_afu *afu;
44
45 afu = kzalloc(sizeof(struct ocxl_afu), GFP_KERNEL);
46 if (!afu)
47 return NULL;
48
49 mutex_init(&afu->contexts_lock);
50 mutex_init(&afu->afu_control_lock);
51 idr_init(&afu->contexts_idr);
52 afu->fn = fn;
53 ocxl_fn_get(fn);
54 return afu;
55}
56
57static void free_afu(struct ocxl_afu *afu)
58{
59 idr_destroy(&afu->contexts_idr);
60 ocxl_fn_put(afu->fn);
61 kfree(afu);
62}
63
64static void free_afu_dev(struct device *dev)
65{
66 struct ocxl_afu *afu = to_ocxl_afu(dev);
67
68 ocxl_unregister_afu(afu);
69 free_afu(afu);
70}
71
72static int set_afu_device(struct ocxl_afu *afu, const char *location)
73{
74 struct ocxl_fn *fn = afu->fn;
75 int rc;
76
77 afu->dev.parent = &fn->dev;
78 afu->dev.release = free_afu_dev;
79 rc = dev_set_name(&afu->dev, "%s.%s.%hhu", afu->config.name, location,
80 afu->config.idx);
81 return rc;
82}
83
84static int assign_afu_actag(struct ocxl_afu *afu, struct pci_dev *dev)
85{
86 struct ocxl_fn *fn = afu->fn;
87 int actag_count, actag_offset;
88
89 /*
90 * if there were not enough actags for the function, each afu
91 * reduces its count as well
92 */
93 actag_count = afu->config.actag_supported *
94 fn->actag_enabled / fn->actag_supported;
95 actag_offset = ocxl_actag_afu_alloc(fn, actag_count);
96 if (actag_offset < 0) {
97 dev_err(&afu->dev, "Can't allocate %d actags for AFU: %d\n",
98 actag_count, actag_offset);
99 return actag_offset;
100 }
101 afu->actag_base = fn->actag_base + actag_offset;
102 afu->actag_enabled = actag_count;
103
104 ocxl_config_set_afu_actag(dev, afu->config.dvsec_afu_control_pos,
105 afu->actag_base, afu->actag_enabled);
106 dev_dbg(&afu->dev, "actag base=%d enabled=%d\n",
107 afu->actag_base, afu->actag_enabled);
108 return 0;
109}
110
111static void reclaim_afu_actag(struct ocxl_afu *afu)
112{
113 struct ocxl_fn *fn = afu->fn;
114 int start_offset, size;
115
116 start_offset = afu->actag_base - fn->actag_base;
117 size = afu->actag_enabled;
118 ocxl_actag_afu_free(afu->fn, start_offset, size);
119}
120
121static int assign_afu_pasid(struct ocxl_afu *afu, struct pci_dev *dev)
122{
123 struct ocxl_fn *fn = afu->fn;
124 int pasid_count, pasid_offset;
125
126 /*
127 * We only support the case where the function configuration
128 * requested enough PASIDs to cover all AFUs.
129 */
130 pasid_count = 1 << afu->config.pasid_supported_log;
131 pasid_offset = ocxl_pasid_afu_alloc(fn, pasid_count);
132 if (pasid_offset < 0) {
133 dev_err(&afu->dev, "Can't allocate %d PASIDs for AFU: %d\n",
134 pasid_count, pasid_offset);
135 return pasid_offset;
136 }
137 afu->pasid_base = fn->pasid_base + pasid_offset;
138 afu->pasid_count = 0;
139 afu->pasid_max = pasid_count;
140
141 ocxl_config_set_afu_pasid(dev, afu->config.dvsec_afu_control_pos,
142 afu->pasid_base,
143 afu->config.pasid_supported_log);
144 dev_dbg(&afu->dev, "PASID base=%d, enabled=%d\n",
145 afu->pasid_base, pasid_count);
146 return 0;
147}
148
149static void reclaim_afu_pasid(struct ocxl_afu *afu)
150{
151 struct ocxl_fn *fn = afu->fn;
152 int start_offset, size;
153
154 start_offset = afu->pasid_base - fn->pasid_base;
155 size = 1 << afu->config.pasid_supported_log;
156 ocxl_pasid_afu_free(afu->fn, start_offset, size);
157}
158
159static int reserve_fn_bar(struct ocxl_fn *fn, int bar)
160{
161 struct pci_dev *dev = to_pci_dev(fn->dev.parent);
162 int rc, idx;
163
164 if (bar != 0 && bar != 2 && bar != 4)
165 return -EINVAL;
166
167 idx = bar >> 1;
168 if (fn->bar_used[idx]++ == 0) {
169 rc = pci_request_region(dev, bar, "ocxl");
170 if (rc)
171 return rc;
172 }
173 return 0;
174}
175
176static void release_fn_bar(struct ocxl_fn *fn, int bar)
177{
178 struct pci_dev *dev = to_pci_dev(fn->dev.parent);
179 int idx;
180
181 if (bar != 0 && bar != 2 && bar != 4)
182 return;
183
184 idx = bar >> 1;
185 if (--fn->bar_used[idx] == 0)
186 pci_release_region(dev, bar);
187 WARN_ON(fn->bar_used[idx] < 0);
188}
189
190static int map_mmio_areas(struct ocxl_afu *afu, struct pci_dev *dev)
191{
192 int rc;
193
194 rc = reserve_fn_bar(afu->fn, afu->config.global_mmio_bar);
195 if (rc)
196 return rc;
197
198 rc = reserve_fn_bar(afu->fn, afu->config.pp_mmio_bar);
199 if (rc) {
200 release_fn_bar(afu->fn, afu->config.global_mmio_bar);
201 return rc;
202 }
203
204 afu->global_mmio_start =
205 pci_resource_start(dev, afu->config.global_mmio_bar) +
206 afu->config.global_mmio_offset;
207 afu->pp_mmio_start =
208 pci_resource_start(dev, afu->config.pp_mmio_bar) +
209 afu->config.pp_mmio_offset;
210
211 afu->global_mmio_ptr = ioremap(afu->global_mmio_start,
212 afu->config.global_mmio_size);
213 if (!afu->global_mmio_ptr) {
214 release_fn_bar(afu->fn, afu->config.pp_mmio_bar);
215 release_fn_bar(afu->fn, afu->config.global_mmio_bar);
216 dev_err(&dev->dev, "Error mapping global mmio area\n");
217 return -ENOMEM;
218 }
219
220 /*
221 * Leave an empty page between the per-process mmio area and
222 * the AFU interrupt mappings
223 */
224 afu->irq_base_offset = afu->config.pp_mmio_stride + PAGE_SIZE;
225 return 0;
226}
227
228static void unmap_mmio_areas(struct ocxl_afu *afu)
229{
230 if (afu->global_mmio_ptr) {
231 iounmap(afu->global_mmio_ptr);
232 afu->global_mmio_ptr = NULL;
233 }
234 afu->global_mmio_start = 0;
235 afu->pp_mmio_start = 0;
236 release_fn_bar(afu->fn, afu->config.pp_mmio_bar);
237 release_fn_bar(afu->fn, afu->config.global_mmio_bar);
238}
239
240static int configure_afu(struct ocxl_afu *afu, u8 afu_idx, struct pci_dev *dev)
241{
242 int rc;
243
244 rc = ocxl_config_read_afu(dev, &afu->fn->config, &afu->config, afu_idx);
245 if (rc)
246 return rc;
247
248 rc = set_afu_device(afu, dev_name(&dev->dev));
249 if (rc)
250 return rc;
251
252 rc = assign_afu_actag(afu, dev);
253 if (rc)
254 return rc;
255
256 rc = assign_afu_pasid(afu, dev);
257 if (rc) {
258 reclaim_afu_actag(afu);
259 return rc;
260 }
261
262 rc = map_mmio_areas(afu, dev);
263 if (rc) {
264 reclaim_afu_pasid(afu);
265 reclaim_afu_actag(afu);
266 return rc;
267 }
268 return 0;
269}
270
271static void deconfigure_afu(struct ocxl_afu *afu)
272{
273 unmap_mmio_areas(afu);
274 reclaim_afu_pasid(afu);
275 reclaim_afu_actag(afu);
276}
277
278static int activate_afu(struct pci_dev *dev, struct ocxl_afu *afu)
279{
280 int rc;
281
282 ocxl_config_set_afu_state(dev, afu->config.dvsec_afu_control_pos, 1);
283 /*
284 * Char device creation is the last step, as processes can
285 * call our driver immediately, so all our inits must be finished.
286 */
287 rc = ocxl_create_cdev(afu);
288 if (rc)
289 return rc;
290 return 0;
291}
292
293static void deactivate_afu(struct ocxl_afu *afu)
294{
295 struct pci_dev *dev = to_pci_dev(afu->fn->dev.parent);
296
297 ocxl_destroy_cdev(afu);
298 ocxl_config_set_afu_state(dev, afu->config.dvsec_afu_control_pos, 0);
299}
300
301static int init_afu(struct pci_dev *dev, struct ocxl_fn *fn, u8 afu_idx)
302{
303 int rc;
304 struct ocxl_afu *afu;
305
306 afu = alloc_afu(fn);
307 if (!afu)
308 return -ENOMEM;
309
310 rc = configure_afu(afu, afu_idx, dev);
311 if (rc) {
312 free_afu(afu);
313 return rc;
314 }
315
316 rc = ocxl_register_afu(afu);
317 if (rc)
318 goto err;
319
320 rc = ocxl_sysfs_add_afu(afu);
321 if (rc)
322 goto err;
323
324 rc = activate_afu(dev, afu);
325 if (rc)
326 goto err_sys;
327
328 list_add_tail(&afu->list, &fn->afu_list);
329 return 0;
330
331err_sys:
332 ocxl_sysfs_remove_afu(afu);
333err:
334 deconfigure_afu(afu);
335 device_unregister(&afu->dev);
336 return rc;
337}
338
339static void remove_afu(struct ocxl_afu *afu)
340{
341 list_del(&afu->list);
342 ocxl_context_detach_all(afu);
343 deactivate_afu(afu);
344 ocxl_sysfs_remove_afu(afu);
345 deconfigure_afu(afu);
346 device_unregister(&afu->dev);
347}
348
349static struct ocxl_fn *alloc_function(struct pci_dev *dev)
350{
351 struct ocxl_fn *fn;
352
353 fn = kzalloc(sizeof(struct ocxl_fn), GFP_KERNEL);
354 if (!fn)
355 return NULL;
356
357 INIT_LIST_HEAD(&fn->afu_list);
358 INIT_LIST_HEAD(&fn->pasid_list);
359 INIT_LIST_HEAD(&fn->actag_list);
360 return fn;
361}
362
363static void free_function(struct ocxl_fn *fn)
364{
365 WARN_ON(!list_empty(&fn->afu_list));
366 WARN_ON(!list_empty(&fn->pasid_list));
367 kfree(fn);
368}
369
370static void free_function_dev(struct device *dev)
371{
372 struct ocxl_fn *fn = to_ocxl_function(dev);
373
374 free_function(fn);
375}
376
377static int set_function_device(struct ocxl_fn *fn, struct pci_dev *dev)
378{
379 int rc;
380
381 fn->dev.parent = &dev->dev;
382 fn->dev.release = free_function_dev;
383 rc = dev_set_name(&fn->dev, "ocxlfn.%s", dev_name(&dev->dev));
384 if (rc)
385 return rc;
386 pci_set_drvdata(dev, fn);
387 return 0;
388}
389
390static int assign_function_actag(struct ocxl_fn *fn)
391{
392 struct pci_dev *dev = to_pci_dev(fn->dev.parent);
393 u16 base, enabled, supported;
394 int rc;
395
396 rc = ocxl_config_get_actag_info(dev, &base, &enabled, &supported);
397 if (rc)
398 return rc;
399
400 fn->actag_base = base;
401 fn->actag_enabled = enabled;
402 fn->actag_supported = supported;
403
404 ocxl_config_set_actag(dev, fn->config.dvsec_function_pos,
405 fn->actag_base, fn->actag_enabled);
406 dev_dbg(&fn->dev, "actag range starting at %d, enabled %d\n",
407 fn->actag_base, fn->actag_enabled);
408 return 0;
409}
410
411static int set_function_pasid(struct ocxl_fn *fn)
412{
413 struct pci_dev *dev = to_pci_dev(fn->dev.parent);
414 int rc, desired_count, max_count;
415
416 /* A function may not require any PASID */
417 if (fn->config.max_pasid_log < 0)
418 return 0;
419
420 rc = ocxl_config_get_pasid_info(dev, &max_count);
421 if (rc)
422 return rc;
423
424 desired_count = 1 << fn->config.max_pasid_log;
425
426 if (desired_count > max_count) {
427 dev_err(&fn->dev,
428 "Function requires more PASIDs than is available (%d vs. %d)\n",
429 desired_count, max_count);
430 return -ENOSPC;
431 }
432
433 fn->pasid_base = 0;
434 return 0;
435}
436
437static int configure_function(struct ocxl_fn *fn, struct pci_dev *dev)
438{
439 int rc;
440
441 rc = pci_enable_device(dev);
442 if (rc) {
443 dev_err(&dev->dev, "pci_enable_device failed: %d\n", rc);
444 return rc;
445 }
446
447 /*
448 * Once it has been confirmed to work on our hardware, we
449 * should reset the function, to force the adapter to restart
450 * from scratch.
451 * A function reset would also reset all its AFUs.
452 *
453 * Some hints for implementation:
454 *
455 * - there's not status bit to know when the reset is done. We
456 * should try reading the config space to know when it's
457 * done.
458 * - probably something like:
459 * Reset
460 * wait 100ms
461 * issue config read
462 * allow device up to 1 sec to return success on config
463 * read before declaring it broken
464 *
465 * Some shared logic on the card (CFG, TLX) won't be reset, so
466 * there's no guarantee that it will be enough.
467 */
468 rc = ocxl_config_read_function(dev, &fn->config);
469 if (rc)
470 return rc;
471
472 rc = set_function_device(fn, dev);
473 if (rc)
474 return rc;
475
476 rc = assign_function_actag(fn);
477 if (rc)
478 return rc;
479
480 rc = set_function_pasid(fn);
481 if (rc)
482 return rc;
483
484 rc = ocxl_link_setup(dev, 0, &fn->link);
485 if (rc)
486 return rc;
487
488 rc = ocxl_config_set_TL(dev, fn->config.dvsec_tl_pos);
489 if (rc) {
490 ocxl_link_release(dev, fn->link);
491 return rc;
492 }
493 return 0;
494}
495
496static void deconfigure_function(struct ocxl_fn *fn)
497{
498 struct pci_dev *dev = to_pci_dev(fn->dev.parent);
499
500 ocxl_link_release(dev, fn->link);
501 pci_disable_device(dev);
502}
503
504static struct ocxl_fn *init_function(struct pci_dev *dev)
505{
506 struct ocxl_fn *fn;
507 int rc;
508
509 fn = alloc_function(dev);
510 if (!fn)
511 return ERR_PTR(-ENOMEM);
512
513 rc = configure_function(fn, dev);
514 if (rc) {
515 free_function(fn);
516 return ERR_PTR(rc);
517 }
518
519 rc = device_register(&fn->dev);
520 if (rc) {
521 deconfigure_function(fn);
522 device_unregister(&fn->dev);
523 return ERR_PTR(rc);
524 }
525 return fn;
526}
527
528static void remove_function(struct ocxl_fn *fn)
529{
530 deconfigure_function(fn);
531 device_unregister(&fn->dev);
532}
533
534static int ocxl_probe(struct pci_dev *dev, const struct pci_device_id *id)
535{
536 int rc, afu_count = 0;
537 u8 afu;
538 struct ocxl_fn *fn;
539
540 if (!radix_enabled()) {
541 dev_err(&dev->dev, "Unsupported memory model (hash)\n");
542 return -ENODEV;
543 }
544
545 fn = init_function(dev);
546 if (IS_ERR(fn)) {
547 dev_err(&dev->dev, "function init failed: %li\n",
548 PTR_ERR(fn));
549 return PTR_ERR(fn);
550 }
551
552 for (afu = 0; afu <= fn->config.max_afu_index; afu++) {
553 rc = ocxl_config_check_afu_index(dev, &fn->config, afu);
554 if (rc > 0) {
555 rc = init_afu(dev, fn, afu);
556 if (rc) {
557 dev_err(&dev->dev,
558 "Can't initialize AFU index %d\n", afu);
559 continue;
560 }
561 afu_count++;
562 }
563 }
564 dev_info(&dev->dev, "%d AFU(s) configured\n", afu_count);
565 return 0;
566}
567
568static void ocxl_remove(struct pci_dev *dev)
569{
570 struct ocxl_afu *afu, *tmp;
571 struct ocxl_fn *fn = pci_get_drvdata(dev);
572
573 list_for_each_entry_safe(afu, tmp, &fn->afu_list, list) {
574 remove_afu(afu);
575 }
576 remove_function(fn);
577}
578
579struct pci_driver ocxl_pci_driver = {
580 .name = "ocxl",
581 .id_table = ocxl_pci_tbl,
582 .probe = ocxl_probe,
583 .remove = ocxl_remove,
584 .shutdown = ocxl_remove,
585};
diff --git a/drivers/misc/ocxl/sysfs.c b/drivers/misc/ocxl/sysfs.c
new file mode 100644
index 000000000000..d9753a1db14b
--- /dev/null
+++ b/drivers/misc/ocxl/sysfs.c
@@ -0,0 +1,142 @@
1// SPDX-License-Identifier: GPL-2.0+
2// Copyright 2017 IBM Corp.
3#include <linux/sysfs.h>
4#include "ocxl_internal.h"
5
6static ssize_t global_mmio_size_show(struct device *device,
7 struct device_attribute *attr,
8 char *buf)
9{
10 struct ocxl_afu *afu = to_ocxl_afu(device);
11
12 return scnprintf(buf, PAGE_SIZE, "%d\n",
13 afu->config.global_mmio_size);
14}
15
16static ssize_t pp_mmio_size_show(struct device *device,
17 struct device_attribute *attr,
18 char *buf)
19{
20 struct ocxl_afu *afu = to_ocxl_afu(device);
21
22 return scnprintf(buf, PAGE_SIZE, "%d\n",
23 afu->config.pp_mmio_stride);
24}
25
26static ssize_t afu_version_show(struct device *device,
27 struct device_attribute *attr,
28 char *buf)
29{
30 struct ocxl_afu *afu = to_ocxl_afu(device);
31
32 return scnprintf(buf, PAGE_SIZE, "%hhu:%hhu\n",
33 afu->config.version_major,
34 afu->config.version_minor);
35}
36
37static ssize_t contexts_show(struct device *device,
38 struct device_attribute *attr,
39 char *buf)
40{
41 struct ocxl_afu *afu = to_ocxl_afu(device);
42
43 return scnprintf(buf, PAGE_SIZE, "%d/%d\n",
44 afu->pasid_count, afu->pasid_max);
45}
46
47static struct device_attribute afu_attrs[] = {
48 __ATTR_RO(global_mmio_size),
49 __ATTR_RO(pp_mmio_size),
50 __ATTR_RO(afu_version),
51 __ATTR_RO(contexts),
52};
53
54static ssize_t global_mmio_read(struct file *filp, struct kobject *kobj,
55 struct bin_attribute *bin_attr, char *buf,
56 loff_t off, size_t count)
57{
58 struct ocxl_afu *afu = to_ocxl_afu(kobj_to_dev(kobj));
59
60 if (count == 0 || off < 0 ||
61 off >= afu->config.global_mmio_size)
62 return 0;
63 memcpy_fromio(buf, afu->global_mmio_ptr + off, count);
64 return count;
65}
66
67static int global_mmio_fault(struct vm_fault *vmf)
68{
69 struct vm_area_struct *vma = vmf->vma;
70 struct ocxl_afu *afu = vma->vm_private_data;
71 unsigned long offset;
72
73 if (vmf->pgoff >= (afu->config.global_mmio_size >> PAGE_SHIFT))
74 return VM_FAULT_SIGBUS;
75
76 offset = vmf->pgoff;
77 offset += (afu->global_mmio_start >> PAGE_SHIFT);
78 vm_insert_pfn(vma, vmf->address, offset);
79 return VM_FAULT_NOPAGE;
80}
81
82static const struct vm_operations_struct global_mmio_vmops = {
83 .fault = global_mmio_fault,
84};
85
86static int global_mmio_mmap(struct file *filp, struct kobject *kobj,
87 struct bin_attribute *bin_attr,
88 struct vm_area_struct *vma)
89{
90 struct ocxl_afu *afu = to_ocxl_afu(kobj_to_dev(kobj));
91
92 if ((vma_pages(vma) + vma->vm_pgoff) >
93 (afu->config.global_mmio_size >> PAGE_SHIFT))
94 return -EINVAL;
95
96 vma->vm_flags |= VM_IO | VM_PFNMAP;
97 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
98 vma->vm_ops = &global_mmio_vmops;
99 vma->vm_private_data = afu;
100 return 0;
101}
102
103int ocxl_sysfs_add_afu(struct ocxl_afu *afu)
104{
105 int i, rc;
106
107 for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) {
108 rc = device_create_file(&afu->dev, &afu_attrs[i]);
109 if (rc)
110 goto err;
111 }
112
113 sysfs_attr_init(&afu->attr_global_mmio.attr);
114 afu->attr_global_mmio.attr.name = "global_mmio_area";
115 afu->attr_global_mmio.attr.mode = 0600;
116 afu->attr_global_mmio.size = afu->config.global_mmio_size;
117 afu->attr_global_mmio.read = global_mmio_read;
118 afu->attr_global_mmio.mmap = global_mmio_mmap;
119 rc = device_create_bin_file(&afu->dev, &afu->attr_global_mmio);
120 if (rc) {
121 dev_err(&afu->dev,
122 "Unable to create global mmio attr for afu: %d\n",
123 rc);
124 goto err;
125 }
126
127 return 0;
128
129err:
130 for (i--; i >= 0; i--)
131 device_remove_file(&afu->dev, &afu_attrs[i]);
132 return rc;
133}
134
135void ocxl_sysfs_remove_afu(struct ocxl_afu *afu)
136{
137 int i;
138
139 for (i = 0; i < ARRAY_SIZE(afu_attrs); i++)
140 device_remove_file(&afu->dev, &afu_attrs[i]);
141 device_remove_bin_file(&afu->dev, &afu->attr_global_mmio);
142}
diff --git a/drivers/misc/ocxl/trace.c b/drivers/misc/ocxl/trace.c
new file mode 100644
index 000000000000..1e6947049697
--- /dev/null
+++ b/drivers/misc/ocxl/trace.c
@@ -0,0 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0+
2// Copyright 2017 IBM Corp.
3#ifndef __CHECKER__
4#define CREATE_TRACE_POINTS
5#include "trace.h"
6#endif
diff --git a/drivers/misc/ocxl/trace.h b/drivers/misc/ocxl/trace.h
new file mode 100644
index 000000000000..bcb7ff330c1e
--- /dev/null
+++ b/drivers/misc/ocxl/trace.h
@@ -0,0 +1,182 @@
1// SPDX-License-Identifier: GPL-2.0+
2// Copyright 2017 IBM Corp.
3#undef TRACE_SYSTEM
4#define TRACE_SYSTEM ocxl
5
6#if !defined(_TRACE_OCXL_H) || defined(TRACE_HEADER_MULTI_READ)
7#define _TRACE_OCXL_H
8
9#include <linux/tracepoint.h>
10
11DECLARE_EVENT_CLASS(ocxl_context,
12 TP_PROTO(pid_t pid, void *spa, int pasid, u32 pidr, u32 tidr),
13 TP_ARGS(pid, spa, pasid, pidr, tidr),
14
15 TP_STRUCT__entry(
16 __field(pid_t, pid)
17 __field(void*, spa)
18 __field(int, pasid)
19 __field(u32, pidr)
20 __field(u32, tidr)
21 ),
22
23 TP_fast_assign(
24 __entry->pid = pid;
25 __entry->spa = spa;
26 __entry->pasid = pasid;
27 __entry->pidr = pidr;
28 __entry->tidr = tidr;
29 ),
30
31 TP_printk("linux pid=%d spa=0x%p pasid=0x%x pidr=0x%x tidr=0x%x",
32 __entry->pid,
33 __entry->spa,
34 __entry->pasid,
35 __entry->pidr,
36 __entry->tidr
37 )
38);
39
40DEFINE_EVENT(ocxl_context, ocxl_context_add,
41 TP_PROTO(pid_t pid, void *spa, int pasid, u32 pidr, u32 tidr),
42 TP_ARGS(pid, spa, pasid, pidr, tidr)
43);
44
45DEFINE_EVENT(ocxl_context, ocxl_context_remove,
46 TP_PROTO(pid_t pid, void *spa, int pasid, u32 pidr, u32 tidr),
47 TP_ARGS(pid, spa, pasid, pidr, tidr)
48);
49
50TRACE_EVENT(ocxl_terminate_pasid,
51 TP_PROTO(int pasid, int rc),
52 TP_ARGS(pasid, rc),
53
54 TP_STRUCT__entry(
55 __field(int, pasid)
56 __field(int, rc)
57 ),
58
59 TP_fast_assign(
60 __entry->pasid = pasid;
61 __entry->rc = rc;
62 ),
63
64 TP_printk("pasid=0x%x rc=%d",
65 __entry->pasid,
66 __entry->rc
67 )
68);
69
70DECLARE_EVENT_CLASS(ocxl_fault_handler,
71 TP_PROTO(void *spa, u64 pe, u64 dsisr, u64 dar, u64 tfc),
72 TP_ARGS(spa, pe, dsisr, dar, tfc),
73
74 TP_STRUCT__entry(
75 __field(void *, spa)
76 __field(u64, pe)
77 __field(u64, dsisr)
78 __field(u64, dar)
79 __field(u64, tfc)
80 ),
81
82 TP_fast_assign(
83 __entry->spa = spa;
84 __entry->pe = pe;
85 __entry->dsisr = dsisr;
86 __entry->dar = dar;
87 __entry->tfc = tfc;
88 ),
89
90 TP_printk("spa=%p pe=0x%llx dsisr=0x%llx dar=0x%llx tfc=0x%llx",
91 __entry->spa,
92 __entry->pe,
93 __entry->dsisr,
94 __entry->dar,
95 __entry->tfc
96 )
97);
98
99DEFINE_EVENT(ocxl_fault_handler, ocxl_fault,
100 TP_PROTO(void *spa, u64 pe, u64 dsisr, u64 dar, u64 tfc),
101 TP_ARGS(spa, pe, dsisr, dar, tfc)
102);
103
104DEFINE_EVENT(ocxl_fault_handler, ocxl_fault_ack,
105 TP_PROTO(void *spa, u64 pe, u64 dsisr, u64 dar, u64 tfc),
106 TP_ARGS(spa, pe, dsisr, dar, tfc)
107);
108
109TRACE_EVENT(ocxl_afu_irq_alloc,
110 TP_PROTO(int pasid, int irq_id, unsigned int virq, int hw_irq,
111 u64 irq_offset),
112 TP_ARGS(pasid, irq_id, virq, hw_irq, irq_offset),
113
114 TP_STRUCT__entry(
115 __field(int, pasid)
116 __field(int, irq_id)
117 __field(unsigned int, virq)
118 __field(int, hw_irq)
119 __field(u64, irq_offset)
120 ),
121
122 TP_fast_assign(
123 __entry->pasid = pasid;
124 __entry->irq_id = irq_id;
125 __entry->virq = virq;
126 __entry->hw_irq = hw_irq;
127 __entry->irq_offset = irq_offset;
128 ),
129
130 TP_printk("pasid=0x%x irq_id=%d virq=%u hw_irq=%d irq_offset=0x%llx",
131 __entry->pasid,
132 __entry->irq_id,
133 __entry->virq,
134 __entry->hw_irq,
135 __entry->irq_offset
136 )
137);
138
139TRACE_EVENT(ocxl_afu_irq_free,
140 TP_PROTO(int pasid, int irq_id),
141 TP_ARGS(pasid, irq_id),
142
143 TP_STRUCT__entry(
144 __field(int, pasid)
145 __field(int, irq_id)
146 ),
147
148 TP_fast_assign(
149 __entry->pasid = pasid;
150 __entry->irq_id = irq_id;
151 ),
152
153 TP_printk("pasid=0x%x irq_id=%d",
154 __entry->pasid,
155 __entry->irq_id
156 )
157);
158
159TRACE_EVENT(ocxl_afu_irq_receive,
160 TP_PROTO(int virq),
161 TP_ARGS(virq),
162
163 TP_STRUCT__entry(
164 __field(int, virq)
165 ),
166
167 TP_fast_assign(
168 __entry->virq = virq;
169 ),
170
171 TP_printk("virq=%d",
172 __entry->virq
173 )
174);
175
176#endif /* _TRACE_OCXL_H */
177
178/* This part must be outside protection */
179#undef TRACE_INCLUDE_PATH
180#define TRACE_INCLUDE_PATH .
181#define TRACE_INCLUDE_FILE trace
182#include <trace/define_trace.h>
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index a3449d717a99..fc01d7d807f3 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -27,6 +27,7 @@
27#include <linux/mutex.h> 27#include <linux/mutex.h>
28#include <asm/rtas.h> 28#include <asm/rtas.h>
29#include <asm/vio.h> 29#include <asm/vio.h>
30#include <linux/firmware.h>
30 31
31#include "../pci.h" 32#include "../pci.h"
32#include "rpaphp.h" 33#include "rpaphp.h"
@@ -44,15 +45,14 @@ static struct device_node *find_vio_slot_node(char *drc_name)
44{ 45{
45 struct device_node *parent = of_find_node_by_name(NULL, "vdevice"); 46 struct device_node *parent = of_find_node_by_name(NULL, "vdevice");
46 struct device_node *dn = NULL; 47 struct device_node *dn = NULL;
47 char *name;
48 int rc; 48 int rc;
49 49
50 if (!parent) 50 if (!parent)
51 return NULL; 51 return NULL;
52 52
53 while ((dn = of_get_next_child(parent, dn))) { 53 while ((dn = of_get_next_child(parent, dn))) {
54 rc = rpaphp_get_drc_props(dn, NULL, &name, NULL, NULL); 54 rc = rpaphp_check_drc_props(dn, drc_name, NULL);
55 if ((rc == 0) && (!strcmp(drc_name, name))) 55 if (rc == 0)
56 break; 56 break;
57 } 57 }
58 58
@@ -64,15 +64,12 @@ static struct device_node *find_php_slot_pci_node(char *drc_name,
64 char *drc_type) 64 char *drc_type)
65{ 65{
66 struct device_node *np = NULL; 66 struct device_node *np = NULL;
67 char *name;
68 char *type;
69 int rc; 67 int rc;
70 68
71 while ((np = of_find_node_by_name(np, "pci"))) { 69 while ((np = of_find_node_by_name(np, "pci"))) {
72 rc = rpaphp_get_drc_props(np, NULL, &name, &type, NULL); 70 rc = rpaphp_check_drc_props(np, drc_name, drc_type);
73 if (rc == 0) 71 if (rc == 0)
74 if (!strcmp(drc_name, name) && !strcmp(drc_type, type)) 72 break;
75 break;
76 } 73 }
77 74
78 return np; 75 return np;
diff --git a/drivers/pci/hotplug/rpadlpar_sysfs.c b/drivers/pci/hotplug/rpadlpar_sysfs.c
index edb5d8a53020..b806314349cf 100644
--- a/drivers/pci/hotplug/rpadlpar_sysfs.c
+++ b/drivers/pci/hotplug/rpadlpar_sysfs.c
@@ -16,6 +16,7 @@
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/pci.h> 17#include <linux/pci.h>
18#include <linux/pci_hotplug.h> 18#include <linux/pci_hotplug.h>
19#include "rpaphp.h"
19#include "rpadlpar.h" 20#include "rpadlpar.h"
20#include "../pci.h" 21#include "../pci.h"
21 22
@@ -27,8 +28,6 @@
27#define ADD_SLOT_ATTR_NAME add_slot 28#define ADD_SLOT_ATTR_NAME add_slot
28#define REMOVE_SLOT_ATTR_NAME remove_slot 29#define REMOVE_SLOT_ATTR_NAME remove_slot
29 30
30#define MAX_DRC_NAME_LEN 64
31
32static ssize_t add_slot_store(struct kobject *kobj, struct kobj_attribute *attr, 31static ssize_t add_slot_store(struct kobject *kobj, struct kobj_attribute *attr,
33 const char *buf, size_t nbytes) 32 const char *buf, size_t nbytes)
34{ 33{
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
index 7db024e68fe6..bdb844b01a3d 100644
--- a/drivers/pci/hotplug/rpaphp.h
+++ b/drivers/pci/hotplug/rpaphp.h
@@ -64,6 +64,10 @@ extern bool rpaphp_debug;
64#define CONFIGURED 1 64#define CONFIGURED 1
65#define EMPTY 0 65#define EMPTY 0
66 66
67/* DRC constants */
68
69#define MAX_DRC_NAME_LEN 64
70
67/* 71/*
68 * struct slot - slot information for each *physical* slot 72 * struct slot - slot information for each *physical* slot
69 */ 73 */
@@ -91,8 +95,8 @@ int rpaphp_get_sensor_state(struct slot *slot, int *state);
91 95
92/* rpaphp_core.c */ 96/* rpaphp_core.c */
93int rpaphp_add_slot(struct device_node *dn); 97int rpaphp_add_slot(struct device_node *dn);
94int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, 98int rpaphp_check_drc_props(struct device_node *dn, char *drc_name,
95 char **drc_name, char **drc_type, int *drc_power_domain); 99 char *drc_type);
96 100
97/* rpaphp_slot.c */ 101/* rpaphp_slot.c */
98void dealloc_slot_struct(struct slot *slot); 102void dealloc_slot_struct(struct slot *slot);
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index 1e29abaaea08..53902c7c38f2 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -30,6 +30,7 @@
30#include <linux/smp.h> 30#include <linux/smp.h>
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/vmalloc.h> 32#include <linux/vmalloc.h>
33#include <asm/firmware.h>
33#include <asm/eeh.h> /* for eeh_add_device() */ 34#include <asm/eeh.h> /* for eeh_add_device() */
34#include <asm/rtas.h> /* rtas_call */ 35#include <asm/rtas.h> /* rtas_call */
35#include <asm/pci-bridge.h> /* for pci_controller */ 36#include <asm/pci-bridge.h> /* for pci_controller */
@@ -196,25 +197,21 @@ static int get_children_props(struct device_node *dn, const int **drc_indexes,
196 return 0; 197 return 0;
197} 198}
198 199
199/* To get the DRC props describing the current node, first obtain it's 200
200 * my-drc-index property. Next obtain the DRC list from it's parent. Use 201/* Verify the existence of 'drc_name' and/or 'drc_type' within the
201 * the my-drc-index for correlation, and obtain the requested properties. 202 * current node. First obtain it's my-drc-index property. Next,
203 * obtain the DRC info from it's parent. Use the my-drc-index for
204 * correlation, and obtain/validate the requested properties.
202 */ 205 */
203int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, 206
204 char **drc_name, char **drc_type, int *drc_power_domain) 207static int rpaphp_check_drc_props_v1(struct device_node *dn, char *drc_name,
208 char *drc_type, unsigned int my_index)
205{ 209{
210 char *name_tmp, *type_tmp;
206 const int *indexes, *names; 211 const int *indexes, *names;
207 const int *types, *domains; 212 const int *types, *domains;
208 const unsigned int *my_index;
209 char *name_tmp, *type_tmp;
210 int i, rc; 213 int i, rc;
211 214
212 my_index = of_get_property(dn, "ibm,my-drc-index", NULL);
213 if (!my_index) {
214 /* Node isn't DLPAR/hotplug capable */
215 return -EINVAL;
216 }
217
218 rc = get_children_props(dn->parent, &indexes, &names, &types, &domains); 215 rc = get_children_props(dn->parent, &indexes, &names, &types, &domains);
219 if (rc < 0) { 216 if (rc < 0) {
220 return -EINVAL; 217 return -EINVAL;
@@ -225,24 +222,84 @@ int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,
225 222
226 /* Iterate through parent properties, looking for my-drc-index */ 223 /* Iterate through parent properties, looking for my-drc-index */
227 for (i = 0; i < be32_to_cpu(indexes[0]); i++) { 224 for (i = 0; i < be32_to_cpu(indexes[0]); i++) {
228 if ((unsigned int) indexes[i + 1] == *my_index) { 225 if ((unsigned int) indexes[i + 1] == my_index)
229 if (drc_name) 226 break;
230 *drc_name = name_tmp; 227
231 if (drc_type)
232 *drc_type = type_tmp;
233 if (drc_index)
234 *drc_index = be32_to_cpu(*my_index);
235 if (drc_power_domain)
236 *drc_power_domain = be32_to_cpu(domains[i+1]);
237 return 0;
238 }
239 name_tmp += (strlen(name_tmp) + 1); 228 name_tmp += (strlen(name_tmp) + 1);
240 type_tmp += (strlen(type_tmp) + 1); 229 type_tmp += (strlen(type_tmp) + 1);
241 } 230 }
242 231
232 if (((drc_name == NULL) || (drc_name && !strcmp(drc_name, name_tmp))) &&
233 ((drc_type == NULL) || (drc_type && !strcmp(drc_type, type_tmp))))
234 return 0;
235
243 return -EINVAL; 236 return -EINVAL;
244} 237}
245EXPORT_SYMBOL_GPL(rpaphp_get_drc_props); 238
239static int rpaphp_check_drc_props_v2(struct device_node *dn, char *drc_name,
240 char *drc_type, unsigned int my_index)
241{
242 struct property *info;
243 unsigned int entries;
244 struct of_drc_info drc;
245 const __be32 *value;
246 char cell_drc_name[MAX_DRC_NAME_LEN];
247 int j, fndit;
248
249 info = of_find_property(dn->parent, "ibm,drc-info", NULL);
250 if (info == NULL)
251 return -EINVAL;
252
253 value = of_prop_next_u32(info, NULL, &entries);
254 if (!value)
255 return -EINVAL;
256
257 for (j = 0; j < entries; j++) {
258 of_read_drc_info_cell(&info, &value, &drc);
259
260 /* Should now know end of current entry */
261
262 if (my_index > drc.last_drc_index)
263 continue;
264
265 fndit = 1;
266 break;
267 }
268 /* Found it */
269
270 if (fndit)
271 sprintf(cell_drc_name, "%s%d", drc.drc_name_prefix,
272 my_index);
273
274 if (((drc_name == NULL) ||
275 (drc_name && !strcmp(drc_name, cell_drc_name))) &&
276 ((drc_type == NULL) ||
277 (drc_type && !strcmp(drc_type, drc.drc_type))))
278 return 0;
279
280 return -EINVAL;
281}
282
283int rpaphp_check_drc_props(struct device_node *dn, char *drc_name,
284 char *drc_type)
285{
286 const unsigned int *my_index;
287
288 my_index = of_get_property(dn, "ibm,my-drc-index", NULL);
289 if (!my_index) {
290 /* Node isn't DLPAR/hotplug capable */
291 return -EINVAL;
292 }
293
294 if (firmware_has_feature(FW_FEATURE_DRC_INFO))
295 return rpaphp_check_drc_props_v2(dn, drc_name, drc_type,
296 *my_index);
297 else
298 return rpaphp_check_drc_props_v1(dn, drc_name, drc_type,
299 *my_index);
300}
301EXPORT_SYMBOL_GPL(rpaphp_check_drc_props);
302
246 303
247static int is_php_type(char *drc_type) 304static int is_php_type(char *drc_type)
248{ 305{
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 6bacb8995e96..0b7b5da63d4e 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -636,6 +636,17 @@ void pci_restore_iov_state(struct pci_dev *dev)
636} 636}
637 637
638/** 638/**
639 * pci_vf_drivers_autoprobe - set PF property drivers_autoprobe for VFs
640 * @dev: the PCI device
641 * @auto_probe: set VF drivers auto probe flag
642 */
643void pci_vf_drivers_autoprobe(struct pci_dev *dev, bool auto_probe)
644{
645 if (dev->is_physfn)
646 dev->sriov->drivers_autoprobe = auto_probe;
647}
648
649/**
639 * pci_iov_bus_range - find bus range used by Virtual Function 650 * pci_iov_bus_range - find bus range used by Virtual Function
640 * @bus: the PCI bus 651 * @bus: the PCI bus
641 * 652 *
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 744805232155..8d7448063fd1 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -278,6 +278,7 @@ static int report_error_detected(struct pci_dev *dev, void *data)
278 } else { 278 } else {
279 err_handler = dev->driver->err_handler; 279 err_handler = dev->driver->err_handler;
280 vote = err_handler->error_detected(dev, result_data->state); 280 vote = err_handler->error_detected(dev, result_data->state);
281 pci_uevent_ers(dev, PCI_ERS_RESULT_NONE);
281 } 282 }
282 283
283 result_data->result = merge_result(result_data->result, vote); 284 result_data->result = merge_result(result_data->result, vote);
@@ -341,6 +342,7 @@ static int report_resume(struct pci_dev *dev, void *data)
341 342
342 err_handler = dev->driver->err_handler; 343 err_handler = dev->driver->err_handler;
343 err_handler->resume(dev); 344 err_handler->resume(dev);
345 pci_uevent_ers(dev, PCI_ERS_RESULT_RECOVERED);
344out: 346out:
345 device_unlock(&dev->dev); 347 device_unlock(&dev->dev);
346 return 0; 348 return 0;
@@ -541,6 +543,7 @@ static void do_recovery(struct pci_dev *dev, int severity)
541 return; 543 return;
542 544
543failed: 545failed:
546 pci_uevent_ers(dev, PCI_ERS_RESULT_DISCONNECT);
544 /* TODO: Should kernel panic here? */ 547 /* TODO: Should kernel panic here? */
545 dev_info(&dev->dev, "AER: Device recovery failed\n"); 548 dev_info(&dev->dev, "AER: Device recovery failed\n");
546} 549}
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
index 437fc35beb7b..e293606b0334 100644
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -44,7 +44,6 @@ static struct ps3av {
44 struct mutex mutex; 44 struct mutex mutex;
45 struct work_struct work; 45 struct work_struct work;
46 struct completion done; 46 struct completion done;
47 struct workqueue_struct *wq;
48 int open_count; 47 int open_count;
49 struct ps3_system_bus_device *dev; 48 struct ps3_system_bus_device *dev;
50 49
@@ -485,7 +484,7 @@ static int ps3av_set_videomode(void)
485 ps3av_set_av_video_mute(PS3AV_CMD_MUTE_ON); 484 ps3av_set_av_video_mute(PS3AV_CMD_MUTE_ON);
486 485
487 /* wake up ps3avd to do the actual video mode setting */ 486 /* wake up ps3avd to do the actual video mode setting */
488 queue_work(ps3av->wq, &ps3av->work); 487 schedule_work(&ps3av->work);
489 488
490 return 0; 489 return 0;
491} 490}
@@ -956,11 +955,6 @@ static int ps3av_probe(struct ps3_system_bus_device *dev)
956 INIT_WORK(&ps3av->work, ps3avd); 955 INIT_WORK(&ps3av->work, ps3avd);
957 init_completion(&ps3av->done); 956 init_completion(&ps3av->done);
958 complete(&ps3av->done); 957 complete(&ps3av->done);
959 ps3av->wq = create_singlethread_workqueue("ps3avd");
960 if (!ps3av->wq) {
961 res = -ENOMEM;
962 goto fail;
963 }
964 958
965 switch (ps3_os_area_get_av_multi_out()) { 959 switch (ps3_os_area_get_av_multi_out()) {
966 case PS3_PARAM_AV_MULTI_OUT_NTSC: 960 case PS3_PARAM_AV_MULTI_OUT_NTSC:
@@ -1018,8 +1012,7 @@ static int ps3av_remove(struct ps3_system_bus_device *dev)
1018 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); 1012 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
1019 if (ps3av) { 1013 if (ps3av) {
1020 ps3av_cmd_fin(); 1014 ps3av_cmd_fin();
1021 if (ps3av->wq) 1015 flush_work(&ps3av->work);
1022 destroy_workqueue(ps3av->wq);
1023 kfree(ps3av); 1016 kfree(ps3av);
1024 ps3av = NULL; 1017 ps3av = NULL;
1025 } 1018 }
diff --git a/drivers/rtc/rtc-opal.c b/drivers/rtc/rtc-opal.c
index e2a946c0e667..304e891e35fc 100644
--- a/drivers/rtc/rtc-opal.c
+++ b/drivers/rtc/rtc-opal.c
@@ -58,6 +58,7 @@ static void tm_to_opal(struct rtc_time *tm, u32 *y_m_d, u64 *h_m_s_ms)
58static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm) 58static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm)
59{ 59{
60 long rc = OPAL_BUSY; 60 long rc = OPAL_BUSY;
61 int retries = 10;
61 u32 y_m_d; 62 u32 y_m_d;
62 u64 h_m_s_ms; 63 u64 h_m_s_ms;
63 __be32 __y_m_d; 64 __be32 __y_m_d;
@@ -67,8 +68,11 @@ static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm)
67 rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms); 68 rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms);
68 if (rc == OPAL_BUSY_EVENT) 69 if (rc == OPAL_BUSY_EVENT)
69 opal_poll_events(NULL); 70 opal_poll_events(NULL);
70 else 71 else if (retries-- && (rc == OPAL_HARDWARE
72 || rc == OPAL_INTERNAL_ERROR))
71 msleep(10); 73 msleep(10);
74 else if (rc != OPAL_BUSY && rc != OPAL_BUSY_EVENT)
75 break;
72 } 76 }
73 77
74 if (rc != OPAL_SUCCESS) 78 if (rc != OPAL_SUCCESS)
@@ -84,6 +88,7 @@ static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm)
84static int opal_set_rtc_time(struct device *dev, struct rtc_time *tm) 88static int opal_set_rtc_time(struct device *dev, struct rtc_time *tm)
85{ 89{
86 long rc = OPAL_BUSY; 90 long rc = OPAL_BUSY;
91 int retries = 10;
87 u32 y_m_d = 0; 92 u32 y_m_d = 0;
88 u64 h_m_s_ms = 0; 93 u64 h_m_s_ms = 0;
89 94
@@ -92,8 +97,11 @@ static int opal_set_rtc_time(struct device *dev, struct rtc_time *tm)
92 rc = opal_rtc_write(y_m_d, h_m_s_ms); 97 rc = opal_rtc_write(y_m_d, h_m_s_ms);
93 if (rc == OPAL_BUSY_EVENT) 98 if (rc == OPAL_BUSY_EVENT)
94 opal_poll_events(NULL); 99 opal_poll_events(NULL);
95 else 100 else if (retries-- && (rc == OPAL_HARDWARE
101 || rc == OPAL_INTERNAL_ERROR))
96 msleep(10); 102 msleep(10);
103 else if (rc != OPAL_BUSY && rc != OPAL_BUSY_EVENT)
104 break;
97 } 105 }
98 106
99 return rc == OPAL_SUCCESS ? 0 : -EIO; 107 return rc == OPAL_SUCCESS ? 0 : -EIO;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 0314e0716c30..ad35aac87971 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1965,6 +1965,7 @@ int pci_vfs_assigned(struct pci_dev *dev);
1965int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); 1965int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs);
1966int pci_sriov_get_totalvfs(struct pci_dev *dev); 1966int pci_sriov_get_totalvfs(struct pci_dev *dev);
1967resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno); 1967resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno);
1968void pci_vf_drivers_autoprobe(struct pci_dev *dev, bool probe);
1968#else 1969#else
1969static inline int pci_iov_virtfn_bus(struct pci_dev *dev, int id) 1970static inline int pci_iov_virtfn_bus(struct pci_dev *dev, int id)
1970{ 1971{
@@ -1992,6 +1993,7 @@ static inline int pci_sriov_get_totalvfs(struct pci_dev *dev)
1992{ return 0; } 1993{ return 0; }
1993static inline resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno) 1994static inline resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno)
1994{ return 0; } 1995{ return 0; }
1996static inline void pci_vf_drivers_autoprobe(struct pci_dev *dev, bool probe) { }
1995#endif 1997#endif
1996 1998
1997#if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE) 1999#if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE)
@@ -2279,6 +2281,42 @@ static inline bool pci_is_thunderbolt_attached(struct pci_dev *pdev)
2279 return false; 2281 return false;
2280} 2282}
2281 2283
2284/**
2285 * pci_uevent_ers - emit a uevent during recovery path of pci device
2286 * @pdev: pci device to check
2287 * @err_type: type of error event
2288 *
2289 */
2290static inline void pci_uevent_ers(struct pci_dev *pdev,
2291 enum pci_ers_result err_type)
2292{
2293 int idx = 0;
2294 char *envp[3];
2295
2296 switch (err_type) {
2297 case PCI_ERS_RESULT_NONE:
2298 case PCI_ERS_RESULT_CAN_RECOVER:
2299 envp[idx++] = "ERROR_EVENT=BEGIN_RECOVERY";
2300 envp[idx++] = "DEVICE_ONLINE=0";
2301 break;
2302 case PCI_ERS_RESULT_RECOVERED:
2303 envp[idx++] = "ERROR_EVENT=SUCCESSFUL_RECOVERY";
2304 envp[idx++] = "DEVICE_ONLINE=1";
2305 break;
2306 case PCI_ERS_RESULT_DISCONNECT:
2307 envp[idx++] = "ERROR_EVENT=FAILED_RECOVERY";
2308 envp[idx++] = "DEVICE_ONLINE=0";
2309 break;
2310 default:
2311 break;
2312 }
2313
2314 if (idx > 0) {
2315 envp[idx++] = NULL;
2316 kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, envp);
2317 }
2318}
2319
2282/* provide the legacy pci_dma_* API */ 2320/* provide the legacy pci_dma_* API */
2283#include <linux/pci-dma-compat.h> 2321#include <linux/pci-dma-compat.h>
2284 2322
diff --git a/include/misc/ocxl-config.h b/include/misc/ocxl-config.h
new file mode 100644
index 000000000000..3526fa996a22
--- /dev/null
+++ b/include/misc/ocxl-config.h
@@ -0,0 +1,45 @@
1// SPDX-License-Identifier: GPL-2.0+
2// Copyright 2017 IBM Corp.
3#ifndef _OCXL_CONFIG_H_
4#define _OCXL_CONFIG_H_
5
6/*
7 * This file lists the various constants used to read the
8 * configuration space of an opencapi adapter.
9 *
10 * It follows the specification for opencapi 3.0
11 */
12
13#define OCXL_EXT_CAP_ID_DVSEC 0x23
14
15#define OCXL_DVSEC_VENDOR_OFFSET 0x4
16#define OCXL_DVSEC_ID_OFFSET 0x8
17#define OCXL_DVSEC_TL_ID 0xF000
18#define OCXL_DVSEC_TL_BACKOFF_TIMERS 0x10
19#define OCXL_DVSEC_TL_RECV_CAP 0x18
20#define OCXL_DVSEC_TL_SEND_CAP 0x20
21#define OCXL_DVSEC_TL_RECV_RATE 0x30
22#define OCXL_DVSEC_TL_SEND_RATE 0x50
23#define OCXL_DVSEC_FUNC_ID 0xF001
24#define OCXL_DVSEC_FUNC_OFF_INDEX 0x08
25#define OCXL_DVSEC_FUNC_OFF_ACTAG 0x0C
26#define OCXL_DVSEC_AFU_INFO_ID 0xF003
27#define OCXL_DVSEC_AFU_INFO_AFU_IDX 0x0A
28#define OCXL_DVSEC_AFU_INFO_OFF 0x0C
29#define OCXL_DVSEC_AFU_INFO_DATA 0x10
30#define OCXL_DVSEC_AFU_CTRL_ID 0xF004
31#define OCXL_DVSEC_AFU_CTRL_AFU_IDX 0x0A
32#define OCXL_DVSEC_AFU_CTRL_TERM_PASID 0x0C
33#define OCXL_DVSEC_AFU_CTRL_ENABLE 0x0F
34#define OCXL_DVSEC_AFU_CTRL_PASID_SUP 0x10
35#define OCXL_DVSEC_AFU_CTRL_PASID_EN 0x11
36#define OCXL_DVSEC_AFU_CTRL_PASID_BASE 0x14
37#define OCXL_DVSEC_AFU_CTRL_ACTAG_SUP 0x18
38#define OCXL_DVSEC_AFU_CTRL_ACTAG_EN 0x1A
39#define OCXL_DVSEC_AFU_CTRL_ACTAG_BASE 0x1C
40#define OCXL_DVSEC_VENDOR_ID 0xF0F0
41#define OCXL_DVSEC_VENDOR_CFG_VERS 0x0C
42#define OCXL_DVSEC_VENDOR_TLX_VERS 0x10
43#define OCXL_DVSEC_VENDOR_DLX_VERS 0x20
44
45#endif /* _OCXL_CONFIG_H_ */
diff --git a/include/misc/ocxl.h b/include/misc/ocxl.h
new file mode 100644
index 000000000000..51ccf76db293
--- /dev/null
+++ b/include/misc/ocxl.h
@@ -0,0 +1,214 @@
1// SPDX-License-Identifier: GPL-2.0+
2// Copyright 2017 IBM Corp.
3#ifndef _MISC_OCXL_H_
4#define _MISC_OCXL_H_
5
6#include <linux/pci.h>
7
8/*
9 * Opencapi drivers all need some common facilities, like parsing the
10 * device configuration space, adding a Process Element to the Shared
11 * Process Area, etc...
12 *
13 * The ocxl module provides a kernel API, to allow other drivers to
14 * reuse common code. A bit like a in-kernel library.
15 */
16
17#define OCXL_AFU_NAME_SZ (24+1) /* add 1 for NULL termination */
18
19/*
20 * The following 2 structures are a fairly generic way of representing
21 * the configuration data for a function and AFU, as read from the
22 * configuration space.
23 */
24struct ocxl_afu_config {
25 u8 idx;
26 int dvsec_afu_control_pos; /* offset of AFU control DVSEC */
27 char name[OCXL_AFU_NAME_SZ];
28 u8 version_major;
29 u8 version_minor;
30 u8 afuc_type;
31 u8 afum_type;
32 u8 profile;
33 u8 global_mmio_bar; /* global MMIO area */
34 u64 global_mmio_offset;
35 u32 global_mmio_size;
36 u8 pp_mmio_bar; /* per-process MMIO area */
37 u64 pp_mmio_offset;
38 u32 pp_mmio_stride;
39 u8 log_mem_size;
40 u8 pasid_supported_log;
41 u16 actag_supported;
42};
43
44struct ocxl_fn_config {
45 int dvsec_tl_pos; /* offset of the Transaction Layer DVSEC */
46 int dvsec_function_pos; /* offset of the Function DVSEC */
47 int dvsec_afu_info_pos; /* offset of the AFU information DVSEC */
48 s8 max_pasid_log;
49 s8 max_afu_index;
50};
51
52/*
53 * Read the configuration space of a function and fill in a
54 * ocxl_fn_config structure with all the function details
55 */
56extern int ocxl_config_read_function(struct pci_dev *dev,
57 struct ocxl_fn_config *fn);
58
59/*
60 * Check if an AFU index is valid for the given function.
61 *
62 * AFU indexes can be sparse, so a driver should check all indexes up
63 * to the maximum found in the function description
64 */
65extern int ocxl_config_check_afu_index(struct pci_dev *dev,
66 struct ocxl_fn_config *fn, int afu_idx);
67
68/*
69 * Read the configuration space of a function for the AFU specified by
70 * the index 'afu_idx'. Fills in a ocxl_afu_config structure
71 */
72extern int ocxl_config_read_afu(struct pci_dev *dev,
73 struct ocxl_fn_config *fn,
74 struct ocxl_afu_config *afu,
75 u8 afu_idx);
76
77/*
78 * Get the max PASID value that can be used by the function
79 */
80extern int ocxl_config_get_pasid_info(struct pci_dev *dev, int *count);
81
82/*
83 * Tell an AFU, by writing in the configuration space, the PASIDs that
84 * it can use. Range starts at 'pasid_base' and its size is a multiple
85 * of 2
86 *
87 * 'afu_control_offset' is the offset of the AFU control DVSEC which
88 * can be found in the function configuration
89 */
90extern void ocxl_config_set_afu_pasid(struct pci_dev *dev,
91 int afu_control_offset,
92 int pasid_base, u32 pasid_count_log);
93
94/*
95 * Get the actag configuration for the function:
96 * 'base' is the first actag value that can be used.
97 * 'enabled' it the number of actags available, starting from base.
98 * 'supported' is the total number of actags desired by all the AFUs
99 * of the function.
100 */
101extern int ocxl_config_get_actag_info(struct pci_dev *dev,
102 u16 *base, u16 *enabled, u16 *supported);
103
104/*
105 * Tell a function, by writing in the configuration space, the actags
106 * it can use.
107 *
108 * 'func_offset' is the offset of the Function DVSEC that can found in
109 * the function configuration
110 */
111extern void ocxl_config_set_actag(struct pci_dev *dev, int func_offset,
112 u32 actag_base, u32 actag_count);
113
114/*
115 * Tell an AFU, by writing in the configuration space, the actags it
116 * can use.
117 *
118 * 'afu_control_offset' is the offset of the AFU control DVSEC for the
119 * desired AFU. It can be found in the AFU configuration
120 */
121extern void ocxl_config_set_afu_actag(struct pci_dev *dev,
122 int afu_control_offset,
123 int actag_base, int actag_count);
124
125/*
126 * Enable/disable an AFU, by writing in the configuration space.
127 *
128 * 'afu_control_offset' is the offset of the AFU control DVSEC for the
129 * desired AFU. It can be found in the AFU configuration
130 */
131extern void ocxl_config_set_afu_state(struct pci_dev *dev,
132 int afu_control_offset, int enable);
133
134/*
135 * Set the Transaction Layer configuration in the configuration space.
136 * Only needed for function 0.
137 *
138 * It queries the host TL capabilities, find some common ground
139 * between the host and device, and set the Transaction Layer on both
140 * accordingly.
141 */
142extern int ocxl_config_set_TL(struct pci_dev *dev, int tl_dvsec);
143
144/*
145 * Request an AFU to terminate a PASID.
146 * Will return once the AFU has acked the request, or an error in case
147 * of timeout.
148 *
149 * The hardware can only terminate one PASID at a time, so caller must
150 * guarantee some kind of serialization.
151 *
152 * 'afu_control_offset' is the offset of the AFU control DVSEC for the
153 * desired AFU. It can be found in the AFU configuration
154 */
155extern int ocxl_config_terminate_pasid(struct pci_dev *dev,
156 int afu_control_offset, int pasid);
157
158/*
159 * Set up the opencapi link for the function.
160 *
161 * When called for the first time for a link, it sets up the Shared
162 * Process Area for the link and the interrupt handler to process
163 * translation faults.
164 *
165 * Returns a 'link handle' that should be used for further calls for
166 * the link
167 */
168extern int ocxl_link_setup(struct pci_dev *dev, int PE_mask,
169 void **link_handle);
170
171/*
172 * Remove the association between the function and its link.
173 */
174extern void ocxl_link_release(struct pci_dev *dev, void *link_handle);
175
176/*
177 * Add a Process Element to the Shared Process Area for a link.
178 * The process is defined by its PASID, pid, tid and its mm_struct.
179 *
180 * 'xsl_err_cb' is an optional callback if the driver wants to be
181 * notified when the translation fault interrupt handler detects an
182 * address error.
183 * 'xsl_err_data' is an argument passed to the above callback, if
184 * defined
185 */
186extern int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr,
187 u64 amr, struct mm_struct *mm,
188 void (*xsl_err_cb)(void *data, u64 addr, u64 dsisr),
189 void *xsl_err_data);
190
191/*
192 * Remove a Process Element from the Shared Process Area for a link
193 */
194extern int ocxl_link_remove_pe(void *link_handle, int pasid);
195
196/*
197 * Allocate an AFU interrupt associated to the link.
198 *
199 * 'hw_irq' is the hardware interrupt number
200 * 'obj_handle' is the 64-bit object handle to be passed to the AFU to
201 * trigger the interrupt.
202 * On P9, 'obj_handle' is an address, which, if written, triggers the
203 * interrupt. It is an MMIO address which needs to be remapped (one
204 * page).
205 */
206extern int ocxl_link_irq_alloc(void *link_handle, int *hw_irq,
207 u64 *obj_handle);
208
209/*
210 * Free a previously allocated AFU interrupt
211 */
212extern void ocxl_link_free_irq(void *link_handle, int hw_irq);
213
214#endif /* _MISC_OCXL_H_ */
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
index bb6836986200..3bf73fb58045 100644
--- a/include/uapi/linux/elf.h
+++ b/include/uapi/linux/elf.h
@@ -396,6 +396,7 @@ typedef struct elf64_shdr {
396#define NT_PPC_TM_CTAR 0x10d /* TM checkpointed Target Address Register */ 396#define NT_PPC_TM_CTAR 0x10d /* TM checkpointed Target Address Register */
397#define NT_PPC_TM_CPPR 0x10e /* TM checkpointed Program Priority Register */ 397#define NT_PPC_TM_CPPR 0x10e /* TM checkpointed Program Priority Register */
398#define NT_PPC_TM_CDSCR 0x10f /* TM checkpointed Data Stream Control Register */ 398#define NT_PPC_TM_CDSCR 0x10f /* TM checkpointed Data Stream Control Register */
399#define NT_PPC_PKEY 0x110 /* Memory Protection Keys registers */
399#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ 400#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
400#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ 401#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */
401#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ 402#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
diff --git a/include/uapi/misc/cxl.h b/include/uapi/misc/cxl.h
index 49e8fd08855a..56376d3907d8 100644
--- a/include/uapi/misc/cxl.h
+++ b/include/uapi/misc/cxl.h
@@ -20,20 +20,22 @@ struct cxl_ioctl_start_work {
20 __u64 work_element_descriptor; 20 __u64 work_element_descriptor;
21 __u64 amr; 21 __u64 amr;
22 __s16 num_interrupts; 22 __s16 num_interrupts;
23 __s16 reserved1; 23 __u16 tid;
24 __s32 reserved2; 24 __s32 reserved1;
25 __u64 reserved2;
25 __u64 reserved3; 26 __u64 reserved3;
26 __u64 reserved4; 27 __u64 reserved4;
27 __u64 reserved5; 28 __u64 reserved5;
28 __u64 reserved6;
29}; 29};
30 30
31#define CXL_START_WORK_AMR 0x0000000000000001ULL 31#define CXL_START_WORK_AMR 0x0000000000000001ULL
32#define CXL_START_WORK_NUM_IRQS 0x0000000000000002ULL 32#define CXL_START_WORK_NUM_IRQS 0x0000000000000002ULL
33#define CXL_START_WORK_ERR_FF 0x0000000000000004ULL 33#define CXL_START_WORK_ERR_FF 0x0000000000000004ULL
34#define CXL_START_WORK_TID 0x0000000000000008ULL
34#define CXL_START_WORK_ALL (CXL_START_WORK_AMR |\ 35#define CXL_START_WORK_ALL (CXL_START_WORK_AMR |\
35 CXL_START_WORK_NUM_IRQS |\ 36 CXL_START_WORK_NUM_IRQS |\
36 CXL_START_WORK_ERR_FF) 37 CXL_START_WORK_ERR_FF |\
38 CXL_START_WORK_TID)
37 39
38 40
39/* Possible modes that an afu can be in */ 41/* Possible modes that an afu can be in */
diff --git a/include/uapi/misc/ocxl.h b/include/uapi/misc/ocxl.h
new file mode 100644
index 000000000000..4b0b0b756f3e
--- /dev/null
+++ b/include/uapi/misc/ocxl.h
@@ -0,0 +1,49 @@
1/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
2/* Copyright 2017 IBM Corp. */
3#ifndef _UAPI_MISC_OCXL_H
4#define _UAPI_MISC_OCXL_H
5
6#include <linux/types.h>
7#include <linux/ioctl.h>
8
9enum ocxl_event_type {
10 OCXL_AFU_EVENT_XSL_FAULT_ERROR = 0,
11};
12
13#define OCXL_KERNEL_EVENT_FLAG_LAST 0x0001 /* This is the last event pending */
14
15struct ocxl_kernel_event_header {
16 __u16 type;
17 __u16 flags;
18 __u32 reserved;
19};
20
21struct ocxl_kernel_event_xsl_fault_error {
22 __u64 addr;
23 __u64 dsisr;
24 __u64 count;
25 __u64 reserved;
26};
27
28struct ocxl_ioctl_attach {
29 __u64 amr;
30 __u64 reserved1;
31 __u64 reserved2;
32 __u64 reserved3;
33};
34
35struct ocxl_ioctl_irq_fd {
36 __u64 irq_offset;
37 __s32 eventfd;
38 __u32 reserved;
39};
40
41/* ioctl numbers */
42#define OCXL_MAGIC 0xCA
43/* AFU devices */
44#define OCXL_IOCTL_ATTACH _IOW(OCXL_MAGIC, 0x10, struct ocxl_ioctl_attach)
45#define OCXL_IOCTL_IRQ_ALLOC _IOR(OCXL_MAGIC, 0x11, __u64)
46#define OCXL_IOCTL_IRQ_FREE _IOW(OCXL_MAGIC, 0x12, __u64)
47#define OCXL_IOCTL_IRQ_SET_FD _IOW(OCXL_MAGIC, 0x13, struct ocxl_ioctl_irq_fd)
48
49#endif /* _UAPI_MISC_OCXL_H */
diff --git a/tools/testing/selftests/powerpc/alignment/Makefile b/tools/testing/selftests/powerpc/alignment/Makefile
index 16b22004e75f..083a48a008b4 100644
--- a/tools/testing/selftests/powerpc/alignment/Makefile
+++ b/tools/testing/selftests/powerpc/alignment/Makefile
@@ -1,4 +1,5 @@
1TEST_GEN_PROGS := copy_unaligned copy_first_unaligned paste_unaligned paste_last_unaligned 1TEST_GEN_PROGS := copy_unaligned copy_first_unaligned paste_unaligned \
2 paste_last_unaligned alignment_handler
2 3
3include ../../lib.mk 4include ../../lib.mk
4 5
diff --git a/tools/testing/selftests/powerpc/alignment/alignment_handler.c b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
new file mode 100644
index 000000000000..39fd362415cf
--- /dev/null
+++ b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
@@ -0,0 +1,491 @@
1/*
2 * Test the powerpc alignment handler on POWER8/POWER9
3 *
4 * Copyright (C) 2017 IBM Corporation (Michael Neuling, Andrew Donnellan)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12/*
13 * This selftest exercises the powerpc alignment fault handler.
14 *
15 * We create two sets of source and destination buffers, one in regular memory,
16 * the other cache-inhibited (we use /dev/fb0 for this).
17 *
18 * We initialise the source buffers, then use whichever set of load/store
19 * instructions is under test to copy bytes from the source buffers to the
20 * destination buffers. For the regular buffers, these instructions will
21 * execute normally. For the cache-inhibited buffers, these instructions
22 * will trap and cause an alignment fault, and the alignment fault handler
23 * will emulate the particular instruction under test. We then compare the
24 * destination buffers to ensure that the native and emulated cases give the
25 * same result.
26 *
27 * TODO:
28 * - Any FIXMEs below
29 * - Test VSX regs < 32 and > 32
30 * - Test all loads and stores
31 * - Check update forms do update register
32 * - Test alignment faults over page boundary
33 *
34 * Some old binutils may not support all the instructions.
35 */
36
37
38#include <sys/mman.h>
39#include <sys/types.h>
40#include <sys/stat.h>
41#include <fcntl.h>
42#include <unistd.h>
43#include <stdio.h>
44#include <stdlib.h>
45#include <string.h>
46#include <assert.h>
47#include <getopt.h>
48#include <setjmp.h>
49#include <signal.h>
50
51#include "utils.h"
52
53int bufsize;
54int debug;
55int testing;
56volatile int gotsig;
57
58void sighandler(int sig, siginfo_t *info, void *ctx)
59{
60 struct ucontext *ucp = ctx;
61
62 if (!testing) {
63 signal(sig, SIG_DFL);
64 kill(0, sig);
65 }
66 gotsig = sig;
67#ifdef __powerpc64__
68 ucp->uc_mcontext.gp_regs[PT_NIP] += 4;
69#else
70 ucp->uc_mcontext.uc_regs->gregs[PT_NIP] += 4;
71#endif
72}
73
74#define XFORM(reg, n) " " #reg " ,%"#n",%2 ;"
75#define DFORM(reg, n) " " #reg " ,0(%"#n") ;"
76
77#define TEST(name, ld_op, st_op, form, ld_reg, st_reg) \
78 void test_##name(char *s, char *d) \
79 { \
80 asm volatile( \
81 #ld_op form(ld_reg, 0) \
82 #st_op form(st_reg, 1) \
83 :: "r"(s), "r"(d), "r"(0) \
84 : "memory", "vs0", "vs32", "r31"); \
85 } \
86 rc |= do_test(#name, test_##name)
87
88#define LOAD_VSX_XFORM_TEST(op) TEST(op, op, stxvd2x, XFORM, 32, 32)
89#define STORE_VSX_XFORM_TEST(op) TEST(op, lxvd2x, op, XFORM, 32, 32)
90#define LOAD_VSX_DFORM_TEST(op) TEST(op, op, stxv, DFORM, 32, 32)
91#define STORE_VSX_DFORM_TEST(op) TEST(op, lxv, op, DFORM, 32, 32)
92#define LOAD_VMX_XFORM_TEST(op) TEST(op, op, stxvd2x, XFORM, 0, 32)
93#define STORE_VMX_XFORM_TEST(op) TEST(op, lxvd2x, op, XFORM, 32, 0)
94#define LOAD_VMX_DFORM_TEST(op) TEST(op, op, stxv, DFORM, 0, 32)
95#define STORE_VMX_DFORM_TEST(op) TEST(op, lxv, op, DFORM, 32, 0)
96
97#define LOAD_XFORM_TEST(op) TEST(op, op, stdx, XFORM, 31, 31)
98#define STORE_XFORM_TEST(op) TEST(op, ldx, op, XFORM, 31, 31)
99#define LOAD_DFORM_TEST(op) TEST(op, op, std, DFORM, 31, 31)
100#define STORE_DFORM_TEST(op) TEST(op, ld, op, DFORM, 31, 31)
101
102#define LOAD_FLOAT_DFORM_TEST(op) TEST(op, op, stfd, DFORM, 0, 0)
103#define STORE_FLOAT_DFORM_TEST(op) TEST(op, lfd, op, DFORM, 0, 0)
104#define LOAD_FLOAT_XFORM_TEST(op) TEST(op, op, stfdx, XFORM, 0, 0)
105#define STORE_FLOAT_XFORM_TEST(op) TEST(op, lfdx, op, XFORM, 0, 0)
106
107
108/* FIXME: Unimplemented tests: */
109// STORE_DFORM_TEST(stq) /* FIXME: need two registers for quad */
110// STORE_DFORM_TEST(stswi) /* FIXME: string instruction */
111
112// STORE_XFORM_TEST(stwat) /* AMO can't emulate or run on CI */
113// STORE_XFORM_TEST(stdat) /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
114
115
116/* preload byte by byte */
117void preload_data(void *dst, int offset, int width)
118{
119 char *c = dst;
120 int i;
121
122 c += offset;
123
124 for (i = 0 ; i < width ; i++)
125 c[i] = i;
126}
127
128int test_memcpy(void *dst, void *src, int size, int offset,
129 void (*test_func)(char *, char *))
130{
131 char *s, *d;
132
133 s = src;
134 s += offset;
135 d = dst;
136 d += offset;
137
138 assert(size == 16);
139 gotsig = 0;
140 testing = 1;
141
142 test_func(s, d); /* run the actual test */
143
144 testing = 0;
145 if (gotsig) {
146 if (debug)
147 printf(" Got signal %i\n", gotsig);
148 return 1;
149 }
150 return 0;
151}
152
153void dumpdata(char *s1, char *s2, int n, char *test_name)
154{
155 int i;
156
157 printf(" %s: unexpected result:\n", test_name);
158 printf(" mem:");
159 for (i = 0; i < n; i++)
160 printf(" %02x", s1[i]);
161 printf("\n");
162 printf(" ci: ");
163 for (i = 0; i < n; i++)
164 printf(" %02x", s2[i]);
165 printf("\n");
166}
167
168int test_memcmp(void *s1, void *s2, int n, int offset, char *test_name)
169{
170 char *s1c, *s2c;
171
172 s1c = s1;
173 s1c += offset;
174 s2c = s2;
175 s2c += offset;
176
177 if (memcmp(s1c, s2c, n)) {
178 if (debug) {
179 printf("\n Compare failed. Offset:%i length:%i\n",
180 offset, n);
181 dumpdata(s1c, s2c, n, test_name);
182 }
183 return 1;
184 }
185 return 0;
186}
187
188/*
189 * Do two memcpy tests using the same instructions. One cachable
190 * memory and the other doesn't.
191 */
192int do_test(char *test_name, void (*test_func)(char *, char *))
193{
194 int offset, width, fd, rc = 0, r;
195 void *mem0, *mem1, *ci0, *ci1;
196
197 printf("\tDoing %s:\t", test_name);
198
199 fd = open("/dev/fb0", O_RDWR);
200 if (fd < 0) {
201 printf("\n");
202 perror("Can't open /dev/fb0");
203 SKIP_IF(1);
204 }
205
206 ci0 = mmap(NULL, bufsize, PROT_WRITE, MAP_SHARED,
207 fd, 0x0);
208 ci1 = mmap(NULL, bufsize, PROT_WRITE, MAP_SHARED,
209 fd, bufsize);
210 if ((ci0 == MAP_FAILED) || (ci1 == MAP_FAILED)) {
211 printf("\n");
212 perror("mmap failed");
213 SKIP_IF(1);
214 }
215
216 rc = posix_memalign(&mem0, bufsize, bufsize);
217 if (rc) {
218 printf("\n");
219 return rc;
220 }
221
222 rc = posix_memalign(&mem1, bufsize, bufsize);
223 if (rc) {
224 printf("\n");
225 free(mem0);
226 return rc;
227 }
228
229 /* offset = 0 no alignment fault, so skip */
230 for (offset = 1; offset < 16; offset++) {
231 width = 16; /* vsx == 16 bytes */
232 r = 0;
233
234 /* load pattern into memory byte by byte */
235 preload_data(ci0, offset, width);
236 preload_data(mem0, offset, width); // FIXME: remove??
237 memcpy(ci0, mem0, bufsize);
238 memcpy(ci1, mem1, bufsize); /* initialise output to the same */
239
240 /* sanity check */
241 test_memcmp(mem0, ci0, width, offset, test_name);
242
243 r |= test_memcpy(ci1, ci0, width, offset, test_func);
244 r |= test_memcpy(mem1, mem0, width, offset, test_func);
245 if (r && !debug) {
246 printf("FAILED: Got signal");
247 break;
248 }
249
250 r |= test_memcmp(mem1, ci1, width, offset, test_name);
251 rc |= r;
252 if (r && !debug) {
253 printf("FAILED: Wrong Data");
254 break;
255 }
256 }
257 if (!r)
258 printf("PASSED");
259 printf("\n");
260
261 munmap(ci0, bufsize);
262 munmap(ci1, bufsize);
263 free(mem0);
264 free(mem1);
265
266 return rc;
267}
268
269int test_alignment_handler_vsx_206(void)
270{
271 int rc = 0;
272
273 printf("VSX: 2.06B\n");
274 LOAD_VSX_XFORM_TEST(lxvd2x);
275 LOAD_VSX_XFORM_TEST(lxvw4x);
276 LOAD_VSX_XFORM_TEST(lxsdx);
277 LOAD_VSX_XFORM_TEST(lxvdsx);
278 STORE_VSX_XFORM_TEST(stxvd2x);
279 STORE_VSX_XFORM_TEST(stxvw4x);
280 STORE_VSX_XFORM_TEST(stxsdx);
281 return rc;
282}
283
284int test_alignment_handler_vsx_207(void)
285{
286 int rc = 0;
287
288 printf("VSX: 2.07B\n");
289 LOAD_VSX_XFORM_TEST(lxsspx);
290 LOAD_VSX_XFORM_TEST(lxsiwax);
291 LOAD_VSX_XFORM_TEST(lxsiwzx);
292 STORE_VSX_XFORM_TEST(stxsspx);
293 STORE_VSX_XFORM_TEST(stxsiwx);
294 return rc;
295}
296
297int test_alignment_handler_vsx_300(void)
298{
299 int rc = 0;
300
301 SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00));
302 printf("VSX: 3.00B\n");
303 LOAD_VMX_DFORM_TEST(lxsd);
304 LOAD_VSX_XFORM_TEST(lxsibzx);
305 LOAD_VSX_XFORM_TEST(lxsihzx);
306 LOAD_VMX_DFORM_TEST(lxssp);
307 LOAD_VSX_DFORM_TEST(lxv);
308 LOAD_VSX_XFORM_TEST(lxvb16x);
309 LOAD_VSX_XFORM_TEST(lxvh8x);
310 LOAD_VSX_XFORM_TEST(lxvx);
311 LOAD_VSX_XFORM_TEST(lxvwsx);
312 LOAD_VSX_XFORM_TEST(lxvl);
313 LOAD_VSX_XFORM_TEST(lxvll);
314 STORE_VMX_DFORM_TEST(stxsd);
315 STORE_VSX_XFORM_TEST(stxsibx);
316 STORE_VSX_XFORM_TEST(stxsihx);
317 STORE_VMX_DFORM_TEST(stxssp);
318 STORE_VSX_DFORM_TEST(stxv);
319 STORE_VSX_XFORM_TEST(stxvb16x);
320 STORE_VSX_XFORM_TEST(stxvh8x);
321 STORE_VSX_XFORM_TEST(stxvx);
322 STORE_VSX_XFORM_TEST(stxvl);
323 STORE_VSX_XFORM_TEST(stxvll);
324 return rc;
325}
326
327int test_alignment_handler_integer(void)
328{
329 int rc = 0;
330
331 printf("Integer\n");
332 LOAD_DFORM_TEST(lbz);
333 LOAD_DFORM_TEST(lbzu);
334 LOAD_XFORM_TEST(lbzx);
335 LOAD_XFORM_TEST(lbzux);
336 LOAD_DFORM_TEST(lhz);
337 LOAD_DFORM_TEST(lhzu);
338 LOAD_XFORM_TEST(lhzx);
339 LOAD_XFORM_TEST(lhzux);
340 LOAD_DFORM_TEST(lha);
341 LOAD_DFORM_TEST(lhau);
342 LOAD_XFORM_TEST(lhax);
343 LOAD_XFORM_TEST(lhaux);
344 LOAD_XFORM_TEST(lhbrx);
345 LOAD_DFORM_TEST(lwz);
346 LOAD_DFORM_TEST(lwzu);
347 LOAD_XFORM_TEST(lwzx);
348 LOAD_XFORM_TEST(lwzux);
349 LOAD_DFORM_TEST(lwa);
350 LOAD_XFORM_TEST(lwax);
351 LOAD_XFORM_TEST(lwaux);
352 LOAD_XFORM_TEST(lwbrx);
353 LOAD_DFORM_TEST(ld);
354 LOAD_DFORM_TEST(ldu);
355 LOAD_XFORM_TEST(ldx);
356 LOAD_XFORM_TEST(ldux);
357 LOAD_XFORM_TEST(ldbrx);
358 LOAD_DFORM_TEST(lmw);
359 STORE_DFORM_TEST(stb);
360 STORE_XFORM_TEST(stbx);
361 STORE_DFORM_TEST(stbu);
362 STORE_XFORM_TEST(stbux);
363 STORE_DFORM_TEST(sth);
364 STORE_XFORM_TEST(sthx);
365 STORE_DFORM_TEST(sthu);
366 STORE_XFORM_TEST(sthux);
367 STORE_XFORM_TEST(sthbrx);
368 STORE_DFORM_TEST(stw);
369 STORE_XFORM_TEST(stwx);
370 STORE_DFORM_TEST(stwu);
371 STORE_XFORM_TEST(stwux);
372 STORE_XFORM_TEST(stwbrx);
373 STORE_DFORM_TEST(std);
374 STORE_XFORM_TEST(stdx);
375 STORE_DFORM_TEST(stdu);
376 STORE_XFORM_TEST(stdux);
377 STORE_XFORM_TEST(stdbrx);
378 STORE_DFORM_TEST(stmw);
379 return rc;
380}
381
382int test_alignment_handler_vmx(void)
383{
384 int rc = 0;
385
386 printf("VMX\n");
387 LOAD_VMX_XFORM_TEST(lvx);
388
389 /*
390 * FIXME: These loads only load part of the register, so our
391 * testing method doesn't work. Also they don't take alignment
392 * faults, so it's kinda pointless anyway
393 *
394 LOAD_VMX_XFORM_TEST(lvebx)
395 LOAD_VMX_XFORM_TEST(lvehx)
396 LOAD_VMX_XFORM_TEST(lvewx)
397 LOAD_VMX_XFORM_TEST(lvxl)
398 */
399 STORE_VMX_XFORM_TEST(stvx);
400 STORE_VMX_XFORM_TEST(stvebx);
401 STORE_VMX_XFORM_TEST(stvehx);
402 STORE_VMX_XFORM_TEST(stvewx);
403 STORE_VMX_XFORM_TEST(stvxl);
404 return rc;
405}
406
407int test_alignment_handler_fp(void)
408{
409 int rc = 0;
410
411 printf("Floating point\n");
412 LOAD_FLOAT_DFORM_TEST(lfd);
413 LOAD_FLOAT_XFORM_TEST(lfdx);
414 LOAD_FLOAT_DFORM_TEST(lfdp);
415 LOAD_FLOAT_XFORM_TEST(lfdpx);
416 LOAD_FLOAT_DFORM_TEST(lfdu);
417 LOAD_FLOAT_XFORM_TEST(lfdux);
418 LOAD_FLOAT_DFORM_TEST(lfs);
419 LOAD_FLOAT_XFORM_TEST(lfsx);
420 LOAD_FLOAT_DFORM_TEST(lfsu);
421 LOAD_FLOAT_XFORM_TEST(lfsux);
422 LOAD_FLOAT_XFORM_TEST(lfiwzx);
423 LOAD_FLOAT_XFORM_TEST(lfiwax);
424 STORE_FLOAT_DFORM_TEST(stfd);
425 STORE_FLOAT_XFORM_TEST(stfdx);
426 STORE_FLOAT_DFORM_TEST(stfdp);
427 STORE_FLOAT_XFORM_TEST(stfdpx);
428 STORE_FLOAT_DFORM_TEST(stfdu);
429 STORE_FLOAT_XFORM_TEST(stfdux);
430 STORE_FLOAT_DFORM_TEST(stfs);
431 STORE_FLOAT_XFORM_TEST(stfsx);
432 STORE_FLOAT_DFORM_TEST(stfsu);
433 STORE_FLOAT_XFORM_TEST(stfsux);
434 STORE_FLOAT_XFORM_TEST(stfiwx);
435
436 return rc;
437}
438
439void usage(char *prog)
440{
441 printf("Usage: %s [options]\n", prog);
442 printf(" -d Enable debug error output\n");
443 printf("\n");
444 printf("This test requires a POWER8 or POWER9 CPU and a usable ");
445 printf("framebuffer at /dev/fb0.\n");
446}
447
448int main(int argc, char *argv[])
449{
450
451 struct sigaction sa;
452 int rc = 0;
453 int option = 0;
454
455 while ((option = getopt(argc, argv, "d")) != -1) {
456 switch (option) {
457 case 'd':
458 debug++;
459 break;
460 default:
461 usage(argv[0]);
462 exit(1);
463 }
464 }
465
466 bufsize = getpagesize();
467
468 sa.sa_sigaction = sighandler;
469 sigemptyset(&sa.sa_mask);
470 sa.sa_flags = SA_SIGINFO;
471 if (sigaction(SIGSEGV, &sa, NULL) == -1
472 || sigaction(SIGBUS, &sa, NULL) == -1
473 || sigaction(SIGILL, &sa, NULL) == -1) {
474 perror("sigaction");
475 exit(1);
476 }
477
478 rc |= test_harness(test_alignment_handler_vsx_206,
479 "test_alignment_handler_vsx_206");
480 rc |= test_harness(test_alignment_handler_vsx_207,
481 "test_alignment_handler_vsx_207");
482 rc |= test_harness(test_alignment_handler_vsx_300,
483 "test_alignment_handler_vsx_300");
484 rc |= test_harness(test_alignment_handler_integer,
485 "test_alignment_handler_integer");
486 rc |= test_harness(test_alignment_handler_vmx,
487 "test_alignment_handler_vmx");
488 rc |= test_harness(test_alignment_handler_fp,
489 "test_alignment_handler_fp");
490 return rc;
491}
diff --git a/tools/testing/selftests/powerpc/benchmarks/mmap_bench.c b/tools/testing/selftests/powerpc/benchmarks/mmap_bench.c
index 8d084a2d6e74..7a0a462a2272 100644
--- a/tools/testing/selftests/powerpc/benchmarks/mmap_bench.c
+++ b/tools/testing/selftests/powerpc/benchmarks/mmap_bench.c
@@ -7,17 +7,34 @@
7#include <stdlib.h> 7#include <stdlib.h>
8#include <sys/mman.h> 8#include <sys/mman.h>
9#include <time.h> 9#include <time.h>
10#include <getopt.h>
10 11
11#include "utils.h" 12#include "utils.h"
12 13
13#define ITERATIONS 5000000 14#define ITERATIONS 5000000
14 15
15#define MEMSIZE (128 * 1024 * 1024) 16#define MEMSIZE (1UL << 27)
17#define PAGE_SIZE (1UL << 16)
18#define CHUNK_COUNT (MEMSIZE/PAGE_SIZE)
19
20static int pg_fault;
21static int iterations = ITERATIONS;
22
23static struct option options[] = {
24 { "pgfault", no_argument, &pg_fault, 1 },
25 { "iterations", required_argument, 0, 'i' },
26 { 0, },
27};
28
29static void usage(void)
30{
31 printf("mmap_bench <--pgfault> <--iterations count>\n");
32}
16 33
17int test_mmap(void) 34int test_mmap(void)
18{ 35{
19 struct timespec ts_start, ts_end; 36 struct timespec ts_start, ts_end;
20 unsigned long i = ITERATIONS; 37 unsigned long i = iterations;
21 38
22 clock_gettime(CLOCK_MONOTONIC, &ts_start); 39 clock_gettime(CLOCK_MONOTONIC, &ts_start);
23 40
@@ -25,6 +42,11 @@ int test_mmap(void)
25 char *c = mmap(NULL, MEMSIZE, PROT_READ|PROT_WRITE, 42 char *c = mmap(NULL, MEMSIZE, PROT_READ|PROT_WRITE,
26 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 43 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
27 FAIL_IF(c == MAP_FAILED); 44 FAIL_IF(c == MAP_FAILED);
45 if (pg_fault) {
46 int count;
47 for (count = 0; count < CHUNK_COUNT; count++)
48 c[count << 16] = 'c';
49 }
28 munmap(c, MEMSIZE); 50 munmap(c, MEMSIZE);
29 } 51 }
30 52
@@ -35,7 +57,32 @@ int test_mmap(void)
35 return 0; 57 return 0;
36} 58}
37 59
38int main(void) 60int main(int argc, char *argv[])
39{ 61{
62 signed char c;
63 while (1) {
64 int option_index = 0;
65
66 c = getopt_long(argc, argv, "", options, &option_index);
67
68 if (c == -1)
69 break;
70
71 switch (c) {
72 case 0:
73 if (options[option_index].flag != 0)
74 break;
75
76 usage();
77 exit(1);
78 break;
79 case 'i':
80 iterations = atoi(optarg);
81 break;
82 default:
83 usage();
84 exit(1);
85 }
86 }
40 return test_harness(test_mmap, "mmap_bench"); 87 return test_harness(test_mmap, "mmap_bench");
41} 88}
diff --git a/tools/testing/selftests/powerpc/mm/.gitignore b/tools/testing/selftests/powerpc/mm/.gitignore
index e715a3f2fbf4..7d7c42ed6de9 100644
--- a/tools/testing/selftests/powerpc/mm/.gitignore
+++ b/tools/testing/selftests/powerpc/mm/.gitignore
@@ -1,4 +1,5 @@
1hugetlb_vs_thp_test 1hugetlb_vs_thp_test
2subpage_prot 2subpage_prot
3tempfile 3tempfile
4prot_sao \ No newline at end of file 4prot_sao
5segv_errors \ No newline at end of file
diff --git a/tools/testing/selftests/powerpc/mm/Makefile b/tools/testing/selftests/powerpc/mm/Makefile
index bf315bcbe663..8ebbe96d80a8 100644
--- a/tools/testing/selftests/powerpc/mm/Makefile
+++ b/tools/testing/selftests/powerpc/mm/Makefile
@@ -2,7 +2,7 @@
2noarg: 2noarg:
3 $(MAKE) -C ../ 3 $(MAKE) -C ../
4 4
5TEST_GEN_PROGS := hugetlb_vs_thp_test subpage_prot prot_sao 5TEST_GEN_PROGS := hugetlb_vs_thp_test subpage_prot prot_sao segv_errors
6TEST_GEN_FILES := tempfile 6TEST_GEN_FILES := tempfile
7 7
8include ../../lib.mk 8include ../../lib.mk
diff --git a/tools/testing/selftests/powerpc/mm/segv_errors.c b/tools/testing/selftests/powerpc/mm/segv_errors.c
new file mode 100644
index 000000000000..06ae76ee3ea1
--- /dev/null
+++ b/tools/testing/selftests/powerpc/mm/segv_errors.c
@@ -0,0 +1,78 @@
1// SPDX-License-Identifier: GPL-2.0
2
3/*
4 * Copyright 2017 John Sperbeck
5 *
6 * Test that an access to a mapped but inaccessible area causes a SEGV and
7 * reports si_code == SEGV_ACCERR.
8 */
9
10#include <stdbool.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <unistd.h>
15#include <signal.h>
16#include <sys/mman.h>
17#include <assert.h>
18#include <ucontext.h>
19
20#include "utils.h"
21
22static bool faulted;
23static int si_code;
24
25static void segv_handler(int n, siginfo_t *info, void *ctxt_v)
26{
27 ucontext_t *ctxt = (ucontext_t *)ctxt_v;
28 struct pt_regs *regs = ctxt->uc_mcontext.regs;
29
30 faulted = true;
31 si_code = info->si_code;
32 regs->nip += 4;
33}
34
35int test_segv_errors(void)
36{
37 struct sigaction act = {
38 .sa_sigaction = segv_handler,
39 .sa_flags = SA_SIGINFO,
40 };
41 char c, *p = NULL;
42
43 p = mmap(NULL, getpagesize(), 0, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
44 FAIL_IF(p == MAP_FAILED);
45
46 FAIL_IF(sigaction(SIGSEGV, &act, NULL) != 0);
47
48 faulted = false;
49 si_code = 0;
50
51 /*
52 * We just need a compiler barrier, but mb() works and has the nice
53 * property of being easy to spot in the disassembly.
54 */
55 mb();
56 c = *p;
57 mb();
58
59 FAIL_IF(!faulted);
60 FAIL_IF(si_code != SEGV_ACCERR);
61
62 faulted = false;
63 si_code = 0;
64
65 mb();
66 *p = c;
67 mb();
68
69 FAIL_IF(!faulted);
70 FAIL_IF(si_code != SEGV_ACCERR);
71
72 return 0;
73}
74
75int main(void)
76{
77 return test_harness(test_segv_errors, "segv_errors");
78}
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-vsx.c b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-vsx.c
index 0df3c23b7888..277dade1b382 100644
--- a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-vsx.c
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-vsx.c
@@ -79,8 +79,8 @@ trans:
79 : [res] "=r" (result), [texasr] "=r" (texasr) 79 : [res] "=r" (result), [texasr] "=r" (texasr)
80 : [fp_load] "r" (fp_load), [fp_load_ckpt] "r" (fp_load_ckpt), 80 : [fp_load] "r" (fp_load), [fp_load_ckpt] "r" (fp_load_ckpt),
81 [sprn_texasr] "i" (SPRN_TEXASR) 81 [sprn_texasr] "i" (SPRN_TEXASR)
82 : "memory", "r0", "r1", "r2", "r3", "r4", 82 : "memory", "r0", "r1", "r3", "r4",
83 "r8", "r9", "r10", "r11" 83 "r7", "r8", "r9", "r10", "r11"
84 ); 84 );
85 85
86 if (result) { 86 if (result) {
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c
index 94e57cb89769..51427a2465f6 100644
--- a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c
@@ -76,8 +76,7 @@ trans:
76 : [tfhar] "=r" (tfhar), [res] "=r" (result), 76 : [tfhar] "=r" (tfhar), [res] "=r" (result),
77 [texasr] "=r" (texasr), [cptr1] "=r" (cptr1) 77 [texasr] "=r" (texasr), [cptr1] "=r" (cptr1)
78 : [sprn_texasr] "i" (SPRN_TEXASR) 78 : [sprn_texasr] "i" (SPRN_TEXASR)
79 : "memory", "r0", "r1", "r2", "r3", "r4", 79 : "memory", "r0", "r8", "r31"
80 "r8", "r9", "r10", "r11", "r31"
81 ); 80 );
82 81
83 /* There are 2 32bit instructions before tbegin. */ 82 /* There are 2 32bit instructions before tbegin. */
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-vsx.c b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-vsx.c
index b4081e2b22d5..17c23cabac3e 100644
--- a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-vsx.c
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-vsx.c
@@ -67,7 +67,7 @@ trans:
67 : [res] "=r" (result), [texasr] "=r" (texasr) 67 : [res] "=r" (result), [texasr] "=r" (texasr)
68 : [fp_load] "r" (fp_load), [fp_load_ckpt] "r" (fp_load_ckpt), 68 : [fp_load] "r" (fp_load), [fp_load_ckpt] "r" (fp_load_ckpt),
69 [sprn_texasr] "i" (SPRN_TEXASR), [cptr1] "r" (&cptr[1]) 69 [sprn_texasr] "i" (SPRN_TEXASR), [cptr1] "r" (&cptr[1])
70 : "memory", "r0", "r1", "r2", "r3", "r4", 70 : "memory", "r0", "r1", "r3", "r4",
71 "r7", "r8", "r9", "r10", "r11" 71 "r7", "r8", "r9", "r10", "r11"
72 ); 72 );
73 73
diff --git a/tools/testing/selftests/powerpc/tm/.gitignore b/tools/testing/selftests/powerpc/tm/.gitignore
index 241a4a4ee0e4..bb90d4b79524 100644
--- a/tools/testing/selftests/powerpc/tm/.gitignore
+++ b/tools/testing/selftests/powerpc/tm/.gitignore
@@ -13,3 +13,4 @@ tm-signal-context-chk-vmx
13tm-signal-context-chk-vsx 13tm-signal-context-chk-vsx
14tm-vmx-unavail 14tm-vmx-unavail
15tm-unavailable 15tm-unavailable
16tm-trap
diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile
index 8ed6f8c57230..a23453943ad2 100644
--- a/tools/testing/selftests/powerpc/tm/Makefile
+++ b/tools/testing/selftests/powerpc/tm/Makefile
@@ -3,7 +3,7 @@ SIGNAL_CONTEXT_CHK_TESTS := tm-signal-context-chk-gpr tm-signal-context-chk-fpu
3 tm-signal-context-chk-vmx tm-signal-context-chk-vsx 3 tm-signal-context-chk-vmx tm-signal-context-chk-vsx
4 4
5TEST_GEN_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack \ 5TEST_GEN_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack \
6 tm-vmxcopy tm-fork tm-tar tm-tmspr tm-vmx-unavail tm-unavailable \ 6 tm-vmxcopy tm-fork tm-tar tm-tmspr tm-vmx-unavail tm-unavailable tm-trap \
7 $(SIGNAL_CONTEXT_CHK_TESTS) 7 $(SIGNAL_CONTEXT_CHK_TESTS)
8 8
9include ../../lib.mk 9include ../../lib.mk
@@ -18,6 +18,7 @@ $(OUTPUT)/tm-tmspr: CFLAGS += -pthread
18$(OUTPUT)/tm-vmx-unavail: CFLAGS += -pthread -m64 18$(OUTPUT)/tm-vmx-unavail: CFLAGS += -pthread -m64
19$(OUTPUT)/tm-resched-dscr: ../pmu/lib.o 19$(OUTPUT)/tm-resched-dscr: ../pmu/lib.o
20$(OUTPUT)/tm-unavailable: CFLAGS += -O0 -pthread -m64 -Wno-error=uninitialized -mvsx 20$(OUTPUT)/tm-unavailable: CFLAGS += -O0 -pthread -m64 -Wno-error=uninitialized -mvsx
21$(OUTPUT)/tm-trap: CFLAGS += -O0 -pthread -m64
21 22
22SIGNAL_CONTEXT_CHK_TESTS := $(patsubst %,$(OUTPUT)/%,$(SIGNAL_CONTEXT_CHK_TESTS)) 23SIGNAL_CONTEXT_CHK_TESTS := $(patsubst %,$(OUTPUT)/%,$(SIGNAL_CONTEXT_CHK_TESTS))
23$(SIGNAL_CONTEXT_CHK_TESTS): tm-signal.S 24$(SIGNAL_CONTEXT_CHK_TESTS): tm-signal.S
diff --git a/tools/testing/selftests/powerpc/tm/tm-trap.c b/tools/testing/selftests/powerpc/tm/tm-trap.c
new file mode 100644
index 000000000000..5d92c23ee6cb
--- /dev/null
+++ b/tools/testing/selftests/powerpc/tm/tm-trap.c
@@ -0,0 +1,329 @@
1/*
2 * Copyright 2017, Gustavo Romero, IBM Corp.
3 * Licensed under GPLv2.
4 *
5 * Check if thread endianness is flipped inadvertently to BE on trap
6 * caught in TM whilst MSR.FP and MSR.VEC are zero (i.e. just after
7 * load_fp and load_vec overflowed).
8 *
9 * The issue can be checked on LE machines simply by zeroing load_fp
10 * and load_vec and then causing a trap in TM. Since the endianness
11 * changes to BE on return from the signal handler, 'nop' is
12 * thread as an illegal instruction in following sequence:
13 * tbegin.
14 * beq 1f
15 * trap
16 * tend.
17 * 1: nop
18 *
19 * However, although the issue is also present on BE machines, it's a
20 * bit trickier to check it on BE machines because MSR.LE bit is set
21 * to zero which determines a BE endianness that is the native
22 * endianness on BE machines, so nothing notably critical happens,
23 * i.e. no illegal instruction is observed immediately after returning
24 * from the signal handler (as it happens on LE machines). Thus to test
25 * it on BE machines LE endianness is forced after a first trap and then
26 * the endianness is verified on subsequent traps to determine if the
27 * endianness "flipped back" to the native endianness (BE).
28 */
29
30#define _GNU_SOURCE
31#include <error.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include <unistd.h>
35#include <htmintrin.h>
36#include <inttypes.h>
37#include <pthread.h>
38#include <sched.h>
39#include <signal.h>
40#include <stdbool.h>
41
42#include "tm.h"
43#include "utils.h"
44
45#define pr_error(error_code, format, ...) \
46 error_at_line(1, error_code, __FILE__, __LINE__, format, ##__VA_ARGS__)
47
48#define MSR_LE 1UL
49#define LE 1UL
50
51pthread_t t0_ping;
52pthread_t t1_pong;
53
54int exit_from_pong;
55
56int trap_event;
57int le;
58
59bool success;
60
61void trap_signal_handler(int signo, siginfo_t *si, void *uc)
62{
63 ucontext_t *ucp = uc;
64 uint64_t thread_endianness;
65
66 /* Get thread endianness: extract bit LE from MSR */
67 thread_endianness = MSR_LE & ucp->uc_mcontext.gp_regs[PT_MSR];
68
69 /***
70 * Little-Endian Machine
71 */
72
73 if (le) {
74 /* First trap event */
75 if (trap_event == 0) {
76 /* Do nothing. Since it is returning from this trap
77 * event that endianness is flipped by the bug, so just
78 * let the process return from the signal handler and
79 * check on the second trap event if endianness is
80 * flipped or not.
81 */
82 }
83 /* Second trap event */
84 else if (trap_event == 1) {
85 /*
86 * Since trap was caught in TM on first trap event, if
87 * endianness was still LE (not flipped inadvertently)
88 * after returning from the signal handler instruction
89 * (1) is executed (basically a 'nop'), as it's located
90 * at address of tbegin. +4 (rollback addr). As (1) on
91 * LE endianness does in effect nothing, instruction (2)
92 * is then executed again as 'trap', generating a second
93 * trap event (note that in that case 'trap' is caught
94 * not in transacional mode). On te other hand, if after
95 * the return from the signal handler the endianness in-
96 * advertently flipped, instruction (1) is tread as a
97 * branch instruction, i.e. b .+8, hence instruction (3)
98 * and (4) are executed (tbegin.; trap;) and we get sim-
99 * ilaly on the trap signal handler, but now in TM mode.
100 * Either way, it's now possible to check the MSR LE bit
101 * once in the trap handler to verify if endianness was
102 * flipped or not after the return from the second trap
103 * event. If endianness is flipped, the bug is present.
104 * Finally, getting a trap in TM mode or not is just
105 * worth noting because it affects the math to determine
106 * the offset added to the NIP on return: the NIP for a
107 * trap caught in TM is the rollback address, i.e. the
108 * next instruction after 'tbegin.', whilst the NIP for
109 * a trap caught in non-transactional mode is the very
110 * same address of the 'trap' instruction that generated
111 * the trap event.
112 */
113
114 if (thread_endianness == LE) {
115 /* Go to 'success', i.e. instruction (6) */
116 ucp->uc_mcontext.gp_regs[PT_NIP] += 16;
117 } else {
118 /*
119 * Thread endianness is BE, so it flipped
120 * inadvertently. Thus we flip back to LE and
121 * set NIP to go to 'failure', instruction (5).
122 */
123 ucp->uc_mcontext.gp_regs[PT_MSR] |= 1UL;
124 ucp->uc_mcontext.gp_regs[PT_NIP] += 4;
125 }
126 }
127 }
128
129 /***
130 * Big-Endian Machine
131 */
132
133 else {
134 /* First trap event */
135 if (trap_event == 0) {
136 /*
137 * Force thread endianness to be LE. Instructions (1),
138 * (3), and (4) will be executed, generating a second
139 * trap in TM mode.
140 */
141 ucp->uc_mcontext.gp_regs[PT_MSR] |= 1UL;
142 }
143 /* Second trap event */
144 else if (trap_event == 1) {
145 /*
146 * Do nothing. If bug is present on return from this
147 * second trap event endianness will flip back "automat-
148 * ically" to BE, otherwise thread endianness will
149 * continue to be LE, just as it was set above.
150 */
151 }
152 /* A third trap event */
153 else {
154 /*
155 * Once here it means that after returning from the sec-
156 * ond trap event instruction (4) (trap) was executed
157 * as LE, generating a third trap event. In that case
158 * endianness is still LE as set on return from the
159 * first trap event, hence no bug. Otherwise, bug
160 * flipped back to BE on return from the second trap
161 * event and instruction (4) was executed as 'tdi' (so
162 * basically a 'nop') and branch to 'failure' in
163 * instruction (5) was taken to indicate failure and we
164 * never get here.
165 */
166
167 /*
168 * Flip back to BE and go to instruction (6), i.e. go to
169 * 'success'.
170 */
171 ucp->uc_mcontext.gp_regs[PT_MSR] &= ~1UL;
172 ucp->uc_mcontext.gp_regs[PT_NIP] += 8;
173 }
174 }
175
176 trap_event++;
177}
178
179void usr1_signal_handler(int signo, siginfo_t *si, void *not_used)
180{
181 /* Got a USR1 signal from ping(), so just tell pong() to exit */
182 exit_from_pong = 1;
183}
184
185void *ping(void *not_used)
186{
187 uint64_t i;
188
189 trap_event = 0;
190
191 /*
192 * Wait an amount of context switches so load_fp and load_vec overflows
193 * and MSR_[FP|VEC|V] is 0.
194 */
195 for (i = 0; i < 1024*1024*512; i++)
196 ;
197
198 asm goto(
199 /*
200 * [NA] means "Native Endianness", i.e. it tells how a
201 * instruction is executed on machine's native endianness (in
202 * other words, native endianness matches kernel endianness).
203 * [OP] means "Opposite Endianness", i.e. on a BE machine, it
204 * tells how a instruction is executed as a LE instruction; con-
205 * versely, on a LE machine, it tells how a instruction is
206 * executed as a BE instruction. When [NA] is omitted, it means
207 * that the native interpretation of a given instruction is not
208 * relevant for the test. Likewise when [OP] is omitted.
209 */
210
211 " tbegin. ;" /* (0) tbegin. [NA] */
212 " tdi 0, 0, 0x48;" /* (1) nop [NA]; b (3) [OP] */
213 " trap ;" /* (2) trap [NA] */
214 ".long 0x1D05007C;" /* (3) tbegin. [OP] */
215 ".long 0x0800E07F;" /* (4) trap [OP]; nop [NA] */
216 " b %l[failure] ;" /* (5) b [NA]; MSR.LE flipped (bug) */
217 " b %l[success] ;" /* (6) b [NA]; MSR.LE did not flip (ok)*/
218
219 : : : : failure, success);
220
221failure:
222 success = false;
223 goto exit_from_ping;
224
225success:
226 success = true;
227
228exit_from_ping:
229 /* Tell pong() to exit before leaving */
230 pthread_kill(t1_pong, SIGUSR1);
231 return NULL;
232}
233
234void *pong(void *not_used)
235{
236 while (!exit_from_pong)
237 /*
238 * Induce context switches on ping() thread
239 * until ping() finishes its job and signs
240 * to exit from this loop.
241 */
242 sched_yield();
243
244 return NULL;
245}
246
247int tm_trap_test(void)
248{
249 uint16_t k = 1;
250
251 int rc;
252
253 pthread_attr_t attr;
254 cpu_set_t cpuset;
255
256 struct sigaction trap_sa;
257
258 trap_sa.sa_flags = SA_SIGINFO;
259 trap_sa.sa_sigaction = trap_signal_handler;
260 sigaction(SIGTRAP, &trap_sa, NULL);
261
262 struct sigaction usr1_sa;
263
264 usr1_sa.sa_flags = SA_SIGINFO;
265 usr1_sa.sa_sigaction = usr1_signal_handler;
266 sigaction(SIGUSR1, &usr1_sa, NULL);
267
268 /* Set only CPU 0 in the mask. Both threads will be bound to cpu 0. */
269 CPU_ZERO(&cpuset);
270 CPU_SET(0, &cpuset);
271
272 /* Init pthread attribute */
273 rc = pthread_attr_init(&attr);
274 if (rc)
275 pr_error(rc, "pthread_attr_init()");
276
277 /*
278 * Bind thread ping() and pong() both to CPU 0 so they ping-pong and
279 * speed up context switches on ping() thread, speeding up the load_fp
280 * and load_vec overflow.
281 */
282 rc = pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpuset);
283 if (rc)
284 pr_error(rc, "pthread_attr_setaffinity()");
285
286 /* Figure out the machine endianness */
287 le = (int) *(uint8_t *)&k;
288
289 printf("%s machine detected. Checking if endianness flips %s",
290 le ? "Little-Endian" : "Big-Endian",
291 "inadvertently on trap in TM... ");
292
293 rc = fflush(0);
294 if (rc)
295 pr_error(rc, "fflush()");
296
297 /* Launch ping() */
298 rc = pthread_create(&t0_ping, &attr, ping, NULL);
299 if (rc)
300 pr_error(rc, "pthread_create()");
301
302 exit_from_pong = 0;
303
304 /* Launch pong() */
305 rc = pthread_create(&t1_pong, &attr, pong, NULL);
306 if (rc)
307 pr_error(rc, "pthread_create()");
308
309 rc = pthread_join(t0_ping, NULL);
310 if (rc)
311 pr_error(rc, "pthread_join()");
312
313 rc = pthread_join(t1_pong, NULL);
314 if (rc)
315 pr_error(rc, "pthread_join()");
316
317 if (success) {
318 printf("no.\n"); /* no, endianness did not flip inadvertently */
319 return EXIT_SUCCESS;
320 }
321
322 printf("yes!\n"); /* yes, endianness did flip inadvertently */
323 return EXIT_FAILURE;
324}
325
326int main(int argc, char **argv)
327{
328 return test_harness(tm_trap_test, "tm_trap_test");
329}
diff --git a/tools/testing/selftests/powerpc/tm/tm-unavailable.c b/tools/testing/selftests/powerpc/tm/tm-unavailable.c
index 96c37f84ce54..e6a0fad2bfd0 100644
--- a/tools/testing/selftests/powerpc/tm/tm-unavailable.c
+++ b/tools/testing/selftests/powerpc/tm/tm-unavailable.c
@@ -15,6 +15,7 @@
15 */ 15 */
16 16
17#define _GNU_SOURCE 17#define _GNU_SOURCE
18#include <error.h>
18#include <stdio.h> 19#include <stdio.h>
19#include <stdlib.h> 20#include <stdlib.h>
20#include <unistd.h> 21#include <unistd.h>
@@ -33,6 +34,11 @@
33#define VSX_UNA_EXCEPTION 2 34#define VSX_UNA_EXCEPTION 2
34 35
35#define NUM_EXCEPTIONS 3 36#define NUM_EXCEPTIONS 3
37#define err_at_line(status, errnum, format, ...) \
38 error_at_line(status, errnum, __FILE__, __LINE__, format ##__VA_ARGS__)
39
40#define pr_warn(code, format, ...) err_at_line(0, code, format, ##__VA_ARGS__)
41#define pr_err(code, format, ...) err_at_line(1, code, format, ##__VA_ARGS__)
36 42
37struct Flags { 43struct Flags {
38 int touch_fp; 44 int touch_fp;
@@ -303,10 +309,19 @@ void test_fp_vec(int fp, int vec, pthread_attr_t *attr)
303 * checking if the failure cause is the one we expect. 309 * checking if the failure cause is the one we expect.
304 */ 310 */
305 do { 311 do {
312 int rc;
313
306 /* Bind 'ping' to CPU 0, as specified in 'attr'. */ 314 /* Bind 'ping' to CPU 0, as specified in 'attr'. */
307 pthread_create(&t0, attr, ping, (void *) &flags); 315 rc = pthread_create(&t0, attr, ping, (void *) &flags);
308 pthread_setname_np(t0, "ping"); 316 if (rc)
309 pthread_join(t0, &ret_value); 317 pr_err(rc, "pthread_create()");
318 rc = pthread_setname_np(t0, "ping");
319 if (rc)
320 pr_warn(rc, "pthread_setname_np");
321 rc = pthread_join(t0, &ret_value);
322 if (rc)
323 pr_err(rc, "pthread_join");
324
310 retries--; 325 retries--;
311 } while (ret_value != NULL && retries); 326 } while (ret_value != NULL && retries);
312 327
@@ -320,7 +335,7 @@ void test_fp_vec(int fp, int vec, pthread_attr_t *attr)
320 335
321int main(int argc, char **argv) 336int main(int argc, char **argv)
322{ 337{
323 int exception; /* FP = 0, VEC = 1, VSX = 2 */ 338 int rc, exception; /* FP = 0, VEC = 1, VSX = 2 */
324 pthread_t t1; 339 pthread_t t1;
325 pthread_attr_t attr; 340 pthread_attr_t attr;
326 cpu_set_t cpuset; 341 cpu_set_t cpuset;
@@ -330,13 +345,23 @@ int main(int argc, char **argv)
330 CPU_SET(0, &cpuset); 345 CPU_SET(0, &cpuset);
331 346
332 /* Init pthread attribute. */ 347 /* Init pthread attribute. */
333 pthread_attr_init(&attr); 348 rc = pthread_attr_init(&attr);
349 if (rc)
350 pr_err(rc, "pthread_attr_init()");
334 351
335 /* Set CPU 0 mask into the pthread attribute. */ 352 /* Set CPU 0 mask into the pthread attribute. */
336 pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpuset); 353 rc = pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpuset);
337 354 if (rc)
338 pthread_create(&t1, &attr /* Bind 'pong' to CPU 0 */, pong, NULL); 355 pr_err(rc, "pthread_attr_setaffinity_np()");
339 pthread_setname_np(t1, "pong"); /* Name it for systemtap convenience */ 356
357 rc = pthread_create(&t1, &attr /* Bind 'pong' to CPU 0 */, pong, NULL);
358 if (rc)
359 pr_err(rc, "pthread_create()");
360
361 /* Name it for systemtap convenience */
362 rc = pthread_setname_np(t1, "pong");
363 if (rc)
364 pr_warn(rc, "pthread_create()");
340 365
341 flags.result = 0; 366 flags.result = 0;
342 367