Merge tag 'fixes_for_v4.20-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 29 Nov 2018 17:56:00 +0000 (09:56 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 29 Nov 2018 17:56:00 +0000 (09:56 -0800)
Pull ext2 and udf fixes from Jan Kara:
 "Three small ext2 and udf fixes"

* tag 'fixes_for_v4.20-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
  ext2: fix potential use after free
  ext2: initialize opts.s_mount_opt as zero before using it
  udf: Allow mounting volumes with incorrect identification strings

371 files changed:
CREDITS
Documentation/admin-guide/kernel-parameters.txt
Documentation/admin-guide/security-bugs.rst
Documentation/core-api/xarray.rst
Documentation/devicetree/bindings/net/can/holt_hi311x.txt
Documentation/devicetree/bindings/net/can/rcar_can.txt
Documentation/devicetree/bindings/net/dsa/dsa.txt
Documentation/devicetree/bindings/spi/spi-uniphier.txt
Documentation/input/event-codes.rst
Documentation/media/uapi/v4l/dev-meta.rst
Documentation/media/uapi/v4l/vidioc-g-fmt.rst
Documentation/networking/rxrpc.txt
MAINTAINERS
Makefile
arch/arm64/include/asm/sysreg.h
arch/arm64/kernel/cpufeature.c
arch/arm64/net/bpf_jit_comp.c
arch/ia64/include/asm/numa.h
arch/ia64/kernel/acpi.c
arch/ia64/mm/numa.c
arch/mips/configs/cavium_octeon_defconfig
arch/mips/kernel/setup.c
arch/mips/kernel/traps.c
arch/mips/loongson64/loongson-3/numa.c
arch/mips/sgi-ip27/ip27-memory.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/net/bpf_jit_comp64.c
arch/riscv/Makefile
arch/riscv/boot/.gitignore [new file with mode: 0644]
arch/riscv/boot/Makefile [new file with mode: 0644]
arch/riscv/boot/install.sh [new file with mode: 0644]
arch/riscv/include/asm/module.h
arch/riscv/include/asm/uaccess.h
arch/riscv/include/asm/unistd.h
arch/riscv/include/uapi/asm/unistd.h [moved from arch/riscv/include/uapi/asm/syscalls.h with 53% similarity]
arch/riscv/kernel/cpu.c
arch/riscv/kernel/head.S
arch/riscv/kernel/vmlinux.lds.S
arch/sparc/net/bpf_jit_comp_64.c
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/lapic.c
arch/x86/kvm/mmu.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/xtensa/kernel/asm-offsets.c
arch/xtensa/kernel/process.c
arch/xtensa/kernel/ptrace.c
drivers/acpi/acpi_platform.c
drivers/atm/firestream.c
drivers/cpufreq/ti-cpufreq.c
drivers/dma-buf/udmabuf.c
drivers/gnss/serial.c
drivers/gnss/sirf.c
drivers/gpio/gpio-mockup.c
drivers/gpio/gpio-pxa.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
drivers/gpu/drm/amd/amdgpu/soc15.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
drivers/gpu/drm/ast/ast_drv.c
drivers/gpu/drm/ast/ast_mode.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/i915_gpu_error.c
drivers/gpu/drm/i915/i915_gpu_error.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/vc4/vc4_kms.c
drivers/gpu/drm/vc4/vc4_plane.c
drivers/hid/hid-ids.h
drivers/hid/hid-input.c
drivers/hid/hid-logitech-hidpp.c
drivers/hid/hid-multitouch.c
drivers/hid/hid-quirks.c
drivers/hid/hid-steam.c
drivers/hid/i2c-hid/i2c-hid-core.c
drivers/hid/uhid.c
drivers/hv/hv_kvp.c
drivers/hwmon/ina2xx.c
drivers/hwmon/mlxreg-fan.c
drivers/hwmon/raspberrypi-hwmon.c
drivers/hwmon/w83795.c
drivers/iommu/amd_iommu_init.c
drivers/iommu/intel-iommu.c
drivers/iommu/intel-svm.c
drivers/iommu/ipmmu-vmsa.c
drivers/media/cec/cec-adap.c
drivers/media/i2c/tc358743.c
drivers/media/pci/intel/ipu3/ipu3-cio2.c
drivers/media/platform/omap3isp/isp.c
drivers/media/platform/vicodec/vicodec-core.c
drivers/media/platform/vim2m.c
drivers/media/v4l2-core/v4l2-ctrls.c
drivers/media/v4l2-core/v4l2-event.c
drivers/media/v4l2-core/v4l2-mem2mem.c
drivers/misc/atmel-ssc.c
drivers/misc/sgi-gru/grukdump.c
drivers/mmc/host/sdhci-pci-core.c
drivers/mtd/nand/raw/atmel/nand-controller.c
drivers/mtd/nand/raw/qcom_nandc.c
drivers/mtd/spi-nor/cadence-quadspi.c
drivers/mtd/spi-nor/spi-nor.c
drivers/net/can/dev.c
drivers/net/can/flexcan.c
drivers/net/can/rcar/rcar_can.c
drivers/net/can/rx-offload.c
drivers/net/can/spi/hi311x.c
drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
drivers/net/can/usb/ucan.c
drivers/net/ethernet/amazon/ena/ena_netdev.c
drivers/net/ethernet/amazon/ena/ena_netdev.h
drivers/net/ethernet/amd/sunlance.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/cavium/thunder/nic_main.c
drivers/net/ethernet/cavium/thunder/nicvf_main.c
drivers/net/ethernet/cavium/thunder/nicvf_queues.c
drivers/net/ethernet/chelsio/Kconfig
drivers/net/ethernet/chelsio/cxgb4/Makefile
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
drivers/net/ethernet/cortina/gemini.c
drivers/net/ethernet/faraday/ftmac100.c
drivers/net/ethernet/hisilicon/hip04_eth.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/ibm/ibmvnic.h
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_xsk.c
drivers/net/ethernet/intel/igb/e1000_i210.c
drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
drivers/net/ethernet/lantiq_xrx200.c
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/mellanox/mlx4/alloc.c
drivers/net/ethernet/mellanox/mlx4/mlx4.h
drivers/net/ethernet/mellanox/mlx4/mr.c
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en/port.c
drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c
drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c
drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
drivers/net/ethernet/microchip/lan743x_main.c
drivers/net/ethernet/microchip/lan743x_main.h
drivers/net/ethernet/qlogic/qed/qed_dcbx.c
drivers/net/ethernet/qlogic/qed/qed_debug.c
drivers/net/ethernet/qlogic/qed/qed_dev.c
drivers/net/ethernet/qlogic/qed/qed_int.c
drivers/net/ethernet/qlogic/qed/qed_main.c
drivers/net/ethernet/qlogic/qed/qed_rdma.c
drivers/net/ethernet/qlogic/qed/qed_rdma.h
drivers/net/ethernet/via/via-velocity.c
drivers/net/phy/mdio-gpio.c
drivers/net/phy/mscc.c
drivers/net/phy/phy_device.c
drivers/net/rionet.c
drivers/net/team/team.c
drivers/net/tun.c
drivers/net/usb/ipheth.c
drivers/net/virtio_net.c
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c
drivers/net/wireless/intel/iwlwifi/fw/acpi.h
drivers/net/wireless/intel/iwlwifi/fw/runtime.h
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
drivers/net/wireless/intel/iwlwifi/mvm/ops.c
drivers/net/wireless/mediatek/mt76/Kconfig
drivers/net/wireless/mediatek/mt76/mac80211.c
drivers/net/wireless/mediatek/mt76/mt76x02.h
drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
drivers/net/wireless/ti/wlcore/sdio.c
drivers/nvme/host/fc.c
drivers/nvmem/core.c
drivers/opp/ti-opp-supply.c
drivers/s390/net/ism_drv.c
drivers/s390/net/qeth_core_main.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/ufs/ufs-hisi.c
drivers/scsi/ufs/ufs_quirks.h
drivers/scsi/ufs/ufshcd.c
drivers/slimbus/qcom-ngd-ctrl.c
drivers/slimbus/slimbus.h
drivers/spi/spi-mt65xx.c
drivers/spi/spi-omap2-mcspi.c
drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
drivers/staging/media/sunxi/cedrus/cedrus.c
drivers/uio/uio.c
drivers/usb/class/cdc-acm.c
drivers/usb/core/hub.c
drivers/usb/core/quirks.c
drivers/usb/dwc2/pci.c
drivers/usb/dwc3/core.c
drivers/usb/dwc3/dwc3-pci.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/function/f_fs.c
drivers/usb/host/xhci-histb.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-mtk.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-plat.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci-tegra.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/misc/appledisplay.c
fs/afs/rxrpc.c
fs/btrfs/disk-io.c
fs/btrfs/file.c
fs/btrfs/qgroup.c
fs/btrfs/relocation.c
fs/btrfs/send.c
fs/btrfs/super.c
fs/dax.c
fs/exec.c
fs/iomap.c
fs/nfs/callback_proc.c
fs/nfs/flexfilelayout/flexfilelayout.c
fs/nfs/flexfilelayout/flexfilelayout.h
fs/nfs/flexfilelayout/flexfilelayoutdev.c
fs/nfs/nfs42proc.c
fs/nfs/nfs4_fs.h
fs/nfs/nfs4state.c
fs/nilfs2/btnode.c
fs/read_write.c
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/libxfs/xfs_ialloc_btree.c
fs/xfs/xfs_bmap_util.c
fs/xfs/xfs_bmap_util.h
fs/xfs/xfs_buf_item.c
fs/xfs/xfs_file.c
fs/xfs/xfs_reflink.c
fs/xfs/xfs_trace.h
include/linux/can/dev.h
include/linux/can/rx-offload.h
include/linux/dma-direct.h
include/linux/filter.h
include/linux/hid.h
include/linux/net_dim.h
include/linux/netfilter/nf_conntrack_proto_gre.h
include/linux/skbuff.h
include/linux/tcp.h
include/linux/usb/quirks.h
include/linux/xarray.h
include/media/v4l2-mem2mem.h
include/net/af_rxrpc.h
include/net/netfilter/ipv4/nf_nat_masquerade.h
include/net/netfilter/ipv6/nf_nat_masquerade.h
include/net/sctp/sctp.h
include/trace/events/rxrpc.h
include/uapi/linux/input-event-codes.h
include/uapi/linux/v4l2-controls.h
kernel/bpf/core.c
kernel/bpf/local_storage.c
kernel/bpf/queue_stack_maps.c
kernel/bpf/verifier.c
kernel/dma/swiotlb.c
kernel/trace/bpf_trace.c
lib/test_firmware.c
lib/test_xarray.c
lib/xarray.c
net/batman-adv/bat_v_elp.c
net/batman-adv/fragmentation.c
net/bridge/br_private.h
net/bridge/br_vlan.c
net/can/raw.c
net/ceph/messenger.c
net/core/dev.c
net/core/filter.c
net/core/skbuff.c
net/ipv4/ip_output.c
net/ipv4/ip_tunnel_core.c
net/ipv4/netfilter/ipt_MASQUERADE.c
net/ipv4/netfilter/nf_nat_masquerade_ipv4.c
net/ipv4/netfilter/nft_masq_ipv4.c
net/ipv4/tcp_input.c
net/ipv4/tcp_output.c
net/ipv4/tcp_timer.c
net/ipv6/addrconf.c
net/ipv6/ip6_output.c
net/ipv6/netfilter.c
net/ipv6/netfilter/ip6t_MASQUERADE.c
net/ipv6/netfilter/nf_nat_masquerade_ipv6.c
net/ipv6/netfilter/nft_masq_ipv6.c
net/ipv6/route.c
net/l2tp/l2tp_core.c
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/nf_conncount.c
net/netfilter/nf_conntrack_proto_gre.c
net/netfilter/nf_tables_api.c
net/netfilter/nfnetlink_cttimeout.c
net/netfilter/nft_compat.c
net/netfilter/nft_flow_offload.c
net/netfilter/xt_RATEEST.c
net/netfilter/xt_hashlimit.c
net/packet/af_packet.c
net/rxrpc/af_rxrpc.c
net/sched/act_pedit.c
net/sched/act_police.c
net/sched/sch_fq.c
net/sctp/output.c
net/sctp/socket.c
net/sctp/stream.c
net/smc/af_smc.c
net/smc/smc_cdc.c
net/smc/smc_cdc.h
net/smc/smc_core.c
net/smc/smc_core.h
net/smc/smc_ism.c
net/smc/smc_ism.h
net/smc/smc_wr.c
net/socket.c
net/tipc/discover.c
net/tipc/net.c
net/tipc/net.h
net/tipc/node.c
net/tipc/socket.c
sound/core/oss/pcm_oss.c
sound/core/oss/pcm_plugin.c
sound/pci/hda/patch_ca0132.c
sound/pci/hda/patch_realtek.c
tools/bpf/bpftool/Documentation/bpftool-cgroup.rst
tools/bpf/bpftool/Documentation/bpftool-map.rst
tools/bpf/bpftool/Documentation/bpftool-net.rst
tools/bpf/bpftool/Documentation/bpftool-perf.rst
tools/bpf/bpftool/Documentation/bpftool-prog.rst
tools/bpf/bpftool/Documentation/bpftool.rst
tools/bpf/bpftool/common.c
tools/bpf/bpftool/main.h
tools/bpf/bpftool/prog.c
tools/include/uapi/linux/pkt_cls.h [new file with mode: 0644]
tools/include/uapi/linux/tc_act/tc_bpf.h [new file with mode: 0644]
tools/power/cpupower/Makefile
tools/power/cpupower/bench/Makefile
tools/power/cpupower/debug/x86_64/Makefile
tools/power/cpupower/lib/cpufreq.c
tools/power/cpupower/lib/cpuidle.c
tools/power/cpupower/lib/cpupower.c
tools/power/cpupower/lib/cpupower_intern.h
tools/testing/selftests/Makefile
tools/testing/selftests/bpf/test_netcnt.c
tools/testing/selftests/bpf/test_verifier.c
tools/testing/selftests/netfilter/Makefile [new file with mode: 0644]
tools/testing/selftests/netfilter/config [new file with mode: 0644]
tools/testing/selftests/netfilter/nft_trans_stress.sh [new file with mode: 0755]
tools/testing/selftests/tc-testing/tdc.py

diff --git a/CREDITS b/CREDITS
index 84cbec4c62115adc38b976504b04799bb6fb0469..c9273393fe14c12d1eb32f2ce65aba527a00c928 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -2204,6 +2204,10 @@ S: Post Office Box 371
 S: North Little Rock, Arkansas 72115
 S: USA
 
+N: Christopher Li
+E: sparse@chrisli.org
+D: Sparse maintainer 2009 - 2018
+
 N: Stephan Linz
 E: linz@mazet.de
 E: Stephan.Linz@gmx.de
index 81d1d5a7472804e50a663480ef92dc67abc71ab5..19f4423e70d913ea2bf0801e4e14b57dc74e320f 100644 (file)
                                        prevent spurious wakeup);
                                n = USB_QUIRK_DELAY_CTRL_MSG (Device needs a
                                        pause after every control message);
+                               o = USB_QUIRK_HUB_SLOW_RESET (Hub needs extra
+                                       delay after resetting its port);
                        Example: quirks=0781:5580:bk,0a5c:5834:gij
 
        usbhid.mousepoll=
index 164bf71149fdf2e6ad099b45196cbd6d1d8347cc..30187d49dc2c7d38869c4073e60093d315c3fc4e 100644 (file)
@@ -32,16 +32,17 @@ Disclosure and embargoed information
 The security list is not a disclosure channel.  For that, see Coordination
 below.
 
-Once a robust fix has been developed, our preference is to release the
-fix in a timely fashion, treating it no differently than any of the other
-thousands of changes and fixes the Linux kernel project releases every
-month.
-
-However, at the request of the reporter, we will postpone releasing the
-fix for up to 5 business days after the date of the report or after the
-embargo has lifted; whichever comes first.  The only exception to that
-rule is if the bug is publicly known, in which case the preference is to
-release the fix as soon as it's available.
+Once a robust fix has been developed, the release process starts.  Fixes
+for publicly known bugs are released immediately.
+
+Although our preference is to release fixes for publicly undisclosed bugs
+as soon as they become available, this may be postponed at the request of
+the reporter or an affected party for up to 7 calendar days from the start
+of the release process, with an exceptional extension to 14 calendar days
+if it is agreed that the criticality of the bug requires more time.  The
+only valid reason for deferring the publication of a fix is to accommodate
+the logistics of QA and large scale rollouts which require release
+coordination.
 
 Whilst embargoed information may be shared with trusted individuals in
 order to develop a fix, such information will not be published alongside
index a4e705108f428e970b4c93be376ed3644dcb3649..dbe96cb5558ef5024fd9607a902c25ad430b4cb7 100644 (file)
@@ -74,7 +74,8 @@ using :c:func:`xa_load`.  xa_store will overwrite any entry with the
 new entry and return the previous entry stored at that index.  You can
 use :c:func:`xa_erase` instead of calling :c:func:`xa_store` with a
 ``NULL`` entry.  There is no difference between an entry that has never
-been stored to and one that has most recently had ``NULL`` stored to it.
+been stored to, one that has been erased and one that has most recently
+had ``NULL`` stored to it.
 
 You can conditionally replace an entry at an index by using
 :c:func:`xa_cmpxchg`.  Like :c:func:`cmpxchg`, it will only succeed if
@@ -105,23 +106,44 @@ may result in the entry being marked at some, but not all of the other
 indices.  Storing into one index may result in the entry retrieved by
 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`.
+
+If all entries in the array are ``NULL``, the :c:func:`xa_empty` function
+will return ``true``.
+
 Finally, you can remove all entries from an XArray by calling
 :c:func:`xa_destroy`.  If the XArray entries are pointers, you may wish
 to free the entries first.  You can do this by iterating over all present
 entries in the XArray using the :c:func:`xa_for_each` iterator.
 
-ID assignment
--------------
+Allocating XArrays
+------------------
+
+If you use :c:func:`DEFINE_XARRAY_ALLOC` to define the XArray, or
+initialise it by passing ``XA_FLAGS_ALLOC`` to :c:func:`xa_init_flags`,
+the XArray changes to track whether entries are in use or not.
 
 You can call :c:func:`xa_alloc` to store the entry at any unused index
 in the XArray.  If you need to modify the array from interrupt context,
 you can use :c:func:`xa_alloc_bh` or :c:func:`xa_alloc_irq` to disable
-interrupts while allocating the ID.  Unlike :c:func:`xa_store`, allocating
-a ``NULL`` pointer does not delete an entry.  Instead it reserves an
-entry like :c:func:`xa_reserve` and you can release it using either
-:c:func:`xa_erase` or :c:func:`xa_release`.  To use ID assignment, the
-XArray must be defined with :c:func:`DEFINE_XARRAY_ALLOC`, or initialised
-by passing ``XA_FLAGS_ALLOC`` to :c:func:`xa_init_flags`,
+interrupts while allocating the ID.
+
+Using :c:func:`xa_store`, :c:func:`xa_cmpxchg` or :c:func:`xa_insert`
+will mark the entry as being allocated.  Unlike a normal XArray, storing
+``NULL`` will mark the entry as being in use, like :c:func:`xa_reserve`.
+To free an entry, use :c:func:`xa_erase` (or :c:func:`xa_release` if
+you only want to free the entry if it's ``NULL``).
+
+You cannot use ``XA_MARK_0`` with an allocating XArray as this mark
+is used to track whether an entry is free or not.  The other marks are
+available for your use.
 
 Memory allocation
 -----------------
@@ -158,6 +180,8 @@ Takes RCU read lock:
 
 Takes xa_lock internally:
  * :c:func:`xa_store`
+ * :c:func:`xa_store_bh`
+ * :c:func:`xa_store_irq`
  * :c:func:`xa_insert`
  * :c:func:`xa_erase`
  * :c:func:`xa_erase_bh`
@@ -167,6 +191,9 @@ Takes xa_lock internally:
  * :c:func:`xa_alloc`
  * :c:func:`xa_alloc_bh`
  * :c:func:`xa_alloc_irq`
+ * :c:func:`xa_reserve`
+ * :c:func:`xa_reserve_bh`
+ * :c:func:`xa_reserve_irq`
  * :c:func:`xa_destroy`
  * :c:func:`xa_set_mark`
  * :c:func:`xa_clear_mark`
@@ -177,6 +204,7 @@ Assumes xa_lock held on entry:
  * :c:func:`__xa_erase`
  * :c:func:`__xa_cmpxchg`
  * :c:func:`__xa_alloc`
+ * :c:func:`__xa_reserve`
  * :c:func:`__xa_set_mark`
  * :c:func:`__xa_clear_mark`
 
@@ -234,7 +262,8 @@ Sharing the XArray with interrupt context is also possible, either
 using :c:func:`xa_lock_irqsave` in both the interrupt handler and process
 context, or :c:func:`xa_lock_irq` in process context and :c:func:`xa_lock`
 in the interrupt handler.  Some of the more common patterns have helper
-functions such as :c:func:`xa_erase_bh` and :c:func:`xa_erase_irq`.
+functions such as :c:func:`xa_store_bh`, :c:func:`xa_store_irq`,
+:c:func:`xa_erase_bh` and :c:func:`xa_erase_irq`.
 
 Sometimes you need to protect access to the XArray with a mutex because
 that lock sits above another mutex in the locking hierarchy.  That does
@@ -322,7 +351,8 @@ to :c:func:`xas_retry`, and retry the operation if it returns ``true``.
      - :c:func:`xa_is_zero`
      - Zero entries appear as ``NULL`` through the Normal API, but occupy
        an entry in the XArray which can be used to reserve the index for
-       future use.
+       future use.  This is used by allocating XArrays for allocated entries
+       which are ``NULL``.
 
 Other internal entries may be added in the future.  As far as possible, they
 will be handled by :c:func:`xas_retry`.
index 903a78da65be288cf750af872584b60e9f42c06f..3a9926f99937039022d283817beac8e9bcbbc926 100644 (file)
@@ -17,7 +17,7 @@ Example:
                reg = <1>;
                clocks = <&clk32m>;
                interrupt-parent = <&gpio4>;
-               interrupts = <13 IRQ_TYPE_EDGE_RISING>;
+               interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
                vdd-supply = <&reg5v0>;
                xceiver-supply = <&reg5v0>;
        };
index cc4372842bf37670284d9b676699b5eb00882de9..9936b9ee67c36672afeb050a5641aa44cebbb728 100644 (file)
@@ -5,6 +5,7 @@ Required properties:
 - compatible: "renesas,can-r8a7743" if CAN controller is a part of R8A7743 SoC.
              "renesas,can-r8a7744" if CAN controller is a part of R8A7744 SoC.
              "renesas,can-r8a7745" if CAN controller is a part of R8A7745 SoC.
+             "renesas,can-r8a774a1" if CAN controller is a part of R8A774A1 SoC.
              "renesas,can-r8a7778" if CAN controller is a part of R8A7778 SoC.
              "renesas,can-r8a7779" if CAN controller is a part of R8A7779 SoC.
              "renesas,can-r8a7790" if CAN controller is a part of R8A7790 SoC.
@@ -14,26 +15,32 @@ Required properties:
              "renesas,can-r8a7794" if CAN controller is a part of R8A7794 SoC.
              "renesas,can-r8a7795" if CAN controller is a part of R8A7795 SoC.
              "renesas,can-r8a7796" if CAN controller is a part of R8A7796 SoC.
+             "renesas,can-r8a77965" if CAN controller is a part of R8A77965 SoC.
              "renesas,rcar-gen1-can" for a generic R-Car Gen1 compatible device.
              "renesas,rcar-gen2-can" for a generic R-Car Gen2 or RZ/G1
              compatible device.
-             "renesas,rcar-gen3-can" for a generic R-Car Gen3 compatible device.
+             "renesas,rcar-gen3-can" for a generic R-Car Gen3 or RZ/G2
+             compatible device.
              When compatible with the generic version, nodes must list the
              SoC-specific version corresponding to the platform first
              followed by the generic version.
 
 - reg: physical base address and size of the R-Car CAN register map.
 - interrupts: interrupt specifier for the sole interrupt.
-- clocks: phandles and clock specifiers for 3 CAN clock inputs.
-- clock-names: 3 clock input name strings: "clkp1", "clkp2", "can_clk".
+- clocks: phandles and clock specifiers for 2 CAN clock inputs for RZ/G2
+         devices.
+         phandles and clock specifiers for 3 CAN clock inputs for every other
+         SoC.
+- clock-names: 2 clock input name strings for RZ/G2: "clkp1", "can_clk".
+              3 clock input name strings for every other SoC: "clkp1", "clkp2",
+              "can_clk".
 - pinctrl-0: pin control group to be used for this controller.
 - pinctrl-names: must be "default".
 
-Required properties for "renesas,can-r8a7795" and "renesas,can-r8a7796"
-compatible:
-In R8A7795 and R8A7796 SoCs, "clkp2" can be CANFD clock. This is a div6 clock
-and can be used by both CAN and CAN FD controller at the same time. It needs to
-be scaled to maximum frequency if any of these controllers use it. This is done
+Required properties for R8A7795, R8A7796 and R8A77965:
+For the denoted SoCs, "clkp2" can be CANFD clock. This is a div6 clock and can
+be used by both CAN and CAN FD controller at the same time. It needs to be
+scaled to maximum frequency if any of these controllers use it. This is done
 using the below properties:
 
 - assigned-clocks: phandle of clkp2(CANFD) clock.
@@ -42,8 +49,9 @@ using the below properties:
 Optional properties:
 - renesas,can-clock-select: R-Car CAN Clock Source Select. Valid values are:
                            <0x0> (default) : Peripheral clock (clkp1)
-                           <0x1> : Peripheral clock (clkp2)
-                           <0x3> : Externally input clock
+                           <0x1> : Peripheral clock (clkp2) (not supported by
+                                   RZ/G2 devices)
+                           <0x3> : External input clock
 
 Example
 -------
index 3ceeb8de11963572cc1bd8ce324433e0dbf6bd03..35694c0c376b91c8b51982d1dce992682b983d92 100644 (file)
@@ -7,7 +7,7 @@ limitations.
 Current Binding
 ---------------
 
-Switches are true Linux devices and can be probes by any means. Once
+Switches are true Linux devices and can be probed by any means. Once
 probed, they register to the DSA framework, passing a node
 pointer. This node is expected to fulfil the following binding, and
 may contain additional properties as required by the device it is
index 504a4ecfc7b16869192c666e903a9d884d9f052d..b04e66a52de5dfc4ca66a3efc5339e4986275033 100644 (file)
@@ -5,18 +5,20 @@ UniPhier SoCs have SCSSI which supports SPI single channel.
 Required properties:
  - compatible: should be "socionext,uniphier-scssi"
  - reg: address and length of the spi master registers
- - #address-cells: must be <1>, see spi-bus.txt
- - #size-cells: must be <0>, see spi-bus.txt
- - clocks: A phandle to the clock for the device.
- - resets: A phandle to the reset control for the device.
+ - interrupts: a single interrupt specifier
+ - pinctrl-names: should be "default"
+ - pinctrl-0: pin control state for the default mode
+ - clocks: a phandle to the clock for the device
+ - resets: a phandle to the reset control for the device
 
 Example:
 
 spi0: spi@54006000 {
        compatible = "socionext,uniphier-scssi";
        reg = <0x54006000 0x100>;
-       #address-cells = <1>;
-       #size-cells = <0>;
+       interrupts = <0 39 4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_spi0>;
        clocks = <&peri_clk 11>;
        resets = <&peri_rst 11>;
 };
index cef220c176a405b8f6839d846e074d295bd2b81e..a8c0873beb952e620db9bb2f2df823624ac90650 100644 (file)
@@ -190,16 +190,7 @@ A few EV_REL codes have special meanings:
 * REL_WHEEL, REL_HWHEEL:
 
   - These codes are used for vertical and horizontal scroll wheels,
-    respectively. The value is the number of "notches" moved on the wheel, the
-    physical size of which varies by device. For high-resolution wheels (which
-    report multiple events for each notch of movement, or do not have notches)
-    this may be an approximation based on the high-resolution scroll events.
-
-* REL_WHEEL_HI_RES:
-
-  - If a vertical scroll wheel supports high-resolution scrolling, this code
-    will be emitted in addition to REL_WHEEL. The value is the (approximate)
-    distance travelled by the user's finger, in microns.
+    respectively.
 
 EV_ABS
 ------
index f7ac8d0d3af14a1a6d951df74847972220711133..b65dc078abeb8ca4a1a9a045eddc2d1b8844c333 100644 (file)
@@ -40,7 +40,7 @@ To use the :ref:`format` ioctls applications set the ``type`` field of the
 the desired operation. Both drivers and applications must set the remainder of
 the :c:type:`v4l2_format` structure to 0.
 
-.. _v4l2-meta-format:
+.. c:type:: v4l2_meta_format
 
 .. tabularcolumns:: |p{1.4cm}|p{2.2cm}|p{13.9cm}|
 
index 3ead350e099f97a6146ff98bf0126a8388149883..9ea494a8facab2cca0b51745cda1af6f0f53fd4c 100644 (file)
@@ -132,6 +132,11 @@ The format as returned by :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` must be identical
       - ``sdr``
       - Definition of a data format, see :ref:`pixfmt`, used by SDR
        capture and output devices.
