Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Feb 2019 18:39:24 +0000 (10:39 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Feb 2019 18:39:24 +0000 (10:39 -0800)
Pull rdma fixes from Jason Gunthorpe:
 "Still not much going on, the usual set of oops and driver fixes this
  time:

   - Fix two uapi breakage regressions in mlx5 drivers

   - Various oops fixes in hfi1, mlx4, umem, uverbs, and ipoib

   - A protocol bug fix for hfi1 preventing it from implementing the
     verbs API properly, and a compatability fix for EXEC STACK user
     programs

   - Fix missed refcounting in the 'advise_mr' patches merged this
     cycle.

   - Fix wrong use of the uABI in the hns SRQ patches merged this cycle"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma:
  IB/uverbs: Fix OOPs in uverbs_user_mmap_disassociate
  IB/ipoib: Fix for use-after-free in ipoib_cm_tx_start
  IB/uverbs: Fix ioctl query port to consider device disassociation
  RDMA/mlx5: Fix flow creation on representors
  IB/uverbs: Fix OOPs upon device disassociation
  RDMA/umem: Add missing initialization of owning_mm
  RDMA/hns: Update the kernel header file of hns
  IB/mlx5: Fix how advise_mr() launches async work
  RDMA/device: Expose ib_device_try_get(()
  IB/hfi1: Add limit test for RC/UC send via loopback
  IB/hfi1: Remove overly conservative VM_EXEC flag check
  IB/{hfi1, qib}: Fix WC.byte_len calculation for UD_SEND_WITH_IMM
  IB/mlx4: Fix using wrong function to destroy sqp AHs under SRIOV
  RDMA/mlx5: Fix check for supported user flags when creating a QP

370 files changed:
Documentation/core-api/xarray.rst
Documentation/devicetree/bindings/display/msm/gpu.txt
Documentation/devicetree/bindings/serio/olpc,ap-sp.txt
Documentation/sysctl/fs.txt
MAINTAINERS
Makefile
arch/arc/include/asm/Kbuild
arch/arc/include/asm/arcregs.h
arch/arc/include/asm/bitops.h
arch/arc/include/asm/perf_event.h
arch/arc/kernel/perf_event.c
arch/arc/kernel/setup.c
arch/arc/kernel/troubleshoot.c
arch/arc/lib/memset-archs.S
arch/arc/mm/fault.c
arch/arc/mm/init.c
arch/arm/include/asm/xen/page-coherent.h
arch/arm/mach-cns3xxx/pcie.c
arch/arm64/include/asm/device.h
arch/arm64/include/asm/xen/page-coherent.h
arch/arm64/mm/dma-mapping.c
arch/s390/include/asm/mmu_context.h
arch/s390/kernel/early.c
arch/s390/kernel/setup.c
arch/s390/kernel/smp.c
arch/s390/kernel/vdso.c
arch/x86/Kconfig
arch/x86/entry/entry_64_compat.S
arch/x86/include/asm/mmu_context.h
arch/x86/kernel/crash.c
arch/x86/kernel/hpet.c
arch/x86/kernel/kexec-bzimage64.c
arch/x86/kernel/kvm.c
arch/x86/kernel/tsc.c
arch/x86/kvm/Makefile
arch/x86/kvm/hyperv.c
arch/x86/kvm/lapic.c
arch/x86/kvm/mmu.c
arch/x86/kvm/svm.c
arch/x86/kvm/trace.h
arch/x86/kvm/vmx/evmcs.c
arch/x86/kvm/vmx/nested.c
arch/x86/kvm/vmx/vmx.c
arch/x86/kvm/x86.c
arch/x86/lib/iomem.c
arch/x86/lib/kaslr.c
arch/x86/mm/mem_encrypt_identity.c
block/blk-mq-debugfs.c
block/blk-wbt.c
drivers/acpi/nfit/core.c
drivers/android/binderfs.c
drivers/ata/pata_macio.c
drivers/ata/sata_inic162x.c
drivers/base/power/runtime.c
drivers/char/ipmi/ipmi_msghandler.c
drivers/char/ipmi/ipmi_ssif.c
drivers/char/mwave/mwavedd.c
drivers/clk/Kconfig
drivers/clk/clk-versaclock5.c
drivers/clk/clk.c
drivers/clk/imx/clk-frac-pll.c
drivers/clk/imx/clk-imx8qxp-lpcg.c
drivers/clk/mmp/clk-of-mmp2.c
drivers/clk/qcom/Kconfig
drivers/clk/qcom/gcc-sdm845.c
drivers/clk/socfpga/clk-pll-s10.c
drivers/clk/socfpga/clk-s10.c
drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
drivers/clk/ti/divider.c
drivers/clk/zynqmp/clkc.c
drivers/cpuidle/poll_state.c
drivers/crypto/cavium/nitrox/nitrox_reqmgr.c
drivers/edac/altera_edac.h
drivers/firewire/sbp2.c
drivers/gpio/gpio-altera-a10sr.c
drivers/gpio/gpio-eic-sprd.c
drivers/gpio/gpio-pcf857x.c
drivers/gpio/gpio-vf610.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c
drivers/gpu/drm/i915/gvt/scheduler.c
drivers/gpu/drm/i915/intel_lrc.c
drivers/gpu/drm/msm/adreno/a6xx_gmu.c
drivers/gpu/drm/msm/adreno/adreno_gpu.c
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
drivers/gpu/drm/msm/msm_drv.h
drivers/gpu/drm/msm/msm_gem.c
drivers/gpu/drm/msm/msm_gem_vma.c
drivers/gpu/drm/msm/msm_gpu.c
drivers/gpu/drm/msm/msm_gpu.h
drivers/gpu/drm/msm/msm_rd.c
drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/hid/i2c-hid/i2c-hid-core.c
drivers/hv/channel.c
drivers/hv/hv_balloon.c
drivers/hv/ring_buffer.c
drivers/hv/vmbus_drv.c
drivers/i3c/master.c
drivers/i3c/master/dw-i3c-master.c
drivers/ide/ide-proc.c
drivers/input/joystick/xpad.c
drivers/input/misc/uinput.c
drivers/input/serio/olpc_apsp.c
drivers/input/touchscreen/Kconfig
drivers/iommu/amd_iommu.c
drivers/iommu/intel-iommu.c
drivers/iommu/mtk_iommu_v1.c
drivers/iommu/of_iommu.c
drivers/irqchip/irq-gic-v3-its.c
drivers/irqchip/irq-gic-v3-mbi.c
drivers/irqchip/irq-madera.c
drivers/irqchip/irq-stm32-exti.c
drivers/md/dm-crypt.c
drivers/md/dm-thin-metadata.c
drivers/md/dm-thin-metadata.h
drivers/md/dm-thin.c
drivers/md/dm.c
drivers/mfd/Kconfig
drivers/misc/ibmvmc.c
drivers/misc/mei/hbm.c
drivers/misc/mei/hw-me-regs.h
drivers/misc/mei/pci-me.c
drivers/misc/pvpanic.c
drivers/mmc/host/Kconfig
drivers/mmc/host/bcm2835.c
drivers/mmc/host/dw_mmc-bluefield.c
drivers/mmc/host/meson-gx-mmc.c
drivers/mmc/host/mtk-sd.c
drivers/mmc/host/sdhci-iproc.c
drivers/net/caif/caif_serial.c
drivers/net/can/dev.c
drivers/net/can/flexcan.c
drivers/net/dsa/mv88e6xxx/serdes.c
drivers/net/ethernet/alteon/acenic.c
drivers/net/ethernet/altera/altera_msgdma.c
drivers/net/ethernet/altera/altera_tse_main.c
drivers/net/ethernet/amd/amd8111e.c
drivers/net/ethernet/apple/bmac.c
drivers/net/ethernet/broadcom/b44.c
drivers/net/ethernet/cadence/macb.h
drivers/net/ethernet/cadence/macb_main.c
drivers/net/ethernet/freescale/dpaa2/Kconfig
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/hisilicon/hns/hns_enet.c
drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
drivers/net/ethernet/hisilicon/hns_mdio.c
drivers/net/ethernet/i825xx/82596.c
drivers/net/ethernet/ibm/ibmveth.c
drivers/net/ethernet/mellanox/mlx4/cq.c
drivers/net/ethernet/mellanox/mlx4/fw.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
drivers/net/ethernet/mellanox/mlx5/core/lag.c
drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
drivers/net/ethernet/mellanox/mlx5/core/qp.c
drivers/net/ethernet/qlogic/qed/qed_dev.c
drivers/net/ethernet/qlogic/qed/qed_l2.c
drivers/net/ethernet/qlogic/qed/qed_l2.h
drivers/net/ethernet/qlogic/qed/qed_ll2.c
drivers/net/ethernet/qlogic/qed/qed_sriov.c
drivers/net/ethernet/qlogic/qed/qed_vf.c
drivers/net/ethernet/realtek/8139cp.c
drivers/net/ethernet/renesas/ravb_main.c
drivers/net/ethernet/sfc/ef10.c
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
drivers/net/ethernet/sun/cassini.c
drivers/net/ethernet/sun/cassini.h
drivers/net/ethernet/ti/cpmac.c
drivers/net/hyperv/hyperv_net.h
drivers/net/hyperv/netvsc.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/hyperv/rndis_filter.c
drivers/net/phy/asix.c
drivers/net/phy/mdio-hisi-femac.c
drivers/net/phy/rockchip.c
drivers/net/usb/asix_devices.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/virt_wifi.c
drivers/nvdimm/dimm.c
drivers/nvdimm/dimm_devs.c
drivers/nvdimm/nd.h
drivers/nvme/host/multipath.c
drivers/nvme/host/rdma.c
drivers/nvme/host/tcp.c
drivers/nvme/target/rdma.c
drivers/pci/controller/dwc/pci-imx6.c
drivers/pci/controller/dwc/pcie-armada8k.c
drivers/phy/qualcomm/phy-ath79-usb.c
drivers/phy/ti/phy-gmii-sel.c
drivers/platform/x86/Kconfig
drivers/s390/char/sclp_config.c
drivers/scsi/aacraid/linit.c
drivers/scsi/csiostor/csio_attr.c
drivers/scsi/lpfc/lpfc_nvme.c
drivers/scsi/lpfc/lpfc_nvme.h
drivers/scsi/lpfc/lpfc_nvmet.c
drivers/scsi/lpfc/lpfc_nvmet.h
drivers/scsi/scsi_lib.c
drivers/scsi/ufs/ufshcd.c
drivers/staging/android/ion/ion.c
drivers/staging/rtl8188eu/os_dep/usb_intf.c
drivers/staging/rtl8723bs/include/ieee80211.h
drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
drivers/staging/wilc1000/host_interface.c
drivers/staging/wilc1000/wilc_wlan.c
drivers/target/target_core_user.c
drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
drivers/tty/n_hdlc.c
drivers/tty/serial/8250/8250_core.c
drivers/tty/serial/fsl_lpuart.c
drivers/tty/serial/qcom_geni_serial.c
drivers/tty/serial/serial_core.c
drivers/tty/tty_io.c
drivers/tty/vt/vt.c
drivers/usb/chipidea/ci_hdrc_imx.c
drivers/usb/core/ledtrig-usbport.c
drivers/usb/dwc2/gadget.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/function/f_sourcesink.c
drivers/usb/host/ehci-mv.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/keyspan_usa26msg.h
drivers/usb/serial/keyspan_usa28msg.h
drivers/usb/serial/keyspan_usa49msg.h
drivers/usb/serial/keyspan_usa67msg.h
drivers/usb/serial/keyspan_usa90msg.h
drivers/usb/serial/pl2303.c
drivers/usb/serial/pl2303.h
drivers/usb/serial/usb-serial-simple.c
drivers/usb/usbip/README [deleted file]
drivers/vfio/pci/trace.h
drivers/vfio/pci/vfio_pci_nvlink2.c
drivers/vhost/net.c
drivers/vhost/scsi.c
drivers/vhost/vhost.c
drivers/vhost/vhost.h
drivers/vhost/vsock.c
drivers/video/console/vgacon.c
drivers/xen/swiotlb-xen.c
fs/ceph/caps.c
fs/ceph/quota.c
fs/cifs/cifs_debug.c
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/smb2inode.c
fs/cifs/smb2misc.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/cifs/trace.c
fs/cifs/trace.h
fs/cifs/transport.c
fs/dcache.c
fs/direct-io.c
fs/fs-writeback.c
fs/gfs2/rgrp.c
fs/iomap.c
fs/nfs/super.c
fs/nfs/write.c
fs/notify/inotify/inotify_user.c
include/dt-bindings/clock/marvell,mmp2.h
include/linux/backing-dev-defs.h
include/linux/blk_types.h
include/linux/dcache.h
include/linux/fs.h
include/linux/hid.h
include/linux/hyperv.h
include/linux/if_arp.h
include/linux/interrupt.h
include/linux/libnvdimm.h
include/linux/pm_runtime.h
include/linux/sched/wake_q.h
include/linux/xarray.h
include/net/ax25.h
include/net/tls.h
include/sound/soc.h
include/uapi/linux/android/binderfs.h [moved from include/uapi/linux/android/binder_ctl.h with 83% similarity]
include/uapi/linux/blkzoned.h
include/uapi/linux/input.h
include/xen/arm/page-coherent.h
kernel/exit.c
kernel/futex.c
kernel/irq/irqdesc.c
kernel/irq/manage.c
kernel/locking/rwsem-xadd.c
kernel/sched/core.c
kernel/time/posix-cpu-timers.c
lib/test_xarray.c
lib/xarray.c
mm/backing-dev.c
mm/mincore.c
mm/page_alloc.c
net/ax25/ax25_ip.c
net/ax25/ax25_route.c
net/bridge/netfilter/ebtables.c
net/can/bcm.c
net/ceph/messenger.c
net/core/dev.c
net/decnet/dn_dev.c
net/ipv4/gre_demux.c
net/ipv4/ip_gre.c
net/ipv4/ip_tunnel.c
net/ipv4/ip_vti.c
net/ipv4/netfilter/ipt_CLUSTERIP.c
net/ipv6/addrconf.c
net/ipv6/ip6_gre.c
net/ipv6/ip6mr.c
net/mac80211/cfg.c
net/mac80211/rx.c
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/nfnetlink_osf.c
net/netfilter/nft_compat.c
net/netrom/nr_timer.c
net/rose/rose_route.c
net/sctp/ipv6.c
net/sctp/protocol.c
net/sctp/sm_make_chunk.c
net/sctp/stream.c
net/tls/tls_sw.c
net/wireless/nl80211.c
net/wireless/reg.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_user.c
sound/core/compress_offload.c
sound/core/pcm_lib.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/soc/amd/raven/acp3x-pcm-dma.c
sound/soc/codecs/hdac_hdmi.c
sound/soc/codecs/pcm512x.c
sound/soc/codecs/rt274.c
sound/soc/codecs/rt5514-spi.c
sound/soc/codecs/rt5682.c
sound/soc/codecs/rt5682.h
sound/soc/codecs/tlv320aic32x4.c
sound/soc/fsl/imx-audmux.c
sound/soc/intel/Kconfig
sound/soc/intel/atom/sst-mfld-platform-pcm.c
sound/soc/intel/boards/broadwell.c
sound/soc/intel/boards/glk_rt5682_max98357a.c
sound/soc/intel/boards/haswell.c
sound/soc/intel/skylake/skl.c
sound/soc/qcom/qdsp6/q6asm-dai.c
sound/soc/qcom/sdm845.c
sound/soc/sh/dma-sh7760.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c
sound/soc/ti/davinci-mcasp.c
sound/soc/xilinx/Kconfig
sound/soc/xilinx/xlnx_i2s.c
sound/usb/quirks.c
tools/testing/nvdimm/dimm_devs.c
tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh
tools/testing/selftests/gpio/gpio-mockup-chardev.c
tools/testing/selftests/ir/Makefile
tools/testing/selftests/kvm/lib/kvm_util.c
tools/testing/selftests/kvm/x86_64/evmcs_test.c
tools/testing/selftests/net/Makefile
tools/testing/selftests/net/xfrm_policy.sh
tools/testing/selftests/rtc/rtctest.c
tools/testing/selftests/seccomp/Makefile
tools/testing/selftests/seccomp/seccomp_bpf.c
tools/testing/selftests/timers/Makefile
tools/testing/selftests/vm/gup_benchmark.c
tools/testing/selftests/x86/mpx-mini-test.c
tools/testing/selftests/x86/protection_keys.c
tools/testing/selftests/x86/unwind_vdso.c

index 6a6d67acaf690abfadc40c05e97a4557060dc188..5d54b27c6ebab15a41e53bb6f9529af128be8092 100644 (file)
@@ -108,12 +108,13 @@ some, but not all of the other indices changing.
 
 Sometimes you need to ensure that a subsequent call to :c:func:`xa_store`
 will not need to allocate memory.  The :c:func:`xa_reserve` function
-will store a reserved entry at the indicated index.  Users of the normal
-API will see this entry as containing ``NULL``.  If you do not need to
-use the reserved entry, you can call :c:func:`xa_release` to remove the
-unused entry.  If another user has stored to the entry in the meantime,
-:c:func:`xa_release` will do nothing; if instead you want the entry to
-become ``NULL``, you should use :c:func:`xa_erase`.
+will store a reserved entry at the indicated index.  Users of the
+normal API will see this entry as containing ``NULL``.  If you do
+not need to use the reserved entry, you can call :c:func:`xa_release`
+to remove the unused entry.  If another user has stored to the entry
+in the meantime, :c:func:`xa_release` will do nothing; if instead you
+want the entry to become ``NULL``, you should use :c:func:`xa_erase`.
+Using :c:func:`xa_insert` on a reserved entry will fail.
 
 If all entries in the array are ``NULL``, the :c:func:`xa_empty` function
 will return ``true``.
@@ -183,6 +184,8 @@ Takes xa_lock internally:
  * :c:func:`xa_store_bh`
  * :c:func:`xa_store_irq`
  * :c:func:`xa_insert`
+ * :c:func:`xa_insert_bh`
+ * :c:func:`xa_insert_irq`
  * :c:func:`xa_erase`
  * :c:func:`xa_erase_bh`
  * :c:func:`xa_erase_irq`
index ac8df3b871f900a0672f266a5b05635a7aca01cf..f8759145ce1a08e57046f4aa63198e642887b4e8 100644 (file)
@@ -27,7 +27,6 @@ Example:
                reg = <0x04300000 0x20000>;
                reg-names = "kgsl_3d0_reg_memory";
                interrupts = <GIC_SPI 80 0>;
-               interrupt-names = "kgsl_3d0_irq";
                clock-names =
                    "core",
                    "iface",
index 36603419d6f8e7858692af125f51726db85c5905..0e72183f52bc9dc5926b34f414941780e70847cc 100644 (file)
@@ -4,14 +4,10 @@ Required properties:
 - compatible : "olpc,ap-sp"
 - reg : base address and length of SoC's WTM registers
 - interrupts : SP-AP interrupt
-- clocks : phandle + clock-specifier for the clock that drives the WTM
-- clock-names:  should be "sp"
 
 Example:
        ap-sp@d4290000 {
                compatible = "olpc,ap-sp";
                reg = <0xd4290000 0x1000>;
                interrupts = <40>;
-               clocks = <&soc_clocks MMP2_CLK_SP>;
-               clock-names = "sp";
        }
index 819caf8ca05f8b4b16226c0f5d6f76068de09131..58649bd4fcfcc30de978b071143f6560b3d5a1e4 100644 (file)
@@ -56,26 +56,32 @@ of any kernel data structures.
 
 dentry-state:
 
-From linux/fs/dentry.c:
+From linux/include/linux/dcache.h:
 --------------------------------------------------------------
-struct {
+struct dentry_stat_t dentry_stat {
         int nr_dentry;
         int nr_unused;
         int age_limit;         /* age in seconds */
         int want_pages;        /* pages requested by system */
-        int dummy[2];
-} dentry_stat = {0, 0, 45, 0,};
--------------------------------------------------------------- 
-
-Dentries are dynamically allocated and deallocated, and
-nr_dentry seems to be 0 all the time. Hence it's safe to
-assume that only nr_unused, age_limit and want_pages are
-used. Nr_unused seems to be exactly what its name says.
+        int nr_negative;       /* # of unused negative dentries */
+        int dummy;             /* Reserved for future use */
+};
+--------------------------------------------------------------
+
+Dentries are dynamically allocated and deallocated.
+
+nr_dentry shows the total number of dentries allocated (active
++ unused). nr_unused shows the number of dentries that are not
+actively used, but are saved in the LRU list for future reuse.
+
 Age_limit is the age in seconds after which dcache entries
 can be reclaimed when memory is short and want_pages is
 nonzero when shrink_dcache_pages() has been called and the
 dcache isn't pruned yet.
 
+nr_negative shows the number of unused dentries that are also
+negative dentries which do not mapped to actual files.
+
 ==============================================================
 
 dquot-max & dquot-nr:
index 51029a425dbece776924ff73dc0f078698f29da8..2d3c1918f1b024ff94876d4ba34882d079f9d10b 100644 (file)
@@ -3052,8 +3052,8 @@ F:        include/linux/bcm963xx_nvram.h
 F:     include/linux/bcm963xx_tag.h
 
 BROADCOM BNX2 GIGABIT ETHERNET DRIVER
-M:     Rasesh Mody <rasesh.mody@cavium.com>
-M:     Dept-GELinuxNICDev@cavium.com
+M:     Rasesh Mody <rmody@marvell.com>
+M:     GR-Linux-NIC-Dev@marvell.com
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     drivers/net/ethernet/broadcom/bnx2.*
@@ -3072,9 +3072,9 @@ S:        Supported
 F:     drivers/scsi/bnx2i/
 
 BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER
-M:     Ariel Elior <ariel.elior@cavium.com>
-M:     Sudarsana Kalluru <sudarsana.kalluru@cavium.com>
-M:     everest-linux-l2@cavium.com
+M:     Ariel Elior <aelior@marvell.com>
+M:     Sudarsana Kalluru <skalluru@marvell.com>
+M:     GR-everest-linux-l2@marvell.com
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     drivers/net/ethernet/broadcom/bnx2x/
@@ -3249,9 +3249,9 @@ S:        Supported
 F:     drivers/scsi/bfa/
 
 BROCADE BNA 10 GIGABIT ETHERNET DRIVER
-M:     Rasesh Mody <rasesh.mody@cavium.com>
-M:     Sudarsana Kalluru <sudarsana.kalluru@cavium.com>
-M:     Dept-GELinuxNICDev@cavium.com
+M:     Rasesh Mody <rmody@marvell.com>
+M:     Sudarsana Kalluru <skalluru@marvell.com>
+M:     GR-Linux-NIC-Dev@marvell.com
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     drivers/net/ethernet/brocade/bna/
@@ -3978,6 +3978,7 @@ F:        drivers/cpufreq/arm_big_little.c
 CPU POWER MONITORING SUBSYSTEM
 M:     Thomas Renninger <trenn@suse.com>
 M:     Shuah Khan <shuah@kernel.org>
+M:     Shuah Khan <skhan@linuxfoundation.org>
 L:     linux-pm@vger.kernel.org
 S:     Maintained
 F:     tools/power/cpupower/
@@ -8258,6 +8259,7 @@ F:        include/uapi/linux/sunrpc/
 
 KERNEL SELFTEST FRAMEWORK
 M:     Shuah Khan <shuah@kernel.org>
+M:     Shuah Khan <skhan@linuxfoundation.org>
 L:     linux-kselftest@vger.kernel.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git
 Q:     https://patchwork.kernel.org/project/linux-kselftest/list/
@@ -10688,9 +10690,9 @@ S:      Maintained
 F:     drivers/net/netdevsim/*
 
 NETXEN (1/10) GbE SUPPORT
-M:     Manish Chopra <manish.chopra@cavium.com>
-M:     Rahul Verma <rahul.verma@cavium.com>
-M:     Dept-GELinuxNICDev@cavium.com
+M:     Manish Chopra <manishc@marvell.com>
+M:     Rahul Verma <rahulv@marvell.com>
+M:     GR-Linux-NIC-Dev@marvell.com
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     drivers/net/ethernet/qlogic/netxen/
@@ -12474,8 +12476,8 @@ S:      Supported
 F:     drivers/scsi/qedi/
 
 QLOGIC QL4xxx ETHERNET DRIVER
-M:     Ariel Elior <Ariel.Elior@cavium.com>
-M:     everest-linux-l2@cavium.com
+M:     Ariel Elior <aelior@marvell.com>
+M:     GR-everest-linux-l2@marvell.com
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     drivers/net/ethernet/qlogic/qed/
@@ -12483,8 +12485,8 @@ F:      include/linux/qed/
 F:     drivers/net/ethernet/qlogic/qede/
 
 QLOGIC QL4xxx RDMA DRIVER
-M:     Michal Kalderon <Michal.Kalderon@cavium.com>
-M:     Ariel Elior <Ariel.Elior@cavium.com>
+M:     Michal Kalderon <mkalderon@marvell.com>
+M:     Ariel Elior <aelior@marvell.com>
 L:     linux-rdma@vger.kernel.org
 S:     Supported
 F:     drivers/infiniband/hw/qedr/
@@ -12504,7 +12506,7 @@ F:      Documentation/scsi/LICENSE.qla2xxx
 F:     drivers/scsi/qla2xxx/
 
 QLOGIC QLA3XXX NETWORK DRIVER
-M:     Dept-GELinuxNICDev@cavium.com
+M:     GR-Linux-NIC-Dev@marvell.com
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     Documentation/networking/device_drivers/qlogic/LICENSE.qla3xxx
@@ -12518,16 +12520,16 @@ F:    Documentation/scsi/LICENSE.qla4xxx
 F:     drivers/scsi/qla4xxx/
 
 QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER
-M:     Shahed Shaikh <Shahed.Shaikh@cavium.com>
-M:     Manish Chopra <manish.chopra@cavium.com>
-M:     Dept-GELinuxNICDev@cavium.com
+M:     Shahed Shaikh <shshaikh@marvell.com>
+M:     Manish Chopra <manishc@marvell.com>
+M:     GR-Linux-NIC-Dev@marvell.com
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     drivers/net/ethernet/qlogic/qlcnic/
 
 QLOGIC QLGE 10Gb ETHERNET DRIVER
-M:     Manish Chopra <manish.chopra@cavium.com>
-M:     Dept-GELinuxNICDev@cavium.com
+M:     Manish Chopra <manishc@marvell.com>
+M:     GR-Linux-NIC-Dev@marvell.com
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     drivers/net/ethernet/qlogic/qlge/
@@ -15841,6 +15843,7 @@ F:      drivers/usb/common/usb-otg-fsm.c
 USB OVER IP DRIVER
 M:     Valentina Manea <valentina.manea.m@gmail.com>
 M:     Shuah Khan <shuah@kernel.org>
+M:     Shuah Khan <skhan@linuxfoundation.org>
 L:     linux-usb@vger.kernel.org
 S:     Maintained
 F:     Documentation/usb/usbip_protocol.txt
@@ -16670,6 +16673,24 @@ T:     git git://linuxtv.org/media_tree.git
 S:     Maintained
 F:     drivers/media/tuners/tuner-xc2028.*
 
+XDP (eXpress Data Path)
+M:     Alexei Starovoitov <ast@kernel.org>
+M:     Daniel Borkmann <daniel@iogearbox.net>
+M:     David S. Miller <davem@davemloft.net>
+M:     Jakub Kicinski <jakub.kicinski@netronome.com>
+M:     Jesper Dangaard Brouer <hawk@kernel.org>
+M:     John Fastabend <john.fastabend@gmail.com>
+L:     netdev@vger.kernel.org
+L:     xdp-newbies@vger.kernel.org
+S:     Supported
+F:     net/core/xdp.c
+F:     include/net/xdp.h
+F:     kernel/bpf/devmap.c
+F:     kernel/bpf/cpumap.c
+F:     include/trace/events/xdp.h
+K:     xdp
+N:     xdp
+
 XDP SOCKETS (AF_XDP)
 M:     Björn Töpel <bjorn.topel@intel.com>
 M:     Magnus Karlsson <magnus.karlsson@intel.com>
index f5b1d0d168e01e90d76b8d26c26c38cc52459787..141653226f3c22ad9385d0b3863f714c8afc8038 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 5
 PATCHLEVEL = 0
 SUBLEVEL = 0
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc4
 NAME = Shy Crocodile
 
 # *DOCUMENTATION*
index feed50ce89fadfc1291080dffb16b969370553d8..caa270261521d45e46759592e9a3007c15fdd80f 100644 (file)
@@ -3,23 +3,19 @@ generic-y += bugs.h
 generic-y += compat.h
 generic-y += device.h
 generic-y += div64.h
-generic-y += dma-mapping.h
 generic-y += emergency-restart.h
 generic-y += extable.h
-generic-y += fb.h
 generic-y += ftrace.h
 generic-y += hardirq.h
 generic-y += hw_irq.h
 generic-y += irq_regs.h
 generic-y += irq_work.h
-generic-y += kmap_types.h
 generic-y += local.h
 generic-y += local64.h
 generic-y += mcs_spinlock.h
 generic-y += mm-arch-hooks.h
 generic-y += msi.h
 generic-y += parport.h
-generic-y += pci.h
 generic-y += percpu.h
 generic-y += preempt.h
 generic-y += topology.h
index 49bfbd879caa6ffa08553e9b0f49b542739bb95b..f1b86cef09057ace18085cb1cb3f18b3be274852 100644 (file)
@@ -216,6 +216,14 @@ struct bcr_fp_arcv2 {
 #endif
 };
 
+struct bcr_actionpoint {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+       unsigned int pad:21, min:1, num:2, ver:8;
+#else
+       unsigned int ver:8, num:2, min:1, pad:21;
+#endif
+};
+
 #include <soc/arc/timers.h>
 
 struct bcr_bpu_arcompact {
@@ -283,7 +291,7 @@ struct cpuinfo_arc_cache {
 };
 
 struct cpuinfo_arc_bpu {
-       unsigned int ver, full, num_cache, num_pred;
+       unsigned int ver, full, num_cache, num_pred, ret_stk;
 };
 
 struct cpuinfo_arc_ccm {
@@ -302,7 +310,7 @@ struct cpuinfo_arc {
        struct {
                unsigned int swap:1, norm:1, minmax:1, barrel:1, crc:1, swape:1, pad1:2,
                             fpu_sp:1, fpu_dp:1, dual:1, dual_enb:1, pad2:4,
-                            debug:1, ap:1, smart:1, rtt:1, pad3:4,
+                            ap_num:4, ap_full:1, smart:1, rtt:1, pad3:1,
                             timer0:1, timer1:1, rtc:1, gfrc:1, pad4:4;
        } extn;
        struct bcr_mpy extn_mpy;
index ee9246184033b3138f8d09878fc7763502b11e5c..202b74c339f0b43c6ca31a9ab0f76ae2240f0934 100644 (file)
@@ -340,7 +340,7 @@ static inline __attribute__ ((const)) int __fls(unsigned long x)
 /*
  * __ffs: Similar to ffs, but zero based (0-31)
  */
-static inline __attribute__ ((const)) int __ffs(unsigned long word)
+static inline __attribute__ ((const)) unsigned long __ffs(unsigned long word)
 {
        if (!word)
                return word;
@@ -400,9 +400,9 @@ static inline __attribute__ ((const)) int ffs(unsigned long x)
 /*
  * __ffs: Similar to ffs, but zero based (0-31)
  */
-static inline __attribute__ ((const)) int __ffs(unsigned long x)
+static inline __attribute__ ((const)) unsigned long __ffs(unsigned long x)
 {
-       int n;
+       unsigned long n;
 
        asm volatile(
        "       ffs.f   %0, %1          \n"  /* 0:31; 31(Z) if src 0 */
index 9185541035cc3a716b59eb12a159850b18c5a7ea..6958545390f0f847ed3a7745b7325964d7f23f17 100644 (file)
@@ -103,7 +103,8 @@ static const char * const arc_pmu_ev_hw_map[] = {
 
        /* counts condition */
        [PERF_COUNT_HW_INSTRUCTIONS] = "iall",
-       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = "ijmp", /* Excludes ZOL jumps */
+       /* All jump instructions that are taken */
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = "ijmptak",
        [PERF_COUNT_ARC_BPOK]         = "bpok",   /* NP-NT, PT-T, PNT-NT */
 #ifdef CONFIG_ISA_ARCV2
        [PERF_COUNT_HW_BRANCH_MISSES] = "bpmp",
index 8aec462d90fbe8f0aa88847272d02004a863f2db..861a8aea51f9fe0c086665dd84677f7ee80ea838 100644 (file)
@@ -1,15 +1,10 @@
-/*
- * Linux performance counter support for ARC700 series
- *
- * Copyright (C) 2013-2015 Synopsys, Inc. (www.synopsys.com)
- *
- * This code is inspired by the perf support of various other architectures.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Linux performance counter support for ARC CPUs.
+// This code is inspired by the perf support of various other architectures.
+//
+// Copyright (C) 2013-2018 Synopsys, Inc. (www.synopsys.com)
+
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <asm/arcregs.h>
 #include <asm/stacktrace.h>
 
+/* HW holds 8 symbols + one for null terminator */
+#define ARCPMU_EVENT_NAME_LEN  9
+
+enum arc_pmu_attr_groups {
+       ARCPMU_ATTR_GR_EVENTS,
+       ARCPMU_ATTR_GR_FORMATS,
+       ARCPMU_NR_ATTR_GR
+};
+
+struct arc_pmu_raw_event_entry {
+       char name[ARCPMU_EVENT_NAME_LEN];
+};
+
 struct arc_pmu {
        struct pmu      pmu;
        unsigned int    irq;
        int             n_counters;
+       int             n_events;
        u64             max_period;
        int             ev_hw_idx[PERF_COUNT_ARC_HW_MAX];
+
+       struct arc_pmu_raw_event_entry  *raw_entry;
+       struct attribute                **attrs;
+       struct perf_pmu_events_attr     *attr;
+       const struct attribute_group    *attr_groups[ARCPMU_NR_ATTR_GR + 1];
 };
 
 struct arc_pmu_cpu {
@@ -49,6 +63,7 @@ static int callchain_trace(unsigned int addr, void *data)
 {
        struct arc_callchain_trace *ctrl = data;
        struct perf_callchain_entry_ctx *entry = ctrl->perf_stuff;
+
        perf_callchain_store(entry, addr);
 
        if (ctrl->depth++ < 3)
@@ -57,8 +72,8 @@ static int callchain_trace(unsigned int addr, void *data)
        return -1;
 }
 
-void
-perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
+void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
+                          struct pt_regs *regs)
 {
        struct arc_callchain_trace ctrl = {
                .depth = 0,
@@ -68,8 +83,8 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re
        arc_unwind_core(NULL, regs, callchain_trace, &ctrl);
 }
 
-void
-perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
+void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
+                        struct pt_regs *regs)
 {
        /*
         * User stack can't be unwound trivially with kernel dwarf unwinder
@@ -82,10 +97,10 @@ static struct arc_pmu *arc_pmu;
 static DEFINE_PER_CPU(struct arc_pmu_cpu, arc_pmu_cpu);
 
 /* read counter #idx; note that counter# != event# on ARC! */
-static uint64_t arc_pmu_read_counter(int idx)
+static u64 arc_pmu_read_counter(int idx)
 {
-       uint32_t tmp;
-       uint64_t result;
+       u32 tmp;
+       u64 result;
 
        /*
         * ARC supports making 'snapshots' of the counters, so we don't
@@ -94,7 +109,7 @@ static uint64_t arc_pmu_read_counter(int idx)
        write_aux_reg(ARC_REG_PCT_INDEX, idx);
        tmp = read_aux_reg(ARC_REG_PCT_CONTROL);
        write_aux_reg(ARC_REG_PCT_CONTROL, tmp | ARC_REG_PCT_CONTROL_SN);
-       result = (uint64_t) (read_aux_reg(ARC_REG_PCT_SNAPH)) << 32;
+       result = (u64) (read_aux_reg(ARC_REG_PCT_SNAPH)) << 32;
        result |= read_aux_reg(ARC_REG_PCT_SNAPL);
 
        return result;
@@ -103,9 +118,9 @@ static uint64_t arc_pmu_read_counter(int idx)
 static void arc_perf_event_update(struct perf_event *event,
                                  struct hw_perf_event *hwc, int idx)
 {
-       uint64_t prev_raw_count = local64_read(&hwc->prev_count);
-       uint64_t new_raw_count = arc_pmu_read_counter(idx);
-       int64_t delta = new_raw_count - prev_raw_count;
+       u64 prev_raw_count = local64_read(&hwc->prev_count);
+       u64 new_raw_count = arc_pmu_read_counter(idx);
+       s64 delta = new_raw_count - prev_raw_count;
 
        /*
         * We aren't afraid of hwc->prev_count changing beneath our feet
@@ -155,7 +170,7 @@ static int arc_pmu_event_init(struct perf_event *event)
        int ret;
 
        if (!is_sampling_event(event)) {
-               hwc->sample_period  = arc_pmu->max_period;
+               hwc->sample_period = arc_pmu->max_period;
                hwc->last_period = hwc->sample_period;
                local64_set(&hwc->period_left, hwc->sample_period);
        }
@@ -192,6 +207,18 @@ static int arc_pmu_event_init(struct perf_event *event)
                pr_debug("init cache event with h/w %08x \'%s\'\n",
                         (int)hwc->config, arc_pmu_ev_hw_map[ret]);
                return 0;
+
+       case PERF_TYPE_RAW:
+               if (event->attr.config >= arc_pmu->n_events)
+                       return -ENOENT;
+
+               hwc->config |= event->attr.config;
+               pr_debug("init raw event with idx %lld \'%s\'\n",
+                        event->attr.config,
+                        arc_pmu->raw_entry[event->attr.config].name);
+
+               return 0;
+
        default:
                return -ENOENT;
        }
@@ -200,7 +227,7 @@ static int arc_pmu_event_init(struct perf_event *event)
 /* starts all counters */
 static void arc_pmu_enable(struct pmu *pmu)
 {
-       uint32_t tmp;
+       u32 tmp;
        tmp = read_aux_reg(ARC_REG_PCT_CONTROL);
        write_aux_reg(ARC_REG_PCT_CONTROL, (tmp & 0xffff0000) | 0x1);
 }
@@ -208,7 +235,7 @@ static void arc_pmu_enable(struct pmu *pmu)
 /* stops all counters */
 static void arc_pmu_disable(struct pmu *pmu)
 {
-       uint32_t tmp;
+       u32 tmp;
        tmp = read_aux_reg(ARC_REG_PCT_CONTROL);
        write_aux_reg(ARC_REG_PCT_CONTROL, (tmp & 0xffff0000) | 0x0);
 }
@@ -228,7 +255,7 @@ static int arc_pmu_event_set_period(struct perf_event *event)
                local64_set(&hwc->period_left, left);
                hwc->last_period = period;
                overflow = 1;
-       } else  if (unlikely(left <= 0)) {
+       } else if (unlikely(left <= 0)) {
                /* left underflowed by less than period. */
                left += period;
                local64_set(&hwc->period_left, left);
@@ -246,8 +273,8 @@ static int arc_pmu_event_set_period(struct perf_event *event)
        write_aux_reg(ARC_REG_PCT_INDEX, idx);
 
        /* Write value */
-       write_aux_reg(ARC_REG_PCT_COUNTL, (u32)value);
-       write_aux_reg(ARC_REG_PCT_COUNTH, (value >> 32));
+       write_aux_reg(ARC_REG_PCT_COUNTL, lower_32_bits(value));
+       write_aux_reg(ARC_REG_PCT_COUNTH, upper_32_bits(value));
 
        perf_event_update_userpage(event);
 
@@ -277,7 +304,7 @@ static void arc_pmu_start(struct perf_event *event, int flags)
        /* Enable interrupt for this counter */
        if (is_sampling_event(event))
                write_aux_reg(ARC_REG_PCT_INT_CTRL,
-                             read_aux_reg(ARC_REG_PCT_INT_CTRL) | (1 << idx));
+                             read_aux_reg(ARC_REG_PCT_INT_CTRL) | BIT(idx));
 
        /* enable ARC pmu here */
        write_aux_reg(ARC_REG_PCT_INDEX, idx);          /* counter # */
@@ -295,9 +322,9 @@ static void arc_pmu_stop(struct perf_event *event, int flags)
                 * Reset interrupt flag by writing of 1. This is required
                 * to make sure pending interrupt was not left.
                 */
-               write_aux_reg(ARC_REG_PCT_INT_ACT, 1 << idx);
+               write_aux_reg(ARC_REG_PCT_INT_ACT, BIT(idx));
                write_aux_reg(ARC_REG_PCT_INT_CTRL,
-                             read_aux_reg(ARC_REG_PCT_INT_CTRL) & ~(1 << idx));
+                             read_aux_reg(ARC_REG_PCT_INT_CTRL) & ~BIT(idx));
        }
 
        if (!(event->hw.state & PERF_HES_STOPPED)) {
@@ -349,9 +376,10 @@ static int arc_pmu_add(struct perf_event *event, int flags)
 
        if (is_sampling_event(event)) {
                /* Mimic full counter overflow as other arches do */
-               write_aux_reg(ARC_REG_PCT_INT_CNTL, (u32)arc_pmu->max_period);
+               write_aux_reg(ARC_REG_PCT_INT_CNTL,
+                             lower_32_bits(arc_pmu->max_period));
                write_aux_reg(ARC_REG_PCT_INT_CNTH,
-                             (arc_pmu->max_period >> 32));
+                             upper_32_bits(arc_pmu->max_period));
        }
 
        write_aux_reg(ARC_REG_PCT_CONFIG, 0);
@@ -392,7 +420,7 @@ static irqreturn_t arc_pmu_intr(int irq, void *dev)
                idx = __ffs(active_ints);
 
                /* Reset interrupt flag by writing of 1 */
-               write_aux_reg(ARC_REG_PCT_INT_ACT, 1 << idx);
+               write_aux_reg(ARC_REG_PCT_INT_ACT, BIT(idx));
 
                /*
                 * On reset of "interrupt active" bit corresponding
@@ -400,7 +428,7 @@ static irqreturn_t arc_pmu_intr(int irq, void *dev)
                 * Now we need to re-enable interrupt for the counter.
                 */
                write_aux_reg(ARC_REG_PCT_INT_CTRL,
-                       read_aux_reg(ARC_REG_PCT_INT_CTRL) | (1 << idx));
+                       read_aux_reg(ARC_REG_PCT_INT_CTRL) | BIT(idx));
 
                event = pmu_cpu->act_counter[idx];
                hwc = &event->hw;
@@ -414,7 +442,7 @@ static irqreturn_t arc_pmu_intr(int irq, void *dev)
                                arc_pmu_stop(event, 0);
                }
 
-               active_ints &= ~(1U << idx);
+               active_ints &= ~BIT(idx);
        } while (active_ints);
 
 done:
@@ -441,19 +469,108 @@ static void arc_cpu_pmu_irq_init(void *data)
        write_aux_reg(ARC_REG_PCT_INT_ACT, 0xffffffff);
 }
 
+/* Event field occupies the bottom 15 bits of our config field */
+PMU_FORMAT_ATTR(event, "config:0-14");
+static struct attribute *arc_pmu_format_attrs[] = {
+       &format_attr_event.attr,
+       NULL,
+};
+
+static struct attribute_group arc_pmu_format_attr_gr = {
+       .name = "format",
+       .attrs = arc_pmu_format_attrs,
+};
+
+static ssize_t arc_pmu_events_sysfs_show(struct device *dev,
+                                        struct device_attribute *attr,
+                                        char *page)
+{
+       struct perf_pmu_events_attr *pmu_attr;
+
+       pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
+       return sprintf(page, "event=0x%04llx\n", pmu_attr->id);
+}
+
+/*
+ * We don't add attrs here as we don't have pre-defined list of perf events.
+ * We will generate and add attrs dynamically in probe() after we read HW
+ * configuration.
+ */
+static struct attribute_group arc_pmu_events_attr_gr = {
+       .name = "events",
+};
+
+static void arc_pmu_add_raw_event_attr(int j, char *str)
+{
+       memmove(arc_pmu->raw_entry[j].name, str, ARCPMU_EVENT_NAME_LEN - 1);
+       arc_pmu->attr[j].attr.attr.name = arc_pmu->raw_entry[j].name;
+       arc_pmu->attr[j].attr.attr.mode = VERIFY_OCTAL_PERMISSIONS(0444);
+       arc_pmu->attr[j].attr.show = arc_pmu_events_sysfs_show;
+       arc_pmu->attr[j].id = j;
+       arc_pmu->attrs[j] = &(arc_pmu->attr[j].attr.attr);
+}
+
+static int arc_pmu_raw_alloc(struct device *dev)
+{
+       arc_pmu->attr = devm_kmalloc_array(dev, arc_pmu->n_events + 1,
+               sizeof(*arc_pmu->attr), GFP_KERNEL | __GFP_ZERO);
+       if (!arc_pmu->attr)
+               return -ENOMEM;
+
+       arc_pmu->attrs = devm_kmalloc_array(dev, arc_pmu->n_events + 1,
+               sizeof(*arc_pmu->attrs), GFP_KERNEL | __GFP_ZERO);
+       if (!arc_pmu->attrs)
+               return -ENOMEM;
+
+       arc_pmu->raw_entry = devm_kmalloc_array(dev, arc_pmu->n_events,
+               sizeof(*arc_pmu->raw_entry), GFP_KERNEL | __GFP_ZERO);
+       if (!arc_pmu->raw_entry)
+               return -ENOMEM;
+
+       return 0;
+}
+
+static inline bool event_in_hw_event_map(int i, char *name)
+{
+       if (!arc_pmu_ev_hw_map[i])
+               return false;
+
+       if (!strlen(arc_pmu_ev_hw_map[i]))
+               return false;
+
+       if (strcmp(arc_pmu_ev_hw_map[i], name))
+               return false;
+
+       return true;
+}
+
+static void arc_pmu_map_hw_event(int j, char *str)
+{
+       int i;
+
+       /* See if HW condition has been mapped to a perf event_id */
+       for (i = 0; i < ARRAY_SIZE(arc_pmu_ev_hw_map); i++) {
+               if (event_in_hw_event_map(i, str)) {
+                       pr_debug("mapping perf event %2d to h/w event \'%8s\' (idx %d)\n",
+                                i, str, j);
+                       arc_pmu->ev_hw_idx[i] = j;
+               }
+       }
+}
+
 static int arc_pmu_device_probe(struct platform_device *pdev)
 {
        struct arc_reg_pct_build pct_bcr;
        struct arc_reg_cc_build cc_bcr;
-       int i, j, has_interrupts;
+       int i, has_interrupts;
        int counter_size;       /* in bits */
 
        union cc_name {
                struct {
-                       uint32_t word0, word1;
+                       u32 word0, word1;
                        char sentinel;
                } indiv;
-               char str[9];
+               char str[ARCPMU_EVENT_NAME_LEN];
        } cc_name;
 
 
@@ -463,15 +580,22 @@ static int arc_pmu_device_probe(struct platform_device *pdev)
                return -ENODEV;
        }
        BUILD_BUG_ON(ARC_PERF_MAX_COUNTERS > 32);
-       BUG_ON(pct_bcr.c > ARC_PERF_MAX_COUNTERS);
+       if (WARN_ON(pct_bcr.c > ARC_PERF_MAX_COUNTERS))
+               return -EINVAL;
 
        READ_BCR(ARC_REG_CC_BUILD, cc_bcr);
-       BUG_ON(!cc_bcr.v); /* Counters exist but No countable conditions ? */
+       if (WARN(!cc_bcr.v, "Counters exist but No countable conditions?"))
+               return -EINVAL;
 
        arc_pmu = devm_kzalloc(&pdev->dev, sizeof(struct arc_pmu), GFP_KERNEL);
        if (!arc_pmu)
                return -ENOMEM;
 
+       arc_pmu->n_events = cc_bcr.c;
+
+       if (arc_pmu_raw_alloc(&pdev->dev))
+               return -ENOMEM;
+
        has_interrupts = is_isa_arcv2() ? pct_bcr.i : 0;
 
        arc_pmu->n_counters = pct_bcr.c;
@@ -481,30 +605,26 @@ static int arc_pmu_device_probe(struct platform_device *pdev)
 
        pr_info("ARC perf\t: %d counters (%d bits), %d conditions%s\n",
                arc_pmu->n_counters, counter_size, cc_bcr.c,
-               has_interrupts ? ", [overflow IRQ support]":"");
+               has_interrupts ? ", [overflow IRQ support]" : "");
 
