This is the start of the stable review cycle for the 5.13.19 release. There are 380 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat, 18 Sep 2021 15:57:06 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.13.19-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.13.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 5.13.19-rc1
Alyssa Rosenzweig alyssa.rosenzweig@collabora.com drm/panfrost: Clamp lock region to Bifrost minimum
Alyssa Rosenzweig alyssa.rosenzweig@collabora.com drm/panfrost: Use u64 for size in lock_region
Alyssa Rosenzweig alyssa.rosenzweig@collabora.com drm/panfrost: Simplify lock_region calculation
Kalyan Thota kalyan_t@codeaurora.org drm/msm/disp/dpu1: add safe lut config in dpu driver
Aaron Liu aaron.liu@amd.com drm/amd/display: setup system context for APUs
Jerry (Fangzhi) Zuo Jerry.Zuo@amd.com drm/amd/display: Update bounding box states (v2)
Aurabindo Pillai aurabindo.pillai@amd.com drm/amd/display: Update number of DCN3 clock states
xinhui pan xinhui.pan@amd.com drm/amdgpu: Fix a deadlock if previous GEM object allocation fails
Andrey Grodzovsky andrey.grodzovsky@amd.com drm/amdgpu: Fix BUG_ON assert
Boris Brezillon boris.brezillon@collabora.com drm/panfrost: Make sure MMU context lifetime is not bound to panfrost_priv
Rajkumar Subbiah rsubbia@codeaurora.org drm/dp_mst: Fix return code on sideband message failure
David Heidelberg david@ixit.cz drm/msi/mdp4: populate priv->kms in mdp4_kms_init
Thomas Zimmermann tzimmermann@suse.de drm/mgag200: Select clock in PLL update functions
Song Yoong Siang yoong.siang.song@intel.com net: stmmac: Fix overall budget calculation for rxtx_napi
Jan Hoffmann jan@3e8.eu net: dsa: lantiq_gswip: fix maximum frame length
Kees Cook keescook@chromium.org lib/test_stackinit: Fix static initializer test
Patryk Duda pdk@semihalf.com platform/chrome: cros_ec_proto: Send command again when timeout occurs
sumiyawang sumiyawang@tencent.com libnvdimm/pmem: Fix crash triggered when I/O in-flight during unbind
Vasily Averin vvs@virtuozzo.com memcg: enable accounting for pids in nested pid namespaces
Rik van Riel riel@surriel.com mm,vmscan: fix divide by zero in get_scan_count
Liu Zixian liuzixian4@huawei.com mm/hugetlb: initialize hugetlb_usage in mm_init
Li Zhijian lizhijian@cn.fujitsu.com mm/hmm: bypass devmap pte when all pfn requested flags are fulfilled
David Hildenbrand david@redhat.com mm/memory_hotplug: use "unsigned long" for PFN in zone_for_pfn_range()
Mike Kravetz mike.kravetz@oracle.com hugetlb: fix hugetlb cgroup refcounting during vma split
Sven Schnelle svens@linux.ibm.com s390/topology: fix topology information when calling cpu hotplug notifiers
Halil Pasic pasic@linux.ibm.com s390/pv: fix the forcing of the swiotlb
Pratik R. Sampat psampat@linux.ibm.com cpufreq: powernv: Fix init_chip_info initialization in numa=off
Evgeny Novikov novikov@ispras.ru mtd: rawnand: intel: Fix error handling in probe
Saurav Kashyap skashyap@marvell.com scsi: qla2xxx: Sync queue idx with queue_pair_map idx
Saurav Kashyap skashyap@marvell.com scsi: qla2xxx: Changes to support kdump kernel
Maciej W. Rozycki macro@orcam.me.uk scsi: BusLogic: Fix missing pr_cont() use
chenying chenying.kernel@bytedance.com ovl: fix BUG_ON() in may_delete() when called from ovl_cleanup()
Petr Mladek pmladek@suse.com printk/console: Check consistent sequence number when handling race in console_unlock()
Masahiro Yamada masahiroy@kernel.org parisc: Fix compile failure when building 64-bit kernel natively
Mikulas Patocka mpatocka@redhat.com parisc: fix crash with signals and alloca
Marc Zyngier maz@kernel.org KVM: arm64: vgic: move irq->get_input_level into an ops structure
Guojia Liao liaoguojia@huawei.com net: hns3: clean up a type mismatch warning
Yang Yingliang yangyingliang@huawei.com net: w5100: check return value after calling platform_get_resource()
Haimin Zhang tcs_kernel@tencent.com fix array-index-out-of-bounds in taprio_change
王贇 yun.wang@linux.alibaba.com net: fix NULL pointer reference in cipso_v4_doi_free
Miaoqing Pan miaoqing@codeaurora.org ath9k: fix sleeping in atomic context
Zekun Shen bruceshenzk@gmail.com ath9k: fix OOB read ar9300_eeprom_restore_internal
Loic Poulain loic.poulain@linaro.org wcn36xx: Fix missing frame timestamp for beacon/probe-resp
Chengfeng Ye cyeaa@connect.ust.hk selftests/bpf: Fix potential unreleased lock
Colin Ian King colin.king@canonical.com parport: remove non-zero check on count
Yevgeny Kliteynik kliteyn@nvidia.com net/mlx5: DR, Enable QP retransmission
Wentao_Liang Wentao_Liang_g@163.com net/mlx5: DR, fix a potential use-after-free bug
Ilan Peer ilan.peer@intel.com iwlwifi: mvm: Fix scan channel flags settings
Johannes Berg johannes.berg@intel.com iwlwifi: fw: correctly limit to monitor dump
Johannes Berg johannes.berg@intel.com iwlwifi: mvm: fix access to BSS elements
Ilan Peer ilan.peer@intel.com iwlwifi: mvm: Fix umac scan request probe parameters
Johannes Berg johannes.berg@intel.com iwlwifi: mvm: avoid static queue number aliasing
Zhang Qilong zhangqilong3@huawei.com iwlwifi: mvm: fix a memory leak in iwl_mvm_mac_ctxt_beacon_changed
Ilan Peer ilan.peer@intel.com iwlwifi: mvm: Do not use full SSIDs in 6GHz scan
Johannes Berg johannes.berg@intel.com iwlwifi: pcie: free RBs during configure
J. Bruce Fields bfields@redhat.com nfsd: fix crash on LOCKT on reexported NFSv3
J. Bruce Fields bfields@redhat.com nfs: don't atempt blocking locks on nfs reexports
Sean Keely Sean.Keely@amd.com drm/amdkfd: Account for SH/SE count when setting up cu masks.
Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com ASoC: soc-pcm: protect BE dailink state changes in trigger
Xiaotan Luo lxt@rock-chips.com ASoC: rockchip: i2s: Fixup config for DAIFMT_DSP_A/B
Sugar Zhang sugar.zhang@rock-chips.com ASoC: rockchip: i2s: Fix regmap_ops hang
Chunfeng Yun chunfeng.yun@mediatek.com usb: xhci-mtk: fix use-after-free of mtk->hcd
Shuah Khan skhan@linuxfoundation.org usbip:vhci_hcd USB port can get stuck in the disabled state
Anirudh Rayabharam mail@anirudhrb.com usbip: give back URBs for unsent unlink requests during cleanup
Nadezda Lutovinova lutovinova@ispras.ru usb: musb: musb_dsps: request_irq() after initializing musb
Nadezda Lutovinova lutovinova@ispras.ru usb: dwc3: imx8mp: request irq after initializing dwc3
Mathias Nyman mathias.nyman@linux.intel.com Revert "USB: xhci: fix U1/U2 handling for hardware with XHCI_INTEL_HOST quirk set"
Ding Hui dinghui@sangfor.com.cn cifs: fix wrong release in sess_alloc_buffer() failed path
Juhee Kang claudiajkang@gmail.com samples: pktgen: fix to print when terminated normally
Nishad Kamdar nishadkamdar@gmail.com mmc: core: Return correct emmc response in case of ioctl error
Li Zhijian lizhijian@cn.fujitsu.com selftests/bpf: Enlarge select() timeout for test_maps
Thomas Hebb tommyhebb@gmail.com mmc: rtsx_pci: Fix long reads when clock is prescaled
Manish Narani manish.narani@xilinx.com mmc: sdhci-of-arasan: Check return value of non-void funtions
Manish Narani manish.narani@xilinx.com mmc: sdhci-of-arasan: Modified SD default speed to 19MHz for ZynqMP
Marc Zyngier maz@kernel.org of: Don't allow __of_attached_node_sysfs() without CONFIG_SYSFS
Gustaw Lewandowski gustaw.lewandowski@linux.intel.com ASoC: Intel: Skylake: Fix passing loadable flag for module
Cezary Rojewski cezary.rojewski@intel.com ASoC: Intel: Skylake: Fix module configuration for KPB and MIXER
Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com soundwire: intel: fix potential race condition during power down
Marcos Paulo de Souza mpdesouza@suse.com btrfs: tree-log: check btrfs_lookup_data_extent return value
Filipe Manana fdmanana@suse.com btrfs: remove racy and unnecessary inode transaction update when using no-holes
Arnd Bergmann arnd@arndb.de m68knommu: only set CONFIG_ISA_DMA_API for ColdFire sub-arch
Subbaraya Sundeep sbhatta@marvell.com octeontx2-pf: Fix NIX1_RX interface backpressure
Chin-Yen Lee timlee@realtek.com rtw88: wow: fix size access error of probe request
Ping-Ke Shih pkshih@realtek.com rtw88: wow: build wow function only if CONFIG_PM is on
Chin-Yen Lee timlee@realtek.com rtw88: use read_poll_timeout instead of fixed sleep
Chris Chiu chris.chiu@canonical.com rtl8xxxu: Fix the handling of TX A-MPDU aggregation
Nathan Chancellor nathan@kernel.org drm/exynos: Always initialize mapping in exynos_drm_register_dma()
J. Bruce Fields bfields@redhat.com lockd: lockd server-side shouldn't set fl_ops
Li Jun jun.li@nxp.com usb: chipidea: host: fix port index underflow and UBSAN complains
Bob Peterson rpeterso@redhat.com gfs2: Don't call dlm after protocol is unmounted
Mark Brown broonie@kernel.org kselftest/arm64: pac: Fix skipping of tests on systems without PAC
Mark Brown broonie@kernel.org kselftest/arm64: mte: Fix misleading output when skipping tests
Eli Cohen elic@nvidia.com net: Fix offloading indirect devices dependency on qdisc order creation
Bongsu Jeon bongsu.jeon@samsung.com selftests: nci: Fix the wrong condition
Bongsu Jeon bongsu.jeon@samsung.com selftests: nci: Fix the code for next nlattr offset
Kees Cook keescook@chromium.org staging: rts5208: Fix get_ms_information() heap buffer size
Brandon Wyman bjwyman@gmail.com hwmon: (pmbus/ibm-cffps) Fix write bits for LED control
Yonghong Song yhs@fb.com selftests/bpf: Fix flaky send_signal test
Yucong Sun fallentree@fb.com selftests/bpf: Correctly display subtest skip status
Stefan Assmann sassmann@kpanic.de iavf: use mutexes for locking of critical sections
J. Bruce Fields bfields@redhat.com rpc: fix gss_svc_init cleanup on failure
Thomas Gleixner tglx@linutronix.de locking/rtmutex: Set proper wait context for lockdep
Luke Hsiao lukehsiao@google.com tcp: enable data-less, empty-cookie SYN with TFO_SERVER_COOKIE_NOT_REQD
Darrick J. Wong djwong@kernel.org iomap: pass writeback errors to the mapping
Ulrich Hecht uli+renesas@fpond.eu serial: sh-sci: fix break handling for sysrq
Rajendra Nayak rnayak@codeaurora.org opp: Don't print an error if required-opps is missing
Luiz Augusto von Dentz luiz.von.dentz@intel.com Bluetooth: Fix handling of LE Enhanced Connection Complete
Sagi Grimberg sagi@grimberg.me nvme: code command_id with a genctr for use-after-free validation
Sagi Grimberg sagi@grimberg.me nvme-tcp: don't check blk_mq_tag_to_rq when receiving pdu data
Raag Jadav raagjadav@gmail.com arm64: dts: ls1046a: fix eeprom entries
Tim Harvey tharvey@gateworks.com arm64: dts: imx8mm-venice-gw71xx: fix USB OTG VBUS
Tim Harvey tharvey@gateworks.com arm64: dts: imx8mm-venice-gw700x: fix invalid pmic pin config
Tim Harvey tharvey@gateworks.com arm64: dts: imx8mm-venice-gw700x: fix mp5416 pmic config
Thierry Reding treding@nvidia.com arm64: tegra: Fix compatible string for Tegra132 CPUs
Andreas Obergschwandtner andreas.obergschwandtner@gmail.com ARM: tegra: tamonten: Fix UART pad setting
Dmitry Osipenko digetx@gmail.com ARM: tegra: acer-a500: Remove bogus USB VBUS regulators
Johan Almbladh johan.almbladh@anyfinetworks.com mac80211: Fix monitor MTU limit so that A-MSDUs get through
Tuo Li islituo@gmail.com drm/display: fix possible null-pointer dereference in dcn10_set_clock()
Tuo Li islituo@gmail.com gpu: drm: amd: amdgpu: amdgpu_i2c: fix possible uninitialized-variable access in amdgpu_i2c_router_select_ddc_port()
Eran Ben Elisha eranbe@nvidia.com net/mlx5: Fix variable type to match 64bit
Kuogee Hsieh khsieh@codeaurora.org drm/msm/dp: do not end dp link training until video is ready
Kuogee Hsieh khsieh@codeaurora.org drm/msm/dp: return correct edid checksum after corrupted edid checksum read
Kuogee Hsieh khsieh@codeaurora.org drm/msm/dp: reduce link rate if failed at link training 1
Desmond Cheong Zhi Xi desmondcheongzx@gmail.com Bluetooth: avoid circular locks in sco_sock_connect
Desmond Cheong Zhi Xi desmondcheongzx@gmail.com Bluetooth: schedule SCO timeouts with delayed_work
Fabio Aiuto fabioaiuto83@gmail.com staging: rtl8723bs: fix right side of condition
Desmond Cheong Zhi Xi desmondcheongzx@gmail.com drm/vmwgfx: fix potential UAF in vmwgfx_surface.c
Jussi Maki joamaki@gmail.com selftests/bpf: Fix xdp_tx.c prog section name
Roy Chan roy.chan@amd.com drm/amd/display: fix incorrect CM/TF programming sequence in dwb
Roy Chan roy.chan@amd.com drm/amd/display: fix missing writeback disablement if plane is removed
Sanjay R Mehta sanju.mehta@amd.com thunderbolt: Fix port linking by checking all adapters
Quanyang Wang quanyang.wang@windriver.com drm: xlnx: zynqmp: release reset to DP controller before accessing DP registers
Quanyang Wang quanyang.wang@windriver.com drm: xlnx: zynqmp_dpsub: Call pm_runtime_get_sync before setting pixel clock
Konrad Dybcio konrad.dybcio@somainline.org drm/msm/dsi: Fix DSI and DSI PHY regulator config from SDM660
David Heidelberg david@ixit.cz drm/msm: mdp4: drop vblank get/put from prepare/complete_commit
Nathan Chancellor nathan@kernel.org net: ethernet: stmmac: Do not use unreachable() in ipq806x_gmac_probe()
Rajendra Nayak rnayak@codeaurora.org nvmem: qfprom: Fix up qfprom_disable_fuse_blowing() ordering
Georgi Djakov georgi.djakov@linaro.org arm64: dts: qcom: sm8250: Fix epss_l3 unit address
Vinod Koul vkoul@kernel.org arm64: dts: qcom: msm8996: don't use underscore in node name
Vinod Koul vkoul@kernel.org arm64: dts: qcom: msm8994: don't use underscore in node name
Vinod Koul vkoul@kernel.org arm64: dts: qcom: sdm630: don't use underscore in node name
Vinod Koul vkoul@kernel.org arm64: dts: qcom: ipq6018: drop '0x' from unit address
Vinod Koul vkoul@kernel.org arm64: dts: qcom: sdm660: use reg value for memory node
Vinod Koul vkoul@kernel.org arm64: dts: qcom: ipq8074: fix pci node reg property
Sebastian Reichel sebastian.reichel@collabora.com ARM: dts: imx53-ppd: Fix ACHC entry
Tony Lindgren tony@atomide.com serial: 8250_omap: Handle optional overrun-throttle-ms property
Alex Elder elder@linaro.org net: ipa: fix IPA v4.9 interconnects
AngeloGioacchino Del Regno angelogioacchino.delregno@somainline.org arm64: dts: qcom: sdm630: Fix TLMM node and pinctrl configuration
AngeloGioacchino Del Regno angelogioacchino.delregno@somainline.org arm64: dts: qcom: sdm630: Rewrite memory map
Bob Peterson rpeterso@redhat.com gfs2: Fix glock recursion in freeze_go_xmote_bh
Evgeny Novikov novikov@ispras.ru media: tegra-cec: Handle errors of clk_prepare_enable()
Krzysztof Hałasa khalasa@piap.pl media: TDA1997x: fix tda1997x_query_dv_timings() return value
Hans Verkuil hverkuil-cisco@xs4all.nl media: v4l2-dv-timings.c: fix wrong condition in two for-loops
Laurent Pinchart laurent.pinchart@ideasonboard.com media: imx: imx7-media-csi: Fix buffer return upon stream start failure
Umang Jain umang.jain@ideasonboard.com media: imx258: Limit the max analogue gain to 480
Laurent Pinchart laurent.pinchart@ideasonboard.com media: imx258: Rectify mismatch of VTS value
Ioana Ciornei ioana.ciornei@nxp.com dpaa2-switch: do not enable the DPSW at probe time
Luiz Augusto von Dentz luiz.von.dentz@intel.com Bluetooth: Fix not generating RPA when required
Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com ASoC: Intel: update sof_pcm512x quirks
Hans de Goede hdegoede@redhat.com ASoC: Intel: bytcr_rt5640: Move "Platform Clock" routes to the maps for the matching in-/output
Vidya Sagar vidyas@nvidia.com arm64: tegra: Fix Tegra194 PCIe EP compatible string
Nicolas Ferre nicolas.ferre@microchip.com ARM: dts: at91: use the right property for shutdown controller
Yufeng Mo moyufeng@huawei.com bonding: 3ad: fix the concurrency between __bond_release_one() and bond_3ad_state_machine_handler()
Pablo Neira Ayuso pablo@netfilter.org netfilter: nft_compat: use nfnetlink_unicast()
Marek Vasut marex@denx.de ARM: dts: stm32: Update AV96 adv7513 node per dtbs_check
Marek Vasut marex@denx.de ARM: dts: stm32: Set {bitclock,frame}-master phandles on ST DKx
Marek Vasut marex@denx.de ARM: dts: stm32: Set {bitclock,frame}-master phandles on DHCOM SoM
Zhen Lei thunder.leizhen@huawei.com workqueue: Fix possible memory leaks in wq_numa_init()
Desmond Cheong Zhi Xi desmondcheongzx@gmail.com Bluetooth: skip invalid hci_sync_conn_complete_evt
Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com drm: rcar-du: Shutdown the display on system shutdown
Andy Shevchenko andriy.shevchenko@linux.intel.com ata: sata_dwc_460ex: No need to call phy_exit() befre phy_init()
Martynas Pumputis m@lambda.lt libbpf: Fix race when pinning maps in parallel
Juhee Kang claudiajkang@gmail.com samples: bpf: Fix tracex7 error raised on the missing argument
Christophe JAILLET christophe.jaillet@wanadoo.fr staging: ks7010: Fix the initialization of the 'sleep_status' structure
Greg Kroah-Hartman gregkh@linuxfoundation.org serial: 8250_pci: make setup_port() parameters explicitly unsigned
Jiri Slaby jirislaby@kernel.org hvsi: don't panic on tty_register_driver failure
Jiri Slaby jirislaby@kernel.org xtensa: ISS: don't panic in rs_init
Maciej W. Rozycki macro@orcam.me.uk serial: 8250: Define RX trigger levels for OxSemi 950 devices
Niklas Schnelle schnelle@linux.ibm.com s390: make PCI mio support a machine flag
Heiko Carstens hca@linux.ibm.com s390/jump_label: print real address in a case of a jump label bug
Gustavo A. R. Silva gustavoars@kernel.org flow_dissector: Fix out-of-bounds warnings
Gustavo A. R. Silva gustavoars@kernel.org ipv4: ip_output.c: Fix out-of-bounds warning in ip_copy_addrs()
Alex Elder elder@linaro.org net: ipa: fix ipa_cmd_table_valid()
Zheyu Ma zheyuma97@gmail.com video: fbdev: riva: Error out if 'pixclock' equals zero
Zheyu Ma zheyuma97@gmail.com video: fbdev: kyro: Error out if 'pixclock' equals zero
Zheyu Ma zheyuma97@gmail.com video: fbdev: asiliantfb: Error out if 'pixclock' equals zero
Jernej Skrabec jernej.skrabec@gmail.com arm64: dts: allwinner: h6: tanix-tx6: Fix regulator node names
Geert Uytterhoeven geert+renesas@glider.be drm/bridge: nwl-dsi: Avoid potential multiplication overflow on 32-bit
Johan Almbladh johan.almbladh@anyfinetworks.com bpf/tests: Do not PASS tests without actually testing the result
Johan Almbladh johan.almbladh@anyfinetworks.com bpf/tests: Fix copy-and-paste error in double word test
Anson Jacob Anson.Jacob@amd.com drm/amd/amdgpu: Update debugfs link_settings output link_rate field in hex
Oak Zeng Oak.Zeng@amd.com drm/amdgpu: Fix a printing message
Arnd Bergmann arnd@arndb.de ethtool: improve compat ioctl handling
Niklas Söderlund niklas.soderlund@corigine.com nfp: fix return statement in nfp_net_parse_meta()
Yang Yingliang yangyingliang@huawei.com media: atomisp: pci: fix error return code in atomisp_pci_probe()
Dinghao Liu dinghao.liu@zju.edu.cn media: atomisp: Fix runtime PM imbalance in atomisp_pci_probe
Evgeny Novikov novikov@ispras.ru media: platform: stm32: unprepare clocks at handling errors in probe
Ezequiel Garcia ezequiel@collabora.com media: hantro: vp8: Move noisy WARN_ON to vpu_debug
Oliver Logush oliver.logush@amd.com drm/amd/display: Fix timer_per_pixel unit error
Shuah Khan skhan@linuxfoundation.org selftests: firmware: Fix ignored return val of asprintf() warn
Eric Auger eric.auger@redhat.com misc/pvpanic-pci: Allow automatic loading
Laurentiu Tudor laurentiu.tudor@nxp.com bus: fsl-mc: fix mmio base address for child DPRCs
Laurentiu Tudor laurentiu.tudor@nxp.com bus: fsl-mc: fix arg in call to dprc_scan_objects()
Zheyu Ma zheyuma97@gmail.com tty: serial: jsm: hold port lock when reporting modem line changes
Mauro Carvalho Chehab mchehab+huawei@kernel.org staging: hisilicon,hi6421-spmi-pmic.yaml: fix patternProperties
Geert Uytterhoeven geert+renesas@glider.be staging: board: Fix uninitialized spinlock when attaching genpd
Jack Pham jackp@codeaurora.org usb: gadget: composite: Allow bMaxPower=0 if self-powered
Evgeny Novikov novikov@ispras.ru USB: EHCI: ehci-mv: improve error handling in mv_ehci_enable()
Maciej Żenczykowski maze@google.com usb: gadget: u_ether: fix a potential null pointer dereference
Kelly Devilliv kelly.devilliv@gmail.com usb: host: fotg210: fix the actual_length of an iso packet
Kelly Devilliv kelly.devilliv@gmail.com usb: host: fotg210: fix the endpoint's transactional opportunities calculation
Sasha Neftin sasha.neftin@intel.com igc: Check if num of q_vectors is smaller than max before array access
Zhouyi Zhou zhouzhouyi@gmail.com rcu: Fix macro name CONFIG_TASKS_RCU_TRACE
Desmond Cheong Zhi Xi desmondcheongzx@gmail.com drm: protect drm_master pointers in drm_lease.c
Desmond Cheong Zhi Xi desmondcheongzx@gmail.com drm: serialize drm_file.master with a new spinlock
Desmond Cheong Zhi Xi desmondcheongzx@gmail.com drm: avoid blocking in drm_clients_info's rcu section
Tianjia Zhang tianjia.zhang@linux.alibaba.com Smack: Fix wrong semantics in smk_access_entry()
Alex Elder elder@linaro.org net: ipa: fix IPA v4.11 interconnect data
Yajun Deng yajun.deng@linux.dev netlink: Deal with ESRCH error in nlmsg_notify()
KuoHsiang Chou kuohsiang_chou@aspeedtech.com drm/ast: Disable fast reset after DRAM initial
Zheyu Ma zheyuma97@gmail.com video: fbdev: kyro: fix a DoS bug by restricting user input
David Heidelberg david@ixit.cz ARM: dts: qcom: apq8064: correct clock names
Stefan Assmann sassmann@kpanic.de iavf: fix locking of critical sections
Stefan Assmann sassmann@kpanic.de iavf: do not override the adapter state in the watchdog task
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ad5624r: Fix incorrect handling of an optional regulator.
Marek Vasut marex@denx.de net: phy: Fix data type in DP83822 dp8382x_disable_wol()
Xin Long lucien.xin@gmail.com tipc: keep the skb in rcv queue until the whole data is read
Rafael J. Wysocki rafael.j.wysocki@intel.com PCI: Use pci_update_current_state() in pci_enable_device_flags()
Sean Anderson sean.anderson@seco.com crypto: mxs-dcp - Use sg_mapping_iter to copy data
Ani Sinha ani@anisinha.ca x86/hyperv: fix for unwanted manipulation of sched_clock when TSC marked unstable
Thomas Zimmermann tzimmermann@suse.de drm/vkms: Let shadow-plane helpers prepare the plane's FB
Martynas Pumputis m@lambda.lt libbpf: Fix reuse of pinned map on older kernel
Tomi Valkeinen tomi.valkeinen@ideasonboard.com media: ti-vpe: cal: fix queuing of the initial buffer
Tomi Valkeinen tomi.valkeinen@ideasonboard.com media: ti-vpe: cal: fix error handling in cal_camerarx_create
Mauro Carvalho Chehab mchehab+huawei@kernel.org media: dib8000: rewrite the init prbs logic
Randy Dunlap rdunlap@infradead.org ASoC: atmel: ATMEL drivers don't need HAS_DMA
Peter Ujfalusi peter.ujfalusi@gmail.com ASoC: ti: davinci-mcasp: Fix DIT mode support
Luben Tuikov luben.tuikov@amd.com drm/amdgpu: Fix amdgpu_ras_eeprom_init()
Daniel Vetter daniel.vetter@ffwll.ch drm/omap: Follow implicit fencing in prepare_fb
Dom Cobley popcornmix@gmail.com drm/vc4: hdmi: Set HD_CTL_WHOLSMP and HD_CTL_CHALIGN_SET
Zack Rusin zackr@vmware.com drm/vmwgfx: Fix some static checker warnings
Zack Rusin zackr@vmware.com drm/vmwgfx: Fix subresource updates with new contexts
Nadav Amit namit@vmware.com userfaultfd: prevent concurrent API initialization
Masahiro Yamada masahiroy@kernel.org kbuild: Fix 'no symbols' warning when CONFIG_TRIM_UNUSD_KSYMS=y
Oleksij Rempel linux@rempel-privat.de MIPS: Malta: fix alignment of the devicetree buffer
Jaegeuk Kim jaegeuk@kernel.org f2fs: should put a page beyond EOF when preparing a write
Jaegeuk Kim jaegeuk@kernel.org f2fs: deallocate compressed pages when error happens
Chao Yu chao@kernel.org f2fs: fix to unmap pages from userspace process in punch_hole()
Chao Yu chao@kernel.org f2fs: fix unexpected ENOENT comes from f2fs_map_blocks()
Chao Yu chao@kernel.org f2fs: fix to account missing .skipped_gc_rwsem
Yongqiang Niu yongqiang.niu@mediatek.com soc: mediatek: cmdq: add address shift in jump
Alexey Kardashevskiy aik@ozlabs.ru KVM: PPC: Fix clearing never mapped TCEs in realmode
Codrin Ciubotariu codrin.ciubotariu@microchip.com clk: at91: clk-generated: Limit the requested rate to our range
Sergio Paracuellos sergio.paracuellos@gmail.com clk: ralink: avoid to set 'CLK_IS_CRITICAL' flag for gates
David Howells dhowells@redhat.com fscache: Fix cookie key hashing
Wenpeng Liang liangwenpeng@huawei.com RDMA/hns: Fix QP's resp incomplete assignment
Srikar Dronamraju srikar@linux.vnet.ibm.com powerpc/smp: Update cpu_core_map on all PowerPc systems
Srikar Dronamraju srikar@linux.vnet.ibm.com powerpc/smp: Fix a crash while booting kvm guest with nr_cpus=2
Hans de Goede hdegoede@redhat.com platform/x86: dell-smbios-wmi: Add missing kfree in error-exit from run_smbios_call
Junxian Huang huangjunxian4@hisilicon.com RDMA/hns: Bugfix for the missing assignment for dip_idx
Junxian Huang huangjunxian4@hisilicon.com RDMA/hns: Bugfix for data type of dip_idx
Kajol Jain kjain@linux.ibm.com powerpc/perf: Fix the check for SIAR value
Nicholas Piggin npiggin@gmail.com KVM: PPC: Book3S HV Nested: Reflect guest PMU in-use to L0 when guest SPRs are live
Alim Akhtar alim.akhtar@samsung.com scsi: ufs: ufs-exynos: Fix static checker warning
Fabiano Rosas farosas@linux.ibm.com KVM: PPC: Book3S HV: Fix copy_tofrom_guest routines
Ahmad Fatoum a.fatoum@pengutronix.de clk: imx8m: fix clock tree update of TF-A managed clocks
Lucas Stach l.stach@pengutronix.de clk: imx8mm: use correct mux type for clkout path
Lukas Bulwahn lukas.bulwahn@gmail.com HID: thrustmaster: clean up Makefile and adapt quirks
Jim Broadus jbroadus@gmail.com HID: i2c-hid: Fix Elan touchpad regression
Basavaraj Natikar Basavaraj.Natikar@amd.com HID: amd_sfh: Fix period data field to enable sensor
YueHaibing yuehaibing@huawei.com RDMA/hns: Fix return in hns_roce_rereg_user_mr()
Lu Baolu baolu.lu@linux.intel.com iommu/vt-d: Update the virtual command related registers
Chao Yu chao@kernel.org f2fs: fix to keep compatibility of fault injection interface
Joel Stanley joel@jms.id.au powerpc/config: Renable MTD_PHYSMAP_OF
Dan Carpenter dan.carpenter@oracle.com scsi: qedf: Fix error codes in qedf_alloc_global_queues()
Dan Carpenter dan.carpenter@oracle.com scsi: qedi: Fix error codes in qedi_alloc_global_queues()
Dan Carpenter dan.carpenter@oracle.com scsi: smartpqi: Fix an error code in pqi_get_raid_map()
Laurent Dufour ldufour@linux.ibm.com powerpc/numa: Consider the max NUMA node for migratable LPAR
Zhen Lei thunder.leizhen@huawei.com pinctrl: single: Fix error return code in pcs_parse_bits_in_pinctrl_entry()
Wei Li liwei391@huawei.com scsi: fdomain: Fix error return code in fdomain_probe()
Anna Schumaker Anna.Schumaker@Netapp.com sunrpc: Fix return value of get_srcport()
Olga Kornievskaia kolga@netapp.com SUNRPC query transport's source port
Trond Myklebust trond.myklebust@hammerspace.com SUNRPC/xprtrdma: Fix reconnection locking
Trond Myklebust trond.myklebust@hammerspace.com SUNRPC: Fix potential memory corruption
Trond Myklebust trond.myklebust@hammerspace.com NFSv4/pnfs: The layout barrier indicate a minimal value for the seqid
Trond Myklebust trond.myklebust@hammerspace.com NFSv4/pNFS: Always allow update of a zero valued layout barrier
Trond Myklebust trond.myklebust@hammerspace.com NFSv4/pNFS: Fix a layoutget livelock loop
Chuck Lever chuck.lever@oracle.com xprtrdma: Put rpcrdma_reps before waking the tear-down completion
Anthony Iliopoulos ailiop@suse.com dma-debug: fix debugfs initialization order
Randy Dunlap rdunlap@infradead.org openrisc: don't printk() unconditionally
Yangtao Li frank.li@vivo.com f2fs: reduce the scope of setting fsck tag when de->name_len is zero
Nathan Chancellor nathan@kernel.org cpuidle: pseries: Mark pseries_idle_proble() as __init
Leon Romanovsky leon@kernel.org RDMA/mlx5: Delete not-available udata check
Leon Romanovsky leon@kernel.org RDMA/efa: Remove double QP type assignment
Leon Romanovsky leon@kernel.org RDMA/hns: Don't overwrite supplied QP attributes
Michal Suchanek msuchanek@suse.de powerpc/stacktrace: Include linux/delay.h
Gautham R. Shenoy ego@linux.vnet.ibm.com cpuidle: pseries: Fixup CEDE0 latency only for POWER10 onwards
Bart Van Assche bvanassche@acm.org scsi: ufs: Fix memory corruption by ufshcd_read_desc_param()
Jason Gunthorpe jgg@ziepe.ca vfio: Use config not menuconfig for VFIO_NOIOMMU
Chao Yu chao@kernel.org f2fs: fix wrong checkpoint_changed value in f2fs_remount()
Chao Yu chao@kernel.org f2fs: compress: add compress_inode to cache compressed blocks
Chao Yu chao@kernel.org f2fs: restructure f2fs page.private layout
Jaehyoung Choi jkkkkk.choi@samsung.com pinctrl: samsung: Fix pinctrl bank pin count
Colin Ian King colin.king@canonical.com scsi: BusLogic: Use %X for u32 sized integer rather than %lX
Leon Romanovsky leon@kernel.org docs: Fix infiniband uverbs minor number
Leon Romanovsky leon@kernel.org RDMA/iwcm: Release resources if iw_cm module initialization fails
Mike Marciniszyn mike.marciniszyn@cornelisnetworks.com IB/hfi1: Adjust pkey entry in index 0
Peter Geis pgwipeout@gmail.com clk: rockchip: drop GRF dependency for rk3328/rk3036 pll types
Christoph Hellwig hch@lst.de scsi: bsg: Remove support for SCSI_IOCTL_SEND_COMMAND
Marek Behún kabel@kernel.org pinctrl: armada-37xx: Correct PWM pins definitions
Chao Yu chao@kernel.org f2fs: quota: fix potential deadlock
Dmitry Torokhov dmitry.torokhov@gmail.com HID: input: do not report stylus battery state as "full"
Chao Yu chao@kernel.org f2fs: compress: fix to set zstd compress level correctly
Pali Rohár pali@kernel.org PCI: aardvark: Fix masking and unmasking legacy INTx interrupts
Pali Rohár pali@kernel.org PCI: aardvark: Increase polling delay to 1.5s while waiting for PIO response
Evan Wang xswang@marvell.com PCI: aardvark: Fix checking for PIO status
Pali Rohár pali@kernel.org PCI: aardvark: Configure PCIe resources from 'ranges' DT property
Hyun Kwon hyun.kwon@xilinx.com PCI: xilinx-nwl: Enable the clock through CCF
Krzysztof Wilczyński kw@linux.com PCI: Return ~0 data on pciconfig_read() CAP_SYS_ADMIN failure
Marek Behún kabel@kernel.org PCI: Restrict ASMedia ASM1062 SATA Max Payload Size Supported
Stuart Hayes stuart.w.hayes@gmail.com PCI/portdrv: Enable Bandwidth Notification only if port supports it
Chao Yu chao@kernel.org f2fs: fix to do sanity check for sb/cp fields correctly
David Heidelberg david@ixit.cz ARM: 9105/1: atags_to_fdt: don't warn about stack size
Hans de Goede hdegoede@redhat.com libata: add ATA_HORKAGE_NO_NCQ_TRIM for Samsung 860 and 870 SSDs
Pavel Begunkov asml.silence@gmail.com io_uring: fail links of cancelled timeouts
Jens Axboe axboe@kernel.dk io-wq: fix race between adding work and activating a free worker
Jens Axboe axboe@kernel.dk io-wq: fix wakeup race when adding new work
Pavel Begunkov asml.silence@gmail.com io_uring: fix io_try_cancel_userdata race for iowq
Pavel Begunkov asml.silence@gmail.com io_uring: add ->splice_fd_in checks
Pavel Begunkov asml.silence@gmail.com io_uring: place fixed tables under memcg limits
Robin Gong yibin.gong@nxp.com dmaengine: imx-sdma: remove duplicated sdma_load_context
Robin Gong yibin.gong@nxp.com Revert "dmaengine: imx-sdma: refine to load context only once"
Julian Wiedmann jwi@linux.ibm.com s390/qdio: cancel the ESTABLISH ccw after timeout
Julian Wiedmann jwi@linux.ibm.com s390/qdio: fix roll-back after timeout on ESTABLISH ccw
Srinivas Kandagatla srinivas.kandagatla@linaro.org nvmem: core: fix error handling while validating keepout regions
Sean Young sean@mess.org media: rc-loopback: return number of emitters rather than error
Mauro Carvalho Chehab mchehab+huawei@kernel.org media: uvc: don't do DMA on stack
Wang Hai wanghai38@huawei.com VMCI: fix NULL pointer dereference when unmapping queue pair
Eddie James eajames@linux.ibm.com spi: fsi: Reduce max transfer size to 8 bytes
Brijesh Singh brijesh.singh@amd.com crypto: ccp - shutdown SEV firmware on kexec
Arne Welzel arne.welzel@corelight.com dm crypt: Avoid percpu_counter spinlock contention in crypt_page_alloc()
Kevin Hao haokexin@gmail.com cpufreq: schedutil: Use kobject release() method to free sugov_tunables
Krzysztof Kozlowski krzysztof.kozlowski@canonical.com power: supply: max17042: handle fails of reading status register
Damien Le Moal damien.lemoal@wdc.com block: bfq: fix bfq_set_next_ioprio_data()
zhenwei pi pizhenwei@bytedance.com crypto: public_key: fix overflow during implicit conversion
Joseph Gates jgates@squareup.com wcn36xx: Ensure finish scan is not requested before start scan
Nuno Sá nuno.sa@analog.com iio: ltc2983: fix device probe
Alexandru Elisei alexandru.elisei@arm.com arm64: Do not trap PMSNEVFR_EL1
Mark Rutland mark.rutland@arm.com arm64: head: avoid over-mapping in map_memory
Will Deacon will@kernel.org arm64: mm: Fix TLBI vs ASID rollover
Marc Zyngier maz@kernel.org arm64: Move .hyp.rodata outside of the _sdata.._edata range
Iwona Winiarska iwona.winiarska@intel.com soc: aspeed: p2a-ctrl: Fix boundary check for mmap
Iwona Winiarska iwona.winiarska@intel.com soc: aspeed: lpc-ctrl: Fix boundary check for mmap
Manivannan Sadhasivam mani@kernel.org soc: qcom: aoss: Fix the out of bound usage of cooling_devs
Enric Balletbo i Serra enric.balletbo@collabora.com soc: mediatek: mmsys: Fix missing UFOE component in mt8173 table routing
Paul Cercueil paul@crapouillou.net pinctrl: ingenic: Fix bias config for X2000(E)
Paul Cercueil paul@crapouillou.net pinctrl: ingenic: Fix incorrect pull up/down info
Marc Zyngier maz@kernel.org pinctrl: stmfx: Fix hazardous u8[] to unsigned long cast
Dinh Nguyen dinguyen@kernel.org clk: socfpga: agilex: add the bypass register for s2f_usr0 clock
Dinh Nguyen dinguyen@kernel.org clk: socfpga: agilex: fix up s2f_user0_clk representation
Dinh Nguyen dinguyen@kernel.org clk: socfpga: agilex: fix the parents of the psi_ref_clk
Rolf Eike Beer eb@emlix.com tools/thermal/tmon: Add cross compiling support
Steven Rostedt (VMware) rostedt@goodmis.org selftests/ftrace: Fix requirement check of README file
jingle.wu jingle.wu@emc.com.tw Input: elan_i2c - reduce the resume time for controller in Whitebox
Colin Ian King colin.king@canonical.com ceph: fix dereference of null pointer cf
Harshvardhan Jha harshvardhan.jha@oracle.com 9p/xen: Fix end of loop tests for list_for_each_entry
Juergen Gross jgross@suse.com xen: fix setting of max_pfn in shared_info
Kajol Jain kjain@linux.ibm.com powerpc/perf/hv-gpci: Fix counter value parsing
Marek Marczykowski-Górecki marmarek@invisiblethingslab.com PCI/MSI: Skip masking MSI-X on Xen PV
Niklas Cassel niklas.cassel@wdc.com blk-zoned: allow BLKREPORTZONE without CAP_SYS_ADMIN
Niklas Cassel niklas.cassel@wdc.com blk-zoned: allow zone management send operations without CAP_SYS_ADMIN
Naohiro Aota naohiro.aota@wdc.com btrfs: zoned: fix double counting of split ordered extent
Desmond Cheong Zhi Xi desmondcheongzx@gmail.com btrfs: reset replace target device to allocation state on close
Anand Jain anand.jain@oracle.com btrfs: fix upper limit for max_inline for page size 64K
Naohiro Aota naohiro.aota@wdc.com btrfs: zoned: suppress reclaim error message on EAGAIN
Naohiro Aota naohiro.aota@wdc.com btrfs: zoned: fix block group alloc_offset calculation
Josef Bacik josef@toxicpanda.com btrfs: reduce the preemptive flushing threshold to 90%
Josef Bacik josef@toxicpanda.com btrfs: wait on async extents when flushing delalloc
Josef Bacik josef@toxicpanda.com btrfs: wake up async_delalloc_pages waiters after submit
Dmitry Osipenko digetx@gmail.com rtc: tps65910: Correct driver module alias
-------------
Diffstat:
Documentation/admin-guide/devices.txt | 6 +- .../pinctrl/marvell,armada-37xx-pinctrl.txt | 8 +- Documentation/filesystems/f2fs.rst | 4 + Makefile | 9 +- arch/arm/boot/compressed/Makefile | 2 + arch/arm/boot/dts/at91-kizbox3_common.dtsi | 2 +- arch/arm/boot/dts/at91-sam9x60ek.dts | 2 +- arch/arm/boot/dts/at91-sama5d27_som1_ek.dts | 2 +- arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts | 2 +- arch/arm/boot/dts/at91-sama5d2_icp.dts | 2 +- arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts | 2 +- arch/arm/boot/dts/at91-sama5d2_xplained.dts | 2 +- arch/arm/boot/dts/imx53-ppd.dts | 23 +- arch/arm/boot/dts/qcom-apq8064.dtsi | 6 +- arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi | 8 +- arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi | 6 +- arch/arm/boot/dts/stm32mp15xx-dkx.dtsi | 8 +- arch/arm/boot/dts/tegra20-acer-a500-picasso.dts | 25 +- arch/arm/boot/dts/tegra20-tamonten.dtsi | 14 +- .../boot/dts/allwinner/sun50i-h6-tanix-tx6.dts | 4 +- arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts | 8 +- arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts | 7 +- .../boot/dts/freescale/imx8mm-venice-gw700x.dtsi | 64 ++--- .../boot/dts/freescale/imx8mm-venice-gw71xx.dtsi | 5 +- arch/arm64/boot/dts/nvidia/tegra132.dtsi | 4 +- arch/arm64/boot/dts/nvidia/tegra194.dtsi | 6 +- arch/arm64/boot/dts/qcom/ipq6018.dtsi | 2 +- arch/arm64/boot/dts/qcom/ipq8074-hk01.dts | 2 +- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 16 +- arch/arm64/boot/dts/qcom/msm8994.dtsi | 6 +- arch/arm64/boot/dts/qcom/msm8996.dtsi | 4 +- arch/arm64/boot/dts/qcom/sdm630.dtsi | 257 ++++++++++++-------- arch/arm64/boot/dts/qcom/sm8250.dtsi | 2 +- arch/arm64/include/asm/el2_setup.h | 13 +- arch/arm64/include/asm/kernel-pgtable.h | 4 +- arch/arm64/include/asm/mmu.h | 29 ++- arch/arm64/include/asm/tlbflush.h | 11 +- arch/arm64/kernel/head.S | 11 +- arch/arm64/kernel/vmlinux.lds.S | 4 +- arch/arm64/kvm/arch_timer.c | 8 +- arch/arm64/kvm/vgic/vgic.c | 14 +- arch/m68k/Kconfig.bus | 2 +- arch/mips/mti-malta/malta-dtshim.c | 2 +- arch/openrisc/kernel/entry.S | 2 + arch/parisc/Makefile | 6 +- arch/parisc/kernel/signal.c | 6 + arch/powerpc/configs/mpc885_ads_defconfig | 1 + arch/powerpc/include/asm/pmc.h | 7 + arch/powerpc/kernel/smp.c | 13 +- arch/powerpc/kernel/stacktrace.c | 1 + arch/powerpc/kvm/book3s_64_mmu_radix.c | 6 +- arch/powerpc/kvm/book3s_64_vio_hv.c | 9 +- arch/powerpc/kvm/book3s_hv.c | 20 ++ arch/powerpc/mm/numa.c | 13 +- arch/powerpc/perf/core-book3s.c | 12 +- arch/powerpc/perf/hv-gpci.c | 2 +- arch/s390/include/asm/setup.h | 2 + arch/s390/include/asm/smp.h | 1 + arch/s390/kernel/early.c | 4 + arch/s390/kernel/jump_label.c | 2 +- arch/s390/kernel/smp.c | 9 +- arch/s390/kernel/topology.c | 13 +- arch/s390/mm/init.c | 2 +- arch/s390/pci/pci.c | 5 +- arch/x86/kernel/cpu/mshyperv.c | 9 +- arch/x86/xen/p2m.c | 4 +- arch/xtensa/platforms/iss/console.c | 17 +- block/bfq-iosched.c | 2 +- block/blk-zoned.c | 6 - block/bsg.c | 5 +- drivers/ata/libata-core.c | 4 + drivers/ata/sata_dwc_460ex.c | 12 +- drivers/bus/fsl-mc/fsl-mc-bus.c | 26 +- drivers/clk/at91/clk-generated.c | 6 + drivers/clk/imx/clk-composite-8m.c | 3 +- drivers/clk/imx/clk-imx8mm.c | 11 +- drivers/clk/imx/clk-imx8mn.c | 7 +- drivers/clk/imx/clk-imx8mq.c | 7 +- drivers/clk/imx/clk.h | 16 +- drivers/clk/ralink/clk-mt7621.c | 9 +- drivers/clk/rockchip/clk-pll.c | 2 +- drivers/clk/socfpga/clk-agilex.c | 19 +- drivers/cpufreq/powernv-cpufreq.c | 16 +- drivers/cpuidle/cpuidle-pseries.c | 18 +- drivers/crypto/ccp/sev-dev.c | 49 ++-- drivers/crypto/ccp/sp-pci.c | 12 + drivers/crypto/mxs-dcp.c | 36 +-- drivers/dma/imx-sdma.c | 13 +- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 23 +- drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c | 2 +- drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 2 +- drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c | 84 +++++-- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h | 1 + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- .../drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 16 +- .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 11 +- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 14 +- .../gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 2 +- .../gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c | 90 +++++-- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 12 +- .../gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 42 +++- drivers/gpu/drm/ast/ast_drv.h | 6 + drivers/gpu/drm/ast/ast_main.c | 5 + drivers/gpu/drm/ast/ast_post.c | 91 +++++-- drivers/gpu/drm/bridge/nwl-dsi.c | 2 +- drivers/gpu/drm/drm_auth.c | 42 +++- drivers/gpu/drm/drm_debugfs.c | 3 +- drivers/gpu/drm/drm_dp_mst_topology.c | 10 +- drivers/gpu/drm/drm_file.c | 1 + drivers/gpu/drm/drm_lease.c | 81 +++++-- drivers/gpu/drm/exynos/exynos_drm_dma.c | 2 + drivers/gpu/drm/mgag200/mgag200_drv.h | 16 ++ drivers/gpu/drm/mgag200/mgag200_mode.c | 20 +- drivers/gpu/drm/mgag200/mgag200_reg.h | 9 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 5 + drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 17 +- drivers/gpu/drm/msm/dp/dp_ctrl.c | 134 +++++++---- drivers/gpu/drm/msm/dp/dp_panel.c | 9 +- drivers/gpu/drm/msm/dsi/dsi_cfg.c | 1 - drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 2 +- drivers/gpu/drm/omapdrm/omap_plane.c | 3 + drivers/gpu/drm/panfrost/panfrost_device.h | 8 +- drivers/gpu/drm/panfrost/panfrost_drv.c | 50 +--- drivers/gpu/drm/panfrost/panfrost_gem.c | 20 +- drivers/gpu/drm/panfrost/panfrost_job.c | 4 +- drivers/gpu/drm/panfrost/panfrost_mmu.c | 191 +++++++++------ drivers/gpu/drm/panfrost/panfrost_mmu.h | 5 +- drivers/gpu/drm/panfrost/panfrost_regs.h | 2 + drivers/gpu/drm/rcar-du/rcar_du_drv.c | 8 + drivers/gpu/drm/vc4/vc4_hdmi.c | 4 +- drivers/gpu/drm/vkms/vkms_plane.c | 38 +-- drivers/gpu/drm/vmwgfx/ttm_memory.c | 2 + drivers/gpu/drm/vmwgfx/vmwgfx_binding.c | 20 +- drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 2 + drivers/gpu/drm/vmwgfx/vmwgfx_mob.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 6 +- drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 8 +- drivers/gpu/drm/vmwgfx/vmwgfx_so.c | 3 +- drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 9 +- drivers/gpu/drm/vmwgfx/vmwgfx_validation.c | 4 +- drivers/gpu/drm/xlnx/zynqmp_disp.c | 3 +- drivers/gpu/drm/xlnx/zynqmp_dp.c | 22 +- drivers/hid/Makefile | 1 - drivers/hid/amd-sfh-hid/amd_sfh_client.c | 2 +- drivers/hid/hid-input.c | 2 - drivers/hid/hid-quirks.c | 2 - drivers/hid/i2c-hid/i2c-hid-core.c | 5 +- drivers/hwmon/pmbus/ibm-cffps.c | 6 +- drivers/iio/dac/ad5624r_spi.c | 18 +- drivers/iio/temperature/ltc2983.c | 30 ++- drivers/infiniband/core/iwcm.c | 19 +- drivers/infiniband/hw/efa/efa_verbs.c | 1 - drivers/infiniband/hw/hfi1/init.c | 7 +- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 4 +- drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 2 +- drivers/infiniband/hw/hns/hns_roce_mr.c | 4 +- drivers/infiniband/hw/hns/hns_roce_qp.c | 11 +- drivers/infiniband/hw/mlx5/qp.c | 3 - drivers/input/mouse/elan_i2c.h | 3 +- drivers/input/mouse/elan_i2c_core.c | 1 + drivers/iommu/intel/pasid.h | 10 +- drivers/mailbox/mtk-cmdq-mailbox.c | 3 +- drivers/md/dm-crypt.c | 7 +- drivers/media/cec/platform/stm32/stm32-cec.c | 26 +- drivers/media/cec/platform/tegra/tegra_cec.c | 10 +- drivers/media/dvb-frontends/dib8000.c | 58 +++-- drivers/media/i2c/imx258.c | 4 +- drivers/media/i2c/tda1997x.c | 5 +- drivers/media/platform/ti-vpe/cal-camerarx.c | 4 +- drivers/media/platform/ti-vpe/cal-video.c | 2 +- drivers/media/rc/rc-loopback.c | 2 +- drivers/media/usb/uvc/uvc_v4l2.c | 34 ++- drivers/media/v4l2-core/v4l2-dv-timings.c | 4 +- drivers/misc/pvpanic/pvpanic-pci.c | 2 + drivers/misc/vmw_vmci/vmci_queue_pair.c | 6 +- drivers/mmc/core/block.c | 3 +- drivers/mmc/host/rtsx_pci_sdmmc.c | 36 ++- drivers/mmc/host/sdhci-of-arasan.c | 36 ++- drivers/mtd/nand/raw/intel-nand-controller.c | 27 ++- drivers/net/bonding/bond_main.c | 3 +- drivers/net/dsa/lantiq_gswip.c | 3 +- .../net/ethernet/freescale/dpaa2/dpaa2-switch.c | 6 - .../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 9 +- drivers/net/ethernet/intel/iavf/iavf.h | 9 +- drivers/net/ethernet/intel/iavf/iavf_ethtool.c | 10 +- drivers/net/ethernet/intel/iavf/iavf_main.c | 122 ++++++---- drivers/net/ethernet/intel/igc/igc_main.c | 9 +- .../ethernet/marvell/octeontx2/nic/otx2_common.c | 15 ++ drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 8 +- .../ethernet/mellanox/mlx5/core/steering/dr_rule.c | 2 +- .../ethernet/mellanox/mlx5/core/steering/dr_send.c | 1 + .../net/ethernet/netronome/nfp/nfp_net_common.c | 2 +- .../net/ethernet/stmicro/stmmac/dwmac-ipq806x.c | 18 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 10 +- drivers/net/ethernet/wiznet/w5100.c | 2 + drivers/net/ipa/ipa_cmd.c | 38 ++- drivers/net/ipa/ipa_cmd.h | 15 +- drivers/net/ipa/ipa_data-v4.11.c | 13 +- drivers/net/ipa/ipa_data-v4.9.c | 9 +- drivers/net/ipa/ipa_table.c | 2 +- drivers/net/phy/dp83822.c | 8 +- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 3 +- drivers/net/wireless/ath/ath9k/hw.c | 12 +- drivers/net/wireless/ath/wcn36xx/main.c | 5 +- drivers/net/wireless/ath/wcn36xx/txrx.c | 4 + drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 1 + drivers/net/wireless/intel/iwlwifi/fw/api/scan.h | 6 +- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 4 +- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 8 +- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 24 +- drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 11 +- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 30 ++- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 5 +- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 3 + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 2 + .../net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 33 ++- drivers/net/wireless/realtek/rtw88/Makefile | 2 +- drivers/net/wireless/realtek/rtw88/fw.c | 8 +- drivers/net/wireless/realtek/rtw88/fw.h | 1 + drivers/net/wireless/realtek/rtw88/wow.c | 21 +- drivers/nvdimm/pmem.c | 4 +- drivers/nvme/host/core.c | 3 +- drivers/nvme/host/nvme.h | 47 +++- drivers/nvme/host/pci.c | 2 +- drivers/nvme/host/rdma.c | 4 +- drivers/nvme/host/tcp.c | 38 ++- drivers/nvme/target/loop.c | 4 +- drivers/nvmem/core.c | 7 +- drivers/nvmem/qfprom.c | 6 +- drivers/of/kobj.c | 2 +- drivers/opp/of.c | 12 +- drivers/parport/ieee1284_ops.c | 2 +- drivers/pci/controller/pci-aardvark.c | 268 ++++++++++++++++++++- drivers/pci/controller/pcie-xilinx-nwl.c | 12 + drivers/pci/msi.c | 3 + drivers/pci/pci.c | 6 +- drivers/pci/pcie/portdrv_core.c | 9 +- drivers/pci/quirks.c | 1 + drivers/pci/syscall.c | 4 +- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 16 +- drivers/pinctrl/pinctrl-ingenic.c | 12 +- drivers/pinctrl/pinctrl-single.c | 1 + drivers/pinctrl/pinctrl-stmfx.c | 6 +- drivers/pinctrl/samsung/pinctrl-samsung.c | 2 +- drivers/platform/chrome/cros_ec_proto.c | 9 + drivers/platform/x86/dell/dell-smbios-wmi.c | 1 + drivers/power/supply/max17042_battery.c | 6 +- drivers/rtc/rtc-tps65910.c | 2 +- drivers/s390/cio/qdio_main.c | 82 ++++--- drivers/scsi/BusLogic.c | 6 +- drivers/scsi/pcmcia/fdomain_cs.c | 4 +- drivers/scsi/qedf/qedf_main.c | 10 +- drivers/scsi/qedi/qedi_main.c | 14 +- drivers/scsi/qla2xxx/qla_nvme.c | 5 +- drivers/scsi/qla2xxx/qla_os.c | 6 + drivers/scsi/smartpqi/smartpqi_init.c | 1 + drivers/scsi/ufs/ufs-exynos.c | 4 +- drivers/scsi/ufs/ufs-exynos.h | 2 +- drivers/scsi/ufs/ufshcd.c | 8 +- drivers/soc/aspeed/aspeed-lpc-ctrl.c | 2 +- drivers/soc/aspeed/aspeed-p2a-ctrl.c | 2 +- drivers/soc/mediatek/mtk-mmsys.h | 4 + drivers/soc/qcom/qcom_aoss.c | 8 +- drivers/soundwire/intel.c | 23 +- drivers/spi/spi-fsi.c | 125 ++-------- drivers/staging/board/board.c | 7 +- .../hikey9xx/hisilicon,hi6421-spmi-pmic.yaml | 6 +- drivers/staging/ks7010/ks7010_sdio.c | 2 +- drivers/staging/media/atomisp/pci/atomisp_v4l2.c | 4 +- drivers/staging/media/hantro/hantro_g1_vp8_dec.c | 13 +- .../staging/media/hantro/rk3399_vpu_hw_vp8_dec.c | 13 +- drivers/staging/media/imx/imx7-media-csi.c | 15 +- drivers/staging/rtl8723bs/hal/hal_com_phycfg.c | 2 +- drivers/staging/rts5208/rtsx_scsi.c | 10 +- drivers/thunderbolt/switch.c | 2 +- drivers/tty/hvc/hvsi.c | 19 +- drivers/tty/serial/8250/8250_omap.c | 25 +- drivers/tty/serial/8250/8250_pci.c | 2 +- drivers/tty/serial/8250/8250_port.c | 3 +- drivers/tty/serial/jsm/jsm_neo.c | 2 + drivers/tty/serial/jsm/jsm_tty.c | 3 + drivers/tty/serial/sh-sci.c | 7 +- drivers/usb/chipidea/host.c | 14 +- drivers/usb/dwc3/dwc3-imx8mp.c | 14 +- drivers/usb/gadget/composite.c | 8 +- drivers/usb/gadget/function/u_ether.c | 5 +- drivers/usb/host/ehci-mv.c | 23 +- drivers/usb/host/fotg210-hcd.c | 41 ++-- drivers/usb/host/fotg210.h | 5 - drivers/usb/host/xhci-mtk.c | 2 +- drivers/usb/host/xhci.c | 24 +- drivers/usb/musb/musb_dsps.c | 13 +- drivers/usb/usbip/vhci_hcd.c | 32 ++- drivers/vfio/Kconfig | 2 +- drivers/video/fbdev/asiliantfb.c | 3 + drivers/video/fbdev/kyro/fbdev.c | 8 + drivers/video/fbdev/riva/fbdev.c | 3 + fs/btrfs/block-group.c | 2 +- fs/btrfs/disk-io.c | 48 ++-- fs/btrfs/free-space-cache.c | 7 +- fs/btrfs/inode.c | 26 +- fs/btrfs/ordered-data.c | 8 + fs/btrfs/space-info.c | 42 +++- fs/btrfs/tree-log.c | 4 +- fs/btrfs/volumes.c | 3 + fs/ceph/caps.c | 3 + fs/cifs/sess.c | 2 +- fs/f2fs/checkpoint.c | 4 +- fs/f2fs/compress.c | 190 +++++++++++++-- fs/f2fs/data.c | 122 +++++++--- fs/f2fs/debug.c | 13 + fs/f2fs/dir.c | 22 +- fs/f2fs/f2fs.h | 173 +++++++++++-- fs/f2fs/file.c | 4 +- fs/f2fs/gc.c | 11 +- fs/f2fs/inline.c | 4 +- fs/f2fs/inode.c | 23 +- fs/f2fs/node.c | 24 +- fs/f2fs/node.h | 30 +-- fs/f2fs/segment.c | 25 +- fs/f2fs/super.c | 148 ++++++++---- fs/fscache/cookie.c | 14 +- fs/fscache/internal.h | 2 + fs/fscache/main.c | 39 +++ fs/gfs2/glops.c | 17 +- fs/gfs2/lock_dlm.c | 5 + fs/io-wq.c | 50 ++-- fs/io_uring.c | 65 ++--- fs/iomap/buffered-io.c | 2 +- fs/lockd/svclock.c | 30 +-- fs/nfs/export.c | 2 +- fs/nfs/pnfs.c | 16 +- fs/nfsd/nfs4state.c | 13 +- fs/overlayfs/dir.c | 6 +- fs/userfaultfd.c | 91 ++++--- include/crypto/public_key.h | 4 +- include/drm/drm_auth.h | 1 + include/drm/drm_file.h | 18 +- include/kvm/arm_vgic.h | 28 ++- include/linux/ethtool.h | 4 - include/linux/exportfs.h | 2 + include/linux/f2fs_fs.h | 1 + include/linux/hugetlb.h | 9 + include/linux/hugetlb_cgroup.h | 12 + include/linux/intel-iommu.h | 6 +- include/linux/memory_hotplug.h | 4 +- include/linux/rcupdate.h | 2 +- include/linux/rtmutex.h | 19 +- include/linux/sunrpc/xprt.h | 1 + include/linux/sunrpc/xprtsock.h | 1 + include/net/bluetooth/hci_core.h | 4 + include/net/flow_offload.h | 1 + include/uapi/linux/serial_reg.h | 1 + kernel/dma/debug.c | 7 +- kernel/fork.c | 1 + kernel/locking/rtmutex.c | 2 +- kernel/pid_namespace.c | 3 +- kernel/printk/printk.c | 7 +- kernel/rcu/tree_plugin.h | 8 +- kernel/sched/cpufreq_schedutil.c | 16 +- kernel/workqueue.c | 12 +- lib/test_bpf.c | 13 +- lib/test_stackinit.c | 20 +- mm/hmm.c | 5 +- mm/hugetlb.c | 4 +- mm/memory_hotplug.c | 4 +- mm/vmscan.c | 2 +- net/9p/trans_xen.c | 4 +- net/bluetooth/hci_event.c | 140 ++++++++--- net/bluetooth/hci_request.c | 81 +++---- net/bluetooth/sco.c | 74 +++--- net/core/flow_dissector.c | 12 +- net/core/flow_offload.c | 89 ++++++- net/ethtool/ioctl.c | 136 +++++++++-- net/ipv4/ip_output.c | 5 +- net/ipv4/tcp_fastopen.c | 3 +- net/mac80211/iface.c | 11 +- net/netfilter/nf_flow_table_offload.c | 1 + net/netfilter/nf_tables_offload.c | 1 + net/netfilter/nft_compat.c | 8 +- net/netlabel/netlabel_cipso_v4.c | 4 +- net/netlink/af_netlink.c | 4 +- net/sched/cls_api.c | 1 + net/sched/sch_taprio.c | 4 +- net/socket.c | 125 +--------- net/sunrpc/auth_gss/svcauth_gss.c | 2 +- net/sunrpc/xprt.c | 8 +- net/sunrpc/xprtrdma/transport.c | 11 +- net/sunrpc/xprtrdma/verbs.c | 10 +- net/sunrpc/xprtsock.c | 7 + net/tipc/socket.c | 36 ++- samples/bpf/test_override_return.sh | 1 + samples/bpf/tracex7_user.c | 5 + .../pktgen/pktgen_sample03_burst_single_flow.sh | 6 +- scripts/gen_ksymdeps.sh | 8 +- scripts/subarch.include | 2 +- security/smack/smack_access.c | 17 +- sound/soc/atmel/Kconfig | 1 - sound/soc/intel/boards/bytcr_rt5640.c | 9 +- sound/soc/intel/boards/sof_pcm512x.c | 13 +- sound/soc/intel/skylake/skl-messages.c | 11 +- sound/soc/intel/skylake/skl-pcm.c | 25 +- sound/soc/rockchip/rockchip_i2s.c | 35 ++- sound/soc/soc-pcm.c | 103 ++++++-- sound/soc/ti/davinci-mcasp.c | 150 ++++++++++-- tools/lib/bpf/libbpf.c | 63 ++++- .../testing/selftests/arm64/mte/mte_common_util.c | 2 +- tools/testing/selftests/arm64/pauth/pac.c | 10 +- .../testing/selftests/bpf/prog_tests/send_signal.c | 16 ++ .../selftests/bpf/prog_tests/sockopt_inherit.c | 4 +- tools/testing/selftests/bpf/progs/xdp_tx.c | 2 +- tools/testing/selftests/bpf/test_maps.c | 2 +- tools/testing/selftests/bpf/test_progs.c | 25 +- tools/testing/selftests/bpf/test_xdp_veth.sh | 2 +- tools/testing/selftests/firmware/fw_namespace.c | 3 +- tools/testing/selftests/ftrace/test.d/functions | 2 +- tools/testing/selftests/nci/nci_dev.c | 6 +- tools/thermal/tmon/Makefile | 2 +- 426 files changed, 4644 insertions(+), 2448 deletions(-)
From: Dmitry Osipenko digetx@gmail.com
commit 8d448fa0a8bb1c8d94eef7647edffe9ac81a281e upstream.
The TPS65910 RTC driver module doesn't auto-load because of the wrong module alias that doesn't match the device name, fix it.
Cc: stable@vger.kernel.org Reported-by: Anton Bambura jenneron@protonmail.com Tested-by: Anton Bambura jenneron@protonmail.com Signed-off-by: Dmitry Osipenko digetx@gmail.com Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Link: https://lore.kernel.org/r/20210808160030.8556-1-digetx@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/rtc/rtc-tps65910.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/rtc/rtc-tps65910.c +++ b/drivers/rtc/rtc-tps65910.c @@ -467,6 +467,6 @@ static struct platform_driver tps65910_r };
module_platform_driver(tps65910_rtc_driver); -MODULE_ALIAS("platform:rtc-tps65910"); +MODULE_ALIAS("platform:tps65910-rtc"); MODULE_AUTHOR("Venu Byravarasu vbyravarasu@nvidia.com"); MODULE_LICENSE("GPL");
From: Josef Bacik josef@toxicpanda.com
commit ac98141d140444fe93e26471d3074c603b70e2ca upstream.
We use the async_delalloc_pages mechanism to make sure that we've completed our async work before trying to continue our delalloc flushing. The reason for this is we need to see any ordered extents that were created by our delalloc flushing. However we're waking up before we do the submit work, which is before we create the ordered extents. This is a pretty wide race window where we could potentially think there are no ordered extents and thus exit shrink_delalloc prematurely. Fix this by waking us up after we've done the work to create ordered extents.
CC: stable@vger.kernel.org # 5.4+ Reviewed-by: Nikolay Borisov nborisov@suse.com Signed-off-by: Josef Bacik josef@toxicpanda.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/inode.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
--- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -1248,11 +1248,6 @@ static noinline void async_cow_submit(st nr_pages = (async_chunk->end - async_chunk->start + PAGE_SIZE) >> PAGE_SHIFT;
- /* atomic_sub_return implies a barrier */ - if (atomic_sub_return(nr_pages, &fs_info->async_delalloc_pages) < - 5 * SZ_1M) - cond_wake_up_nomb(&fs_info->async_submit_wait); - /* * ->inode could be NULL if async_chunk_start has failed to compress, * in which case we don't have anything to submit, yet we need to @@ -1261,6 +1256,11 @@ static noinline void async_cow_submit(st */ if (async_chunk->inode) submit_compressed_extents(async_chunk); + + /* atomic_sub_return implies a barrier */ + if (atomic_sub_return(nr_pages, &fs_info->async_delalloc_pages) < + 5 * SZ_1M) + cond_wake_up_nomb(&fs_info->async_submit_wait); }
static noinline void async_cow_free(struct btrfs_work *work)
From: Josef Bacik josef@toxicpanda.com
commit e16460707e94c3d4c1b5418cb68b28b8efa903b2 upstream.
I've been debugging an early ENOSPC problem in production and finally root caused it to this problem. When we switched to the per-inode in 38d715f494f2 ("btrfs: use btrfs_start_delalloc_roots in shrink_delalloc") I pulled out the async extent handling, because we were doing the correct thing by calling filemap_flush() if we had async extents set. This would properly wait on any async extents by locking the page in the second flush, thus making sure our ordered extents were properly set up.
However when I switched us back to page based flushing, I used sync_inode(), which allows us to pass in our own wbc. The problem here is that sync_inode() is smarter than the filemap_* helpers, it tries to avoid calling writepages at all. This means that our second call could skip calling do_writepages altogether, and thus not wait on the pagelock for the async helpers. This means we could come back before any ordered extents were created and then simply continue on in our flushing mechanisms and ENOSPC out when we have plenty of space to use.
Fix this by putting back the async pages logic in shrink_delalloc. This allows us to bulk write out everything that we need to, and then we can wait in one place for the async helpers to catch up, and then wait on any ordered extents that are created.
Fixes: e076ab2a2ca7 ("btrfs: shrink delalloc pages instead of full inodes") CC: stable@vger.kernel.org # 5.10+ Reviewed-by: Nikolay Borisov nborisov@suse.com Signed-off-by: Josef Bacik josef@toxicpanda.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/inode.c | 4 ---- fs/btrfs/space-info.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-)
--- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -9774,10 +9774,6 @@ static int start_delalloc_inodes(struct &work->work); } else { ret = sync_inode(inode, wbc); - if (!ret && - test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, - &BTRFS_I(inode)->runtime_flags)) - ret = sync_inode(inode, wbc); btrfs_add_delayed_iput(inode); if (ret || wbc->nr_to_write <= 0) goto out; --- a/fs/btrfs/space-info.c +++ b/fs/btrfs/space-info.c @@ -539,9 +539,49 @@ static void shrink_delalloc(struct btrfs while ((delalloc_bytes || ordered_bytes) && loops < 3) { u64 temp = min(delalloc_bytes, to_reclaim) >> PAGE_SHIFT; long nr_pages = min_t(u64, temp, LONG_MAX); + int async_pages;
btrfs_start_delalloc_roots(fs_info, nr_pages, true);
+ /* + * We need to make sure any outstanding async pages are now + * processed before we continue. This is because things like + * sync_inode() try to be smart and skip writing if the inode is + * marked clean. We don't use filemap_fwrite for flushing + * because we want to control how many pages we write out at a + * time, thus this is the only safe way to make sure we've + * waited for outstanding compressed workers to have started + * their jobs and thus have ordered extents set up properly. + * + * This exists because we do not want to wait for each + * individual inode to finish its async work, we simply want to + * start the IO on everybody, and then come back here and wait + * for all of the async work to catch up. Once we're done with + * that we know we'll have ordered extents for everything and we + * can decide if we wait for that or not. + * + * If we choose to replace this in the future, make absolutely + * sure that the proper waiting is being done in the async case, + * as there have been bugs in that area before. + */ + async_pages = atomic_read(&fs_info->async_delalloc_pages); + if (!async_pages) + goto skip_async; + + /* + * We don't want to wait forever, if we wrote less pages in this + * loop than we have outstanding, only wait for that number of + * pages, otherwise we can wait for all async pages to finish + * before continuing. + */ + if (async_pages > nr_pages) + async_pages -= nr_pages; + else + async_pages = 0; + wait_event(fs_info->async_submit_wait, + atomic_read(&fs_info->async_delalloc_pages) <= + async_pages); +skip_async: loops++; if (wait_ordered && !trans) { btrfs_wait_ordered_roots(fs_info, items, 0, (u64)-1);
From: Josef Bacik josef@toxicpanda.com
commit 93c60b17f2b5fca2c5931d7944788d1ef5f25528 upstream.
The preemptive flushing code was added in order to avoid needing to synchronously wait for ENOSPC flushing to recover space. Once we're almost full however we can essentially flush constantly. We were using 98% as a threshold to determine if we were simply full, however in practice this is a really high bar to hit. For example reports of systems running into this problem had around 94% usage and thus continued to flush. Fix this by lowering the threshold to 90%, which is a more sane value, especially for smaller file systems.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=212185 CC: stable@vger.kernel.org # 5.12+ Fixes: 576fa34830af ("btrfs: improve preemptive background space flushing") Signed-off-by: Josef Bacik josef@toxicpanda.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/space-info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/btrfs/space-info.c +++ b/fs/btrfs/space-info.c @@ -833,7 +833,7 @@ static bool need_preemptive_reclaim(stru struct btrfs_space_info *space_info) { u64 ordered, delalloc; - u64 thresh = div_factor_fine(space_info->total_bytes, 98); + u64 thresh = div_factor_fine(space_info->total_bytes, 90); u64 used;
/* If we're just plain full then async reclaim just slows us down. */
From: Naohiro Aota naohiro.aota@wdc.com
commit 0ae79c6fe70d5c5c645733b7ed39d5e6021d8c9a upstream.
alloc_offset is offset from the start of a block group and @offset is actually an address in logical space. Thus, we need to consider block_group->start when calculating them.
Fixes: 011b41bffa3d ("btrfs: zoned: advance allocation pointer after tree log node") CC: stable@vger.kernel.org # 5.12+ Signed-off-by: Naohiro Aota naohiro.aota@wdc.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/free-space-cache.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
--- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -2652,8 +2652,11 @@ int btrfs_remove_free_space(struct btrfs * btrfs_pin_extent_for_log_replay() when replaying the log. * Advance the pointer not to overwrite the tree-log nodes. */ - if (block_group->alloc_offset < offset + bytes) - block_group->alloc_offset = offset + bytes; + if (block_group->start + block_group->alloc_offset < + offset + bytes) { + block_group->alloc_offset = + offset + bytes - block_group->start; + } return 0; }
From: Naohiro Aota naohiro.aota@wdc.com
commit ba86dd9fe60e5853fbff96f2658212908b83f271 upstream.
btrfs_relocate_chunk() can fail with -EAGAIN when e.g. send operations are running. The message can fail btrfs/187 and it's unnecessary because we anyway add it back to the reclaim list.
btrfs_reclaim_bgs_work() `-> btrfs_relocate_chunk() `-> btrfs_relocate_block_group() `-> reloc_chunk_start() `-> if (fs_info->send_in_progress) `-> return -EAGAIN
CC: stable@vger.kernel.org # 5.13+ Fixes: 18bb8bbf13c1 ("btrfs: zoned: automatically reclaim zones") Reviewed-by: Johannes Thumshirn johannes.thumshirn@wdc.com Signed-off-by: Naohiro Aota naohiro.aota@wdc.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/block-group.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/btrfs/block-group.c +++ b/fs/btrfs/block-group.c @@ -1550,7 +1550,7 @@ void btrfs_reclaim_bgs_work(struct work_ bg->start, div64_u64(bg->used * 100, bg->length)); trace_btrfs_reclaim_block_group(bg); ret = btrfs_relocate_chunk(fs_info, bg->start); - if (ret) + if (ret && ret != -EAGAIN) btrfs_err(fs_info, "error relocating chunk %llu", bg->start);
From: Anand Jain anand.jain@oracle.com
commit 6f93e834fa7c5faa0372e46828b4b2a966ac61d7 upstream.
The mount option max_inline ranges from 0 to the sectorsize (which is now equal to page size). But we parse the mount options too early and before the actual sectorsize is read from the superblock. So the upper limit of max_inline is unaware of the actual sectorsize and is limited by the temporary sectorsize 4096, even on a system where the default sectorsize is 64K.
Fix this by reading the superblock sectorsize before the mount option parse.
Reported-by: Alexander Tsvetkov alexander.tsvetkov@oracle.com CC: stable@vger.kernel.org # 5.4+ Signed-off-by: Anand Jain anand.jain@oracle.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/disk-io.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-)
--- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -3329,6 +3329,30 @@ int __cold open_ctree(struct super_block */ fs_info->compress_type = BTRFS_COMPRESS_ZLIB;
+ /* + * Flag our filesystem as having big metadata blocks if they are bigger + * than the page size. + */ + if (btrfs_super_nodesize(disk_super) > PAGE_SIZE) { + if (!(features & BTRFS_FEATURE_INCOMPAT_BIG_METADATA)) + btrfs_info(fs_info, + "flagging fs with big metadata feature"); + features |= BTRFS_FEATURE_INCOMPAT_BIG_METADATA; + } + + /* Set up fs_info before parsing mount options */ + nodesize = btrfs_super_nodesize(disk_super); + sectorsize = btrfs_super_sectorsize(disk_super); + stripesize = sectorsize; + fs_info->dirty_metadata_batch = nodesize * (1 + ilog2(nr_cpu_ids)); + fs_info->delalloc_batch = sectorsize * 512 * (1 + ilog2(nr_cpu_ids)); + + fs_info->nodesize = nodesize; + fs_info->sectorsize = sectorsize; + fs_info->sectorsize_bits = ilog2(sectorsize); + fs_info->csums_per_leaf = BTRFS_MAX_ITEM_SIZE(fs_info) / fs_info->csum_size; + fs_info->stripesize = stripesize; + ret = btrfs_parse_options(fs_info, options, sb->s_flags); if (ret) { err = ret; @@ -3356,30 +3380,6 @@ int __cold open_ctree(struct super_block btrfs_info(fs_info, "has skinny extents");
/* - * flag our filesystem as having big metadata blocks if - * they are bigger than the page size - */ - if (btrfs_super_nodesize(disk_super) > PAGE_SIZE) { - if (!(features & BTRFS_FEATURE_INCOMPAT_BIG_METADATA)) - btrfs_info(fs_info, - "flagging fs with big metadata feature"); - features |= BTRFS_FEATURE_INCOMPAT_BIG_METADATA; - } - - nodesize = btrfs_super_nodesize(disk_super); - sectorsize = btrfs_super_sectorsize(disk_super); - stripesize = sectorsize; - fs_info->dirty_metadata_batch = nodesize * (1 + ilog2(nr_cpu_ids)); - fs_info->delalloc_batch = sectorsize * 512 * (1 + ilog2(nr_cpu_ids)); - - /* Cache block sizes */ - fs_info->nodesize = nodesize; - fs_info->sectorsize = sectorsize; - fs_info->sectorsize_bits = ilog2(sectorsize); - fs_info->csums_per_leaf = BTRFS_MAX_ITEM_SIZE(fs_info) / fs_info->csum_size; - fs_info->stripesize = stripesize; - - /* * mixed block groups end up with duplicate but slightly offset * extent buffers for the same range. It leads to corruptions */
From: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com
commit 0d977e0eba234e01a60bdde27314dc21374201b3 upstream.
This crash was observed with a failed assertion on device close:
BTRFS: Transaction aborted (error -28) WARNING: CPU: 1 PID: 3902 at fs/btrfs/extent-tree.c:2150 btrfs_run_delayed_refs+0x1d2/0x1e0 [btrfs] Modules linked in: btrfs blake2b_generic libcrc32c crc32c_intel xor zstd_decompress zstd_compress xxhash lzo_compress lzo_decompress raid6_pq loop CPU: 1 PID: 3902 Comm: kworker/u8:4 Not tainted 5.14.0-rc5-default+ #1532 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-59-gc9ba527-rebuilt.opensuse.org 04/01/2014 Workqueue: events_unbound btrfs_async_reclaim_metadata_space [btrfs] RIP: 0010:btrfs_run_delayed_refs+0x1d2/0x1e0 [btrfs] RSP: 0018:ffffb7a5452d7d80 EFLAGS: 00010282 RAX: 0000000000000000 RBX: 0000000000000003 RCX: 0000000000000000 RDX: 0000000000000001 RSI: ffffffffabee13c4 RDI: 00000000ffffffff RBP: ffff97834176a378 R08: 0000000000000001 R09: 0000000000000001 R10: 0000000000000000 R11: 0000000000000001 R12: ffff97835195d388 R13: 0000000005b08000 R14: ffff978385484000 R15: 000000000000016c FS: 0000000000000000(0000) GS:ffff9783bd800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000056190d003fe8 CR3: 000000002a81e005 CR4: 0000000000170ea0 Call Trace: flush_space+0x197/0x2f0 [btrfs] btrfs_async_reclaim_metadata_space+0x139/0x300 [btrfs] process_one_work+0x262/0x5e0 worker_thread+0x4c/0x320 ? process_one_work+0x5e0/0x5e0 kthread+0x144/0x170 ? set_kthread_struct+0x40/0x40 ret_from_fork+0x1f/0x30 irq event stamp: 19334989 hardirqs last enabled at (19334997): [<ffffffffab0e0c87>] console_unlock+0x2b7/0x400 hardirqs last disabled at (19335006): [<ffffffffab0e0d0d>] console_unlock+0x33d/0x400 softirqs last enabled at (19334900): [<ffffffffaba0030d>] __do_softirq+0x30d/0x574 softirqs last disabled at (19334893): [<ffffffffab0721ec>] irq_exit_rcu+0x12c/0x140 ---[ end trace 45939e308e0dd3c7 ]--- BTRFS: error (device vdd) in btrfs_run_delayed_refs:2150: errno=-28 No space left BTRFS info (device vdd): forced readonly BTRFS warning (device vdd): failed setting block group ro: -30 BTRFS info (device vdd): suspending dev_replace for unmount assertion failed: !test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state), in fs/btrfs/volumes.c:1150 ------------[ cut here ]------------ kernel BUG at fs/btrfs/ctree.h:3431! invalid opcode: 0000 [#1] PREEMPT SMP CPU: 1 PID: 3982 Comm: umount Tainted: G W 5.14.0-rc5-default+ #1532 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-59-gc9ba527-rebuilt.opensuse.org 04/01/2014 RIP: 0010:assertfail.constprop.0+0x18/0x1a [btrfs] RSP: 0018:ffffb7a5454c7db8 EFLAGS: 00010246 RAX: 0000000000000068 RBX: ffff978364b91c00 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffffffffabee13c4 RDI: 00000000ffffffff RBP: ffff9783523a4c00 R08: 0000000000000001 R09: 0000000000000001 R10: 0000000000000000 R11: 0000000000000001 R12: ffff9783523a4d18 R13: 0000000000000000 R14: 0000000000000004 R15: 0000000000000003 FS: 00007f61c8f42800(0000) GS:ffff9783bd800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000056190cffa810 CR3: 0000000030b96002 CR4: 0000000000170ea0 Call Trace: btrfs_close_one_device.cold+0x11/0x55 [btrfs] close_fs_devices+0x44/0xb0 [btrfs] btrfs_close_devices+0x48/0x160 [btrfs] generic_shutdown_super+0x69/0x100 kill_anon_super+0x14/0x30 btrfs_kill_super+0x12/0x20 [btrfs] deactivate_locked_super+0x2c/0xa0 cleanup_mnt+0x144/0x1b0 task_work_run+0x59/0xa0 exit_to_user_mode_loop+0xe7/0xf0 exit_to_user_mode_prepare+0xaf/0xf0 syscall_exit_to_user_mode+0x19/0x50 do_syscall_64+0x4a/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae
This happens when close_ctree is called while a dev_replace hasn't completed. In close_ctree, we suspend the dev_replace, but keep the replace target around so that we can resume the dev_replace procedure when we mount the root again. This is the call trace:
close_ctree(): btrfs_dev_replace_suspend_for_unmount(); btrfs_close_devices(): btrfs_close_fs_devices(): btrfs_close_one_device(): ASSERT(!test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state));
However, since the replace target sticks around, there is a device with BTRFS_DEV_STATE_REPLACE_TGT set on close, and we fail the assertion in btrfs_close_one_device.
To fix this, if we come across the replace target device when closing, we should properly reset it back to allocation state. This fix also ensures that if a non-target device has a corrupted state and has the BTRFS_DEV_STATE_REPLACE_TGT bit set, the assertion will still catch the error.
Reported-by: David Sterba dsterba@suse.com Fixes: b2a616676839 ("btrfs: fix rw device counting in __btrfs_free_extra_devids") CC: stable@vger.kernel.org # 4.19+ Reviewed-by: Anand Jain anand.jain@oracle.com Signed-off-by: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/volumes.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -1130,6 +1130,9 @@ static void btrfs_close_one_device(struc fs_devices->rw_devices--; }
+ if (device->devid == BTRFS_DEV_REPLACE_DEVID) + clear_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state); + if (test_bit(BTRFS_DEV_STATE_MISSING, &device->dev_state)) fs_devices->missing_devices--;
From: Naohiro Aota naohiro.aota@wdc.com
commit f79645df806565a03abb2847a1d20e6930b25e7e upstream.
btrfs_add_ordered_extent_*() add num_bytes to fs_info->ordered_bytes. Then, splitting an ordered extent will call btrfs_add_ordered_extent_*() again for split extents, leading to double counting of the region of a split extent. These leaked bytes are finally reported at unmount time as follow:
BTRFS info (device dm-1): at unmount dio bytes count 364544
Fix the double counting by subtracting split extent's size from fs_info->ordered_bytes.
Fixes: d22002fd37bd ("btrfs: zoned: split ordered extent when bio is sent") CC: stable@vger.kernel.org # 5.12+ Reviewed-by: Johannes Thumshirn johannes.thumshirn@wdc.com Signed-off-by: Naohiro Aota naohiro.aota@wdc.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/ordered-data.c | 8 ++++++++ 1 file changed, 8 insertions(+)
--- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -917,6 +917,7 @@ static int clone_ordered_extent(struct b u64 len) { struct inode *inode = ordered->inode; + struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info; u64 file_offset = ordered->file_offset + pos; u64 disk_bytenr = ordered->disk_bytenr + pos; u64 num_bytes = len; @@ -934,6 +935,13 @@ static int clone_ordered_extent(struct b else type = __ffs(flags_masked);
+ /* + * The splitting extent is already counted and will be added again + * in btrfs_add_ordered_extent_*(). Subtract num_bytes to avoid + * double counting. + */ + percpu_counter_add_batch(&fs_info->ordered_bytes, -num_bytes, + fs_info->delalloc_batch); if (test_bit(BTRFS_ORDERED_COMPRESSED, &ordered->flags)) { WARN_ON_ONCE(1); ret = btrfs_add_ordered_extent_compress(BTRFS_I(inode),
From: Niklas Cassel niklas.cassel@wdc.com
commit ead3b768bb51259e3a5f2287ff5fc9041eb6f450 upstream.
Zone management send operations (BLKRESETZONE, BLKOPENZONE, BLKCLOSEZONE and BLKFINISHZONE) should be allowed under the same permissions as write(). (write() does not require CAP_SYS_ADMIN).
Additionally, other ioctls like BLKSECDISCARD and BLKZEROOUT only check if the fd was successfully opened with FMODE_WRITE. (They do not require CAP_SYS_ADMIN).
Currently, zone management send operations require both CAP_SYS_ADMIN and that the fd was successfully opened with FMODE_WRITE.
Remove the CAP_SYS_ADMIN requirement, so that zone management send operations match the access control requirement of write(), BLKSECDISCARD and BLKZEROOUT.
Fixes: 3ed05a987e0f ("blk-zoned: implement ioctls") Signed-off-by: Niklas Cassel niklas.cassel@wdc.com Reviewed-by: Damien Le Moal damien.lemoal@wdc.com Reviewed-by: Aravind Ramesh aravind.ramesh@wdc.com Reviewed-by: Adam Manzanares a.manzanares@samsung.com Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Reviewed-by: Johannes Thumshirn johannes.thumshirn@wdc.com Cc: stable@vger.kernel.org # v4.10+ Link: https://lore.kernel.org/r/20210811110505.29649-2-Niklas.Cassel@wdc.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/blk-zoned.c | 3 --- 1 file changed, 3 deletions(-)
--- a/block/blk-zoned.c +++ b/block/blk-zoned.c @@ -349,9 +349,6 @@ int blkdev_zone_mgmt_ioctl(struct block_ if (!blk_queue_is_zoned(q)) return -ENOTTY;
- if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - if (!(mode & FMODE_WRITE)) return -EBADF;
From: Niklas Cassel niklas.cassel@wdc.com
commit 4d643b66089591b4769bcdb6fd1bfeff2fe301b8 upstream.
A user space process should not need the CAP_SYS_ADMIN capability set in order to perform a BLKREPORTZONE ioctl.
Getting the zone report is required in order to get the write pointer. Neither read() nor write() requires CAP_SYS_ADMIN, so it is reasonable that a user space process that can read/write from/to the device, also can get the write pointer. (Since e.g. writes have to be at the write pointer.)
Fixes: 3ed05a987e0f ("blk-zoned: implement ioctls") Signed-off-by: Niklas Cassel niklas.cassel@wdc.com Reviewed-by: Damien Le Moal damien.lemoal@wdc.com Reviewed-by: Aravind Ramesh aravind.ramesh@wdc.com Reviewed-by: Adam Manzanares a.manzanares@samsung.com Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Reviewed-by: Johannes Thumshirn johannes.thumshirn@wdc.com Cc: stable@vger.kernel.org # v4.10+ Link: https://lore.kernel.org/r/20210811110505.29649-3-Niklas.Cassel@wdc.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/blk-zoned.c | 3 --- 1 file changed, 3 deletions(-)
--- a/block/blk-zoned.c +++ b/block/blk-zoned.c @@ -288,9 +288,6 @@ int blkdev_report_zones_ioctl(struct blo if (!blk_queue_is_zoned(q)) return -ENOTTY;
- if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - if (copy_from_user(&rep, argp, sizeof(struct blk_zone_report))) return -EFAULT;
From: Marek Marczykowski-Górecki marmarek@invisiblethingslab.com
commit 1a519dc7a73c977547d8b5108d98c6e769c89f4b upstream.
When running as Xen PV guest, masking MSI-X is a responsibility of the hypervisor. The guest has no write access to the relevant BAR at all - when it tries to, it results in a crash like this:
BUG: unable to handle page fault for address: ffffc9004069100c #PF: supervisor write access in kernel mode #PF: error_code(0x0003) - permissions violation RIP: e030:__pci_enable_msix_range.part.0+0x26b/0x5f0 e1000e_set_interrupt_capability+0xbf/0xd0 [e1000e] e1000_probe+0x41f/0xdb0 [e1000e] local_pci_probe+0x42/0x80 (...)
The recently introduced function msix_mask_all() does not check the global variable pci_msi_ignore_mask which is set by XEN PV to bypass the masking of MSI[-X] interrupts.
Add the check to make this function XEN PV compatible.
Fixes: 7d5ec3d36123 ("PCI/MSI: Mask all unused MSI-X entries") Signed-off-by: Marek Marczykowski-Górecki marmarek@invisiblethingslab.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Acked-by: Bjorn Helgaas bhelgaas@google.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210826170342.135172-1-marmarek@invisiblethingsla... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/msi.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -776,6 +776,9 @@ static void msix_mask_all(void __iomem * u32 ctrl = PCI_MSIX_ENTRY_CTRL_MASKBIT; int i;
+ if (pci_msi_ignore_mask) + return; + for (i = 0; i < tsize; i++, base += PCI_MSIX_ENTRY_SIZE) writel(ctrl, base + PCI_MSIX_ENTRY_VECTOR_CTRL); }
From: Kajol Jain kjain@linux.ibm.com
commit f9addd85fbfacf0d155e83dbee8696d6df5ed0c7 upstream.
H_GetPerformanceCounterInfo (0xF080) hcall returns the counter data in the result buffer. Result buffer has specific format defined in the PAPR specification. One of the fields is counter offset and width of the counter data returned.
Counter data are returned in a unsigned char array in big endian byte order. To get the final counter data, the values must be left shifted byte at a time. But commit 220a0c609ad17 ("powerpc/perf: Add support for the hv gpci (get performance counter info) interface") made the shifting bitwise and also assumed little endian order. Because of that, hcall counters values are reported incorrectly.
In particular this can lead to counters go backwards which messes up the counter prev vs now calculation and leads to huge counter value reporting:
#: perf stat -e hv_gpci/system_tlbie_count_and_time_tlbie_instructions_issued/ -C 0 -I 1000 time counts unit events 1.000078854 18,446,744,073,709,535,232 hv_gpci/system_tlbie_count_and_time_tlbie_instructions_issued/ 2.000213293 0 hv_gpci/system_tlbie_count_and_time_tlbie_instructions_issued/ 3.000320107 0 hv_gpci/system_tlbie_count_and_time_tlbie_instructions_issued/ 4.000428392 0 hv_gpci/system_tlbie_count_and_time_tlbie_instructions_issued/ 5.000537864 0 hv_gpci/system_tlbie_count_and_time_tlbie_instructions_issued/ 6.000649087 0 hv_gpci/system_tlbie_count_and_time_tlbie_instructions_issued/ 7.000760312 0 hv_gpci/system_tlbie_count_and_time_tlbie_instructions_issued/ 8.000865218 16,448 hv_gpci/system_tlbie_count_and_time_tlbie_instructions_issued/ 9.000978985 18,446,744,073,709,535,232 hv_gpci/system_tlbie_count_and_time_tlbie_instructions_issued/ 10.001088891 16,384 hv_gpci/system_tlbie_count_and_time_tlbie_instructions_issued/ 11.001201435 0 hv_gpci/system_tlbie_count_and_time_tlbie_instructions_issued/ 12.001307937 18,446,744,073,709,535,232 hv_gpci/system_tlbie_count_and_time_tlbie_instructions_issued/
Fix the shifting logic to correct match the format, ie. read bytes in big endian order.
Fixes: e4f226b1580b ("powerpc/perf/hv-gpci: Increase request buffer size") Cc: stable@vger.kernel.org # v4.6+ Reported-by: Nageswara R Sastryrnsastry@linux.ibm.com Signed-off-by: Kajol Jain kjain@linux.ibm.com Tested-by: Nageswara R Sastryrnsastry@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20210813082158.429023-1-kjain@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/perf/hv-gpci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/powerpc/perf/hv-gpci.c +++ b/arch/powerpc/perf/hv-gpci.c @@ -175,7 +175,7 @@ static unsigned long single_gpci_request */ count = 0; for (i = offset; i < offset + length; i++) - count |= arg->bytes[i] << (i - offset); + count |= (u64)(arg->bytes[i]) << ((length - 1 - (i - offset)) * 8);
*value = count; out:
From: Juergen Gross jgross@suse.com
commit 4b511d5bfa74b1926daefd1694205c7f1bcf677f upstream.
Xen PV guests are specifying the highest used PFN via the max_pfn field in shared_info. This value is used by the Xen tools when saving or migrating the guest.
Unfortunately this field is misnamed, as in reality it is specifying the number of pages (including any memory holes) of the guest, so it is the highest used PFN + 1. Renaming isn't possible, as this is a public Xen hypervisor interface which needs to be kept stable.
The kernel will set the value correctly initially at boot time, but when adding more pages (e.g. due to memory hotplug or ballooning) a real PFN number is stored in max_pfn. This is done when expanding the p2m array, and the PFN stored there is even possibly wrong, as it should be the last possible PFN of the just added P2M frame, and not one which led to the P2M expansion.
Fix that by setting shared_info->max_pfn to the last possible PFN + 1.
Fixes: 98dd166ea3a3c3 ("x86/xen/p2m: hint at the last populated P2M entry") Cc: stable@vger.kernel.org Signed-off-by: Juergen Gross jgross@suse.com Reviewed-by: Jan Beulich jbeulich@suse.com Link: https://lore.kernel.org/r/20210730092622.9973-2-jgross@suse.com Signed-off-by: Juergen Gross jgross@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/xen/p2m.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c @@ -618,8 +618,8 @@ int xen_alloc_p2m_entry(unsigned long pf }
/* Expanded the p2m? */ - if (pfn > xen_p2m_last_pfn) { - xen_p2m_last_pfn = pfn; + if (pfn >= xen_p2m_last_pfn) { + xen_p2m_last_pfn = ALIGN(pfn + 1, P2M_PER_PAGE); HYPERVISOR_shared_info->arch.max_pfn = xen_p2m_last_pfn; }
From: Harshvardhan Jha harshvardhan.jha@oracle.com
commit 732b33d0dbf17e9483f0b50385bf606f724f50a2 upstream.
This patch addresses the following problems: - priv can never be NULL, so this part of the check is useless - if the loop ran through the whole list, priv->client is invalid and it is more appropriate and sufficient to check for the end of list_for_each_entry loop condition.
Link: http://lkml.kernel.org/r/20210727000709.225032-1-harshvardhan.jha@oracle.com Signed-off-by: Harshvardhan Jha harshvardhan.jha@oracle.com Reviewed-by: Stefano Stabellini sstabellini@kernel.org Tested-by: Stefano Stabellini sstabellini@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Dominique Martinet asmadeus@codewreck.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/9p/trans_xen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/net/9p/trans_xen.c +++ b/net/9p/trans_xen.c @@ -138,7 +138,7 @@ static bool p9_xen_write_todo(struct xen
static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req) { - struct xen_9pfs_front_priv *priv = NULL; + struct xen_9pfs_front_priv *priv; RING_IDX cons, prod, masked_cons, masked_prod; unsigned long flags; u32 size = p9_req->tc.size; @@ -151,7 +151,7 @@ static int p9_xen_request(struct p9_clie break; } read_unlock(&xen_9pfs_lock); - if (!priv || priv->client != client) + if (list_entry_is_head(priv, &xen_9pfs_devs, list)) return -EINVAL;
num = p9_req->tc.tag % priv->num_rings;
From: Colin Ian King colin.king@canonical.com
commit 05a444d3f90a3c3e6362e88a1bf13e1a60f8cace upstream.
Currently in the case where kmem_cache_alloc fails the null pointer cf is dereferenced when assigning cf->is_capsnap = false. Fix this by adding a null pointer check and return path.
Cc: stable@vger.kernel.org Addresses-Coverity: ("Dereference null return") Fixes: b2f9fa1f3bd8 ("ceph: correctly handle releasing an embedded cap flush") Signed-off-by: Colin Ian King colin.king@canonical.com Reviewed-by: Ilya Dryomov idryomov@gmail.com Signed-off-by: Ilya Dryomov idryomov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ceph/caps.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1756,6 +1756,9 @@ struct ceph_cap_flush *ceph_alloc_cap_fl struct ceph_cap_flush *cf;
cf = kmem_cache_alloc(ceph_cap_flush_cachep, GFP_KERNEL); + if (!cf) + return NULL; + cf->is_capsnap = false; return cf; }
From: jingle.wu jingle.wu@emc.com.tw
commit d198b8273e3006818ea287a93eb4d8fd2543e512 upstream.
Similar to controllers found Voxel, Delbin, Magpie and Bobba, the one found in Whitebox does not need to be reset after issuing power-on command, and skipping reset saves resume time.
Signed-off-by: Jingle Wu jingle.wu@emc.com.tw Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210907012924.11391-1-jingle.wu@emc.com.tw Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/input/mouse/elan_i2c.h | 3 ++- drivers/input/mouse/elan_i2c_core.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/input/mouse/elan_i2c.h +++ b/drivers/input/mouse/elan_i2c.h @@ -55,8 +55,9 @@ #define ETP_FW_PAGE_SIZE_512 512 #define ETP_FW_SIGNATURE_SIZE 6
-#define ETP_PRODUCT_ID_DELBIN 0x00C2 +#define ETP_PRODUCT_ID_WHITEBOX 0x00B8 #define ETP_PRODUCT_ID_VOXEL 0x00BF +#define ETP_PRODUCT_ID_DELBIN 0x00C2 #define ETP_PRODUCT_ID_MAGPIE 0x0120 #define ETP_PRODUCT_ID_BOBBA 0x0121
--- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -105,6 +105,7 @@ static u32 elan_i2c_lookup_quirks(u16 ic u32 quirks; } elan_i2c_quirks[] = { { 0x0D, ETP_PRODUCT_ID_DELBIN, ETP_QUIRK_QUICK_WAKEUP }, + { 0x0D, ETP_PRODUCT_ID_WHITEBOX, ETP_QUIRK_QUICK_WAKEUP }, { 0x10, ETP_PRODUCT_ID_VOXEL, ETP_QUIRK_QUICK_WAKEUP }, { 0x14, ETP_PRODUCT_ID_MAGPIE, ETP_QUIRK_QUICK_WAKEUP }, { 0x14, ETP_PRODUCT_ID_BOBBA, ETP_QUIRK_QUICK_WAKEUP },
From: Steven Rostedt (VMware) rostedt@goodmis.org
commit 210f9df02611cbe641ced3239122b270fd907d86 upstream.
The selftest for ftrace checks some features by checking if the README has text that states the feature is supported by that kernel. Unfortunately, this check gives false positives because it many not be checked if there's spaces in the string to check. This is due to the compare between the required variable with the ":README" string stripped, because neither has quotes around them.
Link: https://lkml.kernel.org/r/20210820204742.087177341@goodmis.org
Cc: "Tzvetomir Stoyanov" tz.stoyanov@gmail.com Cc: Tom Zanussi zanussi@kernel.org Cc: Shuah Khan shuah@kernel.org Cc: Shuah Khan skhan@linuxfoundation.org Cc: linux-kselftest@vger.kernel.org Cc: stable@vger.kernel.org Fixes: 1b8eec510ba64 ("selftests/ftrace: Support ":README" suffix for requires") Acked-by: Masami Hiramatsu mhiramat@kernel.org Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/ftrace/test.d/functions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/tools/testing/selftests/ftrace/test.d/functions +++ b/tools/testing/selftests/ftrace/test.d/functions @@ -115,7 +115,7 @@ check_requires() { # Check required file echo "Required tracer $t is not configured." exit_unsupported fi - elif [ $r != $i ]; then + elif [ "$r" != "$i" ]; then if ! grep -Fq "$r" README ; then echo "Required feature pattern "$r" is not in README." exit_unsupported
From: Rolf Eike Beer eb@emlix.com
commit b5f7912bb604b47a0fe024560488a7556dce8ee7 upstream.
Default to prefixed pkg-config when crosscompiling, this matches what other parts of the tools/ directory already do.
[dlezcano] : Reworked description
Signed-off-by: Rolf Eike Beer eb@emlix.com Cc: stable@vger.kernel.org Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Link: https://lore.kernel.org/r/31302992.qZodDJZGDc@devpool47 Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/thermal/tmon/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/tools/thermal/tmon/Makefile +++ b/tools/thermal/tmon/Makefile @@ -10,7 +10,7 @@ override CFLAGS+= $(call cc-option,-O3,- # Add "-fstack-protector" only if toolchain supports it. override CFLAGS+= $(call cc-option,-fstack-protector-strong) CC?= $(CROSS_COMPILE)gcc -PKG_CONFIG?= pkg-config +PKG_CONFIG?= $(CROSS_COMPILE)pkg-config
override CFLAGS+=-D VERSION="$(VERSION)" LDFLAGS+=
From: Dinh Nguyen dinguyen@kernel.org
commit 9d563236cca43fc4fe190b3be173444bd48e2a3b upstream.
The psi_ref_clk comes from the C2 node of the main_pll and periph_pll, not the C3.
Fixes: 80c6b7a0894f ("clk: socfpga: agilex: add clock driver for the Agilex platform") Cc: stable@vger.kernel.org Signed-off-by: Kris Chaplin kris.chaplin@intel.com Signed-off-by: Dinh Nguyen dinguyen@kernel.org Link: https://lore.kernel.org/r/20210713144621.605140-1-dinguyen@kernel.org Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/clk/socfpga/clk-agilex.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/clk/socfpga/clk-agilex.c +++ b/drivers/clk/socfpga/clk-agilex.c @@ -107,10 +107,10 @@ static const struct clk_parent_data gpio };
static const struct clk_parent_data psi_ref_free_mux[] = { - { .fw_name = "main_pll_c3", - .name = "main_pll_c3", }, - { .fw_name = "peri_pll_c3", - .name = "peri_pll_c3", }, + { .fw_name = "main_pll_c2", + .name = "main_pll_c2", }, + { .fw_name = "peri_pll_c2", + .name = "peri_pll_c2", }, { .fw_name = "osc1", .name = "osc1", }, { .fw_name = "cb-intosc-hs-div2-clk",
From: Dinh Nguyen dinguyen@kernel.org
commit f817c132db679d492d96c60993fa2f2c67ab18d0 upstream.
Correct the s2f_user0_mux clock representation.
Fixes: 80c6b7a0894f ("clk: socfpga: agilex: add clock driver for the Agilex platform") Cc: stable@vger.kernel.org Signed-off-by: Kris Chaplin kris.chaplin@intel.com Signed-off-by: Dinh Nguyen dinguyen@kernel.org Link: https://lore.kernel.org/r/20210713144621.605140-2-dinguyen@kernel.org Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/clk/socfpga/clk-agilex.c | 9 +++++++++ 1 file changed, 9 insertions(+)
--- a/drivers/clk/socfpga/clk-agilex.c +++ b/drivers/clk/socfpga/clk-agilex.c @@ -195,6 +195,13 @@ static const struct clk_parent_data sdmm .name = "boot_clk", }, };
+static const struct clk_parent_data s2f_user0_mux[] = { + { .fw_name = "s2f_user0_free_clk", + .name = "s2f_user0_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + static const struct clk_parent_data s2f_user1_mux[] = { { .fw_name = "s2f_user1_free_clk", .name = "s2f_user1_free_clk", }, @@ -319,6 +326,8 @@ static const struct stratix10_gate_clock 4, 0x98, 0, 16, 0x88, 3, 0}, { AGILEX_SDMMC_CLK, "sdmmc_clk", NULL, sdmmc_mux, ARRAY_SIZE(sdmmc_mux), 0, 0x7C, 5, 0, 0, 0, 0x88, 4, 4}, + { AGILEX_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_user0_mux, ARRAY_SIZE(s2f_user0_mux), 0, 0x24, + 6, 0, 0, 0, 0x30, 2, 0}, { AGILEX_S2F_USER1_CLK, "s2f_user1_clk", NULL, s2f_user1_mux, ARRAY_SIZE(s2f_user1_mux), 0, 0x7C, 6, 0, 0, 0, 0x88, 5, 0}, { AGILEX_PSI_REF_CLK, "psi_ref_clk", NULL, psi_mux, ARRAY_SIZE(psi_mux), 0, 0x7C,
From: Dinh Nguyen dinguyen@kernel.org
commit d17929eb1066d1c1653aae9bb4396a9f1d6602ac upstream.
Add the bypass register for the s2f_user0_clk.
Fixes: 80c6b7a0894f ("clk: socfpga: agilex: add clock driver for the Agilex platform") Cc: stable@vger.kernel.org Signed-off-by: Kris Chaplin kris.chaplin@intel.com Signed-off-by: Dinh Nguyen dinguyen@kernel.org Link: https://lore.kernel.org/r/20210713144621.605140-3-dinguyen@kernel.org Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/clk/socfpga/clk-agilex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/clk/socfpga/clk-agilex.c +++ b/drivers/clk/socfpga/clk-agilex.c @@ -280,7 +280,7 @@ static const struct stratix10_perip_cnt_ { AGILEX_SDMMC_FREE_CLK, "sdmmc_free_clk", NULL, sdmmc_free_mux, ARRAY_SIZE(sdmmc_free_mux), 0, 0xE4, 0, 0, 0}, { AGILEX_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", NULL, s2f_usr0_free_mux, - ARRAY_SIZE(s2f_usr0_free_mux), 0, 0xE8, 0, 0, 0}, + ARRAY_SIZE(s2f_usr0_free_mux), 0, 0xE8, 0, 0x30, 2}, { AGILEX_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", NULL, s2f_usr1_free_mux, ARRAY_SIZE(s2f_usr1_free_mux), 0, 0xEC, 0, 0x88, 5}, { AGILEX_PSI_REF_FREE_CLK, "psi_ref_free_clk", NULL, psi_ref_free_mux,
From: Marc Zyngier maz@kernel.org
commit 1b73e588f47397dee6e4bdfd953e0306c60b5fe5 upstream.
Casting a small array of u8 to an unsigned long is *never* OK:
- it does funny thing when the array size is less than that of a long, as it accesses random places in the stack - it makes everything even more fun with a BE kernel
Fix this by building the unsigned long used as a bitmap byte by byte, in a way that works across endianess and has no undefined behaviours.
An extra BUILD_BUG_ON() catches the unlikely case where the array would be larger than a single unsigned long.
Fixes: 1490d9f841b1 ("pinctrl: Add STMFX GPIO expander Pinctrl/GPIO driver") Signed-off-by: Marc Zyngier maz@kernel.org Cc: stable@vger.kernel.org Cc: Amelie Delaunay amelie.delaunay@foss.st.com Cc: Linus Walleij linus.walleij@linaro.org Cc: Maxime Coquelin mcoquelin.stm32@gmail.com Cc: Alexandre Torgue alexandre.torgue@foss.st.com Link: https://lore.kernel.org/r/20210725180830.250218-1-maz@kernel.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pinctrl/pinctrl-stmfx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -566,7 +566,7 @@ static irqreturn_t stmfx_pinctrl_irq_thr u8 pending[NR_GPIO_REGS]; u8 src[NR_GPIO_REGS] = {0, 0, 0}; unsigned long n, status; - int ret; + int i, ret;
ret = regmap_bulk_read(pctl->stmfx->map, STMFX_REG_IRQ_GPI_PENDING, &pending, NR_GPIO_REGS); @@ -576,7 +576,9 @@ static irqreturn_t stmfx_pinctrl_irq_thr regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_SRC, src, NR_GPIO_REGS);
- status = *(unsigned long *)pending; + BUILD_BUG_ON(NR_GPIO_REGS > sizeof(status)); + for (i = 0, status = 0; i < NR_GPIO_REGS; i++) + status |= (unsigned long)pending[i] << (i * 8); for_each_set_bit(n, &status, gc->ngpio) { handle_nested_irq(irq_find_mapping(gc->irq.domain, n)); stmfx_pinctrl_irq_toggle_trigger(pctl, n);
From: Paul Cercueil paul@crapouillou.net
commit d5e931403942b3af39212960c2592b5ba741b2bf upstream.
Fix the pull up/down info for both the JZ4760 and JZ4770 SoCs, as the previous values sometimes contradicted what's written in the programming manual.
Fixes: b5c23aa46537 ("pinctrl: add a pinctrl driver for the Ingenic jz47xx SoCs") Cc: stable@vger.kernel.org # v4.12 Signed-off-by: Paul Cercueil paul@crapouillou.net Tested-by: 周琰杰 (Zhou Yanjie)zhouyanjie@wanyeetech.com Link: https://lore.kernel.org/r/20210717174836.14776-1-paul@crapouillou.net Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pinctrl/pinctrl-ingenic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -710,7 +710,7 @@ static const struct ingenic_chip_info jz };
static const u32 jz4760_pull_ups[6] = { - 0xffffffff, 0xfffcf3ff, 0xffffffff, 0xffffcfff, 0xfffffb7c, 0xfffff00f, + 0xffffffff, 0xfffcf3ff, 0xffffffff, 0xffffcfff, 0xfffffb7c, 0x0000000f, };
static const u32 jz4760_pull_downs[6] = { @@ -936,11 +936,11 @@ static const struct ingenic_chip_info jz };
static const u32 jz4770_pull_ups[6] = { - 0x3fffffff, 0xfff0030c, 0xffffffff, 0xffff4fff, 0xfffffb7c, 0xffa7f00f, + 0x3fffffff, 0xfff0f3fc, 0xffffffff, 0xffff4fff, 0xfffffb7c, 0x0024f00f, };
static const u32 jz4770_pull_downs[6] = { - 0x00000000, 0x000f0c03, 0x00000000, 0x0000b000, 0x00000483, 0x00580ff0, + 0x00000000, 0x000f0c03, 0x00000000, 0x0000b000, 0x00000483, 0x005b0ff0, };
static int jz4770_uart0_data_pins[] = { 0xa0, 0xa3, };
From: Paul Cercueil paul@crapouillou.net
commit 7261851e938f4b0fe8c0f5a8e627ae90e1ba9875 upstream.
The ingenic_set_bias() function's "bias" argument is not a "enum pin_config_param", so its value should not be compared against values of that enum.
This should fix the bias config not working on the X2000(E) SoCs.
Fixes: 943e0da15370 ("pinctrl: Ingenic: Add pinctrl driver for X2000.") Cc: stable@vger.kernel.org # v5.12 Signed-off-by: Paul Cercueil paul@crapouillou.net Tested-by: 周琰杰 (Zhou Yanjie)zhouyanjie@wanyeetech.com Link: https://lore.kernel.org/r/20210717174836.14776-2-paul@crapouillou.net Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pinctrl/pinctrl-ingenic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -3441,17 +3441,17 @@ static void ingenic_set_bias(struct inge { if (jzpc->info->version >= ID_X2000) { switch (bias) { - case PIN_CONFIG_BIAS_PULL_UP: + case GPIO_PULL_UP: ingenic_config_pin(jzpc, pin, X2000_GPIO_PEPD, false); ingenic_config_pin(jzpc, pin, X2000_GPIO_PEPU, true); break;
- case PIN_CONFIG_BIAS_PULL_DOWN: + case GPIO_PULL_DOWN: ingenic_config_pin(jzpc, pin, X2000_GPIO_PEPU, false); ingenic_config_pin(jzpc, pin, X2000_GPIO_PEPD, true); break;
- case PIN_CONFIG_BIAS_DISABLE: + case GPIO_PULL_DIS: default: ingenic_config_pin(jzpc, pin, X2000_GPIO_PEPU, false); ingenic_config_pin(jzpc, pin, X2000_GPIO_PEPD, false);
From: Enric Balletbo i Serra enric.balletbo@collabora.com
commit 25423731956b3d72bc35d336227c88ada49148e8 upstream.
The UFOE (data compression engine) component needs to be enabled to have the imgtec gpu driver working. If we don't enable it we see a black screen. Looks like when we switched to use and array for setting the routing registers in commit 440147639ac7 ("soc: mediatek: mmsys: Use an array for setting the routing registers") we missed to add this component in the new routing table, it was present before that commit, so fix it by adding this component in the mt8173 routing table.
Fixes: 440147639ac7 ("soc: mediatek: mmsys: Use an array for setting the routing registers") Signed-off-by: Enric Balletbo i Serra enric.balletbo@collabora.com Tested-by: Eizan Miyamoto eizan@chromium.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210625062448.3462177-1-enric.balletbo@collabora.... [mb: taking into account mask value] Signed-off-by: Matthias Brugger matthias.bgg@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/soc/mediatek/mtk-mmsys.h | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/soc/mediatek/mtk-mmsys.h +++ b/drivers/soc/mediatek/mtk-mmsys.h @@ -262,6 +262,10 @@ static const struct mtk_mmsys_routes mms DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI3, DISP_REG_CONFIG_DSIO_SEL_IN, DSI3_SEL_IN_MASK, DSI3_SEL_IN_RDMA2 + }, { + DDP_COMPONENT_UFOE, DDP_COMPONENT_DSI0, + DISP_REG_CONFIG_DISP_UFOE_MOUT_EN, UFOE_MOUT_EN_DSI0, + UFOE_MOUT_EN_DSI0 } };
From: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org
commit a89f355e469dcda129c2522be4fdba00c1c74c83 upstream.
In "qmp_cooling_devices_register", the count value is initially QMP_NUM_COOLING_RESOURCES, which is 2. Based on the initial count value, the memory for cooling_devs is allocated. Then while calling the "qmp_cooling_device_add" function, count value is post-incremented for each child node.
This makes the out of bound access to the cooling_dev array. Fix it by passing the QMP_NUM_COOLING_RESOURCES definition to devm_kzalloc() and initializing the count to 0.
While at it, let's also free the memory allocated to cooling_dev if no cooling device is found in DT and during unroll phase.
Cc: stable@vger.kernel.org # 5.4 Fixes: 05589b30b21a ("soc: qcom: Extend AOSS QMP driver to support resources that are used to wake up the SoC.") Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Link: https://lore.kernel.org/r/20210629153249.73428-1-manivannan.sadhasivam@linar... Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/soc/qcom/qcom_aoss.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/soc/qcom/qcom_aoss.c +++ b/drivers/soc/qcom/qcom_aoss.c @@ -476,12 +476,12 @@ static int qmp_cooling_device_add(struct static int qmp_cooling_devices_register(struct qmp *qmp) { struct device_node *np, *child; - int count = QMP_NUM_COOLING_RESOURCES; + int count = 0; int ret;
np = qmp->dev->of_node;
- qmp->cooling_devs = devm_kcalloc(qmp->dev, count, + qmp->cooling_devs = devm_kcalloc(qmp->dev, QMP_NUM_COOLING_RESOURCES, sizeof(*qmp->cooling_devs), GFP_KERNEL);
@@ -497,12 +497,16 @@ static int qmp_cooling_devices_register( goto unroll; }
+ if (!count) + devm_kfree(qmp->dev, qmp->cooling_devs); + return 0;
unroll: while (--count >= 0) thermal_cooling_device_unregister (qmp->cooling_devs[count].cdev); + devm_kfree(qmp->dev, qmp->cooling_devs);
return ret; }
From: Iwona Winiarska iwona.winiarska@intel.com
commit b49a0e69a7b1a68c8d3f64097d06dabb770fec96 upstream.
The check mixes pages (vm_pgoff) with bytes (vm_start, vm_end) on one side of the comparison, and uses resource address (rather than just the resource size) on the other side of the comparison. This can allow malicious userspace to easily bypass the boundary check and map pages that are located outside memory-region reserved by the driver.
Fixes: 6c4e97678501 ("drivers/misc: Add Aspeed LPC control driver") Cc: stable@vger.kernel.org Signed-off-by: Iwona Winiarska iwona.winiarska@intel.com Reviewed-by: Andrew Jeffery andrew@aj.id.au Tested-by: Andrew Jeffery andrew@aj.id.au Reviewed-by: Joel Stanley joel@aj.id.au Signed-off-by: Joel Stanley joel@jms.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/soc/aspeed/aspeed-lpc-ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/soc/aspeed/aspeed-lpc-ctrl.c +++ b/drivers/soc/aspeed/aspeed-lpc-ctrl.c @@ -51,7 +51,7 @@ static int aspeed_lpc_ctrl_mmap(struct f unsigned long vsize = vma->vm_end - vma->vm_start; pgprot_t prot = vma->vm_page_prot;
- if (vma->vm_pgoff + vsize > lpc_ctrl->mem_base + lpc_ctrl->mem_size) + if (vma->vm_pgoff + vma_pages(vma) > lpc_ctrl->mem_size >> PAGE_SHIFT) return -EINVAL;
/* ast2400/2500 AHB accesses are not cache coherent */
From: Iwona Winiarska iwona.winiarska@intel.com
commit 8b07e990fb254fcbaa919616ac77f981cb48c73d upstream.
The check mixes pages (vm_pgoff) with bytes (vm_start, vm_end) on one side of the comparison, and uses resource address (rather than just the resource size) on the other side of the comparison. This can allow malicious userspace to easily bypass the boundary check and map pages that are located outside memory-region reserved by the driver.
Fixes: 01c60dcea9f7 ("drivers/misc: Add Aspeed P2A control driver") Cc: stable@vger.kernel.org Signed-off-by: Iwona Winiarska iwona.winiarska@intel.com Reviewed-by: Andrew Jeffery andrew@aj.id.au Tested-by: Andrew Jeffery andrew@aj.id.au Reviewed-by: Joel Stanley joel@aj.id.au Signed-off-by: Joel Stanley joel@jms.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/soc/aspeed/aspeed-p2a-ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/soc/aspeed/aspeed-p2a-ctrl.c +++ b/drivers/soc/aspeed/aspeed-p2a-ctrl.c @@ -110,7 +110,7 @@ static int aspeed_p2a_mmap(struct file * vsize = vma->vm_end - vma->vm_start; prot = vma->vm_page_prot;
- if (vma->vm_pgoff + vsize > ctrl->mem_base + ctrl->mem_size) + if (vma->vm_pgoff + vma_pages(vma) > ctrl->mem_size >> PAGE_SHIFT) return -EINVAL;
/* ast2400/2500 AHB accesses are not cache coherent */
From: Marc Zyngier maz@kernel.org
commit eb48d154cd0dade56a0e244f0cfa198ea2925ed3 upstream.
The HYP rodata section is currently lumped together with the BSS, which isn't exactly what is expected (it gets registered with kmemleak, for example).
Move it away so that it is actually marked RO. As an added benefit, it isn't registered with kmemleak anymore.
Fixes: 380e18ade4a5 ("KVM: arm64: Introduce a BSS section for use at Hyp") Suggested-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Marc Zyngier maz@kernel.org Cc: stable@vger.kernel.org #5.13 Acked-by: Catalin Marinas catalin.marinas@arm.com Link: https://lore.kernel.org/r/20210802123830.2195174-2-maz@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm64/kernel/vmlinux.lds.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -181,6 +181,8 @@ SECTIONS /* everything from this point to __init_begin will be marked RO NX */ RO_DATA(PAGE_SIZE)
+ HYPERVISOR_DATA_SECTIONS + idmap_pg_dir = .; . += IDMAP_DIR_SIZE; idmap_pg_end = .; @@ -260,8 +262,6 @@ SECTIONS _sdata = .; RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN)
- HYPERVISOR_DATA_SECTIONS - /* * Data written with the MMU off but read with the MMU on requires * cache lines to be invalidated, discarding up to a Cache Writeback
From: Will Deacon will@kernel.org
commit 5e10f9887ed85d4f59266d5c60dd09be96b5dbd4 upstream.
When switching to an 'mm_struct' for the first time following an ASID rollover, a new ASID may be allocated and assigned to 'mm->context.id'. This reassignment can happen concurrently with other operations on the mm, such as unmapping pages and subsequently issuing TLB invalidation.
Consequently, we need to ensure that (a) accesses to 'mm->context.id' are atomic and (b) all page-table updates made prior to a TLBI using the old ASID are guaranteed to be visible to CPUs running with the new ASID.
This was found by inspection after reviewing the VMID changes from Shameer but it looks like a real (yet hard to hit) bug.
Cc: stable@vger.kernel.org Cc: Marc Zyngier maz@kernel.org Cc: Jade Alglave jade.alglave@arm.com Cc: Shameer Kolothum shameerali.kolothum.thodi@huawei.com Signed-off-by: Will Deacon will@kernel.org Reviewed-by: Catalin Marinas catalin.marinas@arm.com Link: https://lore.kernel.org/r/20210806113109.2475-2-will@kernel.org Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm64/include/asm/mmu.h | 29 +++++++++++++++++++++++++---- arch/arm64/include/asm/tlbflush.h | 11 ++++++----- 2 files changed, 31 insertions(+), 9 deletions(-)
--- a/arch/arm64/include/asm/mmu.h +++ b/arch/arm64/include/asm/mmu.h @@ -27,11 +27,32 @@ typedef struct { } mm_context_t;
/* - * This macro is only used by the TLBI and low-level switch_mm() code, - * neither of which can race with an ASID change. We therefore don't - * need to reload the counter using atomic64_read(). + * We use atomic64_read() here because the ASID for an 'mm_struct' can + * be reallocated when scheduling one of its threads following a + * rollover event (see new_context() and flush_context()). In this case, + * a concurrent TLBI (e.g. via try_to_unmap_one() and ptep_clear_flush()) + * may use a stale ASID. This is fine in principle as the new ASID is + * guaranteed to be clean in the TLB, but the TLBI routines have to take + * care to handle the following race: + * + * CPU 0 CPU 1 CPU 2 + * + * // ptep_clear_flush(mm) + * xchg_relaxed(pte, 0) + * DSB ISHST + * old = ASID(mm) + * | <rollover> + * | new = new_context(mm) + * -----------------> atomic_set(mm->context.id, new) + * cpu_switch_mm(mm) + * // Hardware walk of pte using new ASID + * TLBI(old) + * + * In this scenario, the barrier on CPU 0 and the dependency on CPU 1 + * ensure that the page-table walker on CPU 1 *must* see the invalid PTE + * written by CPU 0. */ -#define ASID(mm) ((mm)->context.id.counter & 0xffff) +#define ASID(mm) (atomic64_read(&(mm)->context.id) & 0xffff)
static inline bool arm64_kernel_unmapped_at_el0(void) { --- a/arch/arm64/include/asm/tlbflush.h +++ b/arch/arm64/include/asm/tlbflush.h @@ -245,9 +245,10 @@ static inline void flush_tlb_all(void)
static inline void flush_tlb_mm(struct mm_struct *mm) { - unsigned long asid = __TLBI_VADDR(0, ASID(mm)); + unsigned long asid;
dsb(ishst); + asid = __TLBI_VADDR(0, ASID(mm)); __tlbi(aside1is, asid); __tlbi_user(aside1is, asid); dsb(ish); @@ -256,9 +257,10 @@ static inline void flush_tlb_mm(struct m static inline void flush_tlb_page_nosync(struct vm_area_struct *vma, unsigned long uaddr) { - unsigned long addr = __TLBI_VADDR(uaddr, ASID(vma->vm_mm)); + unsigned long addr;
dsb(ishst); + addr = __TLBI_VADDR(uaddr, ASID(vma->vm_mm)); __tlbi(vale1is, addr); __tlbi_user(vale1is, addr); } @@ -283,9 +285,7 @@ static inline void __flush_tlb_range(str { int num = 0; int scale = 0; - unsigned long asid = ASID(vma->vm_mm); - unsigned long addr; - unsigned long pages; + unsigned long asid, addr, pages;
start = round_down(start, stride); end = round_up(end, stride); @@ -305,6 +305,7 @@ static inline void __flush_tlb_range(str }
dsb(ishst); + asid = ASID(vma->vm_mm);
/* * When the CPU does not support TLB range operations, flush the TLB
From: Mark Rutland mark.rutland@arm.com
commit 90268574a3e8a6b883bd802d702a2738577e1006 upstream.
The `compute_indices` and `populate_entries` macros operate on inclusive bounds, and thus the `map_memory` macro which uses them also operates on inclusive bounds.
We pass `_end` and `_idmap_text_end` to `map_memory`, but these are exclusive bounds, and if one of these is sufficiently aligned (as a result of kernel configuration, physical placement, and KASLR), then:
* In `compute_indices`, the computed `iend` will be in the page/block *after* the final byte of the intended mapping.
* In `populate_entries`, an unnecessary entry will be created at the end of each level of table. At the leaf level, this entry will map up to SWAPPER_BLOCK_SIZE bytes of physical addresses that we did not intend to map.
As we may map up to SWAPPER_BLOCK_SIZE bytes more than intended, we may violate the boot protocol and map physical address past the 2MiB-aligned end address we are permitted to map. As we map these with Normal memory attributes, this may result in further problems depending on what these physical addresses correspond to.
The final entry at each level may require an additional table at that level. As EARLY_ENTRIES() calculates an inclusive bound, we allocate enough memory for this.
Avoid the extraneous mapping by having map_memory convert the exclusive end address to an inclusive end address by subtracting one, and do likewise in EARLY_ENTRIES() when calculating the number of required tables. For clarity, comments are updated to more clearly document which boundaries the macros operate on. For consistency with the other macros, the comments in map_memory are also updated to describe `vstart` and `vend` as virtual addresses.
Fixes: 0370b31e4845 ("arm64: Extend early page table code to allow for larger kernels") Cc: stable@vger.kernel.org # 4.16.x Signed-off-by: Mark Rutland mark.rutland@arm.com Cc: Anshuman Khandual anshuman.khandual@arm.com Cc: Ard Biesheuvel ard.biesheuvel@linaro.org Cc: Steve Capper steve.capper@arm.com Cc: Will Deacon will@kernel.org Acked-by: Will Deacon will@kernel.org Link: https://lore.kernel.org/r/20210823101253.55567-1-mark.rutland@arm.com Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm64/include/asm/kernel-pgtable.h | 4 ++-- arch/arm64/kernel/head.S | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-)
--- a/arch/arm64/include/asm/kernel-pgtable.h +++ b/arch/arm64/include/asm/kernel-pgtable.h @@ -65,8 +65,8 @@ #define EARLY_KASLR (0) #endif
-#define EARLY_ENTRIES(vstart, vend, shift) (((vend) >> (shift)) \ - - ((vstart) >> (shift)) + 1 + EARLY_KASLR) +#define EARLY_ENTRIES(vstart, vend, shift) \ + ((((vend) - 1) >> (shift)) - ((vstart) >> (shift)) + 1 + EARLY_KASLR)
#define EARLY_PGDS(vstart, vend) (EARLY_ENTRIES(vstart, vend, PGDIR_SHIFT))
--- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -176,7 +176,7 @@ SYM_CODE_END(preserve_boot_args) * to be composed of multiple pages. (This effectively scales the end index). * * vstart: virtual address of start of range - * vend: virtual address of end of range + * vend: virtual address of end of range - we map [vstart, vend] * shift: shift used to transform virtual address into index * ptrs: number of entries in page table * istart: index in table corresponding to vstart @@ -213,17 +213,18 @@ SYM_CODE_END(preserve_boot_args) * * tbl: location of page table * rtbl: address to be used for first level page table entry (typically tbl + PAGE_SIZE) - * vstart: start address to map - * vend: end address to map - we map [vstart, vend] + * vstart: virtual address of start of range + * vend: virtual address of end of range - we map [vstart, vend - 1] * flags: flags to use to map last level entries * phys: physical address corresponding to vstart - physical memory is contiguous * pgds: the number of pgd entries * * Temporaries: istart, iend, tmp, count, sv - these need to be different registers - * Preserves: vstart, vend, flags - * Corrupts: tbl, rtbl, istart, iend, tmp, count, sv + * Preserves: vstart, flags + * Corrupts: tbl, rtbl, vend, istart, iend, tmp, count, sv */ .macro map_memory, tbl, rtbl, vstart, vend, flags, phys, pgds, istart, iend, tmp, count, sv + sub \vend, \vend, #1 add \rtbl, \tbl, #PAGE_SIZE mov \sv, \rtbl mov \count, #0
From: Alexandru Elisei alexandru.elisei@arm.com
commit 50cb99fa89aa2bec2cab2f9917010bbd7769bfa3 upstream.
Commit 31c00d2aeaa2 ("arm64: Disable fine grained traps on boot") zeroed the fine grained trap registers to prevent unwanted register traps from occuring. However, for the PMSNEVFR_EL1 register, the corresponding HDFG{R,W}TR_EL2.nPMSNEVFR_EL1 fields must be 1 to disable trapping. Set both fields to 1 if FEAT_SPEv1p2 is detected to disable read and write traps.
Fixes: 31c00d2aeaa2 ("arm64: Disable fine grained traps on boot") Cc: stable@vger.kernel.org # 5.13.x Signed-off-by: Alexandru Elisei alexandru.elisei@arm.com Reviewed-by: Mark Brown broonie@kernel.org Acked-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20210824154523.906270-1-alexandru.elisei@arm.com Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm64/include/asm/el2_setup.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
--- a/arch/arm64/include/asm/el2_setup.h +++ b/arch/arm64/include/asm/el2_setup.h @@ -149,8 +149,17 @@ ubfx x1, x1, #ID_AA64MMFR0_FGT_SHIFT, #4 cbz x1, .Lskip_fgt_@
- msr_s SYS_HDFGRTR_EL2, xzr - msr_s SYS_HDFGWTR_EL2, xzr + mov x0, xzr + mrs x1, id_aa64dfr0_el1 + ubfx x1, x1, #ID_AA64DFR0_PMSVER_SHIFT, #4 + cmp x1, #3 + b.lt .Lset_fgt_@ + /* Disable PMSNEVFR_EL1 read and write traps */ + orr x0, x0, #(1 << 62) + +.Lset_fgt_@: + msr_s SYS_HDFGRTR_EL2, x0 + msr_s SYS_HDFGWTR_EL2, x0 msr_s SYS_HFGRTR_EL2, xzr msr_s SYS_HFGWTR_EL2, xzr msr_s SYS_HFGITR_EL2, xzr
From: Nuno Sá nuno.sa@analog.com
commit b76d26d69ecc97ebb24aaf40427a13c808a4f488 upstream.
There is no reason to assume that the IRQ rising edge (indicating that the device start up phase is done) will happen after we request the IRQ. If the device is already up by the time we request it, the call to 'wait_for_completion_timeout()' will timeout and we will fail the device probe even though there's nothing wrong.
Fix it by just polling the status register until we get the indication that the device is up and running. As a side effect of this fix, requesting the IRQ is also moved to after the setup function.
Fixes: f110f3188e563 ("iio: temperature: Add support for LTC2983") Reported-and-tested-by: Drew Fustini drew@pdp7.com Reviewed-by: Drew Fustini drew@pdp7.com Signed-off-by: Nuno Sá nuno.sa@analog.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Cc: Stable@vger.kernel.org Link: https://lore.kernel.org/r/20210811133220.190264-2-nuno.sa@analog.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/temperature/ltc2983.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-)
--- a/drivers/iio/temperature/ltc2983.c +++ b/drivers/iio/temperature/ltc2983.c @@ -89,6 +89,8 @@
#define LTC2983_STATUS_START_MASK BIT(7) #define LTC2983_STATUS_START(x) FIELD_PREP(LTC2983_STATUS_START_MASK, x) +#define LTC2983_STATUS_UP_MASK GENMASK(7, 6) +#define LTC2983_STATUS_UP(reg) FIELD_GET(LTC2983_STATUS_UP_MASK, reg)
#define LTC2983_STATUS_CHAN_SEL_MASK GENMASK(4, 0) #define LTC2983_STATUS_CHAN_SEL(x) \ @@ -1362,17 +1364,16 @@ put_child:
static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio) { - u32 iio_chan_t = 0, iio_chan_v = 0, chan, iio_idx = 0; + u32 iio_chan_t = 0, iio_chan_v = 0, chan, iio_idx = 0, status; int ret; - unsigned long time; - - /* make sure the device is up */ - time = wait_for_completion_timeout(&st->completion, - msecs_to_jiffies(250));
- if (!time) { + /* make sure the device is up: start bit (7) is 0 and done bit (6) is 1 */ + ret = regmap_read_poll_timeout(st->regmap, LTC2983_STATUS_REG, status, + LTC2983_STATUS_UP(status) == 1, 25000, + 25000 * 10); + if (ret) { dev_err(&st->spi->dev, "Device startup timed out\n"); - return -ETIMEDOUT; + return ret; }
st->iio_chan = devm_kzalloc(&st->spi->dev, @@ -1492,10 +1493,11 @@ static int ltc2983_probe(struct spi_devi ret = ltc2983_parse_dt(st); if (ret) return ret; - /* - * let's request the irq now so it is used to sync the device - * startup in ltc2983_setup() - */ + + ret = ltc2983_setup(st, true); + if (ret) + return ret; + ret = devm_request_irq(&spi->dev, spi->irq, ltc2983_irq_handler, IRQF_TRIGGER_RISING, name, st); if (ret) { @@ -1503,10 +1505,6 @@ static int ltc2983_probe(struct spi_devi return ret; }
- ret = ltc2983_setup(st, true); - if (ret) - return ret; - indio_dev->name = name; indio_dev->num_channels = st->iio_channels; indio_dev->channels = st->iio_chan;
From: Joseph Gates jgates@squareup.com
commit d195d7aac09bddabc2c8326fb02fcec2b0a2de02 upstream.
If the operating channel is the first in the scan list, it was seen that a finish scan request would be sent before a start scan request was sent, causing the firmware to fail all future scans. Track the current channel being scanned to avoid requesting the scan finish before it starts.
Cc: stable@vger.kernel.org Fixes: 5973a2947430 ("wcn36xx: Fix software-driven scan") Signed-off-by: Joseph Gates jgates@squareup.com Signed-off-by: Loic Poulain loic.poulain@linaro.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/1629286303-13179-1-git-send-email-loic.poulain@lin... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/ath/wcn36xx/main.c | 5 ++++- drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -405,13 +405,14 @@ static int wcn36xx_config(struct ieee802 wcn36xx_dbg(WCN36XX_DBG_MAC, "wcn36xx_config channel switch=%d\n", ch);
- if (wcn->sw_scan_opchannel == ch) { + if (wcn->sw_scan_opchannel == ch && wcn->sw_scan_channel) { /* If channel is the initial operating channel, we may * want to receive/transmit regular data packets, then * simply stop the scan session and exit PS mode. */ wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN, wcn->sw_scan_vif); + wcn->sw_scan_channel = 0; } else if (wcn->sw_scan) { /* A scan is ongoing, do not change the operating * channel, but start a scan session on the channel. @@ -419,6 +420,7 @@ static int wcn36xx_config(struct ieee802 wcn36xx_smd_init_scan(wcn, HAL_SYS_MODE_SCAN, wcn->sw_scan_vif); wcn36xx_smd_start_scan(wcn, ch); + wcn->sw_scan_channel = ch; } else { wcn36xx_change_opchannel(wcn, ch); } @@ -699,6 +701,7 @@ static void wcn36xx_sw_scan_start(struct
wcn->sw_scan = true; wcn->sw_scan_vif = vif; + wcn->sw_scan_channel = 0; if (vif_priv->sta_assoc) wcn->sw_scan_opchannel = WCN36XX_HW_CHANNEL(wcn); else --- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h +++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h @@ -232,6 +232,7 @@ struct wcn36xx { struct cfg80211_scan_request *scan_req; bool sw_scan; u8 sw_scan_opchannel; + u8 sw_scan_channel; struct ieee80211_vif *sw_scan_vif; struct mutex scan_lock; bool scan_aborted;
From: zhenwei pi pizhenwei@bytedance.com
commit f985911b7bc75d5c98ed24d8aaa8b94c590f7c6a upstream.
Hit kernel warning like this, it can be reproduced by verifying 256 bytes datafile by keyctl command, run script: RAWDATA=rawdata SIGDATA=sigdata
modprobe pkcs8_key_parser
rm -rf *.der *.pem *.pfx rm -rf $RAWDATA dd if=/dev/random of=$RAWDATA bs=256 count=1
openssl req -nodes -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem \ -subj "/C=CN/ST=GD/L=SZ/O=vihoo/OU=dev/CN=xx.com/emailAddress=yy@xx.com"
KEY_ID=`openssl pkcs8 -in key.pem -topk8 -nocrypt -outform DER | keyctl \ padd asymmetric 123 @s`
keyctl pkey_sign $KEY_ID 0 $RAWDATA enc=pkcs1 hash=sha1 > $SIGDATA keyctl pkey_verify $KEY_ID 0 $RAWDATA $SIGDATA enc=pkcs1 hash=sha1
Then the kernel reports: WARNING: CPU: 5 PID: 344556 at crypto/rsa-pkcs1pad.c:540 pkcs1pad_verify+0x160/0x190 ... Call Trace: public_key_verify_signature+0x282/0x380 ? software_key_query+0x12d/0x180 ? keyctl_pkey_params_get+0xd6/0x130 asymmetric_key_verify_signature+0x66/0x80 keyctl_pkey_verify+0xa5/0x100 do_syscall_64+0x35/0xb0 entry_SYSCALL_64_after_hwframe+0x44/0xae
The reason of this issue, in function 'asymmetric_key_verify_signature': '.digest_size(u8) = params->in_len(u32)' leads overflow of an u8 value, so use u32 instead of u8 for digest_size field. And reorder struct public_key_signature, it saves 8 bytes on a 64-bit machine.
Cc: stable@vger.kernel.org Signed-off-by: zhenwei pi pizhenwei@bytedance.com Reviewed-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/crypto/public_key.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/include/crypto/public_key.h +++ b/include/crypto/public_key.h @@ -38,9 +38,9 @@ extern void public_key_free(struct publi struct public_key_signature { struct asymmetric_key_id *auth_ids[2]; u8 *s; /* Signature */ - u32 s_size; /* Number of bytes in signature */ u8 *digest; - u8 digest_size; /* Number of bytes in digest */ + u32 s_size; /* Number of bytes in signature */ + u32 digest_size; /* Number of bytes in digest */ const char *pkey_algo; const char *hash_algo; const char *encoding;
From: Damien Le Moal damien.lemoal@wdc.com
commit a680dd72ec336b81511e3bff48efac6dbfa563e7 upstream.
For a request that has a priority level equal to or larger than IOPRIO_BE_NR, bfq_set_next_ioprio_data() prints a critical warning but defaults to setting the request new_ioprio field to IOPRIO_BE_NR. This is not consistent with the warning and the allowed values for priority levels. Fix this by setting the request new_ioprio field to IOPRIO_BE_NR - 1, the lowest priority level allowed.
Cc: stable@vger.kernel.org Fixes: aee69d78dec0 ("block, bfq: introduce the BFQ-v0 I/O scheduler as an extra scheduler") Signed-off-by: Damien Le Moal damien.lemoal@wdc.com Reviewed-by: Hannes Reinecke hare@suse.de Link: https://lore.kernel.org/r/20210811033702.368488-2-damien.lemoal@wdc.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/bfq-iosched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -5258,7 +5258,7 @@ bfq_set_next_ioprio_data(struct bfq_queu if (bfqq->new_ioprio >= IOPRIO_BE_NR) { pr_crit("bfq_set_next_ioprio_data: new_ioprio %d\n", bfqq->new_ioprio); - bfqq->new_ioprio = IOPRIO_BE_NR; + bfqq->new_ioprio = IOPRIO_BE_NR - 1; }
bfqq->entity.new_weight = bfq_ioprio_to_weight(bfqq->new_ioprio);
From: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com
commit 54784ffa5b267f57161eb8fbb811499f22a0a0bf upstream.
Reading status register can fail in the interrupt handler. In such case, the regmap_read() will not store anything useful under passed 'val' variable and random stack value will be used to determine type of interrupt.
Handle the regmap_read() failure to avoid handling interrupt type and triggering changed power supply event based on random stack value.
Fixes: 39e7213edc4f ("max17042_battery: Support regmap to access device's registers") Cc: stable@vger.kernel.org Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/power/supply/max17042_battery.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/power/supply/max17042_battery.c +++ b/drivers/power/supply/max17042_battery.c @@ -869,8 +869,12 @@ static irqreturn_t max17042_thread_handl { struct max17042_chip *chip = dev; u32 val; + int ret; + + ret = regmap_read(chip->regmap, MAX17042_STATUS, &val); + if (ret) + return IRQ_HANDLED;
- regmap_read(chip->regmap, MAX17042_STATUS, &val); if ((val & STATUS_INTR_SOCMIN_BIT) || (val & STATUS_INTR_SOCMAX_BIT)) { dev_info(&chip->client->dev, "SOC threshold INTR\n");
From: Kevin Hao haokexin@gmail.com
commit e5c6b312ce3cc97e90ea159446e6bfa06645364d upstream.
The struct sugov_tunables is protected by the kobject, so we can't free it directly. Otherwise we would get a call trace like this: ODEBUG: free active (active state 0) object type: timer_list hint: delayed_work_timer_fn+0x0/0x30 WARNING: CPU: 3 PID: 720 at lib/debugobjects.c:505 debug_print_object+0xb8/0x100 Modules linked in: CPU: 3 PID: 720 Comm: a.sh Tainted: G W 5.14.0-rc1-next-20210715-yocto-standard+ #507 Hardware name: Marvell OcteonTX CN96XX board (DT) pstate: 40400009 (nZcv daif +PAN -UAO -TCO BTYPE=--) pc : debug_print_object+0xb8/0x100 lr : debug_print_object+0xb8/0x100 sp : ffff80001ecaf910 x29: ffff80001ecaf910 x28: ffff00011b10b8d0 x27: ffff800011043d80 x26: ffff00011a8f0000 x25: ffff800013cb3ff0 x24: 0000000000000000 x23: ffff80001142aa68 x22: ffff800011043d80 x21: ffff00010de46f20 x20: ffff800013c0c520 x19: ffff800011d8f5b0 x18: 0000000000000010 x17: 6e6968207473696c x16: 5f72656d6974203a x15: 6570797420746365 x14: 6a626f2029302065 x13: 303378302f307830 x12: 2b6e665f72656d69 x11: ffff8000124b1560 x10: ffff800012331520 x9 : ffff8000100ca6b0 x8 : 000000000017ffe8 x7 : c0000000fffeffff x6 : 0000000000000001 x5 : ffff800011d8c000 x4 : ffff800011d8c740 x3 : 0000000000000000 x2 : ffff0001108301c0 x1 : ab3c90eedf9c0f00 x0 : 0000000000000000 Call trace: debug_print_object+0xb8/0x100 __debug_check_no_obj_freed+0x1c0/0x230 debug_check_no_obj_freed+0x20/0x88 slab_free_freelist_hook+0x154/0x1c8 kfree+0x114/0x5d0 sugov_exit+0xbc/0xc0 cpufreq_exit_governor+0x44/0x90 cpufreq_set_policy+0x268/0x4a8 store_scaling_governor+0xe0/0x128 store+0xc0/0xf0 sysfs_kf_write+0x54/0x80 kernfs_fop_write_iter+0x128/0x1c0 new_sync_write+0xf0/0x190 vfs_write+0x2d4/0x478 ksys_write+0x74/0x100 __arm64_sys_write+0x24/0x30 invoke_syscall.constprop.0+0x54/0xe0 do_el0_svc+0x64/0x158 el0_svc+0x2c/0xb0 el0t_64_sync_handler+0xb0/0xb8 el0t_64_sync+0x198/0x19c irq event stamp: 5518 hardirqs last enabled at (5517): [<ffff8000100cbd7c>] console_unlock+0x554/0x6c8 hardirqs last disabled at (5518): [<ffff800010fc0638>] el1_dbg+0x28/0xa0 softirqs last enabled at (5504): [<ffff8000100106e0>] __do_softirq+0x4d0/0x6c0 softirqs last disabled at (5483): [<ffff800010049548>] irq_exit+0x1b0/0x1b8
So split the original sugov_tunables_free() into two functions, sugov_clear_global_tunables() is just used to clear the global_tunables and the new sugov_tunables_free() is used as kobj_type::release to release the sugov_tunables safely.
Fixes: 9bdcb44e391d ("cpufreq: schedutil: New governor based on scheduler utilization data") Cc: 4.7+ stable@vger.kernel.org # 4.7+ Signed-off-by: Kevin Hao haokexin@gmail.com Acked-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/sched/cpufreq_schedutil.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
--- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -536,9 +536,17 @@ static struct attribute *sugov_attrs[] = }; ATTRIBUTE_GROUPS(sugov);
+static void sugov_tunables_free(struct kobject *kobj) +{ + struct gov_attr_set *attr_set = container_of(kobj, struct gov_attr_set, kobj); + + kfree(to_sugov_tunables(attr_set)); +} + static struct kobj_type sugov_tunables_ktype = { .default_groups = sugov_groups, .sysfs_ops = &governor_sysfs_ops, + .release = &sugov_tunables_free, };
/********************** cpufreq governor interface *********************/ @@ -638,12 +646,10 @@ static struct sugov_tunables *sugov_tuna return tunables; }
-static void sugov_tunables_free(struct sugov_tunables *tunables) +static void sugov_clear_global_tunables(void) { if (!have_governor_per_policy()) global_tunables = NULL; - - kfree(tunables); }
static int sugov_init(struct cpufreq_policy *policy) @@ -706,7 +712,7 @@ out: fail: kobject_put(&tunables->attr_set.kobj); policy->governor_data = NULL; - sugov_tunables_free(tunables); + sugov_clear_global_tunables();
stop_kthread: sugov_kthread_stop(sg_policy); @@ -733,7 +739,7 @@ static void sugov_exit(struct cpufreq_po count = gov_attr_set_put(&tunables->attr_set, &sg_policy->tunables_hook); policy->governor_data = NULL; if (!count) - sugov_tunables_free(tunables); + sugov_clear_global_tunables();
mutex_unlock(&global_tunables_lock);
On 9/16/2021 5:56 PM, Greg Kroah-Hartman wrote:
From: Kevin Hao haokexin@gmail.com
commit e5c6b312ce3cc97e90ea159446e6bfa06645364d upstream.
The struct sugov_tunables is protected by the kobject, so we can't free it directly. Otherwise we would get a call trace like this: ODEBUG: free active (active state 0) object type: timer_list hint: delayed_work_timer_fn+0x0/0x30 WARNING: CPU: 3 PID: 720 at lib/debugobjects.c:505 debug_print_object+0xb8/0x100 Modules linked in: CPU: 3 PID: 720 Comm: a.sh Tainted: G W 5.14.0-rc1-next-20210715-yocto-standard+ #507 Hardware name: Marvell OcteonTX CN96XX board (DT) pstate: 40400009 (nZcv daif +PAN -UAO -TCO BTYPE=--) pc : debug_print_object+0xb8/0x100 lr : debug_print_object+0xb8/0x100 sp : ffff80001ecaf910 x29: ffff80001ecaf910 x28: ffff00011b10b8d0 x27: ffff800011043d80 x26: ffff00011a8f0000 x25: ffff800013cb3ff0 x24: 0000000000000000 x23: ffff80001142aa68 x22: ffff800011043d80 x21: ffff00010de46f20 x20: ffff800013c0c520 x19: ffff800011d8f5b0 x18: 0000000000000010 x17: 6e6968207473696c x16: 5f72656d6974203a x15: 6570797420746365 x14: 6a626f2029302065 x13: 303378302f307830 x12: 2b6e665f72656d69 x11: ffff8000124b1560 x10: ffff800012331520 x9 : ffff8000100ca6b0 x8 : 000000000017ffe8 x7 : c0000000fffeffff x6 : 0000000000000001 x5 : ffff800011d8c000 x4 : ffff800011d8c740 x3 : 0000000000000000 x2 : ffff0001108301c0 x1 : ab3c90eedf9c0f00 x0 : 0000000000000000 Call trace: debug_print_object+0xb8/0x100 __debug_check_no_obj_freed+0x1c0/0x230 debug_check_no_obj_freed+0x20/0x88 slab_free_freelist_hook+0x154/0x1c8 kfree+0x114/0x5d0 sugov_exit+0xbc/0xc0 cpufreq_exit_governor+0x44/0x90 cpufreq_set_policy+0x268/0x4a8 store_scaling_governor+0xe0/0x128 store+0xc0/0xf0 sysfs_kf_write+0x54/0x80 kernfs_fop_write_iter+0x128/0x1c0 new_sync_write+0xf0/0x190 vfs_write+0x2d4/0x478 ksys_write+0x74/0x100 __arm64_sys_write+0x24/0x30 invoke_syscall.constprop.0+0x54/0xe0 do_el0_svc+0x64/0x158 el0_svc+0x2c/0xb0 el0t_64_sync_handler+0xb0/0xb8 el0t_64_sync+0x198/0x19c irq event stamp: 5518 hardirqs last enabled at (5517): [<ffff8000100cbd7c>] console_unlock+0x554/0x6c8 hardirqs last disabled at (5518): [<ffff800010fc0638>] el1_dbg+0x28/0xa0 softirqs last enabled at (5504): [<ffff8000100106e0>] __do_softirq+0x4d0/0x6c0 softirqs last disabled at (5483): [<ffff800010049548>] irq_exit+0x1b0/0x1b8
So split the original sugov_tunables_free() into two functions, sugov_clear_global_tunables() is just used to clear the global_tunables and the new sugov_tunables_free() is used as kobj_type::release to release the sugov_tunables safely.
Fixes: 9bdcb44e391d ("cpufreq: schedutil: New governor based on scheduler utilization data") Cc: 4.7+ stable@vger.kernel.org # 4.7+ Signed-off-by: Kevin Hao haokexin@gmail.com Acked-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
kernel/sched/cpufreq_schedutil.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
--- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -536,9 +536,17 @@ static struct attribute *sugov_attrs[] = }; ATTRIBUTE_GROUPS(sugov); +static void sugov_tunables_free(struct kobject *kobj) +{
- struct gov_attr_set *attr_set = container_of(kobj, struct gov_attr_set, kobj);
- kfree(to_sugov_tunables(attr_set));
+}
- static struct kobj_type sugov_tunables_ktype = { .default_groups = sugov_groups, .sysfs_ops = &governor_sysfs_ops,
- .release = &sugov_tunables_free, };
/********************** cpufreq governor interface *********************/ @@ -638,12 +646,10 @@ static struct sugov_tunables *sugov_tuna return tunables; } -static void sugov_tunables_free(struct sugov_tunables *tunables) +static void sugov_clear_global_tunables(void) { if (!have_governor_per_policy()) global_tunables = NULL;
- kfree(tunables); }
static int sugov_init(struct cpufreq_policy *policy) @@ -706,7 +712,7 @@ out: fail: kobject_put(&tunables->attr_set.kobj); policy->governor_data = NULL;
- sugov_tunables_free(tunables);
- sugov_clear_global_tunables();
stop_kthread: sugov_kthread_stop(sg_policy); @@ -733,7 +739,7 @@ static void sugov_exit(struct cpufreq_po count = gov_attr_set_put(&tunables->attr_set, &sg_policy->tunables_hook); policy->governor_data = NULL; if (!count)
sugov_tunables_free(tunables);
sugov_clear_global_tunables();
mutex_unlock(&global_tunables_lock);
Please defer adding this one.
On Thu, Sep 16, 2021 at 06:55:49PM +0200, Rafael J. Wysocki wrote:
On 9/16/2021 5:56 PM, Greg Kroah-Hartman wrote:
From: Kevin Hao haokexin@gmail.com
commit e5c6b312ce3cc97e90ea159446e6bfa06645364d upstream.
The struct sugov_tunables is protected by the kobject, so we can't free it directly. Otherwise we would get a call trace like this: ODEBUG: free active (active state 0) object type: timer_list hint: delayed_work_timer_fn+0x0/0x30 WARNING: CPU: 3 PID: 720 at lib/debugobjects.c:505 debug_print_object+0xb8/0x100 Modules linked in: CPU: 3 PID: 720 Comm: a.sh Tainted: G W 5.14.0-rc1-next-20210715-yocto-standard+ #507 Hardware name: Marvell OcteonTX CN96XX board (DT) pstate: 40400009 (nZcv daif +PAN -UAO -TCO BTYPE=--) pc : debug_print_object+0xb8/0x100 lr : debug_print_object+0xb8/0x100 sp : ffff80001ecaf910 x29: ffff80001ecaf910 x28: ffff00011b10b8d0 x27: ffff800011043d80 x26: ffff00011a8f0000 x25: ffff800013cb3ff0 x24: 0000000000000000 x23: ffff80001142aa68 x22: ffff800011043d80 x21: ffff00010de46f20 x20: ffff800013c0c520 x19: ffff800011d8f5b0 x18: 0000000000000010 x17: 6e6968207473696c x16: 5f72656d6974203a x15: 6570797420746365 x14: 6a626f2029302065 x13: 303378302f307830 x12: 2b6e665f72656d69 x11: ffff8000124b1560 x10: ffff800012331520 x9 : ffff8000100ca6b0 x8 : 000000000017ffe8 x7 : c0000000fffeffff x6 : 0000000000000001 x5 : ffff800011d8c000 x4 : ffff800011d8c740 x3 : 0000000000000000 x2 : ffff0001108301c0 x1 : ab3c90eedf9c0f00 x0 : 0000000000000000 Call trace: debug_print_object+0xb8/0x100 __debug_check_no_obj_freed+0x1c0/0x230 debug_check_no_obj_freed+0x20/0x88 slab_free_freelist_hook+0x154/0x1c8 kfree+0x114/0x5d0 sugov_exit+0xbc/0xc0 cpufreq_exit_governor+0x44/0x90 cpufreq_set_policy+0x268/0x4a8 store_scaling_governor+0xe0/0x128 store+0xc0/0xf0 sysfs_kf_write+0x54/0x80 kernfs_fop_write_iter+0x128/0x1c0 new_sync_write+0xf0/0x190 vfs_write+0x2d4/0x478 ksys_write+0x74/0x100 __arm64_sys_write+0x24/0x30 invoke_syscall.constprop.0+0x54/0xe0 do_el0_svc+0x64/0x158 el0_svc+0x2c/0xb0 el0t_64_sync_handler+0xb0/0xb8 el0t_64_sync+0x198/0x19c irq event stamp: 5518 hardirqs last enabled at (5517): [<ffff8000100cbd7c>] console_unlock+0x554/0x6c8 hardirqs last disabled at (5518): [<ffff800010fc0638>] el1_dbg+0x28/0xa0 softirqs last enabled at (5504): [<ffff8000100106e0>] __do_softirq+0x4d0/0x6c0 softirqs last disabled at (5483): [<ffff800010049548>] irq_exit+0x1b0/0x1b8
So split the original sugov_tunables_free() into two functions, sugov_clear_global_tunables() is just used to clear the global_tunables and the new sugov_tunables_free() is used as kobj_type::release to release the sugov_tunables safely.
Fixes: 9bdcb44e391d ("cpufreq: schedutil: New governor based on scheduler utilization data") Cc: 4.7+ stable@vger.kernel.org # 4.7+ Signed-off-by: Kevin Hao haokexin@gmail.com Acked-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
kernel/sched/cpufreq_schedutil.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
--- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -536,9 +536,17 @@ static struct attribute *sugov_attrs[] = }; ATTRIBUTE_GROUPS(sugov); +static void sugov_tunables_free(struct kobject *kobj) +{
- struct gov_attr_set *attr_set = container_of(kobj, struct gov_attr_set, kobj);
- kfree(to_sugov_tunables(attr_set));
+}
static struct kobj_type sugov_tunables_ktype = { .default_groups = sugov_groups, .sysfs_ops = &governor_sysfs_ops,
- .release = &sugov_tunables_free,
}; /********************** cpufreq governor interface *********************/ @@ -638,12 +646,10 @@ static struct sugov_tunables *sugov_tuna return tunables; } -static void sugov_tunables_free(struct sugov_tunables *tunables) +static void sugov_clear_global_tunables(void) { if (!have_governor_per_policy()) global_tunables = NULL;
- kfree(tunables);
} static int sugov_init(struct cpufreq_policy *policy) @@ -706,7 +712,7 @@ out: fail: kobject_put(&tunables->attr_set.kobj); policy->governor_data = NULL;
- sugov_tunables_free(tunables);
- sugov_clear_global_tunables();
stop_kthread: sugov_kthread_stop(sg_policy); @@ -733,7 +739,7 @@ static void sugov_exit(struct cpufreq_po count = gov_attr_set_put(&tunables->attr_set, &sg_policy->tunables_hook); policy->governor_data = NULL; if (!count)
sugov_tunables_free(tunables);
mutex_unlock(&global_tunables_lock);sugov_clear_global_tunables();
Please defer adding this one.
I'll drop, let us know when to bring it back.
On 9/17/2021 12:14 AM, Sasha Levin wrote:
On Thu, Sep 16, 2021 at 06:55:49PM +0200, Rafael J. Wysocki wrote:
On 9/16/2021 5:56 PM, Greg Kroah-Hartman wrote:
From: Kevin Hao haokexin@gmail.com
commit e5c6b312ce3cc97e90ea159446e6bfa06645364d upstream.
The struct sugov_tunables is protected by the kobject, so we can't free it directly. Otherwise we would get a call trace like this: ODEBUG: free active (active state 0) object type: timer_list hint: delayed_work_timer_fn+0x0/0x30 WARNING: CPU: 3 PID: 720 at lib/debugobjects.c:505 debug_print_object+0xb8/0x100 Modules linked in: CPU: 3 PID: 720 Comm: a.sh Tainted: G W 5.14.0-rc1-next-20210715-yocto-standard+ #507 Hardware name: Marvell OcteonTX CN96XX board (DT) pstate: 40400009 (nZcv daif +PAN -UAO -TCO BTYPE=--) pc : debug_print_object+0xb8/0x100 lr : debug_print_object+0xb8/0x100 sp : ffff80001ecaf910 x29: ffff80001ecaf910 x28: ffff00011b10b8d0 x27: ffff800011043d80 x26: ffff00011a8f0000 x25: ffff800013cb3ff0 x24: 0000000000000000 x23: ffff80001142aa68 x22: ffff800011043d80 x21: ffff00010de46f20 x20: ffff800013c0c520 x19: ffff800011d8f5b0 x18: 0000000000000010 x17: 6e6968207473696c x16: 5f72656d6974203a x15: 6570797420746365 x14: 6a626f2029302065 x13: 303378302f307830 x12: 2b6e665f72656d69 x11: ffff8000124b1560 x10: ffff800012331520 x9 : ffff8000100ca6b0 x8 : 000000000017ffe8 x7 : c0000000fffeffff x6 : 0000000000000001 x5 : ffff800011d8c000 x4 : ffff800011d8c740 x3 : 0000000000000000 x2 : ffff0001108301c0 x1 : ab3c90eedf9c0f00 x0 : 0000000000000000 Call trace: debug_print_object+0xb8/0x100 __debug_check_no_obj_freed+0x1c0/0x230 debug_check_no_obj_freed+0x20/0x88 slab_free_freelist_hook+0x154/0x1c8 kfree+0x114/0x5d0 sugov_exit+0xbc/0xc0 cpufreq_exit_governor+0x44/0x90 cpufreq_set_policy+0x268/0x4a8 store_scaling_governor+0xe0/0x128 store+0xc0/0xf0 sysfs_kf_write+0x54/0x80 kernfs_fop_write_iter+0x128/0x1c0 new_sync_write+0xf0/0x190 vfs_write+0x2d4/0x478 ksys_write+0x74/0x100 __arm64_sys_write+0x24/0x30 invoke_syscall.constprop.0+0x54/0xe0 do_el0_svc+0x64/0x158 el0_svc+0x2c/0xb0 el0t_64_sync_handler+0xb0/0xb8 el0t_64_sync+0x198/0x19c irq event stamp: 5518 hardirqs last enabled at (5517): [<ffff8000100cbd7c>] console_unlock+0x554/0x6c8 hardirqs last disabled at (5518): [<ffff800010fc0638>] el1_dbg+0x28/0xa0 softirqs last enabled at (5504): [<ffff8000100106e0>] __do_softirq+0x4d0/0x6c0 softirqs last disabled at (5483): [<ffff800010049548>] irq_exit+0x1b0/0x1b8
So split the original sugov_tunables_free() into two functions, sugov_clear_global_tunables() is just used to clear the global_tunables and the new sugov_tunables_free() is used as kobj_type::release to release the sugov_tunables safely.
Fixes: 9bdcb44e391d ("cpufreq: schedutil: New governor based on scheduler utilization data") Cc: 4.7+ stable@vger.kernel.org # 4.7+ Signed-off-by: Kevin Hao haokexin@gmail.com Acked-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
kernel/sched/cpufreq_schedutil.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
--- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -536,9 +536,17 @@ static struct attribute *sugov_attrs[] = }; ATTRIBUTE_GROUPS(sugov); +static void sugov_tunables_free(struct kobject *kobj) +{ + struct gov_attr_set *attr_set = container_of(kobj, struct gov_attr_set, kobj);
+ kfree(to_sugov_tunables(attr_set)); +}
static struct kobj_type sugov_tunables_ktype = { .default_groups = sugov_groups, .sysfs_ops = &governor_sysfs_ops, + .release = &sugov_tunables_free, }; /********************** cpufreq governor interface *********************/ @@ -638,12 +646,10 @@ static struct sugov_tunables *sugov_tuna return tunables; } -static void sugov_tunables_free(struct sugov_tunables *tunables) +static void sugov_clear_global_tunables(void) { if (!have_governor_per_policy()) global_tunables = NULL;
- kfree(tunables); } static int sugov_init(struct cpufreq_policy *policy) @@ -706,7 +712,7 @@ out: fail: kobject_put(&tunables->attr_set.kobj); policy->governor_data = NULL; - sugov_tunables_free(tunables); + sugov_clear_global_tunables(); stop_kthread: sugov_kthread_stop(sg_policy); @@ -733,7 +739,7 @@ static void sugov_exit(struct cpufreq_po count = gov_attr_set_put(&tunables->attr_set, &sg_policy->tunables_hook); policy->governor_data = NULL; if (!count) - sugov_tunables_free(tunables); + sugov_clear_global_tunables(); mutex_unlock(&global_tunables_lock);
Please defer adding this one.
I'll drop, let us know when to bring it back.
You've just picked up the commit that this one depends on ("cpufreq: schedutil: Destroy mutex before kobject_put() frees the memory".
From: Arne Welzel arne.welzel@corelight.com
commit 528b16bfc3ae5f11638e71b3b63a81f9999df727 upstream.
On systems with many cores using dm-crypt, heavy spinlock contention in percpu_counter_compare() can be observed when the page allocation limit for a given device is reached or close to be reached. This is due to percpu_counter_compare() taking a spinlock to compute an exact result on potentially many CPUs at the same time.
Switch to non-exact comparison of allocated and allowed pages by using the value returned by percpu_counter_read_positive() to avoid taking the percpu_counter spinlock.
This may over/under estimate the actual number of allocated pages by at most (batch-1) * num_online_cpus().
Currently, batch is bounded by 32. The system on which this issue was first observed has 256 CPUs and 512GB of RAM. With a 4k page size, this change may over/under estimate by 31MB. With ~10G (2%) allowed dm-crypt allocations, this seems an acceptable error. Certainly preferred over running into the spinlock contention.
This behavior was reproduced on an EC2 c5.24xlarge instance with 96 CPUs and 192GB RAM as follows, but can be provoked on systems with less CPUs as well.
* Disable swap * Tune vm settings to promote regular writeback $ echo 50 > /proc/sys/vm/dirty_expire_centisecs $ echo 25 > /proc/sys/vm/dirty_writeback_centisecs $ echo $((128 * 1024 * 1024)) > /proc/sys/vm/dirty_background_bytes
* Create 8 dmcrypt devices based on files on a tmpfs * Create and mount an ext4 filesystem on each crypt devices * Run stress-ng --hdd 8 within one of above filesystems
Total %system usage collected from sysstat goes to ~35%. Write throughput on the underlying loop device is ~2GB/s. perf profiling an individual kworker kcryptd thread shows the following profile, indicating spinlock contention in percpu_counter_compare():
99.98% 0.00% kworker/u193:46 [kernel.kallsyms] [k] ret_from_fork | --ret_from_fork kthread worker_thread | --99.92%--process_one_work | |--80.52%--kcryptd_crypt | | | |--62.58%--mempool_alloc | | | | | --62.24%--crypt_page_alloc | | | | | --61.51%--__percpu_counter_compare | | | | | --61.34%--__percpu_counter_sum | | | | | |--58.68%--_raw_spin_lock_irqsave | | | | | | | --58.30%--native_queued_spin_lock_slowpath | | | | | --0.69%--cpumask_next | | | | | --0.51%--_find_next_bit | | | |--10.61%--crypt_convert | | | | | |--6.05%--xts_crypt ...
After applying this patch and running the same test, %system usage is lowered to ~7% and write throughput on the loop device increases to ~2.7GB/s. perf report shows mempool_alloc() as ~8% rather than ~62% in the profile and not hitting the percpu_counter() spinlock anymore.
|--8.15%--mempool_alloc | | | |--3.93%--crypt_page_alloc | | | | | --3.75%--__alloc_pages | | | | | --3.62%--get_page_from_freelist | | | | | --3.22%--rmqueue_bulk | | | | | --2.59%--_raw_spin_lock | | | | | --2.57%--native_queued_spin_lock_slowpath | | | --3.05%--_raw_spin_lock_irqsave | | | --2.49%--native_queued_spin_lock_slowpath
Suggested-by: DJ Gregor dj@corelight.com Reviewed-by: Mikulas Patocka mpatocka@redhat.com Signed-off-by: Arne Welzel arne.welzel@corelight.com Fixes: 5059353df86e ("dm crypt: limit the number of allocated pages") Cc: stable@vger.kernel.org Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/dm-crypt.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
--- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -2661,7 +2661,12 @@ static void *crypt_page_alloc(gfp_t gfp_ struct crypt_config *cc = pool_data; struct page *page;
- if (unlikely(percpu_counter_compare(&cc->n_allocated_pages, dm_crypt_pages_per_client) >= 0) && + /* + * Note, percpu_counter_read_positive() may over (and under) estimate + * the current usage by at most (batch - 1) * num_online_cpus() pages, + * but avoids potential spinlock contention of an exact result. + */ + if (unlikely(percpu_counter_read_positive(&cc->n_allocated_pages) >= dm_crypt_pages_per_client) && likely(gfp_mask & __GFP_NORETRY)) return NULL;
From: Brijesh Singh brijesh.singh@amd.com
commit 5441a07a127f106c9936e4f9fa1a8a93e3f31828 upstream.
The commit 97f9ac3db6612 ("crypto: ccp - Add support for SEV-ES to the PSP driver") added support to allocate Trusted Memory Region (TMR) used during the SEV-ES firmware initialization. The TMR gets locked during the firmware initialization and unlocked during the shutdown. While the TMR is locked, access to it is disallowed.
Currently, the CCP driver does not shutdown the firmware during the kexec reboot, leaving the TMR memory locked.
Register a callback to shutdown the SEV firmware on the kexec boot.
Fixes: 97f9ac3db6612 ("crypto: ccp - Add support for SEV-ES to the PSP driver") Reported-by: Lucas Nussbaum lucas.nussbaum@inria.fr Tested-by: Lucas Nussbaum lucas.nussbaum@inria.fr Cc: stable@kernel.org Cc: Tom Lendacky thomas.lendacky@amd.com Cc: Joerg Roedel jroedel@suse.de Cc: Herbert Xu herbert@gondor.apana.org.au Cc: David Rientjes rientjes@google.com Signed-off-by: Brijesh Singh brijesh.singh@amd.com Acked-by: Tom Lendacky thomas.lendacky@gmail.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/crypto/ccp/sev-dev.c | 49 ++++++++++++++++++++----------------------- drivers/crypto/ccp/sp-pci.c | 12 ++++++++++ 2 files changed, 35 insertions(+), 26 deletions(-)
--- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -300,6 +300,9 @@ static int __sev_platform_shutdown_locke struct sev_device *sev = psp_master->sev_data; int ret;
+ if (sev->state == SEV_STATE_UNINIT) + return 0; + ret = __sev_do_cmd_locked(SEV_CMD_SHUTDOWN, NULL, error); if (ret) return ret; @@ -1019,6 +1022,20 @@ e_err: return ret; }
+static void sev_firmware_shutdown(struct sev_device *sev) +{ + sev_platform_shutdown(NULL); + + if (sev_es_tmr) { + /* The TMR area was encrypted, flush it from the cache */ + wbinvd_on_all_cpus(); + + free_pages((unsigned long)sev_es_tmr, + get_order(SEV_ES_TMR_SIZE)); + sev_es_tmr = NULL; + } +} + void sev_dev_destroy(struct psp_device *psp) { struct sev_device *sev = psp->sev_data; @@ -1026,6 +1043,8 @@ void sev_dev_destroy(struct psp_device * if (!sev) return;
+ sev_firmware_shutdown(sev); + if (sev->misc) kref_put(&misc_dev->refcount, sev_exit);
@@ -1056,21 +1075,6 @@ void sev_pci_init(void) if (sev_get_api_version()) goto err;
- /* - * If platform is not in UNINIT state then firmware upgrade and/or - * platform INIT command will fail. These command require UNINIT state. - * - * In a normal boot we should never run into case where the firmware - * is not in UNINIT state on boot. But in case of kexec boot, a reboot - * may not go through a typical shutdown sequence and may leave the - * firmware in INIT or WORKING state. - */ - - if (sev->state != SEV_STATE_UNINIT) { - sev_platform_shutdown(NULL); - sev->state = SEV_STATE_UNINIT; - } - if (sev_version_greater_or_equal(0, 15) && sev_update_firmware(sev->dev) == 0) sev_get_api_version(); @@ -1115,17 +1119,10 @@ err:
void sev_pci_exit(void) { - if (!psp_master->sev_data) - return; - - sev_platform_shutdown(NULL); + struct sev_device *sev = psp_master->sev_data;
- if (sev_es_tmr) { - /* The TMR area was encrypted, flush it from the cache */ - wbinvd_on_all_cpus(); + if (!sev) + return;
- free_pages((unsigned long)sev_es_tmr, - get_order(SEV_ES_TMR_SIZE)); - sev_es_tmr = NULL; - } + sev_firmware_shutdown(sev); } --- a/drivers/crypto/ccp/sp-pci.c +++ b/drivers/crypto/ccp/sp-pci.c @@ -241,6 +241,17 @@ e_err: return ret; }
+static void sp_pci_shutdown(struct pci_dev *pdev) +{ + struct device *dev = &pdev->dev; + struct sp_device *sp = dev_get_drvdata(dev); + + if (!sp) + return; + + sp_destroy(sp); +} + static void sp_pci_remove(struct pci_dev *pdev) { struct device *dev = &pdev->dev; @@ -371,6 +382,7 @@ static struct pci_driver sp_pci_driver = .id_table = sp_pci_table, .probe = sp_pci_probe, .remove = sp_pci_remove, + .shutdown = sp_pci_shutdown, .driver.pm = &sp_pci_pm_ops, };
From: Eddie James eajames@linux.ibm.com
commit 34d34a56a5ea1e54a5af4f34c6ac9df724129351 upstream.
Security changes have forced the SPI controllers to be limited to 8 byte reads. Refactor the sequencing to just handle 8 bytes at a time.
Signed-off-by: Eddie James eajames@linux.ibm.com Link: https://lore.kernel.org/r/20210716133915.14697-2-eajames@linux.ibm.com Signed-off-by: Mark Brown broonie@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/spi/spi-fsi.c | 125 ++++++++------------------------------------------ 1 file changed, 22 insertions(+), 103 deletions(-)
--- a/drivers/spi/spi-fsi.c +++ b/drivers/spi/spi-fsi.c @@ -25,16 +25,11 @@
#define SPI_FSI_BASE 0x70000 #define SPI_FSI_INIT_TIMEOUT_MS 1000 -#define SPI_FSI_MAX_XFR_SIZE 2048 -#define SPI_FSI_MAX_XFR_SIZE_RESTRICTED 8 +#define SPI_FSI_MAX_RX_SIZE 8 +#define SPI_FSI_MAX_TX_SIZE 40
#define SPI_FSI_ERROR 0x0 #define SPI_FSI_COUNTER_CFG 0x1 -#define SPI_FSI_COUNTER_CFG_LOOPS(x) (((u64)(x) & 0xffULL) << 32) -#define SPI_FSI_COUNTER_CFG_N2_RX BIT_ULL(8) -#define SPI_FSI_COUNTER_CFG_N2_TX BIT_ULL(9) -#define SPI_FSI_COUNTER_CFG_N2_IMPLICIT BIT_ULL(10) -#define SPI_FSI_COUNTER_CFG_N2_RELOAD BIT_ULL(11) #define SPI_FSI_CFG1 0x2 #define SPI_FSI_CLOCK_CFG 0x3 #define SPI_FSI_CLOCK_CFG_MM_ENABLE BIT_ULL(32) @@ -76,8 +71,6 @@ struct fsi_spi { struct device *dev; /* SPI controller device */ struct fsi_device *fsi; /* FSI2SPI CFAM engine device */ u32 base; - size_t max_xfr_size; - bool restricted; };
struct fsi_spi_sequence { @@ -241,7 +234,7 @@ static int fsi_spi_reset(struct fsi_spi return fsi_spi_write_reg(ctx, SPI_FSI_STATUS, 0ULL); }
-static int fsi_spi_sequence_add(struct fsi_spi_sequence *seq, u8 val) +static void fsi_spi_sequence_add(struct fsi_spi_sequence *seq, u8 val) { /* * Add the next byte of instruction to the 8-byte sequence register. @@ -251,8 +244,6 @@ static int fsi_spi_sequence_add(struct f */ seq->data |= (u64)val << seq->bit; seq->bit -= 8; - - return ((64 - seq->bit) / 8) - 2; }
static void fsi_spi_sequence_init(struct fsi_spi_sequence *seq) @@ -261,71 +252,11 @@ static void fsi_spi_sequence_init(struct seq->data = 0ULL; }
-static int fsi_spi_sequence_transfer(struct fsi_spi *ctx, - struct fsi_spi_sequence *seq, - struct spi_transfer *transfer) -{ - int loops; - int idx; - int rc; - u8 val = 0; - u8 len = min(transfer->len, 8U); - u8 rem = transfer->len % len; - - loops = transfer->len / len; - - if (transfer->tx_buf) { - val = SPI_FSI_SEQUENCE_SHIFT_OUT(len); - idx = fsi_spi_sequence_add(seq, val); - - if (rem) - rem = SPI_FSI_SEQUENCE_SHIFT_OUT(rem); - } else if (transfer->rx_buf) { - val = SPI_FSI_SEQUENCE_SHIFT_IN(len); - idx = fsi_spi_sequence_add(seq, val); - - if (rem) - rem = SPI_FSI_SEQUENCE_SHIFT_IN(rem); - } else { - return -EINVAL; - } - - if (ctx->restricted && loops > 1) { - dev_warn(ctx->dev, - "Transfer too large; no branches permitted.\n"); - return -EINVAL; - } - - if (loops > 1) { - u64 cfg = SPI_FSI_COUNTER_CFG_LOOPS(loops - 1); - - fsi_spi_sequence_add(seq, SPI_FSI_SEQUENCE_BRANCH(idx)); - - if (transfer->rx_buf) - cfg |= SPI_FSI_COUNTER_CFG_N2_RX | - SPI_FSI_COUNTER_CFG_N2_TX | - SPI_FSI_COUNTER_CFG_N2_IMPLICIT | - SPI_FSI_COUNTER_CFG_N2_RELOAD; - - rc = fsi_spi_write_reg(ctx, SPI_FSI_COUNTER_CFG, cfg); - if (rc) - return rc; - } else { - fsi_spi_write_reg(ctx, SPI_FSI_COUNTER_CFG, 0ULL); - } - - if (rem) - fsi_spi_sequence_add(seq, rem); - - return 0; -} - static int fsi_spi_transfer_data(struct fsi_spi *ctx, struct spi_transfer *transfer) { int rc = 0; u64 status = 0ULL; - u64 cfg = 0ULL;
if (transfer->tx_buf) { int nb; @@ -363,16 +294,6 @@ static int fsi_spi_transfer_data(struct u64 in = 0ULL; u8 *rx = transfer->rx_buf;
- rc = fsi_spi_read_reg(ctx, SPI_FSI_COUNTER_CFG, &cfg); - if (rc) - return rc; - - if (cfg & SPI_FSI_COUNTER_CFG_N2_IMPLICIT) { - rc = fsi_spi_write_reg(ctx, SPI_FSI_DATA_TX, 0); - if (rc) - return rc; - } - while (transfer->len > recv) { do { rc = fsi_spi_read_reg(ctx, SPI_FSI_STATUS, @@ -439,6 +360,10 @@ static int fsi_spi_transfer_init(struct } } while (seq_state && (seq_state != SPI_FSI_STATUS_SEQ_STATE_IDLE));
+ rc = fsi_spi_write_reg(ctx, SPI_FSI_COUNTER_CFG, 0ULL); + if (rc) + return rc; + rc = fsi_spi_read_reg(ctx, SPI_FSI_CLOCK_CFG, &clock_cfg); if (rc) return rc; @@ -459,6 +384,7 @@ static int fsi_spi_transfer_one_message( { int rc; u8 seq_slave = SPI_FSI_SEQUENCE_SEL_SLAVE(mesg->spi->chip_select + 1); + unsigned int len; struct spi_transfer *transfer; struct fsi_spi *ctx = spi_controller_get_devdata(ctlr);
@@ -471,8 +397,7 @@ static int fsi_spi_transfer_one_message( struct spi_transfer *next = NULL;
/* Sequencer must do shift out (tx) first. */ - if (!transfer->tx_buf || - transfer->len > (ctx->max_xfr_size + 8)) { + if (!transfer->tx_buf || transfer->len > SPI_FSI_MAX_TX_SIZE) { rc = -EINVAL; goto error; } @@ -486,9 +411,13 @@ static int fsi_spi_transfer_one_message( fsi_spi_sequence_init(&seq); fsi_spi_sequence_add(&seq, seq_slave);
- rc = fsi_spi_sequence_transfer(ctx, &seq, transfer); - if (rc) - goto error; + len = transfer->len; + while (len > 8) { + fsi_spi_sequence_add(&seq, + SPI_FSI_SEQUENCE_SHIFT_OUT(8)); + len -= 8; + } + fsi_spi_sequence_add(&seq, SPI_FSI_SEQUENCE_SHIFT_OUT(len));
if (!list_is_last(&transfer->transfer_list, &mesg->transfers)) { @@ -496,7 +425,9 @@ static int fsi_spi_transfer_one_message(
/* Sequencer can only do shift in (rx) after tx. */ if (next->rx_buf) { - if (next->len > ctx->max_xfr_size) { + u8 shift; + + if (next->len > SPI_FSI_MAX_RX_SIZE) { rc = -EINVAL; goto error; } @@ -504,10 +435,8 @@ static int fsi_spi_transfer_one_message( dev_dbg(ctx->dev, "Sequence rx of %d bytes.\n", next->len);
- rc = fsi_spi_sequence_transfer(ctx, &seq, - next); - if (rc) - goto error; + shift = SPI_FSI_SEQUENCE_SHIFT_IN(next->len); + fsi_spi_sequence_add(&seq, shift); } else { next = NULL; } @@ -541,9 +470,7 @@ error:
static size_t fsi_spi_max_transfer_size(struct spi_device *spi) { - struct fsi_spi *ctx = spi_controller_get_devdata(spi->controller); - - return ctx->max_xfr_size; + return SPI_FSI_MAX_RX_SIZE; }
static int fsi_spi_probe(struct device *dev) @@ -582,14 +509,6 @@ static int fsi_spi_probe(struct device * ctx->fsi = fsi; ctx->base = base + SPI_FSI_BASE;
- if (of_device_is_compatible(np, "ibm,fsi2spi-restricted")) { - ctx->restricted = true; - ctx->max_xfr_size = SPI_FSI_MAX_XFR_SIZE_RESTRICTED; - } else { - ctx->restricted = false; - ctx->max_xfr_size = SPI_FSI_MAX_XFR_SIZE; - } - rc = devm_spi_register_controller(dev, ctlr); if (rc) spi_controller_put(ctlr);
From: Wang Hai wanghai38@huawei.com
commit a30dc6cf0dc51419021550152e435736aaef8799 upstream.
I got a NULL pointer dereference report when doing fuzz test:
Call Trace: qp_release_pages+0xae/0x130 qp_host_unregister_user_memory.isra.25+0x2d/0x80 vmci_qp_broker_unmap+0x191/0x320 ? vmci_host_do_alloc_queuepair.isra.9+0x1c0/0x1c0 vmci_host_unlocked_ioctl+0x59f/0xd50 ? do_vfs_ioctl+0x14b/0xa10 ? tomoyo_file_ioctl+0x28/0x30 ? vmci_host_do_alloc_queuepair.isra.9+0x1c0/0x1c0 __x64_sys_ioctl+0xea/0x120 do_syscall_64+0x34/0xb0 entry_SYSCALL_64_after_hwframe+0x44/0xae
When a queue pair is created by the following call, it will not register the user memory if the page_store is NULL, and the entry->state will be set to VMCIQPB_CREATED_NO_MEM.
vmci_host_unlocked_ioctl vmci_host_do_alloc_queuepair vmci_qp_broker_alloc qp_broker_alloc qp_broker_create // set entry->state = VMCIQPB_CREATED_NO_MEM;
When unmapping this queue pair, qp_host_unregister_user_memory() will be called to unregister the non-existent user memory, which will result in a null pointer reference. It will also change VMCIQPB_CREATED_NO_MEM to VMCIQPB_CREATED_MEM, which should not be present in this operation.
Only when the qp broker has mem, it can unregister the user memory when unmapping the qp broker.
Only when the qp broker has no mem, it can register the user memory when mapping the qp broker.
Fixes: 06164d2b72aa ("VMCI: queue pairs implementation.") Cc: stable stable@vger.kernel.org Reported-by: Hulk Robot hulkci@huawei.com Reviewed-by: Jorgen Hansen jhansen@vmware.com Signed-off-by: Wang Hai wanghai38@huawei.com Link: https://lore.kernel.org/r/20210818124845.488312-1-wanghai38@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/misc/vmw_vmci/vmci_queue_pair.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/misc/vmw_vmci/vmci_queue_pair.c +++ b/drivers/misc/vmw_vmci/vmci_queue_pair.c @@ -2243,7 +2243,8 @@ int vmci_qp_broker_map(struct vmci_handl
result = VMCI_SUCCESS;
- if (context_id != VMCI_HOST_CONTEXT_ID) { + if (context_id != VMCI_HOST_CONTEXT_ID && + !QPBROKERSTATE_HAS_MEM(entry)) { struct vmci_qp_page_store page_store;
page_store.pages = guest_mem; @@ -2350,7 +2351,8 @@ int vmci_qp_broker_unmap(struct vmci_han goto out; }
- if (context_id != VMCI_HOST_CONTEXT_ID) { + if (context_id != VMCI_HOST_CONTEXT_ID && + QPBROKERSTATE_HAS_MEM(entry)) { qp_acquire_queue_mutex(entry->produce_q); result = qp_save_headers(entry); if (result < VMCI_SUCCESS)
From: Mauro Carvalho Chehab mchehab+huawei@kernel.org
commit 1a10d7fdb6d0e235e9d230916244cc2769d3f170 upstream.
As warned by smatch: drivers/media/usb/uvc/uvc_v4l2.c:911 uvc_ioctl_g_input() error: doing dma on the stack (&i) drivers/media/usb/uvc/uvc_v4l2.c:943 uvc_ioctl_s_input() error: doing dma on the stack (&i)
those two functions call uvc_query_ctrl passing a pointer to a data at the DMA stack. those are used to send URBs via usb_control_msg(). Using DMA stack is not supported and should not work anymore on modern Linux versions.
So, use a kmalloc'ed buffer.
Cc: stable@vger.kernel.org # Kernel 4.9 and upper Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/media/usb/uvc/uvc_v4l2.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-)
--- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -899,8 +899,8 @@ static int uvc_ioctl_g_input(struct file { struct uvc_fh *handle = fh; struct uvc_video_chain *chain = handle->chain; + u8 *buf; int ret; - u8 i;
if (chain->selector == NULL || (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { @@ -908,22 +908,27 @@ static int uvc_ioctl_g_input(struct file return 0; }
+ buf = kmalloc(1, GFP_KERNEL); + if (!buf) + return -ENOMEM; + ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, chain->selector->id, chain->dev->intfnum, UVC_SU_INPUT_SELECT_CONTROL, - &i, 1); - if (ret < 0) - return ret; + buf, 1); + if (!ret) + *input = *buf - 1;
- *input = i - 1; - return 0; + kfree(buf); + + return ret; }
static int uvc_ioctl_s_input(struct file *file, void *fh, unsigned int input) { struct uvc_fh *handle = fh; struct uvc_video_chain *chain = handle->chain; + u8 *buf; int ret; - u32 i;
ret = uvc_acquire_privileges(handle); if (ret < 0) @@ -939,10 +944,17 @@ static int uvc_ioctl_s_input(struct file if (input >= chain->selector->bNrInPins) return -EINVAL;
- i = input + 1; - return uvc_query_ctrl(chain->dev, UVC_SET_CUR, chain->selector->id, - chain->dev->intfnum, UVC_SU_INPUT_SELECT_CONTROL, - &i, 1); + buf = kmalloc(1, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + *buf = input + 1; + ret = uvc_query_ctrl(chain->dev, UVC_SET_CUR, chain->selector->id, + chain->dev->intfnum, UVC_SU_INPUT_SELECT_CONTROL, + buf, 1); + kfree(buf); + + return ret; }
static int uvc_ioctl_queryctrl(struct file *file, void *fh,
From: Sean Young sean@mess.org
commit 6b7f554be8c92319d7e6df92fd247ebb9beb4a45 upstream.
The LIRC_SET_TRANSMITTER_MASK ioctl should return the number of emitters if an invalid list was set.
Cc: stable@vger.kernel.org Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/media/rc/rc-loopback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/media/rc/rc-loopback.c +++ b/drivers/media/rc/rc-loopback.c @@ -42,7 +42,7 @@ static int loop_set_tx_mask(struct rc_de
if ((mask & (RXMASK_REGULAR | RXMASK_LEARNING)) != mask) { dprintk("invalid tx mask: %u\n", mask); - return -EINVAL; + return 2; }
dprintk("setting tx mask: %u\n", mask);
From: Srinivas Kandagatla srinivas.kandagatla@linaro.org
commit de0534df93474f268486c486ea7e01b44a478026 upstream.
Current error path on failure of validating keepout regions is calling put_device, eventhough the device is not even registered at that point.
Fix this by adding proper error handling of freeing ida and nvmem.
Fixes: fd3bb8f54a88 ("nvmem: core: Add support for keepout regions") Cc: stable@vger.kernel.org Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20210806085947.22682-5-srinivas.kandagatla@linaro.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/nvmem/core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
--- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -818,8 +818,11 @@ struct nvmem_device *nvmem_register(cons
if (nvmem->nkeepout) { rval = nvmem_validate_keepouts(nvmem); - if (rval) - goto err_put_device; + if (rval) { + ida_free(&nvmem_ida, nvmem->id); + kfree(nvmem); + return ERR_PTR(rval); + } }
dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
From: Julian Wiedmann jwi@linux.ibm.com
commit 2c197870e4701610ec3b1143808d4e31152caf30 upstream.
When qdio_establish() times out while waiting for the ESTABLISH ccw to complete, it calls qdio_shutdown() to roll back all of its previous actions. But at this point the qdio_irq's state is still QDIO_IRQ_STATE_INACTIVE, so qdio_shutdown() will exit immediately without doing any actual work.
Which means that eg. the qdio_irq's thinint-indicator stays registered, and cdev->handler isn't restored to its old value. And since commit 954d6235be41 ("s390/qdio: make thinint registration symmetric") the qdio_irq also stays on the tiq_list, so on the next qdio_establish() we might get a helpful BUG from the list-debugging code:
... [ 4633.512591] list_add double add: new=00000000005a4110, prev=00000001b357db78, next=00000000005a4110. [ 4633.512621] ------------[ cut here ]------------ [ 4633.512623] kernel BUG at lib/list_debug.c:29! ... [ 4633.512796] [<00000001b2c6ee9a>] __list_add_valid+0x82/0xa0 [ 4633.512798] ([<00000001b2c6ee96>] __list_add_valid+0x7e/0xa0) [ 4633.512800] [<00000001b2fcecce>] qdio_establish_thinint+0x116/0x190 [ 4633.512805] [<00000001b2fcbe58>] qdio_establish+0x128/0x498 ...
Fix this by extracting a goto-chain from the existing error exits in qdio_establish(), and check the return value of the wait_event_...() to detect the timeout condition.
Fixes: 779e6e1c724d ("[S390] qdio: new qdio driver.") Root-caused-by: Benjamin Block bblock@linux.ibm.com Signed-off-by: Julian Wiedmann jwi@linux.ibm.com Reviewed-by: Benjamin Block bblock@linux.ibm.com Cc: stable@vger.kernel.org # 2.6.27 Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/s390/cio/qdio_main.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-)
--- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -1079,6 +1079,7 @@ int qdio_establish(struct ccw_device *cd { struct qdio_irq *irq_ptr = cdev->private->qdio_data; struct subchannel_id schid; + long timeout; int rc;
ccw_device_get_schid(cdev, &schid); @@ -1107,11 +1108,8 @@ int qdio_establish(struct ccw_device *cd qdio_setup_irq(irq_ptr, init_data);
rc = qdio_establish_thinint(irq_ptr); - if (rc) { - qdio_shutdown_irq(irq_ptr); - mutex_unlock(&irq_ptr->setup_mutex); - return rc; - } + if (rc) + goto err_thinint;
/* establish q */ irq_ptr->ccw.cmd_code = irq_ptr->equeue.cmd; @@ -1127,15 +1125,16 @@ int qdio_establish(struct ccw_device *cd if (rc) { DBF_ERROR("%4x est IO ERR", irq_ptr->schid.sch_no); DBF_ERROR("rc:%4x", rc); - qdio_shutdown_thinint(irq_ptr); - qdio_shutdown_irq(irq_ptr); - mutex_unlock(&irq_ptr->setup_mutex); - return rc; + goto err_ccw_start; }
- wait_event_interruptible_timeout(cdev->private->wait_q, - irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED || - irq_ptr->state == QDIO_IRQ_STATE_ERR, HZ); + timeout = wait_event_interruptible_timeout(cdev->private->wait_q, + irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED || + irq_ptr->state == QDIO_IRQ_STATE_ERR, HZ); + if (timeout <= 0) { + rc = (timeout == -ERESTARTSYS) ? -EINTR : -ETIME; + goto err_ccw_timeout; + }
if (irq_ptr->state != QDIO_IRQ_STATE_ESTABLISHED) { mutex_unlock(&irq_ptr->setup_mutex); @@ -1152,6 +1151,14 @@ int qdio_establish(struct ccw_device *cd qdio_print_subchannel_info(irq_ptr); qdio_setup_debug_entries(irq_ptr); return 0; + +err_ccw_timeout: +err_ccw_start: + qdio_shutdown_thinint(irq_ptr); +err_thinint: + qdio_shutdown_irq(irq_ptr); + mutex_unlock(&irq_ptr->setup_mutex); + return rc; } EXPORT_SYMBOL_GPL(qdio_establish);
From: Julian Wiedmann jwi@linux.ibm.com
commit 1c1dc8bda3a05c60877a6649775894db5343bdea upstream.
When the ESTABLISH ccw does not complete within the specified timeout, try our best to cancel the ccw program that is still active on the device. Otherwise the IO subsystem might be accessing it even after the driver eg. called qdio_free().
Fixes: 779e6e1c724d ("[S390] qdio: new qdio driver.") Signed-off-by: Julian Wiedmann jwi@linux.ibm.com Reviewed-by: Benjamin Block bblock@linux.ibm.com Cc: stable@vger.kernel.org # 2.6.27 Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/s390/cio/qdio_main.c | 51 +++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 21 deletions(-)
--- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -886,6 +886,33 @@ static void qdio_shutdown_queues(struct } }
+static int qdio_cancel_ccw(struct qdio_irq *irq, int how) +{ + struct ccw_device *cdev = irq->cdev; + int rc; + + spin_lock_irq(get_ccwdev_lock(cdev)); + qdio_set_state(irq, QDIO_IRQ_STATE_CLEANUP); + if (how & QDIO_FLAG_CLEANUP_USING_CLEAR) + rc = ccw_device_clear(cdev, QDIO_DOING_CLEANUP); + else + /* default behaviour is halt */ + rc = ccw_device_halt(cdev, QDIO_DOING_CLEANUP); + spin_unlock_irq(get_ccwdev_lock(cdev)); + if (rc) { + DBF_ERROR("%4x SHUTD ERR", irq->schid.sch_no); + DBF_ERROR("rc:%4d", rc); + return rc; + } + + wait_event_interruptible_timeout(cdev->private->wait_q, + irq->state == QDIO_IRQ_STATE_INACTIVE || + irq->state == QDIO_IRQ_STATE_ERR, + 10 * HZ); + + return 0; +} + /** * qdio_shutdown - shut down a qdio subchannel * @cdev: associated ccw device @@ -923,27 +950,7 @@ int qdio_shutdown(struct ccw_device *cde qdio_shutdown_queues(irq_ptr); qdio_shutdown_debug_entries(irq_ptr);
- /* cleanup subchannel */ - spin_lock_irq(get_ccwdev_lock(cdev)); - qdio_set_state(irq_ptr, QDIO_IRQ_STATE_CLEANUP); - if (how & QDIO_FLAG_CLEANUP_USING_CLEAR) - rc = ccw_device_clear(cdev, QDIO_DOING_CLEANUP); - else - /* default behaviour is halt */ - rc = ccw_device_halt(cdev, QDIO_DOING_CLEANUP); - spin_unlock_irq(get_ccwdev_lock(cdev)); - if (rc) { - DBF_ERROR("%4x SHUTD ERR", irq_ptr->schid.sch_no); - DBF_ERROR("rc:%4d", rc); - goto no_cleanup; - } - - wait_event_interruptible_timeout(cdev->private->wait_q, - irq_ptr->state == QDIO_IRQ_STATE_INACTIVE || - irq_ptr->state == QDIO_IRQ_STATE_ERR, - 10 * HZ); - -no_cleanup: + rc = qdio_cancel_ccw(irq_ptr, how); qdio_shutdown_thinint(irq_ptr); qdio_shutdown_irq(irq_ptr);
@@ -1153,10 +1160,12 @@ int qdio_establish(struct ccw_device *cd return 0;
err_ccw_timeout: + qdio_cancel_ccw(irq_ptr, QDIO_FLAG_CLEANUP_USING_CLEAR); err_ccw_start: qdio_shutdown_thinint(irq_ptr); err_thinint: qdio_shutdown_irq(irq_ptr); + qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE); mutex_unlock(&irq_ptr->setup_mutex); return rc; }
From: Robin Gong yibin.gong@nxp.com
commit 8592f02464d52776c5cfae4627c6413b0ae7602d upstream.
This reverts commit ad0d92d7ba6aecbe2705907c38ff8d8be4da1e9c, because in spi-imx case, burst length may be changed dynamically.
Fixes: ad0d92d7ba6a ("dmaengine: imx-sdma: refine to load context only once") Cc: stable@vger.kernel.org Signed-off-by: Robin Gong yibin.gong@nxp.com Acked-by: Sascha Hauer s.hauer@pengutronix.de Tested-by: Richard Leitner richard.leitner@skidata.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/dma/imx-sdma.c | 8 -------- 1 file changed, 8 deletions(-)
--- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -379,7 +379,6 @@ struct sdma_channel { unsigned long watermark_level; u32 shp_addr, per_addr; enum dma_status status; - bool context_loaded; struct imx_dma_data data; struct work_struct terminate_worker; }; @@ -954,9 +953,6 @@ static int sdma_load_context(struct sdma int ret; unsigned long flags;
- if (sdmac->context_loaded) - return 0; - if (sdmac->direction == DMA_DEV_TO_MEM) load_address = sdmac->pc_from_device; else if (sdmac->direction == DMA_DEV_TO_DEV) @@ -999,8 +995,6 @@ static int sdma_load_context(struct sdma
spin_unlock_irqrestore(&sdma->channel_0_lock, flags);
- sdmac->context_loaded = true; - return ret; }
@@ -1039,7 +1033,6 @@ static void sdma_channel_terminate_work( vchan_get_all_descriptors(&sdmac->vc, &head); spin_unlock_irqrestore(&sdmac->vc.lock, flags); vchan_dma_desc_free_list(&sdmac->vc, &head); - sdmac->context_loaded = false; }
static int sdma_terminate_all(struct dma_chan *chan) @@ -1307,7 +1300,6 @@ static void sdma_free_chan_resources(str
sdmac->event_id0 = 0; sdmac->event_id1 = 0; - sdmac->context_loaded = false;
sdma_set_channel_priority(sdmac, 0);
From: Robin Gong yibin.gong@nxp.com
commit e555a03b112838883fdd8185d613c35d043732f2 upstream.
Since sdma_transfer_init() will do sdma_load_context before any sdma transfer, no need once more in sdma_config_channel().
Fixes: ad0d92d7ba6a ("dmaengine: imx-sdma: refine to load context only once") Cc: stable@vger.kernel.org Signed-off-by: Robin Gong yibin.gong@nxp.com Acked-by: Vinod Koul vkoul@kernel.org Tested-by: Richard Leitner richard.leitner@skidata.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/dma/imx-sdma.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
--- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -1107,7 +1107,6 @@ static void sdma_set_watermarklevel_for_ static int sdma_config_channel(struct dma_chan *chan) { struct sdma_channel *sdmac = to_sdma_chan(chan); - int ret;
sdma_disable_channel(chan);
@@ -1147,9 +1146,7 @@ static int sdma_config_channel(struct dm sdmac->watermark_level = 0; /* FIXME: M3_BASE_ADDRESS */ }
- ret = sdma_load_context(sdmac); - - return ret; + return 0; }
static int sdma_set_channel_priority(struct sdma_channel *sdmac,
From: Pavel Begunkov asml.silence@gmail.com
commit 0bea96f59ba40e63c0ae93ad6a02417b95f22f4d upstream.
Fixed tables may be large enough, place all of them together with allocated tags under memcg limits.
Cc: stable@vger.kernel.org Signed-off-by: Pavel Begunkov asml.silence@gmail.com Link: https://lore.kernel.org/r/b3ac9f5da9821bb59837b5fe25e8ef4be982218c.162945168... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/io_uring.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -7195,11 +7195,11 @@ static struct io_rsrc_data *io_rsrc_data { struct io_rsrc_data *data;
- data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT); if (!data) return NULL;
- data->tags = kvcalloc(nr, sizeof(*data->tags), GFP_KERNEL); + data->tags = kvcalloc(nr, sizeof(*data->tags), GFP_KERNEL_ACCOUNT); if (!data->tags) { kfree(data); return NULL; @@ -7477,7 +7477,7 @@ static bool io_alloc_file_tables(struct { unsigned i, nr_tables = DIV_ROUND_UP(nr_files, IORING_MAX_FILES_TABLE);
- table->files = kcalloc(nr_tables, sizeof(*table->files), GFP_KERNEL); + table->files = kcalloc(nr_tables, sizeof(*table->files), GFP_KERNEL_ACCOUNT); if (!table->files) return false;
@@ -7485,7 +7485,7 @@ static bool io_alloc_file_tables(struct unsigned int this_files = min(nr_files, IORING_MAX_FILES_TABLE);
table->files[i] = kcalloc(this_files, sizeof(*table->files[i]), - GFP_KERNEL); + GFP_KERNEL_ACCOUNT); if (!table->files[i]) break; nr_files -= this_files;
From: Pavel Begunkov asml.silence@gmail.com
commit 26578cda3db983b17cabe4e577af26306beb9987 upstream.
->splice_fd_in is used only by splice/tee, but no other request checks it for validity. Add the check for most of request types excluding reads/writes/sends/recvs, we don't want overhead for them and can leave them be as is until the field is actually used.
Cc: stable@vger.kernel.org Signed-off-by: Pavel Begunkov asml.silence@gmail.com Link: https://lore.kernel.org/r/f44bc2acd6777d932de3d71a5692235b5b2b7397.162945168... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/io_uring.c | 52 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 22 deletions(-)
--- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -3474,7 +3474,7 @@ static int io_renameat_prep(struct io_ki
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) return -EINVAL; - if (sqe->ioprio || sqe->buf_index) + if (sqe->ioprio || sqe->buf_index || sqe->splice_fd_in) return -EINVAL; if (unlikely(req->flags & REQ_F_FIXED_FILE)) return -EBADF; @@ -3525,7 +3525,8 @@ static int io_unlinkat_prep(struct io_ki
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) return -EINVAL; - if (sqe->ioprio || sqe->off || sqe->len || sqe->buf_index) + if (sqe->ioprio || sqe->off || sqe->len || sqe->buf_index || + sqe->splice_fd_in) return -EINVAL; if (unlikely(req->flags & REQ_F_FIXED_FILE)) return -EBADF; @@ -3571,8 +3572,8 @@ static int io_shutdown_prep(struct io_ki #if defined(CONFIG_NET) if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) return -EINVAL; - if (sqe->ioprio || sqe->off || sqe->addr || sqe->rw_flags || - sqe->buf_index) + if (unlikely(sqe->ioprio || sqe->off || sqe->addr || sqe->rw_flags || + sqe->buf_index || sqe->splice_fd_in)) return -EINVAL;
req->shutdown.how = READ_ONCE(sqe->len); @@ -3720,7 +3721,8 @@ static int io_fsync_prep(struct io_kiocb
if (unlikely(ctx->flags & IORING_SETUP_IOPOLL)) return -EINVAL; - if (unlikely(sqe->addr || sqe->ioprio || sqe->buf_index)) + if (unlikely(sqe->addr || sqe->ioprio || sqe->buf_index || + sqe->splice_fd_in)) return -EINVAL;
req->sync.flags = READ_ONCE(sqe->fsync_flags); @@ -3753,7 +3755,8 @@ static int io_fsync(struct io_kiocb *req static int io_fallocate_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) { - if (sqe->ioprio || sqe->buf_index || sqe->rw_flags) + if (sqe->ioprio || sqe->buf_index || sqe->rw_flags || + sqe->splice_fd_in) return -EINVAL; if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) return -EINVAL; @@ -3784,7 +3787,7 @@ static int __io_openat_prep(struct io_ki const char __user *fname; int ret;
- if (unlikely(sqe->ioprio || sqe->buf_index)) + if (unlikely(sqe->ioprio || sqe->buf_index || sqe->splice_fd_in)) return -EINVAL; if (unlikely(req->flags & REQ_F_FIXED_FILE)) return -EBADF; @@ -3909,7 +3912,8 @@ static int io_remove_buffers_prep(struct struct io_provide_buf *p = &req->pbuf; u64 tmp;
- if (sqe->ioprio || sqe->rw_flags || sqe->addr || sqe->len || sqe->off) + if (sqe->ioprio || sqe->rw_flags || sqe->addr || sqe->len || sqe->off || + sqe->splice_fd_in) return -EINVAL;
tmp = READ_ONCE(sqe->fd); @@ -3980,7 +3984,7 @@ static int io_provide_buffers_prep(struc struct io_provide_buf *p = &req->pbuf; u64 tmp;
- if (sqe->ioprio || sqe->rw_flags) + if (sqe->ioprio || sqe->rw_flags || sqe->splice_fd_in) return -EINVAL;
tmp = READ_ONCE(sqe->fd); @@ -4067,7 +4071,7 @@ static int io_epoll_ctl_prep(struct io_k const struct io_uring_sqe *sqe) { #if defined(CONFIG_EPOLL) - if (sqe->ioprio || sqe->buf_index) + if (sqe->ioprio || sqe->buf_index || sqe->splice_fd_in) return -EINVAL; if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) return -EINVAL; @@ -4113,7 +4117,7 @@ static int io_epoll_ctl(struct io_kiocb static int io_madvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) { #if defined(CONFIG_ADVISE_SYSCALLS) && defined(CONFIG_MMU) - if (sqe->ioprio || sqe->buf_index || sqe->off) + if (sqe->ioprio || sqe->buf_index || sqe->off || sqe->splice_fd_in) return -EINVAL; if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) return -EINVAL; @@ -4148,7 +4152,7 @@ static int io_madvise(struct io_kiocb *r
static int io_fadvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) { - if (sqe->ioprio || sqe->buf_index || sqe->addr) + if (sqe->ioprio || sqe->buf_index || sqe->addr || sqe->splice_fd_in) return -EINVAL; if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) return -EINVAL; @@ -4186,7 +4190,7 @@ static int io_statx_prep(struct io_kiocb { if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) return -EINVAL; - if (sqe->ioprio || sqe->buf_index) + if (sqe->ioprio || sqe->buf_index || sqe->splice_fd_in) return -EINVAL; if (req->flags & REQ_F_FIXED_FILE) return -EBADF; @@ -4222,7 +4226,7 @@ static int io_close_prep(struct io_kiocb if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) return -EINVAL; if (sqe->ioprio || sqe->off || sqe->addr || sqe->len || - sqe->rw_flags || sqe->buf_index) + sqe->rw_flags || sqe->buf_index || sqe->splice_fd_in) return -EINVAL; if (req->flags & REQ_F_FIXED_FILE) return -EBADF; @@ -4283,7 +4287,8 @@ static int io_sfr_prep(struct io_kiocb *
if (unlikely(ctx->flags & IORING_SETUP_IOPOLL)) return -EINVAL; - if (unlikely(sqe->addr || sqe->ioprio || sqe->buf_index)) + if (unlikely(sqe->addr || sqe->ioprio || sqe->buf_index || + sqe->splice_fd_in)) return -EINVAL;
req->sync.off = READ_ONCE(sqe->off); @@ -4710,7 +4715,7 @@ static int io_accept_prep(struct io_kioc
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) return -EINVAL; - if (sqe->ioprio || sqe->len || sqe->buf_index) + if (sqe->ioprio || sqe->len || sqe->buf_index || sqe->splice_fd_in) return -EINVAL;
accept->addr = u64_to_user_ptr(READ_ONCE(sqe->addr)); @@ -4758,7 +4763,8 @@ static int io_connect_prep(struct io_kio
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) return -EINVAL; - if (sqe->ioprio || sqe->len || sqe->buf_index || sqe->rw_flags) + if (sqe->ioprio || sqe->len || sqe->buf_index || sqe->rw_flags || + sqe->splice_fd_in) return -EINVAL;
conn->addr = u64_to_user_ptr(READ_ONCE(sqe->addr)); @@ -5368,7 +5374,7 @@ static int io_poll_update_prep(struct io
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) return -EINVAL; - if (sqe->ioprio || sqe->buf_index) + if (sqe->ioprio || sqe->buf_index || sqe->splice_fd_in) return -EINVAL; flags = READ_ONCE(sqe->len); if (flags & ~(IORING_POLL_UPDATE_EVENTS | IORING_POLL_UPDATE_USER_DATA | @@ -5603,7 +5609,7 @@ static int io_timeout_remove_prep(struct return -EINVAL; if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT))) return -EINVAL; - if (sqe->ioprio || sqe->buf_index || sqe->len) + if (sqe->ioprio || sqe->buf_index || sqe->len || sqe->splice_fd_in) return -EINVAL;
tr->addr = READ_ONCE(sqe->addr); @@ -5662,7 +5668,8 @@ static int io_timeout_prep(struct io_kio
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) return -EINVAL; - if (sqe->ioprio || sqe->buf_index || sqe->len != 1) + if (sqe->ioprio || sqe->buf_index || sqe->len != 1 || + sqe->splice_fd_in) return -EINVAL; if (off && is_timeout_link) return -EINVAL; @@ -5811,7 +5818,8 @@ static int io_async_cancel_prep(struct i return -EINVAL; if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT))) return -EINVAL; - if (sqe->ioprio || sqe->off || sqe->len || sqe->cancel_flags) + if (sqe->ioprio || sqe->off || sqe->len || sqe->cancel_flags || + sqe->splice_fd_in) return -EINVAL;
req->cancel.addr = READ_ONCE(sqe->addr); @@ -5868,7 +5876,7 @@ static int io_rsrc_update_prep(struct io { if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT))) return -EINVAL; - if (sqe->ioprio || sqe->rw_flags) + if (sqe->ioprio || sqe->rw_flags || sqe->splice_fd_in) return -EINVAL;
req->rsrc_update.offset = READ_ONCE(sqe->off);
From: Pavel Begunkov asml.silence@gmail.com
commit dadebc350da2bef62593b1df007a6e0b90baf42a upstream.
WARNING: CPU: 1 PID: 5870 at fs/io_uring.c:5975 io_try_cancel_userdata+0x30f/0x540 fs/io_uring.c:5975 CPU: 0 PID: 5870 Comm: iou-wrk-5860 Not tainted 5.14.0-rc6-next-20210820-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:io_try_cancel_userdata+0x30f/0x540 fs/io_uring.c:5975 Call Trace: io_async_cancel fs/io_uring.c:6014 [inline] io_issue_sqe+0x22d5/0x65a0 fs/io_uring.c:6407 io_wq_submit_work+0x1dc/0x300 fs/io_uring.c:6511 io_worker_handle_work+0xa45/0x1840 fs/io-wq.c:533 io_wqe_worker+0x2cc/0xbb0 fs/io-wq.c:582 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:295
io_try_cancel_userdata() can be called from io_async_cancel() executing in the io-wq context, so the warning fires, which is there to alert anyone accessing task->io_uring->io_wq in a racy way. However, io_wq_put_and_exit() always first waits for all threads to complete, so the only detail left is to zero tctx->io_wq after the context is removed.
note: one little assumption is that when IO_WQ_WORK_CANCEL, the executor won't touch ->io_wq, because io_wq_destroy() might cancel left pending requests in such a way.
Cc: stable@vger.kernel.org Reported-by: syzbot+b0c9d1588ae92866515f@syzkaller.appspotmail.com Signed-off-by: Pavel Begunkov asml.silence@gmail.com Link: https://lore.kernel.org/r/dfdd37a80cfa9ffd3e59538929c99cdd55d8699e.162972175... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/io_uring.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -6289,6 +6289,7 @@ static void io_wq_submit_work(struct io_ if (timeout) io_queue_linked_timeout(timeout);
+ /* either cancelled or io-wq is dying, so don't touch tctx->iowq */ if (work->flags & IO_WQ_WORK_CANCEL) ret = -ECANCELED;
@@ -9098,8 +9099,8 @@ static void io_uring_clean_tctx(struct i * Must be after io_uring_del_task_file() (removes nodes under * uring_lock) to avoid race with io_uring_try_cancel_iowq(). */ - tctx->io_wq = NULL; io_wq_put_and_exit(wq); + tctx->io_wq = NULL; } }
From: Jens Axboe axboe@kernel.dk
commit 87df7fb922d18e96992aa5e824aa34b2065fef59 upstream.
When new work is added, io_wqe_enqueue() checks if we need to wake or create a new worker. But that check is done outside the lock that otherwise synchronizes us with a worker going to sleep, so we can end up in the following situation:
CPU0 CPU1 lock insert work unlock atomic_read(nr_running) != 0 lock atomic_dec(nr_running) no wakeup needed
Hold the wqe lock around the "need to wakeup" check. Then we can also get rid of the temporary work_flags variable, as we know the work will remain valid as long as we hold the lock.
Cc: stable@vger.kernel.org Reported-by: Andres Freund andres@anarazel.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/io-wq.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/fs/io-wq.c +++ b/fs/io-wq.c @@ -798,7 +798,7 @@ append: static void io_wqe_enqueue(struct io_wqe *wqe, struct io_wq_work *work) { struct io_wqe_acct *acct = io_work_get_acct(wqe, work); - int work_flags; + bool do_wake; unsigned long flags;
/* @@ -811,14 +811,14 @@ static void io_wqe_enqueue(struct io_wqe return; }
- work_flags = work->flags; raw_spin_lock_irqsave(&wqe->lock, flags); io_wqe_insert_work(wqe, work); wqe->flags &= ~IO_WQE_FLAG_STALLED; + do_wake = (work->flags & IO_WQ_WORK_CONCURRENT) || + !atomic_read(&acct->nr_running); raw_spin_unlock_irqrestore(&wqe->lock, flags);
- if ((work_flags & IO_WQ_WORK_CONCURRENT) || - !atomic_read(&acct->nr_running)) + if (do_wake) io_wqe_wake_worker(wqe, acct); }
From: Jens Axboe axboe@kernel.dk
commit 94ffb0a282872c2f4b14f757fa1aef2302aeaabb upstream.
The attempt to find and activate a free worker for new work is currently combined with creating a new one if we don't find one, but that opens io-wq up to a race where the worker that is found and activated can put itself to sleep without knowing that it has been selected to perform this new work.
Fix this by moving the activation into where we add the new work item, then we can retain it within the wqe->lock scope and elimiate the race with the worker itself checking inside the lock, but sleeping outside of it.
Cc: stable@vger.kernel.org Reported-by: Andres Freund andres@anarazel.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/io-wq.c | 50 ++++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 26 deletions(-)
--- a/fs/io-wq.c +++ b/fs/io-wq.c @@ -237,9 +237,9 @@ static bool io_wqe_activate_free_worker( * We need a worker. If we find a free one, we're good. If not, and we're * below the max number of workers, create one. */ -static void io_wqe_wake_worker(struct io_wqe *wqe, struct io_wqe_acct *acct) +static void io_wqe_create_worker(struct io_wqe *wqe, struct io_wqe_acct *acct) { - bool ret; + bool do_create = false, first = false;
/* * Most likely an attempt to queue unbounded work on an io_wq that @@ -248,25 +248,18 @@ static void io_wqe_wake_worker(struct io if (unlikely(!acct->max_workers)) pr_warn_once("io-wq is not configured for unbound workers");
- rcu_read_lock(); - ret = io_wqe_activate_free_worker(wqe); - rcu_read_unlock(); - - if (!ret) { - bool do_create = false, first = false; - - raw_spin_lock_irq(&wqe->lock); - if (acct->nr_workers < acct->max_workers) { - atomic_inc(&acct->nr_running); - atomic_inc(&wqe->wq->worker_refs); - if (!acct->nr_workers) - first = true; - acct->nr_workers++; - do_create = true; - } - raw_spin_unlock_irq(&wqe->lock); - if (do_create) - create_io_worker(wqe->wq, wqe, acct->index, first); + raw_spin_lock_irq(&wqe->lock); + if (acct->nr_workers < acct->max_workers) { + if (!acct->nr_workers) + first = true; + acct->nr_workers++; + do_create = true; + } + raw_spin_unlock_irq(&wqe->lock); + if (do_create) { + atomic_inc(&acct->nr_running); + atomic_inc(&wqe->wq->worker_refs); + create_io_worker(wqe->wq, wqe, acct->index, first); } }
@@ -798,7 +791,8 @@ append: static void io_wqe_enqueue(struct io_wqe *wqe, struct io_wq_work *work) { struct io_wqe_acct *acct = io_work_get_acct(wqe, work); - bool do_wake; + unsigned work_flags = work->flags; + bool do_create; unsigned long flags;
/* @@ -814,12 +808,16 @@ static void io_wqe_enqueue(struct io_wqe raw_spin_lock_irqsave(&wqe->lock, flags); io_wqe_insert_work(wqe, work); wqe->flags &= ~IO_WQE_FLAG_STALLED; - do_wake = (work->flags & IO_WQ_WORK_CONCURRENT) || - !atomic_read(&acct->nr_running); + + rcu_read_lock(); + do_create = !io_wqe_activate_free_worker(wqe); + rcu_read_unlock(); + raw_spin_unlock_irqrestore(&wqe->lock, flags);
- if (do_wake) - io_wqe_wake_worker(wqe, acct); + if (do_create && ((work_flags & IO_WQ_WORK_CONCURRENT) || + !atomic_read(&acct->nr_running))) + io_wqe_create_worker(wqe, acct); }
void io_wq_enqueue(struct io_wq *wq, struct io_wq_work *work)
From: Pavel Begunkov asml.silence@gmail.com
commit 2ae2eb9dde18979b40629dd413b9adbd6c894cdf upstream.
When we cancel a timeout we should mark it with REQ_F_FAIL, so linked requests are cancelled as well, but not queued for further execution.
Cc: stable@vger.kernel.org Signed-off-by: Pavel Begunkov asml.silence@gmail.com Link: https://lore.kernel.org/r/fff625b44eeced3a5cae79f60e6acf3fbdf8f990.163119213... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/io_uring.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1307,6 +1307,8 @@ static void io_kill_timeout(struct io_ki struct io_timeout_data *io = req->async_data;
if (hrtimer_try_to_cancel(&io->timer) != -1) { + if (status) + req_set_fail_links(req); atomic_set(&req->ctx->cq_timeouts, atomic_read(&req->ctx->cq_timeouts) + 1); list_del_init(&req->timeout.list);
From: Hans de Goede hdegoede@redhat.com
commit 8a6430ab9c9c87cb64c512e505e8690bbaee190b upstream.
Commit ca6bfcb2f6d9 ("libata: Enable queued TRIM for Samsung SSD 860") limited the existing ATA_HORKAGE_NO_NCQ_TRIM quirk from "Samsung SSD 8*", covering all Samsung 800 series SSDs, to only apply to "Samsung SSD 840*" and "Samsung SSD 850*" series based on information from Samsung.
But there is a large number of users which is still reporting issues with the Samsung 860 and 870 SSDs combined with Intel, ASmedia or Marvell SATA controllers and all reporters also report these problems going away when disabling queued trims.
Note that with AMD SATA controllers users are reporting even worse issues and only completely disabling NCQ helps there, this will be addressed in a separate patch.
Fixes: ca6bfcb2f6d9 ("libata: Enable queued TRIM for Samsung SSD 860") BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=203475 Cc: stable@vger.kernel.org Cc: Kate Hsuan hpa@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Reviewed-by: Damien Le Moal damien.lemoal@wdc.com Reviewed-by: Martin K. Petersen martin.petersen@oracle.com Link: https://lore.kernel.org/r/20210823095220.30157-1-hdegoede@redhat.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/ata/libata-core.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3950,6 +3950,10 @@ static const struct ata_blacklist_entry ATA_HORKAGE_ZERO_AFTER_TRIM, }, { "Samsung SSD 850*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM, }, + { "Samsung SSD 860*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | + ATA_HORKAGE_ZERO_AFTER_TRIM, }, + { "Samsung SSD 870*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | + ATA_HORKAGE_ZERO_AFTER_TRIM, }, { "FCCT*M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM, },
From: David Heidelberg david@ixit.cz
commit b30d0289de72c62516df03fdad8d53f552c69839 upstream.
The merge_fdt_bootargs() function by definition consumes more than 1024 bytes of stack because it has a 1024 byte command line on the stack, meaning that we always get a warning when building this file:
arch/arm/boot/compressed/atags_to_fdt.c: In function 'merge_fdt_bootargs': arch/arm/boot/compressed/atags_to_fdt.c:98:1: warning: the frame size of 1032 bytes is larger than 1024 bytes [-Wframe-larger-than=]
However, as this is the decompressor and we know that it has a very shallow call chain, and we do not actually risk overflowing the kernel stack at runtime here.
This just shuts up the warning by disabling the warning flag for this file.
Tested on Nexus 7 2012 builds.
Acked-by: Nicolas Pitre nico@fluxnic.net Signed-off-by: David Heidelberg david@ixit.cz Signed-off-by: Arnd Bergmann arnd@arndb.de Cc: stable@vger.kernel.org Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm/boot/compressed/Makefile | 2 ++ 1 file changed, 2 insertions(+)
--- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -85,6 +85,8 @@ compress-$(CONFIG_KERNEL_LZ4) = lz4 libfdt_objs := fdt_rw.o fdt_ro.o fdt_wip.o fdt.o
ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y) +CFLAGS_REMOVE_atags_to_fdt.o += -Wframe-larger-than=${CONFIG_FRAME_WARN} +CFLAGS_atags_to_fdt.o += -Wframe-larger-than=1280 OBJS += $(libfdt_objs) atags_to_fdt.o endif ifeq ($(CONFIG_USE_OF),y)
From: Chao Yu chao@kernel.org
commit 65ddf6564843890a58ee3b18bb46ce67d96333fb upstream.
This patch fixes below problems of sb/cp sanity check: - in sanity_check_raw_superi(), it missed to consider log header blocks while cp_payload check. - in f2fs_sanity_check_ckpt(), it missed to check nat_bits_blocks.
Cc: stable@kernel.org Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/super.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)
--- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -3089,11 +3089,13 @@ static int sanity_check_raw_super(struct return -EFSCORRUPTED; }
- if (le32_to_cpu(raw_super->cp_payload) > - (blocks_per_seg - F2FS_CP_PACKS)) { - f2fs_info(sbi, "Insane cp_payload (%u > %u)", + if (le32_to_cpu(raw_super->cp_payload) >= + (blocks_per_seg - F2FS_CP_PACKS - + NR_CURSEG_PERSIST_TYPE)) { + f2fs_info(sbi, "Insane cp_payload (%u >= %u)", le32_to_cpu(raw_super->cp_payload), - blocks_per_seg - F2FS_CP_PACKS); + blocks_per_seg - F2FS_CP_PACKS - + NR_CURSEG_PERSIST_TYPE); return -EFSCORRUPTED; }
@@ -3129,6 +3131,7 @@ int f2fs_sanity_check_ckpt(struct f2fs_s unsigned int cp_pack_start_sum, cp_payload; block_t user_block_count, valid_user_blocks; block_t avail_node_count, valid_node_count; + unsigned int nat_blocks, nat_bits_bytes, nat_bits_blocks; int i, j;
total = le32_to_cpu(raw_super->segment_count); @@ -3249,6 +3252,17 @@ int f2fs_sanity_check_ckpt(struct f2fs_s return 1; }
+ nat_blocks = nat_segs << log_blocks_per_seg; + nat_bits_bytes = nat_blocks / BITS_PER_BYTE; + nat_bits_blocks = F2FS_BLK_ALIGN((nat_bits_bytes << 1) + 8); + if (__is_set_ckpt_flags(ckpt, CP_NAT_BITS_FLAG) && + (cp_payload + F2FS_CP_PACKS + + NR_CURSEG_PERSIST_TYPE + nat_bits_blocks >= blocks_per_seg)) { + f2fs_warn(sbi, "Insane cp_payload: %u, nat_bits_blocks: %u)", + cp_payload, nat_bits_blocks); + return -EFSCORRUPTED; + } + if (unlikely(f2fs_cp_error(sbi))) { f2fs_err(sbi, "A bug case: need to run fsck"); return 1;
From: Stuart Hayes stuart.w.hayes@gmail.com
commit 00823dcbdd415c868390feaca16f0265101efab4 upstream.
Previously we assumed that all Root Ports and Switch Downstream Ports supported Link Bandwidth Notification. Per spec, this is only required for Ports supporting Links wider than x1 and/or multiple Link speeds (PCIe r5.0, sec 7.5.3.6).
Because we assumed all Ports supported it, we tried to set up a Bandwidth Notification IRQ, which failed for devices that don't support IRQs at all, which meant pcieport didn't attach to the Port at all.
Check the Link Bandwidth Notification Capability bit and enable the service only when the Port supports it.
[bhelgaas: commit log] Fixes: e8303bb7a75c ("PCI/LINK: Report degraded links via link bandwidth notification") Link: https://lore.kernel.org/r/20210512213314.7778-1-stuart.w.hayes@gmail.com Signed-off-by: Stuart Hayes stuart.w.hayes@gmail.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Lukas Wunner lukas@wunner.de Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/pcie/portdrv_core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
--- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c @@ -257,8 +257,13 @@ static int get_port_device_capability(st services |= PCIE_PORT_SERVICE_DPC;
if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM || - pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) - services |= PCIE_PORT_SERVICE_BWNOTIF; + pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) { + u32 linkcap; + + pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &linkcap); + if (linkcap & PCI_EXP_LNKCAP_LBNC) + services |= PCIE_PORT_SERVICE_BWNOTIF; + }
return services; }
From: Marek Behún kabel@kernel.org
commit b12d93e9958e028856cbcb061b6e64728ca07755 upstream.
The ASMedia ASM1062 SATA controller advertises Max_Payload_Size_Supported of 512, but in fact it cannot handle incoming TLPs with payload size of 512.
We discovered this issue on PCIe controllers capable of MPS = 512 (Aardvark and DesignWare), where the issue presents itself as an External Abort. Bjorn Helgaas says:
Probably ASM1062 reports a Malformed TLP error when it receives a data payload of 512 bytes, and Aardvark, DesignWare, etc convert this to an arm64 External Abort. [1]
To avoid this problem, limit the ASM1062 Max Payload Size Supported to 256 bytes, so we set the Max Payload Size of devices that may send TLPs to the ASM1062 to 256 or less.
[1] https://lore.kernel.org/linux-pci/20210601170907.GA1949035@bjorn-Precision-5... BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=212695 Link: https://lore.kernel.org/r/20210624171418.27194-2-kabel@kernel.org Reported-by: Rötti espressobinboardarmbiantempmailaddress@posteo.de Signed-off-by: Marek Behún kabel@kernel.org Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Krzysztof Wilczyński kw@linux.com Reviewed-by: Pali Rohár pali@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/quirks.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3241,6 +3241,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SO PCI_DEVICE_ID_SOLARFLARE_SFC4000A_1, fixup_mpss_256); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SOLARFLARE, PCI_DEVICE_ID_SOLARFLARE_SFC4000B, fixup_mpss_256); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ASMEDIA, 0x0612, fixup_mpss_256);
/* * Intel 5000 and 5100 Memory controllers have an erratum with read completion
From: Krzysztof Wilczyński kw@linux.com
commit a8bd29bd49c4156ea0ec5a97812333e2aeef44e7 upstream.
The pciconfig_read() syscall reads PCI configuration space using hardware-dependent config accessors.
If the read fails on PCI, most accessors don't return an error; they pretend the read was successful and got ~0 data from the device, so the syscall returns success with ~0 data in the buffer.
When the accessor does return an error, pciconfig_read() normally fills the user's buffer with ~0 and returns an error in errno. But after e4585da22ad0 ("pci syscall.c: Switch to refcounting API"), we don't fill the buffer with ~0 for the EPERM "user lacks CAP_SYS_ADMIN" error.
Userspace may rely on the ~0 data to detect errors, but after e4585da22ad0, that would not detect CAP_SYS_ADMIN errors.
Restore the original behaviour of filling the buffer with ~0 when the CAP_SYS_ADMIN check fails.
[bhelgaas: commit log, fold in Nathan's fix https://lore.kernel.org/r/20210803200836.500658-1-nathan@kernel.org] Fixes: e4585da22ad0 ("pci syscall.c: Switch to refcounting API") Link: https://lore.kernel.org/r/20210729233755.1509616-1-kw@linux.com Signed-off-by: Krzysztof Wilczyński kw@linux.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/syscall.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/pci/syscall.c +++ b/drivers/pci/syscall.c @@ -22,8 +22,10 @@ SYSCALL_DEFINE5(pciconfig_read, unsigned long err; int cfg_ret;
+ err = -EPERM; + dev = NULL; if (!capable(CAP_SYS_ADMIN)) - return -EPERM; + goto error;
err = -ENODEV; dev = pci_get_domain_bus_and_slot(0, bus, dfn);
From: Hyun Kwon hyun.kwon@xilinx.com
commit de0a01f5296651d3a539f2d23d0db8f359483696 upstream.
Enable PCIe reference clock. There is no remove function that's why this should be enough for simple operation. Normally this clock is enabled by default by firmware but there are usecases where this clock should be enabled by driver itself. It is also good that PCIe clock is recorded in a clock framework.
Link: https://lore.kernel.org/r/ee6997a08fab582b1c6de05f8be184f3fe8d5357.162461810... Fixes: ab597d35ef11 ("PCI: xilinx-nwl: Add support for Xilinx NWL PCIe Host Controller") Signed-off-by: Hyun Kwon hyun.kwon@xilinx.com Signed-off-by: Bharat Kumar Gogada bharat.kumar.gogada@xilinx.com Signed-off-by: Michal Simek michal.simek@xilinx.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pcie-xilinx-nwl.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
--- a/drivers/pci/controller/pcie-xilinx-nwl.c +++ b/drivers/pci/controller/pcie-xilinx-nwl.c @@ -6,6 +6,7 @@ * (C) Copyright 2014 - 2015, Xilinx, Inc. */
+#include <linux/clk.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/irq.h> @@ -169,6 +170,7 @@ struct nwl_pcie { u8 last_busno; struct nwl_msi msi; struct irq_domain *legacy_irq_domain; + struct clk *clk; raw_spinlock_t leg_mask_lock; };
@@ -823,6 +825,16 @@ static int nwl_pcie_probe(struct platfor return err; }
+ pcie->clk = devm_clk_get(dev, NULL); + if (IS_ERR(pcie->clk)) + return PTR_ERR(pcie->clk); + + err = clk_prepare_enable(pcie->clk); + if (err) { + dev_err(dev, "can't enable PCIe ref clock\n"); + return err; + } + err = nwl_pcie_bridge_init(pcie); if (err) { dev_err(dev, "HW Initialization failed\n");
From: Pali Rohár pali@kernel.org
commit 64f160e19e9264a7f6d89c516baae1473b6f8359 upstream.
In commit 6df6ba974a55 ("PCI: aardvark: Remove PCIe outbound window configuration") was removed aardvark PCIe outbound window configuration and commit description said that was recommended solution by HW designers.
But that commit completely removed support for configuring PCIe IO resources without removing PCIe IO 'ranges' from DTS files. After that commit PCIe IO space started to be treated as PCIe MEM space and accessing it just caused kernel crash.
Moreover implementation of PCIe outbound windows prior that commit was incorrect. It completely ignored offset between CPU address and PCIe bus address and expected that in DTS is CPU address always same as PCIe bus address without doing any checks. Also it completely ignored size of every PCIe resource specified in 'ranges' DTS property and expected that every PCIe resource has size 128 MB (also for PCIe IO range). Again without any check. Apparently none of PCIe resource has in DTS specified size of 128 MB. So it was completely broken and thanks to how aardvark mask works, configuration was completely ignored.
This patch reverts back support for PCIe outbound window configuration but implementation is a new without issues mentioned above. PCIe outbound window is required when DTS specify in 'ranges' property non-zero offset between CPU and PCIe address space. To address recommendation by HW designers as specified in commit description of 6df6ba974a55, set default outbound parameters as PCIe MEM access without translation and therefore for this PCIe 'ranges' it is not needed to configure PCIe outbound window. For PCIe IO space is needed to configure aardvark PCIe outbound window.
This patch fixes kernel crash when trying to access PCIe IO space.
Link: https://lore.kernel.org/r/20210624215546.4015-2-pali@kernel.org Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Cc: stable@vger.kernel.org # 6df6ba974a55 ("PCI: aardvark: Remove PCIe outbound window configuration") Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pci-aardvark.c | 195 +++++++++++++++++++++++++++++++++- 1 file changed, 194 insertions(+), 1 deletion(-)
--- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -118,6 +118,46 @@ #define PCIE_MSI_MASK_REG (CONTROL_BASE_ADDR + 0x5C) #define PCIE_MSI_PAYLOAD_REG (CONTROL_BASE_ADDR + 0x9C)
+/* PCIe window configuration */ +#define OB_WIN_BASE_ADDR 0x4c00 +#define OB_WIN_BLOCK_SIZE 0x20 +#define OB_WIN_COUNT 8 +#define OB_WIN_REG_ADDR(win, offset) (OB_WIN_BASE_ADDR + \ + OB_WIN_BLOCK_SIZE * (win) + \ + (offset)) +#define OB_WIN_MATCH_LS(win) OB_WIN_REG_ADDR(win, 0x00) +#define OB_WIN_ENABLE BIT(0) +#define OB_WIN_MATCH_MS(win) OB_WIN_REG_ADDR(win, 0x04) +#define OB_WIN_REMAP_LS(win) OB_WIN_REG_ADDR(win, 0x08) +#define OB_WIN_REMAP_MS(win) OB_WIN_REG_ADDR(win, 0x0c) +#define OB_WIN_MASK_LS(win) OB_WIN_REG_ADDR(win, 0x10) +#define OB_WIN_MASK_MS(win) OB_WIN_REG_ADDR(win, 0x14) +#define OB_WIN_ACTIONS(win) OB_WIN_REG_ADDR(win, 0x18) +#define OB_WIN_DEFAULT_ACTIONS (OB_WIN_ACTIONS(OB_WIN_COUNT-1) + 0x4) +#define OB_WIN_FUNC_NUM_MASK GENMASK(31, 24) +#define OB_WIN_FUNC_NUM_SHIFT 24 +#define OB_WIN_FUNC_NUM_ENABLE BIT(23) +#define OB_WIN_BUS_NUM_BITS_MASK GENMASK(22, 20) +#define OB_WIN_BUS_NUM_BITS_SHIFT 20 +#define OB_WIN_MSG_CODE_ENABLE BIT(22) +#define OB_WIN_MSG_CODE_MASK GENMASK(21, 14) +#define OB_WIN_MSG_CODE_SHIFT 14 +#define OB_WIN_MSG_PAYLOAD_LEN BIT(12) +#define OB_WIN_ATTR_ENABLE BIT(11) +#define OB_WIN_ATTR_TC_MASK GENMASK(10, 8) +#define OB_WIN_ATTR_TC_SHIFT 8 +#define OB_WIN_ATTR_RELAXED BIT(7) +#define OB_WIN_ATTR_NOSNOOP BIT(6) +#define OB_WIN_ATTR_POISON BIT(5) +#define OB_WIN_ATTR_IDO BIT(4) +#define OB_WIN_TYPE_MASK GENMASK(3, 0) +#define OB_WIN_TYPE_SHIFT 0 +#define OB_WIN_TYPE_MEM 0x0 +#define OB_WIN_TYPE_IO 0x4 +#define OB_WIN_TYPE_CONFIG_TYPE0 0x8 +#define OB_WIN_TYPE_CONFIG_TYPE1 0x9 +#define OB_WIN_TYPE_MSG 0xc + /* LMI registers base address and register offsets */ #define LMI_BASE_ADDR 0x6000 #define CFG_REG (LMI_BASE_ADDR + 0x0) @@ -180,6 +220,13 @@ struct advk_pcie { struct platform_device *pdev; void __iomem *base; + struct { + phys_addr_t match; + phys_addr_t remap; + phys_addr_t mask; + u32 actions; + } wins[OB_WIN_COUNT]; + u8 wins_count; struct irq_domain *irq_domain; struct irq_chip irq_chip; struct irq_domain *msi_domain; @@ -366,9 +413,39 @@ err: dev_err(dev, "link never came up\n"); }
+/* + * Set PCIe address window register which could be used for memory + * mapping. + */ +static void advk_pcie_set_ob_win(struct advk_pcie *pcie, u8 win_num, + phys_addr_t match, phys_addr_t remap, + phys_addr_t mask, u32 actions) +{ + advk_writel(pcie, OB_WIN_ENABLE | + lower_32_bits(match), OB_WIN_MATCH_LS(win_num)); + advk_writel(pcie, upper_32_bits(match), OB_WIN_MATCH_MS(win_num)); + advk_writel(pcie, lower_32_bits(remap), OB_WIN_REMAP_LS(win_num)); + advk_writel(pcie, upper_32_bits(remap), OB_WIN_REMAP_MS(win_num)); + advk_writel(pcie, lower_32_bits(mask), OB_WIN_MASK_LS(win_num)); + advk_writel(pcie, upper_32_bits(mask), OB_WIN_MASK_MS(win_num)); + advk_writel(pcie, actions, OB_WIN_ACTIONS(win_num)); +} + +static void advk_pcie_disable_ob_win(struct advk_pcie *pcie, u8 win_num) +{ + advk_writel(pcie, 0, OB_WIN_MATCH_LS(win_num)); + advk_writel(pcie, 0, OB_WIN_MATCH_MS(win_num)); + advk_writel(pcie, 0, OB_WIN_REMAP_LS(win_num)); + advk_writel(pcie, 0, OB_WIN_REMAP_MS(win_num)); + advk_writel(pcie, 0, OB_WIN_MASK_LS(win_num)); + advk_writel(pcie, 0, OB_WIN_MASK_MS(win_num)); + advk_writel(pcie, 0, OB_WIN_ACTIONS(win_num)); +} + static void advk_pcie_setup_hw(struct advk_pcie *pcie) { u32 reg; + int i;
/* Enable TX */ reg = advk_readl(pcie, PCIE_CORE_REF_CLK_REG); @@ -447,15 +524,51 @@ static void advk_pcie_setup_hw(struct ad reg = PCIE_IRQ_ALL_MASK & (~PCIE_IRQ_ENABLE_INTS_MASK); advk_writel(pcie, reg, HOST_CTRL_INT_MASK_REG);
+ /* + * Enable AXI address window location generation: + * When it is enabled, the default outbound window + * configurations (Default User Field: 0xD0074CFC) + * are used to transparent address translation for + * the outbound transactions. Thus, PCIe address + * windows are not required for transparent memory + * access when default outbound window configuration + * is set for memory access. + */ reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG); reg |= PCIE_CORE_CTRL2_OB_WIN_ENABLE; advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG);
- /* Bypass the address window mapping for PIO */ + /* + * Set memory access in Default User Field so it + * is not required to configure PCIe address for + * transparent memory access. + */ + advk_writel(pcie, OB_WIN_TYPE_MEM, OB_WIN_DEFAULT_ACTIONS); + + /* + * Bypass the address window mapping for PIO: + * Since PIO access already contains all required + * info over AXI interface by PIO registers, the + * address window is not required. + */ reg = advk_readl(pcie, PIO_CTRL); reg |= PIO_CTRL_ADDR_WIN_DISABLE; advk_writel(pcie, reg, PIO_CTRL);
+ /* + * Configure PCIe address windows for non-memory or + * non-transparent access as by default PCIe uses + * transparent memory access. + */ + for (i = 0; i < pcie->wins_count; i++) + advk_pcie_set_ob_win(pcie, i, + pcie->wins[i].match, pcie->wins[i].remap, + pcie->wins[i].mask, pcie->wins[i].actions); + + /* Disable remaining PCIe outbound windows */ + for (i = pcie->wins_count; i < OB_WIN_COUNT; i++) + advk_pcie_disable_ob_win(pcie, i); + advk_pcie_train_link(pcie);
/* @@ -1162,6 +1275,7 @@ static int advk_pcie_probe(struct platfo struct device *dev = &pdev->dev; struct advk_pcie *pcie; struct pci_host_bridge *bridge; + struct resource_entry *entry; int ret, irq;
bridge = devm_pci_alloc_host_bridge(dev, sizeof(struct advk_pcie)); @@ -1172,6 +1286,80 @@ static int advk_pcie_probe(struct platfo pcie->pdev = pdev; platform_set_drvdata(pdev, pcie);
+ resource_list_for_each_entry(entry, &bridge->windows) { + resource_size_t start = entry->res->start; + resource_size_t size = resource_size(entry->res); + unsigned long type = resource_type(entry->res); + u64 win_size; + + /* + * Aardvark hardware allows to configure also PCIe window + * for config type 0 and type 1 mapping, but driver uses + * only PIO for issuing configuration transfers which does + * not use PCIe window configuration. + */ + if (type != IORESOURCE_MEM && type != IORESOURCE_MEM_64 && + type != IORESOURCE_IO) + continue; + + /* + * Skip transparent memory resources. Default outbound access + * configuration is set to transparent memory access so it + * does not need window configuration. + */ + if ((type == IORESOURCE_MEM || type == IORESOURCE_MEM_64) && + entry->offset == 0) + continue; + + /* + * The n-th PCIe window is configured by tuple (match, remap, mask) + * and an access to address A uses this window if A matches the + * match with given mask. + * So every PCIe window size must be a power of two and every start + * address must be aligned to window size. Minimal size is 64 KiB + * because lower 16 bits of mask must be zero. Remapped address + * may have set only bits from the mask. + */ + while (pcie->wins_count < OB_WIN_COUNT && size > 0) { + /* Calculate the largest aligned window size */ + win_size = (1ULL << (fls64(size)-1)) | + (start ? (1ULL << __ffs64(start)) : 0); + win_size = 1ULL << __ffs64(win_size); + if (win_size < 0x10000) + break; + + dev_dbg(dev, + "Configuring PCIe window %d: [0x%llx-0x%llx] as %lu\n", + pcie->wins_count, (unsigned long long)start, + (unsigned long long)start + win_size, type); + + if (type == IORESOURCE_IO) { + pcie->wins[pcie->wins_count].actions = OB_WIN_TYPE_IO; + pcie->wins[pcie->wins_count].match = pci_pio_to_address(start); + } else { + pcie->wins[pcie->wins_count].actions = OB_WIN_TYPE_MEM; + pcie->wins[pcie->wins_count].match = start; + } + pcie->wins[pcie->wins_count].remap = start - entry->offset; + pcie->wins[pcie->wins_count].mask = ~(win_size - 1); + + if (pcie->wins[pcie->wins_count].remap & (win_size - 1)) + break; + + start += win_size; + size -= win_size; + pcie->wins_count++; + } + + if (size > 0) { + dev_err(&pcie->pdev->dev, + "Invalid PCIe region [0x%llx-0x%llx]\n", + (unsigned long long)entry->res->start, + (unsigned long long)entry->res->end + 1); + return -EINVAL; + } + } + pcie->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pcie->base)) return PTR_ERR(pcie->base); @@ -1252,6 +1440,7 @@ static int advk_pcie_remove(struct platf { struct advk_pcie *pcie = platform_get_drvdata(pdev); struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie); + int i;
pci_lock_rescan_remove(); pci_stop_root_bus(bridge->bus); @@ -1261,6 +1450,10 @@ static int advk_pcie_remove(struct platf advk_pcie_remove_msi_irq_domain(pcie); advk_pcie_remove_irq_domain(pcie);
+ /* Disable outbound address windows mapping */ + for (i = 0; i < OB_WIN_COUNT; i++) + advk_pcie_disable_ob_win(pcie, i); + return 0; }
From: Evan Wang xswang@marvell.com
commit fcb461e2bc8b83b7eaca20cb2221e8b940f2189c upstream.
There is an issue that when PCIe switch is connected to an Armada 3700 board, there will be lots of warnings about PIO errors when reading the config space. According to Aardvark PIO read and write sequence in HW specification, the current way to check PIO status has the following issues:
1) For PIO read operation, it reports the error message, which should be avoided according to HW specification.
2) For PIO read and write operations, it only checks PIO operation complete status, which is not enough, and error status should also be checked.
This patch aligns the code with Aardvark PIO read and write sequence in HW specification on PIO status check and fix the warnings when reading config space.
[pali: Fix CRS handling when CRSSVE is not enabled]
Link: https://lore.kernel.org/r/20210722144041.12661-2-pali@kernel.org Tested-by: Victor Gu xigu@marvell.com Signed-off-by: Evan Wang xswang@marvell.com Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Victor Gu xigu@marvell.com Reviewed-by: Marek Behún kabel@kernel.org Cc: stable@vger.kernel.org # b1bd5714472c ("PCI: aardvark: Indicate error in 'val' when config read fails") Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pci-aardvark.c | 62 +++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 8 deletions(-)
--- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -58,6 +58,7 @@ #define PIO_COMPLETION_STATUS_CRS 2 #define PIO_COMPLETION_STATUS_CA 4 #define PIO_NON_POSTED_REQ BIT(10) +#define PIO_ERR_STATUS BIT(11) #define PIO_ADDR_LS (PIO_BASE_ADDR + 0x8) #define PIO_ADDR_MS (PIO_BASE_ADDR + 0xc) #define PIO_WR_DATA (PIO_BASE_ADDR + 0x10) @@ -585,7 +586,7 @@ static void advk_pcie_setup_hw(struct ad advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG); }
-static void advk_pcie_check_pio_status(struct advk_pcie *pcie) +static int advk_pcie_check_pio_status(struct advk_pcie *pcie, u32 *val) { struct device *dev = &pcie->pdev->dev; u32 reg; @@ -596,14 +597,49 @@ static void advk_pcie_check_pio_status(s status = (reg & PIO_COMPLETION_STATUS_MASK) >> PIO_COMPLETION_STATUS_SHIFT;
- if (!status) - return; - + /* + * According to HW spec, the PIO status check sequence as below: + * 1) even if COMPLETION_STATUS(bit9:7) indicates successful, + * it still needs to check Error Status(bit11), only when this bit + * indicates no error happen, the operation is successful. + * 2) value Unsupported Request(1) of COMPLETION_STATUS(bit9:7) only + * means a PIO write error, and for PIO read it is successful with + * a read value of 0xFFFFFFFF. + * 3) value Completion Retry Status(CRS) of COMPLETION_STATUS(bit9:7) + * only means a PIO write error, and for PIO read it is successful + * with a read value of 0xFFFF0001. + * 4) value Completer Abort (CA) of COMPLETION_STATUS(bit9:7) means + * error for both PIO read and PIO write operation. + * 5) other errors are indicated as 'unknown'. + */ switch (status) { + case PIO_COMPLETION_STATUS_OK: + if (reg & PIO_ERR_STATUS) { + strcomp_status = "COMP_ERR"; + break; + } + /* Get the read result */ + if (val) + *val = advk_readl(pcie, PIO_RD_DATA); + /* No error */ + strcomp_status = NULL; + break; case PIO_COMPLETION_STATUS_UR: strcomp_status = "UR"; break; case PIO_COMPLETION_STATUS_CRS: + /* PCIe r4.0, sec 2.3.2, says: + * If CRS Software Visibility is not enabled, the Root Complex + * must re-issue the Configuration Request as a new Request. + * A Root Complex implementation may choose to limit the number + * of Configuration Request/CRS Completion Status loops before + * determining that something is wrong with the target of the + * Request and taking appropriate action, e.g., complete the + * Request to the host as a failed transaction. + * + * To simplify implementation do not re-issue the Configuration + * Request and complete the Request as a failed transaction. + */ strcomp_status = "CRS"; break; case PIO_COMPLETION_STATUS_CA: @@ -614,6 +650,9 @@ static void advk_pcie_check_pio_status(s break; }
+ if (!strcomp_status) + return 0; + if (reg & PIO_NON_POSTED_REQ) str_posted = "Non-posted"; else @@ -621,6 +660,8 @@ static void advk_pcie_check_pio_status(s
dev_err(dev, "%s PIO Response Status: %s, %#x @ %#x\n", str_posted, strcomp_status, reg, advk_readl(pcie, PIO_ADDR_LS)); + + return -EFAULT; }
static int advk_pcie_wait_pio(struct advk_pcie *pcie) @@ -858,10 +899,13 @@ static int advk_pcie_rd_conf(struct pci_ return PCIBIOS_SET_FAILED; }
- advk_pcie_check_pio_status(pcie); + /* Check PIO status and get the read result */ + ret = advk_pcie_check_pio_status(pcie, val); + if (ret < 0) { + *val = 0xffffffff; + return PCIBIOS_SET_FAILED; + }
- /* Get the read result */ - *val = advk_readl(pcie, PIO_RD_DATA); if (size == 1) *val = (*val >> (8 * (where & 3))) & 0xff; else if (size == 2) @@ -925,7 +969,9 @@ static int advk_pcie_wr_conf(struct pci_ if (ret < 0) return PCIBIOS_SET_FAILED;
- advk_pcie_check_pio_status(pcie); + ret = advk_pcie_check_pio_status(pcie, NULL); + if (ret < 0) + return PCIBIOS_SET_FAILED;
return PCIBIOS_SUCCESSFUL; }
From: Pali Rohár pali@kernel.org
commit 02bcec3ea5591720114f586960490b04b093a09e upstream.
Measurements in different conditions showed that aardvark hardware PIO response can take up to 1.44s. Increase wait timeout from 1ms to 1.5s to ensure that we do not miss responses from hardware. After 1.44s hardware returns errors (e.g. Completer abort).
The previous two patches fixed checking for PIO status, so now we can use it to also catch errors which are reported by hardware after 1.44s.
After applying this patch, kernel can detect and print PIO errors to dmesg:
[ 6.879999] advk-pcie d0070000.pcie: Non-posted PIO Response Status: CA, 0xe00 @ 0x100004 [ 6.896436] advk-pcie d0070000.pcie: Posted PIO Response Status: COMP_ERR, 0x804 @ 0x100004 [ 6.913049] advk-pcie d0070000.pcie: Posted PIO Response Status: COMP_ERR, 0x804 @ 0x100010 [ 6.929663] advk-pcie d0070000.pcie: Non-posted PIO Response Status: CA, 0xe00 @ 0x100010 [ 6.953558] advk-pcie d0070000.pcie: Posted PIO Response Status: COMP_ERR, 0x804 @ 0x100014 [ 6.970170] advk-pcie d0070000.pcie: Non-posted PIO Response Status: CA, 0xe00 @ 0x100014 [ 6.994328] advk-pcie d0070000.pcie: Posted PIO Response Status: COMP_ERR, 0x804 @ 0x100004
Without this patch kernel prints only a generic error to dmesg:
[ 5.246847] advk-pcie d0070000.pcie: config read/write timed out
Link: https://lore.kernel.org/r/20210722144041.12661-3-pali@kernel.org Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Marek Behún kabel@kernel.org Cc: stable@vger.kernel.org # 7fbcb5da811b ("PCI: aardvark: Don't rely on jiffies while holding spinlock") Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pci-aardvark.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -207,7 +207,7 @@ #define PCIE_CONFIG_WR_TYPE0 0xa #define PCIE_CONFIG_WR_TYPE1 0xb
-#define PIO_RETRY_CNT 500 +#define PIO_RETRY_CNT 750000 /* 1.5 s */ #define PIO_RETRY_DELAY 2 /* 2 us*/
#define LINK_WAIT_MAX_RETRIES 10
From: Pali Rohár pali@kernel.org
commit d212dcee27c1f89517181047e5485fcbba4a25c2 upstream.
irq_mask and irq_unmask callbacks need to be properly guarded by raw spin locks as masking/unmasking procedure needs atomic read-modify-write operation on hardware register.
Link: https://lore.kernel.org/r/20210820155020.3000-1-pali@kernel.org Reported-by: Marc Zyngier maz@kernel.org Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Acked-by: Marc Zyngier maz@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pci-aardvark.c | 9 +++++++++ 1 file changed, 9 insertions(+)
--- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -230,6 +230,7 @@ struct advk_pcie { u8 wins_count; struct irq_domain *irq_domain; struct irq_chip irq_chip; + raw_spinlock_t irq_lock; struct irq_domain *msi_domain; struct irq_domain *msi_inner_domain; struct irq_chip msi_bottom_irq_chip; @@ -1045,22 +1046,28 @@ static void advk_pcie_irq_mask(struct ir { struct advk_pcie *pcie = d->domain->host_data; irq_hw_number_t hwirq = irqd_to_hwirq(d); + unsigned long flags; u32 mask;
+ raw_spin_lock_irqsave(&pcie->irq_lock, flags); mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); mask |= PCIE_ISR1_INTX_ASSERT(hwirq); advk_writel(pcie, mask, PCIE_ISR1_MASK_REG); + raw_spin_unlock_irqrestore(&pcie->irq_lock, flags); }
static void advk_pcie_irq_unmask(struct irq_data *d) { struct advk_pcie *pcie = d->domain->host_data; irq_hw_number_t hwirq = irqd_to_hwirq(d); + unsigned long flags; u32 mask;
+ raw_spin_lock_irqsave(&pcie->irq_lock, flags); mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); mask &= ~PCIE_ISR1_INTX_ASSERT(hwirq); advk_writel(pcie, mask, PCIE_ISR1_MASK_REG); + raw_spin_unlock_irqrestore(&pcie->irq_lock, flags); }
static int advk_pcie_irq_map(struct irq_domain *h, @@ -1144,6 +1151,8 @@ static int advk_pcie_init_irq_domain(str struct irq_chip *irq_chip; int ret = 0;
+ raw_spin_lock_init(&pcie->irq_lock); + pcie_intc_node = of_get_next_child(node, NULL); if (!pcie_intc_node) { dev_err(dev, "No PCIe Intc node found\n");
From: Chao Yu chao@kernel.org
[ Upstream commit 01f6afd0f3ccaa2d5f7fb87e7bd910dc17eef06b ]
As 5kft reported in [1]:
set_compress_context() should set compress level into .i_compress_flag for zstd as well as lz4hc, otherwise, zstd compressor will still use default zstd compress level during compression, fix it.
[1] https://lore.kernel.org/linux-f2fs-devel/8e29f52b-6b0d-45ec-9520-e63eb254287...
Fixes: 3fde13f817e2 ("f2fs: compress: support compress level") Reported-by: 5kft 5kft@5kft.org Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/f2fs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index a5de48e768d7..71af6a64a241 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -4020,7 +4020,8 @@ static inline void set_compress_context(struct inode *inode) 1 << COMPRESS_CHKSUM : 0; F2FS_I(inode)->i_cluster_size = 1 << F2FS_I(inode)->i_log_cluster_size; - if (F2FS_I(inode)->i_compress_algorithm == COMPRESS_LZ4 && + if ((F2FS_I(inode)->i_compress_algorithm == COMPRESS_LZ4 || + F2FS_I(inode)->i_compress_algorithm == COMPRESS_ZSTD) && F2FS_OPTION(sbi).compress_level) F2FS_I(inode)->i_compress_flag |= F2FS_OPTION(sbi).compress_level <<
From: Dmitry Torokhov dmitry.torokhov@gmail.com
[ Upstream commit f4abaa9eebde334045ed6ac4e564d050f1df3013 ]
The power supply states of discharging, charging, full, etc, represent state of charging, not the capacity level of the battery (for which we have a separate property). Current HID usage tables to not allow for expressing charging state of the batteries found in generic styli, so we should simply assume that the battery is discharging even if current capacity is at 100% when battery strength reporting is done via HID interface. In fact, we were doing just that before commit 581c4484769e.
This change helps UIs to not mis-represent fully charged batteries in styli as being charging/topping-off.
Fixes: 581c4484769e ("HID: input: map digitizer battery usage") Reported-by: Kenneth Albanowski kenalba@google.com Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-input.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 68c8644234a4..f43b40450e97 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -419,8 +419,6 @@ static int hidinput_get_battery_property(struct power_supply *psy,
if (dev->battery_status == HID_BATTERY_UNKNOWN) val->intval = POWER_SUPPLY_STATUS_UNKNOWN; - else if (dev->battery_capacity == 100) - val->intval = POWER_SUPPLY_STATUS_FULL; else val->intval = POWER_SUPPLY_STATUS_DISCHARGING; break;
From: Chao Yu chao@kernel.org
[ Upstream commit 9de71ede81e6d1a111fdd868b2d78d459fa77f80 ]
xfstest generic/587 reports a deadlock issue as below:
====================================================== WARNING: possible circular locking dependency detected 5.14.0-rc1 #69 Not tainted ------------------------------------------------------ repquota/8606 is trying to acquire lock: ffff888022ac9320 (&sb->s_type->i_mutex_key#18){+.+.}-{3:3}, at: f2fs_quota_sync+0x207/0x300 [f2fs]
but task is already holding lock: ffff8880084bcde8 (&sbi->quota_sem){.+.+}-{3:3}, at: f2fs_quota_sync+0x59/0x300 [f2fs]
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #2 (&sbi->quota_sem){.+.+}-{3:3}: __lock_acquire+0x648/0x10b0 lock_acquire+0x128/0x470 down_read+0x3b/0x2a0 f2fs_quota_sync+0x59/0x300 [f2fs] f2fs_quota_on+0x48/0x100 [f2fs] do_quotactl+0x5e3/0xb30 __x64_sys_quotactl+0x23a/0x4e0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae
-> #1 (&sbi->cp_rwsem){++++}-{3:3}: __lock_acquire+0x648/0x10b0 lock_acquire+0x128/0x470 down_read+0x3b/0x2a0 f2fs_unlink+0x353/0x670 [f2fs] vfs_unlink+0x1c7/0x380 do_unlinkat+0x413/0x4b0 __x64_sys_unlinkat+0x50/0xb0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae
-> #0 (&sb->s_type->i_mutex_key#18){+.+.}-{3:3}: check_prev_add+0xdc/0xb30 validate_chain+0xa67/0xb20 __lock_acquire+0x648/0x10b0 lock_acquire+0x128/0x470 down_write+0x39/0xc0 f2fs_quota_sync+0x207/0x300 [f2fs] do_quotactl+0xaff/0xb30 __x64_sys_quotactl+0x23a/0x4e0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae
other info that might help us debug this:
Chain exists of: &sb->s_type->i_mutex_key#18 --> &sbi->cp_rwsem --> &sbi->quota_sem
Possible unsafe locking scenario:
CPU0 CPU1 ---- ---- lock(&sbi->quota_sem); lock(&sbi->cp_rwsem); lock(&sbi->quota_sem); lock(&sb->s_type->i_mutex_key#18);
*** DEADLOCK ***
3 locks held by repquota/8606: #0: ffff88801efac0e0 (&type->s_umount_key#53){++++}-{3:3}, at: user_get_super+0xd9/0x190 #1: ffff8880084bc380 (&sbi->cp_rwsem){++++}-{3:3}, at: f2fs_quota_sync+0x3e/0x300 [f2fs] #2: ffff8880084bcde8 (&sbi->quota_sem){.+.+}-{3:3}, at: f2fs_quota_sync+0x59/0x300 [f2fs]
stack backtrace: CPU: 6 PID: 8606 Comm: repquota Not tainted 5.14.0-rc1 #69 Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 Call Trace: dump_stack_lvl+0xce/0x134 dump_stack+0x17/0x20 print_circular_bug.isra.0.cold+0x239/0x253 check_noncircular+0x1be/0x1f0 check_prev_add+0xdc/0xb30 validate_chain+0xa67/0xb20 __lock_acquire+0x648/0x10b0 lock_acquire+0x128/0x470 down_write+0x39/0xc0 f2fs_quota_sync+0x207/0x300 [f2fs] do_quotactl+0xaff/0xb30 __x64_sys_quotactl+0x23a/0x4e0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7f883b0b4efe
The root cause is ABBA deadlock of inode lock and cp_rwsem, reorder locks in f2fs_quota_sync() as below to fix this issue: - lock inode - lock cp_rwsem - lock quota_sem
Fixes: db6ec53b7e03 ("f2fs: add a rw_sem to cover quota flag changes") Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/super.c | 84 ++++++++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 36 deletions(-)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 716b4b8bb9a9..8b2b34500b2a 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -2399,6 +2399,33 @@ static int f2fs_enable_quotas(struct super_block *sb) return 0; }
+static int f2fs_quota_sync_file(struct f2fs_sb_info *sbi, int type) +{ + struct quota_info *dqopt = sb_dqopt(sbi->sb); + struct address_space *mapping = dqopt->files[type]->i_mapping; + int ret = 0; + + ret = dquot_writeback_dquots(sbi->sb, type); + if (ret) + goto out; + + ret = filemap_fdatawrite(mapping); + if (ret) + goto out; + + /* if we are using journalled quota */ + if (is_journalled_quota(sbi)) + goto out; + + ret = filemap_fdatawait(mapping); + + truncate_inode_pages(&dqopt->files[type]->i_data, 0); +out: + if (ret) + set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR); + return ret; +} + int f2fs_quota_sync(struct super_block *sb, int type) { struct f2fs_sb_info *sbi = F2FS_SB(sb); @@ -2406,57 +2433,42 @@ int f2fs_quota_sync(struct super_block *sb, int type) int cnt; int ret;
- /* - * do_quotactl - * f2fs_quota_sync - * down_read(quota_sem) - * dquot_writeback_dquots() - * f2fs_dquot_commit - * block_operation - * down_read(quota_sem) - */ - f2fs_lock_op(sbi); - - down_read(&sbi->quota_sem); - ret = dquot_writeback_dquots(sb, type); - if (ret) - goto out; - /* * Now when everything is written we can discard the pagecache so * that userspace sees the changes. */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - struct address_space *mapping;
if (type != -1 && cnt != type) continue; - if (!sb_has_quota_active(sb, cnt)) - continue;
- mapping = dqopt->files[cnt]->i_mapping; + if (!sb_has_quota_active(sb, type)) + return 0;
- ret = filemap_fdatawrite(mapping); - if (ret) - goto out; + inode_lock(dqopt->files[cnt]);
- /* if we are using journalled quota */ - if (is_journalled_quota(sbi)) - continue; + /* + * do_quotactl + * f2fs_quota_sync + * down_read(quota_sem) + * dquot_writeback_dquots() + * f2fs_dquot_commit + * block_operation + * down_read(quota_sem) + */ + f2fs_lock_op(sbi); + down_read(&sbi->quota_sem);
- ret = filemap_fdatawait(mapping); - if (ret) - set_sbi_flag(F2FS_SB(sb), SBI_QUOTA_NEED_REPAIR); + ret = f2fs_quota_sync_file(sbi, cnt); + + up_read(&sbi->quota_sem); + f2fs_unlock_op(sbi);
- inode_lock(dqopt->files[cnt]); - truncate_inode_pages(&dqopt->files[cnt]->i_data, 0); inode_unlock(dqopt->files[cnt]); + + if (ret) + break; } -out: - if (ret) - set_sbi_flag(F2FS_SB(sb), SBI_QUOTA_NEED_REPAIR); - up_read(&sbi->quota_sem); - f2fs_unlock_op(sbi); return ret; }
From: Marek Behún kabel@kernel.org
[ Upstream commit baf8d6899b1e8906dc076ef26cc633e96a8bb0c3 ]
The PWM pins on North Bridge on Armada 37xx can be configured into PWM or GPIO functions. When in PWM function, each pin can also be configured to drive low on 0 and tri-state on 1 (LED mode).
The current definitions handle this by declaring two pin groups for each pin: - group "pwmN" with functions "pwm" and "gpio" - group "ledN_od" ("od" for open drain) with functions "led" and "gpio"
This is semantically incorrect. The correct definition for each pin should be one group with three functions: "pwm", "led" and "gpio".
Change the "pwmN" groups to support "led" function.
Remove "ledN_od" groups. This cannot break backwards compatibility with older device trees: no device tree uses it since there is no PWM driver for this SOC yet. Also "ledN_od" groups are not even documented.
Fixes: b835d6953009 ("pinctrl: armada-37xx: swap polarity on LED group") Signed-off-by: Marek Behún kabel@kernel.org Acked-by: Rob Herring robh@kernel.org Link: https://lore.kernel.org/r/20210719112938.27594-1-kabel@kernel.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../pinctrl/marvell,armada-37xx-pinctrl.txt | 8 ++++---- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt index 38dc56a57760..ecec514b3155 100644 --- a/Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt @@ -43,19 +43,19 @@ group emmc_nb
group pwm0 - pin 11 (GPIO1-11) - - functions pwm, gpio + - functions pwm, led, gpio
group pwm1 - pin 12 - - functions pwm, gpio + - functions pwm, led, gpio
group pwm2 - pin 13 - - functions pwm, gpio + - functions pwm, led, gpio
group pwm3 - pin 14 - - functions pwm, gpio + - functions pwm, led, gpio
group pmic1 - pin 7 diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index 5a68e242f6b3..5cb018f98800 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -167,10 +167,14 @@ static struct armada_37xx_pin_group armada_37xx_nb_groups[] = { PIN_GRP_GPIO("jtag", 20, 5, BIT(0), "jtag"), PIN_GRP_GPIO("sdio0", 8, 3, BIT(1), "sdio"), PIN_GRP_GPIO("emmc_nb", 27, 9, BIT(2), "emmc"), - PIN_GRP_GPIO("pwm0", 11, 1, BIT(3), "pwm"), - PIN_GRP_GPIO("pwm1", 12, 1, BIT(4), "pwm"), - PIN_GRP_GPIO("pwm2", 13, 1, BIT(5), "pwm"), - PIN_GRP_GPIO("pwm3", 14, 1, BIT(6), "pwm"), + PIN_GRP_GPIO_3("pwm0", 11, 1, BIT(3) | BIT(20), 0, BIT(20), BIT(3), + "pwm", "led"), + PIN_GRP_GPIO_3("pwm1", 12, 1, BIT(4) | BIT(21), 0, BIT(21), BIT(4), + "pwm", "led"), + PIN_GRP_GPIO_3("pwm2", 13, 1, BIT(5) | BIT(22), 0, BIT(22), BIT(5), + "pwm", "led"), + PIN_GRP_GPIO_3("pwm3", 14, 1, BIT(6) | BIT(23), 0, BIT(23), BIT(6), + "pwm", "led"), PIN_GRP_GPIO("pmic1", 7, 1, BIT(7), "pmic"), PIN_GRP_GPIO("pmic0", 6, 1, BIT(8), "pmic"), PIN_GRP_GPIO("i2c2", 2, 2, BIT(9), "i2c"), @@ -184,10 +188,6 @@ static struct armada_37xx_pin_group armada_37xx_nb_groups[] = { PIN_GRP_EXTRA("uart2", 9, 2, BIT(1) | BIT(13) | BIT(14) | BIT(19), BIT(1) | BIT(13) | BIT(14), BIT(1) | BIT(19), 18, 2, "gpio", "uart"), - PIN_GRP_GPIO_2("led0_od", 11, 1, BIT(20), BIT(20), 0, "led"), - PIN_GRP_GPIO_2("led1_od", 12, 1, BIT(21), BIT(21), 0, "led"), - PIN_GRP_GPIO_2("led2_od", 13, 1, BIT(22), BIT(22), 0, "led"), - PIN_GRP_GPIO_2("led3_od", 14, 1, BIT(23), BIT(23), 0, "led"), };
static struct armada_37xx_pin_group armada_37xx_sb_groups[] = {
From: Christoph Hellwig hch@lst.de
[ Upstream commit beec64d0c9749afedf51c3c10cf52de1d9a89cc0 ]
SCSI_IOCTL_SEND_COMMAND has been deprecated longer than bsg exists and has been warning for just as long. More importantly it harcodes SCSI CDBs and thus will do the wrong thing on non-SCSI bsg nodes.
Link: https://lore.kernel.org/r/20210724072033.1284840-2-hch@lst.de Fixes: aa387cc89567 ("block: add bsg helper library") Reviewed-by: Bart Van Assche bvanassche@acm.org Acked-by: Jens Axboe axboe@kernel.dk Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- block/bsg.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/block/bsg.c b/block/bsg.c index bd10922d5cbb..4d0ad5846ccf 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -371,10 +371,13 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case SG_GET_RESERVED_SIZE: case SG_SET_RESERVED_SIZE: case SG_EMULATED_HOST: - case SCSI_IOCTL_SEND_COMMAND: return scsi_cmd_ioctl(bd->queue, NULL, file->f_mode, cmd, uarg); case SG_IO: return bsg_sg_io(bd->queue, file->f_mode, uarg); + case SCSI_IOCTL_SEND_COMMAND: + pr_warn_ratelimited("%s: calling unsupported SCSI_IOCTL_SEND_COMMAND\n", + current->comm); + return -EINVAL; default: return -ENOTTY; }
From: Peter Geis pgwipeout@gmail.com
[ Upstream commit 6fffe52fb336ec2063270a7305652a93ea677ca1 ]
The rk3036/rk3328 pll types were converted to checking the lock status via the internal register in january 2020, so don't need the grf reference since then.
But it was forgotten to remove grf check when deciding between the pll rate ops (read-only vs. read-write), so a clock driver without the needed grf reference might've been put into the read-only mode just because the grf reference was missing.
This affected the rk356x that needs to reclock certain plls at boot.
Fix this by removing the check for the grf for selecting the utilized operations.
Suggested-by: Heiko Stuebner heiko@sntech.de Fixes: 7f6ffbb885d1 ("clk: rockchip: convert rk3036 pll type to use internal lock status") Signed-off-by: Peter Geis pgwipeout@gmail.com [adjusted the commit message, adjusted the fixes tag] Link: https://lore.kernel.org/r/20210728180034.717953-3-pgwipeout@gmail.com Signed-off-by: Heiko Stuebner heiko@sntech.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/rockchip/clk-pll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index fe937bcdb487..f7827b3b7fc1 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -940,7 +940,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, switch (pll_type) { case pll_rk3036: case pll_rk3328: - if (!pll->rate_table || IS_ERR(ctx->grf)) + if (!pll->rate_table) init.ops = &rockchip_rk3036_pll_clk_norate_ops; else init.ops = &rockchip_rk3036_pll_clk_ops;
From: Mike Marciniszyn mike.marciniszyn@cornelisnetworks.com
[ Upstream commit 62004871e1fa7f9a60797595c03477af5b5ec36f ]
It is possible for the primary IPoIB network device associated with any RDMA device to fail to join certain multicast groups preventing IPv6 neighbor discovery and possibly other network ULPs from working correctly. The IPv4 broadcast group is not affected as the IPoIB network device handles joining that multicast group directly.
This is because the primary IPoIB network device uses the pkey at ndex 0 in the associated RDMA device's pkey table. Anytime the pkey value of index 0 changes, the primary IPoIB network device automatically modifies it's broadcast address (i.e. /sys/class/net/[ib0]/broadcast), since the broadcast address includes the pkey value, and then bounces carrier. This includes initial pkey assignment, such as when the pkey at index 0 transitions from the opa default of invalid (0x0000) to some value such as the OPA default pkey for Virtual Fabric 0: 0x8001 or when the fabric manager is restarted with a configuration change causing the pkey at index 0 to change. Many network ULPs are not sensitive to the carrier bounce and are not expecting the broadcast address to change including the linux IPv6 stack. This problem does not affect IPoIB child network devices as their pkey value is constant for all time.
To mitigate this issue, change the default pkey in at index 0 to 0x8001 to cover the predominant case and avoid issues as ipoib comes up and the FM sweeps.
At some point, ipoib multicast support should automatically fix non-broadcast addresses as it does with the primary broadcast address.
Fixes: 7724105686e7 ("IB/hfi1: add driver files") Link: https://lore.kernel.org/r/20210715160445.142451.47651.stgit@awfm-01.cornelis... Suggested-by: Josh Collier josh.d.collier@intel.com Signed-off-by: Mike Marciniszyn mike.marciniszyn@cornelisnetworks.com Signed-off-by: Dennis Dalessandro dennis.dalessandro@cornelisnetworks.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hfi1/init.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c index e3a8a420c045..c076eed9c3b7 100644 --- a/drivers/infiniband/hw/hfi1/init.c +++ b/drivers/infiniband/hw/hfi1/init.c @@ -650,12 +650,7 @@ void hfi1_init_pportdata(struct pci_dev *pdev, struct hfi1_pportdata *ppd,
ppd->pkeys[default_pkey_idx] = DEFAULT_P_KEY; ppd->part_enforce |= HFI1_PART_ENFORCE_IN; - - if (loopback) { - dd_dev_err(dd, "Faking data partition 0x8001 in idx %u\n", - !default_pkey_idx); - ppd->pkeys[!default_pkey_idx] = 0x8001; - } + ppd->pkeys[0] = 0x8001;
INIT_WORK(&ppd->link_vc_work, handle_verify_cap); INIT_WORK(&ppd->link_up_work, handle_link_up);
From: Leon Romanovsky leonro@nvidia.com
[ Upstream commit e677b72a0647249370f2635862bf0241c86f66ad ]
The failure during iw_cm module initialization partially left the system with unreleased memory and other resources. Rewrite the module init/exit routines in such way that netlink commands will be opened only after successful initialization.
Fixes: b493d91d333e ("iwcm: common code for port mapper") Link: https://lore.kernel.org/r/b01239f99cb1a3e6d2b0694c242d89e6410bcd93.162704878... Signed-off-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/core/iwcm.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c index da8adadf4755..75b6da00065a 100644 --- a/drivers/infiniband/core/iwcm.c +++ b/drivers/infiniband/core/iwcm.c @@ -1187,29 +1187,34 @@ static int __init iw_cm_init(void)
ret = iwpm_init(RDMA_NL_IWCM); if (ret) - pr_err("iw_cm: couldn't init iwpm\n"); - else - rdma_nl_register(RDMA_NL_IWCM, iwcm_nl_cb_table); + return ret; + iwcm_wq = alloc_ordered_workqueue("iw_cm_wq", 0); if (!iwcm_wq) - return -ENOMEM; + goto err_alloc;
iwcm_ctl_table_hdr = register_net_sysctl(&init_net, "net/iw_cm", iwcm_ctl_table); if (!iwcm_ctl_table_hdr) { pr_err("iw_cm: couldn't register sysctl paths\n"); - destroy_workqueue(iwcm_wq); - return -ENOMEM; + goto err_sysctl; }
+ rdma_nl_register(RDMA_NL_IWCM, iwcm_nl_cb_table); return 0; + +err_sysctl: + destroy_workqueue(iwcm_wq); +err_alloc: + iwpm_exit(RDMA_NL_IWCM); + return -ENOMEM; }
static void __exit iw_cm_cleanup(void) { + rdma_nl_unregister(RDMA_NL_IWCM); unregister_net_sysctl_table(iwcm_ctl_table_hdr); destroy_workqueue(iwcm_wq); - rdma_nl_unregister(RDMA_NL_IWCM); iwpm_exit(RDMA_NL_IWCM); }
From: Leon Romanovsky leonro@nvidia.com
[ Upstream commit 8d7e415d55610d503fdb8815344846b72d194a40 ]
Starting from the beginning of infiniband subsystem, the uverbs char devices start from 192 as a minor number, see commit bc38a6abdd5a ("[PATCH] IB uverbs: core implementation").
This patch updates the admin guide documentation to reflect it.
Fixes: 9d85025b0418 ("docs-rst: create an user's manual book") Link: https://lore.kernel.org/r/bad03e6bcde45550c01e12908a6fe7dfa4770703.162747734... Signed-off-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/admin-guide/devices.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Documentation/admin-guide/devices.txt b/Documentation/admin-guide/devices.txt index 9c2be821c225..922c23bb4372 100644 --- a/Documentation/admin-guide/devices.txt +++ b/Documentation/admin-guide/devices.txt @@ -2993,10 +2993,10 @@ 65 = /dev/infiniband/issm1 Second InfiniBand IsSM device ... 127 = /dev/infiniband/issm63 63rd InfiniBand IsSM device - 128 = /dev/infiniband/uverbs0 First InfiniBand verbs device - 129 = /dev/infiniband/uverbs1 Second InfiniBand verbs device + 192 = /dev/infiniband/uverbs0 First InfiniBand verbs device + 193 = /dev/infiniband/uverbs1 Second InfiniBand verbs device ... - 159 = /dev/infiniband/uverbs31 31st InfiniBand verbs device + 223 = /dev/infiniband/uverbs31 31st InfiniBand verbs device
232 char Biometric Devices 0 = /dev/biometric/sensor0/fingerprint first fingerprint sensor on first device
From: Colin Ian King colin.king@canonical.com
[ Upstream commit 2127cd21fb78c6e22d92944253afd967b0ff774d ]
An earlier fix changed the print format specifier for adapter->bios_addr to use %lX. However, the integer is a u32 so the fix was wrong. Fix this by using the correct %X format specifier.
Link: https://lore.kernel.org/r/20210730095031.26981-1-colin.king@canonical.com Fixes: 43622697117c ("scsi: BusLogic: use %lX for unsigned long rather than %X") Acked-by: Khalid Aziz khalid@gonehiking.org Signed-off-by: Colin Ian King colin.king@canonical.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Addresses-Coverity: ("Invalid type in argument") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/BusLogic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index adddcd589941..bd615db5c58c 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -1711,7 +1711,7 @@ static bool __init blogic_reportconfig(struct blogic_adapter *adapter) if (adapter->adapter_bus_type != BLOGIC_PCI_BUS) { blogic_info(" DMA Channel: None, ", adapter); if (adapter->bios_addr > 0) - blogic_info("BIOS Address: 0x%lX, ", adapter, + blogic_info("BIOS Address: 0x%X, ", adapter, adapter->bios_addr); else blogic_info("BIOS Address: None, ", adapter);
From: Jaehyoung Choi jkkkkk.choi@samsung.com
[ Upstream commit 70115558ab02fe8d28a6634350b3491a542aaa02 ]
Commit 1abd18d1a51a ("pinctrl: samsung: Register pinctrl before GPIO") changes the order of GPIO and pinctrl registration: now pinctrl is registered before GPIO. That means gpio_chip->ngpio is not set when samsung_pinctrl_register() called, and one cannot rely on that value anymore. Use `pin_bank->nr_pins' instead of `pin_bank->gpio_chip.ngpio' to fix mentioned inconsistency.
Fixes: 1abd18d1a51a ("pinctrl: samsung: Register pinctrl before GPIO") Signed-off-by: Jaehyoung Choi jkkkkk.choi@samsung.com Signed-off-by: Sam Protsenko semen.protsenko@linaro.org Link: https://lore.kernel.org/r/20210730192905.7173-1-semen.protsenko@linaro.org Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/samsung/pinctrl-samsung.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index 376876bd6605..2975b4369f32 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -918,7 +918,7 @@ static int samsung_pinctrl_register(struct platform_device *pdev, pin_bank->grange.pin_base = drvdata->pin_base + pin_bank->pin_base; pin_bank->grange.base = pin_bank->grange.pin_base; - pin_bank->grange.npins = pin_bank->gpio_chip.ngpio; + pin_bank->grange.npins = pin_bank->nr_pins; pin_bank->grange.gc = &pin_bank->gpio_chip; pinctrl_add_gpio_range(drvdata->pctl_dev, &pin_bank->grange); }
From: Chao Yu yuchao0@huawei.com
[ Upstream commit b763f3bedc2da2edf81bba550430847f561eae0e ]
Restruct f2fs page private layout for below reasons:
There are some cases that f2fs wants to set a flag in a page to indicate a specified status of page: a) page is in transaction list for atomic write b) page contains dummy data for aligned write c) page is migrating for GC d) page contains inline data for inline inode flush e) page belongs to merkle tree, and is verified for fsverity f) page is dirty and has filesystem/inode reference count for writeback g) page is temporary and has decompress io context reference for compression
There are existed places in page structure we can use to store f2fs private status/data: - page.flags: PG_checked, PG_private - page.private
However it was a mess when we using them, which may cause potential confliction: page.private PG_private PG_checked page._refcount (+1 at most) a) -1 set +1 b) -2 set c), d), e) set f) 0 set +1 g) pointer set
The other problem is page.flags has no free slot, if we can avoid set zero to page.private and set PG_private flag, then we use non-zero value to indicate PG_private status, so that we may have chance to reclaim PG_private slot for other usage. [1]
The other concern is f2fs has bad scalability in aspect of indicating more page status.
So in this patch, let's restructure f2fs' page.private as below to solve above issues:
Layout A: lowest bit should be 1 | bit0 = 1 | bit1 | bit2 | ... | bit MAX | private data .... | bit 0 PAGE_PRIVATE_NOT_POINTER bit 1 PAGE_PRIVATE_ATOMIC_WRITE bit 2 PAGE_PRIVATE_DUMMY_WRITE bit 3 PAGE_PRIVATE_ONGOING_MIGRATION bit 4 PAGE_PRIVATE_INLINE_INODE bit 5 PAGE_PRIVATE_REF_RESOURCE bit 6- f2fs private data
Layout B: lowest bit should be 0 page.private is a wrapped pointer.
After the change: page.private PG_private PG_checked page._refcount (+1 at most) a) 11 set +1 b) 101 set +1 c) 1001 set +1 d) 10001 set +1 e) set f) 100001 set +1 g) pointer set +1
[1] https://lore.kernel.org/linux-f2fs-devel/20210422154705.GO3596236@casper.inf...
Cc: Matthew Wilcox willy@infradead.org Signed-off-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/checkpoint.c | 4 +- fs/f2fs/compress.c | 10 ++--- fs/f2fs/data.c | 65 ++++++++++++++++------------- fs/f2fs/dir.c | 8 +++- fs/f2fs/f2fs.h | 98 ++++++++++++++++++++++++++++++++++---------- fs/f2fs/gc.c | 6 +-- fs/f2fs/inline.c | 4 +- fs/f2fs/inode.c | 2 +- fs/f2fs/node.c | 10 ++--- fs/f2fs/node.h | 29 ------------- fs/f2fs/segment.c | 19 +++++---- 11 files changed, 146 insertions(+), 109 deletions(-)
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index f795049e63d5..6c208108d69c 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -444,7 +444,7 @@ static int f2fs_set_meta_page_dirty(struct page *page) if (!PageDirty(page)) { __set_page_dirty_nobuffers(page); inc_page_count(F2FS_P_SB(page), F2FS_DIRTY_META); - f2fs_set_page_private(page, 0); + set_page_private_reference(page); return 1; } return 0; @@ -1018,7 +1018,7 @@ void f2fs_update_dirty_page(struct inode *inode, struct page *page) inode_inc_dirty_pages(inode); spin_unlock(&sbi->inode_lock[type]);
- f2fs_set_page_private(page, 0); + set_page_private_reference(page); }
void f2fs_remove_dirty_inode(struct inode *inode) diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 925a5ca3744a..1c65384d13f3 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -74,7 +74,7 @@ bool f2fs_is_compressed_page(struct page *page) return false; if (!page_private(page)) return false; - if (IS_ATOMIC_WRITTEN_PAGE(page) || IS_DUMMY_WRITTEN_PAGE(page)) + if (page_private_nonpointer(page)) return false;
f2fs_bug_on(F2FS_M_SB(page->mapping), @@ -85,8 +85,7 @@ bool f2fs_is_compressed_page(struct page *page) static void f2fs_set_compressed_page(struct page *page, struct inode *inode, pgoff_t index, void *data) { - SetPagePrivate(page); - set_page_private(page, (unsigned long)data); + attach_page_private(page, (void *)data);
/* i_crypto_info and iv index */ page->index = index; @@ -589,8 +588,7 @@ static void f2fs_compress_free_page(struct page *page) { if (!page) return; - set_page_private(page, (unsigned long)NULL); - ClearPagePrivate(page); + detach_page_private(page); page->mapping = NULL; unlock_page(page); mempool_free(page, compress_page_pool); @@ -1399,7 +1397,7 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page)
for (i = 0; i < cic->nr_rpages; i++) { WARN_ON(!cic->rpages[i]); - clear_cold_data(cic->rpages[i]); + clear_page_private_gcing(cic->rpages[i]); end_page_writeback(cic->rpages[i]); }
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index e2d0c7d9673e..d4795eda12fa 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -58,18 +58,19 @@ static bool __is_cp_guaranteed(struct page *page) if (!mapping) return false;
- if (f2fs_is_compressed_page(page)) - return false; - inode = mapping->host; sbi = F2FS_I_SB(inode);
if (inode->i_ino == F2FS_META_INO(sbi) || inode->i_ino == F2FS_NODE_INO(sbi) || - S_ISDIR(inode->i_mode) || - (S_ISREG(inode->i_mode) && + S_ISDIR(inode->i_mode)) + return true; + + if (f2fs_is_compressed_page(page)) + return false; + if ((S_ISREG(inode->i_mode) && (f2fs_is_atomic_file(inode) || IS_NOQUOTA(inode))) || - is_cold_data(page)) + page_private_gcing(page)) return true; return false; } @@ -299,9 +300,8 @@ static void f2fs_write_end_io(struct bio *bio) struct page *page = bvec->bv_page; enum count_type type = WB_DATA_TYPE(page);
- if (IS_DUMMY_WRITTEN_PAGE(page)) { - set_page_private(page, (unsigned long)NULL); - ClearPagePrivate(page); + if (page_private_dummy(page)) { + clear_page_private_dummy(page); unlock_page(page); mempool_free(page, sbi->write_io_dummy);
@@ -331,7 +331,7 @@ static void f2fs_write_end_io(struct bio *bio) dec_page_count(sbi, type); if (f2fs_in_warm_node_list(sbi, page)) f2fs_del_fsync_node_entry(sbi, page); - clear_cold_data(page); + clear_page_private_gcing(page); end_page_writeback(page); } if (!get_pages(sbi, F2FS_WB_CP_DATA) && @@ -455,10 +455,11 @@ static inline void __submit_bio(struct f2fs_sb_info *sbi, GFP_NOIO | __GFP_NOFAIL); f2fs_bug_on(sbi, !page);
- zero_user_segment(page, 0, PAGE_SIZE); - SetPagePrivate(page); - set_page_private(page, DUMMY_WRITTEN_PAGE); lock_page(page); + + zero_user_segment(page, 0, PAGE_SIZE); + set_page_private_dummy(page); + if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) f2fs_bug_on(sbi, 1); } @@ -2482,9 +2483,9 @@ bool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio) if (f2fs_is_atomic_file(inode)) return true; if (fio) { - if (is_cold_data(fio->page)) + if (page_private_gcing(fio->page)) return true; - if (IS_ATOMIC_WRITTEN_PAGE(fio->page)) + if (page_private_dummy(fio->page)) return true; if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED) && f2fs_is_checkpointed_data(sbi, fio->old_blkaddr))) @@ -2540,7 +2541,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio) /* This page is already truncated */ if (fio->old_blkaddr == NULL_ADDR) { ClearPageUptodate(page); - clear_cold_data(page); + clear_page_private_gcing(page); goto out_writepage; } got_it: @@ -2750,7 +2751,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted, inode_dec_dirty_pages(inode); if (err) { ClearPageUptodate(page); - clear_cold_data(page); + clear_page_private_gcing(page); }
if (wbc->for_reclaim) { @@ -3224,7 +3225,7 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi, f2fs_do_read_inline_data(page, ipage); set_inode_flag(inode, FI_DATA_EXIST); if (inode->i_nlink) - set_inline_node(ipage); + set_page_private_inline(ipage); } else { err = f2fs_convert_inline_page(&dn, page); if (err) @@ -3615,12 +3616,13 @@ void f2fs_invalidate_page(struct page *page, unsigned int offset, } }
- clear_cold_data(page); + clear_page_private_gcing(page);
- if (IS_ATOMIC_WRITTEN_PAGE(page)) + if (page_private_atomic(page)) return f2fs_drop_inmem_page(inode, page);
- f2fs_clear_page_private(page); + detach_page_private(page); + set_page_private(page, 0); }
int f2fs_release_page(struct page *page, gfp_t wait) @@ -3630,11 +3632,13 @@ int f2fs_release_page(struct page *page, gfp_t wait) return 0;
/* This is atomic written page, keep Private */ - if (IS_ATOMIC_WRITTEN_PAGE(page)) + if (page_private_atomic(page)) return 0;
- clear_cold_data(page); - f2fs_clear_page_private(page); + clear_page_private_gcing(page); + + detach_page_private(page); + set_page_private(page, 0); return 1; }
@@ -3650,7 +3654,7 @@ static int f2fs_set_data_page_dirty(struct page *page) return __set_page_dirty_nobuffers(page);
if (f2fs_is_atomic_file(inode) && !f2fs_is_commit_atomic_write(inode)) { - if (!IS_ATOMIC_WRITTEN_PAGE(page)) { + if (!page_private_atomic(page)) { f2fs_register_inmem_page(inode, page); return 1; } @@ -3742,7 +3746,7 @@ int f2fs_migrate_page(struct address_space *mapping, { int rc, extra_count; struct f2fs_inode_info *fi = F2FS_I(mapping->host); - bool atomic_written = IS_ATOMIC_WRITTEN_PAGE(page); + bool atomic_written = page_private_atomic(page);
BUG_ON(PageWriteback(page));
@@ -3778,8 +3782,13 @@ int f2fs_migrate_page(struct address_space *mapping, }
if (PagePrivate(page)) { - f2fs_set_page_private(newpage, page_private(page)); - f2fs_clear_page_private(page); + set_page_private(newpage, page_private(page)); + SetPagePrivate(newpage); + get_page(newpage); + + set_page_private(page, 0); + ClearPagePrivate(page); + put_page(page); }
if (mode != MIGRATE_SYNC_NO_COPY) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index dc7ce79672b8..96dcc4aca639 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -929,11 +929,15 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, !f2fs_truncate_hole(dir, page->index, page->index + 1)) { f2fs_clear_page_cache_dirty_tag(page); clear_page_dirty_for_io(page); - f2fs_clear_page_private(page); ClearPageUptodate(page); - clear_cold_data(page); + + clear_page_private_gcing(page); + inode_dec_dirty_pages(dir); f2fs_remove_dirty_inode(dir); + + detach_page_private(page); + set_page_private(page, 0); } f2fs_put_page(page, 1);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 71af6a64a241..a0e828b5c701 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1291,17 +1291,85 @@ enum { */ };
+static inline int f2fs_test_bit(unsigned int nr, char *addr); +static inline void f2fs_set_bit(unsigned int nr, char *addr); +static inline void f2fs_clear_bit(unsigned int nr, char *addr); + /* - * this value is set in page as a private data which indicate that - * the page is atomically written, and it is in inmem_pages list. + * Layout of f2fs page.private: + * + * Layout A: lowest bit should be 1 + * | bit0 = 1 | bit1 | bit2 | ... | bit MAX | private data .... | + * bit 0 PAGE_PRIVATE_NOT_POINTER + * bit 1 PAGE_PRIVATE_ATOMIC_WRITE + * bit 2 PAGE_PRIVATE_DUMMY_WRITE + * bit 3 PAGE_PRIVATE_ONGOING_MIGRATION + * bit 4 PAGE_PRIVATE_INLINE_INODE + * bit 5 PAGE_PRIVATE_REF_RESOURCE + * bit 6- f2fs private data + * + * Layout B: lowest bit should be 0 + * page.private is a wrapped pointer. */ -#define ATOMIC_WRITTEN_PAGE ((unsigned long)-1) -#define DUMMY_WRITTEN_PAGE ((unsigned long)-2) +enum { + PAGE_PRIVATE_NOT_POINTER, /* private contains non-pointer data */ + PAGE_PRIVATE_ATOMIC_WRITE, /* data page from atomic write path */ + PAGE_PRIVATE_DUMMY_WRITE, /* data page for padding aligned IO */ + PAGE_PRIVATE_ONGOING_MIGRATION, /* data page which is on-going migrating */ + PAGE_PRIVATE_INLINE_INODE, /* inode page contains inline data */ + PAGE_PRIVATE_REF_RESOURCE, /* dirty page has referenced resources */ + PAGE_PRIVATE_MAX +}; + +#define PAGE_PRIVATE_GET_FUNC(name, flagname) \ +static inline bool page_private_##name(struct page *page) \ +{ \ + return test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \ + test_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \ +} + +#define PAGE_PRIVATE_SET_FUNC(name, flagname) \ +static inline void set_page_private_##name(struct page *page) \ +{ \ + if (!PagePrivate(page)) { \ + get_page(page); \ + SetPagePrivate(page); \ + } \ + set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \ + set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \ +}
-#define IS_ATOMIC_WRITTEN_PAGE(page) \ - (page_private(page) == ATOMIC_WRITTEN_PAGE) -#define IS_DUMMY_WRITTEN_PAGE(page) \ - (page_private(page) == DUMMY_WRITTEN_PAGE) +#define PAGE_PRIVATE_CLEAR_FUNC(name, flagname) \ +static inline void clear_page_private_##name(struct page *page) \ +{ \ + clear_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \ + if (page_private(page) == 1 << PAGE_PRIVATE_NOT_POINTER) { \ + set_page_private(page, 0); \ + if (PagePrivate(page)) { \ + ClearPagePrivate(page); \ + put_page(page); \ + }\ + } \ +} + +PAGE_PRIVATE_GET_FUNC(nonpointer, NOT_POINTER); +PAGE_PRIVATE_GET_FUNC(reference, REF_RESOURCE); +PAGE_PRIVATE_GET_FUNC(inline, INLINE_INODE); +PAGE_PRIVATE_GET_FUNC(gcing, ONGOING_MIGRATION); +PAGE_PRIVATE_GET_FUNC(atomic, ATOMIC_WRITE); +PAGE_PRIVATE_GET_FUNC(dummy, DUMMY_WRITE); + +PAGE_PRIVATE_SET_FUNC(reference, REF_RESOURCE); +PAGE_PRIVATE_SET_FUNC(inline, INLINE_INODE); +PAGE_PRIVATE_SET_FUNC(gcing, ONGOING_MIGRATION); +PAGE_PRIVATE_SET_FUNC(atomic, ATOMIC_WRITE); +PAGE_PRIVATE_SET_FUNC(dummy, DUMMY_WRITE); + +PAGE_PRIVATE_CLEAR_FUNC(reference, REF_RESOURCE); +PAGE_PRIVATE_CLEAR_FUNC(inline, INLINE_INODE); +PAGE_PRIVATE_CLEAR_FUNC(gcing, ONGOING_MIGRATION); +PAGE_PRIVATE_CLEAR_FUNC(atomic, ATOMIC_WRITE); +PAGE_PRIVATE_CLEAR_FUNC(dummy, DUMMY_WRITE);
/* For compression */ enum compress_algorithm_type { @@ -3169,20 +3237,6 @@ static inline bool __is_valid_data_blkaddr(block_t blkaddr) return true; }
-static inline void f2fs_set_page_private(struct page *page, - unsigned long data) -{ - if (PagePrivate(page)) - return; - - attach_page_private(page, (void *)data); -} - -static inline void f2fs_clear_page_private(struct page *page) -{ - detach_page_private(page); -} - /* * file.c */ diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index ab63951c08cb..5ae066a71d4c 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1336,7 +1336,7 @@ static int move_data_page(struct inode *inode, block_t bidx, int gc_type, goto out; } set_page_dirty(page); - set_cold_data(page); + set_page_private_gcing(page); } else { struct f2fs_io_info fio = { .sbi = F2FS_I_SB(inode), @@ -1362,11 +1362,11 @@ static int move_data_page(struct inode *inode, block_t bidx, int gc_type, f2fs_remove_dirty_inode(inode); }
- set_cold_data(page); + set_page_private_gcing(page);
err = f2fs_do_write_data_page(&fio); if (err) { - clear_cold_data(page); + clear_page_private_gcing(page); if (err == -ENOMEM) { congestion_wait(BLK_RW_ASYNC, DEFAULT_IO_TIMEOUT); diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 92652ca7a7c8..56a20d5c15da 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -173,7 +173,7 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
/* clear inline data and flag after data writeback */ f2fs_truncate_inline_inode(dn->inode, dn->inode_page, 0); - clear_inline_node(dn->inode_page); + clear_page_private_inline(dn->inode_page); clear_out: stat_dec_inline_inode(dn->inode); clear_inode_flag(dn->inode, FI_INLINE_DATA); @@ -255,7 +255,7 @@ int f2fs_write_inline_data(struct inode *inode, struct page *page) set_inode_flag(inode, FI_APPEND_WRITE); set_inode_flag(inode, FI_DATA_EXIST);
- clear_inline_node(dn.inode_page); + clear_page_private_inline(dn.inode_page); f2fs_put_dnode(&dn); return 0; } diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index b401f08569f7..cbda7ca3b3be 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -646,7 +646,7 @@ void f2fs_update_inode(struct inode *inode, struct page *node_page)
/* deleted inode */ if (inode->i_nlink == 0) - clear_inline_node(node_page); + clear_page_private_inline(node_page);
F2FS_I(inode)->i_disk_time[0] = inode->i_atime; F2FS_I(inode)->i_disk_time[1] = inode->i_ctime; diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index e67ce5f13b98..3a8f7afa5059 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1860,8 +1860,8 @@ void f2fs_flush_inline_data(struct f2fs_sb_info *sbi) }
/* flush inline_data, if it's async context. */ - if (is_inline_node(page)) { - clear_inline_node(page); + if (page_private_inline(page)) { + clear_page_private_inline(page); unlock_page(page); flush_inline_data(sbi, ino_of_node(page)); continue; @@ -1941,8 +1941,8 @@ int f2fs_sync_node_pages(struct f2fs_sb_info *sbi, goto write_node;
/* flush inline_data */ - if (is_inline_node(page)) { - clear_inline_node(page); + if (page_private_inline(page)) { + clear_page_private_inline(page); unlock_page(page); flush_inline_data(sbi, ino_of_node(page)); goto lock_node; @@ -2096,7 +2096,7 @@ static int f2fs_set_node_page_dirty(struct page *page) if (!PageDirty(page)) { __set_page_dirty_nobuffers(page); inc_page_count(F2FS_P_SB(page), F2FS_DIRTY_NODES); - f2fs_set_page_private(page, 0); + set_page_private_reference(page); return 1; } return 0; diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h index 7a45c0f10629..d85e8659cfda 100644 --- a/fs/f2fs/node.h +++ b/fs/f2fs/node.h @@ -389,20 +389,6 @@ static inline nid_t get_nid(struct page *p, int off, bool i) * - Mark cold node blocks in their node footer * - Mark cold data pages in page cache */ -static inline int is_cold_data(struct page *page) -{ - return PageChecked(page); -} - -static inline void set_cold_data(struct page *page) -{ - SetPageChecked(page); -} - -static inline void clear_cold_data(struct page *page) -{ - ClearPageChecked(page); -}
static inline int is_node(struct page *page, int type) { @@ -414,21 +400,6 @@ static inline int is_node(struct page *page, int type) #define is_fsync_dnode(page) is_node(page, FSYNC_BIT_SHIFT) #define is_dent_dnode(page) is_node(page, DENT_BIT_SHIFT)
-static inline int is_inline_node(struct page *page) -{ - return PageChecked(page); -} - -static inline void set_inline_node(struct page *page) -{ - SetPageChecked(page); -} - -static inline void clear_inline_node(struct page *page) -{ - ClearPageChecked(page); -} - static inline void set_cold_node(struct page *page, bool is_dir) { struct f2fs_node *rn = F2FS_NODE(page); diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 51dc79fad4fe..8668df7870d0 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -186,10 +186,7 @@ void f2fs_register_inmem_page(struct inode *inode, struct page *page) { struct inmem_pages *new;
- if (PagePrivate(page)) - set_page_private(page, (unsigned long)ATOMIC_WRITTEN_PAGE); - else - f2fs_set_page_private(page, ATOMIC_WRITTEN_PAGE); + set_page_private_atomic(page);
new = f2fs_kmem_cache_alloc(inmem_entry_slab, GFP_NOFS);
@@ -272,9 +269,10 @@ static int __revoke_inmem_pages(struct inode *inode, /* we don't need to invalidate this in the sccessful status */ if (drop || recover) { ClearPageUptodate(page); - clear_cold_data(page); + clear_page_private_gcing(page); } - f2fs_clear_page_private(page); + detach_page_private(page); + set_page_private(page, 0); f2fs_put_page(page, 1);
list_del(&cur->list); @@ -357,7 +355,7 @@ void f2fs_drop_inmem_page(struct inode *inode, struct page *page) struct list_head *head = &fi->inmem_pages; struct inmem_pages *cur = NULL;
- f2fs_bug_on(sbi, !IS_ATOMIC_WRITTEN_PAGE(page)); + f2fs_bug_on(sbi, !page_private_atomic(page));
mutex_lock(&fi->inmem_lock); list_for_each_entry(cur, head, list) { @@ -373,9 +371,12 @@ void f2fs_drop_inmem_page(struct inode *inode, struct page *page) kmem_cache_free(inmem_entry_slab, cur);
ClearPageUptodate(page); - f2fs_clear_page_private(page); + clear_page_private_atomic(page); f2fs_put_page(page, 0);
+ detach_page_private(page); + set_page_private(page, 0); + trace_f2fs_commit_inmem_page(page, INMEM_INVALIDATE); }
@@ -3289,7 +3290,7 @@ static int __get_segment_type_6(struct f2fs_io_info *fio) if (fio->type == DATA) { struct inode *inode = fio->page->mapping->host;
- if (is_cold_data(fio->page)) { + if (page_private_gcing(fio->page)) { if (fio->sbi->am.atgc_enabled && (fio->io_type == FS_DATA_IO) && (fio->sbi->gc_mode != GC_URGENT_HIGH))
From: Chao Yu yuchao0@huawei.com
[ Upstream commit 6ce19aff0b8cd386860855185c6cd79337fc4d2b ]
Support to use address space of inner inode to cache compressed block, in order to improve cache hit ratio of random read.
Signed-off-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/filesystems/f2fs.rst | 3 + fs/f2fs/compress.c | 168 ++++++++++++++++++++++++++++- fs/f2fs/data.c | 41 +++++-- fs/f2fs/debug.c | 13 +++ fs/f2fs/f2fs.h | 71 +++++++++++- fs/f2fs/gc.c | 1 + fs/f2fs/inode.c | 21 +++- fs/f2fs/node.c | 14 +++ fs/f2fs/node.h | 1 + fs/f2fs/segment.c | 6 +- fs/f2fs/super.c | 35 +++++- include/linux/f2fs_fs.h | 1 + 12 files changed, 361 insertions(+), 14 deletions(-)
diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst index 53d396650afb..b91e5a8444d5 100644 --- a/Documentation/filesystems/f2fs.rst +++ b/Documentation/filesystems/f2fs.rst @@ -289,6 +289,9 @@ compress_mode=%s Control file compression mode. This supports "fs" and "user" choosing the target file and the timing. The user can do manual compression/decompression on the compression enabled files using ioctls. +compress_cache Support to use address space of a filesystem managed inode to + cache compressed block, in order to improve cache hit ratio of + random read. inlinecrypt When possible, encrypt/decrypt the contents of encrypted files using the blk-crypto framework rather than filesystem-layer encryption. This allows the use of diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 1c65384d13f3..ba188722ba43 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -12,9 +12,11 @@ #include <linux/lzo.h> #include <linux/lz4.h> #include <linux/zstd.h> +#include <linux/pagevec.h>
#include "f2fs.h" #include "node.h" +#include "segment.h" #include <trace/events/f2fs.h>
static struct kmem_cache *cic_entry_slab; @@ -736,7 +738,7 @@ static int f2fs_compress_pages(struct compress_ctx *cc) return ret; }
-static void f2fs_decompress_cluster(struct decompress_io_ctx *dic) +void f2fs_decompress_cluster(struct decompress_io_ctx *dic) { struct f2fs_sb_info *sbi = F2FS_I_SB(dic->inode); struct f2fs_inode_info *fi = F2FS_I(dic->inode); @@ -835,7 +837,8 @@ static void f2fs_decompress_cluster(struct decompress_io_ctx *dic) * page being waited on in the cluster, and if so, it decompresses the cluster * (or in the case of a failure, cleans up without actually decompressing). */ -void f2fs_end_read_compressed_page(struct page *page, bool failed) +void f2fs_end_read_compressed_page(struct page *page, bool failed, + block_t blkaddr) { struct decompress_io_ctx *dic = (struct decompress_io_ctx *)page_private(page); @@ -845,6 +848,9 @@ void f2fs_end_read_compressed_page(struct page *page, bool failed)
if (failed) WRITE_ONCE(dic->failed, true); + else if (blkaddr) + f2fs_cache_compressed_page(sbi, page, + dic->inode->i_ino, blkaddr);
if (atomic_dec_and_test(&dic->remaining_pages)) f2fs_decompress_cluster(dic); @@ -1683,6 +1689,164 @@ void f2fs_put_page_dic(struct page *page) f2fs_put_dic(dic); }
+const struct address_space_operations f2fs_compress_aops = { + .releasepage = f2fs_release_page, + .invalidatepage = f2fs_invalidate_page, +}; + +struct address_space *COMPRESS_MAPPING(struct f2fs_sb_info *sbi) +{ + return sbi->compress_inode->i_mapping; +} + +void f2fs_invalidate_compress_page(struct f2fs_sb_info *sbi, block_t blkaddr) +{ + if (!sbi->compress_inode) + return; + invalidate_mapping_pages(COMPRESS_MAPPING(sbi), blkaddr, blkaddr); +} + +void f2fs_cache_compressed_page(struct f2fs_sb_info *sbi, struct page *page, + nid_t ino, block_t blkaddr) +{ + struct page *cpage; + int ret; + + if (!test_opt(sbi, COMPRESS_CACHE)) + return; + + if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE_READ)) + return; + + if (!f2fs_available_free_memory(sbi, COMPRESS_PAGE)) + return; + + cpage = find_get_page(COMPRESS_MAPPING(sbi), blkaddr); + if (cpage) { + f2fs_put_page(cpage, 0); + return; + } + + cpage = alloc_page(__GFP_NOWARN | __GFP_IO); + if (!cpage) + return; + + ret = add_to_page_cache_lru(cpage, COMPRESS_MAPPING(sbi), + blkaddr, GFP_NOFS); + if (ret) { + f2fs_put_page(cpage, 0); + return; + } + + set_page_private_data(cpage, ino); + + if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE_READ)) + goto out; + + memcpy(page_address(cpage), page_address(page), PAGE_SIZE); + SetPageUptodate(cpage); +out: + f2fs_put_page(cpage, 1); +} + +bool f2fs_load_compressed_page(struct f2fs_sb_info *sbi, struct page *page, + block_t blkaddr) +{ + struct page *cpage; + bool hitted = false; + + if (!test_opt(sbi, COMPRESS_CACHE)) + return false; + + cpage = f2fs_pagecache_get_page(COMPRESS_MAPPING(sbi), + blkaddr, FGP_LOCK | FGP_NOWAIT, GFP_NOFS); + if (cpage) { + if (PageUptodate(cpage)) { + atomic_inc(&sbi->compress_page_hit); + memcpy(page_address(page), + page_address(cpage), PAGE_SIZE); + hitted = true; + } + f2fs_put_page(cpage, 1); + } + + return hitted; +} + +void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi, nid_t ino) +{ + struct address_space *mapping = sbi->compress_inode->i_mapping; + struct pagevec pvec; + pgoff_t index = 0; + pgoff_t end = MAX_BLKADDR(sbi); + + if (!mapping->nrpages) + return; + + pagevec_init(&pvec); + + do { + unsigned int nr_pages; + int i; + + nr_pages = pagevec_lookup_range(&pvec, mapping, + &index, end - 1); + if (!nr_pages) + break; + + for (i = 0; i < nr_pages; i++) { + struct page *page = pvec.pages[i]; + + if (page->index > end) + break; + + lock_page(page); + if (page->mapping != mapping) { + unlock_page(page); + continue; + } + + if (ino != get_page_private_data(page)) { + unlock_page(page); + continue; + } + + generic_error_remove_page(mapping, page); + unlock_page(page); + } + pagevec_release(&pvec); + cond_resched(); + } while (index < end); +} + +int f2fs_init_compress_inode(struct f2fs_sb_info *sbi) +{ + struct inode *inode; + + if (!test_opt(sbi, COMPRESS_CACHE)) + return 0; + + inode = f2fs_iget(sbi->sb, F2FS_COMPRESS_INO(sbi)); + if (IS_ERR(inode)) + return PTR_ERR(inode); + sbi->compress_inode = inode; + + sbi->compress_percent = COMPRESS_PERCENT; + sbi->compress_watermark = COMPRESS_WATERMARK; + + atomic_set(&sbi->compress_page_hit, 0); + + return 0; +} + +void f2fs_destroy_compress_inode(struct f2fs_sb_info *sbi) +{ + if (!sbi->compress_inode) + return; + iput(sbi->compress_inode); + sbi->compress_inode = NULL; +} + int f2fs_init_page_array_cache(struct f2fs_sb_info *sbi) { dev_t dev = sbi->sb->s_bdev->bd_dev; diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index d4795eda12fa..3058c7e28b11 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -132,7 +132,7 @@ static void f2fs_finish_read_bio(struct bio *bio)
if (f2fs_is_compressed_page(page)) { if (bio->bi_status) - f2fs_end_read_compressed_page(page, true); + f2fs_end_read_compressed_page(page, true, 0); f2fs_put_page_dic(page); continue; } @@ -228,15 +228,19 @@ static void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx) struct bio_vec *bv; struct bvec_iter_all iter_all; bool all_compressed = true; + block_t blkaddr = SECTOR_TO_BLOCK(ctx->bio->bi_iter.bi_sector);
bio_for_each_segment_all(bv, ctx->bio, iter_all) { struct page *page = bv->bv_page;
/* PG_error was set if decryption failed. */ if (f2fs_is_compressed_page(page)) - f2fs_end_read_compressed_page(page, PageError(page)); + f2fs_end_read_compressed_page(page, PageError(page), + blkaddr); else all_compressed = false; + + blkaddr++; }
/* @@ -1352,9 +1356,11 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type) old_blkaddr = dn->data_blkaddr; f2fs_allocate_data_block(sbi, NULL, old_blkaddr, &dn->data_blkaddr, &sum, seg_type, NULL); - if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO) + if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO) { invalidate_mapping_pages(META_MAPPING(sbi), old_blkaddr, old_blkaddr); + f2fs_invalidate_compress_page(sbi, old_blkaddr); + } f2fs_update_data_blkaddr(dn, dn->data_blkaddr);
/* @@ -2174,7 +2180,7 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, goto out_put_dnode; }
- for (i = 0; i < dic->nr_cpages; i++) { + for (i = 0; i < cc->nr_cpages; i++) { struct page *page = dic->cpages[i]; block_t blkaddr; struct bio_post_read_ctx *ctx; @@ -2182,6 +2188,14 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, blkaddr = data_blkaddr(dn.inode, dn.node_page, dn.ofs_in_node + i + 1);
+ f2fs_wait_on_block_writeback(inode, blkaddr); + + if (f2fs_load_compressed_page(sbi, page, blkaddr)) { + if (atomic_dec_and_test(&dic->remaining_pages)) + f2fs_decompress_cluster(dic); + continue; + } + if (bio && (!page_is_mergeable(sbi, bio, *last_block_in_bio, blkaddr) || !f2fs_crypt_mergeable_bio(bio, inode, page->index, NULL))) { @@ -2203,8 +2217,6 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, } }
- f2fs_wait_on_block_writeback(inode, blkaddr); - if (bio_add_page(bio, page, blocksize, 0) < blocksize) goto submit_and_realloc;
@@ -3618,6 +3630,13 @@ void f2fs_invalidate_page(struct page *page, unsigned int offset,
clear_page_private_gcing(page);
+ if (test_opt(sbi, COMPRESS_CACHE)) { + if (f2fs_compressed_file(inode)) + f2fs_invalidate_compress_pages(sbi, inode->i_ino); + if (inode->i_ino == F2FS_COMPRESS_INO(sbi)) + clear_page_private_data(page); + } + if (page_private_atomic(page)) return f2fs_drop_inmem_page(inode, page);
@@ -3635,6 +3654,16 @@ int f2fs_release_page(struct page *page, gfp_t wait) if (page_private_atomic(page)) return 0;
+ if (test_opt(F2FS_P_SB(page), COMPRESS_CACHE)) { + struct f2fs_sb_info *sbi = F2FS_P_SB(page); + struct inode *inode = page->mapping->host; + + if (f2fs_compressed_file(inode)) + f2fs_invalidate_compress_pages(sbi, inode->i_ino); + if (inode->i_ino == F2FS_COMPRESS_INO(sbi)) + clear_page_private_data(page); + } + clear_page_private_gcing(page);
detach_page_private(page); diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index c03949a7ccff..833325038ef3 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -152,6 +152,12 @@ static void update_general_status(struct f2fs_sb_info *sbi) si->node_pages = NODE_MAPPING(sbi)->nrpages; if (sbi->meta_inode) si->meta_pages = META_MAPPING(sbi)->nrpages; +#ifdef CONFIG_F2FS_FS_COMPRESSION + if (sbi->compress_inode) { + si->compress_pages = COMPRESS_MAPPING(sbi)->nrpages; + si->compress_page_hit = atomic_read(&sbi->compress_page_hit); + } +#endif si->nats = NM_I(sbi)->nat_cnt[TOTAL_NAT]; si->dirty_nats = NM_I(sbi)->nat_cnt[DIRTY_NAT]; si->sits = MAIN_SEGS(sbi); @@ -309,6 +315,12 @@ static void update_mem_info(struct f2fs_sb_info *sbi)
si->page_mem += (unsigned long long)npages << PAGE_SHIFT; } +#ifdef CONFIG_F2FS_FS_COMPRESSION + if (sbi->compress_inode) { + unsigned npages = COMPRESS_MAPPING(sbi)->nrpages; + si->page_mem += (unsigned long long)npages << PAGE_SHIFT; + } +#endif }
static int stat_show(struct seq_file *s, void *v) @@ -476,6 +488,7 @@ static int stat_show(struct seq_file *s, void *v) "volatile IO: %4d (Max. %4d)\n", si->inmem_pages, si->aw_cnt, si->max_aw_cnt, si->vw_cnt, si->max_vw_cnt); + seq_printf(s, " - compress: %4d, hit:%8d\n", si->compress_pages, si->compress_page_hit); seq_printf(s, " - nodes: %4d in %4d\n", si->ndirty_node, si->node_pages); seq_printf(s, " - dents: %4d in dirs:%4d (%4d)\n", diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index a0e828b5c701..7084b42a4437 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -98,6 +98,7 @@ extern const char *f2fs_fault_name[FAULT_MAX]; #define F2FS_MOUNT_ATGC 0x08000000 #define F2FS_MOUNT_MERGE_CHECKPOINT 0x10000000 #define F2FS_MOUNT_GC_MERGE 0x20000000 +#define F2FS_MOUNT_COMPRESS_CACHE 0x40000000
#define F2FS_OPTION(sbi) ((sbi)->mount_opt) #define clear_opt(sbi, option) (F2FS_OPTION(sbi).opt &= ~F2FS_MOUNT_##option) @@ -1371,6 +1372,37 @@ PAGE_PRIVATE_CLEAR_FUNC(gcing, ONGOING_MIGRATION); PAGE_PRIVATE_CLEAR_FUNC(atomic, ATOMIC_WRITE); PAGE_PRIVATE_CLEAR_FUNC(dummy, DUMMY_WRITE);
+static inline unsigned long get_page_private_data(struct page *page) +{ + unsigned long data = page_private(page); + + if (!test_bit(PAGE_PRIVATE_NOT_POINTER, &data)) + return 0; + return data >> PAGE_PRIVATE_MAX; +} + +static inline void set_page_private_data(struct page *page, unsigned long data) +{ + if (!PagePrivate(page)) { + get_page(page); + SetPagePrivate(page); + } + set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); + page_private(page) |= data << PAGE_PRIVATE_MAX; +} + +static inline void clear_page_private_data(struct page *page) +{ + page_private(page) &= (1 << PAGE_PRIVATE_MAX) - 1; + if (page_private(page) == 1 << PAGE_PRIVATE_NOT_POINTER) { + set_page_private(page, 0); + if (PagePrivate(page)) { + ClearPagePrivate(page); + put_page(page); + } + } +} + /* For compression */ enum compress_algorithm_type { COMPRESS_LZO, @@ -1385,6 +1417,9 @@ enum compress_flag { COMPRESS_MAX_FLAG, };
+#define COMPRESS_WATERMARK 20 +#define COMPRESS_PERCENT 20 + #define COMPRESS_DATA_RESERVED_SIZE 4 struct compress_data { __le32 clen; /* compressed data size */ @@ -1694,6 +1729,12 @@ struct f2fs_sb_info { u64 compr_written_block; u64 compr_saved_block; u32 compr_new_inode; + + /* For compressed block cache */ + struct inode *compress_inode; /* cache compressed blocks */ + unsigned int compress_percent; /* cache page percentage */ + unsigned int compress_watermark; /* cache page watermark */ + atomic_t compress_page_hit; /* cache hit count */ #endif };
@@ -3660,7 +3701,8 @@ struct f2fs_stat_info { unsigned int bimodal, avg_vblocks; int util_free, util_valid, util_invalid; int rsvd_segs, overp_segs; - int dirty_count, node_pages, meta_pages; + int dirty_count, node_pages, meta_pages, compress_pages; + int compress_page_hit; int prefree_count, call_count, cp_count, bg_cp_count; int tot_segs, node_segs, data_segs, free_segs, free_secs; int bg_node_segs, bg_data_segs; @@ -3996,7 +4038,9 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page); bool f2fs_is_compress_backend_ready(struct inode *inode); int f2fs_init_compress_mempool(void); void f2fs_destroy_compress_mempool(void); -void f2fs_end_read_compressed_page(struct page *page, bool failed); +void f2fs_decompress_cluster(struct decompress_io_ctx *dic); +void f2fs_end_read_compressed_page(struct page *page, bool failed, + block_t blkaddr); bool f2fs_cluster_is_empty(struct compress_ctx *cc); bool f2fs_cluster_can_merge_page(struct compress_ctx *cc, pgoff_t index); void f2fs_compress_ctx_add_page(struct compress_ctx *cc, struct page *page); @@ -4014,10 +4058,19 @@ void f2fs_put_page_dic(struct page *page); int f2fs_init_compress_ctx(struct compress_ctx *cc); void f2fs_destroy_compress_ctx(struct compress_ctx *cc, bool reuse); void f2fs_init_compress_info(struct f2fs_sb_info *sbi); +int f2fs_init_compress_inode(struct f2fs_sb_info *sbi); +void f2fs_destroy_compress_inode(struct f2fs_sb_info *sbi); int f2fs_init_page_array_cache(struct f2fs_sb_info *sbi); void f2fs_destroy_page_array_cache(struct f2fs_sb_info *sbi); int __init f2fs_init_compress_cache(void); void f2fs_destroy_compress_cache(void); +struct address_space *COMPRESS_MAPPING(struct f2fs_sb_info *sbi); +void f2fs_invalidate_compress_page(struct f2fs_sb_info *sbi, block_t blkaddr); +void f2fs_cache_compressed_page(struct f2fs_sb_info *sbi, struct page *page, + nid_t ino, block_t blkaddr); +bool f2fs_load_compressed_page(struct f2fs_sb_info *sbi, struct page *page, + block_t blkaddr); +void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi, nid_t ino); #define inc_compr_inode_stat(inode) \ do { \ struct f2fs_sb_info *sbi = F2FS_I_SB(inode); \ @@ -4046,7 +4099,9 @@ static inline struct page *f2fs_compress_control_page(struct page *page) } static inline int f2fs_init_compress_mempool(void) { return 0; } static inline void f2fs_destroy_compress_mempool(void) { } -static inline void f2fs_end_read_compressed_page(struct page *page, bool failed) +static inline void f2fs_decompress_cluster(struct decompress_io_ctx *dic) { } +static inline void f2fs_end_read_compressed_page(struct page *page, + bool failed, block_t blkaddr) { WARN_ON_ONCE(1); } @@ -4054,10 +4109,20 @@ static inline void f2fs_put_page_dic(struct page *page) { WARN_ON_ONCE(1); } +static inline int f2fs_init_compress_inode(struct f2fs_sb_info *sbi) { return 0; } +static inline void f2fs_destroy_compress_inode(struct f2fs_sb_info *sbi) { } static inline int f2fs_init_page_array_cache(struct f2fs_sb_info *sbi) { return 0; } static inline void f2fs_destroy_page_array_cache(struct f2fs_sb_info *sbi) { } static inline int __init f2fs_init_compress_cache(void) { return 0; } static inline void f2fs_destroy_compress_cache(void) { } +static inline void f2fs_invalidate_compress_page(struct f2fs_sb_info *sbi, + block_t blkaddr) { } +static inline void f2fs_cache_compressed_page(struct f2fs_sb_info *sbi, + struct page *page, nid_t ino, block_t blkaddr) { } +static inline bool f2fs_load_compressed_page(struct f2fs_sb_info *sbi, + struct page *page, block_t blkaddr) { return false; } +static inline void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi, + nid_t ino) { } #define inc_compr_inode_stat(inode) do { } while (0) #endif
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 5ae066a71d4c..83b0a7872b3c 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1261,6 +1261,7 @@ static int move_data_block(struct inode *inode, block_t bidx, f2fs_put_page(mpage, 1); invalidate_mapping_pages(META_MAPPING(fio.sbi), fio.old_blkaddr, fio.old_blkaddr); + f2fs_invalidate_compress_page(fio.sbi, fio.old_blkaddr);
set_page_dirty(fio.encrypted_page); if (clear_page_dirty_for_io(fio.encrypted_page)) diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index cbda7ca3b3be..9141147b5bb0 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -18,6 +18,10 @@
#include <trace/events/f2fs.h>
+#ifdef CONFIG_F2FS_FS_COMPRESSION +extern const struct address_space_operations f2fs_compress_aops; +#endif + void f2fs_mark_inode_dirty_sync(struct inode *inode, bool sync) { if (is_inode_flag_set(inode, FI_NEW_INODE)) @@ -494,6 +498,11 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) if (ino == F2FS_NODE_INO(sbi) || ino == F2FS_META_INO(sbi)) goto make_now;
+#ifdef CONFIG_F2FS_FS_COMPRESSION + if (ino == F2FS_COMPRESS_INO(sbi)) + goto make_now; +#endif + ret = do_read_inode(inode); if (ret) goto bad_inode; @@ -504,6 +513,12 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) } else if (ino == F2FS_META_INO(sbi)) { inode->i_mapping->a_ops = &f2fs_meta_aops; mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); + } else if (ino == F2FS_COMPRESS_INO(sbi)) { +#ifdef CONFIG_F2FS_FS_COMPRESSION + inode->i_mapping->a_ops = &f2fs_compress_aops; +#endif + mapping_set_gfp_mask(inode->i_mapping, + GFP_NOFS | __GFP_HIGHMEM | __GFP_MOVABLE); } else if (S_ISREG(inode->i_mode)) { inode->i_op = &f2fs_file_inode_operations; inode->i_fop = &f2fs_file_operations; @@ -723,8 +738,12 @@ void f2fs_evict_inode(struct inode *inode) trace_f2fs_evict_inode(inode); truncate_inode_pages_final(&inode->i_data);
+ if (test_opt(sbi, COMPRESS_CACHE) && f2fs_compressed_file(inode)) + f2fs_invalidate_compress_pages(sbi, inode->i_ino); + if (inode->i_ino == F2FS_NODE_INO(sbi) || - inode->i_ino == F2FS_META_INO(sbi)) + inode->i_ino == F2FS_META_INO(sbi) || + inode->i_ino == F2FS_COMPRESS_INO(sbi)) goto out_clear;
f2fs_bug_on(sbi, get_dirty_pages(inode)); diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 3a8f7afa5059..dd611efa8aa4 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -97,6 +97,20 @@ bool f2fs_available_free_memory(struct f2fs_sb_info *sbi, int type) mem_size = (atomic_read(&dcc->discard_cmd_cnt) * sizeof(struct discard_cmd)) >> PAGE_SHIFT; res = mem_size < (avail_ram * nm_i->ram_thresh / 100); + } else if (type == COMPRESS_PAGE) { +#ifdef CONFIG_F2FS_FS_COMPRESSION + unsigned long free_ram = val.freeram; + + /* + * free memory is lower than watermark or cached page count + * exceed threshold, deny caching compress page. + */ + res = (free_ram > avail_ram * sbi->compress_watermark / 100) && + (COMPRESS_MAPPING(sbi)->nrpages < + free_ram * sbi->compress_percent / 100); +#else + res = false; +#endif } else { if (!sbi->sb->s_bdi->wb.dirty_exceeded) return true; diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h index d85e8659cfda..84d45385d1f2 100644 --- a/fs/f2fs/node.h +++ b/fs/f2fs/node.h @@ -148,6 +148,7 @@ enum mem_type { EXTENT_CACHE, /* indicates extent cache */ INMEM_PAGES, /* indicates inmemory pages */ DISCARD_CACHE, /* indicates memory of cached discard cmds */ + COMPRESS_PAGE, /* indicates memory of cached compressed pages */ BASE_CHECK, /* check kernel status */ };
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 8668df7870d0..406a6b244782 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -2322,6 +2322,7 @@ void f2fs_invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr) return;
invalidate_mapping_pages(META_MAPPING(sbi), addr, addr); + f2fs_invalidate_compress_page(sbi, addr);
/* add it into sit main buffer */ down_write(&sit_i->sentry_lock); @@ -3469,9 +3470,11 @@ static void do_write_page(struct f2fs_summary *sum, struct f2fs_io_info *fio) reallocate: f2fs_allocate_data_block(fio->sbi, fio->page, fio->old_blkaddr, &fio->new_blkaddr, sum, type, fio); - if (GET_SEGNO(fio->sbi, fio->old_blkaddr) != NULL_SEGNO) + if (GET_SEGNO(fio->sbi, fio->old_blkaddr) != NULL_SEGNO) { invalidate_mapping_pages(META_MAPPING(fio->sbi), fio->old_blkaddr, fio->old_blkaddr); + f2fs_invalidate_compress_page(fio->sbi, fio->old_blkaddr); + }
/* writeout dirty page into bdev */ f2fs_submit_page_write(fio); @@ -3661,6 +3664,7 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO) { invalidate_mapping_pages(META_MAPPING(sbi), old_blkaddr, old_blkaddr); + f2fs_invalidate_compress_page(sbi, old_blkaddr); if (!from_gc) update_segment_mtime(sbi, old_blkaddr, 0); update_sit_entry(sbi, old_blkaddr, -1); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 8b2b34500b2a..97e3efe5a020 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -150,6 +150,7 @@ enum { Opt_compress_extension, Opt_compress_chksum, Opt_compress_mode, + Opt_compress_cache, Opt_atgc, Opt_gc_merge, Opt_nogc_merge, @@ -224,6 +225,7 @@ static match_table_t f2fs_tokens = { {Opt_compress_extension, "compress_extension=%s"}, {Opt_compress_chksum, "compress_chksum"}, {Opt_compress_mode, "compress_mode=%s"}, + {Opt_compress_cache, "compress_cache"}, {Opt_atgc, "atgc"}, {Opt_gc_merge, "gc_merge"}, {Opt_nogc_merge, "nogc_merge"}, @@ -1066,12 +1068,16 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) } kfree(name); break; + case Opt_compress_cache: + set_opt(sbi, COMPRESS_CACHE); + break; #else case Opt_compress_algorithm: case Opt_compress_log_size: case Opt_compress_extension: case Opt_compress_chksum: case Opt_compress_mode: + case Opt_compress_cache: f2fs_info(sbi, "compression options not supported"); break; #endif @@ -1403,6 +1409,8 @@ static void f2fs_put_super(struct super_block *sb)
f2fs_bug_on(sbi, sbi->fsync_node_num);
+ f2fs_destroy_compress_inode(sbi); + iput(sbi->node_inode); sbi->node_inode = NULL;
@@ -1672,6 +1680,9 @@ static inline void f2fs_show_compress_options(struct seq_file *seq, seq_printf(seq, ",compress_mode=%s", "fs"); else if (F2FS_OPTION(sbi).compress_mode == COMPR_MODE_USER) seq_printf(seq, ",compress_mode=%s", "user"); + + if (test_opt(sbi, COMPRESS_CACHE)) + seq_puts(seq, ",compress_cache"); } #endif
@@ -1958,6 +1969,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) bool disable_checkpoint = test_opt(sbi, DISABLE_CHECKPOINT); bool no_io_align = !F2FS_IO_ALIGNED(sbi); bool no_atgc = !test_opt(sbi, ATGC); + bool no_compress_cache = !test_opt(sbi, COMPRESS_CACHE); bool checkpoint_changed; #ifdef CONFIG_QUOTA int i, j; @@ -2050,6 +2062,12 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) goto restore_opts; }
+ if (no_compress_cache == !!test_opt(sbi, COMPRESS_CACHE)) { + err = -EINVAL; + f2fs_warn(sbi, "switch compress_cache option is not allowed"); + goto restore_opts; + } + if ((*flags & SB_RDONLY) && test_opt(sbi, DISABLE_CHECKPOINT)) { err = -EINVAL; f2fs_warn(sbi, "disabling checkpoint not compatible with read-only"); @@ -3975,10 +3993,14 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) goto free_node_inode; }
- err = f2fs_register_sysfs(sbi); + err = f2fs_init_compress_inode(sbi); if (err) goto free_root_inode;
+ err = f2fs_register_sysfs(sbi); + if (err) + goto free_compress_inode; + #ifdef CONFIG_QUOTA /* Enable quota usage during mount */ if (f2fs_sb_has_quota_ino(sbi) && !f2fs_readonly(sb)) { @@ -4119,6 +4141,8 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) /* evict some inodes being cached by GC */ evict_inodes(sb); f2fs_unregister_sysfs(sbi); +free_compress_inode: + f2fs_destroy_compress_inode(sbi); free_root_inode: dput(sb->s_root); sb->s_root = NULL; @@ -4197,6 +4221,15 @@ static void kill_f2fs_super(struct super_block *sb) f2fs_stop_gc_thread(sbi); f2fs_stop_discard_thread(sbi);
+#ifdef CONFIG_F2FS_FS_COMPRESSION + /* + * latter evict_inode() can bypass checking and invalidating + * compress inode cache. + */ + if (test_opt(sbi, COMPRESS_CACHE)) + truncate_inode_pages_final(COMPRESS_MAPPING(sbi)); +#endif + if (is_sbi_flag_set(sbi, SBI_IS_DIRTY) || !is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) { struct cp_control cpc = { diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index 5487a80617a3..0021ea8f7c3b 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -34,6 +34,7 @@ #define F2FS_ROOT_INO(sbi) ((sbi)->root_ino_num) #define F2FS_NODE_INO(sbi) ((sbi)->node_ino_num) #define F2FS_META_INO(sbi) ((sbi)->meta_ino_num) +#define F2FS_COMPRESS_INO(sbi) (NM_I(sbi)->max_nid)
#define F2FS_MAX_QUOTAS 3
From: Chao Yu chao@kernel.org
[ Upstream commit 277afbde6ca2b38729683fc17c031b4bc942068d ]
In f2fs_remount(), return value of test_opt() is an unsigned int type variable, however when we compare it to a bool type variable, it cause wrong result, fix it.
Fixes: 4354994f097d ("f2fs: checkpoint disabling") Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/super.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 97e3efe5a020..d61f7fcdc66b 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1966,11 +1966,10 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) bool need_restart_ckpt = false, need_stop_ckpt = false; bool need_restart_flush = false, need_stop_flush = false; bool no_extent_cache = !test_opt(sbi, EXTENT_CACHE); - bool disable_checkpoint = test_opt(sbi, DISABLE_CHECKPOINT); + bool enable_checkpoint = !test_opt(sbi, DISABLE_CHECKPOINT); bool no_io_align = !F2FS_IO_ALIGNED(sbi); bool no_atgc = !test_opt(sbi, ATGC); bool no_compress_cache = !test_opt(sbi, COMPRESS_CACHE); - bool checkpoint_changed; #ifdef CONFIG_QUOTA int i, j; #endif @@ -2015,8 +2014,6 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) err = parse_options(sb, data, true); if (err) goto restore_opts; - checkpoint_changed = - disable_checkpoint != test_opt(sbi, DISABLE_CHECKPOINT);
/* * Previous and new state of filesystem is RO, @@ -2133,7 +2130,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) need_stop_flush = true; }
- if (checkpoint_changed) { + if (enable_checkpoint == !!test_opt(sbi, DISABLE_CHECKPOINT)) { if (test_opt(sbi, DISABLE_CHECKPOINT)) { err = f2fs_disable_checkpoint(sbi); if (err)
From: Jason Gunthorpe jgg@nvidia.com
[ Upstream commit 26c22cfde5dd6e63f25c48458b0185dcb0fbb2fd ]
VFIO_NOIOMMU is supposed to be an element in the VFIO menu, not start a new menu. Correct this copy-paste mistake.
Fixes: 03a76b60f8ba ("vfio: Include No-IOMMU mode") Signed-off-by: Jason Gunthorpe jgg@nvidia.com Reviewed-by: Cornelia Huck cohuck@redhat.com Link: https://lore.kernel.org/r/0-v1-3f0b685c3679+478-vfio_menuconfig_jgg@nvidia.c... Signed-off-by: Alex Williamson alex.williamson@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/vfio/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig index 67d0bf4efa16..e44bf736e2b2 100644 --- a/drivers/vfio/Kconfig +++ b/drivers/vfio/Kconfig @@ -29,7 +29,7 @@ menuconfig VFIO
If you don't know what to do here, say N.
-menuconfig VFIO_NOIOMMU +config VFIO_NOIOMMU bool "VFIO No-IOMMU support" depends on VFIO help
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit d3d9c4570285090b533b00946b72647361f0345b ]
If param_offset > buff_len then the memcpy() statement in ufshcd_read_desc_param() corrupts memory since it copies 256 + buff_len - param_offset bytes into a buffer with size buff_len. Since param_offset < 256 this results in writing past the bound of the output buffer.
Link: https://lore.kernel.org/r/20210722033439.26550-2-bvanassche@acm.org Fixes: cbe193f6f093 ("scsi: ufs: Fix potential NULL pointer access during memcpy") Reviewed-by: Avri Altman avri.altman@wdc.com Reviewed-by: Daejun Park daejun7.park@samsung.com Signed-off-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/ufs/ufshcd.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 72fd41bfbd54..90837e54c2fe 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -3326,9 +3326,11 @@ int ufshcd_read_desc_param(struct ufs_hba *hba,
if (is_kmalloc) { /* Make sure we don't copy more data than available */ - if (param_offset + param_size > buff_len) - param_size = buff_len - param_offset; - memcpy(param_read_buf, &desc_buf[param_offset], param_size); + if (param_offset >= buff_len) + ret = -EINVAL; + else + memcpy(param_read_buf, &desc_buf[param_offset], + min_t(u32, param_size, buff_len - param_offset)); } out: if (is_kmalloc)
From: Gautham R. Shenoy ego@linux.vnet.ibm.com
[ Upstream commit 50741b70b0cbbafbd9199f5180e66c0c53783a4a ]
Commit d947fb4c965c ("cpuidle: pseries: Fixup exit latency for CEDE(0)") sets the exit latency of CEDE(0) based on the latency values of the Extended CEDE states advertised by the platform
On POWER9 LPARs, the firmwares advertise a very low value of 2us for CEDE1 exit latency on a Dedicated LPAR. The latency advertized by the PHYP hypervisor corresponds to the latency required to wakeup from the underlying hardware idle state. However the wakeup latency from the LPAR perspective should include
1. The time taken to transition the CPU from the Hypervisor into the LPAR post wakeup from platform idle state
2. Time taken to send the IPI from the source CPU (waker) to the idle target CPU (wakee).
1. can be measured via timer idle test, where we queue a timer, say for 1ms, and enter the CEDE state. When the timer fires, in the timer handler we compute how much extra timer over the expected 1ms have we consumed. On a a POWER9 LPAR the numbers are
CEDE latency measured using a timer (numbers in ns) N Min Median Avg 90%ile 99%ile Max Stddev 400 2601 5677 5668.74 5917 6413 9299 455.01
1. and 2. combined can be determined by an IPI latency test where we send an IPI to an idle CPU and in the handler compute the time difference between when the IPI was sent and when the handler ran. We see the following numbers on POWER9 LPAR.
CEDE latency measured using an IPI (numbers in ns) N Min Median Avg 90%ile 99%ile Max Stddev 400 711 7564 7369.43 8559 9514 9698 1200.01
Suppose, we consider the 99th percentile latency value measured using the IPI to be the wakeup latency, the value would be 9.5us This is in the ballpark of the default value of 10us.
Hence, use the exit latency of CEDE(0) based on the latency values advertized by platform only from POWER10 onwards. The values advertized on POWER10 platforms is more realistic and informed by the latency measurements. For earlier platforms stick to the default value of 10us. The fix was suggested by Michael Ellerman.
Fixes: d947fb4c965c ("cpuidle: pseries: Fixup exit latency for CEDE(0)") Reported-by: Enrico Joedecke joedecke@de.ibm.com Signed-off-by: Gautham R. Shenoy ego@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/1626676399-15975-2-git-send-email-ego@linux.vnet.i... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpuidle/cpuidle-pseries.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/cpuidle/cpuidle-pseries.c b/drivers/cpuidle/cpuidle-pseries.c index a2b5c6f60cf0..e592280d8acf 100644 --- a/drivers/cpuidle/cpuidle-pseries.c +++ b/drivers/cpuidle/cpuidle-pseries.c @@ -419,7 +419,21 @@ static int pseries_idle_probe(void) cpuidle_state_table = shared_states; max_idle_state = ARRAY_SIZE(shared_states); } else { - fixup_cede0_latency(); + /* + * Use firmware provided latency values + * starting with POWER10 platforms. In the + * case that we are running on a POWER10 + * platform but in an earlier compat mode, we + * can still use the firmware provided values. + * + * However, on platforms prior to POWER10, we + * cannot rely on the accuracy of the firmware + * provided latency values. On such platforms, + * go with the conservative default estimate + * of 10us. + */ + if (cpu_has_feature(CPU_FTR_ARCH_31) || pvr_version_is(PVR_POWER10)) + fixup_cede0_latency(); cpuidle_state_table = dedicated_states; max_idle_state = NR_DEDICATED_STATES; }
From: Michal Suchanek msuchanek@suse.de
[ Upstream commit a6cae77f1bc89368a4e2822afcddc45c3062d499 ]
commit 7c6986ade69e ("powerpc/stacktrace: Fix spurious "stale" traces in raise_backtrace_ipi()") introduces udelay() call without including the linux/delay.h header. This may happen to work on master but the header that declares the functionshould be included nonetheless.
Fixes: 7c6986ade69e ("powerpc/stacktrace: Fix spurious "stale" traces in raise_backtrace_ipi()") Signed-off-by: Michal Suchanek msuchanek@suse.de Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20210729180103.15578-1-msuchanek@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/stacktrace.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c index ea0d9c36e177..b64b734a5030 100644 --- a/arch/powerpc/kernel/stacktrace.c +++ b/arch/powerpc/kernel/stacktrace.c @@ -8,6 +8,7 @@ * Copyright 2018 Nick Piggin, Michael Ellerman, IBM Corp. */
+#include <linux/delay.h> #include <linux/export.h> #include <linux/kallsyms.h> #include <linux/module.h>
From: Leon Romanovsky leonro@nvidia.com
[ Upstream commit e66e49592b690d6abd537cc207b07a3db2f413d0 ]
QP attributes that were supplied by IB/core already have all parameters set when they are passed to the driver. The drivers are not supposed to change anything in struct ib_qp_init_attr.
Fixes: 66d86e529dd5 ("RDMA/hns: Add UD support for HIP09") Link: https://lore.kernel.org/r/5987138875e8ade9aa339d4db6e1bd9694ed4591.162704018... Signed-off-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hns/hns_roce_qp.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index 230a909ba9bc..80661d368860 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -1158,14 +1158,8 @@ struct ib_qp *hns_roce_create_qp(struct ib_pd *pd, if (!hr_qp) return ERR_PTR(-ENOMEM);
- if (init_attr->qp_type == IB_QPT_XRC_INI) - init_attr->recv_cq = NULL; - - if (init_attr->qp_type == IB_QPT_XRC_TGT) { + if (init_attr->qp_type == IB_QPT_XRC_TGT) hr_qp->xrcdn = to_hr_xrcd(init_attr->xrcd)->xrcdn; - init_attr->recv_cq = NULL; - init_attr->send_cq = NULL; - }
if (init_attr->qp_type == IB_QPT_GSI) { hr_qp->port = init_attr->port_num - 1;
From: Leon Romanovsky leonro@nvidia.com
[ Upstream commit f9193d266347fe9bed5c173e7a1bf96268142a79 ]
The QP type is set by the IB/core and shouldn't be set in the driver.
Fixes: 40909f664d27 ("RDMA/efa: Add EFA verbs implementation") Link: https://lore.kernel.org/r/838c40134c1590167b888ca06ad51071139ff2ae.162704018... Acked-by: Gal Pressman galpress@amazon.com Signed-off-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/efa/efa_verbs.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/infiniband/hw/efa/efa_verbs.c b/drivers/infiniband/hw/efa/efa_verbs.c index 51572f1dc611..72621ecd81f7 100644 --- a/drivers/infiniband/hw/efa/efa_verbs.c +++ b/drivers/infiniband/hw/efa/efa_verbs.c @@ -717,7 +717,6 @@ struct ib_qp *efa_create_qp(struct ib_pd *ibpd,
qp->qp_handle = create_qp_resp.qp_handle; qp->ibqp.qp_num = create_qp_resp.qp_num; - qp->ibqp.qp_type = init_attr->qp_type; qp->max_send_wr = init_attr->cap.max_send_wr; qp->max_recv_wr = init_attr->cap.max_recv_wr; qp->max_send_sge = init_attr->cap.max_send_sge;
From: Leon Romanovsky leonro@nvidia.com
[ Upstream commit 5f6bb7e32283b8e3339b7adc00638234ac199cc4 ]
XRC_TGT QPs are created through kernel verbs and don't have udata at all.
Fixes: 6eefa839c4dd ("RDMA/mlx5: Protect from kernel crash if XRC_TGT doesn't have udata") Fixes: e383085c2425 ("RDMA/mlx5: Set ECE options during QP create") Link: https://lore.kernel.org/r/b68228597e730675020aa5162745390a2d39d3a2.162801476... Signed-off-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/mlx5/qp.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 5851486c0d93..2471f48ea5f3 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -1896,7 +1896,6 @@ static int get_atomic_mode(struct mlx5_ib_dev *dev, static int create_xrc_tgt_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, struct mlx5_create_qp_params *params) { - struct mlx5_ib_create_qp *ucmd = params->ucmd; struct ib_qp_init_attr *attr = params->attr; u32 uidx = params->uidx; struct mlx5_ib_resources *devr = &dev->devr; @@ -1916,8 +1915,6 @@ static int create_xrc_tgt_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, if (!in) return -ENOMEM;
- if (MLX5_CAP_GEN(mdev, ece_support) && ucmd) - MLX5_SET(create_qp_in, in, ece, ucmd->ece_options); qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
MLX5_SET(qpc, qpc, st, MLX5_QP_ST_XRC);
From: Nathan Chancellor nathan@kernel.org
[ Upstream commit d04691d373e75c83424b85c0e68e4a3f9370c10d ]
After commit 7cbd631d4dec ("cpuidle: pseries: Fixup CEDE0 latency only for POWER10 onwards"), pseries_idle_probe() is no longer inlined when compiling with clang, which causes a modpost warning:
WARNING: modpost: vmlinux.o(.text+0xc86a54): Section mismatch in reference from the function pseries_idle_probe() to the function .init.text:fixup_cede0_latency() The function pseries_idle_probe() references the function __init fixup_cede0_latency(). This is often because pseries_idle_probe lacks a __init annotation or the annotation of fixup_cede0_latency is wrong.
pseries_idle_probe() is a non-init function, which calls fixup_cede0_latency(), which is an init function, explaining the mismatch. pseries_idle_probe() is only called from pseries_processor_idle_init(), which is an init function, so mark pseries_idle_probe() as __init so there is no more warning.
Fixes: 054e44ba99ae ("cpuidle: pseries: Add function to parse extended CEDE records") Signed-off-by: Nathan Chancellor nathan@kernel.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20210803211547.1093820-1-nathan@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpuidle/cpuidle-pseries.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/cpuidle/cpuidle-pseries.c b/drivers/cpuidle/cpuidle-pseries.c index e592280d8acf..ff164dec8422 100644 --- a/drivers/cpuidle/cpuidle-pseries.c +++ b/drivers/cpuidle/cpuidle-pseries.c @@ -402,7 +402,7 @@ static void __init fixup_cede0_latency(void) * pseries_idle_probe() * Choose state table for shared versus dedicated partition */ -static int pseries_idle_probe(void) +static int __init pseries_idle_probe(void) {
if (cpuidle_disable != IDLE_NO_OVERRIDE)
From: Yangtao Li frank.li@vivo.com
[ Upstream commit d4bf15a7ce172d186d400d606adf4f34a59130d6 ]
I recently found a case where de->name_len is 0 in f2fs_fill_dentries() easily reproduced, and finally set the fsck flag.
Thread A Thread B - f2fs_readdir - f2fs_read_inline_dir - ctx->pos = d.max - f2fs_add_dentry - f2fs_add_inline_entry - do_convert_inline_dir - f2fs_add_regular_entry - f2fs_readdir - f2fs_fill_dentries - set_sbi_flag(sbi, SBI_NEED_FSCK)
Process A opens the folder, and has been reading without closing it. During this period, Process B created a file under the folder (occupying multiple f2fs_dir_entry, exceeding the d.max of the inline dir). After creation, process A uses the d.max of inline dir to read it again, and it will read that de->name_len is 0.
And Chao pointed out that w/o inline conversion, the race condition still can happen as below:
dir_entry1: A dir_entry2: B dir_entry3: C free slot: _ ctx->pos: ^
Thread A is traversing directory, ctx-pos moves to below position after readdir() by thread A: AAAABBBB___ ^
Then thread B delete dir_entry2, and create dir_entry3.
Thread A calls readdir() to lookup dirents starting from middle of new dirent slots as below: AAAACCCCCC_ ^ In these scenarios, the file system is not damaged, and it's hard to avoid it. But we can bypass tagging FSCK flag if: a) bit_pos (:= ctx->pos % d->max) is non-zero and b) before bit_pos moves to first valid dir_entry.
Fixes: ddf06b753a85 ("f2fs: fix to trigger fsck if dirent.name_len is zero") Signed-off-by: Yangtao Li frank.li@vivo.com [Chao: clean up description] Reviewed-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/dir.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 96dcc4aca639..c821015c0a46 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -995,6 +995,7 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, struct f2fs_sb_info *sbi = F2FS_I_SB(d->inode); struct blk_plug plug; bool readdir_ra = sbi->readdir_ra == 1; + bool found_valid_dirent = false; int err = 0;
bit_pos = ((unsigned long)ctx->pos % d->max); @@ -1009,13 +1010,15 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d,
de = &d->dentry[bit_pos]; if (de->name_len == 0) { + if (found_valid_dirent || !bit_pos) { + printk_ratelimited( + "%sF2FS-fs (%s): invalid namelen(0), ino:%u, run fsck to fix.", + KERN_WARNING, sbi->sb->s_id, + le32_to_cpu(de->ino)); + set_sbi_flag(sbi, SBI_NEED_FSCK); + } bit_pos++; ctx->pos = start_pos + bit_pos; - printk_ratelimited( - "%sF2FS-fs (%s): invalid namelen(0), ino:%u, run fsck to fix.", - KERN_WARNING, sbi->sb->s_id, - le32_to_cpu(de->ino)); - set_sbi_flag(sbi, SBI_NEED_FSCK); continue; }
@@ -1058,6 +1061,7 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, f2fs_ra_node_page(sbi, le32_to_cpu(de->ino));
ctx->pos = start_pos + bit_pos; + found_valid_dirent = true; } out: if (readdir_ra)
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 946e1052cdcc7e585ee5d1e72528ca49fb295243 ]
Don't call printk() when CONFIG_PRINTK is not set. Fixes the following build errors:
or1k-linux-ld: arch/openrisc/kernel/entry.o: in function `_external_irq_handler': (.text+0x804): undefined reference to `printk' (.text+0x804): relocation truncated to fit: R_OR1K_INSN_REL_26 against undefined symbol `printk'
Fixes: 9d02a4283e9c ("OpenRISC: Boot code") Signed-off-by: Randy Dunlap rdunlap@infradead.org Reported-by: kernel test robot lkp@intel.com Cc: Jonas Bonn jonas@southpole.se Cc: Stefan Kristiansson stefan.kristiansson@saunalahti.fi Cc: Stafford Horne shorne@gmail.com Cc: openrisc@lists.librecores.org Signed-off-by: Stafford Horne shorne@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/openrisc/kernel/entry.S | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S index bc657e55c15f..98e4f97db515 100644 --- a/arch/openrisc/kernel/entry.S +++ b/arch/openrisc/kernel/entry.S @@ -547,6 +547,7 @@ EXCEPTION_ENTRY(_external_irq_handler) l.bnf 1f // ext irq enabled, all ok. l.nop
+#ifdef CONFIG_PRINTK l.addi r1,r1,-0x8 l.movhi r3,hi(42f) l.ori r3,r3,lo(42f) @@ -560,6 +561,7 @@ EXCEPTION_ENTRY(_external_irq_handler) .string "\n\rESR interrupt bug: in _external_irq_handler (ESR %x)\n\r" .align 4 .previous +#endif
l.ori r4,r4,SPR_SR_IEE // fix the bug // l.sw PT_SR(r1),r4
From: Anthony Iliopoulos ailiop@suse.com
[ Upstream commit 173735c346c412d9f084825ecb04f24ada0e2986 ]
Due to link order, dma_debug_init is called before debugfs has a chance to initialize (via debugfs_init which also happens in the core initcall stage), so the directories for dma-debug are never created.
Decouple dma_debug_fs_init from dma_debug_init and defer its init until core_initcall_sync (after debugfs has been initialized) while letting dma-debug initialization occur as soon as possible to catch any early mappings, as suggested in [1].
[1] https://lore.kernel.org/linux-iommu/YIgGa6yF%2Fadg8OSN@kroah.com/
Fixes: 15b28bbcd567 ("dma-debug: move initialization to common code") Signed-off-by: Anthony Iliopoulos ailiop@suse.com Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/dma/debug.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c index 14de1271463f..445754529917 100644 --- a/kernel/dma/debug.c +++ b/kernel/dma/debug.c @@ -794,7 +794,7 @@ static int dump_show(struct seq_file *seq, void *v) } DEFINE_SHOW_ATTRIBUTE(dump);
-static void dma_debug_fs_init(void) +static int __init dma_debug_fs_init(void) { struct dentry *dentry = debugfs_create_dir("dma-api", NULL);
@@ -807,7 +807,10 @@ static void dma_debug_fs_init(void) debugfs_create_u32("nr_total_entries", 0444, dentry, &nr_total_entries); debugfs_create_file("driver_filter", 0644, dentry, NULL, &filter_fops); debugfs_create_file("dump", 0444, dentry, NULL, &dump_fops); + + return 0; } +core_initcall_sync(dma_debug_fs_init);
static int device_dma_allocations(struct device *dev, struct dma_debug_entry **out_entry) { @@ -892,8 +895,6 @@ static int dma_debug_init(void) spin_lock_init(&dma_entry_hash[i].lock); }
- dma_debug_fs_init(); - nr_pages = DIV_ROUND_UP(nr_prealloc_entries, DMA_DEBUG_DYNAMIC_ENTRIES); for (i = 0; i < nr_pages; ++i) dma_debug_create_entries(GFP_KERNEL);
From: Chuck Lever chuck.lever@oracle.com
[ Upstream commit 97480cae13ca3a9c1de3eb6fd66cf9650a60db42 ]
Ensure the tear-down completion is awoken only /after/ we've stopped fiddling with rpcrdma_rep objects in rpcrdma_post_recvs().
Fixes: 15788d1d1077 ("xprtrdma: Do not refresh Receive Queue while it is draining") Signed-off-by: Chuck Lever chuck.lever@oracle.com Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/sunrpc/xprtrdma/verbs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 649c23518ec0..5a11e318a0d9 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -1416,11 +1416,6 @@ void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, int needed, bool temp)
rc = ib_post_recv(ep->re_id->qp, wr, (const struct ib_recv_wr **)&bad_wr); - if (atomic_dec_return(&ep->re_receiving) > 0) - complete(&ep->re_done); - -out: - trace_xprtrdma_post_recvs(r_xprt, count, rc); if (rc) { for (wr = bad_wr; wr;) { struct rpcrdma_rep *rep; @@ -1431,6 +1426,11 @@ void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, int needed, bool temp) --count; } } + if (atomic_dec_return(&ep->re_receiving) > 0) + complete(&ep->re_done); + +out: + trace_xprtrdma_post_recvs(r_xprt, count, rc); ep->re_receive_count += count; return; }
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit e20772cbdf463c12088837e5a08bde1b876bfd25 ]
If NFS_LAYOUT_RETURN_REQUESTED is set, but there is no value set for the layout plh_return_seq, we can end up in a livelock loop in which every layout segment retrieved by a new call to layoutget is immediately invalidated by pnfs_layout_need_return(). To get around this, we should just set plh_return_seq to the current value of the layout stateid's seqid.
Fixes: d474f96104bd ("NFS: Don't return layout segments that are in use") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/pnfs.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index be960e47d7f6..3ee607aa007b 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -347,11 +347,15 @@ pnfs_set_plh_return_info(struct pnfs_layout_hdr *lo, enum pnfs_iomode iomode, iomode = IOMODE_ANY; lo->plh_return_iomode = iomode; set_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags); - if (seq != 0) { - WARN_ON_ONCE(lo->plh_return_seq != 0 && lo->plh_return_seq != seq); + /* + * We must set lo->plh_return_seq to avoid livelocks with + * pnfs_layout_need_return() + */ + if (seq == 0) + seq = be32_to_cpu(lo->plh_stateid.seqid); + if (!lo->plh_return_seq || pnfs_seqid_is_newer(seq, lo->plh_return_seq)) lo->plh_return_seq = seq; - pnfs_barrier_update(lo, seq); - } + pnfs_barrier_update(lo, seq); }
static void
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit 45baadaad7bf9183651fb74f4ed1200da48505a5 ]
A zero value for the layout barrier indicates that it has been cleared (since seqid '0' is an illegal value), so we should always allow it to be updated.
Fixes: d29b468da4f9 ("pNFS/NFSv4: Improve rejection of out-of-order layouts") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/pnfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 3ee607aa007b..6cc5ae51fd80 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -335,7 +335,7 @@ static bool pnfs_seqid_is_newer(u32 s1, u32 s2)
static void pnfs_barrier_update(struct pnfs_layout_hdr *lo, u32 newseq) { - if (pnfs_seqid_is_newer(newseq, lo->plh_barrier)) + if (pnfs_seqid_is_newer(newseq, lo->plh_barrier) || !lo->plh_barrier) lo->plh_barrier = newseq; }
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit d6236a98b3bab07c0a1455fd1ab46f79c3978cdc ]
The intention of the layout barrier is to ensure that we do not update the layout to match an older value than the current expectation. Fix the test in pnfs_layout_stateid_blocked() to reflect that it is legal for the seqid of the stateid to match that of the barrier.
Fixes: aa95edf309ef ("NFSv4/pnfs: Fix the layout barrier update") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/pnfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 6cc5ae51fd80..28350d62b9bd 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -1004,7 +1004,7 @@ pnfs_layout_stateid_blocked(const struct pnfs_layout_hdr *lo, { u32 seqid = be32_to_cpu(stateid->seqid);
- return !pnfs_seqid_is_newer(seqid, lo->plh_barrier) && lo->plh_barrier; + return lo->plh_barrier && pnfs_seqid_is_newer(lo->plh_barrier, seqid); }
/* lget is set to 1 if called from inside send_layoutget call chain */
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit c2dc3e5fad13aca5d7bdf4bcb52b1a1d707c8555 ]
We really should not call rpc_wake_up_queued_task_set_status() with xprt->snd_task as an argument unless we are certain that is actually an rpc_task.
Fixes: 0445f92c5d53 ("SUNRPC: Fix disconnection races") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/sunrpc/xprt.h | 1 + net/sunrpc/xprt.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 61b622e334ee..52e5b11e4b6a 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -422,6 +422,7 @@ void xprt_unlock_connect(struct rpc_xprt *, void *); #define XPRT_CONGESTED (9) #define XPRT_CWND_WAIT (10) #define XPRT_WRITE_SPACE (11) +#define XPRT_SND_IS_COOKIE (12)
static inline void xprt_set_connected(struct rpc_xprt *xprt) { diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 3509a7f139b9..19fa8616b8cf 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -774,9 +774,9 @@ void xprt_force_disconnect(struct rpc_xprt *xprt) /* Try to schedule an autoclose RPC call */ if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0) queue_work(xprtiod_workqueue, &xprt->task_cleanup); - else if (xprt->snd_task) + else if (xprt->snd_task && !test_bit(XPRT_SND_IS_COOKIE, &xprt->state)) rpc_wake_up_queued_task_set_status(&xprt->pending, - xprt->snd_task, -ENOTCONN); + xprt->snd_task, -ENOTCONN); spin_unlock(&xprt->transport_lock); } EXPORT_SYMBOL_GPL(xprt_force_disconnect); @@ -865,6 +865,7 @@ bool xprt_lock_connect(struct rpc_xprt *xprt, goto out; if (xprt->snd_task != task) goto out; + set_bit(XPRT_SND_IS_COOKIE, &xprt->state); xprt->snd_task = cookie; ret = true; out: @@ -880,6 +881,7 @@ void xprt_unlock_connect(struct rpc_xprt *xprt, void *cookie) if (!test_bit(XPRT_LOCKED, &xprt->state)) goto out; xprt->snd_task =NULL; + clear_bit(XPRT_SND_IS_COOKIE, &xprt->state); xprt->ops->release_xprt(xprt, NULL); xprt_schedule_autodisconnect(xprt); out:
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit f99fa50880f5300fbbb3c0754ddc7f8738d24fe7 ]
The xprtrdma client code currently relies on the task that initiated the connect to hold the XPRT_LOCK for the duration of the connection attempt. If the task is woken early, due to some other event, then that lock could get released early. Avoid races by using the same mechanism that the socket code uses of transferring lock ownership to the RDMA connect worker itself. That frees us to call rpcrdma_xprt_disconnect() directly since we're now guaranteed exclusion w.r.t. other callers.
Fixes: 4cf44be6f1e8 ("xprtrdma: Fix recursion into rpcrdma_xprt_disconnect()") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/sunrpc/xprt.c | 2 ++ net/sunrpc/xprtrdma/transport.c | 11 +++++------ 2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 19fa8616b8cf..8d3983c8b4d6 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -872,6 +872,7 @@ bool xprt_lock_connect(struct rpc_xprt *xprt, spin_unlock(&xprt->transport_lock); return ret; } +EXPORT_SYMBOL_GPL(xprt_lock_connect);
void xprt_unlock_connect(struct rpc_xprt *xprt, void *cookie) { @@ -888,6 +889,7 @@ void xprt_unlock_connect(struct rpc_xprt *xprt, void *cookie) spin_unlock(&xprt->transport_lock); wake_up_bit(&xprt->state, XPRT_LOCKED); } +EXPORT_SYMBOL_GPL(xprt_unlock_connect);
/** * xprt_connect - schedule a transport connect operation diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index 19a49d26b1e4..d2052f06acfa 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c @@ -249,12 +249,9 @@ xprt_rdma_connect_worker(struct work_struct *work) xprt->stat.connect_start; xprt_set_connected(xprt); rc = -EAGAIN; - } else { - /* Force a call to xprt_rdma_close to clean up */ - spin_lock(&xprt->transport_lock); - set_bit(XPRT_CLOSE_WAIT, &xprt->state); - spin_unlock(&xprt->transport_lock); - } + } else + rpcrdma_xprt_disconnect(r_xprt); + xprt_unlock_connect(xprt, r_xprt); xprt_wake_pending_tasks(xprt, rc); }
@@ -487,6 +484,8 @@ xprt_rdma_connect(struct rpc_xprt *xprt, struct rpc_task *task) struct rpcrdma_ep *ep = r_xprt->rx_ep; unsigned long delay;
+ WARN_ON_ONCE(!xprt_lock_connect(xprt, task, r_xprt)); + delay = 0; if (ep && ep->re_connect_status != 0) { delay = xprt_reconnect_delay(xprt);
From: Olga Kornievskaia kolga@netapp.com
[ Upstream commit a8482488a7d6d320f63a9ee1912dbb5ae5b80a61 ]
Provide ability to query transport's source port.
Signed-off-by: Olga Kornievskaia kolga@netapp.com Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/sunrpc/xprtsock.h | 1 + net/sunrpc/xprtsock.c | 7 +++++++ 2 files changed, 8 insertions(+)
diff --git a/include/linux/sunrpc/xprtsock.h b/include/linux/sunrpc/xprtsock.h index 3c1423ee74b4..8c2a712cb242 100644 --- a/include/linux/sunrpc/xprtsock.h +++ b/include/linux/sunrpc/xprtsock.h @@ -10,6 +10,7 @@
int init_socket_xprt(void); void cleanup_socket_xprt(void); +unsigned short get_srcport(struct rpc_xprt *);
#define RPC_MIN_RESVPORT (1U) #define RPC_MAX_RESVPORT (65535U) diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 3228b7a1836a..3bbf47046e8a 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -1648,6 +1648,13 @@ static int xs_get_srcport(struct sock_xprt *transport) return port; }
+unsigned short get_srcport(struct rpc_xprt *xprt) +{ + struct sock_xprt *sock = container_of(xprt, struct sock_xprt, xprt); + return sock->srcport; +} +EXPORT_SYMBOL(get_srcport); + static unsigned short xs_next_srcport(struct sock_xprt *transport, unsigned short port) { if (transport->srcport != 0)
From: Anna Schumaker Anna.Schumaker@Netapp.com
[ Upstream commit 5d46dd04cb68771f77ba66dbf6fd323a4a2ce00d ]
Since bc1c56e9bbe9 transport->srcport may by unset, causing get_srcport() to return 0 when called. Fix this by querying the port from the underlying socket instead of the transport.
Fixes: bc1c56e9bbe9 (SUNRPC: prevent port reuse on transports which don't request it) Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/sunrpc/xprtsock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 3bbf47046e8a..b836b4c322fc 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -1651,7 +1651,7 @@ static int xs_get_srcport(struct sock_xprt *transport) unsigned short get_srcport(struct rpc_xprt *xprt) { struct sock_xprt *sock = container_of(xprt, struct sock_xprt, xprt); - return sock->srcport; + return xs_sock_getport(sock->sock); } EXPORT_SYMBOL(get_srcport);
From: Wei Li liwei391@huawei.com
[ Upstream commit 632c4ae6da1d629eddf9da1e692d7617c568c256 ]
If request_region() fails the return value is not set. Return -EBUSY on error.
Link: https://lore.kernel.org/r/20210715032625.1395495-1-liwei391@huawei.com Fixes: 8674a8aa2c39 ("scsi: fdomain: Add PCMCIA support") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Wei Li liwei391@huawei.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/pcmcia/fdomain_cs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/pcmcia/fdomain_cs.c b/drivers/scsi/pcmcia/fdomain_cs.c index e42acf314d06..33df6a9ba9b5 100644 --- a/drivers/scsi/pcmcia/fdomain_cs.c +++ b/drivers/scsi/pcmcia/fdomain_cs.c @@ -45,8 +45,10 @@ static int fdomain_probe(struct pcmcia_device *link) goto fail_disable;
if (!request_region(link->resource[0]->start, FDOMAIN_REGION_SIZE, - "fdomain_cs")) + "fdomain_cs")) { + ret = -EBUSY; goto fail_disable; + }
sh = fdomain_create(link->resource[0]->start, link->irq, 7, &link->dev); if (!sh) {
From: Zhen Lei thunder.leizhen@huawei.com
[ Upstream commit d789a490d32fdf0465275e3607f8a3bc87d3f3ba ]
Fix to return -ENOTSUPP instead of 0 when PCS_HAS_PINCONF is true, which is the same as that returned in pcs_parse_pinconf().
Fixes: 4e7e8017a80e ("pinctrl: pinctrl-single: enhance to configure multiple pins of different modules") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Zhen Lei thunder.leizhen@huawei.com Link: https://lore.kernel.org/r/20210722033930.4034-2-thunder.leizhen@huawei.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/pinctrl-single.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 2c9c9835f375..b1f6e4e8bcbb 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -1221,6 +1221,7 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
if (PCS_HAS_PINCONF) { dev_err(pcs->dev, "pinconf not supported\n"); + res = -ENOTSUPP; goto free_pingroups; }
From: Laurent Dufour ldufour@linux.ibm.com
[ Upstream commit 9c7248bb8de31f51c693bfa6a6ea53b1c07e0fa8 ]
When a LPAR is migratable, we should consider the maximum possible NUMA node instead of the number of NUMA nodes from the actual system.
The DT property 'ibm,current-associativity-domains' defines the maximum number of nodes the LPAR can see when running on that box. But if the LPAR is being migrated on another box, it may see up to the nodes defined by 'ibm,max-associativity-domains'. So if a LPAR is migratable, that value should be used.
Unfortunately, there is no easy way to know if an LPAR is migratable or not. The hypervisor exports the property 'ibm,migratable-partition' in the case it set to migrate partition, but that would not mean that the current partition is migratable.
Without this patch, when a LPAR is started on a 2 node box and then migrated to a 3 node box, the hypervisor may spread the LPAR's CPUs on the 3rd node. In that case if a CPU from that 3rd node is added to the LPAR, it will be wrongly assigned to the node because the kernel has been set to use up to 2 nodes (the configuration of the departure node). With this patch applies, the CPU is correctly added to the 3rd node.
Fixes: f9f130ff2ec9 ("powerpc/numa: Detect support for coregroup") Signed-off-by: Laurent Dufour ldufour@linux.ibm.com Reviewed-by: Srikar Dronamraju srikar@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20210511073136.17795-1-ldufour@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/mm/numa.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index f2bf98bdcea2..094a1076fd1f 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -893,7 +893,7 @@ static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn) static void __init find_possible_nodes(void) { struct device_node *rtas; - const __be32 *domains; + const __be32 *domains = NULL; int prop_length, max_nodes; u32 i;
@@ -909,9 +909,14 @@ static void __init find_possible_nodes(void) * it doesn't exist, then fallback on ibm,max-associativity-domains. * Current denotes what the platform can support compared to max * which denotes what the Hypervisor can support. + * + * If the LPAR is migratable, new nodes might be activated after a LPM, + * so we should consider the max number in that case. */ - domains = of_get_property(rtas, "ibm,current-associativity-domains", - &prop_length); + if (!of_get_property(of_root, "ibm,migratable-partition", NULL)) + domains = of_get_property(rtas, + "ibm,current-associativity-domains", + &prop_length); if (!domains) { domains = of_get_property(rtas, "ibm,max-associativity-domains", &prop_length); @@ -920,6 +925,8 @@ static void __init find_possible_nodes(void) }
max_nodes = of_read_number(&domains[min_common_depth], 1); + pr_info("Partition configured for %d NUMA nodes.\n", max_nodes); + for (i = 0; i < max_nodes; i++) { if (!node_possible(i)) node_set(i, node_possible_map);
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit d1f6581a6796c4e9fd8a4a24e8b77463d18f0df1 ]
Return -EINVAL on failure instead of success.
Link: https://lore.kernel.org/r/20210810084613.GB23810@kili Fixes: a91aaae0243b ("scsi: smartpqi: allow for larger raid maps") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/smartpqi/smartpqi_init.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 5db16509b6e1..f573517e8f6e 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -1322,6 +1322,7 @@ static int pqi_get_raid_map(struct pqi_ctrl_info *ctrl_info, "requested %u bytes, received %u bytes\n", raid_map_size, get_unaligned_le32(&raid_map->structure_size)); + rc = -EINVAL; goto error; } }
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 4dbe57d46d54a847875fa33e7d05877bb341585e ]
This function had some left over code that returned 1 on error instead negative error codes. Convert everything to use negative error codes. The caller treats all non-zero returns the same so this does not affect run time.
A couple places set "rc" instead of "status" so those error paths ended up returning success by mistake. Get rid of the "rc" variable and use "status" everywhere.
Remove the bogus "status = 0" initialization, as a future proofing measure so the compiler will warn about uninitialized error codes.
Link: https://lore.kernel.org/r/20210810084753.GD23810@kili Fixes: ace7f46ba5fd ("scsi: qedi: Add QLogic FastLinQ offload iSCSI driver framework.") Acked-by: Manish Rangankar mrangankar@marvell.com Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qedi/qedi_main.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c index edf915432704..99e1a323807d 100644 --- a/drivers/scsi/qedi/qedi_main.c +++ b/drivers/scsi/qedi/qedi_main.c @@ -1621,7 +1621,7 @@ static int qedi_alloc_global_queues(struct qedi_ctx *qedi) { u32 *list; int i; - int status = 0, rc; + int status; u32 *pbl; dma_addr_t page; int num_pages; @@ -1632,14 +1632,14 @@ static int qedi_alloc_global_queues(struct qedi_ctx *qedi) */ if (!qedi->num_queues) { QEDI_ERR(&qedi->dbg_ctx, "No MSI-X vectors available!\n"); - return 1; + return -ENOMEM; }
/* Make sure we allocated the PBL that will contain the physical * addresses of our queues */ if (!qedi->p_cpuq) { - status = 1; + status = -EINVAL; goto mem_alloc_failure; }
@@ -1654,13 +1654,13 @@ static int qedi_alloc_global_queues(struct qedi_ctx *qedi) "qedi->global_queues=%p.\n", qedi->global_queues);
/* Allocate DMA coherent buffers for BDQ */ - rc = qedi_alloc_bdq(qedi); - if (rc) + status = qedi_alloc_bdq(qedi); + if (status) goto mem_alloc_failure;
/* Allocate DMA coherent buffers for NVM_ISCSI_CFG */ - rc = qedi_alloc_nvm_iscsi_cfg(qedi); - if (rc) + status = qedi_alloc_nvm_iscsi_cfg(qedi); + if (status) goto mem_alloc_failure;
/* Allocate a CQ and an associated PBL for each MSI-X
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit ccc89737aa6b9f248cf1623014038beb6c2b7f56 ]
This driver has some left over "return 1" on failure style code mixed with "return negative error codes" style code. The caller doesn't care so we should just convert everything to return negative error codes.
Then there was a problem that there were two variables used to store error codes which just resulted in confusion. If qedf_alloc_bdq() returned a negative error code, we accidentally returned success instead of propagating the error code. So get rid of the "rc" variable and use "status" every where.
Also remove the "status = 0" initialization so that these sorts of bugs will be detected by the compiler in the future.
Link: https://lore.kernel.org/r/20210810085023.GA23998@kili Fixes: 61d8658b4a43 ("scsi: qedf: Add QLogic FastLinQ offload FCoE driver framework.") Acked-by: Manish Rangankar mrangankar@marvell.com Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qedf/qedf_main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index b92570a7c309..98981a61b012 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -3000,7 +3000,7 @@ static int qedf_alloc_global_queues(struct qedf_ctx *qedf) { u32 *list; int i; - int status = 0, rc; + int status; u32 *pbl; dma_addr_t page; int num_pages; @@ -3012,7 +3012,7 @@ static int qedf_alloc_global_queues(struct qedf_ctx *qedf) */ if (!qedf->num_queues) { QEDF_ERR(&(qedf->dbg_ctx), "No MSI-X vectors available!\n"); - return 1; + return -ENOMEM; }
/* @@ -3020,7 +3020,7 @@ static int qedf_alloc_global_queues(struct qedf_ctx *qedf) * addresses of our queues */ if (!qedf->p_cpuq) { - status = 1; + status = -EINVAL; QEDF_ERR(&qedf->dbg_ctx, "p_cpuq is NULL.\n"); goto mem_alloc_failure; } @@ -3036,8 +3036,8 @@ static int qedf_alloc_global_queues(struct qedf_ctx *qedf) "qedf->global_queues=%p.\n", qedf->global_queues);
/* Allocate DMA coherent buffers for BDQ */ - rc = qedf_alloc_bdq(qedf); - if (rc) { + status = qedf_alloc_bdq(qedf); + if (status) { QEDF_ERR(&qedf->dbg_ctx, "Unable to allocate bdq.\n"); goto mem_alloc_failure; }
From: Joel Stanley joel@jms.id.au
[ Upstream commit d0e28a6145c3455b69991245e7f6147eb914b34a ]
CONFIG_MTD_PHYSMAP_OF is not longer enabled as it depends on MTD_PHYSMAP which is not enabled.
This is a regression from commit 642b1e8dbed7 ("mtd: maps: Merge physmap_of.c into physmap-core.c"), which added the extra dependency. Add CONFIG_MTD_PHYSMAP=y so this stays in the config, as Christophe said it is useful for build coverage.
Fixes: 642b1e8dbed7 ("mtd: maps: Merge physmap_of.c into physmap-core.c") Signed-off-by: Joel Stanley joel@jms.id.au Acked-by: Christophe Leroy christophe.leroy@csgroup.eu Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20210817045407.2445664-3-joel@jms.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/configs/mpc885_ads_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/configs/mpc885_ads_defconfig b/arch/powerpc/configs/mpc885_ads_defconfig index 949ff9ccda5e..dbf3ff8adc65 100644 --- a/arch/powerpc/configs/mpc885_ads_defconfig +++ b/arch/powerpc/configs/mpc885_ads_defconfig @@ -34,6 +34,7 @@ CONFIG_MTD_CFI_GEOMETRY=y # CONFIG_MTD_CFI_I2 is not set CONFIG_MTD_CFI_I4=y CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_PHYSMAP=y CONFIG_MTD_PHYSMAP_OF=y # CONFIG_BLK_DEV is not set CONFIG_NETDEVICES=y
From: Chao Yu chao@kernel.org
[ Upstream commit b96d9b3b09f0427b289332c6f6bfbf747a19b654 ]
The value of FAULT_* macros and its description in f2fs.rst became inconsistent, fix this to keep compatibility of fault injection interface.
Fixes: 67883ade7a98 ("f2fs: remove FAULT_ALLOC_BIO") Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/filesystems/f2fs.rst | 1 + fs/f2fs/f2fs.h | 1 + 2 files changed, 2 insertions(+)
diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst index b91e5a8444d5..7f52d9079d76 100644 --- a/Documentation/filesystems/f2fs.rst +++ b/Documentation/filesystems/f2fs.rst @@ -185,6 +185,7 @@ fault_type=%d Support configuring fault injection type, should be FAULT_KVMALLOC 0x000000002 FAULT_PAGE_ALLOC 0x000000004 FAULT_PAGE_GET 0x000000008 + FAULT_ALLOC_BIO 0x000000010 (obsolete) FAULT_ALLOC_NID 0x000000020 FAULT_ORPHAN 0x000000040 FAULT_BLOCK 0x000000080 diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 7084b42a4437..395f18e90a8f 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -43,6 +43,7 @@ enum { FAULT_KVMALLOC, FAULT_PAGE_ALLOC, FAULT_PAGE_GET, + FAULT_ALLOC_BIO, /* it's obsolete due to bio_alloc() will never fail */ FAULT_ALLOC_NID, FAULT_ORPHAN, FAULT_BLOCK,
From: Lu Baolu baolu.lu@linux.intel.com
[ Upstream commit 4d99efb229e63928c6b03a756a2e38cd4777fbe8 ]
The VT-d spec Revision 3.3 updated the virtual command registers, virtual command opcode B register, virtual command response register and virtual command capability register (Section 10.4.43, 10.4.44, 10.4.45, 10.4.46). This updates the virtual command interface implementation in the Intel IOMMU driver accordingly.
Fixes: 24f27d32ab6b7 ("iommu/vt-d: Enlightened PASID allocation") Signed-off-by: Lu Baolu baolu.lu@linux.intel.com Cc: Ashok Raj ashok.raj@intel.com Cc: Sanjay Kumar sanjay.k.kumar@intel.com Cc: Kevin Tian kevin.tian@intel.com Link: https://lore.kernel.org/r/20210713042649.3547403-1-baolu.lu@linux.intel.com Link: https://lore.kernel.org/r/20210818134852.1847070-2-baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/intel/pasid.h | 10 +++++----- include/linux/intel-iommu.h | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/iommu/intel/pasid.h b/drivers/iommu/intel/pasid.h index c11bc8b833b8..d5552e2c160d 100644 --- a/drivers/iommu/intel/pasid.h +++ b/drivers/iommu/intel/pasid.h @@ -28,12 +28,12 @@ #define VCMD_CMD_ALLOC 0x1 #define VCMD_CMD_FREE 0x2 #define VCMD_VRSP_IP 0x1 -#define VCMD_VRSP_SC(e) (((e) >> 1) & 0x3) +#define VCMD_VRSP_SC(e) (((e) & 0xff) >> 1) #define VCMD_VRSP_SC_SUCCESS 0 -#define VCMD_VRSP_SC_NO_PASID_AVAIL 2 -#define VCMD_VRSP_SC_INVALID_PASID 2 -#define VCMD_VRSP_RESULT_PASID(e) (((e) >> 8) & 0xfffff) -#define VCMD_CMD_OPERAND(e) ((e) << 8) +#define VCMD_VRSP_SC_NO_PASID_AVAIL 16 +#define VCMD_VRSP_SC_INVALID_PASID 16 +#define VCMD_VRSP_RESULT_PASID(e) (((e) >> 16) & 0xfffff) +#define VCMD_CMD_OPERAND(e) ((e) << 16) /* * Domain ID reserved for pasid entries programmed for first-level * only and pass-through transfer modes. diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 03faf20a6817..cf2dafe3ce60 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -124,9 +124,9 @@ #define DMAR_MTRR_PHYSMASK8_REG 0x208 #define DMAR_MTRR_PHYSBASE9_REG 0x210 #define DMAR_MTRR_PHYSMASK9_REG 0x218 -#define DMAR_VCCAP_REG 0xe00 /* Virtual command capability register */ -#define DMAR_VCMD_REG 0xe10 /* Virtual command register */ -#define DMAR_VCRSP_REG 0xe20 /* Virtual command response register */ +#define DMAR_VCCAP_REG 0xe30 /* Virtual command capability register */ +#define DMAR_VCMD_REG 0xe00 /* Virtual command register */ +#define DMAR_VCRSP_REG 0xe10 /* Virtual command response register */
#define DMAR_IQER_REG_IQEI(reg) FIELD_GET(GENMASK_ULL(3, 0), reg) #define DMAR_IQER_REG_ITESID(reg) FIELD_GET(GENMASK_ULL(47, 32), reg)
From: YueHaibing yuehaibing@huawei.com
[ Upstream commit c4c7d7a43246a42b0355692c3ed53dff7cbb29bb ]
If re-registering an MR in hns_roce_rereg_user_mr(), we should return NULL instead of passing 0 to ERR_PTR for clarity.
Fixes: 4e9fc1dae2a9 ("RDMA/hns: Optimize the MR registration process") Link: https://lore.kernel.org/r/20210804125939.20516-1-yuehaibing@huawei.com Signed-off-by: YueHaibing yuehaibing@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hns/hns_roce_mr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c index b8454dcb0318..39a085f8e605 100644 --- a/drivers/infiniband/hw/hns/hns_roce_mr.c +++ b/drivers/infiniband/hw/hns/hns_roce_mr.c @@ -361,7 +361,9 @@ struct ib_mr *hns_roce_rereg_user_mr(struct ib_mr *ibmr, int flags, u64 start, free_cmd_mbox: hns_roce_free_cmd_mailbox(hr_dev, mailbox);
- return ERR_PTR(ret); + if (ret) + return ERR_PTR(ret); + return NULL; }
int hns_roce_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata)
From: Basavaraj Natikar Basavaraj.Natikar@amd.com
[ Upstream commit 3978f54817559b28535c58a00d3d31bbd5d0b65a ]
Existing amd-sfh driver is programming the MP2 firmware period field in units of jiffies, but the MP2 firmware expects in milliseconds unit.
Changing it to milliseconds.
Fixes: 4b2c53d93a4b ("SFH:Transport Driver to add support of AMD Sensor Fusion Hub (SFH)") Reviewed-by: Shyam Sundar S K Shyam-sundar.S-k@amd.com Signed-off-by: Basavaraj Natikar Basavaraj.Natikar@amd.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/amd-sfh-hid/amd_sfh_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c index 3589d9945da1..9c7b64e5357a 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_client.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_client.c @@ -186,7 +186,7 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata) rc = -ENOMEM; goto cleanup; } - info.period = msecs_to_jiffies(AMD_SFH_IDLE_LOOP); + info.period = AMD_SFH_IDLE_LOOP; info.sensor_idx = cl_idx; info.dma_address = cl_data->sensor_dma_addr[i];
From: Jim Broadus jbroadus@gmail.com
[ Upstream commit 786537063bbfb3a7ebc6fc21b2baf37fb91df401 ]
A quirk was recently added for Elan devices that has same device match as an entry earlier in the list. The i2c_hid_lookup_quirk function will always return the last match in the list, so the new entry shadows the old entry. The quirk in the previous entry, I2C_HID_QUIRK_BOGUS_IRQ, silenced a flood of messages which have reappeared in the 5.13 kernel.
This change moves the two quirk flags into the same entry.
Fixes: ca66a6770bd9 (HID: i2c-hid: Skip ELAN power-on command after reset) Signed-off-by: Jim Broadus jbroadus@gmail.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/i2c-hid/i2c-hid-core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 46474612e73c..517141138b00 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -171,8 +171,6 @@ static const struct i2c_hid_quirks { I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, { I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_3118, I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, - { USB_VENDOR_ID_ELAN, HID_ANY_ID, - I2C_HID_QUIRK_BOGUS_IRQ }, { USB_VENDOR_ID_ALPS_JP, HID_ANY_ID, I2C_HID_QUIRK_RESET_ON_RESUME }, { I2C_VENDOR_ID_SYNAPTICS, I2C_PRODUCT_ID_SYNAPTICS_SYNA2393, @@ -183,7 +181,8 @@ static const struct i2c_hid_quirks { * Sending the wakeup after reset actually break ELAN touchscreen controller */ { USB_VENDOR_ID_ELAN, HID_ANY_ID, - I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET }, + I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET | + I2C_HID_QUIRK_BOGUS_IRQ }, { 0, 0 } };
From: Lukas Bulwahn lukas.bulwahn@gmail.com
[ Upstream commit 462ba66198a4a8ea996028915af10a698086e302 ]
Commit c49c33637802 ("HID: support for initialization of some Thrustmaster wheels") messed up the Makefile and quirks during the refactoring of this commit.
Luckily, ./scripts/checkkconfigsymbols.py warns on non-existing configs:
HID_TMINIT Referencing files: drivers/hid/Makefile, drivers/hid/hid-quirks.c
Following the discussion (see Link), CONFIG_HID_THRUSTMASTER is the intended config for CONFIG_HID_TMINIT and the file hid-tminit.c was actually added as hid-thrustmaster.c.
So, clean up Makefile and adapt quirks to that refactoring.
Fixes: c49c33637802 ("HID: support for initialization of some Thrustmaster wheels") Link: https://lore.kernel.org/linux-input/CAKXUXMx6dByO03f3dX0X5zjvQp0j2AhJBg0vQFD... Signed-off-by: Lukas Bulwahn lukas.bulwahn@gmail.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/Makefile | 1 - drivers/hid/hid-quirks.c | 2 -- 2 files changed, 3 deletions(-)
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 1ea1a7c0b20f..e29efcb1c040 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -115,7 +115,6 @@ obj-$(CONFIG_HID_STEELSERIES) += hid-steelseries.o obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o hid-thrustmaster.o -obj-$(CONFIG_HID_TMINIT) += hid-tminit.o obj-$(CONFIG_HID_TIVO) += hid-tivo.o obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 51b39bda9a9d..2e104682c22b 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -662,8 +662,6 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) }, -#endif -#if IS_ENABLED(CONFIG_HID_TMINIT) { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65d) }, #endif #if IS_ENABLED(CONFIG_HID_TIVO)
From: Lucas Stach l.stach@pengutronix.de
[ Upstream commit 1822b4dedc4d8cab96fd1d87bf8ff98194e29d9b ]
The mux in the clkout path needs the current selected parent to be enabled for the switch to work. Use the correct mux type to have the clk framework take care of this requirement.
Fixes: c1ae5c6f789a ("clk: imx8mm: add clkout1/2 support") Signed-off-by: Lucas Stach l.stach@pengutronix.de Reviewed-by: Abel Vesa abel.vesa@nxp.com Link: https://lore.kernel.org/r/20210628211554.2510238-1-l.stach@pengutronix.de Signed-off-by: Abel Vesa abel.vesa@nxp.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/imx/clk-imx8mm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index f1919fafb124..ce7127ccddab 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -407,10 +407,10 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) hws[IMX8MM_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2); hws[IMX8MM_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
- hws[IMX8MM_CLK_CLKOUT1_SEL] = imx_clk_hw_mux("clkout1_sel", base + 0x128, 4, 4, clkout_sels, ARRAY_SIZE(clkout_sels)); + hws[IMX8MM_CLK_CLKOUT1_SEL] = imx_clk_hw_mux2("clkout1_sel", base + 0x128, 4, 4, clkout_sels, ARRAY_SIZE(clkout_sels)); hws[IMX8MM_CLK_CLKOUT1_DIV] = imx_clk_hw_divider("clkout1_div", "clkout1_sel", base + 0x128, 0, 4); hws[IMX8MM_CLK_CLKOUT1] = imx_clk_hw_gate("clkout1", "clkout1_div", base + 0x128, 8); - hws[IMX8MM_CLK_CLKOUT2_SEL] = imx_clk_hw_mux("clkout2_sel", base + 0x128, 20, 4, clkout_sels, ARRAY_SIZE(clkout_sels)); + hws[IMX8MM_CLK_CLKOUT2_SEL] = imx_clk_hw_mux2("clkout2_sel", base + 0x128, 20, 4, clkout_sels, ARRAY_SIZE(clkout_sels)); hws[IMX8MM_CLK_CLKOUT2_DIV] = imx_clk_hw_divider("clkout2_div", "clkout2_sel", base + 0x128, 16, 4); hws[IMX8MM_CLK_CLKOUT2] = imx_clk_hw_gate("clkout2", "clkout2_div", base + 0x128, 24);
From: Ahmad Fatoum a.fatoum@pengutronix.de
[ Upstream commit d36207b848a6490e14664e2197a1c8ab51d8148e ]
On the i.MX8M*, the TF-A exposes a SiP (Silicon Provider) service for DDR frequency scaling. The imx8m-ddrc-devfreq driver calls the SiP and then does clk_set_parent on the DDR muxes to synchronize the clock tree.
Since 936c383673b9 ("clk: imx: fix composite peripheral flags"), these TF-A managed muxes have SET_PARENT_GATE set, which results in imx8m-ddrc-devfreq's clk_set_parent after SiP failing with -EBUSY:
echo 25000000 > userspace/set_freq imx8m-ddrc-devfreq 3d400000.memory-controller: failed to set dram_apb parent: -16
Fix this by adding a new i.MX composite flag for firmware managed clocks, which clears SET_PARENT_GATE.
This is safe to do, because updating the Linux clock tree to reflect reality will always be glitch-free.
Fixes: 936c383673b9 ("clk: imx: fix composite peripheral flags") Signed-off-by: Ahmad Fatoum a.fatoum@pengutronix.de Reviewed-by: Abel Vesa abel.vesa@nxp.com Link: https://lore.kernel.org/r/20210810151432.9228-1-a.fatoum@pengutronix.de Signed-off-by: Abel Vesa abel.vesa@nxp.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/imx/clk-composite-8m.c | 3 ++- drivers/clk/imx/clk-imx8mm.c | 7 ++++--- drivers/clk/imx/clk-imx8mn.c | 7 ++++--- drivers/clk/imx/clk-imx8mq.c | 7 ++++--- drivers/clk/imx/clk.h | 16 ++++++++++++++-- 5 files changed, 28 insertions(+), 12 deletions(-)
diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c index 2c309e3dc8e3..04e728538cef 100644 --- a/drivers/clk/imx/clk-composite-8m.c +++ b/drivers/clk/imx/clk-composite-8m.c @@ -216,7 +216,8 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, div->width = PCG_PREDIV_WIDTH; divider_ops = &imx8m_clk_composite_divider_ops; mux_ops = &clk_mux_ops; - flags |= CLK_SET_PARENT_GATE; + if (!(composite_flags & IMX_COMPOSITE_FW_MANAGED)) + flags |= CLK_SET_PARENT_GATE; }
div->lock = &imx_ccm_lock; diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index ce7127ccddab..e92621fa8b9c 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -470,10 +470,11 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
/* * DRAM clocks are manipulated from TF-A outside clock framework. - * Mark with GET_RATE_NOCACHE to always read div value from hardware + * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE + * as div value should always be read from hardware */ - hws[IMX8MM_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE); - hws[IMX8MM_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mm_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE); + hws[IMX8MM_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000); + hws[IMX8MM_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mm_dram_apb_sels, base + 0xa080);
/* IP */ hws[IMX8MM_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100); diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index 88f6630cd472..0a76f969b28b 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -453,10 +453,11 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
/* * DRAM clocks are manipulated from TF-A outside clock framework. - * Mark with GET_RATE_NOCACHE to always read div value from hardware + * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE + * as div value should always be read from hardware */ - hws[IMX8MN_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE); - hws[IMX8MN_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mn_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE); + hws[IMX8MN_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000); + hws[IMX8MN_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mn_dram_apb_sels, base + 0xa080);
hws[IMX8MN_CLK_DISP_PIXEL] = imx8m_clk_hw_composite("disp_pixel", imx8mn_disp_pixel_sels, base + 0xa500); hws[IMX8MN_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mn_sai2_sels, base + 0xa600); diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index c491bc9c61ce..83cc2b1c3294 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -449,11 +449,12 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
/* * DRAM clocks are manipulated from TF-A outside clock framework. - * Mark with GET_RATE_NOCACHE to always read div value from hardware + * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE + * as div value should always be read from hardware */ hws[IMX8MQ_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), CLK_IS_CRITICAL); - hws[IMX8MQ_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE); - hws[IMX8MQ_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mq_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE); + hws[IMX8MQ_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000); + hws[IMX8MQ_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mq_dram_apb_sels, base + 0xa080);
/* IP */ hws[IMX8MQ_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mq_vpu_g1_sels, base + 0xa100); diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index 7571603bee23..e144f983fd8c 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -530,8 +530,9 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name, struct clk *div, struct clk *mux, struct clk *pll, struct clk *step);
-#define IMX_COMPOSITE_CORE BIT(0) -#define IMX_COMPOSITE_BUS BIT(1) +#define IMX_COMPOSITE_CORE BIT(0) +#define IMX_COMPOSITE_BUS BIT(1) +#define IMX_COMPOSITE_FW_MANAGED BIT(2)
struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, const char * const *parent_names, @@ -567,6 +568,17 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, ARRAY_SIZE(parent_names), reg, 0, \ flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
+#define __imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, flags) \ + imx8m_clk_hw_composite_flags(name, parent_names, \ + ARRAY_SIZE(parent_names), reg, IMX_COMPOSITE_FW_MANAGED, \ + flags | CLK_GET_RATE_NOCACHE | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) + +#define imx8m_clk_hw_fw_managed_composite(name, parent_names, reg) \ + __imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, 0) + +#define imx8m_clk_hw_fw_managed_composite_critical(name, parent_names, reg) \ + __imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, CLK_IS_CRITICAL) + #define __imx8m_clk_composite(name, parent_names, reg, flags) \ to_clk(__imx8m_clk_hw_composite(name, parent_names, reg, flags))
From: Fabiano Rosas farosas@linux.ibm.com
[ Upstream commit 5d7d6dac8fe99ed59eee2300e4a03370f94d5222 ]
The __kvmhv_copy_tofrom_guest_radix function was introduced along with nested HV guest support. It uses the platform's Radix MMU quadrants to provide a nested hypervisor with fast access to its nested guests memory (H_COPY_TOFROM_GUEST hypercall). It has also since been added as a fast path for the kvmppc_ld/st routines which are used during instruction emulation.
The commit def0bfdbd603 ("powerpc: use probe_user_read() and probe_user_write()") changed the low level copy function from raw_copy_from_user to probe_user_read, which adds a check to access_ok. In powerpc that is:
static inline bool __access_ok(unsigned long addr, unsigned long size) { return addr < TASK_SIZE_MAX && size <= TASK_SIZE_MAX - addr; }
and TASK_SIZE_MAX is 0x0010000000000000UL for 64-bit, which means that setting the two MSBs of the effective address (which correspond to the quadrant) now cause access_ok to reject the access.
This was not caught earlier because the most common code path via kvmppc_ld/st contains a fallback (kvm_read_guest) that is likely to succeed for L1 guests. For nested guests there is no fallback.
Another issue is that probe_user_read (now __copy_from_user_nofault) does not return the number of bytes not copied in case of failure, so the destination memory is not being cleared anymore in kvmhv_copy_from_guest_radix:
ret = kvmhv_copy_tofrom_guest_radix(vcpu, eaddr, to, NULL, n); if (ret > 0) <-- always false! memset(to + (n - ret), 0, ret);
This patch fixes both issues by skipping access_ok and open-coding the low level __copy_to/from_user_inatomic.
Fixes: def0bfdbd603 ("powerpc: use probe_user_read() and probe_user_write()") Signed-off-by: Fabiano Rosas farosas@linux.ibm.com Reviewed-by: Nicholas Piggin npiggin@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20210805212616.2641017-2-farosas@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kvm/book3s_64_mmu_radix.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c index d909c069363e..e7924664a944 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_radix.c +++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c @@ -64,10 +64,12 @@ unsigned long __kvmhv_copy_tofrom_guest_radix(int lpid, int pid, } isync();
+ pagefault_disable(); if (is_load) - ret = copy_from_user_nofault(to, (const void __user *)from, n); + ret = __copy_from_user_inatomic(to, (const void __user *)from, n); else - ret = copy_to_user_nofault((void __user *)to, from, n); + ret = __copy_to_user_inatomic((void __user *)to, from, n); + pagefault_enable();
/* switch the pid first to avoid running host with unallocated pid */ if (quadrant == 1 && pid != old_pid)
From: Alim Akhtar alim.akhtar@samsung.com
[ Upstream commit 313bf281f2091552f509fd05a74172c70ce7572f ]
clk_get_rate() returns unsigned long and currently this driver stores the return value in u32 type, resulting the below warning:
Fixed smatch warnings:
drivers/scsi/ufs/ufs-exynos.c:286 exynos_ufs_get_clk_info() warn: wrong type for 'ufs->mclk_rate' (should be 'ulong')
drivers/scsi/ufs/ufs-exynos.c:287 exynos_ufs_get_clk_info() warn: wrong type for 'pclk_rate' (should be 'ulong')
Link: https://lore.kernel.org/r/20210819171131.55912-1-alim.akhtar@samsung.com Fixes: 55f4b1f73631 ("scsi: ufs: ufs-exynos: Add UFS host support for Exynos SoCs") Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Alim Akhtar alim.akhtar@samsung.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/ufs/ufs-exynos.c | 4 ++-- drivers/scsi/ufs/ufs-exynos.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c index 70647eacf195..3e5690c45e63 100644 --- a/drivers/scsi/ufs/ufs-exynos.c +++ b/drivers/scsi/ufs/ufs-exynos.c @@ -259,7 +259,7 @@ static int exynos_ufs_get_clk_info(struct exynos_ufs *ufs) struct ufs_hba *hba = ufs->hba; struct list_head *head = &hba->clk_list_head; struct ufs_clk_info *clki; - u32 pclk_rate; + unsigned long pclk_rate; u32 f_min, f_max; u8 div = 0; int ret = 0; @@ -298,7 +298,7 @@ static int exynos_ufs_get_clk_info(struct exynos_ufs *ufs) }
if (unlikely(pclk_rate < f_min || pclk_rate > f_max)) { - dev_err(hba->dev, "not available pclk range %d\n", pclk_rate); + dev_err(hba->dev, "not available pclk range %lu\n", pclk_rate); ret = -EINVAL; goto out; } diff --git a/drivers/scsi/ufs/ufs-exynos.h b/drivers/scsi/ufs/ufs-exynos.h index 06ee565f7eb0..a5804e8eb358 100644 --- a/drivers/scsi/ufs/ufs-exynos.h +++ b/drivers/scsi/ufs/ufs-exynos.h @@ -184,7 +184,7 @@ struct exynos_ufs { u32 pclk_div; u32 pclk_avail_min; u32 pclk_avail_max; - u32 mclk_rate; + unsigned long mclk_rate; int avail_ln_rx; int avail_ln_tx; int rx_sel_idx;
From: Nicholas Piggin npiggin@gmail.com
[ Upstream commit 1782663897945a5cf28e564ba5eed730098e9aa4 ]
After the L1 saves its PMU SPRs but before loading the L2's PMU SPRs, switch the pmcregs_in_use field in the L1 lppaca to the value advertised by the L2 in its VPA. On the way out of the L2, set it back after saving the L2 PMU registers (if they were in-use).
This transfers the PMU liveness indication between the L1 and L2 at the points where the registers are not live.
This fixes the nested HV bug for which a workaround was added to the L0 HV by commit 63279eeb7f93a ("KVM: PPC: Book3S HV: Always save guest pmu for guest capable of nesting"), which explains the problem in detail. That workaround is no longer required for guests that include this bug fix.
Fixes: 360cae313702 ("KVM: PPC: Book3S HV: Nested guest entry via hypercall") Signed-off-by: Nicholas Piggin npiggin@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Reviewed-by: Fabiano Rosas farosas@linux.ibm.com Link: https://lore.kernel.org/r/20210811160134.904987-10-npiggin@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/include/asm/pmc.h | 7 +++++++ arch/powerpc/kvm/book3s_hv.c | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+)
diff --git a/arch/powerpc/include/asm/pmc.h b/arch/powerpc/include/asm/pmc.h index c6bbe9778d3c..3c09109e708e 100644 --- a/arch/powerpc/include/asm/pmc.h +++ b/arch/powerpc/include/asm/pmc.h @@ -34,6 +34,13 @@ static inline void ppc_set_pmu_inuse(int inuse) #endif }
+#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE +static inline int ppc_get_pmu_inuse(void) +{ + return get_paca()->pmcregs_in_use; +} +#endif + extern void power4_enable_pmcs(void);
#else /* CONFIG_PPC64 */ diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 395f98158e81..890fbf4baf15 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -59,6 +59,7 @@ #include <asm/kvm_book3s.h> #include <asm/mmu_context.h> #include <asm/lppaca.h> +#include <asm/pmc.h> #include <asm/processor.h> #include <asm/cputhreads.h> #include <asm/page.h> @@ -3687,6 +3688,18 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit, cpu_has_feature(CPU_FTR_P9_TM_HV_ASSIST)) kvmppc_restore_tm_hv(vcpu, vcpu->arch.shregs.msr, true);
+#ifdef CONFIG_PPC_PSERIES + if (kvmhv_on_pseries()) { + barrier(); + if (vcpu->arch.vpa.pinned_addr) { + struct lppaca *lp = vcpu->arch.vpa.pinned_addr; + get_lppaca()->pmcregs_in_use = lp->pmcregs_in_use; + } else { + get_lppaca()->pmcregs_in_use = 1; + } + barrier(); + } +#endif kvmhv_load_guest_pmu(vcpu);
msr_check_and_set(MSR_FP | MSR_VEC | MSR_VSX); @@ -3823,6 +3836,13 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit, save_pmu |= nesting_enabled(vcpu->kvm);
kvmhv_save_guest_pmu(vcpu, save_pmu); +#ifdef CONFIG_PPC_PSERIES + if (kvmhv_on_pseries()) { + barrier(); + get_lppaca()->pmcregs_in_use = ppc_get_pmu_inuse(); + barrier(); + } +#endif
vc->entry_exit_map = 0x101; vc->in_guest = 0;
From: Kajol Jain kjain@linux.ibm.com
[ Upstream commit 3c69a5f22223fa3e312689ec218b5059784d49d7 ]
Incase of random sampling, there can be scenarios where Sample Instruction Address Register(SIAR) may not latch to the sampled instruction and could result in the value of 0. In these scenarios it is preferred to return regs->nip. These corner cases are seen in the previous generation (p9) also.
Patch adds the check for SIAR value along with regs_use_siar and siar_valid checks so that the function will return regs->nip incase SIAR is zero.
Patch drops the code under PPMU_P10_DD1 flag check which handles SIAR 0 case only for Power10 DD1.
Fixes: 2ca13a4cc56c9 ("powerpc/perf: Use regs->nip when SIAR is zero") Signed-off-by: Kajol Jain kjain@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20210818171556.36912-3-kjain@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/perf/core-book3s.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 51622411a7cc..35658b963d5a 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -2251,18 +2251,10 @@ unsigned long perf_misc_flags(struct pt_regs *regs) */ unsigned long perf_instruction_pointer(struct pt_regs *regs) { - bool use_siar = regs_use_siar(regs); unsigned long siar = mfspr(SPRN_SIAR);
- if (ppmu && (ppmu->flags & PPMU_P10_DD1)) { - if (siar) - return siar; - else - return regs->nip; - } else if (use_siar && siar_valid(regs)) - return mfspr(SPRN_SIAR) + perf_ip_adjust(regs); - else if (use_siar) - return 0; // no valid instruction pointer + if (regs_use_siar(regs) && siar_valid(regs) && siar) + return siar + perf_ip_adjust(regs); else return regs->nip; }
From: Junxian Huang huangjunxian4@hisilicon.com
[ Upstream commit 4303e61264c45cb535255c5b76400f5c4ab1305d ]
dip_idx is associated with qp_num whose data type is u32. However, dip_idx is incorrectly defined as u8 data in the hns_roce_dip struct, which leads to data truncation during value assignment.
Fixes: f91696f2f053 ("RDMA/hns: Support congestion control type selection according to the FW") Link: https://lore.kernel.org/r/1629884592-23424-2-git-send-email-liangwenpeng@hua... Signed-off-by: Junxian Huang huangjunxian4@hisilicon.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h index 23cf2f6bc7a5..d4da840dbc2e 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h @@ -1784,7 +1784,7 @@ struct hns_roce_eq_context {
struct hns_roce_dip { u8 dgid[GID_LEN_V2]; - u8 dip_idx; + u32 dip_idx; struct list_head node; /* all dips are on a list */ };
From: Junxian Huang huangjunxian4@hisilicon.com
[ Upstream commit 074f315fc54a9ce45559a44ca36d9fa1ee1ea2cd ]
When the dgid-dip_idx mapping relationship exists, dip should be assigned.
Fixes: f91696f2f053 ("RDMA/hns: Support congestion control type selection according to the FW") Link: https://lore.kernel.org/r/1629884592-23424-3-git-send-email-liangwenpeng@hua... Signed-off-by: Junxian Huang huangjunxian4@hisilicon.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index dcbe5e28a4f7..90945e664f5d 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -4735,8 +4735,10 @@ static int get_dip_ctx_idx(struct ib_qp *ibqp, const struct ib_qp_attr *attr, spin_lock_irqsave(&hr_dev->dip_list_lock, flags);
list_for_each_entry(hr_dip, &hr_dev->dip_list, node) { - if (!memcmp(grh->dgid.raw, hr_dip->dgid, 16)) + if (!memcmp(grh->dgid.raw, hr_dip->dgid, 16)) { + *dip_idx = hr_dip->dip_idx; goto out; + } }
/* If no dgid is found, a new dip and a mapping between dgid and
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 0487d4fc42d7f31a56cfd9e2237f9ebd889e6112 ]
As pointed out be Kees Cook if we return -EIO because the obj->type != ACPI_TYPE_BUFFER, then we must kfree the output buffer before the return.
Fixes: 1a258e670434 ("platform/x86: dell-smbios-wmi: Add new WMI dispatcher driver") Reported-by: Kees Cook keescook@chromium.org Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20210826140822.71198-1-hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/dell/dell-smbios-wmi.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/platform/x86/dell/dell-smbios-wmi.c b/drivers/platform/x86/dell/dell-smbios-wmi.c index 33f823772733..8e761991455a 100644 --- a/drivers/platform/x86/dell/dell-smbios-wmi.c +++ b/drivers/platform/x86/dell/dell-smbios-wmi.c @@ -69,6 +69,7 @@ static int run_smbios_call(struct wmi_device *wdev) if (obj->type == ACPI_TYPE_INTEGER) dev_dbg(&wdev->dev, "SMBIOS call failed: %llu\n", obj->integer.value); + kfree(output.pointer); return -EIO; } memcpy(&priv->buf->std, obj->buffer.pointer, obj->buffer.length);
From: Srikar Dronamraju srikar@linux.vnet.ibm.com
[ Upstream commit 8efd249babea2fec268cff90b9f5ca723dbb7499 ]
Aneesh reported a crash with a fairly recent upstream kernel when booting kernel whose commandline was appended with nr_cpus=2
1:mon> e cpu 0x1: Vector: 300 (Data Access) at [c000000008a67bd0] pc: c00000000002557c: cpu_to_chip_id+0x3c/0x100 lr: c000000000058380: start_secondary+0x460/0xb00 sp: c000000008a67e70 msr: 8000000000001033 dar: 10 dsisr: 80000 current = 0xc00000000891bb00 paca = 0xc0000018ff981f80 irqmask: 0x03 irq_happened: 0x01 pid = 0, comm = swapper/1 Linux version 5.13.0-rc3-15704-ga050a6d2b7e8 (kvaneesh@ltc-boston8) (gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #433 SMP Tue May 25 02:38:49 CDT 2021 1:mon> t [link register ] c000000000058380 start_secondary+0x460/0xb00 [c000000008a67e70] c000000008a67eb0 (unreliable) [c000000008a67eb0] c0000000000589d4 start_secondary+0xab4/0xb00 [c000000008a67f90] c00000000000c654 start_secondary_prolog+0x10/0x14
Current code assumes that num_possible_cpus() is always greater than threads_per_core. However this may not be true when using nr_cpus=2 or similar options. Handle the case where num_possible_cpus() is not an exact multiple of threads_per_core.
Fixes: c1e53367dab1 ("powerpc/smp: Cache CPU to chip lookup") Reported-by: Aneesh Kumar K.V aneesh.kumar@linux.ibm.com Signed-off-by: Srikar Dronamraju srikar@linux.vnet.ibm.com Debugged-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20210826100401.412519-2-srikar@linux.vnet.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index df6b468976d5..7da1e01e2c7f 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -1085,7 +1085,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) }
if (cpu_to_chip_id(boot_cpuid) != -1) { - int idx = num_possible_cpus() / threads_per_core; + int idx = DIV_ROUND_UP(num_possible_cpus(), threads_per_core);
/* * All threads of a core will all belong to the same core,
From: Srikar Dronamraju srikar@linux.vnet.ibm.com
[ Upstream commit b8b928030332a0ca16d42433eb2c3085600d8704 ]
lscpu() uses core_siblings to list the number of sockets in the system. core_siblings is set using topology_core_cpumask.
While optimizing the powerpc bootup path, Commit 4ca234a9cbd7 ("powerpc/smp: Stop updating cpu_core_mask"). it was found that updating cpu_core_mask() ended up taking a lot of time. It was thought that on Powerpc, cpu_core_mask() would always be same as cpu_cpu_mask() i.e number of sockets will always be equal to number of nodes. As an optimization, cpu_core_mask() was made a snapshot of cpu_cpu_mask().
However that was found to be false with PowerPc KVM guests, where each node could have more than one socket. So with Commit c47f892d7aa6 ("powerpc/smp: Reintroduce cpu_core_mask"), cpu_core_mask was updated based on chip_id but in an optimized way using some mask manipulations and chip_id caching.
However on non-PowerNV and non-pseries KVM guests (i.e not implementing cpu_to_chip_id(), continued to use a copy of cpu_cpu_mask().
There are two issues that were noticed on such systems 1. lscpu would report one extra socket. On a IBM,9009-42A (aka zz system) which has only 2 chips/ sockets/ nodes, lscpu would report Architecture: ppc64le Byte Order: Little Endian CPU(s): 160 On-line CPU(s) list: 0-159 Thread(s) per core: 8 Core(s) per socket: 6 Socket(s): 3 <-------------- NUMA node(s): 2 Model: 2.2 (pvr 004e 0202) Model name: POWER9 (architected), altivec supported Hypervisor vendor: pHyp Virtualization type: para L1d cache: 32K L1i cache: 32K L2 cache: 512K L3 cache: 10240K NUMA node0 CPU(s): 0-79 NUMA node1 CPU(s): 80-159
2. Currently cpu_cpu_mask is updated when a core is added/removed. However its not updated when smt mode switching or on CPUs are explicitly offlined. However all other percpu masks are updated to ensure only active/online CPUs are in the masks. This results in build_sched_domain traces since there will be CPUs in cpu_cpu_mask() but those CPUs are not present in SMT / CACHE / MC / NUMA domains. A loop of threads running smt mode switching and core add/remove will soon show this trace. Hence cpu_cpu_mask has to be update at smt mode switch.
This will have impact on cpu_core_mask(). cpu_core_mask() is a snapshot of cpu_cpu_mask. Different CPUs within the same socket will end up having different cpu_core_masks since they are snapshots at different points of time. This means when lscpu will start reporting many more sockets than the actual number of sockets/ nodes / chips.
Different ways to handle this problem: A. Update the snapshot aka cpu_core_mask for all CPUs whenever cpu_cpu_mask is updated. This would a non-optimal solution. B. Instead of a cpumask_var_t, make cpu_core_map a cpumask pointer pointing to cpu_cpu_mask. However percpu cpumask pointer is frowned upon and we need a clean way to handle PowerPc KVM guest which is not a snapshot. C. Update cpu_core_masks all PowerPc systems like in PowerPc KVM guests using mask manipulations. This approach is relatively simple and unifies with the existing code. D. On top of 3, we could also resurrect get_physical_package_id which could return a nid for the said CPU. However this is not needed at this time.
Option C is the preferred approach for now.
While this is somewhat a revert of Commit 4ca234a9cbd7 ("powerpc/smp: Stop updating cpu_core_mask").
1. Plain revert has some conflicts 2. For chip_id == -1, the cpu_core_mask is made identical to cpu_cpu_mask, unlike previously where cpu_core_mask was set to a core if chip_id doesn't exist.
This goes by the principle that if chip_id is not exposed, then sockets / chip / node share the same set of CPUs.
With the fix, lscpu o/p would be Architecture: ppc64le Byte Order: Little Endian CPU(s): 160 On-line CPU(s) list: 0-159 Thread(s) per core: 8 Core(s) per socket: 6 Socket(s): 2 <-------------- NUMA node(s): 2 Model: 2.2 (pvr 004e 0202) Model name: POWER9 (architected), altivec supported Hypervisor vendor: pHyp Virtualization type: para L1d cache: 32K L1i cache: 32K L2 cache: 512K L3 cache: 10240K NUMA node0 CPU(s): 0-79 NUMA node1 CPU(s): 80-159
Fixes: 4ca234a9cbd7 ("powerpc/smp: Stop updating cpu_core_mask") Signed-off-by: Srikar Dronamraju srikar@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20210826100401.412519-3-srikar@linux.vnet.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/smp.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 7da1e01e2c7f..fe505d8ed55b 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -1503,6 +1503,7 @@ static void add_cpu_to_masks(int cpu) * add it to it's own thread sibling mask. */ cpumask_set_cpu(cpu, cpu_sibling_mask(cpu)); + cpumask_set_cpu(cpu, cpu_core_mask(cpu));
for (i = first_thread; i < first_thread + threads_per_core; i++) if (cpu_online(i)) @@ -1520,11 +1521,6 @@ static void add_cpu_to_masks(int cpu) if (chip_id_lookup_table && ret) chip_id = cpu_to_chip_id(cpu);
- if (chip_id == -1) { - cpumask_copy(per_cpu(cpu_core_map, cpu), cpu_cpu_mask(cpu)); - goto out; - } - if (shared_caches) submask_fn = cpu_l2_cache_mask;
@@ -1534,6 +1530,10 @@ static void add_cpu_to_masks(int cpu) /* Skip all CPUs already part of current CPU core mask */ cpumask_andnot(mask, cpu_online_mask, cpu_core_mask(cpu));
+ /* If chip_id is -1; limit the cpu_core_mask to within DIE*/ + if (chip_id == -1) + cpumask_and(mask, mask, cpu_cpu_mask(cpu)); + for_each_cpu(i, mask) { if (chip_id == cpu_to_chip_id(i)) { or_cpumasks_related(cpu, i, submask_fn, cpu_core_mask); @@ -1543,7 +1543,6 @@ static void add_cpu_to_masks(int cpu) } }
-out: free_cpumask_var(mask); }
From: Wenpeng Liang liangwenpeng@huawei.com
[ Upstream commit d2e0ccffcdd7209fc9881c8970d2a7e28dcb43b9 ]
The resp passed to the user space represents the enable flag of qp, incomplete assignment will cause some features of the user space to be disabled.
Fixes: 90ae0b57e4a5 ("RDMA/hns: Combine enable flags of qp") Fixes: aba457ca890c ("RDMA/hns: Support owner mode doorbell") Link: https://lore.kernel.org/r/1629985056-57004-3-git-send-email-liangwenpeng@hua... Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hns/hns_roce_qp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index 80661d368860..5d5dd0b5d507 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -835,7 +835,6 @@ static int alloc_qp_db(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, goto err_out; } hr_qp->en_flags |= HNS_ROCE_QP_CAP_SQ_RECORD_DB; - resp->cap_flags |= HNS_ROCE_QP_CAP_SQ_RECORD_DB; }
if (user_qp_has_rdb(hr_dev, init_attr, udata, resp)) { @@ -848,7 +847,6 @@ static int alloc_qp_db(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, goto err_sdb; } hr_qp->en_flags |= HNS_ROCE_QP_CAP_RQ_RECORD_DB; - resp->cap_flags |= HNS_ROCE_QP_CAP_RQ_RECORD_DB; } } else { if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09) @@ -1060,6 +1058,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev, }
if (udata) { + resp.cap_flags = hr_qp->en_flags; ret = ib_copy_to_udata(udata, &resp, min(udata->outlen, sizeof(resp))); if (ret) {
From: David Howells dhowells@redhat.com
[ Upstream commit 35b72573e977ed6b18b094136a4fa3e0ffb13603 ]
The current hash algorithm used for hashing cookie keys is really bad, producing almost no dispersion (after a test kernel build, ~30000 files were split over just 18 out of the 32768 hash buckets).
Borrow the full_name_hash() hash function into fscache to do the hashing for cookie keys and, in the future, volume keys.
I don't want to use full_name_hash() as-is because I want the hash value to be consistent across arches and over time as the hash value produced may get used on disk.
I can also optimise parts of it away as the key will always be a padded array of aligned 32-bit words.
Fixes: ec0328e46d6e ("fscache: Maintain a catalogue of allocated cookies") Signed-off-by: David Howells dhowells@redhat.com Reviewed-by: Jeff Layton jlayton@redhat.com cc: linux-cachefs@redhat.com Link: https://lore.kernel.org/r/162431201844.2908479.8293647220901514696.stgit@war... Signed-off-by: Sasha Levin sashal@kernel.org --- fs/fscache/cookie.c | 14 +------------- fs/fscache/internal.h | 2 ++ fs/fscache/main.c | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 13 deletions(-)
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index 751bc5b1cddf..6104f627cc71 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c @@ -74,10 +74,8 @@ void fscache_free_cookie(struct fscache_cookie *cookie) static int fscache_set_key(struct fscache_cookie *cookie, const void *index_key, size_t index_key_len) { - unsigned long long h; u32 *buf; int bufs; - int i;
bufs = DIV_ROUND_UP(index_key_len, sizeof(*buf));
@@ -91,17 +89,7 @@ static int fscache_set_key(struct fscache_cookie *cookie, }
memcpy(buf, index_key, index_key_len); - - /* Calculate a hash and combine this with the length in the first word - * or first half word - */ - h = (unsigned long)cookie->parent; - h += index_key_len + cookie->type; - - for (i = 0; i < bufs; i++) - h += buf[i]; - - cookie->key_hash = h ^ (h >> 32); + cookie->key_hash = fscache_hash(0, buf, bufs); return 0; }
diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h index c483863b740a..aee639d980ba 100644 --- a/fs/fscache/internal.h +++ b/fs/fscache/internal.h @@ -97,6 +97,8 @@ extern struct workqueue_struct *fscache_object_wq; extern struct workqueue_struct *fscache_op_wq; DECLARE_PER_CPU(wait_queue_head_t, fscache_object_cong_wait);
+extern unsigned int fscache_hash(unsigned int salt, unsigned int *data, unsigned int n); + static inline bool fscache_object_congested(void) { return workqueue_congested(WORK_CPU_UNBOUND, fscache_object_wq); diff --git a/fs/fscache/main.c b/fs/fscache/main.c index c1e6cc9091aa..4207f98e405f 100644 --- a/fs/fscache/main.c +++ b/fs/fscache/main.c @@ -93,6 +93,45 @@ static struct ctl_table fscache_sysctls_root[] = { }; #endif
+/* + * Mixing scores (in bits) for (7,20): + * Input delta: 1-bit 2-bit + * 1 round: 330.3 9201.6 + * 2 rounds: 1246.4 25475.4 + * 3 rounds: 1907.1 31295.1 + * 4 rounds: 2042.3 31718.6 + * Perfect: 2048 31744 + * (32*64) (32*31/2 * 64) + */ +#define HASH_MIX(x, y, a) \ + ( x ^= (a), \ + y ^= x, x = rol32(x, 7),\ + x += y, y = rol32(y,20),\ + y *= 9 ) + +static inline unsigned int fold_hash(unsigned long x, unsigned long y) +{ + /* Use arch-optimized multiply if one exists */ + return __hash_32(y ^ __hash_32(x)); +} + +/* + * Generate a hash. This is derived from full_name_hash(), but we want to be + * sure it is arch independent and that it doesn't change as bits of the + * computed hash value might appear on disk. The caller also guarantees that + * the hashed data will be a series of aligned 32-bit words. + */ +unsigned int fscache_hash(unsigned int salt, unsigned int *data, unsigned int n) +{ + unsigned int a, x = 0, y = salt; + + for (; n; n--) { + a = *data++; + HASH_MIX(x, y, a); + } + return fold_hash(x, y); +} + /* * initialise the fs caching module */
From: Sergio Paracuellos sergio.paracuellos@gmail.com
[ Upstream commit c16edf5ff8ece9c4135175da4103cee1bec360be ]
'clk_init_data' for gates is setting up 'CLK_IS_CRITICAL' flag for all of them. This was being doing because some drivers of this SoC might not be ready to use the clock and we don't wanted the kernel to disable them since default behaviour without clock driver was to set all gate bits to enabled state. After a bit more testing and checking driver code it is safe to remove this flag and just let the kernel to disable those gates that are not in use. No regressions seems to appear.
Fixes: 48df7a26f470 ("clk: ralink: add clock driver for mt7621 SoC") Signed-off-by: Sergio Paracuellos sergio.paracuellos@gmail.com Link: https://lore.kernel.org/r/20210727055537.11785-1-sergio.paracuellos@gmail.co... Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/ralink/clk-mt7621.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/drivers/clk/ralink/clk-mt7621.c b/drivers/clk/ralink/clk-mt7621.c index 857da1e274be..a2c045390f00 100644 --- a/drivers/clk/ralink/clk-mt7621.c +++ b/drivers/clk/ralink/clk-mt7621.c @@ -131,14 +131,7 @@ static int mt7621_gate_ops_init(struct device *dev, struct mt7621_gate *sclk) { struct clk_init_data init = { - /* - * Until now no clock driver existed so - * these SoC drivers are not prepared - * yet for the clock. We don't want kernel to - * disable anything so we add CLK_IS_CRITICAL - * flag here. - */ - .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .num_parents = 1, .parent_names = &sclk->parent_name, .ops = &mt7621_gate_ops,
From: Codrin Ciubotariu codrin.ciubotariu@microchip.com
[ Upstream commit af7651e67b9d5f7e63ea23b118e3672ac662244a ]
On clk_generated_determine_rate(), the requested rate could be outside of clk's range. Limit the rate to the clock's range to not return an error.
Fixes: df70aeef6083 ("clk: at91: add generated clock driver") Signed-off-by: Codrin Ciubotariu codrin.ciubotariu@microchip.com Link: https://lore.kernel.org/r/20210707131213.3283509-1-codrin.ciubotariu@microch... Acked-by: Nicolas Ferre nicolas.ferre@microchip.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/at91/clk-generated.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c index b4fc8d71daf2..b656d25a9767 100644 --- a/drivers/clk/at91/clk-generated.c +++ b/drivers/clk/at91/clk-generated.c @@ -128,6 +128,12 @@ static int clk_generated_determine_rate(struct clk_hw *hw, int i; u32 div;
+ /* do not look for a rate that is outside of our range */ + if (gck->range.max && req->rate > gck->range.max) + req->rate = gck->range.max; + if (gck->range.min && req->rate < gck->range.min) + req->rate = gck->range.min; + for (i = 0; i < clk_hw_get_num_parents(hw); i++) { if (gck->chg_pid == i) continue;
From: Alexey Kardashevskiy aik@ozlabs.ru
[ Upstream commit 1d78dfde33a02da1d816279c2e3452978b7abd39 ]
Since commit e1a1ef84cd07 ("KVM: PPC: Book3S: Allocate guest TCEs on demand too"), pages for TCE tables for KVM guests are allocated only when needed. This allows skipping any update when clearing TCEs. This works mostly fine as TCE updates are handled when the MMU is enabled. The realmode handlers fail with H_TOO_HARD when pages are not yet allocated, except when clearing a TCE in which case KVM prints a warning and proceeds to dereference a NULL pointer, which crashes the host OS.
This has not been caught so far as the change in commit e1a1ef84cd07 is reasonably new, and POWER9 runs mostly radix which does not use realmode handlers. With hash, the default TCE table is memset() by QEMU when the machine is reset which triggers page faults and the KVM TCE device's kvm_spapr_tce_fault() handles those with MMU on. And the huge DMA windows are not cleared by VMs which instead successfully create a DMA window big enough to map the VM memory 1:1 and then VMs just map everything without clearing.
This started crashing now as commit 381ceda88c4c ("powerpc/pseries/iommu: Make use of DDW for indirect mapping") added a mode when a dymanic DMA window not big enough to map the VM memory 1:1 but it is used anyway, and the VM now is the first (i.e. not QEMU) to clear a just created table. Note that upstream QEMU needs to be modified to trigger the VM to trigger the host OS crash.
This replaces WARN_ON_ONCE_RM() with a check and return, and adds another warning if TCE is not being cleared.
Fixes: e1a1ef84cd07 ("KVM: PPC: Book3S: Allocate guest TCEs on demand too") Signed-off-by: Alexey Kardashevskiy aik@ozlabs.ru Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20210827040706.517652-1-aik@ozlabs.ru Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kvm/book3s_64_vio_hv.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c index 083a4e037718..e5ba96c41f3f 100644 --- a/arch/powerpc/kvm/book3s_64_vio_hv.c +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c @@ -173,10 +173,13 @@ static void kvmppc_rm_tce_put(struct kvmppc_spapr_tce_table *stt, idx -= stt->offset; page = stt->pages[idx / TCES_PER_PAGE]; /* - * page must not be NULL in real mode, - * kvmppc_rm_ioba_validate() must have taken care of this. + * kvmppc_rm_ioba_validate() allows pages not be allocated if TCE is + * being cleared, otherwise it returns H_TOO_HARD and we skip this. */ - WARN_ON_ONCE_RM(!page); + if (!page) { + WARN_ON_ONCE_RM(tce != 0); + return; + } tbl = kvmppc_page_address(page);
tbl[idx % TCES_PER_PAGE] = tce;
From: Yongqiang Niu yongqiang.niu@mediatek.com
[ Upstream commit 8b60ed2b1674b78ebc433a11efa7d48821229037 ]
Add address shift when compose jump instruction to compatible with 35bit format.
Fixes: 0858fde496f8 ("mailbox: cmdq: variablize address shift in platform") Signed-off-by: Yongqiang Niu yongqiang.niu@mediatek.com Reviewed-by: Nicolas Boichat drinkcat@chromium.org Signed-off-by: Jassi Brar jaswinder.singh@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mailbox/mtk-cmdq-mailbox.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c index 5665b6ea8119..75378e35c3d6 100644 --- a/drivers/mailbox/mtk-cmdq-mailbox.c +++ b/drivers/mailbox/mtk-cmdq-mailbox.c @@ -168,7 +168,8 @@ static void cmdq_task_insert_into_thread(struct cmdq_task *task) dma_sync_single_for_cpu(dev, prev_task->pa_base, prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE); prev_task_base[CMDQ_NUM_CMD(prev_task->pkt) - 1] = - (u64)CMDQ_JUMP_BY_PA << 32 | task->pa_base; + (u64)CMDQ_JUMP_BY_PA << 32 | + (task->pa_base >> task->cmdq->shift_pa); dma_sync_single_for_device(dev, prev_task->pa_base, prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE);
From: Chao Yu chao@kernel.org
[ Upstream commit ad126ebddecbf696e0cf214ff56c7b170fa9f0f7 ]
There is a missing place we forgot to account .skipped_gc_rwsem, fix it.
Fixes: 6f8d4455060d ("f2fs: avoid fi->i_gc_rwsem[WRITE] lock in f2fs_gc") Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/gc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 83b0a7872b3c..1c05e156d9d5 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1497,8 +1497,10 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, int err;
if (S_ISREG(inode->i_mode)) { - if (!down_write_trylock(&fi->i_gc_rwsem[READ])) + if (!down_write_trylock(&fi->i_gc_rwsem[READ])) { + sbi->skipped_gc_rwsem++; continue; + } if (!down_write_trylock( &fi->i_gc_rwsem[WRITE])) { sbi->skipped_gc_rwsem++;
From: Chao Yu chao@kernel.org
[ Upstream commit adf9ea89c719c1d23794e363f631e376b3ff8cbc ]
In below path, it will return ENOENT if filesystem is shutdown:
- f2fs_map_blocks - f2fs_get_dnode_of_data - f2fs_get_node_page - __get_node_page - read_node_page - is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN) return -ENOENT - force return value from ENOENT to 0
It should be fine for read case, since it indicates a hole condition, and caller could use .m_next_pgofs to skip the hole and continue the lookup.
However it may cause confusing for write case, since leaving a hole there, and said nothing was wrong doesn't help.
There is at least one case from dax_iomap_actor() will complain that, so fix this in prior to supporting dax in f2fs.
xfstest generic/388 reports below warning:
ubuntu godown: xfstests-induced forced shutdown of /mnt/scratch_f2fs: ------------[ cut here ]------------ WARNING: CPU: 0 PID: 485833 at fs/dax.c:1127 dax_iomap_actor+0x339/0x370 Call Trace: iomap_apply+0x1c4/0x7b0 ? dax_iomap_rw+0x1c0/0x1c0 dax_iomap_rw+0xad/0x1c0 ? dax_iomap_rw+0x1c0/0x1c0 f2fs_file_write_iter+0x5ab/0x970 [f2fs] do_iter_readv_writev+0x273/0x2e0 do_iter_write+0xab/0x1f0 vfs_iter_write+0x21/0x40 iter_file_splice_write+0x287/0x540 do_splice+0x37c/0xa60 __x64_sys_splice+0x15f/0x3a0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae
ubuntu godown: xfstests-induced forced shutdown of /mnt/scratch_f2fs: ------------[ cut here ]------------ RIP: 0010:dax_iomap_pte_fault.isra.0+0x72e/0x14a0 Call Trace: dax_iomap_fault+0x44/0x70 f2fs_dax_huge_fault+0x155/0x400 [f2fs] f2fs_dax_fault+0x18/0x30 [f2fs] __do_fault+0x4e/0x120 do_fault+0x3cf/0x7a0 __handle_mm_fault+0xa8c/0xf20 ? find_held_lock+0x39/0xd0 handle_mm_fault+0x1b6/0x480 do_user_addr_fault+0x320/0xcd0 ? rcu_read_lock_sched_held+0x67/0xc0 exc_page_fault+0x77/0x3f0 ? asm_exc_page_fault+0x8/0x30 asm_exc_page_fault+0x1e/0x30
Fixes: 83a3bfdb5a8a ("f2fs: indicate shutdown f2fs to allow unmount successfully") Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/data.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 3058c7e28b11..3cd509b085f2 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1490,7 +1490,21 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, if (err) { if (flag == F2FS_GET_BLOCK_BMAP) map->m_pblk = 0; + if (err == -ENOENT) { + /* + * There is one exceptional case that read_node_page() + * may return -ENOENT due to filesystem has been + * shutdown or cp_error, so force to convert error + * number to EIO for such case. + */ + if (map->m_may_create && + (is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN) || + f2fs_cp_error(sbi))) { + err = -EIO; + goto unlock_out; + } + err = 0; if (map->m_next_pgofs) *map->m_next_pgofs =
From: Chao Yu chao@kernel.org
[ Upstream commit c8dc3047c48540183744f959412d44b08c5435e1 ]
We need to unmap pages from userspace process before removing pagecache in punch_hole() like we did in f2fs_setattr().
Similar change: commit 5e44f8c374dc ("ext4: hole-punch use truncate_pagecache_range")
Fixes: fbfa2cc58d53 ("f2fs: add file operations") Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/file.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index fb27d49e4da7..3a11e81fdf65 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1086,7 +1086,6 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len) }
if (pg_start < pg_end) { - struct address_space *mapping = inode->i_mapping; loff_t blk_start, blk_end; struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
@@ -1098,8 +1097,7 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len) down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); down_write(&F2FS_I(inode)->i_mmap_sem);
- truncate_inode_pages_range(mapping, blk_start, - blk_end - 1); + truncate_pagecache_range(inode, blk_start, blk_end - 1);
f2fs_lock_op(sbi); ret = f2fs_truncate_hole(inode, pg_start, pg_end);
From: Jaegeuk Kim jaegeuk@kernel.org
[ Upstream commit 827f02842e40ea2e00f401e8f4cb1bccf3b8cd86 ]
In f2fs_write_multi_pages(), f2fs_compress_pages() allocates pages for compression work in cc->cpages[]. Then, f2fs_write_compressed_pages() initiates bio submission. But, if there's any error before submitting the IOs like early f2fs_cp_error(), previously it didn't free cpages by f2fs_compress_free_page(). Let's fix memory leak by putting that just before deallocating cc->cpages.
Fixes: 4c8ff7095bef ("f2fs: support data compression") Reviewed-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/compress.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index ba188722ba43..14e6a78503f1 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -1363,12 +1363,6 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
for (--i; i >= 0; i--) fscrypt_finalize_bounce_page(&cc->cpages[i]); - for (i = 0; i < cc->nr_cpages; i++) { - if (!cc->cpages[i]) - continue; - f2fs_compress_free_page(cc->cpages[i]); - cc->cpages[i] = NULL; - } out_put_cic: kmem_cache_free(cic_entry_slab, cic); out_put_dnode: @@ -1379,6 +1373,12 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc, else f2fs_unlock_op(sbi); out_free: + for (i = 0; i < cc->nr_cpages; i++) { + if (!cc->cpages[i]) + continue; + f2fs_compress_free_page(cc->cpages[i]); + cc->cpages[i] = NULL; + } page_array_free(cc->inode, cc->cpages, cc->nr_cpages); cc->cpages = NULL; return -EAGAIN;
From: Jaegeuk Kim jaegeuk@kernel.org
[ Upstream commit 9605f75cf36e0bcc0f4ada07b5be712d30107607 ]
The prepare_compress_overwrite() gets/locks a page to prepare a read, and calls f2fs_read_multi_pages() which checks EOF first. If there's any page beyond EOF, we unlock the page and set cc->rpages[i] = NULL, which we can't put the page anymore. This makes page leak, so let's fix by putting that page.
Fixes: a949dc5f2c5c ("f2fs: compress: fix race condition of overwrite vs truncate") Reviewed-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/data.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 3cd509b085f2..198e5ad7c98b 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -2151,6 +2151,8 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, continue; } unlock_page(page); + if (for_write) + put_page(page); cc->rpages[i] = NULL; cc->nr_rpages--; }
From: Oleksij Rempel o.rempel@pengutronix.de
[ Upstream commit bea6a94a279bcbe6b2cde348782b28baf12255a5 ]
Starting with following patch MIPS Malta is not able to boot: | commit 79edff12060fe7772af08607eff50c0e2486c5ba | Author: Rob Herring robh@kernel.org | scripts/dtc: Update to upstream version v1.6.0-51-g183df9e9c2b9
The reason is the alignment test added to the fdt_ro_probe_(). To fix this issue, we need to make sure that fdt_buf is aligned.
Since the dtc patch was designed to uncover potential issue, I handle initial MIPS Malta patch as initial bug.
Fixes: e81a8c7dabac ("MIPS: Malta: Setup RAM regions via DT") Signed-off-by: Oleksij Rempel o.rempel@pengutronix.de Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/mti-malta/malta-dtshim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/mips/mti-malta/malta-dtshim.c b/arch/mips/mti-malta/malta-dtshim.c index 0ddf03df6268..f451268f6c38 100644 --- a/arch/mips/mti-malta/malta-dtshim.c +++ b/arch/mips/mti-malta/malta-dtshim.c @@ -22,7 +22,7 @@ #define ROCIT_CONFIG_GEN1_MEMMAP_SHIFT 8 #define ROCIT_CONFIG_GEN1_MEMMAP_MASK (0xf << 8)
-static unsigned char fdt_buf[16 << 10] __initdata; +static unsigned char fdt_buf[16 << 10] __initdata __aligned(8);
/* determined physical memory size, not overridden by command line args */ extern unsigned long physical_memsize;
From: Masahiro Yamada masahiroy@kernel.org
[ Upstream commit 52d83df682c82055961531853c066f4f16e234ea ]
When CONFIG_TRIM_UNUSED_KSYMS is enabled, I see some warnings like this:
nm: arch/x86/entry/vdso/vdso32/note.o: no symbols
$NM (both GNU nm and llvm-nm) warns when no symbol is found in the object. Suppress the stderr.
Fangrui Song mentioned binutils>=2.37 `nm -q` can be used to suppress "no symbols" [1], and llvm-nm>=13.0.0 supports -q as well.
We cannot use it for now, but note it as a TODO.
[1]: https://sourceware.org/bugzilla/show_bug.cgi?id=27408
Fixes: bbda5ec671d3 ("kbuild: simplify dependency generation for CONFIG_TRIM_UNUSED_KSYMS") Signed-off-by: Masahiro Yamada masahiroy@kernel.org Reviewed-by: Nathan Chancellor nathan@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/gen_ksymdeps.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/scripts/gen_ksymdeps.sh b/scripts/gen_ksymdeps.sh index 1324986e1362..725e8c9c1b53 100755 --- a/scripts/gen_ksymdeps.sh +++ b/scripts/gen_ksymdeps.sh @@ -4,7 +4,13 @@ set -e
# List of exported symbols -ksyms=$($NM $1 | sed -n 's/.*__ksym_marker_(.*)/\1/p' | tr A-Z a-z) +# +# If the object has no symbol, $NM warns 'no symbols'. +# Suppress the stderr. +# TODO: +# Use -q instead of 2>/dev/null when we upgrade the minimum version of +# binutils to 2.37, llvm to 13.0.0. +ksyms=$($NM $1 2>/dev/null | sed -n 's/.*__ksym_marker_(.*)/\1/p' | tr A-Z a-z)
if [ -z "$ksyms" ]; then exit 0
From: Nadav Amit namit@vmware.com
[ Upstream commit 22e5fe2a2a279d9a6fcbdfb4dffe73821bef1c90 ]
userfaultfd assumes that the enabled features are set once and never changed after UFFDIO_API ioctl succeeded.
However, currently, UFFDIO_API can be called concurrently from two different threads, succeed on both threads and leave userfaultfd's features in non-deterministic state. Theoretically, other uffd operations (ioctl's and page-faults) can be dispatched while adversely affected by such changes of features.
Moreover, the writes to ctx->state and ctx->features are not ordered, which can - theoretically, again - let userfaultfd_ioctl() think that userfaultfd API completed, while the features are still not initialized.
To avoid races, it is arguably best to get rid of ctx->state. Since there are only 2 states, record the API initialization in ctx->features as the uppermost bit and remove ctx->state.
Link: https://lkml.kernel.org/r/20210808020724.1022515-3-namit@vmware.com Fixes: 9cd75c3cd4c3d ("userfaultfd: non-cooperative: add ability to report non-PF events from uffd descriptor") Signed-off-by: Nadav Amit namit@vmware.com Cc: Alexander Viro viro@zeniv.linux.org.uk Cc: Andrea Arcangeli aarcange@redhat.com Cc: Axel Rasmussen axelrasmussen@google.com Cc: Jens Axboe axboe@kernel.dk Cc: Mike Rapoport rppt@linux.vnet.ibm.com Cc: Peter Xu peterx@redhat.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/userfaultfd.c | 91 +++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 47 deletions(-)
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index 8fc8bbf9635b..e55f861d23fd 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c @@ -33,11 +33,6 @@ int sysctl_unprivileged_userfaultfd __read_mostly;
static struct kmem_cache *userfaultfd_ctx_cachep __read_mostly;
-enum userfaultfd_state { - UFFD_STATE_WAIT_API, - UFFD_STATE_RUNNING, -}; - /* * Start with fault_pending_wqh and fault_wqh so they're more likely * to be in the same cacheline. @@ -69,8 +64,6 @@ struct userfaultfd_ctx { unsigned int flags; /* features requested from the userspace */ unsigned int features; - /* state machine */ - enum userfaultfd_state state; /* released */ bool released; /* memory mappings are changing because of non-cooperative event */ @@ -104,6 +97,14 @@ struct userfaultfd_wake_range { unsigned long len; };
+/* internal indication that UFFD_API ioctl was successfully executed */ +#define UFFD_FEATURE_INITIALIZED (1u << 31) + +static bool userfaultfd_is_initialized(struct userfaultfd_ctx *ctx) +{ + return ctx->features & UFFD_FEATURE_INITIALIZED; +} + static int userfaultfd_wake_function(wait_queue_entry_t *wq, unsigned mode, int wake_flags, void *key) { @@ -666,7 +667,6 @@ int dup_userfaultfd(struct vm_area_struct *vma, struct list_head *fcs)
refcount_set(&ctx->refcount, 1); ctx->flags = octx->flags; - ctx->state = UFFD_STATE_RUNNING; ctx->features = octx->features; ctx->released = false; ctx->mmap_changing = false; @@ -943,38 +943,33 @@ static __poll_t userfaultfd_poll(struct file *file, poll_table *wait)
poll_wait(file, &ctx->fd_wqh, wait);
- switch (ctx->state) { - case UFFD_STATE_WAIT_API: + if (!userfaultfd_is_initialized(ctx)) return EPOLLERR; - case UFFD_STATE_RUNNING: - /* - * poll() never guarantees that read won't block. - * userfaults can be waken before they're read(). - */ - if (unlikely(!(file->f_flags & O_NONBLOCK))) - return EPOLLERR; - /* - * lockless access to see if there are pending faults - * __pollwait last action is the add_wait_queue but - * the spin_unlock would allow the waitqueue_active to - * pass above the actual list_add inside - * add_wait_queue critical section. So use a full - * memory barrier to serialize the list_add write of - * add_wait_queue() with the waitqueue_active read - * below. - */ - ret = 0; - smp_mb(); - if (waitqueue_active(&ctx->fault_pending_wqh)) - ret = EPOLLIN; - else if (waitqueue_active(&ctx->event_wqh)) - ret = EPOLLIN;
- return ret; - default: - WARN_ON_ONCE(1); + /* + * poll() never guarantees that read won't block. + * userfaults can be waken before they're read(). + */ + if (unlikely(!(file->f_flags & O_NONBLOCK))) return EPOLLERR; - } + /* + * lockless access to see if there are pending faults + * __pollwait last action is the add_wait_queue but + * the spin_unlock would allow the waitqueue_active to + * pass above the actual list_add inside + * add_wait_queue critical section. So use a full + * memory barrier to serialize the list_add write of + * add_wait_queue() with the waitqueue_active read + * below. + */ + ret = 0; + smp_mb(); + if (waitqueue_active(&ctx->fault_pending_wqh)) + ret = EPOLLIN; + else if (waitqueue_active(&ctx->event_wqh)) + ret = EPOLLIN; + + return ret; }
static const struct file_operations userfaultfd_fops; @@ -1169,7 +1164,7 @@ static ssize_t userfaultfd_read(struct file *file, char __user *buf, int no_wait = file->f_flags & O_NONBLOCK; struct inode *inode = file_inode(file);
- if (ctx->state == UFFD_STATE_WAIT_API) + if (!userfaultfd_is_initialized(ctx)) return -EINVAL;
for (;;) { @@ -1905,9 +1900,10 @@ static int userfaultfd_continue(struct userfaultfd_ctx *ctx, unsigned long arg) static inline unsigned int uffd_ctx_features(__u64 user_features) { /* - * For the current set of features the bits just coincide + * For the current set of features the bits just coincide. Set + * UFFD_FEATURE_INITIALIZED to mark the features as enabled. */ - return (unsigned int)user_features; + return (unsigned int)user_features | UFFD_FEATURE_INITIALIZED; }
/* @@ -1920,12 +1916,10 @@ static int userfaultfd_api(struct userfaultfd_ctx *ctx, { struct uffdio_api uffdio_api; void __user *buf = (void __user *)arg; + unsigned int ctx_features; int ret; __u64 features;
- ret = -EINVAL; - if (ctx->state != UFFD_STATE_WAIT_API) - goto out; ret = -EFAULT; if (copy_from_user(&uffdio_api, buf, sizeof(uffdio_api))) goto out; @@ -1945,9 +1939,13 @@ static int userfaultfd_api(struct userfaultfd_ctx *ctx, ret = -EFAULT; if (copy_to_user(buf, &uffdio_api, sizeof(uffdio_api))) goto out; - ctx->state = UFFD_STATE_RUNNING; + /* only enable the requested features for this uffd context */ - ctx->features = uffd_ctx_features(features); + ctx_features = uffd_ctx_features(features); + ret = -EINVAL; + if (cmpxchg(&ctx->features, 0, ctx_features) != 0) + goto err_out; + ret = 0; out: return ret; @@ -1964,7 +1962,7 @@ static long userfaultfd_ioctl(struct file *file, unsigned cmd, int ret = -EINVAL; struct userfaultfd_ctx *ctx = file->private_data;
- if (cmd != UFFDIO_API && ctx->state == UFFD_STATE_WAIT_API) + if (cmd != UFFDIO_API && !userfaultfd_is_initialized(ctx)) return -EINVAL;
switch(cmd) { @@ -2078,7 +2076,6 @@ SYSCALL_DEFINE1(userfaultfd, int, flags) refcount_set(&ctx->refcount, 1); ctx->flags = flags; ctx->features = 0; - ctx->state = UFFD_STATE_WAIT_API; ctx->released = false; ctx->mmap_changing = false; ctx->mm = current->mm;
From: Zack Rusin zackr@vmware.com
[ Upstream commit a12be0277316ed923411c9c80b2899ee74d2b033 ]
The has_dx variable was only set during the initialization which meant that UPDATE_SUBRESOURCE was never used. We were emulating it with UPDATE_GB_IMAGE but that's always been a stop-gap. Instead of has_dx which has been deprecated a long time ago we need to check for whether shader model 4.0 or newer is available to the device.
Signed-off-by: Zack Rusin zackr@vmware.com Reviewed-by: Roland Scheidegger sroland@vmware.com Reviewed-by: Martin Krastev krastevm@vmware.com Link: https://patchwork.freedesktop.org/patch/msgid/20210609172307.131929-4-zackr@... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index beab3e19d8e2..5ff88f8c2382 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -1883,7 +1883,6 @@ static void vmw_surface_dirty_range_add(struct vmw_resource *res, size_t start, static int vmw_surface_dirty_sync(struct vmw_resource *res) { struct vmw_private *dev_priv = res->dev_priv; - bool has_dx = 0; u32 i, num_dirty; struct vmw_surface_dirty *dirty = (struct vmw_surface_dirty *) res->dirty; @@ -1910,7 +1909,7 @@ static int vmw_surface_dirty_sync(struct vmw_resource *res) if (!num_dirty) goto out;
- alloc_size = num_dirty * ((has_dx) ? sizeof(*cmd1) : sizeof(*cmd2)); + alloc_size = num_dirty * ((has_sm4_context(dev_priv)) ? sizeof(*cmd1) : sizeof(*cmd2)); cmd = VMW_CMD_RESERVE(dev_priv, alloc_size); if (!cmd) return -ENOMEM; @@ -1928,7 +1927,7 @@ static int vmw_surface_dirty_sync(struct vmw_resource *res) * DX_UPDATE_SUBRESOURCE is aware of array surfaces. * UPDATE_GB_IMAGE is not. */ - if (has_dx) { + if (has_sm4_context(dev_priv)) { cmd1->header.id = SVGA_3D_CMD_DX_UPDATE_SUBRESOURCE; cmd1->header.size = sizeof(cmd1->body); cmd1->body.sid = res->id;
From: Zack Rusin zackr@vmware.com
[ Upstream commit 74231041d14030f1ae6582b9233bfe782ac23e33 ]
Fix some minor issues that Coverity spotted in the code. None of that are serious but they're all valid concerns so fixing them makes sense.
Signed-off-by: Zack Rusin zackr@vmware.com Reviewed-by: Roland Scheidegger sroland@vmware.com Reviewed-by: Martin Krastev krastevm@vmware.com Link: https://patchwork.freedesktop.org/patch/msgid/20210609172307.131929-5-zackr@... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vmwgfx/ttm_memory.c | 2 ++ drivers/gpu/drm/vmwgfx/vmwgfx_binding.c | 20 ++++++++------------ drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c | 4 +++- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 2 ++ drivers/gpu/drm/vmwgfx/vmwgfx_mob.c | 4 +++- drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 6 ++++-- drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 8 ++++++-- drivers/gpu/drm/vmwgfx/vmwgfx_so.c | 3 ++- drivers/gpu/drm/vmwgfx/vmwgfx_validation.c | 4 ++-- 10 files changed, 33 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/vmwgfx/ttm_memory.c b/drivers/gpu/drm/vmwgfx/ttm_memory.c index aeb0a22a2c34..edd17c30d5a5 100644 --- a/drivers/gpu/drm/vmwgfx/ttm_memory.c +++ b/drivers/gpu/drm/vmwgfx/ttm_memory.c @@ -435,8 +435,10 @@ int ttm_mem_global_init(struct ttm_mem_global *glob, struct device *dev)
si_meminfo(&si);
+ spin_lock(&glob->lock); /* set it as 0 by default to keep original behavior of OOM */ glob->lower_mem_limit = 0; + spin_unlock(&glob->lock);
ret = ttm_mem_init_kernel_zone(glob, &si); if (unlikely(ret != 0)) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c index 81f525a82b77..4e7de45407c8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c @@ -715,7 +715,7 @@ static int vmw_binding_scrub_cb(struct vmw_ctx_bindinfo *bi, bool rebind) * without checking which bindings actually need to be emitted * * @cbs: Pointer to the context's struct vmw_ctx_binding_state - * @bi: Pointer to where the binding info array is stored in @cbs + * @biv: Pointer to where the binding info array is stored in @cbs * @max_num: Maximum number of entries in the @bi array. * * Scans the @bi array for bindings and builds a buffer of view id data. @@ -725,11 +725,9 @@ static int vmw_binding_scrub_cb(struct vmw_ctx_bindinfo *bi, bool rebind) * contains the command data. */ static void vmw_collect_view_ids(struct vmw_ctx_binding_state *cbs, - const struct vmw_ctx_bindinfo *bi, + const struct vmw_ctx_bindinfo_view *biv, u32 max_num) { - const struct vmw_ctx_bindinfo_view *biv = - container_of(bi, struct vmw_ctx_bindinfo_view, bi); unsigned long i;
cbs->bind_cmd_count = 0; @@ -838,7 +836,7 @@ static int vmw_emit_set_sr(struct vmw_ctx_binding_state *cbs, */ static int vmw_emit_set_rt(struct vmw_ctx_binding_state *cbs) { - const struct vmw_ctx_bindinfo *loc = &cbs->render_targets[0].bi; + const struct vmw_ctx_bindinfo_view *loc = &cbs->render_targets[0]; struct { SVGA3dCmdHeader header; SVGA3dCmdDXSetRenderTargets body; @@ -874,7 +872,7 @@ static int vmw_emit_set_rt(struct vmw_ctx_binding_state *cbs) * without checking which bindings actually need to be emitted * * @cbs: Pointer to the context's struct vmw_ctx_binding_state - * @bi: Pointer to where the binding info array is stored in @cbs + * @biso: Pointer to where the binding info array is stored in @cbs * @max_num: Maximum number of entries in the @bi array. * * Scans the @bi array for bindings and builds a buffer of SVGA3dSoTarget data. @@ -884,11 +882,9 @@ static int vmw_emit_set_rt(struct vmw_ctx_binding_state *cbs) * contains the command data. */ static void vmw_collect_so_targets(struct vmw_ctx_binding_state *cbs, - const struct vmw_ctx_bindinfo *bi, + const struct vmw_ctx_bindinfo_so_target *biso, u32 max_num) { - const struct vmw_ctx_bindinfo_so_target *biso = - container_of(bi, struct vmw_ctx_bindinfo_so_target, bi); unsigned long i; SVGA3dSoTarget *so_buffer = (SVGA3dSoTarget *) cbs->bind_cmd_buffer;
@@ -919,7 +915,7 @@ static void vmw_collect_so_targets(struct vmw_ctx_binding_state *cbs, */ static int vmw_emit_set_so_target(struct vmw_ctx_binding_state *cbs) { - const struct vmw_ctx_bindinfo *loc = &cbs->so_targets[0].bi; + const struct vmw_ctx_bindinfo_so_target *loc = &cbs->so_targets[0]; struct { SVGA3dCmdHeader header; SVGA3dCmdDXSetSOTargets body; @@ -1066,7 +1062,7 @@ static int vmw_emit_set_vb(struct vmw_ctx_binding_state *cbs)
static int vmw_emit_set_uav(struct vmw_ctx_binding_state *cbs) { - const struct vmw_ctx_bindinfo *loc = &cbs->ua_views[0].views[0].bi; + const struct vmw_ctx_bindinfo_view *loc = &cbs->ua_views[0].views[0]; struct { SVGA3dCmdHeader header; SVGA3dCmdDXSetUAViews body; @@ -1096,7 +1092,7 @@ static int vmw_emit_set_uav(struct vmw_ctx_binding_state *cbs)
static int vmw_emit_set_cs_uav(struct vmw_ctx_binding_state *cbs) { - const struct vmw_ctx_bindinfo *loc = &cbs->ua_views[1].views[0].bi; + const struct vmw_ctx_bindinfo_view *loc = &cbs->ua_views[1].views[0]; struct { SVGA3dCmdHeader header; SVGA3dCmdDXSetCSUAViews body; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c index 2e23e537cdf5..dac4624c5dc1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c @@ -516,7 +516,7 @@ static void vmw_cmdbuf_work_func(struct work_struct *work) struct vmw_cmdbuf_man *man = container_of(work, struct vmw_cmdbuf_man, work); struct vmw_cmdbuf_header *entry, *next; - uint32_t dummy; + uint32_t dummy = 0; bool send_fence = false; struct list_head restart_head[SVGA_CB_CONTEXT_MAX]; int i; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c index b262d61d839d..9487faff5229 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c @@ -159,6 +159,7 @@ void vmw_cmdbuf_res_commit(struct list_head *list) void vmw_cmdbuf_res_revert(struct list_head *list) { struct vmw_cmdbuf_res *entry, *next; + int ret;
list_for_each_entry_safe(entry, next, list, head) { switch (entry->state) { @@ -166,7 +167,8 @@ void vmw_cmdbuf_res_revert(struct list_head *list) vmw_cmdbuf_res_free(entry->man, entry); break; case VMW_CMDBUF_RES_DEL: - drm_ht_insert_item(&entry->man->resources, &entry->hash); + ret = drm_ht_insert_item(&entry->man->resources, &entry->hash); + BUG_ON(ret); list_del(&entry->head); list_add_tail(&entry->head, &entry->man->list); entry->state = VMW_CMDBUF_RES_COMMITTED; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index d6a6d8a3387a..319ecca5d1cb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -2546,6 +2546,8 @@ static int vmw_cmd_dx_so_define(struct vmw_private *dev_priv,
so_type = vmw_so_cmd_to_type(header->id); res = vmw_context_cotable(ctx_node->ctx, vmw_so_cotables[so_type]); + if (IS_ERR(res)) + return PTR_ERR(res); cmd = container_of(header, typeof(*cmd), header); ret = vmw_cotable_notify(res, cmd->defined_id);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c index f2d625415458..2d8caf09f172 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c @@ -506,11 +506,13 @@ static void vmw_mob_pt_setup(struct vmw_mob *mob, { unsigned long num_pt_pages = 0; struct ttm_buffer_object *bo = mob->pt_bo; - struct vmw_piter save_pt_iter; + struct vmw_piter save_pt_iter = {0}; struct vmw_piter pt_iter; const struct vmw_sg_table *vsgt; int ret;
+ BUG_ON(num_data_pages == 0); + ret = ttm_bo_reserve(bo, false, true, NULL); BUG_ON(ret != 0);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c index 609269625468..e90fd3d16697 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c @@ -154,6 +154,7 @@ static unsigned long vmw_port_hb_out(struct rpc_channel *channel, /* HB port can't access encrypted memory. */ if (hb && !mem_encrypt_active()) { unsigned long bp = channel->cookie_high; + u32 channel_id = (channel->channel_id << 16);
si = (uintptr_t) msg; di = channel->cookie_low; @@ -161,7 +162,7 @@ static unsigned long vmw_port_hb_out(struct rpc_channel *channel, VMW_PORT_HB_OUT( (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG, msg_len, si, di, - VMWARE_HYPERVISOR_HB | (channel->channel_id << 16) | + VMWARE_HYPERVISOR_HB | channel_id | VMWARE_HYPERVISOR_OUT, VMW_HYPERVISOR_MAGIC, bp, eax, ebx, ecx, edx, si, di); @@ -209,6 +210,7 @@ static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply, /* HB port can't access encrypted memory */ if (hb && !mem_encrypt_active()) { unsigned long bp = channel->cookie_low; + u32 channel_id = (channel->channel_id << 16);
si = channel->cookie_high; di = (uintptr_t) reply; @@ -216,7 +218,7 @@ static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply, VMW_PORT_HB_IN( (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG, reply_len, si, di, - VMWARE_HYPERVISOR_HB | (channel->channel_id << 16), + VMWARE_HYPERVISOR_HB | channel_id, VMW_HYPERVISOR_MAGIC, bp, eax, ebx, ecx, edx, si, di);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 35f02958ee2c..f275a08999ef 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -114,6 +114,7 @@ static void vmw_resource_release(struct kref *kref) container_of(kref, struct vmw_resource, kref); struct vmw_private *dev_priv = res->dev_priv; int id; + int ret; struct idr *idr = &dev_priv->res_idr[res->func->res_type];
spin_lock(&dev_priv->resource_lock); @@ -122,7 +123,8 @@ static void vmw_resource_release(struct kref *kref) if (res->backup) { struct ttm_buffer_object *bo = &res->backup->base;
- ttm_bo_reserve(bo, false, false, NULL); + ret = ttm_bo_reserve(bo, false, false, NULL); + BUG_ON(ret); if (vmw_resource_mob_attached(res) && res->func->unbind != NULL) { struct ttm_validate_buffer val_buf; @@ -1002,7 +1004,9 @@ int vmw_resource_pin(struct vmw_resource *res, bool interruptible) if (res->backup) { vbo = res->backup;
- ttm_bo_reserve(&vbo->base, interruptible, false, NULL); + ret = ttm_bo_reserve(&vbo->base, interruptible, false, NULL); + if (ret) + goto out_no_validate; if (!vbo->base.pin_count) { ret = ttm_bo_validate (&vbo->base, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_so.c b/drivers/gpu/drm/vmwgfx/vmwgfx_so.c index 2877c7b43bd7..615bf9ca03d7 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_so.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_so.c @@ -539,7 +539,8 @@ const SVGACOTableType vmw_so_cotables[] = { [vmw_so_ds] = SVGA_COTABLE_DEPTHSTENCIL, [vmw_so_rs] = SVGA_COTABLE_RASTERIZERSTATE, [vmw_so_ss] = SVGA_COTABLE_SAMPLER, - [vmw_so_so] = SVGA_COTABLE_STREAMOUTPUT + [vmw_so_so] = SVGA_COTABLE_STREAMOUTPUT, + [vmw_so_max]= SVGA_COTABLE_MAX };
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c index e7570f422400..bf20ca9f3a24 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c @@ -586,13 +586,13 @@ int vmw_validation_bo_validate(struct vmw_validation_context *ctx, bool intr) container_of(entry->base.bo, typeof(*vbo), base);
if (entry->cpu_blit) { - struct ttm_operation_ctx ctx = { + struct ttm_operation_ctx ttm_ctx = { .interruptible = intr, .no_wait_gpu = false };
ret = ttm_bo_validate(entry->base.bo, - &vmw_nonfixed_placement, &ctx); + &vmw_nonfixed_placement, &ttm_ctx); } else { ret = vmw_validation_bo_validate_single (entry->base.bo, intr, entry->as_mob);
From: Dom Cobley popcornmix@gmail.com
[ Upstream commit 1698ecb218eb82587dbfc71a2e26ded66e5ecf59 ]
Symptom is random switching of speakers when using multichannel.
Repeatedly running speakertest -c8 occasionally starts with channels jumbled. This is fixed with HD_CTL_WHOLSMP.
The other bit looks beneficial and apears harmless in testing so I'd suggest adding it too.
Documentation says: HD_CTL_WHILSMP_SET Wait for whole sample. When this bit is set MAI transmit will start only when there is at least one whole sample available in the fifo.
Documentation says: HD_CTL_CHALIGN_SET Channel Align When Overflow. This bit is used to realign the audio channels in case of an overflow. If this bit is set, after the detection of an overflow, equal amount of dummy words to the missing words will be written to fifo, filling up the broken sample and maintaining alignment.
Signed-off-by: Dom Cobley popcornmix@gmail.com Signed-off-by: Maxime Ripard maxime@cerno.tech Reviewed-by: Nicolas Saenz Julienne nsaenz@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20210525132354.297468-7-maxime... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_hdmi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index edee565334d8..155f305e7c4e 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -1205,7 +1205,9 @@ static int vc4_hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd, HDMI_WRITE(HDMI_MAI_CTL, VC4_SET_FIELD(vc4_hdmi->audio.channels, VC4_HD_MAI_CTL_CHNUM) | - VC4_HD_MAI_CTL_ENABLE); + VC4_HD_MAI_CTL_WHOLSMP | + VC4_HD_MAI_CTL_CHALIGN | + VC4_HD_MAI_CTL_ENABLE); break; case SNDRV_PCM_TRIGGER_STOP: HDMI_WRITE(HDMI_MAI_CTL,
From: Daniel Vetter daniel.vetter@ffwll.ch
[ Upstream commit 942d8344d5f14b9ea2ae43756f319b9f44216ba4 ]
I guess no one ever tried running omap together with lima or panfrost, not even sure that's possible. Anyway for consistency, fix this.
Reviewed-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Tomi Valkeinen tomba@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20210622165511.3169559-12-dani... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/omapdrm/omap_plane.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c index 801da917507d..512af976b7e9 100644 --- a/drivers/gpu/drm/omapdrm/omap_plane.c +++ b/drivers/gpu/drm/omapdrm/omap_plane.c @@ -6,6 +6,7 @@
#include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_gem_atomic_helper.h> #include <drm/drm_plane_helper.h>
#include "omap_dmm_tiler.h" @@ -29,6 +30,8 @@ static int omap_plane_prepare_fb(struct drm_plane *plane, if (!new_state->fb) return 0;
+ drm_gem_plane_helper_prepare_fb(plane, new_state); + return omap_framebuffer_pin(new_state->fb); }
From: Luben Tuikov luben.tuikov@amd.com
[ Upstream commit dce4400e6516d18313d23de45b5be8a18980b00e ]
No need to account for the 2 bytes of EEPROM address--this is now well abstracted away by the fixes the the lower layers.
Cc: Andrey Grodzovsky andrey.grodzovsky@amd.com Cc: Alexander Deucher Alexander.Deucher@amd.com Signed-off-by: Luben Tuikov luben.tuikov@amd.com Acked-by: Alexander Deucher Alexander.Deucher@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c index f40c871da0c6..fb701c4fd5c5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c @@ -321,7 +321,7 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control, return ret; }
- __decode_table_header_from_buff(hdr, &buff[2]); + __decode_table_header_from_buff(hdr, buff);
if (hdr->header == EEPROM_TABLE_HDR_VAL) { control->num_recs = (hdr->tbl_size - EEPROM_TABLE_HEADER_SIZE) /
From: Peter Ujfalusi peter.ujfalusi@gmail.com
[ Upstream commit bbdd3f4dbe81e19b9123bc54e23ed54517615524 ]
The DIT mode support has not been tested due to lack of platform where it can be tested. To be able to use the McASP on OMAP4/5 (only supporting DIT mode) we need to have DIT mode working in the McASP driver on a know platform. After hacking around (on BBW, mcasp1.axr1 can be routed out for this) it appeared that DIT mode is broken.
This patch fixes it up and 16/24 bit audio works along with passthrough, but I have only tested with DTS example and test files.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@gmail.com Link: https://lore.kernel.org/r/20210705194249.2385-2-peter.ujfalusi@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/ti/davinci-mcasp.c | 150 ++++++++++++++++++++++++++++++----- 1 file changed, 129 insertions(+), 21 deletions(-)
diff --git a/sound/soc/ti/davinci-mcasp.c b/sound/soc/ti/davinci-mcasp.c index b94220306d1a..41d7cb132198 100644 --- a/sound/soc/ti/davinci-mcasp.c +++ b/sound/soc/ti/davinci-mcasp.c @@ -83,6 +83,8 @@ struct davinci_mcasp { struct snd_pcm_substream *substreams[2]; unsigned int dai_fmt;
+ u32 iec958_status; + /* Audio can not be enabled due to missing parameter(s) */ bool missing_audio_param;
@@ -757,6 +759,9 @@ static int davinci_mcasp_set_tdm_slot(struct snd_soc_dai *dai, { struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
+ if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) + return 0; + dev_dbg(mcasp->dev, "%s() tx_mask 0x%08x rx_mask 0x%08x slots %d width %d\n", __func__, tx_mask, rx_mask, slots, slot_width); @@ -827,6 +832,20 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp, mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXROT(rx_rotate), RXROT(7)); mcasp_set_reg(mcasp, DAVINCI_MCASP_RXMASK_REG, mask); + } else { + /* + * according to the TRM it should be TXROT=0, this one works: + * 16 bit to 23-8 (TXROT=6, rotate 24 bits) + * 24 bit to 23-0 (TXROT=0, rotate 0 bits) + * + * TXROT = 0 only works with 24bit samples + */ + tx_rotate = (sample_width / 4 + 2) & 0x7; + + mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(tx_rotate), + TXROT(7)); + mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXSSZ(15), + TXSSZ(0x0F)); }
mcasp_set_reg(mcasp, DAVINCI_MCASP_TXMASK_REG, mask); @@ -842,10 +861,16 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, u8 tx_ser = 0; u8 rx_ser = 0; u8 slots = mcasp->tdm_slots; - u8 max_active_serializers = (channels + slots - 1) / slots; - u8 max_rx_serializers, max_tx_serializers; + u8 max_active_serializers, max_rx_serializers, max_tx_serializers; int active_serializers, numevt; u32 reg; + + /* In DIT mode we only allow maximum of one serializers for now */ + if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) + max_active_serializers = 1; + else + max_active_serializers = (channels + slots - 1) / slots; + /* Default configuration */ if (mcasp->version < MCASP_VERSION_3) mcasp_set_bits(mcasp, DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); @@ -1031,16 +1056,18 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream, static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp, unsigned int rate) { - u32 cs_value = 0; - u8 *cs_bytes = (u8*) &cs_value; + u8 *cs_bytes = (u8 *)&mcasp->iec958_status;
- /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0 - and LSB first */ - mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(6) | TXSSZ(15)); + if (!mcasp->dat_port) + mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXSEL); + else + mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXSEL);
/* Set TX frame synch : DIT Mode, 1 bit width, internal, rising edge */ mcasp_set_reg(mcasp, DAVINCI_MCASP_TXFMCTL_REG, AFSXE | FSXMOD(0x180));
+ mcasp_set_reg(mcasp, DAVINCI_MCASP_TXMASK_REG, 0xFFFF); + /* Set the TX tdm : for all the slots */ mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, 0xFFFFFFFF);
@@ -1049,16 +1076,8 @@ static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp,
mcasp_clr_bits(mcasp, DAVINCI_MCASP_XEVTCTL_REG, TXDATADMADIS);
- /* Only 44100 and 48000 are valid, both have the same setting */ - mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXDIV(3)); - - /* Enable the DIT */ - mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN); - /* Set S/PDIF channel status bits */ - cs_bytes[0] = IEC958_AES0_CON_NOT_COPYRIGHT; - cs_bytes[1] = IEC958_AES1_CON_PCM_CODER; - + cs_bytes[3] &= ~IEC958_AES3_CON_FS; switch (rate) { case 22050: cs_bytes[3] |= IEC958_AES3_CON_FS_22050; @@ -1088,12 +1107,15 @@ static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp, cs_bytes[3] |= IEC958_AES3_CON_FS_192000; break; default: - printk(KERN_WARNING "unsupported sampling rate: %d\n", rate); + dev_err(mcasp->dev, "unsupported sampling rate: %d\n", rate); return -EINVAL; }
- mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRA_REG, cs_value); - mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRB_REG, cs_value); + mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRA_REG, mcasp->iec958_status); + mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRB_REG, mcasp->iec958_status); + + /* Enable the DIT */ + mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN);
return 0; } @@ -1237,12 +1259,18 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, int slots = mcasp->tdm_slots; int rate = params_rate(params); int sbits = params_width(params); + unsigned int bclk_target;
if (mcasp->slot_width) sbits = mcasp->slot_width;
+ if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE) + bclk_target = rate * sbits * slots; + else + bclk_target = rate * 128; + davinci_mcasp_calc_clk_div(mcasp, mcasp->sysclk_freq, - rate * sbits * slots, true); + bclk_target, true); }
ret = mcasp_common_hw_param(mcasp, substream->stream, @@ -1598,6 +1626,77 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { .set_tdm_slot = davinci_mcasp_set_tdm_slot, };
+static int davinci_mcasp_iec958_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; + uinfo->count = 1; + + return 0; +} + +static int davinci_mcasp_iec958_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *uctl) +{ + struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol); + struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); + + memcpy(uctl->value.iec958.status, &mcasp->iec958_status, + sizeof(mcasp->iec958_status)); + + return 0; +} + +static int davinci_mcasp_iec958_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *uctl) +{ + struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol); + struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); + + memcpy(&mcasp->iec958_status, uctl->value.iec958.status, + sizeof(mcasp->iec958_status)); + + return 0; +} + +static int davinci_mcasp_iec958_con_mask_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol); + struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); + + memset(ucontrol->value.iec958.status, 0xff, sizeof(mcasp->iec958_status)); + return 0; +} + +static const struct snd_kcontrol_new davinci_mcasp_iec958_ctls[] = { + { + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_VOLATILE), + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), + .info = davinci_mcasp_iec958_info, + .get = davinci_mcasp_iec958_get, + .put = davinci_mcasp_iec958_put, + }, { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK), + .info = davinci_mcasp_iec958_info, + .get = davinci_mcasp_iec958_con_mask_get, + }, +}; + +static void davinci_mcasp_init_iec958_status(struct davinci_mcasp *mcasp) +{ + unsigned char *cs = (u8 *)&mcasp->iec958_status; + + cs[0] = IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS_NONE; + cs[1] = IEC958_AES1_CON_PCM_CODER; + cs[2] = IEC958_AES2_CON_SOURCE_UNSPEC | IEC958_AES2_CON_CHANNEL_UNSPEC; + cs[3] = IEC958_AES3_CON_CLOCK_1000PPM; +} + static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai) { struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); @@ -1605,6 +1704,12 @@ static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai) dai->playback_dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; dai->capture_dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE];
+ if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) { + davinci_mcasp_init_iec958_status(mcasp); + snd_soc_add_dai_controls(dai, davinci_mcasp_iec958_ctls, + ARRAY_SIZE(davinci_mcasp_iec958_ctls)); + } + return 0; }
@@ -1651,7 +1756,8 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { .channels_min = 1, .channels_max = 384, .rates = DAVINCI_MCASP_RATES, - .formats = DAVINCI_MCASP_PCM_FMTS, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE, }, .ops = &davinci_mcasp_dai_ops, }, @@ -1871,6 +1977,8 @@ static int davinci_mcasp_get_config(struct davinci_mcasp *mcasp, } else { mcasp->tdm_slots = pdata->tdm_slots; } + } else { + mcasp->tdm_slots = 32; }
mcasp->num_serializer = pdata->num_serializer;
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 6c5c659dfe3f02e08054a6c20019e3886618b512 ]
On a config (such as arch/sh/) which does not set HAS_DMA when MMU is not set, several ATMEL ASoC drivers select symbols that cause kconfig warnings. There is one "depends on HAS_DMA" which is no longer needed. Dropping it eliminates the kconfig warnings and still builds with no problems reported.
Fix the following kconfig warnings:
WARNING: unmet direct dependencies detected for SND_ATMEL_SOC_PDC Depends on [n]: SOUND [=m] && !UML && SND [=m] && SND_SOC [=m] && SND_ATMEL_SOC [=m] && HAS_DMA [=n] Selected by [m]: - SND_ATMEL_SOC_SSC [=m] && SOUND [=m] && !UML && SND [=m] && SND_SOC [=m] && SND_ATMEL_SOC [=m] - SND_ATMEL_SOC_SSC_PDC [=m] && SOUND [=m] && !UML && SND [=m] && SND_SOC [=m] && SND_ATMEL_SOC [=m] && ATMEL_SSC [=m]
WARNING: unmet direct dependencies detected for SND_ATMEL_SOC_SSC_PDC Depends on [n]: SOUND [=m] && !UML && SND [=m] && SND_SOC [=m] && SND_ATMEL_SOC [=m] && ATMEL_SSC [=m] && HAS_DMA [=n] Selected by [m]: - SND_AT91_SOC_SAM9G20_WM8731 [=m] && SOUND [=m] && !UML && SND [=m] && SND_SOC [=m] && SND_ATMEL_SOC [=m] && (ARCH_AT91 || COMPILE_TEST [=y]) && ATMEL_SSC [=m] && SND_SOC_I2C_AND_SPI [=m]
WARNING: unmet direct dependencies detected for SND_ATMEL_SOC_SSC Depends on [n]: SOUND [=m] && !UML && SND [=m] && SND_SOC [=m] && SND_ATMEL_SOC [=m] && HAS_DMA [=n] Selected by [m]: - SND_ATMEL_SOC_SSC_DMA [=m] && SOUND [=m] && !UML && SND [=m] && SND_SOC [=m] && SND_ATMEL_SOC [=m] && ATMEL_SSC [=m]
WARNING: unmet direct dependencies detected for SND_ATMEL_SOC_SSC_DMA Depends on [n]: SOUND [=m] && !UML && SND [=m] && SND_SOC [=m] && SND_ATMEL_SOC [=m] && ATMEL_SSC [=m] && HAS_DMA [=n] Selected by [m]: - SND_ATMEL_SOC_WM8904 [=m] && SOUND [=m] && !UML && SND [=m] && SND_SOC [=m] && SND_ATMEL_SOC [=m] && (ARCH_AT91 || COMPILE_TEST [=y]) && ATMEL_SSC [=m] && I2C [=m] - SND_AT91_SOC_SAM9X5_WM8731 [=m] && SOUND [=m] && !UML && SND [=m] && SND_SOC [=m] && SND_ATMEL_SOC [=m] && (ARCH_AT91 || COMPILE_TEST [=y]) && ATMEL_SSC [=m] && SND_SOC_I2C_AND_SPI [=m]
Signed-off-by: Randy Dunlap rdunlap@infradead.org Reviewed-by: Codrin Ciubotariu codrin.ciubotariu@microchip.com Acked-by: Alexandre Belloni alexandre.belloni@bootlin.com Link: https://lore.kernel.org/r/20210707214752.3831-1-rdunlap@infradead.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/atmel/Kconfig | 1 - 1 file changed, 1 deletion(-)
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig index ec04e3386bc0..8617793ed955 100644 --- a/sound/soc/atmel/Kconfig +++ b/sound/soc/atmel/Kconfig @@ -11,7 +11,6 @@ if SND_ATMEL_SOC
config SND_ATMEL_SOC_PDC bool - depends on HAS_DMA
config SND_ATMEL_SOC_DMA bool
From: Mauro Carvalho Chehab mchehab+huawei@kernel.org
[ Upstream commit 8db11aebdb8f93f46a8513c22c9bd52fa23263aa ]
The logic at dib8000_get_init_prbs() has a few issues:
1. the tables used there has an extra unused value at the beginning; 2. the dprintk() message doesn't write the right value when transmission mode is not 8K; 3. the array overflow validation is done by the callers.
Rewrite the code to fix such issues.
This should also shut up those smatch warnings:
drivers/media/dvb-frontends/dib8000.c:2125 dib8000_get_init_prbs() error: buffer overflow 'lut_prbs_8k' 14 <= 14 drivers/media/dvb-frontends/dib8000.c:2129 dib8000_get_init_prbs() error: buffer overflow 'lut_prbs_2k' 14 <= 14 drivers/media/dvb-frontends/dib8000.c:2131 dib8000_get_init_prbs() error: buffer overflow 'lut_prbs_4k' 14 <= 14 drivers/media/dvb-frontends/dib8000.c:2134 dib8000_get_init_prbs() error: buffer overflow 'lut_prbs_8k' 14 <= 14
Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/dvb-frontends/dib8000.c | 58 +++++++++++++++++++-------- 1 file changed, 41 insertions(+), 17 deletions(-)
diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c index 082796534b0a..bb02354a48b8 100644 --- a/drivers/media/dvb-frontends/dib8000.c +++ b/drivers/media/dvb-frontends/dib8000.c @@ -2107,32 +2107,55 @@ static void dib8000_load_ana_fe_coefs(struct dib8000_state *state, const s16 *an dib8000_write_word(state, 117 + mode, ana_fe[mode]); }
-static const u16 lut_prbs_2k[14] = { - 0, 0x423, 0x009, 0x5C7, 0x7A6, 0x3D8, 0x527, 0x7FF, 0x79B, 0x3D6, 0x3A2, 0x53B, 0x2F4, 0x213 +static const u16 lut_prbs_2k[13] = { + 0x423, 0x009, 0x5C7, + 0x7A6, 0x3D8, 0x527, + 0x7FF, 0x79B, 0x3D6, + 0x3A2, 0x53B, 0x2F4, + 0x213 }; -static const u16 lut_prbs_4k[14] = { - 0, 0x208, 0x0C3, 0x7B9, 0x423, 0x5C7, 0x3D8, 0x7FF, 0x3D6, 0x53B, 0x213, 0x029, 0x0D0, 0x48E + +static const u16 lut_prbs_4k[13] = { + 0x208, 0x0C3, 0x7B9, + 0x423, 0x5C7, 0x3D8, + 0x7FF, 0x3D6, 0x53B, + 0x213, 0x029, 0x0D0, + 0x48E }; -static const u16 lut_prbs_8k[14] = { - 0, 0x740, 0x069, 0x7DD, 0x208, 0x7B9, 0x5C7, 0x7FF, 0x53B, 0x029, 0x48E, 0x4C4, 0x367, 0x684 + +static const u16 lut_prbs_8k[13] = { + 0x740, 0x069, 0x7DD, + 0x208, 0x7B9, 0x5C7, + 0x7FF, 0x53B, 0x029, + 0x48E, 0x4C4, 0x367, + 0x684 };
static u16 dib8000_get_init_prbs(struct dib8000_state *state, u16 subchannel) { int sub_channel_prbs_group = 0; + int prbs_group;
- sub_channel_prbs_group = (subchannel / 3) + 1; - dprintk("sub_channel_prbs_group = %d , subchannel =%d prbs = 0x%04x\n", sub_channel_prbs_group, subchannel, lut_prbs_8k[sub_channel_prbs_group]); + sub_channel_prbs_group = subchannel / 3; + if (sub_channel_prbs_group >= ARRAY_SIZE(lut_prbs_2k)) + return 0;
switch (state->fe[0]->dtv_property_cache.transmission_mode) { case TRANSMISSION_MODE_2K: - return lut_prbs_2k[sub_channel_prbs_group]; + prbs_group = lut_prbs_2k[sub_channel_prbs_group]; + break; case TRANSMISSION_MODE_4K: - return lut_prbs_4k[sub_channel_prbs_group]; + prbs_group = lut_prbs_4k[sub_channel_prbs_group]; + break; default: case TRANSMISSION_MODE_8K: - return lut_prbs_8k[sub_channel_prbs_group]; + prbs_group = lut_prbs_8k[sub_channel_prbs_group]; } + + dprintk("sub_channel_prbs_group = %d , subchannel =%d prbs = 0x%04x\n", + sub_channel_prbs_group, subchannel, prbs_group); + + return prbs_group; }
static void dib8000_set_13seg_channel(struct dib8000_state *state) @@ -2409,10 +2432,8 @@ static void dib8000_set_isdbt_common_channel(struct dib8000_state *state, u8 seq /* TSB or ISDBT ? apply it now */ if (c->isdbt_sb_mode) { dib8000_set_sb_channel(state); - if (c->isdbt_sb_subchannel < 14) - init_prbs = dib8000_get_init_prbs(state, c->isdbt_sb_subchannel); - else - init_prbs = 0; + init_prbs = dib8000_get_init_prbs(state, + c->isdbt_sb_subchannel); } else { dib8000_set_13seg_channel(state); init_prbs = 0xfff; @@ -3004,6 +3025,7 @@ static int dib8000_tune(struct dvb_frontend *fe)
unsigned long *timeout = &state->timeout; unsigned long now = jiffies; + u16 init_prbs; #ifdef DIB8000_AGC_FREEZE u16 agc1, agc2; #endif @@ -3302,8 +3324,10 @@ static int dib8000_tune(struct dvb_frontend *fe) break;
case CT_DEMOD_STEP_11: /* 41 : init prbs autosearch */ - if (state->subchannel <= 41) { - dib8000_set_subchannel_prbs(state, dib8000_get_init_prbs(state, state->subchannel)); + init_prbs = dib8000_get_init_prbs(state, state->subchannel); + + if (init_prbs) { + dib8000_set_subchannel_prbs(state, init_prbs); *tune_state = CT_DEMOD_STEP_9; } else { *tune_state = CT_DEMOD_STOP;
From: Tomi Valkeinen tomi.valkeinen@ideasonboard.com
[ Upstream commit 918d6d120a60c2640263396308eeb2b6afeb0cd6 ]
cal_camerarx_create() doesn't handle error returned from cal_camerarx_sd_init_cfg(). Fix this.
Signed-off-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/ti-vpe/cal-camerarx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/ti-vpe/cal-camerarx.c b/drivers/media/platform/ti-vpe/cal-camerarx.c index cbe6114908de..63d13bcc83b4 100644 --- a/drivers/media/platform/ti-vpe/cal-camerarx.c +++ b/drivers/media/platform/ti-vpe/cal-camerarx.c @@ -842,7 +842,9 @@ struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal, if (ret) goto error;
- cal_camerarx_sd_init_cfg(sd, NULL); + ret = cal_camerarx_sd_init_cfg(sd, NULL); + if (ret) + goto error;
ret = v4l2_device_register_subdev(&cal->v4l2_dev, sd); if (ret)
From: Tomi Valkeinen tomi.valkeinen@ideasonboard.com
[ Upstream commit 892c37f8a3d673b945e951a8754695c119a2b1b0 ]
When starting streaming the driver currently programs the buffer address to the CAL base-address register and assigns the buffer pointer to ctx->dma.pending. This is not correct, as the buffer is not "pending", but active, and causes the first buffer to be needlessly written twice.
Fix this by assigning the buffer pointer to ctx->dma.active.
Signed-off-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/ti-vpe/cal-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/ti-vpe/cal-video.c b/drivers/media/platform/ti-vpe/cal-video.c index 7b7436a355ee..b9405f70af9f 100644 --- a/drivers/media/platform/ti-vpe/cal-video.c +++ b/drivers/media/platform/ti-vpe/cal-video.c @@ -694,7 +694,7 @@ static int cal_start_streaming(struct vb2_queue *vq, unsigned int count)
spin_lock_irq(&ctx->dma.lock); buf = list_first_entry(&ctx->dma.queue, struct cal_buffer, list); - ctx->dma.pending = buf; + ctx->dma.active = buf; list_del(&buf->list); spin_unlock_irq(&ctx->dma.lock);
From: Martynas Pumputis m@lambda.lt
[ Upstream commit 97eb31384af943d6b97eb5947262cee4ef25cb87 ]
When loading a BPF program with a pinned map, the loader checks whether the pinned map can be reused, i.e. their properties match. To derive such of the pinned map, the loader invokes BPF_OBJ_GET_INFO_BY_FD and then does the comparison.
Unfortunately, on < 4.12 kernels the BPF_OBJ_GET_INFO_BY_FD is not available, so loading the program fails with the following error:
libbpf: failed to get map info for map FD 5: Invalid argument libbpf: couldn't reuse pinned map at '/sys/fs/bpf/tc/globals/cilium_call_policy': parameter mismatch" libbpf: map 'cilium_call_policy': error reusing pinned map libbpf: map 'cilium_call_policy': failed to create: Invalid argument(-22) libbpf: failed to load object 'bpf_overlay.o'
To fix this, fallback to derivation of the map properties via /proc/$PID/fdinfo/$MAP_FD if BPF_OBJ_GET_INFO_BY_FD fails with EINVAL, which can be used as an indicator that the kernel doesn't support the latter.
Signed-off-by: Martynas Pumputis m@lambda.lt Signed-off-by: Andrii Nakryiko andrii@kernel.org Acked-by: John Fastabend john.fastabend@gmail.com Link: https://lore.kernel.org/bpf/20210712125552.58705-1-m@lambda.lt Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/libbpf.c | 48 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index f6ebda75b030..c4d36328069c 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -3844,6 +3844,42 @@ static int bpf_map_find_btf_info(struct bpf_object *obj, struct bpf_map *map) return 0; }
+static int bpf_get_map_info_from_fdinfo(int fd, struct bpf_map_info *info) +{ + char file[PATH_MAX], buff[4096]; + FILE *fp; + __u32 val; + int err; + + snprintf(file, sizeof(file), "/proc/%d/fdinfo/%d", getpid(), fd); + memset(info, 0, sizeof(*info)); + + fp = fopen(file, "r"); + if (!fp) { + err = -errno; + pr_warn("failed to open %s: %d. No procfs support?\n", file, + err); + return err; + } + + while (fgets(buff, sizeof(buff), fp)) { + if (sscanf(buff, "map_type:\t%u", &val) == 1) + info->type = val; + else if (sscanf(buff, "key_size:\t%u", &val) == 1) + info->key_size = val; + else if (sscanf(buff, "value_size:\t%u", &val) == 1) + info->value_size = val; + else if (sscanf(buff, "max_entries:\t%u", &val) == 1) + info->max_entries = val; + else if (sscanf(buff, "map_flags:\t%i", &val) == 1) + info->map_flags = val; + } + + fclose(fp); + + return 0; +} + int bpf_map__reuse_fd(struct bpf_map *map, int fd) { struct bpf_map_info info = {}; @@ -3852,6 +3888,8 @@ int bpf_map__reuse_fd(struct bpf_map *map, int fd) char *new_name;
err = bpf_obj_get_info_by_fd(fd, &info, &len); + if (err && errno == EINVAL) + err = bpf_get_map_info_from_fdinfo(fd, &info); if (err) return err;
@@ -4318,12 +4356,16 @@ static bool map_is_reuse_compat(const struct bpf_map *map, int map_fd) struct bpf_map_info map_info = {}; char msg[STRERR_BUFSIZE]; __u32 map_info_len; + int err;
map_info_len = sizeof(map_info);
- if (bpf_obj_get_info_by_fd(map_fd, &map_info, &map_info_len)) { - pr_warn("failed to get map info for map FD %d: %s\n", - map_fd, libbpf_strerror_r(errno, msg, sizeof(msg))); + err = bpf_obj_get_info_by_fd(map_fd, &map_info, &map_info_len); + if (err && errno == EINVAL) + err = bpf_get_map_info_from_fdinfo(map_fd, &map_info); + if (err) { + pr_warn("failed to get map info for map FD %d: %s\n", map_fd, + libbpf_strerror_r(errno, msg, sizeof(msg))); return false; }
From: Thomas Zimmermann tzimmermann@suse.de
[ Upstream commit b43e2ec03b0de040d536591713ea9c875ff34ba9 ]
Replace vkms' prepare_fb and cleanup_fb functions with the generic code for shadow-buffered planes. No functional changes.
This change also fixes a problem where IGT kms_flip tests would create a segmentation fault within vkms. The driver's prepare_fb function did not report an error if a BO's vmap operation failed. The kernel later tried to operate on the non-mapped memory areas. The shared shadow-plane helpers handle errors correctly, so that the driver now avoids the segmantation fault.
v2: * include paragraph about IGT tests in commit message (Melissa)
Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Reviewed-by: Melissa Wen melissa.srw@gmail.com Link: https://patchwork.freedesktop.org/patch/msgid/20210705074633.9425-4-tzimmerm... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vkms/vkms_plane.c | 38 +------------------------------ 1 file changed, 1 insertion(+), 37 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index 6d310d31b75d..1b10ab2b80a3 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -8,7 +8,6 @@ #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_plane_helper.h> -#include <drm/drm_gem_shmem_helper.h>
#include "vkms_drv.h"
@@ -150,45 +149,10 @@ static int vkms_plane_atomic_check(struct drm_plane *plane, return 0; }
-static int vkms_prepare_fb(struct drm_plane *plane, - struct drm_plane_state *state) -{ - struct drm_gem_object *gem_obj; - struct dma_buf_map map; - int ret; - - if (!state->fb) - return 0; - - gem_obj = drm_gem_fb_get_obj(state->fb, 0); - ret = drm_gem_shmem_vmap(gem_obj, &map); - if (ret) - DRM_ERROR("vmap failed: %d\n", ret); - - return drm_gem_plane_helper_prepare_fb(plane, state); -} - -static void vkms_cleanup_fb(struct drm_plane *plane, - struct drm_plane_state *old_state) -{ - struct drm_gem_object *gem_obj; - struct drm_gem_shmem_object *shmem_obj; - struct dma_buf_map map; - - if (!old_state->fb) - return; - - gem_obj = drm_gem_fb_get_obj(old_state->fb, 0); - shmem_obj = to_drm_gem_shmem_obj(drm_gem_fb_get_obj(old_state->fb, 0)); - dma_buf_map_set_vaddr(&map, shmem_obj->vaddr); - drm_gem_shmem_vunmap(gem_obj, &map); -} - static const struct drm_plane_helper_funcs vkms_primary_helper_funcs = { .atomic_update = vkms_plane_atomic_update, .atomic_check = vkms_plane_atomic_check, - .prepare_fb = vkms_prepare_fb, - .cleanup_fb = vkms_cleanup_fb, + DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, };
struct drm_plane *vkms_plane_init(struct vkms_device *vkmsdev,
From: Ani Sinha ani@anisinha.ca
[ Upstream commit c445535c3efbfb8cb42d098e624d46ab149664b7 ]
Marking TSC as unstable has a side effect of marking sched_clock as unstable when TSC is still being used as the sched_clock. This is not desirable. Hyper-V ultimately uses a paravirtualized clock source that provides a stable scheduler clock even on systems without TscInvariant CPU capability. Hence, mark_tsc_unstable() call should be called _after_ scheduler clock has been changed to the paravirtualized clocksource. This will prevent any unwanted manipulation of the sched_clock. Only TSC will be correctly marked as unstable.
Signed-off-by: Ani Sinha ani@anisinha.ca Reviewed-by: Michael Kelley mikelley@microsoft.com Tested-by: Michael Kelley mikelley@microsoft.com Link: https://lore.kernel.org/r/20210713030522.1714803-1-ani@anisinha.ca Signed-off-by: Wei Liu wei.liu@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/cpu/mshyperv.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 4fa0a4280895..ea87d9ed77e9 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -370,8 +370,6 @@ static void __init ms_hyperv_init_platform(void) if (ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) { wrmsrl(HV_X64_MSR_TSC_INVARIANT_CONTROL, 0x1); setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE); - } else { - mark_tsc_unstable("running on Hyper-V"); }
/* @@ -432,6 +430,13 @@ static void __init ms_hyperv_init_platform(void) /* Register Hyper-V specific clocksource */ hv_init_clocksource(); #endif + /* + * TSC should be marked as unstable only after Hyper-V + * clocksource has been initialized. This ensures that the + * stability of the sched_clock is not altered. + */ + if (!(ms_hyperv.features & HV_ACCESS_TSC_INVARIANT)) + mark_tsc_unstable("running on Hyper-V"); }
static bool __init ms_hyperv_x2apic_available(void)
From: Sean Anderson sean.anderson@seco.com
[ Upstream commit 2e6d793e1bf07fe5e20cfbbdcec9e1af7e5097eb ]
This uses the sg_pcopy_from_buffer to copy data, instead of doing it ourselves.
In addition to reducing code size, this fixes the following oops resulting from failing to kmap the page:
[ 68.896381] Unable to handle kernel NULL pointer dereference at virtual address 00000ab8 [ 68.904539] pgd = 3561adb3 [ 68.907475] [00000ab8] *pgd=00000000 [ 68.911153] Internal error: Oops: 805 [#1] ARM [ 68.915618] Modules linked in: cfg80211 rfkill des_generic libdes arc4 libarc4 cbc ecb algif_skcipher sha256_generic libsha256 sha1_generic hmac aes_generic libaes cmac sha512_generic md5 md4 algif_hash af_alg i2c_imx i2c_core ci_hdrc_imx ci_hdrc mxs_dcp ulpi roles udc_core imx_sdma usbmisc_imx usb_common firmware_class virt_dma phy_mxs_usb nf_tables nfnetlink ip_tables x_tables ipv6 autofs4 [ 68.950741] CPU: 0 PID: 139 Comm: mxs_dcp_chan/ae Not tainted 5.10.34 #296 [ 68.958501] Hardware name: Freescale i.MX6 Ultralite (Device Tree) [ 68.964710] PC is at memcpy+0xa8/0x330 [ 68.968479] LR is at 0xd7b2bc9d [ 68.971638] pc : [<c053e7c8>] lr : [<d7b2bc9d>] psr: 000f0013 [ 68.977920] sp : c2cbbee4 ip : 00000010 fp : 00000010 [ 68.983159] r10: 00000000 r9 : c3283a40 r8 : 1a5a6f08 [ 68.988402] r7 : 4bfe0ecc r6 : 76d8a220 r5 : c32f9050 r4 : 00000001 [ 68.994945] r3 : 00000ab8 r2 : fffffff0 r1 : c32f9050 r0 : 00000ab8 [ 69.001492] Flags: nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none [ 69.008646] Control: 10c53c7d Table: 83664059 DAC: 00000051 [ 69.014414] Process mxs_dcp_chan/ae (pid: 139, stack limit = 0x667b57ab) [ 69.021133] Stack: (0xc2cbbee4 to 0xc2cbc000) [ 69.025519] bee0: c32f9050 c3235408 00000010 00000010 00000ab8 00000001 bf10406c [ 69.033720] bf00: 00000000 00000000 00000010 00000000 c32355d0 832fb080 00000000 c13de2fc [ 69.041921] bf20: c3628010 00000010 c33d5780 00000ab8 bf1067e8 00000002 c21e5010 c2cba000 [ 69.050125] bf40: c32f8040 00000000 bf106a40 c32f9040 c3283a80 00000001 bf105240 c3234040 [ 69.058327] bf60: ffffe000 c3204100 c2c69800 c2cba000 00000000 bf103b84 00000000 c2eddc54 [ 69.066530] bf80: c3204144 c0140d1c c2cba000 c2c69800 c0140be8 00000000 00000000 00000000 [ 69.074730] bfa0: 00000000 00000000 00000000 c0100114 00000000 00000000 00000000 00000000 [ 69.082932] bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 69.091131] bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000 [ 69.099364] [<c053e7c8>] (memcpy) from [<bf10406c>] (dcp_chan_thread_aes+0x4e8/0x840 [mxs_dcp]) [ 69.108117] [<bf10406c>] (dcp_chan_thread_aes [mxs_dcp]) from [<c0140d1c>] (kthread+0x134/0x160) [ 69.116941] [<c0140d1c>] (kthread) from [<c0100114>] (ret_from_fork+0x14/0x20) [ 69.124178] Exception stack(0xc2cbbfb0 to 0xc2cbbff8) [ 69.129250] bfa0: 00000000 00000000 00000000 00000000 [ 69.137450] bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 69.145648] bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 [ 69.152289] Code: e320f000 e4803004 e4804004 e4805004 (e4806004)
Signed-off-by: Sean Anderson sean.anderson@seco.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/mxs-dcp.c | 36 +++++++++--------------------------- 1 file changed, 9 insertions(+), 27 deletions(-)
diff --git a/drivers/crypto/mxs-dcp.c b/drivers/crypto/mxs-dcp.c index f397cc5bf102..d19e5ffb5104 100644 --- a/drivers/crypto/mxs-dcp.c +++ b/drivers/crypto/mxs-dcp.c @@ -300,21 +300,20 @@ static int mxs_dcp_aes_block_crypt(struct crypto_async_request *arq)
struct scatterlist *dst = req->dst; struct scatterlist *src = req->src; - const int nents = sg_nents(req->src); + int dst_nents = sg_nents(dst);
const int out_off = DCP_BUF_SZ; uint8_t *in_buf = sdcp->coh->aes_in_buf; uint8_t *out_buf = sdcp->coh->aes_out_buf;
- uint8_t *out_tmp, *src_buf, *dst_buf = NULL; uint32_t dst_off = 0; + uint8_t *src_buf = NULL; uint32_t last_out_len = 0;
uint8_t *key = sdcp->coh->aes_key;
int ret = 0; - int split = 0; - unsigned int i, len, clen, rem = 0, tlen = 0; + unsigned int i, len, clen, tlen = 0; int init = 0; bool limit_hit = false;
@@ -332,7 +331,7 @@ static int mxs_dcp_aes_block_crypt(struct crypto_async_request *arq) memset(key + AES_KEYSIZE_128, 0, AES_KEYSIZE_128); }
- for_each_sg(req->src, src, nents, i) { + for_each_sg(req->src, src, sg_nents(src), i) { src_buf = sg_virt(src); len = sg_dma_len(src); tlen += len; @@ -357,34 +356,17 @@ static int mxs_dcp_aes_block_crypt(struct crypto_async_request *arq) * submit the buffer. */ if (actx->fill == out_off || sg_is_last(src) || - limit_hit) { + limit_hit) { ret = mxs_dcp_run_aes(actx, req, init); if (ret) return ret; init = 0;
- out_tmp = out_buf; + sg_pcopy_from_buffer(dst, dst_nents, out_buf, + actx->fill, dst_off); + dst_off += actx->fill; last_out_len = actx->fill; - while (dst && actx->fill) { - if (!split) { - dst_buf = sg_virt(dst); - dst_off = 0; - } - rem = min(sg_dma_len(dst) - dst_off, - actx->fill); - - memcpy(dst_buf + dst_off, out_tmp, rem); - out_tmp += rem; - dst_off += rem; - actx->fill -= rem; - - if (dst_off == sg_dma_len(dst)) { - dst = sg_next(dst); - split = 0; - } else { - split = 1; - } - } + actx->fill = 0; } } while (len);
From: Rafael J. Wysocki rafael.j.wysocki@intel.com
[ Upstream commit 14858dcc3b3587f4bb5c48e130ee7d68fc2b0a29 ]
Updating the current_state field of struct pci_dev the way it is done in pci_enable_device_flags() before calling do_pci_enable_device() may not work. For example, if the given PCI device depends on an ACPI power resource whose _STA method initially returns 0 ("off"), but the config space of the PCI device is accessible and the power state retrieved from the PCI_PM_CTRL register is D0, the current_state field in the struct pci_dev representing that device will get out of sync with the power.state of its ACPI companion object and that will lead to power management issues going forward.
To avoid such issues, make pci_enable_device_flags() call pci_update_current_state() which takes ACPI device power management into account, if present, to retrieve the current power state of the device.
Link: https://lore.kernel.org/lkml/20210314000439.3138941-1-luzmaximilian@gmail.co... Reported-by: Maximilian Luz luzmaximilian@gmail.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Tested-by: Maximilian Luz luzmaximilian@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/pci.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index a9d0530b7846..8b3cb62c63cc 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1906,11 +1906,7 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) * so that things like MSI message writing will behave as expected * (e.g. if the device really is in D0 at enable time). */ - if (dev->pm_cap) { - u16 pmcsr; - pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); - dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); - } + pci_update_current_state(dev, dev->current_state);
if (atomic_inc_return(&dev->enable_cnt) > 1) return 0; /* already enabled */
From: Xin Long lucien.xin@gmail.com
[ Upstream commit f4919ff59c2828064b4156e3c3600a169909bcf4 ]
Currently, when userspace reads a datagram with a buffer that is smaller than this datagram, the data will be truncated and only part of it can be received by users. It doesn't seem right that users don't know the datagram size and have to use a huge buffer to read it to avoid the truncation.
This patch to fix it by keeping the skb in rcv queue until the whole data is read by users. Only the last msg of the datagram will be marked with MSG_EOR, just as TCP/SCTP does.
Note that this will work as above only when MSG_EOR is set in the flags parameter of recvmsg(), so that it won't break any old user applications.
Signed-off-by: Xin Long lucien.xin@gmail.com Acked-by: Jon Maloy jmaloy@redhat.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/tipc/socket.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-)
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index a0dce194a404..5d036b9c15d2 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -1905,6 +1905,7 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m, bool connected = !tipc_sk_type_connectionless(sk); struct tipc_sock *tsk = tipc_sk(sk); int rc, err, hlen, dlen, copy; + struct tipc_skb_cb *skb_cb; struct sk_buff_head xmitq; struct tipc_msg *hdr; struct sk_buff *skb; @@ -1928,6 +1929,7 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m, if (unlikely(rc)) goto exit; skb = skb_peek(&sk->sk_receive_queue); + skb_cb = TIPC_SKB_CB(skb); hdr = buf_msg(skb); dlen = msg_data_sz(hdr); hlen = msg_hdr_sz(hdr); @@ -1947,18 +1949,33 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m,
/* Capture data if non-error msg, otherwise just set return value */ if (likely(!err)) { - copy = min_t(int, dlen, buflen); - if (unlikely(copy != dlen)) - m->msg_flags |= MSG_TRUNC; - rc = skb_copy_datagram_msg(skb, hlen, m, copy); + int offset = skb_cb->bytes_read; + + copy = min_t(int, dlen - offset, buflen); + rc = skb_copy_datagram_msg(skb, hlen + offset, m, copy); + if (unlikely(rc)) + goto exit; + if (unlikely(offset + copy < dlen)) { + if (flags & MSG_EOR) { + if (!(flags & MSG_PEEK)) + skb_cb->bytes_read = offset + copy; + } else { + m->msg_flags |= MSG_TRUNC; + skb_cb->bytes_read = 0; + } + } else { + if (flags & MSG_EOR) + m->msg_flags |= MSG_EOR; + skb_cb->bytes_read = 0; + } } else { copy = 0; rc = 0; - if (err != TIPC_CONN_SHUTDOWN && connected && !m->msg_control) + if (err != TIPC_CONN_SHUTDOWN && connected && !m->msg_control) { rc = -ECONNRESET; + goto exit; + } } - if (unlikely(rc)) - goto exit;
/* Mark message as group event if applicable */ if (unlikely(grp_evt)) { @@ -1981,9 +1998,10 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m, tipc_node_distr_xmit(sock_net(sk), &xmitq); }
- tsk_advance_rx_queue(sk); + if (!skb_cb->bytes_read) + tsk_advance_rx_queue(sk);
- if (likely(!connected)) + if (likely(!connected) || skb_cb->bytes_read) goto exit;
/* Send connection flow control advertisement when applicable */
From: Marek Vasut marex@denx.de
[ Upstream commit 0d6835ffe50c9c1f098b5704394331710b67af48 ]
The last argument of phy_clear_bits_mmd(..., u16 val); is u16 and not int, just inline the value into the function call arguments.
No functional change.
Signed-off-by: Marek Vasut marex@denx.de Cc: Andrew Lunn andrew@lunn.ch Cc: Florian Fainelli f.fainelli@gmail.com Cc: David S. Miller davem@davemloft.net Reviewed-by: Florian Fainelli f.fainelli@gmail.com Reviewed-by: Andrew Lunn andrew@lunn.ch Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/phy/dp83822.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c index f7a2ec150e54..211b5476a6f5 100644 --- a/drivers/net/phy/dp83822.c +++ b/drivers/net/phy/dp83822.c @@ -326,11 +326,9 @@ static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
static int dp8382x_disable_wol(struct phy_device *phydev) { - int value = DP83822_WOL_EN | DP83822_WOL_MAGIC_EN | - DP83822_WOL_SECURE_ON; - - return phy_clear_bits_mmd(phydev, DP83822_DEVADDR, - MII_DP83822_WOL_CFG, value); + return phy_clear_bits_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG, + DP83822_WOL_EN | DP83822_WOL_MAGIC_EN | + DP83822_WOL_SECURE_ON); }
static int dp83822_read_status(struct phy_device *phydev)
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 97683c851f9cdbd3ea55697cbe2dcb6af4287bbd ]
The naming of the regulator is problematic. VCC is usually a supply voltage whereas these devices have a separate VREF pin.
Secondly, the regulator core might have provided a stub regulator if a real regulator wasn't provided. That would in turn have failed to provide a voltage when queried. So reality was that there was no way to use the internal reference.
In order to avoid breaking any dts out in the wild, make sure to fallback to the original vcc naming if vref is not available.
Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Reported-by: kernel test robot lkp@intel.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20210627163244.1090296-9-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ad5624r_spi.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/drivers/iio/dac/ad5624r_spi.c b/drivers/iio/dac/ad5624r_spi.c index 9bde86982912..530529feebb5 100644 --- a/drivers/iio/dac/ad5624r_spi.c +++ b/drivers/iio/dac/ad5624r_spi.c @@ -229,7 +229,7 @@ static int ad5624r_probe(struct spi_device *spi) if (!indio_dev) return -ENOMEM; st = iio_priv(indio_dev); - st->reg = devm_regulator_get(&spi->dev, "vcc"); + st->reg = devm_regulator_get_optional(&spi->dev, "vref"); if (!IS_ERR(st->reg)) { ret = regulator_enable(st->reg); if (ret) @@ -240,6 +240,22 @@ static int ad5624r_probe(struct spi_device *spi) goto error_disable_reg;
voltage_uv = ret; + } else { + if (PTR_ERR(st->reg) != -ENODEV) + return PTR_ERR(st->reg); + /* Backwards compatibility. This naming is not correct */ + st->reg = devm_regulator_get_optional(&spi->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + return ret; + + ret = regulator_get_voltage(st->reg); + if (ret < 0) + goto error_disable_reg; + + voltage_uv = ret; + } }
spi_set_drvdata(spi, indio_dev);
From: Stefan Assmann sassmann@kpanic.de
[ Upstream commit 22c8fd71d3a5e6fe584ccc2c1e8760e5baefd5aa ]
The iavf watchdog task overrides adapter->state to __IAVF_RESETTING when it detects a pending reset. Then schedules iavf_reset_task() which takes care of the reset.
The reset task is capable of handling the reset without changing adapter->state. In fact we lose the state information when the watchdog task prematurely changes the adapter state. This may lead to a crash if instead of the reset task the iavf_remove() function gets called before the reset task. In that case (if we were in state __IAVF_RUNNING previously) the iavf_remove() function triggers iavf_close() which fails to close the device because of the incorrect state information.
This may result in a crash due to pending interrupts. kernel BUG at drivers/pci/msi.c:357! [...] Call Trace: [<ffffffffbddf24dd>] pci_disable_msix+0x3d/0x50 [<ffffffffc08d2a63>] iavf_reset_interrupt_capability+0x23/0x40 [iavf] [<ffffffffc08d312a>] iavf_remove+0x10a/0x350 [iavf] [<ffffffffbddd3359>] pci_device_remove+0x39/0xc0 [<ffffffffbdeb492f>] __device_release_driver+0x7f/0xf0 [<ffffffffbdeb49c3>] device_release_driver+0x23/0x30 [<ffffffffbddcabb4>] pci_stop_bus_device+0x84/0xa0 [<ffffffffbddcacc2>] pci_stop_and_remove_bus_device+0x12/0x20 [<ffffffffbddf361f>] pci_iov_remove_virtfn+0xaf/0x160 [<ffffffffbddf3bcc>] sriov_disable+0x3c/0xf0 [<ffffffffbddf3ca3>] pci_disable_sriov+0x23/0x30 [<ffffffffc0667365>] i40e_free_vfs+0x265/0x2d0 [i40e] [<ffffffffc0667624>] i40e_pci_sriov_configure+0x144/0x1f0 [i40e] [<ffffffffbddd5307>] sriov_numvfs_store+0x177/0x1d0 Code: 00 00 e8 3c 25 e3 ff 49 c7 86 88 08 00 00 00 00 00 00 5b 41 5c 41 5d 41 5e 41 5f 5d c3 48 8b 7b 28 e8 0d 44 RIP [<ffffffffbbbf1068>] free_msi_irqs+0x188/0x190
The solution is to not touch the adapter->state in iavf_watchdog_task() and let the reset task handle the state transition.
Signed-off-by: Stefan Assmann sassmann@kpanic.de Tested-by: Konrad Jankowski konrad0.jankowski@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/iavf/iavf_main.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index 606a01ce4073..0d0f16617dde 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -1984,7 +1984,6 @@ static void iavf_watchdog_task(struct work_struct *work) /* check for hw reset */ reg_val = rd32(hw, IAVF_VF_ARQLEN1) & IAVF_VF_ARQLEN1_ARQENABLE_MASK; if (!reg_val) { - adapter->state = __IAVF_RESETTING; adapter->flags |= IAVF_FLAG_RESET_PENDING; adapter->aq_required = 0; adapter->current_op = VIRTCHNL_OP_UNKNOWN;
From: Stefan Assmann sassmann@kpanic.de
[ Upstream commit 226d528512cfac890a1619aea4301f3dd314fe60 ]
To avoid races between iavf_init_task(), iavf_reset_task(), iavf_watchdog_task(), iavf_adminq_task() as well as the shutdown and remove functions more locking is required. The current protection by __IAVF_IN_CRITICAL_TASK is needed in additional places.
- The reset task performs state transitions, therefore needs locking. - The adminq task acts on replies from the PF in iavf_virtchnl_completion() which may alter the states. - The init task is not only run during probe but also if a VF gets stuck to reinitialize it. - The shutdown function performs a state transition. - The remove function performs a state transition and also free's resources.
iavf_lock_timeout() is introduced to avoid waiting infinitely and cause a deadlock. Rather unlock and print a warning.
Signed-off-by: Stefan Assmann sassmann@kpanic.de Tested-by: Konrad Jankowski konrad0.jankowski@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/iavf/iavf_main.c | 57 ++++++++++++++++++--- 1 file changed, 50 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index 0d0f16617dde..e5e6a5b11e6d 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -131,6 +131,30 @@ enum iavf_status iavf_free_virt_mem_d(struct iavf_hw *hw, return 0; }
+/** + * iavf_lock_timeout - try to set bit but give up after timeout + * @adapter: board private structure + * @bit: bit to set + * @msecs: timeout in msecs + * + * Returns 0 on success, negative on failure + **/ +static int iavf_lock_timeout(struct iavf_adapter *adapter, + enum iavf_critical_section_t bit, + unsigned int msecs) +{ + unsigned int wait, delay = 10; + + for (wait = 0; wait < msecs; wait += delay) { + if (!test_and_set_bit(bit, &adapter->crit_section)) + return 0; + + msleep(delay); + } + + return -1; +} + /** * iavf_schedule_reset - Set the flags and schedule a reset event * @adapter: board private structure @@ -2097,6 +2121,10 @@ static void iavf_reset_task(struct work_struct *work) if (test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section)) return;
+ if (iavf_lock_timeout(adapter, __IAVF_IN_CRITICAL_TASK, 200)) { + schedule_work(&adapter->reset_task); + return; + } while (test_and_set_bit(__IAVF_IN_CLIENT_TASK, &adapter->crit_section)) usleep_range(500, 1000); @@ -2311,6 +2339,8 @@ static void iavf_adminq_task(struct work_struct *work) if (!event.msg_buf) goto out;
+ if (iavf_lock_timeout(adapter, __IAVF_IN_CRITICAL_TASK, 200)) + goto freedom; do { ret = iavf_clean_arq_element(hw, &event, &pending); v_op = (enum virtchnl_ops)le32_to_cpu(event.desc.cookie_high); @@ -2324,6 +2354,7 @@ static void iavf_adminq_task(struct work_struct *work) if (pending != 0) memset(event.msg_buf, 0, IAVF_MAX_AQ_BUF_SIZE); } while (pending); + clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section);
if ((adapter->flags & (IAVF_FLAG_RESET_PENDING | IAVF_FLAG_RESET_NEEDED)) || @@ -3628,6 +3659,10 @@ static void iavf_init_task(struct work_struct *work) init_task.work); struct iavf_hw *hw = &adapter->hw;
+ if (iavf_lock_timeout(adapter, __IAVF_IN_CRITICAL_TASK, 5000)) { + dev_warn(&adapter->pdev->dev, "failed to set __IAVF_IN_CRITICAL_TASK in %s\n", __FUNCTION__); + return; + } switch (adapter->state) { case __IAVF_STARTUP: if (iavf_startup(adapter) < 0) @@ -3640,14 +3675,14 @@ static void iavf_init_task(struct work_struct *work) case __IAVF_INIT_GET_RESOURCES: if (iavf_init_get_resources(adapter) < 0) goto init_failed; - return; + goto out; default: goto init_failed; }
queue_delayed_work(iavf_wq, &adapter->init_task, msecs_to_jiffies(30)); - return; + goto out; init_failed: if (++adapter->aq_wait_count > IAVF_AQ_MAX_ERR) { dev_err(&adapter->pdev->dev, @@ -3656,9 +3691,11 @@ static void iavf_init_task(struct work_struct *work) iavf_shutdown_adminq(hw); adapter->state = __IAVF_STARTUP; queue_delayed_work(iavf_wq, &adapter->init_task, HZ * 5); - return; + goto out; } queue_delayed_work(iavf_wq, &adapter->init_task, HZ); +out: + clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); }
/** @@ -3675,9 +3712,12 @@ static void iavf_shutdown(struct pci_dev *pdev) if (netif_running(netdev)) iavf_close(netdev);
+ if (iavf_lock_timeout(adapter, __IAVF_IN_CRITICAL_TASK, 5000)) + dev_warn(&adapter->pdev->dev, "failed to set __IAVF_IN_CRITICAL_TASK in %s\n", __FUNCTION__); /* Prevent the watchdog from running. */ adapter->state = __IAVF_REMOVE; adapter->aq_required = 0; + clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section);
#ifdef CONFIG_PM pci_save_state(pdev); @@ -3911,10 +3951,6 @@ static void iavf_remove(struct pci_dev *pdev) err); }
- /* Shut down all the garbage mashers on the detention level */ - adapter->state = __IAVF_REMOVE; - adapter->aq_required = 0; - adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED; iavf_request_reset(adapter); msleep(50); /* If the FW isn't responding, kick it once, but only once. */ @@ -3922,6 +3958,13 @@ static void iavf_remove(struct pci_dev *pdev) iavf_request_reset(adapter); msleep(50); } + if (iavf_lock_timeout(adapter, __IAVF_IN_CRITICAL_TASK, 5000)) + dev_warn(&adapter->pdev->dev, "failed to set __IAVF_IN_CRITICAL_TASK in %s\n", __FUNCTION__); + + /* Shut down all the garbage mashers on the detention level */ + adapter->state = __IAVF_REMOVE; + adapter->aq_required = 0; + adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED; iavf_free_all_tx_resources(adapter); iavf_free_all_rx_resources(adapter); iavf_misc_irq_disable(adapter);
From: David Heidelberg david@ixit.cz
[ Upstream commit 0dc6c59892ead17a9febd11202c9f6794aac1895 ]
Since new code doesn't take old clk names in account, it does fixes error:
msm_dsi 4700000.mdss_dsi: dev_pm_opp_set_clkname: Couldn't find clock: -2
and following kernel oops introduced by b0530eb1191 ("drm/msm/dpu: Use OPP API to set clk/perf state").
Also removes warning about deprecated clock names.
Tested against linux-5.10.y LTS on Nexus 7 2013.
Reviewed-by: Brian Masney masneyb@onstation.org Signed-off-by: David Heidelberg david@ixit.cz Link: https://lore.kernel.org/r/20210707131453.24041-1-david@ixit.cz Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/qcom-apq8064.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi index 2687c4e890ba..e36d590e8373 100644 --- a/arch/arm/boot/dts/qcom-apq8064.dtsi +++ b/arch/arm/boot/dts/qcom-apq8064.dtsi @@ -1262,9 +1262,9 @@ dsi0: mdss_dsi@4700000 { <&mmcc DSI1_BYTE_CLK>, <&mmcc DSI_PIXEL_CLK>, <&mmcc DSI1_ESC_CLK>; - clock-names = "iface_clk", "bus_clk", "core_mmss_clk", - "src_clk", "byte_clk", "pixel_clk", - "core_clk"; + clock-names = "iface", "bus", "core_mmss", + "src", "byte", "pixel", + "core";
assigned-clocks = <&mmcc DSI1_BYTE_SRC>, <&mmcc DSI1_ESC_SRC>,
From: Zheyu Ma zheyuma97@gmail.com
[ Upstream commit 98a65439172dc69cb16834e62e852afc2adb83ed ]
The user can pass in any value to the driver through the 'ioctl' interface. The driver dost not check, which may cause DoS bugs.
The following log reveals it:
divide error: 0000 [#1] PREEMPT SMP KASAN PTI RIP: 0010:SetOverlayViewPort+0x133/0x5f0 drivers/video/fbdev/kyro/STG4000OverlayDevice.c:476 Call Trace: kyro_dev_overlay_viewport_set drivers/video/fbdev/kyro/fbdev.c:378 [inline] kyrofb_ioctl+0x2eb/0x330 drivers/video/fbdev/kyro/fbdev.c:603 do_fb_ioctl+0x1f3/0x700 drivers/video/fbdev/core/fbmem.c:1171 fb_ioctl+0xeb/0x130 drivers/video/fbdev/core/fbmem.c:1185 vfs_ioctl fs/ioctl.c:48 [inline] __do_sys_ioctl fs/ioctl.c:753 [inline] __se_sys_ioctl fs/ioctl.c:739 [inline] __x64_sys_ioctl+0x19b/0x220 fs/ioctl.c:739 do_syscall_64+0x32/0x80 arch/x86/entry/common.c:46 entry_SYSCALL_64_after_hwframe+0x44/0xae
Signed-off-by: Zheyu Ma zheyuma97@gmail.com Signed-off-by: Sam Ravnborg sam@ravnborg.org Link: https://patchwork.freedesktop.org/patch/msgid/1626235762-2590-1-git-send-ema... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/video/fbdev/kyro/fbdev.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/video/fbdev/kyro/fbdev.c b/drivers/video/fbdev/kyro/fbdev.c index 8fbde92ae8b9..4b8c7c16b1df 100644 --- a/drivers/video/fbdev/kyro/fbdev.c +++ b/drivers/video/fbdev/kyro/fbdev.c @@ -372,6 +372,11 @@ static int kyro_dev_overlay_viewport_set(u32 x, u32 y, u32 ulWidth, u32 ulHeight /* probably haven't called CreateOverlay yet */ return -EINVAL;
+ if (ulWidth == 0 || ulWidth == 0xffffffff || + ulHeight == 0 || ulHeight == 0xffffffff || + (x < 2 && ulWidth + 2 == 0)) + return -EINVAL; + /* Stop Ramdac Output */ DisableRamdacOutput(deviceInfo.pSTGReg);
From: KuoHsiang Chou kuohsiang_chou@aspeedtech.com
[ Upstream commit f34bf652d680cf65783e7c57d61c94ee87f092bd ]
[Bug][AST2500]
V1: When AST2500 acts as stand-alone VGA so that DRAM and DVO initialization have to be achieved by VGA driver with P2A (PCI to AHB) enabling. However, HW suggests disable Fast reset mode after DRAM initializaton, because fast reset mode is mainly designed for ARM ICE debugger. Once Fast reset is checked as enabling, WDT (Watch Dog Timer) should be first enabled to avoid system deadlock before disable fast reset mode.
V2: Use to_pci_dev() to get revision of PCI configuration.
V3: If SCU00 is not unlocked, just enter its password again. It is unnecessary to clear AHB lock condition and restore WDT default setting again, before Fast-reset clearing.
V4: repatch after "error : could not build fake ancestor" resolved.
V5: Since CVE_2019_6260 item3, Most of AST2500 have disabled P2A(PCIe to AMBA). However, for backward compatibility, some patches about P2A, such as items of v5.2 and v5.3, are considered to be upstreamed with comments. 1. Add define macro to improve source readability. ast_drv.h, ast_main.c, ast_post.c 2. Add comment about "Fast restet" is enabled for ARM-ICE debugger ast_post.c 3. Add comment about Reset USB port to patch USB unknown device issue ast_post.c
Signed-off-by: KuoHsiang Chou kuohsiang_chou@aspeedtech.com Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Link: https://patchwork.freedesktop.org/patch/msgid/20210709080900.4056-1-kuohsian... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/ast/ast_drv.h | 6 +++ drivers/gpu/drm/ast/ast_main.c | 5 ++ drivers/gpu/drm/ast/ast_post.c | 91 ++++++++++++++++++++++++---------- 3 files changed, 76 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 911f9f414774..39ca338eb80b 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -337,6 +337,11 @@ int ast_mode_config_init(struct ast_private *ast); #define AST_DP501_LINKRATE 0xf014 #define AST_DP501_EDID_DATA 0xf020
+/* Define for Soc scratched reg */ +#define AST_VRAM_INIT_STATUS_MASK GENMASK(7, 6) +//#define AST_VRAM_INIT_BY_BMC BIT(7) +//#define AST_VRAM_INIT_READY BIT(6) + int ast_mm_init(struct ast_private *ast);
/* ast post */ @@ -346,6 +351,7 @@ bool ast_is_vga_enabled(struct drm_device *dev); void ast_post_gpu(struct drm_device *dev); u32 ast_mindwm(struct ast_private *ast, u32 r); void ast_moutdwm(struct ast_private *ast, u32 r, u32 v); +void ast_patch_ahb_2500(struct ast_private *ast); /* ast dp501 */ void ast_set_dp501_video_output(struct drm_device *dev, u8 mode); bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size); diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 2aff2e6cf450..79a361867955 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -97,6 +97,11 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev) jregd0 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); jregd1 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) { + /* Patch AST2500 */ + if (((pdev->revision & 0xF0) == 0x40) + && ((jregd0 & AST_VRAM_INIT_STATUS_MASK) == 0)) + ast_patch_ahb_2500(ast); + /* Double check it's actually working */ data = ast_read32(ast, 0xf004); if ((data != 0xFFFFFFFF) && (data != 0x00)) { diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c index 0607658dde51..b5d92f652fd8 100644 --- a/drivers/gpu/drm/ast/ast_post.c +++ b/drivers/gpu/drm/ast/ast_post.c @@ -2028,6 +2028,40 @@ static bool ast_dram_init_2500(struct ast_private *ast) return true; }
+void ast_patch_ahb_2500(struct ast_private *ast) +{ + u32 data; + + /* Clear bus lock condition */ + ast_moutdwm(ast, 0x1e600000, 0xAEED1A03); + ast_moutdwm(ast, 0x1e600084, 0x00010000); + ast_moutdwm(ast, 0x1e600088, 0x00000000); + ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8); + data = ast_mindwm(ast, 0x1e6e2070); + if (data & 0x08000000) { /* check fast reset */ + /* + * If "Fast restet" is enabled for ARM-ICE debugger, + * then WDT needs to enable, that + * WDT04 is WDT#1 Reload reg. + * WDT08 is WDT#1 counter restart reg to avoid system deadlock + * WDT0C is WDT#1 control reg + * [6:5]:= 01:Full chip + * [4]:= 1:1MHz clock source + * [1]:= 1:WDT will be cleeared and disabled after timeout occurs + * [0]:= 1:WDT enable + */ + ast_moutdwm(ast, 0x1E785004, 0x00000010); + ast_moutdwm(ast, 0x1E785008, 0x00004755); + ast_moutdwm(ast, 0x1E78500c, 0x00000033); + udelay(1000); + } + do { + ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8); + data = ast_mindwm(ast, 0x1e6e2000); + } while (data != 1); + ast_moutdwm(ast, 0x1e6e207c, 0x08000000); /* clear fast reset */ +} + void ast_post_chip_2500(struct drm_device *dev) { struct ast_private *ast = to_ast_private(dev); @@ -2035,39 +2069,44 @@ void ast_post_chip_2500(struct drm_device *dev) u8 reg;
reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); - if ((reg & 0x80) == 0) {/* vga only */ + if ((reg & AST_VRAM_INIT_STATUS_MASK) == 0) {/* vga only */ /* Clear bus lock condition */ - ast_moutdwm(ast, 0x1e600000, 0xAEED1A03); - ast_moutdwm(ast, 0x1e600084, 0x00010000); - ast_moutdwm(ast, 0x1e600088, 0x00000000); - ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8); - ast_write32(ast, 0xf004, 0x1e6e0000); - ast_write32(ast, 0xf000, 0x1); - ast_write32(ast, 0x12000, 0x1688a8a8); - while (ast_read32(ast, 0x12000) != 0x1) - ; - - ast_write32(ast, 0x10000, 0xfc600309); - while (ast_read32(ast, 0x10000) != 0x1) - ; + ast_patch_ahb_2500(ast); + + /* Disable watchdog */ + ast_moutdwm(ast, 0x1E78502C, 0x00000000); + ast_moutdwm(ast, 0x1E78504C, 0x00000000); + + /* + * Reset USB port to patch USB unknown device issue + * SCU90 is Multi-function Pin Control #5 + * [29]:= 1:Enable USB2.0 Host port#1 (that the mutually shared USB2.0 Hub + * port). + * SCU94 is Multi-function Pin Control #6 + * [14:13]:= 1x:USB2.0 Host2 controller + * SCU70 is Hardware Strap reg + * [23]:= 1:CLKIN is 25MHz and USBCK1 = 24/48 MHz (determined by + * [18]: 0(24)/1(48) MHz) + * SCU7C is Write clear reg to SCU70 + * [23]:= write 1 and then SCU70[23] will be clear as 0b. + */ + ast_moutdwm(ast, 0x1E6E2090, 0x20000000); + ast_moutdwm(ast, 0x1E6E2094, 0x00004000); + if (ast_mindwm(ast, 0x1E6E2070) & 0x00800000) { + ast_moutdwm(ast, 0x1E6E207C, 0x00800000); + mdelay(100); + ast_moutdwm(ast, 0x1E6E2070, 0x00800000); + } + /* Modify eSPI reset pin */ + temp = ast_mindwm(ast, 0x1E6E2070); + if (temp & 0x02000000) + ast_moutdwm(ast, 0x1E6E207C, 0x00004000);
/* Slow down CPU/AHB CLK in VGA only mode */ temp = ast_read32(ast, 0x12008); temp |= 0x73; ast_write32(ast, 0x12008, temp);
- /* Reset USB port to patch USB unknown device issue */ - ast_moutdwm(ast, 0x1e6e2090, 0x20000000); - temp = ast_mindwm(ast, 0x1e6e2094); - temp |= 0x00004000; - ast_moutdwm(ast, 0x1e6e2094, temp); - temp = ast_mindwm(ast, 0x1e6e2070); - if (temp & 0x00800000) { - ast_moutdwm(ast, 0x1e6e207c, 0x00800000); - mdelay(100); - ast_moutdwm(ast, 0x1e6e2070, 0x00800000); - } - if (!ast_dram_init_2500(ast)) drm_err(dev, "DRAM init failed !\n");
From: Yajun Deng yajun.deng@linux.dev
[ Upstream commit fef773fc8110d8124c73a5e6610f89e52814637d ]
Yonghong Song report: The bpf selftest tc_bpf failed with latest bpf-next. The following is the command to run and the result: $ ./test_progs -n 132 [ 40.947571] bpf_testmod: loading out-of-tree module taints kernel. test_tc_bpf:PASS:test_tc_bpf__open_and_load 0 nsec test_tc_bpf:PASS:bpf_tc_hook_create(BPF_TC_INGRESS) 0 nsec test_tc_bpf:PASS:bpf_tc_hook_create invalid hook.attach_point 0 nsec test_tc_bpf_basic:PASS:bpf_obj_get_info_by_fd 0 nsec test_tc_bpf_basic:PASS:bpf_tc_attach 0 nsec test_tc_bpf_basic:PASS:handle set 0 nsec test_tc_bpf_basic:PASS:priority set 0 nsec test_tc_bpf_basic:PASS:prog_id set 0 nsec test_tc_bpf_basic:PASS:bpf_tc_attach replace mode 0 nsec test_tc_bpf_basic:PASS:bpf_tc_query 0 nsec test_tc_bpf_basic:PASS:handle set 0 nsec test_tc_bpf_basic:PASS:priority set 0 nsec test_tc_bpf_basic:PASS:prog_id set 0 nsec libbpf: Kernel error message: Failed to send filter delete notification test_tc_bpf_basic:FAIL:bpf_tc_detach unexpected error: -3 (errno 3) test_tc_bpf:FAIL:test_tc_internal ingress unexpected error: -3 (errno 3)
The failure seems due to the commit cfdf0d9ae75b ("rtnetlink: use nlmsg_notify() in rtnetlink_send()")
Deal with ESRCH error in nlmsg_notify() even the report variable is zero.
Reported-by: Yonghong Song yhs@fb.com Signed-off-by: Yajun Deng yajun.deng@linux.dev Link: https://lore.kernel.org/r/20210719051816.11762-1-yajun.deng@linux.dev Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/netlink/af_netlink.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 6133e412b948..b9ed16ff09c1 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -2545,13 +2545,15 @@ int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 portid, /* errors reported via destination sk->sk_err, but propagate * delivery errors if NETLINK_BROADCAST_ERROR flag is set */ err = nlmsg_multicast(sk, skb, exclude_portid, group, flags); + if (err == -ESRCH) + err = 0; }
if (report) { int err2;
err2 = nlmsg_unicast(sk, skb, portid); - if (!err || err == -ESRCH) + if (!err) err = err2; }
From: Alex Elder elder@linaro.org
[ Upstream commit 0ac26271344478ff718329fa9d4ef81d4bcbc43b ]
Currently three interconnects are defined for the Qualcomm SC7280 SoC, but this was based on a misunderstanding. There should only be two interconnects defined: one between the IPA and system memory; and another between the AP and IPA config space. The bandwidths defined for the memory and config interconnects do not match what I understand to be proper values, so update these.
Signed-off-by: Alex Elder elder@linaro.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ipa/ipa_data-v4.11.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ipa/ipa_data-v4.11.c b/drivers/net/ipa/ipa_data-v4.11.c index 05806ceae8b5..157f8d47058b 100644 --- a/drivers/net/ipa/ipa_data-v4.11.c +++ b/drivers/net/ipa/ipa_data-v4.11.c @@ -346,18 +346,13 @@ static const struct ipa_mem_data ipa_mem_data = { static const struct ipa_interconnect_data ipa_interconnect_data[] = { { .name = "memory", - .peak_bandwidth = 465000, /* 465 MBps */ - .average_bandwidth = 80000, /* 80 MBps */ - }, - /* Average rate is unused for the next two interconnects */ - { - .name = "imem", - .peak_bandwidth = 68570, /* 68.57 MBps */ - .average_bandwidth = 80000, /* 80 MBps (unused?) */ + .peak_bandwidth = 600000, /* 600 MBps */ + .average_bandwidth = 150000, /* 150 MBps */ }, + /* Average rate is unused for the next interconnect */ { .name = "config", - .peak_bandwidth = 30000, /* 30 MBps */ + .peak_bandwidth = 74000, /* 74 MBps */ .average_bandwidth = 0, /* unused */ }, };
From: Tianjia Zhang tianjia.zhang@linux.alibaba.com
[ Upstream commit 6d14f5c7028eea70760df284057fe198ce7778dd ]
In the smk_access_entry() function, if no matching rule is found in the rust_list, a negative error code will be used to perform bit operations with the MAY_ enumeration value. This is semantically wrong. This patch fixes this issue.
Signed-off-by: Tianjia Zhang tianjia.zhang@linux.alibaba.com Signed-off-by: Casey Schaufler casey@schaufler-ca.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/smack/smack_access.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index 7eabb448acab..169929c6c4eb 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c @@ -81,23 +81,22 @@ int log_policy = SMACK_AUDIT_DENIED; int smk_access_entry(char *subject_label, char *object_label, struct list_head *rule_list) { - int may = -ENOENT; struct smack_rule *srp;
list_for_each_entry_rcu(srp, rule_list, list) { if (srp->smk_object->smk_known == object_label && srp->smk_subject->smk_known == subject_label) { - may = srp->smk_access; - break; + int may = srp->smk_access; + /* + * MAY_WRITE implies MAY_LOCK. + */ + if ((may & MAY_WRITE) == MAY_WRITE) + may |= MAY_LOCK; + return may; } }
- /* - * MAY_WRITE implies MAY_LOCK. - */ - if ((may & MAY_WRITE) == MAY_WRITE) - may |= MAY_LOCK; - return may; + return -ENOENT; }
/**
From: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com
[ Upstream commit 5eff9585de220cdd131237f5665db5e6c6bdf590 ]
Inside drm_clients_info, the rcu_read_lock is held to lock pid_task()->comm. However, within this protected section, a call to drm_is_current_master is made, which involves a mutex lock in a future patch. However, this is illegal because the mutex lock might block while in the RCU read-side critical section.
Since drm_is_current_master isn't protected by rcu_read_lock, we avoid this by moving it out of the RCU critical section.
The following report came from intel-gfx ci's igt@debugfs_test@read_all_entries testcase:
============================= [ BUG: Invalid wait context ] 5.13.0-CI-Patchwork_20515+ #1 Tainted: G W ----------------------------- debugfs_test/1101 is trying to lock: ffff888132d901a8 (&dev->master_mutex){+.+.}-{3:3}, at: drm_is_current_master+0x1e/0x50 other info that might help us debug this: context-{4:4} 3 locks held by debugfs_test/1101: #0: ffff88810fdffc90 (&p->lock){+.+.}-{3:3}, at: seq_read_iter+0x53/0x3b0 #1: ffff888132d90240 (&dev->filelist_mutex){+.+.}-{3:3}, at: drm_clients_info+0x63/0x2a0 #2: ffffffff82734220 (rcu_read_lock){....}-{1:2}, at: drm_clients_info+0x1b1/0x2a0 stack backtrace: CPU: 8 PID: 1101 Comm: debugfs_test Tainted: G W 5.13.0-CI-Patchwork_20515+ #1 Hardware name: Intel Corporation CometLake Client Platform/CometLake S UDIMM (ERB/CRB), BIOS CMLSFWR1.R00.1263.D00.1906260926 06/26/2019 Call Trace: dump_stack+0x7f/0xad __lock_acquire.cold.78+0x2af/0x2ca lock_acquire+0xd3/0x300 ? drm_is_current_master+0x1e/0x50 ? __mutex_lock+0x76/0x970 ? lockdep_hardirqs_on+0xbf/0x130 __mutex_lock+0xab/0x970 ? drm_is_current_master+0x1e/0x50 ? drm_is_current_master+0x1e/0x50 ? drm_is_current_master+0x1e/0x50 drm_is_current_master+0x1e/0x50 drm_clients_info+0x107/0x2a0 seq_read_iter+0x178/0x3b0 seq_read+0x104/0x150 full_proxy_read+0x4e/0x80 vfs_read+0xa5/0x1b0 ksys_read+0x5a/0xd0 do_syscall_64+0x39/0xb0 entry_SYSCALL_64_after_hwframe+0x44/0xae
Signed-off-by: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch Link: https://patchwork.freedesktop.org/patch/msgid/20210712043508.11584-3-desmond... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_debugfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 3d7182001004..b0a826489488 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -91,6 +91,7 @@ static int drm_clients_info(struct seq_file *m, void *data) mutex_lock(&dev->filelist_mutex); list_for_each_entry_reverse(priv, &dev->filelist, lhead) { struct task_struct *task; + bool is_current_master = drm_is_current_master(priv);
rcu_read_lock(); /* locks pid_task()->comm */ task = pid_task(priv->pid, PIDTYPE_PID); @@ -99,7 +100,7 @@ static int drm_clients_info(struct seq_file *m, void *data) task ? task->comm : "<unknown>", pid_vnr(priv->pid), priv->minor->index, - drm_is_current_master(priv) ? 'y' : 'n', + is_current_master ? 'y' : 'n', priv->authenticated ? 'y' : 'n', from_kuid_munged(seq_user_ns(m), uid), priv->magic);
From: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com
[ Upstream commit 0b0860a3cf5eccf183760b1177a1dcdb821b0b66 ]
Currently, drm_file.master pointers should be protected by drm_device.master_mutex when being dereferenced. This is because drm_file.master is not invariant for the lifetime of drm_file. If drm_file is not the creator of master, then drm_file.is_master is false, and a call to drm_setmaster_ioctl will invoke drm_new_set_master, which then allocates a new master for drm_file and puts the old master.
Thus, without holding drm_device.master_mutex, the old value of drm_file.master could be freed while it is being used by another concurrent process.
However, it is not always possible to lock drm_device.master_mutex to dereference drm_file.master. Through the fbdev emulation code, this might occur in a deep nest of other locks. But drm_device.master_mutex is also the outermost lock in the nesting hierarchy, so this leads to potential deadlocks.
To address this, we introduce a new spin lock at the bottom of the lock hierarchy that only serializes drm_file.master. With this change, the value of drm_file.master changes only when both drm_device.master_mutex and drm_file.master_lookup_lock are held. Hence, any process holding either of those locks can ensure that the value of drm_file.master will not change concurrently.
Since no lock depends on the new drm_file.master_lookup_lock, when drm_file.master is dereferenced, but drm_device.master_mutex cannot be held, we can safely protect the master pointer with drm_file.master_lookup_lock.
Reported-by: Daniel Vetter daniel.vetter@ffwll.ch Signed-off-by: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch Link: https://patchwork.freedesktop.org/patch/msgid/20210712043508.11584-5-desmond... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_auth.c | 17 +++++++++++------ drivers/gpu/drm/drm_file.c | 1 + include/drm/drm_file.h | 12 +++++++++--- 3 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index 232abbba3686..0024ad93d24b 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c @@ -135,16 +135,18 @@ static void drm_set_master(struct drm_device *dev, struct drm_file *fpriv, static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv) { struct drm_master *old_master; + struct drm_master *new_master;
lockdep_assert_held_once(&dev->master_mutex);
WARN_ON(fpriv->is_master); old_master = fpriv->master; - fpriv->master = drm_master_create(dev); - if (!fpriv->master) { - fpriv->master = old_master; + new_master = drm_master_create(dev); + if (!new_master) return -ENOMEM; - } + spin_lock(&fpriv->master_lookup_lock); + fpriv->master = new_master; + spin_unlock(&fpriv->master_lookup_lock);
fpriv->is_master = 1; fpriv->authenticated = 1; @@ -302,10 +304,13 @@ int drm_master_open(struct drm_file *file_priv) /* if there is no current master make this fd it, but do not create * any master object for render clients */ mutex_lock(&dev->master_mutex); - if (!dev->master) + if (!dev->master) { ret = drm_new_set_master(dev, file_priv); - else + } else { + spin_lock(&file_priv->master_lookup_lock); file_priv->master = drm_master_get(dev->master); + spin_unlock(&file_priv->master_lookup_lock); + } mutex_unlock(&dev->master_mutex);
return ret; diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index 7efbccffc2ea..c6feeb5651b0 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -176,6 +176,7 @@ struct drm_file *drm_file_alloc(struct drm_minor *minor) init_waitqueue_head(&file->event_wait); file->event_space = 4096; /* set aside 4k for event buffer */
+ spin_lock_init(&file->master_lookup_lock); mutex_init(&file->event_read_lock);
if (drm_core_check_feature(dev, DRIVER_GEM)) diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h index b81b3bfb08c8..9b82988e3427 100644 --- a/include/drm/drm_file.h +++ b/include/drm/drm_file.h @@ -226,15 +226,21 @@ struct drm_file { /** * @master: * - * Master this node is currently associated with. Only relevant if - * drm_is_primary_client() returns true. Note that this only - * matches &drm_device.master if the master is the currently active one. + * Master this node is currently associated with. Protected by struct + * &drm_device.master_mutex, and serialized by @master_lookup_lock. + * + * Only relevant if drm_is_primary_client() returns true. Note that + * this only matches &drm_device.master if the master is the currently + * active one. * * See also @authentication and @is_master and the :ref:`section on * primary nodes and authentication <drm_primary_node>`. */ struct drm_master *master;
+ /** @master_lock: Serializes @master. */ + spinlock_t master_lookup_lock; + /** @pid: Process that opened this file. */ struct pid *pid;
From: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com
[ Upstream commit 56f0729a510f92151682ff6c89f69724d5595d6e ]
drm_file->master pointers should be protected by drm_device.master_mutex or drm_file.master_lookup_lock when being dereferenced.
However, in drm_lease.c, there are multiple instances where drm_file->master is accessed and dereferenced while neither lock is held. This makes drm_lease.c vulnerable to use-after-free bugs.
We address this issue in 2 ways:
1. Add a new drm_file_get_master() function that calls drm_master_get on drm_file->master while holding on to drm_file.master_lookup_lock. Since drm_master_get increments the reference count of master, this prevents master from being freed until we unreference it with drm_master_put.
2. In each case where drm_file->master is directly accessed and eventually dereferenced in drm_lease.c, we wrap the access in a call to the new drm_file_get_master function, then unreference the master pointer once we are done using it.
Reported-by: Daniel Vetter daniel.vetter@ffwll.ch Signed-off-by: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com Reviewed-by: Emil Velikov emil.l.velikov@gmail.com Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch Link: https://patchwork.freedesktop.org/patch/msgid/20210712043508.11584-6-desmond... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_auth.c | 25 ++++++++++++ drivers/gpu/drm/drm_lease.c | 81 ++++++++++++++++++++++++++++--------- include/drm/drm_auth.h | 1 + include/drm/drm_file.h | 6 +++ 4 files changed, 93 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index 0024ad93d24b..c7adbeaf10b1 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c @@ -376,6 +376,31 @@ struct drm_master *drm_master_get(struct drm_master *master) } EXPORT_SYMBOL(drm_master_get);
+/** + * drm_file_get_master - reference &drm_file.master of @file_priv + * @file_priv: DRM file private + * + * Increments the reference count of @file_priv's &drm_file.master and returns + * the &drm_file.master. If @file_priv has no &drm_file.master, returns NULL. + * + * Master pointers returned from this function should be unreferenced using + * drm_master_put(). + */ +struct drm_master *drm_file_get_master(struct drm_file *file_priv) +{ + struct drm_master *master = NULL; + + spin_lock(&file_priv->master_lookup_lock); + if (!file_priv->master) + goto unlock; + master = drm_master_get(file_priv->master); + +unlock: + spin_unlock(&file_priv->master_lookup_lock); + return master; +} +EXPORT_SYMBOL(drm_file_get_master); + static void drm_master_destroy(struct kref *kref) { struct drm_master *master = container_of(kref, struct drm_master, refcount); diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c index da4f085fc09e..aef22634005e 100644 --- a/drivers/gpu/drm/drm_lease.c +++ b/drivers/gpu/drm/drm_lease.c @@ -107,10 +107,19 @@ static bool _drm_has_leased(struct drm_master *master, int id) */ bool _drm_lease_held(struct drm_file *file_priv, int id) { - if (!file_priv || !file_priv->master) + bool ret; + struct drm_master *master; + + if (!file_priv) return true;
- return _drm_lease_held_master(file_priv->master, id); + master = drm_file_get_master(file_priv); + if (!master) + return true; + ret = _drm_lease_held_master(master, id); + drm_master_put(&master); + + return ret; }
/** @@ -129,13 +138,22 @@ bool drm_lease_held(struct drm_file *file_priv, int id) struct drm_master *master; bool ret;
- if (!file_priv || !file_priv->master || !file_priv->master->lessor) + if (!file_priv) return true;
- master = file_priv->master; + master = drm_file_get_master(file_priv); + if (!master) + return true; + if (!master->lessor) { + ret = true; + goto out; + } mutex_lock(&master->dev->mode_config.idr_mutex); ret = _drm_lease_held_master(master, id); mutex_unlock(&master->dev->mode_config.idr_mutex); + +out: + drm_master_put(&master); return ret; }
@@ -155,10 +173,16 @@ uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in) int count_in, count_out; uint32_t crtcs_out = 0;
- if (!file_priv || !file_priv->master || !file_priv->master->lessor) + if (!file_priv) return crtcs_in;
- master = file_priv->master; + master = drm_file_get_master(file_priv); + if (!master) + return crtcs_in; + if (!master->lessor) { + crtcs_out = crtcs_in; + goto out; + } dev = master->dev;
count_in = count_out = 0; @@ -177,6 +201,9 @@ uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in) count_in++; } mutex_unlock(&master->dev->mode_config.idr_mutex); + +out: + drm_master_put(&master); return crtcs_out; }
@@ -490,7 +517,7 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev, size_t object_count; int ret = 0; struct idr leases; - struct drm_master *lessor = lessor_priv->master; + struct drm_master *lessor; struct drm_master *lessee = NULL; struct file *lessee_file = NULL; struct file *lessor_file = lessor_priv->filp; @@ -502,12 +529,6 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EOPNOTSUPP;
- /* Do not allow sub-leases */ - if (lessor->lessor) { - DRM_DEBUG_LEASE("recursive leasing not allowed\n"); - return -EINVAL; - } - /* need some objects */ if (cl->object_count == 0) { DRM_DEBUG_LEASE("no objects in lease\n"); @@ -519,12 +540,22 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev, return -EINVAL; }
+ lessor = drm_file_get_master(lessor_priv); + /* Do not allow sub-leases */ + if (lessor->lessor) { + DRM_DEBUG_LEASE("recursive leasing not allowed\n"); + ret = -EINVAL; + goto out_lessor; + } + object_count = cl->object_count;
object_ids = memdup_user(u64_to_user_ptr(cl->object_ids), array_size(object_count, sizeof(__u32))); - if (IS_ERR(object_ids)) - return PTR_ERR(object_ids); + if (IS_ERR(object_ids)) { + ret = PTR_ERR(object_ids); + goto out_lessor; + }
idr_init(&leases);
@@ -535,14 +566,15 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev, if (ret) { DRM_DEBUG_LEASE("lease object lookup failed: %i\n", ret); idr_destroy(&leases); - return ret; + goto out_lessor; }
/* Allocate a file descriptor for the lease */ fd = get_unused_fd_flags(cl->flags & (O_CLOEXEC | O_NONBLOCK)); if (fd < 0) { idr_destroy(&leases); - return fd; + ret = fd; + goto out_lessor; }
DRM_DEBUG_LEASE("Creating lease\n"); @@ -578,6 +610,7 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev, /* Hook up the fd */ fd_install(fd, lessee_file);
+ drm_master_put(&lessor); DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl succeeded\n"); return 0;
@@ -587,6 +620,8 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev, out_leases: put_unused_fd(fd);
+out_lessor: + drm_master_put(&lessor); DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl failed: %d\n", ret); return ret; } @@ -609,7 +644,7 @@ int drm_mode_list_lessees_ioctl(struct drm_device *dev, struct drm_mode_list_lessees *arg = data; __u32 __user *lessee_ids = (__u32 __user *) (uintptr_t) (arg->lessees_ptr); __u32 count_lessees = arg->count_lessees; - struct drm_master *lessor = lessor_priv->master, *lessee; + struct drm_master *lessor, *lessee; int count; int ret = 0;
@@ -620,6 +655,7 @@ int drm_mode_list_lessees_ioctl(struct drm_device *dev, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EOPNOTSUPP;
+ lessor = drm_file_get_master(lessor_priv); DRM_DEBUG_LEASE("List lessees for %d\n", lessor->lessee_id);
mutex_lock(&dev->mode_config.idr_mutex); @@ -643,6 +679,7 @@ int drm_mode_list_lessees_ioctl(struct drm_device *dev, arg->count_lessees = count;
mutex_unlock(&dev->mode_config.idr_mutex); + drm_master_put(&lessor);
return ret; } @@ -662,7 +699,7 @@ int drm_mode_get_lease_ioctl(struct drm_device *dev, struct drm_mode_get_lease *arg = data; __u32 __user *object_ids = (__u32 __user *) (uintptr_t) (arg->objects_ptr); __u32 count_objects = arg->count_objects; - struct drm_master *lessee = lessee_priv->master; + struct drm_master *lessee; struct idr *object_idr; int count; void *entry; @@ -676,6 +713,7 @@ int drm_mode_get_lease_ioctl(struct drm_device *dev, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EOPNOTSUPP;
+ lessee = drm_file_get_master(lessee_priv); DRM_DEBUG_LEASE("get lease for %d\n", lessee->lessee_id);
mutex_lock(&dev->mode_config.idr_mutex); @@ -703,6 +741,7 @@ int drm_mode_get_lease_ioctl(struct drm_device *dev, arg->count_objects = count;
mutex_unlock(&dev->mode_config.idr_mutex); + drm_master_put(&lessee);
return ret; } @@ -721,7 +760,7 @@ int drm_mode_revoke_lease_ioctl(struct drm_device *dev, void *data, struct drm_file *lessor_priv) { struct drm_mode_revoke_lease *arg = data; - struct drm_master *lessor = lessor_priv->master; + struct drm_master *lessor; struct drm_master *lessee; int ret = 0;
@@ -731,6 +770,7 @@ int drm_mode_revoke_lease_ioctl(struct drm_device *dev, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EOPNOTSUPP;
+ lessor = drm_file_get_master(lessor_priv); mutex_lock(&dev->mode_config.idr_mutex);
lessee = _drm_find_lessee(lessor, arg->lessee_id); @@ -751,6 +791,7 @@ int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
fail: mutex_unlock(&dev->mode_config.idr_mutex); + drm_master_put(&lessor);
return ret; } diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h index 6bf8b2b78991..f99d3417f304 100644 --- a/include/drm/drm_auth.h +++ b/include/drm/drm_auth.h @@ -107,6 +107,7 @@ struct drm_master { };
struct drm_master *drm_master_get(struct drm_master *master); +struct drm_master *drm_file_get_master(struct drm_file *file_priv); void drm_master_put(struct drm_master **master); bool drm_is_current_master(struct drm_file *fpriv);
diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h index 9b82988e3427..726cfe0ff5f5 100644 --- a/include/drm/drm_file.h +++ b/include/drm/drm_file.h @@ -233,6 +233,12 @@ struct drm_file { * this only matches &drm_device.master if the master is the currently * active one. * + * When dereferencing this pointer, either hold struct + * &drm_device.master_mutex for the duration of the pointer's use, or + * use drm_file_get_master() if struct &drm_device.master_mutex is not + * currently held and there is no other need to hold it. This prevents + * @master from being freed during use. + * * See also @authentication and @is_master and the :ref:`section on * primary nodes and authentication <drm_primary_node>`. */
From: Zhouyi Zhou zhouzhouyi@gmail.com
[ Upstream commit fed31a4dd3adb5455df7c704de2abb639a1dc1c0 ]
This commit fixes several typos where CONFIG_TASKS_RCU_TRACE should instead be CONFIG_TASKS_TRACE_RCU. Among other things, these typos could cause CONFIG_TASKS_TRACE_RCU_READ_MB=y kernels to suffer from memory-ordering bugs that could result in false-positive quiescent states and too-short grace periods.
Signed-off-by: Zhouyi Zhou zhouzhouyi@gmail.com Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/rcupdate.h | 2 +- kernel/rcu/tree_plugin.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 1199ffd305d1..fcd8ec0b7408 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -167,7 +167,7 @@ void synchronize_rcu_tasks(void); # define synchronize_rcu_tasks synchronize_rcu # endif
-# ifdef CONFIG_TASKS_RCU_TRACE +# ifdef CONFIG_TASKS_TRACE_RCU # define rcu_tasks_trace_qs(t) \ do { \ if (!likely(READ_ONCE((t)->trc_reader_checked)) && \ diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h index ad0156b86937..d14905051535 100644 --- a/kernel/rcu/tree_plugin.h +++ b/kernel/rcu/tree_plugin.h @@ -2995,17 +2995,17 @@ static void noinstr rcu_dynticks_task_exit(void) /* Turn on heavyweight RCU tasks trace readers on idle/user entry. */ static void rcu_dynticks_task_trace_enter(void) { -#ifdef CONFIG_TASKS_RCU_TRACE +#ifdef CONFIG_TASKS_TRACE_RCU if (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB)) current->trc_reader_special.b.need_mb = true; -#endif /* #ifdef CONFIG_TASKS_RCU_TRACE */ +#endif /* #ifdef CONFIG_TASKS_TRACE_RCU */ }
/* Turn off heavyweight RCU tasks trace readers on idle/user exit. */ static void rcu_dynticks_task_trace_exit(void) { -#ifdef CONFIG_TASKS_RCU_TRACE +#ifdef CONFIG_TASKS_TRACE_RCU if (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB)) current->trc_reader_special.b.need_mb = false; -#endif /* #ifdef CONFIG_TASKS_RCU_TRACE */ +#endif /* #ifdef CONFIG_TASKS_TRACE_RCU */ }
From: Sasha Neftin sasha.neftin@intel.com
[ Upstream commit 373e2829e7c2e1e606503cdb5c97749f512a4be9 ]
Ensure that the adapter->q_vector[MAX_Q_VECTORS] array isn't accessed beyond its size. It was fixed by using a local variable num_q_vectors as a limit for loop index, and ensure that num_q_vectors is not bigger than MAX_Q_VECTORS.
Suggested-by: Aleksandr Loktionov aleksandr.loktionov@intel.com Signed-off-by: Sasha Neftin sasha.neftin@intel.com Tested-by: Dvora Fuxbrumer dvorax.fuxbrumer@linux.intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/igc/igc_main.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index 9b85fdf01297..3e301c5c5270 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -4402,6 +4402,7 @@ static irqreturn_t igc_msix_ring(int irq, void *data) */ static int igc_request_msix(struct igc_adapter *adapter) { + unsigned int num_q_vectors = adapter->num_q_vectors; int i = 0, err = 0, vector = 0, free_vector = 0; struct net_device *netdev = adapter->netdev;
@@ -4410,7 +4411,13 @@ static int igc_request_msix(struct igc_adapter *adapter) if (err) goto err_out;
- for (i = 0; i < adapter->num_q_vectors; i++) { + if (num_q_vectors > MAX_Q_VECTORS) { + num_q_vectors = MAX_Q_VECTORS; + dev_warn(&adapter->pdev->dev, + "The number of queue vectors (%d) is higher than max allowed (%d)\n", + adapter->num_q_vectors, MAX_Q_VECTORS); + } + for (i = 0; i < num_q_vectors; i++) { struct igc_q_vector *q_vector = adapter->q_vector[i];
vector++;
From: Kelly Devilliv kelly.devilliv@gmail.com
[ Upstream commit c2e898764245c852bc8ee4857613ba4f3a6d761d ]
Now that usb_endpoint_maxp() only returns the lowest 11 bits from wMaxPacketSize, we should make use of the usb_endpoint_* helpers instead and remove the unnecessary max_packet()/hb_mult() macro.
Signed-off-by: Kelly Devilliv kelly.devilliv@gmail.com Link: https://lore.kernel.org/r/20210627125747.127646-3-kelly.devilliv@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/fotg210-hcd.c | 36 ++++++++++++++++------------------ 1 file changed, 17 insertions(+), 19 deletions(-)
diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c index 9c2eda0918e1..3b5d185c108a 100644 --- a/drivers/usb/host/fotg210-hcd.c +++ b/drivers/usb/host/fotg210-hcd.c @@ -2509,11 +2509,6 @@ static unsigned qh_completions(struct fotg210_hcd *fotg210, return count; }
-/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */ -#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03)) -/* ... and packet size, for any kind of endpoint descriptor */ -#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff) - /* reverse of qh_urb_transaction: free a list of TDs. * used for cleanup after errors, before HC sees an URB's TDs. */ @@ -2599,7 +2594,7 @@ static struct list_head *qh_urb_transaction(struct fotg210_hcd *fotg210, token |= (1 /* "in" */ << 8); /* else it's already initted to "out" pid (0 << 8) */
- maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, !is_input)); + maxpacket = usb_maxpacket(urb->dev, urb->pipe, !is_input);
/* * buffer gets wrapped in one or more qtds; @@ -2713,9 +2708,11 @@ static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb, gfp_t flags) { struct fotg210_qh *qh = fotg210_qh_alloc(fotg210, flags); + struct usb_host_endpoint *ep; u32 info1 = 0, info2 = 0; int is_input, type; int maxp = 0; + int mult; struct usb_tt *tt = urb->dev->tt; struct fotg210_qh_hw *hw;
@@ -2730,14 +2727,15 @@ static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb,
is_input = usb_pipein(urb->pipe); type = usb_pipetype(urb->pipe); - maxp = usb_maxpacket(urb->dev, urb->pipe, !is_input); + ep = usb_pipe_endpoint(urb->dev, urb->pipe); + maxp = usb_endpoint_maxp(&ep->desc); + mult = usb_endpoint_maxp_mult(&ep->desc);
/* 1024 byte maxpacket is a hardware ceiling. High bandwidth * acts like up to 3KB, but is built from smaller packets. */ - if (max_packet(maxp) > 1024) { - fotg210_dbg(fotg210, "bogus qh maxpacket %d\n", - max_packet(maxp)); + if (maxp > 1024) { + fotg210_dbg(fotg210, "bogus qh maxpacket %d\n", maxp); goto done; }
@@ -2751,8 +2749,7 @@ static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb, */ if (type == PIPE_INTERRUPT) { qh->usecs = NS_TO_US(usb_calc_bus_time(USB_SPEED_HIGH, - is_input, 0, - hb_mult(maxp) * max_packet(maxp))); + is_input, 0, mult * maxp)); qh->start = NO_FRAME;
if (urb->dev->speed == USB_SPEED_HIGH) { @@ -2789,7 +2786,7 @@ static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb, think_time = tt ? tt->think_time : 0; qh->tt_usecs = NS_TO_US(think_time + usb_calc_bus_time(urb->dev->speed, - is_input, 0, max_packet(maxp))); + is_input, 0, maxp)); qh->period = urb->interval; if (qh->period > fotg210->periodic_size) { qh->period = fotg210->periodic_size; @@ -2852,11 +2849,11 @@ static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb, * to help them do so. So now people expect to use * such nonconformant devices with Linux too; sigh. */ - info1 |= max_packet(maxp) << 16; + info1 |= maxp << 16; info2 |= (FOTG210_TUNE_MULT_HS << 30); } else { /* PIPE_INTERRUPT */ - info1 |= max_packet(maxp) << 16; - info2 |= hb_mult(maxp) << 30; + info1 |= maxp << 16; + info2 |= mult << 30; } break; default: @@ -3926,6 +3923,7 @@ static void iso_stream_init(struct fotg210_hcd *fotg210, int is_input; long bandwidth; unsigned multi; + struct usb_host_endpoint *ep;
/* * this might be a "high bandwidth" highspeed endpoint, @@ -3933,14 +3931,14 @@ static void iso_stream_init(struct fotg210_hcd *fotg210, */ epnum = usb_pipeendpoint(pipe); is_input = usb_pipein(pipe) ? USB_DIR_IN : 0; - maxp = usb_maxpacket(dev, pipe, !is_input); + ep = usb_pipe_endpoint(dev, pipe); + maxp = usb_endpoint_maxp(&ep->desc); if (is_input) buf1 = (1 << 11); else buf1 = 0;
- maxp = max_packet(maxp); - multi = hb_mult(maxp); + multi = usb_endpoint_maxp_mult(&ep->desc); buf1 |= maxp; maxp *= multi;
From: Kelly Devilliv kelly.devilliv@gmail.com
[ Upstream commit 091cb2f782f32ab68c6f5f326d7868683d3d4875 ]
We should acquire the actual_length of an iso packet from the iTD directly using FOTG210_ITD_LENGTH() macro.
Signed-off-by: Kelly Devilliv kelly.devilliv@gmail.com Link: https://lore.kernel.org/r/20210627125747.127646-4-kelly.devilliv@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/fotg210-hcd.c | 5 ++--- drivers/usb/host/fotg210.h | 5 ----- 2 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c index 3b5d185c108a..670a2fecc9c7 100644 --- a/drivers/usb/host/fotg210-hcd.c +++ b/drivers/usb/host/fotg210-hcd.c @@ -4459,13 +4459,12 @@ static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
/* HC need not update length with this error */ if (!(t & FOTG210_ISOC_BABBLE)) { - desc->actual_length = - fotg210_itdlen(urb, desc, t); + desc->actual_length = FOTG210_ITD_LENGTH(t); urb->actual_length += desc->actual_length; } } else if (likely((t & FOTG210_ISOC_ACTIVE) == 0)) { desc->status = 0; - desc->actual_length = fotg210_itdlen(urb, desc, t); + desc->actual_length = FOTG210_ITD_LENGTH(t); urb->actual_length += desc->actual_length; } else { /* URB was too late */ diff --git a/drivers/usb/host/fotg210.h b/drivers/usb/host/fotg210.h index 6cee40ec65b4..67f59517ebad 100644 --- a/drivers/usb/host/fotg210.h +++ b/drivers/usb/host/fotg210.h @@ -686,11 +686,6 @@ static inline unsigned fotg210_read_frame_index(struct fotg210_hcd *fotg210) return fotg210_readl(fotg210, &fotg210->regs->frame_index); }
-#define fotg210_itdlen(urb, desc, t) ({ \ - usb_pipein((urb)->pipe) ? \ - (desc)->length - FOTG210_ITD_LENGTH(t) : \ - FOTG210_ITD_LENGTH(t); \ -}) /*-------------------------------------------------------------------------*/
#endif /* __LINUX_FOTG210_H */
From: Maciej Żenczykowski maze@google.com
[ Upstream commit 8ae01239609b29ec2eff55967c8e0fe3650cfa09 ]
f_ncm tx timeout can call us with null skb to flush a pending frame. In this case skb is NULL to begin with but ceases to be null after dev->wrap() completes.
In such a case in->maxpacket will be read, even though we've failed to check that 'in' is not NULL.
Though I've never observed this fail in practice, however the 'flush operation' simply does not make sense with a null usb IN endpoint - there's nowhere to flush to... (note that we're the gadget/device, and IN is from the point of view of the host, so here IN actually means outbound...)
Cc: Brooke Basile brookebasile@gmail.com Cc: "Bryan O'Donoghue" bryan.odonoghue@linaro.org Cc: Felipe Balbi balbi@kernel.org Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Lorenzo Colitti lorenzo@google.com Signed-off-by: Maciej Żenczykowski maze@google.com Link: https://lore.kernel.org/r/20210701114834.884597-6-zenczykowski@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/function/u_ether.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index d1d044d9f859..85a3f6d4b5af 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -492,8 +492,9 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, } spin_unlock_irqrestore(&dev->lock, flags);
- if (skb && !in) { - dev_kfree_skb_any(skb); + if (!in) { + if (skb) + dev_kfree_skb_any(skb); return NETDEV_TX_OK; }
From: Evgeny Novikov novikov@ispras.ru
[ Upstream commit 61136a12cbed234374ec6f588af57c580b20b772 ]
mv_ehci_enable() did not disable and unprepare clocks in case of failures of phy_init(). Besides, it did not take into account failures of ehci_clock_enable() (in effect, failures of clk_prepare_enable()). The patch fixes both issues and gets rid of redundant wrappers around clk_prepare_enable() and clk_disable_unprepare() to simplify this a bit.
Found by Linux Driver Verification project (linuxtesting.org).
Acked-by: Alan Stern stern@rowland.harvard.edu Signed-off-by: Evgeny Novikov novikov@ispras.ru Link: https://lore.kernel.org/r/20210708083056.21543-1-novikov@ispras.ru Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/ehci-mv.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c index cffdc8d01b2a..8fd27249ad25 100644 --- a/drivers/usb/host/ehci-mv.c +++ b/drivers/usb/host/ehci-mv.c @@ -42,26 +42,25 @@ struct ehci_hcd_mv { int (*set_vbus)(unsigned int vbus); };
-static void ehci_clock_enable(struct ehci_hcd_mv *ehci_mv) +static int mv_ehci_enable(struct ehci_hcd_mv *ehci_mv) { - clk_prepare_enable(ehci_mv->clk); -} + int retval;
-static void ehci_clock_disable(struct ehci_hcd_mv *ehci_mv) -{ - clk_disable_unprepare(ehci_mv->clk); -} + retval = clk_prepare_enable(ehci_mv->clk); + if (retval) + return retval;
-static int mv_ehci_enable(struct ehci_hcd_mv *ehci_mv) -{ - ehci_clock_enable(ehci_mv); - return phy_init(ehci_mv->phy); + retval = phy_init(ehci_mv->phy); + if (retval) + clk_disable_unprepare(ehci_mv->clk); + + return retval; }
static void mv_ehci_disable(struct ehci_hcd_mv *ehci_mv) { phy_exit(ehci_mv->phy); - ehci_clock_disable(ehci_mv); + clk_disable_unprepare(ehci_mv->clk); }
static int mv_ehci_reset(struct usb_hcd *hcd)
From: Jack Pham jackp@codeaurora.org
[ Upstream commit bcacbf06c891374e7fdd7b72d11cda03b0269b43 ]
Currently the composite driver encodes the MaxPower field of the configuration descriptor by reading the c->MaxPower of the usb_configuration only if it is non-zero, otherwise it falls back to using the value hard-coded in CONFIG_USB_GADGET_VBUS_DRAW. However, there are cases when a configuration must explicitly set bMaxPower to 0, particularly if its bmAttributes also has the Self-Powered bit set, which is a valid combination.
This is specifically called out in the USB PD specification section 9.1, in which a PDUSB device "shall report zero in the bMaxPower field after negotiating a mutually agreeable Contract", and also verified by the USB Type-C Functional Test TD.4.10.2 Sink Power Precedence Test.
The fix allows the c->MaxPower to be used for encoding the bMaxPower even if it is 0, if the self-powered bit is also set. An example usage of this would be for a ConfigFS gadget to be dynamically updated by userspace when the Type-C connection is determined to be operating in Power Delivery mode.
Co-developed-by: Ronak Vijay Raheja rraheja@codeaurora.org Acked-by: Felipe Balbi balbi@kernel.org Signed-off-by: Ronak Vijay Raheja rraheja@codeaurora.org Signed-off-by: Jack Pham jackp@codeaurora.org Link: https://lore.kernel.org/r/20210720080907.30292-1-jackp@codeaurora.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/composite.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 72a9797dbbae..504c1cbc255d 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -482,7 +482,7 @@ static u8 encode_bMaxPower(enum usb_device_speed speed, { unsigned val;
- if (c->MaxPower) + if (c->MaxPower || (c->bmAttributes & USB_CONFIG_ATT_SELFPOWER)) val = c->MaxPower; else val = CONFIG_USB_GADGET_VBUS_DRAW; @@ -936,7 +936,11 @@ static int set_config(struct usb_composite_dev *cdev, }
/* when we return, be sure our power usage is valid */ - power = c->MaxPower ? c->MaxPower : CONFIG_USB_GADGET_VBUS_DRAW; + if (c->MaxPower || (c->bmAttributes & USB_CONFIG_ATT_SELFPOWER)) + power = c->MaxPower; + else + power = CONFIG_USB_GADGET_VBUS_DRAW; + if (gadget->speed < USB_SPEED_SUPER) power = min(power, 500U); else
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit df00609821bf17f50a75a446266d19adb8339d84 ]
On Armadillo-800-EVA with CONFIG_DEBUG_SPINLOCK=y:
BUG: spinlock bad magic on CPU#0, swapper/1 lock: lcdc0_device+0x10c/0x308, .magic: 00000000, .owner: <none>/-1, .owner_cpu: 0 CPU: 0 PID: 1 Comm: swapper Not tainted 5.11.0-rc5-armadillo-00036-gbbca04be7a80-dirty #287 Hardware name: Generic R8A7740 (Flattened Device Tree) [<c010c3c8>] (unwind_backtrace) from [<c010a49c>] (show_stack+0x10/0x14) [<c010a49c>] (show_stack) from [<c0159534>] (do_raw_spin_lock+0x20/0x94) [<c0159534>] (do_raw_spin_lock) from [<c040858c>] (dev_pm_get_subsys_data+0x8c/0x11c) [<c040858c>] (dev_pm_get_subsys_data) from [<c05fbcac>] (genpd_add_device+0x78/0x2b8) [<c05fbcac>] (genpd_add_device) from [<c0412db4>] (of_genpd_add_device+0x34/0x4c) [<c0412db4>] (of_genpd_add_device) from [<c0a1ea74>] (board_staging_register_device+0x11c/0x148) [<c0a1ea74>] (board_staging_register_device) from [<c0a1eac4>] (board_staging_register_devices+0x24/0x28)
of_genpd_add_device() is called before platform_device_register(), as it needs to attach the genpd before the device is probed. But the spinlock is only initialized when the device is registered.
Fix this by open-coding the spinlock initialization, cfr. device_pm_init_common() in the internal drivers/base code, and in the SuperH early platform code.
Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/57783ece7ddae55f2bda2f59f452180bff744ea0.162625739... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/board/board.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/board/board.c b/drivers/staging/board/board.c index cb6feb34dd40..f980af037345 100644 --- a/drivers/staging/board/board.c +++ b/drivers/staging/board/board.c @@ -136,6 +136,7 @@ int __init board_staging_register_clock(const struct board_staging_clk *bsc) static int board_staging_add_dev_domain(struct platform_device *pdev, const char *domain) { + struct device *dev = &pdev->dev; struct of_phandle_args pd_args; struct device_node *np;
@@ -148,7 +149,11 @@ static int board_staging_add_dev_domain(struct platform_device *pdev, pd_args.np = np; pd_args.args_count = 0;
- return of_genpd_add_device(&pd_args, &pdev->dev); + /* Initialization similar to device_pm_init_common() */ + spin_lock_init(&dev->power.lock); + dev->power.early_init = true; + + return of_genpd_add_device(&pd_args, dev); } #else static inline int board_staging_add_dev_domain(struct platform_device *pdev,
From: Mauro Carvalho Chehab mchehab+huawei@kernel.org
[ Upstream commit 334201d503d5903f38f6e804263fc291ce8f451a ]
The regex at the patternProperties is wrong, although this was not reported as the DT schema was not enforcing properties.
Fix it.
Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Link: https://lore.kernel.org/r/46b2f30df235481cb1404913380e45706dfd8253.162651586... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml b/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml index 3b23ad56b31a..ef664b4458fb 100644 --- a/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml +++ b/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml @@ -42,6 +42,8 @@ properties: regulators: type: object
+ additionalProperties: false + properties: '#address-cells': const: 1 @@ -50,11 +52,13 @@ properties: const: 0
patternProperties: - '^ldo[0-9]+@[0-9a-f]$': + '^(ldo|LDO)[0-9]+$': type: object
$ref: "/schemas/regulator/regulator.yaml#"
+ unevaluatedProperties: false + required: - compatible - reg
From: Zheyu Ma zheyuma97@gmail.com
[ Upstream commit 240e126c28df084222f0b661321e8e3ecb0d232e ]
uart_handle_dcd_change() requires a port lock to be held and will emit a warning when lockdep is enabled.
Held corresponding lock to fix the following warnings.
[ 132.528648] WARNING: CPU: 5 PID: 11600 at drivers/tty/serial/serial_core.c:3046 uart_handle_dcd_change+0xf4/0x120 [ 132.530482] Modules linked in: [ 132.531050] CPU: 5 PID: 11600 Comm: jsm Not tainted 5.14.0-rc1-00003-g7fef2edf7cc7-dirty #31 [ 132.535268] RIP: 0010:uart_handle_dcd_change+0xf4/0x120 [ 132.557100] Call Trace: [ 132.557562] ? __free_pages+0x83/0xb0 [ 132.558213] neo_parse_modem+0x156/0x220 [ 132.558897] neo_param+0x399/0x840 [ 132.559495] jsm_tty_open+0x12f/0x2d0 [ 132.560131] uart_startup.part.18+0x153/0x340 [ 132.560888] ? lock_is_held_type+0xe9/0x140 [ 132.561660] uart_port_activate+0x7f/0xe0 [ 132.562351] ? uart_startup.part.18+0x340/0x340 [ 132.563003] tty_port_open+0x8d/0xf0 [ 132.563523] ? uart_set_options+0x1e0/0x1e0 [ 132.564125] uart_open+0x24/0x40 [ 132.564604] tty_open+0x15c/0x630
Signed-off-by: Zheyu Ma zheyuma97@gmail.com Link: https://lore.kernel.org/r/1626242003-3809-1-git-send-email-zheyuma97@gmail.c... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/jsm/jsm_neo.c | 2 ++ drivers/tty/serial/jsm/jsm_tty.c | 3 +++ 2 files changed, 5 insertions(+)
diff --git a/drivers/tty/serial/jsm/jsm_neo.c b/drivers/tty/serial/jsm/jsm_neo.c index bf0e2a4cb0ce..c6f927a76c3b 100644 --- a/drivers/tty/serial/jsm/jsm_neo.c +++ b/drivers/tty/serial/jsm/jsm_neo.c @@ -815,7 +815,9 @@ static void neo_parse_isr(struct jsm_board *brd, u32 port) /* Parse any modem signal changes */ jsm_dbg(INTR, &ch->ch_bd->pci_dev, "MOD_STAT: sending to parse_modem_sigs\n"); + spin_lock_irqsave(&ch->uart_port.lock, lock_flags); neo_parse_modem(ch, readb(&ch->ch_neo_uart->msr)); + spin_unlock_irqrestore(&ch->uart_port.lock, lock_flags); } }
diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index 8e42a7682c63..d74cbbbf33c6 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c @@ -187,6 +187,7 @@ static void jsm_tty_break(struct uart_port *port, int break_state)
static int jsm_tty_open(struct uart_port *port) { + unsigned long lock_flags; struct jsm_board *brd; struct jsm_channel *channel = container_of(port, struct jsm_channel, uart_port); @@ -240,6 +241,7 @@ static int jsm_tty_open(struct uart_port *port) channel->ch_cached_lsr = 0; channel->ch_stops_sent = 0;
+ spin_lock_irqsave(&port->lock, lock_flags); termios = &port->state->port.tty->termios; channel->ch_c_cflag = termios->c_cflag; channel->ch_c_iflag = termios->c_iflag; @@ -259,6 +261,7 @@ static int jsm_tty_open(struct uart_port *port) jsm_carrier(channel);
channel->ch_open_count++; + spin_unlock_irqrestore(&port->lock, lock_flags);
jsm_dbg(OPEN, &channel->ch_bd->pci_dev, "finish\n"); return 0;
From: Laurentiu Tudor laurentiu.tudor@nxp.com
[ Upstream commit aa0a1ae020e2d24749e9f8085f12ca6d46899c94 ]
Second parameter of dprc_scan_objects() is a bool not a pointer so change from NULL to false.
Signed-off-by: Laurentiu Tudor laurentiu.tudor@nxp.com Link: https://lore.kernel.org/r/20210715140718.8513-1-laurentiu.tudor@nxp.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bus/fsl-mc/fsl-mc-bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index 380ad1fdb745..74faaf3e4e27 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -219,7 +219,7 @@ static int scan_fsl_mc_bus(struct device *dev, void *data) root_mc_dev = to_fsl_mc_device(dev); root_mc_bus = to_fsl_mc_bus(root_mc_dev); mutex_lock(&root_mc_bus->scan_mutex); - dprc_scan_objects(root_mc_dev, NULL); + dprc_scan_objects(root_mc_dev, false); mutex_unlock(&root_mc_bus->scan_mutex);
exit:
From: Laurentiu Tudor laurentiu.tudor@nxp.com
[ Upstream commit 8990f96a012f42543005b07d9e482694192e9309 ]
Some versions of the MC firmware wrongly report 0 for register base address of the DPMCP associated with child DPRC objects thus rendering them unusable. This is particularly troublesome in ACPI boot scenarios where the legacy way of extracting this base address from the device tree does not apply. Given that DPMCPs share the same base address, workaround this by using the base address extracted from the root DPRC container.
Signed-off-by: Laurentiu Tudor laurentiu.tudor@nxp.com Link: https://lore.kernel.org/r/20210715140718.8513-8-laurentiu.tudor@nxp.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bus/fsl-mc/fsl-mc-bus.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index 74faaf3e4e27..57f78d1cc9d8 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -67,6 +67,8 @@ struct fsl_mc_addr_translation_range { #define MC_FAPR_PL BIT(18) #define MC_FAPR_BMT BIT(17)
+static phys_addr_t mc_portal_base_phys_addr; + /** * fsl_mc_bus_match - device to driver matching callback * @dev: the fsl-mc device to match against @@ -702,14 +704,30 @@ static int fsl_mc_device_get_mmio_regions(struct fsl_mc_device *mc_dev, * If base address is in the region_desc use it otherwise * revert to old mechanism */ - if (region_desc.base_address) + if (region_desc.base_address) { regions[i].start = region_desc.base_address + region_desc.base_offset; - else + } else { error = translate_mc_addr(mc_dev, mc_region_type, region_desc.base_offset, ®ions[i].start);
+ /* + * Some versions of the MC firmware wrongly report + * 0 for register base address of the DPMCP associated + * with child DPRC objects thus rendering them unusable. + * This is particularly troublesome in ACPI boot + * scenarios where the legacy way of extracting this + * base address from the device tree does not apply. + * Given that DPMCPs share the same base address, + * workaround this by using the base address extracted + * from the root DPRC container. + */ + if (is_fsl_mc_bus_dprc(mc_dev) && + regions[i].start == region_desc.base_offset) + regions[i].start += mc_portal_base_phys_addr; + } + if (error < 0) { dev_err(parent_dev, "Invalid MC offset: %#x (for %s.%d's region %d)\n", @@ -1125,6 +1143,8 @@ static int fsl_mc_bus_probe(struct platform_device *pdev) plat_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); mc_portal_phys_addr = plat_res->start; mc_portal_size = resource_size(plat_res); + mc_portal_base_phys_addr = mc_portal_phys_addr & ~0x3ffffff; + error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr, mc_portal_size, NULL, FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, &mc_io);
From: Eric Auger eric.auger@redhat.com
[ Upstream commit 28b6a003bcdfa1fc4603b9185b247ecca7af9bef ]
The virtual machine monitor (QEMU) exposes the pvpanic-pci device to the guest. On guest side the module exists but currently isn't loaded automatically. So the driver fails to be probed and does not its job of handling guest panic events.
Instead of requiring manual modprobe, let's include a device database using the MODULE_DEVICE_TABLE macro and let the module auto-load when the guest gets exposed with such a pvpanic-pci device.
Signed-off-by: Eric Auger eric.auger@redhat.com Link: https://lore.kernel.org/r/20210629072214.901004-1-eric.auger@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/misc/pvpanic/pvpanic-pci.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/misc/pvpanic/pvpanic-pci.c b/drivers/misc/pvpanic/pvpanic-pci.c index 046ce4ecc195..4a3250564442 100644 --- a/drivers/misc/pvpanic/pvpanic-pci.c +++ b/drivers/misc/pvpanic/pvpanic-pci.c @@ -119,4 +119,6 @@ static struct pci_driver pvpanic_pci_driver = { }, };
+MODULE_DEVICE_TABLE(pci, pvpanic_pci_id_tbl); + module_pci_driver(pvpanic_pci_driver);
From: Shuah Khan skhan@linuxfoundation.org
[ Upstream commit fe968ca2cac91888310b143a483123c84906e3fc ]
Fix the following ingonred return val of asprintf() warn during build:
cc -Wall -O2 fw_namespace.c -o ../tools/testing/selftests/firmware/fw_namespace fw_namespace.c: In function ‘main’: fw_namespace.c:132:2: warning: ignoring return value of ‘asprintf’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 132 | asprintf(&fw_path, "/lib/firmware/%s", fw_name); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Signed-off-by: Shuah Khan skhan@linuxfoundation.org Link: https://lore.kernel.org/r/20210708031827.51293-1-skhan@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/firmware/fw_namespace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/firmware/fw_namespace.c b/tools/testing/selftests/firmware/fw_namespace.c index 0e393cb5f42d..4c6f0cd83c5b 100644 --- a/tools/testing/selftests/firmware/fw_namespace.c +++ b/tools/testing/selftests/firmware/fw_namespace.c @@ -129,7 +129,8 @@ int main(int argc, char **argv) die("mounting tmpfs to /lib/firmware failed\n");
sys_path = argv[1]; - asprintf(&fw_path, "/lib/firmware/%s", fw_name); + if (asprintf(&fw_path, "/lib/firmware/%s", fw_name) < 0) + die("error: failed to build full fw_path\n");
setup_fw(fw_path);
From: Oliver Logush oliver.logush@amd.com
[ Upstream commit 23e55639b87fb16a9f0f66032ecb57060df6c46c ]
[why] The units of the time_per_pixel variable were incorrect, this had to be changed for the code to properly function.
[how] The change was very straightforward, only required one line of code to be changed where the calculation was done.
Acked-by: Rodrigo Siqueira Rodrigo.Siqueira@amd.com Signed-off-by: Oliver Logush oliver.logush@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index 81f583733fa8..12e92f620483 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -2461,7 +2461,7 @@ void dcn20_set_mcif_arb_params( wb_arb_params->cli_watermark[k] = get_wm_writeback_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; wb_arb_params->pstate_watermark[k] = get_wm_writeback_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; } - wb_arb_params->time_per_pixel = 16.0 / context->res_ctx.pipe_ctx[i].stream->phy_pix_clk; /* 4 bit fraction, ms */ + wb_arb_params->time_per_pixel = 16.0 * 1000 / (context->res_ctx.pipe_ctx[i].stream->phy_pix_clk / 1000); /* 4 bit fraction, ms */ wb_arb_params->slice_lines = 32; wb_arb_params->arbitration_slice = 2; wb_arb_params->max_scaled_time = dcn20_calc_max_scaled_time(wb_arb_params->time_per_pixel,
From: Ezequiel Garcia ezequiel@collabora.com
[ Upstream commit 6ad61a7847da09b6261824accb539d05bcdfef65 ]
When the VP8 decoders can't find a reference frame, the driver falls back to the current output frame.
This will probably produce some undesirable results, leading to frame corruption, but shouldn't cause noisy warnings.
Signed-off-by: Ezequiel Garcia ezequiel@collabora.com Acked-by: Nicolas Dufresne nicolas.dufresne@collabora.com Tested-by: Alex Bee knaerzche@gmail.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/media/hantro/hantro_g1_vp8_dec.c | 13 ++++++++++--- .../staging/media/hantro/rk3399_vpu_hw_vp8_dec.c | 13 ++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/drivers/staging/media/hantro/hantro_g1_vp8_dec.c b/drivers/staging/media/hantro/hantro_g1_vp8_dec.c index 57002ba70176..3cd90637ac63 100644 --- a/drivers/staging/media/hantro/hantro_g1_vp8_dec.c +++ b/drivers/staging/media/hantro/hantro_g1_vp8_dec.c @@ -376,12 +376,17 @@ static void cfg_ref(struct hantro_ctx *ctx, vb2_dst = hantro_get_dst_buf(ctx);
ref = hantro_get_ref(ctx, hdr->last_frame_ts); - if (!ref) + if (!ref) { + vpu_debug(0, "failed to find last frame ts=%llu\n", + hdr->last_frame_ts); ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0); + } vdpu_write_relaxed(vpu, ref, G1_REG_ADDR_REF(0));
ref = hantro_get_ref(ctx, hdr->golden_frame_ts); - WARN_ON(!ref && hdr->golden_frame_ts); + if (!ref && hdr->golden_frame_ts) + vpu_debug(0, "failed to find golden frame ts=%llu\n", + hdr->golden_frame_ts); if (!ref) ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0); if (hdr->flags & V4L2_VP8_FRAME_FLAG_SIGN_BIAS_GOLDEN) @@ -389,7 +394,9 @@ static void cfg_ref(struct hantro_ctx *ctx, vdpu_write_relaxed(vpu, ref, G1_REG_ADDR_REF(4));
ref = hantro_get_ref(ctx, hdr->alt_frame_ts); - WARN_ON(!ref && hdr->alt_frame_ts); + if (!ref && hdr->alt_frame_ts) + vpu_debug(0, "failed to find alt frame ts=%llu\n", + hdr->alt_frame_ts); if (!ref) ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0); if (hdr->flags & V4L2_VP8_FRAME_FLAG_SIGN_BIAS_ALT) diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c index 8661a3cc1e6b..361619201605 100644 --- a/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c +++ b/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c @@ -453,12 +453,17 @@ static void cfg_ref(struct hantro_ctx *ctx, vb2_dst = hantro_get_dst_buf(ctx);
ref = hantro_get_ref(ctx, hdr->last_frame_ts); - if (!ref) + if (!ref) { + vpu_debug(0, "failed to find last frame ts=%llu\n", + hdr->last_frame_ts); ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0); + } vdpu_write_relaxed(vpu, ref, VDPU_REG_VP8_ADDR_REF0);
ref = hantro_get_ref(ctx, hdr->golden_frame_ts); - WARN_ON(!ref && hdr->golden_frame_ts); + if (!ref && hdr->golden_frame_ts) + vpu_debug(0, "failed to find golden frame ts=%llu\n", + hdr->golden_frame_ts); if (!ref) ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0); if (hdr->flags & V4L2_VP8_FRAME_FLAG_SIGN_BIAS_GOLDEN) @@ -466,7 +471,9 @@ static void cfg_ref(struct hantro_ctx *ctx, vdpu_write_relaxed(vpu, ref, VDPU_REG_VP8_ADDR_REF2_5(2));
ref = hantro_get_ref(ctx, hdr->alt_frame_ts); - WARN_ON(!ref && hdr->alt_frame_ts); + if (!ref && hdr->alt_frame_ts) + vpu_debug(0, "failed to find alt frame ts=%llu\n", + hdr->alt_frame_ts); if (!ref) ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0); if (hdr->flags & V4L2_VP8_FRAME_FLAG_SIGN_BIAS_ALT)
From: Evgeny Novikov novikov@ispras.ru
[ Upstream commit 055d2db28ec2fa3ab5c527c5604f1b32b89fa13a ]
stm32_cec_probe() did not unprepare clocks on error handling paths. The patch fixes that.
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Evgeny Novikov novikov@ispras.ru Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/cec/platform/stm32/stm32-cec.c | 26 ++++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/drivers/media/cec/platform/stm32/stm32-cec.c b/drivers/media/cec/platform/stm32/stm32-cec.c index ea4b1ebfca99..0ffd89712536 100644 --- a/drivers/media/cec/platform/stm32/stm32-cec.c +++ b/drivers/media/cec/platform/stm32/stm32-cec.c @@ -305,14 +305,16 @@ static int stm32_cec_probe(struct platform_device *pdev)
cec->clk_hdmi_cec = devm_clk_get(&pdev->dev, "hdmi-cec"); if (IS_ERR(cec->clk_hdmi_cec) && - PTR_ERR(cec->clk_hdmi_cec) == -EPROBE_DEFER) - return -EPROBE_DEFER; + PTR_ERR(cec->clk_hdmi_cec) == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto err_unprepare_cec_clk; + }
if (!IS_ERR(cec->clk_hdmi_cec)) { ret = clk_prepare(cec->clk_hdmi_cec); if (ret) { dev_err(&pdev->dev, "Can't prepare hdmi-cec clock\n"); - return ret; + goto err_unprepare_cec_clk; } }
@@ -324,19 +326,27 @@ static int stm32_cec_probe(struct platform_device *pdev) CEC_NAME, caps, CEC_MAX_LOG_ADDRS); ret = PTR_ERR_OR_ZERO(cec->adap); if (ret) - return ret; + goto err_unprepare_hdmi_cec_clk;
ret = cec_register_adapter(cec->adap, &pdev->dev); - if (ret) { - cec_delete_adapter(cec->adap); - return ret; - } + if (ret) + goto err_delete_adapter;
cec_hw_init(cec);
platform_set_drvdata(pdev, cec);
return 0; + +err_delete_adapter: + cec_delete_adapter(cec->adap); + +err_unprepare_hdmi_cec_clk: + clk_unprepare(cec->clk_hdmi_cec); + +err_unprepare_cec_clk: + clk_unprepare(cec->clk_cec); + return ret; }
static int stm32_cec_remove(struct platform_device *pdev)
From: Dinghao Liu dinghao.liu@zju.edu.cn
[ Upstream commit 672fe1cf145ab9978c62eb827d6a16aa6b63994b ]
When hmm_pool_register() fails, a pairing PM usage counter increment is needed to keep the counter balanced. It's the same for the following error paths.
Link: https://lore.kernel.org/linux-media/20210408081850.24278-1-dinghao.liu@zju.e... Signed-off-by: Dinghao Liu dinghao.liu@zju.edu.cn Acked-by: Andy Shevchenko andy.shevchenko@gmail.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/media/atomisp/pci/atomisp_v4l2.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index 0295e2e32d79..02f774ed80c8 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -1815,6 +1815,7 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i hmm_cleanup(); hmm_pool_unregister(HMM_POOL_TYPE_RESERVED); hmm_pool_fail: + pm_runtime_get_noresume(&pdev->dev); destroy_workqueue(isp->wdt_work_queue); wdt_work_queue_fail: atomisp_acc_cleanup(isp);
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit d14e272958bdfdc40dcafb827d24ba6fdafa9d52 ]
If init_atomisp_wdts() fails, atomisp_pci_probe() need return error code.
Link: https://lore.kernel.org/linux-media/20210617072329.1233662-1-yangyingliang@h... Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/media/atomisp/pci/atomisp_v4l2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index 02f774ed80c8..fa1bd99cd6f1 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -1763,7 +1763,8 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i if (err < 0) goto register_entities_fail; /* init atomisp wdts */ - if (init_atomisp_wdts(isp) != 0) + err = init_atomisp_wdts(isp); + if (err != 0) goto wdt_work_queue_fail;
/* save the iunit context only once after all the values are init'ed. */
From: Niklas Söderlund niklas.soderlund@corigine.com
[ Upstream commit 4431531c482a2c05126caaa9fcc5053a4a5c495b ]
The return type of the function is bool and while NULL do evaluate to false it's not very nice, fix this by explicitly returning false. There is no functional change.
Signed-off-by: Niklas Söderlund niklas.soderlund@corigine.com Signed-off-by: Louis Peens louis.peens@corigine.com Signed-off-by: Simon Horman simon.horman@corigine.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c index eeb30680b4dc..0a0a26376bea 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c @@ -1697,7 +1697,7 @@ nfp_net_parse_meta(struct net_device *netdev, struct nfp_meta_parsed *meta, case NFP_NET_META_RESYNC_INFO: if (nfp_net_tls_rx_resync_req(netdev, data, pkt, pkt_len)) - return NULL; + return false; data += sizeof(struct nfp_net_tls_resync_req); break; default:
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit dd98d2895de6485c884a9cb42de69fed02826fa4 ]
The ethtool compat ioctl handling is hidden away in net/socket.c, which introduces a couple of minor oddities:
- The implementation may end up diverging, as seen in the RXNFC extension in commit 84a1d9c48200 ("net: ethtool: extend RXNFC API to support RSS spreading of filter matches") that does not work in compat mode.
- Most architectures do not need the compat handling at all because u64 and compat_u64 have the same alignment.
- On x86, the conversion is done for both x32 and i386 user space, but it's actually wrong to do it for x32 and cannot work there.
- On 32-bit Arm, it never worked for compat oabi user space, since that needs to do the same conversion but does not.
- It would be nice to get rid of both compat_alloc_user_space() and copy_in_user() throughout the kernel.
None of these actually seems to be a serious problem that real users are likely to encounter, but fixing all of them actually leads to code that is both shorter and more readable.
Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/ethtool.h | 4 -- net/ethtool/ioctl.c | 136 +++++++++++++++++++++++++++++++++++----- net/socket.c | 125 +----------------------------------- 3 files changed, 121 insertions(+), 144 deletions(-)
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index e030f7510cd3..b21a553e2e06 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -17,8 +17,6 @@ #include <linux/compat.h> #include <uapi/linux/ethtool.h>
-#ifdef CONFIG_COMPAT - struct compat_ethtool_rx_flow_spec { u32 flow_type; union ethtool_flow_union h_u; @@ -38,8 +36,6 @@ struct compat_ethtool_rxnfc { u32 rule_locs[]; };
-#endif /* CONFIG_COMPAT */ - #include <linux/rculist.h>
/** diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c index baa5d10043cb..6134b180f59f 100644 --- a/net/ethtool/ioctl.c +++ b/net/ethtool/ioctl.c @@ -7,6 +7,7 @@ * the information ethtool needs. */
+#include <linux/compat.h> #include <linux/module.h> #include <linux/types.h> #include <linux/capability.h> @@ -807,6 +808,120 @@ static noinline_for_stack int ethtool_get_sset_info(struct net_device *dev, return ret; }
+static noinline_for_stack int +ethtool_rxnfc_copy_from_compat(struct ethtool_rxnfc *rxnfc, + const struct compat_ethtool_rxnfc __user *useraddr, + size_t size) +{ + struct compat_ethtool_rxnfc crxnfc = {}; + + /* We expect there to be holes between fs.m_ext and + * fs.ring_cookie and at the end of fs, but nowhere else. + * On non-x86, no conversion should be needed. + */ + BUILD_BUG_ON(!IS_ENABLED(CONFIG_X86_64) && + sizeof(struct compat_ethtool_rxnfc) != + sizeof(struct ethtool_rxnfc)); + BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_ext) + + sizeof(useraddr->fs.m_ext) != + offsetof(struct ethtool_rxnfc, fs.m_ext) + + sizeof(rxnfc->fs.m_ext)); + BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.location) - + offsetof(struct compat_ethtool_rxnfc, fs.ring_cookie) != + offsetof(struct ethtool_rxnfc, fs.location) - + offsetof(struct ethtool_rxnfc, fs.ring_cookie)); + + if (copy_from_user(&crxnfc, useraddr, min(size, sizeof(crxnfc)))) + return -EFAULT; + + *rxnfc = (struct ethtool_rxnfc) { + .cmd = crxnfc.cmd, + .flow_type = crxnfc.flow_type, + .data = crxnfc.data, + .fs = { + .flow_type = crxnfc.fs.flow_type, + .h_u = crxnfc.fs.h_u, + .h_ext = crxnfc.fs.h_ext, + .m_u = crxnfc.fs.m_u, + .m_ext = crxnfc.fs.m_ext, + .ring_cookie = crxnfc.fs.ring_cookie, + .location = crxnfc.fs.location, + }, + .rule_cnt = crxnfc.rule_cnt, + }; + + return 0; +} + +static int ethtool_rxnfc_copy_from_user(struct ethtool_rxnfc *rxnfc, + const void __user *useraddr, + size_t size) +{ + if (compat_need_64bit_alignment_fixup()) + return ethtool_rxnfc_copy_from_compat(rxnfc, useraddr, size); + + if (copy_from_user(rxnfc, useraddr, size)) + return -EFAULT; + + return 0; +} + +static int ethtool_rxnfc_copy_to_compat(void __user *useraddr, + const struct ethtool_rxnfc *rxnfc, + size_t size, const u32 *rule_buf) +{ + struct compat_ethtool_rxnfc crxnfc; + + memset(&crxnfc, 0, sizeof(crxnfc)); + crxnfc = (struct compat_ethtool_rxnfc) { + .cmd = rxnfc->cmd, + .flow_type = rxnfc->flow_type, + .data = rxnfc->data, + .fs = { + .flow_type = rxnfc->fs.flow_type, + .h_u = rxnfc->fs.h_u, + .h_ext = rxnfc->fs.h_ext, + .m_u = rxnfc->fs.m_u, + .m_ext = rxnfc->fs.m_ext, + .ring_cookie = rxnfc->fs.ring_cookie, + .location = rxnfc->fs.location, + }, + .rule_cnt = rxnfc->rule_cnt, + }; + + if (copy_to_user(useraddr, &crxnfc, min(size, sizeof(crxnfc)))) + return -EFAULT; + + return 0; +} + +static int ethtool_rxnfc_copy_to_user(void __user *useraddr, + const struct ethtool_rxnfc *rxnfc, + size_t size, const u32 *rule_buf) +{ + int ret; + + if (compat_need_64bit_alignment_fixup()) { + ret = ethtool_rxnfc_copy_to_compat(useraddr, rxnfc, size, + rule_buf); + useraddr += offsetof(struct compat_ethtool_rxnfc, rule_locs); + } else { + ret = copy_to_user(useraddr, &rxnfc, size); + useraddr += offsetof(struct ethtool_rxnfc, rule_locs); + } + + if (ret) + return -EFAULT; + + if (rule_buf) { + if (copy_to_user(useraddr, rule_buf, + rxnfc->rule_cnt * sizeof(u32))) + return -EFAULT; + } + + return 0; +} + static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev, u32 cmd, void __user *useraddr) { @@ -825,7 +940,7 @@ static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev, info_size = (offsetof(struct ethtool_rxnfc, data) + sizeof(info.data));
- if (copy_from_user(&info, useraddr, info_size)) + if (ethtool_rxnfc_copy_from_user(&info, useraddr, info_size)) return -EFAULT;
rc = dev->ethtool_ops->set_rxnfc(dev, &info); @@ -833,7 +948,7 @@ static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev, return rc;
if (cmd == ETHTOOL_SRXCLSRLINS && - copy_to_user(useraddr, &info, info_size)) + ethtool_rxnfc_copy_to_user(useraddr, &info, info_size, NULL)) return -EFAULT;
return 0; @@ -859,7 +974,7 @@ static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev, info_size = (offsetof(struct ethtool_rxnfc, data) + sizeof(info.data));
- if (copy_from_user(&info, useraddr, info_size)) + if (ethtool_rxnfc_copy_from_user(&info, useraddr, info_size)) return -EFAULT;
/* If FLOW_RSS was requested then user-space must be using the @@ -867,7 +982,7 @@ static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev, */ if (cmd == ETHTOOL_GRXFH && info.flow_type & FLOW_RSS) { info_size = sizeof(info); - if (copy_from_user(&info, useraddr, info_size)) + if (ethtool_rxnfc_copy_from_user(&info, useraddr, info_size)) return -EFAULT; /* Since malicious users may modify the original data, * we need to check whether FLOW_RSS is still requested. @@ -893,18 +1008,7 @@ static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev, if (ret < 0) goto err_out;
- ret = -EFAULT; - if (copy_to_user(useraddr, &info, info_size)) - goto err_out; - - if (rule_buf) { - useraddr += offsetof(struct ethtool_rxnfc, rule_locs); - if (copy_to_user(useraddr, rule_buf, - info.rule_cnt * sizeof(u32))) - goto err_out; - } - ret = 0; - + ret = ethtool_rxnfc_copy_to_user(useraddr, &info, info_size, rule_buf); err_out: kfree(rule_buf);
diff --git a/net/socket.c b/net/socket.c index 877f1fb61719..caac290ba7ec 100644 --- a/net/socket.c +++ b/net/socket.c @@ -3099,128 +3099,6 @@ static int compat_dev_ifconf(struct net *net, struct compat_ifconf __user *uifc3 return 0; }
-static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) -{ - struct compat_ethtool_rxnfc __user *compat_rxnfc; - bool convert_in = false, convert_out = false; - size_t buf_size = 0; - struct ethtool_rxnfc __user *rxnfc = NULL; - struct ifreq ifr; - u32 rule_cnt = 0, actual_rule_cnt; - u32 ethcmd; - u32 data; - int ret; - - if (get_user(data, &ifr32->ifr_ifru.ifru_data)) - return -EFAULT; - - compat_rxnfc = compat_ptr(data); - - if (get_user(ethcmd, &compat_rxnfc->cmd)) - return -EFAULT; - - /* Most ethtool structures are defined without padding. - * Unfortunately struct ethtool_rxnfc is an exception. - */ - switch (ethcmd) { - default: - break; - case ETHTOOL_GRXCLSRLALL: - /* Buffer size is variable */ - if (get_user(rule_cnt, &compat_rxnfc->rule_cnt)) - return -EFAULT; - if (rule_cnt > KMALLOC_MAX_SIZE / sizeof(u32)) - return -ENOMEM; - buf_size += rule_cnt * sizeof(u32); - fallthrough; - case ETHTOOL_GRXRINGS: - case ETHTOOL_GRXCLSRLCNT: - case ETHTOOL_GRXCLSRULE: - case ETHTOOL_SRXCLSRLINS: - convert_out = true; - fallthrough; - case ETHTOOL_SRXCLSRLDEL: - buf_size += sizeof(struct ethtool_rxnfc); - convert_in = true; - rxnfc = compat_alloc_user_space(buf_size); - break; - } - - if (copy_from_user(&ifr.ifr_name, &ifr32->ifr_name, IFNAMSIZ)) - return -EFAULT; - - ifr.ifr_data = convert_in ? rxnfc : (void __user *)compat_rxnfc; - - if (convert_in) { - /* We expect there to be holes between fs.m_ext and - * fs.ring_cookie and at the end of fs, but nowhere else. - */ - BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_ext) + - sizeof(compat_rxnfc->fs.m_ext) != - offsetof(struct ethtool_rxnfc, fs.m_ext) + - sizeof(rxnfc->fs.m_ext)); - BUILD_BUG_ON( - offsetof(struct compat_ethtool_rxnfc, fs.location) - - offsetof(struct compat_ethtool_rxnfc, fs.ring_cookie) != - offsetof(struct ethtool_rxnfc, fs.location) - - offsetof(struct ethtool_rxnfc, fs.ring_cookie)); - - if (copy_in_user(rxnfc, compat_rxnfc, - (void __user *)(&rxnfc->fs.m_ext + 1) - - (void __user *)rxnfc) || - copy_in_user(&rxnfc->fs.ring_cookie, - &compat_rxnfc->fs.ring_cookie, - (void __user *)(&rxnfc->fs.location + 1) - - (void __user *)&rxnfc->fs.ring_cookie)) - return -EFAULT; - if (ethcmd == ETHTOOL_GRXCLSRLALL) { - if (put_user(rule_cnt, &rxnfc->rule_cnt)) - return -EFAULT; - } else if (copy_in_user(&rxnfc->rule_cnt, - &compat_rxnfc->rule_cnt, - sizeof(rxnfc->rule_cnt))) - return -EFAULT; - } - - ret = dev_ioctl(net, SIOCETHTOOL, &ifr, NULL); - if (ret) - return ret; - - if (convert_out) { - if (copy_in_user(compat_rxnfc, rxnfc, - (const void __user *)(&rxnfc->fs.m_ext + 1) - - (const void __user *)rxnfc) || - copy_in_user(&compat_rxnfc->fs.ring_cookie, - &rxnfc->fs.ring_cookie, - (const void __user *)(&rxnfc->fs.location + 1) - - (const void __user *)&rxnfc->fs.ring_cookie) || - copy_in_user(&compat_rxnfc->rule_cnt, &rxnfc->rule_cnt, - sizeof(rxnfc->rule_cnt))) - return -EFAULT; - - if (ethcmd == ETHTOOL_GRXCLSRLALL) { - /* As an optimisation, we only copy the actual - * number of rules that the underlying - * function returned. Since Mallory might - * change the rule count in user memory, we - * check that it is less than the rule count - * originally given (as the user buffer size), - * which has been range-checked. - */ - if (get_user(actual_rule_cnt, &rxnfc->rule_cnt)) - return -EFAULT; - if (actual_rule_cnt < rule_cnt) - rule_cnt = actual_rule_cnt; - if (copy_in_user(&compat_rxnfc->rule_locs[0], - &rxnfc->rule_locs[0], - rule_cnt * sizeof(u32))) - return -EFAULT; - } - } - - return 0; -} - static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32) { compat_uptr_t uptr32; @@ -3377,8 +3255,6 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock, return old_bridge_ioctl(argp); case SIOCGIFCONF: return compat_dev_ifconf(net, argp); - case SIOCETHTOOL: - return ethtool_ioctl(net, argp); case SIOCWANDEV: return compat_siocwandev(net, argp); case SIOCGIFMAP: @@ -3391,6 +3267,7 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock, return sock->ops->gettstamp(sock, argp, cmd == SIOCGSTAMP_OLD, !COMPAT_USE_64BIT_TIME);
+ case SIOCETHTOOL: case SIOCBONDSLAVEINFOQUERY: case SIOCBONDINFOQUERY: case SIOCSHWTSTAMP:
From: Oak Zeng Oak.Zeng@amd.com
[ Upstream commit 95f71f12aa45d65b7f2ccab95569795edffd379a ]
The printing message "PSP loading VCN firmware" is mis-leading because people might think driver is loading VCN firmware. Actually when this message is printed, driver is just preparing some VCN ucode, not loading VCN firmware yet. The actual VCN firmware loading will be in the PSP block hw_init. Fix the printing message
Signed-off-by: Oak Zeng Oak.Zeng@amd.com Reviewed-by: Christian Konig christian.koenig@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 2 +- drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index 27b1ced145d2..14ae2bfad59d 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c @@ -119,7 +119,7 @@ static int vcn_v1_0_sw_init(void *handle) adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].fw = adev->vcn.fw; adev->firmware.fw_size += ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE); - DRM_INFO("PSP loading VCN firmware\n"); + dev_info(adev->dev, "Will use PSP to load VCN firmware\n"); }
r = amdgpu_vcn_resume(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c index 8af567c546db..f4686e918e0d 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c @@ -122,7 +122,7 @@ static int vcn_v2_0_sw_init(void *handle) adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].fw = adev->vcn.fw; adev->firmware.fw_size += ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE); - DRM_INFO("PSP loading VCN firmware\n"); + dev_info(adev->dev, "Will use PSP to load VCN firmware\n"); }
r = amdgpu_vcn_resume(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c index 888b17d84691..e0c0c3734432 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c @@ -152,7 +152,7 @@ static int vcn_v2_5_sw_init(void *handle) adev->firmware.fw_size += ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE); } - DRM_INFO("PSP loading VCN firmware\n"); + dev_info(adev->dev, "Will use PSP to load VCN firmware\n"); }
r = amdgpu_vcn_resume(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c index 3b23de996db2..c2c5c4af51d2 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c @@ -152,7 +152,7 @@ static int vcn_v3_0_sw_init(void *handle) adev->firmware.fw_size += ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE); } - DRM_INFO("PSP loading VCN firmware\n"); + dev_info(adev->dev, "Will use PSP to load VCN firmware\n"); }
r = amdgpu_vcn_resume(adev);
From: Anson Jacob Anson.Jacob@amd.com
[ Upstream commit 1a394b3c3de2577f200cb623c52a5c2b82805cec ]
link_rate is updated via debugfs using hex values, set it to output in hex as well.
eg: Resolution: 1920x1080@144Hz cat /sys/kernel/debug/dri/0/DP-1/link_settings Current: 4 0x14 0 Verified: 4 0x1e 0 Reported: 4 0x1e 16 Preferred: 0 0x0 0
echo "4 0x1e" > /sys/kernel/debug/dri/0/DP-1/link_settings
cat /sys/kernel/debug/dri/0/DP-1/link_settings Current: 4 0x1e 0 Verified: 4 0x1e 0 Reported: 4 0x1e 16 Preferred: 4 0x1e 0
Signed-off-by: Anson Jacob Anson.Jacob@amd.com Reviewed-by: Harry Wentland harry.wentland@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index 1b6b15708b96..08ff1166ffc8 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -197,29 +197,29 @@ static ssize_t dp_link_settings_read(struct file *f, char __user *buf,
rd_buf_ptr = rd_buf;
- str_len = strlen("Current: %d %d %d "); - snprintf(rd_buf_ptr, str_len, "Current: %d %d %d ", + str_len = strlen("Current: %d 0x%x %d "); + snprintf(rd_buf_ptr, str_len, "Current: %d 0x%x %d ", link->cur_link_settings.lane_count, link->cur_link_settings.link_rate, link->cur_link_settings.link_spread); rd_buf_ptr += str_len;
- str_len = strlen("Verified: %d %d %d "); - snprintf(rd_buf_ptr, str_len, "Verified: %d %d %d ", + str_len = strlen("Verified: %d 0x%x %d "); + snprintf(rd_buf_ptr, str_len, "Verified: %d 0x%x %d ", link->verified_link_cap.lane_count, link->verified_link_cap.link_rate, link->verified_link_cap.link_spread); rd_buf_ptr += str_len;
- str_len = strlen("Reported: %d %d %d "); - snprintf(rd_buf_ptr, str_len, "Reported: %d %d %d ", + str_len = strlen("Reported: %d 0x%x %d "); + snprintf(rd_buf_ptr, str_len, "Reported: %d 0x%x %d ", link->reported_link_cap.lane_count, link->reported_link_cap.link_rate, link->reported_link_cap.link_spread); rd_buf_ptr += str_len;
- str_len = strlen("Preferred: %d %d %d "); - snprintf(rd_buf_ptr, str_len, "Preferred: %d %d %d\n", + str_len = strlen("Preferred: %d 0x%x %d "); + snprintf(rd_buf_ptr, str_len, "Preferred: %d 0x%x %d\n", link->preferred_link_setting.lane_count, link->preferred_link_setting.link_rate, link->preferred_link_setting.link_spread);
From: Johan Almbladh johan.almbladh@anyfinetworks.com
[ Upstream commit ae7f47041d928b1a2f28717d095b4153c63cbf6a ]
This test now operates on DW as stated instead of W, which was already covered by another test.
Signed-off-by: Johan Almbladh johan.almbladh@anyfinetworks.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20210721104058.3755254-1-johan.almbladh@anyfinet... Signed-off-by: Sasha Levin sashal@kernel.org --- lib/test_bpf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/test_bpf.c b/lib/test_bpf.c index 4dc4dcbecd12..f826df50355b 100644 --- a/lib/test_bpf.c +++ b/lib/test_bpf.c @@ -4286,8 +4286,8 @@ static struct bpf_test tests[] = { .u.insns_int = { BPF_LD_IMM64(R0, 0), BPF_LD_IMM64(R1, 0xffffffffffffffffLL), - BPF_STX_MEM(BPF_W, R10, R1, -40), - BPF_LDX_MEM(BPF_W, R0, R10, -40), + BPF_STX_MEM(BPF_DW, R10, R1, -40), + BPF_LDX_MEM(BPF_DW, R0, R10, -40), BPF_EXIT_INSN(), }, INTERNAL,
From: Johan Almbladh johan.almbladh@anyfinetworks.com
[ Upstream commit 2b7e9f25e590726cca76700ebdb10e92a7a72ca1 ]
Each test case can have a set of sub-tests, where each sub-test can run the cBPF/eBPF test snippet with its own data_size and expected result. Before, the end of the sub-test array was indicated by both data_size and result being zero. However, most or all of the internal eBPF tests has a data_size of zero already. When such a test also had an expected value of zero, the test was never run but reported as PASS anyway.
Now the test runner always runs the first sub-test, regardless of the data_size and result values. The sub-test array zero-termination only applies for any additional sub-tests.
There are other ways fix it of course, but this solution at least removes the surprise of eBPF tests with a zero result always succeeding.
Signed-off-by: Johan Almbladh johan.almbladh@anyfinetworks.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20210721103822.3755111-1-johan.almbladh@anyfinet... Signed-off-by: Sasha Levin sashal@kernel.org --- lib/test_bpf.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/lib/test_bpf.c b/lib/test_bpf.c index f826df50355b..acf825d81671 100644 --- a/lib/test_bpf.c +++ b/lib/test_bpf.c @@ -6659,7 +6659,14 @@ static int run_one(const struct bpf_prog *fp, struct bpf_test *test) u64 duration; u32 ret;
- if (test->test[i].data_size == 0 && + /* + * NOTE: Several sub-tests may be present, in which case + * a zero {data_size, result} tuple indicates the end of + * the sub-test array. The first test is always run, + * even if both data_size and result happen to be zero. + */ + if (i > 0 && + test->test[i].data_size == 0 && test->test[i].result == 0) break;
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 47956bc86ee4e8530cac386a04f62a6095f7afbe ]
As nwl_dsi.lanes is u32, and NSEC_PER_SEC is 1000000000L, the second multiplication in
dsi->lanes * 8 * NSEC_PER_SEC
will overflow on a 32-bit platform. Fix this by making the constant unsigned long long, forcing 64-bit arithmetic.
As iMX8 is arm64, this driver is currently used on 64-bit platforms only, where long is 64-bit, so this cannot happen. But the issue will start to happen when the driver is reused for a 32-bit SoC (e.g. i.MX7ULP), or when code is copied for a new driver.
Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: Fabio Estevam festevam@gmail.com Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Sam Ravnborg sam@ravnborg.org Link: https://patchwork.freedesktop.org/patch/msgid/ebb82941a86b4e35c4fcfb1ef5a5cf... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/nwl-dsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c index c65ca860712d..6cac2e58cd15 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -196,7 +196,7 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps) u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
return DIV64_U64_ROUND_UP(ps * dsi->mode.clock * bpp, - dsi->lanes * 8 * NSEC_PER_SEC); + dsi->lanes * 8ULL * NSEC_PER_SEC); }
/*
From: Jernej Skrabec jernej.skrabec@gmail.com
[ Upstream commit 7ab1f6539762946de06ca14d7401ae123821bc40 ]
Regulator node names don't reflect class of the device. Fix that by prefixing names with "regulator-".
Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Signed-off-by: Maxime Ripard maxime@cerno.tech Link: https://lore.kernel.org/r/20210722161220.51181-2-jernej.skrabec@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts index be81330db14f..02641191682e 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts @@ -32,14 +32,14 @@ hdmi_con_in: endpoint { }; };
- reg_vcc3v3: vcc3v3 { + reg_vcc3v3: regulator-vcc3v3 { compatible = "regulator-fixed"; regulator-name = "vcc3v3"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; };
- reg_vdd_cpu_gpu: vdd-cpu-gpu { + reg_vdd_cpu_gpu: regulator-vdd-cpu-gpu { compatible = "regulator-fixed"; regulator-name = "vdd-cpu-gpu"; regulator-min-microvolt = <1135000>;
From: Zheyu Ma zheyuma97@gmail.com
[ Upstream commit b36b242d4b8ea178f7fd038965e3cac7f30c3f09 ]
The userspace program could pass any values to the driver through ioctl() interface. If the driver doesn't check the value of 'pixclock', it may cause divide error.
Fix this by checking whether 'pixclock' is zero first.
The following log reveals it:
[ 43.861711] divide error: 0000 [#1] PREEMPT SMP KASAN PTI [ 43.861737] CPU: 2 PID: 11764 Comm: i740 Not tainted 5.14.0-rc2-00513-gac532c9bbcfb-dirty #224 [ 43.861756] RIP: 0010:asiliantfb_check_var+0x4e/0x730 [ 43.861843] Call Trace: [ 43.861848] ? asiliantfb_remove+0x190/0x190 [ 43.861858] fb_set_var+0x2e4/0xeb0 [ 43.861866] ? fb_blank+0x1a0/0x1a0 [ 43.861873] ? lock_acquire+0x1ef/0x530 [ 43.861884] ? lock_release+0x810/0x810 [ 43.861892] ? lock_is_held_type+0x100/0x140 [ 43.861903] ? ___might_sleep+0x1ee/0x2d0 [ 43.861914] ? __mutex_lock+0x620/0x1190 [ 43.861921] ? do_fb_ioctl+0x313/0x700 [ 43.861929] ? mutex_lock_io_nested+0xfa0/0xfa0 [ 43.861936] ? __this_cpu_preempt_check+0x1d/0x30 [ 43.861944] ? _raw_spin_unlock_irqrestore+0x46/0x60 [ 43.861952] ? lockdep_hardirqs_on+0x59/0x100 [ 43.861959] ? _raw_spin_unlock_irqrestore+0x46/0x60 [ 43.861967] ? trace_hardirqs_on+0x6a/0x1c0 [ 43.861978] do_fb_ioctl+0x31e/0x700
Signed-off-by: Zheyu Ma zheyuma97@gmail.com Signed-off-by: Sam Ravnborg sam@ravnborg.org Link: https://patchwork.freedesktop.org/patch/msgid/1627293835-17441-2-git-send-em... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/video/fbdev/asiliantfb.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/video/fbdev/asiliantfb.c b/drivers/video/fbdev/asiliantfb.c index 3e006da47752..84c56f525889 100644 --- a/drivers/video/fbdev/asiliantfb.c +++ b/drivers/video/fbdev/asiliantfb.c @@ -227,6 +227,9 @@ static int asiliantfb_check_var(struct fb_var_screeninfo *var, { unsigned long Ftarget, ratio, remainder;
+ if (!var->pixclock) + return -EINVAL; + ratio = 1000000 / var->pixclock; remainder = 1000000 % var->pixclock; Ftarget = 1000000 * ratio + (1000000 * remainder) / var->pixclock;
From: Zheyu Ma zheyuma97@gmail.com
[ Upstream commit 1520b4b7ba964f8eec2e7dd14c571d50de3e5191 ]
The userspace program could pass any values to the driver through ioctl() interface. if the driver doesn't check the value of 'pixclock', it may cause divide error because the value of 'lineclock' and 'frameclock' will be zero.
Fix this by checking whether 'pixclock' is zero in kyrofb_check_var().
The following log reveals it:
[ 103.073930] divide error: 0000 [#1] PREEMPT SMP KASAN PTI [ 103.073942] CPU: 4 PID: 12483 Comm: syz-executor Not tainted 5.14.0-rc2-00478-g2734d6c1b1a0-dirty #118 [ 103.073959] RIP: 0010:kyrofb_set_par+0x316/0xc80 [ 103.074045] Call Trace: [ 103.074048] ? ___might_sleep+0x1ee/0x2d0 [ 103.074060] ? kyrofb_ioctl+0x330/0x330 [ 103.074069] fb_set_var+0x5bf/0xeb0 [ 103.074078] ? fb_blank+0x1a0/0x1a0 [ 103.074085] ? lock_acquire+0x3bd/0x530 [ 103.074094] ? lock_release+0x810/0x810 [ 103.074103] ? ___might_sleep+0x1ee/0x2d0 [ 103.074114] ? __mutex_lock+0x620/0x1190 [ 103.074126] ? trace_hardirqs_on+0x6a/0x1c0 [ 103.074137] do_fb_ioctl+0x31e/0x700 [ 103.074144] ? fb_getput_cmap+0x280/0x280 [ 103.074152] ? rcu_read_lock_sched_held+0x11/0x80 [ 103.074162] ? rcu_read_lock_sched_held+0x11/0x80 [ 103.074171] ? __sanitizer_cov_trace_switch+0x67/0xf0 [ 103.074181] ? __sanitizer_cov_trace_const_cmp2+0x20/0x80 [ 103.074191] ? do_vfs_ioctl+0x14b/0x16c0 [ 103.074199] ? vfs_fileattr_set+0xb60/0xb60 [ 103.074207] ? rcu_read_lock_sched_held+0x11/0x80 [ 103.074216] ? lock_release+0x483/0x810 [ 103.074224] ? __fget_files+0x217/0x3d0 [ 103.074234] ? __fget_files+0x239/0x3d0 [ 103.074243] ? do_fb_ioctl+0x700/0x700 [ 103.074250] fb_ioctl+0xe6/0x130
Signed-off-by: Zheyu Ma zheyuma97@gmail.com Signed-off-by: Sam Ravnborg sam@ravnborg.org Link: https://patchwork.freedesktop.org/patch/msgid/1627293835-17441-3-git-send-em... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/video/fbdev/kyro/fbdev.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/video/fbdev/kyro/fbdev.c b/drivers/video/fbdev/kyro/fbdev.c index 4b8c7c16b1df..25801e8e3f74 100644 --- a/drivers/video/fbdev/kyro/fbdev.c +++ b/drivers/video/fbdev/kyro/fbdev.c @@ -399,6 +399,9 @@ static int kyrofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { struct kyrofb_info *par = info->par;
+ if (!var->pixclock) + return -EINVAL; + if (var->bits_per_pixel != 16 && var->bits_per_pixel != 32) { printk(KERN_WARNING "kyrofb: depth not supported: %u\n", var->bits_per_pixel); return -EINVAL;
From: Zheyu Ma zheyuma97@gmail.com
[ Upstream commit f92763cb0feba247e0939ed137b495601fd072a5 ]
The userspace program could pass any values to the driver through ioctl() interface. If the driver doesn't check the value of 'pixclock', it may cause divide error.
Fix this by checking whether 'pixclock' is zero first.
The following log reveals it:
[ 33.396850] divide error: 0000 [#1] PREEMPT SMP KASAN PTI [ 33.396864] CPU: 5 PID: 11754 Comm: i740 Not tainted 5.14.0-rc2-00513-gac532c9bbcfb-dirty #222 [ 33.396883] RIP: 0010:riva_load_video_mode+0x417/0xf70 [ 33.396969] Call Trace: [ 33.396973] ? debug_smp_processor_id+0x1c/0x20 [ 33.396984] ? tick_nohz_tick_stopped+0x1a/0x90 [ 33.396996] ? rivafb_copyarea+0x3c0/0x3c0 [ 33.397003] ? wake_up_klogd.part.0+0x99/0xd0 [ 33.397014] ? vprintk_emit+0x110/0x4b0 [ 33.397024] ? vprintk_default+0x26/0x30 [ 33.397033] ? vprintk+0x9c/0x1f0 [ 33.397041] ? printk+0xba/0xed [ 33.397054] ? record_print_text.cold+0x16/0x16 [ 33.397063] ? __kasan_check_read+0x11/0x20 [ 33.397074] ? profile_tick+0xc0/0x100 [ 33.397084] ? __sanitizer_cov_trace_const_cmp4+0x24/0x80 [ 33.397094] ? riva_set_rop_solid+0x2a0/0x2a0 [ 33.397102] rivafb_set_par+0xbe/0x610 [ 33.397111] ? riva_set_rop_solid+0x2a0/0x2a0 [ 33.397119] fb_set_var+0x5bf/0xeb0 [ 33.397127] ? fb_blank+0x1a0/0x1a0 [ 33.397134] ? lock_acquire+0x1ef/0x530 [ 33.397143] ? lock_release+0x810/0x810 [ 33.397151] ? lock_is_held_type+0x100/0x140 [ 33.397159] ? ___might_sleep+0x1ee/0x2d0 [ 33.397170] ? __mutex_lock+0x620/0x1190 [ 33.397180] ? trace_hardirqs_on+0x6a/0x1c0 [ 33.397190] do_fb_ioctl+0x31e/0x700
Signed-off-by: Zheyu Ma zheyuma97@gmail.com Signed-off-by: Sam Ravnborg sam@ravnborg.org Link: https://patchwork.freedesktop.org/patch/msgid/1627293835-17441-4-git-send-em... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/video/fbdev/riva/fbdev.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/video/fbdev/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c index 55554b0433cb..84d5e23ad7d3 100644 --- a/drivers/video/fbdev/riva/fbdev.c +++ b/drivers/video/fbdev/riva/fbdev.c @@ -1084,6 +1084,9 @@ static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) int mode_valid = 0; NVTRACE_ENTER(); + if (!var->pixclock) + return -EINVAL; + switch (var->bits_per_pixel) { case 1 ... 8: var->red.offset = var->green.offset = var->blue.offset = 0;
From: Alex Elder elder@linaro.org
[ Upstream commit f2c1dac0abcfa93e8b20065b8d6b4b2b6f9990aa ]
Stop supporting different sizes for hashed and non-hashed filter or route tables. Add BUILD_BUG_ON() calls to verify the sizes of the fields in the filter/route table initialization immediate command are the same.
Add a check to ipa_cmd_table_valid() to ensure the size of the memory region being checked fits within the immediate command field that must hold it.
Remove two Boolean parameters used only for error reporting. This actually fixes a bug that would only show up if IPA_VALIDATE were defined. Define ipa_cmd_table_valid() unconditionally (no longer dependent on IPA_VALIDATE).
Signed-off-by: Alex Elder elder@linaro.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ipa/ipa_cmd.c | 38 ++++++++++++++++++++++++------------- drivers/net/ipa/ipa_cmd.h | 15 +++------------ drivers/net/ipa/ipa_table.c | 2 +- 3 files changed, 29 insertions(+), 26 deletions(-)
diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c index 525cdf28d9ea..1e43748dcb40 100644 --- a/drivers/net/ipa/ipa_cmd.c +++ b/drivers/net/ipa/ipa_cmd.c @@ -159,35 +159,45 @@ static void ipa_cmd_validate_build(void) BUILD_BUG_ON(TABLE_SIZE > field_max(IP_FLTRT_FLAGS_NHASH_SIZE_FMASK)); #undef TABLE_COUNT_MAX #undef TABLE_SIZE -}
-#ifdef IPA_VALIDATE + /* Hashed and non-hashed fields are assumed to be the same size */ + BUILD_BUG_ON(field_max(IP_FLTRT_FLAGS_HASH_SIZE_FMASK) != + field_max(IP_FLTRT_FLAGS_NHASH_SIZE_FMASK)); + BUILD_BUG_ON(field_max(IP_FLTRT_FLAGS_HASH_ADDR_FMASK) != + field_max(IP_FLTRT_FLAGS_NHASH_ADDR_FMASK)); +}
/* Validate a memory region holding a table */ -bool ipa_cmd_table_valid(struct ipa *ipa, const struct ipa_mem *mem, - bool route, bool ipv6, bool hashed) +bool ipa_cmd_table_valid(struct ipa *ipa, const struct ipa_mem *mem, bool route) { + u32 offset_max = field_max(IP_FLTRT_FLAGS_NHASH_ADDR_FMASK); + u32 size_max = field_max(IP_FLTRT_FLAGS_NHASH_SIZE_FMASK); + const char *table = route ? "route" : "filter"; struct device *dev = &ipa->pdev->dev; - u32 offset_max;
- offset_max = hashed ? field_max(IP_FLTRT_FLAGS_HASH_ADDR_FMASK) - : field_max(IP_FLTRT_FLAGS_NHASH_ADDR_FMASK); + /* Size must fit in the immediate command field that holds it */ + if (mem->size > size_max) { + dev_err(dev, "%s table region size too large\n", table); + dev_err(dev, " (0x%04x > 0x%04x)\n", + mem->size, size_max); + + return false; + } + + /* Offset must fit in the immediate command field that holds it */ if (mem->offset > offset_max || ipa->mem_offset > offset_max - mem->offset) { - dev_err(dev, "IPv%c %s%s table region offset too large\n", - ipv6 ? '6' : '4', hashed ? "hashed " : "", - route ? "route" : "filter"); + dev_err(dev, "%s table region offset too large\n", table); dev_err(dev, " (0x%04x + 0x%04x > 0x%04x)\n", ipa->mem_offset, mem->offset, offset_max);
return false; }
+ /* Entire memory range must fit within IPA-local memory */ if (mem->offset > ipa->mem_size || mem->size > ipa->mem_size - mem->offset) { - dev_err(dev, "IPv%c %s%s table region out of range\n", - ipv6 ? '6' : '4', hashed ? "hashed " : "", - route ? "route" : "filter"); + dev_err(dev, "%s table region out of range\n", table); dev_err(dev, " (0x%04x + 0x%04x > 0x%04x)\n", mem->offset, mem->size, ipa->mem_size);
@@ -197,6 +207,8 @@ bool ipa_cmd_table_valid(struct ipa *ipa, const struct ipa_mem *mem, return true; }
+#ifdef IPA_VALIDATE + /* Validate the memory region that holds headers */ static bool ipa_cmd_header_valid(struct ipa *ipa) { diff --git a/drivers/net/ipa/ipa_cmd.h b/drivers/net/ipa/ipa_cmd.h index b99262281f41..ea723419c826 100644 --- a/drivers/net/ipa/ipa_cmd.h +++ b/drivers/net/ipa/ipa_cmd.h @@ -57,20 +57,18 @@ struct ipa_cmd_info { enum dma_data_direction direction; };
-#ifdef IPA_VALIDATE - /** * ipa_cmd_table_valid() - Validate a memory region holding a table * @ipa: - IPA pointer * @mem: - IPA memory region descriptor * @route: - Whether the region holds a route or filter table - * @ipv6: - Whether the table is for IPv6 or IPv4 - * @hashed: - Whether the table is hashed or non-hashed * * Return: true if region is valid, false otherwise */ bool ipa_cmd_table_valid(struct ipa *ipa, const struct ipa_mem *mem, - bool route, bool ipv6, bool hashed); + bool route); + +#ifdef IPA_VALIDATE
/** * ipa_cmd_data_valid() - Validate command-realted configuration is valid @@ -82,13 +80,6 @@ bool ipa_cmd_data_valid(struct ipa *ipa);
#else /* !IPA_VALIDATE */
-static inline bool ipa_cmd_table_valid(struct ipa *ipa, - const struct ipa_mem *mem, bool route, - bool ipv6, bool hashed) -{ - return true; -} - static inline bool ipa_cmd_data_valid(struct ipa *ipa) { return true; diff --git a/drivers/net/ipa/ipa_table.c b/drivers/net/ipa/ipa_table.c index 3168d72f4245..618a84cf669a 100644 --- a/drivers/net/ipa/ipa_table.c +++ b/drivers/net/ipa/ipa_table.c @@ -174,7 +174,7 @@ ipa_table_valid_one(struct ipa *ipa, bool route, bool ipv6, bool hashed) size = (1 + IPA_FILTER_COUNT_MAX) * sizeof(__le64); }
- if (!ipa_cmd_table_valid(ipa, mem, route, ipv6, hashed)) + if (!ipa_cmd_table_valid(ipa, mem, route)) return false;
/* mem->size >= size is sufficient, but we'll demand more */
From: Gustavo A. R. Silva gustavoars@kernel.org
[ Upstream commit 6321c7acb82872ef6576c520b0e178eaad3a25c0 ]
Fix the following out-of-bounds warning:
In function 'ip_copy_addrs', inlined from '__ip_queue_xmit' at net/ipv4/ip_output.c:517:2: net/ipv4/ip_output.c:449:2: warning: 'memcpy' offset [40, 43] from the object at 'fl' is out of the bounds of referenced subobject 'saddr' with type 'unsigned int' at offset 36 [-Warray-bounds] 449 | memcpy(&iph->saddr, &fl4->saddr, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 450 | sizeof(fl4->saddr) + sizeof(fl4->daddr)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The problem is that the original code is trying to copy data into a couple of struct members adjacent to each other in a single call to memcpy(). This causes a legitimate compiler warning because memcpy() overruns the length of &iph->saddr and &fl4->saddr. As these are just a couple of struct members, fix this by using direct assignments, instead of memcpy().
This helps with the ongoing efforts to globally enable -Warray-bounds and get us closer to being able to tighten the FORTIFY_SOURCE routines on memcpy().
Link: https://github.com/KSPP/linux/issues/109 Reported-by: kernel test robot lkp@intel.com Link: https://lore.kernel.org/lkml/d5ae2e65-1f18-2577-246f-bada7eee6ccd@intel.com/ Signed-off-by: Gustavo A. R. Silva gustavoars@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/ip_output.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 8d8a8da3ae7e..a202dcec0dc2 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -446,8 +446,9 @@ static void ip_copy_addrs(struct iphdr *iph, const struct flowi4 *fl4) { BUILD_BUG_ON(offsetof(typeof(*fl4), daddr) != offsetof(typeof(*fl4), saddr) + sizeof(fl4->saddr)); - memcpy(&iph->saddr, &fl4->saddr, - sizeof(fl4->saddr) + sizeof(fl4->daddr)); + + iph->saddr = fl4->saddr; + iph->daddr = fl4->daddr; }
/* Note: skb->sk can be different from sk, in case of tunnels */
From: Gustavo A. R. Silva gustavoars@kernel.org
[ Upstream commit 323e0cb473e2a8706ff162b6b4f4fa16023c9ba7 ]
Fix the following out-of-bounds warnings:
net/core/flow_dissector.c: In function '__skb_flow_dissect':
net/core/flow_dissector.c:1104:4: warning: 'memcpy' offset [24, 39] from the object at '<unknown>' is out of the bounds of referenced subobject 'saddr' with type 'struct in6_addr' at offset 8 [-Warray-bounds]
1104 | memcpy(&key_addrs->v6addrs, &iph->saddr, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1105 | sizeof(key_addrs->v6addrs)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from include/linux/ipv6.h:5, from net/core/flow_dissector.c:6: include/uapi/linux/ipv6.h:133:18: note: subobject 'saddr' declared here 133 | struct in6_addr saddr; | ^~~~~
net/core/flow_dissector.c:1059:4: warning: 'memcpy' offset [16, 19] from the object at '<unknown>' is out of the bounds of referenced subobject 'saddr' with type 'unsigned int' at offset 12 [-Warray-bounds]
1059 | memcpy(&key_addrs->v4addrs, &iph->saddr, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1060 | sizeof(key_addrs->v4addrs)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from include/linux/ip.h:17, from net/core/flow_dissector.c:5: include/uapi/linux/ip.h:103:9: note: subobject 'saddr' declared here 103 | __be32 saddr; | ^~~~~
The problem is that the original code is trying to copy data into a couple of struct members adjacent to each other in a single call to memcpy(). So, the compiler legitimately complains about it. As these are just a couple of members, fix this by copying each one of them in separate calls to memcpy().
This helps with the ongoing efforts to globally enable -Warray-bounds and get us closer to being able to tighten the FORTIFY_SOURCE routines on memcpy().
Link: https://github.com/KSPP/linux/issues/109 Reported-by: kernel test robot lkp@intel.com Link: https://lore.kernel.org/lkml/d5ae2e65-1f18-2577-246f-bada7eee6ccd@intel.com/ Signed-off-by: Gustavo A. R. Silva gustavoars@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/flow_dissector.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 3ed7c98a98e1..6076c75706d0 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -1056,8 +1056,10 @@ bool __skb_flow_dissect(const struct net *net, FLOW_DISSECTOR_KEY_IPV4_ADDRS, target_container);
- memcpy(&key_addrs->v4addrs, &iph->saddr, - sizeof(key_addrs->v4addrs)); + memcpy(&key_addrs->v4addrs.src, &iph->saddr, + sizeof(key_addrs->v4addrs.src)); + memcpy(&key_addrs->v4addrs.dst, &iph->daddr, + sizeof(key_addrs->v4addrs.dst)); key_control->addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; }
@@ -1101,8 +1103,10 @@ bool __skb_flow_dissect(const struct net *net, FLOW_DISSECTOR_KEY_IPV6_ADDRS, target_container);
- memcpy(&key_addrs->v6addrs, &iph->saddr, - sizeof(key_addrs->v6addrs)); + memcpy(&key_addrs->v6addrs.src, &iph->saddr, + sizeof(key_addrs->v6addrs.src)); + memcpy(&key_addrs->v6addrs.dst, &iph->daddr, + sizeof(key_addrs->v6addrs.dst)); key_control->addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; }
From: Heiko Carstens hca@linux.ibm.com
[ Upstream commit 5492886c14744d239e87f1b0b774b5a341e755cc ]
In case of a jump label print the real address of the piece of code where a mismatch was detected. This is right before the system panics, so there is nothing revealed.
Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/kernel/jump_label.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/s390/kernel/jump_label.c b/arch/s390/kernel/jump_label.c index ab584e8e3527..9156653b56f6 100644 --- a/arch/s390/kernel/jump_label.c +++ b/arch/s390/kernel/jump_label.c @@ -36,7 +36,7 @@ static void jump_label_bug(struct jump_entry *entry, struct insn *expected, unsigned char *ipe = (unsigned char *)expected; unsigned char *ipn = (unsigned char *)new;
- pr_emerg("Jump label code mismatch at %pS [%p]\n", ipc, ipc); + pr_emerg("Jump label code mismatch at %pS [%px]\n", ipc, ipc); pr_emerg("Found: %6ph\n", ipc); pr_emerg("Expected: %6ph\n", ipe); pr_emerg("New: %6ph\n", ipn);
From: Niklas Schnelle schnelle@linux.ibm.com
[ Upstream commit 3322ba0d7bea1e24ae464418626f6a15b69533ab ]
Kernel support for the newer PCI mio instructions can be toggled off with the pci=nomio command line option which needs to integrate with common code PCI option parsing. However this option then toggles static branches which can't be toggled yet in an early_param() call.
Thus commit 9964f396f1d0 ("s390: fix setting of mio addressing control") moved toggling the static branches to the PCI init routine.
With this setup however we can't check for mio support outside the PCI code during early boot, i.e. before switching the static branches, which we need to be able to export this as an ELF HWCAP.
Improve on this by turning mio availability into a machine flag that gets initially set based on CONFIG_PCI and the facility bit and gets toggled off if pci=nomio is found during PCI option parsing allowing simple access to this machine flag after early init.
Reviewed-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Niklas Schnelle schnelle@linux.ibm.com Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/include/asm/setup.h | 2 ++ arch/s390/kernel/early.c | 4 ++++ arch/s390/pci/pci.c | 5 ++--- 3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index 3e388fa208d4..519d517fedf4 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h @@ -36,6 +36,7 @@ #define MACHINE_FLAG_NX BIT(15) #define MACHINE_FLAG_GS BIT(16) #define MACHINE_FLAG_SCC BIT(17) +#define MACHINE_FLAG_PCI_MIO BIT(18)
#define LPP_MAGIC BIT(31) #define LPP_PID_MASK _AC(0xffffffff, UL) @@ -109,6 +110,7 @@ extern unsigned long mio_wb_bit_mask; #define MACHINE_HAS_NX (S390_lowcore.machine_flags & MACHINE_FLAG_NX) #define MACHINE_HAS_GS (S390_lowcore.machine_flags & MACHINE_FLAG_GS) #define MACHINE_HAS_SCC (S390_lowcore.machine_flags & MACHINE_FLAG_SCC) +#define MACHINE_HAS_PCI_MIO (S390_lowcore.machine_flags & MACHINE_FLAG_PCI_MIO)
/* * Console mode. Override with conmode= diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index a361d2e70025..661585587cbe 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -236,6 +236,10 @@ static __init void detect_machine_facilities(void) clock_comparator_max = -1ULL >> 1; __ctl_set_bit(0, 53); } + if (IS_ENABLED(CONFIG_PCI) && test_facility(153)) { + S390_lowcore.machine_flags |= MACHINE_FLAG_PCI_MIO; + /* the control bit is set during PCI initialization */ + } }
static inline void save_vector_registers(void) diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 77cd965cffef..34839bad33e4 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -893,7 +893,6 @@ static void zpci_mem_exit(void) }
static unsigned int s390_pci_probe __initdata = 1; -static unsigned int s390_pci_no_mio __initdata; unsigned int s390_pci_force_floating __initdata; static unsigned int s390_pci_initialized;
@@ -904,7 +903,7 @@ char * __init pcibios_setup(char *str) return NULL; } if (!strcmp(str, "nomio")) { - s390_pci_no_mio = 1; + S390_lowcore.machine_flags &= ~MACHINE_FLAG_PCI_MIO; return NULL; } if (!strcmp(str, "force_floating")) { @@ -935,7 +934,7 @@ static int __init pci_base_init(void) return 0; }
- if (test_facility(153) && !s390_pci_no_mio) { + if (MACHINE_HAS_PCI_MIO) { static_branch_enable(&have_mio); ctl_set_bit(2, 5); }
From: Maciej W. Rozycki macro@orcam.me.uk
[ Upstream commit d7aff291d069c4418285f3c8ee27b0ff67ce5998 ]
Oxford Semiconductor 950 serial port devices have a 128-byte FIFO and in the enhanced (650) mode, which we select in `autoconfig_has_efr' with the ECB bit set in the EFR register, they support the receive interrupt trigger level selectable with FCR bits 7:6 from the set of 16, 32, 112, 120. This applies to the original OX16C950 discrete UART[1] as well as 950 cores embedded into more complex devices.
For these devices we set the default to 112, which sets an excessively high level of 112 or 7/8 of the FIFO capacity, unlike with other port types where we choose at most 1/2 of their respective FIFO capacities. Additionally we don't make the trigger level configurable. Consequently frequent input overruns happen with high bit rates where hardware flow control cannot be used (e.g. terminal applications) even with otherwise highly-performant systems.
Lower the default receive interrupt trigger level to 32 then, and make it configurable. Document the trigger levels along with other port types, including the set of 16, 32, 64, 112 for the transmit interrupt as well[2].
[1] "OX16C950 rev B High Performance UART with 128 byte FIFOs", Oxford Semiconductor, Inc., DS-0031, Sep 05, Table 10: "Receiver Trigger Levels", p. 22
[2] same, Table 9: "Transmit Interrupt Trigger Levels", p. 22
Signed-off-by: Maciej W. Rozycki macro@orcam.me.uk Link: https://lore.kernel.org/r/alpine.DEB.2.21.2106260608480.37803@angie.orcam.me... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_port.c | 3 ++- include/uapi/linux/serial_reg.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 9422284bb3f3..81bafcf77bb2 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -122,7 +122,8 @@ static const struct serial8250_config uart_config[] = { .name = "16C950/954", .fifo_size = 128, .tx_loadsz = 128, - .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01, + .rxtrig_bytes = {16, 32, 112, 120}, /* UART_CAP_EFR breaks billionon CF bluetooth card. */ .flags = UART_CAP_FIFO | UART_CAP_SLEEP, }, diff --git a/include/uapi/linux/serial_reg.h b/include/uapi/linux/serial_reg.h index be07b5470f4b..f51bc8f36813 100644 --- a/include/uapi/linux/serial_reg.h +++ b/include/uapi/linux/serial_reg.h @@ -62,6 +62,7 @@ * ST16C654: 8 16 56 60 8 16 32 56 PORT_16654 * TI16C750: 1 16 32 56 xx xx xx xx PORT_16750 * TI16C752: 8 16 56 60 8 16 32 56 + * OX16C950: 16 32 112 120 16 32 64 112 PORT_16C950 * Tegra: 1 4 8 14 16 8 4 1 PORT_TEGRA */ #define UART_FCR_R_TRIG_00 0x00
From: Jiri Slaby jslaby@suse.cz
[ Upstream commit 23411c720052ad860b3e579ee4873511e367130a ]
While alloc_tty_driver failure in rs_init would mean we have much bigger problem, there is no reason to panic when tty_register_driver fails there. It can fail for various reasons.
So handle the failure gracefully. Actually handle them both while at it. This will make at least the console functional as it was enabled earlier by console_initcall in iss_console_init. Instead of shooting down the whole system.
We move tty_port_init() after alloc_tty_driver(), so that we don't need to destroy the port in case the latter function fails.
Cc: Chris Zankel chris@zankel.net Cc: Max Filippov jcmvbkbc@gmail.com Cc: linux-xtensa@linux-xtensa.org Acked-by: Max Filippov jcmvbkbc@gmail.com Signed-off-by: Jiri Slaby jslaby@suse.cz Link: https://lore.kernel.org/r/20210723074317.32690-2-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/xtensa/platforms/iss/console.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index a3dda25a4e45..eed02cf3d6b0 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c @@ -143,9 +143,13 @@ static const struct tty_operations serial_ops = {
static int __init rs_init(void) { - tty_port_init(&serial_port); + int ret;
serial_driver = alloc_tty_driver(SERIAL_MAX_NUM_LINES); + if (!serial_driver) + return -ENOMEM; + + tty_port_init(&serial_port);
/* Initialize the tty_driver structure */
@@ -163,8 +167,15 @@ static int __init rs_init(void) tty_set_operations(serial_driver, &serial_ops); tty_port_link_device(&serial_port, serial_driver, 0);
- if (tty_register_driver(serial_driver)) - panic("Couldn't register serial driver\n"); + ret = tty_register_driver(serial_driver); + if (ret) { + pr_err("Couldn't register serial driver\n"); + tty_driver_kref_put(serial_driver); + tty_port_destroy(&serial_port); + + return ret; + } + return 0; }
From: Jiri Slaby jslaby@suse.cz
[ Upstream commit 7ccbdcc4d08a6d7041e4849219bbb12ffa45db4c ]
The alloc_tty_driver failure is handled gracefully in hvsi_init. But tty_register_driver is not. panic is called if that one fails.
So handle the failure of tty_register_driver gracefully too. This will keep at least the console functional as it was enabled earlier by console_initcall in hvsi_console_init. Instead of shooting down the whole system.
This means, we disable interrupts and restore hvsi_wait back to poll_for_state().
Cc: linuxppc-dev@lists.ozlabs.org Signed-off-by: Jiri Slaby jslaby@suse.cz Link: https://lore.kernel.org/r/20210723074317.32690-3-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/hvc/hvsi.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index e8c58f9bd263..d6afaae1729a 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c @@ -1038,7 +1038,7 @@ static const struct tty_operations hvsi_ops = {
static int __init hvsi_init(void) { - int i; + int i, ret;
hvsi_driver = alloc_tty_driver(hvsi_count); if (!hvsi_driver) @@ -1069,12 +1069,25 @@ static int __init hvsi_init(void) } hvsi_wait = wait_for_state; /* irqs active now */
- if (tty_register_driver(hvsi_driver)) - panic("Couldn't register hvsi console driver\n"); + ret = tty_register_driver(hvsi_driver); + if (ret) { + pr_err("Couldn't register hvsi console driver\n"); + goto err_free_irq; + }
printk(KERN_DEBUG "HVSI: registered %i devices\n", hvsi_count);
return 0; +err_free_irq: + hvsi_wait = poll_for_state; + for (i = 0; i < hvsi_count; i++) { + struct hvsi_struct *hp = &hvsi_ports[i]; + + free_irq(hp->virq, hp); + } + tty_driver_kref_put(hvsi_driver); + + return ret; } device_initcall(hvsi_init);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
[ Upstream commit 3a96e97ab4e835078e6f27b7e1c0947814df3841 ]
The bar and offset parameters to setup_port() are used in pointer math, and while it would be very difficult to get them to wrap as a negative number, just be "safe" and make them unsigned so that static checkers do not trip over them unintentionally.
Cc: Jiri Slaby jirislaby@kernel.org Reported-by: Jordy Zomer jordy@pwning.systems Link: https://lore.kernel.org/r/20210726130717.2052096-1-gregkh@linuxfoundation.or... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 1934940b9617..2ad136dcfcc8 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -87,7 +87,7 @@ static void moan_device(const char *str, struct pci_dev *dev)
static int setup_port(struct serial_private *priv, struct uart_8250_port *port, - int bar, int offset, int regshift) + u8 bar, unsigned int offset, int regshift) { struct pci_dev *dev = priv->dev;
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 56315e55119c0ea57e142b6efb7c31208628ad86 ]
'sleep_status' has 3 atomic_t members. Initialize the 3 of them instead of initializing only 2 of them and setting 0 twice to the same variable.
Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Link: https://lore.kernel.org/r/d2e52a33a9beab41879551d0ae2fdfc99970adab.162685699... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/ks7010/ks7010_sdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/ks7010/ks7010_sdio.c b/drivers/staging/ks7010/ks7010_sdio.c index cbc0032c1604..98d759e7cc95 100644 --- a/drivers/staging/ks7010/ks7010_sdio.c +++ b/drivers/staging/ks7010/ks7010_sdio.c @@ -939,9 +939,9 @@ static void ks7010_private_init(struct ks_wlan_private *priv, memset(&priv->wstats, 0, sizeof(priv->wstats));
/* sleep mode */ + atomic_set(&priv->sleepstatus.status, 0); atomic_set(&priv->sleepstatus.doze_request, 0); atomic_set(&priv->sleepstatus.wakeup_request, 0); - atomic_set(&priv->sleepstatus.wakeup_request, 0);
trx_device_init(priv); hostif_init(priv);
From: Juhee Kang claudiajkang@gmail.com
[ Upstream commit 7d07006f05922b95518be403f08ef8437b67aa32 ]
The current behavior of 'tracex7' doesn't consist with other bpf samples tracex{1..6}. Other samples do not require any argument to run with, but tracex7 should be run with btrfs device argument. (it should be executed with test_override_return.sh)
Currently, tracex7 doesn't have any description about how to run this program and raises an unexpected error. And this result might be confusing since users might not have a hunch about how to run this program.
// Current behavior # ./tracex7 sh: 1: Syntax error: word unexpected (expecting ")") // Fixed behavior # ./tracex7 ERROR: Run with the btrfs device argument!
In order to fix this error, this commit adds logic to report a message and exit when running this program with a missing argument.
Additionally in test_override_return.sh, there is a problem with multiple directory(tmpmnt) creation. So in this commit adds a line with removing the directory with every execution.
Signed-off-by: Juhee Kang claudiajkang@gmail.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Acked-by: Yonghong Song yhs@fb.com Link: https://lore.kernel.org/bpf/20210727041056.23455-1-claudiajkang@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- samples/bpf/test_override_return.sh | 1 + samples/bpf/tracex7_user.c | 5 +++++ 2 files changed, 6 insertions(+)
diff --git a/samples/bpf/test_override_return.sh b/samples/bpf/test_override_return.sh index e68b9ee6814b..35db26f736b9 100755 --- a/samples/bpf/test_override_return.sh +++ b/samples/bpf/test_override_return.sh @@ -1,5 +1,6 @@ #!/bin/bash
+rm -r tmpmnt rm -f testfile.img dd if=/dev/zero of=testfile.img bs=1M seek=1000 count=1 DEVICE=$(losetup --show -f testfile.img) diff --git a/samples/bpf/tracex7_user.c b/samples/bpf/tracex7_user.c index fdcd6580dd73..8be7ce18d3ba 100644 --- a/samples/bpf/tracex7_user.c +++ b/samples/bpf/tracex7_user.c @@ -14,6 +14,11 @@ int main(int argc, char **argv) int ret = 0; FILE *f;
+ if (!argv[1]) { + fprintf(stderr, "ERROR: Run with the btrfs device argument!\n"); + return 0; + } + snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); obj = bpf_object__open_file(filename, NULL); if (libbpf_get_error(obj)) {
From: Martynas Pumputis m@lambda.lt
[ Upstream commit 043c5bb3c4f43670ab4fea0b847373ab42d25f3e ]
When loading in parallel multiple programs which use the same to-be pinned map, it is possible that two instances of the loader will call bpf_object__create_maps() at the same time. If the map doesn't exist when both instances call bpf_object__reuse_map(), then one of the instances will fail with EEXIST when calling bpf_map__pin().
Fix the race by retrying reusing a map if bpf_map__pin() returns EEXIST. The fix is similar to the one in iproute2: e4c4685fd6e4 ("bpf: Fix race condition with map pinning").
Before retrying the pinning, we don't do any special cleaning of an internal map state. The closer code inspection revealed that it's not required:
- bpf_object__create_map(): map->inner_map is destroyed after a successful call, map->fd is closed if pinning fails. - bpf_object__populate_internal_map(): created map elements is destroyed upon close(map->fd). - init_map_slots(): slots are freed after their initialization.
Signed-off-by: Martynas Pumputis m@lambda.lt Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20210726152001.34845-1-m@lambda.lt Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/libbpf.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index c4d36328069c..533512d933c6 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -4570,10 +4570,13 @@ bpf_object__create_maps(struct bpf_object *obj) char *cp, errmsg[STRERR_BUFSIZE]; unsigned int i, j; int err; + bool retried;
for (i = 0; i < obj->nr_maps; i++) { map = &obj->maps[i];
+ retried = false; +retry: if (map->pin_path) { err = bpf_object__reuse_map(map); if (err) { @@ -4581,6 +4584,12 @@ bpf_object__create_maps(struct bpf_object *obj) map->name); goto err_out; } + if (retried && map->fd < 0) { + pr_warn("map '%s': cannot find pinned map\n", + map->name); + err = -ENOENT; + goto err_out; + } }
if (map->fd >= 0) { @@ -4614,9 +4623,13 @@ bpf_object__create_maps(struct bpf_object *obj) if (map->pin_path && !map->pinned) { err = bpf_map__pin(map, NULL); if (err) { + zclose(map->fd); + if (!retried && err == -EEXIST) { + retried = true; + goto retry; + } pr_warn("map '%s': failed to auto-pin at '%s': %d\n", map->name, map->pin_path, err); - zclose(map->fd); goto err_out; } }
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 3ad4a31620355358316fa08fcfab37b9d6c33347 ]
Last change to device managed APIs cleaned up error path to simple phy_exit() call, which in some cases has been executed with NULL parameter. This per se is not a problem, but rather logical misconception: no need to free resource when it's for sure has not been allocated yet. Fix the driver accordingly.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Link: https://lore.kernel.org/r/20210727125130.19977-1-andriy.shevchenko@linux.int... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ata/sata_dwc_460ex.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index f0ef844428bb..338c2e50f759 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c @@ -1259,24 +1259,20 @@ static int sata_dwc_probe(struct platform_device *ofdev) irq = irq_of_parse_and_map(np, 0); if (irq == NO_IRQ) { dev_err(&ofdev->dev, "no SATA DMA irq\n"); - err = -ENODEV; - goto error_out; + return -ENODEV; }
#ifdef CONFIG_SATA_DWC_OLD_DMA if (!of_find_property(np, "dmas", NULL)) { err = sata_dwc_dma_init_old(ofdev, hsdev); if (err) - goto error_out; + return err; } #endif
hsdev->phy = devm_phy_optional_get(hsdev->dev, "sata-phy"); - if (IS_ERR(hsdev->phy)) { - err = PTR_ERR(hsdev->phy); - hsdev->phy = NULL; - goto error_out; - } + if (IS_ERR(hsdev->phy)) + return PTR_ERR(hsdev->phy);
err = phy_init(hsdev->phy); if (err)
From: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com
[ Upstream commit 015f2ebb93767d40c442e749642fffaf10316d78 ]
When the system shuts down or warm reboots, the display may be active, with the hardware accessing system memory. Upon reboot, the DDR will not be accessible, which may cause issues.
Implement the platform_driver .shutdown() operation and shut down the display to fix this.
Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com Reviewed-by: Kieran Bingham kieran.bingham+renesas@ideasonboard.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/rcar-du/rcar_du_drv.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index c22551c2facb..2a06ec1cbefb 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c @@ -559,6 +559,13 @@ static int rcar_du_remove(struct platform_device *pdev) return 0; }
+static void rcar_du_shutdown(struct platform_device *pdev) +{ + struct rcar_du_device *rcdu = platform_get_drvdata(pdev); + + drm_atomic_helper_shutdown(&rcdu->ddev); +} + static int rcar_du_probe(struct platform_device *pdev) { struct rcar_du_device *rcdu; @@ -615,6 +622,7 @@ static int rcar_du_probe(struct platform_device *pdev) static struct platform_driver rcar_du_platform_driver = { .probe = rcar_du_probe, .remove = rcar_du_remove, + .shutdown = rcar_du_shutdown, .driver = { .name = "rcar-du", .pm = &rcar_du_pm_ops,
From: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com
[ Upstream commit 92fe24a7db751b80925214ede43f8d2be792ea7b ]
Syzbot reported a corrupted list in kobject_add_internal [1]. This happens when multiple HCI_EV_SYNC_CONN_COMPLETE event packets with status 0 are sent for the same HCI connection. This causes us to register the device more than once which corrupts the kset list.
As this is forbidden behavior, we add a check for whether we're trying to process the same HCI_EV_SYNC_CONN_COMPLETE event multiple times for one connection. If that's the case, the event is invalid, so we report an error that the device is misbehaving, and ignore the packet.
Link: https://syzkaller.appspot.com/bug?extid=66264bf2fd0476be7e6c [1] Reported-by: syzbot+66264bf2fd0476be7e6c@syzkaller.appspotmail.com Tested-by: syzbot+66264bf2fd0476be7e6c@syzkaller.appspotmail.com Signed-off-by: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/hci_event.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 62c99e015609..c5de24372971 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -4373,6 +4373,21 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
switch (ev->status) { case 0x00: + /* The synchronous connection complete event should only be + * sent once per new connection. Receiving a successful + * complete event when the connection status is already + * BT_CONNECTED means that the device is misbehaving and sent + * multiple complete event packets for the same new connection. + * + * Registering the device more than once can corrupt kernel + * memory, hence upon detecting this invalid event, we report + * an error and ignore the packet. + */ + if (conn->state == BT_CONNECTED) { + bt_dev_err(hdev, "Ignoring connect complete event for existing connection"); + goto unlock; + } + conn->handle = __le16_to_cpu(ev->handle); conn->state = BT_CONNECTED; conn->type = ev->link_type;
From: Zhen Lei thunder.leizhen@huawei.com
[ Upstream commit f728c4a9e8405caae69d4bc1232c54ff57b5d20f ]
In error handling branch "if (WARN_ON(node == NUMA_NO_NODE))", the previously allocated memories are not released. Doing this before allocating memory eliminates memory leaks.
tj: Note that the condition only occurs when the arch code is pretty broken and the WARN_ON might as well be BUG_ON().
Signed-off-by: Zhen Lei thunder.leizhen@huawei.com Reviewed-by: Lai Jiangshan jiangshanlai@gmail.com Signed-off-by: Tejun Heo tj@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/workqueue.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index f148eacda55a..542c2d03dab6 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -5902,6 +5902,13 @@ static void __init wq_numa_init(void) return; }
+ for_each_possible_cpu(cpu) { + if (WARN_ON(cpu_to_node(cpu) == NUMA_NO_NODE)) { + pr_warn("workqueue: NUMA node mapping not available for cpu%d, disabling NUMA support\n", cpu); + return; + } + } + wq_update_unbound_numa_attrs_buf = alloc_workqueue_attrs(); BUG_ON(!wq_update_unbound_numa_attrs_buf);
@@ -5919,11 +5926,6 @@ static void __init wq_numa_init(void)
for_each_possible_cpu(cpu) { node = cpu_to_node(cpu); - if (WARN_ON(node == NUMA_NO_NODE)) { - pr_warn("workqueue: NUMA node mapping not available for cpu%d, disabling NUMA support\n", cpu); - /* happens iff arch is bonkers, let's just proceed */ - return; - } cpumask_set_cpu(cpu, tbl[node]); }
From: Marek Vasut marex@denx.de
[ Upstream commit a79e78c391dc074742c855dc0108a88f781d56a3 ]
Fix the following dtbs_check warning: arch/arm/boot/dts/stm32mp157c-dhcom-pdk2.dt.yaml: codec@a: port:endpoint@0:frame-master: True is not of type 'array' arch/arm/boot/dts/stm32mp157c-dhcom-pdk2.dt.yaml: codec@a: port:endpoint@0:bitclock-master: True is not of type 'array'
Signed-off-by: Marek Vasut marex@denx.de Cc: Alexandre Torgue alexandre.torgue@foss.st.com Cc: Patrice Chotard patrice.chotard@foss.st.com Cc: Patrick Delaunay patrick.delaunay@foss.st.com Cc: kernel@dh-electronics.com Cc: linux-stm32@st-md-mailman.stormreply.com To: linux-arm-kernel@lists.infradead.org Signed-off-by: Alexandre Torgue alexandre.torgue@foss.st.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi index 6cf1c8b4c6e2..c9577ba2973d 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi @@ -172,15 +172,15 @@ sgtl5000_port: port { sgtl5000_tx_endpoint: endpoint@0 { reg = <0>; remote-endpoint = <&sai2a_endpoint>; - frame-master; - bitclock-master; + frame-master = <&sgtl5000_tx_endpoint>; + bitclock-master = <&sgtl5000_tx_endpoint>; };
sgtl5000_rx_endpoint: endpoint@1 { reg = <1>; remote-endpoint = <&sai2b_endpoint>; - frame-master; - bitclock-master; + frame-master = <&sgtl5000_rx_endpoint>; + bitclock-master = <&sgtl5000_rx_endpoint>; }; };
From: Marek Vasut marex@denx.de
[ Upstream commit 8aec45d7884f16cc21d668693c5b88bff8df0f02 ]
Fix the following dtbs_check warning: cs42l51@4a: port:endpoint@0:frame-master: True is not of type 'array' cs42l51@4a: port:endpoint@0:bitclock-master: True is not of type 'array'
Signed-off-by: Marek Vasut marex@denx.de Cc: Alexandre Torgue alexandre.torgue@foss.st.com Cc: Patrice Chotard patrice.chotard@foss.st.com Cc: Patrick Delaunay patrick.delaunay@foss.st.com Cc: linux-stm32@st-md-mailman.stormreply.com To: linux-arm-kernel@lists.infradead.org Signed-off-by: Alexandre Torgue alexandre.torgue@foss.st.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/stm32mp15xx-dkx.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi index 59f18846cf5d..586aac8a998c 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi @@ -220,15 +220,15 @@ cs42l51_port: port { cs42l51_tx_endpoint: endpoint@0 { reg = <0>; remote-endpoint = <&sai2a_endpoint>; - frame-master; - bitclock-master; + frame-master = <&cs42l51_tx_endpoint>; + bitclock-master = <&cs42l51_tx_endpoint>; };
cs42l51_rx_endpoint: endpoint@1 { reg = <1>; remote-endpoint = <&sai2b_endpoint>; - frame-master; - bitclock-master; + frame-master = <&cs42l51_rx_endpoint>; + bitclock-master = <&cs42l51_rx_endpoint>; }; }; };
From: Marek Vasut marex@denx.de
[ Upstream commit 1e6bc5987a5252948e3411e5a2dbb434fd1ea107 ]
Swap reg and reg-names order and drop adi,input-justification and adi,input-style to fix the following dtbs_check warnings: arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dt.yaml: hdmi-transmitter@3d: adi,input-justification: False schema does not allow ['evenly'] arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dt.yaml: hdmi-transmitter@3d: adi,input-style: False schema does not allow [[1]] arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dt.yaml: hdmi-transmitter@3d: reg-names:1: 'edid' was expected arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dt.yaml: hdmi-transmitter@3d: reg-names:2: 'cec' was expected
Signed-off-by: Marek Vasut marex@denx.de Cc: Alexandre Torgue alexandre.torgue@foss.st.com Cc: Patrice Chotard patrice.chotard@foss.st.com Cc: Patrick Delaunay patrick.delaunay@foss.st.com Cc: linux-stm32@st-md-mailman.stormreply.com To: linux-arm-kernel@lists.infradead.org Signed-off-by: Alexandre Torgue alexandre.torgue@foss.st.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi index 64dca5b7f748..6885948f3024 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi @@ -220,8 +220,8 @@ &i2c2 { /* X6 I2C2 */ &i2c4 { hdmi-transmitter@3d { compatible = "adi,adv7513"; - reg = <0x3d>, <0x2d>, <0x4d>, <0x5d>; - reg-names = "main", "cec", "edid", "packet"; + reg = <0x3d>, <0x4d>, <0x2d>, <0x5d>; + reg-names = "main", "edid", "cec", "packet"; clocks = <&cec_clock>; clock-names = "cec";
@@ -239,8 +239,6 @@ hdmi-transmitter@3d { adi,input-depth = <8>; adi,input-colorspace = "rgb"; adi,input-clock = "1x"; - adi,input-style = <1>; - adi,input-justification = "evenly";
ports { #address-cells = <1>;
From: Pablo Neira Ayuso pablo@netfilter.org
[ Upstream commit 241d1af4c11a75d4c17ecc0193a6ab60553efbfc ]
Use nfnetlink_unicast() which already translates EAGAIN to ENOBUFS, since EAGAIN is reserved to report missing module dependencies to the nfnetlink core.
e0241ae6ac59 ("netfilter: use nfnetlink_unicast() forgot to update this spot.
Reported-by: Yajun Deng yajun.deng@linux.dev Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/netfilter/nft_compat.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c index 5415ab14400d..31e6da30da5f 100644 --- a/net/netfilter/nft_compat.c +++ b/net/netfilter/nft_compat.c @@ -680,14 +680,12 @@ static int nfnl_compat_get_rcu(struct sk_buff *skb, goto out_put; }
- ret = netlink_unicast(info->sk, skb2, NETLINK_CB(skb).portid, - MSG_DONTWAIT); - if (ret > 0) - ret = 0; + ret = nfnetlink_unicast(skb2, info->net, NETLINK_CB(skb).portid); out_put: rcu_read_lock(); module_put(THIS_MODULE); - return ret == -EAGAIN ? -ENOBUFS : ret; + + return ret; }
static const struct nla_policy nfnl_compat_policy_get[NFTA_COMPAT_MAX+1] = {
From: Yufeng Mo moyufeng@huawei.com
[ Upstream commit 220ade77452c15ecb1ab94c3f8aaeb6d033c3582 ]
Some time ago, I reported a calltrace issue "did not find a suitable aggregator", please see[1]. After a period of analysis and reproduction, I find that this problem is caused by concurrency.
Before the problem occurs, the bond structure is like follows:
bond0 - slaver0(eth0) - agg0.lag_ports -> port0 - port1 \ port0 \ slaver1(eth1) - agg1.lag_ports -> NULL \ port1
If we run 'ifenslave bond0 -d eth1', the process is like below:
excuting __bond_release_one() | bond_upper_dev_unlink()[step1] | | | | | bond_3ad_lacpdu_recv() | | ->bond_3ad_rx_indication() | | spin_lock_bh() | | ->ad_rx_machine() | | ->__record_pdu()[step2] | | spin_unlock_bh() | | | | bond_3ad_state_machine_handler() | spin_lock_bh() | ->ad_port_selection_logic() | ->try to find free aggregator[step3] | ->try to find suitable aggregator[step4] | ->did not find a suitable aggregator[step5] | spin_unlock_bh() | | | | bond_3ad_unbind_slave() | spin_lock_bh() spin_unlock_bh()
step1: already removed slaver1(eth1) from list, but port1 remains step2: receive a lacpdu and update port0 step3: port0 will be removed from agg0.lag_ports. The struct is "agg0.lag_ports -> port1" now, and agg0 is not free. At the same time, slaver1/agg1 has been removed from the list by step1. So we can't find a free aggregator now. step4: can't find suitable aggregator because of step2 step5: cause a calltrace since port->aggregator is NULL
To solve this concurrency problem, put bond_upper_dev_unlink() after bond_3ad_unbind_slave(). In this way, we can invalid the port first and skip this port in bond_3ad_state_machine_handler(). This eliminates the situation that the slaver has been removed from the list but the port is still valid.
[1]https://lore.kernel.org/netdev/10374.1611947473@famine/
Signed-off-by: Yufeng Mo moyufeng@huawei.com Acked-by: Jay Vosburgh jay.vosburgh@canonical.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/bonding/bond_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 9a184c99fbe4..3476ef223736 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2245,7 +2245,6 @@ static int __bond_release_one(struct net_device *bond_dev, /* recompute stats just before removing the slave */ bond_get_stats(bond->dev, &bond->bond_stats);
- bond_upper_dev_unlink(bond, slave); /* unregister rx_handler early so bond_handle_frame wouldn't be called * for this slave anymore. */ @@ -2254,6 +2253,8 @@ static int __bond_release_one(struct net_device *bond_dev, if (BOND_MODE(bond) == BOND_MODE_8023AD) bond_3ad_unbind_slave(slave);
+ bond_upper_dev_unlink(bond, slave); + if (bond_mode_can_use_xmit_hash(bond)) bond_update_slave_arr(bond, slave);
From: Nicolas Ferre nicolas.ferre@microchip.com
[ Upstream commit 818c4593434e81c9971b8fc278215121622c755e ]
The wrong property "atmel,shdwc-debouncer" was used to specify the debounce delay for the shutdown controler. Replace it with the documented and implemented property "debounce-delay-us", as mentioned in v4 driver submission. See: https://lore.kernel.org/r/1458134390-23847-3-git-send-email-nicolas.ferre@at...
Signed-off-by: Nicolas Ferre nicolas.ferre@microchip.com Reported-by: Clément Léger clement.leger@bootlin.com Reviewed-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20210730172729.28093-1-nicolas.ferre@microchip.com... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/at91-kizbox3_common.dtsi | 2 +- arch/arm/boot/dts/at91-sam9x60ek.dts | 2 +- arch/arm/boot/dts/at91-sama5d27_som1_ek.dts | 2 +- arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts | 2 +- arch/arm/boot/dts/at91-sama5d2_icp.dts | 2 +- arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts | 2 +- arch/arm/boot/dts/at91-sama5d2_xplained.dts | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/arm/boot/dts/at91-kizbox3_common.dtsi b/arch/arm/boot/dts/at91-kizbox3_common.dtsi index c4b3750495da..abe27adfa4d6 100644 --- a/arch/arm/boot/dts/at91-kizbox3_common.dtsi +++ b/arch/arm/boot/dts/at91-kizbox3_common.dtsi @@ -336,7 +336,7 @@ &pwm0 { };
&shutdown_controller { - atmel,shdwc-debouncer = <976>; + debounce-delay-us = <976>; atmel,wakeup-rtc-timer;
input@0 { diff --git a/arch/arm/boot/dts/at91-sam9x60ek.dts b/arch/arm/boot/dts/at91-sam9x60ek.dts index ebbc9b23aef1..b1068cca4228 100644 --- a/arch/arm/boot/dts/at91-sam9x60ek.dts +++ b/arch/arm/boot/dts/at91-sam9x60ek.dts @@ -662,7 +662,7 @@ &rtt { };
&shutdown_controller { - atmel,shdwc-debouncer = <976>; + debounce-delay-us = <976>; status = "okay";
input@0 { diff --git a/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts b/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts index a9e6fee55a2a..8034e5dacc80 100644 --- a/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts +++ b/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts @@ -138,7 +138,7 @@ i2c3: i2c@600 { };
shdwc@f8048010 { - atmel,shdwc-debouncer = <976>; + debounce-delay-us = <976>; atmel,wakeup-rtc-timer;
input@0 { diff --git a/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts b/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts index ff83967fd008..c145c4e5ef58 100644 --- a/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts +++ b/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts @@ -205,7 +205,7 @@ &sdmmc0 { };
&shutdown_controller { - atmel,shdwc-debouncer = <976>; + debounce-delay-us = <976>; atmel,wakeup-rtc-timer;
input@0 { diff --git a/arch/arm/boot/dts/at91-sama5d2_icp.dts b/arch/arm/boot/dts/at91-sama5d2_icp.dts index bd64721fa23c..34faca597c35 100644 --- a/arch/arm/boot/dts/at91-sama5d2_icp.dts +++ b/arch/arm/boot/dts/at91-sama5d2_icp.dts @@ -693,7 +693,7 @@ &sdmmc0 { };
&shutdown_controller { - atmel,shdwc-debouncer = <976>; + debounce-delay-us = <976>; atmel,wakeup-rtc-timer;
input@0 { diff --git a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts index dfd150eb0fd8..3f972a4086c3 100644 --- a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts +++ b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts @@ -203,7 +203,7 @@ i2c2: i2c@600 { };
shdwc@f8048010 { - atmel,shdwc-debouncer = <976>; + debounce-delay-us = <976>;
input@0 { reg = <0>; diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts index 509c732a0d8b..627b7bf88d83 100644 --- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts @@ -347,7 +347,7 @@ i2c2: i2c@600 { };
shdwc@f8048010 { - atmel,shdwc-debouncer = <976>; + debounce-delay-us = <976>; atmel,wakeup-rtc-timer;
input@0 {
From: Vidya Sagar vidyas@nvidia.com
[ Upstream commit bf2942a8b7c38e8cc2d5157b4f0323d7f4e5ec71 ]
The initialization sequence performed by the generic platform driver pcie-designware-plat.c for a DWC based implementation doesn't work for Tegra194. Tegra194 has a different initialization sequence requirement which can only be satisfied by the Tegra194 specific platform driver pcie-tegra194.c. So, remove the generic compatible string "snps,dw-pcie-ep" from Tegra194's endpoint controller nodes.
Signed-off-by: Vidya Sagar vidyas@nvidia.com Reviewed-by: Jon Hunter jonathanh@nvidia.com Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/nvidia/tegra194.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi index 2e40b6047283..203318aa660f 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi @@ -2005,7 +2005,7 @@ pcie@141a0000 { };
pcie_ep@14160000 { - compatible = "nvidia,tegra194-pcie-ep", "snps,dw-pcie-ep"; + compatible = "nvidia,tegra194-pcie-ep"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX4A>; reg = <0x00 0x14160000 0x0 0x00020000>, /* appl registers (128K) */ <0x00 0x36040000 0x0 0x00040000>, /* iATU_DMA reg space (256K) */ @@ -2037,7 +2037,7 @@ pcie_ep@14160000 { };
pcie_ep@14180000 { - compatible = "nvidia,tegra194-pcie-ep", "snps,dw-pcie-ep"; + compatible = "nvidia,tegra194-pcie-ep"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8B>; reg = <0x00 0x14180000 0x0 0x00020000>, /* appl registers (128K) */ <0x00 0x38040000 0x0 0x00040000>, /* iATU_DMA reg space (256K) */ @@ -2069,7 +2069,7 @@ pcie_ep@14180000 { };
pcie_ep@141a0000 { - compatible = "nvidia,tegra194-pcie-ep", "snps,dw-pcie-ep"; + compatible = "nvidia,tegra194-pcie-ep"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8A>; reg = <0x00 0x141a0000 0x0 0x00020000>, /* appl registers (128K) */ <0x00 0x3a040000 0x0 0x00040000>, /* iATU_DMA reg space (256K) */
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit dccd1dfd0770bfd494b68d1135b4547b2c602c42 ]
Move the "Platform Clock" routes for the "Internal Mic" and "Speaker" routes to the intmic_*_map[] / *_spk_map[] arrays.
This ensures that these "Platform Clock" routes do not get added when the BYT_RT5640_NO_INTERNAL_MIC_MAP / BYT_RT5640_NO_SPEAKERS quirks are used.
Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20210802142501.991985-2-hdegoede@redhat.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/intel/boards/bytcr_rt5640.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 22dbd9d93c1e..4bddb969176f 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -290,9 +290,6 @@ static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = { static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = { {"Headphone", NULL, "Platform Clock"}, {"Headset Mic", NULL, "Platform Clock"}, - {"Internal Mic", NULL, "Platform Clock"}, - {"Speaker", NULL, "Platform Clock"}, - {"Headset Mic", NULL, "MICBIAS1"}, {"IN2P", NULL, "Headset Mic"}, {"Headphone", NULL, "HPOL"}, @@ -300,19 +297,23 @@ static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = { };
static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = { + {"Internal Mic", NULL, "Platform Clock"}, {"DMIC1", NULL, "Internal Mic"}, };
static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic2_map[] = { + {"Internal Mic", NULL, "Platform Clock"}, {"DMIC2", NULL, "Internal Mic"}, };
static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = { + {"Internal Mic", NULL, "Platform Clock"}, {"Internal Mic", NULL, "MICBIAS1"}, {"IN1P", NULL, "Internal Mic"}, };
static const struct snd_soc_dapm_route byt_rt5640_intmic_in3_map[] = { + {"Internal Mic", NULL, "Platform Clock"}, {"Internal Mic", NULL, "MICBIAS1"}, {"IN3P", NULL, "Internal Mic"}, }; @@ -354,6 +355,7 @@ static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif2_map[] = { };
static const struct snd_soc_dapm_route byt_rt5640_stereo_spk_map[] = { + {"Speaker", NULL, "Platform Clock"}, {"Speaker", NULL, "SPOLP"}, {"Speaker", NULL, "SPOLN"}, {"Speaker", NULL, "SPORP"}, @@ -361,6 +363,7 @@ static const struct snd_soc_dapm_route byt_rt5640_stereo_spk_map[] = { };
static const struct snd_soc_dapm_route byt_rt5640_mono_spk_map[] = { + {"Speaker", NULL, "Platform Clock"}, {"Speaker", NULL, "SPOLP"}, {"Speaker", NULL, "SPOLN"}, };
From: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
[ Upstream commit 22414cade8dfec25ab94df52b3a4f7aa8edb6120 ]
The default SOF topology enables SSP capture and DMICs, even though both of these hardware capabilities are not always available in hardware (specific versions of HiFiberry and DMIC kit needed).
For the SSP capture, this leads to annoying "SP5-Codec: ASoC: no backend capture" and "streamSSP5-Codec: ASoC: no users capture at close - state 0" errors.
Update the quirks to match what the topology needs, which also allows for the ability to remove SSP capture and DMIC support.
BugLink: https://github.com/thesofproject/linux/issues/3061 Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Guennadi Liakhovetski guennadi.liakhovetski@linux.intel.com Link: https://lore.kernel.org/r/20210802152151.15832-4-pierre-louis.bossart@linux.... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/intel/boards/sof_pcm512x.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/sound/soc/intel/boards/sof_pcm512x.c b/sound/soc/intel/boards/sof_pcm512x.c index 8620d4f38493..335c212c1961 100644 --- a/sound/soc/intel/boards/sof_pcm512x.c +++ b/sound/soc/intel/boards/sof_pcm512x.c @@ -26,11 +26,16 @@
#define SOF_PCM512X_SSP_CODEC(quirk) ((quirk) & GENMASK(3, 0)) #define SOF_PCM512X_SSP_CODEC_MASK (GENMASK(3, 0)) +#define SOF_PCM512X_ENABLE_SSP_CAPTURE BIT(4) +#define SOF_PCM512X_ENABLE_DMIC BIT(5)
#define IDISP_CODEC_MASK 0x4
/* Default: SSP5 */ -static unsigned long sof_pcm512x_quirk = SOF_PCM512X_SSP_CODEC(5); +static unsigned long sof_pcm512x_quirk = + SOF_PCM512X_SSP_CODEC(5) | + SOF_PCM512X_ENABLE_SSP_CAPTURE | + SOF_PCM512X_ENABLE_DMIC;
static bool is_legacy_cpu;
@@ -245,8 +250,9 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].dpcm_playback = 1; /* * capture only supported with specific versions of the Hifiberry DAC+ - * links[id].dpcm_capture = 1; */ + if (sof_pcm512x_quirk & SOF_PCM512X_ENABLE_SSP_CAPTURE) + links[id].dpcm_capture = 1; links[id].no_pcm = 1; links[id].cpus = &cpus[id]; links[id].num_cpus = 1; @@ -381,6 +387,9 @@ static int sof_audio_probe(struct platform_device *pdev)
ssp_codec = sof_pcm512x_quirk & SOF_PCM512X_SSP_CODEC_MASK;
+ if (!(sof_pcm512x_quirk & SOF_PCM512X_ENABLE_DMIC)) + dmic_be_num = 0; + /* compute number of dai links */ sof_audio_card_pcm512x.num_links = 1 + dmic_be_num + hdmi_num;
From: Luiz Augusto von Dentz luiz.von.dentz@intel.com
[ Upstream commit c45074d68a9b1e893d86520af71fab37693c3d7e ]
Code was checking if random_addr and hdev->rpa match without first checking if the RPA has not been set (BDADDR_ANY), furthermore it was clearing HCI_RPA_EXPIRED before the command completes and the RPA is actually programmed which in case of failure would leave the expired RPA still set.
Since advertising instance have a similar problem the clearing of HCI_RPA_EXPIRED has been moved to hci_event.c after checking the random address is in fact the hdev->rap and then proceed to set the expire timeout.
Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/bluetooth/hci_core.h | 4 ++ net/bluetooth/hci_event.c | 32 +++++++++---- net/bluetooth/hci_request.c | 81 ++++++++++++++------------------ 3 files changed, 61 insertions(+), 56 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 34a92d5ed12b..22a60291f203 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1411,6 +1411,10 @@ void hci_conn_del_sysfs(struct hci_conn *conn); !hci_dev_test_flag(dev, HCI_AUTO_OFF)) #define bredr_sc_enabled(dev) (lmp_sc_capable(dev) && \ hci_dev_test_flag(dev, HCI_SC_ENABLED)) +#define rpa_valid(dev) (bacmp(&dev->rpa, BDADDR_ANY) && \ + !hci_dev_test_flag(dev, HCI_RPA_EXPIRED)) +#define adv_rpa_valid(adv) (bacmp(&adv->random_addr, BDADDR_ANY) && \ + !adv->rpa_expired)
#define scan_1m(dev) (((dev)->le_tx_def_phys & HCI_LE_SET_PHY_1M) || \ ((dev)->le_rx_def_phys & HCI_LE_SET_PHY_1M)) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index c5de24372971..c30682c90fc5 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -40,6 +40,8 @@ #define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00"
+#define secs_to_jiffies(_secs) msecs_to_jiffies((_secs) * 1000) + /* Handle HCI Event packets */
static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb, @@ -1171,6 +1173,12 @@ static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb)
bacpy(&hdev->random_addr, sent);
+ if (!bacmp(&hdev->rpa, sent)) { + hci_dev_clear_flag(hdev, HCI_RPA_EXPIRED); + queue_delayed_work(hdev->workqueue, &hdev->rpa_expired, + secs_to_jiffies(hdev->rpa_timeout)); + } + hci_dev_unlock(hdev); }
@@ -1201,24 +1209,30 @@ static void hci_cc_le_set_adv_set_random_addr(struct hci_dev *hdev, { __u8 status = *((__u8 *) skb->data); struct hci_cp_le_set_adv_set_rand_addr *cp; - struct adv_info *adv_instance; + struct adv_info *adv;
if (status) return;
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_SET_RAND_ADDR); - if (!cp) + /* Update only in case the adv instance since handle 0x00 shall be using + * HCI_OP_LE_SET_RANDOM_ADDR since that allows both extended and + * non-extended adverting. + */ + if (!cp || !cp->handle) return;
hci_dev_lock(hdev);
- if (!cp->handle) { - /* Store in hdev for instance 0 (Set adv and Directed advs) */ - bacpy(&hdev->random_addr, &cp->bdaddr); - } else { - adv_instance = hci_find_adv_instance(hdev, cp->handle); - if (adv_instance) - bacpy(&adv_instance->random_addr, &cp->bdaddr); + adv = hci_find_adv_instance(hdev, cp->handle); + if (adv) { + bacpy(&adv->random_addr, &cp->bdaddr); + if (!bacmp(&hdev->rpa, &cp->bdaddr)) { + adv->rpa_expired = false; + queue_delayed_work(hdev->workqueue, + &adv->rpa_expired_cb, + secs_to_jiffies(hdev->rpa_timeout)); + } }
hci_dev_unlock(hdev); diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index b069f640394d..477519ab63b8 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -2053,8 +2053,6 @@ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy, * current RPA has expired then generate a new one. */ if (use_rpa) { - int to; - /* If Controller supports LL Privacy use own address type is * 0x03 */ @@ -2065,14 +2063,10 @@ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy, *own_addr_type = ADDR_LE_DEV_RANDOM;
if (adv_instance) { - if (!adv_instance->rpa_expired && - !bacmp(&adv_instance->random_addr, &hdev->rpa)) + if (adv_rpa_valid(adv_instance)) return 0; - - adv_instance->rpa_expired = false; } else { - if (!hci_dev_test_and_clear_flag(hdev, HCI_RPA_EXPIRED) && - !bacmp(&hdev->random_addr, &hdev->rpa)) + if (rpa_valid(hdev)) return 0; }
@@ -2084,14 +2078,6 @@ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
bacpy(rand_addr, &hdev->rpa);
- to = msecs_to_jiffies(hdev->rpa_timeout * 1000); - if (adv_instance) - queue_delayed_work(hdev->workqueue, - &adv_instance->rpa_expired_cb, to); - else - queue_delayed_work(hdev->workqueue, - &hdev->rpa_expired, to); - return 0; }
@@ -2134,6 +2120,30 @@ void __hci_req_clear_ext_adv_sets(struct hci_request *req) hci_req_add(req, HCI_OP_LE_CLEAR_ADV_SETS, 0, NULL); }
+static void set_random_addr(struct hci_request *req, bdaddr_t *rpa) +{ + struct hci_dev *hdev = req->hdev; + + /* If we're advertising or initiating an LE connection we can't + * go ahead and change the random address at this time. This is + * because the eventual initiator address used for the + * subsequently created connection will be undefined (some + * controllers use the new address and others the one we had + * when the operation started). + * + * In this kind of scenario skip the update and let the random + * address be updated at the next cycle. + */ + if (hci_dev_test_flag(hdev, HCI_LE_ADV) || + hci_lookup_le_connect(hdev)) { + bt_dev_dbg(hdev, "Deferring random address update"); + hci_dev_set_flag(hdev, HCI_RPA_EXPIRED); + return; + } + + hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, rpa); +} + int __hci_req_setup_ext_adv_instance(struct hci_request *req, u8 instance) { struct hci_cp_le_set_ext_adv_params cp; @@ -2236,6 +2246,13 @@ int __hci_req_setup_ext_adv_instance(struct hci_request *req, u8 instance) } else { if (!bacmp(&random_addr, &hdev->random_addr)) return 0; + /* Instance 0x00 doesn't have an adv_info, instead it + * uses hdev->random_addr to track its address so + * whenever it needs to be updated this also set the + * random address since hdev->random_addr is shared with + * scan state machine. + */ + set_random_addr(req, &random_addr); }
memset(&cp, 0, sizeof(cp)); @@ -2493,30 +2510,6 @@ void hci_req_clear_adv_instance(struct hci_dev *hdev, struct sock *sk, false); }
-static void set_random_addr(struct hci_request *req, bdaddr_t *rpa) -{ - struct hci_dev *hdev = req->hdev; - - /* If we're advertising or initiating an LE connection we can't - * go ahead and change the random address at this time. This is - * because the eventual initiator address used for the - * subsequently created connection will be undefined (some - * controllers use the new address and others the one we had - * when the operation started). - * - * In this kind of scenario skip the update and let the random - * address be updated at the next cycle. - */ - if (hci_dev_test_flag(hdev, HCI_LE_ADV) || - hci_lookup_le_connect(hdev)) { - bt_dev_dbg(hdev, "Deferring random address update"); - hci_dev_set_flag(hdev, HCI_RPA_EXPIRED); - return; - } - - hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, rpa); -} - int hci_update_random_address(struct hci_request *req, bool require_privacy, bool use_rpa, u8 *own_addr_type) { @@ -2528,8 +2521,6 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy, * the current RPA in use, then generate a new one. */ if (use_rpa) { - int to; - /* If Controller supports LL Privacy use own address type is * 0x03 */ @@ -2539,8 +2530,7 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy, else *own_addr_type = ADDR_LE_DEV_RANDOM;
- if (!hci_dev_test_and_clear_flag(hdev, HCI_RPA_EXPIRED) && - !bacmp(&hdev->random_addr, &hdev->rpa)) + if (rpa_valid(hdev)) return 0;
err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa); @@ -2551,9 +2541,6 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy,
set_random_addr(req, &hdev->rpa);
- to = msecs_to_jiffies(hdev->rpa_timeout * 1000); - queue_delayed_work(hdev->workqueue, &hdev->rpa_expired, to); - return 0; }
From: Ioana Ciornei ioana.ciornei@nxp.com
[ Upstream commit 042ad90ca7ce70f35dc5efd5b2043d2f8aceb12a ]
We should not enable the switch interfaces at probe time since this is trigged by the open callback. Remove the call dpsw_enable() which does exactly this.
Signed-off-by: Ioana Ciornei ioana.ciornei@nxp.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c | 6 ------ 1 file changed, 6 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c index 58964d22cb17..e3a3499ba7a2 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c @@ -3231,12 +3231,6 @@ static int dpaa2_switch_probe(struct fsl_mc_device *sw_dev) ðsw->fq[i].napi, dpaa2_switch_poll, NAPI_POLL_WEIGHT);
- err = dpsw_enable(ethsw->mc_io, 0, ethsw->dpsw_handle); - if (err) { - dev_err(ethsw->dev, "dpsw_enable err %d\n", err); - goto err_free_netdev; - } - /* Setup IRQs */ err = dpaa2_switch_setup_irqs(sw_dev); if (err)
From: Laurent Pinchart laurent.pinchart@ideasonboard.com
[ Upstream commit 51f93add3669f1b1f540de1cf397815afbd4c756 ]
The frame_length_lines (0x0340) registers are hard-coded as follows:
- 4208x3118 frame_length_lines = 0x0c50
- 2104x1560 frame_length_lines = 0x0638
- 1048x780 frame_length_lines = 0x034c
The driver exposes the V4L2_CID_VBLANK control in read-only mode and sets its value to vts_def - height, where vts_def is a mode-dependent value coming from the supported_modes array. It is set using one of the following macros defined in the driver:
#define IMX258_VTS_30FPS 0x0c98 #define IMX258_VTS_30FPS_2K 0x0638 #define IMX258_VTS_30FPS_VGA 0x034c
There's a clear mismatch in the value for the full resolution mode i.e. IMX258_VTS_30FPS. Fix it by rectifying the macro with the value set for the frame_length_lines register as stated above.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Umang Jain umang.jain@ideasonboard.com Reviewed-by: Bingbu Cao bingbu.cao@intel.com Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/imx258.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c index a017ec4e0f50..b3fa28d05fa6 100644 --- a/drivers/media/i2c/imx258.c +++ b/drivers/media/i2c/imx258.c @@ -23,7 +23,7 @@ #define IMX258_CHIP_ID 0x0258
/* V_TIMING internal */ -#define IMX258_VTS_30FPS 0x0c98 +#define IMX258_VTS_30FPS 0x0c50 #define IMX258_VTS_30FPS_2K 0x0638 #define IMX258_VTS_30FPS_VGA 0x034c #define IMX258_VTS_MAX 0xffff
From: Umang Jain umang.jain@ideasonboard.com
[ Upstream commit f809665ee75fff3f4ea8907f406a66d380aeb184 ]
The range for analog gain mentioned in the datasheet is [0, 480]. The real gain formula mentioned in the datasheet is:
Gain = 512 / (512 – X)
Hence, values larger than 511 clearly makes no sense. The gain register field is also documented to be of 9-bits in the datasheet.
Certainly, it is enough to infer that, the kernel driver currently advertises an arbitrary analog gain max. Fix it by rectifying the value as per the data sheet i.e. 480.
Signed-off-by: Umang Jain umang.jain@ideasonboard.com Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Reviewed-by: Dave Stevenson dave.stevenson@raspberrypi.com Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/imx258.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c index b3fa28d05fa6..cdeaaec31879 100644 --- a/drivers/media/i2c/imx258.c +++ b/drivers/media/i2c/imx258.c @@ -47,7 +47,7 @@ /* Analog gain control */ #define IMX258_REG_ANALOG_GAIN 0x0204 #define IMX258_ANA_GAIN_MIN 0 -#define IMX258_ANA_GAIN_MAX 0x1fff +#define IMX258_ANA_GAIN_MAX 480 #define IMX258_ANA_GAIN_STEP 1 #define IMX258_ANA_GAIN_DEFAULT 0x0
From: Laurent Pinchart laurent.pinchart@ideasonboard.com
[ Upstream commit 0ada1697ed4256b38225319c9896661142a3572d ]
When the stream fails to start, the first two buffers in the queue have been moved to the active_vb2_buf array and are returned to vb2 by imx7_csi_dma_unsetup_vb2_buf(). The function is called with the buffer state set to VB2_BUF_STATE_ERROR unconditionally, which is correct when stopping the stream, but not when the start operation fails. In that case, the state should be set to VB2_BUF_STATE_QUEUED. Fix it.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Tested-by: Martin Kepplinger martin.kepplinger@puri.sm Reviewed-by: Rui Miguel Silva rmfrfs@gmail.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/media/imx/imx7-media-csi.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c index f85a2f5f1413..ad1bca3fe047 100644 --- a/drivers/staging/media/imx/imx7-media-csi.c +++ b/drivers/staging/media/imx/imx7-media-csi.c @@ -361,6 +361,7 @@ static void imx7_csi_dma_unsetup_vb2_buf(struct imx7_csi *csi,
vb->timestamp = ktime_get_ns(); vb2_buffer_done(vb, return_status); + csi->active_vb2_buf[i] = NULL; } } } @@ -386,9 +387,10 @@ static int imx7_csi_dma_setup(struct imx7_csi *csi) return 0; }
-static void imx7_csi_dma_cleanup(struct imx7_csi *csi) +static void imx7_csi_dma_cleanup(struct imx7_csi *csi, + enum vb2_buffer_state return_status) { - imx7_csi_dma_unsetup_vb2_buf(csi, VB2_BUF_STATE_ERROR); + imx7_csi_dma_unsetup_vb2_buf(csi, return_status); imx_media_free_dma_buf(csi->dev, &csi->underrun_buf); }
@@ -537,9 +539,10 @@ static int imx7_csi_init(struct imx7_csi *csi) return 0; }
-static void imx7_csi_deinit(struct imx7_csi *csi) +static void imx7_csi_deinit(struct imx7_csi *csi, + enum vb2_buffer_state return_status) { - imx7_csi_dma_cleanup(csi); + imx7_csi_dma_cleanup(csi, return_status); imx7_csi_init_default(csi); imx7_csi_dmareq_rff_disable(csi); clk_disable_unprepare(csi->mclk); @@ -702,7 +705,7 @@ static int imx7_csi_s_stream(struct v4l2_subdev *sd, int enable)
ret = v4l2_subdev_call(csi->src_sd, video, s_stream, 1); if (ret < 0) { - imx7_csi_deinit(csi); + imx7_csi_deinit(csi, VB2_BUF_STATE_QUEUED); goto out_unlock; }
@@ -712,7 +715,7 @@ static int imx7_csi_s_stream(struct v4l2_subdev *sd, int enable)
v4l2_subdev_call(csi->src_sd, video, s_stream, 0);
- imx7_csi_deinit(csi); + imx7_csi_deinit(csi, VB2_BUF_STATE_ERROR); }
csi->is_streaming = !!enable;
From: Hans Verkuil hverkuil-cisco@xs4all.nl
[ Upstream commit 4108b3e6db31acc4c68133290bbcc87d4db905c9 ]
These for-loops should test against v4l2_dv_timings_presets[i].bt.width, not if i < v4l2_dv_timings_presets[i].bt.width. Luckily nothing ever broke, since the smallest width is still a lot higher than the total number of presets, but it is wrong.
The last item in the presets array is all 0, so the for-loop must stop when it reaches that sentinel.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Reported-by: Krzysztof Hałasa khalasa@piap.pl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/v4l2-core/v4l2-dv-timings.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index 230d65a64217..af48705c704f 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c @@ -196,7 +196,7 @@ bool v4l2_find_dv_timings_cap(struct v4l2_dv_timings *t, if (!v4l2_valid_dv_timings(t, cap, fnc, fnc_handle)) return false;
- for (i = 0; i < v4l2_dv_timings_presets[i].bt.width; i++) { + for (i = 0; v4l2_dv_timings_presets[i].bt.width; i++) { if (v4l2_valid_dv_timings(v4l2_dv_timings_presets + i, cap, fnc, fnc_handle) && v4l2_match_dv_timings(t, v4l2_dv_timings_presets + i, @@ -218,7 +218,7 @@ bool v4l2_find_dv_timings_cea861_vic(struct v4l2_dv_timings *t, u8 vic) { unsigned int i;
- for (i = 0; i < v4l2_dv_timings_presets[i].bt.width; i++) { + for (i = 0; v4l2_dv_timings_presets[i].bt.width; i++) { const struct v4l2_bt_timings *bt = &v4l2_dv_timings_presets[i].bt;
From: Krzysztof Hałasa khalasa@piap.pl
[ Upstream commit 7dee1030871a48d4f3c5a74227a4b4188463479a ]
Correctly propagate the tda1997x_detect_std error value.
Signed-off-by: Krzysztof Hałasa khalasa@piap.pl Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/tda1997x.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c index 9554c8348c02..17cc69c3227f 100644 --- a/drivers/media/i2c/tda1997x.c +++ b/drivers/media/i2c/tda1997x.c @@ -1695,14 +1695,15 @@ static int tda1997x_query_dv_timings(struct v4l2_subdev *sd, struct v4l2_dv_timings *timings) { struct tda1997x_state *state = to_state(sd); + int ret;
v4l_dbg(1, debug, state->client, "%s\n", __func__); memset(timings, 0, sizeof(struct v4l2_dv_timings)); mutex_lock(&state->lock); - tda1997x_detect_std(state, timings); + ret = tda1997x_detect_std(state, timings); mutex_unlock(&state->lock);
- return 0; + return ret; }
static const struct v4l2_subdev_video_ops tda1997x_video_ops = {
From: Evgeny Novikov novikov@ispras.ru
[ Upstream commit 38367073c796a37a61549b1f66a71b3adb03802d ]
tegra_cec_probe() and tegra_cec_resume() ignored possible errors of clk_prepare_enable(). The patch fixes this.
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Evgeny Novikov novikov@ispras.ru Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/cec/platform/tegra/tegra_cec.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/media/cec/platform/tegra/tegra_cec.c b/drivers/media/cec/platform/tegra/tegra_cec.c index 1ac0c70a5981..5e907395ca2e 100644 --- a/drivers/media/cec/platform/tegra/tegra_cec.c +++ b/drivers/media/cec/platform/tegra/tegra_cec.c @@ -366,7 +366,11 @@ static int tegra_cec_probe(struct platform_device *pdev) return -ENOENT; }
- clk_prepare_enable(cec->clk); + ret = clk_prepare_enable(cec->clk); + if (ret) { + dev_err(&pdev->dev, "Unable to prepare clock for CEC\n"); + return ret; + }
/* set context info. */ cec->dev = &pdev->dev; @@ -446,9 +450,7 @@ static int tegra_cec_resume(struct platform_device *pdev)
dev_notice(&pdev->dev, "Resuming\n");
- clk_prepare_enable(cec->clk); - - return 0; + return clk_prepare_enable(cec->clk); } #endif
From: Bob Peterson rpeterso@redhat.com
[ Upstream commit 9d9b16054b7d357afde69a027514c695092b0d22 ]
We must not call gfs2_consist (which does a file system withdraw) from the freeze glock's freeze_go_xmote_bh function because the withdraw will try to use the freeze glock, thus causing a glock recursion error.
This patch changes freeze_go_xmote_bh to call function gfs2_assert_withdraw_delayed instead of gfs2_consist to avoid recursion.
Signed-off-by: Bob Peterson rpeterso@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/gfs2/glops.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 54d3fbeb3002..384565d63eea 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -610,16 +610,13 @@ static int freeze_go_xmote_bh(struct gfs2_glock *gl) j_gl->gl_ops->go_inval(j_gl, DIO_METADATA);
error = gfs2_find_jhead(sdp->sd_jdesc, &head, false); - if (error) - gfs2_consist(sdp); - if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) - gfs2_consist(sdp); - - /* Initialize some head of the log stuff */ - if (!gfs2_withdrawn(sdp)) { - sdp->sd_log_sequence = head.lh_sequence + 1; - gfs2_log_pointers_init(sdp, head.lh_blkno); - } + if (gfs2_assert_withdraw_delayed(sdp, !error)) + return error; + if (gfs2_assert_withdraw_delayed(sdp, head.lh_flags & + GFS2_LOG_HEAD_UNMOUNT)) + return -EIO; + sdp->sd_log_sequence = head.lh_sequence + 1; + gfs2_log_pointers_init(sdp, head.lh_blkno); } return 0; }
From: AngeloGioacchino Del Regno angelogioacchino.delregno@somainline.org
[ Upstream commit 26e02c98a9ad63eb21b9be4ac92002f555130d3b ]
The memory map was wrong. Fix it.
Signed-off-by: AngeloGioacchino Del Regno angelogioacchino.delregno@somainline.org Signed-off-by: Konrad Dybcio konrad.dybcio@somainline.org Link: https://lore.kernel.org/r/20210728222542.54269-2-konrad.dybcio@somainline.or... Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sdm630.dtsi | 41 ++++++++++++---------------- 1 file changed, 18 insertions(+), 23 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi index f91a928466c3..5ea3884b3ccb 100644 --- a/arch/arm64/boot/dts/qcom/sdm630.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi @@ -343,10 +343,19 @@ wlan_msa_mem: wlan-msa-mem@85700000 { };
qhee_code: qhee-code@85800000 { - reg = <0x0 0x85800000 0x0 0x3700000>; + reg = <0x0 0x85800000 0x0 0x600000>; no-map; };
+ rmtfs_mem: memory@85e00000 { + compatible = "qcom,rmtfs-mem"; + reg = <0x0 0x85e00000 0x0 0x200000>; + no-map; + + qcom,client-id = <1>; + qcom,vmid = <15>; + }; + smem_region: smem-mem@86000000 { reg = <0 0x86000000 0 0x200000>; no-map; @@ -357,58 +366,44 @@ tz_mem: memory@86200000 { no-map; };
- modem_fw_mem: modem-fw-region@8ac00000 { + mpss_region: mpss@8ac00000 { reg = <0x0 0x8ac00000 0x0 0x7e00000>; no-map; };
- adsp_fw_mem: adsp-fw-region@92a00000 { + adsp_region: adsp@92a00000 { reg = <0x0 0x92a00000 0x0 0x1e00000>; no-map; };
- pil_mba_mem: pil-mba-region@94800000 { + mba_region: mba@94800000 { reg = <0x0 0x94800000 0x0 0x200000>; no-map; };
- buffer_mem: buffer-region@94a00000 { + buffer_mem: tzbuffer@94a00000 { reg = <0x0 0x94a00000 0x0 0x100000>; no-map; };
- venus_fw_mem: venus-fw-region@9f800000 { + venus_region: venus@9f800000 { reg = <0x0 0x9f800000 0x0 0x800000>; no-map; };
- secure_region2: secure-region2@f7c00000 { - reg = <0x0 0xf7c00000 0x0 0x5c00000>; - no-map; - }; - adsp_mem: adsp-region@f6000000 { reg = <0x0 0xf6000000 0x0 0x800000>; no-map; };
- qseecom_ta_mem: qseecom-ta-region@fec00000 { - reg = <0x0 0xfec00000 0x0 0x1000000>; - no-map; - }; - qseecom_mem: qseecom-region@f6800000 { reg = <0x0 0xf6800000 0x0 0x1400000>; no-map; };
- secure_display_memory: secure-region@f5c00000 { - reg = <0x0 0xf5c00000 0x0 0x5c00000>; - no-map; - }; - - cont_splash_mem: cont-splash-region@9d400000 { - reg = <0x0 0x9d400000 0x0 0x23ff000>; + zap_shader_region: gpu@fed00000 { + compatible = "shared-dma-pool"; + reg = <0x0 0xfed00000 0x0 0xa00000>; no-map; }; };
From: AngeloGioacchino Del Regno angelogioacchino.delregno@somainline.org
[ Upstream commit 36a0d47aee6a8cfd3c6cf4274732d8ef994a25b4 ]
Previous pinctrl configuration was wrong. Fix it and clean up how multi-pin states are described.
Signed-off-by: AngeloGioacchino Del Regno angelogioacchino.delregno@somainline.org Signed-off-by: Konrad Dybcio konrad.dybcio@somainline.org Link: https://lore.kernel.org/r/20210728222542.54269-9-konrad.dybcio@somainline.or... [bjorn: Polished the commit message] Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sdm630.dtsi | 212 ++++++++++++++++++--------- 1 file changed, 139 insertions(+), 73 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi index 5ea3884b3ccb..5b73659f2a75 100644 --- a/arch/arm64/boot/dts/qcom/sdm630.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi @@ -522,14 +522,18 @@ tcsr_mutex_regs: syscon@1f40000 { reg = <0x01f40000 0x20000>; };
- tlmm: pinctrl@3000000 { + tlmm: pinctrl@3100000 { compatible = "qcom,sdm630-pinctrl"; - reg = <0x03000000 0xc00000>; + reg = <0x03100000 0x400000>, + <0x03500000 0x400000>, + <0x03900000 0x400000>; + reg-names = "south", "center", "north"; interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>; gpio-controller; - #gpio-cells = <0x2>; + gpio-ranges = <&tlmm 0 0 114>; + #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <0x2>; + #interrupt-cells = <2>;
blsp1_uart1_default: blsp1-uart1-default { pins = "gpio0", "gpio1", "gpio2", "gpio3"; @@ -549,40 +553,48 @@ blsp1_uart2_default: blsp1-uart2-default { bias-disable; };
- blsp2_uart1_tx_active: blsp2-uart1-tx-active { - pins = "gpio16"; - drive-strength = <2>; - bias-disable; - }; - - blsp2_uart1_tx_sleep: blsp2-uart1-tx-sleep { - pins = "gpio16"; - drive-strength = <2>; - bias-pull-up; - }; + blsp2_uart1_default: blsp2-uart1-active { + tx-rts { + pins = "gpio16", "gpio19"; + function = "blsp_uart5"; + drive-strength = <2>; + bias-disable; + };
- blsp2_uart1_rxcts_active: blsp2-uart1-rxcts-active { - pins = "gpio17", "gpio18"; - drive-strength = <2>; - bias-disable; - }; + rx { + /* + * Avoid garbage data while BT module + * is powered off or not driving signal + */ + pins = "gpio17"; + function = "blsp_uart5"; + drive-strength = <2>; + bias-pull-up; + };
- blsp2_uart1_rxcts_sleep: blsp2-uart1-rxcts-sleep { - pins = "gpio17", "gpio18"; - drive-strength = <2>; - bias-no-pull; + cts { + /* Match the pull of the BT module */ + pins = "gpio18"; + function = "blsp_uart5"; + drive-strength = <2>; + bias-pull-down; + }; };
- blsp2_uart1_rfr_active: blsp2-uart1-rfr-active { - pins = "gpio19"; - drive-strength = <2>; - bias-disable; - }; + blsp2_uart1_sleep: blsp2-uart1-sleep { + tx { + pins = "gpio16"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + };
- blsp2_uart1_rfr_sleep: blsp2-uart1-rfr-sleep { - pins = "gpio19"; - drive-strength = <2>; - bias-no-pull; + rx-cts-rts { + pins = "gpio17", "gpio18", "gpio19"; + function = "gpio"; + drive-strength = <2>; + bias-no-pull; + }; };
i2c1_default: i2c1-default { @@ -681,50 +693,106 @@ i2c8_sleep: i2c8-sleep { bias-pull-up; };
- sdc1_clk_on: sdc1-clk-on { - pins = "sdc1_clk"; - bias-disable; - drive-strength = <16>; - }; + sdc1_state_on: sdc1-on { + clk { + pins = "sdc1_clk"; + bias-disable; + drive-strength = <16>; + };
- sdc1_clk_off: sdc1-clk-off { - pins = "sdc1_clk"; - bias-disable; - drive-strength = <2>; - }; + cmd { + pins = "sdc1_cmd"; + bias-pull-up; + drive-strength = <10>; + };
- sdc1_cmd_on: sdc1-cmd-on { - pins = "sdc1_cmd"; - bias-pull-up; - drive-strength = <10>; - }; + data { + pins = "sdc1_data"; + bias-pull-up; + drive-strength = <10>; + };
- sdc1_cmd_off: sdc1-cmd-off { - pins = "sdc1_cmd"; - bias-pull-up; - drive-strength = <2>; + rclk { + pins = "sdc1_rclk"; + bias-pull-down; + }; };
- sdc1_data_on: sdc1-data-on { - pins = "sdc1_data"; - bias-pull-up; - drive-strength = <8>; - }; + sdc1_state_off: sdc1-off { + clk { + pins = "sdc1_clk"; + bias-disable; + drive-strength = <2>; + };
- sdc1_data_off: sdc1-data-off { - pins = "sdc1_data"; - bias-pull-up; - drive-strength = <2>; + cmd { + pins = "sdc1_cmd"; + bias-pull-up; + drive-strength = <2>; + }; + + data { + pins = "sdc1_data"; + bias-pull-up; + drive-strength = <2>; + }; + + rclk { + pins = "sdc1_rclk"; + bias-pull-down; + }; };
- sdc1_rclk_on: sdc1-rclk-on { - pins = "sdc1_rclk"; - bias-pull-down; + sdc2_state_on: sdc2-on { + clk { + pins = "sdc2_clk"; + bias-disable; + drive-strength = <16>; + }; + + cmd { + pins = "sdc2_cmd"; + bias-pull-up; + drive-strength = <10>; + }; + + data { + pins = "sdc2_data"; + bias-pull-up; + drive-strength = <10>; + }; + + sd-cd { + pins = "gpio54"; + bias-pull-up; + drive-strength = <2>; + }; };
- sdc1_rclk_off: sdc1-rclk-off { - pins = "sdc1_rclk"; - bias-pull-down; + sdc2_state_off: sdc2-off { + clk { + pins = "sdc2_clk"; + bias-disable; + drive-strength = <2>; + }; + + cmd { + pins = "sdc2_cmd"; + bias-pull-up; + drive-strength = <2>; + }; + + data { + pins = "sdc2_data"; + bias-pull-up; + drive-strength = <2>; + }; + + sd-cd { + pins = "gpio54"; + bias-disable; + drive-strength = <2>; + }; }; };
@@ -818,8 +886,8 @@ sdhc_1: sdhci@c0c4000 { clock-names = "core", "iface", "xo", "ice";
pinctrl-names = "default", "sleep"; - pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>; - pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>; + pinctrl-0 = <&sdc1_state_on>; + pinctrl-1 = <&sdc1_state_off>;
bus-width = <8>; non-removable; @@ -964,10 +1032,8 @@ blsp2_uart1: serial@c1af000 { dmas = <&blsp2_dma 0>, <&blsp2_dma 1>; dma-names = "tx", "rx"; pinctrl-names = "default", "sleep"; - pinctrl-0 = <&blsp2_uart1_tx_active &blsp2_uart1_rxcts_active - &blsp2_uart1_rfr_active>; - pinctrl-1 = <&blsp2_uart1_tx_sleep &blsp2_uart1_rxcts_sleep - &blsp2_uart1_rfr_sleep>; + pinctrl-0 = <&blsp2_uart1_default>; + pinctrl-1 = <&blsp2_uart1_sleep>; status = "disabled"; };
From: Alex Elder elder@linaro.org
[ Upstream commit 0fd75f5760b6a7a7f35dff46a6cdc4f6d1a86ee8 ]
Three interconnects are defined for IPA version 4.9, but there should only be two. They should also use names that match what's used for other platforms (and specified in the Device Tree binding).
Signed-off-by: Alex Elder elder@linaro.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ipa/ipa_data-v4.9.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ipa/ipa_data-v4.9.c b/drivers/net/ipa/ipa_data-v4.9.c index e41be790f45e..75b50a50e348 100644 --- a/drivers/net/ipa/ipa_data-v4.9.c +++ b/drivers/net/ipa/ipa_data-v4.9.c @@ -392,18 +392,13 @@ static const struct ipa_mem_data ipa_mem_data = { /* Interconnect rates are in 1000 byte/second units */ static const struct ipa_interconnect_data ipa_interconnect_data[] = { { - .name = "ipa_to_llcc", + .name = "memory", .peak_bandwidth = 600000, /* 600 MBps */ .average_bandwidth = 150000, /* 150 MBps */ }, - { - .name = "llcc_to_ebi1", - .peak_bandwidth = 1804000, /* 1.804 GBps */ - .average_bandwidth = 150000, /* 150 MBps */ - }, /* Average rate is unused for the next interconnect */ { - .name = "appss_to_ipa", + .name = "config", .peak_bandwidth = 74000, /* 74 MBps */ .average_bandwidth = 0, /* unused */ },
From: Tony Lindgren tony@atomide.com
[ Upstream commit 1fe0e1fa3209ad8e9124147775bd27b1d9f04bd4 ]
Handle optional overrun-throttle-ms property as done for 8250_fsl in commit 6d7f677a2afa ("serial: 8250: Rate limit serial port rx interrupts during input overruns"). This can be used to rate limit the UART interrupts on noisy lines that end up producing messages like the following:
ttyS ttyS2: 4 input overrun(s)
At least on droid4, the multiplexed USB and UART port is left to UART mode by the bootloader for a debug console, and if a USB charger is connected on boot, we get noise on the UART until the PMIC related drivers for PHY and charger are loaded.
With this patch and overrun-throttle-ms = <500> we avoid the extra rx interrupts.
Cc: Carl Philipp Klemm philipp@uvos.xyz Cc: Merlijn Wajer merlijn@wizzup.org Cc: Pavel Machek pavel@ucw.cz Cc: Sebastian Reichel sre@kernel.org Cc: Vignesh Raghavendra vigneshr@ti.com Signed-off-by: Tony Lindgren tony@atomide.com Link: https://lore.kernel.org/r/20210727103533.51547-2-tony@atomide.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_omap.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 79418d4beb48..b6c731a267d2 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -617,7 +617,7 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) struct uart_port *port = dev_id; struct omap8250_priv *priv = port->private_data; struct uart_8250_port *up = up_to_u8250p(port); - unsigned int iir; + unsigned int iir, lsr; int ret;
#ifdef CONFIG_SERIAL_8250_DMA @@ -628,6 +628,7 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) #endif
serial8250_rpm_get(up); + lsr = serial_port_in(port, UART_LSR); iir = serial_port_in(port, UART_IIR); ret = serial8250_handle_irq(port, iir);
@@ -642,6 +643,24 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) serial_port_in(port, UART_RX); }
+ /* Stop processing interrupts on input overrun */ + if ((lsr & UART_LSR_OE) && up->overrun_backoff_time_ms > 0) { + unsigned long delay; + + up->ier = port->serial_in(port, UART_IER); + if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) { + port->ops->stop_rx(port); + } else { + /* Keep restarting the timer until + * the input overrun subsides. + */ + cancel_delayed_work(&up->overrun_backoff); + } + + delay = msecs_to_jiffies(up->overrun_backoff_time_ms); + schedule_delayed_work(&up->overrun_backoff, delay); + } + serial8250_rpm_put(up);
return IRQ_RETVAL(ret); @@ -1353,6 +1372,10 @@ static int omap8250_probe(struct platform_device *pdev) } }
+ if (of_property_read_u32(np, "overrun-throttle-ms", + &up.overrun_backoff_time_ms) != 0) + up.overrun_backoff_time_ms = 0; + priv->wakeirq = irq_of_parse_and_map(np, 1);
pdata = of_device_get_match_data(&pdev->dev);
From: Sebastian Reichel sebastian.reichel@collabora.com
[ Upstream commit cd7cd5b716d594e27a933c12f026d4f2426d7bf4 ]
PPD has only one ACHC device, which effectively is a Kinetis microcontroller. It has one SPI interface used for normal communication. Additionally it's possible to flash the device firmware using NXP's EzPort protocol by correctly driving a second chip select pin and the device reset pin.
Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Link: https://lore.kernel.org/r/20210802172309.164365-3-sebastian.reichel@collabor... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/imx53-ppd.dts | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/arch/arm/boot/dts/imx53-ppd.dts b/arch/arm/boot/dts/imx53-ppd.dts index be040b6a02fa..1f3ee60fb102 100644 --- a/arch/arm/boot/dts/imx53-ppd.dts +++ b/arch/arm/boot/dts/imx53-ppd.dts @@ -70,6 +70,12 @@ cko2_11M: sgtl-clock-cko2 { clock-frequency = <11289600>; };
+ achc_24M: achc-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + }; + sgtlsound: sound { compatible = "fsl,imx53-cpuvo-sgtl5000", "fsl,imx-audio-sgtl5000"; @@ -314,16 +320,13 @@ &gpio4 11 GPIO_ACTIVE_LOW &gpio4 12 GPIO_ACTIVE_LOW>; status = "okay";
- spidev0: spi@0 { - compatible = "ge,achc"; - reg = <0>; - spi-max-frequency = <1000000>; - }; - - spidev1: spi@1 { - compatible = "ge,achc"; - reg = <1>; - spi-max-frequency = <1000000>; + spidev0: spi@1 { + compatible = "ge,achc", "nxp,kinetis-k20"; + reg = <1>, <0>; + vdd-supply = <®_3v3>; + vdda-supply = <®_3v3>; + clocks = <&achc_24M>; + reset-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>; };
gpioxra0: gpio@2 {
From: Vinod Koul vkoul@kernel.org
[ Upstream commit 52c9887fba71fc8f12d343833fc595c762aac8c7 ]
reg property should be array of values, here it is a single array, leading to below warning:
arch/arm64/boot/dts/qcom/ipq8074-hk01.dt.yaml: soc: pci@10000000:reg:0: [268435456, 3869, 268439328, 168, 557056, 8192, 269484032, 4096] is too long arch/arm64/boot/dts/qcom/ipq8074-hk01.dt.yaml: soc: pci@10000000:ranges: 'oneOf' conditional failed, one must be fixed: arch/arm64/boot/dts/qcom/ipq8074-hk01.dt.yaml: soc: pci@10000000:ranges: 'oneOf' conditional failed, one must be fixed: [[2164260864, 0, 270532608, 270532608, 0, 1048576, 2181038080, 0, 271581184, 271581184, 0, 13631488]] is not of type 'null' [2164260864, 0, 270532608, 270532608, 0, 1048576, 2181038080, 0, 271581184, 271581184, 0, 13631488] is too long arch/arm64/boot/dts/qcom/ipq8074-hk01.dt.yaml: soc: pci@20000000:reg:0: [536870912, 3869, 536874784, 168, 524288, 8192, 537919488, 4096] is too long arch/arm64/boot/dts/qcom/ipq8074-hk01.dt.yaml: soc: pci@20000000:ranges: 'oneOf' conditional failed, one must be fixed: arch/arm64/boot/dts/qcom/ipq8074-hk01.dt.yaml: soc: pci@20000000:ranges: 'oneOf' conditional failed, one must be fixed: [[2164260864, 0, 538968064, 538968064, 0, 1048576, 2181038080, 0, 540016640, 540016640, 0, 13631488]] is not of type 'null' [2164260864, 0, 538968064, 538968064, 0, 1048576, 2181038080, 0, 540016640, 540016640, 0, 13631488] is too long
Signed-off-by: Vinod Koul vkoul@kernel.org Link: https://lore.kernel.org/r/20210308060826.3074234-17-vkoul@kernel.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi index a32e5e79ab0b..e8db62470b23 100644 --- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -567,10 +567,10 @@ frame@b128000 {
pcie1: pci@10000000 { compatible = "qcom,pcie-ipq8074"; - reg = <0x10000000 0xf1d - 0x10000f20 0xa8 - 0x00088000 0x2000 - 0x10100000 0x1000>; + reg = <0x10000000 0xf1d>, + <0x10000f20 0xa8>, + <0x00088000 0x2000>, + <0x10100000 0x1000>; reg-names = "dbi", "elbi", "parf", "config"; device_type = "pci"; linux,pci-domain = <1>; @@ -629,10 +629,10 @@ IRQ_TYPE_LEVEL_HIGH>, /* int_c */
pcie0: pci@20000000 { compatible = "qcom,pcie-ipq8074"; - reg = <0x20000000 0xf1d - 0x20000f20 0xa8 - 0x00080000 0x2000 - 0x20100000 0x1000>; + reg = <0x20000000 0xf1d>, + <0x20000f20 0xa8>, + <0x00080000 0x2000>, + <0x20100000 0x1000>; reg-names = "dbi", "elbi", "parf", "config"; device_type = "pci"; linux,pci-domain = <0>;
From: Vinod Koul vkoul@kernel.org
[ Upstream commit c81210e38966cfa1c784364e4035081c3227cf5b ]
memory node like other node should be node@reg, which is missing in this case, so fix it up
arch/arm64/boot/dts/qcom/ipq8074-hk01.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 1073741824, 0, 536870912]]}
Signed-off-by: Vinod Koul vkoul@kernel.org Link: https://lore.kernel.org/r/20210308060826.3074234-18-vkoul@kernel.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/ipq8074-hk01.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts b/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts index e8c37a1693d3..cc08dc4eb56a 100644 --- a/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts +++ b/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts @@ -20,7 +20,7 @@ chosen { stdout-path = "serial0"; };
- memory { + memory@40000000 { device_type = "memory"; reg = <0x0 0x40000000 0x0 0x20000000>; };
From: Vinod Koul vkoul@kernel.org
[ Upstream commit 1b91b8ef60e9a67141e66af3cca532c00f4605fe ]
Nodes need not contain '0x' for the unit address. Drop it to fix the below warning:
arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dt.yaml: reserved-memory: 'memory@0x60000' does not match any of the regexes
Signed-off-by: Vinod Koul vkoul@kernel.org Link: https://lore.kernel.org/r/20210308060826.3074234-19-vkoul@kernel.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/ipq6018.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi index 9fa5b028e4f3..23ee1bfa4318 100644 --- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi @@ -151,7 +151,7 @@ reserved-memory { #size-cells = <2>; ranges;
- rpm_msg_ram: memory@0x60000 { + rpm_msg_ram: memory@60000 { reg = <0x0 0x60000 0x0 0x6000>; no-map; };
From: Vinod Koul vkoul@kernel.org
[ Upstream commit 639dfdbecd88ec05bda87b1d5d419afad50af21c ]
We have underscore (_) in node name so fix that up as well.
Fix this by changing node name to use dash (-)
Signed-off-by: Vinod Koul vkoul@kernel.org Link: https://lore.kernel.org/r/20210308060826.3074234-11-vkoul@kernel.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sdm630.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi index 5b73659f2a75..06a0ae773ad5 100644 --- a/arch/arm64/boot/dts/qcom/sdm630.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi @@ -17,14 +17,14 @@ / { chosen { };
clocks { - xo_board: xo_board { + xo_board: xo-board { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <19200000>; clock-output-names = "xo_board"; };
- sleep_clk: sleep_clk { + sleep_clk: sleep-clk { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <32764>;
From: Vinod Koul vkoul@kernel.org
[ Upstream commit 8c678beca7ed3fa8a2c6d86f6603bc23400f9ad8 ]
We have underscore (_) in node name leading to warning: arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon-cityman.dt.yaml: clocks: xo_board: {'type': 'object'} is not allowed for {'compatible': ['fixed-clock'], '#clock-cells': [[0]], 'clock-frequency': [[19200000]], 'phandle': [[26]]} arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon-cityman.dt.yaml: clocks: sleep_clk: {'type': 'object'} is not allowed for {'compatible': ['fixed-clock'], '#clock-cells': [[0]], 'clock-frequency': [[32768]]}
Fix this by changing node name to use dash (-)
Signed-off-by: Vinod Koul vkoul@kernel.org Link: https://lore.kernel.org/r/20210308060826.3074234-9-vkoul@kernel.org [bjorn: Added clock-output-names to satisfy parent_names] Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8994.dtsi | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi index f9f0b5aa6a26..87a3217e88ef 100644 --- a/arch/arm64/boot/dts/qcom/msm8994.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi @@ -15,16 +15,18 @@ / { chosen { };
clocks { - xo_board: xo_board { + xo_board: xo-board { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <19200000>; + clock-output-names = "xo_board"; };
- sleep_clk: sleep_clk { + sleep_clk: sleep-clk { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <32768>; + clock-output-names = "sleep_clk"; }; };
From: Vinod Koul vkoul@kernel.org
[ Upstream commit 84f3efbe5b4654077608bc2fc027177fe4592321 ]
We have underscore (_) in node name leading to warning:
arch/arm64/boot/dts/qcom/apq8096-db820c.dt.yaml: clocks: $nodename:0: 'clocks' does not match '^([a-z][a-z0-9\-]+-bus|bus|soc|axi|ahb|apb)(@[0-9a-f]+)?$' arch/arm64/boot/dts/qcom/apq8096-db820c.dt.yaml: clocks: xo_board: {'type': 'object'} is not allowed for {'compatible': ['fixed-clock'], '#clock-cells': [[0]], 'clock-frequency': [[19200000]], 'clock-output-names': ['xo_board'], 'phandle': [[115]]}
Fix this by changing node name to use dash (-)
Signed-off-by: Vinod Koul vkoul@kernel.org Link: https://lore.kernel.org/r/20210308060826.3074234-10-vkoul@kernel.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8996.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index ce430ba9c118..957487f84ead 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -17,14 +17,14 @@ / { chosen { };
clocks { - xo_board: xo_board { + xo_board: xo-board { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <19200000>; clock-output-names = "xo_board"; };
- sleep_clk: sleep_clk { + sleep_clk: sleep-clk { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <32764>;
From: Georgi Djakov georgi.djakov@linaro.org
[ Upstream commit 77b53d65dc1e54321ec841912f06bcb558a079c0 ]
The unit address of the epss_l3 node is incorrect and does not match the address of its "reg" property. Let's fix it.
Signed-off-by: Georgi Djakov georgi.djakov@linaro.org Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Sibi Sankar sibis@codeaurora.org Link: https://lore.kernel.org/r/20210211193637.9737-1-georgi.djakov@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sm8250.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi index 1316bea3eab5..6d28bfd9a8f5 100644 --- a/arch/arm64/boot/dts/qcom/sm8250.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi @@ -3773,7 +3773,7 @@ apps_bcm_voter: bcm_voter { }; };
- epss_l3: interconnect@18591000 { + epss_l3: interconnect@18590000 { compatible = "qcom,sm8250-epss-l3"; reg = <0 0x18590000 0 0x1000>;
From: Rajendra Nayak rnayak@codeaurora.org
[ Upstream commit 11c4b3e264d68ba6dcd52d12dbcfd3f564f2f137 ]
qfprom_disable_fuse_blowing() disables a bunch of resources, and then does a few register writes in the 'conf' address space. It works perhaps because the resources are needed only for the 'raw' register space writes, and that the 'conf' space allows read/writes regardless. However that makes the code look confusing, so just move the register writes before turning off the resources in the function.
Reviewed-by: Douglas Anderson dianders@chromium.org Signed-off-by: Rajendra Nayak rnayak@codeaurora.org Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20210806085947.22682-3-srinivas.kandagatla@linaro.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvmem/qfprom.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/nvmem/qfprom.c b/drivers/nvmem/qfprom.c index d6d3f24685a8..f372eda2b255 100644 --- a/drivers/nvmem/qfprom.c +++ b/drivers/nvmem/qfprom.c @@ -138,6 +138,9 @@ static void qfprom_disable_fuse_blowing(const struct qfprom_priv *priv, { int ret;
+ writel(old->timer_val, priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET); + writel(old->accel_val, priv->qfpconf + QFPROM_ACCEL_OFFSET); + /* * This may be a shared rail and may be able to run at a lower rate * when we're not blowing fuses. At the moment, the regulator framework @@ -158,9 +161,6 @@ static void qfprom_disable_fuse_blowing(const struct qfprom_priv *priv, "Failed to set clock rate for disable (ignoring)\n");
clk_disable_unprepare(priv->secclk); - - writel(old->timer_val, priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET); - writel(old->accel_val, priv->qfpconf + QFPROM_ACCEL_OFFSET); }
/**
From: Nathan Chancellor nathan@kernel.org
[ Upstream commit 4367355dd90942a71641c98c40c74589c9bddf90 ]
When compiling with clang in certain configurations, an objtool warning appears:
drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.o: warning: objtool: ipq806x_gmac_probe() falls through to next function phy_modes()
This happens because the unreachable annotation in the third switch statement is not eliminated. The compiler should know that the first default case would prevent the second and third from being reached as the comment notes but sanitizer options can make it harder for the compiler to reason this out.
Help the compiler out by eliminating the unreachable() annotation and unifying the default case error handling so that there is no objtool warning, the meaning of the code stays the same, and there is less duplication.
Reported-by: Sami Tolvanen samitolvanen@google.com Tested-by: Sami Tolvanen samitolvanen@google.com Signed-off-by: Nathan Chancellor nathan@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- .../ethernet/stmicro/stmmac/dwmac-ipq806x.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c index 28dd0ed85a82..f7dc8458cde8 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c @@ -289,10 +289,7 @@ static int ipq806x_gmac_probe(struct platform_device *pdev) val &= ~NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL; break; default: - dev_err(&pdev->dev, "Unsupported PHY mode: "%s"\n", - phy_modes(gmac->phy_mode)); - err = -EINVAL; - goto err_remove_config_dt; + goto err_unsupported_phy; } regmap_write(gmac->nss_common, NSS_COMMON_GMAC_CTL(gmac->id), val);
@@ -309,10 +306,7 @@ static int ipq806x_gmac_probe(struct platform_device *pdev) NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id); break; default: - dev_err(&pdev->dev, "Unsupported PHY mode: "%s"\n", - phy_modes(gmac->phy_mode)); - err = -EINVAL; - goto err_remove_config_dt; + goto err_unsupported_phy; } regmap_write(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, val);
@@ -329,8 +323,7 @@ static int ipq806x_gmac_probe(struct platform_device *pdev) NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id); break; default: - /* We don't get here; the switch above will have errored out */ - unreachable(); + goto err_unsupported_phy; } regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
@@ -361,6 +354,11 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
return 0;
+err_unsupported_phy: + dev_err(&pdev->dev, "Unsupported PHY mode: "%s"\n", + phy_modes(gmac->phy_mode)); + err = -EINVAL; + err_remove_config_dt: stmmac_remove_config_dt(pdev, plat_dat);
From: David Heidelberg david@ixit.cz
[ Upstream commit 56bd931ae506730c9ab1e4cc4bfefa43fc2d18fa ]
msm_atomic is doing vblank get/put's already, currently there no need to duplicate the effort in MDP4
Fix warning: ... WARNING: CPU: 3 PID: 79 at drivers/gpu/drm/drm_vblank.c:1194 drm_vblank_put+0x1cc/0x1d4 ... and multiple vblank time-outs: ... msm 5100000.mdp: vblank time out, crtc=1 ...
Tested on Nexus 7 2013 (deb), LTS 5.10.50.
Introduced by: 119ecb7fd3b5 ("drm/msm/mdp4: request vblank during modeset")
Signed-off-by: David Heidelberg david@ixit.cz Link: https://lore.kernel.org/r/20210715060925.7880-1-david@ixit.cz Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 13 ------------- 1 file changed, 13 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c index 0712752742f4..1f12bccee2b8 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -89,13 +89,6 @@ static void mdp4_disable_commit(struct msm_kms *kms)
static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state) { - int i; - struct drm_crtc *crtc; - struct drm_crtc_state *crtc_state; - - /* see 119ecb7fd */ - for_each_new_crtc_in_state(state, crtc, crtc_state, i) - drm_crtc_vblank_get(crtc); }
static void mdp4_flush_commit(struct msm_kms *kms, unsigned crtc_mask) @@ -114,12 +107,6 @@ static void mdp4_wait_flush(struct msm_kms *kms, unsigned crtc_mask)
static void mdp4_complete_commit(struct msm_kms *kms, unsigned crtc_mask) { - struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); - struct drm_crtc *crtc; - - /* see 119ecb7fd */ - for_each_crtc_mask(mdp4_kms->dev, crtc, crtc_mask) - drm_crtc_vblank_put(crtc); }
static long mdp4_round_pixclk(struct msm_kms *kms, unsigned long rate,
From: Konrad Dybcio konrad.dybcio@somainline.org
[ Upstream commit 462f7017a6918d152870bfb8852f3c70fd74b296 ]
VDDA is not present and the specified load value is wrong. Fix it.
Signed-off-by: Konrad Dybcio konrad.dybcio@somainline.org Link: https://lore.kernel.org/r/20210728222057.52641-1-konrad.dybcio@somainline.or... Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dsi/dsi_cfg.c | 1 - drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c index f3f1c03c7db9..763f127e4621 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c @@ -154,7 +154,6 @@ static const struct msm_dsi_config sdm660_dsi_cfg = { .reg_cfg = { .num = 2, .regs = { - {"vdd", 73400, 32 }, /* 0.9 V */ {"vdda", 12560, 4 }, /* 1.2 V */ }, }, diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index 65d68eb9e3cb..c96fd752fa1d 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -1049,7 +1049,7 @@ const struct msm_dsi_phy_cfg dsi_phy_14nm_660_cfgs = { .reg_cfg = { .num = 1, .regs = { - {"vcca", 17000, 32}, + {"vcca", 73400, 32}, }, }, .ops = {
From: Quanyang Wang quanyang.wang@windriver.com
[ Upstream commit a19effb6dbe5bd1be77a6d68eba04dba8993ffeb ]
The Runtime PM subsystem will force the device "fd4a0000.zynqmp-display" to enter suspend state while booting if the following conditions are met: - the usage counter is zero (pm_runtime_get_sync hasn't been called yet) - no 'active' children (no zynqmp-dp-snd-xx node under dpsub node) - no other device in the same power domain (dpdma node has no "power-domains = <&zynqmp_firmware PD_DP>" property)
So there is a scenario as below: 1) DP device enters suspend state <- call zynqmp_gpd_power_off 2) zynqmp_disp_crtc_setup_clock <- configurate register VPLL_FRAC_CFG 3) pm_runtime_get_sync <- call zynqmp_gpd_power_on and clear previous VPLL_FRAC_CFG configuration 4) clk_prepare_enable(disp->pclk) <- enable failed since VPLL_FRAC_CFG configuration is corrupted
From above, we can see that pm_runtime_get_sync may clear register
VPLL_FRAC_CFG configuration and result the failure of clk enabling. Putting pm_runtime_get_sync at the very beginning of the function zynqmp_disp_crtc_atomic_enable can resolve this issue.
Signed-off-by: Quanyang Wang quanyang.wang@windriver.com Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/xlnx/zynqmp_disp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c index 109d627968ac..01c6ce7784dd 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_disp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c @@ -1452,9 +1452,10 @@ zynqmp_disp_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; int ret, vrefresh;
+ pm_runtime_get_sync(disp->dev); + zynqmp_disp_crtc_setup_clock(crtc, adjusted_mode);
- pm_runtime_get_sync(disp->dev); ret = clk_prepare_enable(disp->pclk); if (ret) { dev_err(disp->dev, "failed to enable a pixel clock\n");
From: Quanyang Wang quanyang.wang@windriver.com
[ Upstream commit a338619bd76011035d462f0f9e8b2f24d7fe5a1e ]
When insmod zynqmp-dpsub.ko after rmmod it, system will hang with the error log as below:
root@xilinx-zynqmp:~# insmod zynqmp-dpsub.ko [ 88.391289] [drm] Initialized zynqmp-dpsub 1.0.0 20130509 for fd4a0000.display on minor 0 [ 88.529906] Console: switching to colour frame buffer device 128x48 [ 88.549402] zynqmp-dpsub fd4a0000.display: [drm] fb0: zynqmp-dpsubdrm frame buffer device [ 88.571624] zynqmp-dpsub fd4a0000.display: ZynqMP DisplayPort Subsystem driver probed root@xilinx-zynqmp:~# rmmod zynqmp_dpsub [ 94.023404] Console: switching to colour dummy device 80x25 root@xilinx-zynqmp:~# insmod zynqmp-dpsub.ko <hang here>
This is because that in zynqmp_dp_probe it tries to access some DP registers while the DP controller is still in the reset state. When running "rmmod zynqmp_dpsub", zynqmp_dp_reset(dp, true) in zynqmp_dp_phy_exit is called to force the DP controller into the reset state. Then insmod will call zynqmp_dp_probe to program the DP registers, but at this moment the DP controller hasn't been brought out of the reset state yet since the function zynqmp_dp_reset(dp, false) is called later and this will result the system hang.
Releasing the reset to DP controller before any read/write operation to it will fix this issue. And for symmetry, move zynqmp_dp_reset() call from zynqmp_dp_phy_exit() to zynqmp_dp_remove().
Signed-off-by: Quanyang Wang quanyang.wang@windriver.com Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/xlnx/zynqmp_dp.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c index 59d1fb017da0..13811332b349 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c @@ -402,10 +402,6 @@ static int zynqmp_dp_phy_init(struct zynqmp_dp *dp) } }
- ret = zynqmp_dp_reset(dp, false); - if (ret < 0) - return ret; - zynqmp_dp_clr(dp, ZYNQMP_DP_PHY_RESET, ZYNQMP_DP_PHY_RESET_ALL_RESET);
/* @@ -441,8 +437,6 @@ static void zynqmp_dp_phy_exit(struct zynqmp_dp *dp) ret); }
- zynqmp_dp_reset(dp, true); - for (i = 0; i < dp->num_lanes; i++) { ret = phy_exit(dp->phy[i]); if (ret) @@ -1682,9 +1676,13 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub, struct drm_device *drm) return PTR_ERR(dp->reset); }
+ ret = zynqmp_dp_reset(dp, false); + if (ret < 0) + return ret; + ret = zynqmp_dp_phy_probe(dp); if (ret) - return ret; + goto err_reset;
/* Initialize the hardware. */ zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN, @@ -1696,7 +1694,7 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub, struct drm_device *drm)
ret = zynqmp_dp_phy_init(dp); if (ret) - return ret; + goto err_reset;
zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMITTER_ENABLE, 1);
@@ -1708,15 +1706,18 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub, struct drm_device *drm) zynqmp_dp_irq_handler, IRQF_ONESHOT, dev_name(dp->dev), dp); if (ret < 0) - goto error; + goto err_phy_exit;
dev_dbg(dp->dev, "ZynqMP DisplayPort Tx probed with %u lanes\n", dp->num_lanes);
return 0;
-error: +err_phy_exit: zynqmp_dp_phy_exit(dp); +err_reset: + zynqmp_dp_reset(dp, true); + return ret; }
@@ -1734,4 +1735,5 @@ void zynqmp_dp_remove(struct zynqmp_dpsub *dpsub) zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, 0xffffffff);
zynqmp_dp_phy_exit(dp); + zynqmp_dp_reset(dp, true); }
From: Sanjay R Mehta sanju.mehta@amd.com
[ Upstream commit 42716425ad7e1b6529ec61c260c11176841f4b5f ]
In tb_switch_default_link_ports(), while linking of ports, only odd-numbered ports (1,3,5..) are considered and even-numbered ports are not considered.
AMD host router has lane adapters at 2 and 3 and link ports at adapter 2 is not considered due to which lane bonding gets disabled.
Hence added a fix such that all ports are considered during linking of ports.
Signed-off-by: Basavaraj Natikar Basavaraj.Natikar@amd.com Signed-off-by: Sanjay R Mehta sanju.mehta@amd.com Signed-off-by: Mika Westerberg mika.westerberg@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thunderbolt/switch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index a82032c081e8..03229350ea73 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -2308,7 +2308,7 @@ static void tb_switch_default_link_ports(struct tb_switch *sw) { int i;
- for (i = 1; i <= sw->config.max_port_number; i += 2) { + for (i = 1; i <= sw->config.max_port_number; i++) { struct tb_port *port = &sw->ports[i]; struct tb_port *subordinate;
From: Roy Chan roy.chan@amd.com
[ Upstream commit 82367e7f22d085092728f45fd5fbb15e3fb997c0 ]
[Why] If the plane has been removed, the writeback disablement logic doesn't run
[How] fix the logic order
Acked-by: Anson Jacob Anson.Jacob@amd.com Signed-off-by: Roy Chan roy.chan@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 14 ++++++++------ drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 12 +++++++++++- 2 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index 793554e61c52..03b941e76de2 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -1703,13 +1703,15 @@ void dcn20_program_front_end_for_ctx( dcn20_program_pipe(dc, pipe, context); pipe = pipe->bottom_pipe; } - /* Program secondary blending tree and writeback pipes */ - pipe = &context->res_ctx.pipe_ctx[i]; - if (!pipe->prev_odm_pipe && pipe->stream->num_wb_info > 0 - && (pipe->update_flags.raw || pipe->plane_state->update_flags.raw || pipe->stream->update_flags.raw) - && hws->funcs.program_all_writeback_pipes_in_tree) - hws->funcs.program_all_writeback_pipes_in_tree(dc, pipe->stream, context); } + /* Program secondary blending tree and writeback pipes */ + pipe = &context->res_ctx.pipe_ctx[i]; + if (!pipe->top_pipe && !pipe->prev_odm_pipe + && pipe->stream && pipe->stream->num_wb_info > 0 + && (pipe->update_flags.raw || (pipe->plane_state && pipe->plane_state->update_flags.raw) + || pipe->stream->update_flags.raw) + && hws->funcs.program_all_writeback_pipes_in_tree) + hws->funcs.program_all_writeback_pipes_in_tree(dc, pipe->stream, context); } }
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index d53f8b39699b..37944f94c693 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -396,12 +396,22 @@ void dcn30_program_all_writeback_pipes_in_tree( for (i_pipe = 0; i_pipe < dc->res_pool->pipe_count; i_pipe++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i_pipe];
+ if (!pipe_ctx->plane_state) + continue; + if (pipe_ctx->plane_state == wb_info.writeback_source_plane) { wb_info.mpcc_inst = pipe_ctx->plane_res.mpcc_inst; break; } } - ASSERT(wb_info.mpcc_inst != -1); + + if (wb_info.mpcc_inst == -1) { + /* Disable writeback pipe and disconnect from MPCC + * if source plane has been removed + */ + dc->hwss.disable_writeback(dc, wb_info.dwb_pipe_inst); + continue; + }
ASSERT(wb_info.dwb_pipe_inst < dc->res_pool->res_cap->num_dwb); dwb = dc->res_pool->dwbc[wb_info.dwb_pipe_inst];
From: Roy Chan roy.chan@amd.com
[ Upstream commit 781e1e23131cce56fb557e6ec2260480a6bd08cc ]
[How] the programming sequeune was for old asic. the correct programming sequeunce should be similar to the one used in mpc. the fix is copied from the mpc programming sequeunce.
Reviewed-by: Anthony Koo Anthony.Koo@amd.com Acked-by: Anson Jacob Anson.Jacob@amd.com Signed-off-by: Roy Chan roy.chan@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../drm/amd/display/dc/dcn30/dcn30_dwb_cm.c | 90 +++++++++++++------ 1 file changed, 64 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c index 3fe9e41e4dbd..6a3d3a0ec0a3 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c @@ -49,6 +49,11 @@ static void dwb3_get_reg_field_ogam(struct dcn30_dwbc *dwbc30, struct dcn3_xfer_func_reg *reg) { + reg->shifts.field_region_start_base = dwbc30->dwbc_shift->DWB_OGAM_RAMA_EXP_REGION_START_BASE_B; + reg->masks.field_region_start_base = dwbc30->dwbc_mask->DWB_OGAM_RAMA_EXP_REGION_START_BASE_B; + reg->shifts.field_offset = dwbc30->dwbc_shift->DWB_OGAM_RAMA_OFFSET_B; + reg->masks.field_offset = dwbc30->dwbc_mask->DWB_OGAM_RAMA_OFFSET_B; + reg->shifts.exp_region0_lut_offset = dwbc30->dwbc_shift->DWB_OGAM_RAMA_EXP_REGION0_LUT_OFFSET; reg->masks.exp_region0_lut_offset = dwbc30->dwbc_mask->DWB_OGAM_RAMA_EXP_REGION0_LUT_OFFSET; reg->shifts.exp_region0_num_segments = dwbc30->dwbc_shift->DWB_OGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; @@ -66,8 +71,6 @@ static void dwb3_get_reg_field_ogam(struct dcn30_dwbc *dwbc30, reg->masks.field_region_end_base = dwbc30->dwbc_mask->DWB_OGAM_RAMA_EXP_REGION_END_BASE_B; reg->shifts.field_region_linear_slope = dwbc30->dwbc_shift->DWB_OGAM_RAMA_EXP_REGION_START_SLOPE_B; reg->masks.field_region_linear_slope = dwbc30->dwbc_mask->DWB_OGAM_RAMA_EXP_REGION_START_SLOPE_B; - reg->masks.field_offset = dwbc30->dwbc_mask->DWB_OGAM_RAMA_OFFSET_B; - reg->shifts.field_offset = dwbc30->dwbc_shift->DWB_OGAM_RAMA_OFFSET_B; reg->shifts.exp_region_start = dwbc30->dwbc_shift->DWB_OGAM_RAMA_EXP_REGION_START_B; reg->masks.exp_region_start = dwbc30->dwbc_mask->DWB_OGAM_RAMA_EXP_REGION_START_B; reg->shifts.exp_resion_start_segment = dwbc30->dwbc_shift->DWB_OGAM_RAMA_EXP_REGION_START_SEGMENT_B; @@ -147,18 +150,19 @@ static enum dc_lut_mode dwb3_get_ogam_current( uint32_t state_mode; uint32_t ram_select;
- REG_GET(DWB_OGAM_CONTROL, - DWB_OGAM_MODE, &state_mode); - REG_GET(DWB_OGAM_CONTROL, - DWB_OGAM_SELECT, &ram_select); + REG_GET_2(DWB_OGAM_CONTROL, + DWB_OGAM_MODE_CURRENT, &state_mode, + DWB_OGAM_SELECT_CURRENT, &ram_select);
if (state_mode == 0) { mode = LUT_BYPASS; } else if (state_mode == 2) { if (ram_select == 0) mode = LUT_RAM_A; - else + else if (ram_select == 1) mode = LUT_RAM_B; + else + mode = LUT_BYPASS; } else { // Reserved value mode = LUT_BYPASS; @@ -172,10 +176,10 @@ static void dwb3_configure_ogam_lut( struct dcn30_dwbc *dwbc30, bool is_ram_a) { - REG_UPDATE(DWB_OGAM_LUT_CONTROL, - DWB_OGAM_LUT_READ_COLOR_SEL, 7); - REG_UPDATE(DWB_OGAM_CONTROL, - DWB_OGAM_SELECT, is_ram_a == true ? 0 : 1); + REG_UPDATE_2(DWB_OGAM_LUT_CONTROL, + DWB_OGAM_LUT_WRITE_COLOR_MASK, 7, + DWB_OGAM_LUT_HOST_SEL, (is_ram_a == true) ? 0 : 1); + REG_SET(DWB_OGAM_LUT_INDEX, 0, DWB_OGAM_LUT_INDEX, 0); }
@@ -185,17 +189,45 @@ static void dwb3_program_ogam_pwl(struct dcn30_dwbc *dwbc30, { uint32_t i;
- // triple base implementation - for (i = 0; i < num/2; i++) { - REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[2*i+0].red_reg); - REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[2*i+0].green_reg); - REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[2*i+0].blue_reg); - REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[2*i+1].red_reg); - REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[2*i+1].green_reg); - REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[2*i+1].blue_reg); - REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[2*i+2].red_reg); - REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[2*i+2].green_reg); - REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[2*i+2].blue_reg); + uint32_t last_base_value_red = rgb[num-1].red_reg + rgb[num-1].delta_red_reg; + uint32_t last_base_value_green = rgb[num-1].green_reg + rgb[num-1].delta_green_reg; + uint32_t last_base_value_blue = rgb[num-1].blue_reg + rgb[num-1].delta_blue_reg; + + if (is_rgb_equal(rgb, num)) { + for (i = 0 ; i < num; i++) + REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[i].red_reg); + + REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, last_base_value_red); + + } else { + + REG_UPDATE(DWB_OGAM_LUT_CONTROL, + DWB_OGAM_LUT_WRITE_COLOR_MASK, 4); + + for (i = 0 ; i < num; i++) + REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[i].red_reg); + + REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, last_base_value_red); + + REG_SET(DWB_OGAM_LUT_INDEX, 0, DWB_OGAM_LUT_INDEX, 0); + + REG_UPDATE(DWB_OGAM_LUT_CONTROL, + DWB_OGAM_LUT_WRITE_COLOR_MASK, 2); + + for (i = 0 ; i < num; i++) + REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[i].green_reg); + + REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, last_base_value_green); + + REG_SET(DWB_OGAM_LUT_INDEX, 0, DWB_OGAM_LUT_INDEX, 0); + + REG_UPDATE(DWB_OGAM_LUT_CONTROL, + DWB_OGAM_LUT_WRITE_COLOR_MASK, 1); + + for (i = 0 ; i < num; i++) + REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[i].blue_reg); + + REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, last_base_value_blue); } }
@@ -211,6 +243,8 @@ static bool dwb3_program_ogam_lut( return false; }
+ REG_SET(DWB_OGAM_CONTROL, 0, DWB_OGAM_MODE, 2); + current_mode = dwb3_get_ogam_current(dwbc30); if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A) next_mode = LUT_RAM_B; @@ -227,8 +261,7 @@ static bool dwb3_program_ogam_lut( dwb3_program_ogam_pwl( dwbc30, params->rgb_resulted, params->hw_points_num);
- REG_SET(DWB_OGAM_CONTROL, 0, DWB_OGAM_MODE, 2); - REG_SET(DWB_OGAM_CONTROL, 0, DWB_OGAM_SELECT, next_mode == LUT_RAM_A ? 0 : 1); + REG_UPDATE(DWB_OGAM_CONTROL, DWB_OGAM_SELECT, next_mode == LUT_RAM_A ? 0 : 1);
return true; } @@ -271,14 +304,19 @@ static void dwb3_program_gamut_remap(
struct color_matrices_reg gam_regs;
- REG_UPDATE(DWB_GAMUT_REMAP_COEF_FORMAT, DWB_GAMUT_REMAP_COEF_FORMAT, coef_format); - if (regval == NULL || select == CM_GAMUT_REMAP_MODE_BYPASS) { REG_SET(DWB_GAMUT_REMAP_MODE, 0, DWB_GAMUT_REMAP_MODE, 0); return; }
+ REG_UPDATE(DWB_GAMUT_REMAP_COEF_FORMAT, DWB_GAMUT_REMAP_COEF_FORMAT, coef_format); + + gam_regs.shifts.csc_c11 = dwbc30->dwbc_shift->DWB_GAMUT_REMAPA_C11; + gam_regs.masks.csc_c11 = dwbc30->dwbc_mask->DWB_GAMUT_REMAPA_C11; + gam_regs.shifts.csc_c12 = dwbc30->dwbc_shift->DWB_GAMUT_REMAPA_C12; + gam_regs.masks.csc_c12 = dwbc30->dwbc_mask->DWB_GAMUT_REMAPA_C12; + switch (select) { case CM_GAMUT_REMAP_MODE_RAMA_COEFF: gam_regs.csc_c11_c12 = REG(DWB_GAMUT_REMAPA_C11_C12);
From: Jussi Maki joamaki@gmail.com
[ Upstream commit 95413846cca37f20000dd095cf6d91f8777129d7 ]
The program type cannot be deduced from 'tx' which causes an invalid argument error when trying to load xdp_tx.o using the skeleton. Rename the section name to "xdp" so that libbpf can deduce the type.
Signed-off-by: Jussi Maki joamaki@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20210731055738.16820-7-joamaki@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/progs/xdp_tx.c | 2 +- tools/testing/selftests/bpf/test_xdp_veth.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/bpf/progs/xdp_tx.c b/tools/testing/selftests/bpf/progs/xdp_tx.c index 94e6c2b281cb..5f725c720e00 100644 --- a/tools/testing/selftests/bpf/progs/xdp_tx.c +++ b/tools/testing/selftests/bpf/progs/xdp_tx.c @@ -3,7 +3,7 @@ #include <linux/bpf.h> #include <bpf/bpf_helpers.h>
-SEC("tx") +SEC("xdp") int xdp_tx(struct xdp_md *xdp) { return XDP_TX; diff --git a/tools/testing/selftests/bpf/test_xdp_veth.sh b/tools/testing/selftests/bpf/test_xdp_veth.sh index ba8ffcdaac30..995278e684b6 100755 --- a/tools/testing/selftests/bpf/test_xdp_veth.sh +++ b/tools/testing/selftests/bpf/test_xdp_veth.sh @@ -108,7 +108,7 @@ ip link set dev veth2 xdp pinned $BPF_DIR/progs/redirect_map_1 ip link set dev veth3 xdp pinned $BPF_DIR/progs/redirect_map_2
ip -n ns1 link set dev veth11 xdp obj xdp_dummy.o sec xdp_dummy -ip -n ns2 link set dev veth22 xdp obj xdp_tx.o sec tx +ip -n ns2 link set dev veth22 xdp obj xdp_tx.o sec xdp ip -n ns3 link set dev veth33 xdp obj xdp_dummy.o sec xdp_dummy
trap cleanup EXIT
From: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com
[ Upstream commit 2bc5da528dd570c5ecabc107e6fbdbc55974276f ]
drm_file.master should be protected by either drm_device.master_mutex or drm_file.master_lookup_lock when being dereferenced. However, drm_master_get is called on unprotected file_priv->master pointers in vmw_surface_define_ioctl and vmw_gb_surface_define_internal.
This is fixed by replacing drm_master_get with drm_file_get_master.
Signed-off-by: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch Reviewed-by: Zack Rusin zackr@vmware.com Signed-off-by: Zack Rusin zackr@vmware.com Link: https://patchwork.freedesktop.org/patch/msgid/20210724111824.59266-4-desmond... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index 5ff88f8c2382..0c62cd400b64 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -869,7 +869,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, user_srf->prime.base.shareable = false; user_srf->prime.base.tfile = NULL; if (drm_is_primary_client(file_priv)) - user_srf->master = drm_master_get(file_priv->master); + user_srf->master = drm_file_get_master(file_priv);
/** * From this point, the generic resource management functions @@ -1540,7 +1540,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev,
user_srf = container_of(srf, struct vmw_user_surface, srf); if (drm_is_primary_client(file_priv)) - user_srf->master = drm_master_get(file_priv->master); + user_srf->master = drm_file_get_master(file_priv);
ret = ttm_read_lock(&dev_priv->reservation_sem, true); if (unlikely(ret != 0))
From: Fabio Aiuto fabioaiuto83@gmail.com
[ Upstream commit e3678dc1ea40425b7218c20e2fe7b00a72f23a41 ]
TxNum value is compared against ODM_RF_PATH_D, which is inconsistent. Compare it against RF_MAX_TX_NUM, as in other places in the same file.
Signed-off-by: Fabio Aiuto fabioaiuto83@gmail.com Link: https://lore.kernel.org/r/147631fe6f4f5de84cc54a62ba71d739b92697be.162832934... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/rtl8723bs/hal/hal_com_phycfg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c b/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c index 94d11689b4ac..33ff80da3277 100644 --- a/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c +++ b/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c @@ -707,7 +707,7 @@ static void PHY_StoreTxPowerByRateNew( if (RfPath > ODM_RF_PATH_D) return;
- if (TxNum > ODM_RF_PATH_D) + if (TxNum > RF_MAX_TX_NUM) return;
for (i = 0; i < rateNum; ++i) {
From: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com
[ Upstream commit ba316be1b6a00db7126ed9a39f9bee434a508043 ]
struct sock.sk_timer should be used as a sock cleanup timer. However, SCO uses it to implement sock timeouts.
This causes issues because struct sock.sk_timer's callback is run in an IRQ context, and the timer callback function sco_sock_timeout takes a spin lock on the socket. However, other functions such as sco_conn_del and sco_conn_ready take the spin lock with interrupts enabled.
This inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} lock usage could lead to deadlocks as reported by Syzbot [1]: CPU0 ---- lock(slock-AF_BLUETOOTH-BTPROTO_SCO); <Interrupt> lock(slock-AF_BLUETOOTH-BTPROTO_SCO);
To fix this, we use delayed work to implement SCO sock timouts instead. This allows us to avoid taking the spin lock on the socket in an IRQ context, and corrects the misuse of struct sock.sk_timer.
As a note, cancel_delayed_work is used instead of cancel_delayed_work_sync in sco_sock_set_timer and sco_sock_clear_timer to avoid a deadlock. In the future, the call to bh_lock_sock inside sco_sock_timeout should be changed to lock_sock to synchronize with other functions using lock_sock. However, since sco_sock_set_timer and sco_sock_clear_timer are sometimes called under the locked socket (in sco_connect and __sco_sock_close), cancel_delayed_work_sync might cause them to sleep until an sco_sock_timeout that has started finishes running. But sco_sock_timeout would also sleep until it can grab the lock_sock.
Using cancel_delayed_work is fine because sco_sock_timeout does not change from run to run, hence there is no functional difference between: 1. waiting for a timeout to finish running before scheduling another timeout 2. scheduling another timeout while a timeout is running.
Link: https://syzkaller.appspot.com/bug?id=9089d89de0502e120f234ca0fc8a703f7368b31... [1] Reported-by: syzbot+2f6d7c28bb4bf7e82060@syzkaller.appspotmail.com Tested-by: syzbot+2f6d7c28bb4bf7e82060@syzkaller.appspotmail.com Signed-off-by: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/sco.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 9769a7ceb689..04deea76b52b 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -48,6 +48,8 @@ struct sco_conn { spinlock_t lock; struct sock *sk;
+ struct delayed_work timeout_work; + unsigned int mtu; };
@@ -74,9 +76,20 @@ struct sco_pinfo { #define SCO_CONN_TIMEOUT (HZ * 40) #define SCO_DISCONN_TIMEOUT (HZ * 2)
-static void sco_sock_timeout(struct timer_list *t) +static void sco_sock_timeout(struct work_struct *work) { - struct sock *sk = from_timer(sk, t, sk_timer); + struct sco_conn *conn = container_of(work, struct sco_conn, + timeout_work.work); + struct sock *sk; + + sco_conn_lock(conn); + sk = conn->sk; + if (sk) + sock_hold(sk); + sco_conn_unlock(conn); + + if (!sk) + return;
BT_DBG("sock %p state %d", sk, sk->sk_state);
@@ -90,14 +103,21 @@ static void sco_sock_timeout(struct timer_list *t)
static void sco_sock_set_timer(struct sock *sk, long timeout) { + if (!sco_pi(sk)->conn) + return; + BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout); - sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout); + cancel_delayed_work(&sco_pi(sk)->conn->timeout_work); + schedule_delayed_work(&sco_pi(sk)->conn->timeout_work, timeout); }
static void sco_sock_clear_timer(struct sock *sk) { + if (!sco_pi(sk)->conn) + return; + BT_DBG("sock %p state %d", sk, sk->sk_state); - sk_stop_timer(sk, &sk->sk_timer); + cancel_delayed_work(&sco_pi(sk)->conn->timeout_work); }
/* ---- SCO connections ---- */ @@ -177,6 +197,9 @@ static void sco_conn_del(struct hci_conn *hcon, int err) sco_chan_del(sk, err); bh_unlock_sock(sk); sock_put(sk); + + /* Ensure no more work items will run before freeing conn. */ + cancel_delayed_work_sync(&conn->timeout_work); }
hcon->sco_data = NULL; @@ -191,6 +214,8 @@ static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, sco_pi(sk)->conn = conn; conn->sk = sk;
+ INIT_DELAYED_WORK(&conn->timeout_work, sco_sock_timeout); + if (parent) bt_accept_enqueue(parent, sk, true); } @@ -496,8 +521,6 @@ static struct sock *sco_sock_alloc(struct net *net, struct socket *sock,
sco_pi(sk)->setting = BT_VOICE_CVSD_16BIT;
- timer_setup(&sk->sk_timer, sco_sock_timeout, 0); - bt_sock_link(&sco_sk_list, sk); return sk; }
From: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com
[ Upstream commit 734bc5ff783115aa3164f4e9dd5967ae78e0a8ab ]
In a future patch, calls to bh_lock_sock in sco.c should be replaced by lock_sock now that none of the functions are run in IRQ context.
However, doing so results in a circular locking dependency:
====================================================== WARNING: possible circular locking dependency detected 5.14.0-rc4-syzkaller #0 Not tainted ------------------------------------------------------ syz-executor.2/14867 is trying to acquire lock: ffff88803e3c1120 (sk_lock-AF_BLUETOOTH-BTPROTO_SCO){+.+.}-{0:0}, at: lock_sock include/net/sock.h:1613 [inline] ffff88803e3c1120 (sk_lock-AF_BLUETOOTH-BTPROTO_SCO){+.+.}-{0:0}, at: sco_conn_del+0x12a/0x2a0 net/bluetooth/sco.c:191
but task is already holding lock: ffffffff8d2dc7c8 (hci_cb_list_lock){+.+.}-{3:3}, at: hci_disconn_cfm include/net/bluetooth/hci_core.h:1497 [inline] ffffffff8d2dc7c8 (hci_cb_list_lock){+.+.}-{3:3}, at: hci_conn_hash_flush+0xda/0x260 net/bluetooth/hci_conn.c:1608
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #2 (hci_cb_list_lock){+.+.}-{3:3}: __mutex_lock_common kernel/locking/mutex.c:959 [inline] __mutex_lock+0x12a/0x10a0 kernel/locking/mutex.c:1104 hci_connect_cfm include/net/bluetooth/hci_core.h:1482 [inline] hci_remote_features_evt net/bluetooth/hci_event.c:3263 [inline] hci_event_packet+0x2f4d/0x7c50 net/bluetooth/hci_event.c:6240 hci_rx_work+0x4f8/0xd30 net/bluetooth/hci_core.c:5122 process_one_work+0x98d/0x1630 kernel/workqueue.c:2276 worker_thread+0x658/0x11f0 kernel/workqueue.c:2422 kthread+0x3e5/0x4d0 kernel/kthread.c:319 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:295
-> #1 (&hdev->lock){+.+.}-{3:3}: __mutex_lock_common kernel/locking/mutex.c:959 [inline] __mutex_lock+0x12a/0x10a0 kernel/locking/mutex.c:1104 sco_connect net/bluetooth/sco.c:245 [inline] sco_sock_connect+0x227/0xa10 net/bluetooth/sco.c:601 __sys_connect_file+0x155/0x1a0 net/socket.c:1879 __sys_connect+0x161/0x190 net/socket.c:1896 __do_sys_connect net/socket.c:1906 [inline] __se_sys_connect net/socket.c:1903 [inline] __x64_sys_connect+0x6f/0xb0 net/socket.c:1903 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x44/0xae
-> #0 (sk_lock-AF_BLUETOOTH-BTPROTO_SCO){+.+.}-{0:0}: check_prev_add kernel/locking/lockdep.c:3051 [inline] check_prevs_add kernel/locking/lockdep.c:3174 [inline] validate_chain kernel/locking/lockdep.c:3789 [inline] __lock_acquire+0x2a07/0x54a0 kernel/locking/lockdep.c:5015 lock_acquire kernel/locking/lockdep.c:5625 [inline] lock_acquire+0x1ab/0x510 kernel/locking/lockdep.c:5590 lock_sock_nested+0xca/0x120 net/core/sock.c:3170 lock_sock include/net/sock.h:1613 [inline] sco_conn_del+0x12a/0x2a0 net/bluetooth/sco.c:191 sco_disconn_cfm+0x71/0xb0 net/bluetooth/sco.c:1202 hci_disconn_cfm include/net/bluetooth/hci_core.h:1500 [inline] hci_conn_hash_flush+0x127/0x260 net/bluetooth/hci_conn.c:1608 hci_dev_do_close+0x528/0x1130 net/bluetooth/hci_core.c:1778 hci_unregister_dev+0x1c0/0x5a0 net/bluetooth/hci_core.c:4015 vhci_release+0x70/0xe0 drivers/bluetooth/hci_vhci.c:340 __fput+0x288/0x920 fs/file_table.c:280 task_work_run+0xdd/0x1a0 kernel/task_work.c:164 exit_task_work include/linux/task_work.h:32 [inline] do_exit+0xbd4/0x2a60 kernel/exit.c:825 do_group_exit+0x125/0x310 kernel/exit.c:922 get_signal+0x47f/0x2160 kernel/signal.c:2808 arch_do_signal_or_restart+0x2a9/0x1c40 arch/x86/kernel/signal.c:865 handle_signal_work kernel/entry/common.c:148 [inline] exit_to_user_mode_loop kernel/entry/common.c:172 [inline] exit_to_user_mode_prepare+0x17d/0x290 kernel/entry/common.c:209 __syscall_exit_to_user_mode_work kernel/entry/common.c:291 [inline] syscall_exit_to_user_mode+0x19/0x60 kernel/entry/common.c:302 ret_from_fork+0x15/0x30 arch/x86/entry/entry_64.S:288
other info that might help us debug this:
Chain exists of: sk_lock-AF_BLUETOOTH-BTPROTO_SCO --> &hdev->lock --> hci_cb_list_lock
Possible unsafe locking scenario:
CPU0 CPU1 ---- ---- lock(hci_cb_list_lock); lock(&hdev->lock); lock(hci_cb_list_lock); lock(sk_lock-AF_BLUETOOTH-BTPROTO_SCO);
*** DEADLOCK ***
The issue is that the lock hierarchy should go from &hdev->lock --> hci_cb_list_lock --> sk_lock-AF_BLUETOOTH-BTPROTO_SCO. For example, one such call trace is:
hci_dev_do_close(): hci_dev_lock(); hci_conn_hash_flush(): hci_disconn_cfm(): mutex_lock(&hci_cb_list_lock); sco_disconn_cfm(): sco_conn_del(): lock_sock(sk);
However, in sco_sock_connect, we call lock_sock before calling hci_dev_lock inside sco_connect, thus inverting the lock hierarchy.
We fix this by pulling the call to hci_dev_lock out from sco_connect.
Signed-off-by: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/sco.c | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 04deea76b52b..bd0d616dbc37 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -235,44 +235,32 @@ static int sco_chan_add(struct sco_conn *conn, struct sock *sk, return err; }
-static int sco_connect(struct sock *sk) +static int sco_connect(struct hci_dev *hdev, struct sock *sk) { struct sco_conn *conn; struct hci_conn *hcon; - struct hci_dev *hdev; int err, type;
BT_DBG("%pMR -> %pMR", &sco_pi(sk)->src, &sco_pi(sk)->dst);
- hdev = hci_get_route(&sco_pi(sk)->dst, &sco_pi(sk)->src, BDADDR_BREDR); - if (!hdev) - return -EHOSTUNREACH; - - hci_dev_lock(hdev); - if (lmp_esco_capable(hdev) && !disable_esco) type = ESCO_LINK; else type = SCO_LINK;
if (sco_pi(sk)->setting == BT_VOICE_TRANSPARENT && - (!lmp_transp_capable(hdev) || !lmp_esco_capable(hdev))) { - err = -EOPNOTSUPP; - goto done; - } + (!lmp_transp_capable(hdev) || !lmp_esco_capable(hdev))) + return -EOPNOTSUPP;
hcon = hci_connect_sco(hdev, type, &sco_pi(sk)->dst, sco_pi(sk)->setting); - if (IS_ERR(hcon)) { - err = PTR_ERR(hcon); - goto done; - } + if (IS_ERR(hcon)) + return PTR_ERR(hcon);
conn = sco_conn_add(hcon); if (!conn) { hci_conn_drop(hcon); - err = -ENOMEM; - goto done; + return -ENOMEM; }
/* Update source addr of the socket */ @@ -280,7 +268,7 @@ static int sco_connect(struct sock *sk)
err = sco_chan_add(conn, sk, NULL); if (err) - goto done; + return err;
if (hcon->state == BT_CONNECTED) { sco_sock_clear_timer(sk); @@ -290,9 +278,6 @@ static int sco_connect(struct sock *sk) sco_sock_set_timer(sk, sk->sk_sndtimeo); }
-done: - hci_dev_unlock(hdev); - hci_dev_put(hdev); return err; }
@@ -585,6 +570,7 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen { struct sockaddr_sco *sa = (struct sockaddr_sco *) addr; struct sock *sk = sock->sk; + struct hci_dev *hdev; int err;
BT_DBG("sk %p", sk); @@ -599,12 +585,19 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen if (sk->sk_type != SOCK_SEQPACKET) return -EINVAL;
+ hdev = hci_get_route(&sa->sco_bdaddr, &sco_pi(sk)->src, BDADDR_BREDR); + if (!hdev) + return -EHOSTUNREACH; + hci_dev_lock(hdev); + lock_sock(sk);
/* Set destination address and psm */ bacpy(&sco_pi(sk)->dst, &sa->sco_bdaddr);
- err = sco_connect(sk); + err = sco_connect(hdev, sk); + hci_dev_unlock(hdev); + hci_dev_put(hdev); if (err) goto done;
From: Kuogee Hsieh khsieh@codeaurora.org
[ Upstream commit 4b85d405cfe938ae7ad61656484ae88dee289e3b ]
Reduce link rate and re start link training if link training 1 failed due to loss of clock recovery done to fix Link Layer CTS case 4.3.1.7. Also only update voltage and pre-emphasis swing level after link training started to fix Link Layer CTS case 4.3.1.6.
Changes in V2: -- replaced cr_status with link_status[DP_LINK_STATUS_SIZE] -- replaced dp_ctrl_any_lane_cr_done() with dp_ctrl_colco_recovery_any_ok() -- replaced dp_ctrl_any_ane_cr_lose() with !drm_dp_clock_recovery_ok()
Changes in V3: -- return failed if lane_count <= 1
Signed-off-by: Kuogee Hsieh khsieh@codeaurora.org Reviewed-by: Stephen Boyd swboyd@chromium.org Link: https://lore.kernel.org/r/1628196295-7382-3-git-send-email-khsieh@codeaurora... [remove unused cr_status variable] Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dp/dp_ctrl.c | 78 ++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 34 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index 6856223e91e1..eb63920b36e8 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -83,13 +83,6 @@ struct dp_ctrl_private { struct completion video_comp; };
-struct dp_cr_status { - u8 lane_0_1; - u8 lane_2_3; -}; - -#define DP_LANE0_1_CR_DONE 0x11 - static int dp_aux_link_configure(struct drm_dp_aux *aux, struct dp_link_info *link) { @@ -1080,7 +1073,7 @@ static int dp_ctrl_read_link_status(struct dp_ctrl_private *ctrl, }
static int dp_ctrl_link_train_1(struct dp_ctrl_private *ctrl, - struct dp_cr_status *cr, int *training_step) + int *training_step) { int tries, old_v_level, ret = 0; u8 link_status[DP_LINK_STATUS_SIZE]; @@ -1109,9 +1102,6 @@ static int dp_ctrl_link_train_1(struct dp_ctrl_private *ctrl, if (ret) return ret;
- cr->lane_0_1 = link_status[0]; - cr->lane_2_3 = link_status[1]; - if (drm_dp_clock_recovery_ok(link_status, ctrl->link->link_params.num_lanes)) { return 0; @@ -1188,7 +1178,7 @@ static void dp_ctrl_clear_training_pattern(struct dp_ctrl_private *ctrl) }
static int dp_ctrl_link_train_2(struct dp_ctrl_private *ctrl, - struct dp_cr_status *cr, int *training_step) + int *training_step) { int tries = 0, ret = 0; char pattern; @@ -1204,10 +1194,6 @@ static int dp_ctrl_link_train_2(struct dp_ctrl_private *ctrl, else pattern = DP_TRAINING_PATTERN_2;
- ret = dp_ctrl_update_vx_px(ctrl); - if (ret) - return ret; - ret = dp_catalog_ctrl_set_pattern(ctrl->catalog, pattern); if (ret) return ret; @@ -1220,8 +1206,6 @@ static int dp_ctrl_link_train_2(struct dp_ctrl_private *ctrl, ret = dp_ctrl_read_link_status(ctrl, link_status); if (ret) return ret; - cr->lane_0_1 = link_status[0]; - cr->lane_2_3 = link_status[1];
if (drm_dp_channel_eq_ok(link_status, ctrl->link->link_params.num_lanes)) { @@ -1241,7 +1225,7 @@ static int dp_ctrl_link_train_2(struct dp_ctrl_private *ctrl, static int dp_ctrl_reinitialize_mainlink(struct dp_ctrl_private *ctrl);
static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl, - struct dp_cr_status *cr, int *training_step) + int *training_step) { int ret = 0; u8 encoding = DP_SET_ANSI_8B10B; @@ -1257,7 +1241,7 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl, drm_dp_dpcd_write(ctrl->aux, DP_MAIN_LINK_CHANNEL_CODING_SET, &encoding, 1);
- ret = dp_ctrl_link_train_1(ctrl, cr, training_step); + ret = dp_ctrl_link_train_1(ctrl, training_step); if (ret) { DRM_ERROR("link training #1 failed. ret=%d\n", ret); goto end; @@ -1266,7 +1250,7 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl, /* print success info as this is a result of user initiated action */ DRM_DEBUG_DP("link training #1 successful\n");
- ret = dp_ctrl_link_train_2(ctrl, cr, training_step); + ret = dp_ctrl_link_train_2(ctrl, training_step); if (ret) { DRM_ERROR("link training #2 failed. ret=%d\n", ret); goto end; @@ -1282,7 +1266,7 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl, }
static int dp_ctrl_setup_main_link(struct dp_ctrl_private *ctrl, - struct dp_cr_status *cr, int *training_step) + int *training_step) { int ret = 0;
@@ -1297,7 +1281,7 @@ static int dp_ctrl_setup_main_link(struct dp_ctrl_private *ctrl, * a link training pattern, we have to first do soft reset. */
- ret = dp_ctrl_link_train(ctrl, cr, training_step); + ret = dp_ctrl_link_train(ctrl, training_step);
return ret; } @@ -1494,14 +1478,13 @@ static int dp_ctrl_deinitialize_mainlink(struct dp_ctrl_private *ctrl) static int dp_ctrl_link_maintenance(struct dp_ctrl_private *ctrl) { int ret = 0; - struct dp_cr_status cr; int training_step = DP_TRAINING_NONE;
dp_ctrl_push_idle(&ctrl->dp_ctrl);
ctrl->dp_ctrl.pixel_rate = ctrl->panel->dp_mode.drm_mode.clock;
- ret = dp_ctrl_setup_main_link(ctrl, &cr, &training_step); + ret = dp_ctrl_setup_main_link(ctrl, &training_step); if (ret) goto end;
@@ -1632,6 +1615,25 @@ void dp_ctrl_handle_sink_request(struct dp_ctrl *dp_ctrl) } }
+static bool dp_ctrl_clock_recovery_any_ok( + const u8 link_status[DP_LINK_STATUS_SIZE], + int lane_count) +{ + int reduced_cnt; + + if (lane_count <= 1) + return false; + + /* + * only interested in the lane number after reduced + * lane_count = 4, then only interested in 2 lanes + * lane_count = 2, then only interested in 1 lane + */ + reduced_cnt = lane_count >> 1; + + return drm_dp_clock_recovery_ok(link_status, reduced_cnt); +} + int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl) { int rc = 0; @@ -1639,7 +1641,7 @@ int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl) u32 rate = 0; int link_train_max_retries = 5; u32 const phy_cts_pixel_clk_khz = 148500; - struct dp_cr_status cr; + u8 link_status[DP_LINK_STATUS_SIZE]; unsigned int training_step;
if (!dp_ctrl) @@ -1679,19 +1681,21 @@ int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl) }
training_step = DP_TRAINING_NONE; - rc = dp_ctrl_setup_main_link(ctrl, &cr, &training_step); + rc = dp_ctrl_setup_main_link(ctrl, &training_step); if (rc == 0) { /* training completed successfully */ break; } else if (training_step == DP_TRAINING_1) { /* link train_1 failed */ - if (!dp_catalog_link_is_connected(ctrl->catalog)) { + if (!dp_catalog_link_is_connected(ctrl->catalog)) break; - } + + dp_ctrl_read_link_status(ctrl, link_status);
rc = dp_ctrl_link_rate_down_shift(ctrl); if (rc < 0) { /* already in RBR = 1.6G */ - if (cr.lane_0_1 & DP_LANE0_1_CR_DONE) { + if (dp_ctrl_clock_recovery_any_ok(link_status, + ctrl->link->link_params.num_lanes)) { /* * some lanes are ready, * reduce lane number @@ -1707,12 +1711,18 @@ int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl) } } } else if (training_step == DP_TRAINING_2) { - /* link train_2 failed, lower lane rate */ - if (!dp_catalog_link_is_connected(ctrl->catalog)) { + /* link train_2 failed */ + if (!dp_catalog_link_is_connected(ctrl->catalog)) break; - }
- rc = dp_ctrl_link_lane_down_shift(ctrl); + dp_ctrl_read_link_status(ctrl, link_status); + + if (!drm_dp_clock_recovery_ok(link_status, + ctrl->link->link_params.num_lanes)) + rc = dp_ctrl_link_rate_down_shift(ctrl); + else + rc = dp_ctrl_link_lane_down_shift(ctrl); + if (rc < 0) { /* end with failure */ break; /* lane == 1 already */
From: Kuogee Hsieh khsieh@codeaurora.org
[ Upstream commit 7948fe12d47a946fb8025a0534c900e3dd4b5839 ]
Response with correct edid checksum saved at connector after corrupted edid checksum read. This fixes Link Layer CTS cases 4.2.2.3, 4.2.2.6.
Signed-off-by: Kuogee Hsieh khsieh@codeaurora.org Reviewed-by: Stephen Boyd swboyd@chromium.org Link: https://lore.kernel.org/r/1628196295-7382-6-git-send-email-khsieh@codeaurora... Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dp/dp_panel.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c index 9cc816663668..6eeb9a14b584 100644 --- a/drivers/gpu/drm/msm/dp/dp_panel.c +++ b/drivers/gpu/drm/msm/dp/dp_panel.c @@ -272,7 +272,7 @@ static u8 dp_panel_get_edid_checksum(struct edid *edid) { struct edid *last_block; u8 *raw_edid; - bool is_edid_corrupt; + bool is_edid_corrupt = false;
if (!edid) { DRM_ERROR("invalid edid input\n"); @@ -304,7 +304,12 @@ void dp_panel_handle_sink_request(struct dp_panel *dp_panel) panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
if (panel->link->sink_request & DP_TEST_LINK_EDID_READ) { - u8 checksum = dp_panel_get_edid_checksum(dp_panel->edid); + u8 checksum; + + if (dp_panel->edid) + checksum = dp_panel_get_edid_checksum(dp_panel->edid); + else + checksum = dp_panel->connector->real_edid_checksum;
dp_link_send_edid_checksum(panel->link, checksum); dp_link_send_test_response(panel->link);
From: Kuogee Hsieh khsieh@codeaurora.org
[ Upstream commit 2e0adc765d884cc080baa501e250bfad97035b09 ]
Initialize both pre-emphasis and voltage swing level to 0 before start link training and do not end link training until video is ready to reduce the period between end of link training and video start to meet Link Layer CTS requirement. Some dongle main link symbol may become unlocked again if host did not end link training soon enough after completion of link training 2. Host have to re train main link if loss of symbol locked detected before end link training so that the coming video stream can be transmitted to sink properly. This fixes Link Layer CTS cases 4.3.2.1, 4.3.2.2, 4.3.2.3 and 4.3.2.4.
Changes in v3: -- merge retrain link if loss of symbol locked happen into this patch -- replace dp_ctrl_loss_symbol_lock() with dp_ctrl_channel_eq_ok()
Signed-off-by: Kuogee Hsieh khsieh@codeaurora.org Reviewed-by: Stephen Boyd swboyd@chromium.org Link: https://lore.kernel.org/r/1628196295-7382-7-git-send-email-khsieh@codeaurora... Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dp/dp_ctrl.c | 56 +++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index eb63920b36e8..c1514f2cb409 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -1482,6 +1482,9 @@ static int dp_ctrl_link_maintenance(struct dp_ctrl_private *ctrl)
dp_ctrl_push_idle(&ctrl->dp_ctrl);
+ ctrl->link->phy_params.p_level = 0; + ctrl->link->phy_params.v_level = 0; + ctrl->dp_ctrl.pixel_rate = ctrl->panel->dp_mode.drm_mode.clock;
ret = dp_ctrl_setup_main_link(ctrl, &training_step); @@ -1634,6 +1637,16 @@ static bool dp_ctrl_clock_recovery_any_ok( return drm_dp_clock_recovery_ok(link_status, reduced_cnt); }
+static bool dp_ctrl_channel_eq_ok(struct dp_ctrl_private *ctrl) +{ + u8 link_status[DP_LINK_STATUS_SIZE]; + int num_lanes = ctrl->link->link_params.num_lanes; + + dp_ctrl_read_link_status(ctrl, link_status); + + return drm_dp_channel_eq_ok(link_status, num_lanes); +} + int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl) { int rc = 0; @@ -1668,6 +1681,9 @@ int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl) ctrl->link->link_params.rate, ctrl->link->link_params.num_lanes, ctrl->dp_ctrl.pixel_rate);
+ ctrl->link->phy_params.p_level = 0; + ctrl->link->phy_params.v_level = 0; + rc = dp_ctrl_enable_mainlink_clocks(ctrl); if (rc) return rc; @@ -1733,17 +1749,19 @@ int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl) if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) return rc;
- /* stop txing train pattern */ - dp_ctrl_clear_training_pattern(ctrl); + if (rc == 0) { /* link train successfully */ + /* + * do not stop train pattern here + * stop link training at on_stream + * to pass compliance test + */ + } else { + /* + * link training failed + * end txing train pattern here + */ + dp_ctrl_clear_training_pattern(ctrl);
- /* - * keep transmitting idle pattern until video ready - * to avoid main link from loss of sync - */ - if (rc == 0) /* link train successfully */ - dp_ctrl_push_idle(dp_ctrl); - else { - /* link training failed */ dp_ctrl_deinitialize_mainlink(ctrl); rc = -ECONNRESET; } @@ -1751,9 +1769,15 @@ int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl) return rc; }
+static int dp_ctrl_link_retrain(struct dp_ctrl_private *ctrl) +{ + int training_step = DP_TRAINING_NONE; + + return dp_ctrl_setup_main_link(ctrl, &training_step); +} + int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl) { - u32 rate = 0; int ret = 0; bool mainlink_ready = false; struct dp_ctrl_private *ctrl; @@ -1763,10 +1787,6 @@ int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl)
ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
- rate = ctrl->panel->link_info.rate; - - ctrl->link->link_params.rate = rate; - ctrl->link->link_params.num_lanes = ctrl->panel->link_info.num_lanes; ctrl->dp_ctrl.pixel_rate = ctrl->panel->dp_mode.drm_mode.clock;
DRM_DEBUG_DP("rate=%d, num_lanes=%d, pixel_rate=%d\n", @@ -1781,6 +1801,12 @@ int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl) } }
+ if (!dp_ctrl_channel_eq_ok(ctrl)) + dp_ctrl_link_retrain(ctrl); + + /* stop txing train pattern to end link training */ + dp_ctrl_clear_training_pattern(ctrl); + ret = dp_ctrl_enable_stream_clocks(ctrl); if (ret) { DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret);
From: Eran Ben Elisha eranbe@nvidia.com
[ Upstream commit 979aa51967add26b37f9d77e01729d44a2da8e5f ]
Fix the following smatch warning: wait_func_handle_exec_timeout() warn: should '1 << ent->idx' be a 64 bit type?
Use 1ULL, to have a 64 bit type variable.
Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Eran Ben Elisha eranbe@nvidia.com Reviewed-by: Moshe Shemesh moshe@nvidia.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c index 9d79c5ec31e9..db5dfff585c9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c @@ -877,7 +877,7 @@ static void cb_timeout_handler(struct work_struct *work) ent->ret = -ETIMEDOUT; mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) Async, timeout. Will cause a leak of a command resource\n", ent->idx, mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in)); - mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true); + mlx5_cmd_comp_handler(dev, 1ULL << ent->idx, true);
out: cmd_ent_put(ent); /* for the cmd_ent_get() took on schedule delayed work */ @@ -994,7 +994,7 @@ static void cmd_work_handler(struct work_struct *work) MLX5_SET(mbox_out, ent->out, status, status); MLX5_SET(mbox_out, ent->out, syndrome, drv_synd);
- mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true); + mlx5_cmd_comp_handler(dev, 1ULL << ent->idx, true); return; }
@@ -1008,7 +1008,7 @@ static void cmd_work_handler(struct work_struct *work) poll_timeout(ent); /* make sure we read the descriptor after ownership is SW */ rmb(); - mlx5_cmd_comp_handler(dev, 1UL << ent->idx, (ent->ret == -ETIMEDOUT)); + mlx5_cmd_comp_handler(dev, 1ULL << ent->idx, (ent->ret == -ETIMEDOUT)); } }
@@ -1068,7 +1068,7 @@ static void wait_func_handle_exec_timeout(struct mlx5_core_dev *dev, mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in));
ent->ret = -ETIMEDOUT; - mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true); + mlx5_cmd_comp_handler(dev, 1ULL << ent->idx, true); }
static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent)
From: Tuo Li islituo@gmail.com
[ Upstream commit a211260c34cfadc6068fece8c9e99e0fe1e2a2b6 ]
The variable val is declared without initialization, and its address is passed to amdgpu_i2c_get_byte(). In this function, the value of val is accessed in: DRM_DEBUG("i2c 0x%02x 0x%02x read failed\n", addr, *val);
Also, when amdgpu_i2c_get_byte() returns, val may remain uninitialized, but it is accessed in: val &= ~amdgpu_connector->router.ddc_mux_control_pin;
To fix this possible uninitialized-variable access, initialize val to 0 in amdgpu_i2c_router_select_ddc_port().
Reported-by: TOTE Robot oslab@tsinghua.edu.cn Signed-off-by: Tuo Li islituo@gmail.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c index bca4dddd5a15..82608df43396 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c @@ -339,7 +339,7 @@ static void amdgpu_i2c_put_byte(struct amdgpu_i2c_chan *i2c_bus, void amdgpu_i2c_router_select_ddc_port(const struct amdgpu_connector *amdgpu_connector) { - u8 val; + u8 val = 0;
if (!amdgpu_connector->router.ddc_valid) return;
From: Tuo Li islituo@gmail.com
[ Upstream commit 554594567b1fa3da74f88ec7b2dc83d000c58e98 ]
The variable dc->clk_mgr is checked in: if (dc->clk_mgr && dc->clk_mgr->funcs->get_clock)
This indicates dc->clk_mgr can be NULL. However, it is dereferenced in: if (!dc->clk_mgr->funcs->get_clock)
To fix this null-pointer dereference, check dc->clk_mgr and the function pointer dc->clk_mgr->funcs->get_clock earlier, and return if one of them is NULL.
Reported-by: TOTE Robot oslab@tsinghua.edu.cn Signed-off-by: Tuo Li islituo@gmail.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 7c939c0a977b..29f61a8d3e29 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -3938,13 +3938,12 @@ enum dc_status dcn10_set_clock(struct dc *dc, struct dc_clock_config clock_cfg = {0}; struct dc_clocks *current_clocks = &context->bw_ctx.bw.dcn.clk;
- if (dc->clk_mgr && dc->clk_mgr->funcs->get_clock) - dc->clk_mgr->funcs->get_clock(dc->clk_mgr, - context, clock_type, &clock_cfg); - - if (!dc->clk_mgr->funcs->get_clock) + if (!dc->clk_mgr || !dc->clk_mgr->funcs->get_clock) return DC_FAIL_UNSUPPORTED_1;
+ dc->clk_mgr->funcs->get_clock(dc->clk_mgr, + context, clock_type, &clock_cfg); + if (clk_khz > clock_cfg.max_clock_khz) return DC_FAIL_CLK_EXCEED_MAX;
@@ -3962,7 +3961,7 @@ enum dc_status dcn10_set_clock(struct dc *dc, else return DC_ERROR_UNEXPECTED;
- if (dc->clk_mgr && dc->clk_mgr->funcs->update_clocks) + if (dc->clk_mgr->funcs->update_clocks) dc->clk_mgr->funcs->update_clocks(dc->clk_mgr, context, true); return DC_OK;
From: Johan Almbladh johan.almbladh@anyfinetworks.com
[ Upstream commit 79f5962baea74ce1cd4e5949598944bff854b166 ]
The maximum MTU was set to 2304, which is the maximum MSDU size. While this is valid for normal WLAN interfaces, it is too low for monitor interfaces. A monitor interface may receive and inject MPDU frames, and the maximum MPDU frame size is larger than 2304. The MPDU may also contain an A-MSDU frame, in which case the size may be much larger than the MTU limit. Since the maximum size of an A-MSDU depends on the PHY mode of the transmitting STA, it is not possible to set an exact MTU limit for a monitor interface. Now the maximum MTU for a monitor interface is unrestricted.
Signed-off-by: Johan Almbladh johan.almbladh@anyfinetworks.com Link: https://lore.kernel.org/r/20210628123246.2070558-1-johan.almbladh@anyfinetwo... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/iface.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 137fa4c50e07..8df7ab34911c 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1985,9 +1985,16 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops);
- /* MTU range: 256 - 2304 */ + /* MTU range is normally 256 - 2304, where the upper limit is + * the maximum MSDU size. Monitor interfaces send and receive + * MPDU and A-MSDU frames which may be much larger so we do + * not impose an upper limit in that case. + */ ndev->min_mtu = 256; - ndev->max_mtu = local->hw.max_mtu; + if (type == NL80211_IFTYPE_MONITOR) + ndev->max_mtu = 0; + else + ndev->max_mtu = local->hw.max_mtu;
ret = cfg80211_register_netdevice(ndev); if (ret) {
From: Dmitry Osipenko digetx@gmail.com
[ Upstream commit 70e740ad55e5f93a19493720f4105555fade4a73 ]
The configuration of USB VBUS regulators was borrowed from downstream kernel, which is incorrect because the corresponding GPIOs are connected to PROX_EN (A501 3G model) and LED_EN pins in accordance to the board schematics. USB works fine with both GPIOs being disabled, so remove the bogus USB VBUS regulators. The USB VBUS of USB3 is supplied from the fixed 5v system regulator and device-mode USB1 doesn't have VBUS switches.
Signed-off-by: Dmitry Osipenko digetx@gmail.com Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../boot/dts/tegra20-acer-a500-picasso.dts | 25 +------------------ 1 file changed, 1 insertion(+), 24 deletions(-)
diff --git a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts index 14cd3238355b..2c74993f1a9e 100644 --- a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts +++ b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts @@ -716,7 +716,6 @@ usb-phy@c5000000 { nvidia,xcvr-setup-use-fuses; nvidia,xcvr-lsfslew = <2>; nvidia,xcvr-lsrslew = <2>; - vbus-supply = <&vdd_vbus1>; };
usb@c5008000 { @@ -728,7 +727,7 @@ usb-phy@c5008000 { nvidia,xcvr-setup-use-fuses; nvidia,xcvr-lsfslew = <2>; nvidia,xcvr-lsrslew = <2>; - vbus-supply = <&vdd_vbus3>; + vbus-supply = <&vdd_5v0_sys>; };
brcm_wifi_pwrseq: wifi-pwrseq { @@ -988,28 +987,6 @@ vdd_pnl: regulator@3 { vin-supply = <&vdd_5v0_sys>; };
- vdd_vbus1: regulator@4 { - compatible = "regulator-fixed"; - regulator-name = "vdd_usb1_vbus"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - regulator-always-on; - gpio = <&gpio TEGRA_GPIO(D, 0) GPIO_ACTIVE_HIGH>; - enable-active-high; - vin-supply = <&vdd_5v0_sys>; - }; - - vdd_vbus3: regulator@5 { - compatible = "regulator-fixed"; - regulator-name = "vdd_usb3_vbus"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - regulator-always-on; - gpio = <&gpio TEGRA_GPIO(D, 3) GPIO_ACTIVE_HIGH>; - enable-active-high; - vin-supply = <&vdd_5v0_sys>; - }; - sound { compatible = "nvidia,tegra-audio-wm8903-picasso", "nvidia,tegra-audio-wm8903";
From: Andreas Obergschwandtner andreas.obergschwandtner@gmail.com
[ Upstream commit 2270ad2f4e123336af685ecedd1618701cb4ca1e ]
This patch fixes the tristate and pullup configuration for UART 1 to 3 on the Tamonten SOM.
Signed-off-by: Andreas Obergschwandtner andreas.obergschwandtner@gmail.com Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/tegra20-tamonten.dtsi | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/arm/boot/dts/tegra20-tamonten.dtsi b/arch/arm/boot/dts/tegra20-tamonten.dtsi index 95e6bccdb4f6..dd4d506683de 100644 --- a/arch/arm/boot/dts/tegra20-tamonten.dtsi +++ b/arch/arm/boot/dts/tegra20-tamonten.dtsi @@ -185,8 +185,9 @@ conf_ata { nvidia,pins = "ata", "atb", "atc", "atd", "ate", "cdev1", "cdev2", "dap1", "dtb", "gma", "gmb", "gmc", "gmd", "gme", "gpu7", - "gpv", "i2cp", "pta", "rm", "slxa", - "slxk", "spia", "spib", "uac"; + "gpv", "i2cp", "irrx", "irtx", "pta", + "rm", "slxa", "slxk", "spia", "spib", + "uac"; nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,tristate = <TEGRA_PIN_DISABLE>; }; @@ -211,7 +212,7 @@ conf_crtp { conf_ddc { nvidia,pins = "ddc", "dta", "dtd", "kbca", "kbcb", "kbcc", "kbcd", "kbce", "kbcf", - "sdc"; + "sdc", "uad", "uca"; nvidia,pull = <TEGRA_PIN_PULL_UP>; nvidia,tristate = <TEGRA_PIN_DISABLE>; }; @@ -221,10 +222,9 @@ conf_hdint { "lvp0", "owc", "sdb"; nvidia,tristate = <TEGRA_PIN_ENABLE>; }; - conf_irrx { - nvidia,pins = "irrx", "irtx", "sdd", "spic", - "spie", "spih", "uaa", "uab", "uad", - "uca", "ucb"; + conf_sdd { + nvidia,pins = "sdd", "spic", "spie", "spih", + "uaa", "uab", "ucb"; nvidia,pull = <TEGRA_PIN_PULL_UP>; nvidia,tristate = <TEGRA_PIN_ENABLE>; };
From: Thierry Reding treding@nvidia.com
[ Upstream commit f865d0292ff3c0ca09414436510eb4c815815509 ]
The documented compatible string for the CPUs found on Tegra132 is "nvidia,tegra132-denver", rather than the previously used compatible string "nvidia,denver".
Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/nvidia/tegra132.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/nvidia/tegra132.dtsi b/arch/arm64/boot/dts/nvidia/tegra132.dtsi index 9928a87f593a..b0bcda8cc51f 100644 --- a/arch/arm64/boot/dts/nvidia/tegra132.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra132.dtsi @@ -1227,13 +1227,13 @@ cpus {
cpu@0 { device_type = "cpu"; - compatible = "nvidia,denver"; + compatible = "nvidia,tegra132-denver"; reg = <0>; };
cpu@1 { device_type = "cpu"; - compatible = "nvidia,denver"; + compatible = "nvidia,tegra132-denver"; reg = <1>; }; };
From: Tim Harvey tharvey@gateworks.com
[ Upstream commit 092cd75e527044050ea76bf774e7d730709b7e8b ]
Fix various MP5416 PMIC configurations: - Update regulator names per dt-bindings - ensure values fit among valid register values - add required regulator-max-microamp property - add regulator-always-on prop
Signed-off-by: Tim Harvey tharvey@gateworks.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../dts/freescale/imx8mm-venice-gw700x.dtsi | 56 ++++++++++++------- 1 file changed, 37 insertions(+), 19 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi index c769fadbd008..11dda79cc46b 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi @@ -283,65 +283,83 @@ pmic@69 { reg = <0x69>;
regulators { + /* vdd_0p95: DRAM/GPU/VPU */ buck1 { - regulator-name = "vdd_0p95"; - regulator-min-microvolt = <805000>; + regulator-name = "buck1"; + regulator-min-microvolt = <800000>; regulator-max-microvolt = <1000000>; - regulator-max-microamp = <2500000>; + regulator-min-microamp = <3800000>; + regulator-max-microamp = <6800000>; regulator-boot-on; + regulator-always-on; };
+ /* vdd_soc */ buck2 { - regulator-name = "vdd_soc"; - regulator-min-microvolt = <805000>; + regulator-name = "buck2"; + regulator-min-microvolt = <800000>; regulator-max-microvolt = <900000>; - regulator-max-microamp = <1000000>; + regulator-min-microamp = <2200000>; + regulator-max-microamp = <5200000>; regulator-boot-on; + regulator-always-on; };
+ /* vdd_arm */ buck3_reg: buck3 { - regulator-name = "vdd_arm"; - regulator-min-microvolt = <805000>; + regulator-name = "buck3"; + regulator-min-microvolt = <800000>; regulator-max-microvolt = <1000000>; - regulator-max-microamp = <2200000>; - regulator-boot-on; + regulator-min-microamp = <3800000>; + regulator-max-microamp = <6800000>; + regulator-always-on; };
+ /* vdd_1p8 */ buck4 { - regulator-name = "vdd_1p8"; + regulator-name = "buck4"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; - regulator-max-microamp = <500000>; + regulator-min-microamp = <2200000>; + regulator-max-microamp = <5200000>; regulator-boot-on; + regulator-always-on; };
+ /* nvcc_snvs_1p8 */ ldo1 { - regulator-name = "nvcc_snvs_1p8"; + regulator-name = "ldo1"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; - regulator-max-microamp = <300000>; regulator-boot-on; + regulator-always-on; };
+ /* vdd_snvs_0p8 */ ldo2 { - regulator-name = "vdd_snvs_0p8"; + regulator-name = "ldo2"; regulator-min-microvolt = <800000>; regulator-max-microvolt = <800000>; regulator-boot-on; + regulator-always-on; };
+ /* vdd_0p9 */ ldo3 { - regulator-name = "vdd_0p95"; - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <800000>; + regulator-name = "ldo3"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; regulator-boot-on; + regulator-always-on; };
+ /* vdd_1p8 */ ldo4 { - regulator-name = "vdd_1p8"; + regulator-name = "ldo4"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-boot-on; + regulator-always-on; }; }; };
From: Tim Harvey tharvey@gateworks.com
[ Upstream commit 500659f3b401fe6ffd1d63f2449d16d8a4204db7 ]
The GW700x PMIC does not have an interrupt. Remove the invalid pin config.
Signed-off-by: Tim Harvey tharvey@gateworks.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi | 8 -------- 1 file changed, 8 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi index 11dda79cc46b..00f86cada30d 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi @@ -278,8 +278,6 @@ rtc@68 {
pmic@69 { compatible = "mps,mp5416"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pmic>; reg = <0x69>;
regulators { @@ -444,12 +442,6 @@ MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x400001c3 >; };
- pinctrl_pmic: pmicgrp { - fsl,pins = < - MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x41 - >; - }; - pinctrl_uart2: uart2grp { fsl,pins = < MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140
From: Tim Harvey tharvey@gateworks.com
[ Upstream commit bd306fdb4e60bcb1d7ea5431a74092803d3784a6 ]
The GW71xx has a USB Type-C connector with USB 2.0 signaling. GPIO1_12 is the power-enable to the TPS25821 Source controller and power switch responsible for monitoring the CC pins and enabling VBUS. Therefore GPIO1_12 must always be enabled and the vbus output enable from the IMX8MM can be ignored.
To fix USB OTG VBUS enable a pull-up on GPIO1_12 to always power the TPS25821 and change the regulator output to GPIO1_10 which is unconnected.
Signed-off-by: Tim Harvey tharvey@gateworks.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi index 905b68a3daa5..8e4a0ce99790 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi @@ -46,7 +46,7 @@ reg_usb_otg1_vbus: regulator-usb-otg1 { pinctrl-0 = <&pinctrl_reg_usb1_en>; compatible = "regulator-fixed"; regulator-name = "usb_otg1_vbus"; - gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>; + gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>; enable-active-high; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; @@ -156,7 +156,8 @@ MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x41
pinctrl_reg_usb1_en: regusb1grp { fsl,pins = < - MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x41 + MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x41 + MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x141 MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x41 >; };
From: Raag Jadav raagjadav@gmail.com
[ Upstream commit c1a6018d1839c9cb8f807dc863a50102a1a5c412 ]
ls1046afrwy and ls1046ardb boards have CAT24C04[1] and CAT24C05[2] eeproms respectively. Both are 4Kb (512 bytes) in size, and compatible with AT24C04[3]. Remove multi-address entries, as both the boards have a single chip each.
[1] https://www.onsemi.com/pdf/datasheet/cat24c01-d.pdf [2] https://www.onsemi.com/pdf/datasheet/cat24c03-d.pdf [3] https://ww1.microchip.com/downloads/en/DeviceDoc/doc0180.pdf
Signed-off-by: Raag Jadav raagjadav@gmail.com Acked-by: Li Yang leoyang.li@nxp.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts | 8 +------- arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts | 7 +------ 2 files changed, 2 insertions(+), 13 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts index db3d303093f6..6d22efbd645c 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts @@ -83,15 +83,9 @@ rtc@51 { };
eeprom@52 { - compatible = "atmel,24c512"; + compatible = "onnn,cat24c04", "atmel,24c04"; reg = <0x52>; }; - - eeprom@53 { - compatible = "atmel,24c512"; - reg = <0x53>; - }; - }; }; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts index 60acdf0b689e..7025aad8ae89 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts @@ -59,14 +59,9 @@ temp-sensor@4c { };
eeprom@52 { - compatible = "atmel,24c512"; + compatible = "onnn,cat24c05", "atmel,24c04"; reg = <0x52>; }; - - eeprom@53 { - compatible = "atmel,24c512"; - reg = <0x53>; - }; };
&i2c3 {
From: Sagi Grimberg sagi@grimberg.me
[ Upstream commit 3b01a9d0caa8276d9ce314e09610f7fb70f49a00 ]
We already validate it when receiving the c2hdata pdu header and this is not changing so this is a redundant check.
Reviewed-by: Hannes Reinecke hare@suse.de Signed-off-by: Sagi Grimberg sagi@grimberg.me Reviewed-by: Daniel Wagner dwagner@suse.de Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/tcp.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-)
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index ab1ea5b0888e..da289b8f8a27 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -702,17 +702,9 @@ static int nvme_tcp_recv_data(struct nvme_tcp_queue *queue, struct sk_buff *skb, unsigned int *offset, size_t *len) { struct nvme_tcp_data_pdu *pdu = (void *)queue->pdu; - struct nvme_tcp_request *req; - struct request *rq; - - rq = blk_mq_tag_to_rq(nvme_tcp_tagset(queue), pdu->command_id); - if (!rq) { - dev_err(queue->ctrl->ctrl.device, - "queue %d tag %#x not found\n", - nvme_tcp_queue_id(queue), pdu->command_id); - return -ENOENT; - } - req = blk_mq_rq_to_pdu(rq); + struct request *rq = + blk_mq_tag_to_rq(nvme_tcp_tagset(queue), pdu->command_id); + struct nvme_tcp_request *req = blk_mq_rq_to_pdu(rq);
while (true) { int recv_len, ret;
From: Sagi Grimberg sagi@grimberg.me
[ Upstream commit e7006de6c23803799be000a5dcce4d916a36541a ]
We cannot detect a (perhaps buggy) controller that is sending us a completion for a request that was already completed (for example sending a completion twice), this phenomenon was seen in the wild a few times.
So to protect against this, we use the upper 4 msbits of the nvme sqe command_id to use as a 4-bit generation counter and verify it matches the existing request generation that is incrementing on every execution.
The 16-bit command_id structure now is constructed by: | xxxx | xxxxxxxxxxxx | gen request tag
This means that we are giving up some possible queue depth as 12 bits allow for a maximum queue depth of 4095 instead of 65536, however we never create such long queues anyways so no real harm done.
Suggested-by: Keith Busch kbusch@kernel.org Signed-off-by: Sagi Grimberg sagi@grimberg.me Acked-by: Keith Busch kbusch@kernel.org Reviewed-by: Hannes Reinecke hare@suse.de Reviewed-by: Daniel Wagner dwagner@suse.de Tested-by: Daniel Wagner dwagner@suse.de Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/core.c | 3 ++- drivers/nvme/host/nvme.h | 47 +++++++++++++++++++++++++++++++++++++- drivers/nvme/host/pci.c | 2 +- drivers/nvme/host/rdma.c | 4 ++-- drivers/nvme/host/tcp.c | 26 ++++++++++----------- drivers/nvme/target/loop.c | 4 ++-- 6 files changed, 66 insertions(+), 20 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 148e756857a8..a13eec2fca5a 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1009,7 +1009,8 @@ blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req) return BLK_STS_IOERR; }
- cmd->common.command_id = req->tag; + nvme_req(req)->genctr++; + cmd->common.command_id = nvme_cid(req); trace_nvme_setup_cmd(req, cmd); return ret; } diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 0015860ec12b..632076b9c1c9 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -158,6 +158,7 @@ enum nvme_quirks { struct nvme_request { struct nvme_command *cmd; union nvme_result result; + u8 genctr; u8 retries; u8 flags; u16 status; @@ -497,6 +498,49 @@ struct nvme_ctrl_ops { int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size); };
+/* + * nvme command_id is constructed as such: + * | xxxx | xxxxxxxxxxxx | + * gen request tag + */ +#define nvme_genctr_mask(gen) (gen & 0xf) +#define nvme_cid_install_genctr(gen) (nvme_genctr_mask(gen) << 12) +#define nvme_genctr_from_cid(cid) ((cid & 0xf000) >> 12) +#define nvme_tag_from_cid(cid) (cid & 0xfff) + +static inline u16 nvme_cid(struct request *rq) +{ + return nvme_cid_install_genctr(nvme_req(rq)->genctr) | rq->tag; +} + +static inline struct request *nvme_find_rq(struct blk_mq_tags *tags, + u16 command_id) +{ + u8 genctr = nvme_genctr_from_cid(command_id); + u16 tag = nvme_tag_from_cid(command_id); + struct request *rq; + + rq = blk_mq_tag_to_rq(tags, tag); + if (unlikely(!rq)) { + pr_err("could not locate request for tag %#x\n", + tag); + return NULL; + } + if (unlikely(nvme_genctr_mask(nvme_req(rq)->genctr) != genctr)) { + dev_err(nvme_req(rq)->ctrl->device, + "request %#x genctr mismatch (got %#x expected %#x)\n", + tag, genctr, nvme_genctr_mask(nvme_req(rq)->genctr)); + return NULL; + } + return rq; +} + +static inline struct request *nvme_cid_to_rq(struct blk_mq_tags *tags, + u16 command_id) +{ + return blk_mq_tag_to_rq(tags, nvme_tag_from_cid(command_id)); +} + #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS void nvme_fault_inject_init(struct nvme_fault_inject *fault_inj, const char *dev_name); @@ -594,7 +638,8 @@ static inline void nvme_put_ctrl(struct nvme_ctrl *ctrl)
static inline bool nvme_is_aen_req(u16 qid, __u16 command_id) { - return !qid && command_id >= NVME_AQ_BLK_MQ_DEPTH; + return !qid && + nvme_tag_from_cid(command_id) >= NVME_AQ_BLK_MQ_DEPTH; }
void nvme_complete_rq(struct request *req); diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index d963f25fc7ae..01feb1c2278d 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -1017,7 +1017,7 @@ static inline void nvme_handle_cqe(struct nvme_queue *nvmeq, u16 idx) return; }
- req = blk_mq_tag_to_rq(nvme_queue_tagset(nvmeq), command_id); + req = nvme_find_rq(nvme_queue_tagset(nvmeq), command_id); if (unlikely(!req)) { dev_warn(nvmeq->dev->ctrl.device, "invalid id %d completed on queue %d\n", diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index f80682f7df54..b95945c58b3b 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -1731,10 +1731,10 @@ static void nvme_rdma_process_nvme_rsp(struct nvme_rdma_queue *queue, struct request *rq; struct nvme_rdma_request *req;
- rq = blk_mq_tag_to_rq(nvme_rdma_tagset(queue), cqe->command_id); + rq = nvme_find_rq(nvme_rdma_tagset(queue), cqe->command_id); if (!rq) { dev_err(queue->ctrl->ctrl.device, - "tag 0x%x on QP %#x not found\n", + "got bad command_id %#x on QP %#x\n", cqe->command_id, queue->qp->qp_num); nvme_rdma_error_recovery(queue->ctrl); return; diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index da289b8f8a27..258d71807367 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -487,11 +487,11 @@ static int nvme_tcp_process_nvme_cqe(struct nvme_tcp_queue *queue, { struct request *rq;
- rq = blk_mq_tag_to_rq(nvme_tcp_tagset(queue), cqe->command_id); + rq = nvme_find_rq(nvme_tcp_tagset(queue), cqe->command_id); if (!rq) { dev_err(queue->ctrl->ctrl.device, - "queue %d tag 0x%x not found\n", - nvme_tcp_queue_id(queue), cqe->command_id); + "got bad cqe.command_id %#x on queue %d\n", + cqe->command_id, nvme_tcp_queue_id(queue)); nvme_tcp_error_recovery(&queue->ctrl->ctrl); return -EINVAL; } @@ -508,11 +508,11 @@ static int nvme_tcp_handle_c2h_data(struct nvme_tcp_queue *queue, { struct request *rq;
- rq = blk_mq_tag_to_rq(nvme_tcp_tagset(queue), pdu->command_id); + rq = nvme_find_rq(nvme_tcp_tagset(queue), pdu->command_id); if (!rq) { dev_err(queue->ctrl->ctrl.device, - "queue %d tag %#x not found\n", - nvme_tcp_queue_id(queue), pdu->command_id); + "got bad c2hdata.command_id %#x on queue %d\n", + pdu->command_id, nvme_tcp_queue_id(queue)); return -ENOENT; }
@@ -606,7 +606,7 @@ static int nvme_tcp_setup_h2c_data_pdu(struct nvme_tcp_request *req, data->hdr.plen = cpu_to_le32(data->hdr.hlen + hdgst + req->pdu_len + ddgst); data->ttag = pdu->ttag; - data->command_id = rq->tag; + data->command_id = nvme_cid(rq); data->data_offset = cpu_to_le32(req->data_sent); data->data_length = cpu_to_le32(req->pdu_len); return 0; @@ -619,11 +619,11 @@ static int nvme_tcp_handle_r2t(struct nvme_tcp_queue *queue, struct request *rq; int ret;
- rq = blk_mq_tag_to_rq(nvme_tcp_tagset(queue), pdu->command_id); + rq = nvme_find_rq(nvme_tcp_tagset(queue), pdu->command_id); if (!rq) { dev_err(queue->ctrl->ctrl.device, - "queue %d tag %#x not found\n", - nvme_tcp_queue_id(queue), pdu->command_id); + "got bad r2t.command_id %#x on queue %d\n", + pdu->command_id, nvme_tcp_queue_id(queue)); return -ENOENT; } req = blk_mq_rq_to_pdu(rq); @@ -703,7 +703,7 @@ static int nvme_tcp_recv_data(struct nvme_tcp_queue *queue, struct sk_buff *skb, { struct nvme_tcp_data_pdu *pdu = (void *)queue->pdu; struct request *rq = - blk_mq_tag_to_rq(nvme_tcp_tagset(queue), pdu->command_id); + nvme_cid_to_rq(nvme_tcp_tagset(queue), pdu->command_id); struct nvme_tcp_request *req = blk_mq_rq_to_pdu(rq);
while (true) { @@ -796,8 +796,8 @@ static int nvme_tcp_recv_ddgst(struct nvme_tcp_queue *queue, }
if (pdu->hdr.flags & NVME_TCP_F_DATA_SUCCESS) { - struct request *rq = blk_mq_tag_to_rq(nvme_tcp_tagset(queue), - pdu->command_id); + struct request *rq = nvme_cid_to_rq(nvme_tcp_tagset(queue), + pdu->command_id);
nvme_tcp_end_request(rq, NVME_SC_SUCCESS); queue->nr_cqe++; diff --git a/drivers/nvme/target/loop.c b/drivers/nvme/target/loop.c index a5c4a1865026..f6ee47de3038 100644 --- a/drivers/nvme/target/loop.c +++ b/drivers/nvme/target/loop.c @@ -107,10 +107,10 @@ static void nvme_loop_queue_response(struct nvmet_req *req) } else { struct request *rq;
- rq = blk_mq_tag_to_rq(nvme_loop_tagset(queue), cqe->command_id); + rq = nvme_find_rq(nvme_loop_tagset(queue), cqe->command_id); if (!rq) { dev_err(queue->ctrl->ctrl.device, - "tag 0x%x on queue %d not found\n", + "got bad command_id %#x on queue %d\n", cqe->command_id, nvme_loop_queue_idx(queue)); return; }
From: Luiz Augusto von Dentz luiz.von.dentz@intel.com
[ Upstream commit cafae4cd625502f65d1798659c1aa9b62d38cc56 ]
LE Enhanced Connection Complete contains the Local RPA used in the connection which must be used when set otherwise there could problems when pairing since the address used by the remote stack could be the Local RPA:
BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 4, Part E page 2396
'Resolvable Private Address being used by the local device for this connection. This is only valid when the Own_Address_Type (from the HCI_LE_Create_Connection, HCI_LE_Set_Advertising_Parameters, HCI_LE_Set_Extended_Advertising_Parameters, or HCI_LE_Extended_Create_Connection commands) is set to 0x02 or 0x03, and the Controller generated a resolvable private address for the local device using a non-zero local IRK. For other Own_Address_Type values, the Controller shall return all zeros.'
Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/hci_event.c | 93 ++++++++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 31 deletions(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index c30682c90fc5..89f37f26f253 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -5124,9 +5124,64 @@ static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev, } #endif
+static void le_conn_update_addr(struct hci_conn *conn, bdaddr_t *bdaddr, + u8 bdaddr_type, bdaddr_t *local_rpa) +{ + if (conn->out) { + conn->dst_type = bdaddr_type; + conn->resp_addr_type = bdaddr_type; + bacpy(&conn->resp_addr, bdaddr); + + /* Check if the controller has set a Local RPA then it must be + * used instead or hdev->rpa. + */ + if (local_rpa && bacmp(local_rpa, BDADDR_ANY)) { + conn->init_addr_type = ADDR_LE_DEV_RANDOM; + bacpy(&conn->init_addr, local_rpa); + } else if (hci_dev_test_flag(conn->hdev, HCI_PRIVACY)) { + conn->init_addr_type = ADDR_LE_DEV_RANDOM; + bacpy(&conn->init_addr, &conn->hdev->rpa); + } else { + hci_copy_identity_address(conn->hdev, &conn->init_addr, + &conn->init_addr_type); + } + } else { + conn->resp_addr_type = conn->hdev->adv_addr_type; + /* Check if the controller has set a Local RPA then it must be + * used instead or hdev->rpa. + */ + if (local_rpa && bacmp(local_rpa, BDADDR_ANY)) { + conn->resp_addr_type = ADDR_LE_DEV_RANDOM; + bacpy(&conn->resp_addr, local_rpa); + } else if (conn->hdev->adv_addr_type == ADDR_LE_DEV_RANDOM) { + /* In case of ext adv, resp_addr will be updated in + * Adv Terminated event. + */ + if (!ext_adv_capable(conn->hdev)) + bacpy(&conn->resp_addr, + &conn->hdev->random_addr); + } else { + bacpy(&conn->resp_addr, &conn->hdev->bdaddr); + } + + conn->init_addr_type = bdaddr_type; + bacpy(&conn->init_addr, bdaddr); + + /* For incoming connections, set the default minimum + * and maximum connection interval. They will be used + * to check if the parameters are in range and if not + * trigger the connection update procedure. + */ + conn->le_conn_min_interval = conn->hdev->le_conn_min_interval; + conn->le_conn_max_interval = conn->hdev->le_conn_max_interval; + } +} + static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, - bdaddr_t *bdaddr, u8 bdaddr_type, u8 role, u16 handle, - u16 interval, u16 latency, u16 supervision_timeout) + bdaddr_t *bdaddr, u8 bdaddr_type, + bdaddr_t *local_rpa, u8 role, u16 handle, + u16 interval, u16 latency, + u16 supervision_timeout) { struct hci_conn_params *params; struct hci_conn *conn; @@ -5174,32 +5229,7 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, cancel_delayed_work(&conn->le_conn_timeout); }
- if (!conn->out) { - /* Set the responder (our side) address type based on - * the advertising address type. - */ - conn->resp_addr_type = hdev->adv_addr_type; - if (hdev->adv_addr_type == ADDR_LE_DEV_RANDOM) { - /* In case of ext adv, resp_addr will be updated in - * Adv Terminated event. - */ - if (!ext_adv_capable(hdev)) - bacpy(&conn->resp_addr, &hdev->random_addr); - } else { - bacpy(&conn->resp_addr, &hdev->bdaddr); - } - - conn->init_addr_type = bdaddr_type; - bacpy(&conn->init_addr, bdaddr); - - /* For incoming connections, set the default minimum - * and maximum connection interval. They will be used - * to check if the parameters are in range and if not - * trigger the connection update procedure. - */ - conn->le_conn_min_interval = hdev->le_conn_min_interval; - conn->le_conn_max_interval = hdev->le_conn_max_interval; - } + le_conn_update_addr(conn, bdaddr, bdaddr_type, local_rpa);
/* Lookup the identity address from the stored connection * address and address type. @@ -5293,7 +5323,7 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type, - ev->role, le16_to_cpu(ev->handle), + NULL, ev->role, le16_to_cpu(ev->handle), le16_to_cpu(ev->interval), le16_to_cpu(ev->latency), le16_to_cpu(ev->supervision_timeout)); @@ -5307,7 +5337,7 @@ static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev, BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type, - ev->role, le16_to_cpu(ev->handle), + &ev->local_rpa, ev->role, le16_to_cpu(ev->handle), le16_to_cpu(ev->interval), le16_to_cpu(ev->latency), le16_to_cpu(ev->supervision_timeout)); @@ -5343,7 +5373,8 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, struct sk_buff *skb) if (conn) { struct adv_info *adv_instance;
- if (hdev->adv_addr_type != ADDR_LE_DEV_RANDOM) + if (hdev->adv_addr_type != ADDR_LE_DEV_RANDOM || + bacmp(&conn->resp_addr, BDADDR_ANY)) return;
if (!ev->handle) {
From: Rajendra Nayak rnayak@codeaurora.org
[ Upstream commit 020d86fc0df8b865f6dc168d88a7c2dccabd0a9e ]
The 'required-opps' property is considered optional, hence remove the pr_err() in of_parse_required_opp() when we find the property is missing. While at it, also fix the return value of of_get_required_opp_performance_state() when of_parse_required_opp() fails, return a -ENODEV instead of the -EINVAL.
Signed-off-by: Rajendra Nayak rnayak@codeaurora.org Reviewed-by: Ulf Hansson ulf.hansson@linaro.org Acked-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/opp/of.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 01feeba78426..de550ee48e77 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -95,15 +95,7 @@ static struct dev_pm_opp *_find_opp_of_np(struct opp_table *opp_table, static struct device_node *of_parse_required_opp(struct device_node *np, int index) { - struct device_node *required_np; - - required_np = of_parse_phandle(np, "required-opps", index); - if (unlikely(!required_np)) { - pr_err("%s: Unable to parse required-opps: %pOF, index: %d\n", - __func__, np, index); - } - - return required_np; + return of_parse_phandle(np, "required-opps", index); }
/* The caller must call dev_pm_opp_put_opp_table() after the table is used */ @@ -1349,7 +1341,7 @@ int of_get_required_opp_performance_state(struct device_node *np, int index)
required_np = of_parse_required_opp(np, index); if (!required_np) - return -EINVAL; + return -ENODEV;
opp_table = _find_table_of_opp_np(required_np); if (IS_ERR(opp_table)) {
From: Ulrich Hecht uli+renesas@fpond.eu
[ Upstream commit 87b8061bad9bd4b549b2daf36ffbaa57be2789a2 ]
This fixes two issues that cause the sysrq sequence to be inadvertently aborted on SCIF serial consoles:
- a NUL character remains in the RX queue after a break has been detected, which is then passed on to uart_handle_sysrq_char() - the break interrupt is handled twice on controllers with multiplexed ERI and BRI interrupts
Signed-off-by: Ulrich Hecht uli+renesas@fpond.eu Link: https://lore.kernel.org/r/20210816162201.28801-1-uli+renesas@fpond.eu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/sh-sci.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 2d5487bf6855..a2e62f372e10 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1760,6 +1760,10 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr)
/* Handle BREAKs */ sci_handle_breaks(port); + + /* drop invalid character received before break was detected */ + serial_port_in(port, SCxRDR); + sci_clear_SCxSR(port, SCxSR_BREAK_CLEAR(port));
return IRQ_HANDLED; @@ -1839,7 +1843,8 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) ret = sci_er_interrupt(irq, ptr);
/* Break Interrupt */ - if ((ssr_status & SCxSR_BRK(port)) && err_enabled) + if (s->irqs[SCIx_ERI_IRQ] != s->irqs[SCIx_BRI_IRQ] && + (ssr_status & SCxSR_BRK(port)) && err_enabled) ret = sci_br_interrupt(irq, ptr);
/* Overrun Interrupt */
From: Darrick J. Wong djwong@kernel.org
[ Upstream commit b69eea82d37d9ee7cfb3bf05103549dd4ed5ffc3 ]
Modern-day mapping_set_error has the ability to squash the usual negative error code into something appropriate for long-term storage in a struct address_space -- ENOSPC becomes AS_ENOSPC, and everything else becomes EIO. iomap squashes /everything/ to EIO, just as XFS did before that, but this doesn't make sense.
Fix this by making it so that we can pass ENOSPC to userspace when writeback fails due to space problems.
Signed-off-by: Darrick J. Wong djwong@kernel.org Reviewed-by: Matthew Wilcox (Oracle) willy@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/iomap/buffered-io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index 9023717c5188..35839acd0004 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -1045,7 +1045,7 @@ iomap_finish_page_writeback(struct inode *inode, struct page *page,
if (error) { SetPageError(page); - mapping_set_error(inode->i_mapping, -EIO); + mapping_set_error(inode->i_mapping, error); }
WARN_ON_ONCE(i_blocks_per_page(inode, page) > 1 && !iop);
From: Luke Hsiao lukehsiao@google.com
[ Upstream commit e3faa49bcecdfcc80e94dd75709d6acb1a5d89f6 ]
Since the original TFO server code was implemented in commit 168a8f58059a22feb9e9a2dcc1b8053dbbbc12ef ("tcp: TCP Fast Open Server - main code path") the TFO server code has supported the sysctl bit flag TFO_SERVER_COOKIE_NOT_REQD. Currently, when the TFO_SERVER_ENABLE and TFO_SERVER_COOKIE_NOT_REQD sysctl bit flags are set, a server connection will accept a SYN with N bytes of data (N > 0) that has no TFO cookie, create a new fast open connection, process the incoming data in the SYN, and make the connection ready for accepting. After accepting, the connection is ready for read()/recvmsg() to read the N bytes of data in the SYN, ready for write()/sendmsg() calls and data transmissions to transmit data.
This commit changes an edge case in this feature by changing this behavior to apply to (N >= 0) bytes of data in the SYN rather than only (N > 0) bytes of data in the SYN. Now, a server will accept a data-less SYN without a TFO cookie if TFO_SERVER_COOKIE_NOT_REQD is set.
Caveat! While this enables a new kind of TFO (data-less empty-cookie SYN), some firewall rules setup may not work if they assume such packets are not legit TFOs and will filter them.
Signed-off-by: Luke Hsiao lukehsiao@google.com Acked-by: Neal Cardwell ncardwell@google.com Acked-by: Yuchung Cheng ycheng@google.com Signed-off-by: Eric Dumazet edumazet@google.com Link: https://lore.kernel.org/r/20210816205105.2533289-1-luke.w.hsiao@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/tcp_fastopen.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c index d49709ba8e16..107111984384 100644 --- a/net/ipv4/tcp_fastopen.c +++ b/net/ipv4/tcp_fastopen.c @@ -379,8 +379,7 @@ struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb, return NULL; }
- if (syn_data && - tcp_fastopen_no_cookie(sk, dst, TFO_SERVER_COOKIE_NOT_REQD)) + if (tcp_fastopen_no_cookie(sk, dst, TFO_SERVER_COOKIE_NOT_REQD)) goto fastopen;
if (foc->len == 0) {
From: Thomas Gleixner tglx@linutronix.de
[ Upstream commit b41cda03765580caf7723b8c1b672d191c71013f ]
RT mutexes belong to the LD_WAIT_SLEEP class. Make them so.
Signed-off-by: Thomas Gleixner tglx@linutronix.de Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Signed-off-by: Ingo Molnar mingo@kernel.org Link: https://lore.kernel.org/r/20210815211302.031014562@linutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/rtmutex.h | 19 ++++++++++++------- kernel/locking/rtmutex.c | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/include/linux/rtmutex.h b/include/linux/rtmutex.h index d1672de9ca89..87b325aec508 100644 --- a/include/linux/rtmutex.h +++ b/include/linux/rtmutex.h @@ -52,17 +52,22 @@ do { \ } while (0)
#ifdef CONFIG_DEBUG_LOCK_ALLOC -#define __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname) \ - , .dep_map = { .name = #mutexname } +#define __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname) \ + .dep_map = { \ + .name = #mutexname, \ + .wait_type_inner = LD_WAIT_SLEEP, \ + } #else #define __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname) #endif
-#define __RT_MUTEX_INITIALIZER(mutexname) \ - { .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(mutexname.wait_lock) \ - , .waiters = RB_ROOT_CACHED \ - , .owner = NULL \ - __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname)} +#define __RT_MUTEX_INITIALIZER(mutexname) \ +{ \ + .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(mutexname.wait_lock), \ + .waiters = RB_ROOT_CACHED, \ + .owner = NULL, \ + __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname) \ +}
#define DEFINE_RT_MUTEX(mutexname) \ struct rt_mutex mutexname = __RT_MUTEX_INITIALIZER(mutexname) diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index 3c20afbc19e1..ae5afba2162b 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -1556,7 +1556,7 @@ void __sched __rt_mutex_init(struct rt_mutex *lock, const char *name, struct lock_class_key *key) { debug_check_no_locks_freed((void *)lock, sizeof(*lock)); - lockdep_init_map(&lock->dep_map, name, key, 0); + lockdep_init_map_wait(&lock->dep_map, name, key, 0, LD_WAIT_SLEEP);
__rt_mutex_basic_init(lock); }
From: J. Bruce Fields bfields@redhat.com
[ Upstream commit 5a4753446253a427c0ff1e433b9c4933e5af207c ]
The failure case here should be rare, but it's obviously wrong.
Signed-off-by: J. Bruce Fields bfields@redhat.com Signed-off-by: Chuck Lever chuck.lever@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/sunrpc/auth_gss/svcauth_gss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 6dff64374bfe..e22f2d65457d 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -1980,7 +1980,7 @@ gss_svc_init_net(struct net *net) goto out2; return 0; out2: - destroy_use_gss_proxy_proc_entry(net); + rsi_cache_destroy_net(net); out1: rsc_cache_destroy_net(net); return rv;
From: Stefan Assmann sassmann@kpanic.de
[ Upstream commit 5ac49f3c2702f269d31cc37eb9308bc557953c4d ]
As follow-up to the discussion with Jakub Kicinski about iavf locking being insufficient [1] convert iavf to use mutexes instead of bitops. The locking logic is kept as is, just a drop-in replacement of enum iavf_critical_section_t with separate mutexes. The only difference is that the mutexes will be destroyed before the module is unloaded.
[1] https://lwn.net/ml/netdev/20210316150210.00007249%40intel.com/
Signed-off-by: Stefan Assmann sassmann@kpanic.de Tested-by: Marek Szlosek marek.szlosek@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/iavf/iavf.h | 9 +- .../net/ethernet/intel/iavf/iavf_ethtool.c | 10 +- drivers/net/ethernet/intel/iavf/iavf_main.c | 100 +++++++++--------- 3 files changed, 56 insertions(+), 63 deletions(-)
diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h index 90793b36126e..68c80f04113c 100644 --- a/drivers/net/ethernet/intel/iavf/iavf.h +++ b/drivers/net/ethernet/intel/iavf/iavf.h @@ -186,12 +186,6 @@ enum iavf_state_t { __IAVF_RUNNING, /* opened, working */ };
-enum iavf_critical_section_t { - __IAVF_IN_CRITICAL_TASK, /* cannot be interrupted */ - __IAVF_IN_CLIENT_TASK, - __IAVF_IN_REMOVE_TASK, /* device being removed */ -}; - #define IAVF_CLOUD_FIELD_OMAC 0x01 #define IAVF_CLOUD_FIELD_IMAC 0x02 #define IAVF_CLOUD_FIELD_IVLAN 0x04 @@ -236,6 +230,9 @@ struct iavf_adapter { struct iavf_q_vector *q_vectors; struct list_head vlan_filter_list; struct list_head mac_filter_list; + struct mutex crit_lock; + struct mutex client_lock; + struct mutex remove_lock; /* Lock to protect accesses to MAC and VLAN lists */ spinlock_t mac_vlan_list_lock; char misc_vector_name[IFNAMSIZ + 9]; diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c index af43fbd8cb75..edbeb27213f8 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c +++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c @@ -1352,8 +1352,7 @@ static int iavf_add_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx if (!fltr) return -ENOMEM;
- while (test_and_set_bit(__IAVF_IN_CRITICAL_TASK, - &adapter->crit_section)) { + while (!mutex_trylock(&adapter->crit_lock)) { if (--count == 0) { kfree(fltr); return -EINVAL; @@ -1378,7 +1377,7 @@ static int iavf_add_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx if (err && fltr) kfree(fltr);
- clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); + mutex_unlock(&adapter->crit_lock); return err; }
@@ -1563,8 +1562,7 @@ iavf_set_adv_rss_hash_opt(struct iavf_adapter *adapter, return -EINVAL; }
- while (test_and_set_bit(__IAVF_IN_CRITICAL_TASK, - &adapter->crit_section)) { + while (!mutex_trylock(&adapter->crit_lock)) { if (--count == 0) { kfree(rss_new); return -EINVAL; @@ -1600,7 +1598,7 @@ iavf_set_adv_rss_hash_opt(struct iavf_adapter *adapter, if (!err) mod_delayed_work(iavf_wq, &adapter->watchdog_task, 0);
- clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); + mutex_unlock(&adapter->crit_lock);
if (!rss_new_add) kfree(rss_new); diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index e5e6a5b11e6d..23762a7ef740 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -132,21 +132,18 @@ enum iavf_status iavf_free_virt_mem_d(struct iavf_hw *hw, }
/** - * iavf_lock_timeout - try to set bit but give up after timeout - * @adapter: board private structure - * @bit: bit to set + * iavf_lock_timeout - try to lock mutex but give up after timeout + * @lock: mutex that should be locked * @msecs: timeout in msecs * * Returns 0 on success, negative on failure **/ -static int iavf_lock_timeout(struct iavf_adapter *adapter, - enum iavf_critical_section_t bit, - unsigned int msecs) +static int iavf_lock_timeout(struct mutex *lock, unsigned int msecs) { unsigned int wait, delay = 10;
for (wait = 0; wait < msecs; wait += delay) { - if (!test_and_set_bit(bit, &adapter->crit_section)) + if (mutex_trylock(lock)) return 0;
msleep(delay); @@ -1940,7 +1937,7 @@ static void iavf_watchdog_task(struct work_struct *work) struct iavf_hw *hw = &adapter->hw; u32 reg_val;
- if (test_and_set_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section)) + if (!mutex_trylock(&adapter->crit_lock)) goto restart_watchdog;
if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED) @@ -1958,8 +1955,7 @@ static void iavf_watchdog_task(struct work_struct *work) adapter->state = __IAVF_STARTUP; adapter->flags &= ~IAVF_FLAG_PF_COMMS_FAILED; queue_delayed_work(iavf_wq, &adapter->init_task, 10); - clear_bit(__IAVF_IN_CRITICAL_TASK, - &adapter->crit_section); + mutex_unlock(&adapter->crit_lock); /* Don't reschedule the watchdog, since we've restarted * the init task. When init_task contacts the PF and * gets everything set up again, it'll restart the @@ -1969,14 +1965,13 @@ static void iavf_watchdog_task(struct work_struct *work) } adapter->aq_required = 0; adapter->current_op = VIRTCHNL_OP_UNKNOWN; - clear_bit(__IAVF_IN_CRITICAL_TASK, - &adapter->crit_section); + mutex_unlock(&adapter->crit_lock); queue_delayed_work(iavf_wq, &adapter->watchdog_task, msecs_to_jiffies(10)); goto watchdog_done; case __IAVF_RESETTING: - clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); + mutex_unlock(&adapter->crit_lock); queue_delayed_work(iavf_wq, &adapter->watchdog_task, HZ * 2); return; case __IAVF_DOWN: @@ -1999,7 +1994,7 @@ static void iavf_watchdog_task(struct work_struct *work) } break; case __IAVF_REMOVE: - clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); + mutex_unlock(&adapter->crit_lock); return; default: goto restart_watchdog; @@ -2021,7 +2016,7 @@ static void iavf_watchdog_task(struct work_struct *work) if (adapter->state == __IAVF_RUNNING || adapter->state == __IAVF_COMM_FAILED) iavf_detect_recover_hung(&adapter->vsi); - clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); + mutex_unlock(&adapter->crit_lock); restart_watchdog: if (adapter->aq_required) queue_delayed_work(iavf_wq, &adapter->watchdog_task, @@ -2085,7 +2080,7 @@ static void iavf_disable_vf(struct iavf_adapter *adapter) memset(adapter->vf_res, 0, IAVF_VIRTCHNL_VF_RESOURCE_SIZE); iavf_shutdown_adminq(&adapter->hw); adapter->netdev->flags &= ~IFF_UP; - clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); + mutex_unlock(&adapter->crit_lock); adapter->flags &= ~IAVF_FLAG_RESET_PENDING; adapter->state = __IAVF_DOWN; wake_up(&adapter->down_waitqueue); @@ -2118,15 +2113,14 @@ static void iavf_reset_task(struct work_struct *work) /* When device is being removed it doesn't make sense to run the reset * task, just return in such a case. */ - if (test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section)) + if (mutex_is_locked(&adapter->remove_lock)) return;
- if (iavf_lock_timeout(adapter, __IAVF_IN_CRITICAL_TASK, 200)) { + if (iavf_lock_timeout(&adapter->crit_lock, 200)) { schedule_work(&adapter->reset_task); return; } - while (test_and_set_bit(__IAVF_IN_CLIENT_TASK, - &adapter->crit_section)) + while (!mutex_trylock(&adapter->client_lock)) usleep_range(500, 1000); if (CLIENT_ENABLED(adapter)) { adapter->flags &= ~(IAVF_FLAG_CLIENT_NEEDS_OPEN | @@ -2178,7 +2172,7 @@ static void iavf_reset_task(struct work_struct *work) dev_err(&adapter->pdev->dev, "Reset never finished (%x)\n", reg_val); iavf_disable_vf(adapter); - clear_bit(__IAVF_IN_CLIENT_TASK, &adapter->crit_section); + mutex_unlock(&adapter->client_lock); return; /* Do not attempt to reinit. It's dead, Jim. */ }
@@ -2305,13 +2299,13 @@ static void iavf_reset_task(struct work_struct *work) adapter->state = __IAVF_DOWN; wake_up(&adapter->down_waitqueue); } - clear_bit(__IAVF_IN_CLIENT_TASK, &adapter->crit_section); - clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); + mutex_unlock(&adapter->client_lock); + mutex_unlock(&adapter->crit_lock);
return; reset_err: - clear_bit(__IAVF_IN_CLIENT_TASK, &adapter->crit_section); - clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); + mutex_unlock(&adapter->client_lock); + mutex_unlock(&adapter->crit_lock); dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n"); iavf_close(netdev); } @@ -2339,7 +2333,7 @@ static void iavf_adminq_task(struct work_struct *work) if (!event.msg_buf) goto out;
- if (iavf_lock_timeout(adapter, __IAVF_IN_CRITICAL_TASK, 200)) + if (iavf_lock_timeout(&adapter->crit_lock, 200)) goto freedom; do { ret = iavf_clean_arq_element(hw, &event, &pending); @@ -2354,7 +2348,7 @@ static void iavf_adminq_task(struct work_struct *work) if (pending != 0) memset(event.msg_buf, 0, IAVF_MAX_AQ_BUF_SIZE); } while (pending); - clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); + mutex_unlock(&adapter->crit_lock);
if ((adapter->flags & (IAVF_FLAG_RESET_PENDING | IAVF_FLAG_RESET_NEEDED)) || @@ -2421,7 +2415,7 @@ static void iavf_client_task(struct work_struct *work) * later. */
- if (test_and_set_bit(__IAVF_IN_CLIENT_TASK, &adapter->crit_section)) + if (!mutex_trylock(&adapter->client_lock)) return;
if (adapter->flags & IAVF_FLAG_SERVICE_CLIENT_REQUESTED) { @@ -2444,7 +2438,7 @@ static void iavf_client_task(struct work_struct *work) adapter->flags &= ~IAVF_FLAG_CLIENT_NEEDS_OPEN; } out: - clear_bit(__IAVF_IN_CLIENT_TASK, &adapter->crit_section); + mutex_unlock(&adapter->client_lock); }
/** @@ -3047,8 +3041,7 @@ static int iavf_configure_clsflower(struct iavf_adapter *adapter, if (!filter) return -ENOMEM;
- while (test_and_set_bit(__IAVF_IN_CRITICAL_TASK, - &adapter->crit_section)) { + while (!mutex_trylock(&adapter->crit_lock)) { if (--count == 0) goto err; udelay(1); @@ -3079,7 +3072,7 @@ static int iavf_configure_clsflower(struct iavf_adapter *adapter, if (err) kfree(filter);
- clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); + mutex_unlock(&adapter->crit_lock); return err; }
@@ -3226,8 +3219,7 @@ static int iavf_open(struct net_device *netdev) return -EIO; }
- while (test_and_set_bit(__IAVF_IN_CRITICAL_TASK, - &adapter->crit_section)) + while (!mutex_trylock(&adapter->crit_lock)) usleep_range(500, 1000);
if (adapter->state != __IAVF_DOWN) { @@ -3262,7 +3254,7 @@ static int iavf_open(struct net_device *netdev)
iavf_irq_enable(adapter, true);
- clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); + mutex_unlock(&adapter->crit_lock);
return 0;
@@ -3274,7 +3266,7 @@ static int iavf_open(struct net_device *netdev) err_setup_tx: iavf_free_all_tx_resources(adapter); err_unlock: - clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); + mutex_unlock(&adapter->crit_lock);
return err; } @@ -3298,8 +3290,7 @@ static int iavf_close(struct net_device *netdev) if (adapter->state <= __IAVF_DOWN_PENDING) return 0;
- while (test_and_set_bit(__IAVF_IN_CRITICAL_TASK, - &adapter->crit_section)) + while (!mutex_trylock(&adapter->crit_lock)) usleep_range(500, 1000);
set_bit(__IAVF_VSI_DOWN, adapter->vsi.state); @@ -3310,7 +3301,7 @@ static int iavf_close(struct net_device *netdev) adapter->state = __IAVF_DOWN_PENDING; iavf_free_traffic_irqs(adapter);
- clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); + mutex_unlock(&adapter->crit_lock);
/* We explicitly don't free resources here because the hardware is * still active and can DMA into memory. Resources are cleared in @@ -3659,8 +3650,8 @@ static void iavf_init_task(struct work_struct *work) init_task.work); struct iavf_hw *hw = &adapter->hw;
- if (iavf_lock_timeout(adapter, __IAVF_IN_CRITICAL_TASK, 5000)) { - dev_warn(&adapter->pdev->dev, "failed to set __IAVF_IN_CRITICAL_TASK in %s\n", __FUNCTION__); + if (iavf_lock_timeout(&adapter->crit_lock, 5000)) { + dev_warn(&adapter->pdev->dev, "failed to acquire crit_lock in %s\n", __FUNCTION__); return; } switch (adapter->state) { @@ -3695,7 +3686,7 @@ static void iavf_init_task(struct work_struct *work) } queue_delayed_work(iavf_wq, &adapter->init_task, HZ); out: - clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); + mutex_unlock(&adapter->crit_lock); }
/** @@ -3712,12 +3703,12 @@ static void iavf_shutdown(struct pci_dev *pdev) if (netif_running(netdev)) iavf_close(netdev);
- if (iavf_lock_timeout(adapter, __IAVF_IN_CRITICAL_TASK, 5000)) - dev_warn(&adapter->pdev->dev, "failed to set __IAVF_IN_CRITICAL_TASK in %s\n", __FUNCTION__); + if (iavf_lock_timeout(&adapter->crit_lock, 5000)) + dev_warn(&adapter->pdev->dev, "failed to acquire crit_lock in %s\n", __FUNCTION__); /* Prevent the watchdog from running. */ adapter->state = __IAVF_REMOVE; adapter->aq_required = 0; - clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); + mutex_unlock(&adapter->crit_lock);
#ifdef CONFIG_PM pci_save_state(pdev); @@ -3811,6 +3802,9 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* set up the locks for the AQ, do this only once in probe * and destroy them only once in remove */ + mutex_init(&adapter->crit_lock); + mutex_init(&adapter->client_lock); + mutex_init(&adapter->remove_lock); mutex_init(&hw->aq.asq_mutex); mutex_init(&hw->aq.arq_mutex);
@@ -3862,8 +3856,7 @@ static int __maybe_unused iavf_suspend(struct device *dev_d)
netif_device_detach(netdev);
- while (test_and_set_bit(__IAVF_IN_CRITICAL_TASK, - &adapter->crit_section)) + while (!mutex_trylock(&adapter->crit_lock)) usleep_range(500, 1000);
if (netif_running(netdev)) { @@ -3874,7 +3867,7 @@ static int __maybe_unused iavf_suspend(struct device *dev_d) iavf_free_misc_irq(adapter); iavf_reset_interrupt_capability(adapter);
- clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); + mutex_unlock(&adapter->crit_lock);
return 0; } @@ -3936,7 +3929,7 @@ static void iavf_remove(struct pci_dev *pdev) struct iavf_hw *hw = &adapter->hw; int err; /* Indicate we are in remove and not to run reset_task */ - set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section); + mutex_lock(&adapter->remove_lock); cancel_delayed_work_sync(&adapter->init_task); cancel_work_sync(&adapter->reset_task); cancel_delayed_work_sync(&adapter->client_task); @@ -3958,8 +3951,8 @@ static void iavf_remove(struct pci_dev *pdev) iavf_request_reset(adapter); msleep(50); } - if (iavf_lock_timeout(adapter, __IAVF_IN_CRITICAL_TASK, 5000)) - dev_warn(&adapter->pdev->dev, "failed to set __IAVF_IN_CRITICAL_TASK in %s\n", __FUNCTION__); + if (iavf_lock_timeout(&adapter->crit_lock, 5000)) + dev_warn(&adapter->pdev->dev, "failed to acquire crit_lock in %s\n", __FUNCTION__);
/* Shut down all the garbage mashers on the detention level */ adapter->state = __IAVF_REMOVE; @@ -3984,6 +3977,11 @@ static void iavf_remove(struct pci_dev *pdev) /* destroy the locks only once, here */ mutex_destroy(&hw->aq.arq_mutex); mutex_destroy(&hw->aq.asq_mutex); + mutex_destroy(&adapter->client_lock); + mutex_unlock(&adapter->crit_lock); + mutex_destroy(&adapter->crit_lock); + mutex_unlock(&adapter->remove_lock); + mutex_destroy(&adapter->remove_lock);
iounmap(hw->hw_addr); pci_release_regions(pdev);
From: Yucong Sun fallentree@fb.com
[ Upstream commit f667d1d66760fcb27aee6c9964eefde39a464afe ]
In skip_account(), test->skip_cnt is set to 0 at the end, this makes next print statement never display SKIP status for the subtest. This patch moves the accounting logic after the print statement, fixing the issue.
This patch also added SKIP status display for normal tests.
Signed-off-by: Yucong Sun fallentree@fb.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20210817044732.3263066-3-fallentree@fb.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/test_progs.c | 25 ++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index 6396932b97e2..9ed13187136c 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -148,18 +148,18 @@ void test__end_subtest() struct prog_test_def *test = env.test; int sub_error_cnt = test->error_cnt - test->old_error_cnt;
- if (sub_error_cnt) - env.fail_cnt++; - else if (test->skip_cnt == 0) - env.sub_succ_cnt++; - skip_account(); - dump_test_log(test, sub_error_cnt);
fprintf(env.stdout, "#%d/%d %s:%s\n", test->test_num, test->subtest_num, test->subtest_name, sub_error_cnt ? "FAIL" : (test->skip_cnt ? "SKIP" : "OK"));
+ if (sub_error_cnt) + env.fail_cnt++; + else if (test->skip_cnt == 0) + env.sub_succ_cnt++; + skip_account(); + free(test->subtest_name); test->subtest_name = NULL; } @@ -783,17 +783,18 @@ int main(int argc, char **argv) test__end_subtest();
test->tested = true; - if (test->error_cnt) - env.fail_cnt++; - else - env.succ_cnt++; - skip_account();
dump_test_log(test, test->error_cnt);
fprintf(env.stdout, "#%d %s:%s\n", test->test_num, test->test_name, - test->error_cnt ? "FAIL" : "OK"); + test->error_cnt ? "FAIL" : (test->skip_cnt ? "SKIP" : "OK")); + + if (test->error_cnt) + env.fail_cnt++; + else + env.succ_cnt++; + skip_account();
reset_affinity(); restore_netns();
From: Yonghong Song yhs@fb.com
[ Upstream commit b16ac5bf732a5e23d164cf908ec7742d6a6120d3 ]
libbpf CI has reported send_signal test is flaky although I am not able to reproduce it in my local environment. But I am able to reproduce with on-demand libbpf CI ([1]).
Through code analysis, the following is possible reason. The failed subtest runs bpf program in softirq environment. Since bpf_send_signal() only sends to a fork of "test_progs" process. If the underlying current task is not "test_progs", bpf_send_signal() will not be triggered and the subtest will fail.
To reduce the chances where the underlying process is not the intended one, this patch boosted scheduling priority to -20 (highest allowed by setpriority() call). And I did 10 runs with on-demand libbpf CI with this patch and I didn't observe any failures.
[1] https://github.com/libbpf/libbpf/actions/workflows/ondemand.yml
Signed-off-by: Yonghong Song yhs@fb.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20210817190923.3186725-1-yhs@fb.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../selftests/bpf/prog_tests/send_signal.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c index 7043e6ded0e6..75b72c751772 100644 --- a/tools/testing/selftests/bpf/prog_tests/send_signal.c +++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include <test_progs.h> +#include <sys/time.h> +#include <sys/resource.h> #include "test_send_signal_kern.skel.h"
static volatile int sigusr1_received = 0; @@ -41,12 +43,23 @@ static void test_send_signal_common(struct perf_event_attr *attr, }
if (pid == 0) { + int old_prio; + /* install signal handler and notify parent */ signal(SIGUSR1, sigusr1_handler);
close(pipe_c2p[0]); /* close read */ close(pipe_p2c[1]); /* close write */
+ /* boost with a high priority so we got a higher chance + * that if an interrupt happens, the underlying task + * is this process. + */ + errno = 0; + old_prio = getpriority(PRIO_PROCESS, 0); + ASSERT_OK(errno, "getpriority"); + ASSERT_OK(setpriority(PRIO_PROCESS, 0, -20), "setpriority"); + /* notify parent signal handler is installed */ CHECK(write(pipe_c2p[1], buf, 1) != 1, "pipe_write", "err %d\n", -errno);
@@ -62,6 +75,9 @@ static void test_send_signal_common(struct perf_event_attr *attr, /* wait for parent notification and exit */ CHECK(read(pipe_p2c[0], buf, 1) != 1, "pipe_read", "err %d\n", -errno);
+ /* restore the old priority */ + ASSERT_OK(setpriority(PRIO_PROCESS, 0, old_prio), "setpriority"); + close(pipe_c2p[1]); close(pipe_p2c[0]); exit(0);
From: Brandon Wyman bjwyman@gmail.com
[ Upstream commit 76b72736f574ec38b3e94603ea5f74b1853f26b0 ]
When doing a PMBus write for the LED control on the IBM Common Form Factor Power Supplies (ibm-cffps), the DAh command requires that bit 7 be low and bit 6 be high in order to indicate that you are truly attempting to do a write.
Signed-off-by: Brandon Wyman bjwyman@gmail.com Link: https://lore.kernel.org/r/20210806225131.1808759-1-bjwyman@gmail.com Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/pmbus/ibm-cffps.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/pmbus/ibm-cffps.c b/drivers/hwmon/pmbus/ibm-cffps.c index 5668d8305b78..df712ce4b164 100644 --- a/drivers/hwmon/pmbus/ibm-cffps.c +++ b/drivers/hwmon/pmbus/ibm-cffps.c @@ -50,9 +50,9 @@ #define CFFPS_MFR_VAUX_FAULT BIT(6) #define CFFPS_MFR_CURRENT_SHARE_WARNING BIT(7)
-#define CFFPS_LED_BLINK BIT(0) -#define CFFPS_LED_ON BIT(1) -#define CFFPS_LED_OFF BIT(2) +#define CFFPS_LED_BLINK (BIT(0) | BIT(6)) +#define CFFPS_LED_ON (BIT(1) | BIT(6)) +#define CFFPS_LED_OFF (BIT(2) | BIT(6)) #define CFFPS_BLINK_RATE_MS 250
enum {
From: Kees Cook keescook@chromium.org
[ Upstream commit cbe34165cc1b7d1110b268ba8b9f30843c941639 ]
Fix buf allocation size (it needs to be 2 bytes larger). Found when __alloc_size() annotations were added to kmalloc() interfaces.
In file included from ./include/linux/string.h:253, from ./include/linux/bitmap.h:10, from ./include/linux/cpumask.h:12, from ./arch/x86/include/asm/paravirt.h:17, from ./arch/x86/include/asm/irqflags.h:63, from ./include/linux/irqflags.h:16, from ./include/linux/rcupdate.h:26, from ./include/linux/rculist.h:11, from ./include/linux/pid.h:5, from ./include/linux/sched.h:14, from ./include/linux/blkdev.h:5, from drivers/staging/rts5208/rtsx_scsi.c:12: In function 'get_ms_information', inlined from 'ms_sp_cmnd' at drivers/staging/rts5208/rtsx_scsi.c:2877:12, inlined from 'rtsx_scsi_handler' at drivers/staging/rts5208/rtsx_scsi.c:3247:12: ./include/linux/fortify-string.h:54:29: warning: '__builtin_memcpy' forming offset [106, 107] is out of the bounds [0, 106] [-Warray-bounds] 54 | #define __underlying_memcpy __builtin_memcpy | ^ ./include/linux/fortify-string.h:417:2: note: in expansion of macro '__underlying_memcpy' 417 | __underlying_##op(p, q, __fortify_size); \ | ^~~~~~~~~~~~~ ./include/linux/fortify-string.h:463:26: note: in expansion of macro '__fortify_memcpy_chk' 463 | #define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \ | ^~~~~~~~~~~~~~~~~~~~ drivers/staging/rts5208/rtsx_scsi.c:2851:3: note: in expansion of macro 'memcpy' 2851 | memcpy(buf + i, ms_card->raw_sys_info, 96); | ^~~~~~
Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: linux-staging@lists.linux.dev Signed-off-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20210818044252.1533634-1-keescook@chromium.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/rts5208/rtsx_scsi.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/staging/rts5208/rtsx_scsi.c b/drivers/staging/rts5208/rtsx_scsi.c index 1deb74112ad4..11d9d9155eef 100644 --- a/drivers/staging/rts5208/rtsx_scsi.c +++ b/drivers/staging/rts5208/rtsx_scsi.c @@ -2802,10 +2802,10 @@ static int get_ms_information(struct scsi_cmnd *srb, struct rtsx_chip *chip) }
if (dev_info_id == 0x15) { - buf_len = 0x3A; + buf_len = 0x3C; data_len = 0x3A; } else { - buf_len = 0x6A; + buf_len = 0x6C; data_len = 0x6A; }
@@ -2855,11 +2855,7 @@ static int get_ms_information(struct scsi_cmnd *srb, struct rtsx_chip *chip) }
rtsx_stor_set_xfer_buf(buf, buf_len, srb); - - if (dev_info_id == 0x15) - scsi_set_resid(srb, scsi_bufflen(srb) - 0x3C); - else - scsi_set_resid(srb, scsi_bufflen(srb) - 0x6C); + scsi_set_resid(srb, scsi_bufflen(srb) - buf_len);
kfree(buf); return STATUS_SUCCESS;
From: Bongsu Jeon bongsu.jeon@samsung.com
[ Upstream commit 78a7b2a8a0fa31f63ac16ac13601db6ed8259dfc ]
nlattr could have a padding for 4 bytes alignment. So next nla's offset should be calculated with a padding.
Signed-off-by: Bongsu Jeon bongsu.jeon@samsung.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/nci/nci_dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/nci/nci_dev.c b/tools/testing/selftests/nci/nci_dev.c index 57b505cb1561..9687100f15ea 100644 --- a/tools/testing/selftests/nci/nci_dev.c +++ b/tools/testing/selftests/nci/nci_dev.c @@ -113,8 +113,8 @@ static int send_cmd_mt_nla(int sd, __u16 nlmsg_type, __u32 nlmsg_pid, if (nla_len > 0) memcpy(NLA_DATA(na), nla_data[cnt], nla_len[cnt]);
- msg.n.nlmsg_len += NLMSG_ALIGN(na->nla_len); - prv_len = na->nla_len; + prv_len = NLA_ALIGN(nla_len[cnt]) + NLA_HDRLEN; + msg.n.nlmsg_len += prv_len; }
buf = (char *)&msg;
From: Bongsu Jeon bongsu.jeon@samsung.com
[ Upstream commit 1d5b8d01db98abb8c176838fad73287366874582 ]
memcpy should be executed only in case nla_len's value is greater than 0.
Signed-off-by: Bongsu Jeon bongsu.jeon@samsung.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/nci/nci_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/nci/nci_dev.c b/tools/testing/selftests/nci/nci_dev.c index 9687100f15ea..acd4125ff39f 100644 --- a/tools/testing/selftests/nci/nci_dev.c +++ b/tools/testing/selftests/nci/nci_dev.c @@ -110,7 +110,7 @@ static int send_cmd_mt_nla(int sd, __u16 nlmsg_type, __u32 nlmsg_pid, na->nla_type = nla_type[cnt]; na->nla_len = nla_len[cnt] + NLA_HDRLEN;
- if (nla_len > 0) + if (nla_len[cnt] > 0) memcpy(NLA_DATA(na), nla_data[cnt], nla_len[cnt]);
prv_len = NLA_ALIGN(nla_len[cnt]) + NLA_HDRLEN;
From: Eli Cohen elic@nvidia.com
[ Upstream commit 74fc4f828769cca1c3be89ea92cb88feaa27ef52 ]
Currently, when creating an ingress qdisc on an indirect device before the driver registered for callbacks, the driver will not have a chance to register its filter configuration callbacks.
To fix that, modify the code such that it keeps track of all the ingress qdiscs that call flow_indr_dev_setup_offload(). When a driver calls flow_indr_dev_register(), go through the list of tracked ingress qdiscs and call the driver callback entry point so as to give it a chance to register its callback.
Reviewed-by: Jiri Pirko jiri@nvidia.com Signed-off-by: Eli Cohen elic@nvidia.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/flow_offload.h | 1 + net/core/flow_offload.c | 89 ++++++++++++++++++++++++++- net/netfilter/nf_flow_table_offload.c | 1 + net/netfilter/nf_tables_offload.c | 1 + net/sched/cls_api.c | 1 + 5 files changed, 92 insertions(+), 1 deletion(-)
diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h index dc5c1e69cd9f..26788244d75b 100644 --- a/include/net/flow_offload.h +++ b/include/net/flow_offload.h @@ -451,6 +451,7 @@ struct flow_block_offload { struct list_head *driver_block_list; struct netlink_ext_ack *extack; struct Qdisc *sch; + struct list_head *cb_list_head; };
enum tc_setup_type; diff --git a/net/core/flow_offload.c b/net/core/flow_offload.c index 715b67f6c62f..e3f0d5906811 100644 --- a/net/core/flow_offload.c +++ b/net/core/flow_offload.c @@ -321,6 +321,7 @@ EXPORT_SYMBOL(flow_block_cb_setup_simple); static DEFINE_MUTEX(flow_indr_block_lock); static LIST_HEAD(flow_block_indr_list); static LIST_HEAD(flow_block_indr_dev_list); +static LIST_HEAD(flow_indir_dev_list);
struct flow_indr_dev { struct list_head list; @@ -346,6 +347,33 @@ static struct flow_indr_dev *flow_indr_dev_alloc(flow_indr_block_bind_cb_t *cb, return indr_dev; }
+struct flow_indir_dev_info { + void *data; + struct net_device *dev; + struct Qdisc *sch; + enum tc_setup_type type; + void (*cleanup)(struct flow_block_cb *block_cb); + struct list_head list; + enum flow_block_command command; + enum flow_block_binder_type binder_type; + struct list_head *cb_list; +}; + +static void existing_qdiscs_register(flow_indr_block_bind_cb_t *cb, void *cb_priv) +{ + struct flow_block_offload bo; + struct flow_indir_dev_info *cur; + + list_for_each_entry(cur, &flow_indir_dev_list, list) { + memset(&bo, 0, sizeof(bo)); + bo.command = cur->command; + bo.binder_type = cur->binder_type; + INIT_LIST_HEAD(&bo.cb_list); + cb(cur->dev, cur->sch, cb_priv, cur->type, &bo, cur->data, cur->cleanup); + list_splice(&bo.cb_list, cur->cb_list); + } +} + int flow_indr_dev_register(flow_indr_block_bind_cb_t *cb, void *cb_priv) { struct flow_indr_dev *indr_dev; @@ -367,6 +395,7 @@ int flow_indr_dev_register(flow_indr_block_bind_cb_t *cb, void *cb_priv) }
list_add(&indr_dev->list, &flow_block_indr_dev_list); + existing_qdiscs_register(cb, cb_priv); mutex_unlock(&flow_indr_block_lock);
return 0; @@ -463,7 +492,59 @@ struct flow_block_cb *flow_indr_block_cb_alloc(flow_setup_cb_t *cb, } EXPORT_SYMBOL(flow_indr_block_cb_alloc);
-int flow_indr_dev_setup_offload(struct net_device *dev, struct Qdisc *sch, +static struct flow_indir_dev_info *find_indir_dev(void *data) +{ + struct flow_indir_dev_info *cur; + + list_for_each_entry(cur, &flow_indir_dev_list, list) { + if (cur->data == data) + return cur; + } + return NULL; +} + +static int indir_dev_add(void *data, struct net_device *dev, struct Qdisc *sch, + enum tc_setup_type type, void (*cleanup)(struct flow_block_cb *block_cb), + struct flow_block_offload *bo) +{ + struct flow_indir_dev_info *info; + + info = find_indir_dev(data); + if (info) + return -EEXIST; + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->data = data; + info->dev = dev; + info->sch = sch; + info->type = type; + info->cleanup = cleanup; + info->command = bo->command; + info->binder_type = bo->binder_type; + info->cb_list = bo->cb_list_head; + + list_add(&info->list, &flow_indir_dev_list); + return 0; +} + +static int indir_dev_remove(void *data) +{ + struct flow_indir_dev_info *info; + + info = find_indir_dev(data); + if (!info) + return -ENOENT; + + list_del(&info->list); + + kfree(info); + return 0; +} + +int flow_indr_dev_setup_offload(struct net_device *dev, struct Qdisc *sch, enum tc_setup_type type, void *data, struct flow_block_offload *bo, void (*cleanup)(struct flow_block_cb *block_cb)) @@ -471,6 +552,12 @@ int flow_indr_dev_setup_offload(struct net_device *dev, struct Qdisc *sch, struct flow_indr_dev *this;
mutex_lock(&flow_indr_block_lock); + + if (bo->command == FLOW_BLOCK_BIND) + indir_dev_add(data, dev, sch, type, cleanup, bo); + else if (bo->command == FLOW_BLOCK_UNBIND) + indir_dev_remove(data); + list_for_each_entry(this, &flow_block_indr_dev_list, list) this->cb(dev, sch, this->cb_priv, type, bo, data, cleanup);
diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c index 528b2f172684..0587f071e504 100644 --- a/net/netfilter/nf_flow_table_offload.c +++ b/net/netfilter/nf_flow_table_offload.c @@ -1097,6 +1097,7 @@ static void nf_flow_table_block_offload_init(struct flow_block_offload *bo, bo->command = cmd; bo->binder_type = FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS; bo->extack = extack; + bo->cb_list_head = &flowtable->flow_block.cb_list; INIT_LIST_HEAD(&bo->cb_list); }
diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c index b58d73a96523..9656c1646222 100644 --- a/net/netfilter/nf_tables_offload.c +++ b/net/netfilter/nf_tables_offload.c @@ -353,6 +353,7 @@ static void nft_flow_block_offload_init(struct flow_block_offload *bo, bo->command = cmd; bo->binder_type = FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS; bo->extack = extack; + bo->cb_list_head = &basechain->flow_block.cb_list; INIT_LIST_HEAD(&bo->cb_list); }
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index e3e79e9bd706..9b276d14be4c 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -634,6 +634,7 @@ static void tcf_block_offload_init(struct flow_block_offload *bo, bo->block_shared = shared; bo->extack = extack; bo->sch = sch; + bo->cb_list_head = &flow_block->cb_list; INIT_LIST_HEAD(&bo->cb_list); }
From: Mark Brown broonie@kernel.org
[ Upstream commit 83e5dcbece4ea67ec3ad94b897e2844184802fd7 ]
When skipping the tests due to a lack of system support for MTE we currently print a message saying FAIL which makes it look like the test failed even though the test did actually report KSFT_SKIP, creating some confusion. Change the error message to say SKIP instead so things are clearer.
Signed-off-by: Mark Brown broonie@kernel.org Link: https://lore.kernel.org/r/20210819172902.56211-1-broonie@kernel.org Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/arm64/mte/mte_common_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/arm64/mte/mte_common_util.c b/tools/testing/selftests/arm64/mte/mte_common_util.c index f50ac31920d1..0328a1e08f65 100644 --- a/tools/testing/selftests/arm64/mte/mte_common_util.c +++ b/tools/testing/selftests/arm64/mte/mte_common_util.c @@ -298,7 +298,7 @@ int mte_default_setup(void) int ret;
if (!(hwcaps2 & HWCAP2_MTE)) { - ksft_print_msg("FAIL: MTE features unavailable\n"); + ksft_print_msg("SKIP: MTE features unavailable\n"); return KSFT_SKIP; } /* Get current mte mode */
From: Mark Brown broonie@kernel.org
[ Upstream commit 0c69bd2ca6ee20064dde7853cd749284e053a874 ]
The PAC tests check to see if the system supports the relevant PAC features but instead of skipping the tests if they can't be executed they fail the tests which makes things look like they're not working when they are.
Signed-off-by: Mark Brown broonie@kernel.org Link: https://lore.kernel.org/r/20210819165723.43903-1-broonie@kernel.org Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/arm64/pauth/pac.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/arm64/pauth/pac.c b/tools/testing/selftests/arm64/pauth/pac.c index 592fe538506e..b743daa772f5 100644 --- a/tools/testing/selftests/arm64/pauth/pac.c +++ b/tools/testing/selftests/arm64/pauth/pac.c @@ -25,13 +25,15 @@ do { \ unsigned long hwcaps = getauxval(AT_HWCAP); \ /* data key instructions are not in NOP space. This prevents a SIGILL */ \ - ASSERT_NE(0, hwcaps & HWCAP_PACA) TH_LOG("PAUTH not enabled"); \ + if (!(hwcaps & HWCAP_PACA)) \ + SKIP(return, "PAUTH not enabled"); \ } while (0) #define ASSERT_GENERIC_PAUTH_ENABLED() \ do { \ unsigned long hwcaps = getauxval(AT_HWCAP); \ /* generic key instructions are not in NOP space. This prevents a SIGILL */ \ - ASSERT_NE(0, hwcaps & HWCAP_PACG) TH_LOG("Generic PAUTH not enabled"); \ + if (!(hwcaps & HWCAP_PACG)) \ + SKIP(return, "Generic PAUTH not enabled"); \ } while (0)
void sign_specific(struct signatures *sign, size_t val) @@ -256,7 +258,7 @@ TEST(single_thread_different_keys) unsigned long hwcaps = getauxval(AT_HWCAP);
/* generic and data key instructions are not in NOP space. This prevents a SIGILL */ - ASSERT_NE(0, hwcaps & HWCAP_PACA) TH_LOG("PAUTH not enabled"); + ASSERT_PAUTH_ENABLED(); if (!(hwcaps & HWCAP_PACG)) { TH_LOG("WARNING: Generic PAUTH not enabled. Skipping generic key checks"); nkeys = NKEYS - 1; @@ -299,7 +301,7 @@ TEST(exec_changed_keys) unsigned long hwcaps = getauxval(AT_HWCAP);
/* generic and data key instructions are not in NOP space. This prevents a SIGILL */ - ASSERT_NE(0, hwcaps & HWCAP_PACA) TH_LOG("PAUTH not enabled"); + ASSERT_PAUTH_ENABLED(); if (!(hwcaps & HWCAP_PACG)) { TH_LOG("WARNING: Generic PAUTH not enabled. Skipping generic key checks"); nkeys = NKEYS - 1;
From: Bob Peterson rpeterso@redhat.com
[ Upstream commit d1340f80f0b8066321b499a376780da00560e857 ]
In the gfs2 withdraw sequence, the dlm protocol is unmounted with a call to lm_unmount. After a withdraw, users are allowed to unmount the withdrawn file system. But at that point we may still have glocks left over that we need to free via unmount's call to gfs2_gl_hash_clear. These glocks may have never been completed because of whatever problem caused the withdraw (IO errors or whatever).
Before this patch, function gdlm_put_lock would still try to call into dlm to unlock these leftover glocks, which resulted in dlm returning -EINVAL because the lock space was abandoned. These glocks were never freed because there was no mechanism after that to free them.
This patch adds a check to gdlm_put_lock to see if the locking protocol was inactive (DFL_UNMOUNT flag) and if so, free the glock and not make the invalid call into dlm.
I could have combined this "if" with the one that follows, related to leftover glock LVBs, but I felt the code was more readable with its own if clause.
Signed-off-by: Bob Peterson rpeterso@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/gfs2/lock_dlm.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c index dac040162ecc..50578f881e6d 100644 --- a/fs/gfs2/lock_dlm.c +++ b/fs/gfs2/lock_dlm.c @@ -299,6 +299,11 @@ static void gdlm_put_lock(struct gfs2_glock *gl) gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT); gfs2_update_request_times(gl);
+ /* don't want to call dlm if we've unmounted the lock protocol */ + if (test_bit(DFL_UNMOUNT, &ls->ls_recover_flags)) { + gfs2_glock_free(gl); + return; + } /* don't want to skip dlm_unlock writing the lvb when lock has one */
if (test_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags) &&
From: Li Jun jun.li@nxp.com
[ Upstream commit e5d6a7c6cfae9e714a0e8ff64facd1ac68a784c6 ]
If wIndex is 0 (and it often is), these calculations underflow and UBSAN complains, here resolve this by not decrementing the index when it is equal to 0, this copies the solution from commit 85e3990bea49 ("USB: EHCI: avoid undefined pointer arithmetic and placate UBSAN")
Reported-by: Zhipeng Wang zhipeng.wang_1@nxp.com Signed-off-by: Li Jun jun.li@nxp.com Link: https://lore.kernel.org/r/1624004938-2399-1-git-send-email-jun.li@nxp.com Signed-off-by: Peter Chen peter.chen@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/chipidea/host.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index e86d13c04bdb..bdc3885c0d49 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -240,15 +240,18 @@ static int ci_ehci_hub_control( ) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); + unsigned int ports = HCS_N_PORTS(ehci->hcs_params); u32 __iomem *status_reg; - u32 temp; + u32 temp, port_index; unsigned long flags; int retval = 0; bool done = false; struct device *dev = hcd->self.controller; struct ci_hdrc *ci = dev_get_drvdata(dev);
- status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1]; + port_index = wIndex & 0xff; + port_index -= (port_index > 0); + status_reg = &ehci->regs->port_status[port_index];
spin_lock_irqsave(&ehci->lock, flags);
@@ -260,6 +263,11 @@ static int ci_ehci_hub_control( }
if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) { + if (!wIndex || wIndex > ports) { + retval = -EPIPE; + goto done; + } + temp = ehci_readl(ehci, status_reg); if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) { retval = -EPIPE; @@ -288,7 +296,7 @@ static int ci_ehci_hub_control( ehci_writel(ehci, temp, status_reg); }
- set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports); + set_bit(port_index, &ehci->suspended_ports); goto done; }
From: J. Bruce Fields bfields@redhat.com
[ Upstream commit 7de875b231edb807387a81cde288aa9e1015ef9e ]
Locks have two sets of op arrays, fl_lmops for the lock manager (lockd or nfsd), fl_ops for the filesystem. The server-side lockd code has been setting its own fl_ops, which leads to confusion (and crashes) in the reexport case, where the filesystem expects to be the only one setting fl_ops.
And there's no reason for it that I can see-the lm_get/put_owner ops do the same job.
Reported-by: Daire Byrne daire@dneg.com Tested-by: Daire Byrne daire@dneg.com Signed-off-by: J. Bruce Fields bfields@redhat.com Signed-off-by: Chuck Lever chuck.lever@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/lockd/svclock.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-)
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index 498cb70c2c0d..273a81971ed5 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c @@ -395,28 +395,10 @@ nlmsvc_release_lockowner(struct nlm_lock *lock) nlmsvc_put_lockowner(lock->fl.fl_owner); }
-static void nlmsvc_locks_copy_lock(struct file_lock *new, struct file_lock *fl) -{ - struct nlm_lockowner *nlm_lo = (struct nlm_lockowner *)fl->fl_owner; - new->fl_owner = nlmsvc_get_lockowner(nlm_lo); -} - -static void nlmsvc_locks_release_private(struct file_lock *fl) -{ - nlmsvc_put_lockowner((struct nlm_lockowner *)fl->fl_owner); -} - -static const struct file_lock_operations nlmsvc_lock_ops = { - .fl_copy_lock = nlmsvc_locks_copy_lock, - .fl_release_private = nlmsvc_locks_release_private, -}; - void nlmsvc_locks_init_private(struct file_lock *fl, struct nlm_host *host, pid_t pid) { fl->fl_owner = nlmsvc_find_lockowner(host, pid); - if (fl->fl_owner != NULL) - fl->fl_ops = &nlmsvc_lock_ops; }
/* @@ -788,9 +770,21 @@ nlmsvc_notify_blocked(struct file_lock *fl) printk(KERN_WARNING "lockd: notification for unknown block!\n"); }
+static fl_owner_t nlmsvc_get_owner(fl_owner_t owner) +{ + return nlmsvc_get_lockowner(owner); +} + +static void nlmsvc_put_owner(fl_owner_t owner) +{ + nlmsvc_put_lockowner(owner); +} + const struct lock_manager_operations nlmsvc_lock_operations = { .lm_notify = nlmsvc_notify_blocked, .lm_grant = nlmsvc_grant_deferred, + .lm_get_owner = nlmsvc_get_owner, + .lm_put_owner = nlmsvc_put_owner, };
/*
From: Nathan Chancellor nathan@kernel.org
[ Upstream commit c626f3864bbbb28bbe06476b0b497c1330aa4463 ]
In certain randconfigs, clang warns:
drivers/gpu/drm/exynos/exynos_drm_dma.c:121:19: warning: variable 'mapping' is uninitialized when used here [-Wuninitialized] priv->mapping = mapping; ^~~~~~~ drivers/gpu/drm/exynos/exynos_drm_dma.c:111:16: note: initialize the variable 'mapping' to silence this warning void *mapping; ^ = NULL 1 warning generated.
This occurs when CONFIG_EXYNOS_IOMMU is enabled and both CONFIG_ARM_DMA_USE_IOMMU and CONFIG_IOMMU_DMA are disabled, which makes the code look like
void *mapping;
if (0) mapping = arm_iommu_create_mapping() else if (0) mapping = iommu_get_domain_for_dev()
... priv->mapping = mapping;
Add an else branch that initializes mapping to the -ENODEV error pointer so that there is no more warning and the driver does not change during runtime.
Reported-by: kernel test robot lkp@intel.com Signed-off-by: Nathan Chancellor nathan@kernel.org Signed-off-by: Inki Dae inki.dae@samsung.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/exynos/exynos_drm_dma.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dma.c b/drivers/gpu/drm/exynos/exynos_drm_dma.c index 0644936afee2..bf33c3084cb4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dma.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dma.c @@ -115,6 +115,8 @@ int exynos_drm_register_dma(struct drm_device *drm, struct device *dev, EXYNOS_DEV_ADDR_START, EXYNOS_DEV_ADDR_SIZE); else if (IS_ENABLED(CONFIG_IOMMU_DMA)) mapping = iommu_get_domain_for_dev(priv->dma_dev); + else + mapping = ERR_PTR(-ENODEV);
if (IS_ERR(mapping)) return PTR_ERR(mapping);
From: Chris Chiu chris.chiu@canonical.com
[ Upstream commit 95a581ab3592082c60a08090aabe09ac7d0bd650 ]
The TX A-MPDU aggregation is not handled in the driver since the ieee80211_start_tx_ba_session has never been started properly. Start and stop the TX BA session by tracking the TX aggregation status of each TID. Fix the ampdu_action and the tx descriptor accordingly with the given TID.
Signed-off-by: Chris Chiu chris.chiu@canonical.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210804151325.86600-1-chris.chiu@canonical.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 2 ++ .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 33 ++++++++++++++----- 2 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h index 01735776345a..7ddce3c3f0c4 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h @@ -1378,6 +1378,8 @@ struct rtl8xxxu_priv { u8 no_pape:1; u8 int_buf[USB_INTR_CONTENT_LENGTH]; u8 rssi_level; + DECLARE_BITMAP(tx_aggr_started, IEEE80211_NUM_TIDS); + DECLARE_BITMAP(tid_tx_operational, IEEE80211_NUM_TIDS); /* * Only one virtual interface permitted because only STA mode * is supported and no iface_combinations are provided. diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index 9ff09cf7eb62..ce8e2438f86b 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -4805,6 +4805,8 @@ rtl8xxxu_fill_txdesc_v1(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, struct ieee80211_rate *tx_rate = ieee80211_get_tx_rate(hw, tx_info); struct rtl8xxxu_priv *priv = hw->priv; struct device *dev = &priv->udev->dev; + u8 *qc = ieee80211_get_qos_ctl(hdr); + u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; u32 rate; u16 rate_flags = tx_info->control.rates[0].flags; u16 seq_number; @@ -4828,7 +4830,7 @@ rtl8xxxu_fill_txdesc_v1(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
tx_desc->txdw3 = cpu_to_le32((u32)seq_number << TXDESC32_SEQ_SHIFT);
- if (ampdu_enable) + if (ampdu_enable && test_bit(tid, priv->tid_tx_operational)) tx_desc->txdw1 |= cpu_to_le32(TXDESC32_AGG_ENABLE); else tx_desc->txdw1 |= cpu_to_le32(TXDESC32_AGG_BREAK); @@ -4876,6 +4878,8 @@ rtl8xxxu_fill_txdesc_v2(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, struct rtl8xxxu_priv *priv = hw->priv; struct device *dev = &priv->udev->dev; struct rtl8xxxu_txdesc40 *tx_desc40; + u8 *qc = ieee80211_get_qos_ctl(hdr); + u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; u32 rate; u16 rate_flags = tx_info->control.rates[0].flags; u16 seq_number; @@ -4902,7 +4906,7 @@ rtl8xxxu_fill_txdesc_v2(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
tx_desc40->txdw9 = cpu_to_le32((u32)seq_number << TXDESC40_SEQ_SHIFT);
- if (ampdu_enable) + if (ampdu_enable && test_bit(tid, priv->tid_tx_operational)) tx_desc40->txdw2 |= cpu_to_le32(TXDESC40_AGG_ENABLE); else tx_desc40->txdw2 |= cpu_to_le32(TXDESC40_AGG_BREAK); @@ -5015,12 +5019,19 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw, if (ieee80211_is_data_qos(hdr->frame_control) && sta) { if (sta->ht_cap.ht_supported) { u32 ampdu, val32; + u8 *qc = ieee80211_get_qos_ctl(hdr); + u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
ampdu = (u32)sta->ht_cap.ampdu_density; val32 = ampdu << TXDESC_AMPDU_DENSITY_SHIFT; tx_desc->txdw2 |= cpu_to_le32(val32);
ampdu_enable = true; + + if (!test_bit(tid, priv->tx_aggr_started) && + !(skb->protocol == cpu_to_be16(ETH_P_PAE))) + if (!ieee80211_start_tx_ba_session(sta, tid, 0)) + set_bit(tid, priv->tx_aggr_started); } }
@@ -6089,6 +6100,7 @@ rtl8xxxu_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct device *dev = &priv->udev->dev; u8 ampdu_factor, ampdu_density; struct ieee80211_sta *sta = params->sta; + u16 tid = params->tid; enum ieee80211_ampdu_mlme_action action = params->action;
switch (action) { @@ -6101,17 +6113,20 @@ rtl8xxxu_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, dev_dbg(dev, "Changed HT: ampdu_factor %02x, ampdu_density %02x\n", ampdu_factor, ampdu_density); - break; + return IEEE80211_AMPDU_TX_START_IMMEDIATE; + case IEEE80211_AMPDU_TX_STOP_CONT: case IEEE80211_AMPDU_TX_STOP_FLUSH: - dev_dbg(dev, "%s: IEEE80211_AMPDU_TX_STOP_FLUSH\n", __func__); - rtl8xxxu_set_ampdu_factor(priv, 0); - rtl8xxxu_set_ampdu_min_space(priv, 0); - break; case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: - dev_dbg(dev, "%s: IEEE80211_AMPDU_TX_STOP_FLUSH_CONT\n", - __func__); + dev_dbg(dev, "%s: IEEE80211_AMPDU_TX_STOP\n", __func__); rtl8xxxu_set_ampdu_factor(priv, 0); rtl8xxxu_set_ampdu_min_space(priv, 0); + clear_bit(tid, priv->tx_aggr_started); + clear_bit(tid, priv->tid_tx_operational); + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + break; + case IEEE80211_AMPDU_TX_OPERATIONAL: + dev_dbg(dev, "%s: IEEE80211_AMPDU_TX_OPERATIONAL\n", __func__); + set_bit(tid, priv->tid_tx_operational); break; case IEEE80211_AMPDU_RX_START: dev_dbg(dev, "%s: IEEE80211_AMPDU_RX_START\n", __func__);
From: Chin-Yen Lee timlee@realtek.com
[ Upstream commit 02a55c0009a55b204e1e5c17295431f0a9e7d3b6 ]
In current wow flow, driver calls rtw_wow_fw_start and sleep for 100ms, to wait firmware finish preliminary work and then update the value of WOWLAN_WAKE_REASON register to zero. But later firmware will start wow function with power-saving mode, in which mode the value of WOWLAN_WAKE_REASON register is 0xea. So driver may get 0xea value and return fail. We use read_poll_timeout instead to check the value to avoid this issue.
Signed-off-by: Chin-Yen Lee timlee@realtek.com Signed-off-by: Ping-Ke Shih pkshih@realtek.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210728014335.8785-2-pkshih@realtek.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtw88/wow.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/wow.c b/drivers/net/wireless/realtek/rtw88/wow.c index fc9544f4e5e4..bdccfa70dddc 100644 --- a/drivers/net/wireless/realtek/rtw88/wow.c +++ b/drivers/net/wireless/realtek/rtw88/wow.c @@ -283,15 +283,26 @@ static void rtw_wow_rx_dma_start(struct rtw_dev *rtwdev)
static int rtw_wow_check_fw_status(struct rtw_dev *rtwdev, bool wow_enable) { - /* wait 100ms for wow firmware to finish work */ - msleep(100); + int ret; + u8 check; + u32 check_dis;
if (wow_enable) { - if (rtw_read8(rtwdev, REG_WOWLAN_WAKE_REASON)) + ret = read_poll_timeout(rtw_read8, check, !check, 1000, + 100000, true, rtwdev, + REG_WOWLAN_WAKE_REASON); + if (ret) goto wow_fail; } else { - if (rtw_read32_mask(rtwdev, REG_FE1IMR, BIT_FS_RXDONE) || - rtw_read32_mask(rtwdev, REG_RXPKT_NUM, BIT_RW_RELEASE)) + ret = read_poll_timeout(rtw_read32_mask, check_dis, + !check_dis, 1000, 100000, true, rtwdev, + REG_FE1IMR, BIT_FS_RXDONE); + if (ret) + goto wow_fail; + ret = read_poll_timeout(rtw_read32_mask, check_dis, + !check_dis, 1000, 100000, false, rtwdev, + REG_RXPKT_NUM, BIT_RW_RELEASE); + if (ret) goto wow_fail; }
From: Ping-Ke Shih pkshih@realtek.com
[ Upstream commit 05e45887382c4c0f9522515759b34991aa17e69d ]
The kernel test robot reports undefined reference after we report wakeup reason to mac80211. This is because CONFIG_PM is not defined in the testing configuration file. In fact, functions within wow.c are used if CONFIG_PM is defined, so use CONFIG_PM to decide whether we build this file or not.
The reported messages are: hppa-linux-ld: drivers/net/wireless/realtek/rtw88/wow.o: in function `rtw_wow_show_wakeup_reason':
(.text+0x6c4): undefined reference to `ieee80211_report_wowlan_wakeup' hppa-linux-ld: (.text+0x6e0): undefined reference to `ieee80211_report_wowlan_wakeup'
Reported-by: kernel test robot lkp@intel.com Signed-off-by: Ping-Ke Shih pkshih@realtek.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210728014335.8785-4-pkshih@realtek.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtw88/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile index c0e4b111c8b4..73d6807a8cdf 100644 --- a/drivers/net/wireless/realtek/rtw88/Makefile +++ b/drivers/net/wireless/realtek/rtw88/Makefile @@ -15,9 +15,9 @@ rtw88_core-y += main.o \ ps.o \ sec.o \ bf.o \ - wow.o \ regd.o
+rtw88_core-$(CONFIG_PM) += wow.o
obj-$(CONFIG_RTW88_8822B) += rtw88_8822b.o rtw88_8822b-objs := rtw8822b.o rtw8822b_table.o
From: Chin-Yen Lee timlee@realtek.com
[ Upstream commit 69c7044526d984df672b8d9b6d6998c34617cde4 ]
Current flow will lead to null ptr access because of trying to get the size of freed probe-request packets. We store the information of packet size into rsvd page instead and also fix the size error issue, which will cause unstable behavoir of sending probe request by wow firmware.
Signed-off-by: Chin-Yen Lee timlee@realtek.com Signed-off-by: Ping-Ke Shih pkshih@realtek.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210728014335.8785-6-pkshih@realtek.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtw88/fw.c | 8 ++++++-- drivers/net/wireless/realtek/rtw88/fw.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c index ea2cd4db1d3c..ce57932e38a4 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.c +++ b/drivers/net/wireless/realtek/rtw88/fw.c @@ -715,7 +715,7 @@ static u16 rtw_get_rsvd_page_probe_req_size(struct rtw_dev *rtwdev, continue; if ((!ssid && !rsvd_pkt->ssid) || rtw_ssid_equal(rsvd_pkt->ssid, ssid)) - size = rsvd_pkt->skb->len; + size = rsvd_pkt->probe_req_size; }
return size; @@ -943,6 +943,8 @@ static struct sk_buff *rtw_get_rsvd_page_skb(struct ieee80211_hw *hw, ssid->ssid_len, 0); else skb_new = ieee80211_probereq_get(hw, vif->addr, NULL, 0, 0); + if (skb_new) + rsvd_pkt->probe_req_size = (u16)skb_new->len; break; case RSVD_NLO_INFO: skb_new = rtw_nlo_info_get(hw); @@ -1539,6 +1541,7 @@ int rtw_fw_dump_fifo(struct rtw_dev *rtwdev, u8 fifo_sel, u32 addr, u32 size, static void __rtw_fw_update_pkt(struct rtw_dev *rtwdev, u8 pkt_id, u16 size, u8 location) { + struct rtw_chip_info *chip = rtwdev->chip; u8 h2c_pkt[H2C_PKT_SIZE] = {0}; u16 total_size = H2C_PKT_HDR_SIZE + H2C_PKT_UPDATE_PKT_LEN;
@@ -1549,6 +1552,7 @@ static void __rtw_fw_update_pkt(struct rtw_dev *rtwdev, u8 pkt_id, u16 size, UPDATE_PKT_SET_LOCATION(h2c_pkt, location);
/* include txdesc size */ + size += chip->tx_pkt_desc_sz; UPDATE_PKT_SET_SIZE(h2c_pkt, size);
rtw_fw_send_h2c_packet(rtwdev, h2c_pkt); @@ -1558,7 +1562,7 @@ void rtw_fw_update_pkt_probe_req(struct rtw_dev *rtwdev, struct cfg80211_ssid *ssid) { u8 loc; - u32 size; + u16 size;
loc = rtw_get_rsvd_page_probe_req_location(rtwdev, ssid); if (!loc) { diff --git a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h index 7c5b1d75e26f..35bc9e10dcba 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.h +++ b/drivers/net/wireless/realtek/rtw88/fw.h @@ -126,6 +126,7 @@ struct rtw_rsvd_page { u8 page; bool add_txdesc; struct cfg80211_ssid *ssid; + u16 probe_req_size; };
enum rtw_keep_alive_pkt_type {
From: Subbaraya Sundeep sbhatta@marvell.com
[ Upstream commit e8fb4df1f5d84bc08dd4f4827821a851d2eab241 ]
'bp_ena' in Aura context is NIX block index, setting it zero will always backpressure NIX0 block, even if NIXLF belongs to NIX1. Hence fix this by setting it appropriately based on NIX block address.
Signed-off-by: Subbaraya Sundeep sbhatta@marvell.com Signed-off-by: Hariprasad Kelam hkelam@marvell.com Signed-off-by: Sunil Goutham sgoutham@marvell.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- .../ethernet/marvell/octeontx2/nic/otx2_common.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c index e0d1af9e7770..6c64fdbef0df 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c @@ -1201,7 +1201,22 @@ static int otx2_aura_init(struct otx2_nic *pfvf, int aura_id, /* Enable backpressure for RQ aura */ if (aura_id < pfvf->hw.rqpool_cnt && !is_otx2_lbkvf(pfvf->pdev)) { aq->aura.bp_ena = 0; + /* If NIX1 LF is attached then specify NIX1_RX. + * + * Below NPA_AURA_S[BP_ENA] is set according to the + * NPA_BPINTF_E enumeration given as: + * 0x0 + a*0x1 where 'a' is 0 for NIX0_RX and 1 for NIX1_RX so + * NIX0_RX is 0x0 + 0*0x1 = 0 + * NIX1_RX is 0x0 + 1*0x1 = 1 + * But in HRM it is given that + * "NPA_AURA_S[BP_ENA](w1[33:32]) - Enable aura backpressure to + * NIX-RX based on [BP] level. One bit per NIX-RX; index + * enumerated by NPA_BPINTF_E." + */ + if (pfvf->nix_blkaddr == BLKADDR_NIX1) + aq->aura.bp_ena = 1; aq->aura.nix0_bpid = pfvf->bpid[0]; + /* Set backpressure level for RQ's Aura */ aq->aura.bp = RQ_BP_LVL_AURA; }
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit db87db65c1059f3be04506d122f8ec9b2fa3b05e ]
Hi Arnd,
First bad commit (maybe != root cause):
tree: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master head: 2f73937c9aa561e2082839bc1a8efaac75d6e244 commit: 47fd22f2b84765a2f7e3f150282497b902624547 [4771/5318] cs89x0: rework driver configuration config: m68k-randconfig-c003-20210804 (attached as .config) compiler: m68k-linux-gcc (GCC) 10.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?... git remote add linux-next https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git git fetch --no-tags linux-next master git checkout 47fd22f2b84765a2f7e3f150282497b902624547 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross ARCH=m68k
If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot lkp@intel.com
All errors (new ones prefixed by >>):
In file included from include/linux/kernel.h:19, from include/linux/list.h:9, from include/linux/module.h:12, from drivers/net/ethernet/cirrus/cs89x0.c:51: drivers/net/ethernet/cirrus/cs89x0.c: In function 'net_open': drivers/net/ethernet/cirrus/cs89x0.c:897:20: error: implicit declaration of function 'isa_virt_to_bus'; did you mean 'virt_to_bus'? [-Werror=implicit-function-declaration] 897 | (unsigned long)isa_virt_to_bus(lp->dma_buff)); | ^~~~~~~~~~~~~~~ include/linux/printk.h:141:17: note: in definition of macro 'no_printk' 141 | printk(fmt, ##__VA_ARGS__); \ | ^~~~~~~~~~~ drivers/net/ethernet/cirrus/cs89x0.c:86:3: note: in expansion of macro 'pr_debug' 86 | pr_##level(fmt, ##__VA_ARGS__); \ | ^~~ drivers/net/ethernet/cirrus/cs89x0.c:894:3: note: in expansion of macro 'cs89_dbg' 894 | cs89_dbg(1, debug, "%s: dma %lx %lx\n", | ^~~~~~~~
drivers/net/ethernet/cirrus/cs89x0.c:914:3: error: implicit declaration of function 'disable_dma'; did you mean 'disable_irq'? [-Werror=implicit-function-declaration]
As far as I can tell, this is a bug with the m68kmmu architecture, not with my driver: The CONFIG_ISA_DMA_API option is provided for coldfire, which implements it, but dragonball also sets the option as a side-effect, without actually implementing the interfaces. The patch below should fix it.
Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Greg Ungerer gerg@linux-m68k.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/m68k/Kconfig.bus | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/m68k/Kconfig.bus b/arch/m68k/Kconfig.bus index f1be832e2b74..d1e93a39cd3b 100644 --- a/arch/m68k/Kconfig.bus +++ b/arch/m68k/Kconfig.bus @@ -63,7 +63,7 @@ source "drivers/zorro/Kconfig"
endif
-if !MMU +if COLDFIRE
config ISA_DMA_API def_bool !M5272
From: Filipe Manana fdmanana@suse.com
[ Upstream commit cceaa89f02f15f232391ae4be214137b0a0285c0 ]
When using the NO_HOLES feature and expanding the size of an inode, we update the inode's last_trans, last_sub_trans and last_log_commit fields at maybe_insert_hole() so that a fsync does know that the inode needs to be logged (by making sure that btrfs_inode_in_log() returns false). This happens for expanding truncate operations, buffered writes, direct IO writes and when cloning extents to an offset greater than the inode's i_size.
However the way we do it is racy, because in between setting the inode's last_sub_trans and last_log_commit fields, the log transaction ID that was assigned to last_sub_trans might be committed before we read the root's last_log_commit and assign that value to last_log_commit. If that happens it would make a future call to btrfs_inode_in_log() return true. This is a race that should be extremely unlikely to be hit in practice, and it is the same that was described by commit bc0939fcfab0d7 ("btrfs: fix race between marking inode needs to be logged and log syncing").
The fix would simply be to set last_log_commit to the value we assigned to last_sub_trans minus 1, like it was done in that commit. However updating these two fields plus the last_trans field is pointless here because all the callers of btrfs_cont_expand() (which is the only caller of maybe_insert_hole()) always call btrfs_set_inode_last_trans() or btrfs_update_inode() after calling btrfs_cont_expand(). Calling either btrfs_set_inode_last_trans() or btrfs_update_inode() guarantees that the next fsync will log the inode, as it makes btrfs_inode_in_log() return false.
So just remove the code that explicitly sets the inode's last_trans, last_sub_trans and last_log_commit fields.
Reviewed-by: Josef Bacik josef@toxicpanda.com Signed-off-by: Filipe Manana fdmanana@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/inode.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index c3810c6430d9..044300db5e22 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -5064,15 +5064,13 @@ static int maybe_insert_hole(struct btrfs_root *root, struct btrfs_inode *inode, int ret;
/* - * Still need to make sure the inode looks like it's been updated so - * that any holes get logged if we fsync. + * If NO_HOLES is enabled, we don't need to do anything. + * Later, up in the call chain, either btrfs_set_inode_last_sub_trans() + * or btrfs_update_inode() will be called, which guarantee that the next + * fsync will know this inode was changed and needs to be logged. */ - if (btrfs_fs_incompat(fs_info, NO_HOLES)) { - inode->last_trans = fs_info->generation; - inode->last_sub_trans = root->log_transid; - inode->last_log_commit = root->last_log_commit; + if (btrfs_fs_incompat(fs_info, NO_HOLES)) return 0; - }
/* * 1 - for the one we're dropping
From: Marcos Paulo de Souza mpdesouza@suse.com
[ Upstream commit 3736127a3aa805602b7a2ad60ec9cfce68065fbb ]
Function btrfs_lookup_data_extent calls btrfs_search_slot to verify if the EXTENT_ITEM exists in the extent tree. btrfs_search_slot can return values bellow zero if an error happened.
Function replay_one_extent currently checks if the search found something (0 returned) and increments the reference, and if not, it seems to evaluate as 'not found'.
Fix the condition by checking if the value was bellow zero and return early.
Reviewed-by: Filipe Manana fdmanana@suse.com Signed-off-by: Marcos Paulo de Souza mpdesouza@suse.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/tree-log.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 24555cc1f42d..9e9ab41df7da 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -753,7 +753,9 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, */ ret = btrfs_lookup_data_extent(fs_info, ins.objectid, ins.offset); - if (ret == 0) { + if (ret < 0) { + goto out; + } else if (ret == 0) { btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, ins.objectid, ins.offset, 0);
From: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
[ Upstream commit ea6942dad4b2a7e1735aa0f10f3d0b04b847750f ]
The power down sequence sets the link_up flag as false outside of the mutex_lock. This is potentially unsafe.
In additional the flow in that sequence can be improved by first testing if the link was powered, setting the link_up flag as false and proceeding with the power down. In case the CPA bits cannot be cleared, we only flag an error since we cannot deal with interrupts any longer.
Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Signed-off-by: Bard Liao yung-chuan.liao@linux.intel.com Link: https://lore.kernel.org/r/20210818024954.16873-2-yung-chuan.liao@linux.intel... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soundwire/intel.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index fd95f94630b1..c03d51ad40bf 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -537,12 +537,14 @@ static int intel_link_power_down(struct sdw_intel *sdw)
mutex_lock(sdw->link_res->shim_lock);
- intel_shim_master_ip_to_glue(sdw); - if (!(*shim_mask & BIT(link_id))) dev_err(sdw->cdns.dev, "%s: Unbalanced power-up/down calls\n", __func__);
+ sdw->cdns.link_up = false; + + intel_shim_master_ip_to_glue(sdw); + *shim_mask &= ~BIT(link_id);
if (!*shim_mask) { @@ -559,18 +561,19 @@ static int intel_link_power_down(struct sdw_intel *sdw) link_control &= spa_mask;
ret = intel_clear_bit(shim, SDW_SHIM_LCTL, link_control, cpa_mask); + if (ret < 0) { + dev_err(sdw->cdns.dev, "%s: could not power down link\n", __func__); + + /* + * we leave the sdw->cdns.link_up flag as false since we've disabled + * the link at this point and cannot handle interrupts any longer. + */ + } }
mutex_unlock(sdw->link_res->shim_lock);
- if (ret < 0) { - dev_err(sdw->cdns.dev, "%s: could not power down link\n", __func__); - - return ret; - } - - sdw->cdns.link_up = false; - return 0; + return ret; }
static void intel_shim_sync_arm(struct sdw_intel *sdw)
From: Cezary Rojewski cezary.rojewski@intel.com
[ Upstream commit e4e0633bcadc950b4b4af06c7f1bb7f7e3e86321 ]
KeyPhrasebuffer, Mixin and Mixout modules configuration is described by firmware's basic module configuration structure. There are no extended parameters required. Update functions taking part in building INIT_INSTANCE IPC payload to reflect that.
Signed-off-by: Cezary Rojewski cezary.rojewski@intel.com Tested-by: Lukasz Majczak lma@semihalf.com Link: https://lore.kernel.org/r/20210818075742.1515155-6-cezary.rojewski@intel.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/intel/skylake/skl-messages.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index 476ef1897961..79c6cf2c14bf 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c @@ -802,9 +802,12 @@ static u16 skl_get_module_param_size(struct skl_dev *skl,
case SKL_MODULE_TYPE_BASE_OUTFMT: case SKL_MODULE_TYPE_MIC_SELECT: - case SKL_MODULE_TYPE_KPB: return sizeof(struct skl_base_outfmt_cfg);
+ case SKL_MODULE_TYPE_MIXER: + case SKL_MODULE_TYPE_KPB: + return sizeof(struct skl_base_cfg); + default: /* * return only base cfg when no specific module type is @@ -857,10 +860,14 @@ static int skl_set_module_format(struct skl_dev *skl,
case SKL_MODULE_TYPE_BASE_OUTFMT: case SKL_MODULE_TYPE_MIC_SELECT: - case SKL_MODULE_TYPE_KPB: skl_set_base_outfmt_format(skl, module_config, *param_data); break;
+ case SKL_MODULE_TYPE_MIXER: + case SKL_MODULE_TYPE_KPB: + skl_set_base_module_format(skl, module_config, *param_data); + break; + default: skl_set_base_module_format(skl, module_config, *param_data); break;
From: Gustaw Lewandowski gustaw.lewandowski@linux.intel.com
[ Upstream commit c5ed9c547cba1dc1238c6e8a0c290fd62ee6e127 ]
skl_get_module_info() tries to set mconfig->module->loadable before mconfig->module has been assigned thus flag was always set to false and driver did not try to load module binaries.
Signed-off-by: Gustaw Lewandowski gustaw.lewandowski@linux.intel.com Signed-off-by: Cezary Rojewski cezary.rojewski@intel.com Tested-by: Lukasz Majczak lma@semihalf.com Link: https://lore.kernel.org/r/20210818075742.1515155-7-cezary.rojewski@intel.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/intel/skylake/skl-pcm.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index b1ca64d2f7ea..031d5dc7e660 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -1317,21 +1317,6 @@ static int skl_get_module_info(struct skl_dev *skl, return -EIO; }
- list_for_each_entry(module, &skl->uuid_list, list) { - if (guid_equal(uuid_mod, &module->uuid)) { - mconfig->id.module_id = module->id; - if (mconfig->module) - mconfig->module->loadable = module->is_loadable; - ret = 0; - break; - } - } - - if (ret) - return ret; - - uuid_mod = &module->uuid; - ret = -EIO; for (i = 0; i < skl->nr_modules; i++) { skl_module = skl->modules[i]; uuid_tplg = &skl_module->uuid; @@ -1341,10 +1326,18 @@ static int skl_get_module_info(struct skl_dev *skl, break; } } + if (skl->nr_modules && ret) return ret;
+ ret = -EIO; list_for_each_entry(module, &skl->uuid_list, list) { + if (guid_equal(uuid_mod, &module->uuid)) { + mconfig->id.module_id = module->id; + mconfig->module->loadable = module->is_loadable; + ret = 0; + } + for (i = 0; i < MAX_IN_QUEUE; i++) { pin_id = &mconfig->m_in_pin[i].id; if (guid_equal(&pin_id->mod_uuid, &module->uuid)) @@ -1358,7 +1351,7 @@ static int skl_get_module_info(struct skl_dev *skl, } }
- return 0; + return ret; }
static int skl_populate_modules(struct skl_dev *skl)
From: Marc Zyngier maz@kernel.org
[ Upstream commit 6211e9cb2f8faf7faae0b6caf844bfe9527cc607 ]
Trying to boot without SYSFS, but with OF_DYNAMIC quickly results in a crash:
[ 0.088460] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000070 [...] [ 0.103927] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.14.0-rc3 #4179 [ 0.105810] Hardware name: linux,dummy-virt (DT) [ 0.107147] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--) [ 0.108876] pc : kernfs_find_and_get_ns+0x3c/0x7c [ 0.110244] lr : kernfs_find_and_get_ns+0x3c/0x7c [...] [ 0.134087] Call trace: [ 0.134800] kernfs_find_and_get_ns+0x3c/0x7c [ 0.136054] safe_name+0x4c/0xd0 [ 0.136994] __of_attach_node_sysfs+0xf8/0x124 [ 0.138287] of_core_init+0x90/0xfc [ 0.139296] driver_init+0x30/0x4c [ 0.140283] kernel_init_freeable+0x160/0x1b8 [ 0.141543] kernel_init+0x30/0x140 [ 0.142561] ret_from_fork+0x10/0x18
While not having sysfs isn't a very common option these days, it is still expected that such configuration would work.
Paper over it by bailing out from __of_attach_node_sysfs() if CONFIG_SYSFS isn't enabled.
Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20210820144722.169226-1-maz@kernel.org Signed-off-by: Rob Herring robh@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/of/kobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/of/kobj.c b/drivers/of/kobj.c index a32e60b024b8..6675b5e56960 100644 --- a/drivers/of/kobj.c +++ b/drivers/of/kobj.c @@ -119,7 +119,7 @@ int __of_attach_node_sysfs(struct device_node *np) struct property *pp; int rc;
- if (!of_kset) + if (!IS_ENABLED(CONFIG_SYSFS) || !of_kset) return 0;
np->kobj.kset = of_kset;
From: Manish Narani manish.narani@xilinx.com
[ Upstream commit c0b4e411a9b09748466ee06d2ae6772effa64dfb ]
SD standard speed timing was met only at 19MHz and not 25 MHz, that's why changing driver to 19MHz. The reason for this is when a level shifter is used on the board, timing was met for standard speed only at 19MHz. Since this level shifter is commonly required for high speed modes, the driver is modified to use standard speed of 19Mhz.
Signed-off-by: Manish Narani manish.narani@xilinx.com Acked-by: Adrian Hunter adrian.hunter@intel.com Link: https://lore.kernel.org/r/1623753837-21035-2-git-send-email-manish.narani@xi... Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/sdhci-of-arasan.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 839965f7c717..fc3e41c76ab4 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -159,6 +159,12 @@ struct sdhci_arasan_data { /* Controller immediately reports SDHCI_CLOCK_INT_STABLE after enabling the * internal clock even when the clock isn't stable */ #define SDHCI_ARASAN_QUIRK_CLOCK_UNSTABLE BIT(1) +/* + * Some of the Arasan variations might not have timing requirements + * met at 25MHz for Default Speed mode, those controllers work at + * 19MHz instead + */ +#define SDHCI_ARASAN_QUIRK_CLOCK_25_BROKEN BIT(2) };
struct sdhci_arasan_of_data { @@ -290,6 +296,16 @@ static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock) sdhci_arasan->is_phy_on = false; }
+ if (sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_CLOCK_25_BROKEN) { + /* + * Some of the Arasan variations might not have timing + * requirements met at 25MHz for Default Speed mode, + * those controllers work at 19MHz instead. + */ + if (clock == DEFAULT_SPEED_MAX_DTR) + clock = (DEFAULT_SPEED_MAX_DTR * 19) / 25; + } + /* Set the Input and Output Clock Phase Delays */ if (clk_data->set_clk_delays) clk_data->set_clk_delays(host); @@ -1598,6 +1614,8 @@ static int sdhci_arasan_probe(struct platform_device *pdev) if (of_device_is_compatible(np, "xlnx,zynqmp-8.9a")) { host->mmc_host_ops.execute_tuning = arasan_zynqmp_execute_tuning; + + sdhci_arasan->quirks |= SDHCI_ARASAN_QUIRK_CLOCK_25_BROKEN; }
arasan_dt_parse_clk_phases(dev, &sdhci_arasan->clk_data);
From: Manish Narani manish.narani@xilinx.com
[ Upstream commit 66bad6ed2204fdb78a0a8fb89d824397106a5471 ]
At a couple of places, the return values of the non-void functions were not getting checked. This was reported by the coverity tool. Modify the code to check the return values of the same.
Addresses-Coverity: ("check_return") Signed-off-by: Manish Narani manish.narani@xilinx.com Acked-by: Adrian Hunter adrian.hunter@intel.com Link: https://lore.kernel.org/r/1623753837-21035-5-git-send-email-manish.narani@xi... Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/sdhci-of-arasan.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index fc3e41c76ab4..9a630ba37484 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -273,7 +273,12 @@ static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock) * through low speeds without power cycling. */ sdhci_set_clock(host, host->max_clk); - phy_power_on(sdhci_arasan->phy); + if (phy_power_on(sdhci_arasan->phy)) { + pr_err("%s: Cannot power on phy.\n", + mmc_hostname(host->mmc)); + return; + } + sdhci_arasan->is_phy_on = true;
/* @@ -323,7 +328,12 @@ static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock) msleep(20);
if (ctrl_phy) { - phy_power_on(sdhci_arasan->phy); + if (phy_power_on(sdhci_arasan->phy)) { + pr_err("%s: Cannot power on phy.\n", + mmc_hostname(host->mmc)); + return; + } + sdhci_arasan->is_phy_on = true; } } @@ -479,7 +489,9 @@ static int sdhci_arasan_suspend(struct device *dev) ret = phy_power_off(sdhci_arasan->phy); if (ret) { dev_err(dev, "Cannot power off phy.\n"); - sdhci_resume_host(host); + if (sdhci_resume_host(host)) + dev_err(dev, "Cannot resume host.\n"); + return ret; } sdhci_arasan->is_phy_on = false;
From: Thomas Hebb tommyhebb@gmail.com
[ Upstream commit 3ac5e45291f3f0d699a721357380d4593bc2dcb3 ]
For unexplained reasons, the prescaler register for this device needs to be cleared (set to 1) while performing a data read or else the command will hang. This does not appear to affect the real clock rate sent out on the bus, so I assume it's purely to work around a hardware bug.
During normal operation, the prescaler is already set to 1, so nothing needs to be done. However, in "initial mode" (which is used for sub-MHz clock speeds, like the core sets while enumerating cards), it's set to 128 and so we need to reset it during data reads. We currently fail to do this for long reads.
This has no functional affect on the driver's operation currently written, as the MMC core always sets a clock above 1MHz before attempting any long reads. However, the core could conceivably set any clock speed at any time and the driver should still work, so I think this fix is worthwhile.
I personally encountered this issue while performing data recovery on an external chip. My connections had poor signal integrity, so I modified the core code to reduce the clock speed. Without this change, I saw the card enumerate but was unable to actually read any data.
Writes don't seem to work in the situation described above even with this change (and even if the workaround is extended to encompass data write commands). I was not able to find a way to get them working.
Signed-off-by: Thomas Hebb tommyhebb@gmail.com Link: https://lore.kernel.org/r/2fef280d8409ab0100c26c6ac7050227defd098d.162781836... Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/rtsx_pci_sdmmc.c | 36 ++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 13 deletions(-)
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c index 4ca937415734..58cfaffa3c2d 100644 --- a/drivers/mmc/host/rtsx_pci_sdmmc.c +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c @@ -542,9 +542,22 @@ static int sd_write_long_data(struct realtek_pci_sdmmc *host, return 0; }
+static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) +{ + rtsx_pci_write_register(host->pcr, SD_CFG1, + SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_128); +} + +static inline void sd_disable_initial_mode(struct realtek_pci_sdmmc *host) +{ + rtsx_pci_write_register(host->pcr, SD_CFG1, + SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_0); +} + static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) { struct mmc_data *data = mrq->data; + int err;
if (host->sg_count < 0) { data->error = host->sg_count; @@ -553,22 +566,19 @@ static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) return data->error; }
- if (data->flags & MMC_DATA_READ) - return sd_read_long_data(host, mrq); + if (data->flags & MMC_DATA_READ) { + if (host->initial_mode) + sd_disable_initial_mode(host);
- return sd_write_long_data(host, mrq); -} + err = sd_read_long_data(host, mrq);
-static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) -{ - rtsx_pci_write_register(host->pcr, SD_CFG1, - SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_128); -} + if (host->initial_mode) + sd_enable_initial_mode(host);
-static inline void sd_disable_initial_mode(struct realtek_pci_sdmmc *host) -{ - rtsx_pci_write_register(host->pcr, SD_CFG1, - SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_0); + return err; + } + + return sd_write_long_data(host, mrq); }
static void sd_normal_rw(struct realtek_pci_sdmmc *host,
From: Li Zhijian lizhijian@cn.fujitsu.com
[ Upstream commit 2d82d73da35b72b53fe0d96350a2b8d929d07e42 ]
0Day robot observed that it's easily timeout on a heavy load host. ------------------- # selftests: bpf: test_maps # Fork 1024 tasks to 'test_update_delete' # Fork 1024 tasks to 'test_update_delete' # Fork 100 tasks to 'test_hashmap' # Fork 100 tasks to 'test_hashmap_percpu' # Fork 100 tasks to 'test_hashmap_sizes' # Fork 100 tasks to 'test_hashmap_walk' # Fork 100 tasks to 'test_arraymap' # Fork 100 tasks to 'test_arraymap_percpu' # Failed sockmap unexpected timeout not ok 3 selftests: bpf: test_maps # exit=1 # selftests: bpf: test_lru_map # nr_cpus:8 ------------------- Since this test will be scheduled by 0Day to a random host that could have only a few cpus(2-8), enlarge the timeout to avoid a false NG report.
In practice, i tried to pin it to only one cpu by 'taskset 0x01 ./test_maps', and knew 10S is likely enough, but i still perfer to a larger value 30.
Reported-by: kernel test robot lkp@intel.com Signed-off-by: Li Zhijian lizhijian@cn.fujitsu.com Signed-off-by: Alexei Starovoitov ast@kernel.org Acked-by: Song Liu songliubraving@fb.com Link: https://lore.kernel.org/bpf/20210820015556.23276-2-lizhijian@cn.fujitsu.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/test_maps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c index aa38dc4a5e85..90f38c6528a1 100644 --- a/tools/testing/selftests/bpf/test_maps.c +++ b/tools/testing/selftests/bpf/test_maps.c @@ -968,7 +968,7 @@ static void test_sockmap(unsigned int tasks, void *data)
FD_ZERO(&w); FD_SET(sfd[3], &w); - to.tv_sec = 1; + to.tv_sec = 30; to.tv_usec = 0; s = select(sfd[3] + 1, &w, NULL, NULL, &to); if (s == -1) {
From: Nishad Kamdar nishadkamdar@gmail.com
[ Upstream commit e72a55f2e5ddcfb3dce0701caf925ce435b87682 ]
When a read/write command is sent via ioctl to the kernel, and the command fails, the actual error response of the emmc is not sent to the user.
IOCTL read/write tests are carried out using commands 17 (Single BLock Read), 24 (Single Block Write), 18 (Multi Block Read), 25 (Multi Block Write)
The tests are carried out on a 64Gb emmc device. All of these tests try to access an "out of range" sector address (0x09B2FFFF).
It is seen that without the patch the response received by the user is not OUT_OF_RANGE error (R1 response 31st bit is not set) as per JEDEC specification. After applying the patch proper response is seen. This is because the function returns without copying the response to the user in case of failure. This patch fixes the issue.
Hence, this memcpy is required whether we get an error response or not. Therefor it is moved up from the current position up to immediately after we have called mmc_wait_for_req().
The test code and the output of only the CMD17 is included in the commit to limit the message length.
CMD17 (Test Code Snippet): ========================== printf("Forming CMD%d\n", opt_idx); /* single block read */ cmd.blksz = 512; cmd.blocks = 1; cmd.write_flag = 0; cmd.opcode = 17; //cmd.arg = atoi(argv[3]); cmd.arg = 0x09B2FFFF; /* Expecting response R1B */ cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
memset(data, 0, sizeof(__u8) * 512); mmc_ioc_cmd_set_data(cmd, data);
printf("Sending CMD%d: ARG[0x%08x]\n", opt_idx, cmd.arg); if(ioctl(fd, MMC_IOC_CMD, &cmd)) perror("Error");
printf("\nResponse: %08x\n", cmd.response[0]);
CMD17 (Output without patch): ============================= test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 17 Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4 Entering the do_mmc_commands:Device: /dev/mmcblk0 options[17, 0x09B2FFF] Forming CMD17 Sending CMD17: ARG[0x09b2ffff] Error: Connection timed out
Response: 00000000 (Incorrect response)
CMD17 (Output with patch): ========================== test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 17 [sudo] password for test: Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4 Entering the do_mmc_commands:Device: /dev/mmcblk0 options[17, 09B2FFFF] Forming CMD17 Sending CMD17: ARG[0x09b2ffff] Error: Connection timed out
Response: 80000900 (Correct OUT_OF_ERROR response as per JEDEC specification)
Signed-off-by: Nishad Kamdar nishadkamdar@gmail.com Reviewed-by: Avri Altman avri.altman@wdc.com Link: https://lore.kernel.org/r/20210824191726.8296-1-nishadkamdar@gmail.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/core/block.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 2518bc085659..d47829b9fc0f 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -542,6 +542,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, return mmc_sanitize(card, idata->ic.cmd_timeout_ms);
mmc_wait_for_req(card->host, &mrq); + memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp));
if (cmd.error) { dev_err(mmc_dev(card->host), "%s: cmd error %d\n", @@ -591,8 +592,6 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, if (idata->ic.postsleep_min_us) usleep_range(idata->ic.postsleep_min_us, idata->ic.postsleep_max_us);
- memcpy(&(idata->ic.response), cmd.resp, sizeof(cmd.resp)); - if (idata->rpmb || (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) { /* * Ensure RPMB/R1B command has completed by polling CMD13
From: Juhee Kang claudiajkang@gmail.com
[ Upstream commit c0e9422c4e6ca9abd4bd6e1598400c7231eb600b ]
Currently, most pktgen samples print the execution result when the program is terminated normally. However, sample03 doesn't work appropriately.
This is results of samples:
# DEV=eth0 DEST_IP=10.1.0.1 DST_MAC=00:11:22:33:44:55 ./pktgen_sample04_many_flows.sh -n 1 Running... ctrl^C to stop Device: eth0@0 Result: OK: 19(c5+d13) usec, 1 (60byte,0frags) 51762pps 24Mb/sec (24845760bps) errors: 0
# DEV=eth0 DEST_IP=10.1.0.1 DST_MAC=00:11:22:33:44:55 ./pktgen_sample03_burst_single_flow.sh -n 1 Running... ctrl^C to stop
The reason why it doesn't print the execution result when the program is terminated usually is that sample03 doesn't call the function which prints the result, unlike other samples.
So, this commit solves this issue by calling the function before termination. Also, this commit changes control_c function to print_result to maintain consistency with other samples.
Signed-off-by: Juhee Kang claudiajkang@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- samples/pktgen/pktgen_sample03_burst_single_flow.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/samples/pktgen/pktgen_sample03_burst_single_flow.sh b/samples/pktgen/pktgen_sample03_burst_single_flow.sh index 5adcf954de73..c12198d5bbe5 100755 --- a/samples/pktgen/pktgen_sample03_burst_single_flow.sh +++ b/samples/pktgen/pktgen_sample03_burst_single_flow.sh @@ -83,7 +83,7 @@ for ((thread = $F_THREAD; thread <= $L_THREAD; thread++)); do done
# Run if user hits control-c -function control_c() { +function print_result() { # Print results for ((thread = $F_THREAD; thread <= $L_THREAD; thread++)); do dev=${DEV}@${thread} @@ -92,11 +92,13 @@ function control_c() { done } # trap keyboard interrupt (Ctrl-C) -trap control_c SIGINT +trap true SIGINT
if [ -z "$APPEND" ]; then echo "Running... ctrl^C to stop" >&2 pg_ctrl "start" + + print_result else echo "Append mode: config done. Do more or use 'pg_ctrl start' to run" fi
From: Ding Hui dinghui@sangfor.com.cn
[ Upstream commit d72c74197b70bc3c95152f351a568007bffa3e11 ]
smb_buf is allocated by small_smb_init_no_tc(), and buf type is CIFS_SMALL_BUFFER, so we should use cifs_small_buf_release() to release it in failed path.
Signed-off-by: Ding Hui dinghui@sangfor.com.cn Reviewed-by: Paulo Alcantara (SUSE) pc@cjr.nz Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/cifs/sess.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index a92a1fb7cb52..4c22f73b3123 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -889,7 +889,7 @@ sess_alloc_buffer(struct sess_data *sess_data, int wct) return 0;
out_free_smb_buf: - kfree(smb_buf); + cifs_small_buf_release(smb_buf); sess_data->iov[0].iov_base = NULL; sess_data->iov[0].iov_len = 0; sess_data->buf0_type = CIFS_NO_BUFFER;
From: Mathias Nyman mathias.nyman@linux.intel.com
[ Upstream commit 2847c46c61486fd8bca9136a6e27177212e78c69 ]
This reverts commit 5d5323a6f3625f101dbfa94ba3ef7706cce38760.
That commit effectively disabled Intel host initiated U1/U2 lpm for devices with periodic endpoints.
Before that commit we disabled host initiated U1/U2 lpm if the exit latency was larger than any periodic endpoint service interval, this is according to xhci spec xhci 1.1 specification section 4.23.5.2
After that commit we incorrectly checked that service interval was smaller than U1/U2 inactivity timeout. This is not relevant, and can't happen for Intel hosts as previously set U1/U2 timeout = 105% * service interval.
Patch claimed it solved cases where devices can't be enumerated because of bandwidth issues. This might be true but it's a side effect of accidentally turning off lpm.
exit latency calculations have been revised since then
Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Link: https://lore.kernel.org/r/20210820123503.2605901-5-mathias.nyman@linux.intel... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/xhci.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 9248ce8d09a4..cb21add9d7be 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -4705,19 +4705,19 @@ static u16 xhci_calculate_u1_timeout(struct xhci_hcd *xhci, { unsigned long long timeout_ns;
- if (xhci->quirks & XHCI_INTEL_HOST) - timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc); - else - timeout_ns = udev->u1_params.sel; - /* Prevent U1 if service interval is shorter than U1 exit latency */ if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) { - if (xhci_service_interval_to_ns(desc) <= timeout_ns) { + if (xhci_service_interval_to_ns(desc) <= udev->u1_params.mel) { dev_dbg(&udev->dev, "Disable U1, ESIT shorter than exit latency\n"); return USB3_LPM_DISABLED; } }
+ if (xhci->quirks & XHCI_INTEL_HOST) + timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc); + else + timeout_ns = udev->u1_params.sel; + /* The U1 timeout is encoded in 1us intervals. * Don't return a timeout of zero, because that's USB3_LPM_DISABLED. */ @@ -4769,19 +4769,19 @@ static u16 xhci_calculate_u2_timeout(struct xhci_hcd *xhci, { unsigned long long timeout_ns;
- if (xhci->quirks & XHCI_INTEL_HOST) - timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc); - else - timeout_ns = udev->u2_params.sel; - /* Prevent U2 if service interval is shorter than U2 exit latency */ if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) { - if (xhci_service_interval_to_ns(desc) <= timeout_ns) { + if (xhci_service_interval_to_ns(desc) <= udev->u2_params.mel) { dev_dbg(&udev->dev, "Disable U2, ESIT shorter than exit latency\n"); return USB3_LPM_DISABLED; } }
+ if (xhci->quirks & XHCI_INTEL_HOST) + timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc); + else + timeout_ns = udev->u2_params.sel; + /* The U2 timeout is encoded in 256us intervals */ timeout_ns = DIV_ROUND_UP_ULL(timeout_ns, 256 * 1000); /* If the necessary timeout value is bigger than what we can set in the
From: Nadezda Lutovinova lutovinova@ispras.ru
[ Upstream commit 6a48d0ae01a6ab05ae5e78328546a2f5f6d3054a ]
If IRQ occurs between calling devm_request_threaded_irq() and initializing dwc3_imx->dwc3, then null pointer dereference occurs since dwc3_imx->dwc3 is used in dwc3_imx8mp_interrupt().
The patch puts registration of the interrupt handler after initializing of neccesery data.
Found by Linux Driver Verification project (linuxtesting.org).
Reviewed-by: Fabio Estevam festevam@gmail.com Acked-by: Felipe Balbi balbi@kernel.org Signed-off-by: Nadezda Lutovinova lutovinova@ispras.ru Link: https://lore.kernel.org/r/20210819154818.18334-1-lutovinova@ispras.ru Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc3/dwc3-imx8mp.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/usb/dwc3/dwc3-imx8mp.c b/drivers/usb/dwc3/dwc3-imx8mp.c index 756faa46d33a..d328d20abfbc 100644 --- a/drivers/usb/dwc3/dwc3-imx8mp.c +++ b/drivers/usb/dwc3/dwc3-imx8mp.c @@ -152,13 +152,6 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev) } dwc3_imx->irq = irq;
- err = devm_request_threaded_irq(dev, irq, NULL, dwc3_imx8mp_interrupt, - IRQF_ONESHOT, dev_name(dev), dwc3_imx); - if (err) { - dev_err(dev, "failed to request IRQ #%d --> %d\n", irq, err); - goto disable_clks; - } - pm_runtime_set_active(dev); pm_runtime_enable(dev); err = pm_runtime_get_sync(dev); @@ -186,6 +179,13 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev) } of_node_put(dwc3_np);
+ err = devm_request_threaded_irq(dev, irq, NULL, dwc3_imx8mp_interrupt, + IRQF_ONESHOT, dev_name(dev), dwc3_imx); + if (err) { + dev_err(dev, "failed to request IRQ #%d --> %d\n", irq, err); + goto depopulate; + } + device_set_wakeup_capable(dev, true); pm_runtime_put(dev);
From: Nadezda Lutovinova lutovinova@ispras.ru
[ Upstream commit 7c75bde329d7e2a93cf86a5c15c61f96f1446cdc ]
If IRQ occurs between calling dsps_setup_optional_vbus_irq() and dsps_create_musb_pdev(), then null pointer dereference occurs since glue->musb wasn't initialized yet.
The patch puts initializing of neccesery data before registration of the interrupt handler.
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Nadezda Lutovinova lutovinova@ispras.ru Link: https://lore.kernel.org/r/20210819163323.17714-1-lutovinova@ispras.ru Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/musb/musb_dsps.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 5892f3ce0cdc..ce9fc46c9266 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -890,23 +890,22 @@ static int dsps_probe(struct platform_device *pdev) if (!glue->usbss_base) return -ENXIO;
- if (usb_get_dr_mode(&pdev->dev) == USB_DR_MODE_PERIPHERAL) { - ret = dsps_setup_optional_vbus_irq(pdev, glue); - if (ret) - goto err_iounmap; - } - platform_set_drvdata(pdev, glue); pm_runtime_enable(&pdev->dev); ret = dsps_create_musb_pdev(glue, pdev); if (ret) goto err;
+ if (usb_get_dr_mode(&pdev->dev) == USB_DR_MODE_PERIPHERAL) { + ret = dsps_setup_optional_vbus_irq(pdev, glue); + if (ret) + goto err; + } + return 0;
err: pm_runtime_disable(&pdev->dev); -err_iounmap: iounmap(glue->usbss_base); return ret; }
From: Anirudh Rayabharam mail@anirudhrb.com
[ Upstream commit 258c81b341c8025d79073ce2d6ce19dcdc7d10d2 ]
In vhci_device_unlink_cleanup(), the URBs for unsent unlink requests are not given back. This sometimes causes usb_kill_urb to wait indefinitely for that urb to be given back. syzbot has reported a hung task issue [1] for this.
To fix this, give back the urbs corresponding to unsent unlink requests (unlink_tx list) similar to how urbs corresponding to unanswered unlink requests (unlink_rx list) are given back.
[1]: https://syzkaller.appspot.com/bug?id=08f12df95ae7da69814e64eb5515d5a85ed06b7...
Reported-by: syzbot+74d6ef051d3d2eacf428@syzkaller.appspotmail.com Tested-by: syzbot+74d6ef051d3d2eacf428@syzkaller.appspotmail.com Reviewed-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Anirudh Rayabharam mail@anirudhrb.com Link: https://lore.kernel.org/r/20210820190122.16379-2-mail@anirudhrb.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/usbip/vhci_hcd.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 4ba6bcdaa8e9..190bd3d1c1f0 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -957,8 +957,32 @@ static void vhci_device_unlink_cleanup(struct vhci_device *vdev) spin_lock(&vdev->priv_lock);
list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) { + struct urb *urb; + + /* give back urb of unsent unlink request */ pr_info("unlink cleanup tx %lu\n", unlink->unlink_seqnum); + + urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum); + if (!urb) { + list_del(&unlink->list); + kfree(unlink); + continue; + } + + urb->status = -ENODEV; + + usb_hcd_unlink_urb_from_ep(hcd, urb); + list_del(&unlink->list); + + spin_unlock(&vdev->priv_lock); + spin_unlock_irqrestore(&vhci->lock, flags); + + usb_hcd_giveback_urb(hcd, urb, urb->status); + + spin_lock_irqsave(&vhci->lock, flags); + spin_lock(&vdev->priv_lock); + kfree(unlink); }
From: Shuah Khan skhan@linuxfoundation.org
[ Upstream commit 66cce9e73ec61967ed1f97f30cee79bd9a2bb7ee ]
When a remote usb device is attached to the local Virtual USB Host Controller Root Hub port, the bound device driver may send a port reset command.
vhci_hcd accepts port resets only when the device doesn't have port address assigned to it. When reset happens device is in assigned/used state and vhci_hcd rejects it leaving the port in a stuck state.
This problem was found when a blue-tooth or xbox wireless dongle was passed through using usbip.
A few drivers reset the port during probe including mt76 driver specific to this bug report. Fix the problem with a change to honor reset requests when device is in used state (VDEV_ST_USED).
Reported-and-tested-by: Michael msbroadf@gmail.com Suggested-by: Michael msbroadf@gmail.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Link: https://lore.kernel.org/r/20210819225937.41037-1-skhan@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/usbip/vhci_hcd.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 190bd3d1c1f0..b07b2925ff78 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -455,8 +455,14 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, vhci_hcd->port_status[rhport] &= ~(1 << USB_PORT_FEAT_RESET); vhci_hcd->re_timeout = 0;
+ /* + * A few drivers do usb reset during probe when + * the device could be in VDEV_ST_USED state + */ if (vhci_hcd->vdev[rhport].ud.status == - VDEV_ST_NOTASSIGNED) { + VDEV_ST_NOTASSIGNED || + vhci_hcd->vdev[rhport].ud.status == + VDEV_ST_USED) { usbip_dbg_vhci_rh( " enable rhport %d (status %u)\n", rhport,
From: Chunfeng Yun chunfeng.yun@mediatek.com
[ Upstream commit 7f85c16f40d8be5656fb3476909db5c3a5a9c6ea ]
BUG: KASAN: use-after-free in usb_hcd_is_primary_hcd+0x38/0x60 Call trace: dump_backtrace+0x0/0x3dc show_stack+0x20/0x2c dump_stack+0x15c/0x1d4 print_address_description+0x7c/0x510 kasan_report+0x164/0x1ac __asan_report_load8_noabort+0x44/0x50 usb_hcd_is_primary_hcd+0x38/0x60 xhci_mtk_runtime_suspend+0x68/0x148 pm_generic_runtime_suspend+0x90/0xac __rpm_callback+0xb8/0x1f4 rpm_callback+0x54/0x1d0 rpm_suspend+0x4e0/0xc84 __pm_runtime_suspend+0xc4/0x114 xhci_mtk_probe+0xa58/0xd00
This may happen when probe fails, needn't suspend it synchronously, fix it by using pm_runtime_put_noidle().
Reported-by: Pi Hsun pihsun@google.com Signed-off-by: Chunfeng Yun chunfeng.yun@mediatek.com Link: https://lore.kernel.org/r/1629189389-18779-3-git-send-email-chunfeng.yun@med... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/xhci-mtk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index b2058b3bc834..86e5710a5307 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -571,7 +571,7 @@ static int xhci_mtk_probe(struct platform_device *pdev) xhci_mtk_ldos_disable(mtk);
disable_pm: - pm_runtime_put_sync_autosuspend(dev); + pm_runtime_put_noidle(dev); pm_runtime_disable(dev); return ret; }
From: Sugar Zhang sugar.zhang@rock-chips.com
[ Upstream commit 53ca9b9777b95cdd689181d7c547e38dc79adad0 ]
API 'set_fmt' maybe called when PD is off, in the situation, any register access will hang the system. so, enable PD before r/w register.
Signed-off-by: Sugar Zhang sugar.zhang@rock-chips.com Link: https://lore.kernel.org/r/1629950520-14190-4-git-send-email-sugar.zhang@rock... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/rockchip/rockchip_i2s.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 0740764e7f71..d020cb2bdbc4 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -186,7 +186,9 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, { struct rk_i2s_dev *i2s = to_info(cpu_dai); unsigned int mask = 0, val = 0; + int ret = 0;
+ pm_runtime_get_sync(cpu_dai->dev); mask = I2S_CKR_MSS_MASK; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: @@ -199,7 +201,8 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, i2s->is_master_mode = false; break; default: - return -EINVAL; + ret = -EINVAL; + goto err_pm_put; }
regmap_update_bits(i2s->regmap, I2S_CKR, mask, val); @@ -213,7 +216,8 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, val = I2S_CKR_CKP_POS; break; default: - return -EINVAL; + ret = -EINVAL; + goto err_pm_put; }
regmap_update_bits(i2s->regmap, I2S_CKR, mask, val); @@ -236,7 +240,8 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, val = I2S_TXCR_TFS_PCM | I2S_TXCR_PBM_MODE(1); break; default: - return -EINVAL; + ret = -EINVAL; + goto err_pm_put; }
regmap_update_bits(i2s->regmap, I2S_TXCR, mask, val); @@ -259,12 +264,16 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, val = I2S_RXCR_TFS_PCM | I2S_RXCR_PBM_MODE(1); break; default: - return -EINVAL; + ret = -EINVAL; + goto err_pm_put; }
regmap_update_bits(i2s->regmap, I2S_RXCR, mask, val);
- return 0; +err_pm_put: + pm_runtime_put(cpu_dai->dev); + + return ret; }
static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
From: Xiaotan Luo lxt@rock-chips.com
[ Upstream commit 1bf56843e664eef2525bdbfae6a561e98910f676 ]
- DSP_A: PCM delay 1 bit mode, L data MSB after FRM LRC - DSP_B: PCM no delay mode, L data MSB during FRM LRC
Signed-off-by: Xiaotan Luo lxt@rock-chips.com Signed-off-by: Sugar Zhang sugar.zhang@rock-chips.com Link: https://lore.kernel.org/r/1629950562-14281-3-git-send-email-sugar.zhang@rock... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/rockchip/rockchip_i2s.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index d020cb2bdbc4..ac9980ed266e 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -233,12 +233,12 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, case SND_SOC_DAIFMT_I2S: val = I2S_TXCR_IBM_NORMAL; break; - case SND_SOC_DAIFMT_DSP_A: /* PCM no delay mode */ - val = I2S_TXCR_TFS_PCM; - break; - case SND_SOC_DAIFMT_DSP_B: /* PCM delay 1 mode */ + case SND_SOC_DAIFMT_DSP_A: /* PCM delay 1 bit mode */ val = I2S_TXCR_TFS_PCM | I2S_TXCR_PBM_MODE(1); break; + case SND_SOC_DAIFMT_DSP_B: /* PCM no delay mode */ + val = I2S_TXCR_TFS_PCM; + break; default: ret = -EINVAL; goto err_pm_put; @@ -257,12 +257,12 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, case SND_SOC_DAIFMT_I2S: val = I2S_RXCR_IBM_NORMAL; break; - case SND_SOC_DAIFMT_DSP_A: /* PCM no delay mode */ - val = I2S_RXCR_TFS_PCM; - break; - case SND_SOC_DAIFMT_DSP_B: /* PCM delay 1 mode */ + case SND_SOC_DAIFMT_DSP_A: /* PCM delay 1 bit mode */ val = I2S_RXCR_TFS_PCM | I2S_RXCR_PBM_MODE(1); break; + case SND_SOC_DAIFMT_DSP_B: /* PCM no delay mode */ + val = I2S_RXCR_TFS_PCM; + break; default: ret = -EINVAL; goto err_pm_put;
From: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
[ Upstream commit 0c75fc7193387776c10f7c7b440d93496e3d5e21 ]
When more than one FE is connected to a BE, e.g. in a mixing use case, the BE can be triggered multiple times when the FE are opened/started concurrently. This race condition is problematic in the case of SoundWire BE dailinks, and this is not desirable in a general case. The code carefully checks when the BE can be stopped or hw_free'ed, but the trigger code does not use any mutual exclusion.
Fix by using the same spinlock already used to check FE states, and set the state before the trigger. In case of errors, the initial state will be restored.
This patch does not change how the triggers are handled, it only makes sure the states are handled in critical sections.
Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Message-Id: 20210817164054.250028-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/soc-pcm.c | 103 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 85 insertions(+), 18 deletions(-)
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index d1c570ca21ea..b944f56a469a 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2001,6 +2001,8 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, struct snd_soc_pcm_runtime *be; struct snd_soc_dpcm *dpcm; int ret = 0; + unsigned long flags; + enum snd_soc_dpcm_state state;
for_each_dpcm_be(fe, stream, dpcm) { struct snd_pcm_substream *be_substream; @@ -2017,76 +2019,141 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream,
switch (cmd) { case SNDRV_PCM_TRIGGER_START: + spin_lock_irqsave(&fe->card->dpcm_lock, flags); if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) && (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) && - (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) { + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); continue; + } + state = be->dpcm[stream].state; + be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
ret = soc_pcm_trigger(be_substream, cmd); - if (ret) + if (ret) { + spin_lock_irqsave(&fe->card->dpcm_lock, flags); + be->dpcm[stream].state = state; + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); goto end; + }
- be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; break; case SNDRV_PCM_TRIGGER_RESUME: - if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND)) + spin_lock_irqsave(&fe->card->dpcm_lock, flags); + if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND) { + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); continue; + } + + state = be->dpcm[stream].state; + be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
ret = soc_pcm_trigger(be_substream, cmd); - if (ret) + if (ret) { + spin_lock_irqsave(&fe->card->dpcm_lock, flags); + be->dpcm[stream].state = state; + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); goto end; + }
- be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; break; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) + spin_lock_irqsave(&fe->card->dpcm_lock, flags); + if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED) { + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); continue; + } + + state = be->dpcm[stream].state; + be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
ret = soc_pcm_trigger(be_substream, cmd); - if (ret) + if (ret) { + spin_lock_irqsave(&fe->card->dpcm_lock, flags); + be->dpcm[stream].state = state; + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); goto end; + }
- be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; break; case SNDRV_PCM_TRIGGER_STOP: + spin_lock_irqsave(&fe->card->dpcm_lock, flags); if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) && - (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) { + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); continue; + } + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) continue;
+ spin_lock_irqsave(&fe->card->dpcm_lock, flags); + state = be->dpcm[stream].state; + be->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP; + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); + ret = soc_pcm_trigger(be_substream, cmd); - if (ret) + if (ret) { + spin_lock_irqsave(&fe->card->dpcm_lock, flags); + be->dpcm[stream].state = state; + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); goto end; + }
- be->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP; break; case SNDRV_PCM_TRIGGER_SUSPEND: - if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) + spin_lock_irqsave(&fe->card->dpcm_lock, flags); + if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) { + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); continue; + } + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) continue;
+ spin_lock_irqsave(&fe->card->dpcm_lock, flags); + state = be->dpcm[stream].state; + be->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP; + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); + ret = soc_pcm_trigger(be_substream, cmd); - if (ret) + if (ret) { + spin_lock_irqsave(&fe->card->dpcm_lock, flags); + be->dpcm[stream].state = state; + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); goto end; + }
- be->dpcm[stream].state = SND_SOC_DPCM_STATE_SUSPEND; break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) + spin_lock_irqsave(&fe->card->dpcm_lock, flags); + if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) { + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); continue; + } + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) continue;
+ spin_lock_irqsave(&fe->card->dpcm_lock, flags); + state = be->dpcm[stream].state; + be->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED; + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); + ret = soc_pcm_trigger(be_substream, cmd); - if (ret) + if (ret) { + spin_lock_irqsave(&fe->card->dpcm_lock, flags); + be->dpcm[stream].state = state; + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); goto end; + }
- be->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED; break; } }
From: Sean Keely Sean.Keely@amd.com
[ Upstream commit 1ec06c2dee679e9f089e78ed20cb74ee90155f61 ]
On systems with multiple SH per SE compute_static_thread_mgmt_se# is split into independent masks, one for each SH, in the upper and lower 16 bits. We need to detect this and apply cu masking to each SH. The cu mask bits are assigned first to each SE, then to alternate SHs, then finally to higher CU id. This ensures that the maximum number of SPIs are engaged as early as possible while balancing CU assignment to each SH.
v2: Use max SH/SE rather than max SH in cu_per_sh.
v3: Fix comment blocks, ensure se_mask is initially zero filled, and correctly assign se.sh.cu positions to unset bits in cu_mask.
Signed-off-by: Sean Keely Sean.Keely@amd.com Reviewed-by: Felix Kuehling Felix.Kuehling@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c | 84 +++++++++++++++----- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h | 1 + 2 files changed, 64 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c index 88813dad731f..c021519af810 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c @@ -98,36 +98,78 @@ void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm, uint32_t *se_mask) { struct kfd_cu_info cu_info; - uint32_t cu_per_se[KFD_MAX_NUM_SE] = {0}; - int i, se, sh, cu = 0; - + uint32_t cu_per_sh[KFD_MAX_NUM_SE][KFD_MAX_NUM_SH_PER_SE] = {0}; + int i, se, sh, cu; amdgpu_amdkfd_get_cu_info(mm->dev->kgd, &cu_info);
if (cu_mask_count > cu_info.cu_active_number) cu_mask_count = cu_info.cu_active_number;
+ /* Exceeding these bounds corrupts the stack and indicates a coding error. + * Returning with no CU's enabled will hang the queue, which should be + * attention grabbing. + */ + if (cu_info.num_shader_engines > KFD_MAX_NUM_SE) { + pr_err("Exceeded KFD_MAX_NUM_SE, chip reports %d\n", cu_info.num_shader_engines); + return; + } + if (cu_info.num_shader_arrays_per_engine > KFD_MAX_NUM_SH_PER_SE) { + pr_err("Exceeded KFD_MAX_NUM_SH, chip reports %d\n", + cu_info.num_shader_arrays_per_engine * cu_info.num_shader_engines); + return; + } + /* Count active CUs per SH. + * + * Some CUs in an SH may be disabled. HW expects disabled CUs to be + * represented in the high bits of each SH's enable mask (the upper and lower + * 16 bits of se_mask) and will take care of the actual distribution of + * disabled CUs within each SH automatically. + * Each half of se_mask must be filled only on bits 0-cu_per_sh[se][sh]-1. + * + * See note on Arcturus cu_bitmap layout in gfx_v9_0_get_cu_info. + */ for (se = 0; se < cu_info.num_shader_engines; se++) for (sh = 0; sh < cu_info.num_shader_arrays_per_engine; sh++) - cu_per_se[se] += hweight32(cu_info.cu_bitmap[se % 4][sh + (se / 4)]); - - /* Symmetrically map cu_mask to all SEs: - * cu_mask[0] bit0 -> se_mask[0] bit0; - * cu_mask[0] bit1 -> se_mask[1] bit0; - * ... (if # SE is 4) - * cu_mask[0] bit4 -> se_mask[0] bit1; + cu_per_sh[se][sh] = hweight32(cu_info.cu_bitmap[se % 4][sh + (se / 4)]); + + /* Symmetrically map cu_mask to all SEs & SHs: + * se_mask programs up to 2 SH in the upper and lower 16 bits. + * + * Examples + * Assuming 1 SH/SE, 4 SEs: + * cu_mask[0] bit0 -> se_mask[0] bit0 + * cu_mask[0] bit1 -> se_mask[1] bit0 + * ... + * cu_mask[0] bit4 -> se_mask[0] bit1 + * ... + * + * Assuming 2 SH/SE, 4 SEs + * cu_mask[0] bit0 -> se_mask[0] bit0 (SE0,SH0,CU0) + * cu_mask[0] bit1 -> se_mask[1] bit0 (SE1,SH0,CU0) + * ... + * cu_mask[0] bit4 -> se_mask[0] bit16 (SE0,SH1,CU0) + * cu_mask[0] bit5 -> se_mask[1] bit16 (SE1,SH1,CU0) + * ... + * cu_mask[0] bit8 -> se_mask[0] bit1 (SE0,SH0,CU1) * ... + * + * First ensure all CUs are disabled, then enable user specified CUs. */ - se = 0; - for (i = 0; i < cu_mask_count; i++) { - if (cu_mask[i / 32] & (1 << (i % 32))) - se_mask[se] |= 1 << cu; - - do { - se++; - if (se == cu_info.num_shader_engines) { - se = 0; - cu++; + for (i = 0; i < cu_info.num_shader_engines; i++) + se_mask[i] = 0; + + i = 0; + for (cu = 0; cu < 16; cu++) { + for (sh = 0; sh < cu_info.num_shader_arrays_per_engine; sh++) { + for (se = 0; se < cu_info.num_shader_engines; se++) { + if (cu_per_sh[se][sh] > cu) { + if (cu_mask[i / 32] & (1 << (i % 32))) + se_mask[se] |= 1 << (cu + sh * 16); + i++; + if (i == cu_mask_count) + return; + } } - } while (cu >= cu_per_se[se] && cu < 32); + } } } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h index b5e2ea7550d4..6e6918ccedfd 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h @@ -27,6 +27,7 @@ #include "kfd_priv.h"
#define KFD_MAX_NUM_SE 8 +#define KFD_MAX_NUM_SH_PER_SE 2
/** * struct mqd_manager
From: J. Bruce Fields bfields@redhat.com
[ Upstream commit f657f8eef3ff870552c9fd2839e0061046f44618 ]
NFS implements blocking locks by blocking inside its lock method. In the reexport case, this blocks the nfs server thread, which could lead to deadlocks since an nfs server thread might be required to unlock the conflicting lock. It also causes a crash, since the nfs server thread assumes it can free the lock when its lm_notify lock callback is called.
Ideal would be to make the nfs lock method return without blocking in this case, but for now it works just not to attempt blocking locks. The difference is just that the original client will have to poll (as it does in the v4.0 case) instead of getting a callback when the lock's available.
Signed-off-by: J. Bruce Fields bfields@redhat.com Acked-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Chuck Lever chuck.lever@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/export.c | 2 +- fs/nfsd/nfs4state.c | 8 ++++++-- include/linux/exportfs.h | 2 ++ 3 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/fs/nfs/export.c b/fs/nfs/export.c index 37a1a88df771..d772c20bbfd1 100644 --- a/fs/nfs/export.c +++ b/fs/nfs/export.c @@ -180,5 +180,5 @@ const struct export_operations nfs_export_ops = { .fetch_iversion = nfs_fetch_iversion, .flags = EXPORT_OP_NOWCC|EXPORT_OP_NOSUBTREECHK| EXPORT_OP_CLOSE_BEFORE_UNLINK|EXPORT_OP_REMOTE_FS| - EXPORT_OP_NOATOMIC_ATTR, + EXPORT_OP_NOATOMIC_ATTR|EXPORT_OP_SYNC_LOCKS, }; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index ab81e8ae3265..938b54aa1aa9 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -6727,6 +6727,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_blocked_lock *nbl = NULL; struct file_lock *file_lock = NULL; struct file_lock *conflock = NULL; + struct super_block *sb; __be32 status = 0; int lkflg; int err; @@ -6748,6 +6749,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, dprintk("NFSD: nfsd4_lock: permission denied!\n"); return status; } + sb = cstate->current_fh.fh_dentry->d_sb;
if (lock->lk_is_new) { if (nfsd4_has_session(cstate)) @@ -6796,7 +6798,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, fp = lock_stp->st_stid.sc_file; switch (lock->lk_type) { case NFS4_READW_LT: - if (nfsd4_has_session(cstate)) + if (nfsd4_has_session(cstate) && + !(sb->s_export_op->flags & EXPORT_OP_SYNC_LOCKS)) fl_flags |= FL_SLEEP; fallthrough; case NFS4_READ_LT: @@ -6808,7 +6811,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, fl_type = F_RDLCK; break; case NFS4_WRITEW_LT: - if (nfsd4_has_session(cstate)) + if (nfsd4_has_session(cstate) && + !(sb->s_export_op->flags & EXPORT_OP_SYNC_LOCKS)) fl_flags |= FL_SLEEP; fallthrough; case NFS4_WRITE_LT: diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h index fe848901fcc3..3260fe714846 100644 --- a/include/linux/exportfs.h +++ b/include/linux/exportfs.h @@ -221,6 +221,8 @@ struct export_operations { #define EXPORT_OP_NOATOMIC_ATTR (0x10) /* Filesystem cannot supply atomic attribute updates */ +#define EXPORT_OP_SYNC_LOCKS (0x20) /* Filesystem can't do + asychronous blocking locks */ unsigned long flags; };
From: J. Bruce Fields bfields@redhat.com
[ Upstream commit 0bcc7ca40bd823193224e9f38bafbd8325aaf566 ]
Unlike other filesystems, NFSv3 tries to use fl_file in the GETLK case.
Signed-off-by: J. Bruce Fields bfields@redhat.com Signed-off-by: Chuck Lever chuck.lever@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfsd/nfs4state.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 938b54aa1aa9..42c42ee3f00a 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -6932,8 +6932,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, /* * The NFSv4 spec allows a client to do a LOCKT without holding an OPEN, * so we do a temporary open here just to get an open file to pass to - * vfs_test_lock. (Arguably perhaps test_lock should be done with an - * inode operation.) + * vfs_test_lock. */ static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock) { @@ -6948,7 +6947,9 @@ static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct NFSD_MAY_READ)); if (err) goto out; + lock->fl_file = nf->nf_file; err = nfserrno(vfs_test_lock(nf->nf_file, lock)); + lock->fl_file = NULL; out: fh_unlock(fhp); nfsd_file_put(nf);
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 6ac5720086c8b176794eb74c5cc09f8b79017f38 ]
When switching op-modes, or more generally when reconfiguring, we might switch the RB size. In _iwl_pcie_rx_init() we have a comment saying we must free all RBs since we might switch the size, but this is actually too late: the switch has been done and we'll free the buffers with the wrong size.
Fix this by always freeing the buffers, if any, at the start of configure, instead of only after the size may have changed.
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20210802170640.42d7c93279c4.I07f74e65aab0e... Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 5 ++++- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index fb8491412be4..586c4104edf2 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -487,6 +487,9 @@ void iwl_pcie_free_rbs_pool(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int i;
+ if (!trans_pcie->rx_pool) + return; + for (i = 0; i < RX_POOL_SIZE(trans_pcie->num_rx_bufs); i++) { if (!trans_pcie->rx_pool[i].page) continue; @@ -1093,7 +1096,7 @@ static int _iwl_pcie_rx_init(struct iwl_trans *trans) INIT_LIST_HEAD(&rba->rbd_empty); spin_unlock_bh(&rba->lock);
- /* free all first - we might be reconfigured for a different size */ + /* free all first - we overwrite everything here */ iwl_pcie_free_rbs_pool(trans);
for (i = 0; i < RX_QUEUE_SIZE; i++) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 239bc177a3e5..a7a495dbf64d 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -1866,6 +1866,9 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+ /* free all first - we might be reconfigured for a different size */ + iwl_pcie_free_rbs_pool(trans); + trans->txqs.cmd.q_id = trans_cfg->cmd_queue; trans->txqs.cmd.fifo = trans_cfg->cmd_fifo; trans->txqs.cmd.wdg_timeout = trans_cfg->cmd_q_wdg_timeout;
From: Ilan Peer ilan.peer@intel.com
[ Upstream commit deedf9b97cd4ef45da476c9bdd2a5f3276053956 ]
The scan request processing populated the direct SSIDs in the FW scan request command also for 6GHz scan, which is not needed and might result in unexpected behavior.
Fix the code to add the direct SSIDs only in case the scan is not a 6GHz scan.
Signed-off-by: Ilan Peer ilan.peer@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20210802170640.f465937c7bbf.Ic11a1659ddda8... Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index 5a0696c44f6d..3627de2af344 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -2368,14 +2368,17 @@ static int iwl_mvm_scan_umac_v14(struct iwl_mvm *mvm, struct ieee80211_vif *vif, if (ret) return ret;
- iwl_mvm_scan_umac_fill_probe_p_v4(params, &scan_p->probe_params, - &bitmap_ssid); if (!params->scan_6ghz) { + iwl_mvm_scan_umac_fill_probe_p_v4(params, &scan_p->probe_params, + &bitmap_ssid); iwl_mvm_scan_umac_fill_ch_p_v6(mvm, params, vif, - &scan_p->channel_params, bitmap_ssid); + &scan_p->channel_params, bitmap_ssid);
return 0; + } else { + pb->preq = params->preq; } + cp->flags = iwl_mvm_scan_umac_chan_flags_v2(mvm, params, vif); cp->n_aps_override[0] = IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY; cp->n_aps_override[1] = IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS;
From: Zhang Qilong zhangqilong3@huawei.com
[ Upstream commit 0f5d44ac6e55551798dd3da0ff847c8df5990822 ]
If beacon_inject_active is true, we will return without freeing beacon. Fid that by freeing it before returning.
Signed-off-by: Zhang Qilong zhangqilong3@huawei.com [reworded the commit message] Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20210802172232.d16206ca60fc.I9984a9b442c84... Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index fd5e08961651..7f0c82189808 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -1005,8 +1005,10 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm, return -ENOMEM;
#ifdef CONFIG_IWLWIFI_DEBUGFS - if (mvm->beacon_inject_active) + if (mvm->beacon_inject_active) { + dev_kfree_skb(beacon); return -EBUSY; + } #endif
ret = iwl_mvm_mac_ctxt_send_beacon(mvm, vif, beacon);
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit c6ce1c74ef2923b8ffd85f7f8b486f804f343b39 ]
When TVQM is enabled (iwl_mvm_has_new_tx_api() is true), then queue numbers are just sequentially assigned 0, 1, 2, ... Prior to TVQM, in DQA, there were some statically allocated queue numbers: * IWL_MVM_DQA_AUX_QUEUE == 1, * both IWL_MVM_DQA_INJECT_MONITOR_QUEUE and IWL_MVM_DQA_P2P_DEVICE_QUEUE == 2, and * IWL_MVM_DQA_AP_PROBE_RESP_QUEUE == 9.
Now, these values are assigned to the members mvm->aux_queue, mvm->snif_queue, mvm->probe_queue and mvm->p2p_dev_queue by default. Normally, this doesn't really matter, and if TVQM is in fact available we override them to the real values after allocating a queue for use there.
However, this allocation doesn't always happen. For example, for mvm->p2p_dev_queue (== 2) it only happens when the P2P Device interface is started, if any. If it's not started, the value in mvm->p2p_dev_queue remains 2. This wouldn't really matter all that much if it weren't for iwl_mvm_is_static_queue() which checks a queue number against one of those four static numbers.
Now, if no P2P Device or monitor interface is added then queue 2 may be dynamically allocated, yet alias mvm->p2p_dev_queue or mvm->snif_queue, and thus iwl_mvm_is_static_queue() erroneously returns true for it. If it then gets full, all interface queues are stopped, instead of just backpressuring against the one TXQ that's really the only affected one.
This clearly can lead to issues, as everything is stopped even if just a single TXQ filled its corresponding HW queue, if it happens to have an appropriate number (2 or 9, AUX is always reassigned.) Due to a mac80211 bug, this also led to a situation in which the queues remained stopped across a deauthentication and then attempts to connect to a new AP started failing, but that's fixed separately.
Fix all of this by simply initializing the queue numbers to the invalid value until they're used, if TVQM is enabled, and also setting them back to that value when the queues are later freed again.
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20210802172232.2e47e623f9e2.I9b0830dafbb68... Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 24 +++++++++++++--- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 30 ++++++++++++-------- 2 files changed, 38 insertions(+), 16 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index ebed82c590e5..31611542e1aa 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -754,10 +754,26 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
mvm->fw_restart = iwlwifi_mod_params.fw_restart ? -1 : 0;
- mvm->aux_queue = IWL_MVM_DQA_AUX_QUEUE; - mvm->snif_queue = IWL_MVM_DQA_INJECT_MONITOR_QUEUE; - mvm->probe_queue = IWL_MVM_DQA_AP_PROBE_RESP_QUEUE; - mvm->p2p_dev_queue = IWL_MVM_DQA_P2P_DEVICE_QUEUE; + if (iwl_mvm_has_new_tx_api(mvm)) { + /* + * If we have the new TX/queue allocation API initialize them + * all to invalid numbers. We'll rewrite the ones that we need + * later, but that doesn't happen for all of them all of the + * time (e.g. P2P Device is optional), and if a dynamic queue + * ends up getting number 2 (IWL_MVM_DQA_P2P_DEVICE_QUEUE) then + * iwl_mvm_is_static_queue() erroneously returns true, and we + * might have things getting stuck. + */ + mvm->aux_queue = IWL_MVM_INVALID_QUEUE; + mvm->snif_queue = IWL_MVM_INVALID_QUEUE; + mvm->probe_queue = IWL_MVM_INVALID_QUEUE; + mvm->p2p_dev_queue = IWL_MVM_INVALID_QUEUE; + } else { + mvm->aux_queue = IWL_MVM_DQA_AUX_QUEUE; + mvm->snif_queue = IWL_MVM_DQA_INJECT_MONITOR_QUEUE; + mvm->probe_queue = IWL_MVM_DQA_AP_PROBE_RESP_QUEUE; + mvm->p2p_dev_queue = IWL_MVM_DQA_P2P_DEVICE_QUEUE; + }
mvm->sf_state = SF_UNINIT; if (iwl_mvm_has_unified_ucode(mvm)) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index f618368eda83..c310c366c38e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -316,8 +316,9 @@ static int iwl_mvm_invalidate_sta_queue(struct iwl_mvm *mvm, int queue, }
static int iwl_mvm_disable_txq(struct iwl_mvm *mvm, struct ieee80211_sta *sta, - int queue, u8 tid, u8 flags) + u16 *queueptr, u8 tid, u8 flags) { + int queue = *queueptr; struct iwl_scd_txq_cfg_cmd cmd = { .scd_queue = queue, .action = SCD_CFG_DISABLE_QUEUE, @@ -326,6 +327,7 @@ static int iwl_mvm_disable_txq(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
if (iwl_mvm_has_new_tx_api(mvm)) { iwl_trans_txq_free(mvm->trans, queue); + *queueptr = IWL_MVM_INVALID_QUEUE;
return 0; } @@ -487,6 +489,7 @@ static int iwl_mvm_free_inactive_queue(struct iwl_mvm *mvm, int queue, u8 sta_id, tid; unsigned long disable_agg_tids = 0; bool same_sta; + u16 queue_tmp = queue; int ret;
lockdep_assert_held(&mvm->mutex); @@ -509,7 +512,7 @@ static int iwl_mvm_free_inactive_queue(struct iwl_mvm *mvm, int queue, iwl_mvm_invalidate_sta_queue(mvm, queue, disable_agg_tids, false);
- ret = iwl_mvm_disable_txq(mvm, old_sta, queue, tid, 0); + ret = iwl_mvm_disable_txq(mvm, old_sta, &queue_tmp, tid, 0); if (ret) { IWL_ERR(mvm, "Failed to free inactive queue %d (ret=%d)\n", @@ -1184,6 +1187,7 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm, unsigned int wdg_timeout = iwl_mvm_get_wd_timeout(mvm, mvmsta->vif, false, false); int queue = -1; + u16 queue_tmp; unsigned long disable_agg_tids = 0; enum iwl_mvm_agg_state queue_state; bool shared_queue = false, inc_ssn; @@ -1332,7 +1336,8 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm, return 0;
out_err: - iwl_mvm_disable_txq(mvm, sta, queue, tid, 0); + queue_tmp = queue; + iwl_mvm_disable_txq(mvm, sta, &queue_tmp, tid, 0);
return ret; } @@ -1779,7 +1784,7 @@ static void iwl_mvm_disable_sta_queues(struct iwl_mvm *mvm, if (mvm_sta->tid_data[i].txq_id == IWL_MVM_INVALID_QUEUE) continue;
- iwl_mvm_disable_txq(mvm, sta, mvm_sta->tid_data[i].txq_id, i, + iwl_mvm_disable_txq(mvm, sta, &mvm_sta->tid_data[i].txq_id, i, 0); mvm_sta->tid_data[i].txq_id = IWL_MVM_INVALID_QUEUE; } @@ -1987,7 +1992,7 @@ static int iwl_mvm_add_int_sta_with_queue(struct iwl_mvm *mvm, int macidx, ret = iwl_mvm_add_int_sta_common(mvm, sta, addr, macidx, maccolor); if (ret) { if (!iwl_mvm_has_new_tx_api(mvm)) - iwl_mvm_disable_txq(mvm, NULL, *queue, + iwl_mvm_disable_txq(mvm, NULL, queue, IWL_MAX_TID_COUNT, 0); return ret; } @@ -2060,7 +2065,7 @@ int iwl_mvm_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) if (WARN_ON_ONCE(mvm->snif_sta.sta_id == IWL_MVM_INVALID_STA)) return -EINVAL;
- iwl_mvm_disable_txq(mvm, NULL, mvm->snif_queue, IWL_MAX_TID_COUNT, 0); + iwl_mvm_disable_txq(mvm, NULL, &mvm->snif_queue, IWL_MAX_TID_COUNT, 0); ret = iwl_mvm_rm_sta_common(mvm, mvm->snif_sta.sta_id); if (ret) IWL_WARN(mvm, "Failed sending remove station\n"); @@ -2077,7 +2082,7 @@ int iwl_mvm_rm_aux_sta(struct iwl_mvm *mvm) if (WARN_ON_ONCE(mvm->aux_sta.sta_id == IWL_MVM_INVALID_STA)) return -EINVAL;
- iwl_mvm_disable_txq(mvm, NULL, mvm->aux_queue, IWL_MAX_TID_COUNT, 0); + iwl_mvm_disable_txq(mvm, NULL, &mvm->aux_queue, IWL_MAX_TID_COUNT, 0); ret = iwl_mvm_rm_sta_common(mvm, mvm->aux_sta.sta_id); if (ret) IWL_WARN(mvm, "Failed sending remove station\n"); @@ -2173,7 +2178,7 @@ static void iwl_mvm_free_bcast_sta_queues(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - int queue; + u16 *queueptr, queue;
lockdep_assert_held(&mvm->mutex);
@@ -2182,10 +2187,10 @@ static void iwl_mvm_free_bcast_sta_queues(struct iwl_mvm *mvm, switch (vif->type) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_ADHOC: - queue = mvm->probe_queue; + queueptr = &mvm->probe_queue; break; case NL80211_IFTYPE_P2P_DEVICE: - queue = mvm->p2p_dev_queue; + queueptr = &mvm->p2p_dev_queue; break; default: WARN(1, "Can't free bcast queue on vif type %d\n", @@ -2193,7 +2198,8 @@ static void iwl_mvm_free_bcast_sta_queues(struct iwl_mvm *mvm, return; }
- iwl_mvm_disable_txq(mvm, NULL, queue, IWL_MAX_TID_COUNT, 0); + queue = *queueptr; + iwl_mvm_disable_txq(mvm, NULL, queueptr, IWL_MAX_TID_COUNT, 0); if (iwl_mvm_has_new_tx_api(mvm)) return;
@@ -2428,7 +2434,7 @@ int iwl_mvm_rm_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
iwl_mvm_flush_sta(mvm, &mvmvif->mcast_sta, true);
- iwl_mvm_disable_txq(mvm, NULL, mvmvif->cab_queue, 0, 0); + iwl_mvm_disable_txq(mvm, NULL, &mvmvif->cab_queue, 0, 0);
ret = iwl_mvm_rm_sta_common(mvm, mvmvif->mcast_sta.sta_id); if (ret)
From: Ilan Peer ilan.peer@intel.com
[ Upstream commit 35fc5feca7b24b97e828e6e6a4243b4b9b0131f8 ]
Both 'iwl_scan_probe_params_v3' and 'iwl_scan_probe_params_v4' wrongly addressed the 'bssid_array' field which should supposed to be any array of BSSIDs each of size ETH_ALEN and not the opposite. Fix it.
Signed-off-by: Ilan Peer ilan.peer@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20210802215208.04146f24794f.I90726440ddff7... Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/fw/api/scan.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h index b2605aefc290..8b200379f7c2 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2020 Intel Corporation + * Copyright (C) 2012-2014, 2018-2021 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -874,7 +874,7 @@ struct iwl_scan_probe_params_v3 { u8 reserved; struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX]; __le32 short_ssid[SCAN_SHORT_SSID_MAX_SIZE]; - u8 bssid_array[ETH_ALEN][SCAN_BSSID_MAX_SIZE]; + u8 bssid_array[SCAN_BSSID_MAX_SIZE][ETH_ALEN]; } __packed; /* SCAN_PROBE_PARAMS_API_S_VER_3 */
/** @@ -894,7 +894,7 @@ struct iwl_scan_probe_params_v4 { __le16 reserved; struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX]; __le32 short_ssid[SCAN_SHORT_SSID_MAX_SIZE]; - u8 bssid_array[ETH_ALEN][SCAN_BSSID_MAX_SIZE]; + u8 bssid_array[SCAN_BSSID_MAX_SIZE][ETH_ALEN]; } __packed; /* SCAN_PROBE_PARAMS_API_S_VER_4 */
#define SCAN_MAX_NUM_CHANS_V3 67
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 6c608cd6962ebdf84fd3de6d42f88ed64d2f4e1b ]
BSS elements are protected using RCU, so we need to use RCU properly to access them, fix that.
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20210805130823.fd8b5791ab44.Iba26800a63010... Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 141d9fc299b0..6981608ef165 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -2987,16 +2987,20 @@ static void iwl_mvm_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy, void *_data) { struct iwl_mvm_he_obss_narrow_bw_ru_data *data = _data; + const struct cfg80211_bss_ies *ies; const struct element *elem;
- elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, bss->ies->data, - bss->ies->len); + rcu_read_lock(); + ies = rcu_dereference(bss->ies); + elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, ies->data, + ies->len);
if (!elem || elem->datalen < 10 || !(elem->data[10] & WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT)) { data->tolerated = false; } + rcu_read_unlock(); }
static void iwl_mvm_check_he_obss_narrow_bw_ru(struct ieee80211_hw *hw,
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit e6344c060209ef4e970cac18adeac1676a2a73cd ]
In commit 79f033f6f229 ("iwlwifi: dbg: don't limit dump decisions to all or monitor") we changed the code to pass around a bitmap, but in the monitor_only case, one place accidentally used the bit number, not the bit mask, resulting in CSR and FW_INFO getting dumped instead of monitor data. Fix that.
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20210805141826.774fd8729a33.Ic985a787071d1... Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index cc4e18ca9566..a27849419d29 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2314,7 +2314,7 @@ static void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt, return;
if (dump_data->monitor_only) - dump_mask &= IWL_FW_ERROR_DUMP_FW_MONITOR; + dump_mask &= BIT(IWL_FW_ERROR_DUMP_FW_MONITOR);
fw_error_dump.trans_ptr = iwl_trans_dump_data(fwrt->trans, dump_mask); file_len = le32_to_cpu(dump_file->file_len);
From: Ilan Peer ilan.peer@intel.com
[ Upstream commit 090f1be3abf3069ef856b29761f181808bf55917 ]
The iwl_mvm_scan_ch_n_aps_flag() is called with a variable before the value of the variable is set. Fix it.
Signed-off-by: Ilan Peer ilan.peer@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20210826224715.f6f188980a5e.Ie7331a8b94004... Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index 3627de2af344..ee3aff8bf7c2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -1648,7 +1648,7 @@ iwl_mvm_umac_scan_cfg_channels_v6(struct iwl_mvm *mvm, struct iwl_scan_channel_cfg_umac *cfg = &cp->channel_config[i]; u32 n_aps_flag = iwl_mvm_scan_ch_n_aps_flag(vif_type, - cfg->v2.channel_num); + channels[i]->hw_value);
cfg->flags = cpu_to_le32(flags | n_aps_flag); cfg->v2.channel_num = channels[i]->hw_value;
From: Wentao_Liang Wentao_Liang_g@163.com
[ Upstream commit 6cc64770fb386b10a64a1fe09328396de7bb5262 ]
In line 849 (#1), "mlx5dr_htbl_put(cur_htbl);" drops the reference to cur_htbl and may cause cur_htbl to be freed.
However, cur_htbl is subsequently used in the next line, which may result in an use-after-free bug.
Fix this by calling mlx5dr_err() before the cur_htbl is put.
Signed-off-by: Wentao_Liang Wentao_Liang_g@163.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c index 43356fad53de..ffdfb5a94b14 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c @@ -846,9 +846,9 @@ dr_rule_handle_ste_branch(struct mlx5dr_rule *rule, new_htbl = dr_rule_rehash(rule, nic_rule, cur_htbl, ste_location, send_ste_list); if (!new_htbl) { - mlx5dr_htbl_put(cur_htbl); mlx5dr_err(dmn, "Failed creating rehash table, htbl-log_size: %d\n", cur_htbl->chunk_size); + mlx5dr_htbl_put(cur_htbl); } else { cur_htbl = new_htbl; }
From: Yevgeny Kliteynik kliteyn@nvidia.com
[ Upstream commit ec449ed8230cd30769de3cb70ee0fce293047372 ]
Under high stress, SW steering might get stuck on polling for completion that never comes. For such cases QP needs to have protocol retransmission mechanism enabled. Currently the retransmission timeout is defined as 0 (unlimited). Fix this by defining a real timeout.
Signed-off-by: Yevgeny Kliteynik kliteyn@nvidia.com Reviewed-by: Alex Vesker valex@nvidia.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c index 9df0e73d1c35..69b49deb66b2 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c @@ -620,6 +620,7 @@ static int dr_cmd_modify_qp_rtr2rts(struct mlx5_core_dev *mdev,
MLX5_SET(qpc, qpc, retry_count, attr->retry_cnt); MLX5_SET(qpc, qpc, rnr_retry, attr->rnr_retry); + MLX5_SET(qpc, qpc, primary_address_path.ack_timeout, 0x8); /* ~1ms */
MLX5_SET(rtr2rts_qp_in, in, opcode, MLX5_CMD_OP_RTR2RTS_QP); MLX5_SET(rtr2rts_qp_in, in, qpn, dr_qp->qpn);
From: Colin Ian King colin.king@canonical.com
[ Upstream commit 0be883a0d795d9146f5325de582584147dd0dcdc ]
The check for count appears to be incorrect since a non-zero count check occurs a couple of statements earlier. Currently the check is always false and the dev->port->irq != PARPORT_IRQ_NONE part of the check is never tested and the if statement is dead-code. Fix this by removing the check on count.
Note that this code is pre-git history, so I can't find a sha for it.
Acked-by: Sudip Mukherjee sudipm.mukherjee@gmail.com Signed-off-by: Colin Ian King colin.king@canonical.com Addresses-Coverity: ("Logically dead code") Link: https://lore.kernel.org/r/20210730100710.27405-1-colin.king@canonical.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/parport/ieee1284_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/parport/ieee1284_ops.c b/drivers/parport/ieee1284_ops.c index 2c11bd3fe1fd..17061f1df0f4 100644 --- a/drivers/parport/ieee1284_ops.c +++ b/drivers/parport/ieee1284_ops.c @@ -518,7 +518,7 @@ size_t parport_ieee1284_ecp_read_data (struct parport *port, goto out;
/* Yield the port for a while. */ - if (count && dev->port->irq != PARPORT_IRQ_NONE) { + if (dev->port->irq != PARPORT_IRQ_NONE) { parport_release (dev); schedule_timeout_interruptible(msecs_to_jiffies(40)); parport_claim_or_block (dev);
From: Chengfeng Ye cyeaa@connect.ust.hk
[ Upstream commit 47bb27a20d6ea22cd092c1fc2bb4fcecac374838 ]
This lock is not released if the program return at the patched branch.
Signed-off-by: Chengfeng Ye cyeaa@connect.ust.hk Signed-off-by: Alexei Starovoitov ast@kernel.org Link: https://lore.kernel.org/bpf/20210827074140.118671-1-cyeaa@connect.ust.hk Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c b/tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c index ec281b0363b8..86f97681ad89 100644 --- a/tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c +++ b/tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c @@ -195,8 +195,10 @@ static void run_test(int cgroup_fd)
pthread_mutex_lock(&server_started_mtx); if (CHECK_FAIL(pthread_create(&tid, NULL, server_thread, - (void *)&server_fd))) + (void *)&server_fd))) { + pthread_mutex_unlock(&server_started_mtx); goto close_server_fd; + } pthread_cond_wait(&server_started, &server_started_mtx); pthread_mutex_unlock(&server_started_mtx);
From: Loic Poulain loic.poulain@linaro.org
[ Upstream commit 8678fd31f2d3eb14f2b8b39c9bc266f16fa24b22 ]
When receiving a beacon or probe response, we should update the boottime_ns field which is the timestamp the frame was received at. (cf mac80211.h)
This fixes a scanning issue with Android since it relies on this timestamp to determine when the AP has been seen for the last time (via the nl80211 BSS_LAST_SEEN_BOOTTIME parameter).
Signed-off-by: Loic Poulain loic.poulain@linaro.org Reviewed-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/1629992768-23785-1-git-send-email-loic.poulain@lin... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/wcn36xx/txrx.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c index 1b831157ede1..cab196bb38cd 100644 --- a/drivers/net/wireless/ath/wcn36xx/txrx.c +++ b/drivers/net/wireless/ath/wcn36xx/txrx.c @@ -287,6 +287,10 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb) status.rate_idx = 0; }
+ if (ieee80211_is_beacon(hdr->frame_control) || + ieee80211_is_probe_resp(hdr->frame_control)) + status.boottime_ns = ktime_get_boottime_ns(); + memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
if (ieee80211_is_beacon(hdr->frame_control)) {
From: Zekun Shen bruceshenzk@gmail.com
[ Upstream commit 23151b9ae79e3bc4f6a0c4cd3a7f355f68dad128 ]
Bad header can have large length field which can cause OOB. cptr is the last bytes for read, and the eeprom is parsed from high to low address. The OOB, triggered by the condition length > cptr could cause memory error with a read on negative index.
There are some sanity check around length, but it is not compared with cptr (the remaining bytes). Here, the corrupted/bad EEPROM can cause panic.
I was able to reproduce the crash, but I cannot find the log and the reproducer now. After I applied the patch, the bug is no longer reproducible.
Signed-off-by: Zekun Shen bruceshenzk@gmail.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/YM3xKsQJ0Hw2hjrc@Zekuns-MBP-16.fios-router.home Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index b4885a700296..b0a4ca3559fd 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3351,7 +3351,8 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah, "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n", cptr, code, reference, length, major, minor); if ((!AR_SREV_9485(ah) && length >= 1024) || - (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485)) { + (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485) || + (length > cptr)) { ath_dbg(common, EEPROM, "Skipping bad header\n"); cptr -= COMP_HDR_LEN; continue;
From: Miaoqing Pan miaoqing@codeaurora.org
[ Upstream commit 7c48662b9d56666219f526a71ace8c15e6e12f1f ]
The problem is that gpio_free() can sleep and the cfg_soc() can be called with spinlocks held. One problematic call tree is:
--> ath_reset_internal() takes &sc->sc_pcu_lock spin lock --> ath9k_hw_reset() --> ath9k_hw_gpio_request_in() --> ath9k_hw_gpio_request() --> ath9k_hw_gpio_cfg_soc()
Remove gpio_free(), use error message instead, so we should make sure there is no GPIO conflict.
Also remove ath9k_hw_gpio_free() from ath9k_hw_apply_gpio_override(), as gpio_mask will never be set for SOC chips.
Signed-off-by: Miaoqing Pan miaoqing@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/1628481916-15030-1-git-send-email-miaoqing@codeaur... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/hw.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 2ca3b86714a9..172081ffe477 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1621,7 +1621,6 @@ static void ath9k_hw_apply_gpio_override(struct ath_hw *ah) ath9k_hw_gpio_request_out(ah, i, NULL, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ath9k_hw_set_gpio(ah, i, !!(ah->gpio_val & BIT(i))); - ath9k_hw_gpio_free(ah, i); } }
@@ -2728,14 +2727,17 @@ static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah, u32 gpio, u32 type) static void ath9k_hw_gpio_cfg_soc(struct ath_hw *ah, u32 gpio, bool out, const char *label) { + int err; + if (ah->caps.gpio_requested & BIT(gpio)) return;
- /* may be requested by BSP, free anyway */ - gpio_free(gpio); - - if (gpio_request_one(gpio, out ? GPIOF_OUT_INIT_LOW : GPIOF_IN, label)) + err = gpio_request_one(gpio, out ? GPIOF_OUT_INIT_LOW : GPIOF_IN, label); + if (err) { + ath_err(ath9k_hw_common(ah), "request GPIO%d failed:%d\n", + gpio, err); return; + }
ah->caps.gpio_requested |= BIT(gpio); }
From: 王贇 yun.wang@linux.alibaba.com
[ Upstream commit 733c99ee8be9a1410287cdbb943887365e83b2d6 ]
In netlbl_cipsov4_add_std() when 'doi_def->map.std' alloc failed, we sometime observe panic:
BUG: kernel NULL pointer dereference, address: ... RIP: 0010:cipso_v4_doi_free+0x3a/0x80 ... Call Trace: netlbl_cipsov4_add_std+0xf4/0x8c0 netlbl_cipsov4_add+0x13f/0x1b0 genl_family_rcv_msg_doit.isra.15+0x132/0x170 genl_rcv_msg+0x125/0x240
This is because in cipso_v4_doi_free() there is no check on 'doi_def->map.std' when 'doi_def->type' equal 1, which is possibe, since netlbl_cipsov4_add_std() haven't initialize it before alloc 'doi_def->map.std'.
This patch just add the check to prevent panic happen for similar cases.
Reported-by: Abaci abaci@linux.alibaba.com Signed-off-by: Michael Wang yun.wang@linux.alibaba.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/netlabel/netlabel_cipso_v4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index 50f40943c815..f3f1df1b0f8e 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c @@ -144,8 +144,8 @@ static int netlbl_cipsov4_add_std(struct genl_info *info, return -ENOMEM; doi_def->map.std = kzalloc(sizeof(*doi_def->map.std), GFP_KERNEL); if (doi_def->map.std == NULL) { - ret_val = -ENOMEM; - goto add_std_failure; + kfree(doi_def); + return -ENOMEM; } doi_def->type = CIPSO_V4_MAP_TRANS;
From: Haimin Zhang tcs_kernel@tencent.com
[ Upstream commit efe487fce3061d94222c6501d7be3aa549b3dc78 ]
syzbot report an array-index-out-of-bounds in taprio_change index 16 is out of range for type '__u16 [16]' that's because mqprio->num_tc is lager than TC_MAX_QUEUE,so we check the return value of netdev_set_num_tc.
Reported-by: syzbot+2b3e5fb6c7ef285a94f6@syzkaller.appspotmail.com Signed-off-by: Haimin Zhang tcs_kernel@tencent.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/sched/sch_taprio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index 5c91df52b8c2..b0d6385fff9e 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -1547,7 +1547,9 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt, taprio_set_picos_per_byte(dev, q);
if (mqprio) { - netdev_set_num_tc(dev, mqprio->num_tc); + err = netdev_set_num_tc(dev, mqprio->num_tc); + if (err) + goto free_sched; for (i = 0; i < mqprio->num_tc; i++) netdev_set_tc_queue(dev, i, mqprio->count[i],
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit a39ff4a47f3e1da3b036817ef436b1a9be10783a ]
It will cause null-ptr-deref if platform_get_resource() returns NULL, we need check the return value.
Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/wiznet/w5100.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/wiznet/w5100.c b/drivers/net/ethernet/wiznet/w5100.c index ec5db481c9cd..15e13d6dc5db 100644 --- a/drivers/net/ethernet/wiznet/w5100.c +++ b/drivers/net/ethernet/wiznet/w5100.c @@ -1052,6 +1052,8 @@ static int w5100_mmio_probe(struct platform_device *pdev) mac_addr = data->mac_addr;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) + return -EINVAL; if (resource_size(mem) < W5100_BUS_DIRECT_SIZE) ops = &w5100_mmio_indirect_ops; else
From: Guojia Liao liaoguojia@huawei.com
[ Upstream commit e79c0e324b011b0288cd411a5b53870a7730f163 ]
abs() returns signed long, which could not convert the type as unsigned, and it may cause a mismatch type warning from static tools. To fix it, this patch uses an variable to save the abs()'s result and does a explicit conversion.
Signed-off-by: Guojia Liao liaoguojia@huawei.com Signed-off-by: Guangbin Huang huangguangbin2@huawei.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c index 38b601031db4..95343f6d15e1 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c @@ -10,7 +10,14 @@
static u16 hclge_errno_to_resp(int errno) { - return abs(errno); + int resp = abs(errno); + + /* The status for pf to vf msg cmd is u16, constrainted by HW. + * We need to keep the same type with it. + * The intput errno is the stander error code, it's safely to + * use a u16 to store the abs(errno). + */ + return (u16)resp; }
/* hclge_gen_resp_to_vf: used to generate a synchronous response to VF when PF
From: Marc Zyngier maz@kernel.org
[ Upstream commit db75f1a33f82ad332b6e139c5960e01999969d2c ]
We already have the option to attach a callback to an interrupt to retrieve its pending state. As we are planning to expand this facility, move this callback into its own data structure.
This will limit the size of individual interrupts as the ops structures can be shared across multiple interrupts.
Signed-off-by: Marc Zyngier maz@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/kvm/arch_timer.c | 8 ++++++-- arch/arm64/kvm/vgic/vgic.c | 14 +++++++------- include/kvm/arm_vgic.h | 28 +++++++++++++++++----------- 3 files changed, 30 insertions(+), 20 deletions(-)
diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index 74e0699661e9..e2288b6bf435 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -1116,6 +1116,10 @@ bool kvm_arch_timer_get_input_level(int vintid) return kvm_timer_should_fire(timer); }
+static struct irq_ops arch_timer_irq_ops = { + .get_input_level = kvm_arch_timer_get_input_level, +}; + int kvm_timer_enable(struct kvm_vcpu *vcpu) { struct arch_timer_cpu *timer = vcpu_timer(vcpu); @@ -1143,7 +1147,7 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu) ret = kvm_vgic_map_phys_irq(vcpu, map.direct_vtimer->host_timer_irq, map.direct_vtimer->irq.irq, - kvm_arch_timer_get_input_level); + &arch_timer_irq_ops); if (ret) return ret;
@@ -1151,7 +1155,7 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu) ret = kvm_vgic_map_phys_irq(vcpu, map.direct_ptimer->host_timer_irq, map.direct_ptimer->irq.irq, - kvm_arch_timer_get_input_level); + &arch_timer_irq_ops); }
if (ret) diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c index 15b666200f0b..111bff47e471 100644 --- a/arch/arm64/kvm/vgic/vgic.c +++ b/arch/arm64/kvm/vgic/vgic.c @@ -182,8 +182,8 @@ bool vgic_get_phys_line_level(struct vgic_irq *irq)
BUG_ON(!irq->hw);
- if (irq->get_input_level) - return irq->get_input_level(irq->intid); + if (irq->ops && irq->ops->get_input_level) + return irq->ops->get_input_level(irq->intid);
WARN_ON(irq_get_irqchip_state(irq->host_irq, IRQCHIP_STATE_PENDING, @@ -480,7 +480,7 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, /* @irq->irq_lock must be held */ static int kvm_vgic_map_irq(struct kvm_vcpu *vcpu, struct vgic_irq *irq, unsigned int host_irq, - bool (*get_input_level)(int vindid)) + struct irq_ops *ops) { struct irq_desc *desc; struct irq_data *data; @@ -500,7 +500,7 @@ static int kvm_vgic_map_irq(struct kvm_vcpu *vcpu, struct vgic_irq *irq, irq->hw = true; irq->host_irq = host_irq; irq->hwintid = data->hwirq; - irq->get_input_level = get_input_level; + irq->ops = ops; return 0; }
@@ -509,11 +509,11 @@ static inline void kvm_vgic_unmap_irq(struct vgic_irq *irq) { irq->hw = false; irq->hwintid = 0; - irq->get_input_level = NULL; + irq->ops = NULL; }
int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq, - u32 vintid, bool (*get_input_level)(int vindid)) + u32 vintid, struct irq_ops *ops) { struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, vintid); unsigned long flags; @@ -522,7 +522,7 @@ int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq, BUG_ON(!irq);
raw_spin_lock_irqsave(&irq->irq_lock, flags); - ret = kvm_vgic_map_irq(vcpu, irq, host_irq, get_input_level); + ret = kvm_vgic_map_irq(vcpu, irq, host_irq, ops); raw_spin_unlock_irqrestore(&irq->irq_lock, flags); vgic_put_irq(vcpu->kvm, irq);
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index ec621180ef09..feaffeaffeec 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -89,6 +89,21 @@ enum vgic_irq_config { VGIC_CONFIG_LEVEL };
+/* + * Per-irq ops overriding some common behavious. + * + * Always called in non-preemptible section and the functions can use + * kvm_arm_get_running_vcpu() to get the vcpu pointer for private IRQs. + */ +struct irq_ops { + /* + * Callback function pointer to in-kernel devices that can tell us the + * state of the input level of mapped level-triggered IRQ faster than + * peaking into the physical GIC. + */ + bool (*get_input_level)(int vintid); +}; + struct vgic_irq { raw_spinlock_t irq_lock; /* Protects the content of the struct */ struct list_head lpi_list; /* Used to link all LPIs together */ @@ -126,16 +141,7 @@ struct vgic_irq { u8 group; /* 0 == group 0, 1 == group 1 */ enum vgic_irq_config config; /* Level or edge */
- /* - * Callback function pointer to in-kernel devices that can tell us the - * state of the input level of mapped level-triggered IRQ faster than - * peaking into the physical GIC. - * - * Always called in non-preemptible section and the functions can use - * kvm_arm_get_running_vcpu() to get the vcpu pointer for private - * IRQs. - */ - bool (*get_input_level)(int vintid); + struct irq_ops *ops;
void *owner; /* Opaque pointer to reserve an interrupt for in-kernel devices. */ @@ -352,7 +358,7 @@ void kvm_vgic_init_cpu_hardware(void); int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, bool level, void *owner); int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq, - u32 vintid, bool (*get_input_level)(int vindid)); + u32 vintid, struct irq_ops *ops); int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid); bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid);
On Thu, 16 Sep 2021 17:01:42 +0100, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
From: Marc Zyngier maz@kernel.org
[ Upstream commit db75f1a33f82ad332b6e139c5960e01999969d2c ]
We already have the option to attach a callback to an interrupt to retrieve its pending state. As we are planning to expand this facility, move this callback into its own data structure.
This will limit the size of individual interrupts as the ops structures can be shared across multiple interrupts.
Signed-off-by: Marc Zyngier maz@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org
arch/arm64/kvm/arch_timer.c | 8 ++++++-- arch/arm64/kvm/vgic/vgic.c | 14 +++++++------- include/kvm/arm_vgic.h | 28 +++++++++++++++++----------- 3 files changed, 30 insertions(+), 20 deletions(-)
As I replied to Sasha earlier, I don't see a good reason to backport this, as it doesn't improve anything on its own. Unless there is a compelling reason to get this backported, I'd rather see it dropped.
Thanks,
M.
On Thu, Sep 16, 2021 at 07:25:27PM +0100, Marc Zyngier wrote:
On Thu, 16 Sep 2021 17:01:42 +0100, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
From: Marc Zyngier maz@kernel.org
[ Upstream commit db75f1a33f82ad332b6e139c5960e01999969d2c ]
We already have the option to attach a callback to an interrupt to retrieve its pending state. As we are planning to expand this facility, move this callback into its own data structure.
This will limit the size of individual interrupts as the ops structures can be shared across multiple interrupts.
Signed-off-by: Marc Zyngier maz@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org
arch/arm64/kvm/arch_timer.c | 8 ++++++-- arch/arm64/kvm/vgic/vgic.c | 14 +++++++------- include/kvm/arm_vgic.h | 28 +++++++++++++++++----------- 3 files changed, 30 insertions(+), 20 deletions(-)
As I replied to Sasha earlier, I don't see a good reason to backport this, as it doesn't improve anything on its own. Unless there is a compelling reason to get this backported, I'd rather see it dropped.
Yes, I'll drop it. I originally brought it as a dependency for a patch that ended up being dropped. Thanks for pointing it out!
From: Mikulas Patocka mpatocka@redhat.com
commit 030f653078316a9cc9ca6bd1b0234dcf858be35d upstream.
I was debugging some crashes on parisc and I found out that there is a crash possibility if a function using alloca is interrupted by a signal. The reason for the crash is that the gcc alloca implementation leaves garbage in the upper 32 bits of the sp register. This normally doesn't matter (the upper bits are ignored because the PSW W-bit is clear), however the signal delivery routine in the kernel uses full 64 bits of sp and it fails with -EFAULT if the upper 32 bits are not zero.
I created this program that demonstrates the problem:
#include <stdlib.h> #include <unistd.h> #include <signal.h> #include <alloca.h>
static __attribute__((noinline,noclone)) void aa(int *size) { void * volatile p = alloca(-*size); while (1) ; }
static void handler(int sig) { write(1, "signal delivered\n", 17); _exit(0); }
int main(void) { int size = -0x100; signal(SIGALRM, handler); alarm(1); aa(&size); }
If you compile it with optimizations, it will crash. The "aa" function has this disassembly:
000106a0 <aa>: 106a0: 08 03 02 41 copy r3,r1 106a4: 08 1e 02 43 copy sp,r3 106a8: 6f c1 00 80 stw,ma r1,40(sp) 106ac: 37 dc 3f c1 ldo -20(sp),ret0 106b0: 0c 7c 12 90 stw ret0,8(r3) 106b4: 0f 40 10 9c ldw 0(r26),ret0 ; ret0 = 0x00000000FFFFFF00 106b8: 97 9c 00 7e subi 3f,ret0,ret0 ; ret0 = 0xFFFFFFFF0000013F 106bc: d7 80 1c 1a depwi 0,31,6,ret0 ; ret0 = 0xFFFFFFFF00000100 106c0: 0b 9e 0a 1e add,l sp,ret0,sp ; sp = 0xFFFFFFFFxxxxxxxx 106c4: e8 1f 1f f7 b,l,n 106c4 <aa+0x24>,r0
This patch fixes the bug by truncating the "usp" variable to 32 bits.
Signed-off-by: Mikulas Patocka mpatocka@redhat.com Cc: stable@vger.kernel.org Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/parisc/kernel/signal.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -237,6 +237,12 @@ setup_rt_frame(struct ksignal *ksig, sig #endif usp = (regs->gr[30] & ~(0x01UL)); +#ifdef CONFIG_64BIT + if (is_compat_task()) { + /* The gcc alloca implementation leaves garbage in the upper 32 bits of sp */ + usp = (compat_uint_t)usp; + } +#endif /*FIXME: frame_size parameter is unused, remove it. */ frame = get_sigframe(&ksig->ka, usp, sizeof(*frame));
From: Masahiro Yamada masahiroy@kernel.org
commit 5f6e0fe01b6b33894cf6f61b359ab5a6d2b7674e upstream.
Commit 23243c1ace9f ("arch: use cross_compiling to check whether it is a cross build or not") broke 64-bit parisc builds on 32-bit parisc systems.
Helge mentioned: - 64-bit parisc userspace is not supported yet [1] - hppa gcc does not support "-m64" flag [2]
That means, parisc developers working on a 32-bit parisc machine need to use hppa64-linux-gnu-gcc (cross compiler) for building the 64-bit parisc kernel.
After the offending commit, gcc is used in such a case because both $(SRCARCH) and $(SUBARCH) are 'parisc', hence cross_compiling is unset.
A correct way is to introduce ARCH=parisc64 because building the 64-bit parisc kernel on a 32-bit parisc system is not exactly a native build, but rather a semi-cross build.
[1]: https://lore.kernel.org/linux-parisc/5dfd81eb-c8ca-b7f5-e80e-8632767c022d@gm... [2]: https://lore.kernel.org/linux-parisc/89515325-fc21-31da-d238-6f7a9abbf9a0@gm...
Fixes: 23243c1ace9f ("arch: use cross_compiling to check whether it is a cross build or not") Signed-off-by: Masahiro Yamada masahiroy@kernel.org Reported-by: Meelis Roos mroos@linux.ee Tested-by: Meelis Roos mroos@linux.ee Cc: stable@vger.kernel.org # v5.13+ Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- Makefile | 5 +++++ arch/parisc/Makefile | 6 +++--- scripts/subarch.include | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-)
--- a/Makefile +++ b/Makefile @@ -404,6 +404,11 @@ ifeq ($(ARCH),sparc64) SRCARCH := sparc endif
+# Additional ARCH settings for parisc +ifeq ($(ARCH),parisc64) + SRCARCH := parisc +endif + export cross_compiling := ifneq ($(SRCARCH),$(SUBARCH)) cross_compiling := 1 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -25,18 +25,18 @@ CHECKFLAGS += -D__hppa__=1 ifdef CONFIG_64BIT UTS_MACHINE := parisc64 CHECKFLAGS += -D__LP64__=1 -CC_ARCHES = hppa64 LD_BFD := elf64-hppa-linux else # 32-bit -CC_ARCHES = hppa hppa2.0 hppa1.1 LD_BFD := elf32-hppa-linux endif
# select defconfig based on actual architecture -ifeq ($(shell uname -m),parisc64) +ifeq ($(ARCH),parisc64) KBUILD_DEFCONFIG := generic-64bit_defconfig + CC_ARCHES := hppa64 else KBUILD_DEFCONFIG := generic-32bit_defconfig + CC_ARCHES := hppa hppa2.0 hppa1.1 endif
export LD_BFD --- a/scripts/subarch.include +++ b/scripts/subarch.include @@ -7,7 +7,7 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \ -e s/sun4u/sparc64/ \ -e s/arm.*/arm/ -e s/sa110/arm/ \ - -e s/s390x/s390/ -e s/parisc64/parisc/ \ + -e s/s390x/s390/ \ -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \ -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \ -e s/riscv.*/riscv/)
From: Petr Mladek pmladek@suse.com
commit 11e4b63abbe23872b45f325a7c6c8b7f9ff42cad upstream.
The standard printk() tries to flush the message to the console immediately. It tries to take the console lock. If the lock is already taken then the current owner is responsible for flushing even the new message.
There is a small race window between checking whether a new message is available and releasing the console lock. It is solved by re-checking the state after releasing the console lock. If the check is positive then console_unlock() tries to take the lock again and process the new message as well.
The commit 996e966640ddea7b535c ("printk: remove logbuf_lock") causes that console_seq is not longer read atomically. As a result, the re-check might be done with an inconsistent 64-bit index.
Solve it by using the last sequence number that has been checked under the console lock. In the worst case, it will take the lock again only to realized that the new message has already been proceed. But it was possible even before.
The variable next_seq is marked as __maybe_unused to call down compiler warning when CONFIG_PRINTK is not defined.
Fixes: commit 996e966640ddea7b535c ("printk: remove logbuf_lock") Reported-by: kernel test robot lkp@intel.com # unused next_seq warning Cc: stable@vger.kernel.org # 5.13 Signed-off-by: Petr Mladek pmladek@suse.com Acked-by: Sergey Senozhatsky senozhatsky@chromium.org Reviewed-by: John Ogness john.ogness@linutronix.de Link: https://lore.kernel.org/r/20210702150657.26760-1-pmladek@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/printk/printk.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
--- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2545,6 +2545,7 @@ void console_unlock(void) bool do_cond_resched, retry; struct printk_info info; struct printk_record r; + u64 __maybe_unused next_seq;
if (console_suspended) { up_console_sem(); @@ -2654,8 +2655,10 @@ skip: cond_resched(); }
- console_locked = 0; + /* Get consistent value of the next-to-be-used sequence number. */ + next_seq = console_seq;
+ console_locked = 0; up_console_sem();
/* @@ -2664,7 +2667,7 @@ skip: * there's a new owner and the console_unlock() from them will do the * flush, no worries. */ - retry = prb_read_valid(prb, console_seq, NULL); + retry = prb_read_valid(prb, next_seq, NULL); printk_safe_exit_irqrestore(flags);
if (retry && console_trylock())
From: chenying chenying.kernel@bytedance.com
commit 52d5a0c6bd8a89f460243ed937856354f8f253a3 upstream.
If function ovl_instantiate() returns an error, ovl_cleanup will be called and try to remove newdentry from wdir, but the newdentry has been moved to udir at this time. This will causes BUG_ON(victim->d_parent->d_inode != dir) in fs/namei.c:may_delete.
Signed-off-by: chenying chenying.kernel@bytedance.com Fixes: 01b39dcc9568 ("ovl: use inode_insert5() to hash a newly created inode") Link: https://lore.kernel.org/linux-unionfs/e6496a94-a161-dc04-c38a-d2544633acb4@b... Cc: stable@vger.kernel.org # v4.18 Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/overlayfs/dir.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -542,8 +542,10 @@ static int ovl_create_over_whiteout(stru goto out_cleanup; } err = ovl_instantiate(dentry, inode, newdentry, hardlink); - if (err) - goto out_cleanup; + if (err) { + ovl_cleanup(udir, newdentry); + dput(newdentry); + } out_dput: dput(upper); out_unlock:
From: Maciej W. Rozycki macro@orcam.me.uk
commit 44d01fc86d952f5a8b8b32bdb4841504d5833d95 upstream.
Update BusLogic driver's messaging system to use pr_cont() for continuation lines, bringing messy output:
pci 0000:00:13.0: PCI->APIC IRQ transform: INT A -> IRQ 17 scsi: ***** BusLogic SCSI Driver Version 2.1.17 of 12 September 2013 ***** scsi: Copyright 1995-1998 by Leonard N. Zubkoff lnz@dandelion.com scsi0: Configuring BusLogic Model BT-958 PCI Wide Ultra SCSI Host Adapter scsi0: Firmware Version: 5.07B, I/O Address: 0x7000, IRQ Channel: 17/Level scsi0: PCI Bus: 0, Device: 19, Address: 0xE0012000, Host Adapter SCSI ID: 7 scsi0: Parity Checking: Enabled, Extended Translation: Enabled scsi0: Synchronous Negotiation: Ultra, Wide Negotiation: Enabled scsi0: Disconnect/Reconnect: Enabled, Tagged Queuing: Enabled scsi0: Scatter/Gather Limit: 128 of 8192 segments, Mailboxes: 211 scsi0: Driver Queue Depth: 211, Host Adapter Queue Depth: 192 scsi0: Tagged Queue Depth: Automatic , Untagged Queue Depth: 3 scsi0: SCSI Bus Termination: Both Enabled , SCAM: Disabled
scsi0: *** BusLogic BT-958 Initialized Successfully *** scsi host0: BusLogic BT-958
back to order:
pci 0000:00:13.0: PCI->APIC IRQ transform: INT A -> IRQ 17 scsi: ***** BusLogic SCSI Driver Version 2.1.17 of 12 September 2013 ***** scsi: Copyright 1995-1998 by Leonard N. Zubkoff lnz@dandelion.com scsi0: Configuring BusLogic Model BT-958 PCI Wide Ultra SCSI Host Adapter scsi0: Firmware Version: 5.07B, I/O Address: 0x7000, IRQ Channel: 17/Level scsi0: PCI Bus: 0, Device: 19, Address: 0xE0012000, Host Adapter SCSI ID: 7 scsi0: Parity Checking: Enabled, Extended Translation: Enabled scsi0: Synchronous Negotiation: Ultra, Wide Negotiation: Enabled scsi0: Disconnect/Reconnect: Enabled, Tagged Queuing: Enabled scsi0: Scatter/Gather Limit: 128 of 8192 segments, Mailboxes: 211 scsi0: Driver Queue Depth: 211, Host Adapter Queue Depth: 192 scsi0: Tagged Queue Depth: Automatic, Untagged Queue Depth: 3 scsi0: SCSI Bus Termination: Both Enabled, SCAM: Disabled scsi0: *** BusLogic BT-958 Initialized Successfully *** scsi host0: BusLogic BT-958
Also diagnostic output such as with the BusLogic=TraceConfiguration parameter is affected and becomes vertical and therefore hard to read. This has now been corrected, e.g.:
pci 0000:00:13.0: PCI->APIC IRQ transform: INT A -> IRQ 17 blogic_cmd(86) Status = 30: 4 ==> 4: FF 05 93 00 blogic_cmd(95) Status = 28: (Modify I/O Address) blogic_cmd(91) Status = 30: 1 ==> 1: 01 blogic_cmd(04) Status = 30: 4 ==> 4: 41 41 35 30 blogic_cmd(8D) Status = 30: 14 ==> 14: 45 DC 00 20 00 00 00 00 00 40 30 37 42 1D scsi: ***** BusLogic SCSI Driver Version 2.1.17 of 12 September 2013 ***** scsi: Copyright 1995-1998 by Leonard N. Zubkoff lnz@dandelion.com blogic_cmd(04) Status = 30: 4 ==> 4: 41 41 35 30 blogic_cmd(0B) Status = 30: 3 ==> 3: 00 08 07 blogic_cmd(0D) Status = 30: 34 ==> 34: 03 01 07 04 00 00 00 00 00 00 00 00 00 00 00 00 FF 42 44 46 FF 00 00 00 00 00 00 00 00 00 FF 00 FF 00 blogic_cmd(8D) Status = 30: 14 ==> 14: 45 DC 00 20 00 00 00 00 00 40 30 37 42 1D blogic_cmd(84) Status = 30: 1 ==> 1: 37 blogic_cmd(8B) Status = 30: 5 ==> 5: 39 35 38 20 20 blogic_cmd(85) Status = 30: 1 ==> 1: 42 blogic_cmd(86) Status = 30: 4 ==> 4: FF 05 93 00 blogic_cmd(91) Status = 30: 64 ==> 64: 41 46 3E 20 39 35 38 20 20 00 C4 00 04 01 07 2F 07 04 35 FF FF FF FF FF FF FF FF FF FF 01 00 FE FF 08 FF FF 00 00 00 00 00 00 00 01 00 01 00 00 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 FC scsi0: Configuring BusLogic Model BT-958 PCI Wide Ultra SCSI Host Adapter
etc.
Link: https://lore.kernel.org/r/alpine.DEB.2.21.2104201940430.44318@angie.orcam.me... Fixes: 4bcc595ccd80 ("printk: reinstate KERN_CONT for printing continuation lines") Cc: stable@vger.kernel.org # v4.9+ Acked-by: Khalid Aziz khalid@gonehiking.org Signed-off-by: Maciej W. Rozycki macro@orcam.me.uk Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/BusLogic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -3451,7 +3451,7 @@ static void blogic_msg(enum blogic_msgle if (buf[0] != '\n' || len > 1) printk("%sscsi%d: %s", blogic_msglevelmap[msglevel], adapter->host_no, buf); } else - printk("%s", buf); + pr_cont("%s", buf); } else { if (begin) { if (adapter != NULL && adapter->adapter_initd) @@ -3459,7 +3459,7 @@ static void blogic_msg(enum blogic_msgle else printk("%s%s", blogic_msglevelmap[msglevel], buf); } else - printk("%s", buf); + pr_cont("%s", buf); } begin = (buf[len - 1] == '\n'); }
From: Saurav Kashyap skashyap@marvell.com
commit 62e0dec59c1e139dab55aff5aa442adc97804271 upstream.
Avoid allocating firmware dump and only allocate a single queue for a kexec kernel.
Link: https://lore.kernel.org/r/20210810043720.1137-12-njavali@marvell.com Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Saurav Kashyap skashyap@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/qla2xxx/qla_os.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -14,6 +14,7 @@ #include <linux/slab.h> #include <linux/blk-mq-pci.h> #include <linux/refcount.h> +#include <linux/crash_dump.h>
#include <scsi/scsi_tcq.h> #include <scsi/scsicam.h> @@ -2818,6 +2819,11 @@ qla2x00_probe_one(struct pci_dev *pdev, return ret; }
+ if (is_kdump_kernel()) { + ql2xmqsupport = 0; + ql2xallocfwdump = 0; + } + /* This may fail but that's ok */ pci_enable_pcie_error_reporting(pdev);
From: Saurav Kashyap skashyap@marvell.com
commit c8fadf019964d0eb1da410ba8b629494d3339db9 upstream.
The first invocation of function find_first_zero_bit will return 0 and queue_id gets set to 0.
An index of queue_pair_map also gets set to 0.
qpair_id = find_first_zero_bit(ha->qpair_qid_map, ha->max_qpairs);
set_bit(qpair_id, ha->qpair_qid_map); ha->queue_pair_map[qpair_id] = qpair;
In the alloc_queue callback driver checks the map, if queue is already allocated:
ha->queue_pair_map[qidx]
This works fine as long as max_qpairs is greater than nvme_max_hw_queues(8) since the size of the queue_pair_map is equal to max_qpair. In case nr_cpus is less than 8, max_qpairs is less than 8. This creates wrong value returned as qpair.
[ 1572.353669] qla2xxx [0000:24:00.3]-2121:6: Returning existing qpair of 4e00000000000000 for idx=2 [ 1572.354458] general protection fault: 0000 [#1] SMP PTI [ 1572.354461] CPU: 1 PID: 44 Comm: kworker/1:1H Kdump: loaded Tainted: G IOE --------- - - 4.18.0-304.el8.x86_64 #1 [ 1572.354462] Hardware name: HP ProLiant DL380p Gen8, BIOS P70 03/01/2013 [ 1572.354467] Workqueue: kblockd blk_mq_run_work_fn [ 1572.354485] RIP: 0010:qla_nvme_post_cmd+0x92/0x760 [qla2xxx] [ 1572.354486] Code: 84 24 5c 01 00 00 00 00 b8 0a 74 1e 66 83 79 48 00 0f 85 a8 03 00 00 48 8b 44 24 08 48 89 ee 4c 89 e7 8b 50 24 e8 5e 8e 00 00 <f0> 41 ff 47 04 0f ae f0 41 f6 47 24 04 74 19 f0 41 ff 4f 04 b8 f0 [ 1572.354487] RSP: 0018:ffff9c81c645fc90 EFLAGS: 00010246 [ 1572.354489] RAX: 0000000000000001 RBX: ffff8ea3e5070138 RCX: 0000000000000001 [ 1572.354490] RDX: 0000000000000001 RSI: 0000000000000001 RDI: ffff8ea4c866b800 [ 1572.354491] RBP: ffff8ea4c866b800 R08: 0000000000005010 R09: ffff8ea4c866b800 [ 1572.354492] R10: 0000000000000001 R11: 000000069d1ca3ff R12: ffff8ea4bc460000 [ 1572.354493] R13: ffff8ea3e50702b0 R14: ffff8ea4c4c16a58 R15: 4e00000000000000 [ 1572.354494] FS: 0000000000000000(0000) GS:ffff8ea4dfd00000(0000) knlGS:0000000000000000 [ 1572.354495] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1572.354496] CR2: 000055884504fa58 CR3: 00000005a1410001 CR4: 00000000000606e0 [ 1572.354497] Call Trace: [ 1572.354503] ? check_preempt_curr+0x62/0x90 [ 1572.354506] ? dma_direct_map_sg+0x72/0x1f0 [ 1572.354509] ? nvme_fc_start_fcp_op.part.32+0x175/0x460 [nvme_fc] [ 1572.354511] ? blk_mq_dispatch_rq_list+0x11c/0x730 [ 1572.354515] ? __switch_to_asm+0x35/0x70 [ 1572.354516] ? __switch_to_asm+0x41/0x70 [ 1572.354518] ? __switch_to_asm+0x35/0x70 [ 1572.354519] ? __switch_to_asm+0x41/0x70 [ 1572.354521] ? __switch_to_asm+0x35/0x70 [ 1572.354522] ? __switch_to_asm+0x41/0x70 [ 1572.354523] ? __switch_to_asm+0x35/0x70 [ 1572.354525] ? entry_SYSCALL_64_after_hwframe+0xb9/0xca [ 1572.354527] ? __switch_to_asm+0x41/0x70 [ 1572.354529] ? __blk_mq_sched_dispatch_requests+0xc6/0x170 [ 1572.354531] ? blk_mq_sched_dispatch_requests+0x30/0x60 [ 1572.354532] ? __blk_mq_run_hw_queue+0x51/0xd0 [ 1572.354535] ? process_one_work+0x1a7/0x360 [ 1572.354537] ? create_worker+0x1a0/0x1a0 [ 1572.354538] ? worker_thread+0x30/0x390 [ 1572.354540] ? create_worker+0x1a0/0x1a0 [ 1572.354541] ? kthread+0x116/0x130 [ 1572.354543] ? kthread_flush_work_fn+0x10/0x10 [ 1572.354545] ? ret_from_fork+0x35/0x40
Fix is to use index 0 for admin and first IO queue.
Link: https://lore.kernel.org/r/20210810043720.1137-14-njavali@marvell.com Fixes: e84067d74301 ("scsi: qla2xxx: Add FC-NVMe F/W initialization and transport registration") Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Saurav Kashyap skashyap@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/qla2xxx/qla_nvme.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_nvme.c +++ b/drivers/scsi/qla2xxx/qla_nvme.c @@ -91,8 +91,9 @@ static int qla_nvme_alloc_queue(struct n struct qla_hw_data *ha; struct qla_qpair *qpair;
- if (!qidx) - qidx++; + /* Map admin queue and 1st IO queue to index 0 */ + if (qidx) + qidx--;
vha = (struct scsi_qla_host *)lport->private; ha = vha->hw;
From: Evgeny Novikov novikov@ispras.ru
commit 0792ec82175ec45a0f45af6e0f2d3cb49c527cd4 upstream.
ebu_nand_probe() did not invoke ebu_dma_cleanup() and clk_disable_unprepare() on some error handling paths. The patch fixes that.
Found by Linux Driver Verification project (linuxtesting.org).
Fixes: 0b1039f016e8 ("mtd: rawnand: Add NAND controller support on Intel LGM SoC") Signed-off-by: Evgeny Novikov novikov@ispras.ru Co-developed-by: Kirill Shilimanov kirill.shilimanov@huawei.com Signed-off-by: Kirill Shilimanov kirill.shilimanov@huawei.com Co-developed-by: Anton Vasilyev vasilyev@ispras.ru Signed-off-by: Anton Vasilyev vasilyev@ispras.ru Cc: stable@vger.kernel.org Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20210817092930.23040-1-novikov@ispras.ru Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/nand/raw/intel-nand-controller.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-)
--- a/drivers/mtd/nand/raw/intel-nand-controller.c +++ b/drivers/mtd/nand/raw/intel-nand-controller.c @@ -631,19 +631,26 @@ static int ebu_nand_probe(struct platfor ebu_host->clk_rate = clk_get_rate(ebu_host->clk);
ebu_host->dma_tx = dma_request_chan(dev, "tx"); - if (IS_ERR(ebu_host->dma_tx)) - return dev_err_probe(dev, PTR_ERR(ebu_host->dma_tx), - "failed to request DMA tx chan!.\n"); + if (IS_ERR(ebu_host->dma_tx)) { + ret = dev_err_probe(dev, PTR_ERR(ebu_host->dma_tx), + "failed to request DMA tx chan!.\n"); + goto err_disable_unprepare_clk; + }
ebu_host->dma_rx = dma_request_chan(dev, "rx"); - if (IS_ERR(ebu_host->dma_rx)) - return dev_err_probe(dev, PTR_ERR(ebu_host->dma_rx), - "failed to request DMA rx chan!.\n"); + if (IS_ERR(ebu_host->dma_rx)) { + ret = dev_err_probe(dev, PTR_ERR(ebu_host->dma_rx), + "failed to request DMA rx chan!.\n"); + ebu_host->dma_rx = NULL; + goto err_cleanup_dma; + }
resname = devm_kasprintf(dev, GFP_KERNEL, "addr_sel%d", cs); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resname); - if (!res) - return -EINVAL; + if (!res) { + ret = -EINVAL; + goto err_cleanup_dma; + } ebu_host->cs[cs].addr_sel = res->start; writel(ebu_host->cs[cs].addr_sel | EBU_ADDR_MASK(5) | EBU_ADDR_SEL_REGEN, ebu_host->ebu + EBU_ADDR_SEL(cs)); @@ -653,7 +660,8 @@ static int ebu_nand_probe(struct platfor mtd = nand_to_mtd(&ebu_host->chip); if (!mtd->name) { dev_err(ebu_host->dev, "NAND label property is mandatory\n"); - return -EINVAL; + ret = -EINVAL; + goto err_cleanup_dma; }
mtd->dev.parent = dev; @@ -681,6 +689,7 @@ err_clean_nand: nand_cleanup(&ebu_host->chip); err_cleanup_dma: ebu_dma_cleanup(ebu_host); +err_disable_unprepare_clk: clk_disable_unprepare(ebu_host->clk);
return ret;
From: Pratik R. Sampat psampat@linux.ibm.com
commit f34ee9cb2c5ac5af426fee6fa4591a34d187e696 upstream.
In the numa=off kernel command-line configuration init_chip_info() loops around the number of chips and attempts to copy the cpumask of that node which is NULL for all iterations after the first chip.
Hence, store the cpu mask for each chip instead of derving cpumask from node while populating the "chips" struct array and copy that to the chips[i].mask
Fixes: 053819e0bf84 ("cpufreq: powernv: Handle throttling due to Pmax capping at chip level") Cc: stable@vger.kernel.org # v4.3+ Reported-by: Shirisha Ganta shirisha.ganta1@ibm.com Signed-off-by: Pratik R. Sampat psampat@linux.ibm.com Reviewed-by: Gautham R. Shenoy ego@linux.vnet.ibm.com [mpe: Rename goto label to out_free_chip_cpu_mask] Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20210728120500.87549-2-psampat@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/cpufreq/powernv-cpufreq.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
--- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c @@ -36,6 +36,7 @@ #define MAX_PSTATE_SHIFT 32 #define LPSTATE_SHIFT 48 #define GPSTATE_SHIFT 56 +#define MAX_NR_CHIPS 32
#define MAX_RAMP_DOWN_TIME 5120 /* @@ -1051,12 +1052,20 @@ static int init_chip_info(void) unsigned int *chip; unsigned int cpu, i; unsigned int prev_chip_id = UINT_MAX; + cpumask_t *chip_cpu_mask; int ret = 0;
chip = kcalloc(num_possible_cpus(), sizeof(*chip), GFP_KERNEL); if (!chip) return -ENOMEM;
+ /* Allocate a chip cpu mask large enough to fit mask for all chips */ + chip_cpu_mask = kcalloc(MAX_NR_CHIPS, sizeof(cpumask_t), GFP_KERNEL); + if (!chip_cpu_mask) { + ret = -ENOMEM; + goto free_and_return; + } + for_each_possible_cpu(cpu) { unsigned int id = cpu_to_chip_id(cpu);
@@ -1064,22 +1073,25 @@ static int init_chip_info(void) prev_chip_id = id; chip[nr_chips++] = id; } + cpumask_set_cpu(cpu, &chip_cpu_mask[nr_chips-1]); }
chips = kcalloc(nr_chips, sizeof(struct chip), GFP_KERNEL); if (!chips) { ret = -ENOMEM; - goto free_and_return; + goto out_free_chip_cpu_mask; }
for (i = 0; i < nr_chips; i++) { chips[i].id = chip[i]; - cpumask_copy(&chips[i].mask, cpumask_of_node(chip[i])); + cpumask_copy(&chips[i].mask, &chip_cpu_mask[i]); INIT_WORK(&chips[i].throttle, powernv_cpufreq_work_fn); for_each_cpu(cpu, &chips[i].mask) per_cpu(chip_info, cpu) = &chips[i]; }
+out_free_chip_cpu_mask: + kfree(chip_cpu_mask); free_and_return: kfree(chip); return ret;
From: Halil Pasic pasic@linux.ibm.com
commit 93ebb6828723b8aef114415c4dc3518342f7dcad upstream.
Since commit 903cd0f315fe ("swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing") if code sets swiotlb_force it needs to do so before the swiotlb is initialised. Otherwise io_tlb_default_mem->force_bounce will not get set to true, and devices that use (the default) swiotlb will not bounce despite switolb_force having the value of SWIOTLB_FORCE.
Let us restore swiotlb functionality for PV by fulfilling this new requirement.
This change addresses what turned out to be a fragility in commit 64e1f0c531d1 ("s390/mm: force swiotlb for protected virtualization"), which ain't exactly broken in its original context, but could give us some more headache if people backport the broken change and forget this fix.
Signed-off-by: Halil Pasic pasic@linux.ibm.com Tested-by: Christian Borntraeger borntraeger@de.ibm.com Reviewed-by: Christian Borntraeger borntraeger@de.ibm.com Fixes: 903cd0f315fe ("swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing") Fixes: 64e1f0c531d1 ("s390/mm: force swiotlb for protected virtualization") Cc: stable@vger.kernel.org #5.3+ Signed-off-by: Konrad Rzeszutek Wilk konrad@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/s390/mm/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -186,9 +186,9 @@ static void pv_init(void) return;
/* make sure bounce buffers are shared */ + swiotlb_force = SWIOTLB_FORCE; swiotlb_init(1); swiotlb_update_mem_attributes(); - swiotlb_force = SWIOTLB_FORCE; }
void __init mem_init(void)
From: Sven Schnelle svens@linux.ibm.com
commit a052096bdd6809eeab809202726634d1ac975aa1 upstream.
The cpu hotplug notifiers are called without updating the core/thread masks when a new CPU is added. This causes problems with code setting up data structures in a cpu hotplug notifier, and relying on that later in normal code.
This caused a crash in the new core scheduling code (SCHED_CORE), where rq->core was set up in a notifier depending on cpu masks.
To fix this, add a cpu_setup_mask which is used in update_cpu_masks() instead of the cpu_online_mask to determine whether the cpu masks should be set for a certain cpu. Also move update_cpu_masks() to update the masks before calling notify_cpu_starting() so that the notifiers are seeing the updated masks.
Signed-off-by: Sven Schnelle svens@linux.ibm.com Cc: stable@vger.kernel.org [hca@linux.ibm.com: get rid of cpu_online_mask handling] Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/s390/include/asm/smp.h | 1 + arch/s390/kernel/smp.c | 9 +++++++-- arch/s390/kernel/topology.c | 13 +++++++------ 3 files changed, 15 insertions(+), 8 deletions(-)
--- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h @@ -18,6 +18,7 @@ extern struct mutex smp_cpu_state_mutex; extern unsigned int smp_cpu_mt_shift; extern unsigned int smp_cpu_mtid; extern __vector128 __initdata boot_cpu_vector_save_area[__NUM_VXRS]; +extern cpumask_t cpu_setup_mask;
extern int __cpu_up(unsigned int cpu, struct task_struct *tidle);
--- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -96,6 +96,7 @@ __vector128 __initdata boot_cpu_vector_s #endif
static unsigned int smp_max_threads __initdata = -1U; +cpumask_t cpu_setup_mask;
static int __init early_nosmt(char *s) { @@ -883,13 +884,14 @@ static void smp_init_secondary(void) vtime_init(); vdso_getcpu_init(); pfault_init(); + cpumask_set_cpu(cpu, &cpu_setup_mask); + update_cpu_masks(); notify_cpu_starting(cpu); if (topology_cpu_dedicated(cpu)) set_cpu_flag(CIF_DEDICATED_CPU); else clear_cpu_flag(CIF_DEDICATED_CPU); set_cpu_online(cpu, true); - update_cpu_masks(); inc_irq_stat(CPU_RST); local_irq_enable(); cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); @@ -945,10 +947,13 @@ early_param("possible_cpus", _setup_poss int __cpu_disable(void) { unsigned long cregs[16]; + int cpu;
/* Handle possible pending IPIs */ smp_handle_ext_call(); - set_cpu_online(smp_processor_id(), false); + cpu = smp_processor_id(); + set_cpu_online(cpu, false); + cpumask_clear_cpu(cpu, &cpu_setup_mask); update_cpu_masks(); /* Disable pseudo page faults on this cpu. */ pfault_fini(); --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@ -67,7 +67,7 @@ static void cpu_group_map(cpumask_t *dst static cpumask_t mask;
cpumask_clear(&mask); - if (!cpu_online(cpu)) + if (!cpumask_test_cpu(cpu, &cpu_setup_mask)) goto out; cpumask_set_cpu(cpu, &mask); switch (topology_mode) { @@ -88,7 +88,7 @@ static void cpu_group_map(cpumask_t *dst case TOPOLOGY_MODE_SINGLE: break; } - cpumask_and(&mask, &mask, cpu_online_mask); + cpumask_and(&mask, &mask, &cpu_setup_mask); out: cpumask_copy(dst, &mask); } @@ -99,16 +99,16 @@ static void cpu_thread_map(cpumask_t *ds int i;
cpumask_clear(&mask); - if (!cpu_online(cpu)) + if (!cpumask_test_cpu(cpu, &cpu_setup_mask)) goto out; cpumask_set_cpu(cpu, &mask); if (topology_mode != TOPOLOGY_MODE_HW) goto out; cpu -= cpu % (smp_cpu_mtid + 1); - for (i = 0; i <= smp_cpu_mtid; i++) - if (cpu_present(cpu + i)) + for (i = 0; i <= smp_cpu_mtid; i++) { + if (cpumask_test_cpu(cpu + i, &cpu_setup_mask)) cpumask_set_cpu(cpu + i, &mask); - cpumask_and(&mask, &mask, cpu_online_mask); + } out: cpumask_copy(dst, &mask); } @@ -569,6 +569,7 @@ void __init topology_init_early(void) alloc_masks(info, &book_info, 2); alloc_masks(info, &drawer_info, 3); out: + cpumask_set_cpu(0, &cpu_setup_mask); __arch_update_cpu_topology(); __arch_update_dedicated_flag(NULL); }
From: Mike Kravetz mike.kravetz@oracle.com
commit 09a26e832705fdb7a9484495b71a05e0bbc65207 upstream.
Guillaume Morin reported hitting the following WARNING followed by GPF or NULL pointer deference either in cgroups_destroy or in the kill_css path.:
percpu ref (css_release) <= 0 (-1) after switching to atomic WARNING: CPU: 23 PID: 130 at lib/percpu-refcount.c:196 percpu_ref_switch_to_atomic_rcu+0x127/0x130 CPU: 23 PID: 130 Comm: ksoftirqd/23 Kdump: loaded Tainted: G O 5.10.60 #1 RIP: 0010:percpu_ref_switch_to_atomic_rcu+0x127/0x130 Call Trace: rcu_core+0x30f/0x530 rcu_core_si+0xe/0x10 __do_softirq+0x103/0x2a2 run_ksoftirqd+0x2b/0x40 smpboot_thread_fn+0x11a/0x170 kthread+0x10a/0x140 ret_from_fork+0x22/0x30
Upon further examination, it was discovered that the css structure was associated with hugetlb reservations.
For private hugetlb mappings the vma points to a reserve map that contains a pointer to the css. At mmap time, reservations are set up and a reference to the css is taken. This reference is dropped in the vma close operation; hugetlb_vm_op_close. However, if a vma is split no additional reference to the css is taken yet hugetlb_vm_op_close will be called twice for the split vma resulting in an underflow.
Fix by taking another reference in hugetlb_vm_op_open. Note that the reference is only taken for the owner of the reserve map. In the more common fork case, the pointer to the reserve map is cleared for non-owning vmas.
Link: https://lkml.kernel.org/r/20210830215015.155224-1-mike.kravetz@oracle.com Fixes: e9fe92ae0cd2 ("hugetlb_cgroup: add reservation accounting for private mappings") Signed-off-by: Mike Kravetz mike.kravetz@oracle.com Reported-by: Guillaume Morin guillaume@morinfr.org Suggested-by: Guillaume Morin guillaume@morinfr.org Tested-by: Guillaume Morin guillaume@morinfr.org Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/hugetlb_cgroup.h | 12 ++++++++++++ mm/hugetlb.c | 4 +++- 2 files changed, 15 insertions(+), 1 deletion(-)
--- a/include/linux/hugetlb_cgroup.h +++ b/include/linux/hugetlb_cgroup.h @@ -118,6 +118,13 @@ static inline void hugetlb_cgroup_put_rs css_put(&h_cg->css); }
+static inline void resv_map_dup_hugetlb_cgroup_uncharge_info( + struct resv_map *resv_map) +{ + if (resv_map->css) + css_get(resv_map->css); +} + extern int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages, struct hugetlb_cgroup **ptr); extern int hugetlb_cgroup_charge_cgroup_rsvd(int idx, unsigned long nr_pages, @@ -196,6 +203,11 @@ static inline void hugetlb_cgroup_put_rs { }
+static inline void resv_map_dup_hugetlb_cgroup_uncharge_info( + struct resv_map *resv_map) +{ +} + static inline int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages, struct hugetlb_cgroup **ptr) { --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -3840,8 +3840,10 @@ static void hugetlb_vm_op_open(struct vm * after this open call completes. It is therefore safe to take a * new reference here without additional locking. */ - if (resv && is_vma_resv_set(vma, HPAGE_RESV_OWNER)) + if (resv && is_vma_resv_set(vma, HPAGE_RESV_OWNER)) { + resv_map_dup_hugetlb_cgroup_uncharge_info(resv); kref_get(&resv->refs); + } }
static void hugetlb_vm_op_close(struct vm_area_struct *vma)
From: David Hildenbrand david@redhat.com
commit 7cf209ba8a86410939a24cb1aeb279479a7e0ca6 upstream.
Patch series "mm/memory_hotplug: preparatory patches for new online policy and memory"
These are all cleanups and one fix previously sent as part of [1]: [PATCH v1 00/12] mm/memory_hotplug: "auto-movable" online policy and memory groups.
These patches make sense even without the other series, therefore I pulled them out to make the other series easier to digest.
[1] https://lkml.kernel.org/r/20210607195430.48228-1-david@redhat.com
This patch (of 4):
Checkpatch complained on a follow-up patch that we are using "unsigned" here, which defaults to "unsigned int" and checkpatch is correct.
As we will search for a fitting zone using the wrong pfn, we might end up onlining memory to one of the special kernel zones, such as ZONE_DMA, which can end badly as the onlined memory does not satisfy properties of these zones.
Use "unsigned long" instead, just as we do in other places when handling PFNs. This can bite us once we have physical addresses in the range of multiple TB.
Link: https://lkml.kernel.org/r/20210712124052.26491-2-david@redhat.com Fixes: e5e689302633 ("mm, memory_hotplug: display allowed zones in the preferred ordering") Signed-off-by: David Hildenbrand david@redhat.com Reviewed-by: Pankaj Gupta pankaj.gupta@ionos.com Reviewed-by: Muchun Song songmuchun@bytedance.com Reviewed-by: Oscar Salvador osalvador@suse.de Cc: David Hildenbrand david@redhat.com Cc: Vitaly Kuznetsov vkuznets@redhat.com Cc: "Michael S. Tsirkin" mst@redhat.com Cc: Jason Wang jasowang@redhat.com Cc: Pankaj Gupta pankaj.gupta.linux@gmail.com Cc: Wei Yang richard.weiyang@linux.alibaba.com Cc: Michal Hocko mhocko@kernel.org Cc: Dan Williams dan.j.williams@intel.com Cc: Anshuman Khandual anshuman.khandual@arm.com Cc: Dave Hansen dave.hansen@linux.intel.com Cc: Vlastimil Babka vbabka@suse.cz Cc: Mike Rapoport rppt@kernel.org Cc: "Rafael J. Wysocki" rjw@rjwysocki.net Cc: Len Brown lenb@kernel.org Cc: Pavel Tatashin pasha.tatashin@soleen.com Cc: Heiko Carstens hca@linux.ibm.com Cc: Michael Ellerman mpe@ellerman.id.au Cc: Catalin Marinas catalin.marinas@arm.com Cc: virtualization@lists.linux-foundation.org Cc: Andy Lutomirski luto@kernel.org Cc: "Aneesh Kumar K.V" aneesh.kumar@linux.ibm.com Cc: Anton Blanchard anton@ozlabs.org Cc: Ard Biesheuvel ardb@kernel.org Cc: Baoquan He bhe@redhat.com Cc: Benjamin Herrenschmidt benh@kernel.crashing.org Cc: Borislav Petkov bp@alien8.de Cc: Christian Borntraeger borntraeger@de.ibm.com Cc: Christophe Leroy christophe.leroy@c-s.fr Cc: Dave Jiang dave.jiang@intel.com Cc: "H. Peter Anvin" hpa@zytor.com Cc: Ingo Molnar mingo@redhat.com Cc: Jia He justin.he@arm.com Cc: Joe Perches joe@perches.com Cc: Kefeng Wang wangkefeng.wang@huawei.com Cc: Laurent Dufour ldufour@linux.ibm.com Cc: Michel Lespinasse michel@lespinasse.org Cc: Nathan Lynch nathanl@linux.ibm.com Cc: Nicholas Piggin npiggin@gmail.com Cc: Paul Mackerras paulus@samba.org Cc: Peter Zijlstra peterz@infradead.org Cc: Pierre Morel pmorel@linux.ibm.com Cc: "Rafael J. Wysocki" rafael.j.wysocki@intel.com Cc: Rich Felker dalias@libc.org Cc: Scott Cheloha cheloha@linux.ibm.com Cc: Sergei Trofimovich slyfox@gentoo.org Cc: Thiago Jung Bauermann bauerman@linux.ibm.com Cc: Thomas Gleixner tglx@linutronix.de Cc: Vasily Gorbik gor@linux.ibm.com Cc: Vishal Verma vishal.l.verma@intel.com Cc: Will Deacon will@kernel.org Cc: Yoshinori Sato ysato@users.sourceforge.jp Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/memory_hotplug.h | 4 ++-- mm/memory_hotplug.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
--- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -366,8 +366,8 @@ extern void sparse_remove_section(struct unsigned long map_offset, struct vmem_altmap *altmap); extern struct page *sparse_decode_mem_map(unsigned long coded_mem_map, unsigned long pnum); -extern struct zone *zone_for_pfn_range(int online_type, int nid, unsigned start_pfn, - unsigned long nr_pages); +extern struct zone *zone_for_pfn_range(int online_type, int nid, + unsigned long start_pfn, unsigned long nr_pages); extern int arch_create_linear_mapping(int nid, u64 start, u64 size, struct mhp_params *params); void arch_remove_linear_mapping(u64 start, u64 size); --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -834,8 +834,8 @@ static inline struct zone *default_zone_ return movable_node_enabled ? movable_zone : kernel_zone; }
-struct zone *zone_for_pfn_range(int online_type, int nid, unsigned start_pfn, - unsigned long nr_pages) +struct zone *zone_for_pfn_range(int online_type, int nid, + unsigned long start_pfn, unsigned long nr_pages) { if (online_type == MMOP_ONLINE_KERNEL) return default_kernel_zone_for_pfn(nid, start_pfn, nr_pages);
From: Li Zhijian lizhijian@cn.fujitsu.com
commit 4b42fb213678d2b6a9eeea92a9be200f23e49583 upstream.
Previously, we noticed the one rpma example was failed[1] since commit 36f30e486dce ("IB/core: Improve ODP to use hmm_range_fault()"), where it will use ODP feature to do RDMA WRITE between fsdax files.
After digging into the code, we found hmm_vma_handle_pte() will still return EFAULT even though all the its requesting flags has been fulfilled. That's because a DAX page will be marked as (_PAGE_SPECIAL | PAGE_DEVMAP) by pte_mkdevmap().
Link: https://github.com/pmem/rpma/issues/1142 [1] Link: https://lkml.kernel.org/r/20210830094232.203029-1-lizhijian@cn.fujitsu.com Fixes: 405506274922 ("mm/hmm: add missing call to hmm_pte_need_fault in HMM_PFN_SPECIAL handling") Signed-off-by: Li Zhijian lizhijian@cn.fujitsu.com Reviewed-by: Christoph Hellwig hch@lst.de Reviewed-by: Jason Gunthorpe jgg@nvidia.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/hmm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/mm/hmm.c +++ b/mm/hmm.c @@ -291,10 +291,13 @@ static int hmm_vma_handle_pte(struct mm_ goto fault;
/* + * Bypass devmap pte such as DAX page when all pfn requested + * flags(pfn_req_flags) are fulfilled. * Since each architecture defines a struct page for the zero page, just * fall through and treat it like a normal page. */ - if (pte_special(pte) && !is_zero_pfn(pte_pfn(pte))) { + if (pte_special(pte) && !pte_devmap(pte) && + !is_zero_pfn(pte_pfn(pte))) { if (hmm_pte_need_fault(hmm_vma_walk, pfn_req_flags, 0)) { pte_unmap(ptep); return -EFAULT;
From: Liu Zixian liuzixian4@huawei.com
commit 13db8c50477d83ad3e3b9b0ae247e5cd833a7ae4 upstream.
After fork, the child process will get incorrect (2x) hugetlb_usage. If a process uses 5 2MB hugetlb pages in an anonymous mapping,
HugetlbPages: 10240 kB
and then forks, the child will show,
HugetlbPages: 20480 kB
The reason for double the amount is because hugetlb_usage will be copied from the parent and then increased when we copy page tables from parent to child. Child will have 2x actual usage.
Fix this by adding hugetlb_count_init in mm_init.
Link: https://lkml.kernel.org/r/20210826071742.877-1-liuzixian4@huawei.com Fixes: 5d317b2b6536 ("mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status") Signed-off-by: Liu Zixian liuzixian4@huawei.com Reviewed-by: Naoya Horiguchi naoya.horiguchi@nec.com Reviewed-by: Mike Kravetz mike.kravetz@oracle.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/hugetlb.h | 9 +++++++++ kernel/fork.c | 1 + 2 files changed, 10 insertions(+)
--- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -835,6 +835,11 @@ static inline spinlock_t *huge_pte_lockp
void hugetlb_report_usage(struct seq_file *m, struct mm_struct *mm);
+static inline void hugetlb_count_init(struct mm_struct *mm) +{ + atomic_long_set(&mm->hugetlb_usage, 0); +} + static inline void hugetlb_count_add(long l, struct mm_struct *mm) { atomic_long_add(l, &mm->hugetlb_usage); @@ -1019,6 +1024,10 @@ static inline spinlock_t *huge_pte_lockp return &mm->page_table_lock; }
+static inline void hugetlb_count_init(struct mm_struct *mm) +{ +} + static inline void hugetlb_report_usage(struct seq_file *f, struct mm_struct *m) { } --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1045,6 +1045,7 @@ static struct mm_struct *mm_init(struct mm->pmd_huge_pte = NULL; #endif mm_init_uprobes_state(mm); + hugetlb_count_init(mm);
if (current->mm) { mm->flags = current->mm->flags & MMF_INIT_MASK;
From: Rik van Riel riel@surriel.com
commit 32d4f4b782bb8f0ceb78c6b5dc46eb577ae25bf7 upstream.
Commit f56ce412a59d ("mm: memcontrol: fix occasional OOMs due to proportional memory.low reclaim") introduced a divide by zero corner case when oomd is being used in combination with cgroup memory.low protection.
When oomd decides to kill a cgroup, it will force the cgroup memory to be reclaimed after killing the tasks, by writing to the memory.max file for that cgroup, forcing the remaining page cache and reclaimable slab to be reclaimed down to zero.
Previously, on cgroups with some memory.low protection that would result in the memory being reclaimed down to the memory.low limit, or likely not at all, having the page cache reclaimed asynchronously later.
With f56ce412a59d the oomd write to memory.max tries to reclaim all the way down to zero, which may race with another reclaimer, to the point of ending up with the divide by zero below.
This patch implements the obvious fix.
Link: https://lkml.kernel.org/r/20210826220149.058089c6@imladris.surriel.com Fixes: f56ce412a59d ("mm: memcontrol: fix occasional OOMs due to proportional memory.low reclaim") Signed-off-by: Rik van Riel riel@surriel.com Acked-by: Roman Gushchin guro@fb.com Acked-by: Michal Hocko mhocko@suse.com Acked-by: Johannes Weiner hannes@cmpxchg.org Acked-by: Chris Down chris@chrisdown.name Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/vmscan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2576,7 +2576,7 @@ out: cgroup_size = max(cgroup_size, protection);
scan = lruvec_size - lruvec_size * protection / - cgroup_size; + (cgroup_size + 1);
/* * Minimally target SWAP_CLUSTER_MAX pages to keep
From: Vasily Averin vvs@virtuozzo.com
commit fab827dbee8c2e06ca4ba000fa6c48bcf9054aba upstream.
Commit 5d097056c9a0 ("kmemcg: account certain kmem allocations to memcg") enabled memcg accounting for pids allocated from init_pid_ns.pid_cachep, but forgot to adjust the setting for nested pid namespaces. As a result, pid memory is not accounted exactly where it is really needed, inside memcg-limited containers with their own pid namespaces.
Pid was one the first kernel objects enabled for memcg accounting. init_pid_ns.pid_cachep marked by SLAB_ACCOUNT and we can expect that any new pids in the system are memcg-accounted.
Though recently I've noticed that it is wrong. nested pid namespaces creates own slab caches for pid objects, nested pids have increased size because contain id both for all parent and for own pid namespaces. The problem is that these slab caches are _NOT_ marked by SLAB_ACCOUNT, as a result any pids allocated in nested pid namespaces are not memcg-accounted.
Pid struct in nested pid namespace consumes up to 500 bytes memory, 100000 such objects gives us up to ~50Mb unaccounted memory, this allow container to exceed assigned memcg limits.
Link: https://lkml.kernel.org/r/8b6de616-fd1a-02c6-cbdb-976ecdcfa604@virtuozzo.com Fixes: 5d097056c9a0 ("kmemcg: account certain kmem allocations to memcg") Cc: stable@vger.kernel.org Signed-off-by: Vasily Averin vvs@virtuozzo.com Reviewed-by: Michal Koutný mkoutny@suse.com Reviewed-by: Shakeel Butt shakeelb@google.com Acked-by: Christian Brauner christian.brauner@ubuntu.com Acked-by: Roman Gushchin guro@fb.com Cc: Michal Hocko mhocko@suse.com Cc: Johannes Weiner hannes@cmpxchg.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/pid_namespace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -51,7 +51,8 @@ static struct kmem_cache *create_pid_cac mutex_lock(&pid_caches_mutex); /* Name collision forces to do allocation under mutex. */ if (!*pkc) - *pkc = kmem_cache_create(name, len, 0, SLAB_HWCACHE_ALIGN, 0); + *pkc = kmem_cache_create(name, len, 0, + SLAB_HWCACHE_ALIGN | SLAB_ACCOUNT, 0); mutex_unlock(&pid_caches_mutex); /* current can fail, but someone else can succeed. */ return READ_ONCE(*pkc);
From: sumiyawang sumiyawang@tencent.com
commit 32b2397c1e56f33b0b1881def965bb89bd12f448 upstream.
There is a use after free crash when the pmem driver tears down its mapping while I/O is still inbound.
This is triggered by driver unbind, "ndctl destroy-namespace", while I/O is in flight.
Fix the sequence of blk_cleanup_queue() vs memunmap().
The crash signature is of the form:
BUG: unable to handle page fault for address: ffffc90080200000 CPU: 36 PID: 9606 Comm: systemd-udevd Call Trace: ? pmem_do_bvec+0xf9/0x3a0 ? xas_alloc+0x55/0xd0 pmem_rw_page+0x4b/0x80 bdev_read_page+0x86/0xb0 do_mpage_readpage+0x5d4/0x7a0 ? lru_cache_add+0xe/0x10 mpage_readpages+0xf9/0x1c0 ? bd_link_disk_holder+0x1a0/0x1a0 blkdev_readpages+0x1d/0x20 read_pages+0x67/0x1a0
ndctl Call Trace in vmcore: PID: 23473 TASK: ffff88c4fbbe8000 CPU: 1 COMMAND: "ndctl" __schedule schedule blk_mq_freeze_queue_wait blk_freeze_queue blk_cleanup_queue pmem_release_queue devm_action_release release_nodes devres_release_all device_release_driver_internal device_driver_detach unbind_store
Cc: stable@vger.kernel.org Signed-off-by: sumiyawang sumiyawang@tencent.com Reviewed-by: yongduan yongduan@tencent.com Link: https://lore.kernel.org/r/1629632949-14749-1-git-send-email-sumiyawang@tence... Fixes: 50f44ee7248a ("mm/devm_memremap_pages: fix final page put race") Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/nvdimm/pmem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -449,11 +449,11 @@ static int pmem_attach_disk(struct devic pmem->pfn_flags |= PFN_MAP; bb_range = pmem->pgmap.range; } else { + addr = devm_memremap(dev, pmem->phys_addr, + pmem->size, ARCH_MEMREMAP_PMEM); if (devm_add_action_or_reset(dev, pmem_release_queue, &pmem->pgmap)) return -ENOMEM; - addr = devm_memremap(dev, pmem->phys_addr, - pmem->size, ARCH_MEMREMAP_PMEM); bb_range.start = res->start; bb_range.end = res->end; }
From: Patryk Duda pdk@semihalf.com
commit 3abc16af57c9939724df92fcbda296b25cc95168 upstream.
Sometimes kernel is trying to probe Fingerprint MCU (FPMCU) when it hasn't initialized SPI yet. This can happen because FPMCU is restarted during system boot and kernel can send message in short window eg. between sysjump to RW and SPI initialization.
Cc: stable@vger.kernel.org # 4.4+ Signed-off-by: Patryk Duda pdk@semihalf.com Link: https://lore.kernel.org/r/20210518140758.29318-1-pdk@semihalf.com Signed-off-by: Benson Leung bleung@chromium.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/platform/chrome/cros_ec_proto.c | 9 +++++++++ 1 file changed, 9 insertions(+)
--- a/drivers/platform/chrome/cros_ec_proto.c +++ b/drivers/platform/chrome/cros_ec_proto.c @@ -279,6 +279,15 @@ static int cros_ec_host_command_proto_qu msg->insize = sizeof(struct ec_response_get_protocol_info);
ret = send_command(ec_dev, msg); + /* + * Send command once again when timeout occurred. + * Fingerprint MCU (FPMCU) is restarted during system boot which + * introduces small window in which FPMCU won't respond for any + * messages sent by kernel. There is no need to wait before next + * attempt because we waited at least EC_MSG_DEADLINE_MS. + */ + if (ret == -ETIMEDOUT) + ret = send_command(ec_dev, msg);
if (ret < 0) { dev_dbg(ec_dev->dev,
From: Kees Cook keescook@chromium.org
commit f9398f15605a50110bf570aaa361163a85113dd1 upstream.
The static initializer test got accidentally converted to a dynamic initializer. Fix this and retain the giant padding hole without using an aligned struct member.
Fixes: 50ceaa95ea09 ("lib: Introduce test_stackinit module") Cc: Ard Biesheuvel ardb@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20210723221933.3431999-2-keescook@chromium.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- lib/test_stackinit.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-)
--- a/lib/test_stackinit.c +++ b/lib/test_stackinit.c @@ -67,10 +67,10 @@ static bool range_contains(char *haystac #define INIT_STRUCT_none /**/ #define INIT_STRUCT_zero = { } #define INIT_STRUCT_static_partial = { .two = 0, } -#define INIT_STRUCT_static_all = { .one = arg->one, \ - .two = arg->two, \ - .three = arg->three, \ - .four = arg->four, \ +#define INIT_STRUCT_static_all = { .one = 0, \ + .two = 0, \ + .three = 0, \ + .four = 0, \ } #define INIT_STRUCT_dynamic_partial = { .two = arg->two, } #define INIT_STRUCT_dynamic_all = { .one = arg->one, \ @@ -84,8 +84,7 @@ static bool range_contains(char *haystac var.one = 0; \ var.two = 0; \ var.three = 0; \ - memset(&var.four, 0, \ - sizeof(var.four)) + var.four = 0
/* * @name: unique string name for the test @@ -210,18 +209,13 @@ struct test_small_hole { unsigned long four; };
-/* Try to trigger unhandled padding in a structure. */ -struct test_aligned { - u32 internal1; - u64 internal2; -} __aligned(64); - +/* Trigger unhandled padding in a structure. */ struct test_big_hole { u8 one; u8 two; u8 three; /* 61 byte padding hole here. */ - struct test_aligned four; + u8 four __aligned(64); } __aligned(64);
struct test_trailing_hole {
From: Jan Hoffmann jan@3e8.eu
commit 552799f8b3b0074d2617f53a63a088f9514a66e3 upstream.
Currently, outgoing packets larger than 1496 bytes are dropped when tagged VLAN is used on a switch port.
Add the frame check sequence length to the value of the register GSWIP_MAC_FLEN to fix this. This matches the lantiq_ppa vendor driver, which uses a value consisting of 1518 bytes for the MAC frame, plus the lengths of special tag and VLAN tags.
Fixes: 14fceff4771e ("net: dsa: Add Lantiq / Intel DSA driver for vrx200") Cc: stable@vger.kernel.org Signed-off-by: Jan Hoffmann jan@3e8.eu Acked-by: Hauke Mehrtens hauke@hauke-m.de Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/dsa/lantiq_gswip.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/net/dsa/lantiq_gswip.c +++ b/drivers/net/dsa/lantiq_gswip.c @@ -843,7 +843,8 @@ static int gswip_setup(struct dsa_switch
gswip_switch_mask(priv, 0, GSWIP_MAC_CTRL_2_MLEN, GSWIP_MAC_CTRL_2p(cpu_port)); - gswip_switch_w(priv, VLAN_ETH_FRAME_LEN + 8, GSWIP_MAC_FLEN); + gswip_switch_w(priv, VLAN_ETH_FRAME_LEN + 8 + ETH_FCS_LEN, + GSWIP_MAC_FLEN); gswip_switch_mask(priv, 0, GSWIP_BM_QUEUE_GCTRL_GL_MOD, GSWIP_BM_QUEUE_GCTRL);
From: Song Yoong Siang yoong.siang.song@intel.com
commit 81d0885d68ec427e62044cf46a400c9958ea0092 upstream.
tx_done is not used for napi_complete_done(). Thus, NAPI busy polling mechanism by gro_flush_timeout and napi_defer_hard_irqs will not able be triggered after a packet is transmitted when there is no receive packet.
Fix this by taking the maximum value between tx_done and rx_done as overall budget completed by the rxtx NAPI poll to ensure XDP Tx ZC operation is continuously polling for next Tx frame. This gives benefit of lower packet submission processing latency and jitter under XDP Tx ZC mode.
Performance of tx-only using xdp-sock on Intel ADL-S platform is the same with and without this patch.
root@intel-corei7-64:~# ./xdpsock -i enp0s30f4 -t -z -q 1 -n 10 sock0@enp0s30f4:1 txonly xdp-drv pps pkts 10.00 rx 0 0 tx 511630 8659520
sock0@enp0s30f4:1 txonly xdp-drv pps pkts 10.00 rx 0 0 tx 511625 13775808
sock0@enp0s30f4:1 txonly xdp-drv pps pkts 10.00 rx 0 0 tx 511619 18892032
Fixes: 132c32ee5bc0 ("net: stmmac: Add TX via XDP zero-copy socket") Cc: stable@vger.kernel.org # 5.13.x Co-developed-by: Ong Boon Leong boon.leong.ong@intel.com Signed-off-by: Ong Boon Leong boon.leong.ong@intel.com Signed-off-by: Song Yoong Siang yoong.siang.song@intel.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -5358,7 +5358,7 @@ static int stmmac_napi_poll_rxtx(struct struct stmmac_channel *ch = container_of(napi, struct stmmac_channel, rxtx_napi); struct stmmac_priv *priv = ch->priv_data; - int rx_done, tx_done; + int rx_done, tx_done, rxtx_done; u32 chan = ch->index;
priv->xstats.napi_poll++; @@ -5368,14 +5368,16 @@ static int stmmac_napi_poll_rxtx(struct
rx_done = stmmac_rx_zc(priv, budget, chan);
+ rxtx_done = max(tx_done, rx_done); + /* If either TX or RX work is not complete, return budget * and keep pooling */ - if (tx_done >= budget || rx_done >= budget) + if (rxtx_done >= budget) return budget;
/* all work done, exit the polling mode */ - if (napi_complete_done(napi, rx_done)) { + if (napi_complete_done(napi, rxtx_done)) { unsigned long flags;
spin_lock_irqsave(&ch->lock, flags); @@ -5386,7 +5388,7 @@ static int stmmac_napi_poll_rxtx(struct spin_unlock_irqrestore(&ch->lock, flags); }
- return min(rx_done, budget - 1); + return min(rxtx_done, budget - 1); }
/**
From: Thomas Zimmermann tzimmermann@suse.de
commit 147696720eca12ae48d020726208b9a61cdd80bc upstream.
Put the clock-selection code into each of the PLL-update functions to make them select the correct pixel clock. Instead of copying the code, introduce a new helper WREG_MISC_MASKED, which does masked writes into <MISC>. Use it from each individual PLL update function.
The pixel clock for video output was not actually set before programming the clock's values. It worked because the device had the correct clock pre-set.
v2: * don't duplicate <MISC> update code (Sam)
Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Fixes: db05f8d3dc87 ("drm/mgag200: Split MISC register update into PLL selection, SYNC and I/O") Acked-by: Sam Ravnborg sam@ravnborg.org Cc: Sam Ravnborg sam@ravnborg.org Cc: Emil Velikov emil.velikov@collabora.com Cc: Dave Airlie airlied@redhat.com Cc: dri-devel@lists.freedesktop.org Cc: stable@vger.kernel.org # v5.9+ Link: https://patchwork.freedesktop.org/patch/msgid/20210714142240.21979-2-tzimmer... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/mgag200/mgag200_drv.h | 16 ++++++++++++++++ drivers/gpu/drm/mgag200/mgag200_mode.c | 20 +++++++++++++------- drivers/gpu/drm/mgag200/mgag200_reg.h | 9 ++++----- 3 files changed, 33 insertions(+), 12 deletions(-)
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -43,6 +43,22 @@ #define ATTR_INDEX 0x1fc0 #define ATTR_DATA 0x1fc1
+#define WREG_MISC(v) \ + WREG8(MGA_MISC_OUT, v) + +#define RREG_MISC(v) \ + ((v) = RREG8(MGA_MISC_IN)) + +#define WREG_MISC_MASKED(v, mask) \ + do { \ + u8 misc_; \ + u8 mask_ = (mask); \ + RREG_MISC(misc_); \ + misc_ &= ~mask_; \ + misc_ |= ((v) & mask_); \ + WREG_MISC(misc_); \ + } while (0) + #define WREG_ATTR(reg, v) \ do { \ RREG8(0x1fda); \ --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -174,6 +174,8 @@ static int mgag200_g200_set_plls(struct drm_dbg_kms(dev, "clock: %ld vco: %ld m: %d n: %d p: %d s: %d\n", clock, f_vco, m, n, p, s);
+ WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK); + WREG_DAC(MGA1064_PIX_PLLC_M, m); WREG_DAC(MGA1064_PIX_PLLC_N, n); WREG_DAC(MGA1064_PIX_PLLC_P, (p | (s << 3))); @@ -289,6 +291,8 @@ static int mga_g200se_set_plls(struct mg return 1; }
+ WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK); + WREG_DAC(MGA1064_PIX_PLLC_M, m); WREG_DAC(MGA1064_PIX_PLLC_N, n); WREG_DAC(MGA1064_PIX_PLLC_P, p); @@ -385,6 +389,8 @@ static int mga_g200wb_set_plls(struct mg } }
+ WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK); + for (i = 0; i <= 32 && pll_locked == false; i++) { if (i > 0) { WREG8(MGAREG_CRTC_INDEX, 0x1e); @@ -522,6 +528,8 @@ static int mga_g200ev_set_plls(struct mg } }
+ WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK); + WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); tmp = RREG8(DAC_DATA); tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS; @@ -654,6 +662,9 @@ static int mga_g200eh_set_plls(struct mg } } } + + WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK); + for (i = 0; i <= 32 && pll_locked == false; i++) { WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); tmp = RREG8(DAC_DATA); @@ -754,6 +765,8 @@ static int mga_g200er_set_plls(struct mg } }
+ WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK); + WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); tmp = RREG8(DAC_DATA); tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS; @@ -787,8 +800,6 @@ static int mga_g200er_set_plls(struct mg
static int mgag200_crtc_set_plls(struct mga_device *mdev, long clock) { - u8 misc; - switch(mdev->type) { case G200_PCI: case G200_AGP: @@ -808,11 +819,6 @@ static int mgag200_crtc_set_plls(struct return mga_g200er_set_plls(mdev, clock); }
- misc = RREG8(MGA_MISC_IN); - misc &= ~MGAREG_MISC_CLK_SEL_MASK; - misc |= MGAREG_MISC_CLK_SEL_MGA_MSK; - WREG8(MGA_MISC_OUT, misc); - return 0; }
--- a/drivers/gpu/drm/mgag200/mgag200_reg.h +++ b/drivers/gpu/drm/mgag200/mgag200_reg.h @@ -222,11 +222,10 @@
#define MGAREG_MISC_IOADSEL (0x1 << 0) #define MGAREG_MISC_RAMMAPEN (0x1 << 1) -#define MGAREG_MISC_CLK_SEL_MASK GENMASK(3, 2) -#define MGAREG_MISC_CLK_SEL_VGA25 (0x0 << 2) -#define MGAREG_MISC_CLK_SEL_VGA28 (0x1 << 2) -#define MGAREG_MISC_CLK_SEL_MGA_PIX (0x2 << 2) -#define MGAREG_MISC_CLK_SEL_MGA_MSK (0x3 << 2) +#define MGAREG_MISC_CLKSEL_MASK GENMASK(3, 2) +#define MGAREG_MISC_CLKSEL_VGA25 (0x0 << 2) +#define MGAREG_MISC_CLKSEL_VGA28 (0x1 << 2) +#define MGAREG_MISC_CLKSEL_MGA (0x3 << 2) #define MGAREG_MISC_VIDEO_DIS (0x1 << 4) #define MGAREG_MISC_HIGH_PG_SEL (0x1 << 5) #define MGAREG_MISC_HSYNCPOL BIT(6)
From: David Heidelberg david@ixit.cz
commit cb0927ab80d224c9074f53d1a55b087d12ec5a85 upstream.
Without this fix boot throws NULL ptr exception at msm_dsi_manager_setup_encoder on devices like Nexus 7 2013 (MDP4 v4.4).
Fixes: 03436e3ec69c ("drm/msm/dsi: Move setup_encoder to modeset_init")
Cc: stable@vger.kernel.org Signed-off-by: David Heidelberg david@ixit.cz Link: https://lore.kernel.org/r/20210811170631.39296-1-david@ixit.cz Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -399,6 +399,7 @@ struct msm_kms *mdp4_kms_init(struct drm { struct platform_device *pdev = to_platform_device(dev->dev); struct mdp4_platform_config *config = mdp4_get_config(pdev); + struct msm_drm_private *priv = dev->dev_private; struct mdp4_kms *mdp4_kms; struct msm_kms *kms = NULL; struct msm_gem_address_space *aspace; @@ -418,7 +419,8 @@ struct msm_kms *mdp4_kms_init(struct drm goto fail; }
- kms = &mdp4_kms->base.base; + priv->kms = &mdp4_kms->base.base; + kms = priv->kms;
mdp4_kms->dev = dev;
From: Rajkumar Subbiah rsubbia@codeaurora.org
commit 92bd92c44d0d9be5dcbcda315b4be4b909ed9740 upstream.
Commit 2f015ec6eab6 ("drm/dp_mst: Add sideband down request tracing + selftests") added some debug code for sideband message tracing. But it seems to have unintentionally changed the behavior on sideband message failure. It catches and returns failure only if DRM_UT_DP is enabled. Otherwise it ignores the error code and returns success. So on an MST unplug, the caller is unaware that the clear payload message failed and ends up waiting for 4 seconds for the response. Fixes the issue by returning the proper error code.
Changes in V2: -- Revise commit text as review comment -- add Fixes text
Changes in V3: -- remove "unlikely" optimization
Fixes: 2f015ec6eab6 ("drm/dp_mst: Add sideband down request tracing + selftests") Cc: stable@vger.kernel.org # v5.5+ Signed-off-by: Rajkumar Subbiah rsubbia@codeaurora.org Signed-off-by: Kuogee Hsieh khsieh@codeaurora.org Reviewed-by: Stephen Boyd swboyd@chromium.org Reviewed-by: Jani Nikula jani.nikula@intel.com Reviewed-by: Lyude Paul lyude@redhat.com Signed-off-by: Lyude Paul lyude@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/1625585434-9562-1-git-send-ema... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/drm_dp_mst_topology.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
--- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -2867,11 +2867,13 @@ static int process_single_tx_qlock(struc idx += tosend + 1;
ret = drm_dp_send_sideband_msg(mgr, up, chunk, idx); - if (unlikely(ret) && drm_debug_enabled(DRM_UT_DP)) { - struct drm_printer p = drm_debug_printer(DBG_PREFIX); + if (ret) { + if (drm_debug_enabled(DRM_UT_DP)) { + struct drm_printer p = drm_debug_printer(DBG_PREFIX);
- drm_printf(&p, "sideband msg failed to send\n"); - drm_dp_mst_dump_sideband_msg_tx(&p, txmsg); + drm_printf(&p, "sideband msg failed to send\n"); + drm_dp_mst_dump_sideband_msg_tx(&p, txmsg); + } return ret; }
From: Boris Brezillon boris.brezillon@collabora.com
commit 7fdc48cc63a30fa3480d18bdd8c5fff2b9b15212 upstream.
Jobs can be in-flight when the file descriptor is closed (either because the process did not terminate properly, or because it didn't wait for all GPU jobs to be finished), and apparently panfrost_job_close() does not cancel already running jobs. Let's refcount the MMU context object so it's lifetime is no longer bound to the FD lifetime and running jobs can finish properly without generating spurious page faults.
Reported-by: Icecream95 ixn@keemail.me Fixes: 7282f7645d06 ("drm/panfrost: Implement per FD address spaces") Cc: stable@vger.kernel.org Signed-off-by: Boris Brezillon boris.brezillon@collabora.com Reviewed-by: Steven Price steven.price@arm.com Link: https://patchwork.freedesktop.org/patch/msgid/20210621133907.1683899-2-boris... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/panfrost/panfrost_device.h | 8 - drivers/gpu/drm/panfrost/panfrost_drv.c | 50 +-------- drivers/gpu/drm/panfrost/panfrost_gem.c | 20 +-- drivers/gpu/drm/panfrost/panfrost_job.c | 4 drivers/gpu/drm/panfrost/panfrost_mmu.c | 160 +++++++++++++++++++---------- drivers/gpu/drm/panfrost/panfrost_mmu.h | 5 6 files changed, 136 insertions(+), 111 deletions(-)
--- a/drivers/gpu/drm/panfrost/panfrost_device.h +++ b/drivers/gpu/drm/panfrost/panfrost_device.h @@ -120,8 +120,12 @@ struct panfrost_device { };
struct panfrost_mmu { + struct panfrost_device *pfdev; + struct kref refcount; struct io_pgtable_cfg pgtbl_cfg; struct io_pgtable_ops *pgtbl_ops; + struct drm_mm mm; + spinlock_t mm_lock; int as; atomic_t as_count; struct list_head list; @@ -132,9 +136,7 @@ struct panfrost_file_priv {
struct drm_sched_entity sched_entity[NUM_JOB_SLOTS];
- struct panfrost_mmu mmu; - struct drm_mm mm; - spinlock_t mm_lock; + struct panfrost_mmu *mmu; };
static inline struct panfrost_device *to_panfrost_device(struct drm_device *ddev) --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -417,7 +417,7 @@ static int panfrost_ioctl_madvise(struct * anyway, so let's not bother. */ if (!list_is_singular(&bo->mappings.list) || - WARN_ON_ONCE(first->mmu != &priv->mmu)) { + WARN_ON_ONCE(first->mmu != priv->mmu)) { ret = -EINVAL; goto out_unlock_mappings; } @@ -449,32 +449,6 @@ int panfrost_unstable_ioctl_check(void) return 0; }
-#define PFN_4G (SZ_4G >> PAGE_SHIFT) -#define PFN_4G_MASK (PFN_4G - 1) -#define PFN_16M (SZ_16M >> PAGE_SHIFT) - -static void panfrost_drm_mm_color_adjust(const struct drm_mm_node *node, - unsigned long color, - u64 *start, u64 *end) -{ - /* Executable buffers can't start or end on a 4GB boundary */ - if (!(color & PANFROST_BO_NOEXEC)) { - u64 next_seg; - - if ((*start & PFN_4G_MASK) == 0) - (*start)++; - - if ((*end & PFN_4G_MASK) == 0) - (*end)--; - - next_seg = ALIGN(*start, PFN_4G); - if (next_seg - *start <= PFN_16M) - *start = next_seg + 1; - - *end = min(*end, ALIGN(*start, PFN_4G) - 1); - } -} - static int panfrost_open(struct drm_device *dev, struct drm_file *file) { @@ -489,15 +463,11 @@ panfrost_open(struct drm_device *dev, st panfrost_priv->pfdev = pfdev; file->driver_priv = panfrost_priv;
- spin_lock_init(&panfrost_priv->mm_lock); - - /* 4G enough for now. can be 48-bit */ - drm_mm_init(&panfrost_priv->mm, SZ_32M >> PAGE_SHIFT, (SZ_4G - SZ_32M) >> PAGE_SHIFT); - panfrost_priv->mm.color_adjust = panfrost_drm_mm_color_adjust; - - ret = panfrost_mmu_pgtable_alloc(panfrost_priv); - if (ret) - goto err_pgtable; + panfrost_priv->mmu = panfrost_mmu_ctx_create(pfdev); + if (IS_ERR(panfrost_priv->mmu)) { + ret = PTR_ERR(panfrost_priv->mmu); + goto err_free; + }
ret = panfrost_job_open(panfrost_priv); if (ret) @@ -506,9 +476,8 @@ panfrost_open(struct drm_device *dev, st return 0;
err_job: - panfrost_mmu_pgtable_free(panfrost_priv); -err_pgtable: - drm_mm_takedown(&panfrost_priv->mm); + panfrost_mmu_ctx_put(panfrost_priv->mmu); +err_free: kfree(panfrost_priv); return ret; } @@ -521,8 +490,7 @@ panfrost_postclose(struct drm_device *de panfrost_perfcnt_close(file); panfrost_job_close(panfrost_priv);
- panfrost_mmu_pgtable_free(panfrost_priv); - drm_mm_takedown(&panfrost_priv->mm); + panfrost_mmu_ctx_put(panfrost_priv->mmu); kfree(panfrost_priv); }
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c +++ b/drivers/gpu/drm/panfrost/panfrost_gem.c @@ -60,7 +60,7 @@ panfrost_gem_mapping_get(struct panfrost
mutex_lock(&bo->mappings.lock); list_for_each_entry(iter, &bo->mappings.list, node) { - if (iter->mmu == &priv->mmu) { + if (iter->mmu == priv->mmu) { kref_get(&iter->refcount); mapping = iter; break; @@ -74,16 +74,13 @@ panfrost_gem_mapping_get(struct panfrost static void panfrost_gem_teardown_mapping(struct panfrost_gem_mapping *mapping) { - struct panfrost_file_priv *priv; - if (mapping->active) panfrost_mmu_unmap(mapping);
- priv = container_of(mapping->mmu, struct panfrost_file_priv, mmu); - spin_lock(&priv->mm_lock); + spin_lock(&mapping->mmu->mm_lock); if (drm_mm_node_allocated(&mapping->mmnode)) drm_mm_remove_node(&mapping->mmnode); - spin_unlock(&priv->mm_lock); + spin_unlock(&mapping->mmu->mm_lock); }
static void panfrost_gem_mapping_release(struct kref *kref) @@ -94,6 +91,7 @@ static void panfrost_gem_mapping_release
panfrost_gem_teardown_mapping(mapping); drm_gem_object_put(&mapping->obj->base.base); + panfrost_mmu_ctx_put(mapping->mmu); kfree(mapping); }
@@ -143,11 +141,11 @@ int panfrost_gem_open(struct drm_gem_obj else align = size >= SZ_2M ? SZ_2M >> PAGE_SHIFT : 0;
- mapping->mmu = &priv->mmu; - spin_lock(&priv->mm_lock); - ret = drm_mm_insert_node_generic(&priv->mm, &mapping->mmnode, + mapping->mmu = panfrost_mmu_ctx_get(priv->mmu); + spin_lock(&mapping->mmu->mm_lock); + ret = drm_mm_insert_node_generic(&mapping->mmu->mm, &mapping->mmnode, size >> PAGE_SHIFT, align, color, 0); - spin_unlock(&priv->mm_lock); + spin_unlock(&mapping->mmu->mm_lock); if (ret) goto err;
@@ -176,7 +174,7 @@ void panfrost_gem_close(struct drm_gem_o
mutex_lock(&bo->mappings.lock); list_for_each_entry(iter, &bo->mappings.list, node) { - if (iter->mmu == &priv->mmu) { + if (iter->mmu == priv->mmu) { mapping = iter; list_del(&iter->node); break; --- a/drivers/gpu/drm/panfrost/panfrost_job.c +++ b/drivers/gpu/drm/panfrost/panfrost_job.c @@ -165,7 +165,7 @@ static void panfrost_job_hw_submit(struc return; }
- cfg = panfrost_mmu_as_get(pfdev, &job->file_priv->mmu); + cfg = panfrost_mmu_as_get(pfdev, job->file_priv->mmu);
job_write(pfdev, JS_HEAD_NEXT_LO(js), jc_head & 0xFFFFFFFF); job_write(pfdev, JS_HEAD_NEXT_HI(js), jc_head >> 32); @@ -527,7 +527,7 @@ static irqreturn_t panfrost_job_irq_hand if (job) { pfdev->jobs[j] = NULL;
- panfrost_mmu_as_put(pfdev, &job->file_priv->mmu); + panfrost_mmu_as_put(pfdev, job->file_priv->mmu); panfrost_devfreq_record_idle(&pfdev->pfdevfreq);
dma_fence_signal_locked(job->done_fence); --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -1,5 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright 2019 Linaro, Ltd, Rob Herring robh@kernel.org */ + +#include <drm/panfrost_drm.h> + #include <linux/atomic.h> #include <linux/bitfield.h> #include <linux/delay.h> @@ -337,7 +340,7 @@ static void mmu_tlb_inv_context_s1(void
static void mmu_tlb_sync_context(void *cookie) { - //struct panfrost_device *pfdev = cookie; + //struct panfrost_mmu *mmu = cookie; // TODO: Wait 1000 GPU cycles for HW_ISSUE_6367/T60X }
@@ -352,57 +355,10 @@ static const struct iommu_flush_ops mmu_ .tlb_flush_walk = mmu_tlb_flush_walk, };
-int panfrost_mmu_pgtable_alloc(struct panfrost_file_priv *priv) -{ - struct panfrost_mmu *mmu = &priv->mmu; - struct panfrost_device *pfdev = priv->pfdev; - - INIT_LIST_HEAD(&mmu->list); - mmu->as = -1; - - mmu->pgtbl_cfg = (struct io_pgtable_cfg) { - .pgsize_bitmap = SZ_4K | SZ_2M, - .ias = FIELD_GET(0xff, pfdev->features.mmu_features), - .oas = FIELD_GET(0xff00, pfdev->features.mmu_features), - .coherent_walk = pfdev->coherent, - .tlb = &mmu_tlb_ops, - .iommu_dev = pfdev->dev, - }; - - mmu->pgtbl_ops = alloc_io_pgtable_ops(ARM_MALI_LPAE, &mmu->pgtbl_cfg, - priv); - if (!mmu->pgtbl_ops) - return -EINVAL; - - return 0; -} - -void panfrost_mmu_pgtable_free(struct panfrost_file_priv *priv) -{ - struct panfrost_device *pfdev = priv->pfdev; - struct panfrost_mmu *mmu = &priv->mmu; - - spin_lock(&pfdev->as_lock); - if (mmu->as >= 0) { - pm_runtime_get_noresume(pfdev->dev); - if (pm_runtime_active(pfdev->dev)) - panfrost_mmu_disable(pfdev, mmu->as); - pm_runtime_put_autosuspend(pfdev->dev); - - clear_bit(mmu->as, &pfdev->as_alloc_mask); - clear_bit(mmu->as, &pfdev->as_in_use_mask); - list_del(&mmu->list); - } - spin_unlock(&pfdev->as_lock); - - free_io_pgtable_ops(mmu->pgtbl_ops); -} - static struct panfrost_gem_mapping * addr_to_mapping(struct panfrost_device *pfdev, int as, u64 addr) { struct panfrost_gem_mapping *mapping = NULL; - struct panfrost_file_priv *priv; struct drm_mm_node *node; u64 offset = addr >> PAGE_SHIFT; struct panfrost_mmu *mmu; @@ -415,11 +371,10 @@ addr_to_mapping(struct panfrost_device * goto out;
found_mmu: - priv = container_of(mmu, struct panfrost_file_priv, mmu);
- spin_lock(&priv->mm_lock); + spin_lock(&mmu->mm_lock);
- drm_mm_for_each_node(node, &priv->mm) { + drm_mm_for_each_node(node, &mmu->mm) { if (offset >= node->start && offset < (node->start + node->size)) { mapping = drm_mm_node_to_panfrost_mapping(node); @@ -429,7 +384,7 @@ found_mmu: } }
- spin_unlock(&priv->mm_lock); + spin_unlock(&mmu->mm_lock); out: spin_unlock(&pfdev->as_lock); return mapping; @@ -542,6 +497,107 @@ err_bo: return ret; }
+static void panfrost_mmu_release_ctx(struct kref *kref) +{ + struct panfrost_mmu *mmu = container_of(kref, struct panfrost_mmu, + refcount); + struct panfrost_device *pfdev = mmu->pfdev; + + spin_lock(&pfdev->as_lock); + if (mmu->as >= 0) { + pm_runtime_get_noresume(pfdev->dev); + if (pm_runtime_active(pfdev->dev)) + panfrost_mmu_disable(pfdev, mmu->as); + pm_runtime_put_autosuspend(pfdev->dev); + + clear_bit(mmu->as, &pfdev->as_alloc_mask); + clear_bit(mmu->as, &pfdev->as_in_use_mask); + list_del(&mmu->list); + } + spin_unlock(&pfdev->as_lock); + + free_io_pgtable_ops(mmu->pgtbl_ops); + drm_mm_takedown(&mmu->mm); + kfree(mmu); +} + +void panfrost_mmu_ctx_put(struct panfrost_mmu *mmu) +{ + kref_put(&mmu->refcount, panfrost_mmu_release_ctx); +} + +struct panfrost_mmu *panfrost_mmu_ctx_get(struct panfrost_mmu *mmu) +{ + kref_get(&mmu->refcount); + + return mmu; +} + +#define PFN_4G (SZ_4G >> PAGE_SHIFT) +#define PFN_4G_MASK (PFN_4G - 1) +#define PFN_16M (SZ_16M >> PAGE_SHIFT) + +static void panfrost_drm_mm_color_adjust(const struct drm_mm_node *node, + unsigned long color, + u64 *start, u64 *end) +{ + /* Executable buffers can't start or end on a 4GB boundary */ + if (!(color & PANFROST_BO_NOEXEC)) { + u64 next_seg; + + if ((*start & PFN_4G_MASK) == 0) + (*start)++; + + if ((*end & PFN_4G_MASK) == 0) + (*end)--; + + next_seg = ALIGN(*start, PFN_4G); + if (next_seg - *start <= PFN_16M) + *start = next_seg + 1; + + *end = min(*end, ALIGN(*start, PFN_4G) - 1); + } +} + +struct panfrost_mmu *panfrost_mmu_ctx_create(struct panfrost_device *pfdev) +{ + struct panfrost_mmu *mmu; + + mmu = kzalloc(sizeof(*mmu), GFP_KERNEL); + if (!mmu) + return ERR_PTR(-ENOMEM); + + mmu->pfdev = pfdev; + spin_lock_init(&mmu->mm_lock); + + /* 4G enough for now. can be 48-bit */ + drm_mm_init(&mmu->mm, SZ_32M >> PAGE_SHIFT, (SZ_4G - SZ_32M) >> PAGE_SHIFT); + mmu->mm.color_adjust = panfrost_drm_mm_color_adjust; + + INIT_LIST_HEAD(&mmu->list); + mmu->as = -1; + + mmu->pgtbl_cfg = (struct io_pgtable_cfg) { + .pgsize_bitmap = SZ_4K | SZ_2M, + .ias = FIELD_GET(0xff, pfdev->features.mmu_features), + .oas = FIELD_GET(0xff00, pfdev->features.mmu_features), + .coherent_walk = pfdev->coherent, + .tlb = &mmu_tlb_ops, + .iommu_dev = pfdev->dev, + }; + + mmu->pgtbl_ops = alloc_io_pgtable_ops(ARM_MALI_LPAE, &mmu->pgtbl_cfg, + mmu); + if (!mmu->pgtbl_ops) { + kfree(mmu); + return ERR_PTR(-EINVAL); + } + + kref_init(&mmu->refcount); + + return mmu; +} + static const char *access_type_name(struct panfrost_device *pfdev, u32 fault_status) { --- a/drivers/gpu/drm/panfrost/panfrost_mmu.h +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.h @@ -18,7 +18,8 @@ void panfrost_mmu_reset(struct panfrost_ u32 panfrost_mmu_as_get(struct panfrost_device *pfdev, struct panfrost_mmu *mmu); void panfrost_mmu_as_put(struct panfrost_device *pfdev, struct panfrost_mmu *mmu);
-int panfrost_mmu_pgtable_alloc(struct panfrost_file_priv *priv); -void panfrost_mmu_pgtable_free(struct panfrost_file_priv *priv); +struct panfrost_mmu *panfrost_mmu_ctx_get(struct panfrost_mmu *mmu); +void panfrost_mmu_ctx_put(struct panfrost_mmu *mmu); +struct panfrost_mmu *panfrost_mmu_ctx_create(struct panfrost_device *pfdev);
#endif
From: Andrey Grodzovsky andrey.grodzovsky@amd.com
commit ea7acd7c5967542353430947f3faf699e70602e5 upstream.
With added CPU domain to placement you can have now 3 placemnts at once.
CC: stable@kernel.org Signed-off-by: Andrey Grodzovsky andrey.grodzovsky@amd.com Reviewed-by: Christian König christian.koenig@amd.com Link: https://patchwork.freedesktop.org/patch/msgid/20210622162339.761651-5-andrey... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -202,7 +202,7 @@ void amdgpu_bo_placement_from_domain(str c++; }
- BUG_ON(c >= AMDGPU_BO_MAX_PLACEMENTS); + BUG_ON(c > AMDGPU_BO_MAX_PLACEMENTS);
placement->num_placement = c; placement->placement = places;
From: xinhui pan xinhui.pan@amd.com
commit 703677d9345d87d7288ed8a2483ca424af7d4b3b upstream.
Fall through to handle the error instead of return.
Fixes: f8aab60422c37 ("drm/amdgpu: Initialise drm_gem_object_funcs for imported BOs") Cc: stable@vger.kernel.org Signed-off-by: xinhui pan xinhui.pan@amd.com Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -277,21 +277,18 @@ retry: r = amdgpu_gem_object_create(adev, size, args->in.alignment, initial_domain, flags, ttm_bo_type_device, resv, &gobj); - if (r) { - if (r != -ERESTARTSYS) { - if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) { - flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; - goto retry; - } + if (r && r != -ERESTARTSYS) { + if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) { + flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; + goto retry; + }
- if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) { - initial_domain |= AMDGPU_GEM_DOMAIN_GTT; - goto retry; - } - DRM_DEBUG("Failed to allocate GEM object (%llu, %d, %llu, %d)\n", - size, initial_domain, args->in.alignment, r); + if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) { + initial_domain |= AMDGPU_GEM_DOMAIN_GTT; + goto retry; } - return r; + DRM_DEBUG("Failed to allocate GEM object (%llu, %d, %llu, %d)\n", + size, initial_domain, args->in.alignment, r); }
if (flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) {
From: Aurabindo Pillai aurabindo.pillai@amd.com
commit 0bbf06d888734041e813b916d7821acd4f72005a upstream.
[Why & How] The DCN3 SoC parameter num_states was calculated but not saved into the object.
Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1403 Cc: stable@vger.kernel.org Signed-off-by: Aurabindo Pillai aurabindo.pillai@amd.com Acked-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -2467,6 +2467,7 @@ void dcn30_update_bw_bounding_box(struct dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16; }
+ dcn3_0_soc.num_states = num_states; for (i = 0; i < dcn3_0_soc.num_states; i++) { dcn3_0_soc.clock_limits[i].state = i; dcn3_0_soc.clock_limits[i].dcfclk_mhz = dcfclk_mhz[i];
From: Jerry (Fangzhi) Zuo Jerry.Zuo@amd.com
commit a7a9d11e12fcc32160d55e8612e72e5ab51b15dc upstream.
[Why] Drop hardcoded dispclk, dppclk, phyclk
[How] Read the corresponding values from clock table entries already populated.
Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1403 Cc: stable@vger.kernel.org Signed-off-by: Jerry (Fangzhi) Zuo Jerry.Zuo@amd.com Signed-off-by: Aurabindo Pillai aurabindo.pillai@amd.com Acked-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 41 +++++++++++++----- 1 file changed, 31 insertions(+), 10 deletions(-)
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -2398,16 +2398,37 @@ void dcn30_update_bw_bounding_box(struct dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
if (bw_params->clk_table.entries[0].memclk_mhz) { + int max_dcfclk_mhz = 0, max_dispclk_mhz = 0, max_dppclk_mhz = 0, max_phyclk_mhz = 0;
- if (bw_params->clk_table.entries[1].dcfclk_mhz > dcfclk_sta_targets[num_dcfclk_sta_targets-1]) { + for (i = 0; i < MAX_NUM_DPM_LVL; i++) { + if (bw_params->clk_table.entries[i].dcfclk_mhz > max_dcfclk_mhz) + max_dcfclk_mhz = bw_params->clk_table.entries[i].dcfclk_mhz; + if (bw_params->clk_table.entries[i].dispclk_mhz > max_dispclk_mhz) + max_dispclk_mhz = bw_params->clk_table.entries[i].dispclk_mhz; + if (bw_params->clk_table.entries[i].dppclk_mhz > max_dppclk_mhz) + max_dppclk_mhz = bw_params->clk_table.entries[i].dppclk_mhz; + if (bw_params->clk_table.entries[i].phyclk_mhz > max_phyclk_mhz) + max_phyclk_mhz = bw_params->clk_table.entries[i].phyclk_mhz; + } + + if (!max_dcfclk_mhz) + max_dcfclk_mhz = dcn3_0_soc.clock_limits[0].dcfclk_mhz; + if (!max_dispclk_mhz) + max_dispclk_mhz = dcn3_0_soc.clock_limits[0].dispclk_mhz; + if (!max_dppclk_mhz) + max_dppclk_mhz = dcn3_0_soc.clock_limits[0].dppclk_mhz; + if (!max_phyclk_mhz) + max_phyclk_mhz = dcn3_0_soc.clock_limits[0].phyclk_mhz; + + if (max_dcfclk_mhz > dcfclk_sta_targets[num_dcfclk_sta_targets-1]) { // If max DCFCLK is greater than the max DCFCLK STA target, insert into the DCFCLK STA target array - dcfclk_sta_targets[num_dcfclk_sta_targets] = bw_params->clk_table.entries[1].dcfclk_mhz; + dcfclk_sta_targets[num_dcfclk_sta_targets] = max_dcfclk_mhz; num_dcfclk_sta_targets++; - } else if (bw_params->clk_table.entries[1].dcfclk_mhz < dcfclk_sta_targets[num_dcfclk_sta_targets-1]) { + } else if (max_dcfclk_mhz < dcfclk_sta_targets[num_dcfclk_sta_targets-1]) { // If max DCFCLK is less than the max DCFCLK STA target, cap values and remove duplicates for (i = 0; i < num_dcfclk_sta_targets; i++) { - if (dcfclk_sta_targets[i] > bw_params->clk_table.entries[1].dcfclk_mhz) { - dcfclk_sta_targets[i] = bw_params->clk_table.entries[1].dcfclk_mhz; + if (dcfclk_sta_targets[i] > max_dcfclk_mhz) { + dcfclk_sta_targets[i] = max_dcfclk_mhz; break; } } @@ -2447,7 +2468,7 @@ void dcn30_update_bw_bounding_box(struct dcfclk_mhz[num_states] = dcfclk_sta_targets[i]; dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++]; } else { - if (j < num_uclk_states && optimal_dcfclk_for_uclk[j] <= bw_params->clk_table.entries[1].dcfclk_mhz) { + if (j < num_uclk_states && optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) { dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j]; dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16; } else { @@ -2462,7 +2483,7 @@ void dcn30_update_bw_bounding_box(struct }
while (j < num_uclk_states && num_states < DC__VOLTAGE_STATES && - optimal_dcfclk_for_uclk[j] <= bw_params->clk_table.entries[1].dcfclk_mhz) { + optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) { dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j]; dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16; } @@ -2475,9 +2496,9 @@ void dcn30_update_bw_bounding_box(struct dcn3_0_soc.clock_limits[i].dram_speed_mts = dram_speed_mts[i];
/* Fill all states with max values of all other clocks */ - dcn3_0_soc.clock_limits[i].dispclk_mhz = bw_params->clk_table.entries[1].dispclk_mhz; - dcn3_0_soc.clock_limits[i].dppclk_mhz = bw_params->clk_table.entries[1].dppclk_mhz; - dcn3_0_soc.clock_limits[i].phyclk_mhz = bw_params->clk_table.entries[1].phyclk_mhz; + dcn3_0_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz; + dcn3_0_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz; + dcn3_0_soc.clock_limits[i].phyclk_mhz = max_phyclk_mhz; dcn3_0_soc.clock_limits[i].dtbclk_mhz = dcn3_0_soc.clock_limits[0].dtbclk_mhz; /* These clocks cannot come from bw_params, always fill from dcn3_0_soc[1] */ /* FCLK, PHYCLK_D18, SOCCLK, DSCCLK */
From: Aaron Liu aaron.liu@amd.com
commit 3ca001aff0878546494d7f403334c8d987924977 upstream.
Scatter/gather is APU feature starting from carrizo. adev->apu_flags is not used for all APUs. adev->flags & AMD_IS_APU can be used for all APUs.
Signed-off-by: Aaron Liu aaron.liu@amd.com Reviewed-by: Huang Rui ray.huang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1176,7 +1176,7 @@ static int amdgpu_dm_init(struct amdgpu_ dc_hardware_init(adev->dm.dc);
#if defined(CONFIG_DRM_AMD_DC_DCN) - if (adev->apu_flags) { + if ((adev->flags & AMD_IS_APU) && (adev->asic_type >= CHIP_CARRIZO)) { struct dc_phy_addr_space_config pa_config;
mmhub_read_system_context(adev, &pa_config);
From: Kalyan Thota kalyan_t@codeaurora.org
commit 5bccb945f38b2aff334619b23b50bb0a6a9995a5 upstream.
Add safe lut configuration for all the targets in dpu driver as per QOS recommendation.
Issue reported on SC7280:
With wait-for-safe feature in smmu enabled, RT client buffer levels are checked to be safe before smmu invalidation. Since display was always set to unsafe it was delaying the invalidaiton process thus impacting the performance on NRT clients such as eMMC and NVMe.
Validated this change on SC7280, With this change eMMC performance has improved significantly.
Changes in v2: - Add fixes tag (Sai) - CC stable kernel (Dimtry)
Changes in v3: - Correct fixes tag with appropriate hash (stephen) - Resend patch adding reviewed by tag - Resend patch adding correct format for pushing into stable tree (Greg)
Fixes: 591e34a091d1 ("drm/msm/disp/dpu1: add support for display for SC7280 target") Cc: stable@vger.kernel.org Signed-off-by: Kalyan Thota kalyan_t@codeaurora.org Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Tested-by: Sai Prakash Ranjan saiprakash.ranjan@codeaurora.org (sc7280, sc7180) Link: https://lore.kernel.org/r/1628070028-2616-1-git-send-email-kalyan_t@codeauro... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -902,6 +902,7 @@ static const struct dpu_perf_cfg sdm845_ .amortizable_threshold = 25, .min_prefill_lines = 24, .danger_lut_tbl = {0xf, 0xffff, 0x0}, + .safe_lut_tbl = {0xfff0, 0xf000, 0xffff}, .qos_lut_tbl = { {.nentry = ARRAY_SIZE(sdm845_qos_linear), .entries = sdm845_qos_linear @@ -929,6 +930,7 @@ static const struct dpu_perf_cfg sc7180_ .min_dram_ib = 1600000, .min_prefill_lines = 24, .danger_lut_tbl = {0xff, 0xffff, 0x0}, + .safe_lut_tbl = {0xfff0, 0xff00, 0xffff}, .qos_lut_tbl = { {.nentry = ARRAY_SIZE(sc7180_qos_linear), .entries = sc7180_qos_linear @@ -956,6 +958,7 @@ static const struct dpu_perf_cfg sm8150_ .min_dram_ib = 800000, .min_prefill_lines = 24, .danger_lut_tbl = {0xf, 0xffff, 0x0}, + .safe_lut_tbl = {0xfff8, 0xf000, 0xffff}, .qos_lut_tbl = { {.nentry = ARRAY_SIZE(sm8150_qos_linear), .entries = sm8150_qos_linear @@ -984,6 +987,7 @@ static const struct dpu_perf_cfg sm8250_ .min_dram_ib = 800000, .min_prefill_lines = 35, .danger_lut_tbl = {0xf, 0xffff, 0x0}, + .safe_lut_tbl = {0xfff0, 0xff00, 0xffff}, .qos_lut_tbl = { {.nentry = ARRAY_SIZE(sc7180_qos_linear), .entries = sc7180_qos_linear @@ -1012,6 +1016,7 @@ static const struct dpu_perf_cfg sc7280_ .min_dram_ib = 1600000, .min_prefill_lines = 24, .danger_lut_tbl = {0xffff, 0xffff, 0x0}, + .safe_lut_tbl = {0xff00, 0xff00, 0xffff}, .qos_lut_tbl = { {.nentry = ARRAY_SIZE(sc7180_qos_macrotile), .entries = sc7180_qos_macrotile
From: Alyssa Rosenzweig alyssa.rosenzweig@collabora.com
commit b5fab345654c603c07525100d744498f28786929 upstream.
In lock_region, simplify the calculation of the region_width parameter. This field is the size, but encoded as ceil(log2(size)) - 1. ceil(log2(size)) may be computed directly as fls(size - 1). However, we want to use the 64-bit versions as the amount to lock can exceed 32-bits.
This avoids undefined (and completely wrong) behaviour when locking all memory (size ~0). In this case, the old code would "round up" ~0 to the nearest page, overflowing to 0. Since fls(0) == 0, this would calculate a region width of 10 + 0 = 10. But then the code would shift by (region_width - 11) = -1. As shifting by a negative number is undefined, UBSAN flags the bug. Of course, even if it were defined the behaviour is wrong, instead of locking all memory almost none would get locked.
The new form of the calculation corrects this special case and avoids the undefined behaviour.
Signed-off-by: Alyssa Rosenzweig alyssa.rosenzweig@collabora.com Reported-and-tested-by: Chris Morgan macromorgan@hotmail.com Fixes: f3ba91228e8e ("drm/panfrost: Add initial panfrost driver") Cc: stable@vger.kernel.org Reviewed-by: Steven Price steven.price@arm.com Reviewed-by: Rob Herring robh@kernel.org Signed-off-by: Steven Price steven.price@arm.com Link: https://patchwork.freedesktop.org/patch/msgid/20210824173028.7528-2-alyssa.r... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/panfrost/panfrost_mmu.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-)
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -59,21 +59,12 @@ static void lock_region(struct panfrost_ { u8 region_width; u64 region = iova & PAGE_MASK; - /* - * fls returns: - * 1 .. 32 - * - * 10 + fls(num_pages) - * results in the range (11 .. 42) - */ - - size = round_up(size, PAGE_SIZE);
- region_width = 10 + fls(size >> PAGE_SHIFT); - if ((size >> PAGE_SHIFT) != (1ul << (region_width - 11))) { - /* not pow2, so must go up to the next pow2 */ - region_width += 1; - } + /* The size is encoded as ceil(log2) minus(1), which may be calculated + * with fls. The size must be clamped to hardware bounds. + */ + size = max_t(u64, size, PAGE_SIZE); + region_width = fls64(size - 1) - 1; region |= region_width;
/* Lock the region that needs to be updated */
From: Alyssa Rosenzweig alyssa.rosenzweig@collabora.com
commit a77b58825d7221d4a45c47881c35a47ba003aa73 upstream.
Mali virtual addresses are 48-bit. Use a u64 instead of size_t to ensure we can express the "lock everything" condition as ~0ULL without overflow. This code was silently broken on any platform where a size_t is less than 48-bits; in particular, it was broken on 32-bit armv7 platforms which remain in use with panfrost. (Mainly RK3288)
Signed-off-by: Alyssa Rosenzweig alyssa.rosenzweig@collabora.com Suggested-by: Rob Herring robh@kernel.org Tested-by: Chris Morgan macromorgan@hotmail.com Reviewed-by: Steven Price steven.price@arm.com Reviewed-by: Rob Herring robh@kernel.org Fixes: f3ba91228e8e ("drm/panfrost: Add initial panfrost driver") Cc: stable@vger.kernel.org Signed-off-by: Steven Price steven.price@arm.com Link: https://patchwork.freedesktop.org/patch/msgid/20210824173028.7528-3-alyssa.r... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/panfrost/panfrost_mmu.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -55,7 +55,7 @@ static int write_cmd(struct panfrost_dev }
static void lock_region(struct panfrost_device *pfdev, u32 as_nr, - u64 iova, size_t size) + u64 iova, u64 size) { u8 region_width; u64 region = iova & PAGE_MASK; @@ -75,7 +75,7 @@ static void lock_region(struct panfrost_
static int mmu_hw_do_operation_locked(struct panfrost_device *pfdev, int as_nr, - u64 iova, size_t size, u32 op) + u64 iova, u64 size, u32 op) { if (as_nr < 0) return 0; @@ -92,7 +92,7 @@ static int mmu_hw_do_operation_locked(st
static int mmu_hw_do_operation(struct panfrost_device *pfdev, struct panfrost_mmu *mmu, - u64 iova, size_t size, u32 op) + u64 iova, u64 size, u32 op) { int ret;
@@ -109,7 +109,7 @@ static void panfrost_mmu_enable(struct p u64 transtab = cfg->arm_mali_lpae_cfg.transtab; u64 memattr = cfg->arm_mali_lpae_cfg.memattr;
- mmu_hw_do_operation_locked(pfdev, as_nr, 0, ~0UL, AS_COMMAND_FLUSH_MEM); + mmu_hw_do_operation_locked(pfdev, as_nr, 0, ~0ULL, AS_COMMAND_FLUSH_MEM);
mmu_write(pfdev, AS_TRANSTAB_LO(as_nr), transtab & 0xffffffffUL); mmu_write(pfdev, AS_TRANSTAB_HI(as_nr), transtab >> 32); @@ -125,7 +125,7 @@ static void panfrost_mmu_enable(struct p
static void panfrost_mmu_disable(struct panfrost_device *pfdev, u32 as_nr) { - mmu_hw_do_operation_locked(pfdev, as_nr, 0, ~0UL, AS_COMMAND_FLUSH_MEM); + mmu_hw_do_operation_locked(pfdev, as_nr, 0, ~0ULL, AS_COMMAND_FLUSH_MEM);
mmu_write(pfdev, AS_TRANSTAB_LO(as_nr), 0); mmu_write(pfdev, AS_TRANSTAB_HI(as_nr), 0); @@ -225,7 +225,7 @@ static size_t get_pgsize(u64 addr, size_
static void panfrost_mmu_flush_range(struct panfrost_device *pfdev, struct panfrost_mmu *mmu, - u64 iova, size_t size) + u64 iova, u64 size) { if (mmu->as < 0) return;
From: Alyssa Rosenzweig alyssa.rosenzweig@collabora.com
commit bd7ffbc3ca12629aeb66fb9e28cf42b7f37e3e3b upstream.
When locking a region, we currently clamp to a PAGE_SIZE as the minimum lock region. While this is valid for Midgard, it is invalid for Bifrost, where the minimum locking size is 8x larger than the 4k page size. Add a hardware definition for the minimum lock region size (corresponding to KBASE_LOCK_REGION_MIN_SIZE_LOG2 in kbase) and respect it.
Signed-off-by: Alyssa Rosenzweig alyssa.rosenzweig@collabora.com Tested-by: Chris Morgan macromorgan@hotmail.com Reviewed-by: Steven Price steven.price@arm.com Reviewed-by: Rob Herring robh@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Steven Price steven.price@arm.com Link: https://patchwork.freedesktop.org/patch/msgid/20210824173028.7528-4-alyssa.r... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/panfrost/panfrost_mmu.c | 2 +- drivers/gpu/drm/panfrost/panfrost_regs.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -63,7 +63,7 @@ static void lock_region(struct panfrost_ /* The size is encoded as ceil(log2) minus(1), which may be calculated * with fls. The size must be clamped to hardware bounds. */ - size = max_t(u64, size, PAGE_SIZE); + size = max_t(u64, size, AS_LOCK_REGION_MIN_SIZE); region_width = fls64(size - 1) - 1; region |= region_width;
--- a/drivers/gpu/drm/panfrost/panfrost_regs.h +++ b/drivers/gpu/drm/panfrost/panfrost_regs.h @@ -318,6 +318,8 @@ #define AS_FAULTSTATUS_ACCESS_TYPE_READ (0x2 << 8) #define AS_FAULTSTATUS_ACCESS_TYPE_WRITE (0x3 << 8)
+#define AS_LOCK_REGION_MIN_SIZE (1ULL << 15) + #define gpu_write(dev, reg, data) writel(data, dev->iomem + reg) #define gpu_read(dev, reg) readl(dev->iomem + reg)
On 9/16/21 9:55 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.13.19 release. There are 380 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat, 18 Sep 2021 15:57:06 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.13.19-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.13.y and the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
Tested-by: Shuah Khan skhan@linuxfoundation.org
thanks, -- Shuah
On 9/16/21 8:55 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.13.19 release. There are 380 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat, 18 Sep 2021 15:57:06 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.13.19-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.13.y and the diffstat can be found below.
thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels:
Tested-by: Florian Fainelli <f.fainelli@gmail.com
On Thu, 16 Sep 2021 17:55:57 +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.13.19 release. There are 380 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat, 18 Sep 2021 15:57:06 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.13.19-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.13.y and the diffstat can be found below.
thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v5.13: 10 builds: 10 pass, 0 fail 28 boots: 28 pass, 0 fail 110 tests: 110 pass, 0 fail
Linux version: 5.13.19-rc1-gd32cd39db441 Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000, tegra194-p2972-0000, tegra194-p3509-0000+p3668-0000, tegra20-ventana, tegra210-p2371-2180, tegra210-p3450-0000, tegra30-cardhu-a04
Tested-by: Jon Hunter jonathanh@nvidia.com
Jon
On Thu, 16 Sept 2021 at 21:47, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.13.19 release. There are 380 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat, 18 Sep 2021 15:57:06 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.13.19-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.13.y and the diffstat can be found below.
thanks,
greg k-h
Results from Linaro’s test farm. No regressions on arm64, arm, x86_64, and i386.
Tested-by: Linux Kernel Functional Testing lkft@linaro.org
## Build * kernel: 5.13.19-rc1 * git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc * git branch: linux-5.13.y * git commit: d32cd39db441202928dd0b4aaae98f80d3bcd7a5 * git describe: v5.13.18-381-gd32cd39db441 * test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.13.y/build/v5.13....
## No regressions (compared to v5.13.17-69-g9af0951786ff)
## No fixes (compared to v5.13.17-69-g9af0951786ff)
## Test result summary total: 94139, pass: 78739, fail: 1134, skip: 13277, xfail: 989
## Build Summary * arc: 10 total, 10 passed, 0 failed * arm: 289 total, 277 passed, 12 failed * arm64: 39 total, 39 passed, 0 failed * dragonboard-410c: 1 total, 1 passed, 0 failed * hi6220-hikey: 1 total, 1 passed, 0 failed * i386: 38 total, 38 passed, 0 failed * juno-r2: 1 total, 1 passed, 0 failed * mips: 51 total, 51 passed, 0 failed * parisc: 12 total, 12 passed, 0 failed * powerpc: 36 total, 35 passed, 1 failed * riscv: 30 total, 30 passed, 0 failed * s390: 18 total, 18 passed, 0 failed * sh: 24 total, 24 passed, 0 failed * sparc: 12 total, 12 passed, 0 failed * x15: 1 total, 0 passed, 1 failed * x86: 1 total, 1 passed, 0 failed * x86_64: 39 total, 39 passed, 0 failed
## Test suites summary * fwts * igt-gpu-tools * install-android-platform-tools-r2600 * kselftest-android * kselftest-arm64 * kselftest-arm64/arm64.btitest.bti_c_func * kselftest-arm64/arm64.btitest.bti_j_func * kselftest-arm64/arm64.btitest.bti_jc_func * kselftest-arm64/arm64.btitest.bti_none_func * kselftest-arm64/arm64.btitest.nohint_func * kselftest-arm64/arm64.btitest.paciasp_func * kselftest-arm64/arm64.nobtitest.bti_c_func * kselftest-arm64/arm64.nobtitest.bti_j_func * kselftest-arm64/arm64.nobtitest.bti_jc_func * kselftest-arm64/arm64.nobtitest.bti_none_func * kselftest-arm64/arm64.nobtitest.nohint_func * kselftest-arm64/arm64.nobtitest.paciasp_func * kselftest-bpf * kselftest-breakpoints * kselftest-capabilities * kselftest-cgroup * kselftest-clone3 * kselftest-core * kselftest-cpu-hotplug * kselftest-cpufreq * kselftest-drivers * kselftest-efivarfs * kselftest-filesystems * kselftest-firmware * kselftest-fpu * kselftest-futex * kselftest-gpio * kselftest-intel_pstate * kselftest-ipc * kselftest-ir * kselftest-kcmp * kselftest-kexec * kselftest-kvm * kselftest-lib * kselftest-livepatch * kselftest-lkdtm * kselftest-membarrier * kselftest-memfd * kselftest-memory-hotplug * kselftest-mincore * kselftest-mount * kselftest-mqueue * kselftest-net * kselftest-netfilter * kselftest-nsfs * kselftest-openat2 * kselftest-pid_namespace * kselftest-pidfd * kselftest-proc * kselftest-pstore * kselftest-ptrace * kselftest-rseq * kselftest-rtc * kselftest-seccomp * kselftest-sigaltstack * kselftest-size * kselftest-splice * kselftest-static_keys * kselftest-sync * kselftest-sysctl * kselftest-tc-testing * kselftest-timens * kselftest-timers * kselftest-tmpfs * kselftest-tpm2 * kselftest-user * kselftest-vm * kselftest-x86 * kselftest-zram * kunit * kvm-unit-tests * libgpiod * libhugetlbfs * linux-log-parser * ltp-cap_bounds-tests * ltp-co[ * ltp-commands-tests * ltp-containers-tests * ltp-controllers-tests * ltp-cpuhotplug-tests * ltp-crypto-tests * ltp-cve-tests * ltp-dio-tests * ltp-fcntl-locktests-tests * ltp-filecaps-tests * ltp-fs-tests * ltp-fs_bind-tests * ltp-fs_perms_simple-tests * ltp-fsx-tests * ltp-hugetlb-tests * ltp-io-tests * ltp-ipc-tests * ltp-math-tests * ltp-mm-tests * ltp-nptl-tests * ltp-open-posix-tests * ltp-pty-tests * ltp-sched-tests * ltp-securebits-tests * ltp-syscalls-tests * ltp-tracing-tests * network-basic-tests * packetdrill * perf * rcutorture * ssuite * v4l2-compliance
-- Linaro LKFT https://lkft.linaro.org
On Thu, Sep 16, 2021 at 05:55:57PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.13.19 release. There are 380 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat, 18 Sep 2021 15:57:06 +0000. Anything received after that time might be too late.
Build results: total: 154 pass: 154 fail: 0 Qemu test results: total: 480 pass: 480 fail: 0
Tested-by: Guenter Roeck linux@roeck-us.net
Guenter
On Thu, 16 Sep 2021 17:55:57 +0200, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.13.19 release. There are 380 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat, 18 Sep 2021 15:57:06 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.13.19-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.13.y and the diffstat can be found below.
thanks,
greg k-h
5.13.19-rc1 Successfully Compiled and booted on my Raspberry PI 4b (8g) (bcm2711)
Tested-by: Fox Chen foxhlchen@gmail.com
linux-stable-mirror@lists.linaro.org