+    * -
+      - struct :c:type:`v4l2_meta_format`
+      - ``meta``
+      - Definition of a metadata format, see :ref:`meta-formats`, used by
+       metadata capture devices.
     * -
       - __u8
       - ``raw_data``\ [200]
index 605e00cdd6beb1d024519ab8417464fc12064724..89f1302d593a5c0404ed8a434ba580e8440a9139 100644 (file)
@@ -1056,18 +1056,23 @@ The kernel interface functions are as follows:
 
        u32 rxrpc_kernel_check_life(struct socket *sock,
                                    struct rxrpc_call *call);
+       void rxrpc_kernel_probe_life(struct socket *sock,
+                                    struct rxrpc_call *call);
 
-     This returns a number that is updated when ACKs are received from the peer
-     (notably including PING RESPONSE ACKs which we can elicit by sending PING
-     ACKs to see if the call still exists on the server).  The caller should
-     compare the numbers of two calls to see if the call is still alive after
-     waiting for a suitable interval.
+     The first function returns a number that is updated when ACKs are received
+     from the peer (notably including PING RESPONSE ACKs which we can elicit by
+     sending PING ACKs to see if the call still exists on the server).  The
+     caller should compare the numbers of two calls to see if the call is still
+     alive after waiting for a suitable interval.
 
      This allows the caller to work out if the server is still contactable and
      if the call is still alive on the server whilst waiting for the server to
      process a client operation.
 
-     This function may transmit a PING ACK.
+     The second function causes a ping ACK to be transmitted to try to provoke
+     the peer into responding, which would then cause the value returned by the
+     first function to change.  Note that this must be called in TASK_RUNNING
+     state.
 
  (*) Get reply timestamp.
 
index b755a89fa3256e557115f0bd3b8a05dcaa5a21cf..da57abebaab35a95a4f94d5db63c74b550c08c9c 100644 (file)
@@ -180,6 +180,7 @@ F:  drivers/net/hamradio/6pack.c
 
 8169 10/100/1000 GIGABIT ETHERNET DRIVER
 M:     Realtek linux nic maintainers <nic_swsd@realtek.com>
+M:     Heiner Kallweit <hkallweit1@gmail.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/ethernet/realtek/r8169.c
@@ -717,7 +718,7 @@ F:  include/linux/mfd/altera-a10sr.h
 F:     include/dt-bindings/reset/altr,rst-mgr-a10sr.h
 
 ALTERA TRIPLE SPEED ETHERNET DRIVER
-M:     Vince Bridgers <vbridger@opensource.altera.com>
+M:     Thor Thayer <thor.thayer@linux.intel.com>
 L:     netdev@vger.kernel.org
 L:     nios2-dev@lists.rocketboards.org (moderated for non-subscribers)
 S:     Maintained
@@ -2800,7 +2801,7 @@ T:        git git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git
 Q:     https://patchwork.ozlabs.org/project/netdev/list/?delegate=77147
 S:     Supported
-F:     arch/x86/net/bpf_jit*
+F:     arch/*/net/*
 F:     Documentation/networking/filter.txt
 F:     Documentation/bpf/
 F:     include/linux/bpf*
@@ -2820,6 +2821,67 @@ F:       tools/bpf/
 F:     tools/lib/bpf/
 F:     tools/testing/selftests/bpf/
 
+BPF JIT for ARM
+M:     Shubham Bansal <illusionist.neo@gmail.com>
+L:     netdev@vger.kernel.org
+S:     Maintained
+F:     arch/arm/net/
+
+BPF JIT for ARM64
+M:     Daniel Borkmann <daniel@iogearbox.net>
+M:     Alexei Starovoitov <ast@kernel.org>
+M:     Zi Shen Lim <zlim.lnx@gmail.com>
+L:     netdev@vger.kernel.org
+S:     Supported
+F:     arch/arm64/net/
+
+BPF JIT for MIPS (32-BIT AND 64-BIT)
+M:     Paul Burton <paul.burton@mips.com>
+L:     netdev@vger.kernel.org
+S:     Maintained
+F:     arch/mips/net/
+
+BPF JIT for NFP NICs
+M:     Jakub Kicinski <jakub.kicinski@netronome.com>
+L:     netdev@vger.kernel.org
+S:     Supported
+F:     drivers/net/ethernet/netronome/nfp/bpf/
+
+BPF JIT for POWERPC (32-BIT AND 64-BIT)
+M:     Naveen N. Rao <naveen.n.rao@linux.ibm.com>
+M:     Sandipan Das <sandipan@linux.ibm.com>
+L:     netdev@vger.kernel.org
+S:     Maintained
+F:     arch/powerpc/net/
+
+BPF JIT for S390
+M:     Martin Schwidefsky <schwidefsky@de.ibm.com>
+M:     Heiko Carstens <heiko.carstens@de.ibm.com>
+L:     netdev@vger.kernel.org
+S:     Maintained
+F:     arch/s390/net/
+X:     arch/s390/net/pnet.c
+
+BPF JIT for SPARC (32-BIT AND 64-BIT)
+M:     David S. Miller <davem@davemloft.net>
+L:     netdev@vger.kernel.org
+S:     Maintained
+F:     arch/sparc/net/
+
+BPF JIT for X86 32-BIT
+M:     Wang YanQing <udknight@gmail.com>
+L:     netdev@vger.kernel.org
+S:     Maintained
+F:     arch/x86/net/bpf_jit_comp32.c
+
+BPF JIT for X86 64-BIT
+M:     Alexei Starovoitov <ast@kernel.org>
+M:     Daniel Borkmann <daniel@iogearbox.net>
+L:     netdev@vger.kernel.org
+S:     Supported
+F:     arch/x86/net/
+X:     arch/x86/net/bpf_jit_comp32.c
+
 BROADCOM B44 10/100 ETHERNET DRIVER
 M:     Michael Chan <michael.chan@broadcom.com>
 L:     netdev@vger.kernel.org
@@ -3276,6 +3338,12 @@ F:       include/uapi/linux/caif/
 F:     include/net/caif/
 F:     net/caif/
 
+CAKE QDISC
+M:     Toke Høiland-Jørgensen <toke@toke.dk>
+L:     cake@lists.bufferbloat.net (moderated for non-subscribers)
+S:     Maintained
+F:     net/sched/sch_cake.c
+
 CALGARY x86-64 IOMMU
 M:     Muli Ben-Yehuda <mulix@mulix.org>
 M:     Jon Mason <jdmason@kudzu.us>
@@ -5528,6 +5596,7 @@ F:        net/bridge/
 ETHERNET PHY LIBRARY
 M:     Andrew Lunn <andrew@lunn.ch>
 M:     Florian Fainelli <f.fainelli@gmail.com>
+M:     Heiner Kallweit <hkallweit1@gmail.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     Documentation/ABI/testing/sysfs-bus-mdio
@@ -6299,6 +6368,7 @@ F:        tools/testing/selftests/gpio/
 
 GPIO SUBSYSTEM
 M:     Linus Walleij <linus.walleij@linaro.org>
+M:     Bartosz Golaszewski <bgolaszewski@baylibre.com>
 L:     linux-gpio@vger.kernel.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git
 S:     Maintained
@@ -7436,6 +7506,20 @@ S:       Maintained
 F:     Documentation/fb/intelfb.txt
 F:     drivers/video/fbdev/intelfb/
 
+INTEL GPIO DRIVERS
+M:     Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+L:     linux-gpio@vger.kernel.org
+S:     Maintained
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git
+F:     drivers/gpio/gpio-ich.c
+F:     drivers/gpio/gpio-intel-mid.c
+F:     drivers/gpio/gpio-lynxpoint.c
+F:     drivers/gpio/gpio-merrifield.c
+F:     drivers/gpio/gpio-ml-ioh.c
+F:     drivers/gpio/gpio-pch.c
+F:     drivers/gpio/gpio-sch.c
+F:     drivers/gpio/gpio-sodaville.c
+
 INTEL GVT-g DRIVERS (Intel GPU Virtualization)
 M:     Zhenyu Wang <zhenyuw@linux.intel.com>
 M:     Zhi Wang <zhi.a.wang@intel.com>
@@ -7446,12 +7530,6 @@ T:       git https://github.com/intel/gvt-linux.git
 S:     Supported
 F:     drivers/gpu/drm/i915/gvt/
 
-INTEL PMIC GPIO DRIVER
-R:     Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-S:     Maintained
-F:     drivers/gpio/gpio-*cove.c
-F:     drivers/gpio/gpio-msic.c
-
 INTEL HID EVENT DRIVER
 M:     Alex Hung <alex.hung@canonical.com>
 L:     platform-driver-x86@vger.kernel.org
@@ -7539,12 +7617,6 @@ W:       https://01.org/linux-acpi
 S:     Supported
 F:     drivers/platform/x86/intel_menlow.c
 
-INTEL MERRIFIELD GPIO DRIVER
-M:     Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-L:     linux-gpio@vger.kernel.org
-S:     Maintained
-F:     drivers/gpio/gpio-merrifield.c
-
 INTEL MIC DRIVERS (mic)
 M:     Sudeep Dutt <sudeep.dutt@intel.com>
 M:     Ashutosh Dixit <ashutosh.dixit@intel.com>
@@ -7577,6 +7649,13 @@ F:       drivers/platform/x86/intel_punit_ipc.c
 F:     arch/x86/include/asm/intel_pmc_ipc.h
 F:     arch/x86/include/asm/intel_punit_ipc.h
 
+INTEL PMIC GPIO DRIVERS
+M:     Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+S:     Maintained
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git
+F:     drivers/gpio/gpio-*cove.c
+F:     drivers/gpio/gpio-msic.c
+
 INTEL MULTIFUNCTION PMIC DEVICE DRIVERS
 R:     Andy Shevchenko <andriy.shevchenko@linux.intel.com>
 S:     Maintained
@@ -13978,11 +14057,10 @@ F:    drivers/tty/serial/sunzilog.h
 F:     drivers/tty/vcc.c
 
 SPARSE CHECKER
-M:     "Christopher Li" <sparse@chrisli.org>
+M:     "Luc Van Oostenryck" <luc.vanoostenryck@gmail.com>
 L:     linux-sparse@vger.kernel.org
 W:     https://sparse.wiki.kernel.org/
 T:     git git://git.kernel.org/pub/scm/devel/sparse/sparse.git
-T:     git git://git.kernel.org/pub/scm/devel/sparse/chrisl/sparse.git
 S:     Maintained
 F:     include/linux/compiler.h
 
@@ -14079,6 +14157,7 @@ F:      Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
 
 STABLE BRANCH
 M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+M:     Sasha Levin <sashal@kernel.org>
 L:     stable@vger.kernel.org
 S:     Supported
 F:     Documentation/process/stable-kernel-rules.rst
index ddbf627cad8f5fd8a2d0d06a913294d88a0ff878..0ce4e29ee342fa191ecd0e3d3dc0e357eae7997c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,8 +2,8 @@
 VERSION = 4
 PATCHLEVEL = 20
 SUBLEVEL = 0
-EXTRAVERSION = -rc3
-NAME = "People's Front"
+EXTRAVERSION = -rc4
+NAME = Shy Crocodile
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
index 0c909c4a932ff3da741fbda7c16cf6a3780d6107..842fb9572661063bd0db34b27e14d4829093208d 100644 (file)
                         SCTLR_ELx_SA     | SCTLR_ELx_I    | SCTLR_ELx_WXN | \
                         SCTLR_ELx_DSSBS | ENDIAN_CLEAR_EL2 | SCTLR_EL2_RES0)
 
-#if (SCTLR_EL2_SET ^ SCTLR_EL2_CLEAR) != 0xffffffffffffffff
+#if (SCTLR_EL2_SET ^ SCTLR_EL2_CLEAR) != 0xffffffffffffffffUL
 #error "Inconsistent SCTLR_EL2 set/clear bits"
 #endif
 
                         SCTLR_EL1_UMA | SCTLR_ELx_WXN     | ENDIAN_CLEAR_EL1 |\
                         SCTLR_ELx_DSSBS | SCTLR_EL1_NTWI  | SCTLR_EL1_RES0)
 
-#if (SCTLR_EL1_SET ^ SCTLR_EL1_CLEAR) != 0xffffffffffffffff
+#if (SCTLR_EL1_SET ^ SCTLR_EL1_CLEAR) != 0xffffffffffffffffUL
 #error "Inconsistent SCTLR_EL1 set/clear bits"
 #endif
 
index af50064dea51ad23c7c47cbe4786839fbf8603fa..aec5ecb85737edbe274b4f1c8a9082ac4a6947e1 100644 (file)
@@ -1333,7 +1333,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .cpu_enable = cpu_enable_hw_dbm,
        },
 #endif
-#ifdef CONFIG_ARM64_SSBD
        {
                .desc = "CRC32 instructions",
                .capability = ARM64_HAS_CRC32,
@@ -1343,6 +1342,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .field_pos = ID_AA64ISAR0_CRC32_SHIFT,
                .min_field_value = 1,
        },
+#ifdef CONFIG_ARM64_SSBD
        {
                .desc = "Speculative Store Bypassing Safe (SSBS)",
                .capability = ARM64_SSBS,
index a6fdaea07c6339cf2754d582765747ee5d8b2ff5..89198017e8e681268504235331471b38b7e945b9 100644 (file)
@@ -351,7 +351,8 @@ static void build_epilogue(struct jit_ctx *ctx)
  * >0 - successfully JITed a 16-byte eBPF instruction.
  * <0 - failed to JIT.
  */