-       cc_name.str[8] = 0;
+       cc_name.str[ARCPMU_EVENT_NAME_LEN - 1] = 0;
        for (i = 0; i < PERF_COUNT_ARC_HW_MAX; i++)
                arc_pmu->ev_hw_idx[i] = -1;
 
        /* loop thru all available h/w condition indexes */
-       for (j = 0; j < cc_bcr.c; j++) {
-               write_aux_reg(ARC_REG_CC_INDEX, j);
+       for (i = 0; i < cc_bcr.c; i++) {
+               write_aux_reg(ARC_REG_CC_INDEX, i);
                cc_name.indiv.word0 = read_aux_reg(ARC_REG_CC_NAME0);
                cc_name.indiv.word1 = read_aux_reg(ARC_REG_CC_NAME1);
 
-               /* See if it has been mapped to a perf event_id */
-               for (i = 0; i < ARRAY_SIZE(arc_pmu_ev_hw_map); i++) {
-                       if (arc_pmu_ev_hw_map[i] &&
-                           !strcmp(arc_pmu_ev_hw_map[i], cc_name.str) &&
-                           strlen(arc_pmu_ev_hw_map[i])) {
-                               pr_debug("mapping perf event %2d to h/w event \'%8s\' (idx %d)\n",
-                                        i, cc_name.str, j);
-                               arc_pmu->ev_hw_idx[i] = j;
-                       }
-               }
+               arc_pmu_map_hw_event(i, cc_name.str);
+               arc_pmu_add_raw_event_attr(i, cc_name.str);
        }
 
+       arc_pmu_events_attr_gr.attrs = arc_pmu->attrs;
+       arc_pmu->attr_groups[ARCPMU_ATTR_GR_EVENTS] = &arc_pmu_events_attr_gr;
+       arc_pmu->attr_groups[ARCPMU_ATTR_GR_FORMATS] = &arc_pmu_format_attr_gr;
+
        arc_pmu->pmu = (struct pmu) {
                .pmu_enable     = arc_pmu_enable,
                .pmu_disable    = arc_pmu_disable,
@@ -514,6 +634,7 @@ static int arc_pmu_device_probe(struct platform_device *pdev)
                .start          = arc_pmu_start,
                .stop           = arc_pmu_stop,
                .read           = arc_pmu_read,
+               .attr_groups    = arc_pmu->attr_groups,
        };
 
        if (has_interrupts) {
@@ -535,17 +656,19 @@ static int arc_pmu_device_probe(struct platform_device *pdev)
        } else
                arc_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
 
-       return perf_pmu_register(&arc_pmu->pmu, pdev->name, PERF_TYPE_RAW);
+       /*
+        * perf parser doesn't really like '-' symbol in events name, so let's
+        * use '_' in arc pct name as it goes to kernel PMU event prefix.
+        */
+       return perf_pmu_register(&arc_pmu->pmu, "arc_pct", PERF_TYPE_RAW);
 }
 
