Merge tag 'tee-subsys-fix-for-4.21' of https://git.linaro.org/people/jens.wiklander...
authorOlof Johansson <olof@lixom.net>
Mon, 31 Dec 2018 21:05:53 +0000 (13:05 -0800)
committerOlof Johansson <olof@lixom.net>
Mon, 31 Dec 2018 21:05:53 +0000 (13:05 -0800)
Avoid possible double list_del in supplicant comms

A fix for the OP-TEE driver to avoid possible double list_del during
tee-supplicant communication while the system is shutting down.

* tag 'tee-subsys-fix-for-4.21' of https://git.linaro.org/people/jens.wiklander/linux-tee:
  tee: optee: avoid possible double list_del()

Signed-off-by: Olof Johansson <olof@lixom.net>
384 files changed:
CREDITS
Documentation/core-api/xarray.rst
Documentation/media/uapi/v4l/extended-controls.rst
MAINTAINERS
Makefile
arch/alpha/kernel/setup.c
arch/alpha/mm/numa.c
arch/arm/boot/dts/arm-realview-pb1176.dts
arch/arm/boot/dts/arm-realview-pb11mp.dts
arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
arch/arm/boot/dts/bcm2837-rpi-3-b.dts
arch/arm/boot/dts/imx7d-nitrogen7.dts
arch/arm/boot/dts/imx7d-pico.dtsi
arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts
arch/arm/mach-imx/cpuidle-imx6sx.c
arch/arm/mach-mmp/cputype.h
arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi
arch/arm64/boot/dts/marvell/armada-ap806.dtsi
arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
arch/arm64/boot/dts/mediatek/mt7622.dtsi
arch/arm64/include/asm/memory.h
arch/arm64/mm/dma-mapping.c
arch/arm64/mm/init.c
arch/m68k/kernel/setup_mm.c
arch/m68k/mm/motorola.c
arch/powerpc/boot/Makefile
arch/powerpc/boot/crt0.S
arch/powerpc/include/asm/perf_event.h
arch/powerpc/include/uapi/asm/Kbuild
arch/powerpc/include/uapi/asm/bpf_perf_event.h [new file with mode: 0644]
arch/powerpc/kernel/legacy_serial.c
arch/powerpc/kernel/msi.c
arch/powerpc/kernel/ptrace.c
arch/powerpc/mm/dump_linuxpagetables.c
arch/powerpc/mm/init_64.c
arch/powerpc/platforms/pseries/Kconfig
arch/powerpc/platforms/pseries/papr_scm.c
arch/sh/include/asm/io.h
arch/sparc/kernel/setup_32.c
arch/sparc/kernel/setup_64.c
arch/sparc/vdso/Makefile
arch/x86/Makefile
arch/x86/entry/calling.h
arch/x86/entry/vdso/Makefile
arch/x86/include/asm/alternative-asm.h
arch/x86/include/asm/alternative.h
arch/x86/include/asm/asm.h
arch/x86/include/asm/bug.h
arch/x86/include/asm/cpufeature.h
arch/x86/include/asm/fsgsbase.h
arch/x86/include/asm/jump_label.h
arch/x86/include/asm/msr-index.h
arch/x86/include/asm/paravirt_types.h
arch/x86/include/asm/pgtable_64_types.h
arch/x86/include/asm/refcount.h
arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c
arch/x86/kernel/cpu/mtrr/if.c
arch/x86/kernel/macros.S [deleted file]
arch/x86/kernel/process_64.c
arch/x86/kernel/ptrace.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/mm/dump_pagetables.c
arch/x86/mm/pageattr.c
arch/x86/mm/pat.c
arch/x86/xen/mmu_pv.c
block/bio.c
block/blk-zoned.c
drivers/auxdisplay/charlcd.c
drivers/clk/qcom/gcc-qcs404.c
drivers/crypto/chelsio/chtls/chtls.h
drivers/crypto/chelsio/chtls/chtls_cm.c
drivers/crypto/chelsio/chtls/chtls_io.c
drivers/crypto/chelsio/chtls/chtls_main.c
drivers/gpio/gpio-max7301.c
drivers/gpio/gpio-mvebu.c
drivers/gpio/gpio-omap.c
drivers/gpio/gpiolib-acpi.c
drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdkfd/kfd_device.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
drivers/gpu/drm/amd/powerplay/inc/smu7_ppsmc.h
drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
drivers/gpu/drm/drm_ioctl.c
drivers/gpu/drm/i915/gvt/fb_decoder.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_gpu_error.c
drivers/gpu/drm/i915/intel_engine_cs.c
drivers/gpu/drm/i915/intel_lrc.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_ringbuffer.h
drivers/gpu/drm/i915/intel_workarounds.c
drivers/gpu/drm/i915/intel_workarounds.h
drivers/gpu/drm/mediatek/mtk_dsi.c
drivers/gpu/drm/nouveau/dispnv50/disp.c
drivers/gpu/drm/nouveau/nouveau_drm.c
drivers/gpu/drm/rockchip/rockchip_drm_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c
drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
drivers/gpu/drm/vmwgfx/vmwgfx_validation.h
drivers/hid/hid-ids.h
drivers/hid/hid-ite.c
drivers/hid/hid-quirks.c
drivers/hv/Kconfig
drivers/hv/vmbus_drv.c
drivers/i2c/busses/i2c-nvidia-gpu.c
drivers/infiniband/core/roce_gid_mgmt.c
drivers/infiniband/hw/hfi1/chip.c
drivers/infiniband/hw/hfi1/hfi.h
drivers/infiniband/hw/hfi1/qp.c
drivers/infiniband/hw/hfi1/verbs.c
drivers/infiniband/hw/mlx5/devx.c
drivers/infiniband/hw/mlx5/odp.c
drivers/input/keyboard/omap4-keypad.c
drivers/input/mouse/elantech.c
drivers/input/mouse/synaptics.c
drivers/md/dm-cache-metadata.c
drivers/md/dm-thin.c
drivers/md/dm-zoned-target.c
drivers/md/dm.c
drivers/media/Kconfig
drivers/media/common/videobuf2/videobuf2-core.c
drivers/media/common/videobuf2/videobuf2-v4l2.c
drivers/media/media-device.c
drivers/media/platform/vicodec/vicodec-core.c
drivers/media/platform/vivid/vivid-sdr-cap.c
drivers/media/platform/vivid/vivid-vbi-cap.c
drivers/media/platform/vivid/vivid-vbi-out.c
drivers/media/platform/vivid/vivid-vid-cap.c
drivers/media/platform/vivid/vivid-vid-out.c
drivers/media/platform/vsp1/vsp1_lif.c
drivers/media/v4l2-core/v4l2-ctrls.c
drivers/mmc/core/block.c
drivers/mmc/core/mmc.c
drivers/mmc/host/omap.c
drivers/mmc/host/omap_hsmmc.c
drivers/mmc/host/sdhci-omap.c
drivers/mmc/host/sdhci-tegra.c
drivers/mmc/host/sdhci.c
drivers/mtd/ubi/build.c
drivers/mtd/ubi/kapi.c
drivers/net/dsa/mv88e6xxx/chip.c
drivers/net/ethernet/apm/xgene/xgene_enet_main.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
drivers/net/ethernet/cadence/macb_main.c
drivers/net/ethernet/cadence/macb_ptp.c
drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
drivers/net/ethernet/hisilicon/hns/hns_enet.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_txrx.c
drivers/net/ethernet/intel/i40e/i40e_txrx_common.h
drivers/net/ethernet/intel/i40e/i40e_xsk.c
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.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_rep.c
drivers/net/ethernet/mellanox/mlx5/core/en_rx.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/fs_core.c
drivers/net/ethernet/mellanox/mlxsw/core.c
drivers/net/ethernet/mellanox/mlxsw/core.h
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_nve.c
drivers/net/ethernet/mellanox/mlxsw/trap.h
drivers/net/ethernet/microchip/lan743x_main.c
drivers/net/ethernet/mscc/ocelot.c
drivers/net/ethernet/neterion/vxge/vxge-config.c
drivers/net/ethernet/netronome/nfp/flower/offload.c
drivers/net/ethernet/nuvoton/w90p910_ether.c
drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
drivers/net/ethernet/qlogic/qed/qed_hsi.h
drivers/net/ethernet/qlogic/qed/qed_ll2.c
drivers/net/ethernet/realtek/r8169.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ieee802154/ca8210.c
drivers/net/ieee802154/mac802154_hwsim.c
drivers/net/phy/phy_device.c
drivers/net/usb/hso.c
drivers/net/usb/lan78xx.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/r8152.c
drivers/net/vxlan.c
drivers/net/wireless/ath/ath10k/core.c
drivers/net/wireless/ath/ath10k/debug.c
drivers/net/wireless/ath/ath10k/thermal.c
drivers/net/wireless/ath/ath10k/wmi-tlv.h
drivers/net/wireless/ath/ath10k/wmi.h
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
drivers/net/wireless/marvell/mwifiex/11n.c
drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
drivers/net/wireless/marvell/mwifiex/uap_txrx.c
drivers/net/wireless/mediatek/mt76/tx.c
drivers/net/wireless/realtek/rtlwifi/base.c
drivers/net/xen-netfront.c
drivers/pci/pcie/aer.c
drivers/pinctrl/meson/pinctrl-meson.c
drivers/pinctrl/qcom/pinctrl-sdm660.c
drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c
drivers/scsi/bnx2fc/bnx2fc_fcoe.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/sd.c
drivers/staging/media/sunxi/cedrus/Kconfig
drivers/staging/media/sunxi/cedrus/cedrus_hw.c
drivers/target/iscsi/cxgbit/cxgbit_cm.c
drivers/target/iscsi/cxgbit/cxgbit_main.c
drivers/thermal/hisi_thermal.c
drivers/thermal/st/stm_thermal.c
drivers/tty/serial/8250/8250_port.c
drivers/tty/serial/sunsu.c
drivers/uio/uio_hv_generic.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci.h
drivers/usb/serial/option.c
drivers/vhost/net.c
drivers/vhost/vhost.c
drivers/video/backlight/pwm_bl.c
fs/aio.c
fs/ceph/super.c
fs/ceph/super.h
fs/cifs/smb2inode.c
fs/cifs/smb2ops.c
fs/cifs/smb2proto.h
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/fuse/inode.c
fs/namei.c
fs/overlayfs/dir.c
fs/overlayfs/export.c
fs/overlayfs/inode.c
fs/proc/proc_sysctl.c
fs/ubifs/Kconfig
fs/ubifs/lpt.c
fs/ubifs/replay.c
fs/ubifs/sb.c
fs/userfaultfd.c
include/asm-generic/bug.h
include/asm-generic/fixmap.h
include/linux/compiler.h
include/linux/compiler_types.h
include/linux/dma-mapping.h
include/linux/filter.h
include/linux/mlx5/mlx5_ifc.h
include/linux/mm_types.h
include/linux/mmzone.h
include/linux/mod_devicetable.h
include/linux/netfilter/nfnetlink.h
include/linux/t10-pi.h
include/linux/xarray.h
include/media/mpeg2-ctrls.h [new file with mode: 0644]
include/media/v4l2-ctrls.h
include/media/videobuf2-core.h
include/net/ip_tunnels.h
include/net/sock.h
include/net/tls.h
include/net/xfrm.h
include/uapi/asm-generic/Kbuild.asm
include/uapi/linux/blkzoned.h
include/uapi/linux/if_tunnel.h
include/uapi/linux/in.h
include/uapi/linux/input-event-codes.h
include/uapi/linux/net_tstamp.h
include/uapi/linux/netlink.h
include/uapi/linux/v4l2-controls.h
include/uapi/linux/videodev2.h
init/Kconfig
kernel/bpf/core.c
kernel/bpf/verifier.c
kernel/dma/direct.c
kernel/fork.c
kernel/futex.c
kernel/time/posix-timers.c
kernel/trace/ftrace.c
kernel/trace/trace_events_filter.c
kernel/trace/trace_events_trigger.c
lib/radix-tree.c
lib/test_xarray.c
lib/xarray.c
mm/huge_memory.c
mm/hugetlb.c
mm/memblock.c
mm/page_alloc.c
mm/shmem.c
mm/sparse.c
net/can/raw.c
net/core/flow_dissector.c
net/core/gro_cells.c
net/core/neighbour.c
net/core/skmsg.c
net/core/sysctl_net_core.c
net/ipv4/devinet.c
net/ipv4/inet_diag.c
net/ipv4/ip_forward.c
net/ipv4/ip_fragment.c
net/ipv4/ipconfig.c
net/ipv4/ipmr.c
net/ipv4/raw.c
net/ipv6/ip6_output.c
net/ipv6/ip6_tunnel.c
net/ipv6/ip6_udp_tunnel.c
net/ipv6/ip6_vti.c
net/ipv6/ip6mr.c
net/ipv6/raw.c
net/ipv6/reassembly.c
net/mac80211/iface.c
net/mac80211/main.c
net/mac80211/status.c
net/netfilter/ipset/ip_set_list_set.c
net/netfilter/nf_conncount.c
net/netfilter/nf_conntrack_seqadj.c
net/netfilter/nf_nat_core.c
net/netfilter/nf_tables_api.c
net/netfilter/nf_tables_core.c
net/netlink/af_netlink.c
net/packet/af_packet.c
net/rds/message.c
net/rds/rdma.c
net/rds/rds.h
net/rds/send.c
net/sched/cls_flower.c
net/sctp/ipv6.c
net/smc/af_smc.c
net/smc/smc.h
net/sunrpc/clnt.c
net/sunrpc/xprt.c
net/sunrpc/xprtsock.c
net/tipc/socket.c
net/tipc/udp_media.c
net/tls/tls_main.c
net/tls/tls_sw.c
net/vmw_vsock/af_vsock.c
net/vmw_vsock/vmci_transport.c
net/wireless/nl80211.c
net/xfrm/xfrm_input.c
net/xfrm/xfrm_output.c
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c
scripts/Kbuild.include
scripts/checkstack.pl
scripts/mod/Makefile
scripts/spdxcheck.py
security/integrity/ima/ima_policy.c
security/keys/keyctl_pkey.c
security/keys/trusted.c
sound/firewire/fireface/ff-protocol-ff400.c
sound/pci/hda/patch_realtek.c
tools/include/uapi/linux/netlink.h
tools/testing/radix-tree/Makefile
tools/testing/radix-tree/main.c
tools/testing/radix-tree/regression.h
tools/testing/radix-tree/regression4.c [new file with mode: 0644]
tools/testing/selftests/bpf/bpf_flow.c
tools/testing/selftests/bpf/test_verifier.c
tools/testing/selftests/net/Makefile
tools/testing/selftests/net/test_vxlan_fdb_changelink.sh [new file with mode: 0755]
tools/testing/selftests/seccomp/seccomp_bpf.c
tools/virtio/linux/kernel.h
virt/kvm/coalesced_mmio.c

diff --git a/CREDITS b/CREDITS
index c9273393fe14c12d1eb32f2ce65aba527a00c928..7d397ee675242954fa00269477522cdfdd885068 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -2541,6 +2541,10 @@ S: Ormond
 S: Victoria 3163
 S: Australia
 
+N: Eric Miao
+E: eric.y.miao@gmail.com
+D: MMP support
+
 N: Pauline Middelink
 E: middelin@polyware.nl
 D: General low-level bug fixes, /proc fixes, identd support
@@ -4115,6 +4119,10 @@ S: 1507 145th Place SE #B5
 S: Bellevue, Washington 98007
 S: USA
 
+N: Haojian Zhuang
+E: haojian.zhuang@gmail.com
+D: MMP support
+
 N: Richard Zidlicky
 E: rz@linux-m68k.org, rdzidlic@geocities.com
 W: http://www.geocities.com/rdzidlic
index dbe96cb5558ef5024fd9607a902c25ad430b4cb7..6a6d67acaf690abfadc40c05e97a4557060dc188 100644 (file)
@@ -187,6 +187,8 @@ Takes xa_lock internally:
  * :c:func:`xa_erase_bh`
  * :c:func:`xa_erase_irq`
  * :c:func:`xa_cmpxchg`
+ * :c:func:`xa_cmpxchg_bh`
+ * :c:func:`xa_cmpxchg_irq`
  * :c:func:`xa_store_range`
  * :c:func:`xa_alloc`
  * :c:func:`xa_alloc_bh`
@@ -263,7 +265,8 @@ 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_store_bh`, :c:func:`xa_store_irq`,
-:c:func:`xa_erase_bh` and :c:func:`xa_erase_irq`.
+:c:func:`xa_erase_bh`, :c:func:`xa_erase_irq`, :c:func:`xa_cmpxchg_bh`
+and :c:func:`xa_cmpxchg_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
index 65a1d873196b6e741fc57da5658bebdc1a8f9d25..027358b91082534edb2f6da8955689ec20868ba3 100644 (file)
@@ -1505,6 +1505,11 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
     configuring a stateless hardware decoding pipeline for MPEG-2.
     The bitstream parameters are defined according to :ref:`mpeg2part2`.
 
+    .. note::
+
+       This compound control is not yet part of the public kernel API and
+       it is expected to change.
+
 .. c:type:: v4l2_ctrl_mpeg2_slice_params
 
 .. cssclass:: longtable
@@ -1625,6 +1630,11 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
     Specifies quantization matrices (as extracted from the bitstream) for the
     associated MPEG-2 slice data.
 
+    .. note::
+
+       This compound control is not yet part of the public kernel API and
+       it is expected to change.
+
 .. c:type:: v4l2_ctrl_mpeg2_quantization
 
 .. cssclass:: longtable
index 8119141a926f3a577b0a351caa71bd39a894f65f..f3a5c97e34196680db3be6e92db9386155a33b7d 100644 (file)
@@ -1739,13 +1739,17 @@ ARM/Mediatek SoC support
 M:     Matthias Brugger <matthias.bgg@gmail.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     linux-mediatek@lists.infradead.org (moderated for non-subscribers)
+W:     https://mtk.bcnfs.org/
+C:     irc://chat.freenode.net/linux-mediatek
 S:     Maintained
 F:     arch/arm/boot/dts/mt6*
 F:     arch/arm/boot/dts/mt7*
 F:     arch/arm/boot/dts/mt8*
 F:     arch/arm/mach-mediatek/
 F:     arch/arm64/boot/dts/mediatek/
+F:     drivers/soc/mediatek/
 N:     mtk
+N:     mt[678]
 K:     mediatek
 
 ARM/Mediatek USB3 PHY DRIVER
@@ -2629,6 +2633,13 @@ S:       Maintained
 F:     Documentation/devicetree/bindings/sound/axentia,*
 F:     sound/soc/atmel/tse850-pcm5142.c
 
+AXXIA I2C CONTROLLER
+M:     Krzysztof Adamski <krzysztof.adamski@nokia.com>
+L:     linux-i2c@vger.kernel.org
+S:     Maintained
+F:     Documentation/devicetree/bindings/i2c/i2c-axxia.txt
+F:     drivers/i2c/busses/i2c-axxia.c
+
 AZ6007 DVB DRIVER
 M:     Mauro Carvalho Chehab <mchehab@kernel.org>
 L:     linux-media@vger.kernel.org
@@ -4046,7 +4057,7 @@ S:        Maintained
 F:     drivers/media/dvb-frontends/cxd2820r*
 
 CXGB3 ETHERNET DRIVER (CXGB3)
-M:     Santosh Raspatur <santosh@chelsio.com>
+M:     Arjun Vynipadath <arjun@chelsio.com>
 L:     netdev@vger.kernel.org
 W:     http://www.chelsio.com
 S:     Supported
@@ -4075,7 +4086,7 @@ S:        Supported
 F:     drivers/crypto/chelsio
 
 CXGB4 ETHERNET DRIVER (CXGB4)
-M:     Ganesh Goudar <ganeshgr@chelsio.com>
+M:     Arjun Vynipadath <arjun@chelsio.com>
 L:     netdev@vger.kernel.org
 W:     http://www.chelsio.com
 S:     Supported
@@ -4843,6 +4854,7 @@ F:        include/uapi/drm/vmwgfx_drm.h
 
 DRM DRIVERS
 M:     David Airlie <airlied@linux.ie>
+M:     Daniel Vetter <daniel@ffwll.ch>
 L:     dri-devel@lists.freedesktop.org
 T:     git git://anongit.freedesktop.org/drm/drm
 B:     https://bugs.freedesktop.org/
@@ -6901,8 +6913,10 @@ Hyper-V CORE AND DRIVERS
 M:     "K. Y. Srinivasan" <kys@microsoft.com>
 M:     Haiyang Zhang <haiyangz@microsoft.com>
 M:     Stephen Hemminger <sthemmin@microsoft.com>
+M:     Sasha Levin <sashal@kernel.org>
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git
 L:     devel@linuxdriverproject.org
-S:     Maintained
+S:     Supported
 F:     Documentation/networking/netvsc.txt
 F:     arch/x86/include/asm/mshyperv.h
 F:     arch/x86/include/asm/trace/hyperv.h
@@ -8938,7 +8952,7 @@ F:        arch/mips/boot/dts/img/pistachio_marduk.dts
 
 MARVELL 88E6XXX ETHERNET SWITCH FABRIC DRIVER
 M:     Andrew Lunn <andrew@lunn.ch>
-M:     Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+M:     Vivien Didelot <vivien.didelot@gmail.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/dsa/mv88e6xxx/
@@ -9443,6 +9457,13 @@ F:       drivers/media/platform/mtk-vpu/
 F:     Documentation/devicetree/bindings/media/mediatek-vcodec.txt
 F:     Documentation/devicetree/bindings/media/mediatek-vpu.txt
 
+MEDIATEK MT76 WIRELESS LAN DRIVER
+M:     Felix Fietkau <nbd@nbd.name>
+M:     Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+L:     linux-wireless@vger.kernel.org
+S:     Maintained
+F:     drivers/net/wireless/mediatek/mt76/
+
 MEDIATEK MT7601U WIRELESS LAN DRIVER
 M:     Jakub Kicinski <kubakici@wp.pl>
 L:     linux-wireless@vger.kernel.org
@@ -10005,12 +10026,9 @@ S:     Odd Fixes
 F:     drivers/media/radio/radio-miropcm20*
 
 MMP SUPPORT
-M:     Eric Miao <eric.y.miao@gmail.com>
-M:     Haojian Zhuang <haojian.zhuang@gmail.com>
+R:     Lubomir Rintel <lkundrak@v3.sk>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-T:     git git://github.com/hzhuang1/linux.git
-T:     git git://git.linaro.org/people/ycmiao/pxa-linux.git
-S:     Maintained
+S:     Odd Fixes
 F:     arch/arm/boot/dts/mmp*
 F:     arch/arm/mach-mmp/
 
@@ -10416,7 +10434,7 @@ F:      drivers/net/wireless/
 
 NETWORKING [DSA]
 M:     Andrew Lunn <andrew@lunn.ch>
-M:     Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+M:     Vivien Didelot <vivien.didelot@gmail.com>
 M:     Florian Fainelli <f.fainelli@gmail.com>
 S:     Maintained
 F:     Documentation/devicetree/bindings/net/dsa/
index f2c3423c3062f2b704c239621d2093cc45280060..7a2a9a175756c41c10e7ca85b87115dbd89f8c39 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 4
 PATCHLEVEL = 20
 SUBLEVEL = 0
-EXTRAVERSION = -rc6
+EXTRAVERSION =
 NAME = Shy Crocodile
 
 # *DOCUMENTATION*
@@ -962,11 +962,6 @@ ifdef CONFIG_STACK_VALIDATION
   ifeq ($(has_libelf),1)
     objtool_target := tools/objtool FORCE
   else
-    ifdef CONFIG_UNWINDER_ORC
-      $(error "Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel")
-    else
-      $(warning "Cannot use CONFIG_STACK_VALIDATION=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel")
-    endif
     SKIP_STACK_VALIDATION := 1
     export SKIP_STACK_VALIDATION
   endif
@@ -1081,7 +1076,7 @@ scripts: scripts_basic scripts_dtc asm-generic gcc-plugins $(autoksyms_h)
 # version.h and scripts_basic is processed / created.
 
 # Listed in dependency order
-PHONY += prepare archprepare macroprepare prepare0 prepare1 prepare2 prepare3
+PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3
 
 # prepare3 is used to check if we are building in a separate output directory,
 # and if so do:
@@ -1104,9 +1099,7 @@ prepare2: prepare3 outputmakefile asm-generic
 prepare1: prepare2 $(version_h) $(autoksyms_h) include/generated/utsrelease.h
        $(cmd_crmodverdir)
 
-macroprepare: prepare1 archmacros
-
-archprepare: archheaders archscripts macroprepare scripts_basic
+archprepare: archheaders archscripts prepare1 scripts_basic
 
 prepare0: archprepare gcc-plugins
        $(Q)$(MAKE) $(build)=.
@@ -1125,6 +1118,14 @@ uapi-asm-generic:
 
 PHONY += prepare-objtool
 prepare-objtool: $(objtool_target)
+ifeq ($(SKIP_STACK_VALIDATION),1)
+ifdef CONFIG_UNWINDER_ORC
+       @echo "error: Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
+       @false
+else
+       @echo "warning: Cannot use CONFIG_STACK_VALIDATION=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
+endif
+endif
 
 # Generate some files
 # ---------------------------------------------------------------------------