-static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
+static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
+                     bool extra_pass)
 {
        const u8 code = insn->code;
        const u8 dst = bpf2a64[insn->dst_reg];
@@ -625,12 +626,19 @@ emit_cond_jmp:
        case BPF_JMP | BPF_CALL:
        {
                const u8 r0 = bpf2a64[BPF_REG_0];
-               const u64 func = (u64)__bpf_call_base + imm;
+               bool func_addr_fixed;
+               u64 func_addr;
+               int ret;
 
-               if (ctx->prog->is_func)
-                       emit_addr_mov_i64(tmp, func, ctx);
+               ret = bpf_jit_get_func_addr(ctx->prog, insn, extra_pass,
+                                           &func_addr, &func_addr_fixed);
+               if (ret < 0)
+                       return ret;
+               if (func_addr_fixed)
+                       /* We can use optimized emission here. */
+                       emit_a64_mov_i64(tmp, func_addr, ctx);
                else
-                       emit_a64_mov_i64(tmp, func, ctx);
+                       emit_addr_mov_i64(tmp, func_addr, ctx);
                emit(A64_BLR(tmp), ctx);
                emit(A64_MOV(1, r0, A64_R(0)), ctx);
                break;
@@ -753,7 +761,7 @@ emit_cond_jmp:
        return 0;
 }
 
-static int build_body(struct jit_ctx *ctx)
+static int build_body(struct jit_ctx *ctx, bool extra_pass)
 {
        const struct bpf_prog *prog = ctx->prog;
        int i;
@@ -762,7 +770,7 @@ static int build_body(struct jit_ctx *ctx)
                const struct bpf_insn *insn = &prog->insnsi[i];
                int ret;
 
-               ret = build_insn(insn, ctx);
+               ret = build_insn(insn, ctx, extra_pass);
                if (ret > 0) {
                        i++;
                        if (ctx->image == NULL)
@@ -858,7 +866,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
        /* 1. Initial fake pass to compute ctx->idx. */
 
        /* Fake pass to fill in ctx->offset. */
-       if (build_body(&ctx)) {
+       if (build_body(&ctx, extra_pass)) {
                prog = orig_prog;
                goto out_off;
        }
@@ -888,7 +896,7 @@ skip_init_ctx:
 
        build_prologue(&ctx, was_classic);
 
-       if (build_body(&ctx)) {
+       if (build_body(&ctx, extra_pass)) {
                bpf_jit_binary_free(header);
                prog = orig_prog;
                goto out_off;
index ebef7f40aabbe26a5fa384294bf05819f949dd30..c5c253cb9bd63ad85177e3e0f00321385362da7e 100644 (file)
@@ -59,7 +59,9 @@ extern struct node_cpuid_s node_cpuid[NR_CPUS];
  */
 
 extern u8 numa_slit[MAX_NUMNODES * MAX_NUMNODES];
-#define node_distance(from,to) (numa_slit[(from) * MAX_NUMNODES + (to)])
+#define slit_distance(from,to) (numa_slit[(from) * MAX_NUMNODES + (to)])
+extern int __node_distance(int from, int to);
+#define node_distance(from,to) __node_distance(from, to)
 
 extern int paddr_to_nid(unsigned long paddr);
 
index 1dacbf5e9e09a5a71f9e21bd5fd88eed8199e823..41eb281709da1c334226fc652d7184888e48d327 100644 (file)
@@ -578,8 +578,8 @@ void __init acpi_numa_fixup(void)
        if (!slit_table) {
                for (i = 0; i < MAX_NUMNODES; i++)
                        for (j = 0; j < MAX_NUMNODES; j++)
-                               node_distance(i, j) = i == j ? LOCAL_DISTANCE :
-                                                       REMOTE_DISTANCE;
+                               slit_distance(i, j) = i == j ?
+                                       LOCAL_DISTANCE : REMOTE_DISTANCE;
                return;
        }
 
@@ -592,7 +592,7 @@ void __init acpi_numa_fixup(void)
                        if (!pxm_bit_test(j))
                                continue;
                        node_to = pxm_to_node(j);
-                       node_distance(node_from, node_to) =
+                       slit_distance(node_from, node_to) =
                            slit_table->entry[i * slit_table->locality_count + j];
                }
        }
index 3861d6e32d5ff910615305ef691b4a30fd1028f2..a03803506b0c041fde49ca23bfae160ba6499bd9 100644 (file)
@@ -36,6 +36,12 @@ struct node_cpuid_s node_cpuid[NR_CPUS] =
  */
 u8 numa_slit[MAX_NUMNODES * MAX_NUMNODES];
 
+int __node_distance(int from, int to)
+{
+       return slit_distance(from, to);
+}
+EXPORT_SYMBOL(__node_distance);
+
 /* Identify which cnode a physical address resides on */
 int
 paddr_to_nid(unsigned long paddr)
index 490b12af103c1285043ecfec912b1839c5586f06..c52d0efacd1466f0320a025d3519ffb8ba212a09 100644 (file)
@@ -140,6 +140,7 @@ CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_DS1307=y
 CONFIG_STAGING=y
 CONFIG_OCTEON_ETHERNET=y
+CONFIG_OCTEON_USB=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_RAS=y
 CONFIG_EXT4_FS=y
index ea09ed6a80a9f2dc0aa625e2fcec0b34e2c6acea..8c6c48ed786a1527c22ba5b46bcdad70029e5865 100644 (file)
@@ -794,6 +794,7 @@ static void __init arch_mem_init(char **cmdline_p)
 
        /* call board setup routine */
        plat_mem_setup();
+       memblock_set_bottom_up(true);
 
        /*
         * Make sure all kernel memory is in the maps.  The "UP" and
index 0f852e1b589193d43f9125cfbfa303d6b47c6fed..15e103c6d799ebd90ad3f55a954c1d40329d5bac 100644 (file)
@@ -2260,10 +2260,8 @@ void __init trap_init(void)
                unsigned long size = 0x200 + VECTORSPACING*64;
                phys_addr_t ebase_pa;
 
-               memblock_set_bottom_up(true);
                ebase = (unsigned long)
                        memblock_alloc_from(size, 1 << fls(size), 0);
-               memblock_set_bottom_up(false);
 
                /*
                 * Try to ensure ebase resides in KSeg0 if possible.
@@ -2307,6 +2305,7 @@ void __init trap_init(void)
        if (board_ebase_setup)
                board_ebase_setup();
        per_cpu_trap_init(true);
+       memblock_set_bottom_up(false);
 
        /*
         * Copy the generic exception handlers to their final destination.
index 622761878cd11bd54e53affa43e5504c0aadc9c0..60bf0a1cb75719d731b60f8b2fe2954074dea77b 100644 (file)
@@ -231,6 +231,8 @@ static __init void prom_meminit(void)
                        cpumask_clear(&__node_data[(node)]->cpumask);
                }
        }
+       max_low_pfn = PHYS_PFN(memblock_end_of_DRAM());
+
        for (cpu = 0; cpu < loongson_sysconf.nr_cpus; cpu++) {
                node = cpu / loongson_sysconf.cores_per_node;
                if (node >= num_online_nodes())
@@ -248,19 +250,9 @@ static __init void prom_meminit(void)
 
 void __init paging_init(void)
 {
-       unsigned node;
        unsigned long zones_size[MAX_NR_ZONES] = {0, };
 
        pagetable_init();
-
-       for_each_online_node(node) {
-               unsigned long  start_pfn, end_pfn;
-
-               get_pfn_range_for_nid(node, &start_pfn, &end_pfn);
-
-               if (end_pfn > max_low_pfn)
-                       max_low_pfn = end_pfn;
-       }
 #ifdef CONFIG_ZONE_DMA32
        zones_size[ZONE_DMA32] = MAX_DMA32_PFN;
 #endif
index d8b8444d679527e3843ea1de091be70926355f34..813d13f92957ed00715ac5914d62dc09bcba1861 100644 (file)
@@ -435,6 +435,7 @@ void __init prom_meminit(void)
 
        mlreset();
        szmem();
+       max_low_pfn = PHYS_PFN(memblock_end_of_DRAM());
 
        for (node = 0; node < MAX_COMPACT_NODES; node++) {
                if (node_online(node)) {
@@ -455,18 +456,8 @@ extern void setup_zero_pages(void);
 void __init paging_init(void)
 {
        unsigned long zones_size[MAX_NR_ZONES] = {0, };
-       unsigned node;
 
        pagetable_init();
-
-       for_each_online_node(node) {
-               unsigned long start_pfn, end_pfn;
-
-               get_pfn_range_for_nid(node, &start_pfn, &end_pfn);
-
-               if (end_pfn > max_low_pfn)
-                       max_low_pfn = end_pfn;
-       }
        zones_size[ZONE_NORMAL] = max_low_pfn;
        free_area_init_nodes(zones_size);
 }
index d65b961661fbf6d9075b34c523269bb1261845fe..a56f8413758ab1d796328093eb754d3b6715f4eb 100644 (file)
@@ -983,6 +983,7 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
                ret = kvmhv_enter_nested_guest(vcpu);
                if (ret == H_INTERRUPT) {
                        kvmppc_set_gpr(vcpu, 3, 0);
+                       vcpu->arch.hcall_needed = 0;
                        return -EINTR;
                }
                break;
index 50b129785aeeead06f8d131a64d30a6ccda2576e..17482f5de3e262f53d67b4199490660362b394a0 100644 (file)
@@ -166,7 +166,33 @@ static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
        PPC_BLR();
 }
 
-static void bpf_jit_emit_func_call(u32 *image, struct codegen_context *ctx, u64 func)
+static void bpf_jit_emit_func_call_hlp(u32 *image, struct codegen_context *ctx,
+                                      u64 func)
+{
+#ifdef PPC64_ELF_ABI_v1
+       /* func points to the function descriptor */
+       PPC_LI64(b2p[TMP_REG_2], func);
+       /* Load actual entry point from function descriptor */
+       PPC_BPF_LL(b2p[TMP_REG_1], b2p[TMP_REG_2], 0);
+       /* ... and move it to LR */
+       PPC_MTLR(b2p[TMP_REG_1]);
+       /*
+        * Load TOC from function descriptor at offset 8.
+        * We can clobber r2 since we get called through a
+        * function pointer (so caller will save/restore r2)
+        * and since we don't use a TOC ourself.
+        */
+       PPC_BPF_LL(2, b2p[TMP_REG_2], 8);
+#else
+       /* We can clobber r12 */
+       PPC_FUNC_ADDR(12, func);
+       PPC_MTLR(12);
+#endif
+       PPC_BLRL();
+}
+
+static void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx,
+                                      u64 func)
 {
        unsigned int i, ctx_idx = ctx->idx;
 
@@ -273,7 +299,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
 {
        const struct bpf_insn *insn = fp->insnsi;
        int flen = fp->len;
-       int i;
+       int i, ret;
 
        /* Start of epilogue code - will only be valid 2nd pass onwards */
        u32 exit_addr = addrs[flen];
@@ -284,8 +310,9 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
                u32 src_reg = b2p[insn[i].src_reg];
                s16 off = insn[i].off;
                s32 imm = insn[i].imm;
+               bool func_addr_fixed;
+               u64 func_addr;
                u64 imm64;
-               u8 *func;
                u32 true_cond;
                u32 tmp_idx;
 
@@ -711,23 +738,15 @@ emit_clear:
                case BPF_JMP | BPF_CALL:
                        ctx->seen |= SEEN_FUNC;
 
-                       /* bpf function call */
-                       if (insn[i].src_reg == BPF_PSEUDO_CALL)
-                               if (!extra_pass)
-                                       func = NULL;
-                               else if (fp->aux->func && off < fp->aux->func_cnt)
-                                       /* use the subprog id from the off
-                                        * field to lookup the callee address
-                                        */
-                                       func = (u8 *) fp->aux->func[off]->bpf_func;
-                               else
-                                       return -EINVAL;
-                       /* kernel helper call */
-                       else
-                               func = (u8 *) __bpf_call_base + imm;
-
-                       bpf_jit_emit_func_call(image, ctx, (u64)func);
+                       ret = bpf_jit_get_func_addr(fp, &insn[i], extra_pass,
+                                                   &func_addr, &func_addr_fixed);
+                       if (ret < 0)
+                               return ret;
 
+                       if (func_addr_fixed)
+                               bpf_jit_emit_func_call_hlp(image, ctx, func_addr);
+                       else
+                               bpf_jit_emit_func_call_rel(image, ctx, func_addr);
                        /* move return value from r3 to BPF_REG_0 */
                        PPC_MR(b2p[BPF_REG_0], 3);
                        break;
index 4af153a182b071fcd4853a8853fb94fb1333312b..4b594f2e4f7ebd9eb791f6c2709f4023d3aa76c6 100644 (file)
@@ -71,6 +71,10 @@ KBUILD_CFLAGS += $(call cc-option,-mstrict-align)
 # arch specific predefines for sparse
 CHECKFLAGS += -D__riscv -D__riscv_xlen=$(BITS)
 
+# Default target when executing plain make
+boot           := arch/riscv/boot
+KBUILD_IMAGE   := $(boot)/Image.gz
+
 head-y := arch/riscv/kernel/head.o
 
 core-y += arch/riscv/kernel/ arch/riscv/mm/
@@ -81,4 +85,13 @@ PHONY += vdso_install
 vdso_install:
        $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@
 
-all: vmlinux
+all: Image.gz
+
+Image: vmlinux
+       $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+
+Image.%: Image
+       $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+
+zinstall install:
+       $(Q)$(MAKE) $(build)=$(boot) $@
diff --git a/arch/riscv/boot/.gitignore b/arch/riscv/boot/.gitignore
new file mode 100644 (file)
index 0000000..8dab0bb
--- /dev/null
@@ -0,0 +1,2 @@
+Image
+Image.gz
diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile
new file mode 100644 (file)
index 0000000..0990a9f
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# arch/riscv/boot/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2018, Anup Patel.
+# Author: Anup Patel <anup@brainfault.org>
+#
+# Based on the ia64 and arm64 boot/Makefile.
+#
+
+OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
+
+targets := Image
+
+$(obj)/Image: vmlinux FORCE
+       $(call if_changed,objcopy)
+
+$(obj)/Image.gz: $(obj)/Image FORCE
+       $(call if_changed,gzip)
+
+install:
+       $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
+       $(obj)/Image System.map "$(INSTALL_PATH)"
+
+zinstall:
+       $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
+       $(obj)/Image.gz System.map "$(INSTALL_PATH)"
diff --git a/arch/riscv/boot/install.sh b/arch/riscv/boot/install.sh
new file mode 100644 (file)
index 0000000..18c3915
--- /dev/null
@@ -0,0 +1,60 @@
+#!/bin/sh
+#
+# arch/riscv/boot/install.sh
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995 by Linus Torvalds
+#
+# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
+# Adapted from code in arch/i386/boot/install.sh by Russell King
+#
+# "make install" script for the RISC-V Linux port
+#
+# Arguments:
+#   $1 - kernel version
+#   $2 - kernel image file
+#   $3 - kernel map file
+#   $4 - default install path (blank if root directory)
+#
+
+verify () {
+       if [ ! -f "$1" ]; then
+               echo ""                                                   1>&2
+               echo " *** Missing file: $1"                              1>&2
+               echo ' *** You need to run "make" before "make install".' 1>&2
+               echo ""                                                   1>&2
+               exit 1
+       fi
+}
+
+# Make sure the files actually exist
+verify "$2"
+verify "$3"
+
+# User may have a custom install script
+if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
+if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
+
+if [ "$(basename $2)" = "Image.gz" ]; then
+# Compressed install
+  echo "Installing compressed kernel"
+  base=vmlinuz
+else
+# Normal install
+  echo "Installing normal kernel"
+  base=vmlinux
+fi
+
+if [ -f $4/$base-$1 ]; then
+  mv $4/$base-$1 $4/$base-$1.old
+fi
+cat $2 > $4/$base-$1
+
+# Install system map file
+if [ -f $4/System.map-$1 ]; then
+  mv $4/System.map-$1 $4/System.map-$1.old
+fi
+cp $3 $4/System.map-$1
index 349df33808c4231d155d2e6018e19cc4cb19cb4d..cd2af4b013e3826e3b43f44565a9b6c1c6ae7b70 100644 (file)
@@ -8,6 +8,7 @@
 
 #define MODULE_ARCH_VERMAGIC    "riscv"
 
+struct module;
 u64 module_emit_got_entry(struct module *mod, u64 val);
 u64 module_emit_plt_entry(struct module *mod, u64 val);
 
index 473cfc84e412f3827703caaadffa34a8983c978d..8c3e3e3c8be1204b67076985a9b54e80217707b1 100644 (file)
@@ -400,13 +400,13 @@ extern unsigned long __must_check __asm_copy_from_user(void *to,
 static inline unsigned long
 raw_copy_from_user(void *to, const void __user *from, unsigned long n)
 {
-       return __asm_copy_to_user(to, from, n);
+       return __asm_copy_from_user(to, from, n);
 }
 
 static inline unsigned long
 raw_copy_to_user(void __user *to, const void *from, unsigned long n)
 {
-       return __asm_copy_from_user(to, from, n);
+       return __asm_copy_to_user(to, from, n);
 }
 
 extern long strncpy_from_user(char *dest, const char __user *src, long count);
index eff7aa9aa1637851aadd871807644560bef5c412..fef96f117b4def3fe9a99ec9ca8b26d2278e087c 100644 (file)
 
 /*
  * There is explicitly no include guard here because this file is expected to
- * be included multiple times.  See uapi/asm/syscalls.h for more info.
+ * be included multiple times.
  */
 
-#define __ARCH_WANT_NEW_STAT
 #define __ARCH_WANT_SYS_CLONE
+
 #include <uapi/asm/unistd.h>
-#include <uapi/asm/syscalls.h>
similarity index 53%
rename from arch/riscv/include/uapi/asm/syscalls.h
rename to arch/riscv/include/uapi/asm/unistd.h
index 206dc4b0f6ea8423bf6446e2e13e679373a43ec5..1f3bd3ebbb0d27f8abcdd092d1c19fe04f2d6457 100644 (file)
@@ -1,13 +1,25 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
 /*
- * Copyright (C) 2017-2018 SiFive
+ * Copyright (C) 2018 David Abdurachmanov <david.abdurachmanov@gmail.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-/*
- * There is explicitly no include guard here because this file is expected to
- * be included multiple times in order to define the syscall macros via
- * __SYSCALL.
- */
+#ifdef __LP64__
+#define __ARCH_WANT_NEW_STAT
+#endif /* __LP64__ */
+
+#include <asm-generic/unistd.h>
 
 /*
  * Allows the instruction cache to be flushed from userspace.  Despite RISC-V
index 3a5a2ee31547b2ca1f3ec0f0cf613ff3448e85e3..b4a7d4427fbb9430e02cdc1855729a9eba90c815 100644 (file)
@@ -64,7 +64,7 @@ int riscv_of_processor_hartid(struct device_node *node)
 
 static void print_isa(struct seq_file *f, const char *orig_isa)
 {
-       static const char *ext = "mafdc";
+       static const char *ext = "mafdcsu";
        const char *isa = orig_isa;
        const char *e;
 
@@ -88,11 +88,14 @@ static void print_isa(struct seq_file *f, const char *orig_isa)
        /*
         * Check the rest of the ISA string for valid extensions, printing those
         * we find.  RISC-V ISA strings define an order, so we only print the
-        * extension bits when they're in order.
+        * extension bits when they're in order. Hide the supervisor (S)
+        * extension from userspace as it's not accessible from there.
         */
        for (e = ext; *e != '\0'; ++e) {
                if (isa[0] == e[0]) {
-                       seq_write(f, isa, 1);
+                       if (isa[0] != 's')
+                               seq_write(f, isa, 1);
+
                        isa++;
                }
        }
index 711190d473d41f47dd52f9fc4720df720ebf57be..fe884cd69abd8f0d7b3fe3a9e20b781937a32502 100644 (file)
@@ -44,6 +44,16 @@ ENTRY(_start)
        amoadd.w a3, a2, (a3)
        bnez a3, .Lsecondary_start
 
+       /* Clear BSS for flat non-ELF images */
+       la a3, __bss_start
+       la a4, __bss_stop
+       ble a4, a3, clear_bss_done
+clear_bss:
+       REG_S zero, (a3)
+       add a3, a3, RISCV_SZPTR
+       blt a3, a4, clear_bss
+clear_bss_done:
+
        /* Save hart ID and DTB physical address */
        mv s0, a0
        mv s1, a1
index ece84991609ca56d2d3549d1a2dde2139a943028..65df1dfdc30385be7a9a149034a0ba66a5bbbd8e 100644 (file)
@@ -74,7 +74,7 @@ SECTIONS
                *(.sbss*)
        }
 
-       BSS_SECTION(0, 0, 0)
+       BSS_SECTION(PAGE_SIZE, PAGE_SIZE, 0)
 
        EXCEPTION_TABLE(0x10)
        NOTES
index 222785af550b46736676808b6e00d8d8cef9a286..5fda4f7bf15d176fbb913435ea0a25c510c8df5a 100644 (file)
@@ -791,7 +791,7 @@ static int emit_compare_and_branch(const u8 code, const u8 dst, u8 src,
 }
 
 /* Just skip the save instruction and the ctx register move.  */
-#define BPF_TAILCALL_PROLOGUE_SKIP     16
+#define BPF_TAILCALL_PROLOGUE_SKIP     32
 #define BPF_TAILCALL_CNT_SP_OFF                (STACK_BIAS + 128)
 
 static void build_prologue(struct jit_ctx *ctx)
@@ -824,9 +824,15 @@ static void build_prologue(struct jit_ctx *ctx)
                const u8 vfp = bpf2sparc[BPF_REG_FP];
 
                emit(ADD | IMMED | RS1(FP) | S13(STACK_BIAS) | RD(vfp), ctx);
+       } else {
+               emit_nop(ctx);
        }
 
        emit_reg_move(I0, O0, ctx);
+       emit_reg_move(I1, O1, ctx);
+       emit_reg_move(I2, O2, ctx);
+       emit_reg_move(I3, O3, ctx);
+       emit_reg_move(I4, O4, ctx);
        /* If you add anything here, adjust BPF_TAILCALL_PROLOGUE_SKIP above. */
 }
 
@@ -1270,6 +1276,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
                const u8 tmp2 = bpf2sparc[TMP_REG_2];
                u32 opcode = 0, rs2;
 
+               if (insn->dst_reg == BPF_REG_FP)
+                       ctx->saw_frame_pointer = true;
+
                ctx->tmp_2_used = true;
                emit_loadimm(imm, tmp2, ctx);
 
@@ -1308,6 +1317,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
                const u8 tmp = bpf2sparc[TMP_REG_1];
                u32 opcode = 0, rs2;
 
+               if (insn->dst_reg == BPF_REG_FP)
+                       ctx->saw_frame_pointer = true;
+
                switch (BPF_SIZE(code)) {
                case BPF_W:
                        opcode = ST32;
@@ -1340,6 +1352,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
                const u8 tmp2 = bpf2sparc[TMP_REG_2];
                const u8 tmp3 = bpf2sparc[TMP_REG_3];
 
+               if (insn->dst_reg == BPF_REG_FP)
+                       ctx->saw_frame_pointer = true;
+
                ctx->tmp_1_used = true;
                ctx->tmp_2_used = true;
                ctx->tmp_3_used = true;
@@ -1360,6 +1375,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
                const u8 tmp2 = bpf2sparc[TMP_REG_2];
                const u8 tmp3 = bpf2sparc[TMP_REG_3];
 
+               if (insn->dst_reg == BPF_REG_FP)
+                       ctx->saw_frame_pointer = true;
+
                ctx->tmp_1_used = true;
                ctx->tmp_2_used = true;
                ctx->tmp_3_used = true;
@@ -1425,12 +1443,12 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
        struct bpf_prog *tmp, *orig_prog = prog;
        struct sparc64_jit_data *jit_data;
        struct bpf_binary_header *header;
+       u32 prev_image_size, image_size;
        bool tmp_blinded = false;
        bool extra_pass = false;
        struct jit_ctx ctx;
-       u32 image_size;
        u8 *image_ptr;
-       int pass;
+       int pass, i;
 
        if (!prog->jit_requested)
                return orig_prog;
@@ -1461,61 +1479,82 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
                header = jit_data->header;
                extra_pass = true;
                image_size = sizeof(u32) * ctx.idx;
+               prev_image_size = image_size;
+               pass = 1;
                goto skip_init_ctx;
        }
 
        memset(&ctx, 0, sizeof(ctx));
        ctx.prog = prog;
 
-       ctx.offset = kcalloc(prog->len, sizeof(unsigned int), GFP_KERNEL);
+       ctx.offset = kmalloc_array(prog->len, sizeof(unsigned int), GFP_KERNEL);
        if (ctx.offset == NULL) {
                prog = orig_prog;
                goto out_off;
        }
 
-       /* Fake pass to detect features used, and get an accurate assessment
-        * of what the final image size will be.
+       /* Longest sequence emitted is for bswap32, 12 instructions.  Pre-cook
+        * the offset array so that we converge faster.
         */
-       if (build_body(&ctx)) {
-               prog = orig_prog;
-               goto out_off;
-       }
-       build_prologue(&ctx);
-       build_epilogue(&ctx);
-
-       /* Now we know the actual image size. */
-       image_size = sizeof(u32) * ctx.idx;
-       header = bpf_jit_binary_alloc(image_size, &image_ptr,
-                                     sizeof(u32), jit_fill_hole);
-       if (header == NULL) {
-               prog = orig_prog;
-               goto out_off;
-       }
+       for (i = 0; i < prog->len; i++)
+               ctx.offset[i] = i * (12 * 4);
 
-       ctx.image = (u32 *)image_ptr;
-skip_init_ctx:
-       for (pass = 1; pass < 3; pass++) {
+       prev_image_size = ~0U;
+       for (pass = 1; pass < 40; pass++) {
                ctx.idx = 0;
 
                build_prologue(&ctx);
-
                if (build_body(&ctx)) {
-                       bpf_jit_binary_free(header);
                        prog = orig_prog;
                        goto out_off;
                }
-
                build_epilogue(&ctx);
 
                if (bpf_jit_enable > 1)
-                       pr_info("Pass %d: shrink = %d, seen = [%c%c%c%c%c%c]\n", pass,
-                               image_size - (ctx.idx * 4),
+                       pr_info("Pass %d: size = %u, seen = [%c%c%c%c%c%c]\n", pass,
+                               ctx.idx * 4,
                                ctx.tmp_1_used ? '1' : ' ',
                                ctx.tmp_2_used ? '2' : ' ',
                                ctx.tmp_3_used ? '3' : ' ',
                                ctx.saw_frame_pointer ? 'F' : ' ',
                                ctx.saw_call ? 'C' : ' ',
                                ctx.saw_tail_call ? 'T' : ' ');
+
+               if (ctx.idx * 4 == prev_image_size)
+                       break;
+               prev_image_size = ctx.idx * 4;
+               cond_resched();
+       }
+
+       /* Now we know the actual image size. */
+       image_size = sizeof(u32) * ctx.idx;
+       header = bpf_jit_binary_alloc(image_size, &image_ptr,
+                                     sizeof(u32), jit_fill_hole);
+       if (header == NULL) {
+               prog = orig_prog;
+               goto out_off;
+       }
+
+       ctx.image = (u32 *)image_ptr;
+skip_init_ctx:
+       ctx.idx = 0;
+
+       build_prologue(&ctx);
+
+       if (build_body(&ctx)) {
+               bpf_jit_binary_free(header);
+               prog = orig_prog;
+               goto out_off;
+       }
+
+       build_epilogue(&ctx);
+
+       if (ctx.idx * 4 != prev_image_size) {
+               pr_err("bpf_jit: Failed to converge, prev_size=%u size=%d\n",
+                      prev_image_size, ctx.idx * 4);
+               bpf_jit_binary_free(header);
+               prog = orig_prog;
+               goto out_off;
        }
 
        if (bpf_jit_enable > 1)
index 55e51ff7e421f80b9145036b9356aa1a63ff21ce..fbda5a917c5b772dca40724bb2c24c189c38be91 100644 (file)
@@ -1094,7 +1094,8 @@ struct kvm_x86_ops {
        bool (*has_wbinvd_exit)(void);
 
        u64 (*read_l1_tsc_offset)(struct kvm_vcpu *vcpu);
-       void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);
+       /* Returns actual tsc_offset set in active VMCS */
+       u64 (*write_l1_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);
 
        void (*get_exit_info)(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2);
 
index 89db20f8cb707666494c906bafedf958508ed12d..c4533d05c214b9e5d776217b5f9e6cec885d31ef 100644 (file)
@@ -55,7 +55,7 @@
 #define PRIo64 "o"
 
 /* #define apic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg) */
-#define apic_debug(fmt, arg...)
+#define apic_debug(fmt, arg...) do {} while (0)
 
 /* 14 is the version for Xeon and Pentium 8.4.8*/
 #define APIC_VERSION                   (0x14UL | ((KVM_APIC_LVT_NUM - 1) << 16))
@@ -576,6 +576,11 @@ int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low,
        rcu_read_lock();
        map = rcu_dereference(kvm->arch.apic_map);
 
+       if (unlikely(!map)) {
+               count = -EOPNOTSUPP;
+               goto out;
+       }
+
        if (min > map->max_apic_id)
                goto out;
        /* Bits above cluster_size are masked in the caller.  */
index cf5f572f230520b4f00694b0afe8ec6738e89868..7c03c0f35444ff9a112a2f3406a894477eaddc2c 100644 (file)
@@ -5074,9 +5074,9 @@ static bool need_remote_flush(u64 old, u64 new)
 }
 
 static u64 mmu_pte_write_fetch_gpte(struct kvm_vcpu *vcpu, gpa_t *gpa,
-                                   const u8 *new, int *bytes)
+                                   int *bytes)
 {
-       u64 gentry;
+       u64 gentry = 0;
        int r;
 
        /*
@@ -5088,22 +5088,12 @@ static u64 mmu_pte_write_fetch_gpte(struct kvm_vcpu *vcpu, gpa_t *gpa,
                /* Handle a 32-bit guest writing two halves of a 64-bit gpte */
                *gpa &= ~(gpa_t)7;
                *bytes = 8;
-               r = kvm_vcpu_read_guest(vcpu, *gpa, &gentry, 8);
-               if (r)
-                       gentry = 0;
-               new = (const u8 *)&gentry;
        }
 
-       switch (*bytes) {
-       case 4:
-               gentry = *(const u32 *)new;
-               break;
-       case 8:
-               gentry = *(const u64 *)new;
-               break;
-       default:
-               gentry = 0;
-               break;
+       if (*bytes == 4 || *bytes == 8) {
+               r = kvm_vcpu_read_guest_atomic(vcpu, *gpa, &gentry, *bytes);
+               if (r)
+                       gentry = 0;
        }
 
        return gentry;
@@ -5207,8 +5197,6 @@ static void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
 
        pgprintk("%s: gpa %llx bytes %d\n", __func__, gpa, bytes);
 
-       gentry = mmu_pte_write_fetch_gpte(vcpu, &gpa, new, &bytes);
-
        /*
         * No need to care whether allocation memory is successful
         * or not since pte prefetch is skiped if it does not have
@@ -5217,6 +5205,9 @@ static void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
        mmu_topup_memory_caches(vcpu);
 
        spin_lock(&vcpu->kvm->mmu_lock);
+
+       gentry = mmu_pte_write_fetch_gpte(vcpu, &gpa, &bytes);
+
        ++vcpu->kvm->stat.mmu_pte_write;
        kvm_mmu_audit(vcpu, AUDIT_PRE_PTE_WRITE);
 
index 0e21ccc46792f6bcc6665ff63979f23979aa1829..cc6467b35a85f6cec9300011cfa0c464574ed5d3 100644 (file)
@@ -1446,7 +1446,7 @@ static u64 svm_read_l1_tsc_offset(struct kvm_vcpu *vcpu)
        return vcpu->arch.tsc_offset;
 }
 
-static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
+static u64 svm_write_l1_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
        u64 g_tsc_offset = 0;
@@ -1464,6 +1464,7 @@ static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
        svm->vmcb->control.tsc_offset = offset + g_tsc_offset;
 
        mark_dirty(svm->vmcb, VMCB_INTERCEPTS);
+       return svm->vmcb->control.tsc_offset;
 }
 
 static void avic_init_vmcb(struct vcpu_svm *svm)
@@ -1664,20 +1665,23 @@ static u64 *avic_get_physical_id_entry(struct kvm_vcpu *vcpu,
 static int avic_init_access_page(struct kvm_vcpu *vcpu)
 {
        struct kvm *kvm = vcpu->kvm;
-       int ret;
+       int ret = 0;
 
+       mutex_lock(&kvm->slots_lock);
        if (kvm->arch.apic_access_page_done)
-               return 0;
+               goto out;
 
-       ret = x86_set_memory_region(kvm,
-                                   APIC_ACCESS_PAGE_PRIVATE_MEMSLOT,
-                                   APIC_DEFAULT_PHYS_BASE,
-                                   PAGE_SIZE);
+       ret = __x86_set_memory_region(kvm,
+                                     APIC_ACCESS_PAGE_PRIVATE_MEMSLOT,
+                                     APIC_DEFAULT_PHYS_BASE,
+                                     PAGE_SIZE);
        if (ret)
-               return ret;
+               goto out;
 
        kvm->arch.apic_access_page_done = true;
-       return 0;
+out:
+       mutex_unlock(&kvm->slots_lock);
+       return ret;
 }
 
 static int avic_init_backing_page(struct kvm_vcpu *vcpu)
@@ -2189,21 +2193,31 @@ out:
        return ERR_PTR(err);
 }
 
+static void svm_clear_current_vmcb(struct vmcb *vmcb)
+{
+       int i;
+
+       for_each_online_cpu(i)
+               cmpxchg(&per_cpu(svm_data, i)->current_vmcb, vmcb, NULL);
+}
+
 static void svm_free_vcpu(struct kvm_vcpu *vcpu)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
 
+       /*
+        * The vmcb page can be recycled, causing a false negative in
+        * svm_vcpu_load(). So, ensure that no logical CPU has this
+        * vmcb page recorded as its current vmcb.
+        */
+       svm_clear_current_vmcb(svm->vmcb);
+
        __free_page(pfn_to_page(__sme_clr(svm->vmcb_pa) >> PAGE_SHIFT));
        __free_pages(virt_to_page(svm->msrpm), MSRPM_ALLOC_ORDER);
        __free_page(virt_to_page(svm->nested.hsave));
        __free_pages(virt_to_page(svm->nested.msrpm), MSRPM_ALLOC_ORDER);
        kvm_vcpu_uninit(vcpu);
        kmem_cache_free(kvm_vcpu_cache, svm);
-       /*
-        * The vmcb page can be recycled, causing a false negative in
-        * svm_vcpu_load(). So do a full IBPB now.
-        */
-       indirect_branch_prediction_barrier();
 }
 
 static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
@@ -7149,7 +7163,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
        .has_wbinvd_exit = svm_has_wbinvd_exit,
 
        .read_l1_tsc_offset = svm_read_l1_tsc_offset,
-       .write_tsc_offset = svm_write_tsc_offset,
+       .write_l1_tsc_offset = svm_write_l1_tsc_offset,
 
        .set_tdp_cr3 = set_tdp_cr3,
 
index 4555077d69ce204148facb207f46ddf882483231..02edd9960e9d94cf8cbac80ea1bfccc5673f3089 100644 (file)
@@ -174,6 +174,7 @@ module_param_named(preemption_timer, enable_preemption_timer, bool, S_IRUGO);
  * refer SDM volume 3b section 21.6.13 & 22.1.3.
  */
 static unsigned int ple_gap = KVM_DEFAULT_PLE_GAP;
+module_param(ple_gap, uint, 0444);
 
 static unsigned int ple_window = KVM_VMX_DEFAULT_PLE_WINDOW;
 module_param(ple_window, uint, 0444);
@@ -984,6 +985,7 @@ struct vcpu_vmx {
        struct shared_msr_entry *guest_msrs;
        int                   nmsrs;
        int                   save_nmsrs;
+       bool                  guest_msrs_dirty;
        unsigned long         host_idt_base;
 #ifdef CONFIG_X86_64
        u64                   msr_host_kernel_gs_base;
@@ -1306,7 +1308,7 @@ static void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked);
 static bool nested_vmx_is_page_fault_vmexit(struct vmcs12 *vmcs12,
                                            u16 error_code);
 static void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu);
-static void __always_inline vmx_disable_intercept_for_msr(unsigned long *msr_bitmap,
+static __always_inline void vmx_disable_intercept_for_msr(unsigned long *msr_bitmap,
                                                          u32 msr, int type);
 
 static DEFINE_PER_CPU(struct vmcs *, vmxarea);
@@ -1610,12 +1612,6 @@ static int nested_enable_evmcs(struct kvm_vcpu *vcpu,
 {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
 
-       /* We don't support disabling the feature for simplicity. */
-       if (vmx->nested.enlightened_vmcs_enabled)
-               return 0;
-
-       vmx->nested.enlightened_vmcs_enabled = true;
-
        /*
         * vmcs_version represents the range of supported Enlightened VMCS
         * versions: lower 8 bits is the minimal version, higher 8 bits is the
@@ -1625,6 +1621,12 @@ static int nested_enable_evmcs(struct kvm_vcpu *vcpu,
        if (vmcs_version)
                *vmcs_version = (KVM_EVMCS_VERSION << 8) | 1;
 
+       /* We don't support disabling the feature for simplicity. */
+       if (vmx->nested.enlightened_vmcs_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;
@@ -2897,6 +2899,20 @@ static void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
 
        vmx->req_immediate_exit = false;
 
+       /*
+        * Note that guest MSRs to be saved/restored can also be changed
+        * when guest state is loaded. This happens when guest transitions
+        * to/from long-mode by setting MSR_EFER.LMA.
+        */
+       if (!vmx->loaded_cpu_state || vmx->guest_msrs_dirty) {
+               vmx->guest_msrs_dirty = false;
+               for (i = 0; i < vmx->save_nmsrs; ++i)
+                       kvm_set_shared_msr(vmx->guest_msrs[i].index,
+                                          vmx->guest_msrs[i].data,
+                                          vmx->guest_msrs[i].mask);
+
+       }
+
        if (vmx->loaded_cpu_state)
                return;
 
@@ -2957,11 +2973,6 @@ static void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
                vmcs_writel(HOST_GS_BASE, gs_base);
                host_state->gs_base = gs_base;
        }
-
-       for (i = 0; i < vmx->save_nmsrs; ++i)
-               kvm_set_shared_msr(vmx->guest_msrs[i].index,
-                                  vmx->guest_msrs[i].data,
-                                  vmx->guest_msrs[i].mask);
 }
 
 static void vmx_prepare_switch_to_host(struct vcpu_vmx *vmx)
@@ -3436,6 +3447,7 @@ static void setup_msrs(struct vcpu_vmx *vmx)
                move_msr_up(vmx, index, save_nmsrs++);
 
        vmx->save_nmsrs = save_nmsrs;
+       vmx->guest_msrs_dirty = true;
 
        if (cpu_has_vmx_msr_bitmap())
                vmx_update_msr_bitmap(&vmx->vcpu);
@@ -3452,11 +3464,9 @@ static u64 vmx_read_l1_tsc_offset(struct kvm_vcpu *vcpu)
        return vcpu->arch.tsc_offset;
 }
 
-/*
- * writes 'offset' into guest's timestamp counter offset register
- */
-static void vmx_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
+static u64 vmx_write_l1_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
 {
+       u64 active_offset = offset;
        if (is_guest_mode(vcpu)) {
                /*
                 * We're here if L1 chose not to trap WRMSR to TSC. According
@@ -3464,17 +3474,16 @@ static void vmx_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
                 * set for L2 remains unchanged, and still needs to be added
                 * to the newly set TSC to get L2's TSC.
                 */
-               struct vmcs12 *vmcs12;
-               /* recalculate vmcs02.TSC_OFFSET: */
-               vmcs12 = get_vmcs12(vcpu);
-               vmcs_write64(TSC_OFFSET, offset +
-                       (nested_cpu_has(vmcs12, CPU_BASED_USE_TSC_OFFSETING) ?
-                        vmcs12->tsc_offset : 0));
+               struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
+               if (nested_cpu_has(vmcs12, CPU_BASED_USE_TSC_OFFSETING))
+                       active_offset += vmcs12->tsc_offset;
        } else {
                trace_kvm_write_tsc_offset(vcpu->vcpu_id,
                                           vmcs_read64(TSC_OFFSET), offset);
-               vmcs_write64(TSC_OFFSET, offset);
        }
+
+       vmcs_write64(TSC_OFFSET, active_offset);
+       return active_offset;
 }
 
 /*
@@ -5944,7 +5953,7 @@ static void free_vpid(int vpid)
        spin_unlock(&vmx_vpid_lock);
 }
 
-static void __always_inline vmx_disable_intercept_for_msr(unsigned long *msr_bitmap,
+static __always_inline void vmx_disable_intercept_for_msr(unsigned long *msr_bitmap,
                                                          u32 msr, int type)
 {
        int f = sizeof(unsigned long);
@@ -5982,7 +5991,7 @@ static void __always_inline vmx_disable_intercept_for_msr(unsigned long *msr_bit
        }
 }
 
-static void __always_inline vmx_enable_intercept_for_msr(unsigned long *msr_bitmap,
+static __always_inline void vmx_enable_intercept_for_msr(unsigned long *msr_bitmap,
                                                         u32 msr, int type)
 {
        int f = sizeof(unsigned long);
@@ -6020,7 +6029,7 @@ static void __always_inline vmx_enable_intercept_for_msr(unsigned long *msr_bitm
        }
 }
 
-static void __always_inline vmx_set_intercept_for_msr(unsigned long *msr_bitmap,
+static __always_inline void vmx_set_intercept_for_msr(unsigned long *msr_bitmap,
                                                      u32 msr, int type, bool value)
 {
        if (value)
@@ -8664,8 +8673,6 @@ static int copy_enlightened_to_vmcs12(struct vcpu_vmx *vmx)
        struct vmcs12 *vmcs12 = vmx->nested.cached_vmcs12;
        struct hv_enlightened_vmcs *evmcs = vmx->nested.hv_evmcs;
 
-       vmcs12->hdr.revision_id = evmcs->revision_id;
-
        /* HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE */
        vmcs12->tpr_threshold = evmcs->tpr_threshold;
        vmcs12->guest_rip = evmcs->guest_rip;
@@ -9369,7 +9376,30 @@ static int nested_vmx_handle_enlightened_vmptrld(struct kvm_vcpu *vcpu,
 
                vmx->nested.hv_evmcs = kmap(vmx->nested.hv_evmcs_page);
 
-               if (vmx->nested.hv_evmcs->revision_id != VMCS12_REVISION) {
+               /*
+                * Currently, KVM only supports eVMCS version 1
+                * (== KVM_EVMCS_VERSION) and thus we expect guest to set this
+                * value to first u32 field of eVMCS which should specify eVMCS
+                * VersionNumber.
+                *
+                * Guest should be aware of supported eVMCS versions by host by
+                * examining CPUID.0x4000000A.EAX[0:15]. Host userspace VMM is
+                * expected to set this CPUID leaf according to the value
+                * returned in vmcs_version from nested_enable_evmcs().
+                *
+                * However, it turns out that Microsoft Hyper-V fails to comply
+                * to their own invented interface: When Hyper-V use eVMCS, it
+                * just sets first u32 field of eVMCS to revision_id specified
+                * in MSR_IA32_VMX_BASIC. Instead of used eVMCS version number
+                * which is one of the supported versions specified in
+                * CPUID.0x4000000A.EAX[0:15].
+                *
+                * To overcome Hyper-V bug, we accept here either a supported
+                * eVMCS version or VMCS12 revision_id as valid values for first
+                * u32 field of eVMCS.
+                */
+               if ((vmx->nested.hv_evmcs->revision_id != KVM_EVMCS_VERSION) &&
+                   (vmx->nested.hv_evmcs->revision_id != VMCS12_REVISION)) {
                        nested_release_evmcs(vcpu);
                        return 0;
                }
@@ -9390,9 +9420,11 @@ static int nested_vmx_handle_enlightened_vmptrld(struct kvm_vcpu *vcpu,
                 * present in struct hv_enlightened_vmcs, ...). Make sure there
                 * are no leftovers.
                 */
-               if (from_launch)
-                       memset(vmx->nested.cached_vmcs12, 0,
-                              sizeof(*vmx->nested.cached_vmcs12));
+               if (from_launch) {
+                       struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
+                       memset(vmcs12, 0, sizeof(*vmcs12));
+                       vmcs12->hdr.revision_id = VMCS12_REVISION;
+               }
 
        }
        return 1;
@@ -15062,7 +15094,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
        .has_wbinvd_exit = cpu_has_vmx_wbinvd_exit,
 
        .read_l1_tsc_offset = vmx_read_l1_tsc_offset,
-       .write_tsc_offset = vmx_write_tsc_offset,
+       .write_l1_tsc_offset = vmx_write_l1_tsc_offset,
 
        .set_tdp_cr3 = vmx_set_cr3,
 
index 5cd5647120f2b439a8d63b52d223499b48e5ff9e..d02937760c3ba8adc6de37ed4b39db9a926f320d 100644 (file)
@@ -1665,8 +1665,7 @@ EXPORT_SYMBOL_GPL(kvm_read_l1_tsc);
 
 static void kvm_vcpu_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
 {
-       kvm_x86_ops->write_tsc_offset(vcpu, offset);
-       vcpu->arch.tsc_offset = offset;
+       vcpu->arch.tsc_offset = kvm_x86_ops->write_l1_tsc_offset(vcpu, offset);
 }
 
 static inline bool kvm_check_tsc_unstable(void)
@@ -1794,7 +1793,8 @@ EXPORT_SYMBOL_GPL(kvm_write_tsc);
 static inline void adjust_tsc_offset_guest(struct kvm_vcpu *vcpu,
                                           s64 adjustment)
 {
-       kvm_vcpu_write_tsc_offset(vcpu, vcpu->arch.tsc_offset + adjustment);
+       u64 tsc_offset = kvm_x86_ops->read_l1_tsc_offset(vcpu);
+       kvm_vcpu_write_tsc_offset(vcpu, tsc_offset + adjustment);
 }
 
 static inline void adjust_tsc_offset_host(struct kvm_vcpu *vcpu, s64 adjustment)
@@ -6918,6 +6918,7 @@ static int kvm_pv_clock_pairing(struct kvm_vcpu *vcpu, gpa_t paddr,
        clock_pairing.nsec = ts.tv_nsec;
        clock_pairing.tsc = kvm_read_l1_tsc(vcpu, cycle);
        clock_pairing.flags = 0;
+       memset(&clock_pairing.pad, 0, sizeof(clock_pairing.pad));
 
        ret = 0;
        if (kvm_write_guest(vcpu->kvm, paddr, &clock_pairing,
@@ -7455,7 +7456,8 @@ static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
        else {
                if (vcpu->arch.apicv_active)
                        kvm_x86_ops->sync_pir_to_irr(vcpu);
-               kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors);
+               if (ioapic_in_kernel(vcpu->kvm))
+                       kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors);
        }
 
        if (is_guest_mode(vcpu))
index 67904f55f1884f52893b3a99b1be785a48dc69da..120dd746a14751f3de4317a35921b2037d8c7cdd 100644 (file)
@@ -94,14 +94,14 @@ int main(void)
        DEFINE(THREAD_SP, offsetof (struct task_struct, thread.sp));
        DEFINE(THREAD_CPENABLE, offsetof (struct thread_info, cpenable));
 #if XTENSA_HAVE_COPROCESSORS
-       DEFINE(THREAD_XTREGS_CP0, offsetof (struct thread_info, xtregs_cp));
-       DEFINE(THREAD_XTREGS_CP1, offsetof (struct thread_info, xtregs_cp));
-       DEFINE(THREAD_XTREGS_CP2, offsetof (struct thread_info, xtregs_cp));
-       DEFINE(THREAD_XTREGS_CP3, offsetof (struct thread_info, xtregs_cp));
-       DEFINE(THREAD_XTREGS_CP4, offsetof (struct thread_info, xtregs_cp));
-       DEFINE(THREAD_XTREGS_CP5, offsetof (struct thread_info, xtregs_cp));
-       DEFINE(THREAD_XTREGS_CP6, offsetof (struct thread_info, xtregs_cp));
-       DEFINE(THREAD_XTREGS_CP7, offsetof (struct thread_info, xtregs_cp));
+       DEFINE(THREAD_XTREGS_CP0, offsetof(struct thread_info, xtregs_cp.cp0));
+       DEFINE(THREAD_XTREGS_CP1, offsetof(struct thread_info, xtregs_cp.cp1));
+       DEFINE(THREAD_XTREGS_CP2, offsetof(struct thread_info, xtregs_cp.cp2));
+       DEFINE(THREAD_XTREGS_CP3, offsetof(struct thread_info, xtregs_cp.cp3));
+       DEFINE(THREAD_XTREGS_CP4, offsetof(struct thread_info, xtregs_cp.cp4));
+       DEFINE(THREAD_XTREGS_CP5, offsetof(struct thread_info, xtregs_cp.cp5));
+       DEFINE(THREAD_XTREGS_CP6, offsetof(struct thread_info, xtregs_cp.cp6));
+       DEFINE(THREAD_XTREGS_CP7, offsetof(struct thread_info, xtregs_cp.cp7));
 #endif
        DEFINE(THREAD_XTREGS_USER, offsetof (struct thread_info, xtregs_user));
        DEFINE(XTREGS_USER_SIZE, sizeof(xtregs_user_t));
index 483dcfb6e681d7d483ef8ebfb948d91b7ee8f1fd..4bb68133a72af93ad00e82d08abb7d26a783b86d 100644 (file)
@@ -94,18 +94,21 @@ void coprocessor_release_all(struct thread_info *ti)
 
 void coprocessor_flush_all(struct thread_info *ti)
 {
-       unsigned long cpenable;
+       unsigned long cpenable, old_cpenable;
        int i;
 
        preempt_disable();
 
+       RSR_CPENABLE(old_cpenable);
        cpenable = ti->cpenable;
+       WSR_CPENABLE(cpenable);
 
        for (i = 0; i < XCHAL_CP_MAX; i++) {
                if ((cpenable & 1) != 0 && coprocessor_owner[i] == ti)
                        coprocessor_flush(ti, i);
                cpenable >>= 1;
        }
+       WSR_CPENABLE(old_cpenable);
 
        preempt_enable();
 }
index c0845cb1cbb9944ed7deaee9bffa3685171574c3..d9541be0605ad52793e5d59a11b2a8dda7f975a7 100644 (file)
@@ -127,12 +127,37 @@ static int ptrace_setregs(struct task_struct *child, void __user *uregs)
 }
 
 
+#if XTENSA_HAVE_COPROCESSORS
+#define CP_OFFSETS(cp) \
+       { \
+               .elf_xtregs_offset = offsetof(elf_xtregs_t, cp), \
+               .ti_offset = offsetof(struct thread_info, xtregs_cp.cp), \
+               .sz = sizeof(xtregs_ ## cp ## _t), \
+       }
+
+static const struct {
+       size_t elf_xtregs_offset;
+       size_t ti_offset;
+       size_t sz;
+} cp_offsets[] = {
+       CP_OFFSETS(cp0),
+       CP_OFFSETS(cp1),
+       CP_OFFSETS(cp2),
+       CP_OFFSETS(cp3),
+       CP_OFFSETS(cp4),
+       CP_OFFSETS(cp5),
+       CP_OFFSETS(cp6),
+       CP_OFFSETS(cp7),
+};
+#endif
+
 static int ptrace_getxregs(struct task_struct *child, void __user *uregs)
 {
        struct pt_regs *regs = task_pt_regs(child);
        struct thread_info *ti = task_thread_info(child);
        elf_xtregs_t __user *xtregs = uregs;
        int ret = 0;
+       int i __maybe_unused;
 
        if (!access_ok(VERIFY_WRITE, uregs, sizeof(elf_xtregs_t)))
                return -EIO;
@@ -140,8 +165,13 @@ static int ptrace_getxregs(struct task_struct *child, void __user *uregs)
 #if XTENSA_HAVE_COPROCESSORS
        /* Flush all coprocessor registers to memory. */
        coprocessor_flush_all(ti);
-       ret |= __copy_to_user(&xtregs->cp0, &ti->xtregs_cp,
-                             sizeof(xtregs_coprocessor_t));
+
+       for (i = 0; i < ARRAY_SIZE(cp_offsets); ++i)
+               ret |= __copy_to_user((char __user *)xtregs +
+                                     cp_offsets[i].elf_xtregs_offset,
+                                     (const char *)ti +
+                                     cp_offsets[i].ti_offset,
+                                     cp_offsets[i].sz);
 #endif
        ret |= __copy_to_user(&xtregs->opt, &regs->xtregs_opt,
                              sizeof(xtregs->opt));
@@ -157,6 +187,7 @@ static int ptrace_setxregs(struct task_struct *child, void __user *uregs)
        struct pt_regs *regs = task_pt_regs(child);
        elf_xtregs_t *xtregs = uregs;
        int ret = 0;
+       int i __maybe_unused;
 
        if (!access_ok(VERIFY_READ, uregs, sizeof(elf_xtregs_t)))
                return -EFAULT;
@@ -166,8 +197,11 @@ static int ptrace_setxregs(struct task_struct *child, void __user *uregs)
        coprocessor_flush_all(ti);
        coprocessor_release_all(ti);
 
-       ret |= __copy_from_user(&ti->xtregs_cp, &xtregs->cp0,
-                               sizeof(xtregs_coprocessor_t));
+       for (i = 0; i < ARRAY_SIZE(cp_offsets); ++i)
+               ret |= __copy_from_user((char *)ti + cp_offsets[i].ti_offset,
+                                       (const char __user *)xtregs +
+                                       cp_offsets[i].elf_xtregs_offset,
+                                       cp_offsets[i].sz);
 #endif
        ret |= __copy_from_user(&regs->xtregs_opt, &xtregs->opt,
                                sizeof(xtregs->opt));
index eaa60c94205a82f685190a5c0790d6ca91df69cb..1f32caa87686e2369b0f4841447d5ab5093b993d 100644 (file)
@@ -30,6 +30,7 @@ static const struct acpi_device_id forbidden_id_list[] = {
        {"PNP0200",  0},        /* AT DMA Controller */
        {"ACPI0009", 0},        /* IOxAPIC */
        {"ACPI000A", 0},        /* IOAPIC */
+       {"SMB0001",  0},        /* ACPI SMBUS virtual device */
        {"", 0},
 };
 
index 4e46dc9e41ad01142ffdcfe1c38921df9db0ebda..11e1663bdc4dee0e2cfd7cd9ba61783d00277bbf 100644 (file)
@@ -1410,7 +1410,7 @@ static int init_q(struct fs_dev *dev, struct queue *txq, int queue,
 
        func_enter ();
 
-       fs_dprintk (FS_DEBUG_INIT, "Inititing queue at %x: %d entries:\n", 
+       fs_dprintk (FS_DEBUG_INIT, "Initializing queue at %x: %d entries:\n",
                    queue, nentries);
 
        p = aligned_kmalloc (sz, GFP_KERNEL, 0x10);
@@ -1443,7 +1443,7 @@ static int init_fp(struct fs_dev *dev, struct freepool *fp, int queue,
 {
        func_enter ();
 
-       fs_dprintk (FS_DEBUG_INIT, "Inititing free pool at %x:\n", queue);
+       fs_dprintk (FS_DEBUG_INIT, "Initializing free pool at %x:\n", queue);
 
        write_fs (dev, FP_CNF(queue), (bufsize * RBFP_RBS) | RBFP_RBSVAL | RBFP_CME);
        write_fs (dev, FP_SA(queue),  0);
index 3f0e2a14895a03dc0c4bc1d01c032d0f50a4b4ae..22b53bf268179ad8c2e873dd9637af61adf2f54d 100644 (file)
@@ -201,19 +201,28 @@ static const struct of_device_id ti_cpufreq_of_match[] = {
        {},
 };
 
+static const struct of_device_id *ti_cpufreq_match_node(void)
+{
+       struct device_node *np;
+       const struct of_device_id *match;
+
+       np = of_find_node_by_path("/");
+       match = of_match_node(ti_cpufreq_of_match, np);
+       of_node_put(np);
+
+       return match;
+}
+
 static int ti_cpufreq_probe(struct platform_device *pdev)
 {
        u32 version[VERSION_COUNT];
-       struct device_node *np;
        const struct of_device_id *match;
        struct opp_table *ti_opp_table;
        struct ti_cpufreq_data *opp_data;
        const char * const reg_names[] = {"vdd", "vbb"};
        int ret;
 
-       np = of_find_node_by_path("/");
-       match = of_match_node(ti_cpufreq_of_match, np);
-       of_node_put(np);
+       match = dev_get_platdata(&pdev->dev);
        if (!match)
                return -ENODEV;
 
@@ -290,7 +299,14 @@ fail_put_node:
 
 static int ti_cpufreq_init(void)
 {
-       platform_device_register_simple("ti-cpufreq", -1, NULL, 0);
+       const struct of_device_id *match;
+
+       /* Check to ensure we are on a compatible platform */
+       match = ti_cpufreq_match_node();
+       if (match)
+               platform_device_register_data(NULL, "ti-cpufreq", -1, match,
+                                             sizeof(*match));
+
        return 0;
 }
 module_init(ti_cpufreq_init);
index 5b44ef226904f9be2530b992c3d06ed338dca53c..fc359ca4503d127fda5f9f631f95d98c4a1d671a 100644 (file)
@@ -184,6 +184,7 @@ static long udmabuf_create(const struct udmabuf_create_list *head,
        exp_info.ops  = &udmabuf_ops;
        exp_info.size = ubuf->pagecount << PAGE_SHIFT;
        exp_info.priv = ubuf;
+       exp_info.flags = O_RDWR;
 
        buf = dma_buf_export(&exp_info);
        if (IS_ERR(buf)) {
index b01ba4438501a959de7796dc2eff67a6126d88e3..31e891f00175c635a9ee92c7e0f090eb135fc29b 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/of.h>
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
+#include <linux/sched.h>
 #include <linux/serdev.h>
 #include <linux/slab.h>
 
@@ -63,7 +64,7 @@ static int gnss_serial_write_raw(struct gnss_device *gdev,
        int ret;
 
        /* write is only buffered synchronously */
-       ret = serdev_device_write(serdev, buf, count, 0);
+       ret = serdev_device_write(serdev, buf, count, MAX_SCHEDULE_TIMEOUT);
        if (ret < 0)
                return ret;
 
index 79cb98950013bbb60f4ff4126cd562453441045a..71d014edd16760d6c37dad72836ed9e13cbfffba 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
+#include <linux/sched.h>
 #include <linux/serdev.h>
 #include <linux/slab.h>
 #include <linux/wait.h>
@@ -83,7 +84,7 @@ static int sirf_write_raw(struct gnss_device *gdev, const unsigned char *buf,
        int ret;
 
        /* write is only buffered synchronously */
-       ret = serdev_device_write(serdev, buf, count, 0);
+       ret = serdev_device_write(serdev, buf, count, MAX_SCHEDULE_TIMEOUT);
        if (ret < 0)
                return ret;
 
index 8269cffc2967f772ba2da14e566fd136bb68da56..6a50f9f59c901b6d38069a67b5b9f7881e8a43b6 100644 (file)
@@ -35,8 +35,8 @@
 #define gpio_mockup_err(...)   pr_err(GPIO_MOCKUP_NAME ": " __VA_ARGS__)
 
 enum {
-       GPIO_MOCKUP_DIR_OUT = 0,
-       GPIO_MOCKUP_DIR_IN = 1,
+       GPIO_MOCKUP_DIR_IN = 0,
+       GPIO_MOCKUP_DIR_OUT = 1,
 };
 
 /*
@@ -131,7 +131,7 @@ static int gpio_mockup_get_direction(struct gpio_chip *gc, unsigned int offset)
 {
        struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
 
-       return chip->lines[offset].dir;
+       return !chip->lines[offset].dir;
 }
 
 static int gpio_mockup_to_irq(struct gpio_chip *gc, unsigned int offset)
index bfe4c5c9f41cef3a9c3a483e5283e015d840bc91..e9600b556f397babf8c472ceb2b012f2de97b42a 100644 (file)
@@ -268,8 +268,8 @@ static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 
        if (pxa_gpio_has_pinctrl()) {
                ret = pinctrl_gpio_direction_input(chip->base + offset);
-               if (!ret)
-                       return 0;
+               if (ret)
+                       return ret;
        }
 
        spin_lock_irqsave(&gpio_lock, flags);
index 230e41562462b27fdf5d11874b3de8c34c107707..a2cbb474901c224bebae335cd0789273a78955ae 100644 (file)
@@ -1295,7 +1295,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
        gdev->descs = kcalloc(chip->ngpio, sizeof(gdev->descs[0]), GFP_KERNEL);
        if (!gdev->descs) {
                status = -ENOMEM;
-               goto err_free_gdev;
+               goto err_free_ida;
        }
 
        if (chip->ngpio == 0) {
@@ -1427,8 +1427,9 @@ err_free_label:
        kfree_const(gdev->label);
 err_free_descs:
        kfree(gdev->descs);
-err_free_gdev:
+err_free_ida:
        ida_simple_remove(&gpio_ida, gdev->id);
+err_free_gdev:
        /* failures here can mean systems won't boot... */
        pr_err("%s: GPIOs %d..%d (%s) failed to register, %d\n", __func__,
               gdev->base, gdev->base + gdev->ngpio - 1,
index c31a8849e9f87705ed3abac2ac23bfcbc7303d85..1580ec60b89f753ce2e12018b2a07eb936802d2e 100644 (file)
@@ -501,8 +501,11 @@ void amdgpu_amdkfd_set_compute_idle(struct kgd_dev *kgd, bool idle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
 
-       amdgpu_dpm_switch_power_profile(adev,
-                                       PP_SMC_POWER_PROFILE_COMPUTE, !idle);
+       if (adev->powerplay.pp_funcs &&
+           adev->powerplay.pp_funcs->switch_power_profile)
+               amdgpu_dpm_switch_power_profile(adev,
+                                               PP_SMC_POWER_PROFILE_COMPUTE,
+                                               !idle);
 }
 
 bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid)
index 6748cd7fc129b0e7b83966da865f674c676c04e1..686a26de50f91e816471548bf3c1a0fc3f86db86 100644 (file)
@@ -626,6 +626,13 @@ int amdgpu_display_modeset_create_props(struct amdgpu_device *adev)
                                         "dither",
                                         amdgpu_dither_enum_list, sz);
 
+       if (amdgpu_device_has_dc_support(adev)) {
+               adev->mode_info.max_bpc_property =
+                       drm_property_create_range(adev->ddev, 0, "max bpc", 8, 16);
+               if (!adev->mode_info.max_bpc_property)
+                       return -ENOMEM;
+       }
+
        return 0;
 }
 
index b9e9e8b02fb756a0d7291c605353d59cd228826e..d1b4d9b6aae0d1743f77dc2373d0c9159d03f937 100644 (file)
@@ -339,6 +339,8 @@ struct amdgpu_mode_info {
        struct drm_property *audio_property;
        /* FMT dithering */
        struct drm_property *dither_property;
+       /* maximum number of bits per channel for monitor color */
+       struct drm_property *max_bpc_property;
        /* hardcoded DFP edid from BIOS */
        struct edid *bios_hardcoded_edid;
        int bios_hardcoded_edid_size;
index e1c2b4e9c7b23a10ac3b1b2b5375d2bf84eae9c2..73ad02aea2b2e802f0dbce340d70877bdc3b6ca1 100644 (file)
@@ -46,6 +46,7 @@ MODULE_FIRMWARE("amdgpu/tahiti_mc.bin");
 MODULE_FIRMWARE("amdgpu/pitcairn_mc.bin");
 MODULE_FIRMWARE("amdgpu/verde_mc.bin");
 MODULE_FIRMWARE("amdgpu/oland_mc.bin");
+MODULE_FIRMWARE("amdgpu/hainan_mc.bin");
 MODULE_FIRMWARE("amdgpu/si58_mc.bin");
 
 #define MC_SEQ_MISC0__MT__MASK   0xf0000000
index bf5e6a413dee6e9b5de53f62ad7547ecb5e5b23e..4cc0dcb1a1875bfc559affd1f55e268a25e6282e 100644 (file)
 #define mmMP0_MISC_LIGHT_SLEEP_CTRL                                                             0x01ba
 #define mmMP0_MISC_LIGHT_SLEEP_CTRL_BASE_IDX                                                    0
 
+/* for Vega20 register name change */
+#define mmHDP_MEM_POWER_CTRL   0x00d4
+#define HDP_MEM_POWER_CTRL__IPH_MEM_POWER_CTRL_EN_MASK 0x00000001L
+#define HDP_MEM_POWER_CTRL__IPH_MEM_POWER_LS_EN_MASK   0x00000002L
+#define HDP_MEM_POWER_CTRL__RC_MEM_POWER_CTRL_EN_MASK  0x00010000L
+#define HDP_MEM_POWER_CTRL__RC_MEM_POWER_LS_EN_MASK            0x00020000L
+#define mmHDP_MEM_POWER_CTRL_BASE_IDX  0
 /*
  * Indirect registers accessor
  */
@@ -870,15 +877,33 @@ static void soc15_update_hdp_light_sleep(struct amdgpu_device *adev, bool enable
 {
        uint32_t def, data;
 
-       def = data = RREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_LS));
+       if (adev->asic_type == CHIP_VEGA20) {
+               def = data = RREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_CTRL));
 
-       if (enable && (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS))
-               data |= HDP_MEM_POWER_LS__LS_ENABLE_MASK;
-       else
-               data &= ~HDP_MEM_POWER_LS__LS_ENABLE_MASK;
+               if (enable && (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS))
+                       data |= HDP_MEM_POWER_CTRL__IPH_MEM_POWER_CTRL_EN_MASK |
+                               HDP_MEM_POWER_CTRL__IPH_MEM_POWER_LS_EN_MASK |
+                               HDP_MEM_POWER_CTRL__RC_MEM_POWER_CTRL_EN_MASK |
+                               HDP_MEM_POWER_CTRL__RC_MEM_POWER_LS_EN_MASK;
+               else
+                       data &= ~(HDP_MEM_POWER_CTRL__IPH_MEM_POWER_CTRL_EN_MASK |
+                               HDP_MEM_POWER_CTRL__IPH_MEM_POWER_LS_EN_MASK |
+                               HDP_MEM_POWER_CTRL__RC_MEM_POWER_CTRL_EN_MASK |
+                               HDP_MEM_POWER_CTRL__RC_MEM_POWER_LS_EN_MASK);
 
-       if (def != data)
-               WREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_LS), data);
+               if (def != data)
+                       WREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_CTRL), data);
+       } else {
+               def = data = RREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_LS));
+
+               if (enable && (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS))
+                       data |= HDP_MEM_POWER_LS__LS_ENABLE_MASK;
+               else
+                       data &= ~HDP_MEM_POWER_LS__LS_ENABLE_MASK;
+
+               if (def != data)
+                       WREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_LS), data);
+       }
 }
 
 static void soc15_update_drm_clock_gating(struct amdgpu_device *adev, bool enable)
index c1262f62cd9f21400c68a6040000d31e4a9a9716..ca925200fe09240ae4f96a2ef7f633726b4cf883 100644 (file)
@@ -2358,8 +2358,15 @@ static void update_stream_scaling_settings(const struct drm_display_mode *mode,
 static enum dc_color_depth
 convert_color_depth_from_display_info(const struct drm_connector *connector)
 {
+       struct dm_connector_state *dm_conn_state =
+               to_dm_connector_state(connector->state);
        uint32_t bpc = connector->display_info.bpc;
 
+       /* TODO: Remove this when there's support for max_bpc in drm */
+       if (dm_conn_state && bpc > dm_conn_state->max_bpc)
+               /* Round down to nearest even number. */
+               bpc = dm_conn_state->max_bpc - (dm_conn_state->max_bpc & 1);
+
        switch (bpc) {
        case 0:
                /*
@@ -2943,6 +2950,9 @@ int amdgpu_dm_connector_atomic_set_property(struct drm_connector *connector,
        } else if (property == adev->mode_info.underscan_property) {
                dm_new_state->underscan_enable = val;
                ret = 0;
+       } else if (property == adev->mode_info.max_bpc_property) {
+               dm_new_state->max_bpc = val;
+               ret = 0;
        }
 
        return ret;
@@ -2985,6 +2995,9 @@ int amdgpu_dm_connector_atomic_get_property(struct drm_connector *connector,
        } else if (property == adev->mode_info.underscan_property) {
                *val = dm_state->underscan_enable;
                ret = 0;
+       } else if (property == adev->mode_info.max_bpc_property) {
+               *val = dm_state->max_bpc;
+               ret = 0;
        }
        return ret;
 }
@@ -3795,6 +3808,9 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
        drm_object_attach_property(&aconnector->base.base,
                                adev->mode_info.underscan_vborder_property,
                                0);
+       drm_object_attach_property(&aconnector->base.base,
+                               adev->mode_info.max_bpc_property,
+                               0);
 
 }
 
index 924a38a1fc446019a0aac035b018b952e3be9923..6e069d777ab22d0e733bb7bc1c62d3d3370cc265 100644 (file)
@@ -204,6 +204,7 @@ struct dm_connector_state {
        enum amdgpu_rmx_type scaling;
        uint8_t underscan_vborder;
        uint8_t underscan_hborder;
+       uint8_t max_bpc;
        bool underscan_enable;
        bool freesync_enable;
        bool freesync_capable;
index ed35ec0341e671ab8f5cee4d89d2417283147bf3..88f6b35ea6fee9cb7bdf40df0eeef3b3d71ee233 100644 (file)
@@ -4525,12 +4525,12 @@ static int smu7_get_sclk_od(struct pp_hwmgr *hwmgr)
        struct smu7_single_dpm_table *sclk_table = &(data->dpm_table.sclk_table);
        struct smu7_single_dpm_table *golden_sclk_table =
                        &(data->golden_dpm_table.sclk_table);
-       int value;
+       int value = sclk_table->dpm_levels[sclk_table->count - 1].value;
+       int golden_value = golden_sclk_table->dpm_levels
+                       [golden_sclk_table->count - 1].value;
 
-       value = (sclk_table->dpm_levels[sclk_table->count - 1].value -
-                       golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) *
-                       100 /
-                       golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value;
+       value -= golden_value;
+       value = DIV_ROUND_UP(value * 100, golden_value);
 
        return value;
 }
@@ -4567,12 +4567,12 @@ static int smu7_get_mclk_od(struct pp_hwmgr *hwmgr)
        struct smu7_single_dpm_table *mclk_table = &(data->dpm_table.mclk_table);
        struct smu7_single_dpm_table *golden_mclk_table =
                        &(data->golden_dpm_table.mclk_table);
-       int value;
+        int value = mclk_table->dpm_levels[mclk_table->count - 1].value;
+       int golden_value = golden_mclk_table->dpm_levels
+                       [golden_mclk_table->count - 1].value;
 
-       value = (mclk_table->dpm_levels[mclk_table->count - 1].value -
-                       golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value) *
-                       100 /
-                       golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value;
+       value -= golden_value;
+       value = DIV_ROUND_UP(value * 100, golden_value);
 
        return value;
 }
index 8c4db86bb4b770b345575564ad335d48e2681835..e2bc6e0c229f96dde7baf50d2f2189efce4c2c2e 100644 (file)
@@ -4522,15 +4522,13 @@ static int vega10_get_sclk_od(struct pp_hwmgr *hwmgr)
        struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
        struct vega10_single_dpm_table *golden_sclk_table =
                        &(data->golden_dpm_table.gfx_table);
-       int value;
-
-       value = (sclk_table->dpm_levels[sclk_table->count - 1].value -
-                       golden_sclk_table->dpm_levels
-                       [golden_sclk_table->count - 1].value) *
-                       100 /
-                       golden_sclk_table->dpm_levels
+       int value = sclk_table->dpm_levels[sclk_table->count - 1].value;
+       int golden_value = golden_sclk_table->dpm_levels
                        [golden_sclk_table->count - 1].value;
 
+       value -= golden_value;
+       value = DIV_ROUND_UP(value * 100, golden_value);
+
        return value;
 }
 
@@ -4575,16 +4573,13 @@ static int vega10_get_mclk_od(struct pp_hwmgr *hwmgr)
        struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
        struct vega10_single_dpm_table *golden_mclk_table =
                        &(data->golden_dpm_table.mem_table);
-       int value;
-
-       value = (mclk_table->dpm_levels
-                       [mclk_table->count - 1].value -
-                       golden_mclk_table->dpm_levels
-                       [golden_mclk_table->count - 1].value) *
-                       100 /
-                       golden_mclk_table->dpm_levels
+       int value = mclk_table->dpm_levels[mclk_table->count - 1].value;
+       int golden_value = golden_mclk_table->dpm_levels
                        [golden_mclk_table->count - 1].value;
 
+       value -= golden_value;
+       value = DIV_ROUND_UP(value * 100, golden_value);
+
        return value;
 }
 
index 74bc37308dc09cb8303cd42146c7d88af3a27c58..54364444ecd121dd611c30148f4e292a8ee18e1a 100644 (file)
@@ -2243,12 +2243,12 @@ static int vega12_get_sclk_od(struct pp_hwmgr *hwmgr)
        struct vega12_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
        struct vega12_single_dpm_table *golden_sclk_table =
                        &(data->golden_dpm_table.gfx_table);
-       int value;
+       int value = sclk_table->dpm_levels[sclk_table->count - 1].value;
+       int golden_value = golden_sclk_table->dpm_levels
+                       [golden_sclk_table->count - 1].value;
 
-       value = (sclk_table->dpm_levels[sclk_table->count - 1].value -
-                       golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) *
-                       100 /
-                       golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value;
+       value -= golden_value;
+       value = DIV_ROUND_UP(value * 100, golden_value);
 
        return value;
 }
@@ -2264,16 +2264,13 @@ static int vega12_get_mclk_od(struct pp_hwmgr *hwmgr)
        struct vega12_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
        struct vega12_single_dpm_table *golden_mclk_table =
                        &(data->golden_dpm_table.mem_table);
-       int value;
-
-       value = (mclk_table->dpm_levels
-                       [mclk_table->count - 1].value -
-                       golden_mclk_table->dpm_levels
-                       [golden_mclk_table->count - 1].value) *
-                       100 /
-                       golden_mclk_table->dpm_levels
+       int value = mclk_table->dpm_levels[mclk_table->count - 1].value;
+       int golden_value = golden_mclk_table->dpm_levels
                        [golden_mclk_table->count - 1].value;
 
+       value -= golden_value;
+       value = DIV_ROUND_UP(value * 100, golden_value);
+
        return value;
 }
 
index 99861f32b1f95aedfb5c64d39814baca329662c2..b4eadd47f3a44a22b95ccd12effd99924a493e24 100644 (file)
@@ -75,7 +75,17 @@ static void vega20_set_default_registry_data(struct pp_hwmgr *hwmgr)
        data->phy_clk_quad_eqn_b = PPREGKEY_VEGA20QUADRATICEQUATION_DFLT;
        data->phy_clk_quad_eqn_c = PPREGKEY_VEGA20QUADRATICEQUATION_DFLT;
 
-       data->registry_data.disallowed_features = 0x0;
+       /*
+        * Disable the following features for now:
+        *   GFXCLK DS
+        *   SOCLK DS
+        *   LCLK DS
+        *   DCEFCLK DS
+        *   FCLK DS
+        *   MP1CLK DS
+        *   MP0CLK DS
+        */
+       data->registry_data.disallowed_features = 0xE0041C00;
        data->registry_data.od_state_in_dc_support = 0;
        data->registry_data.thermal_support = 1;
        data->registry_data.skip_baco_hardware = 0;
@@ -1313,12 +1323,13 @@ static int vega20_get_sclk_od(
                        &(data->dpm_table.gfx_table);
        struct vega20_single_dpm_table *golden_sclk_table =
                        &(data->golden_dpm_table.gfx_table);
-       int value;
+       int value = sclk_table->dpm_levels[sclk_table->count - 1].value;
+       int golden_value = golden_sclk_table->dpm_levels
+                       [golden_sclk_table->count - 1].value;
 
        /* od percentage */
-       value = DIV_ROUND_UP((sclk_table->dpm_levels[sclk_table->count - 1].value -
-               golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) * 100,
-               golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value);
+       value -= golden_value;
+       value = DIV_ROUND_UP(value * 100, golden_value);
 
        return value;
 }
@@ -1358,12 +1369,13 @@ static int vega20_get_mclk_od(
                        &(data->dpm_table.mem_table);
        struct vega20_single_dpm_table *golden_mclk_table =
                        &(data->golden_dpm_table.mem_table);
-       int value;
+       int value = mclk_table->dpm_levels[mclk_table->count - 1].value;
+       int golden_value = golden_mclk_table->dpm_levels
+                       [golden_mclk_table->count - 1].value;
 
        /* od percentage */
-       value = DIV_ROUND_UP((mclk_table->dpm_levels[mclk_table->count - 1].value -
-               golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value) * 100,
-               golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value);
+       value -= golden_value;
+       value = DIV_ROUND_UP(value * 100, golden_value);
 
        return value;
 }
index 69dab82a37714853b5dfdb74dbe479f7d6c10fb1..bf589c53b908d66789679df6f4098c883150fa87 100644 (file)
@@ -60,8 +60,29 @@ static const struct pci_device_id pciidlist[] = {
 
 MODULE_DEVICE_TABLE(pci, pciidlist);
 
+static void ast_kick_out_firmware_fb(struct pci_dev *pdev)
+{
+       struct apertures_struct *ap;
+       bool primary = false;
+
+       ap = alloc_apertures(1);
+       if (!ap)
+               return;
+
+       ap->ranges[0].base = pci_resource_start(pdev, 0);
+       ap->ranges[0].size = pci_resource_len(pdev, 0);
+
+#ifdef CONFIG_X86
+       primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
+#endif
+       drm_fb_helper_remove_conflicting_framebuffers(ap, "astdrmfb", primary);
+       kfree(ap);
+}
+
 static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
+       ast_kick_out_firmware_fb(pdev);
+
        return drm_get_pci_dev(pdev, ent, &driver);
 }
 
index 5e77d456d9bb9434040107a69536815a270c7865..7c6ac3cadb6b7fabcfe9a309d5fc201db6b75bf7 100644 (file)
@@ -568,6 +568,7 @@ static int ast_crtc_do_set_base(struct drm_crtc *crtc,
        }
        ast_bo_unreserve(bo);
 
+       ast_set_offset_reg(crtc);
        ast_set_start_address_crt1(crtc, (u32)gpu_addr);
 
        return 0;
@@ -1254,7 +1255,7 @@ static int ast_cursor_move(struct drm_crtc *crtc,
        ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, ((y >> 8) & 0x07));
 
        /* dummy write to fire HWC */
-       ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xCB, 0xFF, 0x00);
+       ast_show_cursor(crtc);
 
        return 0;
 }
index a502f3e519fdb668c685f392d518361e1e0a1ef2..dd852a25d37540fdf9ee6254f08a68b98df3e9a5 100644 (file)
@@ -219,6 +219,9 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
        mutex_lock(&fb_helper->lock);
        drm_connector_list_iter_begin(dev, &conn_iter);
        drm_for_each_connector_iter(connector, &conn_iter) {
+               if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+                       continue;
+
                ret = __drm_fb_helper_add_one_connector(fb_helper, connector);
                if (ret)
                        goto fail;
index 1aaccbe7e1debd0c11440ac9acae9c15b07880d5..d4fac09095f862aed3131243957059de2df4f6b0 100644 (file)
@@ -1268,7 +1268,7 @@ relocate_entry(struct i915_vma *vma,
                else if (gen >= 4)
                        len = 4;
                else
-                       len = 3;
+                       len = 6;
 
                batch = reloc_gpu(eb, vma, len);
                if (IS_ERR(batch))
@@ -1309,6 +1309,11 @@ relocate_entry(struct i915_vma *vma,
                        *batch++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL;
                        *batch++ = addr;
                        *batch++ = target_offset;
+
+                       /* And again for good measure (blb/pnv) */
+                       *batch++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL;
+                       *batch++ = addr;
+                       *batch++ = target_offset;
                }
 
                goto out;
index 47c302543799007bee421d85039be8b016aed6e7..07999fe09ad231a037bc73379b5fc27aaf484b94 100644 (file)
@@ -3413,6 +3413,11 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
                ggtt->vm.insert_page    = bxt_vtd_ggtt_insert_page__BKL;
                if (ggtt->vm.clear_range != nop_clear_range)
                        ggtt->vm.clear_range = bxt_vtd_ggtt_clear_range__BKL;
+
+               /* Prevent recursively calling stop_machine() and deadlocks. */
+               dev_info(dev_priv->drm.dev,
+                        "Disabling error capture for VT-d workaround\n");
+               i915_disable_error_state(dev_priv, -ENODEV);
        }
 
        ggtt->invalidate = gen6_ggtt_invalidate;
index 8762d17b66591e2afc8fc9647bef2784145f2c19..3eb33e000d6f00f3ae4b3fdbc8f37f38e97b4d83 100644 (file)
@@ -648,6 +648,9 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
                return 0;
        }
 
+       if (IS_ERR(error))
+               return PTR_ERR(error);
+
        if (*error->error_msg)
                err_printf(m, "%s\n", error->error_msg);
        err_printf(m, "Kernel: " UTS_RELEASE "\n");
@@ -1859,6 +1862,7 @@ void i915_capture_error_state(struct drm_i915_private *i915,
        error = i915_capture_gpu_state(i915);
        if (!error) {
                DRM_DEBUG_DRIVER("out of memory, not capturing error state\n");
+               i915_disable_error_state(i915, -ENOMEM);
                return;
        }
 
@@ -1914,5 +1918,14 @@ void i915_reset_error_state(struct drm_i915_private *i915)
        i915->gpu_error.first_error = NULL;
        spin_unlock_irq(&i915->gpu_error.lock);
 
-       i915_gpu_state_put(error);
+       if (!IS_ERR(error))
+               i915_gpu_state_put(error);
+}
+
+void i915_disable_error_state(struct drm_i915_private *i915, int err)
+{
+       spin_lock_irq(&i915->gpu_error.lock);
+       if (!i915->gpu_error.first_error)
+               i915->gpu_error.first_error = ERR_PTR(err);
+       spin_unlock_irq(&i915->gpu_error.lock);
 }
index 8710fb18ed746cface7e9a7b2d6d6ac7cd06b2b4..3ec89a504de52331ade6a9452a844527d84ec515 100644 (file)
@@ -343,6 +343,7 @@ static inline void i915_gpu_state_put(struct i915_gpu_state *gpu)
 
 struct i915_gpu_state *i915_first_error_state(struct drm_i915_private *i915);
 void i915_reset_error_state(struct drm_i915_private *i915);
+void i915_disable_error_state(struct drm_i915_private *i915, int err);
 
 #else
 
@@ -355,13 +356,18 @@ static inline void i915_capture_error_state(struct drm_i915_private *dev_priv,
 static inline struct i915_gpu_state *
 i915_first_error_state(struct drm_i915_private *i915)
 {
-       return NULL;
+       return ERR_PTR(-ENODEV);
 }
 
 static inline void i915_reset_error_state(struct drm_i915_private *i915)
 {
 }
 
+static inline void i915_disable_error_state(struct drm_i915_private *i915,
+                                           int err)
+{
+}
+
 #endif /* IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) */
 
 #endif /* _I915_GPU_ERROR_H_ */
index a54843fdeb2f04a353c30af6e86e131c203b2868..c9878dd1f7cd04dd3a6a7b8877d8f5d95eafc620 100644 (file)
@@ -2890,6 +2890,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
        return;
 
 valid_fb:
+       intel_state->base.rotation = plane_config->rotation;
        intel_fill_fb_ggtt_view(&intel_state->view, fb,
                                intel_state->base.rotation);
        intel_state->color_plane[0].stride =
@@ -7882,8 +7883,15 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
                        plane_config->tiling = I915_TILING_X;
                        fb->modifier = I915_FORMAT_MOD_X_TILED;
                }
+
+               if (val & DISPPLANE_ROTATE_180)
+                       plane_config->rotation = DRM_MODE_ROTATE_180;
        }
 
+       if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B &&
+           val & DISPPLANE_MIRROR)
+               plane_config->rotation |= DRM_MODE_REFLECT_X;
+
        pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
        fourcc = i9xx_format_to_fourcc(pixel_format);
        fb->format = drm_format_info(fourcc);
@@ -8952,6 +8960,29 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
                goto error;
        }
 