-#ifdef CONFIG_OF
 static const struct of_device_id arc_pmu_match[] = {
        { .compatible = "snps,arc700-pct" },
        { .compatible = "snps,archs-pct" },
        {},
 };
 MODULE_DEVICE_TABLE(of, arc_pmu_match);
-#endif
 
 static struct platform_driver arc_pmu_driver = {
        .driver = {
index 2e018b8c2e19ce368c43d8eec102fe5334627da7..feb90093e6b1354eaf60064d7d961c736ded3108 100644 (file)
@@ -123,6 +123,7 @@ static void read_arc_build_cfg_regs(void)
        struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
        const struct id_to_str *tbl;
        struct bcr_isa_arcv2 isa;
+       struct bcr_actionpoint ap;
 
        FIX_PTR(cpu);
 
@@ -195,6 +196,7 @@ static void read_arc_build_cfg_regs(void)
                cpu->bpu.full = bpu.ft;
                cpu->bpu.num_cache = 256 << bpu.bce;
                cpu->bpu.num_pred = 2048 << bpu.pte;
+               cpu->bpu.ret_stk = 4 << bpu.rse;
 
                if (cpu->core.family >= 0x54) {
                        unsigned int exec_ctrl;
@@ -207,8 +209,11 @@ static void read_arc_build_cfg_regs(void)
                }
        }
 
-       READ_BCR(ARC_REG_AP_BCR, bcr);
-       cpu->extn.ap = bcr.ver ? 1 : 0;
+       READ_BCR(ARC_REG_AP_BCR, ap);
+       if (ap.ver) {
+               cpu->extn.ap_num = 2 << ap.num;
+               cpu->extn.ap_full = !!ap.min;
+       }
 
        READ_BCR(ARC_REG_SMART_BCR, bcr);
        cpu->extn.smart = bcr.ver ? 1 : 0;
@@ -216,8 +221,6 @@ static void read_arc_build_cfg_regs(void)
        READ_BCR(ARC_REG_RTT_BCR, bcr);
        cpu->extn.rtt = bcr.ver ? 1 : 0;
 
-       cpu->extn.debug = cpu->extn.ap | cpu->extn.smart | cpu->extn.rtt;
-
        READ_BCR(ARC_REG_ISA_CFG_BCR, isa);
 
        /* some hacks for lack of feature BCR info in old ARC700 cores */
@@ -299,10 +302,10 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
 
        if (cpu->bpu.ver)
                n += scnprintf(buf + n, len - n,
-                             "BPU\t\t: %s%s match, cache:%d, Predict Table:%d",
+                             "BPU\t\t: %s%s match, cache:%d, Predict Table:%d Return stk: %d",
                              IS_AVAIL1(cpu->bpu.full, "full"),
                              IS_AVAIL1(!cpu->bpu.full, "partial"),
-                             cpu->bpu.num_cache, cpu->bpu.num_pred);
+                             cpu->bpu.num_cache, cpu->bpu.num_pred, cpu->bpu.ret_stk);
 
        if (is_isa_arcv2()) {
                struct bcr_lpb lpb;
@@ -336,11 +339,17 @@ static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len)
                               IS_AVAIL1(cpu->extn.fpu_sp, "SP "),
                               IS_AVAIL1(cpu->extn.fpu_dp, "DP "));
 
-       if (cpu->extn.debug)
-               n += scnprintf(buf + n, len - n, "DEBUG\t\t: %s%s%s\n",
-                              IS_AVAIL1(cpu->extn.ap, "ActionPoint "),
+       if (cpu->extn.ap_num | cpu->extn.smart | cpu->extn.rtt) {
+               n += scnprintf(buf + n, len - n, "DEBUG\t\t: %s%s",
                               IS_AVAIL1(cpu->extn.smart, "smaRT "),
                               IS_AVAIL1(cpu->extn.rtt, "RTT "));
+               if (cpu->extn.ap_num) {
+                       n += scnprintf(buf + n, len - n, "ActionPoint %d/%s",
+                                      cpu->extn.ap_num,
+                                      cpu->extn.ap_full ? "full":"min");
+               }
+               n += scnprintf(buf + n, len - n, "\n");
+       }
 
        if (cpu->dccm.sz || cpu->iccm.sz)
                n += scnprintf(buf + n, len - n, "Extn [CCM]\t: DCCM @ %x, %d KB / ICCM: @ %x, %d KB\n",
index e8d9fb4523462a9807358fea19c4e7668cc1126d..215f515442e03d53ee3a18ade4c62e2a06987b3b 100644 (file)
@@ -18,6 +18,8 @@
 #include <asm/arcregs.h>
 #include <asm/irqflags.h>
 
+#define ARC_PATH_MAX   256
+
 /*
  * Common routine to print scratch regs (r0-r12) or callee regs (r13-r25)
  *   -Prints 3 regs per line and a CR.
@@ -58,11 +60,12 @@ static void show_callee_regs(struct callee_regs *cregs)
        print_reg_file(&(cregs->r13), 13);
 }
 
-static void print_task_path_n_nm(struct task_struct *tsk, char *buf)
+static void print_task_path_n_nm(struct task_struct *tsk)
 {
        char *path_nm = NULL;
        struct mm_struct *mm;
        struct file *exe_file;
+       char buf[ARC_PATH_MAX];
 
        mm = get_task_mm(tsk);
        if (!mm)
@@ -72,7 +75,7 @@ static void print_task_path_n_nm(struct task_struct *tsk, char *buf)
        mmput(mm);
 
        if (exe_file) {
-               path_nm = file_path(exe_file, buf, 255);
+               path_nm = file_path(exe_file, buf, ARC_PATH_MAX-1);
                fput(exe_file);
        }
 
@@ -80,10 +83,9 @@ done:
        pr_info("Path: %s\n", !IS_ERR(path_nm) ? path_nm : "?");
 }
 
-static void show_faulting_vma(unsigned long address, char *buf)
+static void show_faulting_vma(unsigned long address)
 {
        struct vm_area_struct *vma;
-       char *nm = buf;
        struct mm_struct *active_mm = current->active_mm;
 
        /* can't use print_vma_addr() yet as it doesn't check for
@@ -96,8 +98,11 @@ static void show_faulting_vma(unsigned long address, char *buf)
         * if the container VMA is not found
         */
        if (vma && (vma->vm_start <= address)) {
+               char buf[ARC_PATH_MAX];
+               char *nm = "?";
+
                if (vma->vm_file) {
-                       nm = file_path(vma->vm_file, buf, PAGE_SIZE - 1);
+                       nm = file_path(vma->vm_file, buf, ARC_PATH_MAX-1);
                        if (IS_ERR(nm))
                                nm = "?";
                }
@@ -173,13 +178,14 @@ void show_regs(struct pt_regs *regs)
 {
        struct task_struct *tsk = current;
        struct callee_regs *cregs;
-       char *buf;
 
-       buf = (char *)__get_free_page(GFP_KERNEL);
-       if (!buf)
-               return;
+       /*
+        * generic code calls us with preemption disabled, but some calls
+        * here could sleep, so re-enable to avoid lockdep splat
+        */
+       preempt_enable();
 
-       print_task_path_n_nm(tsk, buf);
+       print_task_path_n_nm(tsk);
        show_regs_print_info(KERN_INFO);
 
        show_ecr_verbose(regs);
@@ -189,7 +195,7 @@ void show_regs(struct pt_regs *regs)
                (void *)regs->blink, (void *)regs->ret);
 
        if (user_mode(regs))
-               show_faulting_vma(regs->ret, buf); /* faulting code, not data */
+               show_faulting_vma(regs->ret); /* faulting code, not data */
 
        pr_info("[STAT32]: 0x%08lx", regs->status32);
 
@@ -222,7 +228,7 @@ void show_regs(struct pt_regs *regs)
        if (cregs)
                show_callee_regs(cregs);
 
-       free_page((unsigned long)buf);
+       preempt_disable();
 }
 
 void show_kernel_fault_diag(const char *str, struct pt_regs *regs,
index 62ad4bcb841aa70811a637c3621d80190ed0c352..f230bb7092fdb3d7d98883ab7310db1b4bc56654 100644 (file)
@@ -7,11 +7,39 @@
  */
 
 #include <linux/linkage.h>
+#include <asm/cache.h>
 
-#undef PREALLOC_NOT_AVAIL
+/*
+ * The memset implementation below is optimized to use prefetchw and prealloc
+ * instruction in case of CPU with 64B L1 data cache line (L1_CACHE_SHIFT == 6)
+ * If you want to implement optimized memset for other possible L1 data cache
+ * line lengths (32B and 128B) you should rewrite code carefully checking
+ * we don't call any prefetchw/prealloc instruction for L1 cache lines which
+ * don't belongs to memset area.
+ */
+
+#if L1_CACHE_SHIFT == 6
+
+.macro PREALLOC_INSTR  reg, off
+       prealloc        [\reg, \off]
+.endm
+
+.macro PREFETCHW_INSTR reg, off
+       prefetchw       [\reg, \off]
+.endm
+
+#else
+
+.macro PREALLOC_INSTR
+.endm
+
+.macro PREFETCHW_INSTR
+.endm
+
+#endif
 
 ENTRY_CFI(memset)
-       prefetchw [r0]          ; Prefetch the write location
+       PREFETCHW_INSTR r0, 0   ; Prefetch the first write location
        mov.f   0, r2
 ;;; if size is zero
        jz.d    [blink]
@@ -48,11 +76,8 @@ ENTRY_CFI(memset)
 
        lpnz    @.Lset64bytes
        ;; LOOP START
-#ifdef PREALLOC_NOT_AVAIL
-       prefetchw [r3, 64]      ;Prefetch the next write location
-#else
-       prealloc  [r3, 64]
-#endif
+       PREALLOC_INSTR  r3, 64  ; alloc next line w/o fetching
+
 #ifdef CONFIG_ARC_HAS_LL64
        std.ab  r4, [r3, 8]
        std.ab  r4, [r3, 8]
@@ -85,7 +110,6 @@ ENTRY_CFI(memset)
        lsr.f   lp_count, r2, 5 ;Last remaining  max 124 bytes
        lpnz    .Lset32bytes
        ;; LOOP START
-       prefetchw   [r3, 32]    ;Prefetch the next write location
 #ifdef CONFIG_ARC_HAS_LL64
        std.ab  r4, [r3, 8]
        std.ab  r4, [r3, 8]
index a1d7231970848dbc6f1f097fd7536153d63cf38d..8df1638259f3f2daa6b7d3cd3f70f54c3094017a 100644 (file)
@@ -141,12 +141,17 @@ good_area:
         */
        fault = handle_mm_fault(vma, address, flags);
 
-       /* If Pagefault was interrupted by SIGKILL, exit page fault "early" */
        if (fatal_signal_pending(current)) {
-               if ((fault & VM_FAULT_ERROR) && !(fault & VM_FAULT_RETRY))
-                       up_read(&mm->mmap_sem);
-               if (user_mode(regs))
+
+               /*
+                * if fault retry, mmap_sem already relinquished by core mm
+                * so OK to return to user mode (with signal handled first)
+                */
+               if (fault & VM_FAULT_RETRY) {
+                       if (!user_mode(regs))
+                               goto no_context;
                        return;
+               }
        }
 
        perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
index 43bf4c3a1290d818578bfdcda5fefaf76df27810..e1ab2d7f1d646510ab17a4be31b675e88027745b 100644 (file)
@@ -119,7 +119,8 @@ void __init setup_arch_memory(void)
         */
 
        memblock_add_node(low_mem_start, low_mem_sz, 0);
-       memblock_reserve(low_mem_start, __pa(_end) - low_mem_start);
+       memblock_reserve(CONFIG_LINUX_LINK_BASE,
+                        __pa(_end) - CONFIG_LINUX_LINK_BASE);
 
 #ifdef CONFIG_BLK_DEV_INITRD
        if (phys_initrd_size) {
index b3ef061d8b7417b90279c94a8706995fc116bd21..2c403e7c782d31f83b956dcbcc9a9a9027092ffe 100644 (file)
@@ -1 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_ARM_XEN_PAGE_COHERENT_H
+#define _ASM_ARM_XEN_PAGE_COHERENT_H
+
+#include <linux/dma-mapping.h>
+#include <asm/page.h>
 #include <xen/arm/page-coherent.h>
+
+static inline const struct dma_map_ops *xen_get_dma_ops(struct device *dev)
+{
+       if (dev && dev->archdata.dev_dma_ops)
+               return dev->archdata.dev_dma_ops;
+       return get_arch_dma_ops(NULL);
+}
+
+static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
+               dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
+{
+       return xen_get_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs);
+}
+
+static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
+               void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
+{
+       xen_get_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs);
+}
+
+static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
+            dma_addr_t dev_addr, unsigned long offset, size_t size,
+            enum dma_data_direction dir, unsigned long attrs)
+{
+       unsigned long page_pfn = page_to_xen_pfn(page);
+       unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
+       unsigned long compound_pages =
+               (1<<compound_order(page)) * XEN_PFN_PER_PAGE;
+       bool local = (page_pfn <= dev_pfn) &&
+               (dev_pfn - page_pfn < compound_pages);
+
+       /*
+        * Dom0 is mapped 1:1, while the Linux page can span across
+        * multiple Xen pages, it's not possible for it to contain a
+        * mix of local and foreign Xen pages. So if the first xen_pfn
+        * == mfn the page is local otherwise it's a foreign page
+        * grant-mapped in dom0. If the page is local we can safely
+        * call the native dma_ops function, otherwise we call the xen
+        * specific function.
+        */
+       if (local)
+               xen_get_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs);
+       else
+               __xen_dma_map_page(hwdev, page, dev_addr, offset, size, dir, attrs);
+}
+
+static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
+               size_t size, enum dma_data_direction dir, unsigned long attrs)
+{
+       unsigned long pfn = PFN_DOWN(handle);
+       /*
+        * Dom0 is mapped 1:1, while the Linux page can be spanned accross
+        * multiple Xen page, it's not possible to have a mix of local and
+        * foreign Xen page. Dom0 is mapped 1:1, so calling pfn_valid on a
+        * foreign mfn will always return false. If the page is local we can
+        * safely call the native dma_ops function, otherwise we call the xen
+        * specific function.
+        */
+       if (pfn_valid(pfn)) {
+               if (xen_get_dma_ops(hwdev)->unmap_page)
+                       xen_get_dma_ops(hwdev)->unmap_page(hwdev, handle, size, dir, attrs);
+       } else
+               __xen_dma_unmap_page(hwdev, handle, size, dir, attrs);
+}
+
+static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
+               dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+       unsigned long pfn = PFN_DOWN(handle);
+       if (pfn_valid(pfn)) {
+               if (xen_get_dma_ops(hwdev)->sync_single_for_cpu)
+                       xen_get_dma_ops(hwdev)->sync_single_for_cpu(hwdev, handle, size, dir);
+       } else
+               __xen_dma_sync_single_for_cpu(hwdev, handle, size, dir);
+}
+
+static inline void xen_dma_sync_single_for_device(struct device *hwdev,
+               dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+       unsigned long pfn = PFN_DOWN(handle);
+       if (pfn_valid(pfn)) {
+               if (xen_get_dma_ops(hwdev)->sync_single_for_device)
+                       xen_get_dma_ops(hwdev)->sync_single_for_device(hwdev, handle, size, dir);
+       } else
+               __xen_dma_sync_single_for_device(hwdev, handle, size, dir);
+}
+
+#endif /* _ASM_ARM_XEN_PAGE_COHERENT_H */
index 318394ed5c7a97c2923c8c35134b88cb188ef238..95a11d5b3587fd1ba2accad36460a956c17eb173 100644 (file)
@@ -83,7 +83,7 @@ static void __iomem *cns3xxx_pci_map_bus(struct pci_bus *bus,
        } else /* remote PCI bus */
                base = cnspci->cfg1_regs + ((busno & 0xf) << 20);
 
-       return base + (where & 0xffc) + (devfn << 12);
+       return base + where + (devfn << 12);
 }
 
 static int cns3xxx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
@@ -93,7 +93,7 @@ static int cns3xxx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
        u32 mask = (0x1ull << (size * 8)) - 1;
        int shift = (where % 4) * 8;
 
-       ret = pci_generic_config_read32(bus, devfn, where, size, val);
+       ret = pci_generic_config_read(bus, devfn, where, size, val);
 
        if (ret == PCIBIOS_SUCCESSFUL && !bus->number && !devfn &&
            (where & 0xffc) == PCI_CLASS_REVISION)
index 3dd3d664c5c5dfc3ee759af069d248f09eba4e50..4658c937e17304fcf86212294d3cfc9badb40e37 100644 (file)
@@ -20,9 +20,6 @@ struct dev_archdata {
 #ifdef CONFIG_IOMMU_API
        void *iommu;                    /* private IOMMU data */
 #endif
-#ifdef CONFIG_XEN
-       const struct dma_map_ops *dev_dma_ops;
-#endif
 };
 
 struct pdev_archdata {
index b3ef061d8b7417b90279c94a8706995fc116bd21..d88e56b90b93a55fa972fbf22b518c17bdfba1cb 100644 (file)
@@ -1 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_ARM64_XEN_PAGE_COHERENT_H
+#define _ASM_ARM64_XEN_PAGE_COHERENT_H
+
+#include <linux/dma-mapping.h>
+#include <asm/page.h>
 #include <xen/arm/page-coherent.h>
+
+static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
+               dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
+{
+       return dma_direct_alloc(hwdev, size, dma_handle, flags, attrs);
+}
+
+static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
+               void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
+{
+       dma_direct_free(hwdev, size, cpu_addr, dma_handle, attrs);
+}
+
+static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
+               dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+       unsigned long pfn = PFN_DOWN(handle);
+
+       if (pfn_valid(pfn))
+               dma_direct_sync_single_for_cpu(hwdev, handle, size, dir);
+       else
+               __xen_dma_sync_single_for_cpu(hwdev, handle, size, dir);
+}
+
+static inline void xen_dma_sync_single_for_device(struct device *hwdev,
+               dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+       unsigned long pfn = PFN_DOWN(handle);
+       if (pfn_valid(pfn))
+               dma_direct_sync_single_for_device(hwdev, handle, size, dir);
+       else
+               __xen_dma_sync_single_for_device(hwdev, handle, size, dir);
+}
+
+static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
+            dma_addr_t dev_addr, unsigned long offset, size_t size,
+            enum dma_data_direction dir, unsigned long attrs)
+{
+       unsigned long page_pfn = page_to_xen_pfn(page);
+       unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
+       unsigned long compound_pages =
+               (1<<compound_order(page)) * XEN_PFN_PER_PAGE;
+       bool local = (page_pfn <= dev_pfn) &&
+               (dev_pfn - page_pfn < compound_pages);
+
+       if (local)
+               dma_direct_map_page(hwdev, page, offset, size, dir, attrs);
+       else
+               __xen_dma_map_page(hwdev, page, dev_addr, offset, size, dir, attrs);
+}
+
+static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
+               size_t size, enum dma_data_direction dir, unsigned long attrs)
+{
+       unsigned long pfn = PFN_DOWN(handle);
+       /*
+        * Dom0 is mapped 1:1, while the Linux page can be spanned accross
+        * multiple Xen page, it's not possible to have a mix of local and
+        * foreign Xen page. Dom0 is mapped 1:1, so calling pfn_valid on a
+        * foreign mfn will always return false. If the page is local we can
+        * safely call the native dma_ops function, otherwise we call the xen
+        * specific function.
+        */
+       if (pfn_valid(pfn))
+               dma_direct_unmap_page(hwdev, handle, size, dir, attrs);
+       else
+               __xen_dma_unmap_page(hwdev, handle, size, dir, attrs);
+}
+
+#endif /* _ASM_ARM64_XEN_PAGE_COHERENT_H */
index fb0908456a1f99fcb0479d50c33c48c15d2a90a6..78c0a72f822c0a2b0e05b1394e9ca8b982ceb62b 100644 (file)
@@ -466,9 +466,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
        __iommu_setup_dma_ops(dev, dma_base, size, iommu);
 
 #ifdef CONFIG_XEN
-       if (xen_initial_domain()) {
-               dev->archdata.dev_dma_ops = dev->dma_ops;
+       if (xen_initial_domain())
                dev->dma_ops = xen_dma_ops;
-       }
 #endif
 }
index ccbb53e2202404b85aae86e883d3e64405d2d305..8d04e6f3f79649d460376f09217c9e8fe211a850 100644 (file)
@@ -25,7 +25,7 @@ static inline int init_new_context(struct task_struct *tsk,
        atomic_set(&mm->context.flush_count, 0);
        mm->context.gmap_asce = 0;
        mm->context.flush_mm = 0;
-       mm->context.compat_mm = 0;
+       mm->context.compat_mm = test_thread_flag(TIF_31BIT);
 #ifdef CONFIG_PGSTE
        mm->context.alloc_pgste = page_table_allocate_pgste ||
                test_thread_flag(TIF_PGSTE) ||
@@ -90,8 +90,6 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
 {
        int cpu = smp_processor_id();
 
-       if (prev == next)
-               return;
        S390_lowcore.user_asce = next->context.asce;
        cpumask_set_cpu(cpu, &next->context.cpu_attach_mask);
        /* Clear previous user-ASCE from CR1 and CR7 */
@@ -103,7 +101,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
                __ctl_load(S390_lowcore.vdso_asce, 7, 7);
                clear_cpu_flag(CIF_ASCE_SECONDARY);
        }
-       cpumask_clear_cpu(cpu, &prev->context.cpu_attach_mask);
+       if (prev != next)
+               cpumask_clear_cpu(cpu, &prev->context.cpu_attach_mask);
 }
 
 #define finish_arch_post_lock_switch finish_arch_post_lock_switch
index af5c2b3f706567f5f9927686ccfd210b50366221..a8c7789b246b49eb5a546360e4491eaf0f9eac7b 100644 (file)
@@ -63,10 +63,10 @@ static noinline __init void detect_machine_type(void)
        if (stsi(vmms, 3, 2, 2) || !vmms->count)
                return;
 
-       /* Running under KVM? If not we assume z/VM */
+       /* Detect known hypervisors */
        if (!memcmp(vmms->vm[0].cpi, "\xd2\xe5\xd4", 3))
                S390_lowcore.machine_flags |= MACHINE_FLAG_KVM;
-       else
+       else if (!memcmp(vmms->vm[0].cpi, "\xa9\x61\xe5\xd4", 4))
                S390_lowcore.machine_flags |= MACHINE_FLAG_VM;
 }
 
index 72dd23ef771b6bf22f77e71df22a40e05fbee2d5..7ed90a75913572f752652d611a0cd5347279d8e2 100644 (file)
@@ -1006,6 +1006,8 @@ void __init setup_arch(char **cmdline_p)
                pr_info("Linux is running under KVM in 64-bit mode\n");
        else if (MACHINE_IS_LPAR)
                pr_info("Linux is running natively in 64-bit mode\n");
+       else
+               pr_info("Linux is running as a guest in 64-bit mode\n");
 
        /* Have one command line that is parsed and saved in /proc/cmdline */
        /* boot_command_line has been already set up in early.c */
index f82b3d3c36e2d5620e4b8e6b363936bcdf38d673..b198ece2aad63d70f58b2acde1c280ce5534cf7a 100644 (file)
@@ -381,8 +381,13 @@ void smp_call_online_cpu(void (*func)(void *), void *data)
  */
 void smp_call_ipl_cpu(void (*func)(void *), void *data)
 {
+       struct lowcore *lc = pcpu_devices->lowcore;
+
+       if (pcpu_devices[0].address == stap())
+               lc = &S390_lowcore;
+
        pcpu_delegate(&pcpu_devices[0], func, data,
-                     pcpu_devices->lowcore->nodat_stack);
+                     lc->nodat_stack);
 }
 
 int smp_find_processor_id(u16 address)