@@ -1174,9 +1175,6 @@ archheaders:
 PHONY += archscripts
 archscripts:
 
-PHONY += archmacros
-archmacros:
-
 PHONY += __headers
 __headers: $(version_h) scripts_basic uapi-asm-generic archheaders archscripts
        $(Q)$(MAKE) $(build)=scripts build_unifdef
index a37fd990bd5548933d89ce3949341f9e8a17d008..4b5b1b244f86a108bdda89f33316e84c77950df3 100644 (file)
@@ -634,6 +634,7 @@ setup_arch(char **cmdline_p)
 
        /* Find our memory.  */
        setup_memory(kernel_end);
+       memblock_set_bottom_up(true);
 
        /* First guess at cpu cache sizes.  Do this before init_arch.  */
        determine_cpu_caches(cpu->type);
index 74846553e3f18682a958bf6373923830f2b8168a..d0b73371e985ce70a5d7f0845b14911f2a1d62cb 100644 (file)
@@ -144,14 +144,14 @@ setup_memory_node(int nid, void *kernel_end)
        if (!nid && (node_max_pfn < end_kernel_pfn || node_min_pfn > start_kernel_pfn))
                panic("kernel loaded out of ram");
 
+       memblock_add(PFN_PHYS(node_min_pfn),
+                    (node_max_pfn - node_min_pfn) << PAGE_SHIFT);
+
        /* Zone start phys-addr must be 2^(MAX_ORDER-1) aligned.
           Note that we round this down, not up - node memory
           has much larger alignment than 8Mb, so it's safe. */
        node_min_pfn &= ~((1UL << (MAX_ORDER-1))-1);
 
-       memblock_add(PFN_PHYS(node_min_pfn),
-                    (node_max_pfn - node_min_pfn) << PAGE_SHIFT);
-
        NODE_DATA(nid)->node_start_pfn = node_min_pfn;
        NODE_DATA(nid)->node_present_pages = node_max_pfn - node_min_pfn;
 
index f2a1d25eb6cf3f1249bcc2166bee7f86a75b2a6d..83e0fbc4a1a10cf4e4b9418b9646d7f06aaea181 100644 (file)
@@ -45,7 +45,7 @@
        };
 
        /* The voltage to the MMC card is hardwired at 3.3V */
-       vmmc: fixedregulator@0 {
+       vmmc: regulator-vmmc {
                compatible = "regulator-fixed";
                regulator-name = "vmmc";
                regulator-min-microvolt = <3300000>;
@@ -53,7 +53,7 @@
                regulator-boot-on;
         };
 
-       veth: fixedregulator@0 {
+       veth: regulator-veth {
                compatible = "regulator-fixed";
                regulator-name = "veth";
                regulator-min-microvolt = <3300000>;
index 7f9cbdf33a51009ffea23fa488ec8f1e6abe7914..2f6aa24a0b67c707068bba9fb7902525ff1158c0 100644 (file)
        };
 
        /* The voltage to the MMC card is hardwired at 3.3V */
-       vmmc: fixedregulator@0 {
+       vmmc: regulator-vmmc {
                compatible = "regulator-fixed";
                regulator-name = "vmmc";
                regulator-min-microvolt = <3300000>;
                regulator-boot-on;
         };
 
-       veth: fixedregulator@0 {
+       veth: regulator-veth {
                compatible = "regulator-fixed";
                regulator-name = "veth";
                regulator-min-microvolt = <3300000>;
index 4adb85e66be3f975894cb712211478439709f274..93762244be7f469a64d9158b2a904e0b8cde1fdd 100644 (file)
@@ -31,7 +31,7 @@
 
        wifi_pwrseq: wifi-pwrseq {
                compatible = "mmc-pwrseq-simple";
-               reset-gpios = <&expgpio 1 GPIO_ACTIVE_HIGH>;
+               reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
        };
 };
 
index c318bcbc6ba7e327bcf164fd543cd47c04c52d2c..89e6fd547c7572f6bc7d243e5055da4e33dc94a2 100644 (file)
@@ -26,7 +26,7 @@
 
        wifi_pwrseq: wifi-pwrseq {
                compatible = "mmc-pwrseq-simple";
-               reset-gpios = <&expgpio 1 GPIO_ACTIVE_HIGH>;
+               reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
        };
 };
 
index d8aac4a2d02a2489d1843e2d22f2f4cb317eb481..177d21fdeb288d3e458176ddf0d537a746f0d2ba 100644 (file)
                compatible = "regulator-fixed";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
-               clocks = <&clks IMX7D_CLKO2_ROOT_DIV>;
-               clock-names = "slow";
                regulator-name = "reg_wlan";
                startup-delay-us = <70000>;
                gpio = <&gpio4 21 GPIO_ACTIVE_HIGH>;
                enable-active-high;
        };
+
+       usdhc2_pwrseq: usdhc2_pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               clocks = <&clks IMX7D_CLKO2_ROOT_DIV>;
+               clock-names = "ext_clock";
+       };
 };
 
 &adc1 {
        bus-width = <4>;
        non-removable;
        vmmc-supply = <&reg_wlan>;
+       mmc-pwrseq = <&usdhc2_pwrseq>;
        cap-power-off-card;
        keep-power-in-suspend;
        status = "okay";
index 21973eb55671920148e25e6a6b0e1c469093bc8e..f27b3849d3ff3ed91d7e2d504206c4c8a7d8045b 100644 (file)
                regulator-min-microvolt = <1800000>;
                regulator-max-microvolt = <1800000>;
        };
+
+       usdhc2_pwrseq: usdhc2_pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               clocks = <&clks IMX7D_CLKO2_ROOT_DIV>;
+               clock-names = "ext_clock";
+       };
+};
+
+&clks {
+       assigned-clocks = <&clks IMX7D_CLKO2_ROOT_SRC>,
+                         <&clks IMX7D_CLKO2_ROOT_DIV>;
+       assigned-clock-parents = <&clks IMX7D_CKIL>;
+       assigned-clock-rates = <0>, <32768>;
 };
 
 &i2c4 {
 
 &usdhc2 { /* Wifi SDIO */
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc2>;
+       pinctrl-0 = <&pinctrl_usdhc2 &pinctrl_wifi_clk>;
        no-1-8-v;
        non-removable;
        keep-power-in-suspend;
        wakeup-source;
        vmmc-supply = <&reg_ap6212>;
+       mmc-pwrseq = <&usdhc2_pwrseq>;
        status = "okay";
 };
 
 };
 
 &iomuxc_lpsr {
+       pinctrl_wifi_clk: wificlkgrp {
+               fsl,pins = <
+                       MX7D_PAD_LPSR_GPIO1_IO03__CCM_CLKO2     0x7d
+               >;
+       };
+
        pinctrl_wdog: wdoggrp {
                fsl,pins = <
                        MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG_B  0x74
index 742d2946b08be48d205bee2ae6041632b27dccf1..583a5a01642f2f36dc8887acf869c0480f47162a 100644 (file)
 
 &reg_dldo3 {
        regulator-always-on;
-       regulator-min-microvolt = <2500000>;
-       regulator-max-microvolt = <2500000>;
+       regulator-min-microvolt = <3300000>;
+       regulator-max-microvolt = <3300000>;
        regulator-name = "vcc-pd";
 };
 
index 243a108a940b46c9c0d9b13d2802beb11f84d2d9..fd0053e47a151179db824e1aac6fe1526d20327e 100644 (file)
@@ -110,7 +110,7 @@ int __init imx6sx_cpuidle_init(void)
         * except for power up sw2iso which need to be
         * larger than LDO ramp up time.
         */
-       imx_gpc_set_arm_power_up_timing(2, 1);
+       imx_gpc_set_arm_power_up_timing(0xf, 1);
        imx_gpc_set_arm_power_down_timing(1, 1);
 
        return cpuidle_register(&imx6sx_cpuidle_driver, NULL);
index 446edaeb78a71d07a8c719732455589ffa67b49e..a96abcf521b4b095a13658e51f409884d89b35b5 100644 (file)
@@ -44,10 +44,12 @@ static inline int cpu_is_pxa910(void)
 #define cpu_is_pxa910()        (0)
 #endif
 
-#ifdef CONFIG_CPU_MMP2
+#if defined(CONFIG_CPU_MMP2) || defined(CONFIG_MACH_MMP2_DT)
 static inline int cpu_is_mmp2(void)
 {
-       return (((read_cpuid_id() >> 8) & 0xff) == 0x58);
+       return (((read_cpuid_id() >> 8) & 0xff) == 0x58) &&
+               (((mmp_chip_id & 0xfff) == 0x410) ||
+                ((mmp_chip_id & 0xfff) == 0x610));
 }
 #else
 #define cpu_is_mmp2()  (0)
index 64632c8738887804df7a81d5f2b5715280bfffb6..01ea662afba876638c1d44fc0d89f3e52ad4e37e 100644 (file)
                        compatible = "arm,cortex-a72", "arm,armv8";
                        reg = <0x000>;
                        enable-method = "psci";
-                       cpu-idle-states = <&CPU_SLEEP_0>;
                };
                cpu1: cpu@1 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72", "arm,armv8";
                        reg = <0x001>;
                        enable-method = "psci";
-                       cpu-idle-states = <&CPU_SLEEP_0>;
                };
                cpu2: cpu@100 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72", "arm,armv8";
                        reg = <0x100>;
                        enable-method = "psci";
-                       cpu-idle-states = <&CPU_SLEEP_0>;
                };
                cpu3: cpu@101 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72", "arm,armv8";
                        reg = <0x101>;
                        enable-method = "psci";
-                       cpu-idle-states = <&CPU_SLEEP_0>;
                };
        };
 };
index 073610ac0a53e8dcd1786b4b8c8c59b7b955ef50..7d94c1fa592a064d2d42709ce9d6a198ef008eb6 100644 (file)
                method = "smc";
        };
 