+       /*
+        * DRM_MODE_ROTATE_ is counter clockwise to stay compatible with Xrandr
+        * while i915 HW rotation is clockwise, thats why this swapping.
+        */
+       switch (val & PLANE_CTL_ROTATE_MASK) {
+       case PLANE_CTL_ROTATE_0:
+               plane_config->rotation = DRM_MODE_ROTATE_0;
+               break;
+       case PLANE_CTL_ROTATE_90:
+               plane_config->rotation = DRM_MODE_ROTATE_270;
+               break;
+       case PLANE_CTL_ROTATE_180:
+               plane_config->rotation = DRM_MODE_ROTATE_180;
+               break;
+       case PLANE_CTL_ROTATE_270:
+               plane_config->rotation = DRM_MODE_ROTATE_90;
+               break;
+       }
+
+       if (INTEL_GEN(dev_priv) >= 10 &&
+           val & PLANE_CTL_FLIP_HORIZONTAL)
+               plane_config->rotation |= DRM_MODE_REFLECT_X;
+
        base = I915_READ(PLANE_SURF(pipe, plane_id)) & 0xfffff000;
        plane_config->base = base;
 
@@ -15267,6 +15298,14 @@ retry:
                        ret = drm_atomic_add_affected_planes(state, crtc);
                        if (ret)
                                goto out;