@@ -1166,7 +1171,11 @@ static ssize_t __ref rescan_store(struct device *dev,
 {
        int rc;
 
+       rc = lock_device_hotplug_sysfs();
+       if (rc)
+               return rc;
        rc = smp_rescan_cpus();
+       unlock_device_hotplug();
        return rc ? rc : count;
 }
 static DEVICE_ATTR_WO(rescan);
index ebe748a9f472fde63cfccd42921472233f6ea529..4ff354887db412a504bb432956c28b2ba6b8a936 100644 (file)
@@ -224,10 +224,9 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 
        vdso_pages = vdso64_pages;
 #ifdef CONFIG_COMPAT
-       if (is_compat_task()) {
+       mm->context.compat_mm = is_compat_task();
+       if (mm->context.compat_mm)
                vdso_pages = vdso32_pages;
-               mm->context.compat_mm = 1;
-       }
 #endif
        /*
         * vDSO has a problem and was disabled, just don't "enable" it for
index 4b4a7f32b68ed6e28e22793009f33cb36e8e17fa..26387c7bf305bc7d4e14e2d34856802a250c55ba 100644 (file)
@@ -198,7 +198,7 @@ config X86
        select IRQ_FORCED_THREADING
        select NEED_SG_DMA_LENGTH
        select PCI_DOMAINS                      if PCI
-       select PCI_LOCKLESS_CONFIG
+       select PCI_LOCKLESS_CONFIG              if PCI
        select PERF_EVENTS
        select RTC_LIB
        select RTC_MC146818_LIB
index 8eaf8952c408cd619124f9696b4888fae2f529ad..39913770a44d5aeed855c51082a6cf55080457f1 100644 (file)
@@ -361,7 +361,8 @@ ENTRY(entry_INT80_compat)
 
        /* Need to switch before accessing the thread stack. */
        SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
-       movq    %rsp, %rdi
+       /* In the Xen PV case we already run on the thread stack. */
+       ALTERNATIVE "movq %rsp, %rdi", "jmp .Lint80_keep_stack", X86_FEATURE_XENPV
        movq    PER_CPU_VAR(cpu_current_top_of_stack), %rsp
 
        pushq   6*8(%rdi)               /* regs->ss */
@@ -370,8 +371,9 @@ ENTRY(entry_INT80_compat)
        pushq   3*8(%rdi)               /* regs->cs */
        pushq   2*8(%rdi)               /* regs->ip */
        pushq   1*8(%rdi)               /* regs->orig_ax */
-
        pushq   (%rdi)                  /* pt_regs->di */
+.Lint80_keep_stack:
+
        pushq   %rsi                    /* pt_regs->si */
        xorl    %esi, %esi              /* nospec   si */
        pushq   %rdx                    /* pt_regs->dx */
index 0ca50611e8cec0b5af0f29947bee90761bc76ef1..19d18fae6ec660e8119f21d2f80cf0ac3552486e 100644 (file)
@@ -178,6 +178,10 @@ static inline void switch_ldt(struct mm_struct *prev, struct mm_struct *next)
 
 void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk);
 
+/*
+ * Init a new mm.  Used on mm copies, like at fork()
+ * and on mm's that are brand-new, like at execve().
+ */
 static inline int init_new_context(struct task_struct *tsk,
                                   struct mm_struct *mm)
 {
@@ -228,8 +232,22 @@ do {                                               \
 } while (0)
 #endif
 
+static inline void arch_dup_pkeys(struct mm_struct *oldmm,
+                                 struct mm_struct *mm)
+{
+#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
+       if (!cpu_feature_enabled(X86_FEATURE_OSPKE))
+               return;
+
+       /* Duplicate the oldmm pkey state in mm: */
+       mm->context.pkey_allocation_map = oldmm->context.pkey_allocation_map;
+       mm->context.execute_only_pkey   = oldmm->context.execute_only_pkey;
+#endif
+}
+
 static inline int arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
 {
+       arch_dup_pkeys(oldmm, mm);
        paravirt_arch_dup_mmap(oldmm, mm);
        return ldt_dup_context(oldmm, mm);
 }
index c8b07d8ea5a2bba61448b169a0cd0ea3daa086ad..17ffc869cab822d03e85baea56bade232a0e4598 100644 (file)
@@ -470,6 +470,7 @@ int crash_load_segments(struct kimage *image)
 
        kbuf.memsz = kbuf.bufsz;
        kbuf.buf_align = ELF_CORE_HEADER_ALIGN;
+       kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
        ret = kexec_add_buffer(&kbuf);
        if (ret) {
                vfree((void *)image->arch.elf_headers);
index b0acb22e5a465096b37f7a67a689852685228087..dfd3aca82c61cbe345f462a62ea6b52fa0b81516 100644 (file)
 
 #define HPET_MASK                      CLOCKSOURCE_MASK(32)
 
-/* FSEC = 10^-15
-   NSEC = 10^-9 */
-#define FSEC_PER_NSEC                  1000000L
-
 #define HPET_DEV_USED_BIT              2
 #define HPET_DEV_USED                  (1 << HPET_DEV_USED_BIT)
 #define HPET_DEV_VALID                 0x8
index 278cd07228dd886778cabf708dd2b1237a318d72..0d5efa34f35966f0b272797f737252ed8bdb23a6 100644 (file)
@@ -434,6 +434,7 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
        kbuf.memsz = PAGE_ALIGN(header->init_size);
        kbuf.buf_align = header->kernel_alignment;
        kbuf.buf_min = MIN_KERNEL_LOAD_ADDR;
+       kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
        ret = kexec_add_buffer(&kbuf);
        if (ret)
                goto out_free_params;
@@ -448,6 +449,7 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
                kbuf.bufsz = kbuf.memsz = initrd_len;
                kbuf.buf_align = PAGE_SIZE;
                kbuf.buf_min = MIN_INITRD_LOAD_ADDR;
+               kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
                ret = kexec_add_buffer(&kbuf);
                if (ret)
                        goto out_free_params;
index ba4bfb7f6a36996a806a634bf3c4a86bd594129f..5c93a65ee1e5c2ec56e83eda147bc1bc31e159cd 100644 (file)
@@ -457,6 +457,7 @@ static void __send_ipi_mask(const struct cpumask *mask, int vector)
 #else
        u64 ipi_bitmap = 0;
 #endif
+       long ret;
 
        if (cpumask_empty(mask))
                return;
@@ -482,8 +483,9 @@ static void __send_ipi_mask(const struct cpumask *mask, int vector)
                } else if (apic_id < min + KVM_IPI_CLUSTER_SIZE) {
                        max = apic_id < max ? max : apic_id;
                } else {
-                       kvm_hypercall4(KVM_HC_SEND_IPI, (unsigned long)ipi_bitmap,
+                       ret = kvm_hypercall4(KVM_HC_SEND_IPI, (unsigned long)ipi_bitmap,
                                (unsigned long)(ipi_bitmap >> BITS_PER_LONG), min, icr);
+                       WARN_ONCE(ret < 0, "KVM: failed to send PV IPI: %ld", ret);
                        min = max = apic_id;
                        ipi_bitmap = 0;
                }
@@ -491,8 +493,9 @@ static void __send_ipi_mask(const struct cpumask *mask, int vector)
        }
 
        if (ipi_bitmap) {
-               kvm_hypercall4(KVM_HC_SEND_IPI, (unsigned long)ipi_bitmap,
+               ret = kvm_hypercall4(KVM_HC_SEND_IPI, (unsigned long)ipi_bitmap,
                        (unsigned long)(ipi_bitmap >> BITS_PER_LONG), min, icr);
+               WARN_ONCE(ret < 0, "KVM: failed to send PV IPI: %ld", ret);
        }
 
        local_irq_restore(flags);
index e9f777bfed404340a36de19898fffd129610fc3c..3fae238340699376ef2b5f84d4b6d4c7f60c48c5 100644 (file)
@@ -297,15 +297,16 @@ static int __init tsc_setup(char *str)
 
 __setup("tsc=", tsc_setup);
 
-#define MAX_RETRIES     5
-#define SMI_TRESHOLD    50000
+#define MAX_RETRIES            5
+#define TSC_DEFAULT_THRESHOLD  0x20000
 
 /*
- * Read TSC and the reference counters. Take care of SMI disturbance
+ * Read TSC and the reference counters. Take care of any disturbances
  */
 static u64 tsc_read_refs(u64 *p, int hpet)
 {
        u64 t1, t2;
+       u64 thresh = tsc_khz ? tsc_khz >> 5 : TSC_DEFAULT_THRESHOLD;
        int i;
 
        for (i = 0; i < MAX_RETRIES; i++) {
@@ -315,7 +316,7 @@ static u64 tsc_read_refs(u64 *p, int hpet)
                else
                        *p = acpi_pm_read_early();
                t2 = get_cycles();
-               if ((t2 - t1) < SMI_TRESHOLD)
+               if ((t2 - t1) < thresh)
                        return t2;
        }
        return ULLONG_MAX;
@@ -703,15 +704,15 @@ static unsigned long pit_hpet_ptimer_calibrate_cpu(void)
         * zero. In each wait loop iteration we read the TSC and check
         * the delta to the previous read. We keep track of the min
         * and max values of that delta. The delta is mostly defined
-        * by the IO time of the PIT access, so we can detect when a
-        * SMI/SMM disturbance happened between the two reads. If the
+        * by the IO time of the PIT access, so we can detect when
+        * any disturbance happened between the two reads. If the
         * maximum time is significantly larger than the minimum time,
         * then we discard the result and have another try.
         *
         * 2) Reference counter. If available we use the HPET or the
         * PMTIMER as a reference to check the sanity of that value.
         * We use separate TSC readouts and check inside of the
-        * reference read for a SMI/SMM disturbance. We dicard
+        * reference read for any possible disturbance. We dicard
         * disturbed values here as well. We do that around the PIT
         * calibration delay loop as we have to wait for a certain
         * amount of time anyway.
@@ -744,7 +745,7 @@ static unsigned long pit_hpet_ptimer_calibrate_cpu(void)
                if (ref1 == ref2)
                        continue;
 
-               /* Check, whether the sampling was disturbed by an SMI */
+               /* Check, whether the sampling was disturbed */
                if (tsc1 == ULLONG_MAX || tsc2 == ULLONG_MAX)
                        continue;
 
@@ -1268,7 +1269,7 @@ static DECLARE_DELAYED_WORK(tsc_irqwork, tsc_refine_calibration_work);
  */
 static void tsc_refine_calibration_work(struct work_struct *work)
 {
-       static u64 tsc_start = -1, ref_start;
+       static u64 tsc_start = ULLONG_MAX, ref_start;
        static int hpet;
        u64 tsc_stop, ref_stop, delta;
        unsigned long freq;
@@ -1283,14 +1284,15 @@ static void tsc_refine_calibration_work(struct work_struct *work)
         * delayed the first time we expire. So set the workqueue
         * again once we know timers are working.
         */
-       if (tsc_start == -1) {
+       if (tsc_start == ULLONG_MAX) {
+restart:
                /*
                 * Only set hpet once, to avoid mixing hardware
                 * if the hpet becomes enabled later.
                 */
                hpet = is_hpet_enabled();
-               schedule_delayed_work(&tsc_irqwork, HZ);
                tsc_start = tsc_read_refs(&ref_start, hpet);
+               schedule_delayed_work(&tsc_irqwork, HZ);
                return;
        }
 
@@ -1300,9 +1302,9 @@ static void tsc_refine_calibration_work(struct work_struct *work)
        if (ref_start == ref_stop)
                goto out;
 
-       /* Check, whether the sampling was disturbed by an SMI */
-       if (tsc_start == ULLONG_MAX || tsc_stop == ULLONG_MAX)
-               goto out;
+       /* Check, whether the sampling was disturbed */
+       if (tsc_stop == ULLONG_MAX)
+               goto restart;
 
        delta = tsc_stop - tsc_start;
        delta *= 1000000LL;
index 69b3a7c3001397f65f9cfde541b042347827ee98..31ecf7a76d5a40474e2bc833f9834797e10f295f 100644 (file)
@@ -2,10 +2,6 @@
 
 ccflags-y += -Iarch/x86/kvm
 
-CFLAGS_x86.o := -I.
-CFLAGS_svm.o := -I.
-CFLAGS_vmx.o := -I.
-
 KVM := ../../../virt/kvm
 
 kvm-y                  += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \
index c90a5352d158fa29ff72b42cd11efba0163225e2..89d20ed1d2e8bf7abe753adba301ef2b31ae8398 100644 (file)
@@ -1636,7 +1636,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
                ret = kvm_hvcall_signal_event(vcpu, fast, ingpa);
                if (ret != HV_STATUS_INVALID_PORT_ID)
                        break;
-               /* maybe userspace knows this conn_id: fall through */
+               /* fall through - maybe userspace knows this conn_id. */
        case HVCALL_POST_MESSAGE:
                /* don't bother userspace if it has no way to handle it */
                if (unlikely(rep || !vcpu_to_synic(vcpu)->active)) {
@@ -1832,7 +1832,6 @@ int kvm_vcpu_ioctl_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid,
                        ent->eax |= HV_X64_MSR_VP_INDEX_AVAILABLE;
                        ent->eax |= HV_X64_MSR_RESET_AVAILABLE;
                        ent->eax |= HV_MSR_REFERENCE_TSC_AVAILABLE;
-                       ent->eax |= HV_X64_MSR_GUEST_IDLE_AVAILABLE;
                        ent->eax |= HV_X64_ACCESS_FREQUENCY_MSRS;
                        ent->eax |= HV_X64_ACCESS_REENLIGHTENMENT;
 
@@ -1848,11 +1847,11 @@ int kvm_vcpu_ioctl_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid,
                case HYPERV_CPUID_ENLIGHTMENT_INFO:
                        ent->eax |= HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED;
                        ent->eax |= HV_X64_APIC_ACCESS_RECOMMENDED;
-                       ent->eax |= HV_X64_SYSTEM_RESET_RECOMMENDED;
                        ent->eax |= HV_X64_RELAXED_TIMING_RECOMMENDED;
                        ent->eax |= HV_X64_CLUSTER_IPI_RECOMMENDED;
                        ent->eax |= HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED;
-                       ent->eax |= HV_X64_ENLIGHTENED_VMCS_RECOMMENDED;
+                       if (evmcs_ver)
+                               ent->eax |= HV_X64_ENLIGHTENED_VMCS_RECOMMENDED;
 
                        /*
                         * Default number of spinlock retry attempts, matches
index 9f089e2e09d02b7585a9b9c1203549c62576112f..4b6c2da7265c88f8f530eb026ba6b0e950eac51e 100644 (file)
@@ -1035,6 +1035,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
        switch (delivery_mode) {
        case APIC_DM_LOWEST:
                vcpu->arch.apic_arb_prio++;
+               /* fall through */
        case APIC_DM_FIXED:
                if (unlikely(trig_mode && !level))
                        break;
@@ -1874,6 +1875,7 @@ int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
 
        case APIC_LVT0:
                apic_manage_nmi_watchdog(apic, val);
+               /* fall through */
        case APIC_LVTTHMR:
        case APIC_LVTPC:
        case APIC_LVT1:
index ce770b446238592e985bba826aefdf3bd4e6efcc..da9c42349b1f800ec06ad3441be7ade3f852248f 100644 (file)
@@ -4371,6 +4371,7 @@ __reset_rsvds_bits_mask(struct kvm_vcpu *vcpu,
                        rsvd_bits(maxphyaddr, 51);
                rsvd_check->rsvd_bits_mask[1][4] =
                        rsvd_check->rsvd_bits_mask[0][4];
+               /* fall through */
        case PT64_ROOT_4LEVEL:
                rsvd_check->rsvd_bits_mask[0][3] = exb_bit_rsvd |
                        nonleaf_bit8_rsvd | rsvd_bits(7, 7) |
index a157ca5b686955bbf9942f6a6f3b68247f7bb5cb..f13a3a24d3609e03b2bd849c0058ff41a670f2ca 100644 (file)
@@ -3414,6 +3414,14 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
        kvm_mmu_reset_context(&svm->vcpu);
        kvm_mmu_load(&svm->vcpu);
 
+       /*
+        * Drop what we picked up for L2 via svm_complete_interrupts() so it
+        * doesn't end up in L1.
+        */
+       svm->vcpu.arch.nmi_injected = false;
+       kvm_clear_exception_queue(&svm->vcpu);
+       kvm_clear_interrupt_queue(&svm->vcpu);
+
        return 0;
 }
 
@@ -4395,7 +4403,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
        case MSR_IA32_APICBASE:
                if (kvm_vcpu_apicv_active(vcpu))
                        avic_update_vapic_bar(to_svm(vcpu), data);
-               /* Follow through */
+               /* Fall through */
        default:
                return kvm_set_msr_common(vcpu, msr);
        }
@@ -4504,28 +4512,19 @@ static int avic_incomplete_ipi_interception(struct vcpu_svm *svm)
                kvm_lapic_reg_write(apic, APIC_ICR, icrl);
                break;
        case AVIC_IPI_FAILURE_TARGET_NOT_RUNNING: {
-               int i;
-               struct kvm_vcpu *vcpu;
-               struct kvm *kvm = svm->vcpu.kvm;
                struct kvm_lapic *apic = svm->vcpu.arch.apic;
 
                /*
-                * At this point, we expect that the AVIC HW has already
-                * set the appropriate IRR bits on the valid target
-                * vcpus. So, we just need to kick the appropriate vcpu.
+                * Update ICR high and low, then emulate sending IPI,
+                * which is handled when writing APIC_ICR.
                 */
-               kvm_for_each_vcpu(i, vcpu, kvm) {
-                       bool m = kvm_apic_match_dest(vcpu, apic,
-                                                    icrl & KVM_APIC_SHORT_MASK,
-                                                    GET_APIC_DEST_FIELD(icrh),
-                                                    icrl & KVM_APIC_DEST_MASK);
-
-                       if (m && !avic_vcpu_is_running(vcpu))
-                               kvm_vcpu_wake_up(vcpu);
-               }
+               kvm_lapic_reg_write(apic, APIC_ICR2, icrh);
+               kvm_lapic_reg_write(apic, APIC_ICR, icrl);
                break;
        }
        case AVIC_IPI_FAILURE_INVALID_TARGET:
+               WARN_ONCE(1, "Invalid IPI target: index=%u, vcpu=%d, icr=%#0x:%#0x\n",
+                         index, svm->vcpu.vcpu_id, icrh, icrl);
                break;
        case AVIC_IPI_FAILURE_INVALID_BACKING_PAGE:
                WARN_ONCE(1, "Invalid backing page\n");
index 705f40ae25329ca74fee07191a9104e0945dba92..6432d08c7de79ccbde654b7ab17c9649b75a25c2 100644 (file)
@@ -1465,7 +1465,7 @@ TRACE_EVENT(kvm_hv_send_ipi_ex,
 #endif /* _TRACE_KVM_H */
 
 #undef TRACE_INCLUDE_PATH
-#define TRACE_INCLUDE_PATH arch/x86/kvm
+#define TRACE_INCLUDE_PATH ../../arch/x86/kvm
 #undef TRACE_INCLUDE_FILE
 #define TRACE_INCLUDE_FILE trace
 
index 95bc2247478d90bda1d9305f11986f85db908e5b..5466c6d85cf3ef07388e47012b88fb478ac0d5c2 100644 (file)
@@ -332,16 +332,17 @@ int nested_enable_evmcs(struct kvm_vcpu *vcpu,
                        uint16_t *vmcs_version)
 {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
+       bool evmcs_already_enabled = vmx->nested.enlightened_vmcs_enabled;
+
+       vmx->nested.enlightened_vmcs_enabled = true;
 
        if (vmcs_version)
                *vmcs_version = nested_get_evmcs_version(vcpu);
 
        /* We don't support disabling the feature for simplicity. */
-       if (vmx->nested.enlightened_vmcs_enabled)
+       if (evmcs_already_enabled)
                return 0;
 
-       vmx->nested.enlightened_vmcs_enabled = true;
-
        vmx->nested.msrs.pinbased_ctls_high &= ~EVMCS1_UNSUPPORTED_PINCTRL;
        vmx->nested.msrs.entry_ctls_high &= ~EVMCS1_UNSUPPORTED_VMENTRY_CTRL;
        vmx->nested.msrs.exit_ctls_high &= ~EVMCS1_UNSUPPORTED_VMEXIT_CTRL;
index 2616bd2c7f2c78b25339eff719d37a22b9070404..8ff20523661b87c5e68ee263cef47debb53f1d1f 100644 (file)
@@ -55,7 +55,7 @@ static u16 shadow_read_write_fields[] = {
 static int max_shadow_read_write_fields =
        ARRAY_SIZE(shadow_read_write_fields);
 
-void init_vmcs_shadow_fields(void)
+static void init_vmcs_shadow_fields(void)
 {
        int i, j;
 
@@ -4140,11 +4140,11 @@ static int enter_vmx_operation(struct kvm_vcpu *vcpu)
        if (r < 0)
                goto out_vmcs02;
 
-       vmx->nested.cached_vmcs12 = kmalloc(VMCS12_SIZE, GFP_KERNEL);
+       vmx->nested.cached_vmcs12 = kzalloc(VMCS12_SIZE, GFP_KERNEL);
        if (!vmx->nested.cached_vmcs12)
                goto out_cached_vmcs12;
 
-       vmx->nested.cached_shadow_vmcs12 = kmalloc(VMCS12_SIZE, GFP_KERNEL);
+       vmx->nested.cached_shadow_vmcs12 = kzalloc(VMCS12_SIZE, GFP_KERNEL);
        if (!vmx->nested.cached_shadow_vmcs12)
                goto out_cached_shadow_vmcs12;
 
@@ -5263,13 +5263,17 @@ static int vmx_get_nested_state(struct kvm_vcpu *vcpu,
                        copy_shadow_to_vmcs12(vmx);
        }
 
-       if (copy_to_user(user_kvm_nested_state->data, vmcs12, sizeof(*vmcs12)))
+       /*
+        * Copy over the full allocated size of vmcs12 rather than just the size
+        * of the struct.
+        */
+       if (copy_to_user(user_kvm_nested_state->data, vmcs12, VMCS12_SIZE))
                return -EFAULT;
 
        if (nested_cpu_has_shadow_vmcs(vmcs12) &&
            vmcs12->vmcs_link_pointer != -1ull) {
                if (copy_to_user(user_kvm_nested_state->data + VMCS12_SIZE,
-                                get_shadow_vmcs12(vcpu), sizeof(*vmcs12)))
+                                get_shadow_vmcs12(vcpu), VMCS12_SIZE))
                        return -EFAULT;
        }
 
index f6915f10e584a5f568e2e6a38123ac70c4d3881c..4341175339f32a84bb96d9ec18031e4fadd9baa8 100644 (file)
@@ -423,7 +423,7 @@ static void check_ept_pointer_match(struct kvm *kvm)
        to_kvm_vmx(kvm)->ept_pointers_match = EPT_POINTERS_MATCH;
 }
 
-int kvm_fill_hv_flush_list_func(struct hv_guest_mapping_flush_list *flush,
+static int kvm_fill_hv_flush_list_func(struct hv_guest_mapping_flush_list *flush,
                void *data)
 {
        struct kvm_tlb_range *range = data;
@@ -1773,7 +1773,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                if (!msr_info->host_initiated &&
                    !guest_cpuid_has(vcpu, X86_FEATURE_RDTSCP))
                        return 1;
-               /* Otherwise falls through */
+               /* Else, falls through */
        default:
                msr = find_msr_entry(vmx, msr_info->index);
                if (msr) {
@@ -2014,7 +2014,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                /* Check reserved bit, higher 32 bits should be zero */
                if ((data >> 32) != 0)
                        return 1;
-               /* Otherwise falls through */
+               /* Else, falls through */
        default:
                msr = find_msr_entry(vmx, msr_index);
                if (msr) {
@@ -2344,7 +2344,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf,
                case 37: /* AAT100 */
                case 44: /* BC86,AAY89,BD102 */
                case 46: /* BA97 */
-                       _vmexit_control &= ~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL;
+                       _vmentry_control &= ~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL;
                        _vmexit_control &= ~VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL;
                        pr_warn_once("kvm: VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL "
                                        "does not work properly. Using workaround\n");
@@ -6362,72 +6362,9 @@ static void vmx_update_hv_timer(struct kvm_vcpu *vcpu)
        vmx->loaded_vmcs->hv_timer_armed = false;
 }
 
-static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
+static void __vmx_vcpu_run(struct kvm_vcpu *vcpu, struct vcpu_vmx *vmx)
 {
-       struct vcpu_vmx *vmx = to_vmx(vcpu);
-       unsigned long cr3, cr4, evmcs_rsp;
-
-       /* Record the guest's net vcpu time for enforced NMI injections. */
-       if (unlikely(!enable_vnmi &&
-                    vmx->loaded_vmcs->soft_vnmi_blocked))
-               vmx->loaded_vmcs->entry_time = ktime_get();
-
-       /* Don't enter VMX if guest state is invalid, let the exit handler
-          start emulation until we arrive back to a valid state */
-       if (vmx->emulation_required)
-               return;
-
-       if (vmx->ple_window_dirty) {
-               vmx->ple_window_dirty = false;
-               vmcs_write32(PLE_WINDOW, vmx->ple_window);
-       }
-
-       if (vmx->nested.need_vmcs12_sync)
-               nested_sync_from_vmcs12(vcpu);
-
-       if (test_bit(VCPU_REGS_RSP, (unsigned long *)&vcpu->arch.regs_dirty))
-               vmcs_writel(GUEST_RSP, vcpu->arch.regs[VCPU_REGS_RSP]);
-       if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty))
-               vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]);
-
-       cr3 = __get_current_cr3_fast();
-       if (unlikely(cr3 != vmx->loaded_vmcs->host_state.cr3)) {
-               vmcs_writel(HOST_CR3, cr3);
-               vmx->loaded_vmcs->host_state.cr3 = cr3;
-       }
-
-       cr4 = cr4_read_shadow();
-       if (unlikely(cr4 != vmx->loaded_vmcs->host_state.cr4)) {
-               vmcs_writel(HOST_CR4, cr4);
-               vmx->loaded_vmcs->host_state.cr4 = cr4;
-       }
-
-       /* When single-stepping over STI and MOV SS, we must clear the
-        * corresponding interruptibility bits in the guest state. Otherwise
-        * vmentry fails as it then expects bit 14 (BS) in pending debug
-        * exceptions being set, but that's not correct for the guest debugging
-        * case. */
-       if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
-               vmx_set_interrupt_shadow(vcpu, 0);
-
-       if (static_cpu_has(X86_FEATURE_PKU) &&
-           kvm_read_cr4_bits(vcpu, X86_CR4_PKE) &&
-           vcpu->arch.pkru != vmx->host_pkru)
-               __write_pkru(vcpu->arch.pkru);
-
-       pt_guest_enter(vmx);
-
-       atomic_switch_perf_msrs(vmx);
-
-       vmx_update_hv_timer(vcpu);
-
-       /*
-        * If this vCPU has touched SPEC_CTRL, restore the guest's value if
-        * it's non-zero. Since vmentry is serialising on affected CPUs, there
-        * is no need to worry about the conditional branch over the wrmsr
-        * being speculatively taken.
-        */
-       x86_spec_ctrl_set_guest(vmx->spec_ctrl, 0);
+       unsigned long evmcs_rsp;
 
        vmx->__launched = vmx->loaded_vmcs->launched;
 
@@ -6567,6 +6504,77 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
                , "eax", "ebx", "edi"
 #endif
              );
+}
+STACK_FRAME_NON_STANDARD(__vmx_vcpu_run);
+
+static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
+{
+       struct vcpu_vmx *vmx = to_vmx(vcpu);
+       unsigned long cr3, cr4;
+
+       /* Record the guest's net vcpu time for enforced NMI injections. */
+       if (unlikely(!enable_vnmi &&
+                    vmx->loaded_vmcs->soft_vnmi_blocked))
+               vmx->loaded_vmcs->entry_time = ktime_get();
+
+       /* Don't enter VMX if guest state is invalid, let the exit handler
+          start emulation until we arrive back to a valid state */
+       if (vmx->emulation_required)
+               return;
+
+       if (vmx->ple_window_dirty) {
+               vmx->ple_window_dirty = false;
+               vmcs_write32(PLE_WINDOW, vmx->ple_window);
+       }
+
+       if (vmx->nested.need_vmcs12_sync)
+               nested_sync_from_vmcs12(vcpu);
+
+       if (test_bit(VCPU_REGS_RSP, (unsigned long *)&vcpu->arch.regs_dirty))
+               vmcs_writel(GUEST_RSP, vcpu->arch.regs[VCPU_REGS_RSP]);
+       if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty))
+               vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]);
+
+       cr3 = __get_current_cr3_fast();
+       if (unlikely(cr3 != vmx->loaded_vmcs->host_state.cr3)) {
+               vmcs_writel(HOST_CR3, cr3);
+               vmx->loaded_vmcs->host_state.cr3 = cr3;
+       }
+
+       cr4 = cr4_read_shadow();
+       if (unlikely(cr4 != vmx->loaded_vmcs->host_state.cr4)) {
+               vmcs_writel(HOST_CR4, cr4);
+               vmx->loaded_vmcs->host_state.cr4 = cr4;
+       }
+
+       /* When single-stepping over STI and MOV SS, we must clear the
+        * corresponding interruptibility bits in the guest state. Otherwise
+        * vmentry fails as it then expects bit 14 (BS) in pending debug
+        * exceptions being set, but that's not correct for the guest debugging
+        * case. */
+       if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
+               vmx_set_interrupt_shadow(vcpu, 0);
+
+       if (static_cpu_has(X86_FEATURE_PKU) &&
+           kvm_read_cr4_bits(vcpu, X86_CR4_PKE) &&
+           vcpu->arch.pkru != vmx->host_pkru)
+               __write_pkru(vcpu->arch.pkru);
+
+       pt_guest_enter(vmx);
+
+       atomic_switch_perf_msrs(vmx);
+
+       vmx_update_hv_timer(vcpu);
+
+       /*
+        * If this vCPU has touched SPEC_CTRL, restore the guest's value if
+        * it's non-zero. Since vmentry is serialising on affected CPUs, there
+        * is no need to worry about the conditional branch over the wrmsr
+        * being speculatively taken.
+        */
+       x86_spec_ctrl_set_guest(vmx->spec_ctrl, 0);
+
+       __vmx_vcpu_run(vcpu, vmx);
 
        /*
         * We do not use IBRS in the kernel. If this vCPU has used the
@@ -6648,7 +6656,6 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
        vmx_recover_nmi_blocking(vmx);
        vmx_complete_interrupts(vmx);
 }
-STACK_FRAME_NON_STANDARD(vmx_vcpu_run);
 
 static struct kvm *vmx_vm_alloc(void)
 {
index 02c8e095a23907f821f2ae3f1dc958ec66af0a7b..3d27206f6c010b13d408d45a4eb647430bf2e50d 100644 (file)
@@ -3834,6 +3834,8 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
        case KVM_CAP_HYPERV_SYNIC2:
                if (cap->args[0])
                        return -EINVAL;
+               /* fall through */
+
        case KVM_CAP_HYPERV_SYNIC:
                if (!irqchip_in_kernel(vcpu->kvm))
                        return -EINVAL;