-       cpus {
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               idle_states {
-                       entry_method = "arm,pcsi";
-
-                       CPU_SLEEP_0: cpu-sleep-0 {
-                               compatible = "arm,idle-state";
-                               local-timer-stop;
-                               arm,psci-suspend-param = <0x0010000>;
-                               entry-latency-us = <80>;
-                               exit-latency-us  = <160>;
-                               min-residency-us = <320>;
-                       };
-
-                       CLUSTER_SLEEP_0: cluster-sleep-0 {
-                               compatible = "arm,idle-state";
-                               local-timer-stop;
-                               arm,psci-suspend-param = <0x1010000>;
-                               entry-latency-us = <500>;
-                               exit-latency-us = <1000>;
-                               min-residency-us = <2500>;
-                       };
-               };
-       };
-
        ap806 {
                #address-cells = <2>;
                #size-cells = <2>;
index 5d6005c9b097529522b9112d3682d636b633f61b..710c5c3d87d30ef7dcb1657bb2081883f8b04aa0 100644 (file)
        model = "Bananapi BPI-R64";
        compatible = "bananapi,bpi-r64", "mediatek,mt7622";
 
+       aliases {
+               serial0 = &uart0;
+       };
+
        chosen {
-               bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512";
+               stdout-path = "serial0:115200n8";
+               bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512";
        };
 
        cpus {
index dcad0869b84ca01dc76e2924506583daf1c65c54..3f783348c66a690f3acce45ff76bd5da7c14f48a 100644 (file)
        model = "MediaTek MT7622 RFB1 board";
        compatible = "mediatek,mt7622-rfb1", "mediatek,mt7622";
 
+       aliases {
+               serial0 = &uart0;
+       };
+
        chosen {
-               bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512";
+               stdout-path = "serial0:115200n8";
+               bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512";
        };
 
        cpus {
index fe0c875f1d9513538e5a18c74f641557d89675c8..14a1028ca3a64bd54bd21608655dcf1895d25fa1 100644 (file)
                #reset-cells = <1>;
        };
 
-       timer: timer@10004000 {
-               compatible = "mediatek,mt7622-timer",
-                            "mediatek,mt6577-timer";
-               reg = <0 0x10004000 0 0x80>;
-               interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_LOW>;
-               clocks = <&infracfg CLK_INFRA_APXGPT_PD>,
-                        <&topckgen CLK_TOP_RTC>;
-               clock-names = "system-clk", "rtc-clk";
-       };
-
        scpsys: scpsys@10006000 {
                compatible = "mediatek,mt7622-scpsys",
                             "syscon";
index b96442960aead1692e94d28dd35d33e7954d84b3..f0a5c9531e8bbb455a2ebb94f46ee4efade8e854 100644 (file)
  */
 #define PCI_IO_SIZE            SZ_16M
 
-/*
- * Log2 of the upper bound of the size of a struct page. Used for sizing
- * the vmemmap region only, does not affect actual memory footprint.
- * We don't use sizeof(struct page) directly since taking its size here
- * requires its definition to be available at this point in the inclusion
- * chain, and it may not be a power of 2 in the first place.
- */
-#define STRUCT_PAGE_MAX_SHIFT  6
-
 /*
  * VMEMMAP_SIZE - allows the whole linear region to be covered by
  *                a struct page array
index a3ac262848451ae49535c37a6997a211b0f5e914..a5370440609917c10fb2f2c4ffbc26f5e1a1ba9f 100644 (file)
@@ -429,9 +429,9 @@ static void *__iommu_alloc_attrs(struct device *dev, size_t size,
                                                   prot,
                                                   __builtin_return_address(0));
                if (addr) {
-                       memset(addr, 0, size);
                        if (!coherent)
                                __dma_flush_area(page_to_virt(page), iosize);
+                       memset(addr, 0, size);
                } else {
                        iommu_dma_unmap_page(dev, *handle, iosize, 0, attrs);
                        dma_release_from_contiguous(dev, page,
index 9b432d9fcada8dac8e7b1041437387f29785b2af..0340e45655c687ebc3b223cdee374d97e0e722c7 100644 (file)
@@ -610,14 +610,6 @@ void __init mem_init(void)
        BUILD_BUG_ON(TASK_SIZE_32                       > TASK_SIZE_64);
 #endif
 
-#ifdef CONFIG_SPARSEMEM_VMEMMAP
-       /*
-        * Make sure we chose the upper bound of sizeof(struct page)
-        * correctly when sizing the VMEMMAP array.
-        */
-       BUILD_BUG_ON(sizeof(struct page) > (1 << STRUCT_PAGE_MAX_SHIFT));
-#endif
-
        if (PAGE_SIZE >= 16384 && get_num_physpages() <= 128) {
                extern int sysctl_overcommit_memory;
                /*
index a1a3eaeaf58c960df8e406dca1fcdf0e434470a2..ad0195cbe04255eada56bc8cff364086dc38642e 100644 (file)
@@ -164,8 +164,6 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record)
                                        be32_to_cpu(m->addr);
                                m68k_memory[m68k_num_memory].size =
                                        be32_to_cpu(m->size);
-                               memblock_add(m68k_memory[m68k_num_memory].addr,
-                                            m68k_memory[m68k_num_memory].size);
                                m68k_num_memory++;
                        } else
                                pr_warn("%s: too many memory chunks\n",
index 7497cf30bf1cd41b51afd915a45b5b80fd9dd939..3f3d0bf360910c0d45095a0ef51db604afe5b02b 100644 (file)
@@ -228,6 +228,7 @@ void __init paging_init(void)
 
        min_addr = m68k_memory[0].addr;
        max_addr = min_addr + m68k_memory[0].size;
+       memblock_add(m68k_memory[0].addr, m68k_memory[0].size);
        for (i = 1; i < m68k_num_memory;) {
                if (m68k_memory[i].addr < min_addr) {
                        printk("Ignoring memory chunk at 0x%lx:0x%lx before the first chunk\n",
@@ -238,6 +239,7 @@ void __init paging_init(void)
                                (m68k_num_memory - i) * sizeof(struct m68k_mem_info));
                        continue;
                }
+               memblock_add(m68k_memory[i].addr, m68k_memory[i].size);
                addr = m68k_memory[i].addr + m68k_memory[i].size;
                if (addr > max_addr)
                        max_addr = addr;
index 39354365f54a5ebcbf0b087155e698ebf8337137..ed9883169190577f86bc77059eaefdd5d1f3caff 100644 (file)
@@ -197,7 +197,7 @@ $(obj)/empty.c:
 $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds : $(obj)/%: $(srctree)/$(src)/%.S
        $(Q)cp $< $@
 
-$(obj)/serial.c: $(obj)/autoconf.h
+$(srctree)/$(src)/serial.c: $(obj)/autoconf.h
 
 $(obj)/autoconf.h: $(obj)/%: $(objtree)/include/generated/%
        $(Q)cp $< $@
index 32dfe6d083f3257c41b8e0de835eff8ccd16491c..9b9d17437373bfd7ce821c87e4a98c36e7ef371a 100644 (file)
@@ -15,7 +15,7 @@
 RELA = 7
 RELACOUNT = 0x6ffffff9
 
-       .text
+       .data
        /* A procedure descriptor used when booting this as a COFF file.
         * When making COFF, this comes first in the link and we're
         * linked at 0x500000.
@@ -23,6 +23,8 @@ RELACOUNT = 0x6ffffff9
        .globl  _zimage_start_opd
 _zimage_start_opd:
        .long   0x500000, 0, 0, 0
+       .text
+       b       _zimage_start
 
 #ifdef __powerpc64__
 .balign 8
index 8bf1b6351716ee424d80bf240bbcea54abc35c9e..16a49819da9a993046e5cf15c7de2ef523e7c2fe 100644 (file)
@@ -26,6 +26,8 @@
 #include <asm/ptrace.h>
 #include <asm/reg.h>
 
+#define perf_arch_bpf_user_pt_regs(regs) &regs->user_regs
+
 /*
  * Overload regs->result to specify whether we should use the MSR (result
  * is zero) or the SIAR (result is non zero).
index a658091a19f901c8283cba392e17da0e960970d2..3712152206f3ef8b2b9ca73d76f05af2d46688fc 100644 (file)
@@ -1,7 +1,6 @@
 # UAPI Header export list
 include include/uapi/asm-generic/Kbuild.asm
 
-generic-y += bpf_perf_event.h
 generic-y += param.h
 generic-y += poll.h
 generic-y += resource.h
diff --git a/arch/powerpc/include/uapi/asm/bpf_perf_event.h b/arch/powerpc/include/uapi/asm/bpf_perf_event.h
new file mode 100644 (file)
index 0000000..b551b74
--- /dev/null
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _UAPI__ASM_BPF_PERF_EVENT_H__
+#define _UAPI__ASM_BPF_PERF_EVENT_H__
+
+#include <asm/ptrace.h>
+
+typedef struct user_pt_regs bpf_user_pt_regs_t;
+
+#endif /* _UAPI__ASM_BPF_PERF_EVENT_H__ */
index 33b34a58fc62f50b9d7cb8ad1e82c6eab46bb39f..5b9dce17f0c926c9f4c9c838a06658920086bcdb 100644 (file)
@@ -372,6 +372,8 @@ void __init find_legacy_serial_ports(void)
 
        /* Now find out if one of these is out firmware console */
        path = of_get_property(of_chosen, "linux,stdout-path", NULL);
+       if (path == NULL)
+               path = of_get_property(of_chosen, "stdout-path", NULL);
        if (path != NULL) {
                stdout = of_find_node_by_path(path);
                if (stdout)
@@ -595,8 +597,10 @@ static int __init check_legacy_serial_console(void)
        /* We are getting a weird phandle from OF ... */
        /* ... So use the full path instead */
        name = of_get_property(of_chosen, "linux,stdout-path", NULL);
+       if (name == NULL)
+               name = of_get_property(of_chosen, "stdout-path", NULL);
        if (name == NULL) {
-               DBG(" no linux,stdout-path !\n");
+               DBG(" no stdout-path !\n");
                return -ENODEV;
        }
        prom_stdout = of_find_node_by_path(name);
index dab616a33b8dbe283aa46c05b5492af69190650f..f2197654be070721abd7bd263b68ae2ddd8094eb 100644 (file)
@@ -34,5 +34,10 @@ void arch_teardown_msi_irqs(struct pci_dev *dev)
 {
        struct pci_controller *phb = pci_bus_to_host(dev->bus);
 
-       phb->controller_ops.teardown_msi_irqs(dev);
+       /*
+        * We can be called even when arch_setup_msi_irqs() returns -ENOSYS,
+        * so check the pointer again.
+        */
+       if (phb->controller_ops.teardown_msi_irqs)
+               phb->controller_ops.teardown_msi_irqs(dev);
 }
index afb819f4ca68bee0f88fab357ffe9395508dc106..714c3480c52dcca8761a9d9e2a24e9eaad0a6256 100644 (file)
@@ -3266,12 +3266,17 @@ long do_syscall_trace_enter(struct pt_regs *regs)
        user_exit();
 
        if (test_thread_flag(TIF_SYSCALL_EMU)) {
-               ptrace_report_syscall(regs);
                /*
+                * A nonzero return code from tracehook_report_syscall_entry()
+                * tells us to prevent the syscall execution, but we are not
+                * going to execute it anyway.
+                *
                 * Returning -1 will skip the syscall execution. We want to
                 * avoid clobbering any register also, thus, not 'gotoing'
                 * skip label.
                 */
+               if (tracehook_report_syscall_entry(regs))
+                       ;
                return -1;
        }
 
index 2b74f8adf4d009b101fde1c3873c1bd4ec0833a4..6aa41669ac1aec6b0db81da31d45b47bbade30c1 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/hugetlb.h>
 #include <linux/io.h>
 #include <linux/mm.h>
+#include <linux/highmem.h>
 #include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <asm/fixmap.h>
index 7a9886f98b0c12e8df43fe0e8a897a7d4cbeac9d..a5091c03474753111f77df8de2910152ee38abb8 100644 (file)
@@ -188,15 +188,20 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
        pr_debug("vmemmap_populate %lx..%lx, node %d\n", start, end, node);
 
        for (; start < end; start += page_size) {
-               void *p;
+               void *p = NULL;
                int rc;
 
                if (vmemmap_populated(start, page_size))
                        continue;
 
+               /*
+                * Allocate from the altmap first if we have one. This may
+                * fail due to alignment issues when using 16MB hugepages, so
+                * fall back to system memory if the altmap allocation fail.
+                */
                if (altmap)
                        p = altmap_alloc_block_buf(page_size, altmap);
-               else
+               if (!p)
                        p = vmemmap_alloc_block_buf(page_size, node);
                if (!p)
                        return -ENOMEM;
@@ -255,8 +260,15 @@ void __ref vmemmap_free(unsigned long start, unsigned long end,
 {
        unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift;
        unsigned long page_order = get_order(page_size);
+       unsigned long alt_start = ~0, alt_end = ~0;
+       unsigned long base_pfn;
 
        start = _ALIGN_DOWN(start, page_size);
+       if (altmap) {
+               alt_start = altmap->base_pfn;
+               alt_end = altmap->base_pfn + altmap->reserve +
+                         altmap->free + altmap->alloc + altmap->align;
+       }
 
        pr_debug("vmemmap_free %lx...%lx\n", start, end);
 
@@ -280,8 +292,9 @@ void __ref vmemmap_free(unsigned long start, unsigned long end,
                page = pfn_to_page(addr >> PAGE_SHIFT);
                section_base = pfn_to_page(vmemmap_section_start(start));
                nr_pages = 1 << page_order;
+               base_pfn = PHYS_PFN(addr);
 
-               if (altmap) {
+               if (base_pfn >= alt_start && base_pfn < alt_end) {
                        vmem_altmap_free(altmap, nr_pages);
                } else if (PageReserved(page)) {
                        /* allocated from bootmem */
index 2e4bd32154b5d756396e3793ed7e6066cd572af3..472b784f01ebf0b9106a0753d191c059f3406307 100644 (file)
@@ -140,8 +140,7 @@ config IBMEBUS
          Bus device driver for GX bus based adapters.
 
 config PAPR_SCM
-       depends on PPC_PSERIES && MEMORY_HOTPLUG
-       select LIBNVDIMM
+       depends on PPC_PSERIES && MEMORY_HOTPLUG && LIBNVDIMM
        tristate "Support for the PAPR Storage Class Memory interface"
        help
          Enable access to hypervisor provided storage class memory.
index ee9372b65ca5cf053762d34b0079276becd56779..7d6457ab5d3450f0db4d6cc25e2067c80db59f13 100644 (file)
@@ -55,7 +55,7 @@ static int drc_pmem_bind(struct papr_scm_priv *p)
        do {
                rc = plpar_hcall(H_SCM_BIND_MEM, ret, p->drc_index, 0,
                                p->blocks, BIND_ANY_ADDR, token);
-               token = be64_to_cpu(ret[0]);
+               token = ret[0];
                cond_resched();
        } while (rc == H_BUSY);
 
@@ -64,7 +64,7 @@ static int drc_pmem_bind(struct papr_scm_priv *p)
                return -ENXIO;
        }
 
-       p->bound_addr = be64_to_cpu(ret[1]);
+       p->bound_addr = ret[1];
 
        dev_dbg(&p->pdev->dev, "bound drc %x to %pR\n", p->drc_index, &p->res);
 
@@ -82,7 +82,7 @@ static int drc_pmem_unbind(struct papr_scm_priv *p)
        do {
                rc = plpar_hcall(H_SCM_UNBIND_MEM, ret, p->drc_index,
                                p->bound_addr, p->blocks, token);
-               token = be64_to_cpu(ret);
+               token = ret[0];
                cond_resched();
        } while (rc == H_BUSY);
 
@@ -223,6 +223,9 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p)
                goto err;
        }
 
+       if (nvdimm_bus_check_dimm_count(p->bus, 1))
+               goto err;
+
        /* now add the region */
 
        memset(&mapping, 0, sizeof(mapping));
@@ -257,9 +260,12 @@ err:       nvdimm_bus_unregister(p->bus);
 
 static int papr_scm_probe(struct platform_device *pdev)
 {
-       uint32_t drc_index, metadata_size, unit_cap[2];
        struct device_node *dn = pdev->dev.of_node;
+       u32 drc_index, metadata_size;
+       u64 blocks, block_size;
        struct papr_scm_priv *p;
+       const char *uuid_str;
+       u64 uuid[2];
        int rc;
 
        /* check we have all the required DT properties */
@@ -268,8 +274,18 @@ static int papr_scm_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       if (of_property_read_u32_array(dn, "ibm,unit-capacity", unit_cap, 2)) {
-               dev_err(&pdev->dev, "%pOF: missing unit-capacity!\n", dn);
+       if (of_property_read_u64(dn, "ibm,block-size", &block_size)) {
+               dev_err(&pdev->dev, "%pOF: missing block-size!\n", dn);
+               return -ENODEV;
+       }
+
+       if (of_property_read_u64(dn, "ibm,number-of-blocks", &blocks)) {
+               dev_err(&pdev->dev, "%pOF: missing number-of-blocks!\n", dn);
+               return -ENODEV;
+       }
+
+       if (of_property_read_string(dn, "ibm,unit-guid", &uuid_str)) {
+               dev_err(&pdev->dev, "%pOF: missing unit-guid!\n", dn);
                return -ENODEV;
        }
 
@@ -282,8 +298,13 @@ static int papr_scm_probe(struct platform_device *pdev)
 
        p->dn = dn;
        p->drc_index = drc_index;
-       p->block_size = unit_cap[0];
-       p->blocks     = unit_cap[1];
+       p->block_size = block_size;
+       p->blocks = blocks;
+
+       /* We just need to ensure that set cookies are unique across */
+       uuid_parse(uuid_str, (uuid_t *) uuid);
+       p->nd_set.cookie1 = uuid[0];
+       p->nd_set.cookie2 = uuid[1];
 
        /* might be zero */
        p->metadata_size = metadata_size;
@@ -296,7 +317,7 @@ static int papr_scm_probe(struct platform_device *pdev)
 
        /* setup the resource for the newly bound range */
        p->res.start = p->bound_addr;
-       p->res.end   = p->bound_addr + p->blocks * p->block_size;
+       p->res.end   = p->bound_addr + p->blocks * p->block_size - 1;
        p->res.name  = pdev->name;
        p->res.flags = IORESOURCE_MEM;
 
index 98cb8c802b1a8cccafb1cd52d4717a149490792c..4f7f235f15f856775ee2fbdae67e06ad20fdc363 100644 (file)
@@ -24,6 +24,7 @@
 #define __IO_PREFIX     generic
 #include <asm/io_generic.h>
 #include <asm/io_trapped.h>
+#include <asm-generic/pci_iomap.h>
 #include <mach/mangle-port.h>
 
 #define __raw_writeb(v,a)      (__chk_io_ptr(a), *(volatile u8  __force *)(a) = (v))
index 13664c377196441096f3a09b6de1d6eac9f410ec..3fd238e54af9cd89c4ace53c89776b554581c130 100644 (file)
@@ -310,25 +310,24 @@ void __init setup_arch(char **cmdline_p)
 
        register_console(&prom_early_console);
 
-       printk("ARCH: ");
        switch(sparc_cpu_model) {
        case sun4m:
-               printk("SUN4M\n");
+               pr_info("ARCH: SUN4M\n");
                break;
        case sun4d:
-               printk("SUN4D\n");
+               pr_info("ARCH: SUN4D\n");
                break;
        case sun4e:
-               printk("SUN4E\n");
+               pr_info("ARCH: SUN4E\n");
                break;
        case sun4u:
-               printk("SUN4U\n");
+               pr_info("ARCH: SUN4U\n");
                break;
        case sparc_leon:
-               printk("LEON\n");
+               pr_info("ARCH: LEON\n");
                break;
        default:
-               printk("UNKNOWN!\n");
+               pr_info("ARCH: UNKNOWN!\n");
                break;
        }
 
index cd2825cb84207c16b3cf82870a25877a5793ffee..ecc788aa07bdec63554295cfc3e957b3c524c17b 100644 (file)
@@ -642,9 +642,9 @@ void __init setup_arch(char **cmdline_p)
                register_console(&prom_early_console);
 
        if (tlb_type == hypervisor)
-               printk("ARCH: SUN4V\n");
+               pr_info("ARCH: SUN4V\n");
        else
-               printk("ARCH: SUN4U\n");
+               pr_info("ARCH: SUN4U\n");
 
 #ifdef CONFIG_DUMMY_CONSOLE
        conswitchp = &dummy_con;
index a6e18ca4cc18ce25fe87135b3034588c25fbee36..74e97f77e23b2b9bc439c997ef0a4f1e8ff54efa 100644 (file)
@@ -34,7 +34,7 @@ targets += $(vdso_img_sodbg) $(vdso_img-y:%=vdso%.so)
 CPPFLAGS_vdso.lds += -P -C
 
 VDSO_LDFLAGS_vdso.lds = -m elf64_sparc -soname linux-vdso.so.1 --no-undefined \
-                       -z max-page-size=8192 -z common-page-size=8192
+                       -z max-page-size=8192
 
 $(obj)/vdso64.so.dbg: $(obj)/vdso.lds $(vobjs) FORCE
        $(call if_changed,vdso)
index 75ef499a66e2b81c82fb6abb9bb4bd9a64521e73..85a66c4a8b652b2568473a3384785364495846ab 100644 (file)
@@ -232,13 +232,6 @@ archscripts: scripts_basic
 archheaders:
        $(Q)$(MAKE) $(build)=arch/x86/entry/syscalls all
 
-archmacros:
-       $(Q)$(MAKE) $(build)=arch/x86/kernel arch/x86/kernel/macros.s
-
-ASM_MACRO_FLAGS = -Wa,arch/x86/kernel/macros.s
-export ASM_MACRO_FLAGS
-KBUILD_CFLAGS += $(ASM_MACRO_FLAGS)
-
 ###
 # Kernel objects
 
index 25e5a6bda8c3a971609dff93919ccab27d6a3aa9..20d0885b00fbec4c77dfee23c701ba0c3612890b 100644 (file)
@@ -352,7 +352,7 @@ For 32-bit we have the following conventions - kernel is built with
 .macro CALL_enter_from_user_mode
 #ifdef CONFIG_CONTEXT_TRACKING
 #ifdef HAVE_JUMP_LABEL
-       STATIC_BRANCH_JMP l_yes=.Lafter_call_\@, key=context_tracking_enabled, branch=1
+       STATIC_JUMP_IF_FALSE .Lafter_call_\@, context_tracking_enabled, def=0
 #endif
        call enter_from_user_mode
 .Lafter_call_\@:
index 0624bf2266fd76d2852ce005acb2f9d67dbe6b8f..5bfe2243a08f882c4ab622cd87799ac1a28ff3c2 100644 (file)
@@ -171,7 +171,8 @@ quiet_cmd_vdso = VDSO    $@
                 sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
 
 VDSO_LDFLAGS = -shared $(call ld-option, --hash-style=both) \
-       $(call ld-option, --build-id) -Bsymbolic
+       $(call ld-option, --build-id) $(call ld-option, --eh-frame-hdr) \
+       -Bsymbolic
 GCOV_PROFILE := n
 
 #
index 8e4ea39e55d071de447bb1c1336dce2ec314ad5e..31b627b43a8e01933d6209e746f4c08912d0cdef 100644 (file)
@@ -7,24 +7,16 @@
 #include <asm/asm.h>
 
 #ifdef CONFIG_SMP
-.macro LOCK_PREFIX_HERE
+       .macro LOCK_PREFIX
+672:   lock
        .pushsection .smp_locks,"a"
        .balign 4
-       .long 671f - .          # offset
+       .long 672b - .
        .popsection
-671:
-.endm
-
-.macro LOCK_PREFIX insn:vararg
-       LOCK_PREFIX_HERE
-       lock \insn
-.endm
+       .endm
 #else
-.macro LOCK_PREFIX_HERE
-.endm
-
-.macro LOCK_PREFIX insn:vararg
-.endm
+       .macro LOCK_PREFIX
+       .endm
 #endif
 
 /*
index d7faa16622d81d39ff11d703fad17ed7931cce86..4cd6a3b71824293ae3edb664bc5ed6e48ca5a459 100644 (file)
  */
 
 #ifdef CONFIG_SMP
-#define LOCK_PREFIX_HERE "LOCK_PREFIX_HERE\n\t"
-#define LOCK_PREFIX "LOCK_PREFIX "
+#define LOCK_PREFIX_HERE \
+               ".pushsection .smp_locks,\"a\"\n"       \
+               ".balign 4\n"                           \
+               ".long 671f - .\n" /* offset */         \
+               ".popsection\n"                         \
+               "671:"
+
+#define LOCK_PREFIX LOCK_PREFIX_HERE "\n\tlock; "
+
 #else /* ! CONFIG_SMP */
 #define LOCK_PREFIX_HERE ""
 #define LOCK_PREFIX ""
index 21b086786404baff684ef450bd13aad5abd181ec..6467757bb39f6b6622c0121fe40f9f6fbcfd0b39 100644 (file)
 /* Exception table entry */
 #ifdef __ASSEMBLY__
 # define _ASM_EXTABLE_HANDLE(from, to, handler)                        \
-       ASM_EXTABLE_HANDLE from to handler
-
-.macro ASM_EXTABLE_HANDLE from:req to:req handler:req
-       .pushsection "__ex_table","a"
-       .balign 4
-       .long (\from) - .
-       .long (\to) - .
-       .long (\handler) - .
+       .pushsection "__ex_table","a" ;                         \
+       .balign 4 ;                                             \
+       .long (from) - . ;                                      \
+       .long (to) - . ;                                        \
+       .long (handler) - . ;                                   \
        .popsection
-.endm
-#else /* __ASSEMBLY__ */
-
-# define _ASM_EXTABLE_HANDLE(from, to, handler)                        \
-       "ASM_EXTABLE_HANDLE from=" #from " to=" #to             \
-       " handler=\"" #handler "\"\n\t"
-
-/* For C file, we already have NOKPROBE_SYMBOL macro */
-
-#endif /* __ASSEMBLY__ */
 
 # define _ASM_EXTABLE(from, to)                                        \
        _ASM_EXTABLE_HANDLE(from, to, ex_handler_default)
        _ASM_PTR (entry);                                       \
        .popsection
 
-#ifdef __ASSEMBLY__
 .macro ALIGN_DESTINATION
        /* check for bad alignment of destination */
        movl %edi,%ecx
        _ASM_EXTABLE_UA(100b, 103b)
        _ASM_EXTABLE_UA(101b, 103b)
        .endm
-#endif /* __ASSEMBLY__ */
+
+#else
+# define _EXPAND_EXTABLE_HANDLE(x) #x
+# define _ASM_EXTABLE_HANDLE(from, to, handler)                        \
+       " .pushsection \"__ex_table\",\"a\"\n"                  \
+       " .balign 4\n"                                          \
+       " .long (" #from ") - .\n"                              \
+       " .long (" #to ") - .\n"                                \
+       " .long (" _EXPAND_EXTABLE_HANDLE(handler) ") - .\n"    \
+       " .popsection\n"
+
+# define _ASM_EXTABLE(from, to)                                        \
+       _ASM_EXTABLE_HANDLE(from, to, ex_handler_default)
+
+# define _ASM_EXTABLE_UA(from, to)                             \
+       _ASM_EXTABLE_HANDLE(from, to, ex_handler_uaccess)
+
+# define _ASM_EXTABLE_FAULT(from, to)                          \
+       _ASM_EXTABLE_HANDLE(from, to, ex_handler_fault)
+
+# define _ASM_EXTABLE_EX(from, to)                             \
+       _ASM_EXTABLE_HANDLE(from, to, ex_handler_ext)
+
+# define _ASM_EXTABLE_REFCOUNT(from, to)                       \
+       _ASM_EXTABLE_HANDLE(from, to, ex_handler_refcount)
+
+/* For C file, we already have NOKPROBE_SYMBOL macro */
+#endif
 
 #ifndef __ASSEMBLY__
 /*
index 5090035e6d160fed62820f4eb40a363bb6dff763..6804d66427673ec314659944e65052b5dfba273e 100644 (file)
@@ -4,8 +4,6 @@
 
 #include <linux/stringify.h>
 
-#ifndef __ASSEMBLY__
-
 /*
  * Despite that some emulators terminate on UD2, we use it for WARN().
  *
 
 #define LEN_UD2                2
 
+#ifdef CONFIG_GENERIC_BUG
+
+#ifdef CONFIG_X86_32
+# define __BUG_REL(val)        ".long " __stringify(val)
+#else
+# define __BUG_REL(val)        ".long " __stringify(val) " - 2b"
+#endif
+
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+
+#define _BUG_FLAGS(ins, flags)                                         \
+do {                                                                   \
+       asm volatile("1:\t" ins "\n"                                    \
+                    ".pushsection __bug_table,\"aw\"\n"                \
+                    "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n"   \
+                    "\t"  __BUG_REL(%c0) "\t# bug_entry::file\n"       \
+                    "\t.word %c1"        "\t# bug_entry::line\n"       \
+                    "\t.word %c2"        "\t# bug_entry::flags\n"      \
+                    "\t.org 2b+%c3\n"                                  \
+                    ".popsection"                                      \
+                    : : "i" (__FILE__), "i" (__LINE__),                \
+                        "i" (flags),                                   \
+                        "i" (sizeof(struct bug_entry)));               \
+} while (0)
+
+#else /* !CONFIG_DEBUG_BUGVERBOSE */
+
 #define _BUG_FLAGS(ins, flags)                                         \
 do {                                                                   \
-       asm volatile("ASM_BUG ins=\"" ins "\" file=%c0 line=%c1 "       \
-                    "flags=%c2 size=%c3"                               \
-                    : : "i" (__FILE__), "i" (__LINE__),                \
-                        "i" (flags),                                   \
+       asm volatile("1:\t" ins "\n"                                    \
+                    ".pushsection __bug_table,\"aw\"\n"                \
+                    "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n"   \
+                    "\t.word %c0"        "\t# bug_entry::flags\n"      \
+                    "\t.org 2b+%c1\n"                                  \
+                    ".popsection"                                      \
+                    : : "i" (flags),                                   \
                         "i" (sizeof(struct bug_entry)));               \
 } while (0)
 
+#endif /* CONFIG_DEBUG_BUGVERBOSE */
+
+#else
+
+#define _BUG_FLAGS(ins, flags)  asm volatile(ins)
+
+#endif /* CONFIG_GENERIC_BUG */
+
 #define HAVE_ARCH_BUG
 #define BUG()                                                  \
 do {                                                           \
@@ -46,54 +82,4 @@ do {                                                         \
 
 #include <asm-generic/bug.h>
 
-#else /* __ASSEMBLY__ */
-
-#ifdef CONFIG_GENERIC_BUG
-
-#ifdef CONFIG_X86_32
-.macro __BUG_REL val:req
-       .long \val
-.endm
-#else
-.macro __BUG_REL val:req
-       .long \val - 2b
-.endm
-#endif
-
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-
-.macro ASM_BUG ins:req file:req line:req flags:req size:req
-1:     \ins
-       .pushsection __bug_table,"aw"
-2:     __BUG_REL val=1b        # bug_entry::bug_addr
-       __BUG_REL val=\file     # bug_entry::file
-       .word \line             # bug_entry::line
-       .word \flags            # bug_entry::flags
-       .org 2b+\size
-       .popsection
-.endm
-
-#else /* !CONFIG_DEBUG_BUGVERBOSE */
-
-.macro ASM_BUG ins:req file:req line:req flags:req size:req
-1:     \ins
-       .pushsection __bug_table,"aw"
-2:     __BUG_REL val=1b        # bug_entry::bug_addr
-       .word \flags            # bug_entry::flags
-       .org 2b+\size
-       .popsection
-.endm
-
-#endif /* CONFIG_DEBUG_BUGVERBOSE */
-
-#else /* CONFIG_GENERIC_BUG */
-
-.macro ASM_BUG ins:req file:req line:req flags:req size:req
-       \ins
-.endm
-
-#endif /* CONFIG_GENERIC_BUG */
-
-#endif /* __ASSEMBLY__ */
-
 #endif /* _ASM_X86_BUG_H */
index 7d442722ef241b684c348dc47b6be916d4728a3d..aced6c9290d6f96cdaf4eaadab3dd3835d80b94a 100644 (file)
@@ -2,10 +2,10 @@
 #ifndef _ASM_X86_CPUFEATURE_H
 #define _ASM_X86_CPUFEATURE_H
 
-#ifdef __KERNEL__
-#ifndef __ASSEMBLY__
-
 #include <asm/processor.h>
+
+#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
+
 #include <asm/asm.h>
 #include <linux/bitops.h>
 
@@ -161,10 +161,37 @@ extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit);
  */
 static __always_inline __pure bool _static_cpu_has(u16 bit)
 {
-       asm_volatile_goto("STATIC_CPU_HAS bitnum=%[bitnum] "
-                         "cap_byte=\"%[cap_byte]\" "
-                         "feature=%P[feature] t_yes=%l[t_yes] "
-                         "t_no=%l[t_no] always=%P[always]"
+       asm_volatile_goto("1: jmp 6f\n"
+                "2:\n"
+                ".skip -(((5f-4f) - (2b-1b)) > 0) * "
+                        "((5f-4f) - (2b-1b)),0x90\n"
+                "3:\n"
+                ".section .altinstructions,\"a\"\n"
+                " .long 1b - .\n"              /* src offset */
+                " .long 4f - .\n"              /* repl offset */
+                " .word %P[always]\n"          /* always replace */
+                " .byte 3b - 1b\n"             /* src len */
+                " .byte 5f - 4f\n"             /* repl len */
+                " .byte 3b - 2b\n"             /* pad len */
+                ".previous\n"
+                ".section .altinstr_replacement,\"ax\"\n"
+                "4: jmp %l[t_no]\n"
+                "5:\n"
+                ".previous\n"
+                ".section .altinstructions,\"a\"\n"
+                " .long 1b - .\n"              /* src offset */
+                " .long 0\n"                   /* no replacement */
+                " .word %P[feature]\n"         /* feature bit */
+                " .byte 3b - 1b\n"             /* src len */
+                " .byte 0\n"                   /* repl len */
+                " .byte 0\n"                   /* pad len */
+                ".previous\n"
+                ".section .altinstr_aux,\"ax\"\n"
+                "6:\n"
+                " testb %[bitnum],%[cap_byte]\n"
+                " jnz %l[t_yes]\n"
+                " jmp %l[t_no]\n"
+                ".previous\n"
                 : : [feature]  "i" (bit),
                     [always]   "i" (X86_FEATURE_ALWAYS),
                     [bitnum]   "i" (1 << (bit & 7)),
@@ -199,44 +226,5 @@ t_no:
 #define CPU_FEATURE_TYPEVAL            boot_cpu_data.x86_vendor, boot_cpu_data.x86, \
                                        boot_cpu_data.x86_model
 
-#else /* __ASSEMBLY__ */
-
-.macro STATIC_CPU_HAS bitnum:req cap_byte:req feature:req t_yes:req t_no:req always:req
-1:
-       jmp 6f
-2:
-       .skip -(((5f-4f) - (2b-1b)) > 0) * ((5f-4f) - (2b-1b)),0x90
-3:
-       .section .altinstructions,"a"
-       .long 1b - .            /* src offset */
-       .long 4f - .            /* repl offset */
-       .word \always           /* always replace */
-       .byte 3b - 1b           /* src len */
-       .byte 5f - 4f           /* repl len */
-       .byte 3b - 2b           /* pad len */
-       .previous
-       .section .altinstr_replacement,"ax"
-4:
-       jmp \t_no
-5:
-       .previous
-       .section .altinstructions,"a"
-       .long 1b - .            /* src offset */
-       .long 0                 /* no replacement */
-       .word \feature          /* feature bit */
-       .byte 3b - 1b           /* src len */
-       .byte 0                 /* repl len */
-       .byte 0                 /* pad len */
-       .previous
-       .section .altinstr_aux,"ax"
-6:
-       testb \bitnum,\cap_byte
-       jnz \t_yes
-       jmp \t_no
-       .previous
-.endm
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __KERNEL__ */
+#endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */
 #endif /* _ASM_X86_CPUFEATURE_H */
index eb377b6e9eedee2e311bb13c1616e0ecbe7af350..bca4c743de77c6d80f21f1bb4aeb0e2a188d824b 100644 (file)
@@ -16,8 +16,8 @@
  */
 extern unsigned long x86_fsbase_read_task(struct task_struct *task);
 extern unsigned long x86_gsbase_read_task(struct task_struct *task);
-extern int x86_fsbase_write_task(struct task_struct *task, unsigned long fsbase);
-extern int x86_gsbase_write_task(struct task_struct *task, unsigned long gsbase);
+extern void x86_fsbase_write_task(struct task_struct *task, unsigned long fsbase);
+extern void x86_gsbase_write_task(struct task_struct *task, unsigned long gsbase);
 
 /* Helper functions for reading/writing FS/GS base */
 
@@ -39,8 +39,15 @@ static inline unsigned long x86_gsbase_read_cpu_inactive(void)
        return gsbase;
 }
 
-extern void x86_fsbase_write_cpu(unsigned long fsbase);
-extern void x86_gsbase_write_cpu_inactive(unsigned long gsbase);
+static inline void x86_fsbase_write_cpu(unsigned long fsbase)
+{
+       wrmsrl(MSR_FS_BASE, fsbase);
+}
+
+static inline void x86_gsbase_write_cpu_inactive(unsigned long gsbase)
+{
+       wrmsrl(MSR_KERNEL_GS_BASE, gsbase);
+}
 
 #endif /* CONFIG_X86_64 */
 
index a5fb34fe56a4bb31f78023ff3d258132ff93ee16..21efc9d07ed909adfc37b06188b331ea0e6f747d 100644 (file)
@@ -2,6 +2,19 @@
 #ifndef _ASM_X86_JUMP_LABEL_H
 #define _ASM_X86_JUMP_LABEL_H
 
+#ifndef HAVE_JUMP_LABEL
+/*
+ * For better or for worse, if jump labels (the gcc extension) are missing,
+ * then the entire static branch patching infrastructure is compiled out.
+ * If that happens, the code in here will malfunction.  Raise a compiler
+ * error instead.
+ *
+ * In theory, jump labels and the static branch patching infrastructure
+ * could be decoupled to fix this.
+ */
+#error asm/jump_label.h included on a non-jump-label kernel
+#endif
+
 #define JUMP_LABEL_NOP_SIZE 5
 
 #ifdef CONFIG_X86_64
 
 static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
 {
-       asm_volatile_goto("STATIC_BRANCH_NOP l_yes=\"%l[l_yes]\" key=\"%c0\" "
-                         "branch=\"%c1\""
-                       : :  "i" (key), "i" (branch) : : l_yes);
+       asm_volatile_goto("1:"
+               ".byte " __stringify(STATIC_KEY_INIT_NOP) "\n\t"
+               ".pushsection __jump_table,  \"aw\" \n\t"
+               _ASM_ALIGN "\n\t"
+               ".long 1b - ., %l[l_yes] - . \n\t"
+               _ASM_PTR "%c0 + %c1 - .\n\t"
+               ".popsection \n\t"
+               : :  "i" (key), "i" (branch) : : l_yes);
+
        return false;
 l_yes:
        return true;
@@ -30,8 +49,14 @@ l_yes:
 
 static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch)
 {
-       asm_volatile_goto("STATIC_BRANCH_JMP l_yes=\"%l[l_yes]\" key=\"%c0\" "
-                         "branch=\"%c1\""
+       asm_volatile_goto("1:"
+               ".byte 0xe9\n\t .long %l[l_yes] - 2f\n\t"
+               "2:\n\t"
+               ".pushsection __jump_table,  \"aw\" \n\t"
+               _ASM_ALIGN "\n\t"
+               ".long 1b - ., %l[l_yes] - . \n\t"
+               _ASM_PTR "%c0 + %c1 - .\n\t"
+               ".popsection \n\t"
                : :  "i" (key), "i" (branch) : : l_yes);
 
        return false;
@@ -41,26 +66,37 @@ l_yes:
 
 #else  /* __ASSEMBLY__ */
 
-.macro STATIC_BRANCH_NOP l_yes:req key:req branch:req
-.Lstatic_branch_nop_\@:
-       .byte STATIC_KEY_INIT_NOP
-.Lstatic_branch_no_after_\@:
+.macro STATIC_JUMP_IF_TRUE target, key, def
+.Lstatic_jump_\@:
+       .if \def
+       /* Equivalent to "jmp.d32 \target" */
+       .byte           0xe9
+       .long           \target - .Lstatic_jump_after_\@
+.Lstatic_jump_after_\@:
+       .else
+       .byte           STATIC_KEY_INIT_NOP
+       .endif
        .pushsection __jump_table, "aw"
        _ASM_ALIGN
-       .long           .Lstatic_branch_nop_\@ - ., \l_yes - .
-       _ASM_PTR        \key + \branch - .
+       .long           .Lstatic_jump_\@ - ., \target - .
+       _ASM_PTR        \key - .
        .popsection
 .endm
 
-.macro STATIC_BRANCH_JMP l_yes:req key:req branch:req
-.Lstatic_branch_jmp_\@:
-       .byte 0xe9
-       .long \l_yes - .Lstatic_branch_jmp_after_\@
-.Lstatic_branch_jmp_after_\@:
+.macro STATIC_JUMP_IF_FALSE target, key, def
+.Lstatic_jump_\@:
+       .if \def
+       .byte           STATIC_KEY_INIT_NOP
+       .else
+       /* Equivalent to "jmp.d32 \target" */
+       .byte           0xe9
+       .long           \target - .Lstatic_jump_after_\@
+.Lstatic_jump_after_\@:
+       .endif
        .pushsection __jump_table, "aw"
        _ASM_ALIGN
-       .long           .Lstatic_branch_jmp_\@ - ., \l_yes - .
-       _ASM_PTR        \key + \branch - .
+       .long           .Lstatic_jump_\@ - ., \target - .
+       _ASM_PTR        \key + 1 - .
        .popsection
 .endm
 
index c8f73efb4eceb82391bf908f1f8f292586be5925..9e39cc8bd989855cc2ca8c349c335fe36d029b37 100644 (file)
 #define MSR_F15H_NB_PERF_CTR           0xc0010241
 #define MSR_F15H_PTSC                  0xc0010280
 #define MSR_F15H_IC_CFG                        0xc0011021
+#define MSR_F15H_EX_CFG                        0xc001102c
 
 /* Fam 10h MSRs */
 #define MSR_FAM10H_MMIO_CONF_BASE      0xc0010058
index 26942ad63830407255afc9e6de77267056a97135..488c59686a733cc8ad627f7150a7d4aab72507b9 100644 (file)
@@ -348,11 +348,23 @@ extern struct paravirt_patch_template pv_ops;
 #define paravirt_clobber(clobber)              \
        [paravirt_clobber] "i" (clobber)
 
+/*
+ * Generate some code, and mark it as patchable by the
+ * apply_paravirt() alternate instruction patcher.
+ */
+#define _paravirt_alt(insn_string, type, clobber)      \
+       "771:\n\t" insn_string "\n" "772:\n"            \
+       ".pushsection .parainstructions,\"a\"\n"        \
+       _ASM_ALIGN "\n"                                 \
+       _ASM_PTR " 771b\n"                              \
+       "  .byte " type "\n"                            \
+       "  .byte 772b-771b\n"                           \
+       "  .short " clobber "\n"                        \
+       ".popsection\n"
+
 /* Generate patchable code, with the default asm parameters. */
-#define paravirt_call                                                  \
-       "PARAVIRT_CALL type=\"%c[paravirt_typenum]\""                   \
-       " clobber=\"%c[paravirt_clobber]\""                             \
-       " pv_opptr=\"%c[paravirt_opptr]\";"
+#define paravirt_alt(insn_string)                                      \
+       _paravirt_alt(insn_string, "%c[paravirt_typenum]", "%c[paravirt_clobber]")
 
 /* Simple instruction patching code. */
 #define NATIVE_LABEL(a,x,b) "\n\t.globl " a #x "_" #b "\n" a #x "_" #b ":\n\t"
@@ -372,6 +384,16 @@ unsigned native_patch(u8 type, void *ibuf, unsigned long addr, unsigned len);
 
 int paravirt_disable_iospace(void);
 
+/*
+ * This generates an indirect call based on the operation type number.
+ * The type number, computed in PARAVIRT_PATCH, is derived from the
+ * offset into the paravirt_patch_template structure, and can therefore be
+ * freely converted back into a structure offset.
+ */
+#define PARAVIRT_CALL                                  \
+       ANNOTATE_RETPOLINE_SAFE                         \
+       "call *%c[paravirt_opptr];"
+
 /*
  * These macros are intended to wrap calls through one of the paravirt
  * ops structs, so that they can be later identified and patched at
@@ -509,7 +531,7 @@ int paravirt_disable_iospace(void);
                /* since this condition will never hold */              \
                if (sizeof(rettype) > sizeof(unsigned long)) {          \
                        asm volatile(pre                                \
-                                    paravirt_call                      \
+                                    paravirt_alt(PARAVIRT_CALL)        \
                                     post                               \
                                     : call_clbr, ASM_CALL_CONSTRAINT   \
                                     : paravirt_type(op),               \
@@ -519,7 +541,7 @@ int paravirt_disable_iospace(void);
                        __ret = (rettype)((((u64)__edx) << 32) | __eax); \
                } else {                                                \
                        asm volatile(pre                                \
-                                    paravirt_call                      \
+                                    paravirt_alt(PARAVIRT_CALL)        \
                                     post                               \
                                     : call_clbr, ASM_CALL_CONSTRAINT   \
                                     : paravirt_type(op),               \
@@ -546,7 +568,7 @@ int paravirt_disable_iospace(void);
                PVOP_VCALL_ARGS;                                        \
                PVOP_TEST_NULL(op);                                     \
                asm volatile(pre                                        \
-                            paravirt_call                              \
+                            paravirt_alt(PARAVIRT_CALL)                \
                             post                                       \
                             : call_clbr, ASM_CALL_CONSTRAINT           \
                             : paravirt_type(op),                       \
@@ -664,26 +686,6 @@ struct paravirt_patch_site {
 extern struct paravirt_patch_site __parainstructions[],
        __parainstructions_end[];
 
-#else  /* __ASSEMBLY__ */
-
-/*
- * This generates an indirect call based on the operation type number.
- * The type number, computed in PARAVIRT_PATCH, is derived from the
- * offset into the paravirt_patch_template structure, and can therefore be
- * freely converted back into a structure offset.
- */
-.macro PARAVIRT_CALL type:req clobber:req pv_opptr:req
-771:   ANNOTATE_RETPOLINE_SAFE
-       call *\pv_opptr
-772:   .pushsection .parainstructions,"a"
-       _ASM_ALIGN
-       _ASM_PTR 771b
-       .byte \type
-       .byte 772b-771b
-       .short \clobber
-       .popsection
-.endm
-
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_X86_PARAVIRT_TYPES_H */
index 84bd9bdc1987faa634cd1daad7dbfe94d586a82b..88bca456da994c5b2a76f7046bf12f4f2615361d 100644 (file)
@@ -111,6 +111,11 @@ extern unsigned int ptrs_per_p4d;
  */
 #define MAXMEM                 (1UL << MAX_PHYSMEM_BITS)
 
+#define GUARD_HOLE_PGD_ENTRY   -256UL
+#define GUARD_HOLE_SIZE                (16UL << PGDIR_SHIFT)
+#define GUARD_HOLE_BASE_ADDR   (GUARD_HOLE_PGD_ENTRY << PGDIR_SHIFT)
+#define GUARD_HOLE_END_ADDR    (GUARD_HOLE_BASE_ADDR + GUARD_HOLE_SIZE)
+
 #define LDT_PGD_ENTRY          -240UL
 #define LDT_BASE_ADDR          (LDT_PGD_ENTRY << PGDIR_SHIFT)
 #define LDT_END_ADDR           (LDT_BASE_ADDR + PGDIR_SIZE)
index a8b5e1e133190ff1b8acf6d38795485d11fd061d..dbaed55c1c2442263624aeea5c1faa5afeefba26 100644 (file)
@@ -4,41 +4,6 @@
  * x86-specific implementation of refcount_t. Based on PAX_REFCOUNT from
  * PaX/grsecurity.
  */
-
-#ifdef __ASSEMBLY__
-
-#include <asm/asm.h>
-#include <asm/bug.h>
-
-.macro REFCOUNT_EXCEPTION counter:req
-       .pushsection .text..refcount
-111:   lea \counter, %_ASM_CX
-112:   ud2
-       ASM_UNREACHABLE
-       .popsection
-113:   _ASM_EXTABLE_REFCOUNT(112b, 113b)
-.endm
-
-/* Trigger refcount exception if refcount result is negative. */
-.macro REFCOUNT_CHECK_LT_ZERO counter:req
-       js 111f
-       REFCOUNT_EXCEPTION counter="\counter"
-.endm
-
-/* Trigger refcount exception if refcount result is zero or negative. */
-.macro REFCOUNT_CHECK_LE_ZERO counter:req
-       jz 111f
-       REFCOUNT_CHECK_LT_ZERO counter="\counter"
-.endm
-
-/* Trigger refcount exception unconditionally. */
-.macro REFCOUNT_ERROR counter:req
-       jmp 111f
-       REFCOUNT_EXCEPTION counter="\counter"
-.endm
-
-#else /* __ASSEMBLY__ */
-
 #include <linux/refcount.h>
 #include <asm/bug.h>
 
  * central refcount exception. The fixup address for the exception points
  * back to the regular execution flow in .text.
  */
+#define _REFCOUNT_EXCEPTION                            \
+       ".pushsection .text..refcount\n"                \
+       "111:\tlea %[var], %%" _ASM_CX "\n"             \
+       "112:\t" ASM_UD2 "\n"                           \
+       ASM_UNREACHABLE                                 \
+       ".popsection\n"                                 \
+       "113:\n"                                        \
+       _ASM_EXTABLE_REFCOUNT(112b, 113b)
+
+/* Trigger refcount exception if refcount result is negative. */
+#define REFCOUNT_CHECK_LT_ZERO                         \
+       "js 111f\n\t"                                   \
+       _REFCOUNT_EXCEPTION
+
+/* Trigger refcount exception if refcount result is zero or negative. */
+#define REFCOUNT_CHECK_LE_ZERO                         \
+       "jz 111f\n\t"                                   \
+       REFCOUNT_CHECK_LT_ZERO
+
+/* Trigger refcount exception unconditionally. */
+#define REFCOUNT_ERROR                                 \
+       "jmp 111f\n\t"                                  \
+       _REFCOUNT_EXCEPTION
 
 static __always_inline void refcount_add(unsigned int i, refcount_t *r)
 {
        asm volatile(LOCK_PREFIX "addl %1,%0\n\t"
-               "REFCOUNT_CHECK_LT_ZERO counter=\"%[counter]\""
-               : [counter] "+m" (r->refs.counter)
+               REFCOUNT_CHECK_LT_ZERO
+               : [var] "+m" (r->refs.counter)
                : "ir" (i)
                : "cc", "cx");
 }
@@ -63,32 +51,31 @@ static __always_inline void refcount_add(unsigned int i, refcount_t *r)
 static __always_inline void refcount_inc(refcount_t *r)
 {
        asm volatile(LOCK_PREFIX "incl %0\n\t"
-               "REFCOUNT_CHECK_LT_ZERO counter=\"%[counter]\""
-               : [counter] "+m" (r->refs.counter)
+               REFCOUNT_CHECK_LT_ZERO
+               : [var] "+m" (r->refs.counter)
                : : "cc", "cx");
 }
 
 static __always_inline void refcount_dec(refcount_t *r)
 {
        asm volatile(LOCK_PREFIX "decl %0\n\t"
-               "REFCOUNT_CHECK_LE_ZERO counter=\"%[counter]\""
-               : [counter] "+m" (r->refs.counter)
+               REFCOUNT_CHECK_LE_ZERO
+               : [var] "+m" (r->refs.counter)
                : : "cc", "cx");
 }
 
 static __always_inline __must_check
 bool refcount_sub_and_test(unsigned int i, refcount_t *r)
 {
-
        return GEN_BINARY_SUFFIXED_RMWcc(LOCK_PREFIX "subl",
-                                        "REFCOUNT_CHECK_LT_ZERO counter=\"%[var]\"",
+                                        REFCOUNT_CHECK_LT_ZERO,
                                         r->refs.counter, e, "er", i, "cx");
 }
 
 static __always_inline __must_check bool refcount_dec_and_test(refcount_t *r)
 {
        return GEN_UNARY_SUFFIXED_RMWcc(LOCK_PREFIX "decl",
-                                       "REFCOUNT_CHECK_LT_ZERO counter=\"%[var]\"",
+                                       REFCOUNT_CHECK_LT_ZERO,
                                        r->refs.counter, e, "cx");
 }
 
@@ -106,8 +93,8 @@ bool refcount_add_not_zero(unsigned int i, refcount_t *r)
 
                /* Did we try to increment from/to an undesirable state? */
                if (unlikely(c < 0 || c == INT_MAX || result < c)) {
-                       asm volatile("REFCOUNT_ERROR counter=\"%[counter]\""
-                                    : : [counter] "m" (r->refs.counter)
+                       asm volatile(REFCOUNT_ERROR
+                                    : : [var] "m" (r->refs.counter)
                                     : "cc", "cx");
                        break;
                }
@@ -122,6 +109,4 @@ static __always_inline __must_check bool refcount_inc_not_zero(refcount_t *r)
        return refcount_add_not_zero(1, r);
 }
 
-#endif /* __ASSEMBLY__ */
-
 #endif
index 27937458c231b62772bf956b1bc584fc030281ba..efa4a519f5e552eb1bb67f4ea980728310b3e0a5 100644 (file)
@@ -23,6 +23,7 @@
 
 #define pr_fmt(fmt)    KBUILD_MODNAME ": " fmt
 
+#include <linux/cpu.h>
 #include <linux/kernfs.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
@@ -310,9 +311,11 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
                return -EINVAL;
        buf[nbytes - 1] = '\0';
 
+       cpus_read_lock();
        rdtgrp = rdtgroup_kn_lock_live(of->kn);
        if (!rdtgrp) {
                rdtgroup_kn_unlock(of->kn);
+               cpus_read_unlock();
                return -ENOENT;
        }
        rdt_last_cmd_clear();
@@ -367,6 +370,7 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
 
 out:
        rdtgroup_kn_unlock(of->kn);
+       cpus_read_unlock();
        return ret ?: nbytes;
 }
 
index 2e173d47b450d4febbb9e2028f153bc91382b915..4d36dcc1cf87c5b75bcf085df5e77d745a852070 100644 (file)
@@ -165,6 +165,8 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
        struct mtrr_gentry gentry;
        void __user *arg = (void __user *) __arg;
 
+       memset(&gentry, 0, sizeof(gentry));
+
        switch (cmd) {
        case MTRRIOC_ADD_ENTRY:
        case MTRRIOC_SET_ENTRY:
diff --git a/arch/x86/kernel/macros.S b/arch/x86/kernel/macros.S
deleted file mode 100644 (file)
index 161c950..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/*
- * This file includes headers whose assembly part includes macros which are
- * commonly used. The macros are precompiled into assmebly file which is later
- * assembled together with each compiled file.
- */
-
-#include <linux/compiler.h>
-#include <asm/refcount.h>
-#include <asm/alternative-asm.h>
-#include <asm/bug.h>
-#include <asm/paravirt.h>
-#include <asm/asm.h>
-#include <asm/cpufeature.h>
-#include <asm/jump_label.h>
index bbfbf017065c387c76f3f7c6394f34816fb7a4f5..ddd4fa718c43d271cdcdf326ad88339bc412829d 100644 (file)
@@ -339,24 +339,6 @@ static unsigned long x86_fsgsbase_read_task(struct task_struct *task,
        return base;
 }
 
-void x86_fsbase_write_cpu(unsigned long fsbase)
-{
-       /*
-        * Set the selector to 0 as a notion, that the segment base is
-        * overwritten, which will be checked for skipping the segment load
-        * during context switch.
-        */
-       loadseg(FS, 0);
-       wrmsrl(MSR_FS_BASE, fsbase);
-}
-
-void x86_gsbase_write_cpu_inactive(unsigned long gsbase)
-{
-       /* Set the selector to 0 for the same reason as %fs above. */
-       loadseg(GS, 0);
-       wrmsrl(MSR_KERNEL_GS_BASE, gsbase);
-}
-
 unsigned long x86_fsbase_read_task(struct task_struct *task)
 {
        unsigned long fsbase;
@@ -385,38 +367,18 @@ unsigned long x86_gsbase_read_task(struct task_struct *task)
        return gsbase;
 }
 
-int x86_fsbase_write_task(struct task_struct *task, unsigned long fsbase)
+void x86_fsbase_write_task(struct task_struct *task, unsigned long fsbase)
 {
-       /*
-        * Not strictly needed for %fs, but do it for symmetry
-        * with %gs
-        */
-       if (unlikely(fsbase >= TASK_SIZE_MAX))
-               return -EPERM;
+       WARN_ON_ONCE(task == current);
 
-       preempt_disable();
        task->thread.fsbase = fsbase;
-       if (task == current)
-               x86_fsbase_write_cpu(fsbase);
-       task->thread.fsindex = 0;
-       preempt_enable();
-
-       return 0;
 }
 
-int x86_gsbase_write_task(struct task_struct *task, unsigned long gsbase)
+void x86_gsbase_write_task(struct task_struct *task, unsigned long gsbase)
 {
-       if (unlikely(gsbase >= TASK_SIZE_MAX))
-               return -EPERM;
+       WARN_ON_ONCE(task == current);
 
-       preempt_disable();
        task->thread.gsbase = gsbase;
-       if (task == current)
-               x86_gsbase_write_cpu_inactive(gsbase);
-       task->thread.gsindex = 0;
-       preempt_enable();
-
-       return 0;
 }
 
 int copy_thread_tls(unsigned long clone_flags, unsigned long sp,
@@ -754,11 +716,60 @@ long do_arch_prctl_64(struct task_struct *task, int option, unsigned long arg2)
 
        switch (option) {
        case ARCH_SET_GS: {
-               ret = x86_gsbase_write_task(task, arg2);
+               if (unlikely(arg2 >= TASK_SIZE_MAX))
+                       return -EPERM;
+
+               preempt_disable();
+               /*
+                * ARCH_SET_GS has always overwritten the index
+                * and the base. Zero is the most sensible value
+                * to put in the index, and is the only value that
+                * makes any sense if FSGSBASE is unavailable.
+                */
+               if (task == current) {
+                       loadseg(GS, 0);
+                       x86_gsbase_write_cpu_inactive(arg2);
+
+                       /*
+                        * On non-FSGSBASE systems, save_base_legacy() expects
+                        * that we also fill in thread.gsbase.
+                        */
+                       task->thread.gsbase = arg2;
+
+               } else {
+                       task->thread.gsindex = 0;
+                       x86_gsbase_write_task(task, arg2);
+               }
+               preempt_enable();
                break;
        }
        case ARCH_SET_FS: {
-               ret = x86_fsbase_write_task(task, arg2);
+               /*
+                * Not strictly needed for %fs, but do it for symmetry
+                * with %gs
+                */
+               if (unlikely(arg2 >= TASK_SIZE_MAX))
+                       return -EPERM;
+
+               preempt_disable();
+               /*
+                * Set the selector to 0 for the same reason
+                * as %gs above.
+                */
+               if (task == current) {
+                       loadseg(FS, 0);
+                       x86_fsbase_write_cpu(arg2);
+
+                       /*
+                        * On non-FSGSBASE systems, save_base_legacy() expects
+                        * that we also fill in thread.fsbase.
+                        */
+                       task->thread.fsbase = arg2;
+               } else {
+                       task->thread.fsindex = 0;
+                       x86_fsbase_write_task(task, arg2);
+               }
+               preempt_enable();
                break;
        }
        case ARCH_GET_FS: {
index ffae9b9740fdf3a53619f03c4261be6711d7e7a7..4b8ee05dd6addf89478a4f26e8b8d6be29329721 100644 (file)
@@ -397,11 +397,12 @@ static int putreg(struct task_struct *child,
                if (value >= TASK_SIZE_MAX)
                        return -EIO;
                /*
-                * When changing the FS base, use the same
-                * mechanism as for do_arch_prctl_64().
+                * When changing the FS base, use do_arch_prctl_64()
+                * to set the index to zero and to set the base
+                * as requested.
                 */
                if (child->thread.fsbase != value)
-                       return x86_fsbase_write_task(child, value);
+                       return do_arch_prctl_64(child, ARCH_SET_FS, value);
                return 0;
        case offsetof(struct user_regs_struct,gs_base):
                /*
@@ -410,7 +411,7 @@ static int putreg(struct task_struct *child,
                if (value >= TASK_SIZE_MAX)
                        return -EIO;
                if (child->thread.gsbase != value)
-                       return x86_gsbase_write_task(child, value);
+                       return do_arch_prctl_64(child, ARCH_SET_GS, value);
                return 0;
 #endif
        }
index cc6467b35a85f6cec9300011cfa0c464574ed5d3..101f53ccf5718d99e5c1e95927b153031114c497 100644 (file)
@@ -2937,6 +2937,8 @@ static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu,
 static void nested_svm_init_mmu_context(struct kvm_vcpu *vcpu)
 {
        WARN_ON(mmu_is_nested(vcpu));
+
+       vcpu->arch.mmu = &vcpu->arch.guest_mmu;
        kvm_init_shadow_mmu(vcpu);
        vcpu->arch.mmu->set_cr3           = nested_svm_set_tdp_cr3;
        vcpu->arch.mmu->get_cr3           = nested_svm_get_tdp_cr3;
@@ -2949,6 +2951,7 @@ static void nested_svm_init_mmu_context(struct kvm_vcpu *vcpu)
 
 static void nested_svm_uninit_mmu_context(struct kvm_vcpu *vcpu)
 {
+       vcpu->arch.mmu = &vcpu->arch.root_mmu;
        vcpu->arch.walk_mmu = &vcpu->arch.root_mmu;
 }
 
@@ -3458,7 +3461,6 @@ static void enter_svm_guest_mode(struct vcpu_svm *svm, u64 vmcb_gpa,
                svm->vcpu.arch.hflags &= ~HF_HIF_MASK;
 
        if (nested_vmcb->control.nested_ctl & SVM_NESTED_CTL_NP_ENABLE) {
-               kvm_mmu_unload(&svm->vcpu);
                svm->nested.nested_cr3 = nested_vmcb->control.nested_cr3;
                nested_svm_init_mmu_context(&svm->vcpu);
        }
index 02edd9960e9d94cf8cbac80ea1bfccc5673f3089..8d5d984541beaa111b94e59e512871f91c08a7da 100644 (file)
@@ -11985,6 +11985,8 @@ static void nested_get_vmcs12_pages(struct kvm_vcpu *vcpu)
                        kunmap(vmx->nested.pi_desc_page);
                        kvm_release_page_dirty(vmx->nested.pi_desc_page);
                        vmx->nested.pi_desc_page = NULL;
+                       vmx->nested.pi_desc = NULL;
+                       vmcs_write64(POSTED_INTR_DESC_ADDR, -1ull);
                }
                page = kvm_vcpu_gpa_to_page(vcpu, vmcs12->posted_intr_desc_addr);
                if (is_error_page(page))
index d02937760c3ba8adc6de37ed4b39db9a926f320d..f049ecfac7bb8a8cd7780efd9b40fbbdf8a7d089 100644 (file)
@@ -2426,6 +2426,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
        case MSR_AMD64_PATCH_LOADER:
        case MSR_AMD64_BU_CFG2:
        case MSR_AMD64_DC_CFG:
+       case MSR_F15H_EX_CFG:
                break;
 
        case MSR_IA32_UCODE_REV:
@@ -2721,6 +2722,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
        case MSR_AMD64_BU_CFG2:
        case MSR_IA32_PERF_CTL:
        case MSR_AMD64_DC_CFG:
+       case MSR_F15H_EX_CFG:
                msr_info->data = 0;
                break;
        case MSR_F15H_PERF_CTL0 ... MSR_F15H_PERF_CTR5:
@@ -7446,7 +7448,7 @@ void kvm_make_scan_ioapic_request(struct kvm *kvm)
 
 static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
 {
-       if (!kvm_apic_hw_enabled(vcpu->arch.apic))
+       if (!kvm_apic_present(vcpu))
                return;
 
        bitmap_zero(vcpu->arch.ioapic_handled_vectors, 256);
index fc37bbd23eb8b4c996cddeb1c1f6c39cc2a23f5d..abcb8d00b01486f431fc9fa591f6e6260c8e1153 100644 (file)
@@ -55,10 +55,10 @@ struct addr_marker {
 enum address_markers_idx {
        USER_SPACE_NR = 0,
        KERNEL_SPACE_NR,
-       LOW_KERNEL_NR,
-#if defined(CONFIG_MODIFY_LDT_SYSCALL) && defined(CONFIG_X86_5LEVEL)
+#ifdef CONFIG_MODIFY_LDT_SYSCALL
        LDT_NR,
 #endif
+       LOW_KERNEL_NR,
        VMALLOC_START_NR,
        VMEMMAP_START_NR,
 #ifdef CONFIG_KASAN
@@ -66,9 +66,6 @@ enum address_markers_idx {
        KASAN_SHADOW_END_NR,
 #endif
        CPU_ENTRY_AREA_NR,
-#if defined(CONFIG_MODIFY_LDT_SYSCALL) && !defined(CONFIG_X86_5LEVEL)
-       LDT_NR,
-#endif
 #ifdef CONFIG_X86_ESPFIX64
        ESPFIX_START_NR,
 #endif
@@ -512,11 +509,11 @@ static inline bool is_hypervisor_range(int idx)
 {
 #ifdef CONFIG_X86_64
        /*
-        * ffff800000000000 - ffff87ffffffffff is reserved for
-        * the hypervisor.
+        * A hole in the beginning of kernel address space reserved
+        * for a hypervisor.
         */
-       return  (idx >= pgd_index(__PAGE_OFFSET) - 16) &&
-               (idx <  pgd_index(__PAGE_OFFSET));
+       return  (idx >= pgd_index(GUARD_HOLE_BASE_ADDR)) &&
+               (idx <  pgd_index(GUARD_HOLE_END_ADDR));
 #else
        return false;
 #endif
index db7a1008223886d398c531d8d34720cd0265d17d..a1bcde35db4cac8468a4a344094eee9daacb0f41 100644 (file)
@@ -285,20 +285,16 @@ static void cpa_flush_all(unsigned long cache)
        on_each_cpu(__cpa_flush_all, (void *) cache, 1);
 }
 
-static bool __cpa_flush_range(unsigned long start, int numpages, int cache)
+static bool __inv_flush_all(int cache)
 {
        BUG_ON(irqs_disabled() && !early_boot_irqs_disabled);
 
-       WARN_ON(PAGE_ALIGN(start) != start);
-
        if (cache && !static_cpu_has(X86_FEATURE_CLFLUSH)) {
                cpa_flush_all(cache);
                return true;
        }
 
-       flush_tlb_kernel_range(start, start + PAGE_SIZE * numpages);
-
-       return !cache;
+       return false;
 }
 
 static void cpa_flush_range(unsigned long start, int numpages, int cache)
@@ -306,7 +302,14 @@ static void cpa_flush_range(unsigned long start, int numpages, int cache)
        unsigned int i, level;
        unsigned long addr;
 
-       if (__cpa_flush_range(start, numpages, cache))
+       WARN_ON(PAGE_ALIGN(start) != start);
+
+       if (__inv_flush_all(cache))
+               return;
+
+       flush_tlb_kernel_range(start, start + PAGE_SIZE * numpages);
+
+       if (!cache)
                return;
 
        /*
@@ -332,7 +335,12 @@ static void cpa_flush_array(unsigned long baddr, unsigned long *start,
 {
        unsigned int i, level;
 
-       if (__cpa_flush_range(baddr, numpages, cache))
+       if (__inv_flush_all(cache))
+               return;
+
+       flush_tlb_all();
+
+       if (!cache)
                return;
 
        /*
index 08013524fba18ebe2afc44bf798c5ad77839fa0b..4fe956a63b25b54fe479aadfeb51dfdf66ef74d2 100644 (file)
@@ -519,8 +519,13 @@ static u64 sanitize_phys(u64 address)
         * for a "decoy" virtual address (bit 63 clear) passed to
         * set_memory_X(). __pa() on a "decoy" address results in a
         * physical address with bit 63 set.
+        *
+        * Decoy addresses are not present for 32-bit builds, see
+        * set_mce_nospec().
         */
-       return address & __PHYSICAL_MASK;
+       if (IS_ENABLED(CONFIG_X86_64))
+               return address & __PHYSICAL_MASK;
+       return address;
 }
 
 /*
@@ -546,7 +551,11 @@ int reserve_memtype(u64 start, u64 end, enum page_cache_mode req_type,
 
        start = sanitize_phys(start);
        end = sanitize_phys(end);
-       BUG_ON(start >= end); /* end is exclusive */
+       if (start >= end) {
+               WARN(1, "%s failed: [mem %#010Lx-%#010Lx], req %s\n", __func__,
+                               start, end - 1, cattr_name(req_type));
+               return -EINVAL;
+       }
 
        if (!pat_enabled()) {
                /* This is identical to page table setting without PAT */
index a5d7ed12533707f8714e066cd4be4c30f880988d..0f4fe206dcc2015ce212b19c8865b06f854fb3b1 100644 (file)
@@ -648,19 +648,20 @@ static int __xen_pgd_walk(struct mm_struct *mm, pgd_t *pgd,
                          unsigned long limit)
 {
        int i, nr, flush = 0;
-       unsigned hole_low, hole_high;
+       unsigned hole_low = 0, hole_high = 0;
 
        /* The limit is the last byte to be touched */
        limit--;
        BUG_ON(limit >= FIXADDR_TOP);
 
+#ifdef CONFIG_X86_64
        /*
         * 64-bit has a great big hole in the middle of the address
-        * space, which contains the Xen mappings.  On 32-bit these
-        * will end up making a zero-sized hole and so is a no-op.
+        * space, which contains the Xen mappings.
         */
-       hole_low = pgd_index(USER_LIMIT);
-       hole_high = pgd_index(PAGE_OFFSET);
+       hole_low = pgd_index(GUARD_HOLE_BASE_ADDR);
+       hole_high = pgd_index(GUARD_HOLE_END_ADDR);
+#endif
 
        nr = pgd_index(limit) + 1;
        for (i = 0; i < nr; i++) {
index 4f4d9884443b63a8f002ddd754ea467f9a0e4c16..4d86e90654b20ff284df67ad594fd18013a14b60 100644 (file)
@@ -1261,7 +1261,8 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
                if (ret)
                        goto cleanup;
        } else {
-               zero_fill_bio(bio);
+               if (bmd->is_our_pages)
+                       zero_fill_bio(bio);
                iov_iter_advance(iter, bio->bi_iter.bi_size);
        }
 
index 13ba2011a306a8c4c52fe07bc7a5b147e86472a6..a327bef076422e52501be27ad4c7c4dee42dbb64 100644 (file)
@@ -378,7 +378,7 @@ static struct blk_zone *blk_alloc_zones(int node, unsigned int *nr_zones)
        struct page *page;
        int order;
 
-       for (order = get_order(size); order > 0; order--) {
+       for (order = get_order(size); order >= 0; order--) {
                page = alloc_pages_node(node, GFP_NOIO | __GFP_ZERO, order);
                if (page) {
                        *nr_zones = min_t(unsigned int, *nr_zones,
index 81c22d20d9d9c568ffc2f6c191a407baee330719..60e0b772673f3bd0c631efb6e45b0f624f75aa8a 100644 (file)
@@ -538,6 +538,9 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
        }
        case 'x':       /* gotoxy : LxXXX[yYYY]; */
        case 'y':       /* gotoxy : LyYYY[xXXX]; */
+               if (priv->esc_seq.buf[priv->esc_seq.len - 1] != ';')
+                       break;
+
                /* If the command is valid, move to the new address */
                if (parse_xy(esc, &priv->addr.x, &priv->addr.y))
                        charlcd_gotoxy(lcd);
index ef1b267cb058a4a03f0ead86218ee165653fd737..64da032bb9edb35d571f013ca37582179493961c 100644 (file)
@@ -297,7 +297,7 @@ static struct clk_alpha_pll gpll0_out_main = {
                .hw.init = &(struct clk_init_data){
                        .name = "gpll0_out_main",
                        .parent_names = (const char *[])
-                                       { "gpll0_sleep_clk_src" },
+                                       { "cxo" },
                        .num_parents = 1,
                        .ops = &clk_alpha_pll_ops,
                },
index 7725b6ee14efb2ecc89d9c0822aa19903284d3f5..59bb67d5a7cede7198c652b53550941754cb9a3e 100644 (file)
@@ -153,6 +153,11 @@ struct chtls_dev {
        unsigned int cdev_state;
 };
 
+struct chtls_listen {
+       struct chtls_dev *cdev;
+       struct sock *sk;
+};
+
 struct chtls_hws {
        struct sk_buff_head sk_recv_queue;
        u8 txqid;
@@ -215,6 +220,8 @@ struct chtls_sock {
        u16 resv2;
        u32 delack_mode;
        u32 delack_seq;
+       u32 snd_win;
+       u32 rcv_win;
 
        void *passive_reap_next;        /* placeholder for passive */
        struct chtls_hws tlshws;
index 20209e29f814659227ef11861571c9ed6d7ace9d..931b96c220af973f450cf0b34a37924d40656e9f 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/kallsyms.h>
 #include <linux/kprobes.h>
 #include <linux/if_vlan.h>
+#include <net/inet_common.h>
 #include <net/tcp.h>
 #include <net/dst.h>
 
@@ -887,24 +888,6 @@ static unsigned int chtls_select_mss(const struct chtls_sock *csk,
        return mtu_idx;
 }
 
-static unsigned int select_rcv_wnd(struct chtls_sock *csk)
-{
-       unsigned int rcvwnd;
-       unsigned int wnd;
-       struct sock *sk;
-
-       sk = csk->sk;
-       wnd = tcp_full_space(sk);
-
-       if (wnd < MIN_RCV_WND)
-               wnd = MIN_RCV_WND;
-
-       rcvwnd = MAX_RCV_WND;
-
-       csk_set_flag(csk, CSK_UPDATE_RCV_WND);
-       return min(wnd, rcvwnd);
-}
-
 static unsigned int select_rcv_wscale(int space, int wscale_ok, int win_clamp)
 {
        int wscale = 0;
@@ -951,7 +934,7 @@ static void chtls_pass_accept_rpl(struct sk_buff *skb,
        csk->mtu_idx = chtls_select_mss(csk, dst_mtu(__sk_dst_get(sk)),
                                        req);
        opt0 = TCAM_BYPASS_F |
-              WND_SCALE_V((tp)->rx_opt.rcv_wscale) |
+              WND_SCALE_V(RCV_WSCALE(tp)) |
               MSS_IDX_V(csk->mtu_idx) |
               L2T_IDX_V(csk->l2t_entry->idx) |
               NAGLE_V(!(tp->nonagle & TCP_NAGLE_OFF)) |
@@ -1005,6 +988,25 @@ static int chtls_backlog_rcv(struct sock *sk, struct sk_buff *skb)
        return 0;
 }
 
+static void chtls_set_tcp_window(struct chtls_sock *csk)
+{
+       struct net_device *ndev = csk->egress_dev;
+       struct port_info *pi = netdev_priv(ndev);
+       unsigned int linkspeed;
+       u8 scale;
+
+       linkspeed = pi->link_cfg.speed;
+       scale = linkspeed / SPEED_10000;
+#define CHTLS_10G_RCVWIN (256 * 1024)
+       csk->rcv_win = CHTLS_10G_RCVWIN;
+       if (scale)
+               csk->rcv_win *= scale;
+#define CHTLS_10G_SNDWIN (256 * 1024)
+       csk->snd_win = CHTLS_10G_SNDWIN;
+       if (scale)
+               csk->snd_win *= scale;
+}
+
 static struct sock *chtls_recv_sock(struct sock *lsk,
                                    struct request_sock *oreq,
                                    void *network_hdr,
@@ -1067,6 +1069,9 @@ static struct sock *chtls_recv_sock(struct sock *lsk,
        csk->port_id = port_id;
        csk->egress_dev = ndev;
        csk->tos = PASS_OPEN_TOS_G(ntohl(req->tos_stid));
+       chtls_set_tcp_window(csk);
+       tp->rcv_wnd = csk->rcv_win;
+       csk->sndbuf = csk->snd_win;
        csk->ulp_mode = ULP_MODE_TLS;
        step = cdev->lldi->nrxq / cdev->lldi->nchan;
        csk->rss_qid = cdev->lldi->rxq_ids[port_id * step];
@@ -1076,9 +1081,9 @@ static struct sock *chtls_recv_sock(struct sock *lsk,
        csk->sndbuf = newsk->sk_sndbuf;
        csk->smac_idx = cxgb4_tp_smt_idx(cdev->lldi->adapter_type,
                                         cxgb4_port_viid(ndev));
-       tp->rcv_wnd = select_rcv_wnd(csk);
        RCV_WSCALE(tp) = select_rcv_wscale(tcp_full_space(newsk),
-                                          WSCALE_OK(tp),
+                                          sock_net(newsk)->
+                                               ipv4.sysctl_tcp_window_scaling,
                                           tp->window_clamp);
        neigh_release(n);
        inet_inherit_port(&tcp_hashinfo, lsk, newsk);
@@ -1130,6 +1135,7 @@ static void chtls_pass_accept_request(struct sock *sk,
        struct cpl_t5_pass_accept_rpl *rpl;
        struct cpl_pass_accept_req *req;
        struct listen_ctx *listen_ctx;
+       struct vlan_ethhdr *vlan_eh;
        struct request_sock *oreq;
        struct sk_buff *reply_skb;
        struct chtls_sock *csk;
@@ -1142,6 +1148,10 @@ static void chtls_pass_accept_request(struct sock *sk,
        unsigned int stid;
        unsigned int len;
        unsigned int tid;
+       bool th_ecn, ect;
+       __u8 ip_dsfield; /* IPv4 tos or IPv6 dsfield */
+       u16 eth_hdr_len;
+       bool ecn_ok;
 
        req = cplhdr(skb) + RSS_HDR;
        tid = GET_TID(req);
@@ -1180,24 +1190,40 @@ static void chtls_pass_accept_request(struct sock *sk,
        oreq->mss = 0;
        oreq->ts_recent = 0;
 
-       eh = (struct ethhdr *)(req + 1);
-       iph = (struct iphdr *)(eh + 1);
+       eth_hdr_len = T6_ETH_HDR_LEN_G(ntohl(req->hdr_len));
+       if (eth_hdr_len == ETH_HLEN) {
+               eh = (struct ethhdr *)(req + 1);
+               iph = (struct iphdr *)(eh + 1);
+               network_hdr = (void *)(eh + 1);
+       } else {
+               vlan_eh = (struct vlan_ethhdr *)(req + 1);
+               iph = (struct iphdr *)(vlan_eh + 1);
+               network_hdr = (void *)(vlan_eh + 1);
+       }
        if (iph->version != 0x4)
                goto free_oreq;
 
-       network_hdr = (void *)(eh + 1);
        tcph = (struct tcphdr *)(iph + 1);
+       skb_set_network_header(skb, (void *)iph - (void *)req);
 
        tcp_rsk(oreq)->tfo_listener = false;
        tcp_rsk(oreq)->rcv_isn = ntohl(tcph->seq);
        chtls_set_req_port(oreq, tcph->source, tcph->dest);
-       inet_rsk(oreq)->ecn_ok = 0;
        chtls_set_req_addr(oreq, iph->daddr, iph->saddr);
-       if (req->tcpopt.wsf <= 14) {
+       ip_dsfield = ipv4_get_dsfield(iph);
+       if (req->tcpopt.wsf <= 14 &&
+           sock_net(sk)->ipv4.sysctl_tcp_window_scaling) {
                inet_rsk(oreq)->wscale_ok = 1;
                inet_rsk(oreq)->snd_wscale = req->tcpopt.wsf;
        }
        inet_rsk(oreq)->ir_iif = sk->sk_bound_dev_if;
+       th_ecn = tcph->ece && tcph->cwr;
+       if (th_ecn) {
+               ect = !INET_ECN_is_not_ect(ip_dsfield);
+               ecn_ok = sock_net(sk)->ipv4.sysctl_tcp_ecn;
+               if ((!ect && ecn_ok) || tcp_ca_needs_ecn(sk))
+                       inet_rsk(oreq)->ecn_ok = 1;
+       }
 
        newsk = chtls_recv_sock(sk, oreq, network_hdr, req, cdev);
        if (!newsk)
index afebbd87c4aa1d22ca179f558552cb2f410fcc0a..18f553fcc1673dda35c0aaf663c0670d7a24e458 100644 (file)
@@ -397,7 +397,7 @@ static void tls_tx_data_wr(struct sock *sk, struct sk_buff *skb,
 
        req_wr->lsodisable_to_flags =
                        htonl(TX_ULP_MODE_V(ULP_MODE_TLS) |
-                             FW_OFLD_TX_DATA_WR_URGENT_V(skb_urgent(skb)) |
+                             TX_URG_V(skb_urgent(skb)) |
                              T6_TX_FORCE_F | wr_ulp_mode_force |
                              TX_SHOVE_V((!csk_flag(sk, CSK_TX_MORE_DATA)) &&
                                         skb_queue_empty(&csk->txq)));
@@ -534,10 +534,9 @@ static void make_tx_data_wr(struct sock *sk, struct sk_buff *skb,
                                FW_OFLD_TX_DATA_WR_SHOVE_F);
 
        req->tunnel_to_proxy = htonl(wr_ulp_mode_force |
-                       FW_OFLD_TX_DATA_WR_URGENT_V(skb_urgent(skb)) |
-                       FW_OFLD_TX_DATA_WR_SHOVE_V((!csk_flag
-                                       (sk, CSK_TX_MORE_DATA)) &&
-                                        skb_queue_empty(&csk->txq)));
+                       TX_URG_V(skb_urgent(skb)) |
+                       TX_SHOVE_V((!csk_flag(sk, CSK_TX_MORE_DATA)) &&
+                                  skb_queue_empty(&csk->txq)));
        req->plen = htonl(len);
 }
 
@@ -995,7 +994,6 @@ int chtls_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
        int mss, flags, err;
        int recordsz = 0;
        int copied = 0;
-       int hdrlen = 0;
        long timeo;
 
        lock_sock(sk);
@@ -1032,7 +1030,7 @@ int chtls_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
 
                        recordsz = tls_header_read(&hdr, &msg->msg_iter);
                        size -= TLS_HEADER_LENGTH;
-                       hdrlen += TLS_HEADER_LENGTH;
+                       copied += TLS_HEADER_LENGTH;
                        csk->tlshws.txleft = recordsz;
                        csk->tlshws.type = hdr.type;
                        if (skb)
@@ -1083,10 +1081,8 @@ new_buf:
                        int off = TCP_OFF(sk);
                        bool merge;
 
-                       if (!page)
-                               goto wait_for_memory;
-
-                       pg_size <<= compound_order(page);
+                       if (page)
+                               pg_size <<= compound_order(page);
                        if (off < pg_size &&
                            skb_can_coalesce(skb, i, page, off)) {
                                merge = 1;
@@ -1187,7 +1183,7 @@ out:
                chtls_tcp_push(sk, flags);
 done:
        release_sock(sk);
-       return copied + hdrlen;
+       return copied;
 do_fault:
        if (!skb->len) {
                __skb_unlink(skb, &csk->txq);
index f472c51abe56ac7de376d58483a3508eabcc069b..563f8fe7686adc9c895dbb623cac3f7c9ae5a3a6 100644 (file)
@@ -55,24 +55,19 @@ static void unregister_listen_notifier(struct notifier_block *nb)
 static int listen_notify_handler(struct notifier_block *this,
                                 unsigned long event, void *data)
 {
-       struct chtls_dev *cdev;
-       struct sock *sk;
-       int ret;
+       struct chtls_listen *clisten;
+       int ret = NOTIFY_DONE;
 
-       sk = data;
-       ret =  NOTIFY_DONE;
+       clisten = (struct chtls_listen *)data;
 
        switch (event) {
        case CHTLS_LISTEN_START:
+               ret = chtls_listen_start(clisten->cdev, clisten->sk);
+               kfree(clisten);
+               break;
        case CHTLS_LISTEN_STOP:
-               mutex_lock(&cdev_list_lock);
-               list_for_each_entry(cdev, &cdev_list, list) {
-                       if (event == CHTLS_LISTEN_START)
-                               ret = chtls_listen_start(cdev, sk);
-                       else
-                               chtls_listen_stop(cdev, sk);
-               }
-               mutex_unlock(&cdev_list_lock);
+               chtls_listen_stop(clisten->cdev, clisten->sk);
+               kfree(clisten);
                break;
        }
        return ret;
@@ -90,8 +85,9 @@ static int listen_backlog_rcv(struct sock *sk, struct sk_buff *skb)
        return 0;
 }
 
-static int chtls_start_listen(struct sock *sk)
+static int chtls_start_listen(struct chtls_dev *cdev, struct sock *sk)
 {
+       struct chtls_listen *clisten;
        int err;
 
        if (sk->sk_protocol != IPPROTO_TCP)
@@ -102,21 +98,33 @@ static int chtls_start_listen(struct sock *sk)
                return -EADDRNOTAVAIL;
 
        sk->sk_backlog_rcv = listen_backlog_rcv;
+       clisten = kmalloc(sizeof(*clisten), GFP_KERNEL);
+       if (!clisten)
+               return -ENOMEM;
+       clisten->cdev = cdev;
+       clisten->sk = sk;
        mutex_lock(&notify_mutex);
        err = raw_notifier_call_chain(&listen_notify_list,
-                                     CHTLS_LISTEN_START, sk);
+                                     CHTLS_LISTEN_START, clisten);
        mutex_unlock(&notify_mutex);
        return err;
 }
 
-static void chtls_stop_listen(struct sock *sk)
+static void chtls_stop_listen(struct chtls_dev *cdev, struct sock *sk)
 {
+       struct chtls_listen *clisten;
+
        if (sk->sk_protocol != IPPROTO_TCP)
                return;
 
+       clisten = kmalloc(sizeof(*clisten), GFP_KERNEL);
+       if (!clisten)
+               return;
+       clisten->cdev = cdev;
+       clisten->sk = sk;
        mutex_lock(&notify_mutex);
        raw_notifier_call_chain(&listen_notify_list,
-                               CHTLS_LISTEN_STOP, sk);
+                               CHTLS_LISTEN_STOP, clisten);
        mutex_unlock(&notify_mutex);
 }
 
@@ -138,15 +146,43 @@ static int chtls_inline_feature(struct tls_device *dev)
 
 static int chtls_create_hash(struct tls_device *dev, struct sock *sk)
 {
+       struct chtls_dev *cdev = to_chtls_dev(dev);
+
        if (sk->sk_state == TCP_LISTEN)
-               return chtls_start_listen(sk);
+               return chtls_start_listen(cdev, sk);
        return 0;
 }
 
 static void chtls_destroy_hash(struct tls_device *dev, struct sock *sk)
 {
+       struct chtls_dev *cdev = to_chtls_dev(dev);
+
        if (sk->sk_state == TCP_LISTEN)
-               chtls_stop_listen(sk);
+               chtls_stop_listen(cdev, sk);
+}
+
+static void chtls_free_uld(struct chtls_dev *cdev)
+{
+       int i;
+
+       tls_unregister_device(&cdev->tlsdev);
+       kvfree(cdev->kmap.addr);
+       idr_destroy(&cdev->hwtid_idr);
+       for (i = 0; i < (1 << RSPQ_HASH_BITS); i++)
+               kfree_skb(cdev->rspq_skb_cache[i]);
+       kfree(cdev->lldi);
+       kfree_skb(cdev->askb);
+       kfree(cdev);
+}
+
+static inline void chtls_dev_release(struct kref *kref)
+{
+       struct chtls_dev *cdev;
+       struct tls_device *dev;
+
+       dev = container_of(kref, struct tls_device, kref);
+       cdev = to_chtls_dev(dev);
+       chtls_free_uld(cdev);
 }
 
 static void chtls_register_dev(struct chtls_dev *cdev)
@@ -159,15 +195,12 @@ static void chtls_register_dev(struct chtls_dev *cdev)
        tlsdev->feature = chtls_inline_feature;
        tlsdev->hash = chtls_create_hash;
        tlsdev->unhash = chtls_destroy_hash;
-       tls_register_device(&cdev->tlsdev);
+       tlsdev->release = chtls_dev_release;
+       kref_init(&tlsdev->kref);
+       tls_register_device(tlsdev);
        cdev->cdev_state = CHTLS_CDEV_STATE_UP;
 }
 
-static void chtls_unregister_dev(struct chtls_dev *cdev)
-{
-       tls_unregister_device(&cdev->tlsdev);
-}
-
 static void process_deferq(struct work_struct *task_param)
 {
        struct chtls_dev *cdev = container_of(task_param,
@@ -262,28 +295,16 @@ out:
        return NULL;
 }
 
-static void chtls_free_uld(struct chtls_dev *cdev)
-{
-       int i;
-
-       chtls_unregister_dev(cdev);
-       kvfree(cdev->kmap.addr);
-       idr_destroy(&cdev->hwtid_idr);
-       for (i = 0; i < (1 << RSPQ_HASH_BITS); i++)
-               kfree_skb(cdev->rspq_skb_cache[i]);
-       kfree(cdev->lldi);
-       kfree_skb(cdev->askb);
-       kfree(cdev);
-}
-
 static void chtls_free_all_uld(void)
 {
        struct chtls_dev *cdev, *tmp;
 
        mutex_lock(&cdev_mutex);
        list_for_each_entry_safe(cdev, tmp, &cdev_list, list) {
-               if (cdev->cdev_state == CHTLS_CDEV_STATE_UP)
-                       chtls_free_uld(cdev);
+               if (cdev->cdev_state == CHTLS_CDEV_STATE_UP) {
+                       list_del(&cdev->list);
+                       kref_put(&cdev->tlsdev.kref, cdev->tlsdev.release);
+               }
        }
        mutex_unlock(&cdev_mutex);
 }
@@ -304,7 +325,7 @@ static int chtls_uld_state_change(void *handle, enum cxgb4_state new_state)
                mutex_lock(&cdev_mutex);
                list_del(&cdev->list);
                mutex_unlock(&cdev_mutex);
-               chtls_free_uld(cdev);
+               kref_put(&cdev->tlsdev.kref, cdev->tlsdev.release);
                break;
        default:
                break;
index 05813fbf3daf25f4aeb6ea0233f13c13dd95ad73..647dfbbc4e1cf44ac989a1562e2c2f711fca5d36 100644 (file)
@@ -25,7 +25,7 @@ static int max7301_spi_write(struct device *dev, unsigned int reg,
        struct spi_device *spi = to_spi_device(dev);
        u16 word = ((reg & 0x7F) << 8) | (val & 0xFF);
 
-       return spi_write(spi, (const u8 *)&word, sizeof(word));
+       return spi_write_then_read(spi, &word, sizeof(word), NULL, 0);
 }
 
 /* A read from the MAX7301 means two transfers; here, one message each */
@@ -37,14 +37,8 @@ static int max7301_spi_read(struct device *dev, unsigned int reg)
        struct spi_device *spi = to_spi_device(dev);
 
        word = 0x8000 | (reg << 8);
-       ret = spi_write(spi, (const u8 *)&word, sizeof(word));
-       if (ret)
-               return ret;
-       /*
-        * This relies on the fact, that a transfer with NULL tx_buf shifts out
-        * zero bytes (=NOOP for MAX7301)
-        */
-       ret = spi_read(spi, (u8 *)&word, sizeof(word));
+       ret = spi_write_then_read(spi, &word, sizeof(word), &word,
+                                 sizeof(word));
        if (ret)
                return ret;
        return word & 0xff;
index 6e02148c208b2cc600d75263d1c87064db2ebc23..adc768f908f1ae1937f3d245088c590b449e574f 100644 (file)
@@ -773,9 +773,6 @@ static int mvebu_pwm_probe(struct platform_device *pdev,
                                     "marvell,armada-370-gpio"))
                return 0;
 
-       if (IS_ERR(mvchip->clk))
-               return PTR_ERR(mvchip->clk);
-
        /*
         * There are only two sets of PWM configuration registers for
         * all the GPIO lines on those SoCs which this driver reserves
@@ -786,6 +783,9 @@ static int mvebu_pwm_probe(struct platform_device *pdev,
        if (!res)
                return 0;
 
+       if (IS_ERR(mvchip->clk))
+               return PTR_ERR(mvchip->clk);
+
        /*
         * Use set A for lines of GPIO chip with id 0, B for GPIO chip
         * with id 1. Don't allow further GPIO chips to be used for PWM.
index 9887c3db6e16ace91790fbb938452584512e45c5..5b3e83cd71378b0ee81f83a51e4a69380d752fef 100644 (file)
@@ -32,7 +32,6 @@
 #define OMAP4_GPIO_DEBOUNCINGTIME_MASK 0xFF
 
 #define OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER    BIT(2)
-#define OMAP_GPIO_QUIRK_DEFERRED_WKUP_EN       BIT(1)
 
 struct gpio_regs {
        u32 irqenable1;
@@ -379,18 +378,9 @@ static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio,
                        readl_relaxed(bank->base + bank->regs->fallingdetect);
 
        if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
-               /* Defer wkup_en register update until we idle? */
-               if (bank->quirks & OMAP_GPIO_QUIRK_DEFERRED_WKUP_EN) {
-                       if (trigger)
-                               bank->context.wake_en |= gpio_bit;
-                       else
-                               bank->context.wake_en &= ~gpio_bit;
-               } else {
-                       omap_gpio_rmw(base, bank->regs->wkup_en, gpio_bit,
-                                     trigger != 0);
-                       bank->context.wake_en =
-                               readl_relaxed(bank->base + bank->regs->wkup_en);
-               }
+               omap_gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0);
+               bank->context.wake_en =
+                       readl_relaxed(bank->base + bank->regs->wkup_en);
        }
 
        /* This part needs to be executed always for OMAP{34xx, 44xx} */
@@ -942,44 +932,6 @@ omap2_gpio_disable_level_quirk(struct gpio_bank *bank)
                       bank->base + bank->regs->risingdetect);
 }
 
-/*
- * On omap4 and later SoC variants a level interrupt with wkup_en
- * enabled blocks the GPIO functional clock from idling until the GPIO
- * instance has been reset. To avoid that, we must set wkup_en only for
- * idle for level interrupts, and clear level registers for the duration
- * of idle. The level interrupts will be still there on wakeup by their
- * nature.
- */
-static void __maybe_unused
-omap4_gpio_enable_level_quirk(struct gpio_bank *bank)
-{
-       /* Update wake register for idle, edge bits might be already set */
-       writel_relaxed(bank->context.wake_en,
-                      bank->base + bank->regs->wkup_en);
-
-       /* Clear level registers for idle */
-       writel_relaxed(0, bank->base + bank->regs->leveldetect0);
-       writel_relaxed(0, bank->base + bank->regs->leveldetect1);
-}
-
-static void __maybe_unused
-omap4_gpio_disable_level_quirk(struct gpio_bank *bank)
-{
-       /* Restore level registers after idle */
-       writel_relaxed(bank->context.leveldetect0,
-                      bank->base + bank->regs->leveldetect0);
-       writel_relaxed(bank->context.leveldetect1,
-                      bank->base + bank->regs->leveldetect1);
-
-       /* Clear saved wkup_en for level, it will be set for next idle again */
-       bank->context.wake_en &= ~(bank->context.leveldetect0 |
-                                  bank->context.leveldetect1);
-
-       /* Update wake with only edge configuration */
-       writel_relaxed(bank->context.wake_en,
-                      bank->base + bank->regs->wkup_en);
-}
-
 /*---------------------------------------------------------------------*/
 
 static int omap_mpuio_suspend_noirq(struct device *dev)
@@ -1412,12 +1364,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
                                omap_set_gpio_dataout_mask_multiple;
        }
 
-       if (bank->quirks & OMAP_GPIO_QUIRK_DEFERRED_WKUP_EN) {
-               bank->funcs.idle_enable_level_quirk =
-                       omap4_gpio_enable_level_quirk;
-               bank->funcs.idle_disable_level_quirk =
-                       omap4_gpio_disable_level_quirk;
-       } else if (bank->quirks & OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER) {
+       if (bank->quirks & OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER) {
                bank->funcs.idle_enable_level_quirk =
                        omap2_gpio_enable_level_quirk;
                bank->funcs.idle_disable_level_quirk =
@@ -1806,8 +1753,7 @@ static const struct omap_gpio_platform_data omap4_pdata = {
        .regs = &omap4_gpio_regs,
        .bank_width = 32,
        .dbck_flag = true,
-       .quirks = OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER |
-                 OMAP_GPIO_QUIRK_DEFERRED_WKUP_EN,
+       .quirks = OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER,
 };
 
 static const struct of_device_id omap_gpio_match[] = {
index 55b72fbe163169c29766fbb6e24f58ccfdfd62c2..7f93954c58ea47f3be84c0955d6887f45fac5c25 100644 (file)
 
 #include "gpiolib.h"
 
+/**
+ * struct acpi_gpio_event - ACPI GPIO event handler data
+ *
+ * @node:        list-entry of the events list of the struct acpi_gpio_chip
+ * @handle:      handle of ACPI method to execute when the IRQ triggers
+ * @handler:     irq_handler to pass to request_irq when requesting the IRQ
+ * @pin:         GPIO pin number on the gpio_chip
+ * @irq:         Linux IRQ number for the event, for request_ / free_irq
+ * @irqflags:     flags to pass to request_irq when requesting the IRQ
+ * @irq_is_wake:  If the ACPI flags indicate the IRQ is a wakeup source
+ * @is_requested: True if request_irq has been done
+ * @desc:        gpio_desc for the GPIO pin for this event
+ */
 struct acpi_gpio_event {
        struct list_head node;
        acpi_handle handle;
+       irq_handler_t handler;
        unsigned int pin;
        unsigned int irq;
+       unsigned long irqflags;
+       bool irq_is_wake;
+       bool irq_requested;
        struct gpio_desc *desc;
 };
 
@@ -49,10 +66,10 @@ struct acpi_gpio_chip {
 
 /*
  * For gpiochips which call acpi_gpiochip_request_interrupts() before late_init
- * (so builtin drivers) we register the ACPI GpioInt event handlers from a
+ * (so builtin drivers) we register the ACPI GpioInt IRQ handlers from a
  * late_initcall_sync handler, so that other builtin drivers can register their
  * OpRegions before the event handlers can run.  This list contains gpiochips
- * for which the acpi_gpiochip_request_interrupts() has been deferred.
+ * for which the acpi_gpiochip_request_irqs() call has been deferred.
  */
 static DEFINE_MUTEX(acpi_gpio_deferred_req_irqs_lock);
 static LIST_HEAD(acpi_gpio_deferred_req_irqs_list);
@@ -133,8 +150,42 @@ bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
 }
 EXPORT_SYMBOL_GPL(acpi_gpio_get_irq_resource);
 
-static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
-                                                  void *context)
+static void acpi_gpiochip_request_irq(struct acpi_gpio_chip *acpi_gpio,
+                                     struct acpi_gpio_event *event)
+{
+       int ret, value;
+
+       ret = request_threaded_irq(event->irq, NULL, event->handler,
+                                  event->irqflags, "ACPI:Event", event);
+       if (ret) {
+               dev_err(acpi_gpio->chip->parent,
+                       "Failed to setup interrupt handler for %d\n",
+                       event->irq);
+               return;
+       }
+
+       if (event->irq_is_wake)
+               enable_irq_wake(event->irq);
+
+       event->irq_requested = true;
+
+       /* Make sure we trigger the initial state of edge-triggered IRQs */
+       value = gpiod_get_raw_value_cansleep(event->desc);
+       if (((event->irqflags & IRQF_TRIGGER_RISING) && value == 1) ||
+           ((event->irqflags & IRQF_TRIGGER_FALLING) && value == 0))
+               event->handler(event->irq, event);
+}
+
+static void acpi_gpiochip_request_irqs(struct acpi_gpio_chip *acpi_gpio)
+{
+       struct acpi_gpio_event *event;
+
+       list_for_each_entry(event, &acpi_gpio->events, node)
+               acpi_gpiochip_request_irq(acpi_gpio, event);
+}
+
+static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares,
+                                            void *context)
 {
        struct acpi_gpio_chip *acpi_gpio = context;
        struct gpio_chip *chip = acpi_gpio->chip;
@@ -143,8 +194,7 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
        struct acpi_gpio_event *event;
        irq_handler_t handler = NULL;
        struct gpio_desc *desc;
-       unsigned long irqflags;
-       int ret, pin, irq, value;
+       int ret, pin, irq;
 
        if (!acpi_gpio_get_irq_resource(ares, &agpio))
                return AE_OK;
@@ -175,8 +225,6 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
 
        gpiod_direction_input(desc);
 
-       value = gpiod_get_value_cansleep(desc);
-
        ret = gpiochip_lock_as_irq(chip, pin);
        if (ret) {
                dev_err(chip->parent, "Failed to lock GPIO as interrupt\n");
@@ -189,64 +237,42 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
                goto fail_unlock_irq;
        }
 
-       irqflags = IRQF_ONESHOT;
+       event = kzalloc(sizeof(*event), GFP_KERNEL);
+       if (!event)
+               goto fail_unlock_irq;
+
+       event->irqflags = IRQF_ONESHOT;
        if (agpio->triggering == ACPI_LEVEL_SENSITIVE) {
                if (agpio->polarity == ACPI_ACTIVE_HIGH)
-                       irqflags |= IRQF_TRIGGER_HIGH;
+                       event->irqflags |= IRQF_TRIGGER_HIGH;
                else
-                       irqflags |= IRQF_TRIGGER_LOW;
+                       event->irqflags |= IRQF_TRIGGER_LOW;
        } else {
                switch (agpio->polarity) {
                case ACPI_ACTIVE_HIGH:
-                       irqflags |= IRQF_TRIGGER_RISING;
+                       event->irqflags |= IRQF_TRIGGER_RISING;
                        break;
                case ACPI_ACTIVE_LOW:
-                       irqflags |= IRQF_TRIGGER_FALLING;
+                       event->irqflags |= IRQF_TRIGGER_FALLING;
                        break;
                default:
-                       irqflags |= IRQF_TRIGGER_RISING |
-                                   IRQF_TRIGGER_FALLING;
+                       event->irqflags |= IRQF_TRIGGER_RISING |
+                                          IRQF_TRIGGER_FALLING;
                        break;
                }
        }
 
-       event = kzalloc(sizeof(*event), GFP_KERNEL);
-       if (!event)
-               goto fail_unlock_irq;
-
        event->handle = evt_handle;
+       event->handler = handler;
        event->irq = irq;
+       event->irq_is_wake = agpio->wake_capable == ACPI_WAKE_CAPABLE;
        event->pin = pin;
        event->desc = desc;
 
-       ret = request_threaded_irq(event->irq, NULL, handler, irqflags,
-                                  "ACPI:Event", event);
-       if (ret) {
-               dev_err(chip->parent,
-                       "Failed to setup interrupt handler for %d\n",
-                       event->irq);
-               goto fail_free_event;
-       }
-
-       if (agpio->wake_capable == ACPI_WAKE_CAPABLE)
-               enable_irq_wake(irq);
-
        list_add_tail(&event->node, &acpi_gpio->events);
 
-       /*
-        * Make sure we trigger the initial state of the IRQ when using RISING
-        * or FALLING.  Note we run the handlers on late_init, the AML code
-        * may refer to OperationRegions from other (builtin) drivers which
-        * may be probed after us.
-        */
-       if (((irqflags & IRQF_TRIGGER_RISING) && value == 1) ||
-           ((irqflags & IRQF_TRIGGER_FALLING) && value == 0))
-               handler(event->irq, event);
-
        return AE_OK;
 
-fail_free_event:
-       kfree(event);
 fail_unlock_irq:
        gpiochip_unlock_as_irq(chip, pin);
 fail_free_desc:
@@ -283,6 +309,9 @@ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
        if (ACPI_FAILURE(status))
                return;
 
+       acpi_walk_resources(handle, "_AEI",
+                           acpi_gpiochip_alloc_event, acpi_gpio);
+
        mutex_lock(&acpi_gpio_deferred_req_irqs_lock);
        defer = !acpi_gpio_deferred_req_irqs_done;
        if (defer)
@@ -293,8 +322,7 @@ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
        if (defer)
                return;
 
-       acpi_walk_resources(handle, "_AEI",
-                           acpi_gpiochip_request_interrupt, acpi_gpio);
+       acpi_gpiochip_request_irqs(acpi_gpio);
 }
 EXPORT_SYMBOL_GPL(acpi_gpiochip_request_interrupts);
 
@@ -331,10 +359,13 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip)
        list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) {
                struct gpio_desc *desc;
 
-               if (irqd_is_wakeup_set(irq_get_irq_data(event->irq)))
-                       disable_irq_wake(event->irq);
+               if (event->irq_requested) {
+                       if (event->irq_is_wake)
+                               disable_irq_wake(event->irq);
+
+                       free_irq(event->irq, event);
+               }
 
-               free_irq(event->irq, event);
                desc = event->desc;
                if (WARN_ON(IS_ERR(desc)))
                        continue;
@@ -1200,23 +1231,16 @@ bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id)
        return con_id == NULL;
 }
 
-/* Run deferred acpi_gpiochip_request_interrupts() */
-static int acpi_gpio_handle_deferred_request_interrupts(void)
+/* Run deferred acpi_gpiochip_request_irqs() */
+static int acpi_gpio_handle_deferred_request_irqs(void)
 {
        struct acpi_gpio_chip *acpi_gpio, *tmp;
 
        mutex_lock(&acpi_gpio_deferred_req_irqs_lock);
        list_for_each_entry_safe(acpi_gpio, tmp,
                                 &acpi_gpio_deferred_req_irqs_list,
-                                deferred_req_irqs_list_entry) {
-               acpi_handle handle;
-
-               handle = ACPI_HANDLE(acpi_gpio->chip->parent);
-               acpi_walk_resources(handle, "_AEI",
-                                   acpi_gpiochip_request_interrupt, acpi_gpio);
-
-               list_del_init(&acpi_gpio->deferred_req_irqs_list_entry);
-       }
+                                deferred_req_irqs_list_entry)
+               acpi_gpiochip_request_irqs(acpi_gpio);
 
        acpi_gpio_deferred_req_irqs_done = true;
        mutex_unlock(&acpi_gpio_deferred_req_irqs_lock);
@@ -1224,4 +1248,4 @@ static int acpi_gpio_handle_deferred_request_interrupts(void)
        return 0;
 }
 /* We must use _sync so that this runs after the first deferred_probe run */
-late_initcall_sync(acpi_gpio_handle_deferred_request_interrupts);
+late_initcall_sync(acpi_gpio_handle_deferred_request_irqs);
index 8816c697b2053c7c28f119f1362443d7b9ad6e98..387f1cf1dc207b0adac288cbf3fa413cc219d7f1 100644 (file)
@@ -330,7 +330,9 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
                        case CHIP_TOPAZ:
                                if (((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x81)) ||
                                    ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x83)) ||
-                                   ((adev->pdev->device == 0x6907) && (adev->pdev->revision == 0x87))) {
+                                   ((adev->pdev->device == 0x6907) && (adev->pdev->revision == 0x87)) ||
+                                   ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0xD1)) ||
+                                   ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0xD3))) {
                                        info->is_kicker = true;
                                        strcpy(fw_name, "amdgpu/topaz_k_smc.bin");
                                } else
@@ -351,7 +353,6 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
                                if (type == CGS_UCODE_ID_SMU) {
                                        if (((adev->pdev->device == 0x67ef) &&
                                             ((adev->pdev->revision == 0xe0) ||
-                                             (adev->pdev->revision == 0xe2) ||
                                              (adev->pdev->revision == 0xe5))) ||
                                            ((adev->pdev->device == 0x67ff) &&
                                             ((adev->pdev->revision == 0xcf) ||
@@ -359,8 +360,13 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
                                              (adev->pdev->revision == 0xff)))) {
                                                info->is_kicker = true;
                                                strcpy(fw_name, "amdgpu/polaris11_k_smc.bin");
-                                       } else
+                                       } else if ((adev->pdev->device == 0x67ef) &&
+                                                  (adev->pdev->revision == 0xe2)) {
+                                               info->is_kicker = true;
+                                               strcpy(fw_name, "amdgpu/polaris11_k2_smc.bin");
+                                       } else {
                                                strcpy(fw_name, "amdgpu/polaris11_smc.bin");
+                                       }
                                } else if (type == CGS_UCODE_ID_SMU_SK) {
                                        strcpy(fw_name, "amdgpu/polaris11_smc_sk.bin");
                                }
@@ -375,17 +381,35 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
                                              (adev->pdev->revision == 0xe7) ||
                                              (adev->pdev->revision == 0xef))) ||
                                            ((adev->pdev->device == 0x6fdf) &&
-                                            (adev->pdev->revision == 0xef))) {
+                                            ((adev->pdev->revision == 0xef) ||
+                                             (adev->pdev->revision == 0xff)))) {
                                                info->is_kicker = true;
                                                strcpy(fw_name, "amdgpu/polaris10_k_smc.bin");
-                                       } else
+                                       } else if ((adev->pdev->device == 0x67df) &&
+                                                  ((adev->pdev->revision == 0xe1) ||
+                                                   (adev->pdev->revision == 0xf7))) {
+                                               info->is_kicker = true;
+                                               strcpy(fw_name, "amdgpu/polaris10_k2_smc.bin");
+                                       } else {
                                                strcpy(fw_name, "amdgpu/polaris10_smc.bin");
+                                       }
                                } else if (type == CGS_UCODE_ID_SMU_SK) {
                                        strcpy(fw_name, "amdgpu/polaris10_smc_sk.bin");
                                }
                                break;
                        case CHIP_POLARIS12:
-                               strcpy(fw_name, "amdgpu/polaris12_smc.bin");
+                               if (((adev->pdev->device == 0x6987) &&
+                                    ((adev->pdev->revision == 0xc0) ||
+                                     (adev->pdev->revision == 0xc3))) ||
+                                   ((adev->pdev->device == 0x6981) &&
+                                    ((adev->pdev->revision == 0x00) ||
+                                     (adev->pdev->revision == 0x01) ||
+                                     (adev->pdev->revision == 0x10)))) {
+                                       info->is_kicker = true;
+                                       strcpy(fw_name, "amdgpu/polaris12_k_smc.bin");
+                               } else {
+                                       strcpy(fw_name, "amdgpu/polaris12_smc.bin");
+                               }
                                break;
                        case CHIP_VEGAM:
                                strcpy(fw_name, "amdgpu/vegam_smc.bin");
index 663043c8f0f5710244cb4bc787a8cd19fc076b50..0acc8dee2cb8d3ba99ebcef8af507b91021523ea 100644 (file)
@@ -124,14 +124,14 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs
                goto free_chunk;
        }
 
+       mutex_lock(&p->ctx->lock);
+
        /* skip guilty context job */
        if (atomic_read(&p->ctx->guilty) == 1) {
                ret = -ECANCELED;
                goto free_chunk;
        }
 
-       mutex_lock(&p->ctx->lock);
-
        /* get chunks */
        chunk_array_user = u64_to_user_ptr(cs->in.chunks);
        if (copy_from_user(chunk_array, chunk_array_user,
index 8de55f7f1a3a3922b4a1ac2d17cf12cdd35d1fd6..74b611e8a1b10c88abfaa0eb66950a073a09bd7b 100644 (file)
@@ -872,7 +872,13 @@ static const struct pci_device_id pciidlist[] = {
        {0x1002, 0x6864, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10},
        {0x1002, 0x6867, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10},
        {0x1002, 0x6868, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10},
+       {0x1002, 0x6869, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10},
+       {0x1002, 0x686a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10},
+       {0x1002, 0x686b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10},
        {0x1002, 0x686c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10},
+       {0x1002, 0x686d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10},
+       {0x1002, 0x686e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10},
+       {0x1002, 0x686f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10},
        {0x1002, 0x687f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10},
        /* Vega 12 */
        {0x1002, 0x69A0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12},
@@ -885,6 +891,7 @@ static const struct pci_device_id pciidlist[] = {
        {0x1002, 0x66A1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20},
        {0x1002, 0x66A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20},
        {0x1002, 0x66A3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20},
+       {0x1002, 0x66A4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20},
        {0x1002, 0x66A7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20},
        {0x1002, 0x66AF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20},
        /* Raven */
index a9f18ea7e354377c4ed47532eaaf1257e11b695b..e4ded890b1cbcc950e68288d7bafa1dbfdcaf456 100644 (file)
@@ -337,12 +337,19 @@ static const struct kfd_deviceid supported_devices[] = {
        { 0x6864, &vega10_device_info },        /* Vega10 */
        { 0x6867, &vega10_device_info },        /* Vega10 */
        { 0x6868, &vega10_device_info },        /* Vega10 */
+       { 0x6869, &vega10_device_info },        /* Vega10 */
+       { 0x686A, &vega10_device_info },        /* Vega10 */
+       { 0x686B, &vega10_device_info },        /* Vega10 */
        { 0x686C, &vega10_vf_device_info },     /* Vega10  vf*/
+       { 0x686D, &vega10_device_info },        /* Vega10 */
+       { 0x686E, &vega10_device_info },        /* Vega10 */
+       { 0x686F, &vega10_device_info },        /* Vega10 */
        { 0x687F, &vega10_device_info },        /* Vega10 */
        { 0x66a0, &vega20_device_info },        /* Vega20 */
        { 0x66a1, &vega20_device_info },        /* Vega20 */
        { 0x66a2, &vega20_device_info },        /* Vega20 */
        { 0x66a3, &vega20_device_info },        /* Vega20 */
+       { 0x66a4, &vega20_device_info },        /* Vega20 */
        { 0x66a7, &vega20_device_info },        /* Vega20 */
        { 0x66af, &vega20_device_info }         /* Vega20 */
 };
index 3367dd30cdd0d1c8c8482afb436885383a736103..3b7fce5d7258eb71f2b8fbfa01c82c7143124ae9 100644 (file)
@@ -130,7 +130,7 @@ static void vega20_set_default_registry_data(struct pp_hwmgr *hwmgr)
        data->registry_data.disable_auto_wattman = 1;
        data->registry_data.auto_wattman_debug = 0;
        data->registry_data.auto_wattman_sample_period = 100;
-       data->registry_data.fclk_gfxclk_ratio = 0x3F6CCCCD;
+       data->registry_data.fclk_gfxclk_ratio = 0;
        data->registry_data.auto_wattman_threshold = 50;
        data->registry_data.gfxoff_controlled_by_driver = 1;
        data->gfxoff_allowed = false;
index 62f36ba2435be4770e9a14f9dd8a779a2802fa79..c1a99dfe4913f247d20ce8cafab4dd5e0499715f 100644 (file)
@@ -386,6 +386,8 @@ typedef uint16_t PPSMC_Result;
 #define PPSMC_MSG_AgmResetPsm                 ((uint16_t) 0x403)
 #define PPSMC_MSG_ReadVftCell                 ((uint16_t) 0x404)
 
+#define PPSMC_MSG_ApplyAvfsCksOffVoltage      ((uint16_t) 0x415)
+
 #define PPSMC_MSG_GFX_CU_PG_ENABLE            ((uint16_t) 0x280)
 #define PPSMC_MSG_GFX_CU_PG_DISABLE           ((uint16_t) 0x281)
 #define PPSMC_MSG_GetCurrPkgPwr               ((uint16_t) 0x282)
index 872d3824337bf90ad8abbf4cce1eb9d77630c48a..a1e0ac9ae2482a776416aa987e0787e65dd3fe9a 100644 (file)
@@ -1985,6 +1985,12 @@ int polaris10_thermal_avfs_enable(struct pp_hwmgr *hwmgr)
 
        smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableAvfs);
 
+       /* Apply avfs cks-off voltages to avoid the overshoot
+        * when switching to the highest sclk frequency
+        */
+       if (data->apply_avfs_cks_off_voltage)
+               smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ApplyAvfsCksOffVoltage);
+
        return 0;
 }
 
index 99d5e4f98f49cd7ec103a70eee060b8c9e0241e4..a6edd5df33b0fa0cf9b4b3ed8dd694ba9898b14b 100644 (file)
@@ -37,10 +37,13 @@ MODULE_FIRMWARE("amdgpu/fiji_smc.bin");
 MODULE_FIRMWARE("amdgpu/polaris10_smc.bin");
 MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin");
 MODULE_FIRMWARE("amdgpu/polaris10_k_smc.bin");
+MODULE_FIRMWARE("amdgpu/polaris10_k2_smc.bin");
 MODULE_FIRMWARE("amdgpu/polaris11_smc.bin");
 MODULE_FIRMWARE("amdgpu/polaris11_smc_sk.bin");
 MODULE_FIRMWARE("amdgpu/polaris11_k_smc.bin");
+MODULE_FIRMWARE("amdgpu/polaris11_k2_smc.bin");
 MODULE_FIRMWARE("amdgpu/polaris12_smc.bin");
+MODULE_FIRMWARE("amdgpu/polaris12_k_smc.bin");
 MODULE_FIRMWARE("amdgpu/vegam_smc.bin");
 MODULE_FIRMWARE("amdgpu/vega10_smc.bin");
 MODULE_FIRMWARE("amdgpu/vega10_acg_smc.bin");
index 94bd872d56c48b24512ef660849237781e6316c0..7e6746b2d704c588db58f950461d293d4a1fd018 100644 (file)
@@ -37,6 +37,7 @@
 
 #include <linux/pci.h>
 #include <linux/export.h>
+#include <linux/nospec.h>
 
 /**
  * DOC: getunique and setversion story
@@ -800,13 +801,17 @@ long drm_ioctl(struct file *filp,
 
        if (is_driver_ioctl) {
                /* driver ioctl */
-               if (nr - DRM_COMMAND_BASE >= dev->driver->num_ioctls)
+               unsigned int index = nr - DRM_COMMAND_BASE;
+
+               if (index >= dev->driver->num_ioctls)
                        goto err_i1;
-               ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
+               index = array_index_nospec(index, dev->driver->num_ioctls);
+               ioctl = &dev->driver->ioctls[index];
        } else {
                /* core ioctl */
                if (nr >= DRM_CORE_IOCTL_COUNT)
                        goto err_i1;
+               nr = array_index_nospec(nr, DRM_CORE_IOCTL_COUNT);
                ioctl = &drm_ioctls[nr];
        }
 
@@ -888,6 +893,7 @@ bool drm_ioctl_flags(unsigned int nr, unsigned int *flags)
 
        if (nr >= DRM_CORE_IOCTL_COUNT)
                return false;
+       nr = array_index_nospec(nr, DRM_CORE_IOCTL_COUNT);
 
        *flags = drm_ioctls[nr].flags;
        return true;
index 481896fb712abf4c178b28af2f224a369d0aefd9..85e6736f0a327742329dc9ee3bc8cf2dce294ed3 100644 (file)
@@ -235,7 +235,7 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
                plane->bpp = skl_pixel_formats[fmt].bpp;
                plane->drm_format = skl_pixel_formats[fmt].drm_format;
        } else {
-               plane->tiled = !!(val & DISPPLANE_TILED);
+               plane->tiled = val & DISPPLANE_TILED;
                fmt = bdw_format_to_drm(val & DISPPLANE_PIXFORMAT_MASK);
                plane->bpp = bdw_pixel_formats[fmt].bpp;
                plane->drm_format = bdw_pixel_formats[fmt].drm_format;
index ffdbbac4400eaf7d86390a3ff105a18ef36645ea..47062ee979cfb2d38b6078455562c64ef530ec8a 100644 (file)
@@ -1444,6 +1444,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
 
        intel_uncore_sanitize(dev_priv);
 
+       intel_gt_init_workarounds(dev_priv);
        i915_gem_load_init_fences(dev_priv);
 
        /* On the 945G/GM, the chipset reports the MSI capability on the
index 9102571e9692d1540ad987ed31c4ec735dd80cf5..872a2e159a5f903fc6a9d84d6392cc04a44e6d87 100644 (file)
@@ -67,6 +67,7 @@
 #include "intel_ringbuffer.h"
 #include "intel_uncore.h"
 #include "intel_wopcm.h"
+#include "intel_workarounds.h"
 #include "intel_uc.h"
 
 #include "i915_gem.h"
@@ -1805,6 +1806,7 @@ struct drm_i915_private {
        int dpio_phy_iosf_port[I915_NUM_PHYS_VLV];
 
        struct i915_workarounds workarounds;
+       struct i915_wa_list gt_wa_list;
 
        struct i915_frontbuffer_tracking fb_tracking;
 
@@ -2148,6 +2150,8 @@ struct drm_i915_private {
                struct delayed_work idle_work;
 
                ktime_t last_init_time;
+
+               struct i915_vma *scratch;
        } gt;
 
        /* perform PHY state sanity checks? */
@@ -3870,4 +3874,9 @@ static inline int intel_hws_csb_write_index(struct drm_i915_private *i915)
                return I915_HWS_CSB_WRITE_INDEX;
 }
 
+static inline u32 i915_scratch_offset(const struct drm_i915_private *i915)
+{
+       return i915_ggtt_offset(i915->gt.scratch);
+}
+
 #endif
index 0c8aa57ce83b4033723ded1540986b628d92d772..6ae9a6080cc8838b45dc11fb6de28f63fbe09b04 100644 (file)
@@ -5305,7 +5305,7 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv)
                }
        }
 
-       intel_gt_workarounds_apply(dev_priv);
+       intel_gt_apply_workarounds(dev_priv);
 
        i915_gem_init_swizzling(dev_priv);
 
@@ -5500,6 +5500,44 @@ err_active:
        goto out_ctx;
 }
 
+static int
+i915_gem_init_scratch(struct drm_i915_private *i915, unsigned int size)
+{
+       struct drm_i915_gem_object *obj;
+       struct i915_vma *vma;
+       int ret;
+
+       obj = i915_gem_object_create_stolen(i915, size);
+       if (!obj)
+               obj = i915_gem_object_create_internal(i915, size);
+       if (IS_ERR(obj)) {
+               DRM_ERROR("Failed to allocate scratch page\n");
+               return PTR_ERR(obj);
+       }
+
+       vma = i915_vma_instance(obj, &i915->ggtt.vm, NULL);
+       if (IS_ERR(vma)) {
+               ret = PTR_ERR(vma);
+               goto err_unref;
+       }
+
+       ret = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH);
+       if (ret)
+               goto err_unref;
+
+       i915->gt.scratch = vma;
+       return 0;
+
+err_unref:
+       i915_gem_object_put(obj);
+       return ret;
+}
+
+static void i915_gem_fini_scratch(struct drm_i915_private *i915)
+{
+       i915_vma_unpin_and_release(&i915->gt.scratch, 0);
+}
+
 int i915_gem_init(struct drm_i915_private *dev_priv)
 {
        int ret;
@@ -5546,12 +5584,19 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
                goto err_unlock;
        }
 
-       ret = i915_gem_contexts_init(dev_priv);
+       ret = i915_gem_init_scratch(dev_priv,
+                                   IS_GEN2(dev_priv) ? SZ_256K : PAGE_SIZE);
        if (ret) {
                GEM_BUG_ON(ret == -EIO);
                goto err_ggtt;
        }
 
+       ret = i915_gem_contexts_init(dev_priv);
+       if (ret) {
+               GEM_BUG_ON(ret == -EIO);
+               goto err_scratch;
+       }
+
        ret = intel_engines_init(dev_priv);
        if (ret) {
                GEM_BUG_ON(ret == -EIO);
@@ -5624,6 +5669,8 @@ err_pm:
 err_context:
        if (ret != -EIO)
                i915_gem_contexts_fini(dev_priv);
+err_scratch:
+       i915_gem_fini_scratch(dev_priv);
 err_ggtt:
 err_unlock:
        intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
@@ -5675,8 +5722,11 @@ void i915_gem_fini(struct drm_i915_private *dev_priv)
        intel_uc_fini(dev_priv);
        i915_gem_cleanup_engines(dev_priv);
        i915_gem_contexts_fini(dev_priv);
+       i915_gem_fini_scratch(dev_priv);
        mutex_unlock(&dev_priv->drm.struct_mutex);
 
+       intel_wa_list_free(&dev_priv->gt_wa_list);
+
        intel_cleanup_gt_powersave(dev_priv);
 
        intel_uc_fini_misc(dev_priv);
index d4fac09095f862aed3131243957059de2df4f6b0..1aaccbe7e1debd0c11440ac9acae9c15b07880d5 100644 (file)
@@ -1268,7 +1268,7 @@ relocate_entry(struct i915_vma *vma,
                else if (gen >= 4)
                        len = 4;
                else
-                       len = 6;
+                       len = 3;
 
                batch = reloc_gpu(eb, vma, len);
                if (IS_ERR(batch))
@@ -1309,11 +1309,6 @@ 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 3eb33e000d6f00f3ae4b3fdbc8f37f38e97b4d83..db4128d6c09b6735a02efb76ea7cf756459eaa51 100644 (file)
@@ -1495,7 +1495,7 @@ static void gem_record_rings(struct i915_gpu_state *error)
                        if (HAS_BROKEN_CS_TLB(i915))
                                ee->wa_batchbuffer =
                                        i915_error_object_create(i915,
-                                                                engine->scratch);
+                                                                i915->gt.scratch);
                        request_record_user_bo(request, ee);
 
                        ee->ctx =
index 217ed3ee1cab4e808f1dd8f4e8b60dca36ea65da..76b5f94ea6cb62a38c42bec9d4da03c638489480 100644 (file)
@@ -490,46 +490,6 @@ void intel_engine_setup_common(struct intel_engine_cs *engine)
        intel_engine_init_cmd_parser(engine);
 }
 
-int intel_engine_create_scratch(struct intel_engine_cs *engine,
-                               unsigned int size)
-{
-       struct drm_i915_gem_object *obj;
-       struct i915_vma *vma;
-       int ret;
-
-       WARN_ON(engine->scratch);
-
-       obj = i915_gem_object_create_stolen(engine->i915, size);
-       if (!obj)
-               obj = i915_gem_object_create_internal(engine->i915, size);
-       if (IS_ERR(obj)) {
-               DRM_ERROR("Failed to allocate scratch page\n");
-               return PTR_ERR(obj);
-       }
-
-       vma = i915_vma_instance(obj, &engine->i915->ggtt.vm, NULL);
-       if (IS_ERR(vma)) {
-               ret = PTR_ERR(vma);
-               goto err_unref;
-       }
-
-       ret = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH);
-       if (ret)
-               goto err_unref;
-
-       engine->scratch = vma;
-       return 0;
-
-err_unref:
-       i915_gem_object_put(obj);
-       return ret;
-}
-
-void intel_engine_cleanup_scratch(struct intel_engine_cs *engine)
-{
-       i915_vma_unpin_and_release(&engine->scratch, 0);
-}
-
 static void cleanup_status_page(struct intel_engine_cs *engine)
 {
        if (HWS_NEEDS_PHYSICAL(engine->i915)) {
@@ -704,8 +664,6 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine)
 {
        struct drm_i915_private *i915 = engine->i915;
 
-       intel_engine_cleanup_scratch(engine);
-
        cleanup_status_page(engine);
 
        intel_engine_fini_breadcrumbs(engine);
@@ -720,6 +678,8 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine)
        __intel_context_unpin(i915->kernel_context, engine);
 
        i915_timeline_fini(&engine->timeline);
+
+       intel_wa_list_free(&engine->wa_list);
 }
 
 u64 intel_engine_get_active_head(const struct intel_engine_cs *engine)
index 37c94a54efcbb2501509b5a838e61d983985d8b2..58d1d3d47dd31ed7aa150f6b9865eb05e0a170b7 100644 (file)
@@ -442,8 +442,13 @@ static u64 execlists_update_context(struct i915_request *rq)
         * may not be visible to the HW prior to the completion of the UC
         * register write and that we may begin execution from the context
         * before its image is complete leading to invalid PD chasing.
+        *
+        * Furthermore, Braswell, at least, wants a full mb to be sure that
+        * the writes are coherent in memory (visible to the GPU) prior to
+        * execution, and not just visible to other CPUs (as is the result of
+        * wmb).
         */
-       wmb();
+       mb();
        return ce->lrc_desc;
 }
 
@@ -1443,9 +1448,10 @@ static int execlists_request_alloc(struct i915_request *request)
 static u32 *
 gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine, u32 *batch)
 {
+       /* NB no one else is allowed to scribble over scratch + 256! */
        *batch++ = MI_STORE_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT;
        *batch++ = i915_mmio_reg_offset(GEN8_L3SQCREG4);
-       *batch++ = i915_ggtt_offset(engine->scratch) + 256;
+       *batch++ = i915_scratch_offset(engine->i915) + 256;
        *batch++ = 0;
 
        *batch++ = MI_LOAD_REGISTER_IMM(1);
@@ -1459,7 +1465,7 @@ gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine, u32 *batch)
 
        *batch++ = MI_LOAD_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT;
        *batch++ = i915_mmio_reg_offset(GEN8_L3SQCREG4);
-       *batch++ = i915_ggtt_offset(engine->scratch) + 256;
+       *batch++ = i915_scratch_offset(engine->i915) + 256;
        *batch++ = 0;
 
        return batch;
@@ -1496,7 +1502,7 @@ static u32 *gen8_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch)
                                       PIPE_CONTROL_GLOBAL_GTT_IVB |
                                       PIPE_CONTROL_CS_STALL |
                                       PIPE_CONTROL_QW_WRITE,
-                                      i915_ggtt_offset(engine->scratch) +
+                                      i915_scratch_offset(engine->i915) +
                                       2 * CACHELINE_BYTES);
 
        *batch++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
@@ -1573,7 +1579,7 @@ static u32 *gen9_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch)
                                               PIPE_CONTROL_GLOBAL_GTT_IVB |
                                               PIPE_CONTROL_CS_STALL |
                                               PIPE_CONTROL_QW_WRITE,
-                                              i915_ggtt_offset(engine->scratch)
+                                              i915_scratch_offset(engine->i915)
                                               + 2 * CACHELINE_BYTES);
        }
 
@@ -1793,6 +1799,8 @@ static bool unexpected_starting_state(struct intel_engine_cs *engine)
 
 static int gen8_init_common_ring(struct intel_engine_cs *engine)
 {
+       intel_engine_apply_workarounds(engine);
+
        intel_mocs_init_engine(engine);
 
        intel_engine_reset_breadcrumbs(engine);
@@ -2139,7 +2147,7 @@ static int gen8_emit_flush_render(struct i915_request *request,
 {
        struct intel_engine_cs *engine = request->engine;
        u32 scratch_addr =
-               i915_ggtt_offset(engine->scratch) + 2 * CACHELINE_BYTES;
+               i915_scratch_offset(engine->i915) + 2 * CACHELINE_BYTES;
        bool vf_flush_wa = false, dc_flush_wa = false;
        u32 *cs, flags = 0;
        int len;
@@ -2476,10 +2484,6 @@ int logical_render_ring_init(struct intel_engine_cs *engine)
        if (ret)
                return ret;
 
-       ret = intel_engine_create_scratch(engine, PAGE_SIZE);
-       if (ret)
-               goto err_cleanup_common;
-
        ret = intel_init_workaround_bb(engine);
        if (ret) {
                /*
@@ -2491,11 +2495,9 @@ int logical_render_ring_init(struct intel_engine_cs *engine)
                          ret);
        }
 
-       return 0;
+       intel_engine_init_workarounds(engine);
 
-err_cleanup_common:
-       intel_engine_cleanup_common(engine);
-       return ret;
+       return 0;
 }
 
 int logical_xcs_ring_init(struct intel_engine_cs *engine)
index 187bb0ceb4ac4324b3c12ab72635d4a776b2129c..1f8d2a66c791fee7a4e279942324015d6add1371 100644 (file)
@@ -69,19 +69,28 @@ unsigned int intel_ring_update_space(struct intel_ring *ring)
 static int
 gen2_render_ring_flush(struct i915_request *rq, u32 mode)
 {
+       unsigned int num_store_dw;
        u32 cmd, *cs;
 
        cmd = MI_FLUSH;
-
+       num_store_dw = 0;
        if (mode & EMIT_INVALIDATE)
                cmd |= MI_READ_FLUSH;
+       if (mode & EMIT_FLUSH)
+               num_store_dw = 4;
 
-       cs = intel_ring_begin(rq, 2);
+       cs = intel_ring_begin(rq, 2 + 3 * num_store_dw);
        if (IS_ERR(cs))
                return PTR_ERR(cs);
 
        *cs++ = cmd;
-       *cs++ = MI_NOOP;
+       while (num_store_dw--) {
+               *cs++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL;
+               *cs++ = i915_scratch_offset(rq->i915);
+               *cs++ = 0;
+       }
+       *cs++ = MI_FLUSH | MI_NO_WRITE_FLUSH;
+
        intel_ring_advance(rq, cs);
 
        return 0;
@@ -150,8 +159,7 @@ gen4_render_ring_flush(struct i915_request *rq, u32 mode)
         */
        if (mode & EMIT_INVALIDATE) {
                *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE;
-               *cs++ = i915_ggtt_offset(rq->engine->scratch) |
-                       PIPE_CONTROL_GLOBAL_GTT;
+               *cs++ = i915_scratch_offset(rq->i915) | PIPE_CONTROL_GLOBAL_GTT;
                *cs++ = 0;
                *cs++ = 0;
 
@@ -159,8 +167,7 @@ gen4_render_ring_flush(struct i915_request *rq, u32 mode)
                        *cs++ = MI_FLUSH;
 
                *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE;
-               *cs++ = i915_ggtt_offset(rq->engine->scratch) |
-                       PIPE_CONTROL_GLOBAL_GTT;
+               *cs++ = i915_scratch_offset(rq->i915) | PIPE_CONTROL_GLOBAL_GTT;
                *cs++ = 0;
                *cs++ = 0;
        }
@@ -212,8 +219,7 @@ gen4_render_ring_flush(struct i915_request *rq, u32 mode)
 static int
 intel_emit_post_sync_nonzero_flush(struct i915_request *rq)
 {
-       u32 scratch_addr =
-               i915_ggtt_offset(rq->engine->scratch) + 2 * CACHELINE_BYTES;
+       u32 scratch_addr = i915_scratch_offset(rq->i915) + 2 * CACHELINE_BYTES;
        u32 *cs;
 
        cs = intel_ring_begin(rq, 6);
@@ -246,8 +252,7 @@ intel_emit_post_sync_nonzero_flush(struct i915_request *rq)
 static int
 gen6_render_ring_flush(struct i915_request *rq, u32 mode)
 {
-       u32 scratch_addr =
-               i915_ggtt_offset(rq->engine->scratch) + 2 * CACHELINE_BYTES;
+       u32 scratch_addr = i915_scratch_offset(rq->i915) + 2 * CACHELINE_BYTES;
        u32 *cs, flags = 0;
        int ret;
 
@@ -316,8 +321,7 @@ gen7_render_ring_cs_stall_wa(struct i915_request *rq)
 static int
 gen7_render_ring_flush(struct i915_request *rq, u32 mode)
 {
-       u32 scratch_addr =
-               i915_ggtt_offset(rq->engine->scratch) + 2 * CACHELINE_BYTES;
+       u32 scratch_addr = i915_scratch_offset(rq->i915) + 2 * CACHELINE_BYTES;
        u32 *cs, flags = 0;
 
        /*
@@ -971,7 +975,7 @@ i965_emit_bb_start(struct i915_request *rq,
 }
 
 /* Just userspace ABI convention to limit the wa batch bo to a resonable size */
-#define I830_BATCH_LIMIT (256*1024)
+#define I830_BATCH_LIMIT SZ_256K
 #define I830_TLB_ENTRIES (2)
 #define I830_WA_SIZE max(I830_TLB_ENTRIES*4096, I830_BATCH_LIMIT)
 static int
@@ -979,7 +983,9 @@ i830_emit_bb_start(struct i915_request *rq,
                   u64 offset, u32 len,
                   unsigned int dispatch_flags)
 {
-       u32 *cs, cs_offset = i915_ggtt_offset(rq->engine->scratch);
+       u32 *cs, cs_offset = i915_scratch_offset(rq->i915);
+
+       GEM_BUG_ON(rq->i915->gt.scratch->size < I830_WA_SIZE);
 
        cs = intel_ring_begin(rq, 6);
        if (IS_ERR(cs))
@@ -1437,7 +1443,6 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine)
 {
        struct i915_timeline *timeline;
        struct intel_ring *ring;
-       unsigned int size;
        int err;
 
        intel_engine_setup_common(engine);
@@ -1462,21 +1467,12 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine)
        GEM_BUG_ON(engine->buffer);
        engine->buffer = ring;
 
-       size = PAGE_SIZE;
-       if (HAS_BROKEN_CS_TLB(engine->i915))
-               size = I830_WA_SIZE;
-       err = intel_engine_create_scratch(engine, size);
-       if (err)
-               goto err_unpin;
-
        err = intel_engine_init_common(engine);
        if (err)
-               goto err_scratch;
+               goto err_unpin;
 
        return 0;
 
-err_scratch:
-       intel_engine_cleanup_scratch(engine);
 err_unpin:
        intel_ring_unpin(ring);
 err_ring:
@@ -1550,7 +1546,7 @@ static int flush_pd_dir(struct i915_request *rq)
        /* Stall until the page table load is complete */
        *cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT;
        *cs++ = i915_mmio_reg_offset(RING_PP_DIR_BASE(engine));
-       *cs++ = i915_ggtt_offset(engine->scratch);
+       *cs++ = i915_scratch_offset(rq->i915);
        *cs++ = MI_NOOP;
 
        intel_ring_advance(rq, cs);
@@ -1659,7 +1655,7 @@ static inline int mi_set_context(struct i915_request *rq, u32 flags)
                        /* Insert a delay before the next switch! */
                        *cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT;
                        *cs++ = i915_mmio_reg_offset(last_reg);
-                       *cs++ = i915_ggtt_offset(engine->scratch);
+                       *cs++ = i915_scratch_offset(rq->i915);
                        *cs++ = MI_NOOP;
                }
                *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
index 2dfa585712c28ac4196830a30dafc4448b3de604..767a7192c969751da0fce60a0874523049bc1de2 100644 (file)
@@ -15,6 +15,7 @@
 #include "i915_selftest.h"
 #include "i915_timeline.h"
 #include "intel_gpu_commands.h"
+#include "intel_workarounds.h"
 
 struct drm_printer;
 struct i915_sched_attr;
@@ -440,7 +441,7 @@ struct intel_engine_cs {
 
        struct intel_hw_status_page status_page;
        struct i915_ctx_workarounds wa_ctx;
-       struct i915_vma *scratch;
+       struct i915_wa_list wa_list;
 
        u32             irq_keep_mask; /* always keep these interrupts */
        u32             irq_enable_mask; /* bitmask to enable ring interrupt */
@@ -898,10 +899,6 @@ void intel_engine_setup_common(struct intel_engine_cs *engine);
 int intel_engine_init_common(struct intel_engine_cs *engine);
 void intel_engine_cleanup_common(struct intel_engine_cs *engine);
 
-int intel_engine_create_scratch(struct intel_engine_cs *engine,
-                               unsigned int size);
-void intel_engine_cleanup_scratch(struct intel_engine_cs *engine);
-
 int intel_init_render_ring_buffer(struct intel_engine_cs *engine);
 int intel_init_bsd_ring_buffer(struct intel_engine_cs *engine);
 int intel_init_blt_ring_buffer(struct intel_engine_cs *engine);
index 4bcdeaf8d98fa3de5aec7790971098905b5a688b..6e580891db96fa9350bfa2a2f9a68be50703229b 100644 (file)
  * - Public functions to init or apply the given workaround type.
  */
 
+static void wa_init_start(struct i915_wa_list *wal, const char *name)
+{
+       wal->name = name;
+}
+
+static void wa_init_finish(struct i915_wa_list *wal)
+{
+       if (!wal->count)
+               return;
+
+       DRM_DEBUG_DRIVER("Initialized %u %s workarounds\n",
+                        wal->count, wal->name);
+}
+
 static void wa_add(struct drm_i915_private *i915,
                   i915_reg_t reg, const u32 mask, const u32 val)
 {
@@ -580,160 +594,175 @@ int intel_ctx_workarounds_emit(struct i915_request *rq)
        return 0;
 }
 
-static void bdw_gt_workarounds_apply(struct drm_i915_private *dev_priv)
+static void
+wal_add(struct i915_wa_list *wal, const struct i915_wa *wa)
+{
+       const unsigned int grow = 1 << 4;
+
+       GEM_BUG_ON(!is_power_of_2(grow));
+
+       if (IS_ALIGNED(wal->count, grow)) { /* Either uninitialized or full. */
+               struct i915_wa *list;
+
+               list = kmalloc_array(ALIGN(wal->count + 1, grow), sizeof(*wa),
+                                    GFP_KERNEL);
+               if (!list) {
+                       DRM_ERROR("No space for workaround init!\n");
+                       return;
+               }
+
+               if (wal->list)
+                       memcpy(list, wal->list, sizeof(*wa) * wal->count);
+
+               wal->list = list;
+       }
+
+       wal->list[wal->count++] = *wa;
+}
+
+static void
+wa_masked_en(struct i915_wa_list *wal, i915_reg_t reg, u32 val)
+{
+       struct i915_wa wa = {
+               .reg = reg,
+               .mask = val,
+               .val = _MASKED_BIT_ENABLE(val)
+       };
+
+       wal_add(wal, &wa);
+}
+
+static void
+wa_write_masked_or(struct i915_wa_list *wal, i915_reg_t reg, u32 mask,
+                  u32 val)
 {
+       struct i915_wa wa = {
+               .reg = reg,
+               .mask = mask,
+               .val = val
+       };
+
+       wal_add(wal, &wa);
 }
 
-static void chv_gt_workarounds_apply(struct drm_i915_private *dev_priv)
+static void
+wa_write(struct i915_wa_list *wal, i915_reg_t reg, u32 val)
 {
+       wa_write_masked_or(wal, reg, ~0, val);
 }
 
-static void gen9_gt_workarounds_apply(struct drm_i915_private *dev_priv)
+static void
+wa_write_or(struct i915_wa_list *wal, i915_reg_t reg, u32 val)
 {
-       /* WaContextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk,cfl */
-       I915_WRITE(GEN9_CSFE_CHICKEN1_RCS,
-                  _MASKED_BIT_ENABLE(GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE));
+       wa_write_masked_or(wal, reg, val, val);
+}
 
-       /* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk,cfl */
-       I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) |
-                  GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE);
+static void gen9_gt_workarounds_init(struct drm_i915_private *i915)
+{
+       struct i915_wa_list *wal = &i915->gt_wa_list;
 
        /* WaDisableKillLogic:bxt,skl,kbl */
-       if (!IS_COFFEELAKE(dev_priv))
-               I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
-                          ECOCHK_DIS_TLB);
+       if (!IS_COFFEELAKE(i915))
+               wa_write_or(wal,
+                           GAM_ECOCHK,
+                           ECOCHK_DIS_TLB);
 
-       if (HAS_LLC(dev_priv)) {
+       if (HAS_LLC(i915)) {
                /* WaCompressedResourceSamplerPbeMediaNewHashMode:skl,kbl
                 *
                 * Must match Display Engine. See
                 * WaCompressedResourceDisplayNewHashMode.
                 */
-               I915_WRITE(MMCD_MISC_CTRL,
-                          I915_READ(MMCD_MISC_CTRL) |
-                          MMCD_PCLA |
-                          MMCD_HOTSPOT_EN);
+               wa_write_or(wal,
+                           MMCD_MISC_CTRL,
+                           MMCD_PCLA | MMCD_HOTSPOT_EN);
        }
 
        /* WaDisableHDCInvalidation:skl,bxt,kbl,cfl */
-       I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
-                  BDW_DISABLE_HDC_INVALIDATION);
-
-       /* WaProgramL3SqcReg1DefaultForPerf:bxt,glk */
-       if (IS_GEN9_LP(dev_priv)) {
-               u32 val = I915_READ(GEN8_L3SQCREG1);
-
-               val &= ~L3_PRIO_CREDITS_MASK;
-               val |= L3_GENERAL_PRIO_CREDITS(62) | L3_HIGH_PRIO_CREDITS(2);
-               I915_WRITE(GEN8_L3SQCREG1, val);
-       }
-
-       /* WaOCLCoherentLineFlush:skl,bxt,kbl,cfl */
-       I915_WRITE(GEN8_L3SQCREG4,
-                  I915_READ(GEN8_L3SQCREG4) | GEN8_LQSC_FLUSH_COHERENT_LINES);
-
-       /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,[cnl] */
-       I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
-                  _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
+       wa_write_or(wal,
+                   GAM_ECOCHK,
+                   BDW_DISABLE_HDC_INVALIDATION);
 }
 
-static void skl_gt_workarounds_apply(struct drm_i915_private *dev_priv)
+static void skl_gt_workarounds_init(struct drm_i915_private *i915)
 {
-       gen9_gt_workarounds_apply(dev_priv);
+       struct i915_wa_list *wal = &i915->gt_wa_list;
 
-       /* WaEnableGapsTsvCreditFix:skl */
-       I915_WRITE(GEN8_GARBCNTL,
-                  I915_READ(GEN8_GARBCNTL) | GEN9_GAPS_TSV_CREDIT_DISABLE);
+       gen9_gt_workarounds_init(i915);
 
        /* WaDisableGafsUnitClkGating:skl */
-       I915_WRITE(GEN7_UCGCTL4,
-                  I915_READ(GEN7_UCGCTL4) | GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
+       wa_write_or(wal,
+                   GEN7_UCGCTL4,
+                   GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
 
        /* WaInPlaceDecompressionHang:skl */
-       if (IS_SKL_REVID(dev_priv, SKL_REVID_H0, REVID_FOREVER))
-               I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
-                          I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
-                          GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
+       if (IS_SKL_REVID(i915, SKL_REVID_H0, REVID_FOREVER))
+               wa_write_or(wal,
+                           GEN9_GAMT_ECO_REG_RW_IA,
+                           GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
 }
 
-static void bxt_gt_workarounds_apply(struct drm_i915_private *dev_priv)
+static void bxt_gt_workarounds_init(struct drm_i915_private *i915)
 {
-       gen9_gt_workarounds_apply(dev_priv);
+       struct i915_wa_list *wal = &i915->gt_wa_list;
 
-       /* WaDisablePooledEuLoadBalancingFix:bxt */
-       I915_WRITE(FF_SLICE_CS_CHICKEN2,
-                  _MASKED_BIT_ENABLE(GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE));
+       gen9_gt_workarounds_init(i915);
 
        /* WaInPlaceDecompressionHang:bxt */
-       I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
-                  I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
-                  GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
+       wa_write_or(wal,
+                   GEN9_GAMT_ECO_REG_RW_IA,
+                   GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
 }
 
-static void kbl_gt_workarounds_apply(struct drm_i915_private *dev_priv)
+static void kbl_gt_workarounds_init(struct drm_i915_private *i915)
 {
-       gen9_gt_workarounds_apply(dev_priv);
+       struct i915_wa_list *wal = &i915->gt_wa_list;
 
-       /* WaEnableGapsTsvCreditFix:kbl */
-       I915_WRITE(GEN8_GARBCNTL,
-                  I915_READ(GEN8_GARBCNTL) | GEN9_GAPS_TSV_CREDIT_DISABLE);
+       gen9_gt_workarounds_init(i915);
 
        /* WaDisableDynamicCreditSharing:kbl */
-       if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
-               I915_WRITE(GAMT_CHKN_BIT_REG,
-                          I915_READ(GAMT_CHKN_BIT_REG) |
-                          GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING);
+       if (IS_KBL_REVID(i915, 0, KBL_REVID_B0))
+               wa_write_or(wal,
+                           GAMT_CHKN_BIT_REG,
+                           GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING);
 
        /* WaDisableGafsUnitClkGating:kbl */
-       I915_WRITE(GEN7_UCGCTL4,
-                  I915_READ(GEN7_UCGCTL4) | GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
+       wa_write_or(wal,
+                   GEN7_UCGCTL4,
+                   GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
 
        /* WaInPlaceDecompressionHang:kbl */
-       I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
-                  I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
-                  GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
-
-       /* WaKBLVECSSemaphoreWaitPoll:kbl */
-       if (IS_KBL_REVID(dev_priv, KBL_REVID_A0, KBL_REVID_E0)) {
-               struct intel_engine_cs *engine;
-               unsigned int tmp;
-
-               for_each_engine(engine, dev_priv, tmp) {
-                       if (engine->id == RCS)
-                               continue;
-
-                       I915_WRITE(RING_SEMA_WAIT_POLL(engine->mmio_base), 1);
-               }
-       }
+       wa_write_or(wal,
+                   GEN9_GAMT_ECO_REG_RW_IA,
+                   GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
 }
 
-static void glk_gt_workarounds_apply(struct drm_i915_private *dev_priv)
+static void glk_gt_workarounds_init(struct drm_i915_private *i915)
 {
-       gen9_gt_workarounds_apply(dev_priv);
+       gen9_gt_workarounds_init(i915);
 }
 
-static void cfl_gt_workarounds_apply(struct drm_i915_private *dev_priv)
+static void cfl_gt_workarounds_init(struct drm_i915_private *i915)
 {
-       gen9_gt_workarounds_apply(dev_priv);
+       struct i915_wa_list *wal = &i915->gt_wa_list;
 
-       /* WaEnableGapsTsvCreditFix:cfl */
-       I915_WRITE(GEN8_GARBCNTL,
-                  I915_READ(GEN8_GARBCNTL) | GEN9_GAPS_TSV_CREDIT_DISABLE);
+       gen9_gt_workarounds_init(i915);
 
        /* WaDisableGafsUnitClkGating:cfl */
-       I915_WRITE(GEN7_UCGCTL4,
-                  I915_READ(GEN7_UCGCTL4) | GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
+       wa_write_or(wal,
+                   GEN7_UCGCTL4,
+                   GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
 
        /* WaInPlaceDecompressionHang:cfl */
-       I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
-                  I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
-                  GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
+       wa_write_or(wal,
+                   GEN9_GAMT_ECO_REG_RW_IA,
+                   GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
 }
 
 static void wa_init_mcr(struct drm_i915_private *dev_priv)
 {
        const struct sseu_dev_info *sseu = &(INTEL_INFO(dev_priv)->sseu);
-       u32 mcr;
+       struct i915_wa_list *wal = &dev_priv->gt_wa_list;
        u32 mcr_slice_subslice_mask;
 
        /*
@@ -770,8 +799,6 @@ static void wa_init_mcr(struct drm_i915_private *dev_priv)
                WARN_ON((enabled_mask & disabled_mask) != enabled_mask);
        }
 
-       mcr = I915_READ(GEN8_MCR_SELECTOR);
-
        if (INTEL_GEN(dev_priv) >= 11)
                mcr_slice_subslice_mask = GEN11_MCR_SLICE_MASK |
                                          GEN11_MCR_SUBSLICE_MASK;
@@ -789,148 +816,170 @@ static void wa_init_mcr(struct drm_i915_private *dev_priv)
         * occasions, such as INSTDONE, where this value is dependent
         * on s/ss combo, the read should be done with read_subslice_reg.
         */
-       mcr &= ~mcr_slice_subslice_mask;
-       mcr |= intel_calculate_mcr_s_ss_select(dev_priv);
-       I915_WRITE(GEN8_MCR_SELECTOR, mcr);
+       wa_write_masked_or(wal,
+                          GEN8_MCR_SELECTOR,
+                          mcr_slice_subslice_mask,
+                          intel_calculate_mcr_s_ss_select(dev_priv));
 }
 
-static void cnl_gt_workarounds_apply(struct drm_i915_private *dev_priv)
+static void cnl_gt_workarounds_init(struct drm_i915_private *i915)
 {
-       wa_init_mcr(dev_priv);
+       struct i915_wa_list *wal = &i915->gt_wa_list;
+
+       wa_init_mcr(i915);
 
        /* WaDisableI2mCycleOnWRPort:cnl (pre-prod) */
-       if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0))
-               I915_WRITE(GAMT_CHKN_BIT_REG,
-                          I915_READ(GAMT_CHKN_BIT_REG) |
-                          GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT);
+       if (IS_CNL_REVID(i915, CNL_REVID_B0, CNL_REVID_B0))
+               wa_write_or(wal,
+                           GAMT_CHKN_BIT_REG,
+                           GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT);
 
        /* WaInPlaceDecompressionHang:cnl */
-       I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
-                  I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
-                  GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
-
-       /* WaEnablePreemptionGranularityControlByUMD:cnl */
-       I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
-                  _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
+       wa_write_or(wal,
+                   GEN9_GAMT_ECO_REG_RW_IA,
+                   GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
 }
 
-static void icl_gt_workarounds_apply(struct drm_i915_private *dev_priv)
+static void icl_gt_workarounds_init(struct drm_i915_private *i915)
 {
-       wa_init_mcr(dev_priv);
+       struct i915_wa_list *wal = &i915->gt_wa_list;
 
-       /* This is not an Wa. Enable for better image quality */
-       I915_WRITE(_3D_CHICKEN3,
-                  _MASKED_BIT_ENABLE(_3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE));
+       wa_init_mcr(i915);
 
        /* WaInPlaceDecompressionHang:icl */
-       I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
-                                           GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
-
-       /* WaPipelineFlushCoherentLines:icl */
-       I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) |
-                                  GEN8_LQSC_FLUSH_COHERENT_LINES);
-
-       /* Wa_1405543622:icl
-        * Formerly known as WaGAPZPriorityScheme
-        */
-       I915_WRITE(GEN8_GARBCNTL, I915_READ(GEN8_GARBCNTL) |
-                                 GEN11_ARBITRATION_PRIO_ORDER_MASK);
-
-       /* Wa_1604223664:icl
-        * Formerly known as WaL3BankAddressHashing
-        */
-       I915_WRITE(GEN8_GARBCNTL,
-                  (I915_READ(GEN8_GARBCNTL) & ~GEN11_HASH_CTRL_EXCL_MASK) |
-                  GEN11_HASH_CTRL_EXCL_BIT0);
-       I915_WRITE(GEN11_GLBLINVL,
-                  (I915_READ(GEN11_GLBLINVL) & ~GEN11_BANK_HASH_ADDR_EXCL_MASK) |
-                  GEN11_BANK_HASH_ADDR_EXCL_BIT0);
+       wa_write_or(wal,
+                   GEN9_GAMT_ECO_REG_RW_IA,
+                   GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
 
        /* WaModifyGamTlbPartitioning:icl */
-       I915_WRITE(GEN11_GACB_PERF_CTRL,
-                  (I915_READ(GEN11_GACB_PERF_CTRL) & ~GEN11_HASH_CTRL_MASK) |
-                  GEN11_HASH_CTRL_BIT0 | GEN11_HASH_CTRL_BIT4);
-
-       /* Wa_1405733216:icl
-        * Formerly known as WaDisableCleanEvicts
-        */
-       I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) |
-                                  GEN11_LQSC_CLEAN_EVICT_DISABLE);
+       wa_write_masked_or(wal,
+                          GEN11_GACB_PERF_CTRL,
+                          GEN11_HASH_CTRL_MASK,
+                          GEN11_HASH_CTRL_BIT0 | GEN11_HASH_CTRL_BIT4);
 
        /* Wa_1405766107:icl
         * Formerly known as WaCL2SFHalfMaxAlloc
         */
-       I915_WRITE(GEN11_LSN_UNSLCVC, I915_READ(GEN11_LSN_UNSLCVC) |
-                                     GEN11_LSN_UNSLCVC_GAFS_HALF_SF_MAXALLOC |
-                                     GEN11_LSN_UNSLCVC_GAFS_HALF_CL2_MAXALLOC);
+       wa_write_or(wal,
+                   GEN11_LSN_UNSLCVC,
+                   GEN11_LSN_UNSLCVC_GAFS_HALF_SF_MAXALLOC |
+                   GEN11_LSN_UNSLCVC_GAFS_HALF_CL2_MAXALLOC);
 
        /* Wa_220166154:icl
         * Formerly known as WaDisCtxReload
         */
-       I915_WRITE(GAMW_ECO_DEV_RW_IA_REG, I915_READ(GAMW_ECO_DEV_RW_IA_REG) |
-                                          GAMW_ECO_DEV_CTX_RELOAD_DISABLE);
+       wa_write_or(wal,
+                   GEN8_GAMW_ECO_DEV_RW_IA,
+                   GAMW_ECO_DEV_CTX_RELOAD_DISABLE);
 
        /* Wa_1405779004:icl (pre-prod) */
-       if (IS_ICL_REVID(dev_priv, ICL_REVID_A0, ICL_REVID_A0))
-               I915_WRITE(SLICE_UNIT_LEVEL_CLKGATE,
-                          I915_READ(SLICE_UNIT_LEVEL_CLKGATE) |
-                          MSCUNIT_CLKGATE_DIS);
+       if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_A0))
+               wa_write_or(wal,
+                           SLICE_UNIT_LEVEL_CLKGATE,
+                           MSCUNIT_CLKGATE_DIS);
 
        /* Wa_1406680159:icl */
-       I915_WRITE(SUBSLICE_UNIT_LEVEL_CLKGATE,
-                  I915_READ(SUBSLICE_UNIT_LEVEL_CLKGATE) |
-                  GWUNIT_CLKGATE_DIS);
-
-       /* Wa_1604302699:icl */
-       I915_WRITE(GEN10_L3_CHICKEN_MODE_REGISTER,
-                  I915_READ(GEN10_L3_CHICKEN_MODE_REGISTER) |
-                  GEN11_I2M_WRITE_DISABLE);
+       wa_write_or(wal,
+                   SUBSLICE_UNIT_LEVEL_CLKGATE,
+                   GWUNIT_CLKGATE_DIS);
 
        /* Wa_1406838659:icl (pre-prod) */
-       if (IS_ICL_REVID(dev_priv, ICL_REVID_A0, ICL_REVID_B0))
-               I915_WRITE(INF_UNIT_LEVEL_CLKGATE,
-                          I915_READ(INF_UNIT_LEVEL_CLKGATE) |
-                          CGPSF_CLKGATE_DIS);
-
-       /* WaForwardProgressSoftReset:icl */
-       I915_WRITE(GEN10_SCRATCH_LNCF2,
-                  I915_READ(GEN10_SCRATCH_LNCF2) |
-                  PMFLUSHDONE_LNICRSDROP |
-                  PMFLUSH_GAPL3UNBLOCK |
-                  PMFLUSHDONE_LNEBLK);
+       if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_B0))
+               wa_write_or(wal,
+                           INF_UNIT_LEVEL_CLKGATE,
+                           CGPSF_CLKGATE_DIS);
 
        /* Wa_1406463099:icl
         * Formerly known as WaGamTlbPendError
         */
-       I915_WRITE(GAMT_CHKN_BIT_REG,
-                  I915_READ(GAMT_CHKN_BIT_REG) |
-                  GAMT_CHKN_DISABLE_L3_COH_PIPE);
+       wa_write_or(wal,
+                   GAMT_CHKN_BIT_REG,
+                   GAMT_CHKN_DISABLE_L3_COH_PIPE);
 }
 
-void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv)
+void intel_gt_init_workarounds(struct drm_i915_private *i915)
 {
-       if (INTEL_GEN(dev_priv) < 8)
+       struct i915_wa_list *wal = &i915->gt_wa_list;
+
+       wa_init_start(wal, "GT");
+
+       if (INTEL_GEN(i915) < 8)
                return;
-       else if (IS_BROADWELL(dev_priv))
-               bdw_gt_workarounds_apply(dev_priv);
-       else if (IS_CHERRYVIEW(dev_priv))
-               chv_gt_workarounds_apply(dev_priv);
-       else if (IS_SKYLAKE(dev_priv))
-               skl_gt_workarounds_apply(dev_priv);
-       else if (IS_BROXTON(dev_priv))
-               bxt_gt_workarounds_apply(dev_priv);
-       else if (IS_KABYLAKE(dev_priv))
-               kbl_gt_workarounds_apply(dev_priv);
-       else if (IS_GEMINILAKE(dev_priv))
-               glk_gt_workarounds_apply(dev_priv);
-       else if (IS_COFFEELAKE(dev_priv))
-               cfl_gt_workarounds_apply(dev_priv);
-       else if (IS_CANNONLAKE(dev_priv))
-               cnl_gt_workarounds_apply(dev_priv);
-       else if (IS_ICELAKE(dev_priv))
-               icl_gt_workarounds_apply(dev_priv);
+       else if (IS_BROADWELL(i915))
+               return;
+       else if (IS_CHERRYVIEW(i915))
+               return;
+       else if (IS_SKYLAKE(i915))
+               skl_gt_workarounds_init(i915);
+       else if (IS_BROXTON(i915))
+               bxt_gt_workarounds_init(i915);
+       else if (IS_KABYLAKE(i915))
+               kbl_gt_workarounds_init(i915);
+       else if (IS_GEMINILAKE(i915))
+               glk_gt_workarounds_init(i915);
+       else if (IS_COFFEELAKE(i915))
+               cfl_gt_workarounds_init(i915);
+       else if (IS_CANNONLAKE(i915))
+               cnl_gt_workarounds_init(i915);
+       else if (IS_ICELAKE(i915))
+               icl_gt_workarounds_init(i915);
        else
-               MISSING_CASE(INTEL_GEN(dev_priv));
+               MISSING_CASE(INTEL_GEN(i915));
+
+       wa_init_finish(wal);
+}
+
+static enum forcewake_domains
+wal_get_fw_for_rmw(struct drm_i915_private *dev_priv,
+                  const struct i915_wa_list *wal)
+{
+       enum forcewake_domains fw = 0;
+       struct i915_wa *wa;
+       unsigned int i;
+
+       for (i = 0, wa = wal->list; i < wal->count; i++, wa++)
+               fw |= intel_uncore_forcewake_for_reg(dev_priv,
+                                                    wa->reg,
+                                                    FW_REG_READ |
+                                                    FW_REG_WRITE);
+
+       return fw;
+}
+
+static void
+wa_list_apply(struct drm_i915_private *dev_priv, const struct i915_wa_list *wal)
+{
+       enum forcewake_domains fw;
+       unsigned long flags;
+       struct i915_wa *wa;
+       unsigned int i;
+
+       if (!wal->count)
+               return;
+
+       fw = wal_get_fw_for_rmw(dev_priv, wal);
+
+       spin_lock_irqsave(&dev_priv->uncore.lock, flags);
+       intel_uncore_forcewake_get__locked(dev_priv, fw);
+
+       for (i = 0, wa = wal->list; i < wal->count; i++, wa++) {
+               u32 val = I915_READ_FW(wa->reg);
+
+               val &= ~wa->mask;
+               val |= wa->val;
+
+               I915_WRITE_FW(wa->reg, val);
+       }
+
+       intel_uncore_forcewake_put__locked(dev_priv, fw);
+       spin_unlock_irqrestore(&dev_priv->uncore.lock, flags);
+
+       DRM_DEBUG_DRIVER("Applied %u %s workarounds\n", wal->count, wal->name);
+}
+
+void intel_gt_apply_workarounds(struct drm_i915_private *dev_priv)
+{
+       wa_list_apply(dev_priv, &dev_priv->gt_wa_list);
 }
 
 struct whitelist {
@@ -1077,6 +1126,146 @@ void intel_whitelist_workarounds_apply(struct intel_engine_cs *engine)
        whitelist_apply(engine, whitelist_build(engine, &w));
 }
 
+static void rcs_engine_wa_init(struct intel_engine_cs *engine)
+{
+       struct drm_i915_private *i915 = engine->i915;
+       struct i915_wa_list *wal = &engine->wa_list;
+
+       if (IS_ICELAKE(i915)) {
+               /* This is not an Wa. Enable for better image quality */
+               wa_masked_en(wal,
+                            _3D_CHICKEN3,
+                            _3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE);
+
+               /* WaPipelineFlushCoherentLines:icl */
+               wa_write_or(wal,
+                           GEN8_L3SQCREG4,
+                           GEN8_LQSC_FLUSH_COHERENT_LINES);
+
+               /*
+                * Wa_1405543622:icl
+                * Formerly known as WaGAPZPriorityScheme
+                */
+               wa_write_or(wal,
+                           GEN8_GARBCNTL,
+                           GEN11_ARBITRATION_PRIO_ORDER_MASK);
+
+               /*
+                * Wa_1604223664:icl
+                * Formerly known as WaL3BankAddressHashing
+                */
+               wa_write_masked_or(wal,
+                                  GEN8_GARBCNTL,
+                                  GEN11_HASH_CTRL_EXCL_MASK,
+                                  GEN11_HASH_CTRL_EXCL_BIT0);
+               wa_write_masked_or(wal,
+                                  GEN11_GLBLINVL,
+                                  GEN11_BANK_HASH_ADDR_EXCL_MASK,
+                                  GEN11_BANK_HASH_ADDR_EXCL_BIT0);
+
+               /*
+                * Wa_1405733216:icl
+                * Formerly known as WaDisableCleanEvicts
+                */
+               wa_write_or(wal,
+                           GEN8_L3SQCREG4,
+                           GEN11_LQSC_CLEAN_EVICT_DISABLE);
+
+               /* Wa_1604302699:icl */
+               wa_write_or(wal,
+                           GEN10_L3_CHICKEN_MODE_REGISTER,
+                           GEN11_I2M_WRITE_DISABLE);
+
+               /* WaForwardProgressSoftReset:icl */
+               wa_write_or(wal,
+                           GEN10_SCRATCH_LNCF2,
+                           PMFLUSHDONE_LNICRSDROP |
+                           PMFLUSH_GAPL3UNBLOCK |
+                           PMFLUSHDONE_LNEBLK);
+       }