+
+                       /*
+                        * FIXME hack to force a LUT update to avoid the
+                        * plane update forcing the pipe gamma on without
+                        * having a proper LUT loaded. Remove once we
+                        * have readout for pipe gamma enable.
+                        */
+                       crtc_state->color_mgmt_changed = true;
                }
        }
 
index 8b298e5f012dac121385df61fa72d6a653a21354..db6fa1d0cbdae3efea1e3ddb1c3ce43bf5f8a10e 100644 (file)
@@ -547,6 +547,7 @@ struct intel_initial_plane_config {
        unsigned int tiling;
        int size;
        u32 base;
+       u8 rotation;
 };
 
 #define SKL_MIN_SRC_W 8
index 245f0022bcfd00c730f020b24326bfba90de4ea2..3fe358db12768f23a2fcf7fe971821c4cac3f1b9 100644 (file)
@@ -2493,6 +2493,9 @@ static uint32_t ilk_compute_pri_wm(const struct intel_crtc_state *cstate,
        uint32_t method1, method2;
        int cpp;
 
+       if (mem_value == 0)
+               return U32_MAX;
+
        if (!intel_wm_plane_visible(cstate, pstate))
                return 0;
 
@@ -2522,6 +2525,9 @@ static uint32_t ilk_compute_spr_wm(const struct intel_crtc_state *cstate,
        uint32_t method1, method2;
        int cpp;
 
+       if (mem_value == 0)
+               return U32_MAX;
+
        if (!intel_wm_plane_visible(cstate, pstate))
                return 0;
 
@@ -2545,6 +2551,9 @@ static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate,
 {
        int cpp;
 
+       if (mem_value == 0)
+               return U32_MAX;
+
        if (!intel_wm_plane_visible(cstate, pstate))
                return 0;
 
@@ -3008,6 +3017,34 @@ static void snb_wm_latency_quirk(struct drm_i915_private *dev_priv)
        intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency);
 }
 
+static void snb_wm_lp3_irq_quirk(struct drm_i915_private *dev_priv)
+{
+       /*
+        * On some SNB machines (Thinkpad X220 Tablet at least)
+        * LP3 usage can cause vblank interrupts to be lost.
+        * The DEIIR bit will go high but it looks like the CPU
+        * never gets interrupted.
+        *
+        * It's not clear whether other interrupt source could
+        * be affected or if this is somehow limited to vblank
+        * interrupts only. To play it safe we disable LP3
+        * watermarks entirely.
+        */
+       if (dev_priv->wm.pri_latency[3] == 0 &&
+           dev_priv->wm.spr_latency[3] == 0 &&
+           dev_priv->wm.cur_latency[3] == 0)
+               return;
+
+       dev_priv->wm.pri_latency[3] = 0;
+       dev_priv->wm.spr_latency[3] = 0;
+       dev_priv->wm.cur_latency[3] = 0;
+
+       DRM_DEBUG_KMS("LP3 watermarks disabled due to potential for lost interrupts\n");
+       intel_print_wm_latency(dev_priv, "Primary", dev_priv->wm.pri_latency);
+       intel_print_wm_latency(dev_priv, "Sprite", dev_priv->wm.spr_latency);
+       intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency);
+}
+
 static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv)
 {
        intel_read_wm_latency(dev_priv, dev_priv->wm.pri_latency);
@@ -3024,8 +3061,10 @@ static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv)
        intel_print_wm_latency(dev_priv, "Sprite", dev_priv->wm.spr_latency);
        intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency);
 