@@ -6480,8 +6482,7 @@ restart:
                toggle_interruptibility(vcpu, ctxt->interruptibility);
                vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
                kvm_rip_write(vcpu, ctxt->eip);
-               if (r == EMULATE_DONE &&
-                   (ctxt->tf || (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)))
+               if (r == EMULATE_DONE && ctxt->tf)
                        kvm_vcpu_do_singlestep(vcpu, &r);
                if (!ctxt->have_exception ||
                    exception_type(ctxt->exception.vector) == EXCPT_TRAP)
@@ -7093,10 +7094,10 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
        case KVM_HC_CLOCK_PAIRING:
                ret = kvm_pv_clock_pairing(vcpu, a0, a1);
                break;
+#endif
        case KVM_HC_SEND_IPI:
                ret = kvm_pv_send_ipi(vcpu->kvm, a0, a1, a2, a3, op_64_bit);
                break;
-#endif
        default:
                ret = -KVM_ENOSYS;
                break;
@@ -7937,6 +7938,7 @@ static inline int vcpu_block(struct kvm *kvm, struct kvm_vcpu *vcpu)
                vcpu->arch.pv.pv_unhalted = false;
                vcpu->arch.mp_state =
                        KVM_MP_STATE_RUNNABLE;
+               /* fall through */
        case KVM_MP_STATE_RUNNABLE:
                vcpu->arch.apf.halted = false;
                break;
index 66894675f3c8d3ac65c4efdae5039d904110c9b2..df50451d94ef7edf095defd0253aa7bb329123ab 100644 (file)
@@ -2,8 +2,11 @@
 #include <linux/module.h>
 #include <linux/io.h>
 
+#define movs(type,to,from) \
+       asm volatile("movs" type:"=&D" (to), "=&S" (from):"0" (to), "1" (from):"memory")
+
 /* Originally from i386/string.h */