-       if (IS_GEN6(dev_priv))
+       if (IS_GEN6(dev_priv)) {
                snb_wm_latency_quirk(dev_priv);
+               snb_wm_lp3_irq_quirk(dev_priv);
+       }
 }
 
 static void skl_setup_wm_latency(struct drm_i915_private *dev_priv)
index 127468785f7484495df89a00989c17388548f9c5..1f94b9affe4bbafddede75306c3109b1368bc172 100644 (file)
@@ -214,6 +214,12 @@ static int vc4_atomic_commit(struct drm_device *dev,
                return 0;
        }
 
+       /* We know for sure we don't want an async update here. Set
+        * state->legacy_cursor_update to false to prevent
+        * drm_atomic_helper_setup_commit() from auto-completing
+        * commit->flip_done.
+        */
+       state->legacy_cursor_update = false;
        ret = drm_atomic_helper_setup_commit(state, nonblock);
        if (ret)
                return ret;
index 9dc3fcbd290bef915cea9d12472b79b3dd36db4a..c6635f23918a8c1ec07531fc6aeffede5e6e528f 100644 (file)
@@ -807,7 +807,7 @@ void vc4_plane_async_set_fb(struct drm_plane *plane, struct drm_framebuffer *fb)
 static void vc4_plane_atomic_async_update(struct drm_plane *plane,
                                          struct drm_plane_state *state)
 {
-       struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state);
+       struct vc4_plane_state *vc4_state, *new_vc4_state;
 
        if (plane->state->fb != state->fb) {
                vc4_plane_async_set_fb(plane, state->fb);
@@ -828,7 +828,18 @@ static void vc4_plane_atomic_async_update(struct drm_plane *plane,
        plane->state->src_y = state->src_y;
 
        /* Update the display list based on the new crtc_x/y. */
-       vc4_plane_atomic_check(plane, plane->state);
+       vc4_plane_atomic_check(plane, state);
+
+       new_vc4_state = to_vc4_plane_state(state);
+       vc4_state = to_vc4_plane_state(plane->state);
+
+       /* Update the current vc4_state pos0, pos2 and ptr0 dlist entries. */
+       vc4_state->dlist[vc4_state->pos0_offset] =
+               new_vc4_state->dlist[vc4_state->pos0_offset];
+       vc4_state->dlist[vc4_state->pos2_offset] =
+               new_vc4_state->dlist[vc4_state->pos2_offset];
+       vc4_state->dlist[vc4_state->ptr0_offset] =
+               new_vc4_state->dlist[vc4_state->ptr0_offset];
 
        /* Note that we can't just call vc4_plane_write_dlist()
         * because that would smash the context data that the HVS is
index c0d668944dbe876260a926c0125f4ec1ab4afc52..ed35c9a9a11090a7d4714e2cdfa83a5ca6761b6c 100644 (file)
 
 #define USB_VENDOR_ID_CIDC             0x1677
 
+#define I2C_VENDOR_ID_CIRQUE           0x0488
+#define I2C_PRODUCT_ID_CIRQUE_121F     0x121F
+
 #define USB_VENDOR_ID_CJTOUCH          0x24b8
 #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0020 0x0020
 #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0040 0x0040
 #define USB_VENDOR_ID_LG               0x1fd2
 #define USB_DEVICE_ID_LG_MULTITOUCH    0x0064
 #define USB_DEVICE_ID_LG_MELFAS_MT     0x6007
+#define I2C_DEVICE_ID_LG_8001          0x8001
 
 #define USB_VENDOR_ID_LOGITECH         0x046d
 #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e
 #define USB_DEVICE_ID_MS_TYPE_COVER_2    0x07a9
 #define USB_DEVICE_ID_MS_POWER_COVER     0x07da
 #define USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER 0x02fd
+#define USB_DEVICE_ID_MS_PIXART_MOUSE    0x00cb
 
 #define USB_VENDOR_ID_MOJO             0x8282
 #define USB_DEVICE_ID_RETRO_ADAPTER    0x3201
 #define USB_VENDOR_ID_SYMBOL           0x05e0
 #define USB_DEVICE_ID_SYMBOL_SCANNER_1 0x0800
 #define USB_DEVICE_ID_SYMBOL_SCANNER_2 0x1300
+#define USB_DEVICE_ID_SYMBOL_SCANNER_3 0x1200
 
 #define USB_VENDOR_ID_SYNAPTICS                0x06cb
 #define USB_DEVICE_ID_SYNAPTICS_TP     0x0001
 #define USB_DEVICE_ID_PRIMAX_MOUSE_4D22        0x4d22
 #define USB_DEVICE_ID_PRIMAX_KEYBOARD  0x4e05
 #define USB_DEVICE_ID_PRIMAX_REZEL     0x4e72
+#define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F 0x4d0f
+#define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22 0x4e22
 
 
 #define USB_VENDOR_ID_RISO_KAGAKU      0x1294  /* Riso Kagaku Corp. */
index a2f74e6adc70d162adf641ac3f02ae452e3552a3..d6fab579848743555c53534ad933419ad69318a9 100644 (file)
@@ -325,6 +325,9 @@ static const struct hid_device_id hid_battery_quirks[] = {
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM,
                USB_DEVICE_ID_ELECOM_BM084),
          HID_BATTERY_QUIRK_IGNORE },
+       { HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL,
+               USB_DEVICE_ID_SYMBOL_SCANNER_3),
+         HID_BATTERY_QUIRK_IGNORE },
        {}
 };
 
@@ -1838,47 +1841,3 @@ void hidinput_disconnect(struct hid_device *hid)
 }
 EXPORT_SYMBOL_GPL(hidinput_disconnect);
 
-/**
- * hid_scroll_counter_handle_scroll() - Send high- and low-resolution scroll
- *                                      events given a high-resolution wheel
- *                                      movement.
- * @counter: a hid_scroll_counter struct describing the wheel.
- * @hi_res_value: the movement of the wheel, in the mouse's high-resolution
- *                units.
- *
- * Given a high-resolution movement, this function converts the movement into
- * microns and emits high-resolution scroll events for the input device. It also
- * uses the multiplier from &struct hid_scroll_counter to emit low-resolution
- * scroll events when appropriate for backwards-compatibility with userspace
- * input libraries.
- */
-void hid_scroll_counter_handle_scroll(struct hid_scroll_counter *counter,
-                                     int hi_res_value)
-{
-       int low_res_value, remainder, multiplier;
-
-       input_report_rel(counter->dev, REL_WHEEL_HI_RES,
-                        hi_res_value * counter->microns_per_hi_res_unit);
-
-       /*
-        * Update the low-res remainder with the high-res value,
-        * but reset if the direction has changed.
-        */
-       remainder = counter->remainder;
-       if ((remainder ^ hi_res_value) < 0)
-               remainder = 0;
-       remainder += hi_res_value;
-
-       /*
-        * Then just use the resolution multiplier to see if
-        * we should send a low-res (aka regular wheel) event.
-        */
-       multiplier = counter->resolution_multiplier;
-       low_res_value = remainder / multiplier;
-       remainder -= low_res_value * multiplier;
-       counter->remainder = remainder;
-
-       if (low_res_value)
-               input_report_rel(counter->dev, REL_WHEEL, low_res_value);
-}
-EXPORT_SYMBOL_GPL(hid_scroll_counter_handle_scroll);
index f01280898b24bd7fea8770417137586823578550..19cc980eebce6a3019c44d55dcbef0002e1cda10 100644 (file)
@@ -64,14 +64,6 @@ MODULE_PARM_DESC(disable_tap_to_click,
 #define HIDPP_QUIRK_NO_HIDINPUT                        BIT(23)
 #define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS       BIT(24)
 #define HIDPP_QUIRK_UNIFYING                   BIT(25)
-#define HIDPP_QUIRK_HI_RES_SCROLL_1P0          BIT(26)
-#define HIDPP_QUIRK_HI_RES_SCROLL_X2120                BIT(27)
-#define HIDPP_QUIRK_HI_RES_SCROLL_X2121                BIT(28)
-
-/* Convenience constant to check for any high-res support. */
-#define HIDPP_QUIRK_HI_RES_SCROLL      (HIDPP_QUIRK_HI_RES_SCROLL_1P0 | \
-                                        HIDPP_QUIRK_HI_RES_SCROLL_X2120 | \
-                                        HIDPP_QUIRK_HI_RES_SCROLL_X2121)
 
 #define HIDPP_QUIRK_DELAYED_INIT               HIDPP_QUIRK_NO_HIDINPUT
 
@@ -157,7 +149,6 @@ struct hidpp_device {
        unsigned long capabilities;
 
        struct hidpp_battery battery;
-       struct hid_scroll_counter vertical_wheel_counter;
 };
 
 /* HID++ 1.0 error codes */
@@ -409,53 +400,32 @@ static void hidpp_prefix_name(char **name, int name_length)
 #define HIDPP_SET_LONG_REGISTER                                0x82
 #define HIDPP_GET_LONG_REGISTER                                0x83
 
-/**
- * hidpp10_set_register_bit() - Sets a single bit in a HID++ 1.0 register.
- * @hidpp_dev: the device to set the register on.
- * @register_address: the address of the register to modify.
- * @byte: the byte of the register to modify. Should be less than 3.
- * Return: 0 if successful, otherwise a negative error code.
- */
-static int hidpp10_set_register_bit(struct hidpp_device *hidpp_dev,
-       u8 register_address, u8 byte, u8 bit)
+#define HIDPP_REG_GENERAL                              0x00
+
+static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev)
 {
        struct hidpp_report response;
        int ret;
        u8 params[3] = { 0 };
 
        ret = hidpp_send_rap_command_sync(hidpp_dev,
-                                         REPORT_ID_HIDPP_SHORT,
-                                         HIDPP_GET_REGISTER,
-                                         register_address,
-                                         NULL, 0, &response);
+                                       REPORT_ID_HIDPP_SHORT,
+                                       HIDPP_GET_REGISTER,
+                                       HIDPP_REG_GENERAL,
+                                       NULL, 0, &response);
        if (ret)
                return ret;
 
        memcpy(params, response.rap.params, 3);
 
-       params[byte] |= BIT(bit);
+       /* Set the battery bit */
+       params[0] |= BIT(4);
 
        return hidpp_send_rap_command_sync(hidpp_dev,
-                                          REPORT_ID_HIDPP_SHORT,
-                                          HIDPP_SET_REGISTER,
-                                          register_address,
-                                          params, 3, &response);
-}
-
-
-#define HIDPP_REG_GENERAL                              0x00
-
-static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev)
-{
-       return hidpp10_set_register_bit(hidpp_dev, HIDPP_REG_GENERAL, 0, 4);
-}
-
-#define HIDPP_REG_FEATURES                             0x01
-
-/* On HID++ 1.0 devices, high-res scroll was called "scrolling acceleration". */
-static int hidpp10_enable_scrolling_acceleration(struct hidpp_device *hidpp_dev)
-{
-       return hidpp10_set_register_bit(hidpp_dev, HIDPP_REG_FEATURES, 0, 6);
+                                       REPORT_ID_HIDPP_SHORT,
+                                       HIDPP_SET_REGISTER,
+                                       HIDPP_REG_GENERAL,
+                                       params, 3, &response);
 }
 
 #define HIDPP_REG_BATTERY_STATUS                       0x07
@@ -1166,100 +1136,6 @@ static int hidpp_battery_get_property(struct power_supply *psy,
        return ret;
 }
 
-/* -------------------------------------------------------------------------- */
-/* 0x2120: Hi-resolution scrolling                                            */
-/* -------------------------------------------------------------------------- */
-
-#define HIDPP_PAGE_HI_RESOLUTION_SCROLLING                     0x2120
-
-#define CMD_HI_RESOLUTION_SCROLLING_SET_HIGHRES_SCROLLING_MODE 0x10
-
-static int hidpp_hrs_set_highres_scrolling_mode(struct hidpp_device *hidpp,
-       bool enabled, u8 *multiplier)
-{
-       u8 feature_index;
-       u8 feature_type;
-       int ret;
-       u8 params[1];
-       struct hidpp_report response;
-
-       ret = hidpp_root_get_feature(hidpp,
-                                    HIDPP_PAGE_HI_RESOLUTION_SCROLLING,
-                                    &feature_index,
-                                    &feature_type);
-       if (ret)
-               return ret;
-
-       params[0] = enabled ? BIT(0) : 0;
-       ret = hidpp_send_fap_command_sync(hidpp, feature_index,
-                                         CMD_HI_RESOLUTION_SCROLLING_SET_HIGHRES_SCROLLING_MODE,
-                                         params, sizeof(params), &response);
-       if (ret)
-               return ret;
-       *multiplier = response.fap.params[1];
-       return 0;
-}
-
-/* -------------------------------------------------------------------------- */
-/* 0x2121: HiRes Wheel                                                        */
-/* -------------------------------------------------------------------------- */
-
-#define HIDPP_PAGE_HIRES_WHEEL         0x2121
-
-#define CMD_HIRES_WHEEL_GET_WHEEL_CAPABILITY   0x00
-#define CMD_HIRES_WHEEL_SET_WHEEL_MODE         0x20
-
-static int hidpp_hrw_get_wheel_capability(struct hidpp_device *hidpp,
-       u8 *multiplier)
-{
-       u8 feature_index;
-       u8 feature_type;
-       int ret;
-       struct hidpp_report response;
-
-       ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL,
-                                    &feature_index, &feature_type);
-       if (ret)
-               goto return_default;
-
-       ret = hidpp_send_fap_command_sync(hidpp, feature_index,
-                                         CMD_HIRES_WHEEL_GET_WHEEL_CAPABILITY,
-                                         NULL, 0, &response);
-       if (ret)
-               goto return_default;
-
-       *multiplier = response.fap.params[0];
-       return 0;
-return_default:
-       hid_warn(hidpp->hid_dev,
-                "Couldn't get wheel multiplier (error %d), assuming %d.\n",
-                ret, *multiplier);
-       return ret;
-}
-
-static int hidpp_hrw_set_wheel_mode(struct hidpp_device *hidpp, bool invert,
-       bool high_resolution, bool use_hidpp)
-{
-       u8 feature_index;
-       u8 feature_type;
-       int ret;
-       u8 params[1];
-       struct hidpp_report response;
-
-       ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL,
-                                    &feature_index, &feature_type);
-       if (ret)
-               return ret;
-
-       params[0] = (invert          ? BIT(2) : 0) |
-                   (high_resolution ? BIT(1) : 0) |
-                   (use_hidpp       ? BIT(0) : 0);
-
-       return hidpp_send_fap_command_sync(hidpp, feature_index,
-                                          CMD_HIRES_WHEEL_SET_WHEEL_MODE,
-                                          params, sizeof(params), &response);
-}
-
 /* -------------------------------------------------------------------------- */
 /* 0x4301: Solar Keyboard                                                     */
 /* -------------------------------------------------------------------------- */
@@ -2523,8 +2399,7 @@ static int m560_raw_event(struct hid_device *hdev, u8 *data, int size)
                input_report_rel(mydata->input, REL_Y, v);
 
                v = hid_snto32(data[6], 8);
-               hid_scroll_counter_handle_scroll(
-                               &hidpp->vertical_wheel_counter, v);
+               input_report_rel(mydata->input, REL_WHEEL, v);
 
                input_sync(mydata->input);
        }
@@ -2652,72 +2527,6 @@ static int g920_get_config(struct hidpp_device *hidpp)
        return 0;
 }
 
-/* -------------------------------------------------------------------------- */
-/* High-resolution scroll wheels                                              */
-/* -------------------------------------------------------------------------- */
-
-/**
- * struct hi_res_scroll_info - Stores info on a device's high-res scroll wheel.
- * @product_id: the HID product ID of the device being described.
- * @microns_per_hi_res_unit: the distance moved by the user's finger for each
- *                         high-resolution unit reported by the device, in
- *                         256ths of a millimetre.
- */
-struct hi_res_scroll_info {
-       __u32 product_id;
-       int microns_per_hi_res_unit;
-};
-
-static struct hi_res_scroll_info hi_res_scroll_devices[] = {
-       { /* Anywhere MX */
-         .product_id = 0x1017, .microns_per_hi_res_unit = 445 },
-       { /* Performance MX */
-         .product_id = 0x101a, .microns_per_hi_res_unit = 406 },
-       { /* M560 */
-         .product_id = 0x402d, .microns_per_hi_res_unit = 435 },
-       { /* MX Master 2S */
-         .product_id = 0x4069, .microns_per_hi_res_unit = 406 },
-};
-
-static int hi_res_scroll_look_up_microns(__u32 product_id)
-{
-       int i;
-       int num_devices = sizeof(hi_res_scroll_devices)
-                         / sizeof(hi_res_scroll_devices[0]);
-       for (i = 0; i < num_devices; i++) {
-               if (hi_res_scroll_devices[i].product_id == product_id)
-                       return hi_res_scroll_devices[i].microns_per_hi_res_unit;
-       }
-       /* We don't have a value for this device, so use a sensible default. */
-       return 406;
-}
-
-static int hi_res_scroll_enable(struct hidpp_device *hidpp)
-{
-       int ret;
-       u8 multiplier = 8;
-
-       if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2121) {
-               ret = hidpp_hrw_set_wheel_mode(hidpp, false, true, false);
-               hidpp_hrw_get_wheel_capability(hidpp, &multiplier);
-       } else if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2120) {
-               ret = hidpp_hrs_set_highres_scrolling_mode(hidpp, true,
-                                                          &multiplier);
-       } else /* if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_1P0) */
-               ret = hidpp10_enable_scrolling_acceleration(hidpp);
-
-       if (ret)
-               return ret;
-
-       hidpp->vertical_wheel_counter.resolution_multiplier = multiplier;
-       hidpp->vertical_wheel_counter.microns_per_hi_res_unit =
-               hi_res_scroll_look_up_microns(hidpp->hid_dev->product);
-       hid_info(hidpp->hid_dev, "multiplier = %d, microns = %d\n",
-                multiplier,
-                hidpp->vertical_wheel_counter.microns_per_hi_res_unit);
-       return 0;
-}
-
 /* -------------------------------------------------------------------------- */
 /* Generic HID++ devices                                                      */
 /* -------------------------------------------------------------------------- */
@@ -2763,11 +2572,6 @@ static void hidpp_populate_input(struct hidpp_device *hidpp,
                wtp_populate_input(hidpp, input, origin_is_hid_core);
        else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560)
                m560_populate_input(hidpp, input, origin_is_hid_core);
-
-       if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) {
-               input_set_capability(input, EV_REL, REL_WHEEL_HI_RES);
-               hidpp->vertical_wheel_counter.dev = input;
-       }
 }
 
 static int hidpp_input_configured(struct hid_device *hdev,
@@ -2886,27 +2690,6 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report,
        return 0;
 }
 
-static int hidpp_event(struct hid_device *hdev, struct hid_field *field,
-       struct hid_usage *usage, __s32 value)
-{
-       /* This function will only be called for scroll events, due to the
-        * restriction imposed in hidpp_usages.
-        */
-       struct hidpp_device *hidpp = hid_get_drvdata(hdev);
-       struct hid_scroll_counter *counter = &hidpp->vertical_wheel_counter;
-       /* A scroll event may occur before the multiplier has been retrieved or
-        * the input device set, or high-res scroll enabling may fail. In such
-        * cases we must return early (falling back to default behaviour) to
-        * avoid a crash in hid_scroll_counter_handle_scroll.
-        */
-       if (!(hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) || value == 0
-           || counter->dev == NULL || counter->resolution_multiplier == 0)
-               return 0;
-
-       hid_scroll_counter_handle_scroll(counter, value);
-       return 1;
-}
-
 static int hidpp_initialize_battery(struct hidpp_device *hidpp)
 {
        static atomic_t battery_no = ATOMIC_INIT(0);
@@ -3118,9 +2901,6 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
        if (hidpp->battery.ps)
                power_supply_changed(hidpp->battery.ps);
 
-       if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL)
-               hi_res_scroll_enable(hidpp);
-
        if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) || hidpp->delayed_input)
                /* if the input nodes are already created, we can stop now */
                return;
@@ -3306,63 +3086,35 @@ static void hidpp_remove(struct hid_device *hdev)
        mutex_destroy(&hidpp->send_mutex);
 }
 
-#define LDJ_DEVICE(product) \
-       HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, \
-                  USB_VENDOR_ID_LOGITECH, (product))
-
 static const struct hid_device_id hidpp_devices[] = {
        { /* wireless touchpad */
-         LDJ_DEVICE(0x4011),
+         HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
+               USB_VENDOR_ID_LOGITECH, 0x4011),
          .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT |
                         HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS },
        { /* wireless touchpad T650 */
-         LDJ_DEVICE(0x4101),
+         HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
+               USB_VENDOR_ID_LOGITECH, 0x4101),
          .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT },
        { /* wireless touchpad T651 */
          HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
                USB_DEVICE_ID_LOGITECH_T651),
          .driver_data = HIDPP_QUIRK_CLASS_WTP },
-       { /* Mouse Logitech Anywhere MX */
-         LDJ_DEVICE(0x1017), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
-       { /* Mouse Logitech Cube */
-         LDJ_DEVICE(0x4010), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
-       { /* Mouse Logitech M335 */
-         LDJ_DEVICE(0x4050), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
-       { /* Mouse Logitech M515 */
-         LDJ_DEVICE(0x4007), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
        { /* Mouse logitech M560 */
-         LDJ_DEVICE(0x402d),
-         .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560
-               | HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
-       { /* Mouse Logitech M705 (firmware RQM17) */
-         LDJ_DEVICE(0x101b), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
-       { /* Mouse Logitech M705 (firmware RQM67) */
-         LDJ_DEVICE(0x406d), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
-       { /* Mouse Logitech M720 */
-         LDJ_DEVICE(0x405e), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
-       { /* Mouse Logitech MX Anywhere 2 */
-         LDJ_DEVICE(0x404a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
-       { LDJ_DEVICE(0xb013), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
-       { LDJ_DEVICE(0xb018), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
-       { LDJ_DEVICE(0xb01f), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
-       { /* Mouse Logitech MX Anywhere 2S */
-         LDJ_DEVICE(0x406a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
-       { /* Mouse Logitech MX Master */
-         LDJ_DEVICE(0x4041), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
-       { LDJ_DEVICE(0x4060), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
-       { LDJ_DEVICE(0x4071), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
-       { /* Mouse Logitech MX Master 2S */
-         LDJ_DEVICE(0x4069), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
-       { /* Mouse Logitech Performance MX */
-         LDJ_DEVICE(0x101a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
+         HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
+               USB_VENDOR_ID_LOGITECH, 0x402d),
+         .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560 },
        { /* Keyboard logitech K400 */
-         LDJ_DEVICE(0x4024),
+         HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
+               USB_VENDOR_ID_LOGITECH, 0x4024),
          .driver_data = HIDPP_QUIRK_CLASS_K400 },
        { /* Solar Keyboard Logitech K750 */
-         LDJ_DEVICE(0x4002),
+         HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
+               USB_VENDOR_ID_LOGITECH, 0x4002),
          .driver_data = HIDPP_QUIRK_CLASS_K750 },
 
-       { LDJ_DEVICE(HID_ANY_ID) },
+       { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
+               USB_VENDOR_ID_LOGITECH, HID_ANY_ID)},
 
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL),
                .driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS},
@@ -3371,19 +3123,12 @@ static const struct hid_device_id hidpp_devices[] = {
 
 MODULE_DEVICE_TABLE(hid, hidpp_devices);
 
-static const struct hid_usage_id hidpp_usages[] = {
-       { HID_GD_WHEEL, EV_REL, REL_WHEEL },
-       { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
-};
-
 static struct hid_driver hidpp_driver = {
        .name = "logitech-hidpp-device",
        .id_table = hidpp_devices,
        .probe = hidpp_probe,
        .remove = hidpp_remove,
        .raw_event = hidpp_raw_event,
-       .usage_table = hidpp_usages,
-       .event = hidpp_event,
        .input_configured = hidpp_input_configured,
        .input_mapping = hidpp_input_mapping,
        .input_mapped = hidpp_input_mapped,
index f7c6de2b6730b90d0c189d686fe5ea3bb88bde67..dca0a3a90fb8e9afeb27b20227073fb8b0266688 100644 (file)
@@ -1814,6 +1814,12 @@ static const struct hid_device_id mt_devices[] = {
                MT_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT,
                        USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) },
 
+       /* Cirque devices */
+       { .driver_data = MT_CLS_WIN_8_DUAL,
+               HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
+                       I2C_VENDOR_ID_CIRQUE,
+                       I2C_PRODUCT_ID_CIRQUE_121F) },
+
        /* CJTouch panels */
        { .driver_data = MT_CLS_NSMU,
                MT_USB_DEVICE(USB_VENDOR_ID_CJTOUCH,
index 8237dd86fb17fa9157fd4c97b6da734e34af9733..c85a79986b6afc4f7b4e164e4f95d2b71c949024 100644 (file)
@@ -107,6 +107,7 @@ static const struct hid_device_id hid_quirks[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A), HID_QUIRK_ALWAYS_POLL },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A), HID_QUIRK_ALWAYS_POLL },
        { HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT },
+       { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PIXART_MOUSE), HID_QUIRK_ALWAYS_POLL },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), HID_QUIRK_NO_INIT_REPORTS },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS },
@@ -129,6 +130,8 @@ static const struct hid_device_id hid_quirks[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN), HID_QUIRK_NO_INIT_REPORTS },
        { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
        { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22), HID_QUIRK_ALWAYS_POLL },
+       { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F), HID_QUIRK_ALWAYS_POLL },
+       { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22), HID_QUIRK_ALWAYS_POLL },
        { HID_USB_DEVICE(USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS), HID_QUIRK_NOGET },
        { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001), HID_QUIRK_NOGET },
        { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003), HID_QUIRK_NOGET },
index 0422ec2b13d208d98acdf22c5eb97b6393c5f530..dc4128bfe2ca95d3553c1141f03cbd618d367e5c 100644 (file)
@@ -23,8 +23,9 @@
  * In order to avoid breaking them this driver creates a layered hidraw device,
  * so it can detect when the client is running and then:
  *  - it will not send any command to the controller.
- *  - this input device will be disabled, to avoid double input of the same
+ *  - this input device will be removed, to avoid double input of the same
  *    user action.
+ * When the client is closed, this input device will be created again.
  *
  * For additional functions, such as changing the right-pad margin or switching
  * the led, you can use the user-space tool at:
@@ -113,7 +114,7 @@ struct steam_device {
        spinlock_t lock;
        struct hid_device *hdev, *client_hdev;
        struct mutex mutex;
-       bool client_opened, input_opened;
+       bool client_opened;
        struct input_dev __rcu *input;
        unsigned long quirks;
        struct work_struct work_connect;
@@ -279,18 +280,6 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable)
        }
 }
 
-static void steam_update_lizard_mode(struct steam_device *steam)
-{
-       mutex_lock(&steam->mutex);
-       if (!steam->client_opened) {
-               if (steam->input_opened)
-                       steam_set_lizard_mode(steam, false);
-               else
-                       steam_set_lizard_mode(steam, lizard_mode);
-       }
-       mutex_unlock(&steam->mutex);
-}
-
 static int steam_input_open(struct input_dev *dev)
 {
        struct steam_device *steam = input_get_drvdata(dev);
@@ -301,7 +290,6 @@ static int steam_input_open(struct input_dev *dev)
                return ret;
 
        mutex_lock(&steam->mutex);
-       steam->input_opened = true;
        if (!steam->client_opened && lizard_mode)
                steam_set_lizard_mode(steam, false);
        mutex_unlock(&steam->mutex);
@@ -313,7 +301,6 @@ static void steam_input_close(struct input_dev *dev)
        struct steam_device *steam = input_get_drvdata(dev);
 
        mutex_lock(&steam->mutex);
-       steam->input_opened = false;
        if (!steam->client_opened && lizard_mode)
                steam_set_lizard_mode(steam, true);
        mutex_unlock(&steam->mutex);
@@ -400,7 +387,7 @@ static int steam_battery_register(struct steam_device *steam)
        return 0;
 }
 
-static int steam_register(struct steam_device *steam)
+static int steam_input_register(struct steam_device *steam)
 {
        struct hid_device *hdev = steam->hdev;
        struct input_dev *input;
@@ -414,17 +401,6 @@ static int steam_register(struct steam_device *steam)
                return 0;
        }
 
-       /*
-        * Unlikely, but getting the serial could fail, and it is not so
-        * important, so make up a serial number and go on.
-        */
-       if (steam_get_serial(steam) < 0)
-               strlcpy(steam->serial_no, "XXXXXXXXXX",
-                               sizeof(steam->serial_no));
-
-       hid_info(hdev, "Steam Controller '%s' connected",
-                       steam->serial_no);
-
        input = input_allocate_device();
        if (!input)
                return -ENOMEM;
@@ -492,11 +468,6 @@ static int steam_register(struct steam_device *steam)
                goto input_register_fail;
 
        rcu_assign_pointer(steam->input, input);
-
-       /* ignore battery errors, we can live without it */
-       if (steam->quirks & STEAM_QUIRK_WIRELESS)
-               steam_battery_register(steam);
-
        return 0;
 
 input_register_fail:
@@ -504,27 +475,88 @@ input_register_fail:
        return ret;
 }
 
-static void steam_unregister(struct steam_device *steam)
+static void steam_input_unregister(struct steam_device *steam)
 {
        struct input_dev *input;
+       rcu_read_lock();
+       input = rcu_dereference(steam->input);
+       rcu_read_unlock();
+       if (!input)
+               return;
+       RCU_INIT_POINTER(steam->input, NULL);
+       synchronize_rcu();
+       input_unregister_device(input);
+}
+
+static void steam_battery_unregister(struct steam_device *steam)
+{
        struct power_supply *battery;
 
        rcu_read_lock();
-       input = rcu_dereference(steam->input);
        battery = rcu_dereference(steam->battery);
        rcu_read_unlock();
 
-       if (battery) {
-               RCU_INIT_POINTER(steam->battery, NULL);
-               synchronize_rcu();
-               power_supply_unregister(battery);
+       if (!battery)
+               return;
+       RCU_INIT_POINTER(steam->battery, NULL);
+       synchronize_rcu();
+       power_supply_unregister(battery);
+}
+
+static int steam_register(struct steam_device *steam)
+{
+       int ret;
+
+       /*
+        * This function can be called several times in a row with the
+        * wireless adaptor, without steam_unregister() between them, because
+        * another client send a get_connection_status command, for example.
+        * The battery and serial number are set just once per device.
+        */
+       if (!steam->serial_no[0]) {
+               /*
+                * Unlikely, but getting the serial could fail, and it is not so
+                * important, so make up a serial number and go on.
+                */
+               if (steam_get_serial(steam) < 0)
+                       strlcpy(steam->serial_no, "XXXXXXXXXX",
+                                       sizeof(steam->serial_no));
+
+               hid_info(steam->hdev, "Steam Controller '%s' connected",
+                               steam->serial_no);
+
+               /* ignore battery errors, we can live without it */
+               if (steam->quirks & STEAM_QUIRK_WIRELESS)
+                       steam_battery_register(steam);
+
+               mutex_lock(&steam_devices_lock);
+               list_add(&steam->list, &steam_devices);
+               mutex_unlock(&steam_devices_lock);
        }
-       if (input) {
-               RCU_INIT_POINTER(steam->input, NULL);
-               synchronize_rcu();
+
+       mutex_lock(&steam->mutex);
+       if (!steam->client_opened) {
+               steam_set_lizard_mode(steam, lizard_mode);
+               ret = steam_input_register(steam);
+       } else {
+               ret = 0;
+       }
+       mutex_unlock(&steam->mutex);
+
+       return ret;
+}
+
+static void steam_unregister(struct steam_device *steam)
+{
+       steam_battery_unregister(steam);
+       steam_input_unregister(steam);
+       if (steam->serial_no[0]) {
                hid_info(steam->hdev, "Steam Controller '%s' disconnected",
                                steam->serial_no);
-               input_unregister_device(input);
+               mutex_lock(&steam_devices_lock);
+               list_del(&steam->list);
+               mutex_unlock(&steam_devices_lock);
+               steam->serial_no[0] = 0;
        }
 }
 
@@ -600,6 +632,9 @@ static int steam_client_ll_open(struct hid_device *hdev)
        mutex_lock(&steam->mutex);
        steam->client_opened = true;
        mutex_unlock(&steam->mutex);
+
+       steam_input_unregister(steam);
+
        return ret;
 }
 
@@ -609,13 +644,13 @@ static void steam_client_ll_close(struct hid_device *hdev)
 
        mutex_lock(&steam->mutex);
        steam->client_opened = false;
-       if (steam->input_opened)
-               steam_set_lizard_mode(steam, false);
-       else
-               steam_set_lizard_mode(steam, lizard_mode);
        mutex_unlock(&steam->mutex);
 
        hid_hw_close(steam->hdev);
+       if (steam->connected) {
+               steam_set_lizard_mode(steam, lizard_mode);
+               steam_input_register(steam);
+       }
 }
 
 static int steam_client_ll_raw_request(struct hid_device *hdev,
@@ -744,11 +779,6 @@ static int steam_probe(struct hid_device *hdev,
                }
        }
 
-       mutex_lock(&steam_devices_lock);
-       steam_update_lizard_mode(steam);
-       list_add(&steam->list, &steam_devices);
-       mutex_unlock(&steam_devices_lock);
-
        return 0;
 
 hid_hw_open_fail:
@@ -774,10 +804,6 @@ static void steam_remove(struct hid_device *hdev)
                return;
        }
 
-       mutex_lock(&steam_devices_lock);
-       list_del(&steam->list);
-       mutex_unlock(&steam_devices_lock);
-
        hid_destroy_device(steam->client_hdev);
        steam->client_opened = false;
        cancel_work_sync(&steam->work_connect);
@@ -792,12 +818,14 @@ static void steam_remove(struct hid_device *hdev)
 static void steam_do_connect_event(struct steam_device *steam, bool connected)
 {
        unsigned long flags;
+       bool changed;
 
        spin_lock_irqsave(&steam->lock, flags);
+       changed = steam->connected != connected;
        steam->connected = connected;
        spin_unlock_irqrestore(&steam->lock, flags);
 
-       if (schedule_work(&steam->work_connect) == 0)
+       if (changed && schedule_work(&steam->work_connect) == 0)
                dbg_hid("%s: connected=%d event already queued\n",
                                __func__, connected);
 }
@@ -1019,13 +1047,8 @@ static int steam_raw_event(struct hid_device *hdev,
                        return 0;
                rcu_read_lock();
                input = rcu_dereference(steam->input);
-               if (likely(input)) {
+               if (likely(input))
                        steam_do_input_event(steam, input, data);
-               } else {
-                       dbg_hid("%s: input data without connect event\n",
-                                       __func__);
-                       steam_do_connect_event(steam, true);
-               }
                rcu_read_unlock();
                break;
        case STEAM_EV_CONNECT:
@@ -1074,7 +1097,10 @@ static int steam_param_set_lizard_mode(const char *val,
 
        mutex_lock(&steam_devices_lock);
        list_for_each_entry(steam, &steam_devices, list) {
-               steam_update_lizard_mode(steam);
+               mutex_lock(&steam->mutex);
+               if (!steam->client_opened)
+                       steam_set_lizard_mode(steam, lizard_mode);
+               mutex_unlock(&steam->mutex);
        }
        mutex_unlock(&steam_devices_lock);
        return 0;
index 3cde7c1b9c33cd673858d5089ed097e724fb12b0..8555ce7e737b37a78160d930a9ba12ed311e001b 100644 (file)
@@ -177,6 +177,8 @@ static const struct i2c_hid_quirks {
                I2C_HID_QUIRK_NO_RUNTIME_PM },
        { I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_4B33,
                I2C_HID_QUIRK_DELAY_AFTER_SLEEP },
+       { USB_VENDOR_ID_LG, I2C_DEVICE_ID_LG_8001,
+               I2C_HID_QUIRK_NO_RUNTIME_PM },
        { 0, 0 }
 };
 
index 3c55073136064263c0b1175cbcce60acd81d34ba..840634e0f1e3cc46235cf456a04e547f2be65ba8 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/atomic.h>
 #include <linux/compat.h>
+#include <linux/cred.h>
 #include <linux/device.h>
 #include <linux/fs.h>
 #include <linux/hid.h>
@@ -496,12 +497,13 @@ static int uhid_dev_create2(struct uhid_device *uhid,
                goto err_free;
        }
 
-       len = min(sizeof(hid->name), sizeof(ev->u.create2.name));
-       strlcpy(hid->name, ev->u.create2.name, len);
-       len = min(sizeof(hid->phys), sizeof(ev->u.create2.phys));
-       strlcpy(hid->phys, ev->u.create2.phys, len);
-       len = min(sizeof(hid->uniq), sizeof(ev->u.create2.uniq));
-       strlcpy(hid->uniq, ev->u.create2.uniq, len);
+       /* @hid is zero-initialized, strncpy() is correct, strlcpy() not */
+       len = min(sizeof(hid->name), sizeof(ev->u.create2.name)) - 1;
+       strncpy(hid->name, ev->u.create2.name, len);
+       len = min(sizeof(hid->phys), sizeof(ev->u.create2.phys)) - 1;
+       strncpy(hid->phys, ev->u.create2.phys, len);
+       len = min(sizeof(hid->uniq), sizeof(ev->u.create2.uniq)) - 1;
+       strncpy(hid->uniq, ev->u.create2.uniq, len);
 
        hid->ll_driver = &uhid_hid_driver;
        hid->bus = ev->u.create2.bus;
@@ -722,6 +724,17 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer,
 
        switch (uhid->input_buf.type) {
        case UHID_CREATE:
+               /*
+                * 'struct uhid_create_req' contains a __user pointer which is
+                * copied from, so it's unsafe to allow this with elevated
+                * privileges (e.g. from a setuid binary) or via kernel_write().
+                */
+               if (file->f_cred != current_cred() || uaccess_kernel()) {
+                       pr_err_once("UHID_CREATE from different security context by process %d (%s), this is not allowed.\n",
+                                   task_tgid_vnr(current), current->comm);
+                       ret = -EACCES;
+                       goto unlock;
+               }
                ret = uhid_dev_create(uhid, &uhid->input_buf);
                break;
        case UHID_CREATE2:
index a7513a8a8e3728d0de762d62f7337f527df34544..d6106e1a0d4af597d04cb833215c3b27c0b2aa0d 100644 (file)
@@ -353,6 +353,9 @@ static void process_ib_ipinfo(void *in_msg, void *out_msg, int op)
 
                out->body.kvp_ip_val.dhcp_enabled = in->kvp_ip_val.dhcp_enabled;
 
+               /* fallthrough */
+
+       case KVP_OP_GET_IP_INFO:
                utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.adapter_id,
                                MAX_ADAPTER_ID_SIZE,
                                UTF16_LITTLE_ENDIAN,
@@ -405,7 +408,11 @@ kvp_send_key(struct work_struct *dummy)
                process_ib_ipinfo(in_msg, message, KVP_OP_SET_IP_INFO);
                break;
        case KVP_OP_GET_IP_INFO:
-               /* We only need to pass on message->kvp_hdr.operation.  */
+               /*
+                * We only need to pass on the info of operation, adapter_id
+                * and addr_family to the userland kvp daemon.
+                */
+               process_ib_ipinfo(in_msg, message, KVP_OP_GET_IP_INFO);
                break;
        case KVP_OP_SET:
                switch (in_msg->body.kvp_set.data.value_type) {
@@ -446,9 +453,9 @@ kvp_send_key(struct work_struct *dummy)
 
                }
 
-               break;
-
-       case KVP_OP_GET:
+               /*
+                * The key is always a string - utf16 encoding.
+                */
                message->body.kvp_set.data.key_size =
                        utf16s_to_utf8s(
                        (wchar_t *)in_msg->body.kvp_set.data.key,
@@ -456,6 +463,17 @@ kvp_send_key(struct work_struct *dummy)
                        UTF16_LITTLE_ENDIAN,
                        message->body.kvp_set.data.key,
                        HV_KVP_EXCHANGE_MAX_KEY_SIZE - 1) + 1;
+
+               break;
+
+       case KVP_OP_GET:
+               message->body.kvp_get.data.key_size =
+                       utf16s_to_utf8s(
+                       (wchar_t *)in_msg->body.kvp_get.data.key,
+                       in_msg->body.kvp_get.data.key_size,
+                       UTF16_LITTLE_ENDIAN,
+                       message->body.kvp_get.data.key,
+                       HV_KVP_EXCHANGE_MAX_KEY_SIZE - 1) + 1;
                break;
 
        case KVP_OP_DELETE:
index 71d3445ba869c85654ae3dcaf3a5460e8fadb268..07ee19573b3f0f8d65d6a64710fb1bea557b42eb 100644 (file)
@@ -274,7 +274,7 @@ static int ina2xx_get_value(struct ina2xx_data *data, u8 reg,
                break;
        case INA2XX_CURRENT:
                /* signed register, result in mA */
-               val = regval * data->current_lsb_uA;
+               val = (s16)regval * data->current_lsb_uA;
                val = DIV_ROUND_CLOSEST(val, 1000);
                break;
        case INA2XX_CALIBRATION:
@@ -491,7 +491,7 @@ static int ina2xx_probe(struct i2c_client *client,
        }
 
        data->groups[group++] = &ina2xx_group;
-       if (id->driver_data == ina226)
+       if (chip == ina226)
                data->groups[group++] = &ina226_group;
 
        hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
@@ -500,7 +500,7 @@ static int ina2xx_probe(struct i2c_client *client,
                return PTR_ERR(hwmon_dev);
 
        dev_info(dev, "power monitor %s (Rshunt = %li uOhm)\n",
-                id->name, data->rshunt);
+                client->name, data->rshunt);
 
        return 0;
 }
index de46577c7d5a1711447f0f249604635260c8f958..d8fa4bea4bc8450660fc5b468c4de8d7fad1002c 100644 (file)
@@ -51,7 +51,7 @@
  */
 #define MLXREG_FAN_GET_RPM(rval, d, s) (DIV_ROUND_CLOSEST(15000000 * 100, \
                                         ((rval) + (s)) * (d)))
-#define MLXREG_FAN_GET_FAULT(val, mask) (!!((val) ^ (mask)))
+#define MLXREG_FAN_GET_FAULT(val, mask) (!((val) ^ (mask)))
 #define MLXREG_FAN_PWM_DUTY2STATE(duty)        (DIV_ROUND_CLOSEST((duty) *     \
                                         MLXREG_FAN_MAX_STATE,          \
                                         MLXREG_FAN_MAX_DUTY))