-static __always_inline void __iomem_memcpy(void *to, const void *from, size_t n)
+static __always_inline void rep_movs(void *to, const void *from, size_t n)
 {
        unsigned long d0, d1, d2;
        asm volatile("rep ; movsl\n\t"
@@ -21,13 +24,37 @@ static __always_inline void __iomem_memcpy(void *to, const void *from, size_t n)
 
 void memcpy_fromio(void *to, const volatile void __iomem *from, size_t n)
 {
-       __iomem_memcpy(to, (const void *)from, n);
+       if (unlikely(!n))
+               return;
+
+       /* Align any unaligned source IO */
+       if (unlikely(1 & (unsigned long)from)) {
+               movs("b", to, from);
+               n--;
+       }
+       if (n > 1 && unlikely(2 & (unsigned long)from)) {
+               movs("w", to, from);
+               n-=2;
+       }
+       rep_movs(to, (const void *)from, n);
 }
 EXPORT_SYMBOL(memcpy_fromio);
 
 void memcpy_toio(volatile void __iomem *to, const void *from, size_t n)
 {
-       __iomem_memcpy((void *)to, (const void *) from, n);
+       if (unlikely(!n))
+               return;
+
+       /* Align any unaligned destination IO */
+       if (unlikely(1 & (unsigned long)to)) {
+               movs("b", to, from);
+               n--;
+       }
+       if (n > 1 && unlikely(2 & (unsigned long)to)) {
+               movs("w", to, from);
+               n-=2;
+       }
+       rep_movs((void *)to, (const void *) from, n);
 }
 EXPORT_SYMBOL(memcpy_toio);
 
index 79778ab200e494c16cac7441cdb5da9507940715..a536651164584c96a19b1455f743834291a355c6 100644 (file)
@@ -36,8 +36,8 @@ static inline u16 i8254(void)
        u16 status, timer;
 
        do {
-               outb(I8254_PORT_CONTROL,
-                    I8254_CMD_READBACK | I8254_SELECT_COUNTER0);
+               outb(I8254_CMD_READBACK | I8254_SELECT_COUNTER0,
+                    I8254_PORT_CONTROL);
                status = inb(I8254_PORT_COUNTER0);
                timer  = inb(I8254_PORT_COUNTER0);
                timer |= inb(I8254_PORT_COUNTER0) << 8;
index a19ef1a416ff66f0f1c70928644815dc385aa1e0..4aa9b1480866b70d16dbeafdc711a3479de1d670 100644 (file)
@@ -158,8 +158,8 @@ static void __init sme_populate_pgd(struct sme_populate_pgd_data *ppd)
        pmd = pmd_offset(pud, ppd->vaddr);
        if (pmd_none(*pmd)) {
                pte = ppd->pgtable_area;
-               memset(pte, 0, sizeof(pte) * PTRS_PER_PTE);
-               ppd->pgtable_area += sizeof(pte) * PTRS_PER_PTE;
+               memset(pte, 0, sizeof(*pte) * PTRS_PER_PTE);
+               ppd->pgtable_area += sizeof(*pte) * PTRS_PER_PTE;
                set_pmd(pmd, __pmd(PMD_FLAGS | __pa(pte)));
        }
 
index 90d68760af086bd6de78c71dc4a1f6954ceb7a5b..f8120832ca7b8ea44cf872c3810dd373a662656b 100644 (file)
@@ -308,8 +308,9 @@ static const char *const cmd_flag_name[] = {
        CMD_FLAG_NAME(PREFLUSH),
        CMD_FLAG_NAME(RAHEAD),
        CMD_FLAG_NAME(BACKGROUND),
-       CMD_FLAG_NAME(NOUNMAP),
        CMD_FLAG_NAME(NOWAIT),
+       CMD_FLAG_NAME(NOUNMAP),
+       CMD_FLAG_NAME(HIPRI),
 };
 #undef CMD_FLAG_NAME
 
index f0c56649775fcb35ae978b9dac27bcd4c4001fb3..fd166fbb0f6587c494e6095b8bf6e58de0c67360 100644 (file)
@@ -597,7 +597,7 @@ static void wbt_track(struct rq_qos *rqos, struct request *rq, struct bio *bio)
        rq->wbt_flags |= bio_to_wbt_flags(rwb, bio);
 }
 
-void wbt_issue(struct rq_qos *rqos, struct request *rq)
+static void wbt_issue(struct rq_qos *rqos, struct request *rq)
 {
        struct rq_wb *rwb = RQWB(rqos);
 
@@ -617,7 +617,7 @@ void wbt_issue(struct rq_qos *rqos, struct request *rq)
        }
 }
 
-void wbt_requeue(struct rq_qos *rqos, struct request *rq)
+static void wbt_requeue(struct rq_qos *rqos, struct request *rq)
 {
        struct rq_wb *rwb = RQWB(rqos);
        if (!rwb_enabled(rwb))
index 5143e11e3b0fa5378a5f08ee094706b92ba41962..e18ade5d74e9ecf38126bce5301f027073779bc3 100644 (file)
@@ -409,6 +409,32 @@ static bool payload_dumpable(struct nvdimm *nvdimm, unsigned int func)
        return true;
 }
 
+static int cmd_to_func(struct nfit_mem *nfit_mem, unsigned int cmd,
+               struct nd_cmd_pkg *call_pkg)
+{
+       if (call_pkg) {
+               int i;
+
+               if (nfit_mem->family != call_pkg->nd_family)
+                       return -ENOTTY;
+
+               for (i = 0; i < ARRAY_SIZE(call_pkg->nd_reserved2); i++)
+                       if (call_pkg->nd_reserved2[i])
+                               return -EINVAL;
+               return call_pkg->nd_command;
+       }
+
+       /* Linux ND commands == NVDIMM_FAMILY_INTEL function numbers */
+       if (nfit_mem->family == NVDIMM_FAMILY_INTEL)
+               return cmd;
+
+       /*
+        * Force function number validation to fail since 0 is never
+        * published as a valid function in dsm_mask.
+        */
+       return 0;
+}
+
 int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
                unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc)
 {
@@ -422,30 +448,23 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
        unsigned long cmd_mask, dsm_mask;
        u32 offset, fw_status = 0;
        acpi_handle handle;
-       unsigned int func;
        const guid_t *guid;
-       int rc, i;
+       int func, rc, i;
 
        if (cmd_rc)
                *cmd_rc = -EINVAL;
-       func = cmd;
-       if (cmd == ND_CMD_CALL) {
-               call_pkg = buf;
-               func = call_pkg->nd_command;
-
-               for (i = 0; i < ARRAY_SIZE(call_pkg->nd_reserved2); i++)
-                       if (call_pkg->nd_reserved2[i])
-                               return -EINVAL;
-       }
 
        if (nvdimm) {
                struct acpi_device *adev = nfit_mem->adev;
 
                if (!adev)
                        return -ENOTTY;
-               if (call_pkg && nfit_mem->family != call_pkg->nd_family)
-                       return -ENOTTY;
 
+               if (cmd == ND_CMD_CALL)
+                       call_pkg = buf;
+               func = cmd_to_func(nfit_mem, cmd, call_pkg);
+               if (func < 0)
+                       return func;
                dimm_name = nvdimm_name(nvdimm);
                cmd_name = nvdimm_cmd_name(cmd);
                cmd_mask = nvdimm_cmd_mask(nvdimm);
@@ -456,6 +475,7 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
        } else {
                struct acpi_device *adev = to_acpi_dev(acpi_desc);
 
+               func = cmd;
                cmd_name = nvdimm_bus_cmd_name(cmd);
                cmd_mask = nd_desc->cmd_mask;
                dsm_mask = cmd_mask;
@@ -470,7 +490,13 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
        if (!desc || (cmd && (desc->out_num + desc->in_num == 0)))
                return -ENOTTY;
 
-       if (!test_bit(cmd, &cmd_mask) || !test_bit(func, &dsm_mask))
+       /*
+        * Check for a valid command.  For ND_CMD_CALL, we also have to
+        * make sure that the DSM function is supported.
+        */
+       if (cmd == ND_CMD_CALL && !test_bit(func, &dsm_mask))
+               return -ENOTTY;
+       else if (!test_bit(cmd, &cmd_mask))
                return -ENOTTY;
 
        in_obj.type = ACPI_TYPE_PACKAGE;
@@ -1867,6 +1893,13 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
                return 0;
        }
 
+       /*
+        * Function 0 is the command interrogation function, don't
+        * export it to potential userspace use, and enable it to be
+        * used as an error value in acpi_nfit_ctl().
+        */
+       dsm_mask &= ~1UL;
+
        guid = to_nfit_uuid(nfit_mem->family);
        for_each_set_bit(i, &dsm_mask, BITS_PER_LONG)
                if (acpi_check_dsm(adev_dimm->handle, guid,
@@ -2042,11 +2075,6 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
                if (!nvdimm)
                        continue;
 
-               rc = nvdimm_security_setup_events(nvdimm);
-               if (rc < 0)
-                       dev_warn(acpi_desc->dev,
-                               "security event setup failed: %d\n", rc);
-
                nfit_kernfs = sysfs_get_dirent(nvdimm_kobj(nvdimm)->sd, "nfit");
                if (nfit_kernfs)
                        nfit_mem->flags_attr = sysfs_get_dirent(nfit_kernfs,
index 7496b10532aafde54d68c95f264c2853c6f67f1c..6a2185eb66c59761e5d4f0d0f09120806c12dc8b 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/kdev_t.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
+#include <linux/namei.h>
 #include <linux/magic.h>
 #include <linux/major.h>
 #include <linux/miscdevice.h>
@@ -20,6 +21,7 @@
 #include <linux/parser.h>
 #include <linux/radix-tree.h>
 #include <linux/sched.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/spinlock_types.h>
 #include <linux/stddef.h>
@@ -30,7 +32,7 @@
 #include <linux/xarray.h>
 #include <uapi/asm-generic/errno-base.h>
 #include <uapi/linux/android/binder.h>
-#include <uapi/linux/android/binder_ctl.h>
+#include <uapi/linux/android/binderfs.h>
 
 #include "binder_internal.h"
 
 #define INODE_OFFSET 3
 #define INTSTRLEN 21
 #define BINDERFS_MAX_MINOR (1U << MINORBITS)
-
-static struct vfsmount *binderfs_mnt;
+/* Ensure that the initial ipc namespace always has devices available. */
+#define BINDERFS_MAX_MINOR_CAPPED (BINDERFS_MAX_MINOR - 4)
 
 static dev_t binderfs_dev;
 static DEFINE_MUTEX(binderfs_minors_mutex);
 static DEFINE_IDA(binderfs_minors);
 
+/**
+ * binderfs_mount_opts - mount options for binderfs
+ * @max: maximum number of allocatable binderfs binder devices
+ */
+struct binderfs_mount_opts {
+       int max;
+};
+
+enum {
+       Opt_max,
+       Opt_err
+};
+
+static const match_table_t tokens = {
+       { Opt_max, "max=%d" },
+       { Opt_err, NULL     }
+};
+
 /**
  * binderfs_info - information about a binderfs mount
  * @ipc_ns:         The ipc namespace the binderfs mount belongs to.
@@ -55,13 +75,16 @@ static DEFINE_IDA(binderfs_minors);
  *                  created.
  * @root_gid:       gid that needs to be used when a new binder device is
  *                  created.
+ * @mount_opts:     The mount options in use.
+ * @device_count:   The current number of allocated binder devices.
  */
 struct binderfs_info {
        struct ipc_namespace *ipc_ns;
        struct dentry *control_dentry;
        kuid_t root_uid;
        kgid_t root_gid;
-
+       struct binderfs_mount_opts mount_opts;
+       int device_count;
 };
 
 static inline struct binderfs_info *BINDERFS_I(const struct inode *inode)
@@ -84,7 +107,7 @@ bool is_binderfs_device(const struct inode *inode)
  * @userp:     buffer to copy information about new device for userspace to
  * @req:       struct binderfs_device as copied from userspace
  *
- * This function allocated a new binder_device and reserves a new minor
+ * This function allocates a new binder_device and reserves a new minor
  * number for it.
  * Minor numbers are limited and tracked globally in binderfs_minors. The
  * function will stash a struct binder_device for the specific binder
@@ -100,20 +123,34 @@ static int binderfs_binder_device_create(struct inode *ref_inode,
                                         struct binderfs_device *req)
 {
        int minor, ret;
-       struct dentry *dentry, *dup, *root;
+       struct dentry *dentry, *root;
        struct binder_device *device;
-       size_t name_len = BINDERFS_MAX_NAME + 1;
        char *name = NULL;
+       size_t name_len;
        struct inode *inode = NULL;
        struct super_block *sb = ref_inode->i_sb;
        struct binderfs_info *info = sb->s_fs_info;
+#if defined(CONFIG_IPC_NS)
+       bool use_reserve = (info->ipc_ns == &init_ipc_ns);
+#else
+       bool use_reserve = true;
+#endif
 
        /* Reserve new minor number for the new device. */
        mutex_lock(&binderfs_minors_mutex);
-       minor = ida_alloc_max(&binderfs_minors, BINDERFS_MAX_MINOR, GFP_KERNEL);
-       mutex_unlock(&binderfs_minors_mutex);
-       if (minor < 0)
+       if (++info->device_count <= info->mount_opts.max)
+               minor = ida_alloc_max(&binderfs_minors,
+                                     use_reserve ? BINDERFS_MAX_MINOR :
+                                                   BINDERFS_MAX_MINOR_CAPPED,
+                                     GFP_KERNEL);
+       else
+               minor = -ENOSPC;
+       if (minor < 0) {
+               --info->device_count;
+               mutex_unlock(&binderfs_minors_mutex);
                return minor;
+       }
+       mutex_unlock(&binderfs_minors_mutex);
 
        ret = -ENOMEM;
        device = kzalloc(sizeof(*device), GFP_KERNEL);
@@ -132,12 +169,13 @@ static int binderfs_binder_device_create(struct inode *ref_inode,
        inode->i_uid = info->root_uid;
        inode->i_gid = info->root_gid;
 
-       name = kmalloc(name_len, GFP_KERNEL);
+       req->name[BINDERFS_MAX_NAME] = '\0'; /* NUL-terminate */
+       name_len = strlen(req->name);
+       /* Make sure to include terminating NUL byte */
+       name = kmemdup(req->name, name_len + 1, GFP_KERNEL);
        if (!name)
                goto err;
 
-       strscpy(name, req->name, name_len);
-
        device->binderfs_inode = inode;
        device->context.binder_context_mgr_uid = INVALID_UID;
        device->context.name = name;
@@ -156,28 +194,25 @@ static int binderfs_binder_device_create(struct inode *ref_inode,
 
        root = sb->s_root;
        inode_lock(d_inode(root));
-       dentry = d_alloc_name(root, name);
-       if (!dentry) {
+
+       /* look it up */
+       dentry = lookup_one_len(name, root, name_len);
+       if (IS_ERR(dentry)) {
                inode_unlock(d_inode(root));
-               ret = -ENOMEM;
+               ret = PTR_ERR(dentry);
                goto err;
        }
 
-       /* Verify that the name userspace gave us is not already in use. */
-       dup = d_lookup(root, &dentry->d_name);
-       if (dup) {
-               if (d_really_is_positive(dup)) {
-                       dput(dup);
-                       dput(dentry);
-                       inode_unlock(d_inode(root));
-                       ret = -EEXIST;
-                       goto err;
-               }
-               dput(dup);
+       if (d_really_is_positive(dentry)) {
+               /* already exists */
+               dput(dentry);
+               inode_unlock(d_inode(root));
+               ret = -EEXIST;
+               goto err;
        }
 
        inode->i_private = device;
-       d_add(dentry, inode);
+       d_instantiate(dentry, inode);
        fsnotify_create(root->d_inode, dentry);
        inode_unlock(d_inode(root));
 
@@ -187,6 +222,7 @@ err:
        kfree(name);
        kfree(device);
        mutex_lock(&binderfs_minors_mutex);
+       --info->device_count;
        ida_free(&binderfs_minors, minor);
        mutex_unlock(&binderfs_minors_mutex);
        iput(inode);
@@ -232,6 +268,7 @@ static long binder_ctl_ioctl(struct file *file, unsigned int cmd,
 static void binderfs_evict_inode(struct inode *inode)
 {
        struct binder_device *device = inode->i_private;
+       struct binderfs_info *info = BINDERFS_I(inode);
 
        clear_inode(inode);
 
@@ -239,6 +276,7 @@ static void binderfs_evict_inode(struct inode *inode)
                return;
 
        mutex_lock(&binderfs_minors_mutex);
+       --info->device_count;
        ida_free(&binderfs_minors, device->miscdev.minor);
        mutex_unlock(&binderfs_minors_mutex);
 
@@ -246,43 +284,87 @@ static void binderfs_evict_inode(struct inode *inode)
        kfree(device);
 }
 
+/**
+ * binderfs_parse_mount_opts - parse binderfs mount options
+ * @data: options to set (can be NULL in which case defaults are used)
+ */
+static int binderfs_parse_mount_opts(char *data,
+                                    struct binderfs_mount_opts *opts)
+{
+       char *p;
+       opts->max = BINDERFS_MAX_MINOR;
+
+       while ((p = strsep(&data, ",")) != NULL) {
+               substring_t args[MAX_OPT_ARGS];
+               int token;
+               int max_devices;
+
+               if (!*p)
+                       continue;
+
+               token = match_token(p, tokens, args);
+               switch (token) {
+               case Opt_max:
+                       if (match_int(&args[0], &max_devices) ||
+                           (max_devices < 0 ||
+                            (max_devices > BINDERFS_MAX_MINOR)))
+                               return -EINVAL;
+
+                       opts->max = max_devices;
+                       break;
+               default:
+                       pr_err("Invalid mount options\n");
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static int binderfs_remount(struct super_block *sb, int *flags, char *data)
+{
+       struct binderfs_info *info = sb->s_fs_info;
+       return binderfs_parse_mount_opts(data, &info->mount_opts);
+}
+
+static int binderfs_show_mount_opts(struct seq_file *seq, struct dentry *root)
+{
+       struct binderfs_info *info;
+
+       info = root->d_sb->s_fs_info;
+       if (info->mount_opts.max <= BINDERFS_MAX_MINOR)
+               seq_printf(seq, ",max=%d", info->mount_opts.max);
+
+       return 0;
+}
+
 static const struct super_operations binderfs_super_ops = {
-       .statfs = simple_statfs,
-       .evict_inode = binderfs_evict_inode,
+       .evict_inode    = binderfs_evict_inode,
+       .remount_fs     = binderfs_remount,
+       .show_options   = binderfs_show_mount_opts,
+       .statfs         = simple_statfs,
 };
 
+static inline bool is_binderfs_control_device(const struct dentry *dentry)
+{
+       struct binderfs_info *info = dentry->d_sb->s_fs_info;
+       return info->control_dentry == dentry;
+}
+
 static int binderfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                           struct inode *new_dir, struct dentry *new_dentry,
                           unsigned int flags)
 {
-       struct inode *inode = d_inode(old_dentry);
-
-       /* binderfs doesn't support directories. */
-       if (d_is_dir(old_dentry))
+       if (is_binderfs_control_device(old_dentry) ||
+           is_binderfs_control_device(new_dentry))
                return -EPERM;
 
-       if (flags & ~RENAME_NOREPLACE)
-               return -EINVAL;
-
-       if (!simple_empty(new_dentry))
-               return -ENOTEMPTY;
-
-       if (d_really_is_positive(new_dentry))
-               simple_unlink(new_dir, new_dentry);
-
-       old_dir->i_ctime = old_dir->i_mtime = new_dir->i_ctime =
-               new_dir->i_mtime = inode->i_ctime = current_time(old_dir);
-
-       return 0;
+       return simple_rename(old_dir, old_dentry, new_dir, new_dentry, flags);
 }
 
 static int binderfs_unlink(struct inode *dir, struct dentry *dentry)
 {
-       /*
-        * The control dentry is only ever touched during mount so checking it
-        * here should not require us to take lock.
-        */
-       if (BINDERFS_I(dir)->control_dentry == dentry)
+       if (is_binderfs_control_device(dentry))
                return -EPERM;
 
        return simple_unlink(dir, dentry);
@@ -318,8 +400,6 @@ static int binderfs_binder_ctl_create(struct super_block *sb)
        if (!device)
                return -ENOMEM;
 
-       inode_lock(d_inode(root));
-
        /* If we have already created a binder-control node, return. */
        if (info->control_dentry) {
                ret = 0;
@@ -358,12 +438,10 @@ static int binderfs_binder_ctl_create(struct super_block *sb)
        inode->i_private = device;
        info->control_dentry = dentry;
        d_add(dentry, inode);
-       inode_unlock(d_inode(root));
 
        return 0;
 
 out:
-       inode_unlock(d_inode(root));
        kfree(device);
        iput(inode);
 
@@ -378,12 +456,9 @@ static const struct inode_operations binderfs_dir_inode_operations = {
 
 static int binderfs_fill_super(struct super_block *sb, void *data, int silent)
 {
+       int ret;
        struct binderfs_info *info;
-       int ret = -ENOMEM;
        struct inode *inode = NULL;
-       struct ipc_namespace *ipc_ns = sb->s_fs_info;
-
-       get_ipc_ns(ipc_ns);
 
        sb->s_blocksize = PAGE_SIZE;
        sb->s_blocksize_bits = PAGE_SHIFT;
@@ -405,11 +480,17 @@ static int binderfs_fill_super(struct super_block *sb, void *data, int silent)
        sb->s_op = &binderfs_super_ops;
        sb->s_time_gran = 1;
 
-       info = kzalloc(sizeof(struct binderfs_info), GFP_KERNEL);
-       if (!info)
-               goto err_without_dentry;
+       sb->s_fs_info = kzalloc(sizeof(struct binderfs_info), GFP_KERNEL);
+       if (!sb->s_fs_info)
+               return -ENOMEM;
+       info = sb->s_fs_info;
+
+       info->ipc_ns = get_ipc_ns(current->nsproxy->ipc_ns);
+
+       ret = binderfs_parse_mount_opts(data, &info->mount_opts);
+       if (ret)
+               return ret;
 
-       info->ipc_ns = ipc_ns;
        info->root_gid = make_kgid(sb->s_user_ns, 0);
        if (!gid_valid(info->root_gid))
                info->root_gid = GLOBAL_ROOT_GID;
@@ -417,11 +498,9 @@ static int binderfs_fill_super(struct super_block *sb, void *data, int silent)
        if (!uid_valid(info->root_uid))
                info->root_uid = GLOBAL_ROOT_UID;
 
-       sb->s_fs_info = info;
-
        inode = new_inode(sb);
        if (!inode)
-               goto err_without_dentry;
+               return -ENOMEM;
 
        inode->i_ino = FIRST_INODE;
        inode->i_fop = &simple_dir_operations;
@@ -432,79 +511,28 @@ static int binderfs_fill_super(struct super_block *sb, void *data, int silent)
 
        sb->s_root = d_make_root(inode);
        if (!sb->s_root)
-               goto err_without_dentry;
-
-       ret = binderfs_binder_ctl_create(sb);
-       if (ret)
-               goto err_with_dentry;
-
-       return 0;
-
-err_with_dentry:
-       dput(sb->s_root);
-       sb->s_root = NULL;
-
-err_without_dentry:
-       put_ipc_ns(ipc_ns);
-       iput(inode);
-       kfree(info);
-
-       return ret;
-}
-
-static int binderfs_test_super(struct super_block *sb, void *data)
-{
-       struct binderfs_info *info = sb->s_fs_info;
-
-       if (info)
-               return info->ipc_ns == data;
-
-       return 0;
-}
+               return -ENOMEM;
 
-static int binderfs_set_super(struct super_block *sb, void *data)
-{
-       sb->s_fs_info = data;
-       return set_anon_super(sb, NULL);
+       return binderfs_binder_ctl_create(sb);
 }
 
 static struct dentry *binderfs_mount(struct file_system_type *fs_type,
                                     int flags, const char *dev_name,
                                     void *data)
 {
-       struct super_block *sb;
-       struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
-
-       if (!ns_capable(ipc_ns->user_ns, CAP_SYS_ADMIN))
-               return ERR_PTR(-EPERM);
-
-       sb = sget_userns(fs_type, binderfs_test_super, binderfs_set_super,
-                        flags, ipc_ns->user_ns, ipc_ns);
-       if (IS_ERR(sb))
-               return ERR_CAST(sb);
-
-       if (!sb->s_root) {
-               int ret = binderfs_fill_super(sb, data, flags & SB_SILENT ? 1 : 0);
-               if (ret) {
-                       deactivate_locked_super(sb);
-                       return ERR_PTR(ret);
-               }
-
-               sb->s_flags |= SB_ACTIVE;
-       }
-
-       return dget(sb->s_root);
+       return mount_nodev(fs_type, flags, data, binderfs_fill_super);
 }
 
 static void binderfs_kill_super(struct super_block *sb)
 {
        struct binderfs_info *info = sb->s_fs_info;
 
+       kill_litter_super(sb);
+
        if (info && info->ipc_ns)
                put_ipc_ns(info->ipc_ns);
 
        kfree(info);
-       kill_litter_super(sb);
 }
 
 static struct file_system_type binder_fs_type = {
@@ -530,14 +558,6 @@ static int __init init_binderfs(void)
                return ret;
        }
 
-       binderfs_mnt = kern_mount(&binder_fs_type);
-       if (IS_ERR(binderfs_mnt)) {
-               ret = PTR_ERR(binderfs_mnt);
-               binderfs_mnt = NULL;
-               unregister_filesystem(&binder_fs_type);
-               unregister_chrdev_region(binderfs_dev, BINDERFS_MAX_MINOR);
-       }
-
        return ret;
 }
 
index 8cc9c429ad9589e54f06db537ff9688f94a28988..9e7fc302430ff2b43d86cf0dded1f81cb0576d88 100644 (file)
@@ -915,6 +915,10 @@ static struct scsi_host_template pata_macio_sht = {
        .sg_tablesize           = MAX_DCMDS,
        /* We may not need that strict one */
        .dma_boundary           = ATA_DMA_BOUNDARY,
+       /* Not sure what the real max is but we know it's less than 64K, let's
+        * use 64K minus 256
+        */
+       .max_segment_size       = MAX_DBDMA_SEG,
        .slave_configure        = pata_macio_slave_config,
 };
 
@@ -1044,11 +1048,6 @@ static int pata_macio_common_init(struct pata_macio_priv *priv,
        /* Make sure we have sane initial timings in the cache */
        pata_macio_default_timings(priv);
 
-       /* Not sure what the real max is but we know it's less than 64K, let's
-        * use 64K minus 256
-        */
-       dma_set_max_seg_size(priv->dev, MAX_DBDMA_SEG);
-
        /* Allocate libata host for 1 port */
        memset(&pinfo, 0, sizeof(struct ata_port_info));
        pmac_macio_calc_timing_masks(priv, &pinfo);
index e0bcf9b2dab040d7342c1eb4f4ead9abef550ba9..174e84ce437950702717bfbf6fc2cd6a734291b0 100644 (file)
@@ -245,8 +245,15 @@ struct inic_port_priv {
 
 static struct scsi_host_template inic_sht = {
        ATA_BASE_SHT(DRV_NAME),
-       .sg_tablesize   = LIBATA_MAX_PRD,       /* maybe it can be larger? */
-       .dma_boundary   = INIC_DMA_BOUNDARY,
+       .sg_tablesize           = LIBATA_MAX_PRD, /* maybe it can be larger? */
+
+       /*
+        * This controller is braindamaged.  dma_boundary is 0xffff like others
+        * but it will lock up the whole machine HARD if 65536 byte PRD entry
+        * is fed.  Reduce maximum segment size.
+        */
+       .dma_boundary           = INIC_DMA_BOUNDARY,
+       .max_segment_size       = 65536 - 512,
 };
 
 static const int scr_map[] = {
@@ -868,17 +875,6 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                return rc;
        }
 
-       /*
-        * This controller is braindamaged.  dma_boundary is 0xffff
-        * like others but it will lock up the whole machine HARD if
-        * 65536 byte PRD entry is fed. Reduce maximum segment size.
-        */
-       rc = dma_set_max_seg_size(&pdev->dev, 65536 - 512);
-       if (rc) {
-               dev_err(&pdev->dev, "failed to set the maximum segment size\n");
-               return rc;
-       }
-
        rc = init_controller(hpriv->mmio_base, hpriv->cached_hctl);
        if (rc) {
                dev_err(&pdev->dev, "failed to initialize controller\n");
index 457be03b744d276c9279b2a41686afdc49a05e20..0ea2139c50d875d0fdce8e9fb55374fd6bdc337b 100644 (file)
@@ -130,7 +130,7 @@ u64 pm_runtime_autosuspend_expiration(struct device *dev)
 {
        int autosuspend_delay;
        u64 last_busy, expires = 0;
-       u64 now = ktime_to_ns(ktime_get());
+       u64 now = ktime_get_mono_fast_ns();
 
        if (!dev->power.use_autosuspend)
                goto out;
@@ -909,7 +909,7 @@ static enum hrtimer_restart  pm_suspend_timer_fn(struct hrtimer *timer)
         * If 'expires' is after the current time, we've been called
         * too early.
         */
-       if (expires > 0 && expires < ktime_to_ns(ktime_get())) {
+       if (expires > 0 && expires < ktime_get_mono_fast_ns()) {
                dev->power.timer_expires = 0;
                rpm_suspend(dev, dev->power.timer_autosuspends ?
                    (RPM_ASYNC | RPM_AUTO) : RPM_ASYNC);
@@ -928,7 +928,7 @@ static enum hrtimer_restart  pm_suspend_timer_fn(struct hrtimer *timer)
 int pm_schedule_suspend(struct device *dev, unsigned int delay)
 {
        unsigned long flags;
-       ktime_t expires;
+       u64 expires;
        int retval;
 
        spin_lock_irqsave(&dev->power.lock, flags);
@@ -945,8 +945,8 @@ int pm_schedule_suspend(struct device *dev, unsigned int delay)
        /* Other scheduled or pending requests need to be canceled. */
        pm_runtime_cancel_pending(dev);
 
-       expires = ktime_add(ktime_get(), ms_to_ktime(delay));
-       dev->power.timer_expires = ktime_to_ns(expires);
+       expires = ktime_get_mono_fast_ns() + (u64)delay * NSEC_PER_MSEC;
+       dev->power.timer_expires = expires;
        dev->power.timer_autosuspends = 0;
        hrtimer_start(&dev->power.suspend_timer, expires, HRTIMER_MODE_ABS);
 
index a74ce885b54125b3852cd9f7de66ec5ee2a52ea3..c518659b4d9fe17a39edc9a53651198c08aa2b5f 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/moduleparam.h>
 #include <linux/workqueue.h>
 #include <linux/uuid.h>
+#include <linux/nospec.h>
 
 #define IPMI_DRIVER_VERSION "39.2"
 
@@ -62,7 +63,8 @@ static void ipmi_debug_msg(const char *title, unsigned char *data,
 { }
 #endif
 
-static int initialized;
+static bool initialized;
+static bool drvregistered;
 
 enum ipmi_panic_event_op {
        IPMI_SEND_PANIC_EVENT_NONE,
@@ -612,7 +614,7 @@ static DEFINE_MUTEX(ipmidriver_mutex);
 
 static LIST_HEAD(ipmi_interfaces);
 static DEFINE_MUTEX(ipmi_interfaces_mutex);
-DEFINE_STATIC_SRCU(ipmi_interfaces_srcu);
+struct srcu_struct ipmi_interfaces_srcu;
 
 /*
  * List of watchers that want to know when smi's are added and deleted.
@@ -720,7 +722,15 @@ struct watcher_entry {
 int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher)
 {
        struct ipmi_smi *intf;
-       int index;
+       int index, rv;
+
+       /*
+        * Make sure the driver is actually initialized, this handles
+        * problems with initialization order.
+        */
+       rv = ipmi_init_msghandler();
+       if (rv)
+               return rv;
 
        mutex_lock(&smi_watchers_mutex);
 
@@ -884,7 +894,7 @@ static int deliver_response(struct ipmi_smi *intf, struct ipmi_recv_msg *msg)
 
                if (user) {
                        user->handler->ipmi_recv_hndl(msg, user->handler_data);
-                       release_ipmi_user(msg->user, index);
+                       release_ipmi_user(user, index);
                } else {
                        /* User went away, give up. */
                        ipmi_free_recv_msg(msg);
@@ -1076,7 +1086,7 @@ int ipmi_create_user(unsigned int          if_num,
 {
        unsigned long flags;
        struct ipmi_user *new_user;
-       int           rv = 0, index;
+       int           rv, index;
        struct ipmi_smi *intf;
 
        /*
@@ -1094,18 +1104,9 @@ int ipmi_create_user(unsigned int          if_num,
         * Make sure the driver is actually initialized, this handles
         * problems with initialization order.
         */
-       if (!initialized) {
-               rv = ipmi_init_msghandler();
-               if (rv)
-                       return rv;
-
-               /*
-                * The init code doesn't return an error if it was turned
-                * off, but it won't initialize.  Check that.
-                */
-               if (!initialized)
-                       return -ENODEV;
-       }
+       rv = ipmi_init_msghandler();
+       if (rv)
+               return rv;
 
        new_user = kmalloc(sizeof(*new_user), GFP_KERNEL);
        if (!new_user)
@@ -1183,6 +1184,7 @@ EXPORT_SYMBOL(ipmi_get_smi_info);
 static void free_user(struct kref *ref)
 {
        struct ipmi_user *user = container_of(ref, struct ipmi_user, refcount);
+       cleanup_srcu_struct(&user->release_barrier);
        kfree(user);
 }
 
@@ -1259,7 +1261,6 @@ int ipmi_destroy_user(struct ipmi_user *user)
 {
        _ipmi_destroy_user(user);
 
-       cleanup_srcu_struct(&user->release_barrier);
        kref_put(&user->refcount, free_user);
 
        return 0;
@@ -1298,10 +1299,12 @@ int ipmi_set_my_address(struct ipmi_user *user,
        if (!user)
                return -ENODEV;
 
-       if (channel >= IPMI_MAX_CHANNELS)
+       if (channel >= IPMI_MAX_CHANNELS) {
                rv = -EINVAL;
-       else
+       } else {
+               channel = array_index_nospec(channel, IPMI_MAX_CHANNELS);
                user->intf->addrinfo[channel].address = address;
+       }
        release_ipmi_user(user, index);
 
        return rv;
@@ -1318,10 +1321,12 @@ int ipmi_get_my_address(struct ipmi_user *user,
        if (!user)
                return -ENODEV;
 
-       if (channel >= IPMI_MAX_CHANNELS)
+       if (channel >= IPMI_MAX_CHANNELS) {
                rv = -EINVAL;
-       else
+       } else {
+               channel = array_index_nospec(channel, IPMI_MAX_CHANNELS);
                *address = user->intf->addrinfo[channel].address;
+       }
        release_ipmi_user(user, index);
 
        return rv;
@@ -1338,10 +1343,12 @@ int ipmi_set_my_LUN(struct ipmi_user *user,
        if (!user)
                return -ENODEV;
 
-       if (channel >= IPMI_MAX_CHANNELS)
+       if (channel >= IPMI_MAX_CHANNELS) {
                rv = -EINVAL;
-       else
+       } else {
+               channel = array_index_nospec(channel, IPMI_MAX_CHANNELS);
                user->intf->addrinfo[channel].lun = LUN & 0x3;
+       }
        release_ipmi_user(user, index);
 
        return rv;
@@ -1358,10 +1365,12 @@ int ipmi_get_my_LUN(struct ipmi_user *user,
        if (!user)
                return -ENODEV;
 
-       if (channel >= IPMI_MAX_CHANNELS)
+       if (channel >= IPMI_MAX_CHANNELS) {
                rv = -EINVAL;
-       else
+       } else {
+               channel = array_index_nospec(channel, IPMI_MAX_CHANNELS);
                *address = user->intf->addrinfo[channel].lun;
+       }
        release_ipmi_user(user, index);
 
        return rv;
@@ -2184,6 +2193,7 @@ static int check_addr(struct ipmi_smi  *intf,
 {
        if (addr->channel >= IPMI_MAX_CHANNELS)
                return -EINVAL;
+       addr->channel = array_index_nospec(addr->channel, IPMI_MAX_CHANNELS);
        *lun = intf->addrinfo[addr->channel].lun;
        *saddr = intf->addrinfo[addr->channel].address;
        return 0;
@@ -3291,17 +3301,9 @@ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
         * Make sure the driver is actually initialized, this handles
         * problems with initialization order.
         */
-       if (!initialized) {
-               rv = ipmi_init_msghandler();
-               if (rv)
-                       return rv;
-               /*
-                * The init code doesn't return an error if it was turned
-                * off, but it won't initialize.  Check that.
-                */
-               if (!initialized)
-                       return -ENODEV;
-       }
+       rv = ipmi_init_msghandler();
+       if (rv)
+               return rv;
 
        intf = kzalloc(sizeof(*intf), GFP_KERNEL);
        if (!intf)
@@ -5017,6 +5019,22 @@ static int panic_event(struct notifier_block *this,
        return NOTIFY_DONE;
 }
 
+/* Must be called with ipmi_interfaces_mutex held. */
+static int ipmi_register_driver(void)
+{
+       int rv;
+
+       if (drvregistered)
+               return 0;
+
+       rv = driver_register(&ipmidriver.driver);
+       if (rv)
+               pr_err("Could not register IPMI driver\n");
+       else
+               drvregistered = true;
+       return rv;
+}
+
 static struct notifier_block panic_block = {
        .notifier_call  = panic_event,
        .next           = NULL,
@@ -5027,66 +5045,75 @@ static int ipmi_init_msghandler(void)
 {
        int rv;
 
+       mutex_lock(&ipmi_interfaces_mutex);
+       rv = ipmi_register_driver();
+       if (rv)
+               goto out;
        if (initialized)
-               return 0;
-
-       rv = driver_register(&ipmidriver.driver);
-       if (rv) {
-               pr_err("Could not register IPMI driver\n");
-               return rv;
-       }
+               goto out;
 
-       pr_info("version " IPMI_DRIVER_VERSION "\n");
+       init_srcu_struct(&ipmi_interfaces_srcu);
 
        timer_setup(&ipmi_timer, ipmi_timeout, 0);
        mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
 
        atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
 
-       initialized = 1;
+       initialized = true;
 
-       return 0;
+out:
+       mutex_unlock(&ipmi_interfaces_mutex);
+       return rv;
 }
 
 static int __init ipmi_init_msghandler_mod(void)
 {
-       ipmi_init_msghandler();
-       return 0;
+       int rv;
+
+       pr_info("version " IPMI_DRIVER_VERSION "\n");
+
+       mutex_lock(&ipmi_interfaces_mutex);
+       rv = ipmi_register_driver();
+       mutex_unlock(&ipmi_interfaces_mutex);
+
+       return rv;
 }
 
 static void __exit cleanup_ipmi(void)
 {
        int count;
 
-       if (!initialized)
-               return;
-
-       atomic_notifier_chain_unregister(&panic_notifier_list, &panic_block);
+       if (initialized) {
+               atomic_notifier_chain_unregister(&panic_notifier_list,
+                                                &panic_block);
 
-       /*
-        * This can't be called if any interfaces exist, so no worry
-        * about shutting down the interfaces.
-        */
+               /*
+                * This can't be called if any interfaces exist, so no worry
+                * about shutting down the interfaces.
+                */
 
-       /*
-        * Tell the timer to stop, then wait for it to stop.  This
-        * avoids problems with race conditions removing the timer
-        * here.
-        */
-       atomic_inc(&stop_operation);
-       del_timer_sync(&ipmi_timer);
+               /*
+                * Tell the timer to stop, then wait for it to stop.  This
+                * avoids problems with race conditions removing the timer
+                * here.
+                */
+               atomic_inc(&stop_operation);
+               del_timer_sync(&ipmi_timer);
 
-       driver_unregister(&ipmidriver.driver);
+               initialized = false;
 
-       initialized = 0;
+               /* Check for buffer leaks. */
+               count = atomic_read(&smi_msg_inuse_count);
+               if (count != 0)
+                       pr_warn("SMI message count %d at exit\n", count);
+               count = atomic_read(&recv_msg_inuse_count);
+               if (count != 0)
+                       pr_warn("recv message count %d at exit\n", count);
 
-       /* Check for buffer leaks. */
-       count = atomic_read(&smi_msg_inuse_count);
-       if (count != 0)
-               pr_warn("SMI message count %d at exit\n", count);
-       count = atomic_read(&recv_msg_inuse_count);
-       if (count != 0)
-               pr_warn("recv message count %d at exit\n", count);
+               cleanup_srcu_struct(&ipmi_interfaces_srcu);
+       }
+       if (drvregistered)
+               driver_unregister(&ipmidriver.driver);
 }
 module_exit(cleanup_ipmi);
 
index ca9528c4f183e7ea57cb71805b5a09aaf3bedd69..b7a1ae2afaeac7435410f6c100d7e9941f2cb486 100644 (file)
@@ -632,8 +632,9 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
 
                /* Remove the multi-part read marker. */
                len -= 2;
+               data += 2;
                for (i = 0; i < len; i++)
-                       ssif_info->data[i] = data[i+2];
+                       ssif_info->data[i] = data[i];
                ssif_info->multi_len = len;
                ssif_info->multi_pos = 1;
 
@@ -661,8 +662,19 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
                }
 
                blocknum = data[0];
+               len--;
+               data++;
+
+               if (blocknum != 0xff && len != 31) {
+                   /* All blocks but the last must have 31 data bytes. */
+                       result = -EIO;
+                       if (ssif_info->ssif_debug & SSIF_DEBUG_MSG)
+                               pr_info("Received middle message <31\n");
 
-               if (ssif_info->multi_len + len - 1 > IPMI_MAX_MSG_LENGTH) {
+                       goto continue_op;
+               }
+
+               if (ssif_info->multi_len + len > IPMI_MAX_MSG_LENGTH) {
                        /* Received message too big, abort the operation. */
                        result = -E2BIG;
                        if (ssif_info->ssif_debug & SSIF_DEBUG_MSG)
@@ -671,16 +683,14 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
                        goto continue_op;
                }
 
-               /* Remove the blocknum from the data. */
-               len--;
                for (i = 0; i < len; i++)
-                       ssif_info->data[i + ssif_info->multi_len] = data[i + 1];
+                       ssif_info->data[i + ssif_info->multi_len] = data[i];
                ssif_info->multi_len += len;
                if (blocknum == 0xff) {
                        /* End of read */
                        len = ssif_info->multi_len;
                        data = ssif_info->data;
-               } else if (blocknum + 1 != ssif_info->multi_pos) {
+               } else if (blocknum != ssif_info->multi_pos) {
                        /*
                         * Out of sequence block, just abort.  Block
                         * numbers start at zero for the second block,
@@ -707,6 +717,7 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
                }
        }
 
+ continue_op:
        if (result < 0) {
                ssif_inc_stat(ssif_info, receive_errors);
        } else {
@@ -714,8 +725,6 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
                ssif_inc_stat(ssif_info, received_message_parts);
        }
 
-
- continue_op:
        if (ssif_info->ssif_debug & SSIF_DEBUG_STATE)
                pr_info("DONE 1: state = %d, result=%d\n",
                        ssif_info->ssif_state, result);
index b5e3103c1175575a0e16d3f4168b4d343aca7b6f..e43c876a92232d9fc0e8a18269c5c4fd7342a3ff 100644 (file)
@@ -59,6 +59,7 @@
 #include <linux/mutex.h>
 #include <linux/delay.h>
 #include <linux/serial_8250.h>
+#include <linux/nospec.h>
 #include "smapi.h"
 #include "mwavedd.h"
 #include "3780i.h"
@@ -289,6 +290,8 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd,
                                                ipcnum);
                                return -EINVAL;
                        }
+                       ipcnum = array_index_nospec(ipcnum,
+                                                   ARRAY_SIZE(pDrvData->IPCs));
                        PRINTK_3(TRACE_MWAVE,
                                "mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC"
                                " ipcnum %x entry usIntCount %x\n",
@@ -317,6 +320,8 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd,
                                                " Invalid ipcnum %x\n", ipcnum);
                                return -EINVAL;
                        }
+                       ipcnum = array_index_nospec(ipcnum,
+                                                   ARRAY_SIZE(pDrvData->IPCs));
                        PRINTK_3(TRACE_MWAVE,
                                "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC"
                                " ipcnum %x, usIntCount %x\n",
@@ -383,6 +388,8 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd,
                                                ipcnum);
                                return -EINVAL;
                        }
+                       ipcnum = array_index_nospec(ipcnum,
+                                                   ARRAY_SIZE(pDrvData->IPCs));
                        mutex_lock(&mwave_mutex);
                        if (pDrvData->IPCs[ipcnum].bIsEnabled == true) {
                                pDrvData->IPCs[ipcnum].bIsEnabled = false;
index e5b2fe80eab432c699242cd3146e5c97e2928f7a..d2f0bb5ba47eabd3702a9c249f51f81f8d25a318 100644 (file)
@@ -293,7 +293,6 @@ config COMMON_CLK_BD718XX
 source "drivers/clk/actions/Kconfig"
 source "drivers/clk/bcm/Kconfig"
 source "drivers/clk/hisilicon/Kconfig"
-source "drivers/clk/imx/Kconfig"
 source "drivers/clk/imgtec/Kconfig"
 source "drivers/clk/imx/Kconfig"
 source "drivers/clk/ingenic/Kconfig"
index 5b393e711e94b28559a23b215810c5bdbf3d0666..7d16ab0784ecf4258963a2429ef6ea95e3ecc777 100644 (file)
@@ -262,8 +262,10 @@ static int vc5_mux_set_parent(struct clk_hw *hw, u8 index)
 
                if (vc5->clk_mux_ins == VC5_MUX_IN_XIN)
                        src = VC5_PRIM_SRC_SHDN_EN_XTAL;
-               if (vc5->clk_mux_ins == VC5_MUX_IN_CLKIN)
+               else if (vc5->clk_mux_ins == VC5_MUX_IN_CLKIN)
                        src = VC5_PRIM_SRC_SHDN_EN_CLKIN;
+               else /* Invalid; should have been caught by vc5_probe() */
+                       return -EINVAL;
        }
 
        return regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, mask, src);
index 75d13c0eff1243ebc29bbab45470e34f127e538c..d2477a5058ac2eb2d7925f04ae435479ff1efc9a 100644 (file)
@@ -1513,9 +1513,19 @@ static int clk_fetch_parent_index(struct clk_core *core,
        if (!parent)
                return -EINVAL;
 
-       for (i = 0; i < core->num_parents; i++)
-               if (clk_core_get_parent_by_index(core, i) == parent)
+       for (i = 0; i < core->num_parents; i++) {
+               if (core->parents[i] == parent)
+                       return i;
+
+               if (core->parents[i])
+                       continue;
+
+               /* Fallback to comparing globally unique names */
+               if (!strcmp(parent->name, core->parent_names[i])) {
+                       core->parents[i] = parent;
                        return i;
+               }
+       }
 
        return -EINVAL;
 }
@@ -2779,7 +2789,7 @@ static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
        seq_printf(s, "\"protect_count\": %d,", c->protect_count);
        seq_printf(s, "\"rate\": %lu,", clk_core_get_rate(c));
        seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy(c));
-       seq_printf(s, "\"phase\": %d", clk_core_get_phase(c));
+       seq_printf(s, "\"phase\": %d,", clk_core_get_phase(c));
        seq_printf(s, "\"duty_cycle\": %u",
                   clk_core_get_scaled_duty_cycle(c, 100000));
 }
index 0026c3969b1ec0ddb8aa77e9541905316901e2fe..76b9eb15604e1d241c0a91e7358de37e83a48a40 100644 (file)
@@ -155,13 +155,14 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 {
        struct clk_frac_pll *pll = to_clk_frac_pll(hw);
        u32 val, divfi, divff;
-       u64 temp64 = parent_rate;
+       u64 temp64;
        int ret;
 
        parent_rate *= 8;
        rate *= 2;
        divfi = rate / parent_rate;
-       temp64 *= rate - divfi;
+       temp64 = parent_rate * divfi;
+       temp64 = rate - temp64;
        temp64 *= PLL_FRAC_DENOM;
        do_div(temp64, parent_rate);
        divff = temp64;
index 99c2508de8e56777ea4ab6814470e7584fb3d700..fb6edf1b8aa2688bc1ce7e2e2555698d8c01a583 100644 (file)
@@ -169,6 +169,8 @@ static int imx8qxp_lpcg_clk_probe(struct platform_device *pdev)
                return -ENODEV;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -EINVAL;
        base = devm_ioremap(dev, res->start, resource_size(res));
        if (!base)
                return -ENOMEM;
index 61fefc046ec5ad8fd1de8df585e7c47d50be474b..d083b860f08333ad1caf8082664efdeaf1e0099d 100644 (file)
@@ -53,7 +53,6 @@
 #define APMU_DISP1     0x110
 #define APMU_CCIC0     0x50
 #define APMU_CCIC1     0xf4
-#define APMU_SP                0x68
 #define MPMU_UART_PLL  0x14
 
 struct mmp2_clk_unit {
@@ -210,8 +209,6 @@ static struct mmp_clk_mix_config ccic1_mix_config = {
        .reg_info = DEFINE_MIX_REG_INFO(4, 16, 2, 6, 32),
 };
 
-static DEFINE_SPINLOCK(sp_lock);
-
 static struct mmp_param_mux_clk apmu_mux_clks[] = {
        {MMP2_CLK_DISP0_MUX, "disp0_mux", disp_parent_names, ARRAY_SIZE(disp_parent_names), CLK_SET_RATE_PARENT, APMU_DISP0, 6, 2, 0, &disp0_lock},
        {MMP2_CLK_DISP1_MUX, "disp1_mux", disp_parent_names, ARRAY_SIZE(disp_parent_names), CLK_SET_RATE_PARENT, APMU_DISP1, 6, 2, 0, &disp1_lock},
@@ -242,7 +239,6 @@ static struct mmp_param_gate_clk apmu_gate_clks[] = {
        {MMP2_CLK_CCIC1, "ccic1_clk", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x1b, 0x1b, 0x0, 0, &ccic1_lock},
        {MMP2_CLK_CCIC1_PHY, "ccic1_phy_clk", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x24, 0x24, 0x0, 0, &ccic1_lock},
        {MMP2_CLK_CCIC1_SPHY, "ccic1_sphy_clk", "ccic1_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x300, 0x300, 0x0, 0, &ccic1_lock},
-       {MMP2_CLK_SP, "sp_clk", NULL, CLK_SET_RATE_PARENT, APMU_SP, 0x1b, 0x1b, 0x0, 0, &sp_lock},
 };
 
 static void mmp2_axi_periph_clk_init(struct mmp2_clk_unit *pxa_unit)
index 1b1ba54e33dde801bc380280507ec933f65cddea..1c04575c118f722c5d94ad28c281bdb1a76ec611 100644 (file)
@@ -215,6 +215,7 @@ config MSM_MMCC_8996
 
 config MSM_GCC_8998
        tristate "MSM8998 Global Clock Controller"
+       select QCOM_GDSC
        help
          Support for the global clock controller on msm8998 devices.
          Say Y if you want to use peripheral devices such as UART, SPI,
index c782e62dd98b8949e469cc3c0ca12eb288d0f58f..58fa5c247af10d52cc596616db835bcd7994942d 100644 (file)
@@ -115,8 +115,8 @@ static const char * const gcc_parent_names_6[] = {
        "core_bi_pll_test_se",
 };
 
-static const char * const gcc_parent_names_7[] = {
-       "bi_tcxo",
+static const char * const gcc_parent_names_7_ao[] = {
+       "bi_tcxo_ao",
        "gpll0",
        "gpll0_out_even",
        "core_bi_pll_test_se",
@@ -128,6 +128,12 @@ static const char * const gcc_parent_names_8[] = {
        "core_bi_pll_test_se",
 };
 
+static const char * const gcc_parent_names_8_ao[] = {
+       "bi_tcxo_ao",
+       "gpll0",
+       "core_bi_pll_test_se",
+};
+
 static const struct parent_map gcc_parent_map_10[] = {
        { P_BI_TCXO, 0 },
        { P_GPLL0_OUT_MAIN, 1 },
@@ -210,7 +216,7 @@ static struct clk_rcg2 gcc_cpuss_ahb_clk_src = {
        .freq_tbl = ftbl_gcc_cpuss_ahb_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gcc_cpuss_ahb_clk_src",
-               .parent_names = gcc_parent_names_7,
+               .parent_names = gcc_parent_names_7_ao,
                .num_parents = 4,
                .ops = &clk_rcg2_ops,
        },
@@ -229,7 +235,7 @@ static struct clk_rcg2 gcc_cpuss_rbcpr_clk_src = {
        .freq_tbl = ftbl_gcc_cpuss_rbcpr_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gcc_cpuss_rbcpr_clk_src",
-               .parent_names = gcc_parent_names_8,
+               .parent_names = gcc_parent_names_8_ao,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
index 2d5d8b43727e95a5bd8f9af70c4452fedc1c9c19..c4d0b6f6abf2e1bb1a6027cd19bf0c22dc1b5cfe 100644 (file)
@@ -43,7 +43,7 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hwclk,
        /* Read mdiv and fdiv from the fdbck register */
        reg = readl(socfpgaclk->hw.reg + 0x4);
        mdiv = (reg & SOCFPGA_PLL_MDIV_MASK) >> SOCFPGA_PLL_MDIV_SHIFT;
-       vco_freq = (unsigned long long)parent_rate * (mdiv + 6);
+       vco_freq = (unsigned long long)vco_freq * (mdiv + 6);
 
        return (unsigned long)vco_freq;
 }
index 5b238fc314ac65c83f6bbc44af222ad1f0037110..8281dfbf38c2f8c6e88db7489df6482b70f2a232 100644 (file)
 
 #include "stratix10-clk.h"
 
-static const char * const pll_mux[] = { "osc1", "cb_intosc_hs_div2_clk",
-                                       "f2s_free_clk",};
+static const char * const pll_mux[] = { "osc1", "cb-intosc-hs-div2-clk",
+                                       "f2s-free-clk",};
 static const char * const cntr_mux[] = { "main_pll", "periph_pll",
-                                        "osc1", "cb_intosc_hs_div2_clk",
-                                        "f2s_free_clk"};
-static const char * const boot_mux[] = { "osc1", "cb_intosc_hs_div2_clk",};
+                                        "osc1", "cb-intosc-hs-div2-clk",
+                                        "f2s-free-clk"};
+static const char * const boot_mux[] = { "osc1", "cb-intosc-hs-div2-clk",};
 
 static const char * const noc_free_mux[] = {"main_noc_base_clk",
                                            "peri_noc_base_clk",
-                                           "osc1", "cb_intosc_hs_div2_clk",
-                                           "f2s_free_clk"};
+                                           "osc1", "cb-intosc-hs-div2-clk",
+                                           "f2s-free-clk"};
 
 static const char * const emaca_free_mux[] = {"peri_emaca_clk", "boot_clk"};
 static const char * const emacb_free_mux[] = {"peri_emacb_clk", "boot_clk"};
@@ -33,14 +33,14 @@ static const char * const s2f_usr1_free_mux[] = {"peri_s2f_usr1_clk", "boot_clk"
 static const char * const psi_ref_free_mux[] = {"peri_psi_ref_clk", "boot_clk"};
 static const char * const mpu_mux[] = { "mpu_free_clk", "boot_clk",};
 
-static const char * const s2f_usr0_mux[] = {"f2s_free_clk", "boot_clk"};
+static const char * const s2f_usr0_mux[] = {"f2s-free-clk", "boot_clk"};
 static const char * const emac_mux[] = {"emaca_free_clk", "emacb_free_clk"};
 static const char * const noc_mux[] = {"noc_free_clk", "boot_clk"};
 
 static const char * const mpu_free_mux[] = {"main_mpu_base_clk",
                                            "peri_mpu_base_clk",
-                                           "osc1", "cb_intosc_hs_div2_clk",
-                                           "f2s_free_clk"};
+                                           "osc1", "cb-intosc-hs-div2-clk",
+                                           "f2s-free-clk"};
 
 /* clocks in AO (always on) controller */
 static const struct stratix10_pll_clock s10_pll_clks[] = {
index 269d3595758bebabf0f72d6448ba6633e9cd3c8f..edc31bb56674ad1ea425c93ab4ceb44bf183730b 100644 (file)
@@ -133,9 +133,11 @@ static int tegra124_dfll_fcpu_remove(struct platform_device *pdev)
        struct tegra_dfll_soc_data *soc;
 
        soc = tegra_dfll_unregister(pdev);
-       if (IS_ERR(soc))
+       if (IS_ERR(soc)) {
                dev_err(&pdev->dev, "failed to unregister DFLL: %ld\n",
                        PTR_ERR(soc));
+               return PTR_ERR(soc);
+       }
 
        tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq);
 
index 8d77090ad94aecd283ee085bb77a81491c9c6978..0241450f3eb3c8509e6a3bb5010c130d2e40a384 100644 (file)
@@ -403,8 +403,10 @@ int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div,
        num_dividers = i;
 
        tmp = kcalloc(valid_div + 1, sizeof(*tmp), GFP_KERNEL);
-       if (!tmp)
+       if (!tmp) {
+               *table = ERR_PTR(-ENOMEM);
                return -ENOMEM;
+       }
 
        valid_div = 0;
        *width = 0;
@@ -439,6 +441,7 @@ struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup)
 {
        struct clk_omap_divider *div;
        struct clk_omap_reg *reg;
+       int ret;
 
        if (!setup)
                return NULL;
@@ -458,6 +461,12 @@ struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup)
                div->flags |= CLK_DIVIDER_POWER_OF_TWO;
 
        div->table = _get_div_table_from_setup(setup, &div->width);
+       if (IS_ERR(div->table)) {
+               ret = PTR_ERR(div->table);
+               kfree(div);
+               return ERR_PTR(ret);
+       }
+
 
        div->shift = setup->bit_shift;
        div->latch = -EINVAL;
index f65cc0ff76abdb630b0694eb7c3babcc2c46ff71..b0908ec62f73b057828ec0965a80bd9582f8acb7 100644 (file)
@@ -669,8 +669,8 @@ static int zynqmp_clk_setup(struct device_node *np)
        if (ret)
                return ret;
 
-       zynqmp_data = kzalloc(sizeof(*zynqmp_data) + sizeof(*zynqmp_data) *
-                                               clock_max_idx, GFP_KERNEL);
+       zynqmp_data = kzalloc(struct_size(zynqmp_data, hws, clock_max_idx),
+                             GFP_KERNEL);
        if (!zynqmp_data)
                return -ENOMEM;
 
index b17d153e724fd3c693930ad67583e4804a8b580d..23a1b27579a54d5e35ea373421aec47597d9f241 100644 (file)
@@ -21,7 +21,7 @@ static int __cpuidle poll_idle(struct cpuidle_device *dev,
        local_irq_enable();
        if (!current_set_polling_and_test()) {
                unsigned int loop_count = 0;
-               u64 limit = TICK_USEC;
+               u64 limit = TICK_NSEC;
                int i;
 
                for (i = 1; i < drv->state_count; i++) {
index fe070d75c842695f3b9b1c9fff9c4e80955e1849..4c97478d44bd2a3dec901f96846eb9a944cb57d4 100644 (file)
@@ -537,6 +537,8 @@ static void process_response_list(struct nitrox_cmdq *cmdq)
        struct nitrox_device *ndev = cmdq->ndev;
        struct nitrox_softreq *sr;
        int req_completed = 0, err = 0, budget;
+       completion_t callback;
+       void *cb_arg;
 
        /* check all pending requests */
        budget = atomic_read(&cmdq->pending_count);
@@ -564,13 +566,13 @@ static void process_response_list(struct nitrox_cmdq *cmdq)
                smp_mb__after_atomic();
                /* remove from response list */
                response_list_del(sr, cmdq);
-
                /* ORH error code */
                err = READ_ONCE(*sr->resp.orh) & 0xff;
-
-               if (sr->callback)
-                       sr->callback(sr->cb_arg, err);
+               callback = sr->callback;
+               cb_arg = sr->cb_arg;
                softreq_destroy(sr);
+               if (callback)
+                       callback(cb_arg, err);
 
                req_completed++;
        }
index 4213cb0bb2a792cc6bdb2da5e2cc2ff621687654..f8664bac9fa82bae6d1bf7be616c3a3a83b562bb 100644 (file)
@@ -295,8 +295,8 @@ struct altr_sdram_mc_data {
 #define S10_SYSMGR_ECC_INTSTAT_DERR_OFST  0xA0
 
 /* Sticky registers for Uncorrected Errors */
-#define S10_SYSMGR_UE_VAL_OFST            0x120
-#define S10_SYSMGR_UE_ADDR_OFST           0x124
+#define S10_SYSMGR_UE_VAL_OFST            0x220
+#define S10_SYSMGR_UE_ADDR_OFST           0x224
 
 #define S10_DDR0_IRQ_MASK                 BIT(16)
 
index 09b845e901140b9e1bcb79e4a7e773337a07d85d..a785ffd5af891abe95938da021afb5358ec6d84b 100644 (file)
@@ -1144,10 +1144,6 @@ static int sbp2_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
        if (device->is_local)
                return -ENODEV;
 
-       if (dma_get_max_seg_size(device->card->device) > SBP2_MAX_SEG_SIZE)
-               WARN_ON(dma_set_max_seg_size(device->card->device,
-                                            SBP2_MAX_SEG_SIZE));
-
        shost = scsi_host_alloc(&scsi_driver_template, sizeof(*tgt));
        if (shost == NULL)
                return -ENOMEM;
@@ -1610,6 +1606,7 @@ static struct scsi_host_template scsi_driver_template = {
        .eh_abort_handler       = sbp2_scsi_abort,
        .this_id                = -1,
        .sg_tablesize           = SG_ALL,
+       .max_segment_size       = SBP2_MAX_SEG_SIZE,
        .can_queue              = 1,
        .sdev_attrs             = sbp2_scsi_sysfs_attrs,
 };
index 6b11f131424848b9cd911936f7a124e2edcf32ee..7f9e0304b5109a8b51fc108679cc32d4d8fbb9e8 100644 (file)
@@ -66,8 +66,10 @@ static int altr_a10sr_gpio_direction_input(struct gpio_chip *gc,
 static int altr_a10sr_gpio_direction_output(struct gpio_chip *gc,
                                            unsigned int nr, int value)
 {
-       if (nr <= (ALTR_A10SR_OUT_VALID_RANGE_HI - ALTR_A10SR_LED_VALID_SHIFT))
+       if (nr <= (ALTR_A10SR_OUT_VALID_RANGE_HI - ALTR_A10SR_LED_VALID_SHIFT)) {
+               altr_a10sr_gpio_set(gc, nr, value);
                return 0;
+       }
        return -EINVAL;
 }
 
index e0d6a0a7bc697d0de1e3f1b364a0dc4041ad9b2a..e41223c05f6e2fb9e8ff3492e875e62da72ab684 100644 (file)
@@ -180,7 +180,18 @@ static void sprd_eic_free(struct gpio_chip *chip, unsigned int offset)
 
 static int sprd_eic_get(struct gpio_chip *chip, unsigned int offset)
 {
-       return sprd_eic_read(chip, offset, SPRD_EIC_DBNC_DATA);
+       struct sprd_eic *sprd_eic = gpiochip_get_data(chip);
+
+       switch (sprd_eic->type) {
+       case SPRD_EIC_DEBOUNCE:
+               return sprd_eic_read(chip, offset, SPRD_EIC_DBNC_DATA);
+       case SPRD_EIC_ASYNC:
+               return sprd_eic_read(chip, offset, SPRD_EIC_ASYNC_DATA);
+       case SPRD_EIC_SYNC:
+               return sprd_eic_read(chip, offset, SPRD_EIC_SYNC_DATA);
+       default:
+               return -ENOTSUPP;
+       }
 }
 
 static int sprd_eic_direction_input(struct gpio_chip *chip, unsigned int offset)
@@ -368,6 +379,7 @@ static int sprd_eic_irq_set_type(struct irq_data *data, unsigned int flow_type)
                        irq_set_handler_locked(data, handle_edge_irq);
                        break;
                case IRQ_TYPE_EDGE_BOTH:
+                       sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0);
                        sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 1);
                        irq_set_handler_locked(data, handle_edge_irq);
                        break;
index adf72dda25a2b543e32e6e2aee1d2f4d1b82d352..68a35b65925aca762ca349f0f54704b306b72190 100644 (file)
@@ -84,6 +84,7 @@ MODULE_DEVICE_TABLE(of, pcf857x_of_table);
  */
 struct pcf857x {
        struct gpio_chip        chip;
+       struct irq_chip         irqchip;
        struct i2c_client       *client;
        struct mutex            lock;           /* protect 'out' */
        unsigned                out;            /* software latch */
@@ -252,18 +253,6 @@ static void pcf857x_irq_bus_sync_unlock(struct irq_data *data)
        mutex_unlock(&gpio->lock);
 }
 
-static struct irq_chip pcf857x_irq_chip = {
-       .name           = "pcf857x",
-       .irq_enable     = pcf857x_irq_enable,
-       .irq_disable    = pcf857x_irq_disable,
-       .irq_ack        = noop,
-       .irq_mask       = noop,
-       .irq_unmask     = noop,
-       .irq_set_wake   = pcf857x_irq_set_wake,
-       .irq_bus_lock           = pcf857x_irq_bus_lock,
-       .irq_bus_sync_unlock    = pcf857x_irq_bus_sync_unlock,
-};
-
 /*-------------------------------------------------------------------------*/
 
 static int pcf857x_probe(struct i2c_client *client,
@@ -376,8 +365,17 @@ static int pcf857x_probe(struct i2c_client *client,
 
        /* Enable irqchip if we have an interrupt */
        if (client->irq) {
+               gpio->irqchip.name = "pcf857x",
+               gpio->irqchip.irq_enable = pcf857x_irq_enable,
+               gpio->irqchip.irq_disable = pcf857x_irq_disable,
+               gpio->irqchip.irq_ack = noop,
+               gpio->irqchip.irq_mask = noop,
+               gpio->irqchip.irq_unmask = noop,
+               gpio->irqchip.irq_set_wake = pcf857x_irq_set_wake,
+               gpio->irqchip.irq_bus_lock = pcf857x_irq_bus_lock,
+               gpio->irqchip.irq_bus_sync_unlock = pcf857x_irq_bus_sync_unlock,
                status = gpiochip_irqchip_add_nested(&gpio->chip,
-                                                    &pcf857x_irq_chip,
+                                                    &gpio->irqchip,
                                                     0, handle_level_irq,
                                                     IRQ_TYPE_NONE);
                if (status) {
@@ -392,7 +390,7 @@ static int pcf857x_probe(struct i2c_client *client,
                if (status)
                        goto fail;
 
-               gpiochip_set_nested_irqchip(&gpio->chip, &pcf857x_irq_chip,
+               gpiochip_set_nested_irqchip(&gpio->chip, &gpio->irqchip,
                                            client->irq);
                gpio->irq_parent = client->irq;
        }
index 1b79ebcfce3e5c3e9d59d3586155642bf84ef6ad..541fa6ac399d24b288d7f148717874d2392e9023 100644 (file)
@@ -253,6 +253,7 @@ static int vf610_gpio_probe(struct platform_device *pdev)
        struct vf610_gpio_port *port;
        struct resource *iores;
        struct gpio_chip *gc;
+       int i;
        int ret;
 
        port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
@@ -319,6 +320,10 @@ static int vf610_gpio_probe(struct platform_device *pdev)
        if (ret < 0)
                return ret;
 
+       /* Mask all GPIO interrupts */
+       for (i = 0; i < gc->ngpio; i++)
+               vf610_gpio_writel(0, port->base + PORT_PCR(i));
+
        /* Clear the interrupt status register for all GPIO's */
        vf610_gpio_writel(~0, port->base + PORT_ISFR);
 
index 1651d7f0a303c3e7ea77f3924e83751dd9a41d47..d1adfdf50fb301b3f0be76af309963b955c31884 100644 (file)
@@ -828,7 +828,14 @@ static irqreturn_t lineevent_irq_thread(int irq, void *p)
        /* Do not leak kernel stack to userspace */
        memset(&ge, 0, sizeof(ge));
 
-       ge.timestamp = le->timestamp;
+       /*
+        * We may be running from a nested threaded interrupt in which case
+        * we didn't get the timestamp from lineevent_irq_handler().
+        */
+       if (!le->timestamp)
+               ge.timestamp = ktime_get_real_ns();
+       else
+               ge.timestamp = le->timestamp;
 
        if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE
            && le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) {
index a028661d9e2013dd2a6e5611448438c7590fec82..92b11de1958132c28e4ffd68e1fd782a8e2e5771 100644 (file)
@@ -576,6 +576,7 @@ static const struct amdgpu_px_quirk amdgpu_px_quirk_list[] = {
        { 0x1002, 0x6900, 0x1028, 0x0812, AMDGPU_PX_QUIRK_FORCE_ATPX },
        { 0x1002, 0x6900, 0x1028, 0x0813, AMDGPU_PX_QUIRK_FORCE_ATPX },
        { 0x1002, 0x6900, 0x1025, 0x125A, AMDGPU_PX_QUIRK_FORCE_ATPX },
+       { 0x1002, 0x6900, 0x17AA, 0x3806, AMDGPU_PX_QUIRK_FORCE_ATPX },
        { 0, 0, 0, 0, 0 },
 };
 
index b8747a5c9204d6341a92ab16e51091616f4715d6..99d596dc0e8976a78fee73261526001146490a76 100644 (file)
@@ -32,6 +32,7 @@
 #include "vega10_pptable.h"
 
 #define NUM_DSPCLK_LEVELS 8
+#define VEGA10_ENGINECLOCK_HARDMAX 198000
 
 static void set_hw_cap(struct pp_hwmgr *hwmgr, bool enable,
                enum phm_platform_caps cap)
@@ -258,7 +259,26 @@ static int init_over_drive_limits(
                struct pp_hwmgr *hwmgr,
                const ATOM_Vega10_POWERPLAYTABLE *powerplay_table)
 {
-       hwmgr->platform_descriptor.overdriveLimit.engineClock =
+       const ATOM_Vega10_GFXCLK_Dependency_Table *gfxclk_dep_table =
+                       (const ATOM_Vega10_GFXCLK_Dependency_Table *)
+                       (((unsigned long) powerplay_table) +
+                       le16_to_cpu(powerplay_table->usGfxclkDependencyTableOffset));
+       bool is_acg_enabled = false;
+       ATOM_Vega10_GFXCLK_Dependency_Record_V2 *patom_record_v2;
+
+       if (gfxclk_dep_table->ucRevId == 1) {
+               patom_record_v2 =
+                       (ATOM_Vega10_GFXCLK_Dependency_Record_V2 *)gfxclk_dep_table->entries;
+               is_acg_enabled =
+                       (bool)patom_record_v2[gfxclk_dep_table->ucNumEntries-1].ucACGEnable;
+       }
+
+       if (powerplay_table->ulMaxODEngineClock > VEGA10_ENGINECLOCK_HARDMAX &&
+               !is_acg_enabled)
+               hwmgr->platform_descriptor.overdriveLimit.engineClock =
+                       VEGA10_ENGINECLOCK_HARDMAX;
+       else
+               hwmgr->platform_descriptor.overdriveLimit.engineClock =
                        le32_to_cpu(powerplay_table->ulMaxODEngineClock);
        hwmgr->platform_descriptor.overdriveLimit.memoryClock =
                        le32_to_cpu(powerplay_table->ulMaxODMemoryClock);
index 5567ddc7760f031de674fc5016a17cbd96d3cac0..55bb7885e22880b258ab3b7a108b5b4b0ca1770f 100644 (file)
@@ -332,6 +332,9 @@ static void release_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
 
        i915_gem_object_unpin_map(wa_ctx->indirect_ctx.obj);
        i915_gem_object_put(wa_ctx->indirect_ctx.obj);
+
+       wa_ctx->indirect_ctx.obj = NULL;
+       wa_ctx->indirect_ctx.shadow_va = NULL;
 }
 
 static int set_context_ppgtt_from_shadow(struct intel_vgpu_workload *workload,
@@ -911,11 +914,6 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id)
 
        list_del_init(&workload->list);
 
-       if (!workload->status) {
-               release_shadow_batch_buffer(workload);
-               release_shadow_wa_ctx(&workload->wa_ctx);
-       }
-
        if (workload->status || (vgpu->resetting_eng & ENGINE_MASK(ring_id))) {
                /* if workload->status is not successful means HW GPU
                 * has occurred GPU hang or something wrong with i915/GVT,
@@ -1283,6 +1281,9 @@ void intel_vgpu_destroy_workload(struct intel_vgpu_workload *workload)
 {
        struct intel_vgpu_submission *s = &workload->vgpu->submission;
 
+       release_shadow_batch_buffer(workload);
+       release_shadow_wa_ctx(&workload->wa_ctx);
+
        if (workload->shadow_mm)
                intel_vgpu_mm_put(workload->shadow_mm);
 
index 4796f40a6d4f11a997083eaf0493725942eb3daa..eab9341a5152f90214427aa20cfc7b6414a94858 100644 (file)
@@ -303,6 +303,7 @@ static void __unwind_incomplete_requests(struct intel_engine_cs *engine)
         */
        if (!(prio & I915_PRIORITY_NEWCLIENT)) {
                prio |= I915_PRIORITY_NEWCLIENT;
+               active->sched.attr.priority = prio;
                list_move_tail(&active->sched.link,
                               i915_sched_lookup_priolist(engine, prio));
        }
@@ -645,6 +646,9 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
                int i;
 
                priolist_for_each_request_consume(rq, rn, p, i) {
+                       GEM_BUG_ON(last &&
+                                  need_preempt(engine, last, rq_prio(rq)));
+
                        /*
                         * Can we combine this request with the current port?
                         * It has to be the same context/ringbuffer and not
index 5beb83d1cf87769948575b74957777ce0e5b5d6e..ce1b3cc4bf6d5aea13aa213eccbeea37719f166c 100644 (file)
@@ -944,7 +944,7 @@ static u32 a6xx_gmu_get_arc_level(struct device *dev, unsigned long freq)
        np = dev_pm_opp_get_of_node(opp);
 
        if (np) {
-               of_property_read_u32(np, "qcom,level", &val);
+               of_property_read_u32(np, "opp-level", &val);
                of_node_put(np);
        }
 
index 2e4372ef17a34fd2fc3028c6f8a543477ce54247..2cfee1a4fe0b871ee4cd241ad2b874bc39bd1f94 100644 (file)
@@ -765,7 +765,6 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
        adreno_gpu->rev = config->rev;
 
        adreno_gpu_config.ioname = "kgsl_3d0_reg_memory";
-       adreno_gpu_config.irqname = "kgsl_3d0_irq";
 
        adreno_gpu_config.va_start = SZ_16M;
        adreno_gpu_config.va_end = 0xffffffff;
index fd75870eb17f7c7d5e8f8446f526b19715042b03..6aefcd6db46b4d36295f66bae809d99acc2ada85 100644 (file)
@@ -365,19 +365,6 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
                        &pdpu->pipe_qos_cfg);
 }
 
-static void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable)
-{
-       struct dpu_plane *pdpu = to_dpu_plane(plane);
-       struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
-
-       if (!pdpu->is_rt_pipe)
-               return;
-
-       pm_runtime_get_sync(&dpu_kms->pdev->dev);
-       _dpu_plane_set_qos_ctrl(plane, enable, DPU_PLANE_QOS_PANIC_CTRL);
-       pm_runtime_put_sync(&dpu_kms->pdev->dev);
-}
-
 /**
  * _dpu_plane_set_ot_limit - set OT limit for the given plane
  * @plane:             Pointer to drm plane
@@ -1248,6 +1235,19 @@ static void dpu_plane_reset(struct drm_plane *plane)
 }
 
 #ifdef CONFIG_DEBUG_FS
+static void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable)
+{
+       struct dpu_plane *pdpu = to_dpu_plane(plane);
+       struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
+
+       if (!pdpu->is_rt_pipe)
+               return;
+
+       pm_runtime_get_sync(&dpu_kms->pdev->dev);
+       _dpu_plane_set_qos_ctrl(plane, enable, DPU_PLANE_QOS_PANIC_CTRL);
+       pm_runtime_put_sync(&dpu_kms->pdev->dev);
+}
+
 static ssize_t _dpu_plane_danger_read(struct file *file,
                        char __user *buff, size_t count, loff_t *ppos)
 {
index 9cd6a96c6bf2a522d413681f20d918753921f554..927e5d86f7c17a77eca29c8836d87efeefd984b7 100644 (file)
@@ -250,7 +250,8 @@ void msm_gem_purge_vma(struct msm_gem_address_space *aspace,
 void msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
                struct msm_gem_vma *vma);
 int msm_gem_map_vma(struct msm_gem_address_space *aspace,
-               struct msm_gem_vma *vma, struct sg_table *sgt, int npages);
+               struct msm_gem_vma *vma, int prot,
+               struct sg_table *sgt, int npages);
 void msm_gem_close_vma(struct msm_gem_address_space *aspace,
                struct msm_gem_vma *vma);
 
@@ -333,6 +334,7 @@ void msm_gem_kernel_put(struct drm_gem_object *bo,
 struct drm_gem_object *msm_gem_import(struct drm_device *dev,
                struct dma_buf *dmabuf, struct sg_table *sgt);
 
+__printf(2, 3)
 void msm_gem_object_set_name(struct drm_gem_object *bo, const char *fmt, ...);
 
 int msm_framebuffer_prepare(struct drm_framebuffer *fb,
@@ -396,12 +398,14 @@ void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m);
 int msm_debugfs_late_init(struct drm_device *dev);
 int msm_rd_debugfs_init(struct drm_minor *minor);
 void msm_rd_debugfs_cleanup(struct msm_drm_private *priv);
+__printf(3, 4)
 void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit,
                const char *fmt, ...);
 int msm_perf_debugfs_init(struct drm_minor *minor);
 void msm_perf_debugfs_cleanup(struct msm_drm_private *priv);
 #else
 static inline int msm_debugfs_late_init(struct drm_device *dev) { return 0; }
+__printf(3, 4)
 static inline void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit,
                const char *fmt, ...) {}
 static inline void msm_rd_debugfs_cleanup(struct msm_drm_private *priv) {}
index 51a95da694d8d498dee29bd91ddb880b3478c356..c8886d3071fa35756682d9a27662b61074c27713 100644 (file)
@@ -391,6 +391,10 @@ static int msm_gem_pin_iova(struct drm_gem_object *obj,
        struct msm_gem_object *msm_obj = to_msm_bo(obj);
        struct msm_gem_vma *vma;
        struct page **pages;
+       int prot = IOMMU_READ;
+
+       if (!(msm_obj->flags & MSM_BO_GPU_READONLY))
+               prot |= IOMMU_WRITE;
 
        WARN_ON(!mutex_is_locked(&msm_obj->lock));
 
@@ -405,8 +409,8 @@ static int msm_gem_pin_iova(struct drm_gem_object *obj,
        if (IS_ERR(pages))
                return PTR_ERR(pages);
 
-       return msm_gem_map_vma(aspace, vma, msm_obj->sgt,
-                       obj->size >> PAGE_SHIFT);
+       return msm_gem_map_vma(aspace, vma, prot,
+                       msm_obj->sgt, obj->size >> PAGE_SHIFT);
 }
 
 /* get iova and pin it. Should have a matching put */
index 557360788084eb3db21e0c964722a0ce1923f92b..49c04829cf34412ae0b07f6358f596e3b11eae58 100644 (file)
@@ -68,7 +68,8 @@ void msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
 
 int
 msm_gem_map_vma(struct msm_gem_address_space *aspace,
-               struct msm_gem_vma *vma, struct sg_table *sgt, int npages)
+               struct msm_gem_vma *vma, int prot,
+               struct sg_table *sgt, int npages)
 {
        unsigned size = npages << PAGE_SHIFT;
        int ret = 0;
@@ -86,7 +87,7 @@ msm_gem_map_vma(struct msm_gem_address_space *aspace,
 
        if (aspace->mmu)
                ret = aspace->mmu->funcs->map(aspace->mmu, vma->iova, sgt,
-                               size, IOMMU_READ | IOMMU_WRITE);
+                               size, prot);
 
        if (ret)
                vma->mapped = false;
index 5f3eff3043554491eca50a559599b0e5293e1357..10babd18e28605b1c76faf55c51748c5e85504f1 100644 (file)
@@ -900,7 +900,7 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
        }
 
        /* Get Interrupt: */
-       gpu->irq = platform_get_irq_byname(pdev, config->irqname);
+       gpu->irq = platform_get_irq(pdev, 0);
        if (gpu->irq < 0) {
                ret = gpu->irq;
                DRM_DEV_ERROR(drm->dev, "failed to get irq: %d\n", ret);
index efb49bb64191732a0a8ee683e1f9790389295fa9..ca17086f72c923352328674a9aa50da5c71a6ff1 100644 (file)
@@ -31,7 +31,6 @@ struct msm_gpu_state;
 
 struct msm_gpu_config {
        const char *ioname;
-       const char *irqname;
        uint64_t va_start;
        uint64_t va_end;
        unsigned int nr_rings;
@@ -63,7 +62,7 @@ struct msm_gpu_funcs {
        struct msm_ringbuffer *(*active_ring)(struct msm_gpu *gpu);
        void (*recover)(struct msm_gpu *gpu);
        void (*destroy)(struct msm_gpu *gpu);
-#ifdef CONFIG_DEBUG_FS
+#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
        /* show GPU status in debugfs: */
        void (*show)(struct msm_gpu *gpu, struct msm_gpu_state *state,
                        struct drm_printer *p);
index 90e9d0a48dc0409feca3c8feab838fa83aeed946..d21172933d92804f7847b9a1b4d1ec14001c8570 100644 (file)
@@ -115,7 +115,9 @@ static void rd_write(struct msm_rd_state *rd, const void *buf, int sz)
                char *fptr = &fifo->buf[fifo->head];
                int n;
 
-               wait_event(rd->fifo_event, circ_space(&rd->fifo) > 0);
+               wait_event(rd->fifo_event, circ_space(&rd->fifo) > 0 || !rd->open);
+               if (!rd->open)
+                       return;
 
                /* Note that smp_load_acquire() is not strictly required
                 * as CIRC_SPACE_TO_END() does not access the tail more
@@ -213,7 +215,10 @@ out:
 static int rd_release(struct inode *inode, struct file *file)
 {
        struct msm_rd_state *rd = inode->i_private;
+
        rd->open = false;
+       wake_up_all(&rd->fifo_event);
+
        return 0;
 }
 
index 061d2e0d9011ee88991b3f0fb1b4e2dd54925bee..416da53767018ca9acbcef98689c173af0732fca 100644 (file)
@@ -92,6 +92,8 @@ static void sun4i_hdmi_disable(struct drm_encoder *encoder)
        val = readl(hdmi->base + SUN4I_HDMI_VID_CTRL_REG);
        val &= ~SUN4I_HDMI_VID_CTRL_ENABLE;
        writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG);
+
+       clk_disable_unprepare(hdmi->tmds_clk);
 }
 
 static void sun4i_hdmi_enable(struct drm_encoder *encoder)
@@ -102,6 +104,8 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder)
 
        DRM_DEBUG_DRIVER("Enabling the HDMI Output\n");
 
+       clk_prepare_enable(hdmi->tmds_clk);
+
        sun4i_hdmi_setup_avi_infoframes(hdmi, mode);
        val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI);
        val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END);
index f41d5fe51abe3b812b600c7fa79d789f350ef3ce..9993b692598fb84d1700e26ef7f97856ff842955 100644 (file)
@@ -125,6 +125,7 @@ static int open_collection(struct hid_parser *parser, unsigned type)
 {
        struct hid_collection *collection;
        unsigned usage;
+       int collection_index;
 
        usage = parser->local.usage[0];
 
@@ -167,13 +168,13 @@ static int open_collection(struct hid_parser *parser, unsigned type)
        parser->collection_stack[parser->collection_stack_ptr++] =
                parser->device->maxcollection;
 
-       collection = parser->device->collection +
-               parser->device->maxcollection++;
+       collection_index = parser->device->maxcollection++;
+       collection = parser->device->collection + collection_index;
        collection->type = type;
        collection->usage = usage;
        collection->level = parser->collection_stack_ptr - 1;
-       collection->parent = parser->active_collection;
-       parser->active_collection = collection;
+       collection->parent_idx = (collection->level == 0) ? -1 :
+               parser->collection_stack[collection->level - 1];
 
        if (type == HID_COLLECTION_APPLICATION)
                parser->device->maxapplication++;
@@ -192,8 +193,6 @@ static int close_collection(struct hid_parser *parser)
                return -EINVAL;
        }
        parser->collection_stack_ptr--;
-       if (parser->active_collection)
-               parser->active_collection = parser->active_collection->parent;
        return 0;
 }
 
@@ -1006,10 +1005,12 @@ static void hid_apply_multiplier_to_field(struct hid_device *hid,
                usage = &field->usage[i];
 
                collection = &hid->collection[usage->collection_index];
-               while (collection && collection != multiplier_collection)
-                       collection = collection->parent;
+               while (collection->parent_idx != -1 &&
+                      collection != multiplier_collection)
+                       collection = &hid->collection[collection->parent_idx];
 
-               if (collection || multiplier_collection == NULL)
+               if (collection->parent_idx != -1 ||
+                   multiplier_collection == NULL)
                        usage->resolution_multiplier = effective_multiplier;
 
        }
@@ -1044,9 +1045,9 @@ static void hid_apply_multiplier(struct hid_device *hid,
         * applicable fields later.
         */
        multiplier_collection = &hid->collection[multiplier->usage->collection_index];
-       while (multiplier_collection &&
+       while (multiplier_collection->parent_idx != -1 &&
               multiplier_collection->type != HID_COLLECTION_LOGICAL)
-               multiplier_collection = multiplier_collection->parent;
+               multiplier_collection = &hid->collection[multiplier_collection->parent_idx];
 
        effective_multiplier = hid_calculate_multiplier(hid, multiplier);
 
index 518fa76414f560f8e76d88a2079310cc8b8c4936..24f846d67478cec0d71501569cef2ea5f706cbab 100644 (file)
 #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_010A 0x010a
 #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100 0xe100
 
+#define I2C_VENDOR_ID_GOODIX           0x27c6
+#define I2C_DEVICE_ID_GOODIX_01F0      0x01f0
+
 #define USB_VENDOR_ID_GOODTOUCH                0x1aad
 #define USB_DEVICE_ID_GOODTOUCH_000f   0x000f
 
index 8555ce7e737b37a78160d930a9ba12ed311e001b..c5edfa966343dc098c63af7d4513ffeed02348de 100644 (file)
@@ -179,6 +179,8 @@ static const struct i2c_hid_quirks {
                I2C_HID_QUIRK_DELAY_AFTER_SLEEP },
        { USB_VENDOR_ID_LG, I2C_DEVICE_ID_LG_8001,
                I2C_HID_QUIRK_NO_RUNTIME_PM },
+       { I2C_VENDOR_ID_GOODIX, I2C_DEVICE_ID_GOODIX_01F0,
+               I2C_HID_QUIRK_NO_RUNTIME_PM },
        { 0, 0 }
 };
 
index ce0ba20627236dde727d2f6fd486a1b8d281d327..bea4c9850247bcdbdc9a4668719e2f6fa8ad4fe2 100644 (file)
@@ -701,19 +701,12 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
 int vmbus_disconnect_ring(struct vmbus_channel *channel)
 {
        struct vmbus_channel *cur_channel, *tmp;
-       unsigned long flags;
-       LIST_HEAD(list);
        int ret;
 
        if (channel->primary_channel != NULL)
                return -EINVAL;
 
-       /* Snapshot the list of subchannels */
-       spin_lock_irqsave(&channel->lock, flags);
-       list_splice_init(&channel->sc_list, &list);
-       spin_unlock_irqrestore(&channel->lock, flags);
-
-       list_for_each_entry_safe(cur_channel, tmp, &list, sc_list) {
+       list_for_each_entry_safe(cur_channel, tmp, &channel->sc_list, sc_list) {
                if (cur_channel->rescind)
                        wait_for_completion(&cur_channel->rescind_event);
 
index 5301fef16c31b740fab409ced2f3e7ef6c5bbe23..7c6349a50ef173421cdafea3b289ae9868da711e 100644 (file)
@@ -888,12 +888,14 @@ static unsigned long handle_pg_range(unsigned long pg_start,
                        pfn_cnt -= pgs_ol;
                        /*
                         * Check if the corresponding memory block is already
-                        * online by checking its last previously backed page.
-                        * In case it is we need to bring rest (which was not
-                        * backed previously) online too.
+                        * online. It is possible to observe struct pages still
+                        * being uninitialized here so check section instead.
+                        * In case the section is online we need to bring the
+                        * rest of pfns (which were not backed previously)
+                        * online too.
                         */
                        if (start_pfn > has->start_pfn &&
-                           !PageReserved(pfn_to_page(start_pfn - 1)))
+                           online_section_nr(pfn_to_section_nr(start_pfn)))
                                hv_bring_pgs_online(has, start_pfn, pgs_ol);
 
                }
index 64d0c85d51611199f9bd98e97efe0b54d992df5f..1f1a55e077338cabf233bba7630d805f84fd96f6 100644 (file)
@@ -164,26 +164,25 @@ hv_get_ringbuffer_availbytes(const struct hv_ring_buffer_info *rbi,
 }
 
 /* Get various debug metrics for the specified ring buffer. */
-void hv_ringbuffer_get_debuginfo(const struct hv_ring_buffer_info *ring_info,
-                                struct hv_ring_buffer_debug_info *debug_info)
+int hv_ringbuffer_get_debuginfo(const struct hv_ring_buffer_info *ring_info,
+                               struct hv_ring_buffer_debug_info *debug_info)
 {
        u32 bytes_avail_towrite;
        u32 bytes_avail_toread;
 
-       if (ring_info->ring_buffer) {
-               hv_get_ringbuffer_availbytes(ring_info,
-                                       &bytes_avail_toread,
-                                       &bytes_avail_towrite);
-
-               debug_info->bytes_avail_toread = bytes_avail_toread;
-               debug_info->bytes_avail_towrite = bytes_avail_towrite;
-               debug_info->current_read_index =
-                       ring_info->ring_buffer->read_index;
-               debug_info->current_write_index =
-                       ring_info->ring_buffer->write_index;
-               debug_info->current_interrupt_mask =
-                       ring_info->ring_buffer->interrupt_mask;
-       }
+       if (!ring_info->ring_buffer)
+               return -EINVAL;
+
+       hv_get_ringbuffer_availbytes(ring_info,
+                                    &bytes_avail_toread,
+                                    &bytes_avail_towrite);
+       debug_info->bytes_avail_toread = bytes_avail_toread;
+       debug_info->bytes_avail_towrite = bytes_avail_towrite;
+       debug_info->current_read_index = ring_info->ring_buffer->read_index;
+       debug_info->current_write_index = ring_info->ring_buffer->write_index;
+       debug_info->current_interrupt_mask
+               = ring_info->ring_buffer->interrupt_mask;
+       return 0;
 }
 EXPORT_SYMBOL_GPL(hv_ringbuffer_get_debuginfo);
 
index d0ff65675292bd8b9ac7c6fa99d708e94484a62b..403fee01572c5c93cefadebf0895a7302f777325 100644 (file)
@@ -313,12 +313,16 @@ static ssize_t out_intr_mask_show(struct device *dev,
 {
        struct hv_device *hv_dev = device_to_hv_device(dev);
        struct hv_ring_buffer_debug_info outbound;
+       int ret;
 
        if (!hv_dev->channel)
                return -ENODEV;
-       if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
-               return -EINVAL;
-       hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
+
+       ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound,
+                                         &outbound);
+       if (ret < 0)
+               return ret;
+
        return sprintf(buf, "%d\n", outbound.current_interrupt_mask);
 }
 static DEVICE_ATTR_RO(out_intr_mask);
@@ -328,12 +332,15 @@ static ssize_t out_read_index_show(struct device *dev,
 {
        struct hv_device *hv_dev = device_to_hv_device(dev);
        struct hv_ring_buffer_debug_info outbound;
+       int ret;
 
        if (!hv_dev->channel)
                return -ENODEV;
-       if (hv_dev->channel->state != CHANNEL_OP