index be5ba469089531b26b0ba2d0b1866c20f3e5312b..0d0457245e7d0e19f1acad510cb5a3d295ed812f 100644 (file)
@@ -115,7 +115,6 @@ static int rpi_hwmon_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct rpi_hwmon_data *data;
-       int ret;
 
        data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
        if (!data)
@@ -124,11 +123,6 @@ static int rpi_hwmon_probe(struct platform_device *pdev)
        /* Parent driver assure that firmware is correct */
        data->fw = dev_get_drvdata(dev->parent);
 
-       /* Init throttled */
-       ret = rpi_firmware_property(data->fw, RPI_FIRMWARE_GET_THROTTLED,
-                                   &data->last_throttled,
-                                   sizeof(data->last_throttled));
-
        data->hwmon_dev = devm_hwmon_device_register_with_info(dev, "rpi_volt",
                                                               data,
                                                               &rpi_chip_info,
index 49276bbdac3ddf0dc1153cb1941cf28f0ac10ea7..1bb80f992aa8609ed6df25973548efdfdbc7fe8c 100644 (file)
@@ -1691,7 +1691,7 @@ store_sf_setup(struct device *dev, struct device_attribute *attr,
  * somewhere else in the code
  */
 #define SENSOR_ATTR_TEMP(index) {                                      \
-       SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \
+       SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 5 ? S_IWUSR : 0), \
                show_temp_mode, store_temp_mode, NOT_USED, index - 1),  \
        SENSOR_ATTR_2(temp##index##_input, S_IRUGO, show_temp,          \
                NULL, TEMP_READ, index - 1),                            \
index bb2cd29e165885d1697e4d77614a42333c5457dc..d8f7000a466aa4d2d3d79874428738fec70a4324 100644 (file)
@@ -797,7 +797,8 @@ static int iommu_init_ga_log(struct amd_iommu *iommu)
        entry = iommu_virt_to_phys(iommu->ga_log) | GA_LOG_SIZE_512;
        memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_BASE_OFFSET,
                    &entry, sizeof(entry));
-       entry = (iommu_virt_to_phys(iommu->ga_log) & 0xFFFFFFFFFFFFFULL) & ~7ULL;
+       entry = (iommu_virt_to_phys(iommu->ga_log_tail) &
+                (BIT_ULL(52)-1)) & ~7ULL;
        memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_TAIL_OFFSET,
                    &entry, sizeof(entry));
        writel(0x00, iommu->mmio_base + MMIO_GA_HEAD_OFFSET);
index f3ccf025108b4c377f2f9bc6de80e8222b817a01..41a4b8808802b8bcc30106c37b748eb3507943c0 100644 (file)
@@ -3075,7 +3075,7 @@ static int copy_context_table(struct intel_iommu *iommu,
                        }
 
                        if (old_ce)
-                               iounmap(old_ce);
+                               memunmap(old_ce);
 
                        ret = 0;
                        if (devfn < 0x80)
index db301efe126d4ac9cf2aeb606489565135db7e7d..88715090752670a5701cde52f8a4ce11baec1da4 100644 (file)
@@ -595,7 +595,7 @@ static irqreturn_t prq_event_thread(int irq, void *d)
                        pr_err("%s: Page request without PASID: %08llx %08llx\n",
                               iommu->name, ((unsigned long long *)req)[0],
                               ((unsigned long long *)req)[1]);
-                       goto bad_req;
+                       goto no_pasid;
                }
 
                if (!svm || svm->pasid != req->pasid) {
index b98a031895803a16b8e2d9d0df0a4b1686789aef..ddf3a492e1d59c1fd867f12881e6c3391038cf0f 100644 (file)
@@ -498,6 +498,9 @@ static int ipmmu_domain_init_context(struct ipmmu_vmsa_domain *domain)
 
 static void ipmmu_domain_destroy_context(struct ipmmu_vmsa_domain *domain)
 {
+       if (!domain->mmu)
+               return;
+
        /*
         * Disable the context. Flush the TLB as required when modifying the
         * context registers.
index 31d1f4ab915ea7e07f8843d1feb99217409a1af4..65a933a21e685b9c97fadc7662e34ad31c088798 100644 (file)
@@ -807,7 +807,7 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
        }
 
        if (adap->transmit_queue_sz >= CEC_MAX_MSG_TX_QUEUE_SZ) {
-               dprintk(1, "%s: transmit queue full\n", __func__);
+               dprintk(2, "%s: transmit queue full\n", __func__);
                return -EBUSY;
        }
 
@@ -1180,6 +1180,8 @@ static int cec_config_log_addr(struct cec_adapter *adap,
 {
        struct cec_log_addrs *las = &adap->log_addrs;
        struct cec_msg msg = { };
+       const unsigned int max_retries = 2;
+       unsigned int i;
        int err;
 
        if (cec_has_log_addr(adap, log_addr))
@@ -1188,19 +1190,44 @@ static int cec_config_log_addr(struct cec_adapter *adap,
        /* Send poll message */
        msg.len = 1;
        msg.msg[0] = (log_addr << 4) | log_addr;
-       err = cec_transmit_msg_fh(adap, &msg, NULL, true);
 
-       /*
-        * While trying to poll the physical address was reset
-        * and the adapter was unconfigured, so bail out.
-        */
-       if (!adap->is_configuring)
-               return -EINTR;
+       for (i = 0; i < max_retries; i++) {
+               err = cec_transmit_msg_fh(adap, &msg, NULL, true);
 
-       if (err)
-               return err;
+               /*
+                * While trying to poll the physical address was reset
+                * and the adapter was unconfigured, so bail out.
+                */
+               if (!adap->is_configuring)
+                       return -EINTR;
+
+               if (err)
+                       return err;
 
-       if (msg.tx_status & CEC_TX_STATUS_OK)
+               /*
+                * The message was aborted due to a disconnect or
+                * unconfigure, just bail out.
+                */
+               if (msg.tx_status & CEC_TX_STATUS_ABORTED)
+                       return -EINTR;
+               if (msg.tx_status & CEC_TX_STATUS_OK)
+                       return 0;
+               if (msg.tx_status & CEC_TX_STATUS_NACK)
+                       break;
+               /*
+                * Retry up to max_retries times if the message was neither
+                * OKed or NACKed. This can happen due to e.g. a Lost
+                * Arbitration condition.
+                */
+       }
+
+       /*
+        * If we are unable to get an OK or a NACK after max_retries attempts
+        * (and note that each attempt already consists of four polls), then
+        * then we assume that something is really weird and that it is not a
+        * good idea to try and claim this logical address.
+        */
+       if (i == max_retries)
                return 0;
 
        /*
index ca5d92942820a2fcb439ec1e7d277dd445214276..41d470d9ca943ea84653f9dd8bfb0ab83dafe1a4 100644 (file)
@@ -1918,7 +1918,6 @@ static int tc358743_probe_of(struct tc358743_state *state)
        ret = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep), &endpoint);
        if (ret) {
                dev_err(dev, "failed to parse endpoint\n");
-               ret = ret;
                goto put_node;
        }
 
index 452eb9b42140bb927e7af8287dcbe99b45ef51dd..447baaebca4486c4b5c3b8c5dc261ec3e4cd2ce8 100644 (file)
@@ -1844,14 +1844,12 @@ fail_mutex_destroy:
 static void cio2_pci_remove(struct pci_dev *pci_dev)
 {
        struct cio2_device *cio2 = pci_get_drvdata(pci_dev);
-       unsigned int i;
 
+       media_device_unregister(&cio2->media_dev);
        cio2_notifier_exit(cio2);
+       cio2_queues_exit(cio2);
        cio2_fbpt_exit_dummy(cio2);
-       for (i = 0; i < CIO2_QUEUES; i++)
-               cio2_queue_exit(cio2, &cio2->queue[i]);
        v4l2_device_unregister(&cio2->v4l2_dev);
-       media_device_unregister(&cio2->media_dev);
        media_device_cleanup(&cio2->media_dev);
        mutex_destroy(&cio2->lock);
 }
index 77fb7987b42f33cda57dc8b6627d4befc2d7a83e..13f2828d880df373ff494d10416ecb16be873bf7 100644 (file)
@@ -1587,6 +1587,8 @@ static void isp_pm_complete(struct device *dev)
 
 static void isp_unregister_entities(struct isp_device *isp)
 {
+       media_device_unregister(&isp->media_dev);
+
        omap3isp_csi2_unregister_entities(&isp->isp_csi2a);
        omap3isp_ccp2_unregister_entities(&isp->isp_ccp2);
        omap3isp_ccdc_unregister_entities(&isp->isp_ccdc);
@@ -1597,7 +1599,6 @@ static void isp_unregister_entities(struct isp_device *isp)
        omap3isp_stat_unregister_entities(&isp->isp_hist);
 
        v4l2_device_unregister(&isp->v4l2_dev);
-       media_device_unregister(&isp->media_dev);
        media_device_cleanup(&isp->media_dev);
 }
 
index 1eb9132bfc85fdad1ab68d81442fb435be0ac0f0..b292cff26c8663636a3cc959688032c8d79e6b3d 100644 (file)
@@ -42,7 +42,7 @@ MODULE_PARM_DESC(debug, " activates debug info");
 #define MAX_WIDTH              4096U
 #define MIN_WIDTH              640U
 #define MAX_HEIGHT             2160U
-#define MIN_HEIGHT             480U
+#define MIN_HEIGHT             360U
 
 #define dprintk(dev, fmt, arg...) \
        v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
index af150a0395dfb55ef55bf606df4825ec5b807912..d82db738f174ef048d663d366b4950cd732c2b43 100644 (file)
@@ -1009,7 +1009,7 @@ static const struct v4l2_m2m_ops m2m_ops = {
 
 static const struct media_device_ops m2m_media_ops = {
        .req_validate = vb2_request_validate,
-       .req_queue = vb2_m2m_request_queue,
+       .req_queue = v4l2_m2m_request_queue,
 };
 
 static int vim2m_probe(struct platform_device *pdev)
index 6e37950292cd9b832d589e1728fba7d28d469794..5f2b033a7a42f1cb35dd13e40a498232bd3a225d 100644 (file)
@@ -1664,6 +1664,11 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
                    p_mpeg2_slice_params->forward_ref_index >= VIDEO_MAX_FRAME)
                        return -EINVAL;
 
+               if (p_mpeg2_slice_params->pad ||
+                   p_mpeg2_slice_params->picture.pad ||
+                   p_mpeg2_slice_params->sequence.pad)
+                       return -EINVAL;
+
                return 0;
 
        case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION:
index a3ef1f50a4b3496dcfbe7cb4332a3bab9a3acc56..481e3c65cf97a63202e1223b106c59b5e670651b 100644 (file)
@@ -193,6 +193,22 @@ int v4l2_event_pending(struct v4l2_fh *fh)
 }
 EXPORT_SYMBOL_GPL(v4l2_event_pending);
 
+static void __v4l2_event_unsubscribe(struct v4l2_subscribed_event *sev)
+{
+       struct v4l2_fh *fh = sev->fh;
+       unsigned int i;
+
+       lockdep_assert_held(&fh->subscribe_lock);
+       assert_spin_locked(&fh->vdev->fh_lock);
+
+       /* Remove any pending events for this subscription */
+       for (i = 0; i < sev->in_use; i++) {
+               list_del(&sev->events[sev_pos(sev, i)].list);
+               fh->navailable--;
+       }
+       list_del(&sev->list);
+}
+
 int v4l2_event_subscribe(struct v4l2_fh *fh,
                         const struct v4l2_event_subscription *sub, unsigned elems,
                         const struct v4l2_subscribed_event_ops *ops)
@@ -224,27 +240,23 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
 
        spin_lock_irqsave(&fh->vdev->fh_lock, flags);
        found_ev = v4l2_event_subscribed(fh, sub->type, sub->id);
+       if (!found_ev)
+               list_add(&sev->list, &fh->subscribed);
        spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
 
        if (found_ev) {
                /* Already listening */
                kvfree(sev);
-               goto out_unlock;
-       }
-
-       if (sev->ops && sev->ops->add) {
+       } else if (sev->ops && sev->ops->add) {
                ret = sev->ops->add(sev, elems);
                if (ret) {
+                       spin_lock_irqsave(&fh->vdev->fh_lock, flags);
+                       __v4l2_event_unsubscribe(sev);
+                       spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
                        kvfree(sev);
-                       goto out_unlock;
                }
        }
 
-       spin_lock_irqsave(&fh->vdev->fh_lock, flags);
-       list_add(&sev->list, &fh->subscribed);
-       spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
-
-out_unlock:
        mutex_unlock(&fh->subscribe_lock);
 
        return ret;
@@ -279,7 +291,6 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh,
 {
        struct v4l2_subscribed_event *sev;
        unsigned long flags;
-       int i;
 
        if (sub->type == V4L2_EVENT_ALL) {
                v4l2_event_unsubscribe_all(fh);
@@ -291,14 +302,8 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh,
        spin_lock_irqsave(&fh->vdev->fh_lock, flags);
 
        sev = v4l2_event_subscribed(fh, sub->type, sub->id);
-       if (sev != NULL) {
-               /* Remove any pending events for this subscription */
-               for (i = 0; i < sev->in_use; i++) {
-                       list_del(&sev->events[sev_pos(sev, i)].list);
-                       fh->navailable--;
-               }
-               list_del(&sev->list);
-       }
+       if (sev != NULL)
+               __v4l2_event_unsubscribe(sev);
 
        spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
 
index d7806db222d83b87f39175fb53c06178d98b363e..1ed2465972acab4d0fae6aa4a8d28c966167d224 100644 (file)
@@ -953,7 +953,7 @@ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx,
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_buf_queue);
 
-void vb2_m2m_request_queue(struct media_request *req)
+void v4l2_m2m_request_queue(struct media_request *req)
 {
        struct media_request_object *obj, *obj_safe;
        struct v4l2_m2m_ctx *m2m_ctx = NULL;
@@ -997,7 +997,7 @@ void vb2_m2m_request_queue(struct media_request *req)
        if (m2m_ctx)
                v4l2_m2m_try_schedule(m2m_ctx);
 }
-EXPORT_SYMBOL_GPL(vb2_m2m_request_queue);
+EXPORT_SYMBOL_GPL(v4l2_m2m_request_queue);
 
 /* Videobuf2 ioctl helpers */
 
index b2a0340f277e268739c288e6bb73f62321475c30..d8e3cc2dc7470d8deaa3b89a5855b22b034725db 100644 (file)
@@ -132,7 +132,7 @@ static const struct of_device_id atmel_ssc_dt_ids[] = {
 MODULE_DEVICE_TABLE(of, atmel_ssc_dt_ids);
 #endif
 
-static inline const struct atmel_ssc_platform_data * __init
+static inline const struct atmel_ssc_platform_data *
        atmel_ssc_get_driver_data(struct platform_device *pdev)
 {
        if (pdev->dev.of_node) {
index 313da31502626897a61a65606aa117d0d67dc83b..1540a7785e14743ae1b035aeb21d391af8516050 100644 (file)
@@ -27,6 +27,9 @@
 #include <linux/delay.h>
 #include <linux/bitops.h>
 #include <asm/uv/uv_hub.h>
+
+#include <linux/nospec.h>
+
 #include "gru.h"
 #include "grutables.h"
 #include "gruhandles.h"
@@ -196,6 +199,7 @@ int gru_dump_chiplet_request(unsigned long arg)
        /* Currently, only dump by gid is implemented */
        if (req.gid >= gru_max_gids)
                return -EINVAL;
+       req.gid = array_index_nospec(req.gid, gru_max_gids);
 
        gru = GID_TO_GRU(req.gid);
        ubuf = req.buf;
index 7bfd366d970dae374bae6acd36624eb23f719506..c4115bae5db187f1a331efd5c495b20bc31a5c86 100644 (file)
@@ -12,6 +12,7 @@
  *     - JMicron (hardware and technical support)
  */
 
+#include <linux/bitfield.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/highmem.h>
@@ -462,6 +463,9 @@ struct intel_host {
        u32     dsm_fns;
        int     drv_strength;
        bool    d3_retune;
+       bool    rpm_retune_ok;
+       u32     glk_rx_ctrl1;
+       u32     glk_tun_val;
 };
 
 static const guid_t intel_dsm_guid =
@@ -791,6 +795,77 @@ cleanup:
        return ret;
 }
 
+#ifdef CONFIG_PM
+#define GLK_RX_CTRL1   0x834
+#define GLK_TUN_VAL    0x840
+#define GLK_PATH_PLL   GENMASK(13, 8)
+#define GLK_DLY                GENMASK(6, 0)
+/* Workaround firmware failing to restore the tuning value */
+static void glk_rpm_retune_wa(struct sdhci_pci_chip *chip, bool susp)
+{
+       struct sdhci_pci_slot *slot = chip->slots[0];
+       struct intel_host *intel_host = sdhci_pci_priv(slot);
+       struct sdhci_host *host = slot->host;
+       u32 glk_rx_ctrl1;
+       u32 glk_tun_val;
+       u32 dly;
+
+       if (intel_host->rpm_retune_ok || !mmc_can_retune(host->mmc))
+               return;
+
+       glk_rx_ctrl1 = sdhci_readl(host, GLK_RX_CTRL1);
+       glk_tun_val = sdhci_readl(host, GLK_TUN_VAL);
+
+       if (susp) {
+               intel_host->glk_rx_ctrl1 = glk_rx_ctrl1;
+               intel_host->glk_tun_val = glk_tun_val;
+               return;
+       }
+
+       if (!intel_host->glk_tun_val)
+               return;
+
+       if (glk_rx_ctrl1 != intel_host->glk_rx_ctrl1) {
+               intel_host->rpm_retune_ok = true;
+               return;
+       }
+
+       dly = FIELD_PREP(GLK_DLY, FIELD_GET(GLK_PATH_PLL, glk_rx_ctrl1) +
+                                 (intel_host->glk_tun_val << 1));
+       if (dly == FIELD_GET(GLK_DLY, glk_rx_ctrl1))
+               return;
+
+       glk_rx_ctrl1 = (glk_rx_ctrl1 & ~GLK_DLY) | dly;
+       sdhci_writel(host, glk_rx_ctrl1, GLK_RX_CTRL1);
+
+       intel_host->rpm_retune_ok = true;
+       chip->rpm_retune = true;
+       mmc_retune_needed(host->mmc);
+       pr_info("%s: Requiring re-tune after rpm resume", mmc_hostname(host->mmc));
+}
+
+static void glk_rpm_retune_chk(struct sdhci_pci_chip *chip, bool susp)
+{
+       if (chip->pdev->device == PCI_DEVICE_ID_INTEL_GLK_EMMC &&
+           !chip->rpm_retune)
+               glk_rpm_retune_wa(chip, susp);
+}
+
+static int glk_runtime_suspend(struct sdhci_pci_chip *chip)
+{
+       glk_rpm_retune_chk(chip, true);
+
+       return sdhci_cqhci_runtime_suspend(chip);
+}
+
+static int glk_runtime_resume(struct sdhci_pci_chip *chip)
+{
+       glk_rpm_retune_chk(chip, false);
+
+       return sdhci_cqhci_runtime_resume(chip);
+}
+#endif
+
 #ifdef CONFIG_ACPI
 static int ni_set_max_freq(struct sdhci_pci_slot *slot)
 {
@@ -879,8 +954,8 @@ static const struct sdhci_pci_fixes sdhci_intel_glk_emmc = {
        .resume                 = sdhci_cqhci_resume,
 #endif
 #ifdef CONFIG_PM
-       .runtime